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