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", &OnAction_ft},
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 */
90 {RTW_WLAN_CATEGORY_WNM, "ACTION_WNM", &on_action_wnm},
92 {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
93 {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
94 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
95 {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht},
96 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
100 u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
102 /**************************************************
103 OUI definitions for the vendor specific IE
104 ***************************************************/
105 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
106 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
107 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
108 unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
109 unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
111 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
112 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
114 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
115 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
117 extern unsigned char REALTEK_96B_IE[];
119 #ifdef LEGACY_CHANNEL_PLAN_REF
120 /********************************************************
121 ChannelPlan definitions
122 *********************************************************/
123 static RT_CHANNEL_PLAN legacy_channel_plan[] = {
124 /* 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},
125 /* 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},
126 /* 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},
127 /* 0x03, RTW_CHPLAN_SPAIN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
128 /* 0x04, RTW_CHPLAN_FRANCE */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
129 /* 0x05, RTW_CHPLAN_MKK */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
130 /* 0x06, RTW_CHPLAN_MKK1 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
131 /* 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},
132 /* 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},
133 /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
134 /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
135 /* 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},
136 /* 0x0C, RTW_CHPLAN_CHINA */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 149, 153, 157, 161, 165}, 18},
137 /* 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},
138 /* 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},
139 /* 0x0F, RTW_CHPLAN_TURKEY */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19},
140 /* 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},
141 /* 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},
142 /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */ {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48}, 17},
143 /* 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},
144 /* 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},
148 static struct ch_list_t RTW_ChannelPlan2G[] = {
149 /* 0, RTW_RD_2G_NULL */ CH_LIST_ENT(0),
150 /* 1, RTW_RD_2G_WORLD */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13),
151 /* 2, RTW_RD_2G_ETSI1 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13),
152 /* 3, RTW_RD_2G_FCC1 */ CH_LIST_ENT(11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),
153 /* 4, RTW_RD_2G_MKK1 */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
154 /* 5, RTW_RD_2G_ETSI2 */ CH_LIST_ENT(4, 10, 11, 12, 13),
155 /* 6, RTW_RD_2G_GLOBAL */ CH_LIST_ENT(14, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14),
156 /* 7, RTW_RD_2G_MKK2 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13),
157 /* 8, RTW_RD_2G_FCC2 */ CH_LIST_ENT(13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13),
160 #ifdef CONFIG_IEEE80211_BAND_5GHZ
161 static struct ch_list_t RTW_ChannelPlan5G[] = {
162 /* 0, RTW_RD_5G_NULL */ CH_LIST_ENT(0),
163 /* 1, RTW_RD_5G_ETSI1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140),
164 /* 2, RTW_RD_5G_ETSI2 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165),
165 /* 3, RTW_RD_5G_ETSI3 */ CH_LIST_ENT(22, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165),
166 /* 4, RTW_RD_5G_FCC1 */ CH_LIST_ENT(24, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165),
167 /* 5, RTW_RD_5G_FCC2 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165),
168 /* 6, RTW_RD_5G_FCC3 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165),
169 /* 7, RTW_RD_5G_FCC4 */ CH_LIST_ENT(12, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161),
170 /* 8, RTW_RD_5G_FCC5 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165),
171 /* 9, RTW_RD_5G_FCC6 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64),
172 /* 10, RTW_RD_5G_FCC7 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165),
173 /* 11, RTW_RD_5G_KCC1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161),
174 /* 12, RTW_RD_5G_MKK1 */ CH_LIST_ENT(19, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140),
175 /* 13, RTW_RD_5G_MKK2 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64),
176 /* 14, RTW_RD_5G_MKK3 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140),
177 /* 15, RTW_RD_5G_NCC1 */ CH_LIST_ENT(16, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165),
178 /* 16, RTW_RD_5G_NCC2 */ CH_LIST_ENT(8, 56, 60, 64, 149, 153, 157, 161, 165),
179 /* 17, RTW_RD_5G_NCC3 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165),
180 /* 18, RTW_RD_5G_ETSI4 */ CH_LIST_ENT(4, 36, 40, 44, 48),
181 /* 19, RTW_RD_5G_ETSI5 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165),
182 /* 20, RTW_RD_5G_FCC8 */ CH_LIST_ENT(4, 149, 153, 157, 161),
183 /* 21, RTW_RD_5G_ETSI6 */ CH_LIST_ENT(8, 36, 40, 44, 48, 52, 56, 60, 64),
184 /* 22, RTW_RD_5G_ETSI7 */ CH_LIST_ENT(13, 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165),
185 /* 23, RTW_RD_5G_ETSI8 */ CH_LIST_ENT(9, 36, 40, 44, 48, 149, 153, 157, 161, 165),
186 /* 24, RTW_RD_5G_ETSI9 */ CH_LIST_ENT(11, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140),
187 /* 25, RTW_RD_5G_ETSI10 */ CH_LIST_ENT(5, 149, 153, 157, 161, 165),
188 /* 26, RTW_RD_5G_ETSI11 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165),
189 /* 27, RTW_RD_5G_NCC4 */ CH_LIST_ENT(17, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165),
190 /* 28, RTW_RD_5G_ETSI12 */ CH_LIST_ENT(4, 149, 153, 157, 161),
191 /* 29, RTW_RD_5G_FCC9 */ CH_LIST_ENT(21, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165),
192 /* 30, RTW_RD_5G_ETSI13 */ CH_LIST_ENT(16, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140),
193 /* 31, RTW_RD_5G_FCC10 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161),
194 /* 32, RTW_RD_5G_MKK4 */ CH_LIST_ENT(4, 36, 40, 44, 48),
195 /* 33, RTW_RD_5G_ETSI14 */ CH_LIST_ENT(11, 36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140),
196 /* 34, RTW_RD_5G_FCC11 */ CH_LIST_ENT(25, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 161, 165),
198 /* === Below are driver defined for legacy channel plan compatible, NO static index assigned ==== */
199 /* RTW_RD_5G_OLD_FCC1 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165),
200 /* RTW_RD_5G_OLD_NCC1 */ CH_LIST_ENT(15, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165),
201 /* RTW_RD_5G_OLD_KCC1 */ CH_LIST_ENT(20, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165),
203 #endif /* CONFIG_IEEE80211_BAND_5GHZ */
205 static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[] = {
206 /* ===== 0x00 ~ 0x1F, legacy channel plan ===== */
207 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_KCC1, TXPWR_LMT_FCC), /* 0x00, RTW_CHPLAN_FCC */
208 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_OLD_FCC1, TXPWR_LMT_FCC), /* 0x01, RTW_CHPLAN_IC */
209 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI), /* 0x02, RTW_CHPLAN_ETSI */
210 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), /* 0x03, RTW_CHPLAN_SPAIN */
211 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), /* 0x04, RTW_CHPLAN_FRANCE */
212 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK), /* 0x05, RTW_CHPLAN_MKK */
213 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK), /* 0x06, RTW_CHPLAN_MKK1 */
214 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_FCC6, TXPWR_LMT_ETSI), /* 0x07, RTW_CHPLAN_ISRAEL */
215 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_FCC6, TXPWR_LMT_MKK), /* 0x08, RTW_CHPLAN_TELEC */
216 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x09, RTW_CHPLAN_GLOBAL_DOAMIN */
217 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x0A, RTW_CHPLAN_WORLD_WIDE_13 */
218 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_OLD_NCC1, TXPWR_LMT_FCC), /* 0x0B, RTW_CHPLAN_TAIWAN */
219 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_FCC5, TXPWR_LMT_ETSI), /* 0x0C, RTW_CHPLAN_CHINA */
220 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC3, TXPWR_LMT_WW), /* 0x0D, RTW_CHPLAN_SINGAPORE_INDIA_MEXICO */ /* ETSI:Singapore, India. FCC:Mexico => WW */
221 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_OLD_KCC1, TXPWR_LMT_ETSI), /* 0x0E, RTW_CHPLAN_KOREA */
222 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC6, TXPWR_LMT_ETSI), /* 0x0F, RTW_CHPLAN_TURKEY */
223 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI1, TXPWR_LMT_MKK), /* 0x10, RTW_CHPLAN_JAPAN */
224 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC), /* 0x11, RTW_CHPLAN_FCC_NO_DFS */
225 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_FCC7, TXPWR_LMT_MKK), /* 0x12, RTW_CHPLAN_JAPAN_NO_DFS */
226 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_WW), /* 0x13, RTW_CHPLAN_WORLD_WIDE_5G */
227 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC), /* 0x14, RTW_CHPLAN_TAIWAN_NO_DFS */
228 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC7, TXPWR_LMT_ETSI), /* 0x15, RTW_CHPLAN_ETSI_NO_DFS */
229 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_NCC1, TXPWR_LMT_ETSI), /* 0x16, RTW_CHPLAN_KOREA_NO_DFS */
230 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_FCC7, TXPWR_LMT_MKK), /* 0x17, RTW_CHPLAN_JAPAN_NO_DFS */
231 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC5, TXPWR_LMT_ETSI), /* 0x18, RTW_CHPLAN_PAKISTAN_NO_DFS */
232 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC5, TXPWR_LMT_FCC), /* 0x19, RTW_CHPLAN_TAIWAN2_NO_DFS */
233 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1A, */
234 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1B, */
235 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1C, */
236 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1D, */
237 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x1E, */
238 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_FCC1, TXPWR_LMT_WW), /* 0x1F, RTW_CHPLAN_WORLD_WIDE_ONLY_5G */
240 /* ===== 0x20 ~ 0x7F, new channel plan ===== */
241 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x20, RTW_CHPLAN_WORLD_NULL */
242 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), /* 0x21, RTW_CHPLAN_ETSI1_NULL */
243 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NULL, TXPWR_LMT_FCC), /* 0x22, RTW_CHPLAN_FCC1_NULL */
244 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_NULL, TXPWR_LMT_MKK), /* 0x23, RTW_CHPLAN_MKK1_NULL */
245 CHPLAN_ENT(RTW_RD_2G_ETSI2, RTW_RD_5G_NULL, TXPWR_LMT_ETSI), /* 0x24, RTW_CHPLAN_ETSI2_NULL */
246 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC1, TXPWR_LMT_FCC), /* 0x25, RTW_CHPLAN_FCC1_FCC1 */
247 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI1, TXPWR_LMT_ETSI), /* 0x26, RTW_CHPLAN_WORLD_ETSI1 */
248 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK1, TXPWR_LMT_MKK), /* 0x27, RTW_CHPLAN_MKK1_MKK1 */
249 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_KCC1, TXPWR_LMT_ETSI), /* 0x28, RTW_CHPLAN_WORLD_KCC1 */
250 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC2, TXPWR_LMT_FCC), /* 0x29, RTW_CHPLAN_WORLD_FCC2 */
251 CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_NULL, TXPWR_LMT_FCC), /* 0x2A, RTW_CHPLAN_FCC2_NULL */
252 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x2B, */
253 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x2C, */
254 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x2D, */
255 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x2E, */
256 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x2F, */
257 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC3, TXPWR_LMT_FCC), /* 0x30, RTW_CHPLAN_WORLD_FCC3 */
258 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC4, TXPWR_LMT_FCC), /* 0x31, RTW_CHPLAN_WORLD_FCC4 */
259 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC5, TXPWR_LMT_FCC), /* 0x32, RTW_CHPLAN_WORLD_FCC5 */
260 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC6, TXPWR_LMT_FCC), /* 0x33, RTW_CHPLAN_WORLD_FCC6 */
261 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC7, TXPWR_LMT_FCC), /* 0x34, RTW_CHPLAN_FCC1_FCC7 */
262 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI2, TXPWR_LMT_ETSI), /* 0x35, RTW_CHPLAN_WORLD_ETSI2 */
263 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI3, TXPWR_LMT_ETSI), /* 0x36, RTW_CHPLAN_WORLD_ETSI3 */
264 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK2, TXPWR_LMT_MKK), /* 0x37, RTW_CHPLAN_MKK1_MKK2 */
265 CHPLAN_ENT(RTW_RD_2G_MKK1, RTW_RD_5G_MKK3, TXPWR_LMT_MKK), /* 0x38, RTW_CHPLAN_MKK1_MKK3 */
266 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC1, TXPWR_LMT_FCC), /* 0x39, RTW_CHPLAN_FCC1_NCC1 */
267 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x3A, */
268 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x3B, */
269 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x3C, */
270 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x3D, */
271 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x3E, */
272 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x3F, */
273 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC2, TXPWR_LMT_FCC), /* 0x40, RTW_CHPLAN_FCC1_NCC2 */
274 CHPLAN_ENT(RTW_RD_2G_GLOBAL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x41, RTW_CHPLAN_GLOBAL_NULL */
275 CHPLAN_ENT(RTW_RD_2G_ETSI1, RTW_RD_5G_ETSI4, TXPWR_LMT_ETSI), /* 0x42, RTW_CHPLAN_ETSI1_ETSI4 */
276 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC2, TXPWR_LMT_FCC), /* 0x43, RTW_CHPLAN_FCC1_FCC2 */
277 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC3, TXPWR_LMT_FCC), /* 0x44, RTW_CHPLAN_FCC1_NCC3 */
278 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI5, TXPWR_LMT_ETSI), /* 0x45, RTW_CHPLAN_WORLD_ETSI5 */
279 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC8, TXPWR_LMT_FCC), /* 0x46, RTW_CHPLAN_FCC1_FCC8 */
280 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI6, TXPWR_LMT_ETSI), /* 0x47, RTW_CHPLAN_WORLD_ETSI6 */
281 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI7, TXPWR_LMT_ETSI), /* 0x48, RTW_CHPLAN_WORLD_ETSI7 */
282 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI8, TXPWR_LMT_ETSI), /* 0x49, RTW_CHPLAN_WORLD_ETSI8 */
283 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x4A, */
284 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x4B, */
285 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x4C, */
286 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x4D, */
287 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x4E, */
288 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x4F, */
289 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI9, TXPWR_LMT_ETSI), /* 0x50, RTW_CHPLAN_WORLD_ETSI9 */
290 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI10, TXPWR_LMT_ETSI), /* 0x51, RTW_CHPLAN_WORLD_ETSI10 */
291 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI11, TXPWR_LMT_ETSI), /* 0x52, RTW_CHPLAN_WORLD_ETSI11 */
292 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_NCC4, TXPWR_LMT_FCC), /* 0x53, RTW_CHPLAN_FCC1_NCC4 */
293 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI12, TXPWR_LMT_ETSI), /* 0x54, RTW_CHPLAN_WORLD_ETSI12 */
294 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC9, TXPWR_LMT_FCC), /* 0x55, RTW_CHPLAN_FCC1_FCC9 */
295 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI13, TXPWR_LMT_ETSI), /* 0x56, RTW_CHPLAN_WORLD_ETSI13 */
296 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC10, TXPWR_LMT_FCC), /* 0x57, RTW_CHPLAN_FCC1_FCC10 */
297 CHPLAN_ENT(RTW_RD_2G_MKK2, RTW_RD_5G_MKK4, TXPWR_LMT_MKK), /* 0x58, RTW_CHPLAN_MKK2_MKK4 */
298 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_ETSI14, TXPWR_LMT_ETSI), /* 0x59, RTW_CHPLAN_WORLD_ETSI14 */
299 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x5A, */
300 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x5B, */
301 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x5C, */
302 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x5D, */
303 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x5E, */
304 CHPLAN_ENT(RTW_RD_2G_NULL, RTW_RD_5G_NULL, TXPWR_LMT_WW), /* 0x5F, */
305 CHPLAN_ENT(RTW_RD_2G_FCC1, RTW_RD_5G_FCC5, TXPWR_LMT_FCC), /* 0x60, RTW_CHPLAN_FCC1_FCC5 */
306 CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC7, TXPWR_LMT_FCC), /* 0x61, RTW_CHPLAN_FCC2_FCC7 */
307 CHPLAN_ENT(RTW_RD_2G_FCC2, RTW_RD_5G_FCC1, TXPWR_LMT_FCC), /* 0x62, RTW_CHPLAN_FCC2_FCC1 */
310 static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE =
311 CHPLAN_ENT(RTW_RD_2G_WORLD, RTW_RD_5G_FCC1, TXPWR_LMT_FCC); /* 0x7F, Realtek Define */
313 bool rtw_chplan_is_empty(u8 id)
315 RT_CHANNEL_PLAN_MAP *chplan_map;
317 if (id == RTW_CHPLAN_REALTEK_DEFINE)
318 chplan_map = &RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE;
320 chplan_map = &RTW_ChannelPlanMap[id];
322 if (chplan_map->Index2G == RTW_RD_2G_NULL
323 #ifdef CONFIG_IEEE80211_BAND_5GHZ
324 && chplan_map->Index5G == RTW_RD_5G_NULL
332 void rtw_rfctl_init(_adapter *adapter)
334 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
336 _rtw_memset(rfctl, 0, sizeof(*rfctl));
338 #ifdef CONFIG_DFS_MASTER
339 rfctl->cac_start_time = rfctl->cac_end_time = RTW_CAC_STOPPED;
341 /* TODO: dfs_master_timer */
345 #ifdef CONFIG_DFS_MASTER
347 * called in rtw_dfs_master_enable()
348 * assume the request channel coverage is DFS range
349 * base on the current status and the request channel coverage to check if need to reset complete CAC time
351 bool rtw_is_cac_reset_needed(_adapter *adapter, u8 ch, u8 bw, u8 offset)
353 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
354 bool needed = _FALSE;
355 u32 cur_hi, cur_lo, hi, lo;
357 if (rfctl->radar_detected == 1) {
362 if (rfctl->radar_detect_ch == 0) {
367 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
368 RTW_ERR("request detection range ch:%u, bw:%u, offset:%u\n", ch, bw, offset);
372 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &cur_hi, &cur_lo) == _FALSE) {
373 RTW_ERR("cur detection range ch:%u, bw:%u, offset:%u\n", rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
377 if (hi <= lo || cur_hi <= cur_lo) {
378 RTW_ERR("hi:%u, lo:%u, cur_hi:%u, cur_lo:%u\n", hi, lo, cur_hi, cur_lo);
382 if (rtw_is_range_a_in_b(hi, lo, cur_hi, cur_lo)) {
383 /* request is in current detect range */
387 /* check if request channel coverage has new range and the new range is in DFS range */
388 if (!rtw_is_range_overlap(hi, lo, cur_hi, cur_lo)) {
389 /* request has no overlap with current */
391 } else if (rtw_is_range_a_in_b(cur_hi, cur_lo, hi, lo)) {
392 /* request is supper set of current */
393 if ((hi != cur_hi && rtw_is_dfs_range(hi, cur_hi)) || (lo != cur_lo && rtw_is_dfs_range(cur_lo, lo)))
396 /* request is not supper set of current, but has overlap */
397 if ((lo < cur_lo && rtw_is_dfs_range(cur_lo, lo)) || (hi > cur_hi && rtw_is_dfs_range(hi, cur_hi)))
405 bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
409 u32 r_hi = 0, r_lo = 0;
412 if (rfctl->radar_detect_by_others)
415 if (rfctl->radar_detect_ch == 0)
418 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
423 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch
424 , rfctl->radar_detect_bw, rfctl->radar_detect_offset
425 , &r_hi, &r_lo) == _FALSE) {
430 if (rtw_is_range_overlap(hi, lo, r_hi, r_lo))
437 bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl)
439 return _rtw_rfctl_overlap_radar_detect_ch(rfctl
440 , rfctl_to_dvobj(rfctl)->oper_channel
441 , rfctl_to_dvobj(rfctl)->oper_bwmode
442 , rfctl_to_dvobj(rfctl)->oper_ch_offset);
445 bool rtw_rfctl_is_tx_blocked_by_ch_waiting(struct rf_ctl_t *rfctl)
447 return rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_CH_WAITING(rfctl);
450 bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
456 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
459 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
460 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
465 if (!CH_IS_NON_OCP(&ch_set[i]))
468 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
469 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
480 u32 rtw_chset_get_ch_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
487 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
490 current_time = rtw_get_current_time();
492 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
493 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
498 if (!CH_IS_NON_OCP(&ch_set[i]))
501 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
502 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
504 if (rtw_systime_to_ms(ch_set[i].non_ocp_end_time - current_time) > ms)
505 ms = rtw_systime_to_ms(ch_set[i].non_ocp_end_time - current_time);
514 * rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set
515 * @ch_set: the given channel set
516 * @ch: channel number on which radar is detected
517 * @bw: bandwidth on which radar is detected
518 * @offset: bandwidth offset on which radar is detected
519 * @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS
521 static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
526 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
529 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
530 if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
535 if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
536 && rtw_ch2freq(ch_set[i].ChannelNum) <= hi
539 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
541 ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS);
549 inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
551 _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1);
554 inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
556 _rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms);
559 u32 rtw_get_ch_waiting_ms(_adapter *adapter, u8 ch, u8 bw, u8 offset, u32 *r_non_ocp_ms, u32 *r_cac_ms)
561 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
562 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
565 u8 in_rd_range = 0; /* if in current radar detection range*/
567 if (rtw_chset_is_ch_non_ocp(mlmeext->channel_set, ch, bw, offset))
568 non_ocp_ms = rtw_chset_get_ch_non_ocp_ms(mlmeext->channel_set, ch, bw, offset);
572 if (rfctl->dfs_master_enabled) {
573 u32 cur_hi, cur_lo, hi, lo;
575 if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
576 RTW_ERR("input range ch:%u, bw:%u, offset:%u\n", ch, bw, offset);
580 if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &cur_hi, &cur_lo) == _FALSE) {
581 RTW_ERR("cur detection range ch:%u, bw:%u, offset:%u\n", rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
585 if (rtw_is_range_a_in_b(hi, lo, cur_hi, cur_lo))
589 if (!rtw_is_dfs_ch(ch, bw, offset))
591 else if (in_rd_range && !non_ocp_ms) {
592 if (IS_CH_WAITING(rfctl))
593 cac_ms = rtw_systime_to_ms(rfctl->cac_end_time - rtw_get_current_time());
596 } else if (rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(adapter)))
597 cac_ms = CAC_TIME_CE_MS;
599 cac_ms = CAC_TIME_MS;
602 *r_non_ocp_ms = non_ocp_ms;
606 return non_ocp_ms + cac_ms;
609 void rtw_reset_cac(_adapter *adapter, u8 ch, u8 bw, u8 offset)
611 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
615 rtw_get_ch_waiting_ms(adapter
623 rfctl->cac_start_time = rtw_get_current_time() + rtw_ms_to_systime(non_ocp_ms);
624 rfctl->cac_end_time = rfctl->cac_start_time + rtw_ms_to_systime(cac_ms);
626 /* skip special value */
627 if (rfctl->cac_start_time == RTW_CAC_STOPPED) {
628 rfctl->cac_start_time++;
629 rfctl->cac_end_time++;
631 if (rfctl->cac_end_time == RTW_CAC_STOPPED)
632 rfctl->cac_end_time++;
634 #endif /* CONFIG_DFS_MASTER */
636 /* choose channel with shortest waiting (non ocp + cac) time */
637 bool rtw_choose_shortest_waiting_ch(_adapter *adapter, u8 req_bw, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset, u8 d_flags)
639 #ifndef DBG_CHOOSE_SHORTEST_WAITING_CH
640 #define DBG_CHOOSE_SHORTEST_WAITING_CH 0
643 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
644 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
645 struct registry_priv *regsty = adapter_to_regsty(adapter);
647 u8 ch_c = 0, bw_c = 0, offset_c = 0;
649 u32 min_waiting_ms = 0;
651 if (!dec_ch || !dec_bw || !dec_offset) {
656 /* full search and narrow bw judegement first to avoid potetial judegement timing issue */
657 for (bw = CHANNEL_WIDTH_20; bw <= req_bw; bw++) {
658 if (!hal_is_bw_support(adapter, bw))
661 for (i = 0; i < mlmeext->max_chan_nums; i++) {
666 ch = mlmeext->channel_set[i].ChannelNum;
668 if ((d_flags & RTW_CHF_2G) && ch <= 14)
671 if ((d_flags & RTW_CHF_5G) && ch > 14)
675 if (bw > REGSTY_BW_5G(regsty))
678 if (bw > REGSTY_BW_2G(regsty))
682 if (!rtw_get_offset_by_chbw(ch, bw, &offset))
685 if (!rtw_chset_is_chbw_valid(mlmeext->channel_set, ch, bw, offset))
688 if ((d_flags & RTW_CHF_NON_OCP) && rtw_chset_is_ch_non_ocp(mlmeext->channel_set, ch, bw, offset))
691 if ((d_flags & RTW_CHF_DFS) && rtw_is_dfs_ch(ch, bw, offset))
694 if ((d_flags & RTW_CHF_LONG_CAC) && rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(adapter)))
697 if ((d_flags & RTW_CHF_NON_DFS) && !rtw_is_dfs_ch(ch, bw, offset))
700 if ((d_flags & RTW_CHF_NON_LONG_CAC) && !rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(adapter)))
703 #ifdef CONFIG_DFS_MASTER
704 waiting_ms = rtw_get_ch_waiting_ms(adapter, ch, bw, offset, &non_ocp_ms, &cac_ms);
707 if (DBG_CHOOSE_SHORTEST_WAITING_CH)
708 RTW_INFO(FUNC_ADPT_FMT":%u,%u,%u %u(non_ocp:%u, cac:%u)\n"
709 , FUNC_ADPT_ARG(adapter), ch, bw, offset, waiting_ms, non_ocp_ms, cac_ms);
712 || min_waiting_ms > waiting_ms
713 || (min_waiting_ms == waiting_ms && bw > bw_c) /* wider bw first */
718 min_waiting_ms = waiting_ms;
724 RTW_INFO(FUNC_ADPT_FMT": d_flags:0x%02x %u,%u,%u waiting_ms:%u\n"
725 , FUNC_ADPT_ARG(adapter), d_flags, ch_c, bw_c, offset_c, min_waiting_ms);
729 *dec_offset = offset_c;
739 void dump_country_chplan(void *sel, const struct country_chplan *ent)
741 _RTW_PRINT_SEL(sel, "\"%c%c\", 0x%02X%s\n"
742 , ent->alpha2[0], ent->alpha2[1], ent->chplan
743 , COUNTRY_CHPLAN_EN_11AC(ent) ? " ac" : ""
747 void dump_country_chplan_map(void *sel)
749 const struct country_chplan *ent;
752 #if RTW_DEF_MODULE_REGULATORY_CERT
753 _RTW_PRINT_SEL(sel, "RTW_DEF_MODULE_REGULATORY_CERT:0x%x\n", RTW_DEF_MODULE_REGULATORY_CERT);
755 #ifdef CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP
756 _RTW_PRINT_SEL(sel, "CONFIG_CUSTOMIZED_COUNTRY_CHPLAN_MAP\n");
759 for (code[0] = 'A'; code[0] <= 'Z'; code[0]++) {
760 for (code[1] = 'A'; code[1] <= 'Z'; code[1]++) {
761 ent = rtw_get_chplan_from_country(code);
765 dump_country_chplan(sel, ent);
770 void dump_chplan_id_list(void *sel)
774 for (i = 0; i < RTW_CHPLAN_MAX; i++) {
775 if (!rtw_is_channel_plan_valid(i))
778 _RTW_PRINT_SEL(sel, "0x%02X ", i);
781 RTW_PRINT_SEL(sel, "0x7F\n");
784 void dump_chplan_test(void *sel)
788 /* check invalid channel */
789 for (i = 0; i < RTW_RD_2G_MAX; i++) {
790 for (j = 0; j < CH_LIST_LEN(RTW_ChannelPlan2G[i]); j++) {
791 if (rtw_ch2freq(CH_LIST_CH(RTW_ChannelPlan2G[i], j)) == 0)
792 RTW_PRINT_SEL(sel, "invalid ch:%u at (%d,%d)\n", CH_LIST_CH(RTW_ChannelPlan2G[i], j), i, j);
796 #ifdef CONFIG_IEEE80211_BAND_5GHZ
797 for (i = 0; i < RTW_RD_5G_MAX; i++) {
798 for (j = 0; j < CH_LIST_LEN(RTW_ChannelPlan5G[i]); j++) {
799 if (rtw_ch2freq(CH_LIST_CH(RTW_ChannelPlan5G[i], j)) == 0)
800 RTW_PRINT_SEL(sel, "invalid ch:%u at (%d,%d)\n", CH_LIST_CH(RTW_ChannelPlan5G[i], j), i, j);
806 void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set)
810 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
811 RTW_PRINT_SEL(sel, "ch:%3u, freq:%u, scan_type:%d"
812 , ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType);
814 #ifdef CONFIG_FIND_BEST_CHANNEL
815 _RTW_PRINT_SEL(sel, ", rx_count:%u", ch_set[i].rx_count);
818 #ifdef CONFIG_DFS_MASTER
819 if (rtw_is_dfs_ch(ch_set[i].ChannelNum, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
820 if (CH_IS_NON_OCP(&ch_set[i]))
821 _RTW_PRINT_SEL(sel, ", non_ocp:%d"
822 , rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()));
824 _RTW_PRINT_SEL(sel, ", non_ocp:N/A");
828 _RTW_PRINT_SEL(sel, "\n");
831 RTW_PRINT_SEL(sel, "total ch number:%d\n", i);
834 void dump_cur_chset(void *sel, _adapter *adapter)
836 struct mlme_priv *mlme = &adapter->mlmepriv;
837 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
838 struct registry_priv *regsty = adapter_to_regsty(adapter);
839 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);
842 if (mlme->country_ent)
843 dump_country_chplan(sel, mlme->country_ent);
845 RTW_PRINT_SEL(sel, "chplan:0x%02X\n", mlme->ChannelPlan);
847 RTW_PRINT_SEL(sel, "2G_PLS:%u, 5G_PLS:%u\n"
848 , hal_data->Regulation2_4G, hal_data->Regulation5G);
850 #ifdef CONFIG_DFS_MASTER
851 RTW_PRINT_SEL(sel, "dfs_domain:%u\n", rtw_odm_get_dfs_domain(adapter));
854 for (i = 0; i < MAX_CHANNEL_NUM; i++)
855 if (regsty->excl_chs[i] != 0)
858 if (i < MAX_CHANNEL_NUM) {
859 _RTW_PRINT_SEL(sel, "excl_chs:");
860 for (i = 0; i < MAX_CHANNEL_NUM; i++) {
861 if (regsty->excl_chs[i] == 0)
863 _RTW_PRINT_SEL(sel, "%u ", regsty->excl_chs[i]);
865 RTW_PRINT_SEL(sel, "\n");
868 dump_chset(sel, mlmeext->channel_set);
872 * Search the @param ch in given @param ch_set
873 * @ch_set: the given channel set
874 * @ch: the given channel number
876 * return the index of channel_num in channel_set, -1 if not found
878 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
881 for (i = 0; ch_set[i].ChannelNum != 0; i++) {
882 if (ch == ch_set[i].ChannelNum)
886 if (i >= ch_set[i].ChannelNum)
892 * Check if the @param ch, bw, offset is valid for the given @param ch_set
893 * @ch_set: the given channel set
894 * @ch: the given channel number
895 * @bw: the given bandwidth
896 * @offset: the given channel offset
898 * return valid (1) or not (0)
900 u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
908 cch = rtw_get_center_ch(ch, bw, offset);
910 if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num))
913 for (i = 0; i < op_ch_num; i++) {
915 RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i));
916 if (rtw_ch_set_search_ch(ch_set, *(op_chs + i)) == -1)
920 if (op_ch_num != 0 && i == op_ch_num)
928 * Check the @param ch is fit with setband setting of @param adapter
929 * @adapter: the given adapter
930 * @ch: the given channel number
932 * return _TRUE when check valid, _FALSE not valid
934 bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
936 if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
937 || (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
938 || (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
943 inline void RTW_SET_SCAN_BAND_SKIP(_adapter *padapter, int skip_band)
945 int bs = ATOMIC_READ(&padapter->bandskip);
948 ATOMIC_SET(&padapter->bandskip, bs);
951 inline void RTW_CLR_SCAN_BAND_SKIP(_adapter *padapter, int skip_band)
953 int bs = ATOMIC_READ(&padapter->bandskip);
956 ATOMIC_SET(&padapter->bandskip, bs);
958 inline int RTW_GET_SCAN_BAND_SKIP(_adapter *padapter)
960 return ATOMIC_READ(&padapter->bandskip);
963 #define RTW_IS_SCAN_BAND_SKIP(padapter, skip_band) (ATOMIC_READ(&padapter->bandskip) & (skip_band))
965 bool rtw_mlme_ignore_chan(_adapter *adapter, const u32 ch)
967 if (RTW_IS_SCAN_BAND_SKIP(adapter, BAND_24G) && ch < 35) /* SKIP 2.4G Band channel */
969 if (RTW_IS_SCAN_BAND_SKIP(adapter, BAND_5G) && ch > 35) /* SKIP 5G Band channel */
976 /****************************************************************************
978 Following are the initialization functions for WiFi MLME
980 *****************************************************************************/
982 int init_hw_mlme_ext(_adapter *padapter)
984 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
986 /* set_opmode_cmd(padapter, infra_client_with_mlme); */ /* removed */
988 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
993 void init_mlme_default_rate_set(_adapter *padapter)
995 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
997 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};
998 unsigned char mixed_basicrate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
999 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0xff, 0x00, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1001 _rtw_memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
1002 _rtw_memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
1004 _rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
1007 static void init_mlme_ext_priv_value(_adapter *padapter)
1009 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1010 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1012 ATOMIC_SET(&pmlmeext->event_seq, 0);
1013 pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
1014 #ifdef CONFIG_IEEE80211W
1015 pmlmeext->sa_query_seq = 0;
1016 pmlmeext->mgnt_80211w_IPN = 0;
1017 pmlmeext->mgnt_80211w_IPN_rx = 0;
1018 #endif /* CONFIG_IEEE80211W */
1019 pmlmeext->cur_channel = padapter->registrypriv.channel;
1020 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
1021 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1023 pmlmeext->retry = 0;
1025 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
1027 init_mlme_default_rate_set(padapter);
1029 if (pmlmeext->cur_channel > 14)
1030 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
1032 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
1034 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
1035 pmlmeext->sitesurvey_res.channel_idx = 0;
1036 pmlmeext->sitesurvey_res.bss_cnt = 0;
1037 pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO;
1038 pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
1039 pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
1040 #ifdef CONFIG_SCAN_BACKOP
1041 mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1042 mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1043 pmlmeext->sitesurvey_res.scan_cnt = 0;
1044 pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH;
1045 pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS;
1047 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
1048 pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0;
1050 pmlmeext->scan_abort = _FALSE;
1052 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1053 pmlmeinfo->reauth_count = 0;
1054 pmlmeinfo->reassoc_count = 0;
1055 pmlmeinfo->link_count = 0;
1056 pmlmeinfo->auth_seq = 0;
1057 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1058 pmlmeinfo->key_index = 0;
1061 pmlmeinfo->enc_algo = _NO_PRIVACY_;
1062 pmlmeinfo->authModeToggle = 0;
1064 _rtw_memset(pmlmeinfo->chg_txt, 0, 128);
1066 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1067 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
1069 pmlmeinfo->dialogToken = 0;
1071 pmlmeext->action_public_rxseq = 0xffff;
1072 pmlmeext->action_public_dialog_token = 0xff;
1075 static int has_channel(RT_CHANNEL_INFO *channel_set,
1081 for (i = 0; i < chanset_size; i++) {
1082 if (channel_set[i].ChannelNum == chan)
1089 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
1091 struct p2p_channels *channel_list)
1093 struct registry_priv *regsty = adapter_to_regsty(padapter);
1095 struct p2p_oper_class_map op_class[] = {
1096 { IEEE80211G, 81, 1, 13, 1, BW20 },
1097 { IEEE80211G, 82, 14, 14, 1, BW20 },
1098 #if 0 /* Do not enable HT40 on 2 GHz */
1099 { IEEE80211G, 83, 1, 9, 1, BW40PLUS },
1100 { IEEE80211G, 84, 5, 13, 1, BW40MINUS },
1102 { IEEE80211A, 115, 36, 48, 4, BW20 },
1103 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
1104 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
1105 { IEEE80211A, 124, 149, 161, 4, BW20 },
1106 { IEEE80211A, 125, 149, 169, 4, BW20 },
1107 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
1108 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
1109 { -1, 0, 0, 0, 0, BW20 }
1116 for (op = 0; op_class[op].op_class; op++) {
1118 struct p2p_oper_class_map *o = &op_class[op];
1119 struct p2p_reg_class *reg = NULL;
1121 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
1122 if (!has_channel(channel_set, chanset_size, ch))
1125 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
1128 if ((REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)) &&
1129 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
1133 reg = &channel_list->reg_class[cla];
1135 reg->reg_class = o->op_class;
1138 reg->channel[reg->channels] = ch;
1142 channel_list->reg_classes = cla;
1146 bool rtw_regsty_is_excl_chs(struct registry_priv *regsty, u8 ch)
1150 for (i = 0; i < MAX_CHANNEL_NUM; i++) {
1151 if (regsty->excl_chs[i] == 0)
1153 if (regsty->excl_chs[i] == ch)
1159 static u8 init_channel_set(_adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
1161 struct registry_priv *regsty = adapter_to_regsty(padapter);
1162 u8 index, chanset_size = 0;
1163 u8 b5GBand = _FALSE, b2_4GBand = _FALSE;
1164 u8 Index2G = 0, Index5G = 0;
1165 HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
1168 if (!rtw_is_channel_plan_valid(ChannelPlan)) {
1169 RTW_ERR("ChannelPlan ID 0x%02X error !!!!!\n", ChannelPlan);
1170 return chanset_size;
1173 _rtw_memset(channel_set, 0, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM);
1175 if (IsSupported24G(padapter->registrypriv.wireless_mode))
1178 if (is_supported_5g(padapter->registrypriv.wireless_mode))
1182 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
1183 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
1185 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
1187 for (index = 0; index < CH_LIST_LEN(RTW_ChannelPlan2G[Index2G]); index++) {
1188 if (rtw_regsty_is_excl_chs(regsty, CH_LIST_CH(RTW_ChannelPlan2G[Index2G], index)) == _TRUE)
1191 channel_set[chanset_size].ChannelNum = CH_LIST_CH(RTW_ChannelPlan2G[Index2G], index);
1193 if (RTW_CHPLAN_GLOBAL_DOAMIN == ChannelPlan
1194 || RTW_CHPLAN_GLOBAL_NULL == ChannelPlan
1196 /* Channel 1~11 is active, and 12~14 is passive */
1197 if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
1198 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
1199 else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
1200 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
1201 } else if (RTW_CHPLAN_WORLD_WIDE_13 == ChannelPlan
1202 || RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan
1203 || RTW_RD_2G_WORLD == Index2G
1205 /* channel 12~13, passive scan */
1206 if (channel_set[chanset_size].ChannelNum <= 11)
1207 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
1209 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
1211 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
1217 #ifdef CONFIG_IEEE80211_BAND_5GHZ
1219 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan)
1220 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
1222 Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
1224 for (index = 0; index < CH_LIST_LEN(RTW_ChannelPlan5G[Index5G]); index++) {
1225 if (rtw_regsty_is_excl_chs(regsty, CH_LIST_CH(RTW_ChannelPlan5G[Index5G], index)) == _TRUE)
1228 channel_set[chanset_size].ChannelNum = CH_LIST_CH(RTW_ChannelPlan5G[Index5G], index);
1229 if (channel_set[chanset_size].ChannelNum <= 48
1230 || channel_set[chanset_size].ChannelNum >= 149
1232 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
1233 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
1235 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
1237 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
1239 #else /* CONFIG_DFS */
1240 if (CH_LIST_CH(RTW_ChannelPlan5G[Index5G], index) <= 48
1241 || CH_LIST_CH(RTW_ChannelPlan5G[Index5G], index) >= 149
1243 channel_set[chanset_size].ChannelNum = CH_LIST_CH(RTW_ChannelPlan5G[Index5G], index);
1244 if (RTW_CHPLAN_WORLD_WIDE_5G == ChannelPlan) /* passive scan for all 5G channels */
1245 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
1247 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
1250 #endif /* CONFIG_DFS */
1254 #ifdef CONFIG_DFS_MASTER
1255 for (i = 0; i < chanset_size; i++)
1256 channel_set[i].non_ocp_end_time = rtw_get_current_time();
1258 #endif /* CONFIG_IEEE80211_BAND_5GHZ */
1260 if (RTW_CHPLAN_REALTEK_DEFINE == ChannelPlan) {
1261 hal_data->Regulation2_4G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
1262 hal_data->Regulation5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.regd;
1264 hal_data->Regulation2_4G = RTW_ChannelPlanMap[ChannelPlan].regd;
1265 hal_data->Regulation5G = RTW_ChannelPlanMap[ChannelPlan].regd;
1268 RTW_INFO(FUNC_ADPT_FMT" ChannelPlan ID:0x%02x, ch num:%d\n"
1269 , FUNC_ADPT_ARG(padapter), ChannelPlan, chanset_size);
1271 return chanset_size;
1274 int init_mlme_ext_priv(_adapter *padapter)
1277 struct registry_priv *pregistrypriv = &padapter->registrypriv;
1278 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1279 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1280 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1282 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
1283 /* _rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); */
1285 pmlmeext->padapter = padapter;
1287 /* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */
1289 init_mlme_ext_priv_value(padapter);
1290 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
1292 init_mlme_ext_timer(padapter);
1294 #ifdef CONFIG_AP_MODE
1295 init_mlme_ap_info(padapter);
1298 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set);
1299 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
1300 pmlmeext->last_scan_time = 0;
1301 pmlmeext->mlmeext_init = _TRUE;
1304 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
1305 pmlmeext->active_keep_alive_check = _TRUE;
1307 pmlmeext->active_keep_alive_check = _FALSE;
1310 #ifdef DBG_FIXED_CHAN
1311 pmlmeext->fixed_chan = 0xFF;
1318 void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
1320 _adapter *padapter = pmlmeext->padapter;
1325 if (rtw_is_drv_stopped(padapter)) {
1326 _cancel_timer_ex(&pmlmeext->survey_timer);
1327 _cancel_timer_ex(&pmlmeext->link_timer);
1328 /* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */
1332 static u8 cmp_pkt_chnl_diff(_adapter *padapter, u8 *pframe, uint packet_len)
1334 /* if the channel is same, return 0. else return channel differential */
1338 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
1341 if (padapter->mlmeextpriv.cur_channel >= channel)
1342 return padapter->mlmeextpriv.cur_channel - channel;
1344 return channel - padapter->mlmeextpriv.cur_channel;
1349 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
1351 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1352 u8 *pframe = precv_frame->u.hdr.rx_data;
1355 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
1356 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1357 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1360 ptable->func(padapter, precv_frame);
1365 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1368 struct mlme_handler *ptable;
1369 #ifdef CONFIG_AP_MODE
1370 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1371 #endif /* CONFIG_AP_MODE */
1372 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1373 u8 *pframe = precv_frame->u.hdr.rx_data;
1374 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, get_addr2_ptr(pframe));
1375 struct dvobj_priv *psdpriv = padapter->dvobj;
1376 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1382 pbuf = GetAddr1Ptr(pframe);
1383 RTW_INFO("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1384 pbuf = get_addr2_ptr(pframe);
1385 RTW_INFO("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1386 pbuf = GetAddr3Ptr(pframe);
1387 RTW_INFO("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1391 if (GetFrameType(pframe) != WIFI_MGT_TYPE) {
1395 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
1396 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1397 !_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1400 ptable = mlme_sta_tbl;
1402 index = get_frame_sub_type(pframe) >> 4;
1405 if ((index << 4) == WIFI_ACTION) {
1406 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1407 if (*(pframe + 24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe + 25) == TDLS_DISCOVERY_RESPONSE) {
1408 RTW_INFO("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(get_addr2_ptr(pframe)));
1409 On_TDLS_Dis_Rsp(padapter, precv_frame);
1412 #endif /* CONFIG_TDLS */
1414 if (index >= (sizeof(mlme_sta_tbl) / sizeof(struct mlme_handler))) {
1421 if (GetRetry(pframe)) {
1422 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) {
1423 /* drop the duplicate management frame */
1424 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++;
1425 RTW_INFO("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
1429 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
1433 if (GetRetry(pframe)) {
1438 #ifdef CONFIG_AP_MODE
1439 switch (get_frame_sub_type(pframe)) {
1441 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1442 ptable->func = &OnAuth;
1444 ptable->func = &OnAuthClient;
1447 case WIFI_REASSOCREQ:
1448 _mgt_dispatcher(padapter, ptable, precv_frame);
1449 #ifdef CONFIG_HOSTAPD_MLME
1450 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1451 rtw_hostapd_mlme_rx(padapter, precv_frame);
1455 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1456 #ifdef CONFIG_HOSTAPD_MLME
1457 rtw_hostapd_mlme_rx(padapter, precv_frame);
1459 _mgt_dispatcher(padapter, ptable, precv_frame);
1462 _mgt_dispatcher(padapter, ptable, precv_frame);
1465 _mgt_dispatcher(padapter, ptable, precv_frame);
1468 /* if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) */
1469 _mgt_dispatcher(padapter, ptable, precv_frame);
1472 _mgt_dispatcher(padapter, ptable, precv_frame);
1473 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1474 rtw_hostapd_mlme_rx(padapter, precv_frame);
1479 _mgt_dispatcher(padapter, ptable, precv_frame);
1486 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
1488 bool response = _TRUE;
1490 #ifdef CONFIG_IOCTL_CFG80211
1491 if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
1492 if (rtw_cfg80211_get_is_roch(padapter) == _FALSE
1493 || rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
1494 || adapter_wdev_data(padapter)->p2p_enabled == _FALSE
1495 || padapter->mlmepriv.wps_probe_resp_ie == NULL
1496 || padapter->mlmepriv.p2p_probe_resp_ie == NULL
1498 #ifdef CONFIG_DEBUG_CFG80211
1499 RTW_INFO(ADPT_FMT" DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n"
1500 , ADPT_ARG(padapter)
1501 , adapter_wdev_data(padapter)->p2p_enabled
1502 , padapter->mlmepriv.wps_probe_resp_ie
1503 , padapter->mlmepriv.p2p_probe_resp_ie);
1504 RTW_INFO(ADPT_FMT" DON'T issue_probersp_p2p: is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n"
1505 , ADPT_ARG(padapter)
1506 , rtw_cfg80211_get_is_roch(padapter)
1507 , rtw_get_oper_ch(padapter)
1508 , padapter->wdinfo.listen_channel);
1513 #endif /* CONFIG_IOCTL_CFG80211 */
1514 if (padapter->wdinfo.driver_interface == DRIVER_WEXT) {
1515 /* do nothing if the device name is empty */
1516 if (!padapter->wdinfo.device_name_len)
1520 if (response == _TRUE)
1521 issue_probersp_p2p(padapter, da);
1525 #endif /* CONFIG_P2P */
1528 /****************************************************************************
1530 Following are the callback functions for each subtype of the management frames
1532 *****************************************************************************/
1534 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
1538 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1539 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1540 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1541 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
1542 u8 *pframe = precv_frame->u.hdr.rx_data;
1543 uint len = precv_frame->u.hdr.len;
1544 u8 is_valid_p2p_probereq = _FALSE;
1546 #ifdef CONFIG_ATMEL_RC_PATCH
1547 u8 *target_ie = NULL, *wps_ie = NULL;
1549 uint search_len = 0, wps_ielen = 0, target_ielen = 0;
1550 struct sta_info *psta;
1551 struct sta_priv *pstapriv = &padapter->stapriv;
1556 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1557 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1558 u8 wifi_test_chk_rate = 1;
1560 #ifdef CONFIG_IOCTL_CFG80211
1561 if ((pwdinfo->driver_interface == DRIVER_CFG80211)
1562 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
1563 && (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE)
1565 rtw_cfg80211_rx_probe_request(padapter, precv_frame);
1568 #endif /* CONFIG_IOCTL_CFG80211 */
1570 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1571 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
1572 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
1573 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
1574 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1576 /* Commented by Albert 2011/03/17 */
1577 /* mcs_rate = 0->CCK 1M rate */
1578 /* mcs_rate = 1->CCK 2M rate */
1579 /* mcs_rate = 2->CCK 5.5M rate */
1580 /* mcs_rate = 3->CCK 11M rate */
1581 /* In the P2P mode, the driver should not support the CCK rate */
1583 /* Commented by Kurt 2012/10/16 */
1584 /* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
1585 if (padapter->registrypriv.wifi_spec == 1) {
1586 if (pattrib->data_rate <= 3)
1587 wifi_test_chk_rate = 0;
1590 if (wifi_test_chk_rate == 1) {
1591 is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len);
1592 if (is_valid_p2p_probereq == _TRUE) {
1593 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
1595 if (padapter->wdinfo.driver_interface == DRIVER_WEXT)
1596 report_survey_event(padapter, precv_frame);
1598 p2p_listen_state_process(padapter, get_sa(pframe));
1603 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1610 #endif /* CONFIG_P2P */
1612 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1615 if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
1616 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE) == _FALSE)
1620 /* RTW_INFO("+OnProbeReq\n"); */
1623 #ifdef CONFIG_ATMEL_RC_PATCH
1624 wps_ie = rtw_get_wps_ie(
1625 pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
1626 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
1629 target_ie = rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
1630 if ((target_ie && (target_ielen == 4)) && (_TRUE == _rtw_memcmp((void *)target_ie, "Ozmo", 4))) {
1631 /* psta->flag_atmel_rc = 1; */
1632 unsigned char *sa_addr = get_sa(pframe);
1633 printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n\n",
1634 __func__, *sa_addr, *(sa_addr + 1), *(sa_addr + 2), *(sa_addr + 3), *(sa_addr + 4), *(sa_addr + 5));
1635 _rtw_memcpy(pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
1640 #ifdef CONFIG_AUTO_AP_MODE
1641 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1642 pmlmepriv->cur_network.join_res == _TRUE) {
1644 struct sta_info *psta;
1645 u8 *mac_addr, *peer_addr;
1646 struct sta_priv *pstapriv = &padapter->stapriv;
1647 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
1648 /* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
1650 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1651 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1653 if (!p || ielen != 14)
1654 goto _non_rc_device;
1656 if (!_rtw_memcmp(p + 2, RC_OUI, sizeof(RC_OUI)))
1657 goto _non_rc_device;
1659 if (!_rtw_memcmp(p + 6, get_sa(pframe), ETH_ALEN)) {
1660 RTW_INFO("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1661 MAC_ARG(get_sa(pframe)), MAC_ARG(p + 6));
1663 goto _non_rc_device;
1666 RTW_INFO("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
1669 psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1671 /* allocate a new one */
1672 RTW_INFO("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
1673 psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1676 RTW_INFO(" Exceed the upper limit of supported clients...\n");
1680 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1681 if (rtw_is_list_empty(&psta->asoc_list)) {
1682 psta->expire_to = pstapriv->expire_to;
1683 rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1684 pstapriv->asoc_list_cnt++;
1686 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1688 /* generate pairing ID */
1689 mac_addr = adapter_mac_addr(padapter);
1690 peer_addr = psta->hwaddr;
1691 psta->pid = (u16)(((mac_addr[4] << 8) + mac_addr[5]) + ((peer_addr[4] << 8) + peer_addr[5]));
1693 /* update peer stainfo */
1696 /* get a unique AID */
1698 RTW_INFO("old AID %d\n", psta->aid);
1700 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++)
1701 if (pstapriv->sta_aid[psta->aid - 1] == NULL)
1704 if (psta->aid > pstapriv->max_num_sta) {
1706 RTW_INFO("no room for more AIDs\n");
1709 pstapriv->sta_aid[psta->aid - 1] = psta;
1710 RTW_INFO("allocate new AID = (%d)\n", psta->aid);
1714 psta->qos_option = 1;
1715 psta->bw_mode = CHANNEL_WIDTH_20;
1716 psta->ieee8021x_blocked = _FALSE;
1717 #ifdef CONFIG_80211N_HT
1718 psta->htpriv.ht_option = _TRUE;
1719 psta->htpriv.ampdu_enable = _FALSE;
1720 psta->htpriv.sgi_20m = _FALSE;
1721 psta->htpriv.sgi_40m = _FALSE;
1722 psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1723 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
1724 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
1727 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1729 _rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1731 _enter_critical_bh(&psta->lock, &irqL);
1732 psta->state |= _FW_LINKED;
1733 _exit_critical_bh(&psta->lock, &irqL);
1735 report_add_sta_event(padapter, psta->hwaddr);
1739 issue_probersp(padapter, get_sa(pframe), _FALSE);
1749 #endif /* CONFIG_AUTO_AP_MODE */
1752 #ifdef CONFIG_CONCURRENT_MODE
1753 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
1754 rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) {
1755 /* don't process probe req */
1760 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1761 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1764 /* check (wildcard) SSID */
1766 if (is_valid_p2p_probereq == _TRUE)
1767 goto _issue_probersp;
1769 if ((ielen != 0 && _FALSE == _rtw_memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1770 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode)
1775 if (((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1776 pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1777 /* RTW_INFO("+issue_probersp during ap mode\n"); */
1778 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
1787 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1789 struct sta_info *psta;
1790 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1791 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1792 struct sta_priv *pstapriv = &padapter->stapriv;
1793 u8 *pframe = precv_frame->u.hdr.rx_data;
1795 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1800 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
1801 if (_TRUE == pwdinfo->tx_prov_disc_info.benable) {
1802 if (_rtw_memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, get_addr2_ptr(pframe), ETH_ALEN)) {
1803 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
1804 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1805 issue_p2p_provision_request(padapter,
1806 pwdinfo->tx_prov_disc_info.ssid.Ssid,
1807 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1808 pwdinfo->tx_prov_disc_info.peerDevAddr);
1809 } else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
1810 pwdinfo->tx_prov_disc_info.benable = _FALSE;
1811 issue_p2p_provision_request(padapter,
1814 pwdinfo->tx_prov_disc_info.peerDevAddr);
1819 } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
1820 if (_TRUE == pwdinfo->nego_req_info.benable) {
1821 RTW_INFO("[%s] P2P State is GONEGO ING!\n", __FUNCTION__);
1822 if (_rtw_memcmp(pwdinfo->nego_req_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN)) {
1823 pwdinfo->nego_req_info.benable = _FALSE;
1824 issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr);
1827 } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
1828 if (_TRUE == pwdinfo->invitereq_info.benable) {
1829 RTW_INFO("[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__);
1830 if (_rtw_memcmp(pwdinfo->invitereq_info.peer_macaddr, get_addr2_ptr(pframe), ETH_ALEN)) {
1831 pwdinfo->invitereq_info.benable = _FALSE;
1832 issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr);
1839 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1840 rtw_mi_report_survey_event(padapter, precv_frame);
1844 #if 0 /* move to validate_recv_mgnt_frame */
1845 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
1846 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
1847 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
1849 psta->sta_stats.rx_mgnt_pkts++;
1858 /* for 11n Logo 4.2.31/4.2.32 */
1859 static void rtw_check_legacy_ap(_adapter *padapter, u8 *pframe, u32 len)
1862 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1863 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1865 if (!padapter->registrypriv.wifi_spec)
1868 if(!MLME_IS_AP(padapter))
1872 if (pmlmeext->bstart_bss == _TRUE) {
1876 struct rtw_ieee802_11_elems elems;
1877 struct HT_info_element *pht_info = NULL;
1881 left = len - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_;
1882 pos = pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_;
1883 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
1884 RTW_INFO("%s: parse fail for "MAC_FMT"\n", __func__, MAC_ARG(GetAddr3Ptr(pframe)));
1888 cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1891 if (elems.ht_capabilities == NULL && elems.ht_capabilities_len == 0) {
1894 RTW_INFO("%s: "MAC_FMT" is legacy ap\n", __func__, MAC_ARG(GetAddr3Ptr(pframe)));
1896 ATOMIC_SET(&pmlmepriv->olbc, _TRUE);
1897 ATOMIC_SET(&pmlmepriv->olbc_ht, _TRUE);
1903 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1905 struct sta_info *psta;
1906 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1907 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1908 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1909 struct sta_priv *pstapriv = &padapter->stapriv;
1910 u8 *pframe = precv_frame->u.hdr.rx_data;
1911 uint len = precv_frame->u.hdr.len;
1912 WLAN_BSSID_EX *pbss;
1917 struct sta_info *ptdls_sta;
1918 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1919 #ifdef CONFIG_TDLS_CH_SW
1920 struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
1922 #endif /* CONFIG_TDLS */
1924 if (validate_beacon_len(pframe, len) == _FALSE)
1926 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
1927 p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen,
1928 precv_frame->u.hdr.len - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
1929 if ((p != NULL) && (ielen > 0)) {
1930 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) {
1931 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
1932 RTW_INFO("[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)));
1933 *(p + 1) = ielen - 1;
1938 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)) {
1939 rtw_mi_report_survey_event(padapter, precv_frame);
1944 rtw_check_legacy_ap(padapter, pframe, len);
1946 if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
1947 if ((pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1948 && rtw_sta_linking_test_wait_done()
1950 if (rtw_sta_linking_test_force_fail()) {
1951 set_link_timer(pmlmeext, 1);
1955 /* we should update current network before auth, or some IE is wrong */
1956 pbss = (WLAN_BSSID_EX *)rtw_malloc(sizeof(WLAN_BSSID_EX));
1958 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1959 struct beacon_keys recv_beacon;
1961 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1962 rtw_get_bcn_info(&(pmlmepriv->cur_network));
1964 /* update bcn keys */
1965 if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1966 RTW_INFO("%s: beacon keys ready\n", __func__);
1967 _rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1968 &recv_beacon, sizeof(recv_beacon));
1969 pmlmepriv->new_beacon_cnts = 0;
1971 RTW_ERR("%s: get beacon keys failed\n", __func__);
1972 _rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1973 pmlmepriv->new_beacon_cnts = 0;
1976 rtw_mfree((u8 *)pbss, sizeof(WLAN_BSSID_EX));
1979 /* check the vendor of the assoc AP */
1980 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct rtw_ieee80211_hdr_3addr), len - sizeof(struct rtw_ieee80211_hdr_3addr));
1982 /* update TSF Value */
1983 update_TSF(pmlmeext, pframe, len);
1985 /* reset for adaptive_early_32k */
1986 pmlmeext->adaptive_tsf_done = _FALSE;
1987 pmlmeext->DrvBcnEarly = 0xff;
1988 pmlmeext->DrvBcnTimeOut = 0xff;
1989 pmlmeext->bcn_cnt = 0;
1990 _rtw_memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt));
1991 _rtw_memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio));
1993 #ifdef CONFIG_P2P_PS
1994 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1995 #endif /* CONFIG_P2P_PS */
1997 #if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)
1998 if (padapter->registrypriv.wifi_spec) {
1999 if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
2000 if (rtw_mi_buddy_check_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) {
2001 RTW_PRINT("no issue auth, P2P cross-connect does not permit\n ");
2006 #endif /* CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE */
2009 start_clnt_auth(padapter);
2014 if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
2015 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2017 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
2018 /* Merge from 8712 FW code */
2019 if (cmp_pkt_chnl_diff(padapter, pframe, len) != 0) {
2020 /* join wrong channel, deauth and reconnect */
2021 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
2023 report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE, _FALSE);
2024 pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
2027 #endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
2029 ret = rtw_check_bcn_info(padapter, pframe, len);
2031 RTW_PRINT("ap has changed, disconnect now\n ");
2032 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
2035 /* update WMM, ERP in the beacon */
2036 /* todo: the timer is used instead of the number of the beacon received */
2037 if ((sta_rx_pkts(psta) & 0xf) == 0) {
2038 /* RTW_INFO("update_bcn_info\n"); */
2039 update_beacon_info(padapter, pframe, len, psta);
2042 pmlmepriv->cur_network_scanned->network.Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower;
2044 adaptive_early_32k(pmlmeext, pframe, len);
2047 #ifdef CONFIG_TDLS_CH_SW
2048 if (rtw_tdls_is_chsw_allowed(padapter) == _TRUE) {
2049 /* Send TDLS Channel Switch Request when receiving Beacon */
2050 if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
2051 && (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
2052 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
2053 if (ptdls_sta != NULL) {
2054 if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
2055 _set_timer(&ptdls_sta->stay_on_base_chnl_timer, TDLS_CH_SW_STAY_ON_BASE_CHNL_TIMEOUT);
2060 #endif /* CONFIG_TDLS */
2063 process_csa_ie(padapter, pframe, len); /* channel switch announcement */
2064 #endif /* CONFIG_DFS */
2066 #ifdef CONFIG_P2P_PS
2067 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
2068 #endif /* CONFIG_P2P_PS */
2070 if (pmlmeext->en_hw_update_tsf)
2071 rtw_enable_hw_update_tsf_cmd(padapter);
2073 #if 0 /* move to validate_recv_mgnt_frame */
2074 psta->sta_stats.rx_mgnt_pkts++;
2078 } else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
2083 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2086 * update WMM, ERP in the beacon
2087 * todo: the timer is used instead of the number of the beacon received
2089 if ((sta_rx_pkts(psta) & 0xf) == 0)
2090 update_beacon_info(padapter, pframe, len, psta);
2092 if (pmlmeext->en_hw_update_tsf)
2093 rtw_enable_hw_update_tsf_cmd(padapter);
2095 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);
2096 if (rate_num == 0) {
2097 RTW_INFO(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter));
2098 goto _END_ONBEACON_;
2101 psta = rtw_alloc_stainfo(pstapriv, get_addr2_ptr(pframe));
2103 RTW_INFO(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter));
2104 goto _END_ONBEACON_;
2107 psta->expire_to = pstapriv->adhoc_expire_to;
2109 _rtw_memcpy(psta->bssrateset, rate_set, rate_num);
2110 psta->bssratelen = rate_num;
2112 /* update TSF Value */
2113 update_TSF(pmlmeext, pframe, len);
2115 /* report sta add event */
2116 report_add_sta_event(padapter, get_addr2_ptr(pframe));
2127 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
2129 #ifdef CONFIG_AP_MODE
2131 unsigned int auth_mode, seq, ie_len;
2132 unsigned char *sa, *p;
2135 static struct sta_info stat;
2136 struct sta_info *pstat = NULL;
2137 struct sta_priv *pstapriv = &padapter->stapriv;
2138 struct security_priv *psecuritypriv = &padapter->securitypriv;
2139 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2140 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2141 u8 *pframe = precv_frame->u.hdr.rx_data;
2142 uint len = precv_frame->u.hdr.len;
2146 #ifdef CONFIG_CONCURRENT_MODE
2147 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
2148 rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) {
2149 /* don't process auth request; */
2152 #endif /* CONFIG_CONCURRENT_MODE */
2154 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
2157 RTW_INFO("+OnAuth\n");
2159 sa = get_addr2_ptr(pframe);
2161 auth_mode = psecuritypriv->dot11AuthAlgrthm;
2163 if (GetPrivacy(pframe)) {
2165 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
2167 prxattrib->hdrlen = WLAN_HDR_A3_LEN;
2168 prxattrib->encrypt = _WEP40_;
2170 iv = pframe + prxattrib->hdrlen;
2171 prxattrib->key_index = ((iv[3] >> 6) & 0x3);
2173 prxattrib->iv_len = 4;
2174 prxattrib->icv_len = 4;
2176 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
2181 algorithm = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2182 seq = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2184 RTW_INFO("auth alg=%x, seq=%X\n", algorithm, seq);
2186 if (auth_mode == 2 &&
2187 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
2188 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
2191 if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */
2192 (algorithm == 0 && auth_mode == 1)) { /* rx a open-system auth but shared-key is enabled */
2193 RTW_INFO("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
2194 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
2196 status = _STATS_NO_SUPP_ALG_;
2201 #if CONFIG_RTW_MACADDR_ACL
2202 if (rtw_access_ctrl(padapter, sa) == _FALSE) {
2203 status = _STATS_UNABLE_HANDLE_STA_;
2208 pstat = rtw_get_stainfo(pstapriv, sa);
2209 if (pstat == NULL) {
2211 /* allocate a new one */
2212 RTW_INFO("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
2213 pstat = rtw_alloc_stainfo(pstapriv, sa);
2214 if (pstat == NULL) {
2215 RTW_INFO(" Exceed the upper limit of supported clients...\n");
2216 status = _STATS_UNABLE_HANDLE_STA_;
2220 pstat->state = WIFI_FW_AUTH_NULL;
2221 pstat->auth_seq = 0;
2223 /* pstat->flags = 0; */
2224 /* pstat->capability = 0; */
2226 #ifdef CONFIG_IEEE80211W
2227 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2228 #endif /* CONFIG_IEEE80211W */
2231 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2232 if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {
2233 rtw_list_delete(&pstat->asoc_list);
2234 pstapriv->asoc_list_cnt--;
2235 if (pstat->expire_to > 0)
2236 ;/* TODO: STA re_auth within expire_to */
2238 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2241 ; /* TODO: STA re_auth and auth timeout */
2246 #ifdef CONFIG_IEEE80211W
2247 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2248 #endif /* CONFIG_IEEE80211W */
2250 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2251 if (rtw_is_list_empty(&pstat->auth_list)) {
2253 rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
2254 pstapriv->auth_list_cnt++;
2256 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2259 if (pstat->auth_seq == 0)
2260 pstat->expire_to = pstapriv->auth_to;
2263 if ((pstat->auth_seq + 1) != seq) {
2264 RTW_INFO("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2265 seq, pstat->auth_seq + 1);
2266 status = _STATS_OUT_OF_AUTH_SEQ_;
2270 if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) {
2272 #ifdef CONFIG_IEEE80211W
2273 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2274 #endif /* CONFIG_IEEE80211W */
2276 pstat->state &= ~WIFI_FW_AUTH_NULL;
2277 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2278 pstat->expire_to = pstapriv->assoc_to;
2280 pstat->authalg = algorithm;
2282 RTW_INFO("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2283 seq, pstat->auth_seq + 1);
2284 status = _STATS_OUT_OF_AUTH_SEQ_;
2287 } else { /* shared system or auto authentication */
2289 /* prepare for the challenging txt... */
2291 /* get_random_bytes((void *)pstat->chg_txt, 128); */ /* TODO: */
2292 _rtw_memset((void *)pstat->chg_txt, 78, 128);
2293 #ifdef CONFIG_IEEE80211W
2294 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2295 #endif /* CONFIG_IEEE80211W */
2297 pstat->state &= ~WIFI_FW_AUTH_NULL;
2298 pstat->state |= WIFI_FW_AUTH_STATE;
2300 pstat->authalg = algorithm;
2301 pstat->auth_seq = 2;
2302 } else if (seq == 3) {
2303 /* checking for challenging txt... */
2304 RTW_INFO("checking for challenging txt...\n");
2306 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
2307 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2309 if ((p == NULL) || (ie_len <= 0)) {
2310 RTW_INFO("auth rejected because challenge failure!(1)\n");
2311 status = _STATS_CHALLENGE_FAIL_;
2315 if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
2316 #ifdef CONFIG_IEEE80211W
2317 if (pstat->bpairwise_key_installed != _TRUE && !(pstat->state & WIFI_FW_ASSOC_SUCCESS))
2318 #endif /* CONFIG_IEEE80211W */
2320 pstat->state &= (~WIFI_FW_AUTH_STATE);
2321 pstat->state |= WIFI_FW_AUTH_SUCCESS;
2322 /* challenging txt is correct... */
2323 pstat->expire_to = pstapriv->assoc_to;
2326 RTW_INFO("auth rejected because challenge failure!\n");
2327 status = _STATS_CHALLENGE_FAIL_;
2331 RTW_INFO("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2332 seq, pstat->auth_seq + 1);
2333 status = _STATS_OUT_OF_AUTH_SEQ_;
2339 /* Now, we are going to issue_auth... */
2340 pstat->auth_seq = seq + 1;
2342 #ifdef CONFIG_NATIVEAP_MLME
2343 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2346 if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
2347 pstat->auth_seq = 0;
2355 rtw_free_stainfo(padapter , pstat);
2358 _rtw_memset((char *)pstat, '\0', sizeof(stat));
2359 pstat->auth_seq = 2;
2360 _rtw_memcpy(pstat->hwaddr, sa, 6);
2362 #ifdef CONFIG_NATIVEAP_MLME
2363 issue_auth(padapter, pstat, (unsigned short)status);
2371 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
2373 unsigned int seq, len, status, algthm, offset;
2375 unsigned int go2asoc = 0;
2376 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2377 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2378 #ifdef CONFIG_RTW_80211R
2379 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2380 ft_priv *pftpriv = &pmlmepriv->ftpriv;
2381 struct sta_priv *pstapriv = &padapter->stapriv;
2382 struct sta_info *psta = NULL;
2384 u8 *pframe = precv_frame->u.hdr.rx_data;
2385 uint pkt_len = precv_frame->u.hdr.len;
2387 RTW_INFO("%s\n", __FUNCTION__);
2389 /* check A1 matches or not */
2390 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2393 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
2396 offset = (GetPrivacy(pframe)) ? 4 : 0;
2398 algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2399 seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2400 status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
2403 RTW_INFO("clnt auth fail, status: %d\n", status);
2404 if (status == 13) { /* && pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
2405 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2406 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2408 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2409 /* pmlmeinfo->reauth_count = 0; */
2412 set_link_timer(pmlmeext, 1);
2417 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
2418 /* legendary shared system */
2419 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
2420 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2423 /* RTW_INFO("marc: no challenge text?\n"); */
2427 _rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2428 pmlmeinfo->auth_seq = 3;
2429 issue_auth(padapter, NULL, 0);
2430 set_link_timer(pmlmeext, REAUTH_TO);
2434 /* open, or 802.11r FTAA system */
2437 } else if (seq == 4) {
2438 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2443 /* this is also illegal */
2444 /* RTW_INFO("marc: clnt auth failed due to illegal seq=%x\n", seq); */
2449 #ifdef CONFIG_RTW_80211R
2450 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
2451 u8 target_ap_addr[ETH_ALEN] = {0};
2453 if ((rtw_chk_ft_status(padapter, RTW_FT_AUTHENTICATED_STA)) ||
2454 (rtw_chk_ft_status(padapter, RTW_FT_ASSOCIATING_STA)) ||
2455 (rtw_chk_ft_status(padapter, RTW_FT_ASSOCIATED_STA))) {
2456 /*report_ft_reassoc_event already, and waiting for cfg80211_rtw_update_ft_ies*/
2460 rtw_buf_update(&pmlmepriv->auth_rsp, &pmlmepriv->auth_rsp_len, pframe, pkt_len);
2461 pftpriv->ft_event.ies = pmlmepriv->auth_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6;
2462 pftpriv->ft_event.ies_len = pmlmepriv->auth_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6;
2465 pftpriv->ft_event.ric_ies = NULL;
2466 pftpriv->ft_event.ric_ies_len = 0;
2467 _rtw_memcpy(target_ap_addr, pmlmepriv->assoc_bssid, ETH_ALEN);
2468 report_ft_reassoc_event(padapter, target_ap_addr);
2473 RTW_PRINT("auth success, start assoc\n");
2474 start_clnt_assoc(padapter);
2480 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
2486 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
2488 #ifdef CONFIG_AP_MODE
2490 u16 capab_info, listen_interval;
2491 struct rtw_ieee802_11_elems elems;
2492 struct sta_info *pstat;
2493 unsigned char reassoc, *p, *pos, *wpa_ie;
2494 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
2495 int i, ie_len, wpa_ie_len, left;
2498 unsigned short status = _STATS_SUCCESSFUL_;
2499 unsigned short frame_type, ie_offset = 0;
2500 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2501 struct security_priv *psecuritypriv = &padapter->securitypriv;
2502 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2503 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2504 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
2505 struct sta_priv *pstapriv = &padapter->stapriv;
2506 u8 *pframe = precv_frame->u.hdr.rx_data;
2507 uint pkt_len = precv_frame->u.hdr.len;
2509 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2510 u8 p2p_status_code = P2P_STATUS_SUCCESS;
2513 #endif /* CONFIG_P2P */
2515 #ifdef CONFIG_CONCURRENT_MODE
2516 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
2517 rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) {
2518 /* don't process assoc request; */
2521 #endif /* CONFIG_CONCURRENT_MODE */
2523 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
2526 frame_type = get_frame_sub_type(pframe);
2527 if (frame_type == WIFI_ASSOCREQ) {
2529 ie_offset = _ASOCREQ_IE_OFFSET_;
2530 } else { /* WIFI_REASSOCREQ */
2532 ie_offset = _REASOCREQ_IE_OFFSET_;
2536 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2537 RTW_INFO("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2538 "\n", reassoc, (unsigned long)pkt_len);
2542 pstat = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2543 if (pstat == (struct sta_info *)NULL) {
2544 status = _RSON_CLS2_;
2545 goto asoc_class2_error;
2548 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
2549 /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); */
2550 /* listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2)); */
2551 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN + 2);
2553 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2554 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2557 RTW_INFO("%s\n", __FUNCTION__);
2559 /* check if this stat has been successfully authenticated/assocated */
2560 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
2561 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
2562 status = _RSON_CLS2_;
2563 goto asoc_class2_error;
2565 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2566 pstat->state |= WIFI_FW_ASSOC_STATE;
2569 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2570 pstat->state |= WIFI_FW_ASSOC_STATE;
2574 #if 0/* todo:tkip_countermeasures */
2575 if (hapd->tkip_countermeasures) {
2576 resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2581 pstat->capability = capab_info;
2584 /* check listen_interval */
2585 if (listen_interval > hapd->conf->max_listen_interval) {
2586 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2587 HOSTAPD_LEVEL_DEBUG,
2588 "Too large Listen Interval (%d)",
2590 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2594 pstat->listen_interval = listen_interval;
2597 /* now parse all ieee802_11 ie to point to elems */
2598 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
2600 RTW_INFO("STA " MAC_FMT " sent invalid association request\n",
2601 MAC_ARG(pstat->hwaddr));
2602 status = _STATS_FAILURE_;
2603 goto OnAssocReqFail;
2607 /* now we should check all the fields... */
2609 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
2610 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2612 status = _STATS_FAILURE_;
2614 if (ie_len == 0) /* broadcast ssid, however it is not allowed in assocreq */
2615 status = _STATS_FAILURE_;
2617 /* check if ssid match */
2618 if (!_rtw_memcmp((void *)(p + 2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
2619 status = _STATS_FAILURE_;
2621 if (ie_len != cur->Ssid.SsidLength)
2622 status = _STATS_FAILURE_;
2625 if (_STATS_SUCCESSFUL_ != status)
2626 goto OnAssocReqFail;
2628 rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, rate_set, &rate_num);
2629 if (rate_num == 0) {
2630 RTW_INFO(FUNC_ADPT_FMT" RX assoc-req with no supported rate\n", FUNC_ADPT_ARG(padapter));
2631 status = _STATS_FAILURE_;
2632 goto OnAssocReqFail;
2634 _rtw_memcpy(pstat->bssrateset, rate_set, rate_num);
2635 pstat->bssratelen = rate_num;
2636 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
2638 /* check RSN/WPA/WPS */
2639 pstat->dot8021xalg = 0;
2641 pstat->wpa_group_cipher = 0;
2642 pstat->wpa2_group_cipher = 0;
2643 pstat->wpa_pairwise_cipher = 0;
2644 pstat->wpa2_pairwise_cipher = 0;
2645 _rtw_memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
2646 if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
2648 int group_cipher = 0, pairwise_cipher = 0;
2650 wpa_ie = elems.rsn_ie;
2651 wpa_ie_len = elems.rsn_ie_len;
2653 if (rtw_parse_wpa2_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
2654 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
2655 pstat->wpa_psk |= BIT(1);
2657 pstat->wpa2_group_cipher = group_cipher & psecuritypriv->wpa2_group_cipher;
2658 pstat->wpa2_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa2_pairwise_cipher;
2660 if (!pstat->wpa2_group_cipher)
2661 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2663 if (!pstat->wpa2_pairwise_cipher)
2664 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2666 status = WLAN_STATUS_INVALID_IE;
2668 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
2670 int group_cipher = 0, pairwise_cipher = 0;
2672 wpa_ie = elems.wpa_ie;
2673 wpa_ie_len = elems.wpa_ie_len;
2675 if (rtw_parse_wpa_ie(wpa_ie - 2, wpa_ie_len + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
2676 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
2677 pstat->wpa_psk |= BIT(0);
2679 pstat->wpa_group_cipher = group_cipher & psecuritypriv->wpa_group_cipher;
2680 pstat->wpa_pairwise_cipher = pairwise_cipher & psecuritypriv->wpa_pairwise_cipher;
2682 if (!pstat->wpa_group_cipher)
2683 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
2685 if (!pstat->wpa_pairwise_cipher)
2686 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
2689 status = WLAN_STATUS_INVALID_IE;
2696 if (_STATS_SUCCESSFUL_ != status)
2697 goto OnAssocReqFail;
2699 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
2700 /* if (hapd->conf->wps_state && wpa_ie == NULL) { */ /* todo: to check ap if supporting WPS */
2701 if (wpa_ie == NULL) {
2703 RTW_INFO("STA included WPS IE in "
2704 "(Re)Association Request - assume WPS is "
2706 pstat->flags |= WLAN_STA_WPS;
2707 /* wpabuf_free(sta->wps_ie); */
2708 /* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */
2709 /* elems.wps_ie_len - 4); */
2711 RTW_INFO("STA did not include WPA/RSN IE "
2712 "in (Re)Association Request - possible WPS "
2714 pstat->flags |= WLAN_STA_MAYBE_WPS;
2718 /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
2719 /* that the selected registrar of AP is _FLASE */
2720 if ((psecuritypriv->wpa_psk > 0)
2721 && (pstat->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS))) {
2722 if (pmlmepriv->wps_beacon_ie) {
2723 u8 selected_registrar = 0;
2725 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
2727 if (!selected_registrar) {
2728 RTW_INFO("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
2730 status = _STATS_UNABLE_HANDLE_STA_;
2732 goto OnAssocReqFail;
2740 if (psecuritypriv->wpa_psk == 0) {
2741 RTW_INFO("STA " MAC_FMT ": WPA/RSN IE in association "
2742 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
2744 status = WLAN_STATUS_INVALID_IE;
2746 goto OnAssocReqFail;
2751 RTW_INFO("STA included WPS IE in "
2752 "(Re)Association Request - WPS is "
2754 pstat->flags |= WLAN_STA_WPS;
2757 copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)) : (wpa_ie_len + 2);
2761 _rtw_memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
2766 /* check if there is WMM IE & support WWM-PS */
2767 pstat->flags &= ~WLAN_STA_WME;
2768 pstat->qos_option = 0;
2769 pstat->qos_info = 0;
2770 pstat->has_legacy_ac = _TRUE;
2771 pstat->uapsd_vo = 0;
2772 pstat->uapsd_vi = 0;
2773 pstat->uapsd_be = 0;
2774 pstat->uapsd_bk = 0;
2775 if (pmlmepriv->qospriv.qos_option) {
2776 p = pframe + WLAN_HDR_A3_LEN + ie_offset;
2779 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2781 if (_rtw_memcmp(p + 2, WMM_IE, 6)) {
2783 pstat->flags |= WLAN_STA_WME;
2785 pstat->qos_option = 1;
2786 pstat->qos_info = *(p + 8);
2788 pstat->max_sp_len = (pstat->qos_info >> 5) & 0x3;
2790 if ((pstat->qos_info & 0xf) != 0xf)
2791 pstat->has_legacy_ac = _TRUE;
2793 pstat->has_legacy_ac = _FALSE;
2795 if (pstat->qos_info & 0xf) {
2796 if (pstat->qos_info & BIT(0))
2797 pstat->uapsd_vo = BIT(0) | BIT(1);
2799 pstat->uapsd_vo = 0;
2801 if (pstat->qos_info & BIT(1))
2802 pstat->uapsd_vi = BIT(0) | BIT(1);
2804 pstat->uapsd_vi = 0;
2806 if (pstat->qos_info & BIT(2))
2807 pstat->uapsd_bk = BIT(0) | BIT(1);
2809 pstat->uapsd_bk = 0;
2811 if (pstat->qos_info & BIT(3))
2812 pstat->uapsd_be = BIT(0) | BIT(1);
2814 pstat->uapsd_be = 0;
2827 #ifdef CONFIG_80211N_HT
2828 if (pmlmepriv->htpriv.ht_option == _FALSE)
2831 /* save HT capabilities in the sta object */
2832 _rtw_memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
2833 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) {
2834 pstat->flags |= WLAN_STA_HT;
2836 pstat->flags |= WLAN_STA_WME;
2838 _rtw_memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
2841 pstat->flags &= ~WLAN_STA_HT;
2844 if ((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags & WLAN_STA_HT)) {
2846 status = _STATS_FAILURE_;
2847 goto OnAssocReqFail;
2849 #endif /* CONFIG_80211N_HT */
2851 #ifdef CONFIG_80211AC_VHT
2852 if (pmlmepriv->vhtpriv.vht_option == _FALSE)
2853 goto bypass_vht_chk;
2855 _rtw_memset(&pstat->vhtpriv, 0, sizeof(struct vht_priv));
2856 if (elems.vht_capabilities && elems.vht_capabilities_len == 12) {
2857 pstat->flags |= WLAN_STA_VHT;
2859 _rtw_memcpy(pstat->vhtpriv.vht_cap, elems.vht_capabilities, 12);
2861 if (elems.vht_op_mode_notify && elems.vht_op_mode_notify_len == 1)
2862 _rtw_memcpy(&pstat->vhtpriv.vht_op_mode_notify, elems.vht_op_mode_notify, 1);
2863 else /* for Frame without Operating Mode notify ie; default: 80M */
2864 pstat->vhtpriv.vht_op_mode_notify = CHANNEL_WIDTH_80;
2866 pstat->flags &= ~WLAN_STA_VHT;
2869 if ((pmlmepriv->vhtpriv.vht_option == _FALSE) && (pstat->flags & WLAN_STA_VHT)) {
2871 status = _STATS_FAILURE_;
2872 goto OnAssocReqFail;
2874 #endif /* CONFIG_80211AC_VHT */
2876 if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) &&
2877 ((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
2878 (pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
2880 RTW_INFO("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->hwaddr));
2882 pstat->flags &= ~WLAN_STA_HT;
2883 pstat->flags &= ~WLAN_STA_VHT;
2884 /*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2885 * goto OnAssocReqFail;
2891 * if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) */ /* ? */
2892 pstat->flags |= WLAN_STA_NONERP;
2893 for (i = 0; i < pstat->bssratelen; i++) {
2894 if ((pstat->bssrateset[i] & 0x7f) > 22) {
2895 pstat->flags &= ~WLAN_STA_NONERP;
2900 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2901 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
2903 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
2907 if (status != _STATS_SUCCESSFUL_)
2908 goto OnAssocReqFail;
2911 pstat->is_p2p_device = _FALSE;
2912 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
2913 p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen);
2915 pstat->is_p2p_device = _TRUE;
2916 p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat);
2917 if (p2p_status_code > 0) {
2918 pstat->p2p_status_code = p2p_status_code;
2919 status = _STATS_CAP_FAIL_;
2920 goto OnAssocReqFail;
2924 rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__);
2927 pstat->p2p_status_code = p2p_status_code;
2928 #endif /* CONFIG_P2P */
2930 /* TODO: identify_proprietary_vendor_ie(); */
2931 /* Realtek proprietary IE */
2932 /* identify if this is Broadcom sta */
2933 /* identify if this is ralink sta */
2934 /* Customer proprietary IE */
2938 /* get a unique AID */
2940 RTW_INFO(" old AID %d\n", pstat->aid);
2942 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) {
2943 if (pstapriv->sta_aid[pstat->aid - 1] == NULL) {
2944 if (pstat->aid > pstapriv->max_num_sta) {
2947 RTW_INFO(" no room for more AIDs\n");
2949 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2951 goto OnAssocReqFail;
2955 pstapriv->sta_aid[pstat->aid - 1] = pstat;
2956 RTW_INFO("allocate new AID = (%d)\n", pstat->aid);
2964 pstat->state &= (~WIFI_FW_ASSOC_STATE);
2965 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2966 /* RTW_INFO("==================%s, %d, (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
2967 , __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->hwaddr)); */
2968 #ifdef CONFIG_IEEE80211W
2969 if (pstat->bpairwise_key_installed != _TRUE)
2970 #endif /* CONFIG_IEEE80211W */
2972 _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2973 if (!rtw_is_list_empty(&pstat->auth_list)) {
2974 rtw_list_delete(&pstat->auth_list);
2975 pstapriv->auth_list_cnt--;
2977 _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2979 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2980 if (rtw_is_list_empty(&pstat->asoc_list)) {
2981 pstat->expire_to = pstapriv->expire_to;
2982 rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2983 pstapriv->asoc_list_cnt++;
2985 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2988 /* now the station is qualified to join our BSS... */
2989 if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) {
2990 #ifdef CONFIG_NATIVEAP_MLME
2991 #ifdef CONFIG_IEEE80211W
2992 if (pstat->bpairwise_key_installed != _TRUE)
2993 #endif /* CONFIG_IEEE80211W */
2995 /* .1 bss_cap_update & sta_info_update */
2996 bss_cap_update_on_sta_join(padapter, pstat);
2997 sta_info_update(padapter, pstat);
2999 #ifdef CONFIG_IEEE80211W
3000 if (pstat->bpairwise_key_installed == _TRUE)
3001 status = _STATS_REFUSED_TEMPORARILY_;
3002 #endif /* CONFIG_IEEE80211W */
3003 /* .2 issue assoc rsp before notify station join event. */
3004 if (frame_type == WIFI_ASSOCREQ)
3005 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
3007 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
3009 #ifdef CONFIG_IOCTL_CFG80211
3010 _enter_critical_bh(&pstat->lock, &irqL);
3011 if (pstat->passoc_req) {
3012 rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
3013 pstat->passoc_req = NULL;
3014 pstat->assoc_req_len = 0;
3017 pstat->passoc_req = rtw_zmalloc(pkt_len);
3018 if (pstat->passoc_req) {
3019 _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
3020 pstat->assoc_req_len = pkt_len;
3022 _exit_critical_bh(&pstat->lock, &irqL);
3023 #endif /* CONFIG_IOCTL_CFG80211 */
3024 #ifdef CONFIG_IEEE80211W
3025 if (pstat->bpairwise_key_installed != _TRUE)
3026 #endif /* CONFIG_IEEE80211W */
3028 /* .3-(1) report sta add event */
3029 report_add_sta_event(padapter, pstat->hwaddr);
3031 #ifdef CONFIG_IEEE80211W
3032 if (pstat->bpairwise_key_installed == _TRUE && padapter->securitypriv.binstallBIPkey == _TRUE) {
3033 RTW_INFO(MAC_FMT"\n", MAC_ARG(pstat->hwaddr));
3034 issue_action_SA_Query(padapter, pstat->hwaddr, 0, 0, IEEE80211W_RIGHT_KEY);
3036 #endif /* CONFIG_IEEE80211W */
3037 #endif /* CONFIG_NATIVEAP_MLME */
3044 #ifdef CONFIG_NATIVEAP_MLME
3045 issue_deauth(padapter, (void *)get_addr2_ptr(pframe), status);
3053 #ifdef CONFIG_NATIVEAP_MLME
3055 if (frame_type == WIFI_ASSOCREQ)
3056 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
3058 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
3062 #endif /* CONFIG_AP_MODE */
3068 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
3072 unsigned short status;
3073 PNDIS_802_11_VARIABLE_IEs pIE;
3074 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3075 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3076 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3077 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
3078 u8 *pframe = precv_frame->u.hdr.rx_data;
3079 uint pkt_len = precv_frame->u.hdr.len;
3080 PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
3082 RTW_INFO("%s\n", __FUNCTION__);
3084 /* check A1 matches or not */
3085 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3088 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
3091 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
3094 _cancel_timer_ex(&pmlmeext->link_timer);
3097 status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2));
3099 RTW_INFO("assoc reject, status code: %d\n", status);
3100 pmlmeinfo->state = WIFI_FW_NULL_STATE;
3102 goto report_assoc_result;
3105 /* get capabilities */
3106 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3109 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
3112 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4)) & 0x3fff);
3114 /* following are moved to join event callback function */
3115 /* to handle HT, WMM, rate adaptive, update MAC reg */
3116 /* for not to handle the synchronous IO in the tasklet */
3117 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
3118 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
3120 switch (pIE->ElementID) {
3121 case _VENDOR_SPECIFIC_IE_:
3122 if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) /* WMM */
3123 WMM_param_handler(padapter, pIE);
3124 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
3125 else if (_rtw_memcmp(pIE->data, WFD_OUI, 4)) /* WFD */
3126 rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__);
3130 #ifdef CONFIG_WAPI_SUPPORT
3136 case _HT_CAPABILITY_IE_: /* HT caps */
3137 HT_caps_handler(padapter, pIE);
3140 case _HT_EXTRA_INFO_IE_: /* HT info */
3141 HT_info_handler(padapter, pIE);
3144 #ifdef CONFIG_80211AC_VHT
3145 case EID_VHTCapability:
3146 VHT_caps_handler(padapter, pIE);
3149 case EID_VHTOperation:
3150 VHT_operation_handler(padapter, pIE);
3155 ERP_IE_handler(padapter, pIE);
3159 if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
3160 padapter->tdlsinfo.ap_prohibited = _TRUE;
3161 if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
3162 padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
3164 #endif /* CONFIG_TDLS */
3169 i += (pIE->Length + 2);
3172 #ifdef CONFIG_WAPI_SUPPORT
3173 rtw_wapi_on_assoc_ok(padapter, pIE);
3176 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
3177 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
3179 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
3180 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
3182 report_assoc_result:
3184 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
3186 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
3188 report_join_res(padapter, res);
3193 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
3195 unsigned short reason;
3196 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3197 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3198 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3199 u8 *pframe = precv_frame->u.hdr.rx_data;
3201 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3202 #endif /* CONFIG_P2P */
3205 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3208 RTW_INFO(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3211 if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
3212 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
3213 _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
3215 #endif /* CONFIG_P2P */
3217 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3219 rtw_lock_rx_suspend_timeout(8000);
3221 #ifdef CONFIG_AP_MODE
3222 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
3224 struct sta_info *psta;
3225 struct sta_priv *pstapriv = &padapter->stapriv;
3227 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3228 /* rtw_free_stainfo(padapter, psta); */
3229 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3231 RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3232 , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3234 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3236 u8 updated = _FALSE;
3238 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3239 if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
3240 rtw_list_delete(&psta->asoc_list);
3241 pstapriv->asoc_list_cnt--;
3242 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3245 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3247 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3255 int ignore_received_deauth = 0;
3257 /* Commented by Albert 20130604 */
3258 /* Before sending the auth frame to start the STA/GC mode connection with AP/GO, */
3259 /* we will send the deauth first. */
3260 /* However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. */
3261 /* Added the following code to avoid this case. */
3262 if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) ||
3263 (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) {
3264 if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA)
3265 ignore_received_deauth = 1;
3266 else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
3268 ignore_received_deauth = 1;
3272 RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3273 , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe), ignore_received_deauth);
3275 if (0 == ignore_received_deauth)
3276 receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE);
3278 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3283 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3285 unsigned short reason;
3286 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3287 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3288 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3289 u8 *pframe = precv_frame->u.hdr.rx_data;
3291 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3292 #endif /* CONFIG_P2P */
3295 if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3298 RTW_INFO(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3301 if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
3302 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
3303 _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
3305 #endif /* CONFIG_P2P */
3307 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3309 rtw_lock_rx_suspend_timeout(8000);
3311 #ifdef CONFIG_AP_MODE
3312 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
3314 struct sta_info *psta;
3315 struct sta_priv *pstapriv = &padapter->stapriv;
3317 /* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3318 /* rtw_free_stainfo(padapter, psta); */
3319 /* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3321 RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3322 , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3324 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3326 u8 updated = _FALSE;
3328 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3329 if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
3330 rtw_list_delete(&psta->asoc_list);
3331 pstapriv->asoc_list_cnt--;
3332 updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3335 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3337 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3344 RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3345 , FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3347 receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE);
3349 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3354 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3356 RTW_INFO("%s\n", __FUNCTION__);
3360 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3362 unsigned int ret = _FAIL;
3363 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3364 struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
3366 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3371 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3373 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3376 struct ieee80211_info_element *ie;
3378 RTW_INFO(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3379 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
3381 for_each_ie(ie, ies, ies_len) {
3382 if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3383 ch_switch_mode = ie->data[0];
3385 ch_switch_cnt = ie->data[2];
3386 RTW_INFO("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3387 ch_switch_mode, ch, ch_switch_cnt);
3388 } else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3389 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3390 RTW_INFO("ch_offset:%d\n", ch_offset);
3397 if (ch_offset == -1)
3398 bwmode = mlmeext->cur_bwmode;
3400 bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3401 CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3403 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3406 * 1. the decision of channel switching
3407 * 2. things after channel switching
3410 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
3417 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3419 unsigned int ret = _FAIL;
3420 struct sta_info *psta = NULL;
3421 struct sta_priv *pstapriv = &padapter->stapriv;
3422 u8 *pframe = precv_frame->u.hdr.rx_data;
3423 uint frame_len = precv_frame->u.hdr.len;
3424 u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3428 RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
3430 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3435 category = frame_body[0];
3436 if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3439 action = frame_body[1];
3441 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3442 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3443 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3444 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3446 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3447 #ifdef CONFIG_SPCT_CH_SWITCH
3448 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
3449 frame_len - (frame_body - pframe) - 2);
3460 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
3465 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
3470 #ifdef CONFIG_RTW_WNM
3471 unsigned int on_action_wnm(_adapter *adapter, union recv_frame *rframe)
3473 unsigned int ret = _FAIL;
3474 struct sta_info *sta = NULL;
3475 struct sta_priv *stapriv = &adapter->stapriv;
3476 u8 *frame = rframe->u.hdr.rx_data;
3477 uint frame_len = rframe->u.hdr.len;
3478 u8 *frame_body = (u8 *)(frame + sizeof(struct rtw_ieee80211_hdr_3addr));
3484 sta = rtw_get_stainfo(stapriv, get_addr2_ptr(frame));
3488 category = frame_body[0];
3489 if (category != RTW_WLAN_CATEGORY_WNM)
3492 action = frame_body[1];
3496 #ifdef CONFIG_IOCTL_CFG80211
3497 cnt += sprintf((msg + cnt), "ACT_WNM %u", action);
3498 rtw_cfg80211_rx_action(adapter, rframe, msg);
3507 #endif /* CONFIG_RTW_WNM */
3510 * rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
3511 * @adapter: the adapter to get target RX AMPDU buffer size
3513 * Returns: the target RX AMPDU buffer size
3515 u8 rtw_rx_ampdu_size(_adapter *adapter)
3518 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3520 #ifdef CONFIG_BT_COEXIST
3521 if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
3522 size = rtw_btcoex_GetAMPDUSize(adapter);
3528 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3529 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3530 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
3532 size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
3536 /* default value based on max_rx_ampdu_factor */
3537 if (adapter->driver_rx_ampdu_factor != 0xFF)
3538 max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
3540 rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3542 /* In Maximum A-MPDU Length Exponent subfield of A-MPDU Parameters field of HT Capabilities element,
3543 the unit of max_rx_ampdu_factor are octets. 8K, 16K, 32K, 64K is right.
3544 But the buffer size subfield of Block Ack Parameter Set field in ADDBA action frame indicates
3545 the number of buffers available for this particular TID. Each buffer is equal to max. size of
3547 The size variable means how many MSDUs or AMSDUs, it's not Kbytes.
3549 if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3551 else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3553 else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3555 else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3569 * rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
3570 * @adapter: the adapter to get the permission if RX AMPDU should be set up
3572 * Returns: accept or not
3574 bool rtw_rx_ampdu_is_accept(_adapter *adapter)
3578 if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
3579 accept = adapter->fix_rx_ampdu_accept;
3583 #ifdef CONFIG_BT_COEXIST
3584 if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
3591 if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3592 && !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3593 && adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
3595 accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
3599 /* default value for other cases */
3600 accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
3607 * rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
3608 * @adapter: the adapter to set target RX AMPDU buffer size
3609 * @size: the target RX AMPDU buffer size to set
3610 * @reason: reason for the target RX AMPDU buffer size setting
3612 * Returns: whether the target RX AMPDU buffer size is changed
3614 bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
3616 bool is_adj = _FALSE;
3617 struct mlme_ext_priv *mlmeext;
3618 struct mlme_ext_info *mlmeinfo;
3620 mlmeext = &adapter->mlmeextpriv;
3621 mlmeinfo = &mlmeext->mlmext_info;
3623 if (reason == RX_AMPDU_DRV_FIXED) {
3624 if (adapter->fix_rx_ampdu_size != size) {
3625 adapter->fix_rx_ampdu_size = size;
3627 RTW_INFO(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3629 } else if (reason == RX_AMPDU_DRV_SCAN) {
3630 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
3632 if (ss->rx_ampdu_size != size) {
3633 ss->rx_ampdu_size = size;
3635 RTW_INFO(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3643 * rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3644 * @adapter: the adapter to set if RX AMPDU should be set up
3645 * @accept: if RX AMPDU should be set up
3646 * @reason: reason for the permission if RX AMPDU should be set up
3648 * Returns: whether the permission if RX AMPDU should be set up is changed
3650 bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3652 bool is_adj = _FALSE;
3653 struct mlme_ext_priv *mlmeext;
3654 struct mlme_ext_info *mlmeinfo;
3656 mlmeext = &adapter->mlmeextpriv;
3657 mlmeinfo = &mlmeext->mlmext_info;
3659 if (reason == RX_AMPDU_DRV_FIXED) {
3660 if (adapter->fix_rx_ampdu_accept != accept) {
3661 adapter->fix_rx_ampdu_accept = accept;
3663 RTW_INFO(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3665 } else if (reason == RX_AMPDU_DRV_SCAN) {
3666 if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
3667 adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
3669 RTW_INFO(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3677 * rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3678 * @adapter: the adapter to which @sta belongs
3679 * @sta: the sta to be checked
3680 * @tid: the tid to be checked
3681 * @accept: the target permission if RX AMPDU should be set up
3682 * @size: the target RX AMPDU buffer size
3686 * 1: canceled by no permission
3687 * 2: canceled by different buffer size
3688 * 3: canceled by potential mismatched status
3690 * Blocking function, may sleep
3692 u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3695 struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3697 if (reorder_ctl->enable == _FALSE) {
3698 if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3699 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3705 if (accept == _FALSE) {
3706 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3708 } else if (reorder_ctl->ampdu_size != size) {
3709 send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3717 u8 rx_ampdu_size_sta_limit(_adapter *adapter, struct sta_info *sta)
3721 #ifdef CONFIG_80211N_HT
3722 struct registry_priv *regsty = adapter_to_regsty(adapter);
3723 struct mlme_priv *mlme = &adapter->mlmepriv;
3724 struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info;
3726 u8 bw = rtw_min(sta->bw_mode, adapter->mlmeextpriv.cur_bwmode);
3728 #ifdef CONFIG_80211AC_VHT
3729 if (is_supported_vht(sta->wireless_mode)) {
3730 nss = rtw_min(rtw_vht_mcsmap_to_nss(mlme->vhtpriv.vht_mcs_map)
3731 , rtw_vht_mcsmap_to_nss(sta->vhtpriv.vht_mcs_map));
3734 if (is_supported_ht(sta->wireless_mode)) {
3735 nss = rtw_min(rtw_ht_mcsset_to_nss(mlmeinfo->HT_caps.u.HT_cap_element.MCS_rate)
3736 , rtw_ht_mcsset_to_nss(sta->htpriv.ht_cap.supp_mcs_set));
3740 sz_limit = regsty->rx_ampdu_sz_limit_by_nss_bw[nss - 1][bw];
3741 #endif /* CONFIG_80211N_HT */
3747 * rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3748 * @adapter: the adapter to which @sta belongs
3749 * @sta: the sta to be checked
3750 * @accept: the target permission if RX AMPDU should be set up
3751 * @size: the target RX AMPDU buffer size
3753 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3755 * Blocking function, may sleep
3757 u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3762 for (i = 0; i < TID_NUM; i++) {
3763 if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3771 * rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3772 * @adapter: the adapter to be applied
3774 * Returns: number of the RX AMPDU assciation canceled for applying current target setting
3776 u16 rtw_rx_ampdu_apply(_adapter *adapter)
3779 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
3780 struct sta_info *sta;
3781 u8 accept = rtw_rx_ampdu_is_accept(adapter);
3784 if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
3785 size = adapter->fix_rx_ampdu_size;
3787 size = rtw_rx_ampdu_size(adapter);
3789 if (mlmeext_msr(mlmeext) == WIFI_FW_STATION_STATE) {
3790 sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3794 if (adapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID)
3795 sta_size = rtw_min(size, rx_ampdu_size_sta_limit(adapter, sta));
3796 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size);
3799 } else if (mlmeext_msr(mlmeext) == WIFI_FW_AP_STATE) {
3801 _list *phead, *plist;
3803 char peers[NUM_STA];
3804 struct sta_priv *pstapriv = &adapter->stapriv;
3807 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3809 phead = &pstapriv->asoc_list;
3810 plist = get_next(phead);
3812 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3815 sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3816 plist = get_next(plist);
3818 stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3819 if (stainfo_offset_valid(stainfo_offset))
3820 peers[peer_num++] = stainfo_offset;
3823 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3825 for (i = 0; i < peer_num; i++) {
3826 sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3830 if (adapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID)
3831 sta_size = rtw_min(size, rx_ampdu_size_sta_limit(adapter, sta));
3832 adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size);
3840 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3843 struct sta_info *psta = NULL;
3844 struct recv_reorder_ctrl *preorder_ctrl;
3845 unsigned char *frame_body;
3846 unsigned char category, action;
3847 unsigned short tid, status, reason_code = 0;
3848 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3849 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3850 u8 *pframe = precv_frame->u.hdr.rx_data;
3851 struct sta_priv *pstapriv = &padapter->stapriv;
3853 #ifdef CONFIG_80211N_HT
3855 RTW_INFO("%s\n", __FUNCTION__);
3857 /* check RA matches or not */
3858 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3862 /* check A1 matches or not */
3863 if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3867 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
3868 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3871 addr = get_addr2_ptr(pframe);
3872 psta = rtw_get_stainfo(pstapriv, addr);
3877 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3879 category = frame_body[0];
3880 if (category == RTW_WLAN_CATEGORY_BACK) { /* representing Block Ack */
3882 if ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3883 (psta->htpriv.ht_option == _TRUE) &&
3884 (psta->htpriv.ampdu_enable == _TRUE))
3885 RTW_INFO("Recv [%s] from direc link\n", __FUNCTION__);
3887 #endif /* CONFIG_TDLS */
3888 if (!pmlmeinfo->HT_enable)
3891 action = frame_body[1];
3892 RTW_INFO("%s, action=%d\n", __FUNCTION__, action);
3894 case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
3896 _rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3897 /* process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */
3898 process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr);
3902 case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
3904 /* status = frame_body[3] | (frame_body[4] << 8); */ /* endian issue */
3905 status = RTW_GET_LE16(&frame_body[3]);
3906 tid = ((frame_body[5] >> 2) & 0x7);
3909 RTW_INFO("agg_enable for TID=%d\n", tid);
3910 psta->htpriv.agg_enable_bitmap |= 1 << tid;
3911 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3912 /* amsdu in ampdu */
3913 if (frame_body[5] & 1)
3914 psta->htpriv.tx_amsdu_enable = _TRUE;
3916 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3918 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
3919 RTW_INFO("%s alive check - rx ADDBA response\n", __func__);
3920 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3921 psta->expire_to = pstapriv->expire_to;
3922 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3925 /* RTW_INFO("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */
3928 case RTW_WLAN_ACTION_DELBA: /* DELBA */
3929 if ((frame_body[3] & BIT(3)) == 0) {
3930 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3931 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3933 /* reason_code = frame_body[4] | (frame_body[5] << 8); */
3934 reason_code = RTW_GET_LE16(&frame_body[4]);
3935 } else if ((frame_body[3] & BIT(3)) == BIT(3)) {
3936 tid = (frame_body[3] >> 4) & 0x0F;
3938 preorder_ctrl = &psta->recvreorder_ctrl[tid];
3939 preorder_ctrl->enable = _FALSE;
3940 preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3943 RTW_INFO("%s(): DELBA: %x(%x)\n", __FUNCTION__, pmlmeinfo->agg_enable_bitmap, reason_code);
3944 /* todo: how to notify the host while receiving DELETE BA */
3951 #endif /* CONFIG_80211N_HT */
3957 static int get_reg_classes_full_count(struct p2p_channels channel_list)
3962 for (i = 0; i < channel_list.reg_classes; i++)
3963 cnt += channel_list.reg_class[i].channels;
3968 static void get_channel_cnt_24g_5gl_5gh(struct mlme_ext_priv *pmlmeext, u8 *p24g_cnt, u8 *p5gl_cnt, u8 *p5gh_cnt)
3976 for (i = 0; i < pmlmeext->max_chan_nums; i++) {
3977 if (pmlmeext->channel_set[i].ChannelNum <= 14)
3979 else if ((pmlmeext->channel_set[i].ChannelNum > 14) && (pmlmeext->channel_set[i].ChannelNum <= 48)) {
3980 /* Just include the channel 36, 40, 44, 48 channels for 5G low */
3982 } else if ((pmlmeext->channel_set[i].ChannelNum >= 149) && (pmlmeext->channel_set[i].ChannelNum <= 161)) {
3983 /* Just include the channel 149, 153, 157, 161 channels for 5G high */
3989 void issue_p2p_GO_request(_adapter *padapter, u8 *raddr)
3992 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3993 u8 action = P2P_PUB_ACTION_ACTION;
3994 u32 p2poui = cpu_to_be32(P2POUI);
3995 u8 oui_subtype = P2P_GO_NEGO_REQ;
3996 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
3997 u8 wpsielen = 0, p2pielen = 0, i;
3998 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3999 u16 len_channellist_attr = 0;
4004 struct xmit_frame *pmgntframe;
4005 struct pkt_attrib *pattrib;
4006 unsigned char *pframe;
4007 struct rtw_ieee80211_hdr *pwlanhdr;
4008 unsigned short *fctrl;
4009 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4010 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4011 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4012 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4015 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4016 if (pmgntframe == NULL)
4019 RTW_INFO("[%s] In\n", __FUNCTION__);
4020 /* update attribute */
4021 pattrib = &pmgntframe->attrib;
4022 update_mgntframe_attrib(padapter, pattrib);
4024 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4026 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4027 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4029 fctrl = &(pwlanhdr->frame_ctl);
4032 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4033 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4034 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4036 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4037 pmlmeext->mgnt_seq++;
4038 set_frame_sub_type(pframe, WIFI_ACTION);
4040 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4041 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4043 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4044 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4045 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4046 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4047 pwdinfo->negotiation_dialog_token = 1; /* Initialize the dialog value */
4048 pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
4055 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4060 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4064 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4068 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4070 /* Device Password ID */
4072 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
4076 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4081 if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
4082 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
4083 else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
4084 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
4085 else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
4086 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
4090 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
4093 /* P2P IE Section. */
4097 p2pie[p2pielen++] = 0x50;
4098 p2pie[p2pielen++] = 0x6F;
4099 p2pie[p2pielen++] = 0x9A;
4100 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4102 /* Commented by Albert 20110306 */
4103 /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
4104 /* 1. P2P Capability */
4105 /* 2. Group Owner Intent */
4106 /* 3. Configuration Timeout */
4107 /* 4. Listen Channel */
4108 /* 5. Extended Listen Timing */
4109 /* 6. Intended P2P Interface Address */
4110 /* 7. Channel List */
4111 /* 8. P2P Device Info */
4112 /* 9. Operating Channel */
4115 /* P2P Capability */
4117 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4120 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4124 /* Device Capability Bitmap, 1 byte */
4125 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4127 /* Group Capability Bitmap, 1 byte */
4128 if (pwdinfo->persistent_supported)
4129 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4131 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4134 /* Group Owner Intent */
4136 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
4139 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4143 /* Todo the tie breaker bit. */
4144 p2pie[p2pielen++] = ((pwdinfo->intent << 1) & 0xFE);
4146 /* Configuration Timeout */
4148 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
4151 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4155 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
4156 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
4159 /* Listen Channel */
4161 p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
4164 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4168 /* Country String */
4169 p2pie[p2pielen++] = 'X';
4170 p2pie[p2pielen++] = 'X';
4172 /* The third byte should be set to 0x04. */
4173 /* Described in the "Operating Channel Attribute" section. */
4174 p2pie[p2pielen++] = 0x04;
4176 /* Operating Class */
4177 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
4179 /* Channel Number */
4180 p2pie[p2pielen++] = pwdinfo->listen_channel; /* listening channel number */
4183 /* Extended Listen Timing ATTR */
4185 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
4188 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
4192 /* Availability Period */
4193 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
4196 /* Availability Interval */
4197 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
4201 /* Intended P2P Interface Address */
4203 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
4206 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
4210 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4211 p2pielen += ETH_ALEN;
4216 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4219 /* Country String(3) */
4220 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4221 /* + number of channels in all classes */
4222 len_channellist_attr = 3
4223 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
4224 + get_reg_classes_full_count(pmlmeext->channel_list);
4226 #ifdef CONFIG_CONCURRENT_MODE
4227 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4228 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
4230 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4233 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4239 /* Country String */
4240 p2pie[p2pielen++] = 'X';
4241 p2pie[p2pielen++] = 'X';
4243 /* The third byte should be set to 0x04. */
4244 /* Described in the "Operating Channel Attribute" section. */
4245 p2pie[p2pielen++] = 0x04;
4247 /* Channel Entry List */
4249 #ifdef CONFIG_CONCURRENT_MODE
4250 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
4251 u8 union_ch = rtw_mi_get_union_chan(padapter);
4253 /* Operating Class */
4254 if (union_ch > 14) {
4255 if (union_ch >= 149)
4256 p2pie[p2pielen++] = 0x7c;
4258 p2pie[p2pielen++] = 0x73;
4260 p2pie[p2pielen++] = 0x51;
4263 /* Number of Channels */
4264 /* Just support 1 channel and this channel is AP's channel */
4265 p2pie[p2pielen++] = 1;
4268 p2pie[p2pielen++] = union_ch;
4271 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4272 /* Operating Class */
4273 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4275 /* Number of Channels */
4276 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4279 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
4280 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4283 #else /* CONFIG_CONCURRENT_MODE */
4286 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4287 /* Operating Class */
4288 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4290 /* Number of Channels */
4291 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4294 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
4295 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4298 #endif /* CONFIG_CONCURRENT_MODE */
4302 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4305 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
4306 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4307 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
4311 /* P2P Device Address */
4312 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4313 p2pielen += ETH_ALEN;
4316 /* This field should be big endian. Noted by P2P specification. */
4318 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4322 /* Primary Device Type */
4324 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4328 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
4331 /* Sub Category ID */
4332 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4335 /* Number of Secondary Device Types */
4336 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
4340 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4344 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
4348 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
4349 p2pielen += pwdinfo->device_name_len;
4352 /* Operating Channel */
4354 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4357 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4361 /* Country String */
4362 p2pie[p2pielen++] = 'X';
4363 p2pie[p2pielen++] = 'X';
4365 /* The third byte should be set to 0x04. */
4366 /* Described in the "Operating Channel Attribute" section. */
4367 p2pie[p2pielen++] = 0x04;
4369 /* Operating Class */
4370 if (pwdinfo->operating_channel <= 14) {
4371 /* Operating Class */
4372 p2pie[p2pielen++] = 0x51;
4373 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4374 /* Operating Class */
4375 p2pie[p2pielen++] = 0x73;
4377 /* Operating Class */
4378 p2pie[p2pielen++] = 0x7c;
4381 /* Channel Number */
4382 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
4384 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
4387 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4389 pattrib->pktlen += wfdielen;
4392 pattrib->last_txcmdsz = pattrib->pktlen;
4394 dump_mgntframe(padapter, pmgntframe);
4401 void issue_p2p_GO_response(_adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result)
4404 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4405 u8 action = P2P_PUB_ACTION_ACTION;
4406 u32 p2poui = cpu_to_be32(P2POUI);
4407 u8 oui_subtype = P2P_GO_NEGO_RESP;
4408 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
4411 u16 wps_devicepassword_id = 0x0000;
4412 uint wps_devicepassword_id_len = 0;
4413 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
4414 u16 len_channellist_attr = 0;
4416 struct xmit_frame *pmgntframe;
4417 struct pkt_attrib *pattrib;
4418 unsigned char *pframe;
4419 struct rtw_ieee80211_hdr *pwlanhdr;
4420 unsigned short *fctrl;
4421 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4422 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4423 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4424 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4430 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4431 if (pmgntframe == NULL)
4434 RTW_INFO("[%s] In, result = %d\n", __FUNCTION__, result);
4435 /* update attribute */
4436 pattrib = &pmgntframe->attrib;
4437 update_mgntframe_attrib(padapter, pattrib);
4439 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4441 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4442 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4444 fctrl = &(pwlanhdr->frame_ctl);
4447 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4448 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4449 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4451 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4452 pmlmeext->mgnt_seq++;
4453 set_frame_sub_type(pframe, WIFI_ACTION);
4455 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4456 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4458 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4459 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4460 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4461 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4462 pwdinfo->negotiation_dialog_token = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */
4463 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4465 /* Commented by Albert 20110328 */
4466 /* Try to get the device password ID from the WPS IE of group negotiation request frame */
4467 /* WiFi Direct test plan 5.1.15 */
4468 rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4469 rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *) &wps_devicepassword_id, &wps_devicepassword_id_len);
4470 wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
4472 _rtw_memset(wpsie, 0x00, 255);
4478 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4483 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4487 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4491 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4493 /* Device Password ID */
4495 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
4499 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4503 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
4504 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
4505 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4506 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
4508 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
4511 /* Commented by Kurt 20120113 */
4512 /* If some device wants to do p2p handshake without sending prov_disc_req */
4513 /* We have to get peer_req_cm from here. */
4514 if (_rtw_memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
4515 if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
4516 _rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
4517 else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4518 _rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
4520 _rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
4523 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
4526 /* P2P IE Section. */
4530 p2pie[p2pielen++] = 0x50;
4531 p2pie[p2pielen++] = 0x6F;
4532 p2pie[p2pielen++] = 0x9A;
4533 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4535 /* Commented by Albert 20100908 */
4536 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
4538 /* 2. P2P Capability */
4539 /* 3. Group Owner Intent */
4540 /* 4. Configuration Timeout */
4541 /* 5. Operating Channel */
4542 /* 6. Intended P2P Interface Address */
4543 /* 7. Channel List */
4544 /* 8. Device Info */
4545 /* 9. Group ID ( Only GO ) */
4552 p2pie[p2pielen++] = P2P_ATTR_STATUS;
4555 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4559 p2pie[p2pielen++] = result;
4561 /* P2P Capability */
4563 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4566 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4570 /* Device Capability Bitmap, 1 byte */
4572 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
4573 /* Commented by Albert 2011/03/08 */
4574 /* According to the P2P specification */
4575 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
4576 p2pie[p2pielen++] = 0;
4578 /* Be group owner or meet the error case */
4579 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4582 /* Group Capability Bitmap, 1 byte */
4583 if (pwdinfo->persistent_supported)
4584 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4586 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4588 /* Group Owner Intent */
4590 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
4593 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4597 if (pwdinfo->peer_intent & 0x01) {
4598 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
4599 p2pie[p2pielen++] = (pwdinfo->intent << 1);
4601 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
4602 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
4606 /* Configuration Timeout */
4608 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
4611 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4615 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
4616 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
4618 /* Operating Channel */
4620 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4623 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4627 /* Country String */
4628 p2pie[p2pielen++] = 'X';
4629 p2pie[p2pielen++] = 'X';
4631 /* The third byte should be set to 0x04. */
4632 /* Described in the "Operating Channel Attribute" section. */
4633 p2pie[p2pielen++] = 0x04;
4635 /* Operating Class */
4636 if (pwdinfo->operating_channel <= 14) {
4637 /* Operating Class */
4638 p2pie[p2pielen++] = 0x51;
4639 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4640 /* Operating Class */
4641 p2pie[p2pielen++] = 0x73;
4643 /* Operating Class */
4644 p2pie[p2pielen++] = 0x7c;
4647 /* Channel Number */
4648 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
4650 /* Intended P2P Interface Address */
4652 p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
4655 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
4659 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4660 p2pielen += ETH_ALEN;
4664 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4666 /* Country String(3) */
4667 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4668 /* + number of channels in all classes */
4669 len_channellist_attr = 3
4670 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4671 + get_reg_classes_full_count(pmlmeext->channel_list);
4673 #ifdef CONFIG_CONCURRENT_MODE
4674 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4675 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
4677 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4679 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4685 /* Country String */
4686 p2pie[p2pielen++] = 'X';
4687 p2pie[p2pielen++] = 'X';
4689 /* The third byte should be set to 0x04. */
4690 /* Described in the "Operating Channel Attribute" section. */
4691 p2pie[p2pielen++] = 0x04;
4693 /* Channel Entry List */
4695 #ifdef CONFIG_CONCURRENT_MODE
4696 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
4698 u8 union_chan = rtw_mi_get_union_chan(padapter);
4701 if (union_chan > 14) {
4702 if (union_chan >= 149)
4703 p2pie[p2pielen++] = 0x7c;
4705 p2pie[p2pielen++] = 0x73;
4708 p2pie[p2pielen++] = 0x51;
4710 /* Number of Channels
4711 Just support 1 channel and this channel is AP's channel*/
4712 p2pie[p2pielen++] = 1;
4715 p2pie[p2pielen++] = union_chan;
4718 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4719 /* Operating Class */
4720 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4722 /* Number of Channels */
4723 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4726 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
4727 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4730 #else /* CONFIG_CONCURRENT_MODE */
4733 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4734 /* Operating Class */
4735 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4737 /* Number of Channels */
4738 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4741 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
4742 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4745 #endif /* CONFIG_CONCURRENT_MODE */
4750 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4753 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
4754 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4755 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
4759 /* P2P Device Address */
4760 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4761 p2pielen += ETH_ALEN;
4764 /* This field should be big endian. Noted by P2P specification. */
4766 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4770 /* Primary Device Type */
4772 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4776 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
4779 /* Sub Category ID */
4780 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4783 /* Number of Secondary Device Types */
4784 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
4788 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4792 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
4796 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
4797 p2pielen += pwdinfo->device_name_len;
4799 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4800 /* Group ID Attribute */
4802 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
4805 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
4809 /* p2P Device Address */
4810 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
4811 p2pielen += ETH_ALEN;
4814 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
4815 p2pielen += pwdinfo->nego_ssidlen;
4819 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
4822 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4824 pattrib->pktlen += wfdielen;
4827 pattrib->last_txcmdsz = pattrib->pktlen;
4829 dump_mgntframe(padapter, pmgntframe);
4835 void issue_p2p_GO_confirm(_adapter *padapter, u8 *raddr, u8 result)
4838 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4839 u8 action = P2P_PUB_ACTION_ACTION;
4840 u32 p2poui = cpu_to_be32(P2POUI);
4841 u8 oui_subtype = P2P_GO_NEGO_CONF;
4842 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
4843 u8 wpsielen = 0, p2pielen = 0;
4845 struct xmit_frame *pmgntframe;
4846 struct pkt_attrib *pattrib;
4847 unsigned char *pframe;
4848 struct rtw_ieee80211_hdr *pwlanhdr;
4849 unsigned short *fctrl;
4850 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4851 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4852 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4853 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4858 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4859 if (pmgntframe == NULL)
4862 RTW_INFO("[%s] In\n", __FUNCTION__);
4863 /* update attribute */
4864 pattrib = &pmgntframe->attrib;
4865 update_mgntframe_attrib(padapter, pattrib);
4867 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4869 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4870 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4872 fctrl = &(pwlanhdr->frame_ctl);
4875 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4876 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4877 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4879 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4880 pmlmeext->mgnt_seq++;
4881 set_frame_sub_type(pframe, WIFI_ACTION);
4883 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4884 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4886 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4887 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4888 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4889 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4890 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4894 /* P2P IE Section. */
4898 p2pie[p2pielen++] = 0x50;
4899 p2pie[p2pielen++] = 0x6F;
4900 p2pie[p2pielen++] = 0x9A;
4901 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4903 /* Commented by Albert 20110306 */
4904 /* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */
4906 /* 2. P2P Capability */
4907 /* 3. Operating Channel */
4908 /* 4. Channel List */
4909 /* 5. Group ID ( if this WiFi is GO ) */
4913 p2pie[p2pielen++] = P2P_ATTR_STATUS;
4916 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4920 p2pie[p2pielen++] = result;
4922 /* P2P Capability */
4924 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4927 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4931 /* Device Capability Bitmap, 1 byte */
4932 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4934 /* Group Capability Bitmap, 1 byte */
4935 if (pwdinfo->persistent_supported)
4936 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4938 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4941 /* Operating Channel */
4943 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4946 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4950 /* Country String */
4951 p2pie[p2pielen++] = 'X';
4952 p2pie[p2pielen++] = 'X';
4954 /* The third byte should be set to 0x04. */
4955 /* Described in the "Operating Channel Attribute" section. */
4956 p2pie[p2pielen++] = 0x04;
4959 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
4960 if (pwdinfo->peer_operating_ch <= 14) {
4961 /* Operating Class */
4962 p2pie[p2pielen++] = 0x51;
4963 } else if ((pwdinfo->peer_operating_ch >= 36) && (pwdinfo->peer_operating_ch <= 48)) {
4964 /* Operating Class */
4965 p2pie[p2pielen++] = 0x73;
4967 /* Operating Class */
4968 p2pie[p2pielen++] = 0x7c;
4971 p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
4973 if (pwdinfo->operating_channel <= 14) {
4974 /* Operating Class */
4975 p2pie[p2pielen++] = 0x51;
4976 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4977 /* Operating Class */
4978 p2pie[p2pielen++] = 0x73;
4980 /* Operating Class */
4981 p2pie[p2pielen++] = 0x7c;
4984 /* Channel Number */
4985 p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
4991 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4993 *(u16 *)(p2pie + p2pielen) = 6;
4996 /* Country String */
4997 p2pie[p2pielen++] = 'X';
4998 p2pie[p2pielen++] = 'X';
5000 /* The third byte should be set to 0x04. */
5001 /* Described in the "Operating Channel Attribute" section. */
5002 p2pie[p2pielen++] = 0x04;
5005 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
5006 if (pwdinfo->peer_operating_ch <= 14) {
5007 /* Operating Class */
5008 p2pie[p2pielen++] = 0x51;
5009 } else if ((pwdinfo->peer_operating_ch >= 36) && (pwdinfo->peer_operating_ch <= 48)) {
5010 /* Operating Class */
5011 p2pie[p2pielen++] = 0x73;
5013 /* Operating Class */
5014 p2pie[p2pielen++] = 0x7c;
5016 p2pie[p2pielen++] = 1;
5017 p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
5019 if (pwdinfo->operating_channel <= 14) {
5020 /* Operating Class */
5021 p2pie[p2pielen++] = 0x51;
5022 } else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
5023 /* Operating Class */
5024 p2pie[p2pielen++] = 0x73;
5026 /* Operating Class */
5027 p2pie[p2pielen++] = 0x7c;
5030 /* Channel Number */
5031 p2pie[p2pielen++] = 1;
5032 p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
5035 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5036 /* Group ID Attribute */
5038 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5041 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
5045 /* p2P Device Address */
5046 _rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
5047 p2pielen += ETH_ALEN;
5050 _rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
5051 p2pielen += pwdinfo->nego_ssidlen;
5054 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5057 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
5059 pattrib->pktlen += wfdielen;
5062 pattrib->last_txcmdsz = pattrib->pktlen;
5064 dump_mgntframe(padapter, pmgntframe);
5070 void issue_p2p_invitation_request(_adapter *padapter, u8 *raddr)
5073 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5074 u8 action = P2P_PUB_ACTION_ACTION;
5075 u32 p2poui = cpu_to_be32(P2POUI);
5076 u8 oui_subtype = P2P_INVIT_REQ;
5077 u8 p2pie[255] = { 0x00 };
5080 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5081 u16 len_channellist_attr = 0;
5086 struct xmit_frame *pmgntframe;
5087 struct pkt_attrib *pattrib;
5088 unsigned char *pframe;
5089 struct rtw_ieee80211_hdr *pwlanhdr;
5090 unsigned short *fctrl;
5091 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5092 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5093 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5094 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5097 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5098 if (pmgntframe == NULL)
5101 /* update attribute */
5102 pattrib = &pmgntframe->attrib;
5103 update_mgntframe_attrib(padapter, pattrib);
5105 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5107 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5108 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5110 fctrl = &(pwlanhdr->frame_ctl);
5113 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5114 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5115 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5117 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5118 pmlmeext->mgnt_seq++;
5119 set_frame_sub_type(pframe, WIFI_ACTION);
5121 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5122 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5124 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5125 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5126 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5127 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5128 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5130 /* P2P IE Section. */
5134 p2pie[p2pielen++] = 0x50;
5135 p2pie[p2pielen++] = 0x6F;
5136 p2pie[p2pielen++] = 0x9A;
5137 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5139 /* Commented by Albert 20101011 */
5140 /* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
5141 /* 1. Configuration Timeout */
5142 /* 2. Invitation Flags */
5143 /* 3. Operating Channel ( Only GO ) */
5144 /* 4. P2P Group BSSID ( Should be included if I am the GO ) */
5145 /* 5. Channel List */
5146 /* 6. P2P Group ID */
5147 /* 7. P2P Device Info */
5149 /* Configuration Timeout */
5151 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5154 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5158 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5159 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5161 /* Invitation Flags */
5163 p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
5166 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5170 p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
5173 /* Operating Channel */
5175 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5178 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5182 /* Country String */
5183 p2pie[p2pielen++] = 'X';
5184 p2pie[p2pielen++] = 'X';
5186 /* The third byte should be set to 0x04. */
5187 /* Described in the "Operating Channel Attribute" section. */
5188 p2pie[p2pielen++] = 0x04;
5190 /* Operating Class */
5191 if (pwdinfo->invitereq_info.operating_ch <= 14)
5192 p2pie[p2pielen++] = 0x51;
5193 else if ((pwdinfo->invitereq_info.operating_ch >= 36) && (pwdinfo->invitereq_info.operating_ch <= 48))
5194 p2pie[p2pielen++] = 0x73;
5196 p2pie[p2pielen++] = 0x7c;
5198 /* Channel Number */
5199 p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch; /* operating channel number */
5201 if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) {
5202 /* P2P Group BSSID */
5204 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
5207 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5211 /* P2P Device Address for GO */
5212 _rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
5213 p2pielen += ETH_ALEN;
5218 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5222 /* Country String(3) */
5223 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5224 /* + number of channels in all classes */
5225 len_channellist_attr = 3
5226 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5227 + get_reg_classes_full_count(pmlmeext->channel_list);
5229 #ifdef CONFIG_CONCURRENT_MODE
5230 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5231 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5233 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5235 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5240 /* Country String */
5241 p2pie[p2pielen++] = 'X';
5242 p2pie[p2pielen++] = 'X';
5244 /* The third byte should be set to 0x04. */
5245 /* Described in the "Operating Channel Attribute" section. */
5246 p2pie[p2pielen++] = 0x04;
5248 /* Channel Entry List */
5249 #ifdef CONFIG_CONCURRENT_MODE
5250 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
5251 u8 union_ch = rtw_mi_get_union_chan(padapter);
5253 /* Operating Class */
5254 if (union_ch > 14) {
5255 if (union_ch >= 149)
5256 p2pie[p2pielen++] = 0x7c;
5258 p2pie[p2pielen++] = 0x73;
5260 p2pie[p2pielen++] = 0x51;
5263 /* Number of Channels */
5264 /* Just support 1 channel and this channel is AP's channel */
5265 p2pie[p2pielen++] = 1;
5268 p2pie[p2pielen++] = union_ch;
5271 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5272 /* Operating Class */
5273 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5275 /* Number of Channels */
5276 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5279 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5280 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5283 #else /* CONFIG_CONCURRENT_MODE */
5286 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5287 /* Operating Class */
5288 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5290 /* Number of Channels */
5291 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5294 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5295 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5298 #endif /* CONFIG_CONCURRENT_MODE */
5303 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5306 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
5310 /* P2P Device Address for GO */
5311 _rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
5312 p2pielen += ETH_ALEN;
5315 _rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen);
5316 p2pielen += pwdinfo->invitereq_info.ssidlen;
5321 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5324 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
5325 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5326 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5330 /* P2P Device Address */
5331 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5332 p2pielen += ETH_ALEN;
5335 /* This field should be big endian. Noted by P2P specification. */
5336 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
5339 /* Primary Device Type */
5341 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5345 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5348 /* Sub Category ID */
5349 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5352 /* Number of Secondary Device Types */
5353 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
5357 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5361 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5365 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
5366 p2pielen += pwdinfo->device_name_len;
5368 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5371 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5373 pattrib->pktlen += wfdielen;
5376 pattrib->last_txcmdsz = pattrib->pktlen;
5378 dump_mgntframe(padapter, pmgntframe);
5384 void issue_p2p_invitation_response(_adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code)
5387 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5388 u8 action = P2P_PUB_ACTION_ACTION;
5389 u32 p2poui = cpu_to_be32(P2POUI);
5390 u8 oui_subtype = P2P_INVIT_RESP;
5391 u8 p2pie[255] = { 0x00 };
5393 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
5394 u16 len_channellist_attr = 0;
5399 struct xmit_frame *pmgntframe;
5400 struct pkt_attrib *pattrib;
5401 unsigned char *pframe;
5402 struct rtw_ieee80211_hdr *pwlanhdr;
5403 unsigned short *fctrl;
5404 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5405 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5406 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5407 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5410 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5411 if (pmgntframe == NULL)
5414 /* update attribute */
5415 pattrib = &pmgntframe->attrib;
5416 update_mgntframe_attrib(padapter, pattrib);
5418 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5420 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5421 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5423 fctrl = &(pwlanhdr->frame_ctl);
5426 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5427 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5428 _rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5430 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5431 pmlmeext->mgnt_seq++;
5432 set_frame_sub_type(pframe, WIFI_ACTION);
5434 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5435 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5437 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5438 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5439 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5440 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5441 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5443 /* P2P IE Section. */
5447 p2pie[p2pielen++] = 0x50;
5448 p2pie[p2pielen++] = 0x6F;
5449 p2pie[p2pielen++] = 0x9A;
5450 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5452 /* Commented by Albert 20101005 */
5453 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
5455 /* 2. Configuration Timeout */
5456 /* 3. Operating Channel ( Only GO ) */
5457 /* 4. P2P Group BSSID ( Only GO ) */
5458 /* 5. Channel List */
5462 p2pie[p2pielen++] = P2P_ATTR_STATUS;
5465 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5469 /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
5470 /* Sent the event receiving the P2P Invitation Req frame to DMP UI. */
5471 /* DMP had to compare the MAC address to find out the profile. */
5472 /* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
5473 /* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
5474 /* to NB to rebuild the persistent group. */
5475 p2pie[p2pielen++] = status_code;
5477 /* Configuration Timeout */
5479 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5482 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5486 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5487 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5489 if (status_code == P2P_STATUS_SUCCESS) {
5490 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5491 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
5492 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
5493 /* First one is operating channel attribute. */
5494 /* Second one is P2P Group BSSID attribute. */
5496 /* Operating Channel */
5498 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5501 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5505 /* Country String */
5506 p2pie[p2pielen++] = 'X';
5507 p2pie[p2pielen++] = 'X';
5509 /* The third byte should be set to 0x04. */
5510 /* Described in the "Operating Channel Attribute" section. */
5511 p2pie[p2pielen++] = 0x04;
5513 /* Operating Class */
5514 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
5516 /* Channel Number */
5517 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
5520 /* P2P Group BSSID */
5522 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
5525 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5529 /* P2P Device Address for GO */
5530 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5531 p2pielen += ETH_ALEN;
5537 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5540 /* Country String(3) */
5541 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5542 /* + number of channels in all classes */
5543 len_channellist_attr = 3
5544 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
5545 + get_reg_classes_full_count(pmlmeext->channel_list);
5547 #ifdef CONFIG_CONCURRENT_MODE
5548 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5549 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5551 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5553 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5558 /* Country String */
5559 p2pie[p2pielen++] = 'X';
5560 p2pie[p2pielen++] = 'X';
5562 /* The third byte should be set to 0x04. */
5563 /* Described in the "Operating Channel Attribute" section. */
5564 p2pie[p2pielen++] = 0x04;
5566 /* Channel Entry List */
5567 #ifdef CONFIG_CONCURRENT_MODE
5568 if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
5569 u8 union_ch = rtw_mi_get_union_chan(padapter);
5571 /* Operating Class */
5572 if (union_ch > 14) {
5573 if (union_ch >= 149)
5574 p2pie[p2pielen++] = 0x7c;
5576 p2pie[p2pielen++] = 0x73;
5578 p2pie[p2pielen++] = 0x51;
5581 /* Number of Channels */
5582 /* Just support 1 channel and this channel is AP's channel */
5583 p2pie[p2pielen++] = 1;
5586 p2pie[p2pielen++] = union_ch;
5589 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5590 /* Operating Class */
5591 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5593 /* Number of Channels */
5594 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5597 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5598 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5601 #else /* CONFIG_CONCURRENT_MODE */
5604 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
5605 /* Operating Class */
5606 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
5608 /* Number of Channels */
5609 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
5612 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++)
5613 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
5616 #endif /* CONFIG_CONCURRENT_MODE */
5619 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5622 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5624 pattrib->pktlen += wfdielen;
5627 pattrib->last_txcmdsz = pattrib->pktlen;
5629 dump_mgntframe(padapter, pmgntframe);
5635 void issue_p2p_provision_request(_adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
5637 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5638 u8 action = P2P_PUB_ACTION_ACTION;
5640 u32 p2poui = cpu_to_be32(P2POUI);
5641 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
5642 u8 wpsie[100] = { 0x00 };
5649 struct xmit_frame *pmgntframe;
5650 struct pkt_attrib *pattrib;
5651 unsigned char *pframe;
5652 struct rtw_ieee80211_hdr *pwlanhdr;
5653 unsigned short *fctrl;
5654 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5655 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5656 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5657 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5660 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5661 if (pmgntframe == NULL)
5664 RTW_INFO("[%s] In\n", __FUNCTION__);
5665 /* update attribute */
5666 pattrib = &pmgntframe->attrib;
5667 update_mgntframe_attrib(padapter, pattrib);
5669 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5671 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5672 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5674 fctrl = &(pwlanhdr->frame_ctl);
5677 _rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5678 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5679 _rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5681 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5682 pmlmeext->mgnt_seq++;
5683 set_frame_sub_type(pframe, WIFI_ACTION);
5685 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5686 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5688 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5689 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5690 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5691 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5692 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5694 p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr);
5697 pattrib->pktlen += p2pielen;
5701 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5706 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5710 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5714 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5718 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
5722 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5726 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
5729 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
5733 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5735 pattrib->pktlen += wfdielen;
5738 pattrib->last_txcmdsz = pattrib->pktlen;
5740 dump_mgntframe(padapter, pmgntframe);
5747 u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo)
5749 u8 i, match_result = 0;
5751 RTW_INFO("[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5752 peermacaddr[0], peermacaddr[1], peermacaddr[2], peermacaddr[3], peermacaddr[4], peermacaddr[5]);
5754 for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
5755 RTW_INFO("[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5756 profileinfo->peermac[0], profileinfo->peermac[1], profileinfo->peermac[2], profileinfo->peermac[3], profileinfo->peermac[4], profileinfo->peermac[5]);
5757 if (_rtw_memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) {
5759 RTW_INFO("[%s] Match!\n", __FUNCTION__);
5764 return match_result ;
5767 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5769 struct xmit_frame *pmgntframe;
5770 struct pkt_attrib *pattrib;
5771 unsigned char *pframe;
5772 struct rtw_ieee80211_hdr *pwlanhdr;
5773 unsigned short *fctrl;
5775 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5776 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5777 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5778 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5779 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
5780 u16 beacon_interval = 100;
5782 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5783 u8 wpsie[255] = { 0x00 };
5784 u32 wpsielen = 0, p2pielen = 0;
5788 #ifdef CONFIG_INTEL_WIDI
5789 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
5790 #endif /* CONFIG_INTEL_WIDI */
5792 /* RTW_INFO("%s\n", __FUNCTION__); */
5794 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5795 if (pmgntframe == NULL)
5798 /* update attribute */
5799 pattrib = &pmgntframe->attrib;
5800 update_mgntframe_attrib(padapter, pattrib);
5802 if (IS_CCK_RATE(pattrib->rate)) {
5803 /* force OFDM 6M rate */
5804 pattrib->rate = MGN_6M;
5805 pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
5808 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5810 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5811 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5813 mac = adapter_mac_addr(padapter);
5815 fctrl = &(pwlanhdr->frame_ctl);
5817 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5818 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5820 /* Use the device address for BSSID field. */
5821 _rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5823 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5824 pmlmeext->mgnt_seq++;
5825 set_frame_sub_type(fctrl, WIFI_PROBERSP);
5827 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5828 pattrib->pktlen = pattrib->hdrlen;
5829 pframe += pattrib->hdrlen;
5831 /* timestamp will be inserted by hardware */
5833 pattrib->pktlen += 8;
5835 /* beacon interval: 2 bytes */
5836 _rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5838 pattrib->pktlen += 2;
5840 /* capability info: 2 bytes */
5841 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
5842 capInfo |= cap_ShortPremble;
5843 capInfo |= cap_ShortSlot;
5845 _rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5847 pattrib->pktlen += 2;
5851 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5853 /* supported rates... */
5854 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
5855 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5857 /* DS parameter set */
5858 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5860 #ifdef CONFIG_IOCTL_CFG80211
5861 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
5862 if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
5864 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5865 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5866 pframe += pmlmepriv->wps_probe_resp_ie_len;
5869 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5870 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5871 pframe += pmlmepriv->p2p_probe_resp_ie_len;
5874 #endif /* CONFIG_IOCTL_CFG80211 */
5878 /* Noted by Albert 20100907 */
5879 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
5883 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5888 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5892 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5896 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5898 #ifdef CONFIG_INTEL_WIDI
5899 /* Commented by Kurt */
5900 /* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
5901 if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
5902 || pmlmepriv->num_p2p_sdt != 0) {
5904 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SEC_DEV_TYPE_LIST);
5908 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
5913 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_DISPLAYS);
5917 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(INTEL_DEV_TYPE_OUI);
5920 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_WIDI_CONSUMER_SINK);
5923 if (_rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE) {
5924 /* Vendor Extension */
5925 _rtw_memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN);
5926 wpsielen += L2SDTA_SERVICE_VE_LEN;
5929 #endif /* CONFIG_INTEL_WIDI */
5931 /* WiFi Simple Config State */
5933 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
5937 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5941 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
5945 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
5949 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5953 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5957 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
5961 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
5965 if (pwdinfo->external_uuid == 0) {
5966 _rtw_memset(wpsie + wpsielen, 0x0, 16);
5967 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5969 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
5974 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
5978 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
5982 _rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
5987 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
5991 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
5995 _rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
6000 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
6004 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6008 wpsie[wpsielen++] = 0x31; /* character 1 */
6012 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
6016 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
6020 _rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
6021 wpsielen += ETH_ALEN;
6023 /* Primary Device Type */
6025 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6029 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6034 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6038 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6041 /* Sub Category ID */
6042 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6047 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6051 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6055 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6056 wpsielen += pwdinfo->device_name_len;
6060 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6064 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6068 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
6072 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6075 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
6077 pattrib->pktlen += p2pielen;
6081 wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
6083 pattrib->pktlen += wfdielen;
6086 pattrib->last_txcmdsz = pattrib->pktlen;
6089 dump_mgntframe(padapter, pmgntframe);
6095 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
6098 struct xmit_frame *pmgntframe;
6099 struct pkt_attrib *pattrib;
6100 unsigned char *pframe;
6101 struct rtw_ieee80211_hdr *pwlanhdr;
6102 unsigned short *fctrl;
6104 unsigned char bssrate[NumRates];
6105 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6106 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6107 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6108 int bssrate_len = 0;
6109 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6110 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6111 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
6112 u16 wpsielen = 0, p2pielen = 0;
6117 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6120 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6121 if (pmgntframe == NULL)
6124 /* update attribute */
6125 pattrib = &pmgntframe->attrib;
6126 update_mgntframe_attrib(padapter, pattrib);
6128 if (IS_CCK_RATE(pattrib->rate)) {
6129 /* force OFDM 6M rate */
6130 pattrib->rate = MGN_6M;
6131 pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
6134 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6136 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6137 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6139 mac = adapter_mac_addr(padapter);
6141 fctrl = &(pwlanhdr->frame_ctl);
6145 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6146 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6148 if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
6149 /* This two flags will be set when this is only the P2P client mode. */
6150 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6151 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
6153 /* broadcast probe request frame */
6154 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6155 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6158 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6160 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6161 pmlmeext->mgnt_seq++;
6162 set_frame_sub_type(pframe, WIFI_PROBEREQ);
6164 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6165 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6167 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
6168 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
6170 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
6171 /* Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) */
6172 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
6174 #ifdef CONFIG_IOCTL_CFG80211
6175 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
6176 if (pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL) {
6178 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6179 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6180 pframe += pmlmepriv->wps_probe_req_ie_len;
6183 _rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
6184 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
6185 pframe += pmlmepriv->p2p_probe_req_ie_len;
6188 #endif /* CONFIG_IOCTL_CFG80211 */
6192 /* Noted by Albert 20110221 */
6193 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
6197 *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6202 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6206 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6210 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6212 if (pmlmepriv->wps_probe_req_ie == NULL) {
6215 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
6219 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
6223 if (pwdinfo->external_uuid == 0) {
6224 _rtw_memset(wpsie + wpsielen, 0x0, 16);
6225 _rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
6227 _rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
6232 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6236 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6240 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
6246 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6250 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
6254 _rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
6255 wpsielen += pwdinfo->device_name_len;
6257 /* Primary Device Type */
6259 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
6263 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
6268 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
6272 *(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
6275 /* Sub Category ID */
6276 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
6279 /* Device Password ID */
6281 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
6285 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6289 *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); /* Registrar-specified */
6292 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6296 p2pie[p2pielen++] = 0x50;
6297 p2pie[p2pielen++] = 0x6F;
6298 p2pie[p2pielen++] = 0x9A;
6299 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
6301 /* Commented by Albert 20110221 */
6302 /* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
6303 /* 1. P2P Capability */
6304 /* 2. P2P Device ID if this probe request wants to find the specific P2P device */
6305 /* 3. Listen Channel */
6306 /* 4. Extended Listen Timing */
6307 /* 5. Operating Channel if this WiFi is working as the group owner now */
6309 /* P2P Capability */
6311 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
6314 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
6318 /* Device Capability Bitmap, 1 byte */
6319 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
6321 /* Group Capability Bitmap, 1 byte */
6322 if (pwdinfo->persistent_supported)
6323 p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
6325 p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
6327 /* Listen Channel */
6329 p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
6332 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6336 /* Country String */
6337 p2pie[p2pielen++] = 'X';
6338 p2pie[p2pielen++] = 'X';
6340 /* The third byte should be set to 0x04. */
6341 /* Described in the "Operating Channel Attribute" section. */
6342 p2pie[p2pielen++] = 0x04;
6344 /* Operating Class */
6345 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
6347 /* Channel Number */
6348 p2pie[p2pielen++] = pwdinfo->listen_channel; /* listen channel */
6351 /* Extended Listen Timing */
6353 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
6356 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
6360 /* Availability Period */
6361 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6364 /* Availability Interval */
6365 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6368 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6369 /* Operating Channel (if this WiFi is working as the group owner now) */
6371 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
6374 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6378 /* Country String */
6379 p2pie[p2pielen++] = 'X';
6380 p2pie[p2pielen++] = 'X';
6382 /* The third byte should be set to 0x04. */
6383 /* Described in the "Operating Channel Attribute" section. */
6384 p2pie[p2pielen++] = 0x04;
6386 /* Operating Class */
6387 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
6389 /* Channel Number */
6390 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
6394 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
6399 wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe);
6401 pattrib->pktlen += wfdielen;
6404 pattrib->last_txcmdsz = pattrib->pktlen;
6408 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6410 dump_mgntframe(padapter, pmgntframe);
6418 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6420 _issue_probereq_p2p(adapter, da, _FALSE);
6424 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6425 * 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
6426 * try_cnt means the maximal TX count to try
6428 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6432 u32 start = rtw_get_current_time();
6435 ret = _issue_probereq_p2p(adapter, da, wait_ms > 0 ? _TRUE : _FALSE);
6439 if (RTW_CANNOT_RUN(adapter))
6442 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
6443 rtw_msleep_os(wait_ms);
6445 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
6449 #ifndef DBG_XMIT_ACK
6454 if (try_cnt && wait_ms) {
6456 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6457 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6458 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
6460 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6461 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6462 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
6468 #endif /* CONFIG_P2P */
6470 s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset)
6472 _adapter *adapter = rframe->u.hdr.adapter;
6473 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6474 u8 *frame = rframe->u.hdr.rx_data;
6475 u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num & 0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf);
6476 u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset);
6478 if (GetRetry(frame)) {
6479 if ((seq_ctrl == mlmeext->action_public_rxseq)
6480 && (token == mlmeext->action_public_dialog_token)
6482 RTW_INFO(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6483 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6488 /* TODO: per sta seq & token */
6489 mlmeext->action_public_rxseq = seq_ctrl;
6490 mlmeext->action_public_dialog_token = token;
6495 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6497 _adapter *padapter = precv_frame->u.hdr.adapter;
6498 u8 *pframe = precv_frame->u.hdr.rx_data;
6499 uint len = precv_frame->u.hdr.len;
6503 u32 p2p_ielen, wps_ielen;
6504 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6505 u8 result = P2P_STATUS_SUCCESS;
6506 u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6507 u8 *merged_p2pie = NULL;
6508 u32 merged_p2p_ielen = 0;
6509 #endif /* CONFIG_P2P */
6511 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6514 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
6515 #ifdef CONFIG_IOCTL_CFG80211
6516 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6517 rtw_cfg80211_rx_p2p_action_public(padapter, precv_frame);
6519 #endif /* CONFIG_IOCTL_CFG80211 */
6521 /* Do nothing if the driver doesn't enable the P2P function. */
6522 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6525 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6527 switch (frame_body[6]) { /* OUI Subtype */
6528 case P2P_GO_NEGO_REQ: {
6529 RTW_INFO("[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6530 _rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
6532 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6533 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6535 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) {
6536 /* Commented by Albert 20110526 */
6537 /* In this case, this means the previous nego fail doesn't be reset yet. */
6538 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6539 /* Restore the previous p2p state */
6540 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6541 RTW_INFO("[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));
6543 #ifdef CONFIG_CONCURRENT_MODE
6544 if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
6545 _cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);
6546 #endif /* CONFIG_CONCURRENT_MODE */
6548 /* Commented by Kurt 20110902 */
6549 /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
6550 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6551 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6553 /* Commented by Kurt 20120113 */
6554 /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
6555 if (_rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN))
6556 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN);
6558 result = process_p2p_group_negotation_req(pwdinfo, frame_body, len);
6559 issue_p2p_GO_response(padapter, get_addr2_ptr(pframe), frame_body, len, result);
6560 #ifdef CONFIG_INTEL_WIDI
6561 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6562 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6563 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6564 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6566 #endif /* CONFIG_INTEL_WIDI */
6568 /* Commented by Albert 20110718 */
6569 /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
6570 #ifdef CONFIG_CONCURRENT_MODE
6571 /* Commented by Albert 20120107 */
6572 _set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
6573 #else /* CONFIG_CONCURRENT_MODE */
6574 _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
6575 #endif /* CONFIG_CONCURRENT_MODE */
6578 case P2P_GO_NEGO_RESP: {
6579 RTW_INFO("[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6581 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
6582 /* Commented by Albert 20110425 */
6583 /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
6584 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6585 pwdinfo->nego_req_info.benable = _FALSE;
6586 result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len);
6587 issue_p2p_GO_confirm(pwdinfo->padapter, get_addr2_ptr(pframe), result);
6588 if (P2P_STATUS_SUCCESS == result) {
6589 if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
6590 pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
6591 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6592 pwdinfo->p2p_info.operation_ch[1] = 1; /* Check whether GO is operating in channel 1; */
6593 pwdinfo->p2p_info.operation_ch[2] = 6; /* Check whether GO is operating in channel 6; */
6594 pwdinfo->p2p_info.operation_ch[3] = 11; /* Check whether GO is operating in channel 11; */
6595 #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
6596 pwdinfo->p2p_info.scan_op_ch_only = 1;
6597 _set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
6601 /* Reset the dialog token for group negotiation frames. */
6602 pwdinfo->negotiation_dialog_token = 1;
6604 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6605 _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
6607 RTW_INFO("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6611 case P2P_GO_NEGO_CONF: {
6612 RTW_INFO("[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6613 result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len);
6614 if (P2P_STATUS_SUCCESS == result) {
6615 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);
6628 case P2P_INVIT_REQ: {
6629 /* Added by Albert 2010/10/05 */
6630 /* Received the P2P Invite Request frame. */
6632 RTW_INFO("[%s] Got invite request frame!\n", __FUNCTION__);
6633 p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
6635 /* Parse the necessary information from the P2P Invitation Request frame. */
6636 /* For example: The MAC address of sending this P2P Invitation Request frame. */
6637 u32 attr_contentlen = 0;
6638 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6639 struct group_id_info group_id;
6640 u8 invitation_flag = 0;
6643 merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6645 merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2); /* 2 is for EID and Length */
6646 if (merged_p2pie == NULL) {
6647 RTW_INFO("[%s] Malloc p2p ie fail\n", __FUNCTION__);
6650 _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
6652 merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6654 rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6655 if (attr_contentlen) {
6657 rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6658 /* Commented by Albert 20120510 */
6659 /* Copy to the pwdinfo->p2p_peer_interface_addr. */
6660 /* So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. */
6661 /* #> iwpriv wlan0 p2p_get peer_ifa */
6662 /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
6664 if (attr_contentlen) {
6665 RTW_INFO("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6666 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6667 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6668 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
6671 if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) {
6672 /* Re-invoke the persistent group. */
6674 _rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
6675 rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *) &group_id, &attr_contentlen);
6676 if (attr_contentlen) {
6677 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
6678 /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
6679 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
6680 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
6681 status_code = P2P_STATUS_SUCCESS;
6683 /* The p2p device sending this p2p invitation request wants to be the persistent GO. */
6684 if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) {
6685 u8 operatingch_info[5] = { 0x00 };
6686 if (rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info,
6687 &attr_contentlen)) {
6688 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4]) >= 0) {
6689 /* The operating channel is acceptable for this device. */
6690 pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4];
6691 #ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6692 pwdinfo->rx_invitereq_info.operation_ch[1] = 1; /* Check whether GO is operating in channel 1; */
6693 pwdinfo->rx_invitereq_info.operation_ch[2] = 6; /* Check whether GO is operating in channel 6; */
6694 pwdinfo->rx_invitereq_info.operation_ch[3] = 11; /* Check whether GO is operating in channel 11; */
6695 #endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
6696 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6697 _set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH);
6698 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
6699 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6700 status_code = P2P_STATUS_SUCCESS;
6702 /* The operating channel isn't supported by this device. */
6703 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
6704 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6705 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6706 _set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
6709 /* Commented by Albert 20121130 */
6710 /* Intel will use the different P2P IE to store the operating channel information */
6711 /* Workaround for Intel WiDi 3.5 */
6712 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
6713 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6714 status_code = P2P_STATUS_SUCCESS;
6717 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
6718 #ifdef CONFIG_INTEL_WIDI
6719 _rtw_memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN);
6720 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6721 #endif /* CONFIG_INTEL_WIDI */
6723 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6727 RTW_INFO("[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__);
6728 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6731 /* Received the invitation to join a P2P group. */
6733 _rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
6734 rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *) &group_id, &attr_contentlen);
6735 if (attr_contentlen) {
6736 if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
6737 /* In this case, the GO can't be myself. */
6738 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
6739 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6741 /* The p2p device sending this p2p invitation request wants to join an existing P2P group */
6742 /* Commented by Albert 2012/06/28 */
6743 /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
6744 /* The peer device address should be the destination address for the provisioning discovery request. */
6745 /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
6746 /* The peer interface address should be the address for WPS mac address */
6747 _rtw_memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN);
6748 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6749 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
6750 status_code = P2P_STATUS_SUCCESS;
6753 RTW_INFO("[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__);
6754 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6758 RTW_INFO("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__);
6759 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6762 RTW_INFO("[%s] status_code = %d\n", __FUNCTION__, status_code);
6764 pwdinfo->inviteresp_info.token = frame_body[7];
6765 issue_p2p_invitation_response(padapter, get_addr2_ptr(pframe), pwdinfo->inviteresp_info.token, status_code);
6766 _set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
6768 #ifdef CONFIG_INTEL_WIDI
6769 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6770 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6771 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6772 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6774 #endif /* CONFIG_INTEL_WIDI */
6777 case P2P_INVIT_RESP: {
6778 u8 attr_content = 0x00;
6779 u32 attr_contentlen = 0;
6781 RTW_INFO("[%s] Got invite response frame!\n", __FUNCTION__);
6782 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6783 p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
6785 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6787 if (attr_contentlen == 1) {
6788 RTW_INFO("[%s] Status = %d\n", __FUNCTION__, attr_content);
6789 pwdinfo->invitereq_info.benable = _FALSE;
6791 if (attr_content == P2P_STATUS_SUCCESS) {
6792 if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6793 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
6795 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6797 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
6799 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6800 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
6803 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6804 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
6807 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6808 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
6811 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL))
6812 _set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
6815 case P2P_DEVDISC_REQ:
6817 process_p2p_devdisc_req(pwdinfo, pframe, len);
6821 case P2P_DEVDISC_RESP:
6823 process_p2p_devdisc_resp(pwdinfo, pframe, len);
6827 case P2P_PROVISION_DISC_REQ:
6828 RTW_INFO("[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__);
6829 process_p2p_provdisc_req(pwdinfo, pframe, len);
6830 _rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN);
6833 /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
6834 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6835 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6837 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6838 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
6839 #ifdef CONFIG_INTEL_WIDI
6840 if (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) {
6841 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
6842 _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
6843 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL, 0);
6845 #endif /* CONFIG_INTEL_WIDI */
6848 case P2P_PROVISION_DISC_RESP:
6849 /* Commented by Albert 20110707 */
6850 /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
6851 RTW_INFO("[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__);
6852 /* Commented by Albert 20110426 */
6853 /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
6854 _cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6855 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6856 process_p2p_provdisc_resp(pwdinfo, pframe);
6857 _set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
6867 rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6868 #endif /* CONFIG_P2P */
6872 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6874 unsigned int ret = _FAIL;
6875 u8 *pframe = precv_frame->u.hdr.rx_data;
6876 uint frame_len = precv_frame->u.hdr.len;
6877 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6879 if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6880 if (rtw_action_public_decache(precv_frame, 7) == _FAIL)
6883 if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST))
6884 rtw_rframe_del_wfd_ie(precv_frame, 8);
6886 ret = on_action_public_p2p(precv_frame);
6893 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6895 unsigned int ret = _FAIL;
6896 u8 *pframe = precv_frame->u.hdr.rx_data;
6897 uint frame_len = precv_frame->u.hdr.len;
6898 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6900 _adapter *adapter = precv_frame->u.hdr.adapter;
6904 token = frame_body[2];
6906 if (rtw_action_public_decache(precv_frame, 2) == _FAIL)
6909 #ifdef CONFIG_IOCTL_CFG80211
6910 cnt += sprintf((msg + cnt), "%s(token:%u)", action_public_str(action), token);
6911 rtw_cfg80211_rx_action(adapter, precv_frame, msg);
6920 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6922 unsigned int ret = _FAIL;
6923 u8 *pframe = precv_frame->u.hdr.rx_data;
6924 uint frame_len = precv_frame->u.hdr.len;
6925 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6926 u8 category, action;
6928 /* check RA matches or not */
6929 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6932 category = frame_body[0];
6933 if (category != RTW_WLAN_CATEGORY_PUBLIC)
6936 action = frame_body[1];
6938 case ACT_PUBLIC_BSSCOEXIST:
6939 #ifdef CONFIG_80211N_HT
6940 #ifdef CONFIG_AP_MODE
6941 /*20/40 BSS Coexistence Management frame is a Public Action frame*/
6942 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6943 rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
6944 #endif /*CONFIG_AP_MODE*/
6945 #endif /*CONFIG_80211N_HT*/
6947 case ACT_PUBLIC_VENDOR:
6948 ret = on_action_public_vendor(precv_frame);
6951 ret = on_action_public_default(precv_frame, action);
6959 unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame)
6961 #ifdef CONFIG_RTW_80211R
6967 u8 *pframe_body = NULL;
6968 u8 sta_addr[ETH_ALEN] = {0};
6971 u32 status_code = 0;
6972 struct mlme_ext_priv *pmlmeext = NULL;
6973 struct mlme_ext_info *pmlmeinfo = NULL;
6974 struct mlme_priv *pmlmepriv = NULL;
6975 struct wlan_network *proam_target = NULL;
6976 ft_priv *pftpriv = NULL;
6979 pmlmeext = &padapter->mlmeextpriv;
6980 pmlmeinfo = &(pmlmeext->mlmext_info);
6981 pmlmepriv = &padapter->mlmepriv;
6982 pftpriv = &pmlmepriv->ftpriv;
6983 pframe = precv_frame->u.hdr.rx_data;
6984 frame_len = precv_frame->u.hdr.len;
6985 pframe_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6986 category = pframe_body[0];
6988 if (category != RTW_WLAN_CATEGORY_FT)
6991 action_code = pframe_body[1];
6992 switch (action_code) {
6993 case RTW_WLAN_ACTION_FT_RESPONSE:
6994 RTW_INFO("FT: %s RTW_WLAN_ACTION_FT_RESPONSE\n", __func__);
6995 if (!_rtw_memcmp(adapter_mac_addr(padapter), &pframe_body[2], ETH_ALEN)) {
6996 RTW_ERR("FT: Unmatched STA MAC Address "MAC_FMT"\n", MAC_ARG(&pframe_body[2]));
7000 status_code = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + 14));
7001 if (status_code != 0) {
7002 RTW_ERR("FT: WLAN ACTION FT RESPONSE fail, status: %d\n", status_code);
7006 if (is_zero_mac_addr(&pframe_body[8]) || is_broadcast_mac_addr(&pframe_body[8])) {
7007 RTW_ERR("FT: Invalid Target MAC Address "MAC_FMT"\n", MAC_ARG(padapter->mlmepriv.roam_tgt_addr));
7011 pie = rtw_get_ie(pframe_body, _MDIE_, &ft_ie_len, frame_len);
7013 if (!_rtw_memcmp(&pftpriv->mdid, pie+2, 2)) {
7014 RTW_ERR("FT: Invalid MDID\n");
7019 rtw_set_ft_status(padapter, RTW_FT_REQUESTED_STA);
7020 _cancel_timer_ex(&pmlmeext->ft_link_timer);
7022 /*Disconnect current AP*/
7023 receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress, WLAN_REASON_ACTIVE_ROAM, _FALSE);
7025 pftpriv->ft_action_len = frame_len;
7026 _rtw_memcpy(pftpriv->ft_action, pframe, rtw_min(frame_len, RTW_MAX_FTIE_SZ));
7029 case RTW_WLAN_ACTION_FT_REQUEST:
7030 case RTW_WLAN_ACTION_FT_CONFIRM:
7031 case RTW_WLAN_ACTION_FT_ACK:
7033 RTW_ERR("FT: Unsupported FT Action!\n");
7044 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
7046 u8 *pframe = precv_frame->u.hdr.rx_data;
7047 uint frame_len = precv_frame->u.hdr.len;
7048 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7049 u8 category, action;
7051 /* check RA matches or not */
7052 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7055 category = frame_body[0];
7056 if (category != RTW_WLAN_CATEGORY_HT)
7059 action = frame_body[1];
7061 case RTW_WLAN_ACTION_HT_SM_PS:
7062 #ifdef CONFIG_80211N_HT
7063 #ifdef CONFIG_AP_MODE
7064 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7065 rtw_process_ht_action_smps(padapter, get_addr2_ptr(pframe), frame_body[2]);
7066 #endif /*CONFIG_AP_MODE*/
7067 #endif /*CONFIG_80211N_HT*/
7069 case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
7070 #ifdef CONFIG_BEAMFORMING
7071 /*RTW_INFO("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/
7072 rtw_beamforming_get_report_frame(padapter, precv_frame);
7073 #endif /*CONFIG_BEAMFORMING*/
7084 #ifdef CONFIG_IEEE80211W
7085 unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7087 u8 *pframe = precv_frame->u.hdr.rx_data;
7088 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7089 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7090 struct sta_info *psta;
7091 struct sta_priv *pstapriv = &padapter->stapriv;
7092 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7096 RTW_INFO("OnAction_sa_query\n");
7098 switch (pframe[WLAN_HDR_A3_LEN + 1]) {
7099 case 0: /* SA Query req */
7100 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN + 2], sizeof(u16));
7101 RTW_INFO("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7102 , pframe[WLAN_HDR_A3_LEN + 1], tid, pframe[WLAN_HDR_A3_LEN + 2], pframe[WLAN_HDR_A3_LEN + 3]);
7103 issue_action_SA_Query(padapter, get_addr2_ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7106 case 1: /* SA Query rsp */
7107 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
7109 _cancel_timer_ex(&psta->dot11w_expire_timer);
7111 _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN + 2], sizeof(u16));
7112 RTW_INFO("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN + 1], tid);
7119 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7120 for (pp = 0; pp < pattrib->pkt_len; pp++)
7121 printk(" %02x ", pframe[pp]);
7127 #endif /* CONFIG_IEEE80211W */
7129 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7134 unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7136 #ifdef CONFIG_80211AC_VHT
7137 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
7138 u8 *pframe = precv_frame->u.hdr.rx_data;
7139 uint frame_len = precv_frame->u.hdr.len;
7140 struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7141 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7142 u8 category, action;
7143 struct sta_info *psta = NULL;
7145 /* check RA matches or not */
7146 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7149 category = frame_body[0];
7150 if (category != RTW_WLAN_CATEGORY_VHT)
7153 action = frame_body[1];
7155 case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7156 #ifdef CONFIG_BEAMFORMING
7157 /*RTW_INFO("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/
7158 rtw_beamforming_get_report_frame(padapter, precv_frame);
7159 #endif /*CONFIG_BEAMFORMING*/
7161 case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7162 /* CategoryCode(1) + ActionCode(1) + OpModeNotification(1) */
7163 /* RTW_INFO("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n"); */
7164 psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7166 rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7168 case RTW_WLAN_ACTION_VHT_GROUPID_MANAGEMENT:
7169 #ifdef CONFIG_BEAMFORMING
7170 #ifdef RTW_BEAMFORMING_VERSION_2
7171 rtw_beamforming_get_vht_gid_mgnt_frame(padapter, precv_frame);
7172 #endif /* RTW_BEAMFORMING_VERSION_2 */
7173 #endif /* CONFIG_BEAMFORMING */
7180 #endif /* CONFIG_80211AC_VHT */
7185 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7189 u8 category, OUI_Subtype, dialogToken = 0;
7190 u8 *pframe = precv_frame->u.hdr.rx_data;
7191 uint len = precv_frame->u.hdr.len;
7192 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7194 /* check RA matches or not */
7195 if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7198 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7200 category = frame_body[0];
7201 if (category != RTW_WLAN_CATEGORY_P2P)
7204 if (cpu_to_be32(*((u32 *)(frame_body + 1))) != P2POUI)
7207 #ifdef CONFIG_IOCTL_CFG80211
7208 if (adapter_wdev_data(padapter)->p2p_enabled
7209 && pwdinfo->driver_interface == DRIVER_CFG80211
7211 rtw_cfg80211_rx_action_p2p(padapter, precv_frame);
7214 #endif /* CONFIG_IOCTL_CFG80211 */
7216 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7217 OUI_Subtype = frame_body[5];
7218 dialogToken = frame_body[6];
7220 switch (OUI_Subtype) {
7221 case P2P_NOTICE_OF_ABSENCE:
7225 case P2P_PRESENCE_REQUEST:
7227 process_p2p_presence_req(pwdinfo, pframe, len);
7231 case P2P_PRESENCE_RESPONSE:
7235 case P2P_GO_DISC_REQUEST:
7244 #endif /* CONFIG_P2P */
7250 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7253 unsigned char category;
7254 struct action_handler *ptable;
7255 unsigned char *frame_body;
7256 u8 *pframe = precv_frame->u.hdr.rx_data;
7258 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7260 category = frame_body[0];
7262 for (i = 0; i < sizeof(OnAction_tbl) / sizeof(struct action_handler); i++) {
7263 ptable = &OnAction_tbl[i];
7265 if (category == ptable->num)
7266 ptable->func(padapter, precv_frame);
7274 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7277 /* RTW_INFO("rcvd mgt frame(%x, %x)\n", (get_frame_sub_type(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */
7281 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7283 struct xmit_frame *pmgntframe;
7284 struct xmit_buf *pxmitbuf;
7287 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7289 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7291 if (pmgntframe == NULL) {
7292 RTW_INFO(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7296 pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
7297 if (pxmitbuf == NULL) {
7298 RTW_INFO(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7299 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7304 pmgntframe->frame_tag = MGNT_FRAMETAG;
7305 pmgntframe->pxmitbuf = pxmitbuf;
7306 pmgntframe->buf_addr = pxmitbuf->pbuf;
7307 pxmitbuf->priv_data = pmgntframe;
7314 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7316 return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7319 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7321 return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7325 /****************************************************************************
7327 Following are some TX fuctions for WiFi MLME
7329 *****************************************************************************/
7331 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
7333 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7335 pmlmeext->tx_rate = rate;
7336 /* RTW_INFO("%s(): rate = %x\n",__FUNCTION__, rate); */
7340 void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7342 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7344 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7345 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7346 struct sta_info *psta = NULL;
7347 struct sta_priv *pstapriv = &padapter->stapriv;
7348 struct sta_info *pbcmc_sta = NULL;
7350 psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7351 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7353 pattrib->hdrlen = 24;
7354 pattrib->nr_frags = 1;
7355 pattrib->priority = 7;
7358 pattrib->mac_id = pbcmc_sta->mac_id;
7360 pattrib->mac_id = 0;
7361 RTW_INFO("mgmt use mac_id 0 will affect RA\n");
7363 pattrib->qsel = QSLT_MGNT;
7365 pattrib->pktlen = 0;
7367 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7368 wireless_mode = WIRELESS_11B;
7370 wireless_mode = WIRELESS_11G;
7372 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7373 #ifdef CONFIG_80211AC_VHT
7374 if (pHalData->rf_type == RF_1T1R)
7375 pattrib->raid = RATEID_IDX_VHT_1SS;
7376 else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
7377 pattrib->raid = RATEID_IDX_VHT_2SS;
7378 else if (pHalData->rf_type == RF_3T3R)
7379 pattrib->raid = RATEID_IDX_VHT_3SS;
7381 pattrib->raid = RATEID_IDX_BGN_40M_1SS;
7384 #ifdef CONFIG_80211AC_VHT
7385 pattrib->rate = MGN_VHT1SS_MCS9;
7387 pattrib->rate = MGN_MCS7;
7390 pattrib->encrypt = _NO_PRIVACY_;
7391 pattrib->bswenc = _FALSE;
7393 pattrib->qos_en = _FALSE;
7395 pattrib->bwmode = CHANNEL_WIDTH_20;
7396 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7397 pattrib->sgi = _FALSE;
7399 pattrib->seqnum = pmlmeext->mgnt_seq;
7401 pattrib->retry_ctrl = _TRUE;
7403 pattrib->mbssid = 0;
7404 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7409 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7412 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7413 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7414 struct sta_info *pbcmc_sta = NULL;
7415 /* _rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); */
7417 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7419 pattrib->hdrlen = 24;
7420 pattrib->nr_frags = 1;
7421 pattrib->priority = 7;
7424 pattrib->mac_id = pbcmc_sta->mac_id;
7426 pattrib->mac_id = 1; /* use STA's BCMC sta-info macid */
7428 if (MLME_IS_AP(padapter) || MLME_IS_GO(padapter))
7429 RTW_INFO("%s-"ADPT_FMT" get bcmc sta_info fail,use MACID=1\n", __func__, ADPT_ARG(padapter));
7431 pattrib->qsel = QSLT_MGNT;
7433 #ifdef CONFIG_MCC_MODE
7434 update_mcc_mgntframe_attrib(padapter, pattrib);
7437 pattrib->pktlen = 0;
7439 if (IS_CCK_RATE(pmlmeext->tx_rate))
7440 wireless_mode = WIRELESS_11B;
7442 wireless_mode = WIRELESS_11G;
7443 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7444 pattrib->rate = pmlmeext->tx_rate;
7446 pattrib->encrypt = _NO_PRIVACY_;
7447 pattrib->bswenc = _FALSE;
7449 pattrib->qos_en = _FALSE;
7450 pattrib->ht_en = _FALSE;
7451 pattrib->bwmode = CHANNEL_WIDTH_20;
7452 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7453 pattrib->sgi = _FALSE;
7455 pattrib->seqnum = pmlmeext->mgnt_seq;
7457 pattrib->retry_ctrl = _TRUE;
7459 pattrib->mbssid = 0;
7460 pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7463 void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
7466 struct pkt_attrib *pattrib = &pmgntframe->attrib;
7467 #ifdef CONFIG_BEAMFORMING
7468 struct sta_info *sta = NULL;
7469 #endif /* CONFIG_BEAMFORMING */
7471 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7473 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
7474 _rtw_memcpy(pattrib->ta, get_addr2_ptr(pframe), ETH_ALEN);
7476 #ifdef CONFIG_BEAMFORMING
7477 sta = pattrib->psta;
7479 sta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
7480 pattrib->psta = sta;
7483 update_attrib_txbf_info(padapter, pattrib, sta);
7484 #endif /* CONFIG_BEAMFORMING */
7487 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
7489 if (RTW_CANNOT_RUN(padapter)) {
7490 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7491 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7495 rtw_hal_mgnt_xmit(padapter, pmgntframe);
7498 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7502 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7503 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
7504 struct submit_ctx sctx;
7506 if (RTW_CANNOT_RUN(padapter)) {
7507 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7508 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7512 rtw_sctx_init(&sctx, timeout_ms);
7513 pxmitbuf->sctx = &sctx;
7515 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
7517 if (ret == _SUCCESS)
7518 ret = rtw_sctx_wait(&sctx, __func__);
7520 _enter_critical(&pxmitpriv->lock_sctx, &irqL);
7521 pxmitbuf->sctx = NULL;
7522 _exit_critical(&pxmitpriv->lock_sctx, &irqL);
7527 s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7529 #ifdef CONFIG_XMIT_ACK
7530 static u8 seq_no = 0;
7532 struct xmit_priv *pxmitpriv = &(GET_PRIMARY_ADAPTER(padapter))->xmitpriv;
7534 if (RTW_CANNOT_RUN(padapter)) {
7535 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7536 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7540 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7541 pxmitpriv->ack_tx = _TRUE;
7542 pxmitpriv->seq_no = seq_no++;
7543 pmgntframe->ack_report = 1;
7544 rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7545 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
7546 ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7548 pxmitpriv->ack_tx = _FALSE;
7549 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7552 #else /* !CONFIG_XMIT_ACK */
7553 dump_mgntframe(padapter, pmgntframe);
7556 #endif /* !CONFIG_XMIT_ACK */
7559 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
7561 /* In this case, use 500 ms as the default wait_ack timeout */
7562 return dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, 500);
7566 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
7572 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
7574 /* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
7576 if (ssid_ie && ssid_len_ori > 0) {
7577 switch (hidden_ssid_mode) {
7579 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
7582 remain_len = ies_len - (next_ie - ies);
7585 _rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
7586 len_diff -= ssid_len_ori;
7591 _rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
7601 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
7602 u32 rtw_build_vendor_ie(_adapter *padapter , unsigned char *pframe , u8 mgmt_frame_tyte)
7604 int vendor_ie_num = 0;
7605 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7608 for (vendor_ie_num = 0 ; vendor_ie_num < WLAN_MAX_VENDOR_IE_NUM ; vendor_ie_num++) {
7609 if (pmlmepriv->vendor_ielen[vendor_ie_num] > 0 && pmlmepriv->vendor_ie_mask[vendor_ie_num] & mgmt_frame_tyte) {
7610 _rtw_memcpy(pframe , pmlmepriv->vendor_ie[vendor_ie_num] , pmlmepriv->vendor_ielen[vendor_ie_num]);
7611 pframe += pmlmepriv->vendor_ielen[vendor_ie_num];
7612 len += pmlmepriv->vendor_ielen[vendor_ie_num];
7620 void issue_beacon(_adapter *padapter, int timeout_ms)
7622 struct xmit_frame *pmgntframe;
7623 struct pkt_attrib *pattrib;
7624 unsigned char *pframe;
7625 struct rtw_ieee80211_hdr *pwlanhdr;
7626 unsigned short *fctrl;
7627 unsigned int rate_len;
7628 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7629 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7631 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7632 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
7633 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7634 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7635 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7636 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7638 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7639 #endif /* CONFIG_P2P */
7642 /* RTW_INFO("%s\n", __FUNCTION__); */
7644 #ifdef CONFIG_BCN_ICF
7645 pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv);
7646 if (pmgntframe == NULL)
7648 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
7649 if (pmgntframe == NULL)
7652 RTW_INFO("%s, alloc mgnt frame fail\n", __FUNCTION__);
7655 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7656 _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7657 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
7659 /* update attribute */
7660 pattrib = &pmgntframe->attrib;
7661 update_mgntframe_attrib(padapter, pattrib);
7662 pattrib->qsel = QSLT_BEACON;
7664 #if defined(CONFIG_CONCURRENT_MODE) && (!defined(CONFIG_SWTIMER_BASED_TXBCN))
7665 if (padapter->hw_port == HW_PORT1)
7666 pattrib->mbssid = 1;
7669 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7671 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7672 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7675 fctrl = &(pwlanhdr->frame_ctl);
7678 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7679 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7680 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7682 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7683 /* pmlmeext->mgnt_seq++; */
7684 set_frame_sub_type(pframe, WIFI_BEACON);
7686 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7687 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7689 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7690 /* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7692 /* for P2P : Primary Device Type & Device Name */
7693 u32 wpsielen = 0, insert_len = 0;
7695 wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
7697 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
7698 uint wps_offset, remainder_ielen;
7699 u8 *premainder_ie, *pframe_wscie;
7701 wps_offset = (uint)(wpsie - cur_network->IEs);
7703 premainder_ie = wpsie + wpsielen;
7705 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7707 #ifdef CONFIG_IOCTL_CFG80211
7708 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
7709 if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
7710 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7711 pframe += wps_offset;
7712 pattrib->pktlen += wps_offset;
7714 _rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7715 pframe += pmlmepriv->wps_beacon_ie_len;
7716 pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7718 /* copy remainder_ie to pframe */
7719 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7720 pframe += remainder_ielen;
7721 pattrib->pktlen += remainder_ielen;
7723 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7724 pframe += cur_network->IELength;
7725 pattrib->pktlen += cur_network->IELength;
7728 #endif /* CONFIG_IOCTL_CFG80211 */
7730 pframe_wscie = pframe + wps_offset;
7731 _rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
7732 pframe += (wps_offset + wpsielen);
7733 pattrib->pktlen += (wps_offset + wpsielen);
7735 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
7736 /* Primary Device Type */
7738 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
7742 *(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
7747 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7751 *(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
7754 /* Sub Category ID */
7755 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7761 *(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7765 *(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
7769 _rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
7770 insert_len += pwdinfo->device_name_len;
7773 /* update wsc ie length */
7774 *(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
7776 /* pframe move to end */
7777 pframe += insert_len;
7778 pattrib->pktlen += insert_len;
7780 /* copy remainder_ie to pframe */
7781 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7782 pframe += remainder_ielen;
7783 pattrib->pktlen += remainder_ielen;
7786 #endif /* CONFIG_P2P */
7789 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7790 len_diff = update_hidden_ssid(
7791 pframe + _BEACON_IE_OFFSET_
7792 , cur_network->IELength - _BEACON_IE_OFFSET_
7793 , pmlmeinfo->hidden_ssid_mode
7795 pframe += (cur_network->IELength + len_diff);
7796 pattrib->pktlen += (cur_network->IELength + len_diff);
7803 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
7804 pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
7805 if (wps_ie && wps_ielen > 0)
7806 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
7808 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7810 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7814 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7816 #ifdef CONFIG_IOCTL_CFG80211
7817 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
7818 len = pmlmepriv->p2p_beacon_ie_len;
7819 if (pmlmepriv->p2p_beacon_ie && len > 0)
7820 _rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7822 #endif /* CONFIG_IOCTL_CFG80211 */
7824 len = build_beacon_p2p_ie(pwdinfo, pframe);
7828 pattrib->pktlen += len;
7830 #ifdef CONFIG_MCC_MODE
7831 pframe = rtw_hal_mcc_append_go_p2p_ie(padapter, pframe, &pattrib->pktlen);
7832 #endif /* CONFIG_MCC_MODE*/
7835 len = rtw_append_beacon_wfd_ie(padapter, pframe);
7837 pattrib->pktlen += len;
7840 #endif /* CONFIG_P2P */
7842 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
7843 pattrib->pktlen += rtw_build_vendor_ie(padapter , pframe , WIFI_BEACON_VENDOR_IE_BIT);
7849 /* below for ad-hoc mode */
7851 /* timestamp will be inserted by hardware */
7853 pattrib->pktlen += 8;
7855 /* beacon interval: 2 bytes */
7857 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7860 pattrib->pktlen += 2;
7862 /* capability info: 2 bytes */
7864 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7867 pattrib->pktlen += 2;
7870 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7872 /* supported rates... */
7873 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7874 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7876 /* DS parameter set */
7877 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7879 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
7883 /* IBSS Parameter Set... */
7884 /* ATIMWindow = cur->Configuration.ATIMWindow; */
7886 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
7889 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
7893 /* EXTERNDED SUPPORTED RATE */
7895 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
7898 /* todo:HT for adhoc */
7902 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7903 pmlmepriv->update_bcn = _FALSE;
7905 _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7906 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
7908 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
7909 RTW_INFO("beacon frame too large\n");
7913 pattrib->last_txcmdsz = pattrib->pktlen;
7915 /* RTW_INFO("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
7917 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
7919 dump_mgntframe(padapter, pmgntframe);
7923 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
7925 struct xmit_frame *pmgntframe;
7926 struct pkt_attrib *pattrib;
7927 unsigned char *pframe;
7928 struct rtw_ieee80211_hdr *pwlanhdr;
7929 unsigned short *fctrl;
7930 unsigned char *mac, *bssid;
7931 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7932 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7935 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7936 #endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
7937 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7938 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7939 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7940 unsigned int rate_len;
7942 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7946 #endif /* CONFIG_P2P */
7948 /* RTW_INFO("%s\n", __FUNCTION__); */
7953 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
7956 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
7957 if (pmgntframe == NULL) {
7958 RTW_INFO("%s, alloc mgnt frame fail\n", __FUNCTION__);
7963 /* update attribute */
7964 pattrib = &pmgntframe->attrib;
7965 update_mgntframe_attrib(padapter, pattrib);
7967 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7969 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7970 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7972 mac = adapter_mac_addr(padapter);
7973 bssid = cur_network->MacAddress;
7975 fctrl = &(pwlanhdr->frame_ctl);
7977 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7978 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
7979 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
7981 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7982 pmlmeext->mgnt_seq++;
7983 set_frame_sub_type(fctrl, WIFI_PROBERSP);
7985 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7986 pattrib->pktlen = pattrib->hdrlen;
7987 pframe += pattrib->hdrlen;
7990 if (cur_network->IELength > MAX_IE_SZ)
7993 #if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7994 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
7995 pwps_ie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
7997 /* inerset & update wps_probe_resp_ie */
7998 if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie && (wps_ielen > 0)) {
7999 uint wps_offset, remainder_ielen;
8002 wps_offset = (uint)(pwps_ie - cur_network->IEs);
8004 premainder_ie = pwps_ie + wps_ielen;
8006 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
8008 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
8009 pframe += wps_offset;
8010 pattrib->pktlen += wps_offset;
8012 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
8013 if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) {
8014 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2);
8015 pframe += wps_ielen + 2;
8016 pattrib->pktlen += wps_ielen + 2;
8019 if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
8020 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8021 pframe += remainder_ielen;
8022 pattrib->pktlen += remainder_ielen;
8025 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8026 pframe += cur_network->IELength;
8027 pattrib->pktlen += cur_network->IELength;
8030 /* retrieve SSID IE from cur_network->Ssid */
8034 sint ssid_ielen_diff;
8036 u8 *ies = pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr);
8038 ssid_ie = rtw_get_ie(ies + _FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
8039 (pframe - ies) - _FIXED_IE_LENGTH_);
8041 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
8043 if (ssid_ie && cur_network->Ssid.SsidLength) {
8044 uint remainder_ielen;
8046 remainder_ie = ssid_ie + 2;
8047 remainder_ielen = (pframe - remainder_ie);
8049 if (remainder_ielen > MAX_IE_SZ) {
8050 RTW_WARN(FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
8051 remainder_ielen = MAX_IE_SZ;
8054 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
8055 _rtw_memcpy(remainder_ie + ssid_ielen_diff, buf, remainder_ielen);
8056 *(ssid_ie + 1) = cur_network->Ssid.SsidLength;
8057 _rtw_memcpy(ssid_ie + 2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
8059 pframe += ssid_ielen_diff;
8060 pattrib->pktlen += ssid_ielen_diff;
8063 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8064 pattrib->pktlen += rtw_build_vendor_ie(padapter , pframe , WIFI_PROBERESP_VENDOR_IE_BIT);
8070 /* timestamp will be inserted by hardware */
8072 pattrib->pktlen += 8;
8074 /* beacon interval: 2 bytes */
8076 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
8079 pattrib->pktlen += 2;
8081 /* capability info: 2 bytes */
8083 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8086 pattrib->pktlen += 2;
8088 /* below for ad-hoc mode */
8091 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8093 /* supported rates... */
8094 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8095 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8097 /* DS parameter set */
8098 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8100 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
8103 /* IBSS Parameter Set... */
8104 /* ATIMWindow = cur->Configuration.ATIMWindow; */
8106 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8109 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8113 /* EXTERNDED SUPPORTED RATE */
8115 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8118 /* todo:HT for adhoc */
8123 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8124 /* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
8125 && (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec)) {
8127 #ifdef CONFIG_IOCTL_CFG80211
8128 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
8129 /* if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() */
8130 len = pmlmepriv->p2p_go_probe_resp_ie_len;
8131 if (pmlmepriv->p2p_go_probe_resp_ie && len > 0)
8132 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
8134 #endif /* CONFIG_IOCTL_CFG80211 */
8136 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
8140 pattrib->pktlen += len;
8142 #ifdef CONFIG_MCC_MODE
8143 pframe = rtw_hal_mcc_append_go_p2p_ie(padapter, pframe, &pattrib->pktlen);
8144 #endif /* CONFIG_MCC_MODE*/
8147 len = rtw_append_probe_resp_wfd_ie(padapter, pframe);
8149 pattrib->pktlen += len;
8152 #endif /* CONFIG_P2P */
8155 #ifdef CONFIG_AUTO_AP_MODE
8157 struct sta_info *psta;
8158 struct sta_priv *pstapriv = &padapter->stapriv;
8160 RTW_INFO("(%s)\n", __FUNCTION__);
8162 /* check rc station */
8163 psta = rtw_get_stainfo(pstapriv, da);
8164 if (psta && psta->isrc && psta->pid > 0) {
8165 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
8166 u8 RC_INFO[14] = {0};
8167 /* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
8168 u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8170 RTW_INFO("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8171 psta->pid, MAC_ARG(psta->hwaddr), cu_ch);
8173 /* append vendor specific ie */
8174 _rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8175 _rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8176 _rtw_memcpy(&RC_INFO[10], (u8 *)&psta->pid, 2);
8177 _rtw_memcpy(&RC_INFO[12], (u8 *)&cu_ch, 2);
8179 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8182 #endif /* CONFIG_AUTO_AP_MODE */
8185 pattrib->last_txcmdsz = pattrib->pktlen;
8188 dump_mgntframe(padapter, pmgntframe);
8194 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps, int wait_ack)
8197 struct xmit_frame *pmgntframe;
8198 struct pkt_attrib *pattrib;
8199 unsigned char *pframe;
8200 struct rtw_ieee80211_hdr *pwlanhdr;
8201 unsigned short *fctrl;
8203 unsigned char bssrate[NumRates];
8204 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8205 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8206 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8207 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8208 int bssrate_len = 0;
8209 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8211 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8214 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8215 if (pmgntframe == NULL)
8218 /* update attribute */
8219 pattrib = &pmgntframe->attrib;
8220 update_mgntframe_attrib(padapter, pattrib);
8223 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8225 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8226 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8228 mac = adapter_mac_addr(padapter);
8230 fctrl = &(pwlanhdr->frame_ctl);
8234 /* unicast probe request frame */
8235 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8236 _rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8238 /* broadcast probe request frame */
8239 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8240 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8243 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8245 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8246 pmlmeext->mgnt_seq++;
8247 set_frame_sub_type(pframe, WIFI_PROBEREQ);
8249 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8250 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8253 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
8255 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
8257 get_rate_set(padapter, bssrate, &bssrate_len);
8259 if (bssrate_len > 8) {
8260 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8261 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8263 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8266 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
8269 /* add wps_ie for wps2.0 */
8270 if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
8271 _rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
8272 pframe += pmlmepriv->wps_probe_req_ie_len;
8273 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
8274 /* pmlmepriv->wps_probe_req_ie_len = 0 ; */ /* reset to zero */
8277 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8278 pattrib->pktlen += rtw_build_vendor_ie(padapter , pframe , WIFI_PROBEREQ_VENDOR_IE_BIT);
8281 pattrib->last_txcmdsz = pattrib->pktlen;
8285 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8287 dump_mgntframe(padapter, pmgntframe);
8295 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
8297 _issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
8301 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
8302 * 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
8303 * try_cnt means the maximal TX count to try
8305 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, u8 ch, bool append_wps,
8306 int try_cnt, int wait_ms)
8310 u32 start = rtw_get_current_time();
8312 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8316 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms > 0 ? _TRUE : _FALSE);
8320 if (RTW_CANNOT_RUN(padapter))
8323 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
8324 rtw_msleep_os(wait_ms);
8326 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
8330 #ifndef DBG_XMIT_ACK
8335 if (try_cnt && wait_ms) {
8337 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8338 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8339 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
8341 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8342 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8343 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
8349 /* if psta == NULL, indiate we are station(client) now... */
8350 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
8352 struct xmit_frame *pmgntframe;
8353 struct pkt_attrib *pattrib;
8354 unsigned char *pframe;
8355 struct rtw_ieee80211_hdr *pwlanhdr;
8356 unsigned short *fctrl;
8358 unsigned short val16;
8359 int use_shared_key = 0;
8360 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8361 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8362 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8363 #ifdef CONFIG_RTW_80211R
8364 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8365 ft_priv *pftpriv = &pmlmepriv->ftpriv;
8366 u8 is_ft_roaming = _FALSE;
8367 u8 is_ft_roaming_with_rsn_ie = _TRUE;
8372 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8375 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8376 if (pmgntframe == NULL)
8379 /* update attribute */
8380 pattrib = &pmgntframe->attrib;
8381 update_mgntframe_attrib(padapter, pattrib);
8383 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8385 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8386 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8388 fctrl = &(pwlanhdr->frame_ctl);
8391 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8392 pmlmeext->mgnt_seq++;
8393 set_frame_sub_type(pframe, WIFI_AUTH);
8395 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8396 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8399 if (psta) { /* for AP mode */
8400 #ifdef CONFIG_NATIVEAP_MLME
8402 _rtw_memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
8403 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8404 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8407 /* setting auth algo number */
8408 val16 = (u16)psta->authalg;
8410 if (status != _STATS_SUCCESSFUL_)
8414 val16 = cpu_to_le16(val16);
8418 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8420 /* setting auth seq number */
8421 val16 = (u16)psta->auth_seq;
8422 val16 = cpu_to_le16(val16);
8423 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8425 /* setting status code... */
8427 val16 = cpu_to_le16(val16);
8428 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8430 /* added challenging text... */
8431 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
8432 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
8435 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8436 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8437 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8439 #ifdef CONFIG_RTW_80211R
8440 /*For Fast BSS Transition */
8441 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
8442 is_ft_roaming = _TRUE;
8443 val16 = 2; /* 2: 802.11R FTAA */
8444 val16 = cpu_to_le16(val16);
8448 /* setting auth algo number */
8449 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0; /* 0:OPEN System, 1:Shared key */
8451 val16 = cpu_to_le16(val16);
8456 /* RTW_INFO("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq); */
8458 /* setting IV for auth seq #3 */
8459 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
8460 /* RTW_INFO("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index); */
8461 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
8462 val32 = cpu_to_le32(val32);
8463 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
8465 pattrib->iv_len = 4;
8468 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8470 /* setting auth seq number */
8471 val16 = pmlmeinfo->auth_seq;
8472 val16 = cpu_to_le16(val16);
8473 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8476 /* setting status code... */
8478 val16 = cpu_to_le16(val16);
8479 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8481 #ifdef CONFIG_RTW_80211R
8482 if (is_ft_roaming == _TRUE) {
8483 pie = rtw_get_ie(pftpriv->updated_ft_ies, EID_WPA2, &ft_ie_len, pftpriv->updated_ft_ies_len);
8485 pframe = rtw_set_ie(pframe, EID_WPA2, ft_ie_len, pie+2, &(pattrib->pktlen));
8487 is_ft_roaming_with_rsn_ie = _FALSE;
8489 pie = rtw_get_ie(pftpriv->updated_ft_ies, _MDIE_, &ft_ie_len, pftpriv->updated_ft_ies_len);
8491 pframe = rtw_set_ie(pframe, _MDIE_, ft_ie_len , pie+2, &(pattrib->pktlen));
8493 pie = rtw_get_ie(pftpriv->updated_ft_ies, _FTIE_, &ft_ie_len, pftpriv->updated_ft_ies_len);
8494 if (pie && is_ft_roaming_with_rsn_ie)
8495 pframe = rtw_set_ie(pframe, _FTIE_, ft_ie_len , pie+2, &(pattrib->pktlen));
8499 /* then checking to see if sending challenging text... */
8500 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
8501 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
8505 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8507 pattrib->encrypt = _WEP40_;
8509 pattrib->icv_len = 4;
8511 pattrib->pktlen += pattrib->icv_len;
8517 pattrib->last_txcmdsz = pattrib->pktlen;
8519 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
8520 RTW_INFO("%s\n", __FUNCTION__);
8521 dump_mgntframe(padapter, pmgntframe);
8527 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
8529 #ifdef CONFIG_AP_MODE
8530 struct xmit_frame *pmgntframe;
8531 struct rtw_ieee80211_hdr *pwlanhdr;
8532 struct pkt_attrib *pattrib;
8533 unsigned char *pbuf, *pframe;
8534 unsigned short val, ie_status;
8535 unsigned short *fctrl;
8536 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8537 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8538 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8539 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8540 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
8541 u8 *ie = pnetwork->IEs;
8543 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8548 #endif /* CONFIG_P2P */
8550 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8553 RTW_INFO("%s\n", __FUNCTION__);
8555 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8556 if (pmgntframe == NULL)
8559 /* update attribute */
8560 pattrib = &pmgntframe->attrib;
8561 update_mgntframe_attrib(padapter, pattrib);
8564 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8566 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8567 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8569 fctrl = &(pwlanhdr->frame_ctl);
8572 _rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
8573 _rtw_memcpy((void *)get_addr2_ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
8574 _rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8577 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8578 pmlmeext->mgnt_seq++;
8579 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
8580 set_frame_sub_type(pwlanhdr, pkt_type);
8584 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8585 pattrib->pktlen += pattrib->hdrlen;
8586 pframe += pattrib->hdrlen;
8589 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
8591 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
8593 ie_status = cpu_to_le16(status);
8594 pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
8596 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
8597 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
8599 if (pstat->bssratelen <= 8)
8600 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
8602 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
8603 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen - 8), pstat->bssrateset + 8, &(pattrib->pktlen));
8606 #ifdef CONFIG_IEEE80211W
8607 if (status == _STATS_REFUSED_TEMPORARILY_) {
8609 u32 timeout_interval = 3000;
8610 /* Association Comeback time */
8611 timeout_itvl[0] = 0x03;
8612 timeout_interval = cpu_to_le32(timeout_interval);
8613 _rtw_memcpy(timeout_itvl + 1, &timeout_interval, 4);
8614 pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
8616 #endif /* CONFIG_IEEE80211W */
8618 #ifdef CONFIG_80211N_HT
8619 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
8622 /* FILL HT CAP INFO IE */
8623 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
8624 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8625 if (pbuf && ie_len > 0) {
8626 _rtw_memcpy(pframe, pbuf, ie_len + 2);
8627 pframe += (ie_len + 2);
8628 pattrib->pktlen += (ie_len + 2);
8631 /* FILL HT ADD INFO IE */
8632 /* p = hostapd_eid_ht_operation(hapd, p); */
8633 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8634 if (pbuf && ie_len > 0) {
8635 _rtw_memcpy(pframe, pbuf, ie_len + 2);
8636 pframe += (ie_len + 2);
8637 pattrib->pktlen += (ie_len + 2);
8643 /*adding EXT_CAPAB_IE */
8644 if (pmlmepriv->ext_capab_ie_len > 0) {
8647 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8648 if (pbuf && ie_len > 0) {
8649 _rtw_memcpy(pframe, pbuf, ie_len + 2);
8650 pframe += (ie_len + 2);
8651 pattrib->pktlen += (ie_len + 2);
8655 #ifdef CONFIG_80211AC_VHT
8656 if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
8657 && (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
8658 && (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP)) {
8661 /* FILL VHT CAP IE */
8662 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8663 if (pbuf && ie_len > 0) {
8664 _rtw_memcpy(pframe, pbuf, ie_len + 2);
8665 pframe += (ie_len + 2);
8666 pattrib->pktlen += (ie_len + 2);
8669 /* FILL VHT OPERATION IE */
8670 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8671 if (pbuf && ie_len > 0) {
8672 _rtw_memcpy(pframe, pbuf, ie_len + 2);
8673 pframe += (ie_len + 2);
8674 pattrib->pktlen += (ie_len + 2);
8677 #endif /* CONFIG_80211AC_VHT */
8680 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
8682 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
8684 for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
8685 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
8686 if (pbuf && _rtw_memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
8687 _rtw_memcpy(pframe, pbuf, ie_len + 2);
8688 pframe += (ie_len + 2);
8689 pattrib->pktlen += (ie_len + 2);
8694 if ((pbuf == NULL) || (ie_len == 0))
8701 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8702 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8704 /* add WPS IE ie for wps 2.0 */
8705 if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
8706 _rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8708 pframe += pmlmepriv->wps_assoc_resp_ie_len;
8709 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8713 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) {
8716 if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
8718 if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) {
8719 len = pmlmepriv->p2p_assoc_resp_ie_len;
8720 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len);
8723 len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8725 pattrib->pktlen += len;
8729 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
8730 wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe);
8732 pattrib->pktlen += wfdielen;
8736 #endif /* CONFIG_P2P */
8737 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8738 pattrib->pktlen += rtw_build_vendor_ie(padapter , pframe , WIFI_ASSOCRESP_VENDOR_IE_BIT);
8740 pattrib->last_txcmdsz = pattrib->pktlen;
8742 dump_mgntframe(padapter, pmgntframe);
8747 void _issue_assocreq(_adapter *padapter, u8 is_reassoc)
8750 struct xmit_frame *pmgntframe;
8751 struct pkt_attrib *pattrib;
8752 unsigned char *pframe, *p;
8753 struct rtw_ieee80211_hdr *pwlanhdr;
8754 unsigned short *fctrl;
8755 unsigned short val16;
8756 unsigned int i, j, ie_len, index = 0;
8757 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
8758 PNDIS_802_11_VARIABLE_IEs pIE;
8759 struct registry_priv *pregpriv = &padapter->registrypriv;
8760 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8761 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8762 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8763 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8764 int bssrate_len = 0, sta_bssrate_len = 0;
8765 u8 vs_ie_length = 0;
8767 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8768 u8 p2pie[255] = { 0x00 };
8773 #endif /* CONFIG_P2P */
8779 u8 pow_cap_ele[2] = { 0x00 };
8780 u8 sup_ch[30 * 2] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; /* For supported channel */
8781 #endif /* CONFIG_DFS */
8782 #ifdef CONFIG_RTW_80211R
8785 ft_priv *pftpriv = &pmlmepriv->ftpriv;
8788 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8791 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8792 if (pmgntframe == NULL)
8795 /* update attribute */
8796 pattrib = &pmgntframe->attrib;
8797 update_mgntframe_attrib(padapter, pattrib);
8800 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8802 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8803 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8805 fctrl = &(pwlanhdr->frame_ctl);
8807 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8808 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8809 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8811 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8812 pmlmeext->mgnt_seq++;
8813 if (is_reassoc == _TRUE)
8814 set_frame_sub_type(pframe, WIFI_REASSOCREQ);
8816 set_frame_sub_type(pframe, WIFI_ASSOCREQ);
8818 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8819 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8824 _rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8825 cap |= cap_SpecMgmt;
8826 _rtw_memcpy(pframe, &cap, 2);
8828 _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8829 #endif /* CONFIG_DFS */
8832 pattrib->pktlen += 2;
8834 /* listen interval */
8835 /* todo: listen interval for power saving */
8836 val16 = cpu_to_le16(3);
8837 _rtw_memcpy(pframe , (unsigned char *)&val16, 2);
8839 pattrib->pktlen += 2;
8841 /*Construct Current AP Field for Reassoc-Req only*/
8842 if (is_reassoc == _TRUE) {
8843 _rtw_memcpy(pframe, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8845 pattrib->pktlen += ETH_ALEN;
8849 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8853 if (pmlmeext->cur_channel > 14) {
8854 pow_cap_ele[0] = 13; /* Minimum transmit power capability */
8855 pow_cap_ele[1] = 21; /* Maximum transmit power capability */
8856 pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
8858 /* supported channels */
8860 if (pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14) {
8861 sup_ch[0] = 1; /* First channel number */
8862 sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; /* Number of channel */
8864 sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
8865 sup_ch[idx_5g++] = 1;
8868 } while (pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0);
8869 pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
8871 #endif /* CONFIG_DFS */
8873 /* supported rate & extended supported rate */
8875 #if 1 /* Check if the AP's supported rates are also supported by STA. */
8876 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
8877 /* RTW_INFO("sta_bssrate_len=%d\n", sta_bssrate_len); */
8879 if (pmlmeext->cur_channel == 14) /* for JAPAN, channel 14 can only uses B Mode(CCK) */
8880 sta_bssrate_len = 4;
8883 /* for (i = 0; i < sta_bssrate_len; i++) { */
8884 /* RTW_INFO("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
8887 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8888 if (pmlmeinfo->network.SupportedRates[i] == 0)
8890 RTW_INFO("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
8894 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
8895 if (pmlmeinfo->network.SupportedRates[i] == 0)
8899 /* Check if the AP's supported rates are also supported by STA. */
8900 for (j = 0; j < sta_bssrate_len; j++) {
8901 /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
8902 if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK)
8903 == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
8904 /* RTW_INFO("match i = %d, j=%d\n", i, j); */
8907 /* RTW_INFO("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */
8911 if (j == sta_bssrate_len) {
8912 /* the rate is not supported by STA */
8913 RTW_INFO("%s(): the rate[%d]=%02X is not supported by STA!\n", __FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
8915 /* the rate is supported by STA */
8916 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
8920 bssrate_len = index;
8921 RTW_INFO("bssrate_len = %d\n", bssrate_len);
8923 #else /* Check if the AP's supported rates are also supported by STA. */
8925 get_rate_set(padapter, bssrate, &bssrate_len);
8927 for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
8928 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0)
8931 if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
8934 bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
8937 #endif /* Check if the AP's supported rates are also supported by STA. */
8939 if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
8940 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
8941 rtw_free_xmitframe(pxmitpriv, pmgntframe);
8942 goto exit; /* don't connect to AP if no joint supported rate */
8946 if (bssrate_len > 8) {
8947 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8948 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8949 } else if (bssrate_len > 0)
8950 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8952 RTW_INFO("%s: Connect to AP without 11b and 11g data rate!\n", __FUNCTION__);
8954 /* vendor specific IE, such as WPA, WMM, WPS */
8955 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
8956 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
8958 switch (pIE->ElementID) {
8959 case _VENDOR_SPECIFIC_IE_:
8960 if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
8961 (_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
8962 (_rtw_memcmp(pIE->data, WPS_OUI, 4))) {
8963 vs_ie_length = pIE->Length;
8964 if ((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4))) {
8965 /* Commented by Kurt 20110629 */
8966 /* In some older APs, WPS handshake */
8967 /* would be fail if we append vender extensions informations to AP */
8972 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
8977 #ifdef CONFIG_RTW_80211R
8978 if ((is_reassoc == _TRUE) && (rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
8979 pie = rtw_get_ie(pftpriv->updated_ft_ies, EID_WPA2, &ft_ie_len, pftpriv->updated_ft_ies_len);
8981 pframe = rtw_set_ie(pframe, EID_WPA2, ft_ie_len, pie+2, &(pattrib->pktlen));
8984 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
8986 #ifdef CONFIG_80211N_HT
8987 case EID_HTCapability:
8988 if (padapter->mlmepriv.htpriv.ht_option == _TRUE) {
8989 if (!(is_ap_in_tkip(padapter))) {
8990 _rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
8992 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
8994 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
8999 case EID_EXTCapability:
9000 if (padapter->mlmepriv.htpriv.ht_option == _TRUE)
9001 pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
9003 #endif /* CONFIG_80211N_HT */
9004 #ifdef CONFIG_80211AC_VHT
9005 case EID_VHTCapability:
9006 if (padapter->mlmepriv.vhtpriv.vht_option == _TRUE)
9007 pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
9010 case EID_OpModeNotification:
9011 if (padapter->mlmepriv.vhtpriv.vht_option == _TRUE)
9012 pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
9014 #endif /* CONFIG_80211AC_VHT */
9019 i += (pIE->Length + 2);
9022 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
9023 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
9026 #ifdef CONFIG_WAPI_SUPPORT
9027 rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
9033 #ifdef CONFIG_IOCTL_CFG80211
9034 if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
9035 if (pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len > 0) {
9036 _rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
9037 pframe += pmlmepriv->p2p_assoc_req_ie_len;
9038 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
9041 #endif /* CONFIG_IOCTL_CFG80211 */
9043 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
9044 /* Should add the P2P IE in the association request frame. */
9048 p2pie[p2pielen++] = 0x50;
9049 p2pie[p2pielen++] = 0x6F;
9050 p2pie[p2pielen++] = 0x9A;
9051 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
9053 /* Commented by Albert 20101109 */
9054 /* According to the P2P Specification, the association request frame should contain 3 P2P attributes */
9055 /* 1. P2P Capability */
9056 /* 2. Extended Listen Timing */
9057 /* 3. Device Info */
9058 /* Commented by Albert 20110516 */
9059 /* 4. P2P Interface */
9061 /* P2P Capability */
9063 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
9066 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
9070 /* Device Capability Bitmap, 1 byte */
9071 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
9073 /* Group Capability Bitmap, 1 byte */
9074 if (pwdinfo->persistent_supported)
9075 p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
9077 p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
9079 /* Extended Listen Timing */
9081 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
9084 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
9088 /* Availability Period */
9089 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
9092 /* Availability Interval */
9093 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
9098 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
9101 /* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
9102 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
9103 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
9107 /* P2P Device Address */
9108 _rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
9109 p2pielen += ETH_ALEN;
9112 /* This field should be big endian. Noted by P2P specification. */
9113 if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
9114 (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
9115 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
9117 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC);
9121 /* Primary Device Type */
9123 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
9127 *(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
9130 /* Sub Category ID */
9131 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
9134 /* Number of Secondary Device Types */
9135 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
9139 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
9143 *(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
9147 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
9148 p2pielen += pwdinfo->device_name_len;
9152 p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
9155 *(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D);
9159 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Device Address */
9160 p2pielen += ETH_ALEN;
9162 p2pie[p2pielen++] = 1; /* P2P Interface Address Count */
9164 _rtw_memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Interface Address List */
9165 p2pielen += ETH_ALEN;
9167 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
9171 #endif /* CONFIG_P2P */
9174 wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe);
9176 pattrib->pktlen += wfdielen;
9178 #ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
9179 pattrib->pktlen += rtw_build_vendor_ie(padapter , pframe , WIFI_ASSOCREQ_VENDOR_IE_BIT);
9181 #ifdef CONFIG_RTW_80211R
9182 if (rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
9183 u8 mdieval[3] = {0};
9185 _rtw_memcpy(mdieval, &(pftpriv->mdid), 2);
9186 mdieval[2] = pftpriv->ft_cap;
9187 pframe = rtw_set_ie(pframe, _MDIE_, 3, mdieval, &(pattrib->pktlen));
9190 if (is_reassoc == _TRUE) {
9191 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
9192 u8 is_ft_roaming_with_rsn_ie = _TRUE;
9194 pie = rtw_get_ie(pftpriv->updated_ft_ies, EID_WPA2, &ft_ie_len, pftpriv->updated_ft_ies_len);
9196 is_ft_roaming_with_rsn_ie = _FALSE;
9198 pie = rtw_get_ie(pftpriv->updated_ft_ies, _FTIE_, &ft_ie_len, pftpriv->updated_ft_ies_len);
9199 if (pie && is_ft_roaming_with_rsn_ie)
9200 pframe = rtw_set_ie(pframe, _FTIE_, ft_ie_len , pie+2, &(pattrib->pktlen));
9205 pattrib->last_txcmdsz = pattrib->pktlen;
9206 dump_mgntframe(padapter, pmgntframe);
9211 if (ret == _SUCCESS)
9212 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
9214 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
9219 void issue_assocreq(_adapter *padapter)
9221 _issue_assocreq(padapter, _FALSE);
9224 void issue_reassocreq(_adapter *padapter)
9226 _issue_assocreq(padapter, _TRUE);
9229 /* when wait_ack is ture, this function shoule be called at process context */
9230 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
9233 struct xmit_frame *pmgntframe;
9234 struct pkt_attrib *pattrib;
9235 unsigned char *pframe;
9236 struct rtw_ieee80211_hdr *pwlanhdr;
9237 unsigned short *fctrl;
9238 struct xmit_priv *pxmitpriv;
9239 struct mlme_ext_priv *pmlmeext;
9240 struct mlme_ext_info *pmlmeinfo;
9242 /* RTW_INFO("%s:%d\n", __FUNCTION__, power_mode); */
9247 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9250 pxmitpriv = &(padapter->xmitpriv);
9251 pmlmeext = &(padapter->mlmeextpriv);
9252 pmlmeinfo = &(pmlmeext->mlmext_info);
9254 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9255 if (pmgntframe == NULL)
9258 /* update attribute */
9259 pattrib = &pmgntframe->attrib;
9260 update_mgntframe_attrib(padapter, pattrib);
9261 pattrib->retry_ctrl = _FALSE;
9263 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9265 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9266 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9268 fctrl = &(pwlanhdr->frame_ctl);
9271 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
9273 else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
9279 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9280 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9281 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9283 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9284 pmlmeext->mgnt_seq++;
9285 set_frame_sub_type(pframe, WIFI_DATA_NULL);
9287 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9288 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9290 pattrib->last_txcmdsz = pattrib->pktlen;
9293 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9295 dump_mgntframe(padapter, pmgntframe);
9304 * [IMPORTANT] Don't call this function in interrupt context
9306 * When wait_ms > 0, this function should be called at process context
9307 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9308 * 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
9309 * try_cnt means the maximal TX count to try
9310 * da == NULL for station mode
9312 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
9316 u32 start = rtw_get_current_time();
9317 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9318 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9319 struct sta_info *psta;
9320 u8 macid_sleep_reg_access = _TRUE;
9322 #ifdef CONFIG_MCC_MODE
9323 if (MCC_EN(padapter)) {
9324 /* driver doesn't access macid sleep reg under MCC */
9325 if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC)) {
9326 macid_sleep_reg_access = _FALSE;
9329 RTW_INFO("Warning: Do not tx null data to AP under MCC mode\n");
9337 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9340 /* da == NULL, assum it's null data for sta to ap*/
9342 da = get_my_bssid(&(pmlmeinfo->network));
9344 psta = rtw_get_stainfo(&padapter->stapriv, da);
9346 if (macid_sleep_reg_access) {
9348 rtw_hal_macid_sleep(padapter, psta->mac_id);
9350 rtw_hal_macid_wakeup(padapter, psta->mac_id);
9353 RTW_INFO(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n",
9354 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode ? "sleep" : "wakeup");
9359 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0 ? _TRUE : _FALSE);
9363 if (RTW_CANNOT_RUN(padapter))
9366 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9367 rtw_msleep_os(wait_ms);
9369 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9373 #ifndef DBG_XMIT_ACK
9378 if (try_cnt && wait_ms) {
9380 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9381 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9382 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9384 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9385 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9386 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9393 * [IMPORTANT] This function run in interrupt context
9395 * The null data packet would be sent without power bit,
9396 * and not guarantee success.
9398 s32 issue_nulldata_in_interrupt(PADAPTER padapter, u8 *da, unsigned int power_mode)
9401 struct mlme_ext_priv *pmlmeext;
9402 struct mlme_ext_info *pmlmeinfo;
9405 pmlmeext = &padapter->mlmeextpriv;
9406 pmlmeinfo = &pmlmeext->mlmext_info;
9408 /* da == NULL, assum it's null data for sta to ap*/
9410 da = get_my_bssid(&(pmlmeinfo->network));
9412 ret = _issue_nulldata(padapter, da, power_mode, _FALSE);
9417 /* when wait_ack is ture, this function shoule be called at process context */
9418 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
9421 struct xmit_frame *pmgntframe;
9422 struct pkt_attrib *pattrib;
9423 unsigned char *pframe;
9424 struct rtw_ieee80211_hdr *pwlanhdr;
9425 unsigned short *fctrl, *qc;
9426 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9427 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9428 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9430 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9433 RTW_INFO("%s\n", __FUNCTION__);
9435 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9436 if (pmgntframe == NULL)
9439 /* update attribute */
9440 pattrib = &pmgntframe->attrib;
9441 update_mgntframe_attrib(padapter, pattrib);
9443 pattrib->hdrlen += 2;
9444 pattrib->qos_en = _TRUE;
9446 pattrib->ack_policy = 0;
9449 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9451 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9452 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9454 fctrl = &(pwlanhdr->frame_ctl);
9457 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)
9459 else if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
9465 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
9467 SetPriority(qc, tid);
9469 SetEOSP(qc, pattrib->eosp);
9471 SetAckpolicy(qc, pattrib->ack_policy);
9473 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9474 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9475 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9477 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9478 pmlmeext->mgnt_seq++;
9479 set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
9481 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9482 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
9484 pattrib->last_txcmdsz = pattrib->pktlen;
9487 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9489 dump_mgntframe(padapter, pmgntframe);
9498 * when wait_ms >0 , this function should be called at process context
9499 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9500 * 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
9501 * try_cnt means the maximal TX count to try
9502 * da == NULL for station mode
9504 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
9508 u32 start = rtw_get_current_time();
9509 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9510 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9512 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9515 /* da == NULL, assum it's null data for sta to ap*/
9517 da = get_my_bssid(&(pmlmeinfo->network));
9520 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0 ? _TRUE : _FALSE);
9524 if (RTW_CANNOT_RUN(padapter))
9527 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9528 rtw_msleep_os(wait_ms);
9530 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9534 #ifndef DBG_XMIT_ACK
9539 if (try_cnt && wait_ms) {
9541 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9542 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9543 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9545 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9546 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9547 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9553 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
9555 struct xmit_frame *pmgntframe;
9556 struct pkt_attrib *pattrib;
9557 unsigned char *pframe;
9558 struct rtw_ieee80211_hdr *pwlanhdr;
9559 unsigned short *fctrl;
9560 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9561 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9562 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9565 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
9566 #endif /* CONFIG_P2P */
9568 /* RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
9571 if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
9572 _cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
9573 _set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
9575 #endif /* CONFIG_P2P */
9577 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9580 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9581 if (pmgntframe == NULL)
9584 /* update attribute */
9585 pattrib = &pmgntframe->attrib;
9586 update_mgntframe_attrib(padapter, pattrib);
9587 pattrib->retry_ctrl = _FALSE;
9588 pattrib->key_type = key_type;
9589 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9591 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9592 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9594 fctrl = &(pwlanhdr->frame_ctl);
9597 _rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9598 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9599 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9601 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9602 pmlmeext->mgnt_seq++;
9603 set_frame_sub_type(pframe, WIFI_DEAUTH);
9605 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9606 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9608 reason = cpu_to_le16(reason);
9609 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
9611 pattrib->last_txcmdsz = pattrib->pktlen;
9615 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9617 dump_mgntframe(padapter, pmgntframe);
9625 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
9627 RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9628 return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
9631 #ifdef CONFIG_IEEE80211W
9632 int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
9634 RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9635 return _issue_deauth(padapter, da, reason, _FALSE, key_type);
9637 #endif /* CONFIG_IEEE80211W */
9640 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9641 * 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
9642 * try_cnt means the maximal TX count to try
9644 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
9649 u32 start = rtw_get_current_time();
9651 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9655 ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE : _FALSE, IEEE80211W_RIGHT_KEY);
9659 if (RTW_CANNOT_RUN(padapter))
9662 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9663 rtw_msleep_os(wait_ms);
9665 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9669 #ifndef DBG_XMIT_ACK
9674 if (try_cnt && wait_ms) {
9676 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9677 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9678 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9680 RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9681 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9682 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9688 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9691 _list *plist, *phead;
9692 struct xmit_frame *pmgntframe;
9693 struct pkt_attrib *pattrib;
9694 unsigned char *pframe;
9695 struct rtw_ieee80211_hdr *pwlanhdr;
9696 unsigned short *fctrl;
9697 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9698 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9699 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9700 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9702 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9705 RTW_INFO(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9706 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9708 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9709 if (pmgntframe == NULL)
9712 /* update attribute */
9713 pattrib = &pmgntframe->attrib;
9714 update_mgntframe_attrib(padapter, pattrib);
9716 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9718 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9719 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9721 fctrl = &(pwlanhdr->frame_ctl);
9724 _rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9725 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9726 _rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9728 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9729 pmlmeext->mgnt_seq++;
9730 set_frame_sub_type(pframe, WIFI_ACTION);
9732 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9733 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9735 /* category, action */
9737 u8 category, action;
9738 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9739 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9741 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9742 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9745 pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9746 pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9747 hal_ch_offset_to_secondary_ch_offset(ch_offset));
9749 pattrib->last_txcmdsz = pattrib->pktlen;
9751 dump_mgntframe(padapter, pmgntframe);
9755 #ifdef CONFIG_IEEE80211W
9756 void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
9758 u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
9760 struct xmit_frame *pmgntframe;
9761 struct pkt_attrib *pattrib;
9763 struct rtw_ieee80211_hdr *pwlanhdr;
9765 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9766 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9767 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9768 struct sta_info *psta;
9769 struct sta_priv *pstapriv = &padapter->stapriv;
9770 struct registry_priv *pregpriv = &padapter->registrypriv;
9771 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9773 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9776 RTW_INFO("%s, %04x\n", __FUNCTION__, tid);
9778 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9779 if (pmgntframe == NULL) {
9780 RTW_INFO("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9784 /* update attribute */
9785 pattrib = &pmgntframe->attrib;
9786 update_mgntframe_attrib(padapter, pattrib);
9787 pattrib->key_type = key_type;
9788 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9790 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9791 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9793 fctrl = &(pwlanhdr->frame_ctl);
9797 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9799 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9800 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9801 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9803 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9804 pmlmeext->mgnt_seq++;
9805 set_frame_sub_type(pframe, WIFI_ACTION);
9807 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9808 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9810 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9811 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9814 case 0: /* SA Query req */
9815 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9816 pmlmeext->sa_query_seq++;
9817 /* send sa query request to AP, AP should reply sa query response in 1 second */
9818 if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
9819 psta = rtw_get_stainfo(pstapriv, raddr);
9821 /* RTW_INFO("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
9822 _set_timer(&psta->dot11w_expire_timer, 1000);
9827 case 1: /* SA Query rsp */
9828 tid = cpu_to_le16(tid);
9829 /* RTW_INFO("rtw_set_fixed_ie, %04x\n", tid); */
9830 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9836 pattrib->last_txcmdsz = pattrib->pktlen;
9838 dump_mgntframe(padapter, pmgntframe);
9840 #endif /* CONFIG_IEEE80211W */
9843 * issue_action_ba - internal function to TX Block Ack action frame
9844 * @padapter: the adapter to TX
9845 * @raddr: receiver address
9846 * @action: Block Ack Action
9848 * @size: the announced AMPDU buffer size. used by ADDBA_RESP
9849 * @status: status/reason code. used by ADDBA_RESP, DELBA
9850 * @initiator: if we are the initiator of AMPDU association. used by DELBA
9851 * @wait_ack: used xmit ack
9854 * _SUCCESS: No xmit ack is used or acked
9855 * _FAIL: not acked when using xmit ack
9857 static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9858 , u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9861 u8 category = RTW_WLAN_CATEGORY_BACK;
9864 u16 BA_timeout_value;
9865 u16 BA_starting_seqctrl;
9866 struct xmit_frame *pmgntframe;
9867 struct pkt_attrib *pattrib;
9869 struct rtw_ieee80211_hdr *pwlanhdr;
9871 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9872 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9873 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9874 struct sta_info *psta;
9875 struct sta_priv *pstapriv = &padapter->stapriv;
9876 struct registry_priv *pregpriv = &padapter->registrypriv;
9878 #ifdef CONFIG_80211N_HT
9880 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9883 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9884 if (pmgntframe == NULL)
9887 /* update attribute */
9888 pattrib = &pmgntframe->attrib;
9889 update_mgntframe_attrib(padapter, pattrib);
9891 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9893 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9894 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9896 fctrl = &(pwlanhdr->frame_ctl);
9899 /* _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
9900 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9901 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9902 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9904 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9905 pmlmeext->mgnt_seq++;
9906 set_frame_sub_type(pframe, WIFI_ACTION);
9908 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9909 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9911 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9912 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9914 if (category == 3) {
9916 case RTW_WLAN_ACTION_ADDBA_REQ:
9918 pmlmeinfo->dialogToken++;
9919 } while (pmlmeinfo->dialogToken == 0);
9920 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
9922 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
9923 BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
9925 BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
9928 BA_para_set = cpu_to_le16(BA_para_set);
9929 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9931 /* BA_timeout_value = 0xffff; */ /* max: 65535 TUs(~ 65 ms) */
9932 BA_timeout_value = 5000;/* ~ 5ms */
9933 BA_timeout_value = cpu_to_le16(BA_timeout_value);
9934 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
9936 /* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */
9937 psta = rtw_get_stainfo(pstapriv, raddr);
9939 start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07] & 0xfff) + 1;
9941 RTW_INFO("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
9943 psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
9945 BA_starting_seqctrl = start_seq << 4;
9948 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
9949 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
9952 case RTW_WLAN_ACTION_ADDBA_RESP:
9953 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
9954 status = cpu_to_le16(status);
9955 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
9957 BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
9959 BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
9960 BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
9962 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9963 BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
9965 if (!padapter->registrypriv.wifi_spec) {
9966 if (pregpriv->ampdu_amsdu == 0) /* disabled */
9967 BA_para_set &= ~BIT(0);
9968 else if (pregpriv->ampdu_amsdu == 1) /* enabled */
9969 BA_para_set |= BIT(0);
9972 BA_para_set = cpu_to_le16(BA_para_set);
9974 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9975 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
9978 case RTW_WLAN_ACTION_DELBA:
9980 BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
9981 BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
9983 BA_para_set = cpu_to_le16(BA_para_set);
9984 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
9985 status = cpu_to_le16(status);
9986 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
9993 pattrib->last_txcmdsz = pattrib->pktlen;
9996 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9998 dump_mgntframe(padapter, pmgntframe);
10003 #endif /* CONFIG_80211N_HT */
10008 * issue_addba_req - TX ADDBA_REQ
10009 * @adapter: the adapter to TX
10010 * @ra: receiver address
10013 inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
10015 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
10022 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
10023 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
10028 * issue_addba_rsp - TX ADDBA_RESP
10029 * @adapter: the adapter to TX
10030 * @ra: receiver address
10032 * @status: status code
10033 * @size: the announced AMPDU buffer size
10035 inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
10037 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10044 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
10045 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
10049 * issue_addba_rsp_wait_ack - TX ADDBA_RESP and wait ack
10050 * @adapter: the adapter to TX
10051 * @ra: receiver address
10053 * @status: status code
10054 * @size: the announced AMPDU buffer size
10055 * @try_cnt: the maximal TX count to try
10056 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10057 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10059 inline u8 issue_addba_rsp_wait_ack(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size, int try_cnt, int wait_ms)
10063 u32 start = rtw_get_current_time();
10065 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(adapter)))
10069 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10079 if (RTW_CANNOT_RUN(adapter))
10082 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10083 rtw_msleep_os(wait_ms);
10085 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10087 if (ret != _FAIL) {
10089 #ifndef DBG_XMIT_ACK
10094 if (try_cnt && wait_ms) {
10095 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" status:=%u tid=%u size:%u%s, %d/%d in %u ms\n"
10096 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size
10097 , ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10105 * issue_del_ba - TX DELBA
10106 * @adapter: the adapter to TX
10107 * @ra: receiver address
10109 * @reason: reason code
10110 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10112 inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
10114 issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10121 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
10122 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
10126 * issue_del_ba_ex - TX DELBA with xmit ack options
10127 * @adapter: the adapter to TX
10128 * @ra: receiver address
10130 * @reason: reason code
10131 * @initiator: if we are the initiator of AMPDU association. used by DELBA
10132 * @try_cnt: the maximal TX count to try
10133 * @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10134 * > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10136 int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
10137 , int try_cnt, int wait_ms)
10141 u32 start = rtw_get_current_time();
10143 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(adapter)))
10147 ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10152 , wait_ms > 0 ? _TRUE : _FALSE
10157 if (RTW_CANNOT_RUN(adapter))
10160 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10161 rtw_msleep_os(wait_ms);
10163 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10165 if (ret != _FAIL) {
10167 #ifndef DBG_XMIT_ACK
10172 if (try_cnt && wait_ms) {
10173 RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
10174 , FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
10175 , ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10181 static void issue_action_BSSCoexistPacket(_adapter *padapter)
10184 _list *plist, *phead;
10185 unsigned char category, action;
10186 struct xmit_frame *pmgntframe;
10187 struct pkt_attrib *pattrib;
10188 unsigned char *pframe;
10189 struct rtw_ieee80211_hdr *pwlanhdr;
10190 unsigned short *fctrl;
10191 struct wlan_network *pnetwork = NULL;
10192 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10193 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10194 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10195 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10196 _queue *queue = &(pmlmepriv->scanned_queue);
10197 u8 InfoContent[16] = {0};
10199 #ifdef CONFIG_80211N_HT
10200 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
10203 if (_TRUE == pmlmeinfo->bwmode_updated)
10206 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10209 RTW_INFO("%s\n", __FUNCTION__);
10212 category = RTW_WLAN_CATEGORY_PUBLIC;
10213 action = ACT_PUBLIC_BSSCOEXIST;
10215 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10216 if (pmgntframe == NULL)
10219 /* update attribute */
10220 pattrib = &pmgntframe->attrib;
10221 update_mgntframe_attrib(padapter, pattrib);
10223 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10225 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10226 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10228 fctrl = &(pwlanhdr->frame_ctl);
10231 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10232 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10233 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10235 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10236 pmlmeext->mgnt_seq++;
10237 set_frame_sub_type(pframe, WIFI_ACTION);
10239 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10240 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10242 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10243 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10247 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
10250 iedata |= BIT(2);/* 20 MHz BSS Width Request */
10252 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
10258 _rtw_memset(ICS, 0, sizeof(ICS));
10259 if (pmlmepriv->num_sta_no_ht > 0) {
10262 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10264 phead = get_list_head(queue);
10265 plist = get_next(phead);
10270 WLAN_BSSID_EX *pbss_network;
10272 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
10275 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
10277 plist = get_next(plist);
10279 pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
10281 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
10282 if ((p == NULL) || (len == 0)) { /* non-HT */
10283 if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
10286 ICS[0][pbss_network->Configuration.DSConfig] = 1;
10288 if (ICS[0][0] == 0)
10294 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10297 for (i = 0; i < 8; i++) {
10298 if (ICS[i][0] == 1) {
10301 InfoContent[k] = i;
10302 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); */
10305 for (j = 1; j <= 14; j++) {
10306 if (ICS[i][j] == 1) {
10308 InfoContent[k] = j; /* channel number */
10309 /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
10315 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
10325 pattrib->last_txcmdsz = pattrib->pktlen;
10327 dump_mgntframe(padapter, pmgntframe);
10328 #endif /* CONFIG_80211N_HT */
10331 /* Spatial Multiplexing Powersave (SMPS) action frame */
10332 int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack)
10336 unsigned char category = RTW_WLAN_CATEGORY_HT;
10337 u8 action = RTW_WLAN_ACTION_HT_SM_PS;
10338 u8 sm_power_control = 0;
10339 struct xmit_frame *pmgntframe;
10340 struct pkt_attrib *pattrib;
10341 unsigned char *pframe;
10342 struct rtw_ieee80211_hdr *pwlanhdr;
10343 unsigned short *fctrl;
10344 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10345 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10346 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10349 if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_DISABLED) {
10350 sm_power_control = sm_power_control & ~(BIT(0)); /* SM Power Save Enable = 0 SM Power Save Disable */
10351 } else if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_STATIC) {
10352 sm_power_control = sm_power_control | BIT(0); /* SM Power Save Enable = 1 SM Power Save Enable */
10353 sm_power_control = sm_power_control & ~(BIT(1)); /* SM Mode = 0 Static Mode */
10354 } else if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_DYNAMIC) {
10355 sm_power_control = sm_power_control | BIT(0); /* SM Power Save Enable = 1 SM Power Save Enable */
10356 sm_power_control = sm_power_control | BIT(1); /* SM Mode = 1 Dynamic Mode */
10360 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10363 RTW_INFO("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode);
10365 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10366 if (pmgntframe == NULL)
10369 /* update attribute */
10370 pattrib = &pmgntframe->attrib;
10371 update_mgntframe_attrib(padapter, pattrib);
10373 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10375 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10376 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10378 fctrl = &(pwlanhdr->frame_ctl);
10381 _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
10382 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10383 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
10385 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10386 pmlmeext->mgnt_seq++;
10387 set_frame_sub_type(pframe, WIFI_ACTION);
10389 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10390 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10392 /* category, action */
10393 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10394 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10396 pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
10398 pattrib->last_txcmdsz = pattrib->pktlen;
10401 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10403 dump_mgntframe(padapter, pmgntframe);
10407 if (ret != _SUCCESS)
10408 RTW_INFO("%s, ack to\n", __func__);
10414 * wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10415 * 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
10416 * try_cnt means the maximal TX count to try
10418 int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
10422 u32 start = rtw_get_current_time();
10424 if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10428 ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms > 0 ? _TRUE : _FALSE);
10432 if (RTW_CANNOT_RUN(padapter))
10435 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10436 rtw_msleep_os(wait_ms);
10438 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10440 if (ret != _FAIL) {
10442 #ifndef DBG_XMIT_ACK
10447 if (try_cnt && wait_ms) {
10449 RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
10450 FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
10451 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10453 RTW_INFO(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
10454 FUNC_ADPT_ARG(padapter),
10455 ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10462 int issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode)
10464 RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
10465 return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE);
10469 * _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
10470 * @adapter: the adapter to which @sta belongs
10471 * @initiator: if we are the initiator of AMPDU association
10472 * @sta: the sta to be checked
10473 * @tid: the tid to be checked
10474 * @force: cancel and send DELBA even when no AMPDU association is setup
10475 * @wait_ack: send delba with xmit ack (valid when initiator == 0)
10478 * _FAIL if sta is NULL
10479 * when initiator is 1, always _SUCCESS
10480 * when initiator is 0, _SUCCESS if DELBA is acked
10482 static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10483 , u8 force, int wait_ack)
10485 int ret = _SUCCESS;
10492 if (initiator == 0) {
10494 if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
10495 u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
10497 sta->recvreorder_ctrl[tid].enable = _FALSE;
10498 sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
10500 if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
10503 ret = issue_del_ba_ex(adapter, sta->hwaddr, tid, 37, initiator, 3, 1);
10505 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10507 if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
10508 sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
10510 } else if (initiator == 1) {
10512 #ifdef CONFIG_80211N_HT
10513 if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
10514 sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
10515 sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
10516 issue_del_ba(adapter, sta->hwaddr, tid, 37, initiator);
10525 inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10528 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
10531 inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10534 return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
10537 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
10539 struct sta_priv *pstapriv = &padapter->stapriv;
10540 struct sta_info *psta = NULL;
10541 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10542 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10545 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
10546 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
10549 psta = rtw_get_stainfo(pstapriv, addr);
10554 RTW_INFO("%s:%s\n", __func__, (initiator == 0) ? "RX_DIR" : "TX_DIR");
10555 if (initiator == 1) /* originator */
10556 RTW_INFO("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
10559 for (tid = 0; tid < TID_NUM; tid++)
10560 send_delba_sta_tid(padapter, initiator, psta, tid, 0);
10565 unsigned int send_beacon(_adapter *padapter)
10567 u8 bxmitok = _FALSE;
10570 #if defined(CONFIG_PCI_HCI) && defined(RTL8814AE_SW_BCN)
10571 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10574 #ifdef CONFIG_PCI_HCI
10575 /* RTW_INFO("%s\n", __FUNCTION__); */
10577 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10579 /* 8192EE Port select for Beacon DL */
10580 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10582 issue_beacon(padapter, 0);
10584 #ifdef RTL8814AE_SW_BCN
10585 if (pHalData->bCorrectBCN != 0)
10586 RTW_INFO("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__);
10587 pHalData->bCorrectBCN = 1;
10593 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
10594 u32 start = rtw_get_current_time();
10596 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10597 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10599 issue_beacon(padapter, 100);
10603 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
10605 } while ((poll % 10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
10607 } while (_FALSE == bxmitok && issue < 100 && !RTW_CANNOT_RUN(padapter));
10609 if (RTW_CANNOT_RUN(padapter))
10613 if (_FALSE == bxmitok) {
10614 RTW_INFO("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
10617 u32 passing_time = rtw_get_passing_time_ms(start);
10619 if (passing_time > 100 || issue > 3)
10620 RTW_INFO("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10622 RTW_INFO("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10624 rtw_hal_fw_correct_bcn(padapter);
10633 /****************************************************************************
10635 Following are some utitity fuctions for WiFi MLME
10637 *****************************************************************************/
10639 BOOLEAN IsLegal5GChannel(
10640 IN PADAPTER Adapter,
10645 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
10646 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
10647 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
10650 for (i = 0; i < sizeof(Channel_5G); i++)
10651 if (channel == Channel_5G[i])
10656 /* collect bss info from Beacon and Probe request/response frames. */
10657 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10662 u16 val16, subtype;
10663 u8 *pframe = precv_frame->u.hdr.rx_data;
10664 u32 packet_len = precv_frame->u.hdr.len;
10666 struct registry_priv *pregistrypriv = &padapter->registrypriv;
10667 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10668 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10670 len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10672 if (len > MAX_IE_SZ) {
10673 /* RTW_INFO("IE too long for survey event\n"); */
10677 _rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10679 subtype = get_frame_sub_type(pframe);
10681 if (subtype == WIFI_BEACON) {
10682 bssid->Reserved[0] = 1;
10683 ie_offset = _BEACON_IE_OFFSET_;
10685 /* FIXME : more type */
10686 if (subtype == WIFI_PROBERSP) {
10687 ie_offset = _PROBERSP_IE_OFFSET_;
10688 bssid->Reserved[0] = 3;
10689 } else if (subtype == WIFI_PROBEREQ) {
10690 ie_offset = _PROBEREQ_IE_OFFSET_;
10691 bssid->Reserved[0] = 2;
10693 bssid->Reserved[0] = 0;
10694 ie_offset = _FIXED_IE_LENGTH_;
10698 bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10700 /* below is to copy the information element */
10701 bssid->IELength = len;
10702 _rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10704 /* get the signal strength */
10705 /* bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; */ /* 0-100 index. */
10706 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; /* in dBM.raw data */
10707 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;/* in percentage */
10708 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;/* in percentage */
10709 #ifdef CONFIG_ANTENNA_DIVERSITY
10710 rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &(bssid->PhyInfo.Optimum_antenna), NULL);
10713 /* checking SSID */
10714 p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset);
10716 RTW_INFO("marc: cannot find SSID for survey event\n");
10721 if (len > NDIS_802_11_LENGTH_SSID) {
10722 RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10725 _rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10726 bssid->Ssid.SsidLength = *(p + 1);
10728 bssid->Ssid.SsidLength = 0;
10730 _rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10732 /* checking rate info... */
10734 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10736 if (len > NDIS_802_11_LENGTH_RATES_EX) {
10737 RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10740 _rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10744 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10746 if (len > (NDIS_802_11_LENGTH_RATES_EX - i)) {
10747 RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10750 _rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10755 if (judge_network_type(bssid->SupportedRates, (len + i)) == WIRELESS_11B)
10756 bssid->NetworkTypeInUse = Ndis802_11DS;
10760 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
10764 if (subtype == WIFI_PROBEREQ) {
10767 /* Set Listion Channel */
10768 p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen);
10770 u32 attr_contentlen = 0;
10771 u8 listen_ch[5] = { 0x00 };
10773 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
10774 bssid->Configuration.DSConfig = listen_ch[4];
10776 /* use current channel */
10777 bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10778 RTW_INFO("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10782 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10783 _rtw_memcpy(bssid->MacAddress, get_addr2_ptr(pframe), ETH_ALEN);
10784 bssid->Privacy = 1;
10787 #endif /* CONFIG_P2P */
10789 if (bssid->IELength < 12)
10792 /* Checking for DSConfig */
10793 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10795 bssid->Configuration.DSConfig = 0;
10796 bssid->Configuration.Length = 0;
10799 bssid->Configuration.DSConfig = *(p + 2);
10801 /* In 5G, some ap do not have DSSET IE */
10802 /* checking HT info for channel */
10803 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
10805 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
10806 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)) {
10819 bssid->InfrastructureMode = Ndis802_11Infrastructure;
10820 _rtw_memcpy(bssid->MacAddress, get_addr2_ptr(pframe), ETH_ALEN);
10822 bssid->InfrastructureMode = Ndis802_11IBSS;
10823 _rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
10826 if (val16 & BIT(4))
10827 bssid->Privacy = 1;
10829 bssid->Privacy = 0;
10831 bssid->Configuration.ATIMWindow = 0;
10833 /* 20/40 BSS Coexistence check */
10834 if ((pregistrypriv->wifi_spec == 1) && (_FALSE == pmlmeinfo->bwmode_updated)) {
10835 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10836 #ifdef CONFIG_80211N_HT
10837 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
10838 if (p && len > 0) {
10839 struct HT_caps_element *pHT_caps;
10840 pHT_caps = (struct HT_caps_element *)(p + 2);
10842 if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
10843 pmlmepriv->num_FortyMHzIntolerant++;
10845 pmlmepriv->num_sta_no_ht++;
10846 #endif /* CONFIG_80211N_HT */
10850 #ifdef CONFIG_INTEL_WIDI
10851 /* process_intel_widi_query_or_tigger(padapter, bssid); */
10852 if (process_intel_widi_query_or_tigger(padapter, bssid))
10854 #endif /* CONFIG_INTEL_WIDI */
10856 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
10857 if (strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
10858 RTW_INFO("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
10859 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
10860 , rtw_get_oper_ch(padapter)
10861 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
10866 /* mark bss info receving from nearby channel as SignalQuality 101 */
10867 if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
10868 bssid->PhyInfo.SignalQuality = 101;
10873 void start_create_ibss(_adapter *padapter)
10875 unsigned short caps;
10878 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10879 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10880 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
10882 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
10883 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
10885 /* update wireless mode */
10886 update_wireless_mode(padapter);
10888 /* udpate capability */
10889 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10890 update_capinfo(padapter, caps);
10891 if (caps & cap_IBSS) { /* adhoc master */
10892 /* set_opmode_cmd(padapter, adhoc); */ /* removed */
10895 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10898 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10900 /* switch channel */
10901 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
10904 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
10906 beacon_timing_control(padapter);
10908 /* set msr to WIFI_FW_ADHOC_STATE */
10909 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
10910 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
10913 if (send_beacon(padapter) == _FAIL) {
10915 report_join_res(padapter, -1);
10916 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10918 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
10920 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10922 report_join_res(padapter, 1);
10923 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
10924 rtw_indicate_connect(padapter);
10927 RTW_INFO("start_create_ibss, invalid cap:%x\n", caps);
10930 /* update bc/mc sta_info */
10931 update_bmc_sta(padapter);
10935 void start_clnt_join(_adapter *padapter)
10937 unsigned short caps;
10939 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10940 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10941 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
10942 int beacon_timeout;
10943 u8 ASIX_ID[] = {0x00, 0x0E, 0xC6};
10945 /* update wireless mode */
10946 update_wireless_mode(padapter);
10948 /* udpate capability */
10949 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
10950 update_capinfo(padapter, caps);
10952 /* check if sta is ASIX peer and fix IOT issue if it is. */
10953 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) , ASIX_ID , 3)) {
10954 u8 iot_flag = _TRUE;
10955 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
10958 if (caps & cap_ESS) {
10959 Set_MSR(padapter, WIFI_FW_STATION_STATE);
10961 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
10963 #ifdef CONFIG_WAPI_SUPPORT
10964 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) {
10965 /* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
10969 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
10971 #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
10972 /* Because of AP's not receiving deauth before */
10973 /* AP may: 1)not response auth or 2)deauth us after link is complete */
10974 /* issue deauth before issuing auth to deal with the situation */
10976 /* Commented by Albert 2012/07/21 */
10977 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
10980 _queue *queue = &(padapter->mlmepriv.scanned_queue);
10981 _list *head = get_list_head(queue);
10982 _list *pos = get_next(head);
10983 struct wlan_network *scanned = NULL;
10986 bool has_p2p_ie = _FALSE;
10988 _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
10990 for (pos = get_next(head); !rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
10992 scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
10994 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
10995 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
10997 ie_offset = (scanned->network.Reserved[0] == 2 ? 0 : 12);
10998 if (rtw_get_p2p_ie(scanned->network.IEs + ie_offset, scanned->network.IELength - ie_offset, NULL, NULL))
10999 has_p2p_ie = _TRUE;
11004 _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11006 if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
11007 #endif /* CONFIG_P2P */
11008 /* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
11009 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
11011 #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
11013 /* here wait for receiving the beacon to start auth */
11014 /* and enable a timer */
11015 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
11016 set_link_timer(pmlmeext, beacon_timeout);
11017 _set_timer(&padapter->mlmepriv.assoc_timer,
11018 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout);
11020 #ifdef CONFIG_RTW_80211R
11021 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
11022 if (rtw_chk_ft_flags(padapter, RTW_FT_OVER_DS_SUPPORTED)) {
11023 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11024 ft_priv *pftpriv = &pmlmepriv->ftpriv;
11026 pmlmeinfo->state = WIFI_FW_AUTH_SUCCESS | WIFI_FW_STATION_STATE;
11027 pftpriv->ft_event.ies = pftpriv->ft_action + sizeof(struct rtw_ieee80211_hdr_3addr) + 16;
11028 pftpriv->ft_event.ies_len = pftpriv->ft_action_len - sizeof(struct rtw_ieee80211_hdr_3addr);
11030 /*Not support RIC*/
11031 pftpriv->ft_event.ric_ies = NULL;
11032 pftpriv->ft_event.ric_ies_len = 0;
11033 report_ft_event(padapter);
11035 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11036 start_clnt_auth(padapter);
11041 rtw_sta_linking_test_set_start();
11042 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11044 } else if (caps & cap_IBSS) { /* adhoc client */
11045 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11048 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11050 beacon_timing_control(padapter);
11052 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11054 report_join_res(padapter, 1);
11056 /* RTW_INFO("marc: invalid cap:%x\n", caps); */
11062 void start_clnt_auth(_adapter *padapter)
11064 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11065 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11067 _cancel_timer_ex(&pmlmeext->link_timer);
11069 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
11070 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
11072 pmlmeinfo->auth_seq = 1;
11073 pmlmeinfo->reauth_count = 0;
11074 pmlmeinfo->reassoc_count = 0;
11075 pmlmeinfo->link_count = 0;
11076 pmlmeext->retry = 0;
11078 #ifdef CONFIG_RTW_80211R
11079 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
11080 rtw_set_ft_status(padapter, RTW_FT_AUTHENTICATING_STA);
11081 RTW_PRINT("start ft auth\n");
11084 RTW_PRINT("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 #ifdef CONFIG_RTW_80211R
11103 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED))
11104 issue_reassocreq(padapter);
11107 issue_assocreq(padapter);
11109 set_link_timer(pmlmeext, REASSOC_TO);
11112 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, u8 locally_generated)
11114 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11115 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11117 if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
11120 RTW_INFO("%s\n", __FUNCTION__);
11122 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
11123 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
11124 if (report_del_sta_event(padapter, MacAddr, reason, _TRUE, locally_generated) != _FAIL)
11125 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11126 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
11127 if (report_join_res(padapter, -2) != _FAIL)
11128 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11130 RTW_INFO(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
11131 #ifdef CONFIG_RTW_80211R
11132 if ((rtw_to_roam(padapter) > 0) && !rtw_chk_ft_status(padapter, RTW_FT_REQUESTED_STA))
11133 rtw_reset_ft_status(padapter);
11140 #ifdef CONFIG_80211D
11141 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
11143 struct registry_priv *pregistrypriv;
11144 struct mlme_ext_priv *pmlmeext;
11145 RT_CHANNEL_INFO *chplan_new;
11150 pregistrypriv = &padapter->registrypriv;
11151 pmlmeext = &padapter->mlmeextpriv;
11153 /* Adjust channel plan by AP Country IE */
11154 if (pregistrypriv->enable80211d
11155 && (!pmlmeext->update_channel_plan_by_ap_done)) {
11158 RT_CHANNEL_PLAN chplan_ap;
11159 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
11161 u8 fcn; /* first channel number */
11162 u8 noc; /* number of channel */
11165 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
11175 _rtw_memset(country, 0, 4);
11176 _rtw_memcpy(country, p, 3);
11178 RTW_INFO("%s: 802.11d country=%s\n", __FUNCTION__, country);
11181 while ((ie - p) >= 3) {
11186 for (j = 0; j < noc; j++) {
11188 channel = fcn + j; /* 2.4 GHz */
11190 channel = fcn + j * 4; /* 5 GHz */
11192 chplan_ap.Channel[i++] = channel;
11197 #ifdef CONFIG_RTW_DEBUG
11199 RTW_INFO("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
11200 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) {
11201 _RTW_INFO("%02d,", chplan_ap.Channel[i]);
11207 _rtw_memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
11208 #ifdef CONFIG_RTW_DEBUG
11210 RTW_INFO("%s: STA channel plan {", __FUNCTION__);
11211 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
11212 _RTW_INFO("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType == SCAN_PASSIVE ? 'p' : 'a');
11218 _rtw_memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
11219 chplan_new = pmlmeext->channel_set;
11222 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
11224 if ((i == MAX_CHANNEL_NUM)
11225 || (chplan_sta[i].ChannelNum == 0)
11226 || (chplan_sta[i].ChannelNum > 14))
11229 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
11232 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;
11238 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
11239 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11241 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]) {
11248 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11249 chplan_new[k].ScanType = SCAN_ACTIVE;
11255 /* change AP not support channel to Passive scan */
11256 while ((i < MAX_CHANNEL_NUM)
11257 && (chplan_sta[i].ChannelNum != 0)
11258 && (chplan_sta[i].ChannelNum <= 14)) {
11259 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11261 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11263 chplan_new[k].ScanType = SCAN_PASSIVE;
11269 /* add channel AP supported */
11270 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;
11277 /* keep original STA 2.4G channel plan */
11278 while ((i < MAX_CHANNEL_NUM)
11279 && (chplan_sta[i].ChannelNum != 0)
11280 && (chplan_sta[i].ChannelNum <= 14)) {
11281 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11282 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11287 /* skip AP 2.4G channel plan */
11288 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11292 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
11294 if ((i >= MAX_CHANNEL_NUM)
11295 || (chplan_sta[i].ChannelNum == 0))
11298 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
11301 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
11302 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11303 chplan_new[k].ScanType = SCAN_ACTIVE;
11307 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
11308 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11310 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11312 chplan_new[k].ScanType = SCAN_PASSIVE;
11316 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
11317 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11318 chplan_new[k].ScanType = SCAN_ACTIVE;
11324 /* change AP not support channel to Passive scan */
11325 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
11326 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11328 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11330 chplan_new[k].ScanType = SCAN_PASSIVE;
11336 /* add channel AP supported */
11337 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
11338 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11339 chplan_new[k].ScanType = SCAN_ACTIVE;
11344 /* keep original STA 5G channel plan */
11345 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
11346 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11347 chplan_new[k].ScanType = chplan_sta[i].ScanType;
11353 pmlmeext->update_channel_plan_by_ap_done = 1;
11355 #ifdef CONFIG_RTW_DEBUG
11357 RTW_INFO("%s: new STA channel plan {", __FUNCTION__);
11358 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
11359 _RTW_INFO("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType == SCAN_PASSIVE ? 'p' : 'c');
11366 /* recover the right channel index */
11367 channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11369 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
11370 if (chplan_new[k].ChannelNum == channel) {
11371 RTW_INFO("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11372 __FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k);
11373 pmlmeext->sitesurvey_res.channel_idx = k;
11381 /* If channel is used by AP, set channel scan type to active */
11382 channel = bssid->Configuration.DSConfig;
11383 chplan_new = pmlmeext->channel_set;
11385 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
11386 if (chplan_new[i].ChannelNum == channel) {
11387 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
11388 /* 5G Bnad 2, 3 (DFS) doesn't change to active scan */
11389 if (channel >= 52 && channel <= 144)
11392 chplan_new[i].ScanType = SCAN_ACTIVE;
11393 RTW_INFO("%s: change channel %d scan type from passive to active\n",
11394 __FUNCTION__, channel);
11403 /****************************************************************************
11405 Following are the functions to report events
11407 *****************************************************************************/
11409 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11411 struct cmd_obj *pcmd_obj;
11414 struct survey_event *psurvey_evt;
11415 struct C2HEvent_Header *pc2h_evt_hdr;
11416 struct mlme_ext_priv *pmlmeext;
11417 struct cmd_priv *pcmdpriv;
11418 /* u8 *pframe = precv_frame->u.hdr.rx_data; */
11419 /* uint len = precv_frame->u.hdr.len; */
11424 pmlmeext = &padapter->mlmeextpriv;
11425 pcmdpriv = &padapter->cmdpriv;
11428 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11429 if (pcmd_obj == NULL)
11432 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11433 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11434 if (pevtcmd == NULL) {
11435 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11439 _rtw_init_listhead(&pcmd_obj->list);
11441 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11442 pcmd_obj->cmdsz = cmdsz;
11443 pcmd_obj->parmbuf = pevtcmd;
11445 pcmd_obj->rsp = NULL;
11446 pcmd_obj->rspsz = 0;
11448 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11449 pc2h_evt_hdr->len = sizeof(struct survey_event);
11450 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11451 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11453 psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11455 if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) {
11456 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11457 rtw_mfree((u8 *)pevtcmd, cmdsz);
11461 #ifdef CONFIG_80211D
11462 process_80211d(padapter, &psurvey_evt->bss);
11465 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11467 pmlmeext->sitesurvey_res.bss_cnt++;
11473 void report_surveydone_event(_adapter *padapter)
11475 struct cmd_obj *pcmd_obj;
11478 struct surveydone_event *psurveydone_evt;
11479 struct C2HEvent_Header *pc2h_evt_hdr;
11480 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11481 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11483 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11484 if (pcmd_obj == NULL)
11487 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11488 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11489 if (pevtcmd == NULL) {
11490 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11494 _rtw_init_listhead(&pcmd_obj->list);
11496 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11497 pcmd_obj->cmdsz = cmdsz;
11498 pcmd_obj->parmbuf = pevtcmd;
11500 pcmd_obj->rsp = NULL;
11501 pcmd_obj->rspsz = 0;
11503 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11504 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11505 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11506 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11508 psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11509 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11511 RTW_INFO("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11513 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11519 u32 report_join_res(_adapter *padapter, int res)
11521 struct cmd_obj *pcmd_obj;
11524 struct joinbss_event *pjoinbss_evt;
11525 struct C2HEvent_Header *pc2h_evt_hdr;
11526 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11527 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11528 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11531 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11532 if (pcmd_obj == NULL)
11535 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11536 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11537 if (pevtcmd == NULL) {
11538 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11542 _rtw_init_listhead(&pcmd_obj->list);
11544 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11545 pcmd_obj->cmdsz = cmdsz;
11546 pcmd_obj->parmbuf = pevtcmd;
11548 pcmd_obj->rsp = NULL;
11549 pcmd_obj->rspsz = 0;
11551 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11552 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11553 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11554 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11556 pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11557 _rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11558 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
11560 RTW_INFO("report_join_res(%d)\n", res);
11563 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
11566 ret = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11572 void report_wmm_edca_update(_adapter *padapter)
11574 struct cmd_obj *pcmd_obj;
11577 struct wmm_event *pwmm_event;
11578 struct C2HEvent_Header *pc2h_evt_hdr;
11579 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11580 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11581 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11583 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11584 if (pcmd_obj == NULL)
11587 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11588 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11589 if (pevtcmd == NULL) {
11590 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11594 _rtw_init_listhead(&pcmd_obj->list);
11596 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11597 pcmd_obj->cmdsz = cmdsz;
11598 pcmd_obj->parmbuf = pevtcmd;
11600 pcmd_obj->rsp = NULL;
11601 pcmd_obj->rspsz = 0;
11603 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11604 pc2h_evt_hdr->len = sizeof(struct wmm_event);
11605 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11606 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11608 pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11609 pwmm_event->wmm = 0;
11611 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11617 u32 report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue, u8 locally_generated)
11619 struct cmd_obj *pcmd_obj;
11622 struct sta_info *psta;
11624 struct stadel_event *pdel_sta_evt;
11625 struct C2HEvent_Header *pc2h_evt_hdr;
11626 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11627 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11630 /* prepare cmd parameter */
11631 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11632 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11633 if (pevtcmd == NULL) {
11638 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11639 pc2h_evt_hdr->len = sizeof(struct stadel_event);
11640 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11641 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11643 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11644 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11645 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
11646 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11648 mac_id = (int)psta->mac_id;
11651 pdel_sta_evt->mac_id = mac_id;
11652 pdel_sta_evt->locally_generated = locally_generated;
11656 rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
11657 rtw_mfree(pevtcmd, cmdsz);
11659 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11660 if (pcmd_obj == NULL) {
11661 rtw_mfree(pevtcmd, cmdsz);
11666 _rtw_init_listhead(&pcmd_obj->list);
11667 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11668 pcmd_obj->cmdsz = cmdsz;
11669 pcmd_obj->parmbuf = pevtcmd;
11671 pcmd_obj->rsp = NULL;
11672 pcmd_obj->rspsz = 0;
11674 res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11679 RTW_INFO(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
11680 , FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
11685 void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr)
11687 struct cmd_obj *pcmd_obj;
11690 struct stassoc_event *padd_sta_evt;
11691 struct C2HEvent_Header *pc2h_evt_hdr;
11692 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11693 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11695 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11696 if (pcmd_obj == NULL)
11699 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11700 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11701 if (pevtcmd == NULL) {
11702 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11706 _rtw_init_listhead(&pcmd_obj->list);
11708 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11709 pcmd_obj->cmdsz = cmdsz;
11710 pcmd_obj->parmbuf = pevtcmd;
11712 pcmd_obj->rsp = NULL;
11713 pcmd_obj->rspsz = 0;
11715 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11716 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11717 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11718 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11720 padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11721 _rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11723 RTW_INFO("report_add_sta_event: add STA\n");
11725 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11731 bool rtw_port_switch_chk(_adapter *adapter)
11733 bool switch_needed = _FALSE;
11734 #ifdef CONFIG_CONCURRENT_MODE
11735 #ifdef CONFIG_RUNTIME_PORT_SWITCH
11736 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11737 struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11738 _adapter *if_port0 = NULL;
11739 _adapter *if_port1 = NULL;
11740 struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11741 struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11744 for (i = 0; i < dvobj->iface_nums; i++) {
11745 if (get_hw_port(dvobj->padapters[i]) == HW_PORT0) {
11746 if_port0 = dvobj->padapters[i];
11747 if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
11748 } else if (get_hw_port(dvobj->padapters[i]) == HW_PORT1) {
11749 if_port1 = dvobj->padapters[i];
11750 if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
11754 if (if_port0 == NULL) {
11759 if (if_port1 == NULL) {
11764 #ifdef DBG_RUNTIME_PORT_SWITCH
11765 RTW_INFO(FUNC_ADPT_FMT" wowlan_mode:%u\n"
11766 ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
11767 ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
11768 FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
11769 ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
11770 ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
11771 #endif /* DBG_RUNTIME_PORT_SWITCH */
11773 #ifdef CONFIG_WOWLAN
11774 /* WOWLAN interface(primary, for now) should be port0 */
11775 if (pwrctl->wowlan_mode == _TRUE) {
11776 if (!is_primary_adapter(if_port0)) {
11777 RTW_INFO("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
11778 switch_needed = _TRUE;
11782 #endif /* CONFIG_WOWLAN */
11784 /* AP should use port0 for ctl frame's ack */
11785 if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
11786 RTW_INFO("%s "ADPT_FMT" is AP/GO\n", __func__, ADPT_ARG(if_port1));
11787 switch_needed = _TRUE;
11791 /* GC should use port0 for p2p ps */
11792 if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
11793 && (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11795 && !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
11797 && !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
11799 RTW_INFO("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
11800 switch_needed = _TRUE;
11804 /* port1 linked, but port0 not linked */
11805 if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11806 && !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
11807 && ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
11809 RTW_INFO("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
11810 switch_needed = _TRUE;
11815 #ifdef DBG_RUNTIME_PORT_SWITCH
11816 RTW_INFO(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
11817 #endif /* DBG_RUNTIME_PORT_SWITCH */
11818 #endif /* CONFIG_RUNTIME_PORT_SWITCH */
11819 #endif /* CONFIG_CONCURRENT_MODE */
11820 return switch_needed;
11823 /****************************************************************************
11825 Following are the event callback functions
11827 *****************************************************************************/
11829 /* for sta/adhoc mode */
11830 void update_sta_info(_adapter *padapter, struct sta_info *psta)
11833 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11834 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11835 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11838 VCS_update(padapter, psta);
11840 #ifdef CONFIG_80211N_HT
11842 if (pmlmepriv->htpriv.ht_option) {
11843 psta->htpriv.ht_option = _TRUE;
11845 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
11847 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
11849 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
11850 psta->htpriv.sgi_20m = _TRUE;
11852 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
11853 psta->htpriv.sgi_40m = _TRUE;
11855 psta->qos_option = _TRUE;
11857 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
11858 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
11859 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
11861 _rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
11863 #endif /* CONFIG_80211N_HT */
11865 #ifdef CONFIG_80211N_HT
11866 psta->htpriv.ht_option = _FALSE;
11867 psta->htpriv.ampdu_enable = _FALSE;
11868 psta->htpriv.tx_amsdu_enable = _FALSE;
11869 psta->htpriv.sgi_20m = _FALSE;
11870 psta->htpriv.sgi_40m = _FALSE;
11871 #endif /* CONFIG_80211N_HT */
11872 psta->qos_option = _FALSE;
11876 #ifdef CONFIG_80211N_HT
11877 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
11879 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
11880 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
11881 #endif /* CONFIG_80211N_HT */
11883 psta->bw_mode = pmlmeext->cur_bwmode;
11886 if (pmlmepriv->qospriv.qos_option)
11887 psta->qos_option = _TRUE;
11889 #ifdef CONFIG_80211AC_VHT
11890 _rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
11891 #endif /* CONFIG_80211AC_VHT */
11893 update_ldpc_stbc_cap(psta);
11895 _enter_critical_bh(&psta->lock, &irqL);
11896 psta->state = _FW_LINKED;
11897 _exit_critical_bh(&psta->lock, &irqL);
11901 static void rtw_mlmeext_disconnect(_adapter *padapter)
11903 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11904 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11905 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11906 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
11907 u8 state_backup = (pmlmeinfo->state & 0x03);
11908 u8 ASIX_ID[] = {0x00, 0x0E, 0xC6};
11910 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
11912 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
11913 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
11915 /* set MSR to no link state->infra. mode */
11916 Set_MSR(padapter, _HW_STATE_STATION_);
11918 /* check if sta is ASIX peer and fix IOT issue if it is. */
11919 if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) , ASIX_ID , 3)) {
11920 u8 iot_flag = _FALSE;
11921 rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11923 pmlmeinfo->state = WIFI_FW_NULL_STATE;
11925 #ifdef CONFIG_MCC_MODE
11926 /* mcc disconnect setting before download LPS rsvd page */
11927 rtw_hal_set_mcc_setting_disconnect(padapter);
11928 #endif /* CONFIG_MCC_MODE */
11930 if (state_backup == WIFI_FW_STATION_STATE) {
11931 if (rtw_port_switch_chk(padapter) == _TRUE) {
11932 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
11935 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
11937 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
11943 /* switch to the 20M Hz mode after disconnect */
11944 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
11945 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11947 #ifdef CONFIG_FCS_MODE
11948 if (EN_FCS(padapter))
11949 rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
11952 #ifdef CONFIG_DFS_MASTER
11953 if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
11954 rtw_dfs_master_status_apply(padapter, MLME_AP_STOPPED);
11955 else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
11956 rtw_dfs_master_status_apply(padapter, MLME_STA_DISCONNECTED);
11962 if (rtw_mi_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0) {
11963 set_channel_bwmode(padapter, ch, offset, bw);
11964 rtw_mi_update_union_chan_inf(padapter, ch, offset, bw);
11968 flush_all_cam_entry(padapter);
11970 _cancel_timer_ex(&pmlmeext->link_timer);
11972 /* pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE; */
11973 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
11974 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
11977 padapter->tdlsinfo.ap_prohibited = _FALSE;
11979 /* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
11980 if (padapter->registrypriv.wifi_spec == 1)
11981 padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
11982 #endif /* CONFIG_TDLS */
11986 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
11988 struct sta_info *psta, *psta_bmc;
11989 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11990 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11991 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
11992 struct sta_priv *pstapriv = &padapter->stapriv;
11994 #ifdef CONFIG_ARP_KEEP_ALIVE
11995 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11997 struct security_priv *psecuritypriv = &padapter->securitypriv;
11999 if (join_res < 0) {
12001 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12002 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12004 goto exit_mlmeext_joinbss_event_callback;
12006 #ifdef CONFIG_ARP_KEEP_ALIVE
12007 pmlmepriv->bGetGateway = 1;
12008 pmlmepriv->GetGatewayTryCnt = 0;
12011 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
12012 /* update bc/mc sta_info */
12013 update_bmc_sta(padapter);
12017 /* turn on dynamic functions */
12018 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
12020 /* update IOT-releated issue */
12021 update_IOT_info(padapter);
12023 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
12026 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
12028 /* udpate capability */
12029 update_capinfo(padapter, pmlmeinfo->capability);
12031 /* WMM, Update EDCA param */
12032 WMMOnAssocRsp(padapter);
12035 HTOnAssocRsp(padapter);
12037 #ifdef CONFIG_80211AC_VHT
12039 VHTOnAssocRsp(padapter);
12042 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
12043 if (psta) { /* only for infra. mode */
12044 /* RTW_INFO("set_sta_rate\n"); */
12046 psta->wireless_mode = pmlmeext->cur_wireless_mode;
12048 #ifdef CONFIG_FW_MULTI_PORT_SUPPORT
12049 rtw_hal_set_default_port_id_cmd(padapter, psta->mac_id);
12052 /* set per sta rate after updating HT cap. */
12053 set_sta_rate(padapter, psta);
12055 rtw_sta_media_status_rpt(padapter, psta, 1);
12057 /* wakeup macid after join bss successfully to ensure
12058 the subsequent data frames can be sent out normally */
12059 rtw_hal_macid_wakeup(padapter, psta->mac_id);
12062 #ifndef CONFIG_IOCTL_CFG80211
12063 if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
12064 rtw_sec_restore_wep_key(padapter);
12065 #endif /* CONFIG_IOCTL_CFG80211 */
12067 if (rtw_port_switch_chk(padapter) == _TRUE)
12068 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12071 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12073 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
12074 /* correcting TSF */
12075 correct_TSF(padapter, pmlmeext);
12077 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
12081 #ifndef CONFIG_FW_MULTI_PORT_SUPPORT
12082 if (get_hw_port(padapter) == HW_PORT0)
12084 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
12087 #ifdef CONFIG_BEAMFORMING
12089 beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
12090 #endif/*CONFIG_BEAMFORMING*/
12092 exit_mlmeext_joinbss_event_callback:
12094 rtw_join_done_chk_ch(padapter, join_res);
12096 RTW_INFO("=>%s - End to Connection without 4-way\n", __FUNCTION__);
12099 /* currently only adhoc mode will go here */
12100 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
12102 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12103 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12106 RTW_INFO("%s\n", __FUNCTION__);
12108 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
12109 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */
12110 /* nothing to do */
12111 } else { /* adhoc client */
12112 /* update TSF Value */
12113 /* update_TSF(pmlmeext, pframe, len); */
12115 /* correcting TSF */
12116 correct_TSF(padapter, pmlmeext);
12119 if (send_beacon(padapter) == _FAIL)
12122 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
12126 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12129 /* update adhoc sta_info */
12130 update_sta_info(padapter, psta);
12132 rtw_hal_update_sta_rate_mask(padapter, psta);
12134 /* ToDo: HT for Ad-hoc */
12135 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
12136 psta->raid = rtw_hal_networktype_to_raid(padapter, psta);
12138 /* rate radaptive */
12139 Update_RA_Entry(padapter, psta);
12142 void mlmeext_sta_del_event_callback(_adapter *padapter)
12144 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12145 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12147 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
12148 rtw_mlmeext_disconnect(padapter);
12152 /****************************************************************************
12154 Following are the functions for the timer handlers
12156 *****************************************************************************/
12157 void _linked_info_dump(_adapter *padapter)
12160 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12161 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12162 HAL_DATA_TYPE *HalData = GET_HAL_DATA(padapter);
12163 int undecorated_smoothed_pwdb = 0;
12165 if (padapter->bLinkInfoDump) {
12167 RTW_INFO("\n============["ADPT_FMT"] linked status check ===================\n", ADPT_ARG(padapter));
12169 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
12170 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &undecorated_smoothed_pwdb);
12172 RTW_INFO("AP[" MAC_FMT "] - undecorated_smoothed_pwdb:%d\n",
12173 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress), undecorated_smoothed_pwdb);
12174 } else if ((pmlmeinfo->state & 0x03) == _HW_STATE_AP_) {
12176 _list *phead, *plist;
12178 struct sta_info *psta = NULL;
12179 struct sta_priv *pstapriv = &padapter->stapriv;
12181 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12182 phead = &pstapriv->asoc_list;
12183 plist = get_next(phead);
12184 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12185 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
12186 plist = get_next(plist);
12188 RTW_INFO("STA[" MAC_FMT "]:undecorated_smoothed_pwdb:%d\n",
12189 MAC_ARG(psta->hwaddr), psta->rssi_stat.undecorated_smoothed_pwdb);
12191 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
12195 /*============ tx info ============ */
12196 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, RTW_DBGDUMP);
12198 rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, RTW_DBGDUMP, _FALSE);
12204 /********************************************************************
12206 When station does not receive any packet in MAX_CONTINUAL_NORXPACKET_COUNT*2 seconds,
12207 recipient station will teardown the block ack by issuing DELBA frame.
12209 *********************************************************************/
12210 void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
12213 int ret = _SUCCESS;
12214 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12215 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12218 IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
12219 AP is originator.AP does not transmit unicast packets when STA response its BAR.
12220 This case probably occur ap issue BAR after AP builds BA.
12222 Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
12223 The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
12225 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
12226 for (i = 0; i < TID_NUM ; i++) {
12227 if ((psta->recvreorder_ctrl[i].enable) &&
12228 (sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) ) {
12229 if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
12230 /* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */
12232 ret = issue_del_ba_ex(padapter, psta->hwaddr, i, 39, 0, 3, 1);
12234 issue_del_ba(padapter, psta->hwaddr, i, 39, 0);
12235 psta->recvreorder_ctrl[i].enable = _FALSE;
12237 psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
12238 rtw_reset_continual_no_rx_packet(psta, i);
12241 /* The inactivity timer is reset when MPDUs to the TID is received. */
12242 rtw_reset_continual_no_rx_packet(psta, i);
12248 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
12252 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12253 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12255 #ifdef DBG_EXPIRATION_CHK
12256 RTW_INFO(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12257 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12259 , FUNC_ADPT_ARG(padapter)
12260 , STA_RX_PKTS_DIFF_ARG(psta)
12261 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12262 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12263 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12264 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12265 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12266 , pmlmeinfo->bcn_interval*/
12270 RTW_INFO(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
12271 , padapter->xmitpriv.tx_pkts
12272 , pmlmeinfo->link_count
12276 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
12277 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12278 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
12284 sta_update_last_rx_pkts(psta);
12287 record last rx data packets for every tid.
12289 for (i = 0; i < TID_NUM; i++)
12290 psta->sta_stats.last_rx_data_qos_pkts[i] = psta->sta_stats.rx_data_qos_pkts[i];
12295 u8 chk_adhoc_peer_is_alive(struct sta_info *psta)
12299 #ifdef DBG_EXPIRATION_CHK
12300 RTW_INFO("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12301 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12303 , MAC_ARG(psta->hwaddr)
12304 , psta->rssi_stat.undecorated_smoothed_pwdb
12305 , STA_RX_PKTS_DIFF_ARG(psta)
12306 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12307 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12308 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12309 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12310 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12311 , pmlmeinfo->bcn_interval*/
12316 if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)
12317 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12318 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
12321 sta_update_last_rx_pkts(psta);
12327 u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
12329 if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
12330 && (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
12336 void linked_status_chk_tdls(_adapter *padapter)
12338 struct candidate_pool {
12339 struct sta_info *psta;
12342 struct sta_priv *pstapriv = &padapter->stapriv;
12345 struct sta_info *psta;
12346 int i, num_teardown = 0, num_checkalive = 0;
12347 _list *plist, *phead;
12348 struct tdls_txmgmt txmgmt;
12349 struct candidate_pool checkalive[MAX_ALLOWED_TDLS_STA_NUM];
12350 struct candidate_pool teardown[MAX_ALLOWED_TDLS_STA_NUM];
12351 u8 tdls_sta_max = _FALSE;
12353 #define ALIVE_MIN 2
12354 #define ALIVE_MAX 5
12356 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12357 _rtw_memset(checkalive, 0x00, sizeof(checkalive));
12358 _rtw_memset(teardown, 0x00, sizeof(teardown));
12360 if ((padapter->tdlsinfo.link_established == _TRUE)) {
12361 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12362 for (i = 0; i < NUM_STA; i++) {
12363 phead = &(pstapriv->sta_hash[i]);
12364 plist = get_next(phead);
12366 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12367 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12368 plist = get_next(plist);
12370 if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
12371 psta->alive_count++;
12372 if (psta->alive_count >= ALIVE_MIN) {
12373 if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
12374 if (psta->alive_count < ALIVE_MAX) {
12375 _rtw_memcpy(checkalive[num_checkalive].addr, psta->hwaddr, ETH_ALEN);
12376 checkalive[num_checkalive].psta = psta;
12379 _rtw_memcpy(teardown[num_teardown].addr, psta->hwaddr, ETH_ALEN);
12380 teardown[num_teardown].psta = psta;
12384 psta->alive_count = 0;
12386 psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12387 psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
12389 if ((num_checkalive >= MAX_ALLOWED_TDLS_STA_NUM) || (num_teardown >= MAX_ALLOWED_TDLS_STA_NUM)) {
12390 tdls_sta_max = _TRUE;
12396 if (tdls_sta_max == _TRUE)
12399 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12401 if (num_checkalive > 0) {
12402 for (i = 0; i < num_checkalive; i++) {
12403 _rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12404 issue_tdls_dis_req(padapter, &txmgmt);
12405 issue_tdls_dis_req(padapter, &txmgmt);
12406 issue_tdls_dis_req(padapter, &txmgmt);
12410 if (num_teardown > 0) {
12411 for (i = 0; i < num_teardown; i++) {
12412 RTW_INFO("[%s %d] Send teardown to "MAC_FMT"\n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12413 txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12414 _rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12415 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12421 #endif /* CONFIG_TDLS */
12423 /* from_timer == 1 means driver is in LPS */
12424 void linked_status_chk(_adapter *padapter, u8 from_timer)
12427 struct sta_info *psta;
12428 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12429 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12430 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12431 struct sta_priv *pstapriv = &padapter->stapriv;
12432 #if defined(CONFIG_ARP_KEEP_ALIVE) || defined(CONFIG_LAYER2_ROAMING)
12433 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12435 #ifdef CONFIG_LAYER2_ROAMING
12436 struct recv_priv *precvpriv = &padapter->recvpriv;
12439 if (padapter->registrypriv.mp_mode == _TRUE)
12442 if (is_client_associated_to_ap(padapter)) {
12443 /* linked infrastructure client mode */
12445 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12447 int link_count_limit;
12449 #ifdef CONFIG_LAYER2_ROAMING
12450 if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
12451 RTW_INFO("signal_strength_data.avg_val = %d\n", precvpriv->signal_strength_data.avg_val);
12452 if (precvpriv->signal_strength_data.avg_val < pmlmepriv->roam_rssi_threshold) {
12453 pmlmepriv->need_to_roam = _TRUE;
12454 rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM);
12456 pmlmepriv->need_to_roam = _FALSE;
12460 #ifdef CONFIG_MCC_MODE
12462 * due to tx ps null date to ao, so ap doest not tx pkt to driver
12463 * we may check chk_ap_is_alive fail, and may issue_probereq to wrong channel under sitesurvey
12464 * don't keep alive check under MCC
12466 if (rtw_hal_mcc_link_status_chk(padapter, __func__) == _FALSE)
12470 #if defined(DBG_ROAMING_TEST)
12472 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12477 #ifdef CONFIG_ARP_KEEP_ALIVE
12478 if (!from_timer && pmlmepriv->bGetGateway == 1 && pmlmepriv->GetGatewayTryCnt < 3) {
12479 RTW_INFO("do rtw_gw_addr_query() : %d\n", pmlmepriv->GetGatewayTryCnt);
12480 pmlmepriv->GetGatewayTryCnt++;
12481 if (rtw_gw_addr_query(padapter) == 0)
12482 pmlmepriv->bGetGateway = 0;
12484 _rtw_memset(pmlmepriv->gw_ip, 0, 4);
12485 _rtw_memset(pmlmepriv->gw_mac_addr, 0, 6);
12490 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
12492 link_count_limit = 3; /* 8 sec */
12494 link_count_limit = 15; /* 32 sec */
12496 #endif /* CONFIG_P2P */
12499 link_count_limit = 7; /* 16 sec */
12501 link_count_limit = 29; /* 60 sec */
12505 #ifdef CONFIG_TDLS_CH_SW
12506 if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12508 #endif /* CONFIG_TDLS_CH_SW */
12510 #ifdef CONFIG_TDLS_AUTOCHECKALIVE
12511 linked_status_chk_tdls(padapter);
12512 #endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12513 #endif /* CONFIG_TDLS */
12515 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12516 if (psta != NULL) {
12517 bool is_p2p_enable = _FALSE;
12519 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12522 #ifdef CONFIG_ISSUE_DELBA_WHEN_NO_TRAFFIC
12523 /*issue delba when ap does not tx data packet that is Broadcom ap */
12524 rtw_delba_check(padapter, psta, from_timer);
12526 if (chk_ap_is_alive(padapter, psta) == _FALSE)
12529 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
12532 #if defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK) && !defined(CONFIG_LPS_LCLK_WD_TIMER)
12533 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)
12534 #ifdef CONFIG_MCC_MODE
12535 /* Driver don't know operation channel under MCC*/
12536 /* So driver don't do KEEP_ALIVE_CHECK */
12537 && (!rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC))
12540 u8 backup_ch = 0, backup_bw, backup_offset;
12541 u8 union_ch = 0, union_bw, union_offset;
12543 if (!rtw_mi_get_ch_setting_union(padapter, &union_ch, &union_bw, &union_offset)
12544 || pmlmeext->cur_channel != union_ch)
12545 goto bypass_active_keep_alive;
12547 /* switch to correct channel of current network before issue keep-alive frames */
12548 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12549 backup_ch = rtw_get_oper_ch(padapter);
12550 backup_bw = rtw_get_oper_bw(padapter);
12551 backup_offset = rtw_get_oper_choffset(padapter);
12552 set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
12555 if (rx_chk != _SUCCESS)
12556 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 0, 0, 3, 1);
12558 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12559 tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
12560 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12561 if (tx_chk == _SUCCESS && !is_p2p_enable)
12565 /* back to the original operation channel */
12567 set_channel_bwmode(padapter, backup_ch, backup_offset, backup_bw);
12569 bypass_active_keep_alive:
12572 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12574 if (rx_chk != _SUCCESS) {
12575 if (pmlmeext->retry == 0) {
12576 #ifdef DBG_EXPIRATION_CHK
12577 RTW_INFO("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12579 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12580 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12581 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0);
12585 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit
12586 #ifdef CONFIG_MCC_MODE
12587 /* FW tx nulldata under MCC mode, we just check ap is alive */
12588 && (!rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC))
12589 #endif /* CONFIG_MCC_MODE */
12591 #ifdef DBG_EXPIRATION_CHK
12592 RTW_INFO("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer ? 1 : 0);
12594 tx_chk = issue_nulldata_in_interrupt(padapter, NULL, from_timer ? 1 : 0);
12598 if (rx_chk == _FAIL) {
12600 if (pmlmeext->retry > rx_chk_limit) {
12601 RTW_PRINT(FUNC_ADPT_FMT" disconnect or roaming\n",
12602 FUNC_ADPT_ARG(padapter));
12603 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12604 , WLAN_REASON_EXPIRATION_CHK, _FALSE);
12608 pmlmeext->retry = 0;
12610 if (tx_chk == _FAIL)
12611 pmlmeinfo->link_count %= (link_count_limit + 1);
12613 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
12614 pmlmeinfo->link_count = 0;
12617 } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
12619 } else if (is_client_associated_to_ibss(padapter)) {
12621 _list *phead, *plist, dlist;
12623 _rtw_init_listhead(&dlist);
12625 _enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12627 for (i = 0; i < NUM_STA; i++) {
12629 phead = &(pstapriv->sta_hash[i]);
12630 plist = get_next(phead);
12631 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12632 psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12633 plist = get_next(plist);
12635 if (is_broadcast_mac_addr(psta->hwaddr))
12638 if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to)
12639 psta->expire_to = pstapriv->adhoc_expire_to;
12643 if (psta->expire_to <= 0) {
12644 rtw_list_delete(&psta->list);
12645 rtw_list_insert_tail(&psta->list, &dlist);
12650 _exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12652 plist = get_next(&dlist);
12653 while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) {
12654 psta = LIST_CONTAINOR(plist, struct sta_info, list);
12655 plist = get_next(plist);
12656 rtw_list_delete(&psta->list);
12657 RTW_INFO(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n"
12658 , FUNC_ADPT_ARG(padapter), MAC_ARG(psta->hwaddr));
12659 report_del_sta_event(padapter, psta->hwaddr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE, _FALSE);
12665 void survey_timer_hdl(_adapter *padapter)
12667 struct cmd_obj *cmd;
12668 struct sitesurvey_parm *psurveyPara;
12669 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12670 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12672 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
12675 if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
12676 cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12682 psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
12683 if (psurveyPara == NULL) {
12685 rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
12689 init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12690 rtw_enqueue_cmd(pcmdpriv, cmd);
12697 void link_timer_hdl(_adapter *padapter)
12699 /* static unsigned int rx_pkt = 0; */
12700 /* static u64 tx_cnt = 0; */
12701 /* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */
12702 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12703 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12704 /* struct sta_priv *pstapriv = &padapter->stapriv; */
12705 #ifdef CONFIG_RTW_80211R
12706 struct sta_priv *pstapriv = &padapter->stapriv;
12707 struct sta_info *psta = NULL;
12708 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
12711 if (rtw_sta_linking_test_force_fail())
12712 RTW_INFO("rtw_sta_linking_test_force_fail\n");
12714 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
12715 RTW_INFO("link_timer_hdl:no beacon while connecting\n");
12716 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12717 report_join_res(padapter, -3);
12718 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
12719 /* re-auth timer */
12720 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
12721 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
12723 pmlmeinfo->state = 0;
12724 report_join_res(padapter, -1);
12729 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
12730 /* pmlmeinfo->reauth_count = 0; */
12734 RTW_INFO("link_timer_hdl: auth timeout and try again\n");
12735 pmlmeinfo->auth_seq = 1;
12736 issue_auth(padapter, NULL, 0);
12737 set_link_timer(pmlmeext, REAUTH_TO);
12738 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
12739 /* re-assoc timer */
12740 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
12741 pmlmeinfo->state = WIFI_FW_NULL_STATE;
12742 #ifdef CONFIG_RTW_80211R
12743 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
12744 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12746 rtw_free_stainfo(padapter, psta);
12749 report_join_res(padapter, -2);
12753 #ifdef CONFIG_RTW_80211R
12754 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED)) {
12755 RTW_INFO("link_timer_hdl: reassoc timeout and try again\n");
12756 issue_reassocreq(padapter);
12760 RTW_INFO("link_timer_hdl: assoc timeout and try again\n");
12761 issue_assocreq(padapter);
12764 set_link_timer(pmlmeext, REASSOC_TO);
12770 void addba_timer_hdl(struct sta_info *psta)
12772 #ifdef CONFIG_80211N_HT
12773 struct ht_priv *phtpriv;
12778 phtpriv = &psta->htpriv;
12780 if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
12781 if (phtpriv->candidate_tid_bitmap)
12782 phtpriv->candidate_tid_bitmap = 0x0;
12785 #endif /* CONFIG_80211N_HT */
12788 #ifdef CONFIG_IEEE80211W
12789 void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
12791 struct cmd_obj *pcmd_obj;
12794 struct sta_info *psta;
12796 struct stadel_event *pdel_sta_evt;
12797 struct C2HEvent_Header *pc2h_evt_hdr;
12798 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12799 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12801 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12802 if (pcmd_obj == NULL)
12805 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
12806 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
12807 if (pevtcmd == NULL) {
12808 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
12812 _rtw_init_listhead(&pcmd_obj->list);
12814 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
12815 pcmd_obj->cmdsz = cmdsz;
12816 pcmd_obj->parmbuf = pevtcmd;
12818 pcmd_obj->rsp = NULL;
12819 pcmd_obj->rspsz = 0;
12821 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
12822 pc2h_evt_hdr->len = sizeof(struct stadel_event);
12823 pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA);
12824 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
12826 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
12827 _rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
12828 _rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
12831 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
12833 mac_id = (int)psta->mac_id;
12837 pdel_sta_evt->mac_id = mac_id;
12839 RTW_INFO("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
12841 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
12846 void clnt_sa_query_timeout(_adapter *padapter)
12849 rtw_disassoc_cmd(padapter, 0, 0);
12850 rtw_indicate_disconnect(padapter, 0, _FALSE);
12851 rtw_free_assoc_resources(padapter, 1);
12853 RTW_INFO("SA query timeout client disconnect\n");
12856 void sa_query_timer_hdl(struct sta_info *psta)
12858 _adapter *padapter = psta->padapter;
12860 struct sta_priv *pstapriv = &padapter->stapriv;
12861 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12863 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
12864 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
12865 clnt_sa_query_timeout(padapter);
12866 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
12867 report_sta_timeout_event(padapter, psta->hwaddr, WLAN_REASON_PREV_AUTH_NOT_VALID);
12870 #endif /* CONFIG_IEEE80211W */
12872 #ifdef CONFIG_RTW_80211R
12873 void start_clnt_ft_action(_adapter *padapter, u8 *pTargetAddr)
12875 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12876 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12878 rtw_set_ft_status(padapter, RTW_FT_REQUESTING_STA);
12879 issue_action_ft_request(padapter, pTargetAddr);
12880 _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO);
12883 void ft_link_timer_hdl(_adapter *padapter)
12885 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12886 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12887 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
12888 ft_priv *pftpriv = &pmlmepriv->ftpriv;
12890 if (rtw_chk_ft_status(padapter, RTW_FT_REQUESTING_STA)) {
12891 if (pftpriv->ft_req_retry_cnt < FT_ACTION_REQ_LIMIT) {
12892 pftpriv->ft_req_retry_cnt++;
12893 issue_action_ft_request(padapter, (u8 *)pmlmepriv->roam_network->network.MacAddress);
12894 _set_timer(&pmlmeext->ft_link_timer, REASSOC_TO);
12896 pftpriv->ft_req_retry_cnt = 0;
12898 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12899 rtw_set_ft_status(padapter, RTW_FT_ASSOCIATED_STA);
12901 rtw_reset_ft_status(padapter);
12906 void ft_roam_timer_hdl(_adapter *padapter)
12908 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
12910 receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress
12911 , WLAN_REASON_ACTIVE_ROAM, _FALSE);
12914 void issue_action_ft_request(_adapter *padapter, u8 *pTargetAddr)
12916 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
12917 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
12918 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12919 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12920 struct xmit_frame *pmgntframe = NULL;
12921 struct rtw_ieee80211_hdr *pwlanhdr = NULL;
12922 struct pkt_attrib *pattrib = NULL;
12923 ft_priv *pftpriv = NULL;
12925 u8 category = RTW_WLAN_CATEGORY_FT;
12926 u8 action = RTW_WLAN_ACTION_FT_REQUEST;
12927 u8 is_ft_roaming_with_rsn_ie = _TRUE;
12932 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
12933 if (pmgntframe == NULL)
12936 pattrib = &pmgntframe->attrib;
12937 update_mgntframe_attrib(padapter, pattrib);
12938 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
12940 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
12941 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
12943 fctrl = &(pwlanhdr->frame_ctl);
12946 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
12947 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
12948 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
12950 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
12951 pmlmeext->mgnt_seq++;
12952 set_frame_sub_type(pframe, WIFI_ACTION);
12954 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
12955 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
12957 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
12958 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
12960 _rtw_memcpy(pframe, adapter_mac_addr(padapter), ETH_ALEN);
12961 pframe += ETH_ALEN;
12962 pattrib->pktlen += ETH_ALEN;
12964 _rtw_memcpy(pframe, pTargetAddr, ETH_ALEN);
12965 pframe += ETH_ALEN;
12966 pattrib->pktlen += ETH_ALEN;
12968 pftpriv = &pmlmepriv->ftpriv;
12969 pie = rtw_get_ie(pftpriv->updated_ft_ies, EID_WPA2, &ft_ie_len, pftpriv->updated_ft_ies_len);
12971 pframe = rtw_set_ie(pframe, EID_WPA2, ft_ie_len, pie+2, &(pattrib->pktlen));
12973 is_ft_roaming_with_rsn_ie = _FALSE;
12975 pie = rtw_get_ie(pftpriv->updated_ft_ies, _MDIE_, &ft_ie_len, pftpriv->updated_ft_ies_len);
12977 pframe = rtw_set_ie(pframe, _MDIE_, ft_ie_len , pie+2, &(pattrib->pktlen));
12979 pie = rtw_get_ie(pftpriv->updated_ft_ies, _FTIE_, &ft_ie_len, pftpriv->updated_ft_ies_len);
12980 if (pie && is_ft_roaming_with_rsn_ie)
12981 pframe = rtw_set_ie(pframe, _FTIE_, ft_ie_len , pie+2, &(pattrib->pktlen));
12983 pattrib->last_txcmdsz = pattrib->pktlen;
12984 dump_mgntframe(padapter, pmgntframe);
12987 void report_ft_event(_adapter *padapter)
12989 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
12990 ft_priv *pftpriv = &pmlmepriv->ftpriv;
12991 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12992 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12993 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
12994 struct cfg80211_ft_event_params ft_evt_parms;
12997 _rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms));
12998 rtw_update_ft_stainfo(padapter, pnetwork);
13003 ft_evt_parms.ies_len = pftpriv->ft_event.ies_len;
13004 ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len);
13005 if (ft_evt_parms.ies)
13006 _rtw_memcpy((void *)ft_evt_parms.ies, pftpriv->ft_event.ies, ft_evt_parms.ies_len);
13010 ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN);
13011 if (ft_evt_parms.target_ap)
13012 _rtw_memcpy((void *)ft_evt_parms.target_ap, pnetwork->MacAddress, ETH_ALEN);
13016 ft_evt_parms.ric_ies = pftpriv->ft_event.ric_ies;
13017 ft_evt_parms.ric_ies_len = pftpriv->ft_event.ric_ies_len;
13019 _enter_critical_bh(&pmlmepriv->lock, &irqL);
13020 rtw_set_ft_status(padapter, RTW_FT_AUTHENTICATED_STA);
13021 _exit_critical_bh(&pmlmepriv->lock, &irqL);
13023 rtw_cfg80211_ft_event(padapter, &ft_evt_parms);
13024 RTW_INFO("FT: report_ft_event\n");
13025 rtw_mfree((u8 *)pftpriv->ft_event.target_ap, ETH_ALEN);
13027 rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len);
13032 void report_ft_reassoc_event(_adapter *padapter, u8 *pMacAddr)
13034 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13035 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
13036 struct cmd_obj *pcmd_obj = NULL;
13037 struct stassoc_event *passoc_sta_evt = NULL;
13038 struct C2HEvent_Header *pc2h_evt_hdr = NULL;
13039 u8 *pevtcmd = NULL;
13042 pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
13043 if (pcmd_obj == NULL)
13046 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
13047 pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
13048 if (pevtcmd == NULL) {
13049 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
13053 _rtw_init_listhead(&pcmd_obj->list);
13054 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
13055 pcmd_obj->cmdsz = cmdsz;
13056 pcmd_obj->parmbuf = pevtcmd;
13057 pcmd_obj->rsp = NULL;
13058 pcmd_obj->rspsz = 0;
13060 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
13061 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
13062 pc2h_evt_hdr->ID = GEN_EVT_CODE(_FT_REASSOC);
13063 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
13065 passoc_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
13066 _rtw_memcpy((unsigned char *)(&(passoc_sta_evt->macaddr)), pMacAddr, ETH_ALEN);
13067 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
13071 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
13073 return H2C_SUCCESS;
13076 #ifdef CONFIG_AUTO_AP_MODE
13077 void rtw_start_auto_ap(_adapter *adapter)
13079 RTW_INFO("%s\n", __FUNCTION__);
13081 rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode);
13083 rtw_setopmode_cmd(adapter, Ndis802_11APMode, _TRUE);
13086 static int rtw_auto_ap_start_beacon(_adapter *adapter)
13091 u8 supportRate[16];
13092 int sz = 0, rateLen;
13094 u8 wireless_mode, oper_channel;
13095 u8 ssid[3] = {0}; /* hidden ssid */
13096 u32 ssid_len = sizeof(ssid);
13097 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
13100 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
13105 pbuf = rtw_zmalloc(len);
13110 /* generate beacon */
13113 /* timestamp will be inserted by hardware */
13117 /* beacon interval : 2bytes */
13118 *(u16 *)ie = cpu_to_le16((u16)100); /* BCN_INTERVAL=100; */
13122 /* capability info */
13124 *(u16 *)ie |= cpu_to_le16(cap_ESS);
13125 *(u16 *)ie |= cpu_to_le16(cap_ShortPremble);
13126 /* *(u16*)ie |= cpu_to_le16(cap_Privacy); */
13131 ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
13133 /* supported rates */
13134 wireless_mode = WIRELESS_11BG_24N;
13135 rtw_set_supported_rate(supportRate, wireless_mode) ;
13136 rateLen = rtw_get_rateset_len(supportRate);
13138 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
13140 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
13143 /* DS parameter set */
13144 if (rtw_mi_check_status(adapter, MI_LINKED))
13145 oper_channel = rtw_mi_get_union_chan(adapter);
13147 oper_channel = adapter_to_dvobj(adapter)->oper_channel;
13149 ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
13151 /* ext supported rates */
13153 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
13155 RTW_INFO("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
13157 /* lunch ap mode & start to issue beacon */
13158 if (rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS) {
13164 rtw_mfree(pbuf, len);
13169 #endif/* CONFIG_AUTO_AP_MODE */
13171 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
13174 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13175 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13176 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
13178 if (psetop->mode == Ndis802_11APMode) {
13179 pmlmeinfo->state = WIFI_FW_AP_STATE;
13180 type = _HW_STATE_AP_;
13181 #ifdef CONFIG_NATIVEAP_MLME
13182 /* start_ap_mode(padapter); */
13184 } else if (psetop->mode == Ndis802_11Infrastructure) {
13185 pmlmeinfo->state &= ~(BIT(0) | BIT(1)); /* clear state */
13186 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
13187 type = _HW_STATE_STATION_;
13188 } else if (psetop->mode == Ndis802_11IBSS)
13189 type = _HW_STATE_ADHOC_;
13190 else if (psetop->mode == Ndis802_11Monitor)
13191 type = _HW_STATE_MONITOR_;
13193 type = _HW_STATE_NOLINK_;
13195 #ifdef CONFIG_AP_PORT_SWAP
13196 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, (u8 *)(&type));
13199 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
13201 #ifdef CONFIG_AUTO_AP_MODE
13202 if (psetop->mode == Ndis802_11APMode)
13203 rtw_auto_ap_start_beacon(padapter);
13206 if (rtw_port_switch_chk(padapter) == _TRUE) {
13207 rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
13209 if (psetop->mode == Ndis802_11APMode)
13210 adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; /* ap mode won't dowload rsvd pages */
13211 else if (psetop->mode == Ndis802_11Infrastructure) {
13213 _adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
13215 rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, 0);
13220 #ifdef CONFIG_BT_COEXIST
13221 if (psetop->mode == Ndis802_11APMode ||
13222 psetop->mode == Ndis802_11Monitor) {
13223 /* Do this after port switch to */
13224 /* prevent from downloading rsvd page to wrong port */
13225 rtw_btcoex_MediaStatusNotify(padapter, 1); /* connect */
13227 #endif /* CONFIG_BT_COEXIST */
13229 return H2C_SUCCESS;
13233 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
13235 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13236 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13237 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
13238 WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network;
13239 struct createbss_parm *parm = (struct createbss_parm *)pbuf;
13240 u8 ret = H2C_SUCCESS;
13241 /* u8 initialgain; */
13243 #ifdef CONFIG_AP_MODE
13244 if (pmlmeinfo->state == WIFI_FW_AP_STATE) {
13245 start_bss_network(padapter, parm);
13250 /* below is for ad-hoc master */
13252 rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
13253 rtw_joinbss_reset(padapter);
13255 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
13256 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13257 pmlmeinfo->ERP_enable = 0;
13258 pmlmeinfo->WMM_enable = 0;
13259 pmlmeinfo->HT_enable = 0;
13260 pmlmeinfo->HT_caps_enable = 0;
13261 pmlmeinfo->HT_info_enable = 0;
13262 pmlmeinfo->agg_enable_bitmap = 0;
13263 pmlmeinfo->candidate_tid_bitmap = 0;
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 /* disable dynamic functions, such as high power, DIG */
13270 rtw_phydm_ability_backup(padapter);
13271 rtw_phydm_func_disable_all(padapter);
13273 /* cancel link timer */
13274 _cancel_timer_ex(&pmlmeext->link_timer);
13277 flush_all_cam_entry(padapter);
13279 pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
13280 _rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13281 pnetwork->IELength = pdev_network->IELength;
13283 if (pnetwork->IELength > MAX_IE_SZ) {
13284 ret = H2C_PARAMETERS_ERROR;
13285 goto ibss_post_hdl;
13288 _rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
13289 start_create_ibss(padapter);
13292 ret = H2C_PARAMETERS_ERROR;
13296 rtw_create_ibss_post_hdl(padapter, ret);
13302 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
13305 PNDIS_802_11_VARIABLE_IEs pIE;
13306 struct registry_priv *pregpriv = &padapter->registrypriv;
13307 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13308 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13309 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
13310 #ifdef CONFIG_ANTENNA_DIVERSITY
13311 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
13312 #endif /* CONFIG_ANTENNA_DIVERSITY */
13314 /* u8 initialgain; */
13316 u8 u_ch, u_bw, u_offset;
13319 /* check already connecting to AP or not */
13320 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
13321 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13322 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13323 pmlmeinfo->state = WIFI_FW_NULL_STATE;
13326 flush_all_cam_entry(padapter);
13328 _cancel_timer_ex(&pmlmeext->link_timer);
13330 /* set MSR to nolink->infra. mode */
13331 /* Set_MSR(padapter, _HW_STATE_NOLINK_); */
13332 Set_MSR(padapter, _HW_STATE_STATION_);
13335 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
13338 #ifdef CONFIG_ANTENNA_DIVERSITY
13339 rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
13342 #ifdef CONFIG_WAPI_SUPPORT
13343 rtw_wapi_clear_all_cam_entry(padapter);
13346 rtw_joinbss_reset(padapter);
13348 pmlmeinfo->ERP_enable = 0;
13349 pmlmeinfo->WMM_enable = 0;
13350 pmlmeinfo->HT_enable = 0;
13351 pmlmeinfo->HT_caps_enable = 0;
13352 pmlmeinfo->HT_info_enable = 0;
13353 pmlmeinfo->agg_enable_bitmap = 0;
13354 pmlmeinfo->candidate_tid_bitmap = 0;
13355 pmlmeinfo->bwmode_updated = _FALSE;
13356 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
13357 pmlmeinfo->VHT_enable = 0;
13359 _rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13360 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
13362 if (pnetwork->IELength > MAX_IE_SZ) /* Check pbuf->IELength */
13363 return H2C_PARAMETERS_ERROR;
13365 if (pnetwork->IELength < 2) {
13366 report_join_res(padapter, (-4));
13367 return H2C_SUCCESS;
13369 _rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
13371 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
13373 /* Check AP vendor to move rtw_joinbss_cmd() */
13374 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */
13376 /* sizeof(NDIS_802_11_FIXED_IEs) */
13377 for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
13378 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
13380 switch (pIE->ElementID) {
13381 case _VENDOR_SPECIFIC_IE_: /* Get WMM IE. */
13382 if (_rtw_memcmp(pIE->data, WMM_OUI, 4))
13383 WMM_param_handler(padapter, pIE);
13386 #ifdef CONFIG_80211N_HT
13387 case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */
13388 pmlmeinfo->HT_caps_enable = 1;
13391 case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */
13392 pmlmeinfo->HT_info_enable = 1;
13394 #endif /* CONFIG_80211N_HT */
13396 #ifdef CONFIG_80211AC_VHT
13397 case EID_VHTCapability: /* Get VHT Cap IE. */
13398 pmlmeinfo->VHT_enable = 1;
13401 case EID_VHTOperation: /* Get VHT Operation IE. */
13403 #endif /* CONFIG_80211AC_VHT */
13408 i += (pIE->Length + 2);
13411 rtw_bss_get_chbw(pnetwork
13412 , &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13414 rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13417 if (padapter->registrypriv.wifi_spec) {
13418 /* for WiFi test, follow WMM test plan spec */
13419 acparm = 0x002F431C; /* VO */
13420 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13421 acparm = 0x005E541C; /* VI */
13422 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13423 acparm = 0x0000A525; /* BE */
13424 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13425 acparm = 0x0000A549; /* BK */
13426 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13428 /* for WiFi test, mixed mode with intel STA under bg mode throughput issue */
13429 if (padapter->mlmepriv.htpriv.ht_option == _FALSE) {
13430 acparm = 0x00004320;
13431 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13434 acparm = 0x002F3217; /* VO */
13435 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13436 acparm = 0x005E4317; /* VI */
13437 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13438 acparm = 0x00105320; /* BE */
13439 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13440 acparm = 0x0000A444; /* BK */
13441 rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13445 /* check channel, bandwidth, offset and switch */
13446 if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
13447 report_join_res(padapter, (-4));
13448 return H2C_SUCCESS;
13451 /* disable dynamic functions, such as high power, DIG */
13452 /*rtw_phydm_func_disable_all(padapter);*/
13454 /* config the initial gain under linking, need to write the BB registers */
13455 /* initialgain = 0x1E; */
13456 /*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
13458 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
13460 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
13462 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13464 set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
13465 rtw_mi_update_union_chan_inf(padapter, u_ch, u_offset, u_bw);
13468 rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
13470 /* cancel link timer */
13471 _cancel_timer_ex(&pmlmeext->link_timer);
13473 start_clnt_join(padapter);
13475 return H2C_SUCCESS;
13479 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
13481 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
13482 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13483 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13484 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
13487 if (is_client_associated_to_ap(padapter)) {
13489 if (padapter->mlmepriv.handle_dfs == _FALSE)
13490 #endif /* CONFIG_DFS */
13491 #ifdef CONFIG_PLATFORM_ROCKCHIPS
13492 /* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
13493 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13495 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100);
13496 #endif /* CONFIG_PLATFORM_ROCKCHIPS */
13500 if (padapter->mlmepriv.handle_dfs == _TRUE)
13501 padapter->mlmepriv.handle_dfs = _FALSE;
13502 #endif /* CONFIG_DFS */
13504 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
13507 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
13510 rtw_mlmeext_disconnect(padapter);
13512 rtw_free_uc_swdec_pending_queue(padapter);
13514 rtw_sta_mstatus_report(padapter);
13516 return H2C_SUCCESS;
13519 static const char *const _scan_state_str[] = {
13522 "SCAN_PS_ANNC_WAIT",
13529 "SCAN_SW_ANTDIV_BL",
13530 "SCAN_TO_P2P_LISTEN",
13536 const char *scan_state_str(u8 state)
13538 state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
13539 return _scan_state_str[state];
13542 static bool scan_abort_hdl(_adapter *adapter)
13544 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
13545 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13546 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13548 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
13552 if (pmlmeext->scan_abort == _TRUE) {
13554 if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
13555 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
13556 ss->channel_idx = 3;
13557 RTW_INFO("%s idx:%d, cnt:%u\n", __FUNCTION__
13559 , pwdinfo->find_phase_state_exchange_cnt
13564 ss->channel_idx = ss->ch_num;
13565 RTW_INFO("%s idx:%d\n", __FUNCTION__
13569 pmlmeext->scan_abort = _FALSE;
13576 u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
13578 /* interval larger than this is treated as backgroud scan */
13579 #ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
13580 #define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
13583 #ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
13584 #define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
13586 #ifndef RTW_SCAN_SPARSE_CH_NUM_BG
13587 #define RTW_SCAN_SPARSE_CH_NUM_BG 4
13589 #ifdef CONFIG_LAYER2_ROAMING
13590 #ifndef RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE
13591 #define RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE 1
13595 #define SCAN_SPARSE_CH_NUM_INVALID 255
13597 static u8 token = 255;
13599 bool busy_traffic = _FALSE;
13600 bool miracast_enabled = _FALSE;
13601 bool bg_scan = _FALSE;
13602 u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
13603 u8 scan_division_num;
13604 u8 ret_num = ch_num;
13605 struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
13606 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
13608 if (regsty->wifi_spec)
13611 /* assume ch_num > 6 is normal scan */
13615 if (mlmeext->last_scan_time == 0)
13616 mlmeext->last_scan_time = rtw_get_current_time();
13618 interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
13621 if (rtw_mi_busy_traffic_check(adapter, _FALSE))
13622 busy_traffic = _TRUE;
13624 if (rtw_mi_check_miracast_enabled(adapter))
13625 miracast_enabled = _TRUE;
13627 if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
13630 /* max_allow_ch by conditions*/
13632 #if RTW_SCAN_SPARSE_MIRACAST
13633 if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
13634 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
13637 #if RTW_SCAN_SPARSE_BG
13638 if (bg_scan == _TRUE)
13639 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
13642 #if defined(CONFIG_LAYER2_ROAMING) && defined(RTW_SCAN_SPARSE_ROAMING_ACTIVE)
13643 if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
13644 if (busy_traffic == _TRUE && adapter->mlmepriv.need_to_roam == _TRUE)
13645 max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE);
13650 if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
13654 scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch) ? 1 : 0);
13655 token = (token + 1) % scan_division_num;
13658 RTW_INFO("scan_division_num:%u, token:%u\n", scan_division_num, token);
13660 for (i = 0; i < ch_num; i++) {
13661 if (ch[i].hw_value && (i % scan_division_num) == token
13664 _rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
13669 _rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
13672 mlmeext->last_scan_time = rtw_get_current_time();
13679 static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
13680 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
13683 int scan_ch_num = 0;
13686 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13689 _rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num);
13691 /* acquire channels from in */
13693 for (i = 0; i < in_num; i++) {
13696 RTW_INFO(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
13698 if (!in[i].hw_value || (in[i].flags & RTW_IEEE80211_CHAN_DISABLED))
13700 if (rtw_mlme_band_check(padapter, in[i].hw_value) == _FALSE)
13703 set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value);
13704 if (set_idx >= 0) {
13705 if (j >= out_num) {
13706 RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
13707 FUNC_ADPT_ARG(padapter), out_num);
13711 _rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
13713 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
13714 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13722 /* if out is empty, use channel_set as default */
13724 for (i = 0; i < pmlmeext->max_chan_nums; i++) {
13725 chan = pmlmeext->channel_set[i].ChannelNum;
13726 if (rtw_mlme_band_check(padapter, chan) == _TRUE) {
13727 if (rtw_mlme_ignore_chan(padapter, chan) == _TRUE)
13731 RTW_INFO(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), chan);
13733 if (j >= out_num) {
13734 RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
13735 FUNC_ADPT_ARG(padapter), out_num);
13739 out[j].hw_value = chan;
13741 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
13742 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
13750 j = rtw_scan_sparse(padapter, out, j);
13755 static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
13757 struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
13761 ss->channel_idx = 0;
13763 ss->igi_before_scan = 0;
13764 #ifdef CONFIG_SCAN_BACKOP
13767 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
13768 ss->is_sw_antdiv_bl_scan = 0;
13771 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13772 if (parm->ssid[i].SsidLength) {
13773 _rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
13774 ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
13776 ss->ssid[i].SsidLength = 0;
13779 ss->ch_num = rtw_scan_ch_decision(adapter
13780 , ss->ch, RTW_CHANNEL_SCAN_AMOUNT
13781 , parm->ch, parm->ch_num
13784 ss->scan_mode = parm->scan_mode;
13787 static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
13791 RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
13792 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13793 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
13794 struct ss_res *ss = &pmlmeext->sitesurvey_res;
13797 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
13800 /* handle scan abort request */
13801 scan_abort_hdl(padapter);
13804 if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
13805 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
13806 scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
13808 scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
13809 scan_type = SCAN_ACTIVE;
13810 } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
13812 * Commented by Albert 2011/06/03
13813 * The driver is in the find phase, it should go through the social channel.
13817 scan_ch = pwdinfo->social_chan[ss->channel_idx];
13818 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, scan_ch);
13819 if (ch_set_idx >= 0)
13820 scan_type = pmlmeext->channel_set[ch_set_idx].ScanType;
13822 scan_type = SCAN_ACTIVE;
13824 #endif /* CONFIG_P2P */
13826 struct rtw_ieee80211_channel *ch;
13828 if (ss->channel_idx < ss->ch_num) {
13829 ch = &ss->ch[ss->channel_idx];
13830 scan_ch = ch->hw_value;
13831 scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
13835 if (scan_ch != 0) {
13836 next_state = SCAN_PROCESS;
13837 #ifdef CONFIG_SCAN_BACKOP
13839 struct mi_state mstate;
13840 u8 backop_flags = 0;
13842 rtw_mi_status(padapter, &mstate);
13844 if ((MSTATE_STA_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN))
13845 || (MSTATE_STA_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(pmlmeext, SS_BACKOP_EN_NL)))
13846 backop_flags |= mlmeext_scan_backop_flags_sta(pmlmeext);
13848 if ((MSTATE_AP_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN))
13849 || (MSTATE_AP_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN_NL)))
13850 backop_flags |= mlmeext_scan_backop_flags_ap(pmlmeext);
13852 if (backop_flags) {
13853 if (ss->scan_cnt < ss->scan_cnt_max)
13856 mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
13857 next_state = SCAN_BACKING_OP;
13861 #endif /* CONFIG_SCAN_BACKOP */
13862 } else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
13863 /* go p2p listen */
13864 next_state = SCAN_TO_P2P_LISTEN;
13866 #ifdef CONFIG_ANTENNA_DIVERSITY
13867 } else if (rtw_hal_antdiv_before_linked(padapter)) {
13868 /* go sw antdiv before link */
13869 next_state = SCAN_SW_ANTDIV_BL;
13872 next_state = SCAN_COMPLETE;
13874 #if defined(DBG_SCAN_SW_ANTDIV_BL)
13876 /* for SCAN_SW_ANTDIV_BL state testing */
13877 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
13879 bool is_linked = _FALSE;
13881 for (i = 0; i < dvobj->iface_nums; i++) {
13882 if (rtw_linked_check(dvobj->padapters[i]))
13887 static bool fake_sw_antdiv_bl_state = 0;
13889 if (fake_sw_antdiv_bl_state == 0) {
13890 next_state = SCAN_SW_ANTDIV_BL;
13891 fake_sw_antdiv_bl_state = 1;
13893 fake_sw_antdiv_bl_state = 0;
13896 #endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
13899 #ifdef CONFIG_SCAN_BACKOP
13900 if (next_state != SCAN_PROCESS)
13905 #ifdef DBG_FIXED_CHAN
13906 if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
13907 scan_ch = pmlmeext->fixed_chan;
13918 void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
13920 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13921 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13924 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
13927 if (survey_channel != 0) {
13928 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
13930 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
13931 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
13932 ACS_OP acs_op = ACS_RESET;
13934 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
13935 rtw_set_acs_channel(padapter, survey_channel);
13936 #ifdef DBG_AUTO_CHNL_SEL_NHM
13937 RTW_INFO("[ACS-"ADPT_FMT"]-set ch:%u\n",
13938 ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
13943 if (ScanType == SCAN_ACTIVE) {
13945 #ifdef CONFIG_IOCTL_CFG80211
13946 if (rtw_cfg80211_is_p2p_scan(padapter))
13948 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
13949 || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
13952 issue_probereq_p2p(padapter, NULL);
13953 issue_probereq_p2p(padapter, NULL);
13954 issue_probereq_p2p(padapter, NULL);
13956 #endif /* CONFIG_P2P */
13960 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
13961 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
13962 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13963 if (padapter->registrypriv.wifi_spec)
13964 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13966 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
13967 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
13971 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
13972 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
13973 if (padapter->registrypriv.wifi_spec)
13974 issue_probereq(padapter, NULL, NULL);
13976 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
13977 issue_probereq(padapter, NULL, NULL);
13982 /* channel number is 0 or this channel is not valid. */
13989 void survey_done_set_ch_bw(_adapter *padapter)
13991 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13992 u8 cur_channel = 0;
13996 #ifdef CONFIG_MCC_MODE
13997 if (!rtw_hal_mcc_change_scan_flag(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset)) {
13999 RTW_INFO(FUNC_ADPT_FMT" back to AP channel - ch:%u, bw:%u, offset:%u\n",
14000 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14005 if (rtw_mi_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
14007 RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
14008 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14011 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14015 for (i = 0; i < dvobj->iface_nums; i++) {
14016 iface = dvobj->padapters[i];
14020 #ifdef CONFIG_IOCTL_CFG80211
14021 if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
14025 if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
14026 cur_channel = iface->wdinfo.listen_channel;
14027 cur_bwmode = CHANNEL_WIDTH_20;
14028 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
14030 RTW_INFO(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
14031 FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
14035 #endif /* CONFIG_P2P */
14037 if (cur_channel == 0) {
14038 cur_channel = pmlmeext->cur_channel;
14039 cur_bwmode = pmlmeext->cur_bwmode;
14040 cur_ch_offset = pmlmeext->cur_ch_offset;
14042 RTW_INFO(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
14043 FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14047 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
14052 * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj
14054 * @ps: power saving or not
14056 * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
14059 u8 sitesurvey_ps_annc(_adapter *padapter, bool ps)
14063 if (rtw_mi_issue_nulldata(padapter, NULL, ps, 3, 500))
14069 * sitesurvey_ps_annc - check and doing ps announcement for all the adapters of given @dvobj
14070 * @dvobj: the dvobj to check
14071 * @ps: power saving or not
14073 * Returns: 0: no ps announcement is doing. 1: ps announcement is doing
14076 u8 sitesurvey_ps_annc(struct dvobj_priv *dvobj, bool ps)
14082 for (i = 0; i < dvobj->iface_nums; i++) {
14083 adapter = dvobj->padapters[i];
14088 if (is_client_associated_to_ap(adapter) == _TRUE) {
14089 /* TODO: TDLS peers */
14090 issue_nulldata(adapter, NULL, 1, 3, 500);
14094 if (is_client_associated_to_ap(adapter) == _TRUE) {
14095 /* TODO: TDLS peers */
14096 issue_nulldata(adapter, NULL, 0, 3, 500);
14105 void sitesurvey_set_igi(_adapter *adapter)
14107 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
14108 struct ss_res *ss = &mlmeext->sitesurvey_res;
14111 struct wifidirect_info *pwdinfo = &adapter->wdinfo;
14114 switch (mlmeext_scan_state(mlmeext)) {
14117 #ifdef CONFIG_IOCTL_CFG80211
14118 if (adapter_wdev_data(adapter)->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211)
14121 #endif /* CONFIG_IOCTL_CFG80211 */
14122 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
14125 #endif /* CONFIG_P2P */
14128 /* record IGI status */
14129 ss->igi_scan = igi;
14130 rtw_hal_get_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &ss->igi_before_scan, NULL);
14132 /* disable DIG and set IGI for scan */
14133 rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
14135 case SCAN_COMPLETE:
14136 case SCAN_TO_P2P_LISTEN:
14137 /* enable DIG and restore IGI */
14139 rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
14141 #ifdef CONFIG_SCAN_BACKOP
14142 case SCAN_BACKING_OP:
14143 /* write IGI for op channel when DIG is not enabled */
14144 odm_write_dig(GET_ODM(adapter), ss->igi_before_scan);
14146 case SCAN_LEAVE_OP:
14147 /* write IGI for scan when DIG is not enabled */
14148 odm_write_dig(GET_ODM(adapter), ss->igi_scan);
14150 #endif /* CONFIG_SCAN_BACKOP */
14156 void sitesurvey_set_msr(_adapter *adapter, bool enter)
14159 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
14160 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14163 #ifdef CONFIG_MI_WITH_MBSSID_CAM
14164 rtw_hal_get_hwreg(adapter, HW_VAR_MEDIA_STATUS, (u8 *)(&pmlmeinfo->hw_media_state));
14166 /* set MSR to no link state */
14167 network_type = _HW_STATE_NOLINK_;
14169 #ifdef CONFIG_MI_WITH_MBSSID_CAM
14170 network_type = pmlmeinfo->hw_media_state;
14172 network_type = pmlmeinfo->state & 0x3;
14175 Set_MSR(adapter, network_type);
14177 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
14179 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
14180 struct dvobj_priv *dvobj = padapter->dvobj;
14181 struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
14182 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14183 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14184 struct ss_res *ss = &pmlmeext->sitesurvey_res;
14188 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14191 #ifdef DBG_CHECK_FW_PS_STATE
14192 if (rtw_fw_ps_state(padapter) == _FAIL) {
14193 RTW_INFO("scan without leave 32k\n");
14194 pdbgpriv->dbg_scan_pwr_state_cnt++;
14196 #endif /* DBG_CHECK_FW_PS_STATE */
14198 /* increase channel idx */
14199 if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
14202 /* update scan state to next state (assigned by previous cmd hdl) */
14203 if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
14204 mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
14206 operation_by_state:
14207 switch (mlmeext_scan_state(pmlmeext)) {
14211 * SW parameter initialization
14214 sitesurvey_res_reset(padapter, pparm);
14215 mlmeext_set_scan_state(pmlmeext, SCAN_START);
14216 goto operation_by_state;
14220 * prepare to leave operating channel
14223 #ifdef CONFIG_MCC_MODE
14224 rtw_hal_set_mcc_setting_scan_start(padapter);
14225 #endif /* CONFIG_MCC_MODE */
14227 /* apply rx ampdu setting */
14228 if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
14229 || ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
14230 rtw_rx_ampdu_apply(padapter);
14232 /* clear HW TX queue before scan */
14233 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14235 /* power save state announcement */
14236 if (sitesurvey_ps_annc(padapter, 1)) {
14237 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14238 mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
14239 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14241 mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
14242 goto operation_by_state;
14249 * HW register and DM setting for enter scan
14252 rtw_phydm_ability_backup(padapter);
14254 sitesurvey_set_igi(padapter);
14256 /* config dynamic functions for off channel */
14257 rtw_phydm_func_for_offchannel(padapter);
14258 /* set MSR to no link state */
14259 sitesurvey_set_msr(padapter, _TRUE);
14261 val8 = 1; /* under site survey */
14262 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14264 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14265 goto operation_by_state;
14267 case SCAN_PROCESS: {
14269 RT_SCAN_TYPE scan_type;
14273 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14274 if ((ACS_ENABLE == GET_ACS_STATE(padapter)) && (0 != rtw_get_acs_channel(padapter))) {
14275 ACS_OP acs_op = ACS_SELECT;
14277 rtw_hal_set_odm_var(padapter, HAL_ODM_AUTO_CHNL_SEL, &acs_op, _TRUE);
14281 next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
14282 if (next_state != SCAN_PROCESS) {
14283 #ifdef CONFIG_AUTO_CHNL_SEL_NHM
14284 if (ACS_ENABLE == GET_ACS_STATE(padapter)) {
14285 rtw_set_acs_channel(padapter, 0);
14286 #ifdef DBG_AUTO_CHNL_SEL_NHM
14287 RTW_INFO("[ACS-"ADPT_FMT"]-set ch:%u\n", ADPT_ARG(padapter), rtw_get_acs_channel(padapter));
14292 mlmeext_set_scan_state(pmlmeext, next_state);
14293 goto operation_by_state;
14296 /* still SCAN_PROCESS state */
14299 RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
14300 , FUNC_ADPT_ARG(padapter)
14301 , mlmeext_scan_state_str(pmlmeext)
14303 , pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
14304 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14305 , scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
14306 , ss->ssid[0].SsidLength ? 'S' : ' '
14309 RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c\n"
14310 , FUNC_ADPT_ARG(padapter)
14311 , mlmeext_scan_state_str(pmlmeext)
14314 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14315 , scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
14316 , ss->ssid[0].SsidLength ? 'S' : ' '
14318 #endif /* CONFIG_P2P */
14320 #ifdef DBG_FIXED_CHAN
14321 if (pmlmeext->fixed_chan != 0xff)
14322 RTW_INFO(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
14325 site_survey(padapter, scan_ch, scan_type);
14327 #if defined(CONFIG_ATMEL_RC_PATCH)
14328 if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
14333 scan_ms = ss->scan_ch_ms;
14336 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14337 if (ss->is_sw_antdiv_bl_scan)
14338 scan_ms = scan_ms / 2;
14341 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
14343 struct noise_info info;
14345 info.bPauseDIG = _FALSE;
14347 info.max_time = scan_ms / 2;
14348 info.chan = scan_ch;
14349 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, _FALSE);
14353 set_survey_timer(pmlmeext, scan_ms);
14357 #ifdef CONFIG_SCAN_BACKOP
14358 case SCAN_BACKING_OP: {
14359 u8 back_ch, back_bw, back_ch_offset;
14360 u8 need_ch_setting_union = _TRUE;
14362 #ifdef CONFIG_MCC_MODE
14363 need_ch_setting_union = rtw_hal_mcc_change_scan_flag(padapter,
14364 &back_ch, &back_bw, &back_ch_offset);
14365 #endif /* CONFIG_MCC_MODE */
14367 if (need_ch_setting_union) {
14368 if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0)
14373 RTW_INFO(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
14374 , FUNC_ADPT_ARG(padapter)
14375 , mlmeext_scan_state_str(pmlmeext)
14376 , back_ch, back_bw, back_ch_offset
14377 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
14380 set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
14382 sitesurvey_set_msr(padapter, _FALSE);
14384 val8 = 0; /* survey done */
14385 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14387 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
14388 sitesurvey_set_igi(padapter);
14389 sitesurvey_ps_annc(padapter, 0);
14392 mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
14393 ss->backop_time = rtw_get_current_time();
14395 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME))
14396 rtw_mi_os_xmit_schedule(padapter);
14399 goto operation_by_state;
14403 if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
14404 || pmlmeext->scan_abort
14406 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
14407 goto operation_by_state;
14409 set_survey_timer(pmlmeext, 50);
14412 case SCAN_LEAVING_OP:
14414 * prepare to leave operating channel
14417 /* clear HW TX queue before scan */
14418 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
14420 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
14421 && sitesurvey_ps_annc(padapter, 1)
14423 mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
14424 mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
14425 set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
14427 mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
14428 goto operation_by_state;
14433 case SCAN_LEAVE_OP:
14435 * HW register and DM setting for enter scan
14438 if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC))
14439 sitesurvey_set_igi(padapter);
14441 sitesurvey_set_msr(padapter, _TRUE);
14443 val8 = 1; /* under site survey */
14444 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14446 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14447 goto operation_by_state;
14449 #endif /* CONFIG_SCAN_BACKOP */
14451 #if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14452 case SCAN_SW_ANTDIV_BL:
14455 * For SW antenna diversity before link, it needs to switch to another antenna and scan again.
14456 * It compares the scan result and select better one to do connection.
14459 ss->channel_idx = 0;
14460 ss->is_sw_antdiv_bl_scan = 1;
14462 mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
14463 set_survey_timer(pmlmeext, ss->scan_ch_ms);
14468 case SCAN_TO_P2P_LISTEN:
14470 * Set the P2P State to the listen state of find phase
14471 * and set the current channel to the listen channel
14473 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14474 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
14476 /* turn on phy-dynamic functions */
14477 rtw_phydm_ability_restore(padapter);
14479 sitesurvey_set_igi(padapter);
14481 mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
14482 _set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
14485 case SCAN_P2P_LISTEN:
14486 mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
14487 ss->channel_idx = 0;
14488 goto operation_by_state;
14489 #endif /* CONFIG_P2P */
14491 case SCAN_COMPLETE:
14493 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14494 || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
14496 #ifdef CONFIG_CONCURRENT_MODE
14497 if (pwdinfo->driver_interface == DRIVER_WEXT) {
14498 if (rtw_mi_check_status(padapter, MI_LINKED))
14499 _set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
14503 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
14505 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
14506 #endif /* CONFIG_P2P */
14508 /* switch channel */
14509 survey_done_set_ch_bw(padapter);
14511 sitesurvey_set_msr(padapter, _FALSE);
14513 val8 = 0; /* survey done */
14514 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
14516 /* turn on phy-dynamic functions */
14517 rtw_phydm_ability_restore(padapter);
14519 sitesurvey_set_igi(padapter);
14521 #ifdef CONFIG_MCC_MODE
14522 /* start MCC fail, then tx null data */
14523 if (!rtw_hal_set_mcc_setting_scan_complete(padapter))
14524 #endif /* CONFIG_MCC_MODE */
14525 sitesurvey_ps_annc(padapter, 0);
14527 /* apply rx ampdu setting */
14528 rtw_rx_ampdu_apply(padapter);
14530 mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
14532 report_surveydone_event(padapter);
14534 issue_action_BSSCoexistPacket(padapter);
14535 issue_action_BSSCoexistPacket(padapter);
14536 issue_action_BSSCoexistPacket(padapter);
14539 return H2C_SUCCESS;
14542 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
14544 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
14545 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14546 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14548 if (pparm->mode < 4)
14549 pmlmeinfo->auth_algo = pparm->mode;
14551 return H2C_SUCCESS;
14555 SEC CAM Entry format (32 bytes)
14556 DW0 - MAC_ADDR[15:0] | Valid[15] | MFB[14:8] | RSVD[7] | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0]
14557 DW0 - MAC_ADDR[15:0] | Valid[15] |RSVD[14:9] | RPT_MODE[8] | SPP_MODE[7] | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0] (92E/8812A/8814A)
14558 DW1 - MAC_ADDR[47:16]
14567 /*Set WEP key or Group Key*/
14568 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
14572 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
14573 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14574 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14575 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
14577 bool used = _FALSE;
14579 /* main tx key for wep. */
14581 pmlmeinfo->key_index = pparm->keyid;
14583 #ifdef CONFIG_CONCURRENT_MODE
14584 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
14585 cam_id = rtw_iface_bcmc_id_get(padapter);
14588 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, &used);
14593 #ifndef CONFIG_CONCURRENT_MODE
14594 if (cam_id >= 0 && cam_id <= 3)
14599 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
14600 /* for AP mode ,we will force sec cam entry_id so hw dont search cam when tx*/
14601 addr = adapter_mac_addr(padapter);
14603 /* not default key, searched by A2 */
14604 addr = get_bssid(&padapter->mlmepriv);
14607 /* cam entry searched is pairwise key */
14608 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
14611 RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
14612 , FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
14614 /* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
14615 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14616 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14618 /* clear group key */
14619 while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
14620 RTW_PRINT("clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
14621 clear_cam_entry(padapter, camid_clr);
14622 rtw_camid_free(padapter, camid_clr);
14628 ctrl = BIT(15) | BIT(6) | ((pparm->algorithm) << 2) | pparm->keyid;
14630 RTW_PRINT("set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
14631 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
14633 write_cam(padapter, cam_id, ctrl, addr, pparm->key);
14635 /* if ((cam_id > 3) && (((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)))*/
14636 #ifdef CONFIG_CONCURRENT_MODE
14637 if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
14638 if (is_wep_enc(pparm->algorithm)) {
14639 padapter->securitypriv.dot11Def_camid[pparm->keyid] = cam_id;
14640 padapter->securitypriv.dot118021x_bmc_cam_id =
14641 padapter->securitypriv.dot11Def_camid[padapter->securitypriv.dot11PrivacyKeyIndex];
14642 RTW_PRINT("wep group key - force camid:%d\n", padapter->securitypriv.dot118021x_bmc_cam_id);
14644 /*u8 org_cam_id = padapter->securitypriv.dot118021x_bmc_cam_id;*/
14646 /*force GK's cam id*/
14647 padapter->securitypriv.dot118021x_bmc_cam_id = cam_id;
14650 if ((org_cam_id != INVALID_SEC_MAC_CAM_ID) &&
14651 (org_cam_id != cam_id)) {
14652 RTW_PRINT("clear group key for addr:"MAC_FMT", org_camid:%d new_camid:%d\n", MAC_ARG(addr), org_cam_id, cam_id);
14653 clear_cam_entry(padapter, org_cam_id);
14654 rtw_camid_free(padapter, org_cam_id);
14661 #ifndef CONFIG_CONCURRENT_MODE
14662 if (cam_id >= 0 && cam_id <= 3)
14663 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_TRUE);
14666 /* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */
14667 if (is_wep_enc(pparm->algorithm) && check_mlmeinfo_state(pmlmeext, WIFI_FW_STATION_STATE) &&
14668 _rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC)) {
14669 struct set_stakey_parm sta_pparm;
14671 sta_pparm.algorithm = pparm->algorithm;
14672 sta_pparm.keyid = pparm->keyid;
14673 _rtw_memcpy(sta_pparm.key, pparm->key, 16);
14674 _rtw_memcpy(sta_pparm.addr, get_bssid(&padapter->mlmepriv), ETH_ALEN);
14675 set_stakey_hdl(padapter, (u8 *)&sta_pparm);
14679 /* allow multicast packets to driver */
14680 rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
14682 return H2C_SUCCESS;
14685 void rtw_ap_wep_pk_setting(_adapter *adapter, struct sta_info *psta)
14687 struct security_priv *psecuritypriv = &(adapter->securitypriv);
14688 struct set_stakey_parm sta_pparm;
14691 if (!is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
14694 for (keyid = 0; keyid < 4; keyid++) {
14695 if ((psecuritypriv->key_mask & BIT(keyid)) && (keyid == psecuritypriv->dot11PrivacyKeyIndex)) {
14696 sta_pparm.algorithm = psecuritypriv->dot11PrivacyAlgrthm;
14697 sta_pparm.keyid = keyid;
14698 _rtw_memcpy(sta_pparm.key, &(psecuritypriv->dot11DefKey[keyid].skey[0]), 16);
14699 _rtw_memcpy(sta_pparm.addr, psta->hwaddr, ETH_ALEN);
14701 RTW_PRINT(FUNC_ADPT_FMT"set WEP - PK with "MAC_FMT" keyid:%u\n"
14702 , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->hwaddr), keyid);
14704 set_stakey_hdl(adapter, (u8 *)&sta_pparm);
14709 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
14715 u8 ret = H2C_SUCCESS;
14716 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14717 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14718 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
14719 struct sta_priv *pstapriv = &padapter->stapriv;
14720 struct sta_info *psta;
14722 if (pparm->algorithm == _NO_PRIVACY_)
14725 psta = rtw_get_stainfo(pstapriv, pparm->addr);
14727 RTW_PRINT("%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
14728 ret = H2C_REJECTED;
14732 pmlmeinfo->enc_algo = pparm->algorithm;
14733 if (is_wep_enc(pparm->algorithm))
14734 kid = pparm->keyid;
14735 cam_id = rtw_camid_alloc(padapter, psta, kid, &used);
14739 /* cam entry searched is group key */
14740 if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
14743 RTW_PRINT(FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
14744 , FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
14746 /* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
14747 rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
14748 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
14750 /* clear group key */
14751 while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
14752 RTW_PRINT("clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
14753 clear_cam_entry(padapter, camid_clr);
14754 rtw_camid_free(padapter, camid_clr);
14759 if (pparm->algorithm == _NO_PRIVACY_) {
14760 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
14761 RTW_PRINT("clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
14762 clear_cam_entry(padapter, cam_id);
14763 rtw_camid_free(padapter, cam_id);
14766 RTW_PRINT("set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n",
14767 cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
14768 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
14769 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
14771 ret = H2C_SUCCESS_RSP;
14777 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
14779 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
14780 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14781 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14783 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
14786 return H2C_SUCCESS;
14788 #ifdef CONFIG_80211N_HT
14789 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
14790 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
14791 /* pmlmeinfo->ADDBA_retry_count = 0; */
14792 /* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */
14793 /* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */
14794 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14795 /* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */
14796 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14799 else if ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
14800 (psta->htpriv.ht_option == _TRUE) &&
14801 (psta->htpriv.ampdu_enable == _TRUE)) {
14802 issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
14803 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
14805 #endif /* CONFIG */
14807 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
14808 #endif /* CONFIG_80211N_HT */
14809 return H2C_SUCCESS;
14813 u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf)
14815 struct addBaRsp_parm *pparm = (struct addBaRsp_parm *)pbuf;
14816 u8 ret = _TRUE, i = 0, try_cnt = 3, wait_ms = 50;
14817 struct recv_reorder_ctrl *preorder_ctrl;
14818 struct sta_priv *pstapriv = &padapter->stapriv;
14819 struct sta_info *psta;
14821 psta = rtw_get_stainfo(pstapriv, pparm->addr);
14825 preorder_ctrl = &psta->recvreorder_ctrl[pparm->tid];
14826 ret = issue_addba_rsp_wait_ack(padapter, pparm->addr, pparm->tid, pparm->status, pparm->size, 3, 50);
14828 #ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
14829 /* status = 0 means accept this addba req, so update indicate seq = start_seq under this compile flag */
14830 if (pparm->status == 0) {
14831 preorder_ctrl->indicate_seq = pparm->start_seq;
14833 RTW_INFO("DBG_RX_SEQ %s:%d IndicateSeq: %d, start_seq: %d\n", __func__, __LINE__,
14834 preorder_ctrl->indicate_seq, pparm->start_seq);
14838 preorder_ctrl->indicate_seq = 0xffff;
14842 * status = 0 means accept this addba req
14843 * status = 37 means reject this addba req
14845 if (pparm->status == 0) {
14846 preorder_ctrl->enable = _TRUE;
14847 preorder_ctrl->ampdu_size = pparm->size;
14848 } else if (pparm->status == 37)
14849 preorder_ctrl->enable = _FALSE;
14852 return H2C_SUCCESS;
14855 u8 chk_bmc_sleepq_cmd(_adapter *padapter)
14857 struct cmd_obj *ph2c;
14858 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14862 ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
14863 if (ph2c == NULL) {
14868 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
14870 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14878 u8 set_tx_beacon_cmd(_adapter *padapter)
14880 struct cmd_obj *ph2c;
14881 struct Tx_Beacon_param *ptxBeacon_parm;
14882 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
14883 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14884 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14889 ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
14890 if (ph2c == NULL) {
14895 ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param));
14896 if (ptxBeacon_parm == NULL) {
14897 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
14902 _rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
14904 len_diff = update_hidden_ssid(
14905 ptxBeacon_parm->network.IEs + _BEACON_IE_OFFSET_
14906 , ptxBeacon_parm->network.IELength - _BEACON_IE_OFFSET_
14907 , pmlmeinfo->hidden_ssid_mode
14909 ptxBeacon_parm->network.IELength += len_diff;
14911 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
14913 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
14923 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
14925 u8 evt_code, evt_seq;
14928 void (*event_callback)(_adapter *dev, u8 *pbuf);
14929 struct evt_priv *pevt_priv = &(padapter->evtpriv);
14932 goto _abort_event_;
14934 peventbuf = (uint *)pbuf;
14935 evt_sz = (u16)(*peventbuf & 0xffff);
14936 evt_seq = (u8)((*peventbuf >> 24) & 0x7f);
14937 evt_code = (u8)((*peventbuf >> 16) & 0xff);
14940 #ifdef CHECK_EVENT_SEQ
14941 /* checking event sequence... */
14942 if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)) {
14944 pevt_priv->event_seq = (evt_seq + 1) & 0x7f;
14946 goto _abort_event_;
14950 /* checking if event code is valid */
14951 if (evt_code >= MAX_C2HEVT) {
14952 goto _abort_event_;
14955 /* checking if event size match the event parm size */
14956 if ((wlanevents[evt_code].parmsize != 0) &&
14957 (wlanevents[evt_code].parmsize != evt_sz)) {
14959 goto _abort_event_;
14963 ATOMIC_INC(&pevt_priv->event_seq);
14968 event_callback = wlanevents[evt_code].event_callback;
14969 event_callback(padapter, (u8 *)peventbuf);
14971 pevt_priv->evt_done_cnt++;
14978 return H2C_SUCCESS;
14982 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
14985 return H2C_PARAMETERS_ERROR;
14987 return H2C_SUCCESS;
14990 u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
14992 #ifdef CONFIG_AP_MODE
14994 struct sta_info *psta_bmc;
14995 _list *xmitframe_plist, *xmitframe_phead;
14996 struct xmit_frame *pxmitframe = NULL;
14997 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
14998 struct sta_priv *pstapriv = &padapter->stapriv;
15000 /* for BC/MC Frames */
15001 psta_bmc = rtw_get_bcmc_stainfo(padapter);
15003 return H2C_SUCCESS;
15005 if ((pstapriv->tim_bitmap & BIT(0)) && (psta_bmc->sleepq_len > 0)) {
15006 #ifndef CONFIG_PCI_HCI
15007 rtw_msleep_os(10);/* 10ms, ATIM(HIQ) Windows */
15009 /* _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
15010 _enter_critical_bh(&pxmitpriv->lock, &irqL);
15012 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
15013 xmitframe_plist = get_next(xmitframe_phead);
15015 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
15016 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
15018 xmitframe_plist = get_next(xmitframe_plist);
15020 rtw_list_delete(&pxmitframe->list);
15022 psta_bmc->sleepq_len--;
15023 if (psta_bmc->sleepq_len > 0)
15024 pxmitframe->attrib.mdata = 1;
15026 pxmitframe->attrib.mdata = 0;
15028 pxmitframe->attrib.triggered = 1;
15030 if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
15031 pxmitframe->attrib.qsel = QSLT_HIGH;/* HIQ */
15034 _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15035 if (rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
15036 rtw_os_xmit_complete(padapter, pxmitframe);
15037 _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15039 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
15042 /* _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
15043 _exit_critical_bh(&pxmitpriv->lock, &irqL);
15045 if (rtw_get_intf_type(padapter) != RTW_PCIE) {
15046 /* check hi queue and bmc_sleepq */
15047 rtw_chk_hi_queue_cmd(padapter);
15052 return H2C_SUCCESS;
15055 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
15058 #ifdef CONFIG_SWTIMER_BASED_TXBCN
15060 tx_beacon_handlder(padapter->dvobj);
15064 if (send_beacon(padapter) == _FAIL) {
15065 RTW_INFO("issue_beacon, fail!\n");
15066 return H2C_PARAMETERS_ERROR;
15069 /* tx bc/mc frames after update TIM */
15070 chk_bmc_sleepq_hdl(padapter, NULL);
15073 return H2C_SUCCESS;
15077 * according to channel
15078 * add/remove WLAN_BSSID_EX.IEs's ERP ie
15079 * set WLAN_BSSID_EX.SupportedRates
15080 * update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
15082 void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
15084 u8 network_type, rate_len, total_rate_len, remainder_rate_len;
15085 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
15086 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15090 network_type = WIRELESS_11A;
15091 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
15092 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
15094 network_type = WIRELESS_11BG;
15095 total_rate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
15096 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
15099 rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
15101 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
15103 if (total_rate_len > 8) {
15105 remainder_rate_len = total_rate_len - 8;
15107 rate_len = total_rate_len;
15108 remainder_rate_len = 0;
15111 rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
15113 if (remainder_rate_len)
15114 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates + 8), remainder_rate_len);
15116 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
15118 pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
15121 void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
15123 #define DUMP_ADAPTERS_STATUS 0
15125 struct dvobj_priv *dvobj;
15127 struct mlme_priv *mlme;
15128 struct mlme_ext_priv *mlmeext;
15129 u8 u_ch, u_offset, u_bw;
15132 dvobj = adapter_to_dvobj(adapter);
15134 if (DUMP_ADAPTERS_STATUS) {
15135 RTW_INFO(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
15136 dump_adapters_status(RTW_DBGDUMP , dvobj);
15139 if (join_res >= 0) {
15141 #ifdef CONFIG_MCC_MODE
15142 /* MCC setting success, don't go to ch union process */
15143 if (rtw_hal_set_mcc_setting_join_done_chk_ch(adapter))
15145 #endif /* CONFIG_MCC_MODE */
15147 if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
15148 dump_adapters_status(RTW_DBGDUMP , dvobj);
15152 for (i = 0; i < dvobj->iface_nums; i++) {
15153 iface = dvobj->padapters[i];
15154 mlme = &iface->mlmepriv;
15155 mlmeext = &iface->mlmeextpriv;
15157 if (!iface || iface == adapter)
15160 if (check_fwstate(mlme, WIFI_AP_STATE)
15161 && check_fwstate(mlme, WIFI_ASOC_STATE)
15163 bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
15164 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
15166 if (is_grouped == _FALSE) {
15167 /* handle AP which need to switch ch setting */
15169 /* restore original bw, adjust bw by registry setting on target ch */
15170 mlmeext->cur_bwmode = mlme->ori_bw;
15171 mlmeext->cur_channel = u_ch;
15172 rtw_adjust_chbw(iface
15173 , mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
15175 rtw_sync_chbw(&mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
15176 , &u_ch, &u_bw, &u_offset);
15178 rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
15179 , mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
15181 _rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
15183 rtw_start_bss_hdl_after_chbw_decided(iface);
15186 update_beacon(iface, 0, NULL, _TRUE);
15189 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15192 #ifdef CONFIG_DFS_MASTER
15193 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTED);
15196 for (i = 0; i < dvobj->iface_nums; i++) {
15197 iface = dvobj->padapters[i];
15198 mlme = &iface->mlmepriv;
15199 mlmeext = &iface->mlmeextpriv;
15201 if (!iface || iface == adapter)
15204 if (check_fwstate(mlme, WIFI_AP_STATE)
15205 && check_fwstate(mlme, WIFI_ASOC_STATE))
15206 update_beacon(iface, 0, NULL, _TRUE);
15208 clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15210 #ifdef CONFIG_DFS_MASTER
15211 rtw_dfs_master_status_apply(adapter, MLME_STA_DISCONNECTED);
15215 if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) {
15216 set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
15217 rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw);
15220 if (DUMP_ADAPTERS_STATUS) {
15221 RTW_INFO(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
15222 dump_adapters_status(RTW_DBGDUMP , dvobj);
15226 int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
15228 bool chbw_allow = _TRUE;
15229 bool connect_allow = _TRUE;
15230 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
15231 u8 cur_ch, cur_bw, cur_ch_offset;
15232 u8 u_ch, u_offset, u_bw;
15234 u_ch = cur_ch = pmlmeext->cur_channel;
15235 u_bw = cur_bw = pmlmeext->cur_bwmode;
15236 u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
15238 if (!ch || !bw || !offset) {
15239 connect_allow = _FALSE;
15245 connect_allow = _FALSE;
15246 RTW_ERR(FUNC_ADPT_FMT" cur_ch:%u\n"
15247 , FUNC_ADPT_ARG(adapter), cur_ch);
15251 RTW_INFO(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15253 #ifdef CONFIG_CONCURRENT_MODE
15255 struct dvobj_priv *dvobj;
15257 struct mlme_priv *mlme;
15258 struct mlme_ext_priv *mlmeext;
15259 struct mi_state mstate;
15262 dvobj = adapter_to_dvobj(adapter);
15264 rtw_mi_status_no_self(adapter, &mstate);
15265 RTW_INFO(FUNC_ADPT_FMT" ld_sta_num:%u, ap_num:%u\n"
15266 , FUNC_ADPT_ARG(adapter), MSTATE_STA_LD_NUM(&mstate), MSTATE_AP_NUM(&mstate));
15268 if (!MSTATE_STA_LD_NUM(&mstate) && !MSTATE_AP_NUM(&mstate)) {
15269 /* consider linking STA? */
15270 goto connect_allow_hdl;
15273 if (rtw_mi_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
15274 dump_adapters_status(RTW_DBGDUMP , dvobj);
15277 RTW_INFO(FUNC_ADPT_FMT" union no self: %u,%u,%u\n"
15278 , FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15281 chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
15282 , u_ch, u_bw, u_offset);
15284 RTW_INFO(FUNC_ADPT_FMT" chbw_allow:%d\n"
15285 , FUNC_ADPT_ARG(adapter), chbw_allow);
15287 #ifdef CONFIG_MCC_MODE
15288 /* check setting success, don't go to ch union process */
15289 if (rtw_hal_set_mcc_setting_chk_start_clnt_join(adapter, &u_ch, &u_bw, &u_offset, chbw_allow))
15293 if (chbw_allow == _TRUE) {
15294 rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
15295 rtw_warn_on(cur_ch != pmlmeext->cur_channel);
15296 rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
15297 rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
15298 goto connect_allow_hdl;
15301 #ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
15302 /* chbw_allow is _FALSE, connect allow? */
15303 for (i = 0; i < dvobj->iface_nums; i++) {
15304 iface = dvobj->padapters[i];
15305 mlme = &iface->mlmepriv;
15306 mlmeext = &iface->mlmeextpriv;
15308 if (check_fwstate(mlme, WIFI_STATION_STATE)
15309 && check_fwstate(mlme, WIFI_ASOC_STATE)
15310 #if defined(CONFIG_P2P)
15311 && rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
15314 connect_allow = _FALSE;
15318 #endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
15320 if (MSTATE_STA_LD_NUM(&mstate) + MSTATE_AP_LD_NUM(&mstate) >= 2)
15321 connect_allow = _FALSE;
15323 RTW_INFO(FUNC_ADPT_FMT" connect_allow:%d\n"
15324 , FUNC_ADPT_ARG(adapter), connect_allow);
15326 if (connect_allow == _FALSE)
15330 /* connect_allow == _TRUE */
15332 #ifdef CONFIG_DFS_MASTER
15333 rtw_dfs_master_status_apply(adapter, MLME_STA_CONNECTING);
15336 if (chbw_allow == _FALSE) {
15339 u_offset = cur_ch_offset;
15341 for (i = 0; i < dvobj->iface_nums; i++) {
15342 iface = dvobj->padapters[i];
15343 mlme = &iface->mlmepriv;
15344 mlmeext = &iface->mlmeextpriv;
15346 if (!iface || iface == adapter)
15349 if (check_fwstate(mlme, WIFI_AP_STATE)
15350 && check_fwstate(mlme, WIFI_ASOC_STATE)
15352 #ifdef CONFIG_SPCT_CH_SWITCH
15354 rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
15357 rtw_sta_flush(iface, _FALSE);
15359 rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
15360 set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
15361 } else if (check_fwstate(mlme, WIFI_STATION_STATE)
15362 && check_fwstate(mlme, WIFI_ASOC_STATE)
15364 rtw_disassoc_cmd(iface, 500, RTW_CMDF_DIRECTLY);
15365 rtw_indicate_disconnect(iface, 0, _FALSE);
15366 rtw_free_assoc_resources(iface, 1);
15371 #endif /* CONFIG_CONCURRENT_MODE */
15375 if (connect_allow == _TRUE) {
15376 RTW_INFO(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
15379 *offset = u_offset;
15382 return connect_allow == _TRUE ? _SUCCESS : _FAIL;
15386 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
15388 struct set_ch_parm *set_ch_parm;
15389 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
15390 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15393 return H2C_PARAMETERS_ERROR;
15395 set_ch_parm = (struct set_ch_parm *)pbuf;
15397 RTW_INFO(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
15398 FUNC_NDEV_ARG(padapter->pnetdev),
15399 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
15401 pmlmeext->cur_channel = set_ch_parm->ch;
15402 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
15403 pmlmeext->cur_bwmode = set_ch_parm->bw;
15405 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
15407 return H2C_SUCCESS;
15410 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
15412 struct SetChannelPlan_param *setChannelPlan_param;
15413 struct mlme_priv *mlme = &padapter->mlmepriv;
15414 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15417 return H2C_PARAMETERS_ERROR;
15419 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
15421 if (!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan))
15422 return H2C_PARAMETERS_ERROR;
15424 mlme->country_ent = setChannelPlan_param->country_ent;
15425 mlme->ChannelPlan = setChannelPlan_param->channel_plan;
15427 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
15428 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
15430 rtw_hal_set_odm_var(padapter, HAL_ODM_REGULATION, NULL, _TRUE);
15432 #ifdef CONFIG_IOCTL_CFG80211
15433 rtw_reg_notify_by_driver(padapter);
15434 #endif /* CONFIG_IOCTL_CFG80211 */
15436 return H2C_SUCCESS;
15439 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
15441 struct LedBlink_param *ledBlink_param;
15444 return H2C_PARAMETERS_ERROR;
15446 ledBlink_param = (struct LedBlink_param *)pbuf;
15448 #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
15449 BlinkHandler((PLED_DATA)ledBlink_param->pLed);
15452 return H2C_SUCCESS;
15455 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
15458 struct SetChannelSwitch_param *setChannelSwitch_param;
15460 u8 gval8 = 0x00, sval8 = 0xff;
15463 return H2C_PARAMETERS_ERROR;
15465 setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
15466 new_ch_no = setChannelSwitch_param->new_ch_no;
15468 rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15470 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
15472 RTW_INFO("DFS detected! Swiching channel to %d!\n", new_ch_no);
15473 set_channel_bwmode(padapter, new_ch_no, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
15475 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
15477 rtw_disassoc_cmd(padapter, 0, RTW_CMDF_DIRECTLY);
15478 rtw_indicate_disconnect(padapter, 0, _FALSE);
15479 rtw_free_assoc_resources(padapter, 1);
15480 rtw_free_network_queue(padapter, _TRUE);
15482 if (((new_ch_no >= 52) && (new_ch_no <= 64)) || ((new_ch_no >= 100) && (new_ch_no <= 140)))
15483 RTW_INFO("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
15485 return H2C_SUCCESS;
15487 return H2C_REJECTED;
15488 #endif /* CONFIG_DFS */
15492 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
15496 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
15497 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
15498 #ifdef CONFIG_TDLS_CH_SW
15499 struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
15501 struct TDLSoption_param *TDLSoption;
15502 struct sta_info *ptdls_sta = NULL;
15503 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15504 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
15505 u8 survey_channel, i, min, option;
15506 struct tdls_txmgmt txmgmt;
15507 u32 setchtime, resp_sleep = 0, wait_time;
15508 u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15513 return H2C_PARAMETERS_ERROR;
15515 TDLSoption = (struct TDLSoption_param *)pbuf;
15516 option = TDLSoption->option;
15518 if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
15519 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), TDLSoption->addr);
15520 if (ptdls_sta == NULL)
15521 return H2C_REJECTED;
15523 if (!(option == TDLS_RS_RCR))
15524 return H2C_REJECTED;
15527 /* _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
15528 /* RTW_INFO("[%s] option:%d\n", __FUNCTION__, option); */
15531 case TDLS_ESTABLISHED: {
15532 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
15533 /* So we can receive all kinds of data frames. */
15536 /* leave ALL PS when TDLS is established */
15537 rtw_pwr_wakeup(padapter);
15539 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
15540 RTW_INFO("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
15542 /* Set TDLS sta rate. */
15543 /* Update station supportRate */
15544 rtw_hal_update_sta_rate_mask(padapter, ptdls_sta);
15545 if (pmlmeext->cur_channel > 14) {
15546 if (ptdls_sta->ra_mask & 0xffff000)
15547 sta_band |= WIRELESS_11_5N ;
15549 if (ptdls_sta->ra_mask & 0xff0)
15550 sta_band |= WIRELESS_11A;
15553 #ifdef CONFIG_80211AC_VHT
15554 if (ptdls_sta->vhtpriv.vht_option)
15555 sta_band = WIRELESS_11_5AC;
15559 if (ptdls_sta->ra_mask & 0xffff000)
15560 sta_band |= WIRELESS_11_24N;
15562 if (ptdls_sta->ra_mask & 0xff0)
15563 sta_band |= WIRELESS_11G;
15565 if (ptdls_sta->ra_mask & 0x0f)
15566 sta_band |= WIRELESS_11B;
15568 ptdls_sta->wireless_mode = sta_band;
15569 ptdls_sta->raid = rtw_hal_networktype_to_raid(padapter, ptdls_sta);
15570 set_sta_rate(padapter, ptdls_sta);
15571 rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
15573 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta, _TRUE);
15576 case TDLS_ISSUE_PTI:
15577 ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
15578 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
15579 _set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
15581 #ifdef CONFIG_TDLS_CH_SW
15582 case TDLS_CH_SW_RESP:
15583 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15584 txmgmt.status_code = 0;
15585 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15587 issue_nulldata(padapter, NULL, 1, 3, 3);
15589 RTW_INFO("[TDLS ] issue tdls channel switch response\n");
15590 ret = issue_tdls_ch_switch_rsp(padapter, &txmgmt, _TRUE);
15592 /* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
15593 /* then we just switch to AP's channel*/
15594 if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
15595 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_END_TO_BASE_CHNL);
15599 if (ret == _SUCCESS)
15600 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_OFF_CHNL);
15602 RTW_INFO("[TDLS] issue_tdls_ch_switch_rsp wait ack fail !!!!!!!!!!\n");
15605 case TDLS_CH_SW_PREPARE:
15606 pchsw_info->ch_sw_state |= TDLS_CH_SWITCH_PREPARE_STATE;
15608 /* to collect IQK info of off-chnl */
15610 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15611 set_channel_bwmode(padapter, pchsw_info->off_ch_num, pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20);
15613 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
15615 /* switch back to base-chnl */
15616 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
15618 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_START);
15620 pchsw_info->ch_sw_state &= ~(TDLS_CH_SWITCH_PREPARE_STATE);
15623 case TDLS_CH_SW_START:
15624 rtw_tdls_set_ch_sw_oper_control(padapter, _TRUE);
15626 case TDLS_CH_SW_TO_OFF_CHNL:
15627 issue_nulldata(padapter, NULL, 1, 3, 3);
15629 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15630 _set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout) / 1000);
15632 if (rtw_tdls_do_ch_sw(padapter, ptdls_sta, TDLS_CH_SW_OFF_CHNL, pchsw_info->off_ch_num,
15633 pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20, ptdls_sta->ch_switch_time) == _SUCCESS) {
15634 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
15635 if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) {
15636 if (issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->hwaddr, 0, 1, 3) == _FAIL)
15637 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15642 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15643 _cancel_timer(&ptdls_sta->ch_sw_timer, &bcancelled);
15648 case TDLS_CH_SW_END:
15649 case TDLS_CH_SW_END_TO_BASE_CHNL:
15650 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15651 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
15652 _cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
15653 _cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
15655 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_base_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_base_chnl));
15656 _rtw_memset(pHalData->tdls_ch_sw_iqk_info_off_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_off_chnl));
15659 if (option == TDLS_CH_SW_END_TO_BASE_CHNL)
15660 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CH_SW_TO_BASE_CHNL);
15663 case TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED:
15664 case TDLS_CH_SW_TO_BASE_CHNL:
15665 pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
15667 if (option == TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED) {
15668 if (ptdls_sta != NULL) {
15669 /* Send unsolicited channel switch rsp. to peer */
15670 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15671 txmgmt.status_code = 0;
15672 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15673 issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
15677 if (rtw_tdls_do_ch_sw(padapter, ptdls_sta, TDLS_CH_SW_BASE_CHNL, pmlmeext->cur_channel,
15678 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode, ptdls_sta->ch_switch_time) == _SUCCESS) {
15679 issue_nulldata(padapter, NULL, 0, 3, 3);
15680 /* set ch sw monitor timer for responder */
15681 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
15682 _set_timer(&ptdls_sta->ch_sw_monitor_timer, TDLS_CH_SW_MONITOR_TIMEOUT);
15688 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
15689 RTW_INFO("[TDLS] write REG_RCR, set bit6 on\n");
15691 case TDLS_TEARDOWN_STA:
15692 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
15693 txmgmt.status_code = 0;
15694 _rtw_memcpy(txmgmt.peer, ptdls_sta->hwaddr, ETH_ALEN);
15696 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
15698 case TDLS_TEARDOWN_STA_LOCALLY:
15699 #ifdef CONFIG_TDLS_CH_SW
15700 if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
15701 pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
15702 TDLS_CH_SWITCH_ON_STATE |
15703 TDLS_PEER_AT_OFF_STATE);
15704 rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
15705 _rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
15708 rtw_sta_media_status_rpt(padapter, ptdls_sta, 0);
15709 free_tdls_sta(padapter, ptdls_sta);
15713 /* _exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
15715 return H2C_SUCCESS;
15717 return H2C_REJECTED;
15718 #endif /* CONFIG_TDLS */
15722 u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
15724 struct RunInThread_param *p;
15728 return H2C_PARAMETERS_ERROR;
15729 p = (struct RunInThread_param *)pbuf;
15732 p->func(p->context);
15734 return H2C_SUCCESS;
15737 u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf)
15740 struct readMAC_parm *preadmacparm = NULL;
15746 return H2C_PARAMETERS_ERROR;
15748 preadmacparm = (struct readMAC_parm *) pbuf;
15749 sz = preadmacparm->len;
15750 addr = preadmacparm->addr;
15755 value = rtw_read8(padapter, addr);
15758 value = rtw_read16(padapter, addr);
15761 value = rtw_read32(padapter, addr);
15764 RTW_INFO("%s: Unknown size\n", __func__);
15767 RTW_INFO("%s: addr:0x%02x valeu:0x%02x\n", __func__, addr, value);
15769 return H2C_SUCCESS;