OSDN Git Service

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