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