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