1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 #define _RTW_MLME_EXT_C_ 8 9 #include <drv_types.h> 10 #include <rtw_debug.h> 11 #include <rtw_wifi_regd.h> 12 #include <hal_btcoex.h> 13 #include <linux/kernel.h> 14 15 static struct mlme_handler mlme_sta_tbl[] = { 16 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, 17 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, 18 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq}, 19 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp}, 20 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq}, 21 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp}, 22 23 /*---------------------------------------------------------- 24 below 2 are reserved 25 -----------------------------------------------------------*/ 26 {0, "DoReserved", &DoReserved}, 27 {0, "DoReserved", &DoReserved}, 28 {WIFI_BEACON, "OnBeacon", &OnBeacon}, 29 {WIFI_ATIM, "OnATIM", &OnAtim}, 30 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc}, 31 {WIFI_AUTH, "OnAuth", &OnAuthClient}, 32 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth}, 33 {WIFI_ACTION, "OnAction", &OnAction}, 34 {WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction}, 35 }; 36 37 static struct action_handler OnAction_tbl[] = { 38 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct}, 39 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &DoReserved}, 40 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &DoReserved}, 41 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back}, 42 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public}, 43 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved}, 44 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved}, 45 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht}, 46 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query}, 47 {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved}, 48 {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved}, 49 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &DoReserved}, 50 {RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &DoReserved}, 51 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &DoReserved}, 52 }; 53 54 static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; 55 56 /************************************************** 57 OUI definitions for the vendor specific IE 58 ***************************************************/ 59 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; 60 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; 61 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; 62 unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09}; 63 unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A}; 64 65 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; 66 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; 67 68 static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20}; 69 70 /******************************************************** 71 ChannelPlan definitions 72 *********************************************************/ 73 static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = { 74 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */ 75 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */ 76 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */ 77 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */ 78 {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */ 79 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x05, RT_CHANNEL_DOMAIN_2G_GLOBAL , Passive scan CH 12, 13, 14 */ 80 {{}, 0}, /* 0x06, RT_CHANNEL_DOMAIN_2G_NULL */ 81 }; 82 83 static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = { 84 {{}, 0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */ 85 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */ 86 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */ 87 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22}, /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */ 88 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */ 89 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */ 90 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */ 91 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */ 92 {{149, 153, 157, 161, 165}, 5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */ 93 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */ 94 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20}, /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */ 95 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20}, /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */ 96 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */ 97 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */ 98 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */ 99 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */ 100 {{56, 60, 64, 149, 153, 157, 161, 165}, 8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */ 101 {{149, 153, 157, 161, 165}, 5}, /* 0x11, RT_CHANNEL_DOMAIN_5G_NCC3 */ 102 {{36, 40, 44, 48}, 4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_ETSI4 */ 103 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20}, /* 0x13, RT_CHANNEL_DOMAIN_5G_ETSI5 */ 104 {{149, 153, 157, 161}, 4}, /* 0x14, RT_CHANNEL_DOMAIN_5G_FCC8 */ 105 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x15, RT_CHANNEL_DOMAIN_5G_ETSI6 */ 106 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, /* 0x16, RT_CHANNEL_DOMAIN_5G_ETSI7 */ 107 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, /* 0x17, RT_CHANNEL_DOMAIN_5G_ETSI8 */ 108 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, /* 0x18, RT_CHANNEL_DOMAIN_5G_ETSI9 */ 109 {{149, 153, 157, 161, 165}, 5}, /* 0x19, RT_CHANNEL_DOMAIN_5G_ETSI10 */ 110 {{36, 40, 44, 48, 52, 56, 60, 64, 132, 136, 140, 149, 153, 157, 161, 165}, 16}, /* 0x1A, RT_CHANNEL_DOMAIN_5G_ETSI11 */ 111 {{52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17}, /* 0x1B, RT_CHANNEL_DOMAIN_5G_NCC4 */ 112 {{149, 153, 157, 161}, 4}, /* 0x1C, RT_CHANNEL_DOMAIN_5G_ETSI12 */ 113 {{36, 40, 44, 48, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 17}, /* 0x1D, RT_CHANNEL_DOMAIN_5G_FCC9 */ 114 {{36, 40, 44, 48, 100, 104, 108, 112, 116, 132, 136, 140}, 12}, /* 0x1E, RT_CHANNEL_DOMAIN_5G_ETSI13 */ 115 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161}, 20}, /* 0x1F, RT_CHANNEL_DOMAIN_5G_FCC10 */ 116 117 /* Driver self defined for old channel plan Compatible , Remember to modify if have new channel plan definition ===== */ 118 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21}, /* 0x20, RT_CHANNEL_DOMAIN_5G_FCC */ 119 {{36, 40, 44, 48}, 4}, /* 0x21, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */ 120 {{36, 40, 44, 48, 149, 153, 157, 161}, 8}, /* 0x22, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */ 121 }; 122 123 static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { 124 /* 0x00 ~ 0x1F , Old Define ===== */ 125 {0x02, 0x20}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */ 126 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */ 127 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */ 128 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */ 129 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */ 130 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */ 131 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */ 132 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */ 133 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */ 134 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */ 135 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */ 136 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */ 137 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */ 138 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */ 139 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */ 140 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */ 141 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */ 142 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */ 143 {0x01, 0x21}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */ 144 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */ 145 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */ 146 {0x00, 0x21}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */ 147 {0x00, 0x22}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */ 148 {0x03, 0x21}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */ 149 {0x06, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */ 150 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */ 151 {0x00, 0x00}, /* 0x1A, */ 152 {0x00, 0x00}, /* 0x1B, */ 153 {0x00, 0x00}, /* 0x1C, */ 154 {0x00, 0x00}, /* 0x1D, */ 155 {0x00, 0x00}, /* 0x1E, */ 156 {0x06, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */ 157 /* 0x20 ~ 0x7F , New Define ===== */ 158 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */ 159 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */ 160 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */ 161 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */ 162 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */ 163 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */ 164 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */ 165 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */ 166 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */ 167 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */ 168 {0x00, 0x00}, /* 0x2A, */ 169 {0x00, 0x00}, /* 0x2B, */ 170 {0x00, 0x00}, /* 0x2C, */ 171 {0x00, 0x00}, /* 0x2D, */ 172 {0x00, 0x00}, /* 0x2E, */ 173 {0x00, 0x00}, /* 0x2F, */ 174 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */ 175 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */ 176 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */ 177 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */ 178 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */ 179 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */ 180 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */ 181 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */ 182 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */ 183 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */ 184 {0x00, 0x00}, /* 0x3A, */ 185 {0x00, 0x00}, /* 0x3B, */ 186 {0x00, 0x00}, /* 0x3C, */ 187 {0x00, 0x00}, /* 0x3D, */ 188 {0x00, 0x00}, /* 0x3E, */ 189 {0x00, 0x00}, /* 0x3F, */ 190 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */ 191 {0x05, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL */ 192 {0x01, 0x12}, /* 0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4 */ 193 {0x02, 0x05}, /* 0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2 */ 194 {0x02, 0x11}, /* 0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3 */ 195 {0x00, 0x13}, /* 0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5 */ 196 {0x02, 0x14}, /* 0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8 */ 197 {0x00, 0x15}, /* 0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6 */ 198 {0x00, 0x16}, /* 0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7 */ 199 {0x00, 0x17}, /* 0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8 */ 200 {0x00, 0x18}, /* 0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9 */ 201 {0x00, 0x19}, /* 0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10 */ 202 {0x00, 0x1A}, /* 0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11 */ 203 {0x02, 0x1B}, /* 0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4 */ 204 {0x00, 0x1C}, /* 0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12 */ 205 {0x02, 0x1D}, /* 0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9 */ 206 {0x00, 0x1E}, /* 0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13 */ 207 {0x02, 0x1F}, /* 0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 */ 208 }; 209 210 /* use the combination for max channel numbers */ 211 static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02}; 212 213 /* Search the @param ch in given @param ch_set 214 * @ch_set: the given channel set 215 * @ch: the given channel number 216 * 217 * return the index of channel_num in channel_set, -1 if not found 218 */ 219 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch) 220 { 221 int i; 222 223 for (i = 0; ch_set[i].ChannelNum != 0; i++) { 224 if (ch == ch_set[i].ChannelNum) 225 break; 226 } 227 228 if (i >= ch_set[i].ChannelNum) 229 return -1; 230 return i; 231 } 232 233 /* Check the @param ch is fit with setband setting of @param adapter 234 * @adapter: the given adapter 235 * @ch: the given channel number 236 * 237 * return true when check valid, false not valid 238 */ 239 bool rtw_mlme_band_check(struct adapter *adapter, const u32 ch) 240 { 241 if (adapter->setband == GHZ24_50 /* 2.4G and 5G */ 242 || (adapter->setband == GHZ_24 && ch < 35) /* 2.4G only */ 243 || (adapter->setband == GHZ_50 && ch > 35) /* 5G only */ 244 ) { 245 return true; 246 } 247 return false; 248 } 249 250 /**************************************************************************** 251 252 Following are the initialization functions for WiFi MLME 253 254 *****************************************************************************/ 255 256 int init_hw_mlme_ext(struct adapter *padapter) 257 { 258 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 259 260 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); 261 return _SUCCESS; 262 } 263 264 void init_mlme_default_rate_set(struct adapter *padapter) 265 { 266 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 267 268 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}; 269 unsigned char mixed_basicrate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,}; 270 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0x00, 0x00, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; 271 272 memcpy(pmlmeext->datarate, mixed_datarate, NumRates); 273 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates); 274 275 memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set)); 276 } 277 278 static void init_mlme_ext_priv_value(struct adapter *padapter) 279 { 280 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 281 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 282 283 atomic_set(&pmlmeext->event_seq, 0); 284 pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */ 285 pmlmeext->sa_query_seq = 0; 286 pmlmeext->mgnt_80211w_IPN = 0; 287 pmlmeext->mgnt_80211w_IPN_rx = 0; 288 pmlmeext->cur_channel = padapter->registrypriv.channel; 289 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 290 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 291 292 pmlmeext->retry = 0; 293 294 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode; 295 296 init_mlme_default_rate_set(padapter); 297 298 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB; 299 pmlmeext->sitesurvey_res.state = SCAN_DISABLE; 300 pmlmeext->sitesurvey_res.channel_idx = 0; 301 pmlmeext->sitesurvey_res.bss_cnt = 0; 302 pmlmeext->scan_abort = false; 303 304 pmlmeinfo->state = WIFI_FW_NULL_STATE; 305 pmlmeinfo->reauth_count = 0; 306 pmlmeinfo->reassoc_count = 0; 307 pmlmeinfo->link_count = 0; 308 pmlmeinfo->auth_seq = 0; 309 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; 310 pmlmeinfo->key_index = 0; 311 pmlmeinfo->iv = 0; 312 313 pmlmeinfo->enc_algo = _NO_PRIVACY_; 314 pmlmeinfo->authModeToggle = 0; 315 316 memset(pmlmeinfo->chg_txt, 0, 128); 317 318 pmlmeinfo->slotTime = SHORT_SLOT_TIME; 319 pmlmeinfo->preamble_mode = PREAMBLE_AUTO; 320 321 pmlmeinfo->dialogToken = 0; 322 323 pmlmeext->action_public_rxseq = 0xffff; 324 pmlmeext->action_public_dialog_token = 0xff; 325 } 326 327 static int has_channel(RT_CHANNEL_INFO *channel_set, 328 u8 chanset_size, 329 u8 chan) 330 { 331 int i; 332 333 for (i = 0; i < chanset_size; i++) { 334 if (channel_set[i].ChannelNum == chan) { 335 return 1; 336 } 337 } 338 339 return 0; 340 } 341 342 static void init_channel_list(struct adapter *padapter, RT_CHANNEL_INFO *channel_set, 343 u8 chanset_size, 344 struct p2p_channels *channel_list) 345 { 346 347 static const struct p2p_oper_class_map op_class[] = { 348 { IEEE80211G, 81, 1, 13, 1, BW20 }, 349 { IEEE80211G, 82, 14, 14, 1, BW20 }, 350 { IEEE80211A, 115, 36, 48, 4, BW20 }, 351 { IEEE80211A, 116, 36, 44, 8, BW40PLUS }, 352 { IEEE80211A, 117, 40, 48, 8, BW40MINUS }, 353 { IEEE80211A, 124, 149, 161, 4, BW20 }, 354 { IEEE80211A, 125, 149, 169, 4, BW20 }, 355 { IEEE80211A, 126, 149, 157, 8, BW40PLUS }, 356 { IEEE80211A, 127, 153, 161, 8, BW40MINUS }, 357 { -1, 0, 0, 0, 0, BW20 } 358 }; 359 360 int cla, op; 361 362 cla = 0; 363 364 for (op = 0; op_class[op].op_class; op++) { 365 u8 ch; 366 const struct p2p_oper_class_map *o = &op_class[op]; 367 struct p2p_reg_class *reg = NULL; 368 369 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { 370 if (!has_channel(channel_set, chanset_size, ch)) 371 continue; 372 373 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc)) 374 continue; 375 376 if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) && 377 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw))) 378 continue; 379 380 if (!reg) { 381 reg = &channel_list->reg_class[cla]; 382 cla++; 383 reg->reg_class = o->op_class; 384 reg->channels = 0; 385 } 386 reg->channel[reg->channels] = ch; 387 reg->channels++; 388 } 389 } 390 channel_list->reg_classes = cla; 391 392 } 393 394 static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set) 395 { 396 u8 index, chanset_size = 0; 397 u8 b5GBand = false, b2_4GBand = false; 398 u8 Index2G = 0, Index5G = 0; 399 400 memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM); 401 402 if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) { 403 DBG_871X("ChannelPlan ID %x error !!!!!\n", ChannelPlan); 404 return chanset_size; 405 } 406 407 if (IsSupported24G(padapter->registrypriv.wireless_mode)) { 408 b2_4GBand = true; 409 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan) 410 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G; 411 else 412 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G; 413 } 414 415 if (b2_4GBand) { 416 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) { 417 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index]; 418 419 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||/* Channel 1~11 is active, and 12~14 is passive */ 420 (RT_CHANNEL_DOMAIN_GLOBAL_NULL == ChannelPlan)) { 421 if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11) 422 channel_set[chanset_size].ScanType = SCAN_ACTIVE; 423 else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14)) 424 channel_set[chanset_size].ScanType = SCAN_PASSIVE; 425 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan || 426 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan || 427 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) { /* channel 12~13, passive scan */ 428 if (channel_set[chanset_size].ChannelNum <= 11) 429 channel_set[chanset_size].ScanType = SCAN_ACTIVE; 430 else 431 channel_set[chanset_size].ScanType = SCAN_PASSIVE; 432 } else 433 channel_set[chanset_size].ScanType = SCAN_ACTIVE; 434 435 chanset_size++; 436 } 437 } 438 439 if (b5GBand) { 440 for (index = 0; index < RTW_ChannelPlan5G[Index5G].Len; index++) { 441 if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48 442 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149) { 443 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index]; 444 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)/* passive scan for all 5G channels */ 445 channel_set[chanset_size].ScanType = SCAN_PASSIVE; 446 else 447 channel_set[chanset_size].ScanType = SCAN_ACTIVE; 448 DBG_871X("%s(): channel_set[%d].ChannelNum = %d\n", __func__, chanset_size, channel_set[chanset_size].ChannelNum); 449 chanset_size++; 450 } 451 } 452 } 453 454 DBG_871X("%s ChannelPlan ID %x Chan num:%d \n", __func__, ChannelPlan, chanset_size); 455 return chanset_size; 456 } 457 458 void init_mlme_ext_priv(struct adapter *padapter) 459 { 460 struct registry_priv *pregistrypriv = &padapter->registrypriv; 461 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 462 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 463 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 464 465 pmlmeext->padapter = padapter; 466 467 /* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */ 468 469 init_mlme_ext_priv_value(padapter); 470 pmlmeinfo->accept_addba_req = pregistrypriv->accept_addba_req; 471 472 init_mlme_ext_timer(padapter); 473 474 init_mlme_ap_info(padapter); 475 476 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set); 477 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); 478 pmlmeext->last_scan_time = 0; 479 pmlmeext->chan_scan_time = SURVEY_TO; 480 pmlmeext->mlmeext_init = true; 481 pmlmeext->active_keep_alive_check = true; 482 483 #ifdef DBG_FIXED_CHAN 484 pmlmeext->fixed_chan = 0xFF; 485 #endif 486 } 487 488 void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) 489 { 490 struct adapter *padapter = pmlmeext->padapter; 491 492 if (!padapter) 493 return; 494 495 if (padapter->bDriverStopped) { 496 del_timer_sync(&pmlmeext->survey_timer); 497 del_timer_sync(&pmlmeext->link_timer); 498 /* del_timer_sync(&pmlmeext->ADDBA_timer); */ 499 } 500 } 501 502 static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame) 503 { 504 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 505 u8 *pframe = precv_frame->u.hdr.rx_data; 506 507 if (ptable->func) { 508 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ 509 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && 510 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) 511 return; 512 513 ptable->func(padapter, precv_frame); 514 } 515 } 516 517 void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame) 518 { 519 int index; 520 struct mlme_handler *ptable; 521 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 522 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 523 u8 *pframe = precv_frame->u.hdr.rx_data; 524 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe)); 525 struct dvobj_priv *psdpriv = padapter->dvobj; 526 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 527 528 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_, 529 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n", 530 GetFrameType(pframe), GetFrameSubType(pframe))); 531 532 if (GetFrameType(pframe) != WIFI_MGT_TYPE) { 533 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe))); 534 return; 535 } 536 537 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ 538 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && 539 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) { 540 return; 541 } 542 543 ptable = mlme_sta_tbl; 544 545 index = GetFrameSubType(pframe) >> 4; 546 547 if (index >= ARRAY_SIZE(mlme_sta_tbl)) { 548 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("Currently we do not support reserved sub-fr-type =%d\n", index)); 549 return; 550 } 551 ptable += index; 552 553 if (psta != NULL) { 554 if (GetRetry(pframe)) { 555 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) { 556 /* drop the duplicate management frame */ 557 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++; 558 DBG_871X("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num); 559 return; 560 } 561 } 562 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num; 563 } 564 565 switch (GetFrameSubType(pframe)) { 566 case WIFI_AUTH: 567 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 568 ptable->func = &OnAuth; 569 else 570 ptable->func = &OnAuthClient; 571 fallthrough; 572 case WIFI_ASSOCREQ: 573 case WIFI_REASSOCREQ: 574 _mgt_dispatcher(padapter, ptable, precv_frame); 575 break; 576 case WIFI_PROBEREQ: 577 _mgt_dispatcher(padapter, ptable, precv_frame); 578 break; 579 case WIFI_BEACON: 580 _mgt_dispatcher(padapter, ptable, precv_frame); 581 break; 582 case WIFI_ACTION: 583 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */ 584 _mgt_dispatcher(padapter, ptable, precv_frame); 585 break; 586 default: 587 _mgt_dispatcher(padapter, ptable, precv_frame); 588 break; 589 } 590 } 591 592 /**************************************************************************** 593 594 Following are the callback functions for each subtype of the management frames 595 596 *****************************************************************************/ 597 598 unsigned int OnProbeReq(struct adapter *padapter, union recv_frame *precv_frame) 599 { 600 unsigned int ielen; 601 unsigned char *p; 602 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 603 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 604 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 605 struct wlan_bssid_ex *cur = &pmlmeinfo->network; 606 u8 *pframe = precv_frame->u.hdr.rx_data; 607 uint len = precv_frame->u.hdr.len; 608 u8 is_valid_p2p_probereq = false; 609 610 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 611 return _SUCCESS; 612 613 if (check_fwstate(pmlmepriv, _FW_LINKED) == false && 614 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == false) { 615 return _SUCCESS; 616 } 617 618 619 /* DBG_871X("+OnProbeReq\n"); */ 620 621 #ifdef CONFIG_AUTO_AP_MODE 622 if (check_fwstate(pmlmepriv, _FW_LINKED) && 623 pmlmepriv->cur_network.join_res) { 624 struct sta_info *psta; 625 u8 *mac_addr, *peer_addr; 626 struct sta_priv *pstapriv = &padapter->stapriv; 627 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A}; 628 /* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */ 629 630 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen, 631 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); 632 633 if (!p || ielen != 14) 634 goto _non_rc_device; 635 636 if (memcmp(p+2, RC_OUI, sizeof(RC_OUI))) 637 goto _non_rc_device; 638 639 if (memcmp(p+6, get_sa(pframe), ETH_ALEN)) { 640 DBG_871X("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __func__, 641 MAC_ARG(get_sa(pframe)), MAC_ARG(p+6)); 642 643 goto _non_rc_device; 644 } 645 646 DBG_871X("%s, got the pairing device("MAC_FMT")\n", __func__, MAC_ARG(get_sa(pframe))); 647 648 /* new a station */ 649 psta = rtw_get_stainfo(pstapriv, get_sa(pframe)); 650 if (psta == NULL) { 651 /* allocate a new one */ 652 DBG_871X("going to alloc stainfo for rc ="MAC_FMT"\n", MAC_ARG(get_sa(pframe))); 653 psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe)); 654 if (!psta) { 655 /* TODO: */ 656 DBG_871X(" Exceed the upper limit of supported clients...\n"); 657 return _SUCCESS; 658 } 659 660 spin_lock_bh(&pstapriv->asoc_list_lock); 661 if (list_empty(&psta->asoc_list)) { 662 psta->expire_to = pstapriv->expire_to; 663 list_add_tail(&psta->asoc_list, &pstapriv->asoc_list); 664 pstapriv->asoc_list_cnt++; 665 } 666 spin_unlock_bh(&pstapriv->asoc_list_lock); 667 668 /* generate pairing ID */ 669 mac_addr = myid(&(padapter->eeprompriv)); 670 peer_addr = psta->hwaddr; 671 psta->pid = (u16)(((mac_addr[4]<<8) + mac_addr[5]) + ((peer_addr[4]<<8) + peer_addr[5])); 672 673 /* update peer stainfo */ 674 psta->isrc = true; 675 /* psta->aid = 0; */ 676 /* psta->mac_id = 2; */ 677 678 /* get a unique AID */ 679 if (psta->aid > 0) { 680 DBG_871X("old AID %d\n", psta->aid); 681 } else { 682 for (psta->aid = 1; psta->aid <= NUM_STA; psta->aid++) 683 if (pstapriv->sta_aid[psta->aid - 1] == NULL) 684 break; 685 686 if (psta->aid > pstapriv->max_num_sta) { 687 psta->aid = 0; 688 DBG_871X("no room for more AIDs\n"); 689 return _SUCCESS; 690 } 691 pstapriv->sta_aid[psta->aid - 1] = psta; 692 DBG_871X("allocate new AID = (%d)\n", psta->aid); 693 } 694 695 psta->qos_option = 1; 696 psta->bw_mode = CHANNEL_WIDTH_20; 697 psta->ieee8021x_blocked = false; 698 psta->htpriv.ht_option = true; 699 psta->htpriv.ampdu_enable = false; 700 psta->htpriv.sgi_20m = false; 701 psta->htpriv.sgi_40m = false; 702 psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 703 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */ 704 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ 705 706 rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, true); 707 708 memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); 709 710 spin_lock_bh(&psta->lock); 711 psta->state |= _FW_LINKED; 712 spin_unlock_bh(&psta->lock); 713 714 report_add_sta_event(padapter, psta->hwaddr, psta->aid); 715 716 } 717 718 issue_probersp(padapter, get_sa(pframe), false); 719 720 return _SUCCESS; 721 722 } 723 724 _non_rc_device: 725 726 return _SUCCESS; 727 728 #endif /* CONFIG_AUTO_AP_MODE */ 729 730 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen, 731 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); 732 733 734 /* check (wildcard) SSID */ 735 if (p != NULL) { 736 if (is_valid_p2p_probereq) 737 goto _issue_probersp; 738 739 if ((ielen != 0 && false == !memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) 740 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode) 741 ) 742 return _SUCCESS; 743 744 _issue_probersp: 745 if ((check_fwstate(pmlmepriv, _FW_LINKED) && 746 pmlmepriv->cur_network.join_res) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 747 /* DBG_871X("+issue_probersp during ap mode\n"); */ 748 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); 749 } 750 751 } 752 753 return _SUCCESS; 754 755 } 756 757 unsigned int OnProbeRsp(struct adapter *padapter, union recv_frame *precv_frame) 758 { 759 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 760 761 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { 762 report_survey_event(padapter, precv_frame); 763 return _SUCCESS; 764 } 765 766 return _SUCCESS; 767 768 } 769 770 unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame) 771 { 772 int cam_idx; 773 struct sta_info *psta; 774 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 775 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 776 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 777 struct sta_priv *pstapriv = &padapter->stapriv; 778 u8 *pframe = precv_frame->u.hdr.rx_data; 779 uint len = precv_frame->u.hdr.len; 780 struct wlan_bssid_ex *pbss; 781 int ret = _SUCCESS; 782 u8 *p = NULL; 783 u32 ielen = 0; 784 785 p = rtw_get_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_); 786 if ((p != NULL) && (ielen > 0)) { 787 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) { 788 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */ 789 DBG_871X("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe))); 790 *(p + 1) = ielen - 1; 791 } 792 } 793 794 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { 795 report_survey_event(padapter, precv_frame); 796 return _SUCCESS; 797 } 798 799 if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { 800 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { 801 /* we should update current network before auth, or some IE is wrong */ 802 pbss = rtw_malloc(sizeof(struct wlan_bssid_ex)); 803 if (pbss) { 804 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { 805 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, true); 806 rtw_get_bcn_info(&(pmlmepriv->cur_network)); 807 } 808 kfree(pbss); 809 } 810 811 /* check the vendor of the assoc AP */ 812 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr)); 813 814 /* update TSF Value */ 815 update_TSF(pmlmeext, pframe, len); 816 817 /* reset for adaptive_early_32k */ 818 pmlmeext->adaptive_tsf_done = false; 819 pmlmeext->DrvBcnEarly = 0xff; 820 pmlmeext->DrvBcnTimeOut = 0xff; 821 pmlmeext->bcn_cnt = 0; 822 memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt)); 823 memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio)); 824 825 /* start auth */ 826 start_clnt_auth(padapter); 827 828 return _SUCCESS; 829 } 830 831 if (((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { 832 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 833 if (psta != NULL) { 834 ret = rtw_check_bcn_info(padapter, pframe, len); 835 if (!ret) { 836 DBG_871X_LEVEL(_drv_always_, "ap has changed, disconnect now\n "); 837 receive_disconnect(padapter, pmlmeinfo->network.MacAddress, 0); 838 return _SUCCESS; 839 } 840 /* update WMM, ERP in the beacon */ 841 /* todo: the timer is used instead of the number of the beacon received */ 842 if ((sta_rx_pkts(psta) & 0xf) == 0) 843 /* DBG_871X("update_bcn_info\n"); */ 844 update_beacon_info(padapter, pframe, len, psta); 845 846 adaptive_early_32k(pmlmeext, pframe, len); 847 } 848 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { 849 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 850 if (psta != NULL) { 851 /* update WMM, ERP in the beacon */ 852 /* todo: the timer is used instead of the number of the beacon received */ 853 if ((sta_rx_pkts(psta) & 0xf) == 0) { 854 /* DBG_871X("update_bcn_info\n"); */ 855 update_beacon_info(padapter, pframe, len, psta); 856 } 857 } else { 858 /* allocate a new CAM entry for IBSS station */ 859 cam_idx = allocate_fw_sta_entry(padapter); 860 if (cam_idx == NUM_STA) 861 goto _END_ONBEACON_; 862 863 /* get supported rate */ 864 if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) { 865 pmlmeinfo->FW_sta_info[cam_idx].status = 0; 866 goto _END_ONBEACON_; 867 } 868 869 /* update TSF Value */ 870 update_TSF(pmlmeext, pframe, len); 871 872 /* report sta add event */ 873 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx); 874 } 875 } 876 } 877 878 _END_ONBEACON_: 879 880 return _SUCCESS; 881 882 } 883 884 unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame) 885 { 886 unsigned int auth_mode, seq, ie_len; 887 unsigned char *sa, *p; 888 u16 algorithm; 889 int status; 890 static struct sta_info stat; 891 struct sta_info *pstat = NULL; 892 struct sta_priv *pstapriv = &padapter->stapriv; 893 struct security_priv *psecuritypriv = &padapter->securitypriv; 894 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 895 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 896 u8 *pframe = precv_frame->u.hdr.rx_data; 897 uint len = precv_frame->u.hdr.len; 898 u8 offset = 0; 899 900 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 901 return _FAIL; 902 903 DBG_871X("+OnAuth\n"); 904 905 sa = GetAddr2Ptr(pframe); 906 907 auth_mode = psecuritypriv->dot11AuthAlgrthm; 908 909 if (GetPrivacy(pframe)) { 910 u8 *iv; 911 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib); 912 913 prxattrib->hdrlen = WLAN_HDR_A3_LEN; 914 prxattrib->encrypt = _WEP40_; 915 916 iv = pframe+prxattrib->hdrlen; 917 prxattrib->key_index = ((iv[3]>>6)&0x3); 918 919 prxattrib->iv_len = 4; 920 prxattrib->icv_len = 4; 921 922 rtw_wep_decrypt(padapter, (u8 *)precv_frame); 923 924 offset = 4; 925 } 926 927 algorithm = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset)); 928 seq = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2)); 929 930 DBG_871X("auth alg =%x, seq =%X\n", algorithm, seq); 931 932 if (auth_mode == 2 && 933 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ && 934 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_) 935 auth_mode = 0; 936 937 if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */ 938 (algorithm == 0 && auth_mode == 1)) { /* rx a open-system auth but shared-key is enabled */ 939 DBG_871X("auth rejected due to bad alg [alg =%d, auth_mib =%d] %02X%02X%02X%02X%02X%02X\n", 940 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]); 941 942 status = _STATS_NO_SUPP_ALG_; 943 944 goto auth_fail; 945 } 946 947 if (rtw_access_ctrl(padapter, sa) == false) { 948 status = _STATS_UNABLE_HANDLE_STA_; 949 goto auth_fail; 950 } 951 952 pstat = rtw_get_stainfo(pstapriv, sa); 953 if (pstat == NULL) { 954 955 /* allocate a new one */ 956 DBG_871X("going to alloc stainfo for sa ="MAC_FMT"\n", MAC_ARG(sa)); 957 pstat = rtw_alloc_stainfo(pstapriv, sa); 958 if (pstat == NULL) { 959 DBG_871X(" Exceed the upper limit of supported clients...\n"); 960 status = _STATS_UNABLE_HANDLE_STA_; 961 goto auth_fail; 962 } 963 964 pstat->state = WIFI_FW_AUTH_NULL; 965 pstat->auth_seq = 0; 966 967 /* pstat->flags = 0; */ 968 /* pstat->capability = 0; */ 969 } else { 970 971 spin_lock_bh(&pstapriv->asoc_list_lock); 972 if (list_empty(&pstat->asoc_list) == false) { 973 list_del_init(&pstat->asoc_list); 974 pstapriv->asoc_list_cnt--; 975 if (pstat->expire_to > 0) { 976 /* TODO: STA re_auth within expire_to */ 977 } 978 } 979 spin_unlock_bh(&pstapriv->asoc_list_lock); 980 981 if (seq == 1) { 982 /* TODO: STA re_auth and auth timeout */ 983 } 984 } 985 986 spin_lock_bh(&pstapriv->auth_list_lock); 987 if (list_empty(&pstat->auth_list)) { 988 989 list_add_tail(&pstat->auth_list, &pstapriv->auth_list); 990 pstapriv->auth_list_cnt++; 991 } 992 spin_unlock_bh(&pstapriv->auth_list_lock); 993 994 if (pstat->auth_seq == 0) 995 pstat->expire_to = pstapriv->auth_to; 996 997 998 if ((pstat->auth_seq + 1) != seq) { 999 DBG_871X("(1)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n", 1000 seq, pstat->auth_seq+1); 1001 status = _STATS_OUT_OF_AUTH_SEQ_; 1002 goto auth_fail; 1003 } 1004 1005 if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) { 1006 if (seq == 1) { 1007 pstat->state &= ~WIFI_FW_AUTH_NULL; 1008 pstat->state |= WIFI_FW_AUTH_SUCCESS; 1009 pstat->expire_to = pstapriv->assoc_to; 1010 pstat->authalg = algorithm; 1011 } else { 1012 DBG_871X("(2)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n", 1013 seq, pstat->auth_seq+1); 1014 status = _STATS_OUT_OF_AUTH_SEQ_; 1015 goto auth_fail; 1016 } 1017 } else { /* shared system or auto authentication */ 1018 if (seq == 1) { 1019 /* prepare for the challenging txt... */ 1020 memset((void *)pstat->chg_txt, 78, 128); 1021 1022 pstat->state &= ~WIFI_FW_AUTH_NULL; 1023 pstat->state |= WIFI_FW_AUTH_STATE; 1024 pstat->authalg = algorithm; 1025 pstat->auth_seq = 2; 1026 } else if (seq == 3) { 1027 /* checking for challenging txt... */ 1028 DBG_871X("checking for challenging txt...\n"); 1029 1030 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&ie_len, 1031 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4); 1032 1033 if ((p == NULL) || (ie_len <= 0)) { 1034 DBG_871X("auth rejected because challenge failure!(1)\n"); 1035 status = _STATS_CHALLENGE_FAIL_; 1036 goto auth_fail; 1037 } 1038 1039 if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) { 1040 pstat->state &= (~WIFI_FW_AUTH_STATE); 1041 pstat->state |= WIFI_FW_AUTH_SUCCESS; 1042 /* challenging txt is correct... */ 1043 pstat->expire_to = pstapriv->assoc_to; 1044 } else { 1045 DBG_871X("auth rejected because challenge failure!\n"); 1046 status = _STATS_CHALLENGE_FAIL_; 1047 goto auth_fail; 1048 } 1049 } else { 1050 DBG_871X("(3)auth rejected because out of seq [rx_seq =%d, exp_seq =%d]!\n", 1051 seq, pstat->auth_seq+1); 1052 status = _STATS_OUT_OF_AUTH_SEQ_; 1053 goto auth_fail; 1054 } 1055 } 1056 1057 1058 /* Now, we are going to issue_auth... */ 1059 pstat->auth_seq = seq + 1; 1060 1061 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_)); 1062 1063 if (pstat->state & WIFI_FW_AUTH_SUCCESS) 1064 pstat->auth_seq = 0; 1065 1066 1067 return _SUCCESS; 1068 1069 auth_fail: 1070 1071 if (pstat) 1072 rtw_free_stainfo(padapter, pstat); 1073 1074 pstat = &stat; 1075 memset((char *)pstat, '\0', sizeof(stat)); 1076 pstat->auth_seq = 2; 1077 memcpy(pstat->hwaddr, sa, 6); 1078 1079 issue_auth(padapter, pstat, (unsigned short)status); 1080 1081 return _FAIL; 1082 1083 } 1084 1085 unsigned int OnAuthClient(struct adapter *padapter, union recv_frame *precv_frame) 1086 { 1087 unsigned int seq, len, status, offset; 1088 unsigned char *p; 1089 unsigned int go2asoc = 0; 1090 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1091 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1092 u8 *pframe = precv_frame->u.hdr.rx_data; 1093 uint pkt_len = precv_frame->u.hdr.len; 1094 1095 DBG_871X("%s\n", __func__); 1096 1097 /* check A1 matches or not */ 1098 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN)) 1099 return _SUCCESS; 1100 1101 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) 1102 return _SUCCESS; 1103 1104 offset = (GetPrivacy(pframe)) ? 4 : 0; 1105 1106 seq = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2)); 1107 status = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4)); 1108 1109 if (status != 0) { 1110 DBG_871X("clnt auth fail, status: %d\n", status); 1111 if (status == 13) { /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */ 1112 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) 1113 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; 1114 else 1115 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; 1116 /* pmlmeinfo->reauth_count = 0; */ 1117 } 1118 1119 set_link_timer(pmlmeext, 1); 1120 goto authclnt_fail; 1121 } 1122 1123 if (seq == 2) { 1124 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) { 1125 /* legendary shared system */ 1126 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len, 1127 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_); 1128 1129 if (p == NULL) { 1130 /* DBG_871X("marc: no challenge text?\n"); */ 1131 goto authclnt_fail; 1132 } 1133 1134 memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len); 1135 pmlmeinfo->auth_seq = 3; 1136 issue_auth(padapter, NULL, 0); 1137 set_link_timer(pmlmeext, REAUTH_TO); 1138 1139 return _SUCCESS; 1140 } else { 1141 /* open system */ 1142 go2asoc = 1; 1143 } 1144 } else if (seq == 4) { 1145 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) { 1146 go2asoc = 1; 1147 } else { 1148 goto authclnt_fail; 1149 } 1150 } else { 1151 /* this is also illegal */ 1152 /* DBG_871X("marc: clnt auth failed due to illegal seq =%x\n", seq); */ 1153 goto authclnt_fail; 1154 } 1155 1156 if (go2asoc) { 1157 DBG_871X_LEVEL(_drv_always_, "auth success, start assoc\n"); 1158 start_clnt_assoc(padapter); 1159 return _SUCCESS; 1160 } 1161 1162 authclnt_fail: 1163 1164 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */ 1165 1166 return _FAIL; 1167 1168 } 1169 1170 unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) 1171 { 1172 u16 capab_info; 1173 struct rtw_ieee802_11_elems elems; 1174 struct sta_info *pstat; 1175 unsigned char reassoc, *p, *pos, *wpa_ie; 1176 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; 1177 int i, ie_len, wpa_ie_len, left; 1178 unsigned char supportRate[16]; 1179 int supportRateNum; 1180 unsigned short status = _STATS_SUCCESSFUL_; 1181 unsigned short frame_type, ie_offset = 0; 1182 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1183 struct security_priv *psecuritypriv = &padapter->securitypriv; 1184 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1185 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1186 struct wlan_bssid_ex *cur = &(pmlmeinfo->network); 1187 struct sta_priv *pstapriv = &padapter->stapriv; 1188 u8 *pframe = precv_frame->u.hdr.rx_data; 1189 uint pkt_len = precv_frame->u.hdr.len; 1190 1191 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 1192 return _FAIL; 1193 1194 frame_type = GetFrameSubType(pframe); 1195 if (frame_type == WIFI_ASSOCREQ) { 1196 reassoc = 0; 1197 ie_offset = _ASOCREQ_IE_OFFSET_; 1198 } else { /* WIFI_REASSOCREQ */ 1199 reassoc = 1; 1200 ie_offset = _REASOCREQ_IE_OFFSET_; 1201 } 1202 1203 1204 if (pkt_len < sizeof(struct ieee80211_hdr_3addr) + ie_offset) { 1205 DBG_871X("handle_assoc(reassoc =%d) - too short payload (len =%lu)" 1206 "\n", reassoc, (unsigned long)pkt_len); 1207 return _FAIL; 1208 } 1209 1210 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 1211 if (!pstat) { 1212 status = _RSON_CLS2_; 1213 goto asoc_class2_error; 1214 } 1215 1216 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN); 1217 /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); */ 1218 1219 left = pkt_len - (sizeof(struct ieee80211_hdr_3addr) + ie_offset); 1220 pos = pframe + (sizeof(struct ieee80211_hdr_3addr) + ie_offset); 1221 1222 1223 DBG_871X("%s\n", __func__); 1224 1225 /* check if this stat has been successfully authenticated/assocated */ 1226 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) { 1227 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) { 1228 status = _RSON_CLS2_; 1229 goto asoc_class2_error; 1230 } else { 1231 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS); 1232 pstat->state |= WIFI_FW_ASSOC_STATE; 1233 } 1234 } else { 1235 pstat->state &= (~WIFI_FW_AUTH_SUCCESS); 1236 pstat->state |= WIFI_FW_ASSOC_STATE; 1237 } 1238 1239 1240 pstat->capability = capab_info; 1241 1242 /* now parse all ieee802_11 ie to point to elems */ 1243 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed || 1244 !elems.ssid) { 1245 DBG_871X("STA " MAC_FMT " sent invalid association request\n", 1246 MAC_ARG(pstat->hwaddr)); 1247 status = _STATS_FAILURE_; 1248 goto OnAssocReqFail; 1249 } 1250 1251 /* now we should check all the fields... */ 1252 /* checking SSID */ 1253 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len, 1254 pkt_len - WLAN_HDR_A3_LEN - ie_offset); 1255 1256 if (!p || ie_len == 0) { 1257 /* broadcast ssid, however it is not allowed in assocreq */ 1258 status = _STATS_FAILURE_; 1259 goto OnAssocReqFail; 1260 } else { 1261 /* check if ssid match */ 1262 if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength)) 1263 status = _STATS_FAILURE_; 1264 1265 if (ie_len != cur->Ssid.SsidLength) 1266 status = _STATS_FAILURE_; 1267 } 1268 1269 if (status != _STATS_SUCCESSFUL_) 1270 goto OnAssocReqFail; 1271 1272 /* check if the supported rate is ok */ 1273 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); 1274 if (p == NULL) { 1275 DBG_871X("Rx a sta assoc-req which supported rate is empty!\n"); 1276 /* use our own rate set as statoin used */ 1277 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */ 1278 /* supportRateNum = AP_BSSRATE_LEN; */ 1279 1280 status = _STATS_FAILURE_; 1281 goto OnAssocReqFail; 1282 } else { 1283 memcpy(supportRate, p+2, ie_len); 1284 supportRateNum = ie_len; 1285 1286 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len, 1287 pkt_len - WLAN_HDR_A3_LEN - ie_offset); 1288 if (p != NULL) { 1289 1290 if (supportRateNum <= sizeof(supportRate)) { 1291 memcpy(supportRate+supportRateNum, p+2, ie_len); 1292 supportRateNum += ie_len; 1293 } 1294 } 1295 } 1296 1297 /* todo: mask supportRate between AP & STA -> move to update raid */ 1298 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */ 1299 1300 /* update station supportRate */ 1301 pstat->bssratelen = supportRateNum; 1302 memcpy(pstat->bssrateset, supportRate, supportRateNum); 1303 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen); 1304 1305 /* check RSN/WPA/WPS */ 1306 pstat->dot8021xalg = 0; 1307 pstat->wpa_psk = 0; 1308 pstat->wpa_group_cipher = 0; 1309 pstat->wpa2_group_cipher = 0; 1310 pstat->wpa_pairwise_cipher = 0; 1311 pstat->wpa2_pairwise_cipher = 0; 1312 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie)); 1313 if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) { 1314 1315 int group_cipher = 0, pairwise_cipher = 0; 1316 1317 wpa_ie = elems.rsn_ie; 1318 wpa_ie_len = elems.rsn_ie_len; 1319 1320 if (rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { 1321 pstat->dot8021xalg = 1;/* psk, todo:802.1x */ 1322 pstat->wpa_psk |= BIT(1); 1323 1324 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher; 1325 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher; 1326 1327 if (!pstat->wpa2_group_cipher) 1328 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 1329 1330 if (!pstat->wpa2_pairwise_cipher) 1331 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; 1332 } else { 1333 status = WLAN_STATUS_INVALID_IE; 1334 } 1335 1336 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) { 1337 1338 int group_cipher = 0, pairwise_cipher = 0; 1339 1340 wpa_ie = elems.wpa_ie; 1341 wpa_ie_len = elems.wpa_ie_len; 1342 1343 if (rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { 1344 pstat->dot8021xalg = 1;/* psk, todo:802.1x */ 1345 pstat->wpa_psk |= BIT(0); 1346 1347 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher; 1348 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher; 1349 1350 if (!pstat->wpa_group_cipher) 1351 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID; 1352 1353 if (!pstat->wpa_pairwise_cipher) 1354 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID; 1355 1356 } else { 1357 status = WLAN_STATUS_INVALID_IE; 1358 } 1359 1360 } else { 1361 wpa_ie = NULL; 1362 wpa_ie_len = 0; 1363 } 1364 1365 if (status != _STATS_SUCCESSFUL_) 1366 goto OnAssocReqFail; 1367 1368 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); 1369 if (!wpa_ie) { 1370 if (elems.wps_ie) { 1371 DBG_871X("STA included WPS IE in " 1372 "(Re)Association Request - assume WPS is " 1373 "used\n"); 1374 pstat->flags |= WLAN_STA_WPS; 1375 /* wpabuf_free(sta->wps_ie); */ 1376 /* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */ 1377 /* elems.wps_ie_len - 4); */ 1378 } else { 1379 DBG_871X("STA did not include WPA/RSN IE " 1380 "in (Re)Association Request - possible WPS " 1381 "use\n"); 1382 pstat->flags |= WLAN_STA_MAYBE_WPS; 1383 } 1384 1385 1386 /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */ 1387 /* that the selected registrar of AP is _FLASE */ 1388 if ((psecuritypriv->wpa_psk > 0) 1389 && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) { 1390 if (pmlmepriv->wps_beacon_ie) { 1391 u8 selected_registrar = 0; 1392 1393 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL); 1394 1395 if (!selected_registrar) { 1396 DBG_871X("selected_registrar is false , or AP is not ready to do WPS\n"); 1397 1398 status = _STATS_UNABLE_HANDLE_STA_; 1399 1400 goto OnAssocReqFail; 1401 } 1402 } 1403 } 1404 1405 } else { 1406 int copy_len; 1407 1408 if (psecuritypriv->wpa_psk == 0) { 1409 DBG_871X("STA " MAC_FMT ": WPA/RSN IE in association " 1410 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr)); 1411 1412 status = WLAN_STATUS_INVALID_IE; 1413 1414 goto OnAssocReqFail; 1415 1416 } 1417 1418 if (elems.wps_ie) { 1419 DBG_871X("STA included WPS IE in " 1420 "(Re)Association Request - WPS is " 1421 "used\n"); 1422 pstat->flags |= WLAN_STA_WPS; 1423 copy_len = 0; 1424 } else { 1425 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2); 1426 } 1427 1428 1429 if (copy_len > 0) 1430 memcpy(pstat->wpa_ie, wpa_ie-2, copy_len); 1431 1432 } 1433 1434 1435 /* check if there is WMM IE & support WWM-PS */ 1436 pstat->flags &= ~WLAN_STA_WME; 1437 pstat->qos_option = 0; 1438 pstat->qos_info = 0; 1439 pstat->has_legacy_ac = true; 1440 pstat->uapsd_vo = 0; 1441 pstat->uapsd_vi = 0; 1442 pstat->uapsd_be = 0; 1443 pstat->uapsd_bk = 0; 1444 if (pmlmepriv->qospriv.qos_option) { 1445 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0; 1446 for (;;) { 1447 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); 1448 if (p != NULL) { 1449 if (!memcmp(p+2, WMM_IE, 6)) { 1450 1451 pstat->flags |= WLAN_STA_WME; 1452 1453 pstat->qos_option = 1; 1454 pstat->qos_info = *(p+8); 1455 1456 pstat->max_sp_len = (pstat->qos_info>>5)&0x3; 1457 1458 if ((pstat->qos_info&0xf) != 0xf) 1459 pstat->has_legacy_ac = true; 1460 else 1461 pstat->has_legacy_ac = false; 1462 1463 if (pstat->qos_info&0xf) { 1464 if (pstat->qos_info&BIT(0)) 1465 pstat->uapsd_vo = BIT(0)|BIT(1); 1466 else 1467 pstat->uapsd_vo = 0; 1468 1469 if (pstat->qos_info&BIT(1)) 1470 pstat->uapsd_vi = BIT(0)|BIT(1); 1471 else 1472 pstat->uapsd_vi = 0; 1473 1474 if (pstat->qos_info&BIT(2)) 1475 pstat->uapsd_bk = BIT(0)|BIT(1); 1476 else 1477 pstat->uapsd_bk = 0; 1478 1479 if (pstat->qos_info&BIT(3)) 1480 pstat->uapsd_be = BIT(0)|BIT(1); 1481 else 1482 pstat->uapsd_be = 0; 1483 1484 } 1485 1486 break; 1487 } 1488 } else { 1489 break; 1490 } 1491 p = p + ie_len + 2; 1492 } 1493 } 1494 1495 /* save HT capabilities in the sta object */ 1496 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap)); 1497 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap)) { 1498 pstat->flags |= WLAN_STA_HT; 1499 1500 pstat->flags |= WLAN_STA_WME; 1501 1502 memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap)); 1503 1504 } else 1505 pstat->flags &= ~WLAN_STA_HT; 1506 1507 1508 if ((pmlmepriv->htpriv.ht_option == false) && (pstat->flags&WLAN_STA_HT)) { 1509 status = _STATS_FAILURE_; 1510 goto OnAssocReqFail; 1511 } 1512 1513 1514 if ((pstat->flags & WLAN_STA_HT) && 1515 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) || 1516 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP))) { 1517 DBG_871X("HT: " MAC_FMT " tried to " 1518 "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr)); 1519 1520 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */ 1521 /* goto OnAssocReqFail; */ 1522 } 1523 pstat->flags |= WLAN_STA_NONERP; 1524 for (i = 0; i < pstat->bssratelen; i++) { 1525 if ((pstat->bssrateset[i] & 0x7f) > 22) { 1526 pstat->flags &= ~WLAN_STA_NONERP; 1527 break; 1528 } 1529 } 1530 1531 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 1532 pstat->flags |= WLAN_STA_SHORT_PREAMBLE; 1533 else 1534 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE; 1535 1536 1537 1538 if (status != _STATS_SUCCESSFUL_) 1539 goto OnAssocReqFail; 1540 1541 /* TODO: identify_proprietary_vendor_ie(); */ 1542 /* Realtek proprietary IE */ 1543 /* identify if this is Broadcom sta */ 1544 /* identify if this is ralink sta */ 1545 /* Customer proprietary IE */ 1546 1547 1548 1549 /* get a unique AID */ 1550 if (pstat->aid > 0) { 1551 DBG_871X(" old AID %d\n", pstat->aid); 1552 } else { 1553 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) 1554 if (pstapriv->sta_aid[pstat->aid - 1] == NULL) 1555 break; 1556 1557 /* if (pstat->aid > NUM_STA) { */ 1558 if (pstat->aid > pstapriv->max_num_sta) { 1559 1560 pstat->aid = 0; 1561 1562 DBG_871X(" no room for more AIDs\n"); 1563 1564 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 1565 1566 goto OnAssocReqFail; 1567 1568 1569 } else { 1570 pstapriv->sta_aid[pstat->aid - 1] = pstat; 1571 DBG_871X("allocate new AID = (%d)\n", pstat->aid); 1572 } 1573 } 1574 1575 1576 pstat->state &= (~WIFI_FW_ASSOC_STATE); 1577 pstat->state |= WIFI_FW_ASSOC_SUCCESS; 1578 1579 spin_lock_bh(&pstapriv->auth_list_lock); 1580 if (!list_empty(&pstat->auth_list)) { 1581 list_del_init(&pstat->auth_list); 1582 pstapriv->auth_list_cnt--; 1583 } 1584 spin_unlock_bh(&pstapriv->auth_list_lock); 1585 1586 spin_lock_bh(&pstapriv->asoc_list_lock); 1587 if (list_empty(&pstat->asoc_list)) { 1588 pstat->expire_to = pstapriv->expire_to; 1589 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list); 1590 pstapriv->asoc_list_cnt++; 1591 } 1592 spin_unlock_bh(&pstapriv->asoc_list_lock); 1593 1594 /* now the station is qualified to join our BSS... */ 1595 if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) { 1596 /* 1 bss_cap_update & sta_info_update */ 1597 bss_cap_update_on_sta_join(padapter, pstat); 1598 sta_info_update(padapter, pstat); 1599 1600 /* 2 issue assoc rsp before notify station join event. */ 1601 if (frame_type == WIFI_ASSOCREQ) 1602 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); 1603 else 1604 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); 1605 1606 spin_lock_bh(&pstat->lock); 1607 if (pstat->passoc_req) { 1608 kfree(pstat->passoc_req); 1609 pstat->passoc_req = NULL; 1610 pstat->assoc_req_len = 0; 1611 } 1612 1613 pstat->passoc_req = rtw_zmalloc(pkt_len); 1614 if (pstat->passoc_req) { 1615 memcpy(pstat->passoc_req, pframe, pkt_len); 1616 pstat->assoc_req_len = pkt_len; 1617 } 1618 spin_unlock_bh(&pstat->lock); 1619 1620 /* 3-(1) report sta add event */ 1621 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid); 1622 } 1623 1624 return _SUCCESS; 1625 1626 asoc_class2_error: 1627 1628 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); 1629 1630 return _FAIL; 1631 1632 OnAssocReqFail: 1633 1634 pstat->aid = 0; 1635 if (frame_type == WIFI_ASSOCREQ) 1636 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); 1637 else 1638 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); 1639 1640 return _FAIL; 1641 } 1642 1643 unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame) 1644 { 1645 uint i; 1646 int res; 1647 unsigned short status; 1648 struct ndis_80211_var_ie *pIE; 1649 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1650 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1651 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1652 /* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */ 1653 u8 *pframe = precv_frame->u.hdr.rx_data; 1654 uint pkt_len = precv_frame->u.hdr.len; 1655 1656 DBG_871X("%s\n", __func__); 1657 1658 /* check A1 matches or not */ 1659 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN)) 1660 return _SUCCESS; 1661 1662 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE))) 1663 return _SUCCESS; 1664 1665 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) 1666 return _SUCCESS; 1667 1668 del_timer_sync(&pmlmeext->link_timer); 1669 1670 /* status */ 1671 status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2)); 1672 if (status > 0) { 1673 DBG_871X("assoc reject, status code: %d\n", status); 1674 pmlmeinfo->state = WIFI_FW_NULL_STATE; 1675 res = -4; 1676 goto report_assoc_result; 1677 } 1678 1679 /* get capabilities */ 1680 pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); 1681 1682 /* set slot time */ 1683 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20; 1684 1685 /* AID */ 1686 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff); 1687 1688 /* following are moved to join event callback function */ 1689 /* to handle HT, WMM, rate adaptive, update MAC reg */ 1690 /* for not to handle the synchronous IO in the tasklet */ 1691 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) { 1692 pIE = (struct ndis_80211_var_ie *)(pframe + i); 1693 1694 switch (pIE->ElementID) { 1695 case _VENDOR_SPECIFIC_IE_: 1696 if (!memcmp(pIE->data, WMM_PARA_OUI, 6)) /* WMM */ 1697 WMM_param_handler(padapter, pIE); 1698 break; 1699 1700 case _HT_CAPABILITY_IE_: /* HT caps */ 1701 HT_caps_handler(padapter, pIE); 1702 break; 1703 1704 case _HT_EXTRA_INFO_IE_: /* HT info */ 1705 HT_info_handler(padapter, pIE); 1706 break; 1707 1708 case _ERPINFO_IE_: 1709 ERP_IE_handler(padapter, pIE); 1710 1711 default: 1712 break; 1713 } 1714 1715 i += (pIE->Length + 2); 1716 } 1717 1718 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE); 1719 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; 1720 1721 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */ 1722 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates); 1723 1724 report_assoc_result: 1725 if (res > 0) { 1726 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len); 1727 } else { 1728 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); 1729 } 1730 1731 report_join_res(padapter, res); 1732 1733 return _SUCCESS; 1734 } 1735 1736 unsigned int OnDeAuth(struct adapter *padapter, union recv_frame *precv_frame) 1737 { 1738 unsigned short reason; 1739 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1740 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1741 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1742 u8 *pframe = precv_frame->u.hdr.rx_data; 1743 1744 /* check A3 */ 1745 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) 1746 return _SUCCESS; 1747 1748 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); 1749 1750 DBG_871X("%s Reason code(%d)\n", __func__, reason); 1751 1752 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1753 struct sta_info *psta; 1754 struct sta_priv *pstapriv = &padapter->stapriv; 1755 1756 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */ 1757 /* rtw_free_stainfo(padapter, psta); */ 1758 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */ 1759 1760 DBG_871X_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n", 1761 reason, GetAddr2Ptr(pframe)); 1762 1763 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 1764 if (psta) { 1765 u8 updated = false; 1766 1767 spin_lock_bh(&pstapriv->asoc_list_lock); 1768 if (list_empty(&psta->asoc_list) == false) { 1769 list_del_init(&psta->asoc_list); 1770 pstapriv->asoc_list_cnt--; 1771 updated = ap_free_sta(padapter, psta, false, reason); 1772 1773 } 1774 spin_unlock_bh(&pstapriv->asoc_list_lock); 1775 1776 associated_clients_update(padapter, updated); 1777 } 1778 1779 1780 return _SUCCESS; 1781 } else { 1782 int ignore_received_deauth = 0; 1783 1784 /* Commented by Albert 20130604 */ 1785 /* Before sending the auth frame to start the STA/GC mode connection with AP/GO, */ 1786 /* we will send the deauth first. */ 1787 /* However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. */ 1788 /* Added the following code to avoid this case. */ 1789 if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) || 1790 (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) { 1791 if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) { 1792 ignore_received_deauth = 1; 1793 } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) { 1794 /* TODO: 802.11r */ 1795 ignore_received_deauth = 1; 1796 } 1797 } 1798 1799 DBG_871X_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n", 1800 reason, GetAddr3Ptr(pframe), ignore_received_deauth); 1801 1802 if (0 == ignore_received_deauth) { 1803 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); 1804 } 1805 } 1806 pmlmepriv->LinkDetectInfo.bBusyTraffic = false; 1807 return _SUCCESS; 1808 1809 } 1810 1811 unsigned int OnDisassoc(struct adapter *padapter, union recv_frame *precv_frame) 1812 { 1813 unsigned short reason; 1814 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1815 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1816 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1817 u8 *pframe = precv_frame->u.hdr.rx_data; 1818 1819 /* check A3 */ 1820 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) 1821 return _SUCCESS; 1822 1823 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); 1824 1825 DBG_871X("%s Reason code(%d)\n", __func__, reason); 1826 1827 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1828 struct sta_info *psta; 1829 struct sta_priv *pstapriv = &padapter->stapriv; 1830 1831 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */ 1832 /* rtw_free_stainfo(padapter, psta); */ 1833 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */ 1834 1835 DBG_871X_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n", 1836 reason, GetAddr2Ptr(pframe)); 1837 1838 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 1839 if (psta) { 1840 u8 updated = false; 1841 1842 spin_lock_bh(&pstapriv->asoc_list_lock); 1843 if (list_empty(&psta->asoc_list) == false) { 1844 list_del_init(&psta->asoc_list); 1845 pstapriv->asoc_list_cnt--; 1846 updated = ap_free_sta(padapter, psta, false, reason); 1847 1848 } 1849 spin_unlock_bh(&pstapriv->asoc_list_lock); 1850 1851 associated_clients_update(padapter, updated); 1852 } 1853 1854 return _SUCCESS; 1855 } else { 1856 DBG_871X_LEVEL(_drv_always_, "sta recv disassoc reason code(%d) sta:%pM\n", 1857 reason, GetAddr3Ptr(pframe)); 1858 1859 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); 1860 } 1861 pmlmepriv->LinkDetectInfo.bBusyTraffic = false; 1862 return _SUCCESS; 1863 1864 } 1865 1866 unsigned int OnAtim(struct adapter *padapter, union recv_frame *precv_frame) 1867 { 1868 DBG_871X("%s\n", __func__); 1869 return _SUCCESS; 1870 } 1871 1872 unsigned int on_action_spct(struct adapter *padapter, union recv_frame *precv_frame) 1873 { 1874 struct sta_info *psta = NULL; 1875 struct sta_priv *pstapriv = &padapter->stapriv; 1876 u8 *pframe = precv_frame->u.hdr.rx_data; 1877 u8 *frame_body = (u8 *)(pframe + sizeof(struct ieee80211_hdr_3addr)); 1878 u8 category; 1879 u8 action; 1880 1881 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev)); 1882 1883 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 1884 1885 if (!psta) 1886 goto exit; 1887 1888 category = frame_body[0]; 1889 if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT) 1890 goto exit; 1891 1892 action = frame_body[1]; 1893 switch (action) { 1894 case RTW_WLAN_ACTION_SPCT_MSR_REQ: 1895 case RTW_WLAN_ACTION_SPCT_MSR_RPRT: 1896 case RTW_WLAN_ACTION_SPCT_TPC_REQ: 1897 case RTW_WLAN_ACTION_SPCT_TPC_RPRT: 1898 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH: 1899 break; 1900 default: 1901 break; 1902 } 1903 1904 exit: 1905 return _FAIL; 1906 } 1907 1908 unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_frame) 1909 { 1910 u8 *addr; 1911 struct sta_info *psta = NULL; 1912 struct recv_reorder_ctrl *preorder_ctrl; 1913 unsigned char *frame_body; 1914 unsigned char category, action; 1915 unsigned short tid, status, reason_code = 0; 1916 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1917 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1918 u8 *pframe = precv_frame->u.hdr.rx_data; 1919 struct sta_priv *pstapriv = &padapter->stapriv; 1920 1921 DBG_871X("%s\n", __func__); 1922 1923 /* check RA matches or not */ 1924 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */ 1925 return _SUCCESS; 1926 1927 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 1928 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) 1929 return _SUCCESS; 1930 1931 addr = GetAddr2Ptr(pframe); 1932 psta = rtw_get_stainfo(pstapriv, addr); 1933 1934 if (!psta) 1935 return _SUCCESS; 1936 1937 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); 1938 1939 category = frame_body[0]; 1940 if (category == RTW_WLAN_CATEGORY_BACK) {/* representing Block Ack */ 1941 if (!pmlmeinfo->HT_enable) 1942 return _SUCCESS; 1943 1944 action = frame_body[1]; 1945 DBG_871X("%s, action =%d\n", __func__, action); 1946 switch (action) { 1947 case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */ 1948 1949 memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request)); 1950 /* process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */ 1951 process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr); 1952 1953 if (pmlmeinfo->accept_addba_req) { 1954 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0); 1955 } else { 1956 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */ 1957 } 1958 1959 break; 1960 1961 case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */ 1962 status = RTW_GET_LE16(&frame_body[3]); 1963 tid = ((frame_body[5] >> 2) & 0x7); 1964 1965 if (status == 0) { 1966 /* successful */ 1967 DBG_871X("agg_enable for TID =%d\n", tid); 1968 psta->htpriv.agg_enable_bitmap |= BIT(tid); 1969 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); 1970 } else { 1971 psta->htpriv.agg_enable_bitmap &= ~BIT(tid); 1972 } 1973 1974 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { 1975 DBG_871X("%s alive check - rx ADDBA response\n", __func__); 1976 psta->htpriv.agg_enable_bitmap &= ~BIT(tid); 1977 psta->expire_to = pstapriv->expire_to; 1978 psta->state ^= WIFI_STA_ALIVE_CHK_STATE; 1979 } 1980 1981 /* DBG_871X("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */ 1982 break; 1983 1984 case RTW_WLAN_ACTION_DELBA: /* DELBA */ 1985 if ((frame_body[3] & BIT(3)) == 0) { 1986 psta->htpriv.agg_enable_bitmap &= 1987 ~BIT((frame_body[3] >> 4) & 0xf); 1988 psta->htpriv.candidate_tid_bitmap &= 1989 ~BIT((frame_body[3] >> 4) & 0xf); 1990 1991 /* reason_code = frame_body[4] | (frame_body[5] << 8); */ 1992 reason_code = RTW_GET_LE16(&frame_body[4]); 1993 } else if ((frame_body[3] & BIT(3)) == BIT(3)) { 1994 tid = (frame_body[3] >> 4) & 0x0F; 1995 1996 preorder_ctrl = &psta->recvreorder_ctrl[tid]; 1997 preorder_ctrl->enable = false; 1998 preorder_ctrl->indicate_seq = 0xffff; 1999 #ifdef DBG_RX_SEQ 2000 DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __func__, __LINE__, 2001 preorder_ctrl->indicate_seq); 2002 #endif 2003 } 2004 2005 DBG_871X("%s(): DELBA: %x(%x)\n", __func__, pmlmeinfo->agg_enable_bitmap, reason_code); 2006 /* todo: how to notify the host while receiving DELETE BA */ 2007 break; 2008 2009 default: 2010 break; 2011 } 2012 } 2013 return _SUCCESS; 2014 } 2015 2016 static s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token) 2017 { 2018 struct adapter *adapter = recv_frame->u.hdr.adapter; 2019 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); 2020 u8 *frame = recv_frame->u.hdr.rx_data; 2021 u16 seq_ctrl = ((recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) | 2022 (recv_frame->u.hdr.attrib.frag_num & 0xf); 2023 2024 if (GetRetry(frame)) { 2025 if (token >= 0) { 2026 if ((seq_ctrl == mlmeext->action_public_rxseq) 2027 && (token == mlmeext->action_public_dialog_token)) { 2028 DBG_871X(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x, token:%d\n", 2029 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token); 2030 return _FAIL; 2031 } 2032 } else { 2033 if (seq_ctrl == mlmeext->action_public_rxseq) { 2034 DBG_871X(FUNC_ADPT_FMT" seq_ctrl = 0x%x, rxseq = 0x%x\n", 2035 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq); 2036 return _FAIL; 2037 } 2038 } 2039 } 2040 2041 mlmeext->action_public_rxseq = seq_ctrl; 2042 2043 if (token >= 0) 2044 mlmeext->action_public_dialog_token = token; 2045 2046 return _SUCCESS; 2047 } 2048 2049 static unsigned int on_action_public_p2p(union recv_frame *precv_frame) 2050 { 2051 u8 *pframe = precv_frame->u.hdr.rx_data; 2052 u8 *frame_body; 2053 u8 dialogToken = 0; 2054 2055 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); 2056 2057 dialogToken = frame_body[7]; 2058 2059 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL) 2060 return _FAIL; 2061 2062 return _SUCCESS; 2063 } 2064 2065 static unsigned int on_action_public_vendor(union recv_frame *precv_frame) 2066 { 2067 unsigned int ret = _FAIL; 2068 u8 *pframe = precv_frame->u.hdr.rx_data; 2069 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); 2070 2071 if (!memcmp(frame_body + 2, P2P_OUI, 4)) { 2072 ret = on_action_public_p2p(precv_frame); 2073 } 2074 2075 return ret; 2076 } 2077 2078 static unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action) 2079 { 2080 unsigned int ret = _FAIL; 2081 u8 *pframe = precv_frame->u.hdr.rx_data; 2082 uint frame_len = precv_frame->u.hdr.len; 2083 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); 2084 u8 token; 2085 struct adapter *adapter = precv_frame->u.hdr.adapter; 2086 int cnt = 0; 2087 char msg[64]; 2088 2089 token = frame_body[2]; 2090 2091 if (rtw_action_public_decache(precv_frame, token) == _FAIL) 2092 goto exit; 2093 2094 cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token); 2095 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg); 2096 2097 ret = _SUCCESS; 2098 2099 exit: 2100 return ret; 2101 } 2102 2103 unsigned int on_action_public(struct adapter *padapter, union recv_frame *precv_frame) 2104 { 2105 unsigned int ret = _FAIL; 2106 u8 *pframe = precv_frame->u.hdr.rx_data; 2107 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); 2108 u8 category, action; 2109 2110 /* check RA matches or not */ 2111 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN)) 2112 goto exit; 2113 2114 category = frame_body[0]; 2115 if (category != RTW_WLAN_CATEGORY_PUBLIC) 2116 goto exit; 2117 2118 action = frame_body[1]; 2119 switch (action) { 2120 case ACT_PUBLIC_VENDOR: 2121 ret = on_action_public_vendor(precv_frame); 2122 break; 2123 default: 2124 ret = on_action_public_default(precv_frame, action); 2125 break; 2126 } 2127 2128 exit: 2129 return ret; 2130 } 2131 2132 unsigned int OnAction_ht(struct adapter *padapter, union recv_frame *precv_frame) 2133 { 2134 u8 *pframe = precv_frame->u.hdr.rx_data; 2135 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); 2136 u8 category, action; 2137 2138 /* check RA matches or not */ 2139 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN)) 2140 goto exit; 2141 2142 category = frame_body[0]; 2143 if (category != RTW_WLAN_CATEGORY_HT) 2144 goto exit; 2145 2146 action = frame_body[1]; 2147 switch (action) { 2148 case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING: 2149 break; 2150 default: 2151 break; 2152 } 2153 2154 exit: 2155 2156 return _SUCCESS; 2157 } 2158 2159 unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv_frame) 2160 { 2161 u8 *pframe = precv_frame->u.hdr.rx_data; 2162 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 2163 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2164 unsigned short tid; 2165 /* Baron */ 2166 2167 DBG_871X("OnAction_sa_query\n"); 2168 2169 switch (pframe[WLAN_HDR_A3_LEN+1]) { 2170 case 0: /* SA Query req */ 2171 memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short)); 2172 DBG_871X("OnAction_sa_query request, action =%d, tid =%04x\n", pframe[WLAN_HDR_A3_LEN+1], tid); 2173 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid); 2174 break; 2175 2176 case 1: /* SA Query rsp */ 2177 del_timer_sync(&pmlmeext->sa_query_timer); 2178 DBG_871X("OnAction_sa_query response, action =%d, tid =%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN+1], pframe[WLAN_HDR_A3_LEN+2]); 2179 break; 2180 default: 2181 break; 2182 } 2183 if (0) { 2184 int pp; 2185 2186 printk("pattrib->pktlen = %d =>", pattrib->pkt_len); 2187 for (pp = 0; pp < pattrib->pkt_len; pp++) 2188 printk(" %02x ", pframe[pp]); 2189 printk("\n"); 2190 } 2191 2192 return _SUCCESS; 2193 } 2194 2195 unsigned int OnAction(struct adapter *padapter, union recv_frame *precv_frame) 2196 { 2197 int i; 2198 unsigned char category; 2199 struct action_handler *ptable; 2200 unsigned char *frame_body; 2201 u8 *pframe = precv_frame->u.hdr.rx_data; 2202 2203 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); 2204 2205 category = frame_body[0]; 2206 2207 for (i = 0; i < ARRAY_SIZE(OnAction_tbl); i++) { 2208 ptable = &OnAction_tbl[i]; 2209 2210 if (category == ptable->num) 2211 ptable->func(padapter, precv_frame); 2212 2213 } 2214 2215 return _SUCCESS; 2216 2217 } 2218 2219 unsigned int DoReserved(struct adapter *padapter, union recv_frame *precv_frame) 2220 { 2221 2222 /* DBG_871X("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */ 2223 return _SUCCESS; 2224 } 2225 2226 static struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once) 2227 { 2228 struct xmit_frame *pmgntframe; 2229 struct xmit_buf *pxmitbuf; 2230 2231 if (once) 2232 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv); 2233 else 2234 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv); 2235 2236 if (pmgntframe == NULL) { 2237 DBG_871X(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once); 2238 goto exit; 2239 } 2240 2241 pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv); 2242 if (pxmitbuf == NULL) { 2243 DBG_871X(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter)); 2244 rtw_free_xmitframe(pxmitpriv, pmgntframe); 2245 pmgntframe = NULL; 2246 goto exit; 2247 } 2248 2249 pmgntframe->frame_tag = MGNT_FRAMETAG; 2250 pmgntframe->pxmitbuf = pxmitbuf; 2251 pmgntframe->buf_addr = pxmitbuf->pbuf; 2252 pxmitbuf->priv_data = pmgntframe; 2253 2254 exit: 2255 return pmgntframe; 2256 2257 } 2258 2259 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) 2260 { 2261 return _alloc_mgtxmitframe(pxmitpriv, false); 2262 } 2263 2264 /**************************************************************************** 2265 2266 Following are some TX functions for WiFi MLME 2267 2268 *****************************************************************************/ 2269 2270 void update_mgnt_tx_rate(struct adapter *padapter, u8 rate) 2271 { 2272 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2273 2274 pmlmeext->tx_rate = rate; 2275 /* DBG_871X("%s(): rate = %x\n", __func__, rate); */ 2276 } 2277 2278 void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib) 2279 { 2280 u8 wireless_mode; 2281 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2282 2283 /* memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); */ 2284 2285 pattrib->hdrlen = 24; 2286 pattrib->nr_frags = 1; 2287 pattrib->priority = 7; 2288 pattrib->mac_id = 0; 2289 pattrib->qsel = 0x12; 2290 2291 pattrib->pktlen = 0; 2292 2293 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB) 2294 wireless_mode = WIRELESS_11B; 2295 else 2296 wireless_mode = WIRELESS_11G; 2297 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode); 2298 pattrib->rate = pmlmeext->tx_rate; 2299 2300 pattrib->encrypt = _NO_PRIVACY_; 2301 pattrib->bswenc = false; 2302 2303 pattrib->qos_en = false; 2304 pattrib->ht_en = false; 2305 pattrib->bwmode = CHANNEL_WIDTH_20; 2306 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 2307 pattrib->sgi = false; 2308 2309 pattrib->seqnum = pmlmeext->mgnt_seq; 2310 2311 pattrib->retry_ctrl = true; 2312 2313 pattrib->mbssid = 0; 2314 2315 } 2316 2317 void update_mgntframe_attrib_addr(struct adapter *padapter, struct xmit_frame *pmgntframe) 2318 { 2319 u8 *pframe; 2320 struct pkt_attrib *pattrib = &pmgntframe->attrib; 2321 2322 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2323 2324 memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN); 2325 memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN); 2326 } 2327 2328 void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe) 2329 { 2330 if (padapter->bSurpriseRemoved || 2331 padapter->bDriverStopped) { 2332 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); 2333 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); 2334 return; 2335 } 2336 2337 rtw_hal_mgnt_xmit(padapter, pmgntframe); 2338 } 2339 2340 s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms) 2341 { 2342 s32 ret = _FAIL; 2343 _irqL irqL; 2344 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2345 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf; 2346 struct submit_ctx sctx; 2347 2348 if (padapter->bSurpriseRemoved || 2349 padapter->bDriverStopped) { 2350 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); 2351 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); 2352 return ret; 2353 } 2354 2355 rtw_sctx_init(&sctx, timeout_ms); 2356 pxmitbuf->sctx = &sctx; 2357 2358 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); 2359 2360 if (ret == _SUCCESS) 2361 ret = rtw_sctx_wait(&sctx, __func__); 2362 2363 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL); 2364 pxmitbuf->sctx = NULL; 2365 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL); 2366 2367 return ret; 2368 } 2369 2370 s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe) 2371 { 2372 static u8 seq_no; 2373 s32 ret = _FAIL; 2374 u32 timeout_ms = 500;/* 500ms */ 2375 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2376 2377 if (padapter->bSurpriseRemoved || 2378 padapter->bDriverStopped) { 2379 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); 2380 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); 2381 return -1; 2382 } 2383 2384 if (mutex_lock_interruptible(&pxmitpriv->ack_tx_mutex) == 0) { 2385 pxmitpriv->ack_tx = true; 2386 pxmitpriv->seq_no = seq_no++; 2387 pmgntframe->ack_report = 1; 2388 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) 2389 ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms); 2390 2391 pxmitpriv->ack_tx = false; 2392 mutex_unlock(&pxmitpriv->ack_tx_mutex); 2393 } 2394 2395 return ret; 2396 } 2397 2398 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) 2399 { 2400 u8 *ssid_ie; 2401 sint ssid_len_ori; 2402 int len_diff = 0; 2403 2404 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len); 2405 2406 /* DBG_871X("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */ 2407 2408 if (ssid_ie && ssid_len_ori > 0) { 2409 switch (hidden_ssid_mode) { 2410 case 1: 2411 { 2412 u8 *next_ie = ssid_ie + 2 + ssid_len_ori; 2413 u32 remain_len = 0; 2414 2415 remain_len = ies_len - (next_ie-ies); 2416 2417 ssid_ie[1] = 0; 2418 memcpy(ssid_ie+2, next_ie, remain_len); 2419 len_diff -= ssid_len_ori; 2420 2421 break; 2422 } 2423 case 2: 2424 memset(&ssid_ie[2], 0, ssid_len_ori); 2425 break; 2426 default: 2427 break; 2428 } 2429 } 2430 2431 return len_diff; 2432 } 2433 2434 void issue_beacon(struct adapter *padapter, int timeout_ms) 2435 { 2436 struct xmit_frame *pmgntframe; 2437 struct pkt_attrib *pattrib; 2438 unsigned char *pframe; 2439 struct ieee80211_hdr *pwlanhdr; 2440 __le16 *fctrl; 2441 unsigned int rate_len; 2442 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2443 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2444 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2445 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2446 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); 2447 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 2448 2449 /* DBG_871X("%s\n", __func__); */ 2450 2451 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2452 if (!pmgntframe) { 2453 DBG_871X("%s, alloc mgnt frame fail\n", __func__); 2454 return; 2455 } 2456 2457 spin_lock_bh(&pmlmepriv->bcn_update_lock); 2458 2459 /* update attribute */ 2460 pattrib = &pmgntframe->attrib; 2461 update_mgntframe_attrib(padapter, pattrib); 2462 pattrib->qsel = 0x10; 2463 2464 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2465 2466 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2467 pwlanhdr = (struct ieee80211_hdr *)pframe; 2468 2469 2470 fctrl = &(pwlanhdr->frame_control); 2471 *(fctrl) = 0; 2472 2473 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); 2474 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 2475 memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); 2476 2477 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); 2478 /* pmlmeext->mgnt_seq++; */ 2479 SetFrameSubType(pframe, WIFI_BEACON); 2480 2481 pframe += sizeof(struct ieee80211_hdr_3addr); 2482 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 2483 2484 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { 2485 /* DBG_871X("ie len =%d\n", cur_network->IELength); */ 2486 { 2487 int len_diff; 2488 2489 memcpy(pframe, cur_network->IEs, cur_network->IELength); 2490 len_diff = update_hidden_ssid( 2491 pframe+_BEACON_IE_OFFSET_ 2492 , cur_network->IELength-_BEACON_IE_OFFSET_ 2493 , pmlmeinfo->hidden_ssid_mode 2494 ); 2495 pframe += (cur_network->IELength+len_diff); 2496 pattrib->pktlen += (cur_network->IELength+len_diff); 2497 } 2498 2499 { 2500 u8 *wps_ie; 2501 uint wps_ielen; 2502 u8 sr = 0; 2503 2504 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_, 2505 pattrib->pktlen-sizeof(struct ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen); 2506 if (wps_ie && wps_ielen > 0) { 2507 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); 2508 } 2509 if (sr != 0) 2510 set_fwstate(pmlmepriv, WIFI_UNDER_WPS); 2511 else 2512 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS); 2513 } 2514 2515 goto _issue_bcn; 2516 2517 } 2518 2519 /* below for ad-hoc mode */ 2520 2521 /* timestamp will be inserted by hardware */ 2522 pframe += 8; 2523 pattrib->pktlen += 8; 2524 2525 /* beacon interval: 2 bytes */ 2526 2527 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 2528 2529 pframe += 2; 2530 pattrib->pktlen += 2; 2531 2532 /* capability info: 2 bytes */ 2533 2534 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); 2535 2536 pframe += 2; 2537 pattrib->pktlen += 2; 2538 2539 /* SSID */ 2540 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); 2541 2542 /* supported rates... */ 2543 rate_len = rtw_get_rateset_len(cur_network->SupportedRates); 2544 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen); 2545 2546 /* DS parameter set */ 2547 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen); 2548 2549 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */ 2550 { 2551 u8 erpinfo = 0; 2552 u32 ATIMWindow; 2553 /* IBSS Parameter Set... */ 2554 /* ATIMWindow = cur->Configuration.ATIMWindow; */ 2555 ATIMWindow = 0; 2556 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen); 2557 2558 /* ERP IE */ 2559 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); 2560 } 2561 2562 2563 /* EXTERNDED SUPPORTED RATE */ 2564 if (rate_len > 8) { 2565 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); 2566 } 2567 2568 2569 /* todo:HT for adhoc */ 2570 2571 _issue_bcn: 2572 2573 pmlmepriv->update_bcn = false; 2574 2575 spin_unlock_bh(&pmlmepriv->bcn_update_lock); 2576 2577 if ((pattrib->pktlen + TXDESC_SIZE) > 512) { 2578 DBG_871X("beacon frame too large\n"); 2579 return; 2580 } 2581 2582 pattrib->last_txcmdsz = pattrib->pktlen; 2583 2584 /* DBG_871X("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */ 2585 if (timeout_ms > 0) 2586 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms); 2587 else 2588 dump_mgntframe(padapter, pmgntframe); 2589 2590 } 2591 2592 void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq) 2593 { 2594 struct xmit_frame *pmgntframe; 2595 struct pkt_attrib *pattrib; 2596 unsigned char *pframe; 2597 struct ieee80211_hdr *pwlanhdr; 2598 __le16 *fctrl; 2599 unsigned char *mac, *bssid; 2600 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2601 2602 u8 *pwps_ie; 2603 uint wps_ielen; 2604 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2605 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2606 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2607 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); 2608 unsigned int rate_len; 2609 2610 /* DBG_871X("%s\n", __func__); */ 2611 2612 if (da == NULL) 2613 return; 2614 2615 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2616 if (pmgntframe == NULL) { 2617 DBG_871X("%s, alloc mgnt frame fail\n", __func__); 2618 return; 2619 } 2620 2621 2622 /* update attribute */ 2623 pattrib = &pmgntframe->attrib; 2624 update_mgntframe_attrib(padapter, pattrib); 2625 2626 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2627 2628 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2629 pwlanhdr = (struct ieee80211_hdr *)pframe; 2630 2631 mac = myid(&(padapter->eeprompriv)); 2632 bssid = cur_network->MacAddress; 2633 2634 fctrl = &(pwlanhdr->frame_control); 2635 *(fctrl) = 0; 2636 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 2637 memcpy(pwlanhdr->addr2, mac, ETH_ALEN); 2638 memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); 2639 2640 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2641 pmlmeext->mgnt_seq++; 2642 SetFrameSubType(fctrl, WIFI_PROBERSP); 2643 2644 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr); 2645 pattrib->pktlen = pattrib->hdrlen; 2646 pframe += pattrib->hdrlen; 2647 2648 2649 if (cur_network->IELength > MAX_IE_SZ) 2650 return; 2651 2652 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { 2653 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen); 2654 2655 /* inerset & update wps_probe_resp_ie */ 2656 if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie && (wps_ielen > 0)) { 2657 uint wps_offset, remainder_ielen; 2658 u8 *premainder_ie; 2659 2660 wps_offset = (uint)(pwps_ie - cur_network->IEs); 2661 2662 premainder_ie = pwps_ie + wps_ielen; 2663 2664 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen; 2665 2666 memcpy(pframe, cur_network->IEs, wps_offset); 2667 pframe += wps_offset; 2668 pattrib->pktlen += wps_offset; 2669 2670 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */ 2671 if ((wps_offset+wps_ielen+2) <= MAX_IE_SZ) { 2672 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2); 2673 pframe += wps_ielen+2; 2674 pattrib->pktlen += wps_ielen+2; 2675 } 2676 2677 if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) { 2678 memcpy(pframe, premainder_ie, remainder_ielen); 2679 pframe += remainder_ielen; 2680 pattrib->pktlen += remainder_ielen; 2681 } 2682 } else { 2683 memcpy(pframe, cur_network->IEs, cur_network->IELength); 2684 pframe += cur_network->IELength; 2685 pattrib->pktlen += cur_network->IELength; 2686 } 2687 2688 /* retrieve SSID IE from cur_network->Ssid */ 2689 { 2690 u8 *ssid_ie; 2691 sint ssid_ielen; 2692 sint ssid_ielen_diff; 2693 u8 buf[MAX_IE_SZ]; 2694 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr); 2695 2696 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen, 2697 (pframe-ies)-_FIXED_IE_LENGTH_); 2698 2699 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen; 2700 2701 if (ssid_ie && cur_network->Ssid.SsidLength) { 2702 uint remainder_ielen; 2703 u8 *remainder_ie; 2704 2705 remainder_ie = ssid_ie+2; 2706 remainder_ielen = (pframe-remainder_ie); 2707 2708 if (remainder_ielen > MAX_IE_SZ) { 2709 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter)); 2710 remainder_ielen = MAX_IE_SZ; 2711 } 2712 2713 memcpy(buf, remainder_ie, remainder_ielen); 2714 memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen); 2715 *(ssid_ie+1) = cur_network->Ssid.SsidLength; 2716 memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength); 2717 2718 pframe += ssid_ielen_diff; 2719 pattrib->pktlen += ssid_ielen_diff; 2720 } 2721 } 2722 } else { 2723 /* timestamp will be inserted by hardware */ 2724 pframe += 8; 2725 pattrib->pktlen += 8; 2726 2727 /* beacon interval: 2 bytes */ 2728 2729 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 2730 2731 pframe += 2; 2732 pattrib->pktlen += 2; 2733 2734 /* capability info: 2 bytes */ 2735 2736 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); 2737 2738 pframe += 2; 2739 pattrib->pktlen += 2; 2740 2741 /* below for ad-hoc mode */ 2742 2743 /* SSID */ 2744 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); 2745 2746 /* supported rates... */ 2747 rate_len = rtw_get_rateset_len(cur_network->SupportedRates); 2748 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen); 2749 2750 /* DS parameter set */ 2751 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen); 2752 2753 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { 2754 u8 erpinfo = 0; 2755 u32 ATIMWindow; 2756 /* IBSS Parameter Set... */ 2757 /* ATIMWindow = cur->Configuration.ATIMWindow; */ 2758 ATIMWindow = 0; 2759 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen); 2760 2761 /* ERP IE */ 2762 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen); 2763 } 2764 2765 2766 /* EXTERNDED SUPPORTED RATE */ 2767 if (rate_len > 8) { 2768 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); 2769 } 2770 2771 2772 /* todo:HT for adhoc */ 2773 2774 } 2775 2776 #ifdef CONFIG_AUTO_AP_MODE 2777 { 2778 struct sta_info *psta; 2779 struct sta_priv *pstapriv = &padapter->stapriv; 2780 2781 DBG_871X("(%s)\n", __func__); 2782 2783 /* check rc station */ 2784 psta = rtw_get_stainfo(pstapriv, da); 2785 if (psta && psta->isrc && psta->pid > 0) { 2786 u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A}; 2787 u8 RC_INFO[14] = {0}; 2788 /* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */ 2789 u16 cu_ch = (u16)cur_network->Configuration.DSConfig; 2790 2791 DBG_871X("%s, reply rc(pid = 0x%x) device "MAC_FMT" in ch =%d\n", __func__, 2792 psta->pid, MAC_ARG(psta->hwaddr), cu_ch); 2793 2794 /* append vendor specific ie */ 2795 memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI)); 2796 memcpy(&RC_INFO[4], mac, ETH_ALEN); 2797 memcpy(&RC_INFO[10], (u8 *)&psta->pid, 2); 2798 memcpy(&RC_INFO[12], (u8 *)&cu_ch, 2); 2799 2800 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen); 2801 } 2802 } 2803 #endif /* CONFIG_AUTO_AP_MODE */ 2804 2805 2806 pattrib->last_txcmdsz = pattrib->pktlen; 2807 2808 2809 dump_mgntframe(padapter, pmgntframe); 2810 2811 return; 2812 2813 } 2814 2815 static int _issue_probereq(struct adapter *padapter, 2816 struct ndis_802_11_ssid *pssid, 2817 u8 *da, u8 ch, bool append_wps, bool wait_ack) 2818 { 2819 int ret = _FAIL; 2820 struct xmit_frame *pmgntframe; 2821 struct pkt_attrib *pattrib; 2822 unsigned char *pframe; 2823 struct ieee80211_hdr *pwlanhdr; 2824 __le16 *fctrl; 2825 unsigned char *mac; 2826 unsigned char bssrate[NumRates]; 2827 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2828 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2829 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2830 int bssrate_len = 0; 2831 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 2832 2833 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("+issue_probereq\n")); 2834 2835 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2836 if (!pmgntframe) 2837 goto exit; 2838 2839 /* update attribute */ 2840 pattrib = &pmgntframe->attrib; 2841 update_mgntframe_attrib(padapter, pattrib); 2842 2843 2844 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2845 2846 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2847 pwlanhdr = (struct ieee80211_hdr *)pframe; 2848 2849 mac = myid(&(padapter->eeprompriv)); 2850 2851 fctrl = &(pwlanhdr->frame_control); 2852 *(fctrl) = 0; 2853 2854 if (da) { 2855 /* unicast probe request frame */ 2856 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 2857 memcpy(pwlanhdr->addr3, da, ETH_ALEN); 2858 } else { 2859 /* broadcast probe request frame */ 2860 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); 2861 memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN); 2862 } 2863 2864 memcpy(pwlanhdr->addr2, mac, ETH_ALEN); 2865 2866 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2867 pmlmeext->mgnt_seq++; 2868 SetFrameSubType(pframe, WIFI_PROBEREQ); 2869 2870 pframe += sizeof(struct ieee80211_hdr_3addr); 2871 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 2872 2873 if (pssid) 2874 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen)); 2875 else 2876 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen)); 2877 2878 get_rate_set(padapter, bssrate, &bssrate_len); 2879 2880 if (bssrate_len > 8) { 2881 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &(pattrib->pktlen)); 2882 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); 2883 } else { 2884 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &(pattrib->pktlen)); 2885 } 2886 2887 if (ch) 2888 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen); 2889 2890 if (append_wps) { 2891 /* add wps_ie for wps2.0 */ 2892 if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) { 2893 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); 2894 pframe += pmlmepriv->wps_probe_req_ie_len; 2895 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; 2896 } 2897 } 2898 2899 pattrib->last_txcmdsz = pattrib->pktlen; 2900 2901 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz)); 2902 2903 if (wait_ack) { 2904 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); 2905 } else { 2906 dump_mgntframe(padapter, pmgntframe); 2907 ret = _SUCCESS; 2908 } 2909 2910 exit: 2911 return ret; 2912 } 2913 2914 inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da) 2915 { 2916 _issue_probereq(padapter, pssid, da, 0, 1, false); 2917 } 2918 2919 int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, u8 ch, bool append_wps, 2920 int try_cnt, int wait_ms) 2921 { 2922 int ret; 2923 int i = 0; 2924 2925 do { 2926 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, 2927 wait_ms > 0); 2928 2929 i++; 2930 2931 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 2932 break; 2933 2934 if (i < try_cnt && wait_ms > 0 && ret == _FAIL) 2935 msleep(wait_ms); 2936 2937 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); 2938 2939 if (ret != _FAIL) { 2940 ret = _SUCCESS; 2941 #ifndef DBG_XMIT_ACK 2942 goto exit; 2943 #endif 2944 } 2945 2946 if (try_cnt && wait_ms) { 2947 if (da) 2948 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n", 2949 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter), 2950 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms); 2951 else 2952 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", 2953 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), 2954 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms); 2955 } 2956 exit: 2957 return ret; 2958 } 2959 2960 /* if psta == NULL, indicate we are station(client) now... */ 2961 void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status) 2962 { 2963 struct xmit_frame *pmgntframe; 2964 struct pkt_attrib *pattrib; 2965 unsigned char *pframe; 2966 struct ieee80211_hdr *pwlanhdr; 2967 __le16 *fctrl; 2968 unsigned int val32; 2969 unsigned short val16; 2970 int use_shared_key = 0; 2971 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2972 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2973 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2974 __le16 le_tmp; 2975 2976 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2977 if (pmgntframe == NULL) 2978 return; 2979 2980 /* update attribute */ 2981 pattrib = &pmgntframe->attrib; 2982 update_mgntframe_attrib(padapter, pattrib); 2983 2984 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2985 2986 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2987 pwlanhdr = (struct ieee80211_hdr *)pframe; 2988 2989 fctrl = &(pwlanhdr->frame_control); 2990 *(fctrl) = 0; 2991 2992 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2993 pmlmeext->mgnt_seq++; 2994 SetFrameSubType(pframe, WIFI_AUTH); 2995 2996 pframe += sizeof(struct ieee80211_hdr_3addr); 2997 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 2998 2999 3000 if (psta) { /* for AP mode */ 3001 memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN); 3002 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3003 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); 3004 3005 /* setting auth algo number */ 3006 val16 = (u16)psta->authalg; 3007 3008 if (status != _STATS_SUCCESSFUL_) 3009 val16 = 0; 3010 3011 if (val16) 3012 use_shared_key = 1; 3013 3014 le_tmp = cpu_to_le16(val16); 3015 3016 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3017 3018 /* setting auth seq number */ 3019 val16 = (u16)psta->auth_seq; 3020 le_tmp = cpu_to_le16(val16); 3021 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3022 3023 /* setting status code... */ 3024 val16 = status; 3025 le_tmp = cpu_to_le16(val16); 3026 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3027 3028 /* added challenging text... */ 3029 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) 3030 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen)); 3031 3032 } else { 3033 memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); 3034 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); 3035 memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); 3036 3037 /* setting auth algo number */ 3038 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/* 0:OPEN System, 1:Shared key */ 3039 if (val16) { 3040 use_shared_key = 1; 3041 } 3042 le_tmp = cpu_to_le16(val16); 3043 /* DBG_871X("%s auth_algo = %s auth_seq =%d\n", __func__, (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED", pmlmeinfo->auth_seq); */ 3044 3045 /* setting IV for auth seq #3 */ 3046 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) { 3047 __le32 le_tmp32; 3048 3049 /* DBG_871X("==> iv(%d), key_index(%d)\n", pmlmeinfo->iv, pmlmeinfo->key_index); */ 3050 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30)); 3051 le_tmp32 = cpu_to_le32(val32); 3052 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &(pattrib->pktlen)); 3053 3054 pattrib->iv_len = 4; 3055 } 3056 3057 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3058 3059 /* setting auth seq number */ 3060 le_tmp = cpu_to_le16(pmlmeinfo->auth_seq); 3061 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3062 3063 3064 /* setting status code... */ 3065 le_tmp = cpu_to_le16(status); 3066 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3067 3068 /* then checking to see if sending challenging text... */ 3069 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) { 3070 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen)); 3071 3072 SetPrivacy(fctrl); 3073 3074 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr); 3075 3076 pattrib->encrypt = _WEP40_; 3077 3078 pattrib->icv_len = 4; 3079 3080 pattrib->pktlen += pattrib->icv_len; 3081 3082 } 3083 3084 } 3085 3086 pattrib->last_txcmdsz = pattrib->pktlen; 3087 3088 rtw_wep_encrypt(padapter, (u8 *)pmgntframe); 3089 DBG_871X("%s\n", __func__); 3090 dump_mgntframe(padapter, pmgntframe); 3091 } 3092 3093 3094 void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type) 3095 { 3096 struct xmit_frame *pmgntframe; 3097 struct ieee80211_hdr *pwlanhdr; 3098 struct pkt_attrib *pattrib; 3099 unsigned char *pbuf, *pframe; 3100 unsigned short val; 3101 __le16 *fctrl; 3102 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3103 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3104 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 3105 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3106 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); 3107 u8 *ie = pnetwork->IEs; 3108 __le16 lestatus, le_tmp; 3109 3110 DBG_871X("%s\n", __func__); 3111 3112 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3113 if (pmgntframe == NULL) 3114 return; 3115 3116 /* update attribute */ 3117 pattrib = &pmgntframe->attrib; 3118 update_mgntframe_attrib(padapter, pattrib); 3119 3120 3121 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3122 3123 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3124 pwlanhdr = (struct ieee80211_hdr *)pframe; 3125 3126 fctrl = &(pwlanhdr->frame_control); 3127 *(fctrl) = 0; 3128 3129 memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN); 3130 memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN); 3131 memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3132 3133 3134 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3135 pmlmeext->mgnt_seq++; 3136 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) 3137 SetFrameSubType(pwlanhdr, pkt_type); 3138 else 3139 return; 3140 3141 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr); 3142 pattrib->pktlen += pattrib->hdrlen; 3143 pframe += pattrib->hdrlen; 3144 3145 /* capability */ 3146 val = *(unsigned short *)rtw_get_capability_from_ie(ie); 3147 3148 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &(pattrib->pktlen)); 3149 3150 lestatus = cpu_to_le16(status); 3151 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &(pattrib->pktlen)); 3152 3153 le_tmp = cpu_to_le16(pstat->aid | BIT(14) | BIT(15)); 3154 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3155 3156 if (pstat->bssratelen <= 8) { 3157 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen)); 3158 } else { 3159 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen)); 3160 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen)); 3161 } 3162 3163 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) { 3164 uint ie_len = 0; 3165 3166 /* FILL HT CAP INFO IE */ 3167 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */ 3168 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); 3169 if (pbuf && ie_len > 0) { 3170 memcpy(pframe, pbuf, ie_len+2); 3171 pframe += (ie_len+2); 3172 pattrib->pktlen += (ie_len+2); 3173 } 3174 3175 /* FILL HT ADD INFO IE */ 3176 /* p = hostapd_eid_ht_operation(hapd, p); */ 3177 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); 3178 if (pbuf && ie_len > 0) { 3179 memcpy(pframe, pbuf, ie_len+2); 3180 pframe += (ie_len+2); 3181 pattrib->pktlen += (ie_len+2); 3182 } 3183 3184 } 3185 3186 /* FILL WMM IE */ 3187 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) { 3188 uint ie_len = 0; 3189 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; 3190 3191 for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) { 3192 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); 3193 if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6)) { 3194 memcpy(pframe, pbuf, ie_len+2); 3195 pframe += (ie_len+2); 3196 pattrib->pktlen += (ie_len+2); 3197 3198 break; 3199 } 3200 3201 if ((pbuf == NULL) || (ie_len == 0)) { 3202 break; 3203 } 3204 } 3205 3206 } 3207 3208 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) { 3209 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &(pattrib->pktlen)); 3210 } 3211 3212 /* add WPS IE ie for wps 2.0 */ 3213 if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) { 3214 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len); 3215 3216 pframe += pmlmepriv->wps_assoc_resp_ie_len; 3217 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len; 3218 } 3219 3220 pattrib->last_txcmdsz = pattrib->pktlen; 3221 3222 dump_mgntframe(padapter, pmgntframe); 3223 } 3224 3225 void issue_assocreq(struct adapter *padapter) 3226 { 3227 int ret = _FAIL; 3228 struct xmit_frame *pmgntframe; 3229 struct pkt_attrib *pattrib; 3230 unsigned char *pframe; 3231 struct ieee80211_hdr *pwlanhdr; 3232 __le16 *fctrl; 3233 __le16 val16; 3234 unsigned int i, j, index = 0; 3235 unsigned char bssrate[NumRates], sta_bssrate[NumRates]; 3236 struct ndis_80211_var_ie *pIE; 3237 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3238 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 3239 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3240 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3241 int bssrate_len = 0, sta_bssrate_len = 0; 3242 u8 vs_ie_length = 0; 3243 3244 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3245 if (pmgntframe == NULL) 3246 goto exit; 3247 3248 /* update attribute */ 3249 pattrib = &pmgntframe->attrib; 3250 update_mgntframe_attrib(padapter, pattrib); 3251 3252 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3253 3254 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3255 pwlanhdr = (struct ieee80211_hdr *)pframe; 3256 3257 fctrl = &(pwlanhdr->frame_control); 3258 *(fctrl) = 0; 3259 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3260 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3261 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3262 3263 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3264 pmlmeext->mgnt_seq++; 3265 SetFrameSubType(pframe, WIFI_ASSOCREQ); 3266 3267 pframe += sizeof(struct ieee80211_hdr_3addr); 3268 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3269 3270 /* caps */ 3271 memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); 3272 3273 pframe += 2; 3274 pattrib->pktlen += 2; 3275 3276 /* listen interval */ 3277 /* todo: listen interval for power saving */ 3278 val16 = cpu_to_le16(3); 3279 memcpy(pframe, (unsigned char *)&val16, 2); 3280 pframe += 2; 3281 pattrib->pktlen += 2; 3282 3283 /* SSID */ 3284 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen)); 3285 3286 /* supported rate & extended supported rate */ 3287 3288 /* Check if the AP's supported rates are also supported by STA. */ 3289 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len); 3290 /* DBG_871X("sta_bssrate_len =%d\n", sta_bssrate_len); */ 3291 3292 if (pmlmeext->cur_channel == 14) /* for JAPAN, channel 14 can only uses B Mode(CCK) */ 3293 sta_bssrate_len = 4; 3294 3295 3296 /* for (i = 0; i < sta_bssrate_len; i++) { */ 3297 /* DBG_871X("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */ 3298 /* */ 3299 3300 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { 3301 if (pmlmeinfo->network.SupportedRates[i] == 0) 3302 break; 3303 DBG_871X("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]); 3304 } 3305 3306 3307 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { 3308 if (pmlmeinfo->network.SupportedRates[i] == 0) 3309 break; 3310 3311 3312 /* Check if the AP's supported rates are also supported by STA. */ 3313 for (j = 0; j < sta_bssrate_len; j++) { 3314 /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */ 3315 if ((pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK) 3316 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) { 3317 /* DBG_871X("match i = %d, j =%d\n", i, j); */ 3318 break; 3319 } else { 3320 /* DBG_871X("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */ 3321 } 3322 } 3323 3324 if (j == sta_bssrate_len) { 3325 /* the rate is not supported by STA */ 3326 DBG_871X("%s(): the rate[%d]=%02X is not supported by STA!\n", __func__, i, pmlmeinfo->network.SupportedRates[i]); 3327 } else { 3328 /* the rate is supported by STA */ 3329 bssrate[index++] = pmlmeinfo->network.SupportedRates[i]; 3330 } 3331 } 3332 3333 bssrate_len = index; 3334 DBG_871X("bssrate_len = %d\n", bssrate_len); 3335 3336 if (bssrate_len == 0) { 3337 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); 3338 rtw_free_xmitframe(pxmitpriv, pmgntframe); 3339 goto exit; /* don't connect to AP if no joint supported rate */ 3340 } 3341 3342 3343 if (bssrate_len > 8) { 3344 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, bssrate, &(pattrib->pktlen)); 3345 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); 3346 } else 3347 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, bssrate_len, bssrate, &(pattrib->pktlen)); 3348 3349 /* vendor specific IE, such as WPA, WMM, WPS */ 3350 for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.IELength;) { 3351 pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.IEs + i); 3352 3353 switch (pIE->ElementID) { 3354 case _VENDOR_SPECIFIC_IE_: 3355 if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) || 3356 (!memcmp(pIE->data, WMM_OUI, 4)) || 3357 (!memcmp(pIE->data, WPS_OUI, 4))) { 3358 vs_ie_length = pIE->Length; 3359 if ((!padapter->registrypriv.wifi_spec) && (!memcmp(pIE->data, WPS_OUI, 4))) { 3360 /* Commented by Kurt 20110629 3361 * In some older APs, WPS handshake 3362 * would be fail if we append vendor 3363 * extensions information to AP 3364 */ 3365 3366 vs_ie_length = 14; 3367 } 3368 3369 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen)); 3370 } 3371 break; 3372 3373 case EID_WPA2: 3374 pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen)); 3375 break; 3376 case EID_HTCapability: 3377 if (padapter->mlmepriv.htpriv.ht_option) { 3378 if (!(is_ap_in_tkip(padapter))) { 3379 memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element)); 3380 pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length, (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen)); 3381 } 3382 } 3383 break; 3384 3385 case EID_EXTCapability: 3386 if (padapter->mlmepriv.htpriv.ht_option) 3387 pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen)); 3388 break; 3389 default: 3390 break; 3391 } 3392 3393 i += (pIE->Length + 2); 3394 } 3395 3396 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) 3397 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6, REALTEK_96B_IE, &(pattrib->pktlen)); 3398 3399 3400 pattrib->last_txcmdsz = pattrib->pktlen; 3401 dump_mgntframe(padapter, pmgntframe); 3402 3403 ret = _SUCCESS; 3404 3405 exit: 3406 if (ret == _SUCCESS) 3407 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); 3408 else 3409 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); 3410 } 3411 3412 /* when wait_ack is true, this function should be called at process context */ 3413 static int _issue_nulldata(struct adapter *padapter, unsigned char *da, 3414 unsigned int power_mode, bool wait_ack) 3415 { 3416 int ret = _FAIL; 3417 struct xmit_frame *pmgntframe; 3418 struct pkt_attrib *pattrib; 3419 unsigned char *pframe; 3420 struct ieee80211_hdr *pwlanhdr; 3421 __le16 *fctrl; 3422 struct xmit_priv *pxmitpriv; 3423 struct mlme_ext_priv *pmlmeext; 3424 struct mlme_ext_info *pmlmeinfo; 3425 3426 /* DBG_871X("%s:%d\n", __func__, power_mode); */ 3427 3428 if (!padapter) 3429 goto exit; 3430 3431 pxmitpriv = &(padapter->xmitpriv); 3432 pmlmeext = &(padapter->mlmeextpriv); 3433 pmlmeinfo = &(pmlmeext->mlmext_info); 3434 3435 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3436 if (pmgntframe == NULL) 3437 goto exit; 3438 3439 /* update attribute */ 3440 pattrib = &pmgntframe->attrib; 3441 update_mgntframe_attrib(padapter, pattrib); 3442 pattrib->retry_ctrl = false; 3443 3444 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3445 3446 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3447 pwlanhdr = (struct ieee80211_hdr *)pframe; 3448 3449 fctrl = &(pwlanhdr->frame_control); 3450 *(fctrl) = 0; 3451 3452 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) 3453 SetFrDs(fctrl); 3454 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) 3455 SetToDs(fctrl); 3456 3457 if (power_mode) 3458 SetPwrMgt(fctrl); 3459 3460 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 3461 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3462 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3463 3464 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3465 pmlmeext->mgnt_seq++; 3466 SetFrameSubType(pframe, WIFI_DATA_NULL); 3467 3468 pframe += sizeof(struct ieee80211_hdr_3addr); 3469 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3470 3471 pattrib->last_txcmdsz = pattrib->pktlen; 3472 3473 if (wait_ack) { 3474 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); 3475 } else { 3476 dump_mgntframe(padapter, pmgntframe); 3477 ret = _SUCCESS; 3478 } 3479 3480 exit: 3481 return ret; 3482 } 3483 3484 /* 3485 * [IMPORTANT] Don't call this function in interrupt context 3486 * 3487 * When wait_ms > 0, this function should be called at process context 3488 * da == NULL for station mode 3489 */ 3490 int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms) 3491 { 3492 int ret; 3493 int i = 0; 3494 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3495 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3496 struct sta_info *psta; 3497 3498 3499 /* da == NULL, assume it's null data for sta to ap*/ 3500 if (!da) 3501 da = get_my_bssid(&(pmlmeinfo->network)); 3502 3503 psta = rtw_get_stainfo(&padapter->stapriv, da); 3504 if (psta) { 3505 if (power_mode) 3506 rtw_hal_macid_sleep(padapter, psta->mac_id); 3507 else 3508 rtw_hal_macid_wakeup(padapter, psta->mac_id); 3509 } else { 3510 DBG_871X(FUNC_ADPT_FMT ": Can't find sta info for " MAC_FMT ", skip macid %s!!\n", 3511 FUNC_ADPT_ARG(padapter), MAC_ARG(da), power_mode?"sleep":"wakeup"); 3512 rtw_warn_on(1); 3513 } 3514 3515 do { 3516 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0); 3517 3518 i++; 3519 3520 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 3521 break; 3522 3523 if (i < try_cnt && wait_ms > 0 && ret == _FAIL) 3524 msleep(wait_ms); 3525 3526 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); 3527 3528 if (ret != _FAIL) { 3529 ret = _SUCCESS; 3530 #ifndef DBG_XMIT_ACK 3531 goto exit; 3532 #endif 3533 } 3534 3535 if (try_cnt && wait_ms) { 3536 if (da) 3537 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n", 3538 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter), 3539 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms); 3540 else 3541 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", 3542 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), 3543 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms); 3544 } 3545 exit: 3546 return ret; 3547 } 3548 3549 /* 3550 * [IMPORTANT] This function run in interrupt context 3551 * 3552 * The null data packet would be sent without power bit, 3553 * and not guarantee success. 3554 */ 3555 s32 issue_nulldata_in_interrupt(struct adapter *padapter, u8 *da) 3556 { 3557 struct mlme_ext_priv *pmlmeext; 3558 struct mlme_ext_info *pmlmeinfo; 3559 3560 3561 pmlmeext = &padapter->mlmeextpriv; 3562 pmlmeinfo = &pmlmeext->mlmext_info; 3563 3564 /* da == NULL, assume it's null data for sta to ap*/ 3565 if (!da) 3566 da = get_my_bssid(&(pmlmeinfo->network)); 3567 3568 return _issue_nulldata(padapter, da, 0, false); 3569 } 3570 3571 /* when wait_ack is true, this function should be called at process context */ 3572 static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, 3573 u16 tid, bool wait_ack) 3574 { 3575 int ret = _FAIL; 3576 struct xmit_frame *pmgntframe; 3577 struct pkt_attrib *pattrib; 3578 unsigned char *pframe; 3579 struct ieee80211_hdr *pwlanhdr; 3580 __le16 *fctrl; 3581 u16 *qc; 3582 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3583 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3584 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3585 3586 DBG_871X("%s\n", __func__); 3587 3588 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3589 if (pmgntframe == NULL) 3590 goto exit; 3591 3592 /* update attribute */ 3593 pattrib = &pmgntframe->attrib; 3594 update_mgntframe_attrib(padapter, pattrib); 3595 3596 pattrib->hdrlen += 2; 3597 pattrib->qos_en = true; 3598 pattrib->eosp = 1; 3599 pattrib->ack_policy = 0; 3600 pattrib->mdata = 0; 3601 3602 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3603 3604 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3605 pwlanhdr = (struct ieee80211_hdr *)pframe; 3606 3607 fctrl = &(pwlanhdr->frame_control); 3608 *(fctrl) = 0; 3609 3610 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) 3611 SetFrDs(fctrl); 3612 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) 3613 SetToDs(fctrl); 3614 3615 if (pattrib->mdata) 3616 SetMData(fctrl); 3617 3618 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2); 3619 3620 SetPriority(qc, tid); 3621 3622 SetEOSP(qc, pattrib->eosp); 3623 3624 SetAckpolicy(qc, pattrib->ack_policy); 3625 3626 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 3627 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3628 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3629 3630 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3631 pmlmeext->mgnt_seq++; 3632 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); 3633 3634 pframe += sizeof(struct ieee80211_qos_hdr); 3635 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr); 3636 3637 pattrib->last_txcmdsz = pattrib->pktlen; 3638 3639 if (wait_ack) { 3640 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); 3641 } else { 3642 dump_mgntframe(padapter, pmgntframe); 3643 ret = _SUCCESS; 3644 } 3645 3646 exit: 3647 return ret; 3648 } 3649 3650 /* when wait_ms >0 , this function should be called at process context */ 3651 /* da == NULL for station mode */ 3652 int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms) 3653 { 3654 int ret; 3655 int i = 0; 3656 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3657 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3658 3659 /* da == NULL, assume it's null data for sta to ap*/ 3660 if (!da) 3661 da = get_my_bssid(&(pmlmeinfo->network)); 3662 3663 do { 3664 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0); 3665 3666 i++; 3667 3668 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 3669 break; 3670 3671 if (i < try_cnt && wait_ms > 0 && ret == _FAIL) 3672 msleep(wait_ms); 3673 3674 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); 3675 3676 if (ret != _FAIL) { 3677 ret = _SUCCESS; 3678 #ifndef DBG_XMIT_ACK 3679 goto exit; 3680 #endif 3681 } 3682 3683 if (try_cnt && wait_ms) { 3684 if (da) 3685 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n", 3686 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter), 3687 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms); 3688 else 3689 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", 3690 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), 3691 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms); 3692 } 3693 exit: 3694 return ret; 3695 } 3696 3697 static int _issue_deauth(struct adapter *padapter, unsigned char *da, 3698 unsigned short reason, bool wait_ack) 3699 { 3700 struct xmit_frame *pmgntframe; 3701 struct pkt_attrib *pattrib; 3702 unsigned char *pframe; 3703 struct ieee80211_hdr *pwlanhdr; 3704 __le16 *fctrl; 3705 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3706 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3707 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3708 int ret = _FAIL; 3709 __le16 le_tmp; 3710 3711 /* DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */ 3712 3713 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3714 if (pmgntframe == NULL) { 3715 goto exit; 3716 } 3717 3718 /* update attribute */ 3719 pattrib = &pmgntframe->attrib; 3720 update_mgntframe_attrib(padapter, pattrib); 3721 pattrib->retry_ctrl = false; 3722 3723 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3724 3725 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3726 pwlanhdr = (struct ieee80211_hdr *)pframe; 3727 3728 fctrl = &(pwlanhdr->frame_control); 3729 *(fctrl) = 0; 3730 3731 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 3732 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3733 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3734 3735 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3736 pmlmeext->mgnt_seq++; 3737 SetFrameSubType(pframe, WIFI_DEAUTH); 3738 3739 pframe += sizeof(struct ieee80211_hdr_3addr); 3740 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3741 3742 le_tmp = cpu_to_le16(reason); 3743 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3744 3745 pattrib->last_txcmdsz = pattrib->pktlen; 3746 3747 3748 if (wait_ack) { 3749 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); 3750 } else { 3751 dump_mgntframe(padapter, pmgntframe); 3752 ret = _SUCCESS; 3753 } 3754 3755 exit: 3756 return ret; 3757 } 3758 3759 int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason) 3760 { 3761 DBG_871X("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); 3762 return _issue_deauth(padapter, da, reason, false); 3763 } 3764 3765 int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt, 3766 int wait_ms) 3767 { 3768 int ret; 3769 int i = 0; 3770 3771 do { 3772 ret = _issue_deauth(padapter, da, reason, wait_ms > 0); 3773 3774 i++; 3775 3776 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 3777 break; 3778 3779 if (i < try_cnt && wait_ms > 0 && ret == _FAIL) 3780 mdelay(wait_ms); 3781 3782 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); 3783 3784 if (ret != _FAIL) { 3785 ret = _SUCCESS; 3786 #ifndef DBG_XMIT_ACK 3787 goto exit; 3788 #endif 3789 } 3790 3791 if (try_cnt && wait_ms) { 3792 if (da) 3793 DBG_871X(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n", 3794 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter), 3795 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms); 3796 else 3797 DBG_871X(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n", 3798 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter), 3799 ret == _SUCCESS?", acked":"", i, try_cnt, (i + 1) * wait_ms); 3800 } 3801 exit: 3802 return ret; 3803 } 3804 3805 void issue_action_SA_Query(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid) 3806 { 3807 u8 category = RTW_WLAN_CATEGORY_SA_QUERY; 3808 struct xmit_frame *pmgntframe; 3809 struct pkt_attrib *pattrib; 3810 u8 *pframe; 3811 struct ieee80211_hdr *pwlanhdr; 3812 __le16 *fctrl; 3813 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3814 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3815 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3816 __le16 le_tmp; 3817 3818 DBG_871X("%s\n", __func__); 3819 3820 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3821 if (pmgntframe == NULL) { 3822 DBG_871X("%s: alloc_mgtxmitframe fail\n", __func__); 3823 return; 3824 } 3825 3826 /* update attribute */ 3827 pattrib = &pmgntframe->attrib; 3828 update_mgntframe_attrib(padapter, pattrib); 3829 3830 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3831 3832 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3833 pwlanhdr = (struct ieee80211_hdr *)pframe; 3834 3835 fctrl = &(pwlanhdr->frame_control); 3836 *(fctrl) = 0; 3837 3838 if (raddr) 3839 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); 3840 else 3841 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3842 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3843 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3844 3845 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3846 pmlmeext->mgnt_seq++; 3847 SetFrameSubType(pframe, WIFI_ACTION); 3848 3849 pframe += sizeof(struct ieee80211_hdr_3addr); 3850 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3851 3852 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); 3853 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); 3854 3855 switch (action) { 3856 case 0: /* SA Query req */ 3857 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen); 3858 pmlmeext->sa_query_seq++; 3859 /* send sa query request to AP, AP should reply sa query response in 1 second */ 3860 set_sa_query_timer(pmlmeext, 1000); 3861 break; 3862 3863 case 1: /* SA Query rsp */ 3864 le_tmp = cpu_to_le16(tid); 3865 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); 3866 break; 3867 default: 3868 break; 3869 } 3870 3871 pattrib->last_txcmdsz = pattrib->pktlen; 3872 3873 dump_mgntframe(padapter, pmgntframe); 3874 } 3875 3876 void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status) 3877 { 3878 u8 category = RTW_WLAN_CATEGORY_BACK; 3879 u16 start_seq; 3880 u16 BA_para_set; 3881 u16 reason_code; 3882 u16 BA_timeout_value; 3883 u16 BA_starting_seqctrl = 0; 3884 enum HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor; 3885 struct xmit_frame *pmgntframe; 3886 struct pkt_attrib *pattrib; 3887 u8 *pframe; 3888 struct ieee80211_hdr *pwlanhdr; 3889 __le16 *fctrl; 3890 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3891 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3892 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3893 struct sta_info *psta; 3894 struct sta_priv *pstapriv = &padapter->stapriv; 3895 struct registry_priv *pregpriv = &padapter->registrypriv; 3896 __le16 le_tmp; 3897 3898 DBG_871X("%s, category =%d, action =%d, status =%d\n", __func__, category, action, status); 3899 3900 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3901 if (!pmgntframe) 3902 return; 3903 3904 /* update attribute */ 3905 pattrib = &pmgntframe->attrib; 3906 update_mgntframe_attrib(padapter, pattrib); 3907 3908 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3909 3910 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3911 pwlanhdr = (struct ieee80211_hdr *)pframe; 3912 3913 fctrl = &(pwlanhdr->frame_control); 3914 *(fctrl) = 0; 3915 3916 /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */ 3917 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); 3918 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3919 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3920 3921 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3922 pmlmeext->mgnt_seq++; 3923 SetFrameSubType(pframe, WIFI_ACTION); 3924 3925 pframe += sizeof(struct ieee80211_hdr_3addr); 3926 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3927 3928 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); 3929 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); 3930 3931 if (category == 3) { 3932 switch (action) { 3933 case 0: /* ADDBA req */ 3934 do { 3935 pmlmeinfo->dialogToken++; 3936 } while (pmlmeinfo->dialogToken == 0); 3937 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen)); 3938 3939 if (hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter)) { 3940 /* A-MSDU NOT Supported */ 3941 BA_para_set = 0; 3942 /* immediate Block Ack */ 3943 BA_para_set |= BIT(1) & IEEE80211_ADDBA_PARAM_POLICY_MASK; 3944 /* TID */ 3945 BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK; 3946 /* max buffer size is 8 MSDU */ 3947 BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; 3948 } else { 3949 BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */ 3950 } 3951 le_tmp = cpu_to_le16(BA_para_set); 3952 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3953 3954 BA_timeout_value = 5000;/* 5ms */ 3955 le_tmp = cpu_to_le16(BA_timeout_value); 3956 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3957 3958 /* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */ 3959 psta = rtw_get_stainfo(pstapriv, raddr); 3960 if (psta != NULL) { 3961 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1; 3962 3963 DBG_871X("BA_starting_seqctrl = %d for TID =%d\n", start_seq, status & 0x07); 3964 3965 psta->BA_starting_seqctrl[status & 0x07] = start_seq; 3966 3967 BA_starting_seqctrl = start_seq << 4; 3968 } 3969 3970 le_tmp = cpu_to_le16(BA_starting_seqctrl); 3971 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3972 break; 3973 3974 case 1: /* ADDBA rsp */ 3975 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen)); 3976 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen)); 3977 if (padapter->driver_rx_ampdu_factor != 0xFF) 3978 max_rx_ampdu_factor = 3979 (enum HT_CAP_AMPDU_FACTOR)padapter->driver_rx_ampdu_factor; 3980 else 3981 rtw_hal_get_def_var(padapter, 3982 HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); 3983 3984 if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor) 3985 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */ 3986 else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor) 3987 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */ 3988 else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor) 3989 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */ 3990 else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor) 3991 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */ 3992 else 3993 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */ 3994 3995 if (hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter) && 3996 padapter->driver_rx_ampdu_factor == 0xFF) { 3997 /* max buffer size is 8 MSDU */ 3998 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; 3999 BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; 4000 } 4001 4002 if (pregpriv->ampdu_amsdu == 0)/* disabled */ 4003 le_tmp = cpu_to_le16(BA_para_set & ~BIT(0)); 4004 else if (pregpriv->ampdu_amsdu == 1)/* enabled */ 4005 le_tmp = cpu_to_le16(BA_para_set | BIT(0)); 4006 else /* auto */ 4007 le_tmp = cpu_to_le16(BA_para_set); 4008 4009 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 4010 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen)); 4011 break; 4012 case 2:/* DELBA */ 4013 BA_para_set = (status & 0x1F) << 3; 4014 le_tmp = cpu_to_le16(BA_para_set); 4015 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 4016 4017 reason_code = 37; 4018 le_tmp = cpu_to_le16(reason_code); 4019 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 4020 break; 4021 default: 4022 break; 4023 } 4024 } 4025 4026 pattrib->last_txcmdsz = pattrib->pktlen; 4027 4028 dump_mgntframe(padapter, pmgntframe); 4029 } 4030 4031 static void issue_action_BSSCoexistPacket(struct adapter *padapter) 4032 { 4033 struct list_head *plist, *phead; 4034 unsigned char category, action; 4035 struct xmit_frame *pmgntframe; 4036 struct pkt_attrib *pattrib; 4037 unsigned char *pframe; 4038 struct ieee80211_hdr *pwlanhdr; 4039 __le16 *fctrl; 4040 struct wlan_network *pnetwork = NULL; 4041 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 4042 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 4043 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 4044 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4045 struct __queue *queue = &(pmlmepriv->scanned_queue); 4046 u8 InfoContent[16] = {0}; 4047 u8 ICS[8][15]; 4048 4049 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0)) 4050 return; 4051 4052 if (true == pmlmeinfo->bwmode_updated) 4053 return; 4054 4055 4056 DBG_871X("%s\n", __func__); 4057 4058 4059 category = RTW_WLAN_CATEGORY_PUBLIC; 4060 action = ACT_PUBLIC_BSSCOEXIST; 4061 4062 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 4063 if (pmgntframe == NULL) { 4064 return; 4065 } 4066 4067 /* update attribute */ 4068 pattrib = &pmgntframe->attrib; 4069 update_mgntframe_attrib(padapter, pattrib); 4070 4071 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 4072 4073 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 4074 pwlanhdr = (struct ieee80211_hdr *)pframe; 4075 4076 fctrl = &(pwlanhdr->frame_control); 4077 *(fctrl) = 0; 4078 4079 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 4080 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 4081 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 4082 4083 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 4084 pmlmeext->mgnt_seq++; 4085 SetFrameSubType(pframe, WIFI_ACTION); 4086 4087 pframe += sizeof(struct ieee80211_hdr_3addr); 4088 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 4089 4090 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); 4091 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); 4092 4093 4094 /* */ 4095 if (pmlmepriv->num_FortyMHzIntolerant > 0) { 4096 u8 iedata = 0; 4097 4098 iedata |= BIT(2);/* 20 MHz BSS Width Request */ 4099 4100 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen)); 4101 4102 } 4103 4104 4105 /* */ 4106 memset(ICS, 0, sizeof(ICS)); 4107 if (pmlmepriv->num_sta_no_ht > 0) { 4108 int i; 4109 4110 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 4111 4112 phead = get_list_head(queue); 4113 plist = get_next(phead); 4114 4115 while (1) { 4116 int len; 4117 u8 *p; 4118 struct wlan_bssid_ex *pbss_network; 4119 4120 if (phead == plist) 4121 break; 4122 4123 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list); 4124 4125 plist = get_next(plist); 4126 4127 pbss_network = (struct wlan_bssid_ex *)&pnetwork->network; 4128 4129 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_); 4130 if ((p == NULL) || (len == 0)) {/* non-HT */ 4131 4132 if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14)) 4133 continue; 4134 4135 ICS[0][pbss_network->Configuration.DSConfig] = 1; 4136 4137 if (ICS[0][0] == 0) 4138 ICS[0][0] = 1; 4139 } 4140 4141 } 4142 4143 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 4144 4145 4146 for (i = 0; i < 8; i++) { 4147 if (ICS[i][0] == 1) { 4148 int j, k = 0; 4149 4150 InfoContent[k] = i; 4151 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */ 4152 k++; 4153 4154 for (j = 1; j <= 14; j++) { 4155 if (ICS[i][j] == 1) { 4156 if (k < 16) { 4157 InfoContent[k] = j; /* channel number */ 4158 /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */ 4159 k++; 4160 } 4161 } 4162 } 4163 4164 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen)); 4165 4166 } 4167 4168 } 4169 4170 4171 } 4172 4173 4174 pattrib->last_txcmdsz = pattrib->pktlen; 4175 4176 dump_mgntframe(padapter, pmgntframe); 4177 } 4178 4179 unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr) 4180 { 4181 struct sta_priv *pstapriv = &padapter->stapriv; 4182 struct sta_info *psta = NULL; 4183 /* struct recv_reorder_ctrl *preorder_ctrl; */ 4184 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4185 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4186 u16 tid; 4187 4188 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 4189 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) 4190 return _SUCCESS; 4191 4192 psta = rtw_get_stainfo(pstapriv, addr); 4193 if (psta == NULL) 4194 return _SUCCESS; 4195 4196 /* DBG_871X("%s:%s\n", __func__, (initiator == 0)?"RX_DIR":"TX_DIR"); */ 4197 4198 if (initiator == 0) {/* recipient */ 4199 for (tid = 0; tid < MAXTID; tid++) { 4200 if (psta->recvreorder_ctrl[tid].enable) { 4201 DBG_871X("rx agg disable tid(%d)\n", tid); 4202 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F)); 4203 psta->recvreorder_ctrl[tid].enable = false; 4204 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff; 4205 #ifdef DBG_RX_SEQ 4206 DBG_871X("DBG_RX_SEQ %s:%d indicate_seq:%u\n", __func__, __LINE__, 4207 psta->recvreorder_ctrl[tid].indicate_seq); 4208 #endif 4209 } 4210 } 4211 } else if (initiator == 1) {/* originator */ 4212 /* DBG_871X("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap); */ 4213 for (tid = 0; tid < MAXTID; tid++) { 4214 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) { 4215 DBG_871X("tx agg disable tid(%d)\n", tid); 4216 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F)); 4217 psta->htpriv.agg_enable_bitmap &= ~BIT(tid); 4218 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); 4219 4220 } 4221 } 4222 } 4223 4224 return _SUCCESS; 4225 4226 } 4227 4228 unsigned int send_beacon(struct adapter *padapter) 4229 { 4230 u8 bxmitok = false; 4231 int issue = 0; 4232 int poll = 0; 4233 unsigned long start = jiffies; 4234 4235 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); 4236 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL); 4237 do { 4238 issue_beacon(padapter, 100); 4239 issue++; 4240 do { 4241 cond_resched(); 4242 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok)); 4243 poll++; 4244 } while ((poll%10) != 0 && false == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); 4245 4246 } while (false == bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); 4247 4248 if (padapter->bSurpriseRemoved || padapter->bDriverStopped) { 4249 return _FAIL; 4250 } 4251 4252 4253 if (false == bxmitok) { 4254 DBG_871X("%s fail! %u ms\n", __func__, jiffies_to_msecs(jiffies - start)); 4255 return _FAIL; 4256 } else { 4257 unsigned long passing_time = jiffies_to_msecs(jiffies - start); 4258 4259 if (passing_time > 100 || issue > 3) 4260 DBG_871X("%s success, issue:%d, poll:%d, %lu ms\n", __func__, issue, poll, passing_time); 4261 /* else */ 4262 /* DBG_871X("%s success, issue:%d, poll:%d, %u ms\n", __func__, issue, poll, passing_time); */ 4263 4264 return _SUCCESS; 4265 } 4266 } 4267 4268 /**************************************************************************** 4269 4270 Following are some utility functions for WiFi MLME 4271 4272 *****************************************************************************/ 4273 4274 void site_survey(struct adapter *padapter) 4275 { 4276 unsigned char survey_channel = 0, val8; 4277 RT_SCAN_TYPE ScanType = SCAN_PASSIVE; 4278 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4279 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4280 u32 initialgain = 0; 4281 u32 channel_scan_time_ms = 0; 4282 4283 { 4284 struct rtw_ieee80211_channel *ch; 4285 4286 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) { 4287 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx]; 4288 survey_channel = ch->hw_value; 4289 ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE; 4290 } 4291 } 4292 4293 DBG_871X(FUNC_ADPT_FMT" ch:%u (cnt:%u) at %dms, %c%c%c\n" 4294 , FUNC_ADPT_ARG(padapter) 4295 , survey_channel 4296 , pmlmeext->sitesurvey_res.channel_idx 4297 , jiffies_to_msecs(jiffies - padapter->mlmepriv.scan_start_time) 4298 , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P' 4299 , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' ' 4300 ); 4301 #ifdef DBG_FIXED_CHAN 4302 DBG_871X(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan); 4303 #endif 4304 4305 if (survey_channel != 0) { 4306 /* PAUSE 4-AC Queue when site_survey */ 4307 /* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ 4308 /* val8 |= 0x0f; */ 4309 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ 4310 if (pmlmeext->sitesurvey_res.channel_idx == 0) { 4311 #ifdef DBG_FIXED_CHAN 4312 if (pmlmeext->fixed_chan != 0xff) 4313 set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); 4314 else 4315 #endif 4316 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); 4317 } else { 4318 #ifdef DBG_FIXED_CHAN 4319 if (pmlmeext->fixed_chan != 0xff) 4320 SelectChannel(padapter, pmlmeext->fixed_chan); 4321 else 4322 #endif 4323 SelectChannel(padapter, survey_channel); 4324 } 4325 4326 if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */ 4327 { 4328 int i; 4329 4330 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { 4331 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { 4332 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */ 4333 if (padapter->registrypriv.wifi_spec) 4334 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); 4335 else 4336 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0); 4337 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); 4338 } 4339 } 4340 4341 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { 4342 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */ 4343 if (padapter->registrypriv.wifi_spec) 4344 issue_probereq(padapter, NULL, NULL); 4345 else 4346 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0); 4347 issue_probereq(padapter, NULL, NULL); 4348 } 4349 } 4350 } 4351 4352 channel_scan_time_ms = pmlmeext->chan_scan_time; 4353 4354 set_survey_timer(pmlmeext, channel_scan_time_ms); 4355 #if defined(CONFIG_SIGNAL_DISPLAY_DBM) && defined(CONFIG_BACKGROUND_NOISE_MONITOR) 4356 { 4357 struct noise_info info; 4358 4359 info.bPauseDIG = false; 4360 info.IGIValue = 0; 4361 info.max_time = channel_scan_time_ms/2;/* ms */ 4362 info.chan = survey_channel; 4363 rtw_hal_set_odm_var(padapter, HAL_ODM_NOISE_MONITOR, &info, false); 4364 } 4365 #endif 4366 4367 } else { 4368 4369 /* channel number is 0 or this channel is not valid. */ 4370 4371 { 4372 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE; 4373 4374 /* switch back to the original channel */ 4375 /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */ 4376 4377 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); 4378 4379 /* flush 4-AC Queue after site_survey */ 4380 /* val8 = 0; */ 4381 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ 4382 4383 /* config MSR */ 4384 Set_MSR(padapter, (pmlmeinfo->state & 0x3)); 4385 4386 initialgain = 0xff; /* restore RX GAIN */ 4387 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); 4388 /* turn on dynamic functions */ 4389 Restore_DM_Func_Flag(padapter); 4390 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */ 4391 4392 if (is_client_associated_to_ap(padapter)) 4393 issue_nulldata(padapter, NULL, 0, 3, 500); 4394 4395 val8 = 0; /* survey done */ 4396 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); 4397 4398 report_surveydone_event(padapter); 4399 4400 pmlmeext->chan_scan_time = SURVEY_TO; 4401 pmlmeext->sitesurvey_res.state = SCAN_DISABLE; 4402 4403 issue_action_BSSCoexistPacket(padapter); 4404 issue_action_BSSCoexistPacket(padapter); 4405 issue_action_BSSCoexistPacket(padapter); 4406 } 4407 } 4408 4409 return; 4410 4411 } 4412 4413 /* collect bss info from Beacon and Probe request/response frames. */ 4414 u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, struct wlan_bssid_ex *bssid) 4415 { 4416 int i; 4417 u32 len; 4418 u8 *p; 4419 u16 val16, subtype; 4420 u8 *pframe = precv_frame->u.hdr.rx_data; 4421 u32 packet_len = precv_frame->u.hdr.len; 4422 u8 ie_offset; 4423 struct registry_priv *pregistrypriv = &padapter->registrypriv; 4424 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4425 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4426 __le32 le32_tmp; 4427 4428 len = packet_len - sizeof(struct ieee80211_hdr_3addr); 4429 4430 if (len > MAX_IE_SZ) { 4431 /* DBG_871X("IE too long for survey event\n"); */ 4432 return _FAIL; 4433 } 4434 4435 memset(bssid, 0, sizeof(struct wlan_bssid_ex)); 4436 4437 subtype = GetFrameSubType(pframe); 4438 4439 if (subtype == WIFI_BEACON) { 4440 bssid->Reserved[0] = 1; 4441 ie_offset = _BEACON_IE_OFFSET_; 4442 } else { 4443 /* FIXME : more type */ 4444 if (subtype == WIFI_PROBERSP) { 4445 ie_offset = _PROBERSP_IE_OFFSET_; 4446 bssid->Reserved[0] = 3; 4447 } else if (subtype == WIFI_PROBEREQ) { 4448 ie_offset = _PROBEREQ_IE_OFFSET_; 4449 bssid->Reserved[0] = 2; 4450 } else { 4451 bssid->Reserved[0] = 0; 4452 ie_offset = _FIXED_IE_LENGTH_; 4453 } 4454 } 4455 4456 bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len; 4457 4458 /* below is to copy the information element */ 4459 bssid->IELength = len; 4460 memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength); 4461 4462 /* get the signal strength */ 4463 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; /* in dBM.raw data */ 4464 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;/* in percentage */ 4465 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;/* in percentage */ 4466 4467 /* checking SSID */ 4468 p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset); 4469 if (p == NULL) { 4470 DBG_871X("marc: cannot find SSID for survey event\n"); 4471 return _FAIL; 4472 } 4473 4474 if (*(p + 1)) { 4475 if (len > NDIS_802_11_LENGTH_SSID) { 4476 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); 4477 return _FAIL; 4478 } 4479 memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); 4480 bssid->Ssid.SsidLength = *(p + 1); 4481 } else 4482 bssid->Ssid.SsidLength = 0; 4483 4484 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); 4485 4486 /* checking rate info... */ 4487 i = 0; 4488 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset); 4489 if (p != NULL) { 4490 if (len > NDIS_802_11_LENGTH_RATES_EX) { 4491 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); 4492 return _FAIL; 4493 } 4494 memcpy(bssid->SupportedRates, (p + 2), len); 4495 i = len; 4496 } 4497 4498 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset); 4499 if (p != NULL) { 4500 if (len > (NDIS_802_11_LENGTH_RATES_EX-i)) { 4501 DBG_871X("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len); 4502 return _FAIL; 4503 } 4504 memcpy(bssid->SupportedRates + i, (p + 2), len); 4505 } 4506 4507 bssid->NetworkTypeInUse = Ndis802_11OFDM24; 4508 4509 if (bssid->IELength < 12) 4510 return _FAIL; 4511 4512 /* Checking for DSConfig */ 4513 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset); 4514 4515 bssid->Configuration.DSConfig = 0; 4516 bssid->Configuration.Length = 0; 4517 4518 if (p) { 4519 bssid->Configuration.DSConfig = *(p + 2); 4520 } else { 4521 /* In 5G, some ap do not have DSSET IE */ 4522 /* checking HT info for channel */ 4523 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset); 4524 if (p) { 4525 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2); 4526 4527 bssid->Configuration.DSConfig = HT_info->primary_channel; 4528 } else { /* use current channel */ 4529 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter); 4530 } 4531 } 4532 4533 memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->IEs), 2); 4534 bssid->Configuration.BeaconPeriod = le32_to_cpu(le32_tmp); 4535 4536 val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); 4537 4538 if (val16 & BIT(0)) { 4539 bssid->InfrastructureMode = Ndis802_11Infrastructure; 4540 memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN); 4541 } else { 4542 bssid->InfrastructureMode = Ndis802_11IBSS; 4543 memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN); 4544 } 4545 4546 if (val16 & BIT(4)) 4547 bssid->Privacy = 1; 4548 else 4549 bssid->Privacy = 0; 4550 4551 bssid->Configuration.ATIMWindow = 0; 4552 4553 /* 20/40 BSS Coexistence check */ 4554 if ((pregistrypriv->wifi_spec == 1) && (false == pmlmeinfo->bwmode_updated)) { 4555 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 4556 4557 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset); 4558 if (p && len > 0) { 4559 struct HT_caps_element *pHT_caps; 4560 4561 pHT_caps = (struct HT_caps_element *)(p + 2); 4562 4563 if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14)) 4564 pmlmepriv->num_FortyMHzIntolerant++; 4565 } else 4566 pmlmepriv->num_sta_no_ht++; 4567 } 4568 4569 #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1 4570 if (strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) { 4571 DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n" 4572 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig 4573 , rtw_get_oper_ch(padapter) 4574 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi 4575 ); 4576 } 4577 #endif 4578 4579 /* mark bss info receiving from nearby channel as SignalQuality 101 */ 4580 if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter)) 4581 bssid->PhyInfo.SignalQuality = 101; 4582 4583 return _SUCCESS; 4584 } 4585 4586 void start_create_ibss(struct adapter *padapter) 4587 { 4588 unsigned short caps; 4589 u8 val8; 4590 u8 join_type; 4591 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4592 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4593 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 4594 4595 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; 4596 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); 4597 4598 /* update wireless mode */ 4599 update_wireless_mode(padapter); 4600 4601 /* update capability */ 4602 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); 4603 update_capinfo(padapter, caps); 4604 if (caps&cap_IBSS) {/* adhoc master */ 4605 val8 = 0xcf; 4606 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); 4607 4608 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL); 4609 4610 /* switch channel */ 4611 /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */ 4612 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); 4613 4614 beacon_timing_control(padapter); 4615 4616 /* set msr to WIFI_FW_ADHOC_STATE */ 4617 pmlmeinfo->state = WIFI_FW_ADHOC_STATE; 4618 Set_MSR(padapter, (pmlmeinfo->state & 0x3)); 4619 4620 /* issue beacon */ 4621 if (send_beacon(padapter) == _FAIL) { 4622 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n")); 4623 4624 report_join_res(padapter, -1); 4625 pmlmeinfo->state = WIFI_FW_NULL_STATE; 4626 } else { 4627 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress); 4628 join_type = 0; 4629 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 4630 4631 report_join_res(padapter, 1); 4632 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; 4633 rtw_indicate_connect(padapter); 4634 } 4635 } else { 4636 DBG_871X("start_create_ibss, invalid cap:%x\n", caps); 4637 return; 4638 } 4639 /* update bc/mc sta_info */ 4640 update_bmc_sta(padapter); 4641 4642 } 4643 4644 void start_clnt_join(struct adapter *padapter) 4645 { 4646 unsigned short caps; 4647 u8 val8; 4648 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4649 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4650 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 4651 int beacon_timeout; 4652 4653 /* update wireless mode */ 4654 update_wireless_mode(padapter); 4655 4656 /* update capability */ 4657 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); 4658 update_capinfo(padapter, caps); 4659 if (caps&cap_ESS) { 4660 Set_MSR(padapter, WIFI_FW_STATION_STATE); 4661 4662 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf; 4663 4664 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); 4665 4666 /* Because of AP's not receiving deauth before */ 4667 /* AP may: 1)not response auth or 2)deauth us after link is complete */ 4668 /* issue deauth before issuing auth to deal with the situation */ 4669 4670 /* Commented by Albert 2012/07/21 */ 4671 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */ 4672 { 4673 /* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */ 4674 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100); 4675 } 4676 4677 /* here wait for receiving the beacon to start auth */ 4678 /* and enable a timer */ 4679 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval); 4680 set_link_timer(pmlmeext, beacon_timeout); 4681 _set_timer(&padapter->mlmepriv.assoc_timer, 4682 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout); 4683 4684 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; 4685 } else if (caps&cap_IBSS) { /* adhoc client */ 4686 Set_MSR(padapter, WIFI_FW_ADHOC_STATE); 4687 4688 val8 = 0xcf; 4689 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); 4690 4691 beacon_timing_control(padapter); 4692 4693 pmlmeinfo->state = WIFI_FW_ADHOC_STATE; 4694 4695 report_join_res(padapter, 1); 4696 } else { 4697 /* DBG_871X("marc: invalid cap:%x\n", caps); */ 4698 return; 4699 } 4700 4701 } 4702 4703 void start_clnt_auth(struct adapter *padapter) 4704 { 4705 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4706 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4707 4708 del_timer_sync(&pmlmeext->link_timer); 4709 4710 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL); 4711 pmlmeinfo->state |= WIFI_FW_AUTH_STATE; 4712 4713 pmlmeinfo->auth_seq = 1; 4714 pmlmeinfo->reauth_count = 0; 4715 pmlmeinfo->reassoc_count = 0; 4716 pmlmeinfo->link_count = 0; 4717 pmlmeext->retry = 0; 4718 4719 4720 DBG_871X_LEVEL(_drv_always_, "start auth\n"); 4721 issue_auth(padapter, NULL, 0); 4722 4723 set_link_timer(pmlmeext, REAUTH_TO); 4724 4725 } 4726 4727 4728 void start_clnt_assoc(struct adapter *padapter) 4729 { 4730 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4731 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4732 4733 del_timer_sync(&pmlmeext->link_timer); 4734 4735 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE)); 4736 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE); 4737 4738 issue_assocreq(padapter); 4739 4740 set_link_timer(pmlmeext, REASSOC_TO); 4741 } 4742 4743 unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) 4744 { 4745 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4746 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4747 4748 /* check A3 */ 4749 if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) 4750 return _SUCCESS; 4751 4752 DBG_871X("%s\n", __func__); 4753 4754 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) { 4755 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { 4756 pmlmeinfo->state = WIFI_FW_NULL_STATE; 4757 report_del_sta_event(padapter, MacAddr, reason); 4758 4759 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) { 4760 pmlmeinfo->state = WIFI_FW_NULL_STATE; 4761 report_join_res(padapter, -2); 4762 } 4763 } 4764 4765 return _SUCCESS; 4766 } 4767 4768 static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid) 4769 { 4770 struct registry_priv *pregistrypriv; 4771 struct mlme_ext_priv *pmlmeext; 4772 RT_CHANNEL_INFO *chplan_new; 4773 u8 channel; 4774 u8 i; 4775 4776 4777 pregistrypriv = &padapter->registrypriv; 4778 pmlmeext = &padapter->mlmeextpriv; 4779 4780 /* Adjust channel plan by AP Country IE */ 4781 if (pregistrypriv->enable80211d && 4782 (!pmlmeext->update_channel_plan_by_ap_done)) { 4783 u8 *ie, *p; 4784 u32 len; 4785 RT_CHANNEL_PLAN chplan_ap; 4786 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM]; 4787 u8 country[4]; 4788 u8 fcn; /* first channel number */ 4789 u8 noc; /* number of channel */ 4790 u8 j, k; 4791 4792 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_); 4793 if (!ie) 4794 return; 4795 if (len < 6) 4796 return; 4797 4798 ie += 2; 4799 p = ie; 4800 ie += len; 4801 4802 memset(country, 0, 4); 4803 memcpy(country, p, 3); 4804 p += 3; 4805 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, 4806 ("%s: 802.11d country =%s\n", __func__, country)); 4807 4808 i = 0; 4809 while ((ie - p) >= 3) { 4810 fcn = *(p++); 4811 noc = *(p++); 4812 p++; 4813 4814 for (j = 0; j < noc; j++) { 4815 if (fcn <= 14) 4816 channel = fcn + j; /* 2.4 GHz */ 4817 else 4818 channel = fcn + j*4; /* 5 GHz */ 4819 4820 chplan_ap.Channel[i++] = channel; 4821 } 4822 } 4823 chplan_ap.Len = i; 4824 4825 #ifdef DEBUG_RTL871X 4826 i = 0; 4827 DBG_871X("%s: AP[%s] channel plan {", __func__, bssid->Ssid.Ssid); 4828 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) { 4829 DBG_8192C("%02d,", chplan_ap.Channel[i]); 4830 i++; 4831 } 4832 DBG_871X("}\n"); 4833 #endif 4834 4835 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta)); 4836 #ifdef DEBUG_RTL871X 4837 i = 0; 4838 DBG_871X("%s: STA channel plan {", __func__); 4839 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { 4840 DBG_871X("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType == SCAN_PASSIVE?'p':'a'); 4841 i++; 4842 } 4843 DBG_871X("}\n"); 4844 #endif 4845 4846 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set)); 4847 chplan_new = pmlmeext->channel_set; 4848 4849 i = j = k = 0; 4850 if (pregistrypriv->wireless_mode & WIRELESS_11G) { 4851 do { 4852 if ((i == MAX_CHANNEL_NUM) || 4853 (chplan_sta[i].ChannelNum == 0) || 4854 (chplan_sta[i].ChannelNum > 14)) 4855 break; 4856 4857 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14)) 4858 break; 4859 4860 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { 4861 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4862 chplan_new[k].ScanType = SCAN_ACTIVE; 4863 i++; 4864 j++; 4865 k++; 4866 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { 4867 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4868 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */ 4869 chplan_new[k].ScanType = SCAN_PASSIVE; 4870 i++; 4871 k++; 4872 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { 4873 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4874 chplan_new[k].ScanType = SCAN_ACTIVE; 4875 j++; 4876 k++; 4877 } 4878 } while (1); 4879 4880 /* change AP not support channel to Passive scan */ 4881 while ((i < MAX_CHANNEL_NUM) && 4882 (chplan_sta[i].ChannelNum != 0) && 4883 (chplan_sta[i].ChannelNum <= 14)) { 4884 4885 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4886 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */ 4887 chplan_new[k].ScanType = SCAN_PASSIVE; 4888 i++; 4889 k++; 4890 } 4891 4892 /* add channel AP supported */ 4893 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { 4894 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4895 chplan_new[k].ScanType = SCAN_ACTIVE; 4896 j++; 4897 k++; 4898 } 4899 } else { 4900 /* keep original STA 2.4G channel plan */ 4901 while ((i < MAX_CHANNEL_NUM) && 4902 (chplan_sta[i].ChannelNum != 0) && 4903 (chplan_sta[i].ChannelNum <= 14)) { 4904 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4905 chplan_new[k].ScanType = chplan_sta[i].ScanType; 4906 i++; 4907 k++; 4908 } 4909 4910 /* skip AP 2.4G channel plan */ 4911 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { 4912 j++; 4913 } 4914 } 4915 4916 if (pregistrypriv->wireless_mode & WIRELESS_11A) { 4917 do { 4918 if ((i == MAX_CHANNEL_NUM) || 4919 (chplan_sta[i].ChannelNum == 0)) 4920 break; 4921 4922 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0)) 4923 break; 4924 4925 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { 4926 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4927 chplan_new[k].ScanType = SCAN_ACTIVE; 4928 i++; 4929 j++; 4930 k++; 4931 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { 4932 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4933 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */ 4934 chplan_new[k].ScanType = SCAN_PASSIVE; 4935 i++; 4936 k++; 4937 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { 4938 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4939 chplan_new[k].ScanType = SCAN_ACTIVE; 4940 j++; 4941 k++; 4942 } 4943 } while (1); 4944 4945 /* change AP not support channel to Passive scan */ 4946 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { 4947 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4948 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */ 4949 chplan_new[k].ScanType = SCAN_PASSIVE; 4950 i++; 4951 k++; 4952 } 4953 4954 /* add channel AP supported */ 4955 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) { 4956 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4957 chplan_new[k].ScanType = SCAN_ACTIVE; 4958 j++; 4959 k++; 4960 } 4961 } else { 4962 /* keep original STA 5G channel plan */ 4963 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) { 4964 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4965 chplan_new[k].ScanType = chplan_sta[i].ScanType; 4966 i++; 4967 k++; 4968 } 4969 } 4970 4971 pmlmeext->update_channel_plan_by_ap_done = 1; 4972 4973 #ifdef DEBUG_RTL871X 4974 k = 0; 4975 DBG_871X("%s: new STA channel plan {", __func__); 4976 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) { 4977 DBG_871X("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType == SCAN_PASSIVE?'p':'c'); 4978 k++; 4979 } 4980 DBG_871X("}\n"); 4981 #endif 4982 } 4983 4984 /* If channel is used by AP, set channel scan type to active */ 4985 channel = bssid->Configuration.DSConfig; 4986 chplan_new = pmlmeext->channel_set; 4987 i = 0; 4988 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) { 4989 if (chplan_new[i].ChannelNum == channel) { 4990 if (chplan_new[i].ScanType == SCAN_PASSIVE) { 4991 /* 5G Bnad 2, 3 (DFS) doesn't change to active scan */ 4992 if (channel >= 52 && channel <= 144) 4993 break; 4994 4995 chplan_new[i].ScanType = SCAN_ACTIVE; 4996 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_, 4997 ("%s: change channel %d scan type from passive to active\n", 4998 __func__, channel)); 4999 } 5000 break; 5001 } 5002 i++; 5003 } 5004 } 5005 5006 /**************************************************************************** 5007 5008 Following are the functions to report events 5009 5010 *****************************************************************************/ 5011 5012 void report_survey_event(struct adapter *padapter, union recv_frame *precv_frame) 5013 { 5014 struct cmd_obj *pcmd_obj; 5015 u8 *pevtcmd; 5016 u32 cmdsz; 5017 struct survey_event *psurvey_evt; 5018 struct C2HEvent_Header *pc2h_evt_hdr; 5019 struct mlme_ext_priv *pmlmeext; 5020 struct cmd_priv *pcmdpriv; 5021 /* u8 *pframe = precv_frame->u.hdr.rx_data; */ 5022 /* uint len = precv_frame->u.hdr.len; */ 5023 5024 if (!padapter) 5025 return; 5026 5027 pmlmeext = &padapter->mlmeextpriv; 5028 pcmdpriv = &padapter->cmdpriv; 5029 5030 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 5031 if (!pcmd_obj) 5032 return; 5033 5034 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); 5035 pevtcmd = rtw_zmalloc(cmdsz); 5036 if (!pevtcmd) { 5037 kfree(pcmd_obj); 5038 return; 5039 } 5040 5041 INIT_LIST_HEAD(&pcmd_obj->list); 5042 5043 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 5044 pcmd_obj->cmdsz = cmdsz; 5045 pcmd_obj->parmbuf = pevtcmd; 5046 5047 pcmd_obj->rsp = NULL; 5048 pcmd_obj->rspsz = 0; 5049 5050 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 5051 pc2h_evt_hdr->len = sizeof(struct survey_event); 5052 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey); 5053 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 5054 5055 psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 5056 5057 if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) { 5058 kfree(pcmd_obj); 5059 kfree(pevtcmd); 5060 return; 5061 } 5062 5063 process_80211d(padapter, &psurvey_evt->bss); 5064 5065 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 5066 5067 pmlmeext->sitesurvey_res.bss_cnt++; 5068 5069 return; 5070 5071 } 5072 5073 void report_surveydone_event(struct adapter *padapter) 5074 { 5075 struct cmd_obj *pcmd_obj; 5076 u8 *pevtcmd; 5077 u32 cmdsz; 5078 struct surveydone_event *psurveydone_evt; 5079 struct C2HEvent_Header *pc2h_evt_hdr; 5080 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5081 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 5082 5083 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 5084 if (!pcmd_obj) 5085 return; 5086 5087 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header)); 5088 pevtcmd = rtw_zmalloc(cmdsz); 5089 if (!pevtcmd) { 5090 kfree(pcmd_obj); 5091 return; 5092 } 5093 5094 INIT_LIST_HEAD(&pcmd_obj->list); 5095 5096 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 5097 pcmd_obj->cmdsz = cmdsz; 5098 pcmd_obj->parmbuf = pevtcmd; 5099 5100 pcmd_obj->rsp = NULL; 5101 pcmd_obj->rspsz = 0; 5102 5103 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 5104 pc2h_evt_hdr->len = sizeof(struct surveydone_event); 5105 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone); 5106 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 5107 5108 psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 5109 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt; 5110 5111 DBG_871X("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter)); 5112 5113 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 5114 5115 return; 5116 5117 } 5118 5119 void report_join_res(struct adapter *padapter, int res) 5120 { 5121 struct cmd_obj *pcmd_obj; 5122 u8 *pevtcmd; 5123 u32 cmdsz; 5124 struct joinbss_event *pjoinbss_evt; 5125 struct C2HEvent_Header *pc2h_evt_hdr; 5126 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5127 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5128 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 5129 5130 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 5131 if (!pcmd_obj) 5132 return; 5133 5134 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); 5135 pevtcmd = rtw_zmalloc(cmdsz); 5136 if (!pevtcmd) { 5137 kfree(pcmd_obj); 5138 return; 5139 } 5140 5141 INIT_LIST_HEAD(&pcmd_obj->list); 5142 5143 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 5144 pcmd_obj->cmdsz = cmdsz; 5145 pcmd_obj->parmbuf = pevtcmd; 5146 5147 pcmd_obj->rsp = NULL; 5148 pcmd_obj->rspsz = 0; 5149 5150 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 5151 pc2h_evt_hdr->len = sizeof(struct joinbss_event); 5152 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss); 5153 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 5154 5155 pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 5156 memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex)); 5157 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res; 5158 5159 DBG_871X("report_join_res(%d)\n", res); 5160 5161 5162 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network); 5163 5164 5165 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 5166 5167 return; 5168 5169 } 5170 5171 void report_wmm_edca_update(struct adapter *padapter) 5172 { 5173 struct cmd_obj *pcmd_obj; 5174 u8 *pevtcmd; 5175 u32 cmdsz; 5176 struct wmm_event *pwmm_event; 5177 struct C2HEvent_Header *pc2h_evt_hdr; 5178 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5179 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 5180 5181 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 5182 if (!pcmd_obj) 5183 return; 5184 5185 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header)); 5186 pevtcmd = rtw_zmalloc(cmdsz); 5187 if (!pevtcmd) { 5188 kfree(pcmd_obj); 5189 return; 5190 } 5191 5192 INIT_LIST_HEAD(&pcmd_obj->list); 5193 5194 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 5195 pcmd_obj->cmdsz = cmdsz; 5196 pcmd_obj->parmbuf = pevtcmd; 5197 5198 pcmd_obj->rsp = NULL; 5199 pcmd_obj->rspsz = 0; 5200 5201 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 5202 pc2h_evt_hdr->len = sizeof(struct wmm_event); 5203 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM); 5204 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 5205 5206 pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 5207 pwmm_event->wmm = 0; 5208 5209 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 5210 5211 return; 5212 5213 } 5214 5215 void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) 5216 { 5217 struct cmd_obj *pcmd_obj; 5218 u8 *pevtcmd; 5219 u32 cmdsz; 5220 struct sta_info *psta; 5221 int mac_id; 5222 struct stadel_event *pdel_sta_evt; 5223 struct C2HEvent_Header *pc2h_evt_hdr; 5224 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5225 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 5226 5227 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 5228 if (pcmd_obj == NULL) { 5229 return; 5230 } 5231 5232 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); 5233 pevtcmd = rtw_zmalloc(cmdsz); 5234 if (pevtcmd == NULL) { 5235 kfree(pcmd_obj); 5236 return; 5237 } 5238 5239 INIT_LIST_HEAD(&pcmd_obj->list); 5240 5241 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 5242 pcmd_obj->cmdsz = cmdsz; 5243 pcmd_obj->parmbuf = pevtcmd; 5244 5245 pcmd_obj->rsp = NULL; 5246 pcmd_obj->rspsz = 0; 5247 5248 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 5249 pc2h_evt_hdr->len = sizeof(struct stadel_event); 5250 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA); 5251 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 5252 5253 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 5254 memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN); 5255 memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2); 5256 5257 5258 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr); 5259 if (psta) 5260 mac_id = (int)psta->mac_id; 5261 else 5262 mac_id = (-1); 5263 5264 pdel_sta_evt->mac_id = mac_id; 5265 5266 DBG_871X("report_del_sta_event: delete STA, mac_id =%d\n", mac_id); 5267 5268 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 5269 } 5270 5271 void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx) 5272 { 5273 struct cmd_obj *pcmd_obj; 5274 u8 *pevtcmd; 5275 u32 cmdsz; 5276 struct stassoc_event *padd_sta_evt; 5277 struct C2HEvent_Header *pc2h_evt_hdr; 5278 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5279 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 5280 5281 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 5282 if (pcmd_obj == NULL) 5283 return; 5284 5285 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); 5286 pevtcmd = rtw_zmalloc(cmdsz); 5287 if (pevtcmd == NULL) { 5288 kfree(pcmd_obj); 5289 return; 5290 } 5291 5292 INIT_LIST_HEAD(&pcmd_obj->list); 5293 5294 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 5295 pcmd_obj->cmdsz = cmdsz; 5296 pcmd_obj->parmbuf = pevtcmd; 5297 5298 pcmd_obj->rsp = NULL; 5299 pcmd_obj->rspsz = 0; 5300 5301 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 5302 pc2h_evt_hdr->len = sizeof(struct stassoc_event); 5303 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA); 5304 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 5305 5306 padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 5307 memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN); 5308 padd_sta_evt->cam_id = cam_idx; 5309 5310 DBG_871X("report_add_sta_event: add STA\n"); 5311 5312 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 5313 } 5314 5315 /**************************************************************************** 5316 5317 Following are the event callback functions 5318 5319 *****************************************************************************/ 5320 5321 /* for sta/adhoc mode */ 5322 void update_sta_info(struct adapter *padapter, struct sta_info *psta) 5323 { 5324 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 5325 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5326 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5327 5328 /* ERP */ 5329 VCS_update(padapter, psta); 5330 5331 /* HT */ 5332 if (pmlmepriv->htpriv.ht_option) { 5333 psta->htpriv.ht_option = true; 5334 5335 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable; 5336 5337 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2; 5338 5339 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20)) 5340 psta->htpriv.sgi_20m = true; 5341 5342 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40)) 5343 psta->htpriv.sgi_40m = true; 5344 5345 psta->qos_option = true; 5346 5347 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap; 5348 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap; 5349 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap; 5350 5351 memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap)); 5352 } else { 5353 psta->htpriv.ht_option = false; 5354 5355 psta->htpriv.ampdu_enable = false; 5356 5357 psta->htpriv.sgi_20m = false; 5358 psta->htpriv.sgi_40m = false; 5359 psta->qos_option = false; 5360 5361 } 5362 5363 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset; 5364 5365 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */ 5366 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ 5367 5368 psta->bw_mode = pmlmeext->cur_bwmode; 5369 5370 /* QoS */ 5371 if (pmlmepriv->qospriv.qos_option) 5372 psta->qos_option = true; 5373 5374 update_ldpc_stbc_cap(psta); 5375 5376 spin_lock_bh(&psta->lock); 5377 psta->state = _FW_LINKED; 5378 spin_unlock_bh(&psta->lock); 5379 5380 } 5381 5382 static void rtw_mlmeext_disconnect(struct adapter *padapter) 5383 { 5384 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 5385 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5386 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5387 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 5388 5389 /* set_opmode_cmd(padapter, infra_client_with_mlme); */ 5390 5391 /* For safety, prevent from keeping macid sleep. 5392 * If we can sure all power mode enter/leave are paired, 5393 * this check can be removed. 5394 * Lucas@20131113 5395 */ 5396 /* wakeup macid after disconnect. */ 5397 { 5398 struct sta_info *psta; 5399 5400 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(pnetwork)); 5401 if (psta) 5402 rtw_hal_macid_wakeup(padapter, psta->mac_id); 5403 } 5404 5405 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); 5406 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); 5407 5408 /* set MSR to no link state -> infra. mode */ 5409 Set_MSR(padapter, _HW_STATE_STATION_); 5410 5411 pmlmeinfo->state = WIFI_FW_NULL_STATE; 5412 5413 /* switch to the 20M Hz mode after disconnect */ 5414 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 5415 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 5416 5417 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); 5418 5419 flush_all_cam_entry(padapter); 5420 5421 del_timer_sync(&pmlmeext->link_timer); 5422 5423 /* pmlmepriv->LinkDetectInfo.TrafficBusyState = false; */ 5424 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; 5425 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; 5426 5427 } 5428 5429 void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res) 5430 { 5431 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5432 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5433 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); 5434 struct sta_priv *pstapriv = &padapter->stapriv; 5435 u8 join_type; 5436 struct sta_info *psta; 5437 5438 if (join_res < 0) { 5439 join_type = 1; 5440 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 5441 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); 5442 5443 goto exit_mlmeext_joinbss_event_callback; 5444 } 5445 5446 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) 5447 /* update bc/mc sta_info */ 5448 update_bmc_sta(padapter); 5449 5450 5451 /* turn on dynamic functions */ 5452 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); 5453 5454 /* update IOT-related issue */ 5455 update_IOT_info(padapter); 5456 5457 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates); 5458 5459 /* BCN interval */ 5460 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval)); 5461 5462 /* update capability */ 5463 update_capinfo(padapter, pmlmeinfo->capability); 5464 5465 /* WMM, Update EDCA param */ 5466 WMMOnAssocRsp(padapter); 5467 5468 /* HT */ 5469 HTOnAssocRsp(padapter); 5470 5471 /* Set cur_channel&cur_bwmode&cur_ch_offset */ 5472 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); 5473 5474 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); 5475 if (psta) { /* only for infra. mode */ 5476 5477 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; 5478 5479 /* DBG_871X("set_sta_rate\n"); */ 5480 5481 psta->wireless_mode = pmlmeext->cur_wireless_mode; 5482 5483 /* set per sta rate after updating HT cap. */ 5484 set_sta_rate(padapter, psta); 5485 5486 rtw_sta_media_status_rpt(padapter, psta, 1); 5487 5488 /* wakeup macid after join bss successfully to ensure 5489 the subsequent data frames can be sent out normally */ 5490 rtw_hal_macid_wakeup(padapter, psta->mac_id); 5491 } 5492 5493 join_type = 2; 5494 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 5495 5496 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) { 5497 /* correcting TSF */ 5498 correct_TSF(padapter, pmlmeext); 5499 5500 /* set_link_timer(pmlmeext, DISCONNECT_TO); */ 5501 } 5502 5503 if (get_iface_type(padapter) == IFACE_PORT0) 5504 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); 5505 5506 exit_mlmeext_joinbss_event_callback: 5507 5508 DBG_871X("=>%s\n", __func__); 5509 5510 } 5511 5512 /* currently only adhoc mode will go here */ 5513 void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta) 5514 { 5515 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 5516 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5517 u8 join_type; 5518 5519 DBG_871X("%s\n", __func__); 5520 5521 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { 5522 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */ 5523 5524 /* nothing to do */ 5525 } else { /* adhoc client */ 5526 /* update TSF Value */ 5527 /* update_TSF(pmlmeext, pframe, len); */ 5528 5529 /* correcting TSF */ 5530 correct_TSF(padapter, pmlmeext); 5531 5532 /* start beacon */ 5533 if (send_beacon(padapter) == _FAIL) { 5534 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0; 5535 5536 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE; 5537 5538 return; 5539 } 5540 5541 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; 5542 5543 } 5544 5545 join_type = 2; 5546 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 5547 } 5548 5549 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; 5550 5551 psta->bssratelen = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates); 5552 memcpy(psta->bssrateset, pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates, psta->bssratelen); 5553 5554 /* update adhoc sta_info */ 5555 update_sta_info(padapter, psta); 5556 5557 rtw_hal_update_sta_rate_mask(padapter, psta); 5558 5559 /* ToDo: HT for Ad-hoc */ 5560 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel); 5561 psta->raid = networktype_to_raid_ex(padapter, psta); 5562 5563 /* rate radaptive */ 5564 Update_RA_Entry(padapter, psta); 5565 } 5566 5567 void mlmeext_sta_del_event_callback(struct adapter *padapter) 5568 { 5569 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) 5570 rtw_mlmeext_disconnect(padapter); 5571 } 5572 5573 /**************************************************************************** 5574 5575 Following are the functions for the timer handlers 5576 5577 *****************************************************************************/ 5578 void _linked_info_dump(struct adapter *padapter) 5579 { 5580 int i; 5581 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5582 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5583 int UndecoratedSmoothedPWDB; 5584 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); 5585 5586 if (padapter->bLinkInfoDump) { 5587 5588 DBG_871X("\n ============["ADPT_FMT"] linked status check ===================\n", ADPT_ARG(padapter)); 5589 5590 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) { 5591 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); 5592 5593 DBG_871X("AP[" MAC_FMT "] - UndecoratedSmoothedPWDB:%d\n", 5594 MAC_ARG(padapter->mlmepriv.cur_network.network.MacAddress), UndecoratedSmoothedPWDB); 5595 } else if ((pmlmeinfo->state&0x03) == _HW_STATE_AP_) { 5596 struct list_head *phead, *plist; 5597 5598 struct sta_info *psta = NULL; 5599 struct sta_priv *pstapriv = &padapter->stapriv; 5600 5601 spin_lock_bh(&pstapriv->asoc_list_lock); 5602 phead = &pstapriv->asoc_list; 5603 plist = get_next(phead); 5604 while (phead != plist) { 5605 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list); 5606 plist = get_next(plist); 5607 5608 DBG_871X("STA[" MAC_FMT "]:UndecoratedSmoothedPWDB:%d\n", 5609 MAC_ARG(psta->hwaddr), psta->rssi_stat.UndecoratedSmoothedPWDB); 5610 } 5611 spin_unlock_bh(&pstapriv->asoc_list_lock); 5612 5613 } 5614 for (i = 0; i < NUM_STA; i++) { 5615 if (pdvobj->macid[i]) { 5616 if (i != 1) /* skip bc/mc sta */ 5617 /* tx info ============ */ 5618 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i); 5619 } 5620 } 5621 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_RX_INFO_DUMP, NULL); 5622 5623 5624 } 5625 5626 5627 } 5628 5629 static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta) 5630 { 5631 u8 ret = false; 5632 5633 #ifdef DBG_EXPIRATION_CHK 5634 DBG_871X(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu" 5635 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/ 5636 ", retry:%u\n" 5637 , FUNC_ADPT_ARG(padapter) 5638 , STA_RX_PKTS_DIFF_ARG(psta) 5639 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts 5640 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts 5641 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts 5642 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts 5643 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts 5644 , pmlmeinfo->bcn_interval*/ 5645 , pmlmeext->retry 5646 ); 5647 5648 DBG_871X(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter) 5649 , padapter->xmitpriv.tx_pkts 5650 , pmlmeinfo->link_count 5651 ); 5652 #endif 5653 5654 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) 5655 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) 5656 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta) 5657 ) { 5658 ret = false; 5659 } else { 5660 ret = true; 5661 } 5662 5663 sta_update_last_rx_pkts(psta); 5664 5665 return ret; 5666 } 5667 5668 void linked_status_chk(struct adapter *padapter) 5669 { 5670 u32 i; 5671 struct sta_info *psta; 5672 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 5673 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5674 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5675 struct sta_priv *pstapriv = &padapter->stapriv; 5676 5677 5678 if (is_client_associated_to_ap(padapter)) { 5679 /* linked infrastructure client mode */ 5680 5681 int tx_chk = _SUCCESS, rx_chk = _SUCCESS; 5682 int rx_chk_limit; 5683 int link_count_limit; 5684 5685 #if defined(DBG_ROAMING_TEST) 5686 rx_chk_limit = 1; 5687 #else 5688 rx_chk_limit = 8; 5689 #endif 5690 link_count_limit = 7; /* 16 sec */ 5691 5692 /* Marked by Kurt 20130715 */ 5693 /* For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly. */ 5694 /* todo: To check why we under miracast session, rx_chk would be false */ 5695 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress); 5696 if (psta != NULL) { 5697 if (chk_ap_is_alive(padapter, psta) == false) 5698 rx_chk = _FAIL; 5699 5700 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts) 5701 tx_chk = _FAIL; 5702 5703 { 5704 if (rx_chk != _SUCCESS) { 5705 if (pmlmeext->retry == 0) { 5706 #ifdef DBG_EXPIRATION_CHK 5707 DBG_871X("issue_probereq to trigger probersp, retry =%d\n", pmlmeext->retry); 5708 #endif 5709 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); 5710 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); 5711 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); 5712 } 5713 } 5714 5715 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) { 5716 #ifdef DBG_EXPIRATION_CHK 5717 DBG_871X("%s issue_nulldata 0\n", __func__); 5718 #endif 5719 tx_chk = issue_nulldata_in_interrupt(padapter, NULL); 5720 } 5721 } 5722 5723 if (rx_chk == _FAIL) { 5724 pmlmeext->retry++; 5725 if (pmlmeext->retry > rx_chk_limit) { 5726 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n", 5727 FUNC_ADPT_ARG(padapter)); 5728 receive_disconnect(padapter, pmlmeinfo->network.MacAddress 5729 , WLAN_REASON_EXPIRATION_CHK); 5730 return; 5731 } 5732 } else { 5733 pmlmeext->retry = 0; 5734 } 5735 5736 if (tx_chk == _FAIL) { 5737 pmlmeinfo->link_count %= (link_count_limit+1); 5738 } else { 5739 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts; 5740 pmlmeinfo->link_count = 0; 5741 } 5742 5743 } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */ 5744 } else if (is_client_associated_to_ibss(padapter)) { 5745 /* linked IBSS mode */ 5746 /* for each assoc list entry to check the rx pkt counter */ 5747 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) { 5748 if (pmlmeinfo->FW_sta_info[i].status == 1) { 5749 psta = pmlmeinfo->FW_sta_info[i].psta; 5750 5751 if (NULL == psta) 5752 continue; 5753 5754 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) { 5755 5756 if (pmlmeinfo->FW_sta_info[i].retry < 3) { 5757 pmlmeinfo->FW_sta_info[i].retry++; 5758 } else { 5759 pmlmeinfo->FW_sta_info[i].retry = 0; 5760 pmlmeinfo->FW_sta_info[i].status = 0; 5761 report_del_sta_event(padapter, psta->hwaddr 5762 , 65535/* indicate disconnect caused by no rx */ 5763 ); 5764 } 5765 } else { 5766 pmlmeinfo->FW_sta_info[i].retry = 0; 5767 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta); 5768 } 5769 } 5770 } 5771 5772 /* set_link_timer(pmlmeext, DISCONNECT_TO); */ 5773 5774 } 5775 5776 } 5777 5778 void survey_timer_hdl(struct timer_list *t) 5779 { 5780 struct adapter *padapter = 5781 from_timer(padapter, t, mlmeextpriv.survey_timer); 5782 struct cmd_obj *ph2c; 5783 struct sitesurvey_parm *psurveyPara; 5784 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 5785 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5786 5787 /* DBG_871X("marc: survey timer\n"); */ 5788 5789 /* issue rtw_sitesurvey_cmd */ 5790 if (pmlmeext->sitesurvey_res.state > SCAN_START) { 5791 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { 5792 pmlmeext->sitesurvey_res.channel_idx++; 5793 } 5794 5795 if (pmlmeext->scan_abort) { 5796 { 5797 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num; 5798 DBG_871X("%s idx:%d\n", __func__ 5799 , pmlmeext->sitesurvey_res.channel_idx 5800 ); 5801 } 5802 5803 pmlmeext->scan_abort = false;/* reset */ 5804 } 5805 5806 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 5807 if (ph2c == NULL) { 5808 goto exit_survey_timer_hdl; 5809 } 5810 5811 psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm)); 5812 if (psurveyPara == NULL) { 5813 kfree(ph2c); 5814 goto exit_survey_timer_hdl; 5815 } 5816 5817 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); 5818 rtw_enqueue_cmd(pcmdpriv, ph2c); 5819 } 5820 5821 5822 exit_survey_timer_hdl: 5823 5824 return; 5825 } 5826 5827 void link_timer_hdl(struct timer_list *t) 5828 { 5829 struct adapter *padapter = 5830 from_timer(padapter, t, mlmeextpriv.link_timer); 5831 /* static unsigned int rx_pkt = 0; */ 5832 /* static u64 tx_cnt = 0; */ 5833 /* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */ 5834 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5835 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5836 /* struct sta_priv *pstapriv = &padapter->stapriv; */ 5837 5838 5839 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { 5840 DBG_871X("link_timer_hdl:no beacon while connecting\n"); 5841 pmlmeinfo->state = WIFI_FW_NULL_STATE; 5842 report_join_res(padapter, -3); 5843 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) { 5844 /* re-auth timer */ 5845 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) { 5846 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */ 5847 /* */ 5848 pmlmeinfo->state = 0; 5849 report_join_res(padapter, -1); 5850 return; 5851 /* */ 5852 /* else */ 5853 /* */ 5854 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */ 5855 /* pmlmeinfo->reauth_count = 0; */ 5856 /* */ 5857 } 5858 5859 DBG_871X("link_timer_hdl: auth timeout and try again\n"); 5860 pmlmeinfo->auth_seq = 1; 5861 issue_auth(padapter, NULL, 0); 5862 set_link_timer(pmlmeext, REAUTH_TO); 5863 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) { 5864 /* re-assoc timer */ 5865 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) { 5866 pmlmeinfo->state = WIFI_FW_NULL_STATE; 5867 report_join_res(padapter, -2); 5868 return; 5869 } 5870 5871 DBG_871X("link_timer_hdl: assoc timeout and try again\n"); 5872 issue_assocreq(padapter); 5873 set_link_timer(pmlmeext, REASSOC_TO); 5874 } 5875 } 5876 5877 void addba_timer_hdl(struct timer_list *t) 5878 { 5879 struct sta_info *psta = from_timer(psta, t, addba_retry_timer); 5880 struct ht_priv *phtpriv; 5881 5882 if (!psta) 5883 return; 5884 5885 phtpriv = &psta->htpriv; 5886 5887 if (phtpriv->ht_option && phtpriv->ampdu_enable) { 5888 if (phtpriv->candidate_tid_bitmap) 5889 phtpriv->candidate_tid_bitmap = 0x0; 5890 5891 } 5892 } 5893 5894 void sa_query_timer_hdl(struct timer_list *t) 5895 { 5896 struct adapter *padapter = 5897 from_timer(padapter, t, mlmeextpriv.sa_query_timer); 5898 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 5899 /* disconnect */ 5900 spin_lock_bh(&pmlmepriv->lock); 5901 5902 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 5903 rtw_disassoc_cmd(padapter, 0, true); 5904 rtw_indicate_disconnect(padapter); 5905 rtw_free_assoc_resources(padapter, 1); 5906 } 5907 5908 spin_unlock_bh(&pmlmepriv->lock); 5909 DBG_871X("SA query timeout disconnect\n"); 5910 } 5911 5912 u8 NULL_hdl(struct adapter *padapter, u8 *pbuf) 5913 { 5914 return H2C_SUCCESS; 5915 } 5916 5917 #ifdef CONFIG_AUTO_AP_MODE 5918 static int rtw_auto_ap_start_beacon(struct adapter *adapter) 5919 { 5920 int ret = 0; 5921 u8 *pbuf = NULL; 5922 uint len; 5923 u8 supportRate[16]; 5924 int sz = 0, rateLen; 5925 u8 *ie; 5926 u8 wireless_mode, oper_channel; 5927 u8 ssid[3] = {0}; /* hidden ssid */ 5928 u32 ssid_len = sizeof(ssid); 5929 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); 5930 5931 5932 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true) 5933 return -EINVAL; 5934 5935 5936 len = 128; 5937 pbuf = rtw_zmalloc(len); 5938 if (!pbuf) 5939 return -ENOMEM; 5940 5941 5942 /* generate beacon */ 5943 ie = pbuf; 5944 5945 /* timestamp will be inserted by hardware */ 5946 sz += 8; 5947 ie += sz; 5948 5949 /* beacon interval : 2bytes */ 5950 *(u16 *)ie = cpu_to_le16((u16)100);/* BCN_INTERVAL = 100; */ 5951 sz += 2; 5952 ie += 2; 5953 5954 /* capability info */ 5955 *(u16 *)ie = 0; 5956 *(u16 *)ie |= cpu_to_le16(cap_ESS); 5957 *(u16 *)ie |= cpu_to_le16(cap_ShortPremble); 5958 /* u16*)ie |= cpu_to_le16(cap_Privacy); */ 5959 sz += 2; 5960 ie += 2; 5961 5962 /* SSID */ 5963 ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz); 5964 5965 /* supported rates */ 5966 wireless_mode = WIRELESS_11BG_24N; 5967 rtw_set_supported_rate(supportRate, wireless_mode); 5968 rateLen = rtw_get_rateset_len(supportRate); 5969 if (rateLen > 8) { 5970 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz); 5971 } else { 5972 ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz); 5973 } 5974 5975 5976 /* DS parameter set */ 5977 if (check_buddy_fwstate(adapter, _FW_LINKED) && 5978 check_buddy_fwstate(adapter, WIFI_STATION_STATE)) { 5979 struct adapter *pbuddystruct adapter = adapter->pbuddystruct adapter; 5980 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddystruct adapter->mlmeextpriv; 5981 5982 oper_channel = pbuddy_mlmeext->cur_channel; 5983 } else { 5984 oper_channel = adapter_to_dvobj(adapter)->oper_channel; 5985 } 5986 ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz); 5987 5988 /* ext supported rates */ 5989 if (rateLen > 8) { 5990 ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz); 5991 } 5992 5993 DBG_871X("%s, start auto ap beacon sz =%d\n", __func__, sz); 5994 5995 /* lunch ap mode & start to issue beacon */ 5996 if (rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS) { 5997 5998 } else { 5999 ret = -EINVAL; 6000 } 6001 6002 6003 kfree(pbuf); 6004 6005 return ret; 6006 6007 } 6008 #endif/* CONFIG_AUTO_AP_MODE */ 6009 6010 u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) 6011 { 6012 u8 type; 6013 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6014 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6015 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf; 6016 6017 if (psetop->mode == Ndis802_11APMode) { 6018 pmlmeinfo->state = WIFI_FW_AP_STATE; 6019 type = _HW_STATE_AP_; 6020 /* start_ap_mode(padapter); */ 6021 } else if (psetop->mode == Ndis802_11Infrastructure) { 6022 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */ 6023 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */ 6024 type = _HW_STATE_STATION_; 6025 } else if (psetop->mode == Ndis802_11IBSS) { 6026 type = _HW_STATE_ADHOC_; 6027 } else { 6028 type = _HW_STATE_NOLINK_; 6029 } 6030 6031 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); 6032 /* Set_MSR(padapter, type); */ 6033 6034 6035 #ifdef CONFIG_AUTO_AP_MODE 6036 if (psetop->mode == Ndis802_11APMode) 6037 rtw_auto_ap_start_beacon(padapter); 6038 #endif 6039 6040 if (psetop->mode == Ndis802_11APMode) { 6041 /* Do this after port switch to */ 6042 /* prevent from downloading rsvd page to wrong port */ 6043 rtw_btcoex_MediaStatusNotify(padapter, 1); /* connect */ 6044 } 6045 6046 return H2C_SUCCESS; 6047 6048 } 6049 6050 u8 createbss_hdl(struct adapter *padapter, u8 *pbuf) 6051 { 6052 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6053 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6054 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 6055 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; 6056 /* u32 initialgain; */ 6057 6058 if (pmlmeinfo->state == WIFI_FW_AP_STATE) { 6059 struct wlan_bssid_ex *network = &padapter->mlmepriv.cur_network.network; 6060 6061 start_bss_network(padapter, (u8 *)network); 6062 return H2C_SUCCESS; 6063 } 6064 6065 /* below is for ad-hoc master */ 6066 if (pparm->network.InfrastructureMode == Ndis802_11IBSS) { 6067 rtw_joinbss_reset(padapter); 6068 6069 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 6070 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 6071 pmlmeinfo->ERP_enable = 0; 6072 pmlmeinfo->WMM_enable = 0; 6073 pmlmeinfo->HT_enable = 0; 6074 pmlmeinfo->HT_caps_enable = 0; 6075 pmlmeinfo->HT_info_enable = 0; 6076 pmlmeinfo->agg_enable_bitmap = 0; 6077 pmlmeinfo->candidate_tid_bitmap = 0; 6078 6079 /* disable dynamic functions, such as high power, DIG */ 6080 Save_DM_Func_Flag(padapter); 6081 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); 6082 6083 /* config the initial gain under linking, need to write the BB registers */ 6084 /* initialgain = 0x1E; */ 6085 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */ 6086 6087 /* cancel link timer */ 6088 del_timer_sync(&pmlmeext->link_timer); 6089 6090 /* clear CAM */ 6091 flush_all_cam_entry(padapter); 6092 6093 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength)); 6094 pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength; 6095 6096 if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */ 6097 return H2C_PARAMETERS_ERROR; 6098 6099 memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength); 6100 6101 start_create_ibss(padapter); 6102 6103 } 6104 6105 return H2C_SUCCESS; 6106 6107 } 6108 6109 u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf) 6110 { 6111 u8 join_type; 6112 struct ndis_80211_var_ie *pIE; 6113 struct registry_priv *pregpriv = &padapter->registrypriv; 6114 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6115 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6116 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 6117 u32 i; 6118 u8 cbw40_enable = 0; 6119 /* u32 initialgain; */ 6120 /* u32 acparm; */ 6121 u8 ch, bw, offset; 6122 6123 /* check already connecting to AP or not */ 6124 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { 6125 if (pmlmeinfo->state & WIFI_FW_STATION_STATE) { 6126 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100); 6127 } 6128 pmlmeinfo->state = WIFI_FW_NULL_STATE; 6129 6130 /* clear CAM */ 6131 flush_all_cam_entry(padapter); 6132 6133 del_timer_sync(&pmlmeext->link_timer); 6134 6135 /* set MSR to nolink -> infra. mode */ 6136 /* Set_MSR(padapter, _HW_STATE_NOLINK_); */ 6137 Set_MSR(padapter, _HW_STATE_STATION_); 6138 6139 6140 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); 6141 } 6142 6143 rtw_joinbss_reset(padapter); 6144 6145 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 6146 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 6147 pmlmeinfo->ERP_enable = 0; 6148 pmlmeinfo->WMM_enable = 0; 6149 pmlmeinfo->HT_enable = 0; 6150 pmlmeinfo->HT_caps_enable = 0; 6151 pmlmeinfo->HT_info_enable = 0; 6152 pmlmeinfo->agg_enable_bitmap = 0; 6153 pmlmeinfo->candidate_tid_bitmap = 0; 6154 pmlmeinfo->bwmode_updated = false; 6155 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */ 6156 pmlmeinfo->VHT_enable = 0; 6157 6158 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength)); 6159 pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength; 6160 6161 if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */ 6162 return H2C_PARAMETERS_ERROR; 6163 6164 memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength); 6165 6166 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; 6167 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); 6168 6169 /* Check AP vendor to move rtw_joinbss_cmd() */ 6170 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */ 6171 6172 /* sizeof(struct ndis_802_11_fix_ie) */ 6173 for (i = _FIXED_IE_LENGTH_; i < pnetwork->IELength;) { 6174 pIE = (struct ndis_80211_var_ie *)(pnetwork->IEs + i); 6175 6176 switch (pIE->ElementID) { 6177 case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */ 6178 if (!memcmp(pIE->data, WMM_OUI, 4)) 6179 WMM_param_handler(padapter, pIE); 6180 break; 6181 6182 case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */ 6183 pmlmeinfo->HT_caps_enable = 1; 6184 break; 6185 6186 case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */ 6187 pmlmeinfo->HT_info_enable = 1; 6188 6189 /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */ 6190 { 6191 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data); 6192 6193 if (pnetwork->Configuration.DSConfig > 14) { 6194 if ((pregpriv->bw_mode >> 4) > CHANNEL_WIDTH_20) 6195 cbw40_enable = 1; 6196 } else { 6197 if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20) 6198 cbw40_enable = 1; 6199 } 6200 6201 if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) { 6202 /* switch to the 40M Hz mode according to the AP */ 6203 pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; 6204 switch (pht_info->infos[0] & 0x3) { 6205 case 1: 6206 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; 6207 break; 6208 6209 case 3: 6210 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; 6211 break; 6212 6213 default: 6214 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 6215 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 6216 break; 6217 } 6218 6219 DBG_871X("set HT ch/bw before connected\n"); 6220 } 6221 } 6222 break; 6223 default: 6224 break; 6225 } 6226 6227 i += (pIE->Length + 2); 6228 } 6229 6230 /* check channel, bandwidth, offset and switch */ 6231 if (rtw_chk_start_clnt_join(padapter, &ch, &bw, &offset) == _FAIL) { 6232 report_join_res(padapter, (-4)); 6233 return H2C_SUCCESS; 6234 } 6235 6236 /* disable dynamic functions, such as high power, DIG */ 6237 /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); */ 6238 6239 /* config the initial gain under linking, need to write the BB registers */ 6240 /* initialgain = 0x1E; */ 6241 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */ 6242 6243 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); 6244 join_type = 0; 6245 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 6246 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL); 6247 6248 set_channel_bwmode(padapter, ch, offset, bw); 6249 6250 /* cancel link timer */ 6251 del_timer_sync(&pmlmeext->link_timer); 6252 6253 start_clnt_join(padapter); 6254 6255 return H2C_SUCCESS; 6256 6257 } 6258 6259 u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) 6260 { 6261 struct disconnect_parm *param = (struct disconnect_parm *)pbuf; 6262 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6263 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6264 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 6265 u8 val8; 6266 6267 if (is_client_associated_to_ap(padapter)) { 6268 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100); 6269 } 6270 6271 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) { 6272 /* Stop BCN */ 6273 val8 = 0; 6274 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8)); 6275 } 6276 6277 rtw_mlmeext_disconnect(padapter); 6278 6279 rtw_free_uc_swdec_pending_queue(padapter); 6280 6281 return H2C_SUCCESS; 6282 } 6283 6284 static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out, 6285 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num) 6286 { 6287 int i, j; 6288 int set_idx; 6289 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6290 6291 /* clear first */ 6292 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num); 6293 6294 /* acquire channels from in */ 6295 j = 0; 6296 for (i = 0; i < in_num; i++) { 6297 6298 DBG_871X(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i])); 6299 6300 set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value); 6301 if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED) 6302 && set_idx >= 0 6303 && rtw_mlme_band_check(padapter, in[i].hw_value) 6304 ) { 6305 if (j >= out_num) { 6306 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n", 6307 FUNC_ADPT_ARG(padapter), out_num); 6308 break; 6309 } 6310 6311 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel)); 6312 6313 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE) 6314 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; 6315 6316 j++; 6317 } 6318 if (j >= out_num) 6319 break; 6320 } 6321 6322 /* if out is empty, use channel_set as default */ 6323 if (j == 0) { 6324 for (i = 0; i < pmlmeext->max_chan_nums; i++) { 6325 6326 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), pmlmeext->channel_set[i].ChannelNum); 6327 6328 if (rtw_mlme_band_check(padapter, pmlmeext->channel_set[i].ChannelNum)) { 6329 6330 if (j >= out_num) { 6331 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" out_num:%u not enough\n", 6332 FUNC_ADPT_ARG(padapter), out_num); 6333 break; 6334 } 6335 6336 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum; 6337 6338 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE) 6339 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; 6340 6341 j++; 6342 } 6343 } 6344 } 6345 6346 return j; 6347 } 6348 6349 u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) 6350 { 6351 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6352 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf; 6353 u8 bdelayscan = false; 6354 u8 val8; 6355 u32 initialgain; 6356 u32 i; 6357 6358 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) { 6359 pmlmeext->sitesurvey_res.state = SCAN_START; 6360 pmlmeext->sitesurvey_res.bss_cnt = 0; 6361 pmlmeext->sitesurvey_res.channel_idx = 0; 6362 6363 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { 6364 if (pparm->ssid[i].SsidLength) { 6365 memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE); 6366 pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength; 6367 } else { 6368 pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0; 6369 } 6370 } 6371 6372 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter 6373 , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT 6374 , pparm->ch, pparm->ch_num 6375 ); 6376 6377 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode; 6378 6379 /* issue null data if associating to the AP */ 6380 if (is_client_associated_to_ap(padapter)) { 6381 pmlmeext->sitesurvey_res.state = SCAN_TXNULL; 6382 6383 issue_nulldata(padapter, NULL, 1, 3, 500); 6384 6385 bdelayscan = true; 6386 } 6387 if (bdelayscan) { 6388 /* delay 50ms to protect nulldata(1). */ 6389 set_survey_timer(pmlmeext, 50); 6390 return H2C_SUCCESS; 6391 } 6392 } 6393 6394 if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) { 6395 /* disable dynamic functions, such as high power, DIG */ 6396 Save_DM_Func_Flag(padapter); 6397 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); 6398 6399 /* config the initial gain under scanning, need to write the BB 6400 * registers 6401 */ 6402 initialgain = 0x1e; 6403 6404 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); 6405 6406 /* set MSR to no link state */ 6407 Set_MSR(padapter, _HW_STATE_NOLINK_); 6408 6409 val8 = 1; /* under site survey */ 6410 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); 6411 6412 pmlmeext->sitesurvey_res.state = SCAN_PROCESS; 6413 } 6414 6415 site_survey(padapter); 6416 6417 return H2C_SUCCESS; 6418 6419 } 6420 6421 u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf) 6422 { 6423 struct setauth_parm *pparm = (struct setauth_parm *)pbuf; 6424 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6425 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6426 6427 if (pparm->mode < 4) 6428 pmlmeinfo->auth_algo = pparm->mode; 6429 6430 return H2C_SUCCESS; 6431 } 6432 6433 u8 setkey_hdl(struct adapter *padapter, u8 *pbuf) 6434 { 6435 u16 ctrl = 0; 6436 s16 cam_id = 0; 6437 struct setkey_parm *pparm = (struct setkey_parm *)pbuf; 6438 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6439 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6440 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 6441 u8 *addr; 6442 6443 /* main tx key for wep. */ 6444 if (pparm->set_tx) 6445 pmlmeinfo->key_index = pparm->keyid; 6446 6447 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid); 6448 6449 if (cam_id < 0) { 6450 } else { 6451 if (cam_id > 3) /* not default key, searched by A2 */ 6452 addr = get_bssid(&padapter->mlmepriv); 6453 else 6454 addr = null_addr; 6455 6456 ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid; 6457 write_cam(padapter, cam_id, ctrl, addr, pparm->key); 6458 DBG_871X_LEVEL(_drv_always_, "set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n" 6459 , cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm)); 6460 } 6461 6462 if (cam_id >= 0 && cam_id <= 3) 6463 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)true); 6464 6465 /* allow multicast packets to driver */ 6466 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr); 6467 6468 return H2C_SUCCESS; 6469 } 6470 6471 u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf) 6472 { 6473 u16 ctrl = 0; 6474 s16 cam_id = 0; 6475 u8 ret = H2C_SUCCESS; 6476 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6477 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6478 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf; 6479 struct sta_priv *pstapriv = &padapter->stapriv; 6480 struct sta_info *psta; 6481 6482 if (pparm->algorithm == _NO_PRIVACY_) 6483 goto write_to_cam; 6484 6485 psta = rtw_get_stainfo(pstapriv, pparm->addr); 6486 if (!psta) { 6487 DBG_871X_LEVEL(_drv_always_, "%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr)); 6488 ret = H2C_REJECTED; 6489 goto exit; 6490 } 6491 6492 pmlmeinfo->enc_algo = pparm->algorithm; 6493 cam_id = rtw_camid_alloc(padapter, psta, 0); 6494 if (cam_id < 0) 6495 goto exit; 6496 6497 write_to_cam: 6498 if (pparm->algorithm == _NO_PRIVACY_) { 6499 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1)) >= 0) { 6500 DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id); 6501 clear_cam_entry(padapter, cam_id); 6502 rtw_camid_free(padapter, cam_id); 6503 } 6504 } else { 6505 DBG_871X_LEVEL(_drv_always_, "set pairwise key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n", 6506 cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm)); 6507 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid; 6508 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); 6509 } 6510 ret = H2C_SUCCESS_RSP; 6511 6512 exit: 6513 return ret; 6514 } 6515 6516 u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf) 6517 { 6518 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf; 6519 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6520 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6521 6522 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr); 6523 6524 if (!psta) 6525 return H2C_SUCCESS; 6526 6527 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) || 6528 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) { 6529 /* pmlmeinfo->ADDBA_retry_count = 0; */ 6530 /* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */ 6531 /* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */ 6532 issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid); 6533 /* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */ 6534 _set_timer(&psta->addba_retry_timer, ADDBA_TO); 6535 } else { 6536 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid); 6537 } 6538 return H2C_SUCCESS; 6539 } 6540 6541 6542 u8 chk_bmc_sleepq_cmd(struct adapter *padapter) 6543 { 6544 struct cmd_obj *ph2c; 6545 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); 6546 u8 res = _SUCCESS; 6547 6548 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 6549 if (ph2c == NULL) { 6550 res = _FAIL; 6551 goto exit; 6552 } 6553 6554 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq)); 6555 6556 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 6557 6558 exit: 6559 return res; 6560 } 6561 6562 u8 set_tx_beacon_cmd(struct adapter *padapter) 6563 { 6564 struct cmd_obj *ph2c; 6565 struct Tx_Beacon_param *ptxBeacon_parm; 6566 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); 6567 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6568 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 6569 u8 res = _SUCCESS; 6570 int len_diff = 0; 6571 6572 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 6573 if (ph2c == NULL) { 6574 res = _FAIL; 6575 goto exit; 6576 } 6577 6578 ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param)); 6579 if (ptxBeacon_parm == NULL) { 6580 kfree(ph2c); 6581 res = _FAIL; 6582 goto exit; 6583 } 6584 6585 memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex)); 6586 6587 len_diff = update_hidden_ssid( 6588 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_ 6589 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_ 6590 , pmlmeinfo->hidden_ssid_mode 6591 ); 6592 ptxBeacon_parm->network.IELength += len_diff; 6593 6594 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon)); 6595 6596 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 6597 6598 exit: 6599 return res; 6600 } 6601 6602 6603 u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf) 6604 { 6605 u8 evt_code, evt_seq; 6606 u16 evt_sz; 6607 uint *peventbuf; 6608 void (*event_callback)(struct adapter *dev, u8 *pbuf); 6609 struct evt_priv *pevt_priv = &(padapter->evtpriv); 6610 6611 if (pbuf == NULL) 6612 goto _abort_event_; 6613 6614 peventbuf = (uint *)pbuf; 6615 evt_sz = (u16)(*peventbuf&0xffff); 6616 evt_seq = (u8)((*peventbuf>>24)&0x7f); 6617 evt_code = (u8)((*peventbuf>>16)&0xff); 6618 6619 6620 #ifdef CHECK_EVENT_SEQ 6621 /* checking event sequence... */ 6622 if (evt_seq != (atomic_read(&pevt_priv->event_seq) & 0x7f)) { 6623 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, 6624 ("Event Seq Error! %d vs %d\n", (evt_seq & 0x7f), 6625 (atomic_read(&pevt_priv->event_seq) & 0x7f))); 6626 6627 pevt_priv->event_seq = (evt_seq+1)&0x7f; 6628 6629 goto _abort_event_; 6630 } 6631 #endif 6632 6633 /* checking if event code is valid */ 6634 if (evt_code >= MAX_C2HEVT) { 6635 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code)); 6636 goto _abort_event_; 6637 } 6638 6639 /* checking if event size match the event parm size */ 6640 if ((wlanevents[evt_code].parmsize != 0) && 6641 (wlanevents[evt_code].parmsize != evt_sz)) { 6642 6643 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n", 6644 evt_code, wlanevents[evt_code].parmsize, evt_sz)); 6645 goto _abort_event_; 6646 6647 } 6648 6649 atomic_inc(&pevt_priv->event_seq); 6650 6651 peventbuf += 2; 6652 6653 if (peventbuf) { 6654 event_callback = wlanevents[evt_code].event_callback; 6655 event_callback(padapter, (u8 *)peventbuf); 6656 6657 pevt_priv->evt_done_cnt++; 6658 } 6659 6660 6661 _abort_event_: 6662 6663 6664 return H2C_SUCCESS; 6665 6666 } 6667 6668 u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf) 6669 { 6670 if (!pbuf) 6671 return H2C_PARAMETERS_ERROR; 6672 6673 return H2C_SUCCESS; 6674 } 6675 6676 u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf) 6677 { 6678 struct sta_info *psta_bmc; 6679 struct list_head *xmitframe_plist, *xmitframe_phead; 6680 struct xmit_frame *pxmitframe = NULL; 6681 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 6682 struct sta_priv *pstapriv = &padapter->stapriv; 6683 6684 /* for BC/MC Frames */ 6685 psta_bmc = rtw_get_bcmc_stainfo(padapter); 6686 if (!psta_bmc) 6687 return H2C_SUCCESS; 6688 6689 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) { 6690 msleep(10);/* 10ms, ATIM(HIQ) Windows */ 6691 6692 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */ 6693 spin_lock_bh(&pxmitpriv->lock); 6694 6695 xmitframe_phead = get_list_head(&psta_bmc->sleep_q); 6696 xmitframe_plist = get_next(xmitframe_phead); 6697 6698 while (xmitframe_phead != xmitframe_plist) { 6699 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); 6700 6701 xmitframe_plist = get_next(xmitframe_plist); 6702 6703 list_del_init(&pxmitframe->list); 6704 6705 psta_bmc->sleepq_len--; 6706 if (psta_bmc->sleepq_len > 0) 6707 pxmitframe->attrib.mdata = 1; 6708 else 6709 pxmitframe->attrib.mdata = 0; 6710 6711 pxmitframe->attrib.triggered = 1; 6712 6713 if (xmitframe_hiq_filter(pxmitframe)) 6714 pxmitframe->attrib.qsel = 0x11;/* HIQ */ 6715 6716 rtw_hal_xmitframe_enqueue(padapter, pxmitframe); 6717 } 6718 6719 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */ 6720 spin_unlock_bh(&pxmitpriv->lock); 6721 6722 /* check hi queue and bmc_sleepq */ 6723 rtw_chk_hi_queue_cmd(padapter); 6724 } 6725 6726 return H2C_SUCCESS; 6727 } 6728 6729 u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf) 6730 { 6731 if (send_beacon(padapter) == _FAIL) { 6732 DBG_871X("issue_beacon, fail!\n"); 6733 return H2C_PARAMETERS_ERROR; 6734 } 6735 6736 /* tx bc/mc frames after update TIM */ 6737 chk_bmc_sleepq_hdl(padapter, NULL); 6738 6739 return H2C_SUCCESS; 6740 } 6741 6742 int rtw_chk_start_clnt_join(struct adapter *padapter, u8 *ch, u8 *bw, u8 *offset) 6743 { 6744 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6745 unsigned char cur_ch = pmlmeext->cur_channel; 6746 unsigned char cur_bw = pmlmeext->cur_bwmode; 6747 unsigned char cur_ch_offset = pmlmeext->cur_ch_offset; 6748 bool connect_allow = true; 6749 6750 if (!ch || !bw || !offset) { 6751 rtw_warn_on(1); 6752 connect_allow = false; 6753 } 6754 6755 if (connect_allow) { 6756 DBG_871X("start_join_set_ch_bw: ch =%d, bwmode =%d, ch_offset =%d\n", cur_ch, cur_bw, cur_ch_offset); 6757 *ch = cur_ch; 6758 *bw = cur_bw; 6759 *offset = cur_ch_offset; 6760 } 6761 6762 return connect_allow ? _SUCCESS : _FAIL; 6763 } 6764 6765 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */ 6766 int rtw_get_ch_setting_union(struct adapter *adapter, u8 *ch, u8 *bw, u8 *offset) 6767 { 6768 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); 6769 struct adapter *iface; 6770 6771 if (ch) 6772 *ch = 0; 6773 if (bw) 6774 *bw = CHANNEL_WIDTH_20; 6775 if (offset) 6776 *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 6777 6778 iface = dvobj->padapters; 6779 6780 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING)) 6781 return 0; 6782 6783 return 1; 6784 } 6785 6786 u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf) 6787 { 6788 struct set_ch_parm *set_ch_parm; 6789 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6790 6791 if (!pbuf) 6792 return H2C_PARAMETERS_ERROR; 6793 6794 set_ch_parm = (struct set_ch_parm *)pbuf; 6795 6796 DBG_871X(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", 6797 FUNC_NDEV_ARG(padapter->pnetdev), 6798 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset); 6799 6800 pmlmeext->cur_channel = set_ch_parm->ch; 6801 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset; 6802 pmlmeext->cur_bwmode = set_ch_parm->bw; 6803 6804 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw); 6805 6806 return H2C_SUCCESS; 6807 } 6808 6809 u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf) 6810 { 6811 struct SetChannelPlan_param *setChannelPlan_param; 6812 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6813 6814 if (!pbuf) 6815 return H2C_PARAMETERS_ERROR; 6816 6817 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf; 6818 6819 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set); 6820 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); 6821 6822 if ((padapter->rtw_wdev != NULL) && (padapter->rtw_wdev->wiphy)) { 6823 struct regulatory_request request; 6824 6825 request.initiator = NL80211_REGDOM_SET_BY_DRIVER; 6826 rtw_reg_notifier(padapter->rtw_wdev->wiphy, &request); 6827 } 6828 6829 return H2C_SUCCESS; 6830 } 6831 6832 u8 led_blink_hdl(struct adapter *padapter, unsigned char *pbuf) 6833 { 6834 struct LedBlink_param *ledBlink_param; 6835 6836 if (!pbuf) 6837 return H2C_PARAMETERS_ERROR; 6838 6839 ledBlink_param = (struct LedBlink_param *)pbuf; 6840 return H2C_SUCCESS; 6841 } 6842 6843 u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf) 6844 { 6845 return H2C_REJECTED; 6846 } 6847 6848 /* TDLS_ESTABLISHED : write RCR DATA BIT */ 6849 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */ 6850 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */ 6851 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */ 6852 /* TDLS_OFF_CH : first time set channel to off channel */ 6853 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */ 6854 /* TDLS_P_OFF_CH : periodically go to off channel */ 6855 /* TDLS_P_BASE_CH : periodically go back to base channel */ 6856 /* TDLS_RS_RCR : restore RCR */ 6857 /* TDLS_TEAR_STA : free tdls sta */ 6858 u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf) 6859 { 6860 return H2C_REJECTED; 6861 } 6862 6863 u8 run_in_thread_hdl(struct adapter *padapter, u8 *pbuf) 6864 { 6865 struct RunInThread_param *p; 6866 6867 6868 if (NULL == pbuf) 6869 return H2C_PARAMETERS_ERROR; 6870 p = (struct RunInThread_param *)pbuf; 6871 6872 if (p->func) 6873 p->func(p->context); 6874 6875 return H2C_SUCCESS; 6876 } 6877