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