add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8723bs / hal / rtl8723b / rtl8723b_cmd.c
1 /******************************************************************************\r
2  *\r
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.\r
4  *\r
5  * This program is free software; you can redistribute it and/or modify it\r
6  * under the terms of version 2 of the GNU General Public License as\r
7  * published by the Free Software Foundation.\r
8  *\r
9  * This program is distributed in the hope that it will be useful, but WITHOUT\r
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
12  * more details.\r
13  *\r
14  * You should have received a copy of the GNU General Public License along with\r
15  * this program; if not, write to the Free Software Foundation, Inc.,\r
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA\r
17  *\r
18  *\r
19  ******************************************************************************/\r
20 #define _RTL8723B_CMD_C_\r
21 \r
22 #include <rtl8723b_hal.h>\r
23 #include "hal_com_h2c.h"\r
24 \r
25 #define MAX_H2C_BOX_NUMS        4\r
26 #define MESSAGE_BOX_SIZE                4\r
27 \r
28 #define RTL8723B_MAX_CMD_LEN    7\r
29 #define RTL8723B_EX_MESSAGE_BOX_SIZE    4\r
30 \r
31 static u8 _is_fw_read_cmd_down(_adapter* padapter, u8 msgbox_num)\r
32 {\r
33         u8      read_down = _FALSE;\r
34         int     retry_cnts = 100;\r
35 \r
36         u8 valid;\r
37 \r
38         //DBG_8192C(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num);\r
39 \r
40         do{\r
41                 valid = rtw_read8(padapter,REG_HMETFR) & BIT(msgbox_num);\r
42                 if(0 == valid ){\r
43                         read_down = _TRUE;\r
44                 }\r
45 #ifdef CONFIG_WOWLAN\r
46                 else\r
47                         rtw_msleep_os(1);               \r
48 #endif\r
49         }while( (!read_down) && (retry_cnts--));\r
50 \r
51         return read_down;\r
52 \r
53 }\r
54 \r
55 \r
56 /*****************************************\r
57 * H2C Msg format :\r
58 *| 31 - 8               |7-5    | 4 - 0 |\r
59 *| h2c_msg      |Class  |CMD_ID |\r
60 *| 31-0                                         |\r
61 *| Ext msg                                      |\r
62 *\r
63 ******************************************/\r
64 s32 FillH2CCmd8723B(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)\r
65 {\r
66         u8 bcmd_down = _FALSE;\r
67         s32 retry_cnts = 100;\r
68         u8 h2c_box_num;\r
69         u32     msgbox_addr;\r
70         u32 msgbox_ex_addr=0;\r
71         PHAL_DATA_TYPE pHalData;\r
72         u32     h2c_cmd = 0;\r
73         u32     h2c_cmd_ex = 0;\r
74         s32 ret = _FAIL;\r
75         struct dvobj_priv *psdpriv = padapter->dvobj;\r
76         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;\r
77 _func_enter_;\r
78 \r
79         padapter = GET_PRIMARY_ADAPTER(padapter);\r
80         pHalData = GET_HAL_DATA(padapter);\r
81 #ifdef DBG_CHECK_FW_PS_STATE\r
82 #ifdef DBG_CHECK_FW_PS_STATE_H2C\r
83         if(rtw_fw_ps_state(padapter) == _FAIL)\r
84         {\r
85                 DBG_871X("%s: h2c doesn't leave 32k ElementID=%02x \n", __FUNCTION__, ElementID);\r
86                 pdbgpriv->dbg_h2c_leave32k_fail_cnt++;\r
87         }\r
88 \r
89         //DBG_871X("H2C ElementID=%02x , pHalData->LastHMEBoxNum=%02x\n", ElementID, pHalData->LastHMEBoxNum);\r
90 #endif //DBG_CHECK_FW_PS_STATE_H2C\r
91 #endif //DBG_CHECK_FW_PS_STATE\r
92         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);\r
93 \r
94         if (!pCmdBuffer) {\r
95                 goto exit;\r
96         }\r
97         if(CmdLen > RTL8723B_MAX_CMD_LEN) {\r
98                 goto exit;\r
99         }\r
100         if (padapter->bSurpriseRemoved == _TRUE)\r
101                 goto exit;\r
102 \r
103         //pay attention to if  race condition happened in  H2C cmd setting.\r
104         do{\r
105                 h2c_box_num = pHalData->LastHMEBoxNum;\r
106 \r
107                 if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){\r
108                         DBG_8192C(" fw read cmd failed...\n");\r
109 #ifdef DBG_CHECK_FW_PS_STATE\r
110                         DBG_871X("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n", rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)\r
111                                 , rtw_read32(padapter, 0x1c8), rtw_read32(padapter, 0x1cc));\r
112 #endif //DBG_CHECK_FW_PS_STATE\r
113                         //DBG_8192C(" 0x1c0: 0x%8x\n", rtw_read32(padapter, 0x1c0));\r
114                         //DBG_8192C(" 0x1c4: 0x%8x\n", rtw_read32(padapter, 0x1c4));\r
115                         goto exit;\r
116                 }\r
117 \r
118                 if(CmdLen<=3)\r
119                 {\r
120                         _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen );\r
121                 }\r
122                 else{\r
123                         _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, 3);\r
124                         _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3, CmdLen-3);\r
125 //                      *(u8*)(&h2c_cmd) |= BIT(7);\r
126                 }\r
127 \r
128                 *(u8*)(&h2c_cmd) |= ElementID;\r
129 \r
130                 if(CmdLen>3){\r
131                         msgbox_ex_addr = REG_HMEBOX_EXT0_8723B + (h2c_box_num *RTL8723B_EX_MESSAGE_BOX_SIZE);\r
132                         h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex );\r
133                         rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);\r
134                 }\r
135                 msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *MESSAGE_BOX_SIZE);\r
136                 h2c_cmd = le32_to_cpu( h2c_cmd );\r
137                 rtw_write32(padapter,msgbox_addr, h2c_cmd);\r
138 \r
139                 bcmd_down = _TRUE;\r
140 \r
141                 //DBG_8192C("MSG_BOX:%d, CmdLen(%d), CmdID(0x%x), reg:0x%x =>h2c_cmd:0x%.8x, reg:0x%x =>h2c_cmd_ex:0x%.8x\n"\r
142                 //      ,pHalData->LastHMEBoxNum , CmdLen, ElementID, msgbox_addr, h2c_cmd, msgbox_ex_addr, h2c_cmd_ex);\r
143 \r
144                 pHalData->LastHMEBoxNum = (h2c_box_num+1) % MAX_H2C_BOX_NUMS;\r
145 \r
146         }while((!bcmd_down) && (retry_cnts--));\r
147 \r
148         ret = _SUCCESS;\r
149 \r
150 exit:\r
151 \r
152         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);     \r
153 \r
154 _func_exit_;\r
155 \r
156         return ret;\r
157 }\r
158 \r
159 static void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)\r
160 {\r
161         struct rtw_ieee80211_hdr        *pwlanhdr;\r
162         u16                                     *fctrl;\r
163         u32                                     rate_len, pktlen;\r
164         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
165         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
166         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);\r
167         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
168 \r
169 \r
170         //DBG_871X("%s\n", __FUNCTION__);\r
171 \r
172         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;\r
173 \r
174         fctrl = &(pwlanhdr->frame_ctl);\r
175         *(fctrl) = 0;\r
176 \r
177         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);\r
178         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
179         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);\r
180 \r
181         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);\r
182         //pmlmeext->mgnt_seq++;\r
183         SetFrameSubType(pframe, WIFI_BEACON);\r
184 \r
185         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);\r
186         pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);\r
187 \r
188         //timestamp will be inserted by hardware\r
189         pframe += 8;\r
190         pktlen += 8;\r
191 \r
192         // beacon interval: 2 bytes\r
193         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);\r
194 \r
195         pframe += 2;\r
196         pktlen += 2;\r
197 \r
198         // capability info: 2 bytes\r
199         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);\r
200 \r
201         pframe += 2;\r
202         pktlen += 2;\r
203 \r
204         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)\r
205         {\r
206                 //DBG_871X("ie len=%d\n", cur_network->IELength);\r
207                 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);\r
208                 _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);\r
209 \r
210                 goto _ConstructBeacon;\r
211         }\r
212 \r
213         //below for ad-hoc mode\r
214 \r
215         // SSID\r
216         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);\r
217 \r
218         // supported rates...\r
219         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);\r
220         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);\r
221 \r
222         // DS parameter set\r
223         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);\r
224 \r
225         if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)\r
226         {\r
227                 u32 ATIMWindow;\r
228                 // IBSS Parameter Set...\r
229                 //ATIMWindow = cur->Configuration.ATIMWindow;\r
230                 ATIMWindow = 0;\r
231                 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);\r
232         }\r
233 \r
234 \r
235         //todo: ERP IE\r
236 \r
237 \r
238         // EXTERNDED SUPPORTED RATE\r
239         if (rate_len > 8)\r
240         {\r
241                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);\r
242         }\r
243 \r
244 \r
245         //todo:HT for adhoc\r
246 \r
247 _ConstructBeacon:\r
248 \r
249         if ((pktlen + TXDESC_SIZE) > 512)\r
250         {\r
251                 DBG_871X("beacon frame too large\n");\r
252                 return;\r
253         }\r
254 \r
255         *pLength = pktlen;\r
256 \r
257         //DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen);\r
258 \r
259 }\r
260 \r
261 static void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength)\r
262 {\r
263         struct rtw_ieee80211_hdr        *pwlanhdr;\r
264         u16                                     *fctrl;\r
265         u32                                     pktlen;\r
266         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
267         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
268 \r
269         //DBG_871X("%s\n", __FUNCTION__);\r
270 \r
271         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;\r
272 \r
273         // Frame control.\r
274         fctrl = &(pwlanhdr->frame_ctl);\r
275         *(fctrl) = 0;\r
276         SetPwrMgt(fctrl);\r
277         SetFrameSubType(pframe, WIFI_PSPOLL);\r
278 \r
279         // AID.\r
280         SetDuration(pframe, (pmlmeinfo->aid | 0xc000));\r
281 \r
282         // BSSID.\r
283         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
284 \r
285         // TA.\r
286         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
287 \r
288         *pLength = 16;\r
289 }\r
290 \r
291 static void ConstructNullFunctionData(\r
292         PADAPTER padapter,\r
293         u8              *pframe,\r
294         u32             *pLength,\r
295         u8              *StaAddr,\r
296         u8              bQoS,\r
297         u8              AC,\r
298         u8              bEosp,\r
299         u8              bForcePowerSave)\r
300 {\r
301         struct rtw_ieee80211_hdr        *pwlanhdr;\r
302         u16                                             *fctrl;\r
303         u32                                             pktlen;\r
304         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;\r
305         struct wlan_network             *cur_network = &pmlmepriv->cur_network;\r
306         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
307         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
308 \r
309 \r
310         //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);\r
311 \r
312         pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;\r
313 \r
314         fctrl = &pwlanhdr->frame_ctl;\r
315         *(fctrl) = 0;\r
316         if (bForcePowerSave)\r
317         {\r
318                 SetPwrMgt(fctrl);\r
319         }\r
320 \r
321         switch(cur_network->network.InfrastructureMode)\r
322         {\r
323                 case Ndis802_11Infrastructure:\r
324                         SetToDs(fctrl);\r
325                         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
326                         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
327                         _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);\r
328                         break;\r
329                 case Ndis802_11APMode:\r
330                         SetFrDs(fctrl);\r
331                         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);\r
332                         _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
333                         _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
334                         break;\r
335                 case Ndis802_11IBSS:\r
336                 default:\r
337                         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);\r
338                         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
339                         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
340                         break;\r
341         }\r
342 \r
343         SetSeqNum(pwlanhdr, 0);\r
344 \r
345         if (bQoS == _TRUE) {\r
346                 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;\r
347 \r
348                 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);\r
349 \r
350                 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;\r
351                 SetPriority(&pwlanqoshdr->qc, AC);\r
352                 SetEOSP(&pwlanqoshdr->qc, bEosp);\r
353 \r
354                 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);\r
355         } else {\r
356                 SetFrameSubType(pframe, WIFI_DATA_NULL);\r
357 \r
358                 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);\r
359         }\r
360 \r
361         *pLength = pktlen;\r
362 }\r
363 \r
364 \r
365 #ifdef CONFIG_WOWLAN    \r
366 //\r
367 // Description:\r
368 //      Construct the ARP response packet to support ARP offload.\r
369 //\r
370 static void ConstructARPResponse(\r
371         PADAPTER padapter,\r
372         u8                      *pframe,\r
373         u32                     *pLength,\r
374         u8                      *pIPAddress\r
375         )\r
376 {\r
377         struct rtw_ieee80211_hdr        *pwlanhdr;\r
378         u16                                             *fctrl;\r
379         u32                                             pktlen;\r
380         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;\r
381         struct wlan_network             *cur_network = &pmlmepriv->cur_network;\r
382         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
383         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
384         struct security_priv *psecuritypriv = &padapter->securitypriv;\r
385         static u8                       ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};\r
386         u8                              *pARPRspPkt = pframe;\r
387         //for TKIP Cal MIC\r
388         u8                              *payload = pframe;\r
389         u8                      EncryptionHeadOverhead = 0;\r
390         //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);\r
391 \r
392         pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;\r
393 \r
394         fctrl = &pwlanhdr->frame_ctl;\r
395         *(fctrl) = 0;\r
396 \r
397         //-------------------------------------------------------------------------\r
398         // MAC Header.\r
399         //-------------------------------------------------------------------------\r
400         SetFrameType(fctrl, WIFI_DATA);\r
401         //SetFrameSubType(fctrl, 0);\r
402         SetToDs(fctrl);\r
403         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
404         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
405         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
406 \r
407         SetSeqNum(pwlanhdr, 0);\r
408         SetDuration(pwlanhdr, 0);\r
409         //SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0);\r
410         //SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data);\r
411         //SET_80211_HDR_TO_DS(pARPRspPkt, 1);\r
412         //SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid);\r
413         //SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress);\r
414         //SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid);\r
415 \r
416         //SET_80211_HDR_DURATION(pARPRspPkt, 0);\r
417         //SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0);\r
418 #ifdef CONFIG_WAPI_SUPPORT\r
419         *pLength = sMacHdrLng;\r
420 #else\r
421         *pLength = 24;\r
422 #endif\r
423 \r
424 //YJ,del,120503\r
425 #if 0\r
426         //-------------------------------------------------------------------------\r
427         // Qos Header: leave space for it if necessary.\r
428         //-------------------------------------------------------------------------\r
429         if(pStaQos->CurrentQosMode > QOS_DISABLE)\r
430         {\r
431                 SET_80211_HDR_QOS_EN(pARPRspPkt, 1);\r
432                 PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng);\r
433                 *pLength += sQoSCtlLng;\r
434         }\r
435 #endif\r
436         //-------------------------------------------------------------------------\r
437         // Security Header: leave space for it if necessary.\r
438         //-------------------------------------------------------------------------\r
439 \r
440 #if 1\r
441         switch (psecuritypriv->dot11PrivacyAlgrthm)\r
442         {\r
443                 case _WEP40_:\r
444                 case _WEP104_:\r
445                         EncryptionHeadOverhead = 4;\r
446                         break;\r
447                 case _TKIP_:\r
448                         EncryptionHeadOverhead = 8;     \r
449                         break;                  \r
450                 case _AES_:\r
451                         EncryptionHeadOverhead = 8;\r
452                         break;\r
453 #ifdef CONFIG_WAPI_SUPPORT\r
454                 case _SMS4_:\r
455                         EncryptionHeadOverhead = 18;\r
456                         break;\r
457 #endif                  \r
458                 default:\r
459                         EncryptionHeadOverhead = 0;\r
460         }\r
461         \r
462         if(EncryptionHeadOverhead > 0)\r
463         {\r
464                 _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);\r
465                 *pLength += EncryptionHeadOverhead;\r
466                 //SET_80211_HDR_WEP(pARPRspPkt, 1);  //Suggested by CCW.\r
467                 SetPrivacy(fctrl);\r
468         }       \r
469 #endif\r
470         //-------------------------------------------------------------------------\r
471         // Frame Body.\r
472         //-------------------------------------------------------------------------\r
473         pARPRspPkt =  (u8*)(pframe+ *pLength);\r
474         payload = pARPRspPkt; //Get Payload pointer\r
475         // LLC header\r
476         _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);       \r
477         *pLength += 8;\r
478 \r
479         // ARP element\r
480         pARPRspPkt += 8;\r
481         SET_ARP_PKT_HW(pARPRspPkt, 0x0100);\r
482         SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008);       // IP protocol\r
483         SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);\r
484         SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);\r
485         SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response\r
486         SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv)));\r
487         SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);\r
488 #ifdef CONFIG_ARP_KEEP_ALIVE\r
489         if (rtw_gw_addr_query(padapter)==0) {\r
490                 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);\r
491                 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);\r
492         }\r
493         else\r
494 #endif\r
495         {\r
496                 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, get_my_bssid(&(pmlmeinfo->network)));\r
497                 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pIPAddress);\r
498                 DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));\r
499                 DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(pIPAddress));\r
500         }\r
501         \r
502         *pLength += 28;\r
503 \r
504         if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_)\r
505         {\r
506                 u8      mic[8];\r
507                 struct mic_data micdata;\r
508                 struct sta_info *psta = NULL;\r
509                 u8      priority[4]={0x0,0x0,0x0,0x0};\r
510                 u8      null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};\r
511 \r
512                 DBG_871X("%s(): Add MIC\n",__FUNCTION__);\r
513 \r
514                 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network)));\r
515                 if (psta != NULL) {\r
516                         if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){\r
517                                 DBG_871X("%s(): STA dot11tkiptxmickey==0\n",__FUNCTION__);\r
518                         }\r
519                         //start to calculate the mic code\r
520                         rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);\r
521                 }\r
522 \r
523                 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  //DA\r
524 \r
525                 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA\r
526 \r
527                 priority[0]=0;\r
528                 rtw_secmicappend(&micdata, &priority[0], 4);\r
529 \r
530                 rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28\r
531 \r
532                 rtw_secgetmic(&micdata,&(mic[0]));\r
533 \r
534                 pARPRspPkt += 28;\r
535                 _rtw_memcpy(pARPRspPkt, &(mic[0]),8);\r
536 \r
537                 *pLength += 8;\r
538         }\r
539 }\r
540 \r
541 #ifdef CONFIG_PNO_SUPPORT\r
542 static void ConstructPnoInfo(\r
543         PADAPTER padapter,\r
544         u8                      *pframe,\r
545         u32                     *pLength\r
546         )\r
547 {\r
548 \r
549         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);\r
550 \r
551         u8      *pPnoInfoPkt = pframe;\r
552         pPnoInfoPkt =  (u8*)(pframe+ *pLength);\r
553         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 4);\r
554 \r
555         *pLength+=4;\r
556         pPnoInfoPkt += 4;\r
557         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 4);\r
558 \r
559         *pLength+=4;\r
560         pPnoInfoPkt += 4;\r
561         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);\r
562 \r
563         *pLength+=4;\r
564         pPnoInfoPkt += 4;\r
565         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);\r
566 \r
567         *pLength+=4;\r
568         pPnoInfoPkt += 4;\r
569         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length,\r
570                         MAX_PNO_LIST_COUNT);\r
571 \r
572         *pLength+=MAX_PNO_LIST_COUNT;\r
573         pPnoInfoPkt += MAX_PNO_LIST_COUNT;\r
574         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_chiper_info,\r
575                         MAX_PNO_LIST_COUNT);\r
576 \r
577         *pLength+=MAX_PNO_LIST_COUNT;\r
578         pPnoInfoPkt += MAX_PNO_LIST_COUNT;\r
579         _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info,\r
580                         MAX_PNO_LIST_COUNT);\r
581 \r
582         *pLength+=MAX_PNO_LIST_COUNT;\r
583         pPnoInfoPkt += MAX_PNO_LIST_COUNT;\r
584 }\r
585 \r
586 static void ConstructSSIDList(\r
587         PADAPTER padapter,\r
588         u8                      *pframe,\r
589         u32                     *pLength\r
590         )\r
591 {\r
592         int i = 0;\r
593         u8      *pSSIDListPkt = pframe;\r
594         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);\r
595 \r
596         pSSIDListPkt =  (u8*)(pframe+ *pLength);\r
597 \r
598         for(i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {\r
599                 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,\r
600                         pwrctl->pnlo_info->ssid_length[i]);\r
601 \r
602                 *pLength += WLAN_SSID_MAXLEN;\r
603                 pSSIDListPkt += WLAN_SSID_MAXLEN;\r
604         }\r
605 }\r
606 \r
607 static void ConstructScanInfo(\r
608         PADAPTER padapter,\r
609         u8                      *pframe,\r
610         u32                     *pLength\r
611         )\r
612 {\r
613         int i = 0;\r
614         u8      *pScanInfoPkt = pframe;\r
615         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);\r
616 \r
617         pScanInfoPkt =  (u8*)(pframe+ *pLength);\r
618 \r
619         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);\r
620 \r
621         *pLength+=1;\r
622         pScanInfoPkt += 1;\r
623         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);\r
624 \r
625 \r
626         *pLength+=1;\r
627         pScanInfoPkt += 1;\r
628         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);\r
629 \r
630 \r
631         *pLength+=1;\r
632         pScanInfoPkt += 1;\r
633         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);\r
634 \r
635         *pLength+=1;\r
636         pScanInfoPkt += 1;\r
637         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);\r
638 \r
639         *pLength+=1;\r
640         pScanInfoPkt += 1;\r
641         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);\r
642 \r
643         *pLength+=1;\r
644         pScanInfoPkt += 1;\r
645         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);\r
646 \r
647         *pLength+=1;\r
648         pScanInfoPkt += 1;\r
649         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);\r
650 \r
651         *pLength+=1;\r
652         pScanInfoPkt += 1;\r
653         _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);\r
654 \r
655         *pLength+=8;\r
656         pScanInfoPkt += 8;\r
657 \r
658         for(i = 0 ; i < MAX_SCAN_LIST_COUNT ; i ++) {\r
659                 _rtw_memcpy(pScanInfoPkt,\r
660                         &pwrctl->pscan_info->ssid_channel_info[i], 4);\r
661                 *pLength+=4;\r
662                 pScanInfoPkt += 4;\r
663         }\r
664 }\r
665 #endif\r
666 \r
667 #ifdef CONFIG_GTK_OL\r
668 static void ConstructGTKResponse(\r
669         PADAPTER padapter,\r
670         u8                      *pframe,\r
671         u32                     *pLength\r
672         )\r
673 {\r
674         struct rtw_ieee80211_hdr        *pwlanhdr;\r
675         u16                                             *fctrl;\r
676         u32                                             pktlen;\r
677         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;\r
678         struct wlan_network             *cur_network = &pmlmepriv->cur_network;\r
679         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
680         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
681         struct security_priv *psecuritypriv = &padapter->securitypriv;\r
682         static u8                       LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};\r
683         static u8                       GTKbody_a[11] ={0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};\r
684         u8                              *pGTKRspPkt = pframe;\r
685         u8                      EncryptionHeadOverhead = 0;\r
686         //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);\r
687 \r
688         pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;\r
689 \r
690         fctrl = &pwlanhdr->frame_ctl;\r
691         *(fctrl) = 0;\r
692 \r
693         //-------------------------------------------------------------------------\r
694         // MAC Header.\r
695         //-------------------------------------------------------------------------\r
696         SetFrameType(fctrl, WIFI_DATA);\r
697         //SetFrameSubType(fctrl, 0);\r
698         SetToDs(fctrl);\r
699         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
700         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
701         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
702 \r
703         SetSeqNum(pwlanhdr, 0);\r
704         SetDuration(pwlanhdr, 0);\r
705 \r
706 #ifdef CONFIG_WAPI_SUPPORT\r
707         *pLength = sMacHdrLng;\r
708 #else\r
709         *pLength = 24;\r
710 #endif //CONFIG_WAPI_SUPPORT\r
711 \r
712 //YJ,del,120503\r
713 #if 0\r
714         //-------------------------------------------------------------------------\r
715         // Qos Header: leave space for it if necessary.\r
716         //-------------------------------------------------------------------------\r
717         if(pStaQos->CurrentQosMode > QOS_DISABLE)\r
718         {\r
719                 SET_80211_HDR_QOS_EN(pGTKRspPkt, 1);\r
720                 PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng);\r
721                 *pLength += sQoSCtlLng;\r
722         }\r
723 #endif //0\r
724         //-------------------------------------------------------------------------\r
725         // Security Header: leave space for it if necessary.\r
726         //-------------------------------------------------------------------------\r
727 \r
728 #if 1\r
729         switch (psecuritypriv->dot11PrivacyAlgrthm)\r
730         {\r
731                 case _WEP40_:\r
732                 case _WEP104_:\r
733                         EncryptionHeadOverhead = 4;\r
734                         break;\r
735                 case _TKIP_:\r
736                         EncryptionHeadOverhead = 8;     \r
737                         break;                  \r
738                 case _AES_:\r
739                         EncryptionHeadOverhead = 8;\r
740                         break;\r
741 #ifdef CONFIG_WAPI_SUPPORT\r
742                 case _SMS4_:\r
743                         EncryptionHeadOverhead = 18;\r
744                         break;\r
745 #endif //CONFIG_WAPI_SUPPORT\r
746                 default:\r
747                         EncryptionHeadOverhead = 0;\r
748         }\r
749         \r
750         if(EncryptionHeadOverhead > 0)\r
751         {\r
752                 _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);\r
753                 *pLength += EncryptionHeadOverhead;\r
754                 //SET_80211_HDR_WEP(pGTKRspPkt, 1);  //Suggested by CCW.\r
755                 //GTK's privacy bit is done by FW\r
756                 //SetPrivacy(fctrl);\r
757         }       \r
758 #endif //1\r
759         //-------------------------------------------------------------------------\r
760         // Frame Body.\r
761         //-------------------------------------------------------------------------\r
762         pGTKRspPkt =  (u8*)(pframe+ *pLength); \r
763         // LLC header\r
764         _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);  \r
765         *pLength += 8;\r
766 \r
767         // GTK element\r
768         pGTKRspPkt += 8;\r
769         \r
770         //GTK frame body after LLC, part 1\r
771         _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11); \r
772         *pLength += 11;\r
773         pGTKRspPkt += 11;\r
774         //GTK frame body after LLC, part 2\r
775         _rtw_memset(&(pframe[*pLength]), 0, 88);\r
776         *pLength += 88;\r
777         pGTKRspPkt += 88;\r
778 \r
779 }\r
780 #endif //CONFIG_GTK_OL\r
781 \r
782 #ifdef CONFIG_PNO_SUPPORT\r
783 static void ConstructProbeReq(_adapter *padapter, u8 *pframe, u32 *pLength)\r
784 {\r
785         struct rtw_ieee80211_hdr        *pwlanhdr;\r
786         u16                             *fctrl;\r
787         u32                             pktlen;\r
788         unsigned char                   *mac;\r
789         unsigned char                   bssrate[NumRates];\r
790         struct xmit_priv                *pxmitpriv = &(padapter->xmitpriv);\r
791         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);\r
792         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
793         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
794         int     bssrate_len = 0;\r
795         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
796 \r
797         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;\r
798         mac = myid(&(padapter->eeprompriv));\r
799 \r
800         fctrl = &(pwlanhdr->frame_ctl);\r
801         *(fctrl) = 0;\r
802 \r
803         //broadcast probe request frame\r
804         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);\r
805         _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);\r
806 \r
807         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);\r
808 \r
809         SetSeqNum(pwlanhdr, 0);\r
810         SetFrameSubType(pframe, WIFI_PROBEREQ);\r
811 \r
812         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);\r
813         pframe += pktlen;\r
814 \r
815         pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);\r
816 \r
817         get_rate_set(padapter, bssrate, &bssrate_len);\r
818 \r
819         if (bssrate_len > 8)\r
820         {\r
821                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);\r
822                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);\r
823         }\r
824         else\r
825         {\r
826                 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);\r
827         }\r
828 \r
829         *pLength = pktlen;\r
830 }\r
831 #endif //CONFIG_PNO_SUPPORT\r
832 #endif //CONFIG_WOWLAN\r
833 \r
834 static void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID)\r
835 {\r
836         struct rtw_ieee80211_hdr        *pwlanhdr;\r
837         u16                                     *fctrl;\r
838         u8                                      *mac, *bssid;\r
839         u32                                     pktlen;\r
840         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
841         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
842         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);\r
843 \r
844 \r
845         //DBG_871X("%s\n", __FUNCTION__);\r
846 \r
847         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;\r
848 \r
849         mac = myid(&(padapter->eeprompriv));\r
850         bssid = cur_network->MacAddress;\r
851 \r
852         fctrl = &(pwlanhdr->frame_ctl);\r
853         *(fctrl) = 0;\r
854         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);\r
855         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);\r
856         _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);\r
857 \r
858         SetSeqNum(pwlanhdr, 0);\r
859         SetFrameSubType(fctrl, WIFI_PROBERSP);\r
860 \r
861         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);\r
862         pframe += pktlen;\r
863 \r
864         if(cur_network->IELength>MAX_IE_SZ)\r
865                 return;\r
866 \r
867         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);\r
868         pframe += cur_network->IELength;\r
869         pktlen += cur_network->IELength;\r
870 \r
871         *pLength = pktlen;\r
872 }\r
873 \r
874 // To check if reserved page content is destroyed by beacon beacuse beacon is too large.\r
875 // 2010.06.23. Added by tynli.\r
876 VOID\r
877 CheckFwRsvdPageContent(\r
878         IN      PADAPTER                Adapter\r
879 )\r
880 {\r
881         HAL_DATA_TYPE*  pHalData = GET_HAL_DATA(Adapter);\r
882         u32     MaxBcnPageNum;\r
883 \r
884         if(pHalData->FwRsvdPageStartOffset != 0)\r
885         {\r
886                 /*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize);\r
887                 RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset),\r
888                         ("CheckFwRsvdPageContent(): The reserved page content has been"\\r
889                         "destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!",\r
890                         MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/\r
891         }\r
892 }\r
893 \r
894 static void rtl8723b_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)\r
895 {\r
896         u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0};\r
897 \r
898         DBG_871X("8723BRsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",  \r
899                 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,\r
900                 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,\r
901                 rsvdpageloc->LocBTQosNull);\r
902 \r
903         SET_8723B_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);\r
904         SET_8723B_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);\r
905         SET_8723B_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);\r
906         SET_8723B_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);\r
907         SET_8723B_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);\r
908         \r
909         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CRsvdPageParm:", u1H2CRsvdPageParm, H2C_RSVDPAGE_LOC_LEN);\r
910         FillH2CCmd8723B(padapter, H2C_8723B_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm);\r
911 }\r
912 \r
913 static void rtl8723b_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)\r
914 {\r
915         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);\r
916         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;\r
917         u8      res = 0, count = 0;\r
918 #ifdef CONFIG_WOWLAN    \r
919         u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};\r
920 \r
921         DBG_871X("8723BAOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",  \r
922                         rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,\r
923                         rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,\r
924                         rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,\r
925                         rsvdpageloc->LocNetList);\r
926 \r
927 #ifdef CONFIG_PNO_SUPPORT\r
928         DBG_871X("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);\r
929 #endif\r
930         if (check_fwstate(pmlmepriv, _FW_LINKED)) {\r
931         SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);\r
932         SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);\r
933         //SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv);\r
934         SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);\r
935         SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);\r
936 #ifdef CONFIG_GTK_OL\r
937         SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);\r
938 #endif // CONFIG_GTK_OL\r
939         } else {\r
940 #ifdef CONFIG_PNO_SUPPORT\r
941                 if(!pwrpriv->pno_in_resume) {\r
942                         SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocPNOInfo);\r
943                 }\r
944 #endif\r
945         }\r
946 \r
947         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CAoacRsvdPageParm:", u1H2CAoacRsvdPageParm, H2C_AOAC_RSVDPAGE_LOC_LEN);\r
948         FillH2CCmd8723B(padapter, H2C_8723B_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);\r
949 \r
950 #ifdef CONFIG_PNO_SUPPORT\r
951         if (!check_fwstate(pmlmepriv, WIFI_AP_STATE) &&\r
952                         !check_fwstate(pmlmepriv, _FW_LINKED) &&\r
953                         pwrpriv->pno_in_resume == _FALSE) {\r
954 \r
955                 res = rtw_read8(padapter, 0x1b8);\r
956                 while(res == 0 && count < 25) {\r
957                         DBG_871X("[%d] FW loc_NLOInfo: %d\n", count, res);\r
958                         res = rtw_read8(padapter, 0x1b8);\r
959                         count++;\r
960                         rtw_msleep_os(2);\r
961                 }\r
962         }\r
963 #endif // CONFIG_PNO_SUPPORT\r
964 #endif // CONFIG_WOWLAN\r
965 }\r
966 \r
967 #ifdef CONFIG_AP_WOWLAN\r
968 static void rtl8723b_set_ap_wow_rsvdpage_cmd(PADAPTER padapter,\r
969                 PRSVDPAGE_LOC rsvdpageloc)\r
970 {\r
971         struct  pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);\r
972         struct  mlme_priv *pmlmepriv = &padapter->mlmepriv;\r
973         u8      res = 0, count = 0, header = 0;\r
974         u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};\r
975 \r
976         header = rtw_read8(padapter, REG_BCNQ_BDNY);\r
977 \r
978         DBG_871X("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,\r
979                         rsvdpageloc->LocApOffloadBCN,\r
980                         rsvdpageloc->LocProbeRsp,\r
981                         header);\r
982 \r
983         SET_8723B_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,\r
984                         rsvdpageloc->LocApOffloadBCN + header);\r
985 \r
986         FillH2CCmd8723B(padapter, H2C_8723B_BCN_RSVDPAGE,\r
987                         H2C_BCN_RSVDPAGE_LEN, rsvdparm);\r
988 \r
989         rtw_msleep_os(10);\r
990 \r
991         _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));\r
992 \r
993         SET_8723B_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(\r
994                         rsvdparm,\r
995                         rsvdpageloc->LocProbeRsp + header);\r
996 \r
997         FillH2CCmd8723B(padapter, H2C_8723B_PROBERSP_RSVDPAGE,\r
998                         H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);\r
999 \r
1000         rtw_msleep_os(10);\r
1001 }\r
1002 #endif //CONFIG_AP_WOWLAN\r
1003 \r
1004 void rtl8723b_set_FwMediaStatusRpt_cmd(PADAPTER padapter, u8 mstatus, u8 macid)\r
1005 {\r
1006         u8 u1H2CMediaStatusRptParm[H2C_MEDIA_STATUS_RPT_LEN]={0};\r
1007         u8 macid_end = 0;\r
1008 \r
1009         DBG_871X("%s(): mstatus = %d macid=%d\n", __func__, mstatus, macid);\r
1010 \r
1011         SET_8723B_H2CCMD_MSRRPT_PARM_OPMODE(u1H2CMediaStatusRptParm, mstatus);\r
1012         SET_8723B_H2CCMD_MSRRPT_PARM_MACID_IND(u1H2CMediaStatusRptParm, 0);\r
1013         SET_8723B_H2CCMD_MSRRPT_PARM_MACID(u1H2CMediaStatusRptParm, macid);\r
1014         SET_8723B_H2CCMD_MSRRPT_PARM_MACID_END(u1H2CMediaStatusRptParm, macid_end);\r
1015 \r
1016         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CMediaStatusRptParm:", u1H2CMediaStatusRptParm, H2C_MEDIA_STATUS_RPT_LEN);\r
1017         FillH2CCmd8723B(padapter, H2C_8723B_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, u1H2CMediaStatusRptParm);\r
1018 }\r
1019 \r
1020 static void rtl8723b_set_FwKeepAlive_cmd(PADAPTER padapter, u8 benable, u8 pkt_type)\r
1021 {\r
1022         u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN]={0};\r
1023         u8 adopt = 1, check_period = 5;\r
1024 \r
1025         DBG_871X("%s(): benable = %d\n", __func__, benable);\r
1026         SET_8723B_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, benable);\r
1027         SET_8723B_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);\r
1028         SET_8723B_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);\r
1029         SET_8723B_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);\r
1030 \r
1031         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CKeepAliveParm:", u1H2CKeepAliveParm, H2C_KEEP_ALIVE_CTRL_LEN);\r
1032 \r
1033         FillH2CCmd8723B(padapter, H2C_8723B_KEEP_ALIVE, H2C_KEEP_ALIVE_CTRL_LEN, u1H2CKeepAliveParm);\r
1034 }\r
1035 \r
1036 static void rtl8723b_set_FwDisconDecision_cmd(PADAPTER padapter, u8 benable)\r
1037 {\r
1038         u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN]={0};\r
1039         u8 adopt = 1, check_period = 10, trypkt_num = 0;\r
1040 \r
1041         DBG_871X("%s(): benable = %d\n", __func__, benable);\r
1042         SET_8723B_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, benable);\r
1043         SET_8723B_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);\r
1044         SET_8723B_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);\r
1045         SET_8723B_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);\r
1046 \r
1047         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CDisconDecisionParm:", u1H2CDisconDecisionParm, H2C_DISCON_DECISION_LEN);\r
1048 \r
1049         FillH2CCmd8723B(padapter, H2C_8723B_DISCON_DECISION, H2C_DISCON_DECISION_LEN, u1H2CDisconDecisionParm);\r
1050 }\r
1051 \r
1052 void rtl8723b_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask)\r
1053 {\r
1054         u8 u1H2CMacIdConfigParm[H2C_MACID_CFG_LEN]={0};\r
1055 \r
1056         DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask);\r
1057         \r
1058 _func_enter_;\r
1059 \r
1060         SET_8723B_H2CCMD_MACID_CFG_MACID(u1H2CMacIdConfigParm, mac_id);\r
1061         SET_8723B_H2CCMD_MACID_CFG_RAID(u1H2CMacIdConfigParm, raid);\r
1062         SET_8723B_H2CCMD_MACID_CFG_SGI_EN(u1H2CMacIdConfigParm, (sgi)? 1:0);\r
1063         SET_8723B_H2CCMD_MACID_CFG_BW(u1H2CMacIdConfigParm, bw);\r
1064         SET_8723B_H2CCMD_MACID_CFG_RATE_MASK0(u1H2CMacIdConfigParm, (u8)(mask & 0x000000ff));\r
1065         SET_8723B_H2CCMD_MACID_CFG_RATE_MASK1(u1H2CMacIdConfigParm, (u8)((mask & 0x0000ff00) >>8));\r
1066         SET_8723B_H2CCMD_MACID_CFG_RATE_MASK2(u1H2CMacIdConfigParm, (u8)((mask & 0x00ff0000) >> 16));\r
1067         SET_8723B_H2CCMD_MACID_CFG_RATE_MASK3(u1H2CMacIdConfigParm, (u8)((mask & 0xff000000) >> 24));\r
1068         \r
1069         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CMacIdConfigParm:", u1H2CMacIdConfigParm, H2C_MACID_CFG_LEN);\r
1070         FillH2CCmd8723B(padapter, H2C_8723B_MACID_CFG, H2C_MACID_CFG_LEN, u1H2CMacIdConfigParm);\r
1071 \r
1072 _func_exit_;\r
1073 }\r
1074 \r
1075 void rtl8723b_set_FwRssiSetting_cmd(_adapter*padapter, u8 *param)\r
1076 {\r
1077         u8 u1H2CRssiSettingParm[H2C_RSSI_SETTING_LEN]={0};\r
1078         u8 mac_id = *param;\r
1079         u8 rssi = *(param+2);\r
1080         u8 uldl_state = 0;\r
1081 \r
1082 _func_enter_;\r
1083         //DBG_871X("%s(): param=%.2x-%.2x-%.2x\n", __func__, *param, *(param+1), *(param+2));\r
1084         //DBG_871X("%s(): mac_id=%d rssi=%d\n", __func__, mac_id, rssi);\r
1085 \r
1086         SET_8723B_H2CCMD_RSSI_SETTING_MACID(u1H2CRssiSettingParm, mac_id);\r
1087         SET_8723B_H2CCMD_RSSI_SETTING_RSSI(u1H2CRssiSettingParm, rssi);\r
1088         SET_8723B_H2CCMD_RSSI_SETTING_ULDL_STATE(u1H2CRssiSettingParm, uldl_state);\r
1089 \r
1090         RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "u1H2CRssiSettingParm:", u1H2CRssiSettingParm, H2C_RSSI_SETTING_LEN);\r
1091         FillH2CCmd8723B(padapter, H2C_8723B_RSSI_SETTING, H2C_RSSI_SETTING_LEN, u1H2CRssiSettingParm);\r
1092 \r
1093 _func_exit_;\r
1094 }\r
1095 \r
1096 void rtl8723b_set_FwAPReqRPT_cmd(PADAPTER padapter, u32 need_ack)\r
1097 {\r
1098         u8 u1H2CApReqRptParm[H2C_AP_REQ_TXRPT_LEN]={0};\r
1099         u8 macid1 = 1, macid2 = 0;\r
1100 \r
1101         DBG_871X("%s(): need_ack = %d\n", __func__, need_ack);\r
1102 \r
1103         SET_8723B_H2CCMD_APREQRPT_PARM_MACID1(u1H2CApReqRptParm, macid1);\r
1104         SET_8723B_H2CCMD_APREQRPT_PARM_MACID2(u1H2CApReqRptParm, macid2);\r
1105 \r
1106         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CApReqRptParm:", u1H2CApReqRptParm, H2C_AP_REQ_TXRPT_LEN);\r
1107         FillH2CCmd8723B(padapter, H2C_8723B_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm);\r
1108 }\r
1109 \r
1110 void rtl8723b_set_FwPwrMode_cmd(PADAPTER padapter, u8 psmode)\r
1111 {\r
1112         int i;\r
1113         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);\r
1114         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;\r
1115         u8 u1H2CPwrModeParm[H2C_PWRMODE_LEN]={0};\r
1116         u8 PowerState=0, awake_intvl = 1, byte5 = 0, rlbm = 0;\r
1117         struct wifidirect_info *wdinfo = &(padapter->wdinfo);\r
1118 \r
1119 _func_enter_;\r
1120 \r
1121         if(pwrpriv->dtim > 0)\r
1122                 DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d, dtim=%d\n", __func__, psmode, pwrpriv->smart_ps, pwrpriv->dtim);\r
1123         else\r
1124                 DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d\n", __func__, psmode, pwrpriv->smart_ps);\r
1125 \r
1126 #ifdef CONFIG_WOWLAN\r
1127         if(psmode == PS_MODE_DTIM)  //For WOWLAN LPS, DTIM = (awake_intvl - 1)\r
1128         {\r
1129 #ifdef CONFIG_PLATFORM_ARM_SUN8I\r
1130                 awake_intvl = 4;//DTIM=3\r
1131 #else\r
1132                 awake_intvl = 3;//DTIM=2\r
1133 #endif\r
1134                 rlbm = 2;\r
1135         }\r
1136         else\r
1137 #endif //CONFIG_WOWLAN\r
1138         {\r
1139                 if(pwrpriv->dtim > 0 && pwrpriv->dtim < 16)\r
1140                         awake_intvl = pwrpriv->dtim+1;//DTIM = (awake_intvl - 1)\r
1141                 else\r
1142 #ifdef CONFIG_PLATFORM_ARM_SUN8I\r
1143                         awake_intvl = 4;//DTIM=3\r
1144 #else\r
1145                         awake_intvl = 3;//DTIM=2\r
1146 #endif\r
1147 \r
1148                 rlbm = 2;\r
1149         }       \r
1150 \r
1151 \r
1152         if (!rtw_p2p_chk_state(wdinfo, P2P_STATE_NONE)) {\r
1153                 awake_intvl = 2;\r
1154                 rlbm = 2;\r
1155         }\r
1156 \r
1157         if(padapter->registrypriv.wifi_spec==1)\r
1158         {\r
1159                 awake_intvl = 2;\r
1160                 rlbm = 2;\r
1161         }\r
1162 \r
1163         if (psmode > 0)\r
1164         {\r
1165 #ifdef CONFIG_BT_COEXIST\r
1166                 if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)\r
1167                 {\r
1168                         PowerState = rtw_btcoex_RpwmVal(padapter);\r
1169                         byte5 = rtw_btcoex_LpsVal(padapter);\r
1170 \r
1171                         if ((rlbm == 2) && (byte5 & BIT(4)))\r
1172                         {\r
1173                                 // Keep awake interval to 1 to prevent from\r
1174                                 // decreasing coex performance\r
1175                                 awake_intvl = 2;\r
1176                                 rlbm = 2;\r
1177                         }\r
1178                 }\r
1179                 else\r
1180 #endif // CONFIG_BT_COEXIST\r
1181                 {\r
1182                         PowerState = 0x00;// AllON(0x0C), RFON(0x04), RFOFF(0x00)\r
1183                         byte5 = 0x40;\r
1184                 }\r
1185         }\r
1186         else\r
1187         {\r
1188                 PowerState = 0x0C;// AllON(0x0C), RFON(0x04), RFOFF(0x00)\r
1189                 byte5 = 0x40;\r
1190         }\r
1191 \r
1192         SET_8723B_H2CCMD_PWRMODE_PARM_MODE(u1H2CPwrModeParm, (psmode>0)?1:0);\r
1193         SET_8723B_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CPwrModeParm, pwrpriv->smart_ps);\r
1194         SET_8723B_H2CCMD_PWRMODE_PARM_RLBM(u1H2CPwrModeParm, rlbm);\r
1195         SET_8723B_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CPwrModeParm, awake_intvl);\r
1196         SET_8723B_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CPwrModeParm, padapter->registrypriv.uapsd_enable);\r
1197         SET_8723B_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CPwrModeParm, PowerState);\r
1198         SET_8723B_H2CCMD_PWRMODE_PARM_BYTE5(u1H2CPwrModeParm, byte5);\r
1199 #ifdef CONFIG_LPS_LCLK\r
1200         if(psmode != PS_MODE_ACTIVE)\r
1201         {\r
1202                 if(pmlmeext ->adaptive_tsf_done == _FALSE && pmlmeext->bcn_cnt>0)\r
1203                 {\r
1204                         u8 ratio_20_delay, ratio_80_delay;\r
1205 \r
1206                         //byte 6 for adaptive_early_32k\r
1207                         //[0:3] = DrvBcnEarly  (ms) , [4:7] = DrvBcnTimeOut  (ms)\r
1208                         // 20% for DrvBcnEarly, 80% for DrvBcnTimeOut\r
1209                         ratio_20_delay = 0;\r
1210                         ratio_80_delay = 0;\r
1211                         pmlmeext->DrvBcnEarly = 0xff;\r
1212                         pmlmeext->DrvBcnTimeOut = 0xff;\r
1213 \r
1214                         DBG_871X("%s(): bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt);\r
1215 \r
1216                         for(i=0; i<9; i++)\r
1217                         {\r
1218                                 pmlmeext->bcn_delay_ratio[i] = (pmlmeext->bcn_delay_cnt[i] * 100) /pmlmeext->bcn_cnt;\r
1219 \r
1220                                 DBG_871X("%s(): bcn_delay_cnt[%d]=%d, bcn_delay_ratio[%d] = %d\n", __func__, i, pmlmeext->bcn_delay_cnt[i]\r
1221                                         ,i ,pmlmeext->bcn_delay_ratio[i]);\r
1222         \r
1223                                 ratio_20_delay += pmlmeext->bcn_delay_ratio[i];\r
1224                                 ratio_80_delay += pmlmeext->bcn_delay_ratio[i];\r
1225 \r
1226                                 if(ratio_20_delay > 20 && pmlmeext->DrvBcnEarly == 0xff)\r
1227                                 {\r
1228                                         pmlmeext->DrvBcnEarly = i;\r
1229                                         DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly);\r
1230                                 }       \r
1231 \r
1232                                 if(ratio_80_delay > 80 && pmlmeext->DrvBcnTimeOut == 0xff)\r
1233                                 {\r
1234                                         pmlmeext->DrvBcnTimeOut = i;\r
1235                                         DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut);\r
1236                                 }\r
1237 \r
1238                                 //reset adaptive_early_32k cnt\r
1239                                 pmlmeext->bcn_delay_cnt[i] = 0;\r
1240                                 pmlmeext->bcn_delay_ratio[i] = 0;\r
1241                         \r
1242                         }\r
1243 \r
1244                         pmlmeext->bcn_cnt = 0;\r
1245                         pmlmeext ->adaptive_tsf_done = _TRUE;\r
1246 \r
1247                 }\r
1248                 else\r
1249                 {\r
1250                         DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly);\r
1251                         DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut);\r
1252                 }\r
1253 \r
1254 /* offload to FW if fw version > v15.10\r
1255                 pmlmeext->DrvBcnEarly=0;\r
1256                 pmlmeext->DrvBcnTimeOut=7;\r
1257 \r
1258                 if((pmlmeext->DrvBcnEarly!=0Xff) && (pmlmeext->DrvBcnTimeOut!=0xff))\r
1259                         u1H2CPwrModeParm[H2C_PWRMODE_LEN-1] = BIT(0) | ((pmlmeext->DrvBcnEarly<<1)&0x0E) |((pmlmeext->DrvBcnTimeOut<<4)&0xf0) ;\r
1260 */\r
1261 \r
1262         }\r
1263 #endif\r
1264 \r
1265 #ifdef CONFIG_BT_COEXIST\r
1266         rtw_btcoex_RecordPwrMode(padapter, u1H2CPwrModeParm, H2C_PWRMODE_LEN);\r
1267 #endif // CONFIG_BT_COEXIST\r
1268 \r
1269         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPwrModeParm:", u1H2CPwrModeParm, H2C_PWRMODE_LEN);\r
1270 \r
1271         FillH2CCmd8723B(padapter, H2C_8723B_SET_PWR_MODE, H2C_PWRMODE_LEN, u1H2CPwrModeParm);\r
1272 _func_exit_;\r
1273 }\r
1274 \r
1275 void rtl8723b_set_FwPsTuneParam_cmd(PADAPTER padapter)\r
1276 {\r
1277         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);\r
1278         u8 u1H2CPsTuneParm[H2C_PSTUNEPARAM_LEN]={0};\r
1279         u8 bcn_to_limit = 10; //10 * 100 * awakeinterval (ms)\r
1280         u8 dtim_timeout = 5; //ms //wait broadcast data timer\r
1281         u8 ps_timeout = 20;  //ms //Keep awake when tx\r
1282         u8 dtim_period = 3; \r
1283 \r
1284 _func_enter_;\r
1285         //DBG_871X("%s(): FW LPS mode = %d\n", __func__, psmode);\r
1286 \r
1287         SET_8723B_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(u1H2CPsTuneParm, bcn_to_limit);\r
1288         SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(u1H2CPsTuneParm, dtim_timeout);\r
1289         SET_8723B_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(u1H2CPsTuneParm, ps_timeout);\r
1290         SET_8723B_H2CCMD_PSTUNE_PARM_ADOPT(u1H2CPsTuneParm, 1);\r
1291         SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(u1H2CPsTuneParm, dtim_period);\r
1292 \r
1293         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPsTuneParm:", u1H2CPsTuneParm, H2C_PSTUNEPARAM_LEN);\r
1294 \r
1295         FillH2CCmd8723B(padapter, H2C_8723B_PS_TUNING_PARA, H2C_PSTUNEPARAM_LEN, u1H2CPsTuneParm);\r
1296 _func_exit_;\r
1297 }\r
1298 \r
1299 void rtl8723b_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param)\r
1300 {\r
1301         u8 u1H2CBtMpOperParm[H2C_BTMP_OPER_LEN]={0};\r
1302 \r
1303 _func_enter_;\r
1304 \r
1305         DBG_8192C("%s: idx=%d ver=%d reqnum=%d param1=0x%02x param2=0x%02x\n", __FUNCTION__, idx, ver, reqnum, param[0], param[1]);\r
1306 \r
1307         SET_8723B_H2CCMD_BT_MPOPER_VER(u1H2CBtMpOperParm, ver);\r
1308         SET_8723B_H2CCMD_BT_MPOPER_REQNUM(u1H2CBtMpOperParm, reqnum);\r
1309         SET_8723B_H2CCMD_BT_MPOPER_IDX(u1H2CBtMpOperParm, idx);\r
1310         SET_8723B_H2CCMD_BT_MPOPER_PARAM1(u1H2CBtMpOperParm, param[0]);\r
1311         SET_8723B_H2CCMD_BT_MPOPER_PARAM2(u1H2CBtMpOperParm, param[1]);\r
1312 \r
1313         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CBtMpOperParm:", u1H2CBtMpOperParm, H2C_BTMP_OPER_LEN);\r
1314 \r
1315         FillH2CCmd8723B(padapter, H2C_8723B_BT_MP_OPER, H2C_BTMP_OPER_LEN, u1H2CBtMpOperParm);\r
1316 _func_exit_;\r
1317 }\r
1318 \r
1319 void rtl8723b_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param)\r
1320 {\r
1321         //u8 cmd_param; //BIT0:enable, BIT1:NoConnect32k\r
1322 \r
1323         DBG_871X("%s()\n", __func__);\r
1324 \r
1325         cmd_param = cmd_param;\r
1326 \r
1327         FillH2CCmd8723B(padapter, H2C_8723B_FWLPS_IN_IPS_, 1, &cmd_param);\r
1328 \r
1329 }\r
1330 \r
1331 #ifdef CONFIG_WOWLAN\r
1332 static void rtl8723b_set_FwWoWlanCtrl_Cmd(PADAPTER padapter, u8 bFuncEn)\r
1333 {\r
1334         struct security_priv *psecpriv = &padapter->securitypriv;\r
1335         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);\r
1336         u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN]={0};\r
1337         u8 discont_wake = 1, gpionum = 0, gpio_dur = 0, hw_unicast = 0, gpio_pulse_cnt=100;\r
1338         u8 sdio_wakeup_enable = 1;\r
1339         u8 gpio_high_active = 0; //0: low active, 1: high active\r
1340         u8 magic_pkt = 0;\r
1341         \r
1342 #ifdef CONFIG_GPIO_WAKEUP\r
1343         gpionum = WAKEUP_GPIO_IDX;\r
1344         sdio_wakeup_enable = 0;\r
1345 #endif\r
1346 \r
1347 #ifdef CONFIG_PNO_SUPPORT\r
1348         if (!ppwrpriv->wowlan_pno_enable) {\r
1349                 magic_pkt = 1;\r
1350         }\r
1351 #endif\r
1352 \r
1353         if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_)\r
1354                 hw_unicast = 1;\r
1355 \r
1356         DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn);\r
1357 \r
1358         SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, bFuncEn);\r
1359         SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, 0);\r
1360         SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);\r
1361         SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);\r
1362         SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);\r
1363         SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);\r
1364         SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake); \r
1365         SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);\r
1366         SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);\r
1367         SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);\r
1368         //SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, 1);\r
1369         SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, 0x09);\r
1370         \r
1371         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CWoWlanCtrlParm:", u1H2CWoWlanCtrlParm, H2C_WOWLAN_LEN);\r
1372 \r
1373         FillH2CCmd8723B(padapter, H2C_8723B_WOWLAN, H2C_WOWLAN_LEN, u1H2CWoWlanCtrlParm);\r
1374 }\r
1375 \r
1376 static void rtl8723b_set_FwRemoteWakeCtrl_Cmd(PADAPTER padapter, u8 benable)\r
1377 {\r
1378         u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN]={0};\r
1379         struct security_priv* psecuritypriv=&(padapter->securitypriv);\r
1380         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);\r
1381         u8 res = 0, count = 0;\r
1382 \r
1383         DBG_871X("%s(): Enable=%d\n", __func__, benable);\r
1384 \r
1385 #ifdef CONFIG_PNO_SUPPORT\r
1386         SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(u1H2CRemoteWakeCtrlParm, benable);\r
1387         SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, benable);\r
1388 #endif\r
1389 \r
1390         if (!ppwrpriv->wowlan_pno_enable) {\r
1391         SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(u1H2CRemoteWakeCtrlParm, benable);\r
1392         SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 1);\r
1393 #ifdef CONFIG_GTK_OL\r
1394         if(psecuritypriv->binstallKCK_KEK == _TRUE && psecuritypriv->dot11PrivacyAlgrthm == _AES_)\r
1395         {\r
1396                 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 1);\r
1397         }\r
1398         else\r
1399         {\r
1400                 DBG_871X("no kck or security is not AES\n");\r
1401                 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 0);\r
1402         }\r
1403 #endif //CONFIG_GTK_OL\r
1404 \r
1405         SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(u1H2CRemoteWakeCtrlParm, 1);\r
1406 \r
1407                 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) || (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_))\r
1408                 {\r
1409                         SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(u1H2CRemoteWakeCtrlParm, 0);\r
1410                 }\r
1411                 else\r
1412                 {\r
1413                         SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(u1H2CRemoteWakeCtrlParm, 1);\r
1414                 }\r
1415         }\r
1416 exit:\r
1417         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CRemoteWakeCtrlParm:", u1H2CRemoteWakeCtrlParm, H2C_REMOTE_WAKE_CTRL_LEN);\r
1418         FillH2CCmd8723B(padapter, H2C_8723B_REMOTE_WAKE_CTRL,\r
1419                 H2C_REMOTE_WAKE_CTRL_LEN, u1H2CRemoteWakeCtrlParm);\r
1420 #ifdef CONFIG_PNO_SUPPORT\r
1421         if (ppwrpriv->wowlan_pno_enable && ppwrpriv->pno_in_resume == _FALSE) {\r
1422                 res = rtw_read8(padapter, REG_PNO_STATUS);\r
1423                 DBG_871X("cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", res);\r
1424                 while(!(res&BIT(7)) && count < 25) {\r
1425                         DBG_871X("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", count, res);\r
1426                         res = rtw_read8(padapter, REG_PNO_STATUS);\r
1427                         count++;\r
1428                         rtw_msleep_os(2);\r
1429                 }\r
1430                 DBG_871X("cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", res);\r
1431         }\r
1432 #endif //CONFIG_PNO_SUPPORT\r
1433 }\r
1434 \r
1435 static void rtl8723b_set_FwAOACGlobalInfo_Cmd(PADAPTER padapter,  u8 group_alg, u8 pairwise_alg)\r
1436 {\r
1437         u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN]={0};\r
1438 \r
1439         DBG_871X("%s(): group_alg=%d pairwise_alg=%d\n", __func__, group_alg, pairwise_alg);\r
1440 \r
1441         SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm, pairwise_alg);\r
1442         SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm, group_alg);\r
1443         \r
1444         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CAOACGlobalInfoParm:", u1H2CAOACGlobalInfoParm, H2C_AOAC_GLOBAL_INFO_LEN);\r
1445 \r
1446         FillH2CCmd8723B(padapter, H2C_8723B_AOAC_GLOBAL_INFO, H2C_AOAC_GLOBAL_INFO_LEN, u1H2CAOACGlobalInfoParm);\r
1447 }\r
1448 \r
1449 #ifdef CONFIG_PNO_SUPPORT\r
1450 static void rtl8723b_set_FwScanOffloadInfo_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc, u8 enable)\r
1451 {\r
1452         u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN]={0};\r
1453         u8 res = 0, count = 0;\r
1454         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);\r
1455 \r
1456         DBG_871X("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n", \r
1457                 __func__, rsvdpageloc->LocProbePacket, rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);\r
1458 \r
1459         SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);\r
1460         SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm, rsvdpageloc->LocScanInfo);\r
1461         SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm, rsvdpageloc->LocProbePacket);\r
1462         SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm, rsvdpageloc->LocSSIDInfo);\r
1463 \r
1464         RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CScanOffloadInfoParm:", u1H2CScanOffloadInfoParm, H2C_SCAN_OFFLOAD_CTRL_LEN);\r
1465         FillH2CCmd8723B(padapter, H2C_8723B_D0_SCAN_OFFLOAD_INFO, H2C_SCAN_OFFLOAD_CTRL_LEN, u1H2CScanOffloadInfoParm);\r
1466 \r
1467         if (pwrpriv->pno_in_resume == _FALSE) {\r
1468                 res = rtw_read8(padapter, 0x1b9);\r
1469                 while( res == 0 && count < 25) {\r
1470                         DBG_871X("[%d] 0x1b9 0x%02x\n", count, res);\r
1471                         res = rtw_read8(padapter, 0x1b9);\r
1472                         DBG_871X("[%d] 0x1c4: 0x%08x 0x1cc:0x%08x\n",\r
1473                                 count, rtw_read32(padapter, 0x1c4), rtw_read32(padapter, 0x1cc));\r
1474                         rtw_msleep_os(2);\r
1475                         count++;\r
1476                 }\r
1477                 count = 0;\r
1478                 res = rtw_read8(padapter, 0x1b9);\r
1479                 while( res != 0x77 && count < 50) {\r
1480                         DBG_871X("[%d] 0x1b9 0x%02x\n", count, res);\r
1481                         res = rtw_read8(padapter, 0x1b9);\r
1482                         DBG_871X("[%d] 0x1c4: 0x%08x 0x1cc:0x%08x\n",\r
1483                                 count, rtw_read32(padapter, 0x1c4), rtw_read32(padapter, 0x1cc));\r
1484                         rtw_msleep_os(2);\r
1485                         count++;\r
1486                 }\r
1487                 DBG_871X("0x1b9: 0x%02x\n", res);\r
1488         }\r
1489 }\r
1490 #endif //CONFIG_PNO_SUPPORT\r
1491 \r
1492 #if 0\r
1493 void dump_TX_FIFO(_adapter* padapter){\r
1494         int i;\r
1495         u8 val = 0 ;\r
1496         u8 base = 0;\r
1497         u32 addr = 0;\r
1498 \r
1499         DBG_871X("+%s+\n", __func__);\r
1500         val = rtw_read8(padapter, 0x106);\r
1501         rtw_write8(padapter, 0x106, 0x69);\r
1502         DBG_871X("0x106: 0x%02x\n", val);\r
1503         base = rtw_read8(padapter, 0x209);\r
1504         DBG_871X("0x209: 0x%02x\n", base);\r
1505 \r
1506         DBG_871X("beacon:\n");\r
1507         addr = ((base)*128)/8;\r
1508         for (i = 0 ; i < 32 ; i+=2) {\r
1509                 rtw_write32(padapter, 0x140, addr + i);\r
1510                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1511                 rtw_write32(padapter, 0x140, addr + i + 1);\r
1512                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1513         }\r
1514 \r
1515         DBG_871X("probe_response:\n");\r
1516         addr = ((base + 2)*128)/8;\r
1517         for (i = 0 ; i < 48 ; i+=2) {\r
1518                 rtw_write32(padapter, 0x140, addr + i);\r
1519                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1520                 rtw_write32(padapter, 0x140, addr + i + 1);\r
1521                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1522         }\r
1523 #if 0\r
1524         DBG_871X("GTK Info:\n");\r
1525         addr = ((base + 8)*128)/8;\r
1526         for (i = 0 ; i < 4 ; i+=2) {\r
1527                 rtw_write32(padapter, 0x140, addr + i);\r
1528                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1529                 rtw_write32(padapter, 0x140, addr + i + 1);\r
1530                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1531         }\r
1532 \r
1533         DBG_871X("GTK Rsp:\n");\r
1534         addr = ((base + 9)*128)/8;\r
1535         for (i = 0 ; i < 32 ; i+=2) {\r
1536                 rtw_write32(padapter, 0x140, addr + i);\r
1537                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1538                 rtw_write32(padapter, 0x140, addr + i + 1);\r
1539                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1540         }\r
1541 #endif\r
1542 #if 0\r
1543         DBG_871X("probe request:\n");\r
1544         addr = ((base + 6)*128)/8;\r
1545         for (i = 0 ; i < 16 ; i+=2) {\r
1546                 rtw_write32(padapter, 0x140, addr + i);\r
1547                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1548                 rtw_write32(padapter, 0x140, addr + i + 1);\r
1549                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1550         }\r
1551 \r
1552         DBG_871X("PNO_INFO:\n");\r
1553         addr = ((base + 7)*128)/8;\r
1554         for (i = 0 ; i < 16 ; i+=2) {\r
1555                 rtw_write32(padapter, 0x140, addr + i);\r
1556                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1557                 rtw_write32(padapter, 0x140, addr + i + 1);\r
1558                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1559         }\r
1560 \r
1561         DBG_871X("SSID_INFO:\n");\r
1562         addr = ((base + 8)*128)/8;\r
1563         for (i = 0 ; i < 16 ; i+=2) {\r
1564                 rtw_write32(padapter, 0x140, addr + i);\r
1565                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1566                 rtw_write32(padapter, 0x140, addr + i + 1);\r
1567                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1568         }\r
1569 \r
1570         DBG_871X("SCAN_INFO:\n");\r
1571         addr = ((base + 9)*128)/8;\r
1572         for (i = 0 ; i < 16 ; i+=2) {\r
1573                 rtw_write32(padapter, 0x140, addr + i);\r
1574                 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1575                 rtw_write32(padapter, 0x140, addr + i + 1);\r
1576                 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));\r
1577         }\r
1578 #endif\r
1579         rtw_write8(padapter, 0x106, val);\r
1580         DBG_871X("-%s-\n", __func__);\r
1581 }\r
1582 #endif\r
1583 \r
1584 static void rtl8723b_set_FwWoWlanRelated_cmd(_adapter* padapter, u8 enable)\r
1585 {\r
1586         struct security_priv *psecpriv = &padapter->securitypriv;\r
1587         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);\r
1588         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;\r
1589         struct sta_info *psta = NULL;\r
1590         u8      pkt_type = 0;\r
1591         \r
1592         DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable);\r
1593 _func_enter_;\r
1594         if(enable)\r
1595         {\r
1596                 rtl8723b_set_FwAOACGlobalInfo_Cmd(padapter, psecpriv->dot118021XGrpPrivacy, psecpriv->dot11PrivacyAlgrthm);\r
1597 \r
1598                 rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT);      //RT_MEDIA_CONNECT will confuse in the future\r
1599 \r
1600                 if(!(ppwrpriv->wowlan_pno_enable))\r
1601                 {\r
1602                         psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(pmlmepriv));\r
1603                         if (psta != NULL)\r
1604                                 rtl8723b_set_FwMediaStatusRpt_cmd(padapter, RT_MEDIA_CONNECT, psta->mac_id);\r
1605                 }       \r
1606                 else\r
1607                         DBG_871X("%s(): Disconnected, no FwMediaStatusRpt CONNECT\n",__FUNCTION__);\r
1608 \r
1609                 rtw_msleep_os(2);\r
1610 \r
1611                 if(!(ppwrpriv->wowlan_pno_enable)) {\r
1612                 rtl8723b_set_FwDisconDecision_cmd(padapter, enable);\r
1613                 rtw_msleep_os(2);\r
1614                 \r
1615                         if ((psecpriv->dot11PrivacyAlgrthm != _WEP40_) || (psecpriv->dot11PrivacyAlgrthm != _WEP104_))\r
1616                                 pkt_type = 1;\r
1617                         rtl8723b_set_FwKeepAlive_cmd(padapter, enable, pkt_type);\r
1618                 rtw_msleep_os(2);\r
1619                 }\r
1620 \r
1621                 rtl8723b_set_FwWoWlanCtrl_Cmd(padapter, enable);\r
1622                 rtw_msleep_os(2);\r
1623 \r
1624                 rtl8723b_set_FwRemoteWakeCtrl_Cmd(padapter, enable);\r
1625         }\r
1626         else\r
1627         {\r
1628 #if 0\r
1629                 dump_TX_FIFO(padapter);\r
1630 #endif\r
1631                 rtl8723b_set_FwRemoteWakeCtrl_Cmd(padapter, enable);\r
1632                 rtw_msleep_os(2);                       \r
1633                 rtl8723b_set_FwWoWlanCtrl_Cmd(padapter, enable);\r
1634         }\r
1635         \r
1636 _func_exit_;\r
1637         DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);\r
1638         return ;\r
1639 }\r
1640 \r
1641 void rtl8723b_set_wowlan_cmd(_adapter* padapter, u8 enable)\r
1642 {\r
1643         rtl8723b_set_FwWoWlanRelated_cmd(padapter, enable);\r
1644 }\r
1645 #endif //CONFIG_WOWLAN\r
1646 \r
1647 #ifdef CONFIG_AP_WOWLAN\r
1648 static void rtl8723b_set_FwAPWoWlanCtrl_Cmd(PADAPTER padapter, u8 bFuncEn)\r
1649 {\r
1650         u8 u1H2CAPWoWlanCtrlParm[H2C_WOWLAN_LEN]={0};\r
1651         u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;\r
1652         u8 gpio_high_active = 1; //0: low active, 1: high active\r
1653         u8 gpio_pulse = bFuncEn;\r
1654 #ifdef CONFIG_GPIO_WAKEUP\r
1655         gpionum = WAKEUP_GPIO_IDX;\r
1656 #endif\r
1657 \r
1658         DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn);\r
1659 \r
1660         if (bFuncEn)\r
1661                 gpio_dur = 16;\r
1662         else\r
1663                 gpio_dur = 0;\r
1664 \r
1665         SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,\r
1666                         gpionum);\r
1667         SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,\r
1668                         gpio_pulse);\r
1669         SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,\r
1670                         gpio_high_active);\r
1671         SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,\r
1672                         bFuncEn);\r
1673         SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,\r
1674                         gpio_dur);\r
1675 \r
1676         FillH2CCmd8723B(padapter, H2C_8723B_AP_WOW_GPIO_CTRL,\r
1677                         H2C_AP_WOW_GPIO_CTRL_LEN, u1H2CAPWoWlanCtrlParm);\r
1678 }\r
1679 \r
1680 static void rtl8723b_set_Fw_AP_Offload_Cmd(PADAPTER padapter, u8 bFuncEn)\r
1681 {\r
1682         u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN]={0};\r
1683 \r
1684         DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn);\r
1685 \r
1686         SET_8723B_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, bFuncEn);\r
1687 \r
1688         FillH2CCmd8723B(padapter, H2C_8723B_AP_OFFLOAD,\r
1689                         H2C_AP_OFFLOAD_LEN, u1H2CAPOffloadCtrlParm);\r
1690 }\r
1691 \r
1692 static void rtl8723b_set_AP_FwWoWlan_cmd(_adapter* padapter, u8 enable)\r
1693 {\r
1694         struct security_priv *psecpriv = &padapter->securitypriv;\r
1695         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);\r
1696         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;\r
1697         struct sta_info *psta = NULL;\r
1698         u8      pkt_type = 0;\r
1699 \r
1700         DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable);\r
1701 _func_enter_;\r
1702         if (enable) {\r
1703                 rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT);\r
1704                 issue_beacon(padapter, 0);\r
1705         }\r
1706 #if 0\r
1707         else\r
1708 \r
1709                 dump_TX_FIFO(padapter);\r
1710 #endif\r
1711         rtl8723b_set_FwAPWoWlanCtrl_Cmd(padapter, enable);\r
1712         rtw_msleep_os(10);\r
1713         rtl8723b_set_Fw_AP_Offload_Cmd(padapter, enable);\r
1714         rtw_msleep_os(10);\r
1715 _func_exit_;\r
1716         DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);\r
1717         return ;\r
1718 }\r
1719 \r
1720 void rtl8723b_set_ap_wowlan_cmd(_adapter* padapter, u8 enable)\r
1721 {\r
1722         rtl8723b_set_AP_FwWoWlan_cmd(padapter, enable);\r
1723 }\r
1724 #endif //CONFIG_AP_WOWLAN\r
1725 \r
1726 static s32 rtl8723b_set_FwLowPwrLps_cmd(PADAPTER padapter, u8 enable)\r
1727 {\r
1728         //TODO\r
1729         return _FALSE;  \r
1730 }\r
1731 \r
1732 //\r
1733 // Description: Fill the reserved packets that FW will use to RSVD page.\r
1734 //                      Now we just send 4 types packet to rsvd page.\r
1735 //                      (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.\r
1736 //      Input:\r
1737 //          bDLFinished - FALSE: At the first time we will send all the packets as a large packet to Hw,\r
1738 //                                              so we need to set the packet length to total lengh.\r
1739 //                            TRUE: At the second time, we should send the first packet (default:beacon)\r
1740 //                                              to Hw again and set the lengh in descriptor to the real beacon lengh.\r
1741 // 2009.10.15 by tynli.\r
1742 static void rtl8723b_set_FwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished)\r
1743 {\r
1744         PHAL_DATA_TYPE pHalData;\r
1745         struct xmit_frame       *pcmdframe;     \r
1746         struct pkt_attrib       *pattrib;\r
1747         struct xmit_priv        *pxmitpriv;\r
1748         struct mlme_ext_priv    *pmlmeext;\r
1749         struct mlme_ext_info    *pmlmeinfo;\r
1750         struct pwrctrl_priv *pwrctl;\r
1751         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;\r
1752         u32     BeaconLength=0, ProbeRspLength=0, PSPollLength=0;\r
1753         u32     NullDataLength=0, QosNullLength=0, BTQosNullLength=0;\r
1754         u32     ProbeReqLength=0;\r
1755         u8      *ReservedPagePacket;\r
1756         u8      TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;\r
1757         u8      TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;\r
1758         u16     BufIndex, PageSize = 128;\r
1759         u32     TotalPacketLen, MaxRsvdPageBufSize=0;\r
1760         RSVDPAGE_LOC    RsvdPageLoc;\r
1761 #ifdef CONFIG_WOWLAN    \r
1762         u32     ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0;\r
1763         u32     SSIDLegnth = 0;\r
1764         struct security_priv *psecuritypriv = &padapter->securitypriv; //added by xx\r
1765         u8 currentip[4];\r
1766         u8 cur_dot11txpn[8];\r
1767 #ifdef CONFIG_GTK_OL\r
1768         struct sta_priv *pstapriv = &padapter->stapriv;\r
1769         struct sta_info * psta;\r
1770         u8 kek[RTW_KEK_LEN];\r
1771         u8 kck[RTW_KCK_LEN];\r
1772 #endif\r
1773 #endif\r
1774 #ifdef DBG_CONFIG_ERROR_DETECT\r
1775         struct sreset_priv *psrtpriv;\r
1776 #endif // DBG_CONFIG_ERROR_DETECT\r
1777 \r
1778         //DBG_871X("%s---->\n", __FUNCTION__);\r
1779 \r
1780         pHalData = GET_HAL_DATA(padapter);\r
1781 #ifdef DBG_CONFIG_ERROR_DETECT\r
1782         psrtpriv = &pHalData->srestpriv;\r
1783 #endif\r
1784         pxmitpriv = &padapter->xmitpriv;\r
1785         pmlmeext = &padapter->mlmeextpriv;\r
1786         pmlmeinfo = &pmlmeext->mlmext_info;\r
1787         pwrctl = adapter_to_pwrctl(padapter);\r
1788 \r
1789         RsvdPageNum = BCNQ_PAGE_NUM_8723B + WOWLAN_PAGE_NUM_8723B;\r
1790         MaxRsvdPageBufSize = RsvdPageNum*PageSize;\r
1791 \r
1792         pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);\r
1793         if (pcmdframe == NULL) {\r
1794                 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);\r
1795                 return;\r
1796         }\r
1797 \r
1798         ReservedPagePacket = pcmdframe->buf_addr;\r
1799         _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));\r
1800 \r
1801         //3 (1) beacon\r
1802         BufIndex = TxDescOffset;\r
1803         ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);\r
1804 \r
1805         // When we count the first page size, we need to reserve description size for the RSVD\r
1806         // packet, it will be filled in front of the packet in TXPKTBUF.\r
1807         CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);\r
1808         //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware\r
1809         if (CurtPktPageNum == 1)\r
1810         {\r
1811                 CurtPktPageNum += 1;\r
1812         }\r
1813         TotalPageNum += CurtPktPageNum;\r
1814 \r
1815         BufIndex += (CurtPktPageNum*PageSize);\r
1816 \r
1817         //3 (2) ps-poll\r
1818         RsvdPageLoc.LocPsPoll = TotalPageNum;\r
1819         ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength);\r
1820         rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE, _FALSE, _FALSE);\r
1821 \r
1822         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PS-POLL %p %d\n", \r
1823         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (PSPollLength+TxDescLen));\r
1824 \r
1825         CurtPktPageNum = (u8)PageNum_128(TxDescLen + PSPollLength);\r
1826 \r
1827         TotalPageNum += CurtPktPageNum;\r
1828 \r
1829         BufIndex += (CurtPktPageNum*PageSize);\r
1830 \r
1831         //3 (3) null data\r
1832         RsvdPageLoc.LocNullData = TotalPageNum;\r
1833         ConstructNullFunctionData(\r
1834                 padapter,\r
1835                 &ReservedPagePacket[BufIndex],\r
1836                 &NullDataLength,\r
1837                 get_my_bssid(&pmlmeinfo->network),\r
1838                 _FALSE, 0, 0, _FALSE);\r
1839         rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, _FALSE, _FALSE, _FALSE);\r
1840 \r
1841         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: NULL DATA %p %d\n", \r
1842         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (NullDataLength+TxDescLen));\r
1843 \r
1844         CurtPktPageNum = (u8)PageNum_128(TxDescLen + NullDataLength);\r
1845 \r
1846         TotalPageNum += CurtPktPageNum;\r
1847 \r
1848         BufIndex += (CurtPktPageNum*PageSize);\r
1849 \r
1850 #if 0\r
1851         //3 (4) probe response\r
1852         RsvdPageLoc.LocProbeRsp = TotalPageNum;\r
1853         ConstructProbeRsp(\r
1854                 padapter,\r
1855                 &ReservedPagePacket[BufIndex],\r
1856                 &ProbeRspLength,\r
1857                 get_my_bssid(&pmlmeinfo->network),\r
1858                 _FALSE);\r
1859         rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE, _FALSE, _FALSE);\r
1860 \r
1861         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n", \r
1862         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (ProbeRspLength+TxDescLen));\r
1863 \r
1864         CurtPktPageNum = (u8)PageNum_128(TxDescLen + ProbeRspLength);\r
1865 \r
1866         TotalPageNum += CurtPktPageNum;\r
1867 \r
1868         BufIndex += (CurtPktPageNum*PageSize);\r
1869 #endif\r
1870 \r
1871         //3 (5) Qos null data\r
1872         RsvdPageLoc.LocQosNull = TotalPageNum;\r
1873         ConstructNullFunctionData(\r
1874                 padapter,\r
1875                 &ReservedPagePacket[BufIndex],\r
1876                 &QosNullLength,\r
1877                 get_my_bssid(&pmlmeinfo->network),\r
1878                 _TRUE, 0, 0, _FALSE);\r
1879         rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, _FALSE, _FALSE, _FALSE);\r
1880 \r
1881         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n", \r
1882         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (QosNullLength+TxDescLen));\r
1883 \r
1884         CurtPktPageNum = (u8)PageNum_128(TxDescLen + QosNullLength);\r
1885 \r
1886         TotalPageNum += CurtPktPageNum;\r
1887 \r
1888         BufIndex += (CurtPktPageNum*PageSize);\r
1889 \r
1890         //3 (6) BT Qos null data\r
1891         RsvdPageLoc.LocBTQosNull = TotalPageNum;\r
1892         ConstructNullFunctionData(\r
1893                 padapter,\r
1894                 &ReservedPagePacket[BufIndex],\r
1895                 &BTQosNullLength,\r
1896                 get_my_bssid(&pmlmeinfo->network),\r
1897                 _TRUE, 0, 0, _FALSE);\r
1898         rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);\r
1899 \r
1900         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: BT QOS NULL DATA %p %d\n", \r
1901         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (BTQosNullLength+TxDescLen));\r
1902 \r
1903         CurtPktPageNum = (u8)PageNum_128(TxDescLen + BTQosNullLength);\r
1904 \r
1905         TotalPageNum += CurtPktPageNum;\r
1906 \r
1907         BufIndex += (CurtPktPageNum*PageSize);\r
1908 \r
1909 #ifdef CONFIG_WOWLAN\r
1910         if (check_fwstate(pmlmepriv, _FW_LINKED)) {\r
1911         //if (pwrctl->wowlan_mode == _TRUE) {\r
1912                 //BufIndex += (CurtPktPageNum*PageSize);\r
1913 \r
1914         //3(7) ARP RSP\r
1915         rtw_get_current_ip_address(padapter, currentip);\r
1916         RsvdPageLoc.LocArpRsp= TotalPageNum;\r
1917 #ifdef DBG_CONFIG_ERROR_DETECT\r
1918         if(psrtpriv->silent_reset_inprogress == _FALSE)\r
1919 #endif //DBG_CONFIG_ERROR_DETECT\r
1920         {\r
1921         ConstructARPResponse(\r
1922                 padapter, \r
1923                 &ReservedPagePacket[BufIndex],\r
1924                 &ARPLegnth,\r
1925                 currentip\r
1926                 );\r
1927         rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ARPLegnth, _FALSE, _FALSE, _TRUE);\r
1928 \r
1929         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: ARP RSP %p %d\n", \r
1930         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (ARPLegnth+TxDescLen));\r
1931 \r
1932         CurtPktPageNum = (u8)PageNum_128(TxDescLen + ARPLegnth);\r
1933         }\r
1934 #ifdef DBG_CONFIG_ERROR_DETECT\r
1935         else\r
1936                 CurtPktPageNum = (u8)PageNum_128(128);\r
1937 #endif //DBG_CONFIG_ERROR_DETECT\r
1938         TotalPageNum += CurtPktPageNum;\r
1939 \r
1940         BufIndex += (CurtPktPageNum*PageSize);\r
1941 \r
1942         //3(8) SEC IV\r
1943         rtw_get_sec_iv(padapter, cur_dot11txpn, get_my_bssid(&pmlmeinfo->network));\r
1944         RsvdPageLoc.LocRemoteCtrlInfo = TotalPageNum;\r
1945         _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, cur_dot11txpn, _AES_IV_LEN_);\r
1946 \r
1947         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: SEC IV %p %d\n", \r
1948         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], _AES_IV_LEN_);\r
1949 \r
1950         CurtPktPageNum = (u8)PageNum_128(_AES_IV_LEN_);\r
1951 \r
1952         TotalPageNum += CurtPktPageNum;\r
1953         \r
1954 #ifdef CONFIG_GTK_OL\r
1955         BufIndex += (CurtPktPageNum*PageSize);\r
1956 \r
1957         //if the ap staion info. exists, get the kek, kck from staion info.\r
1958         psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));\r
1959         if (psta == NULL) \r
1960         {\r
1961                 _rtw_memset(kek, 0, RTW_KEK_LEN);\r
1962                 _rtw_memset(kck, 0, RTW_KCK_LEN);\r
1963                 DBG_8192C("%s, KEK, KCK download rsvd page all zero \n", __func__);\r
1964         }\r
1965         else\r
1966         {\r
1967                 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);\r
1968                 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);\r
1969         }\r
1970         \r
1971         //3(9) KEK, KCK\r
1972         RsvdPageLoc.LocGTKInfo = TotalPageNum;\r
1973         _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, kck, RTW_KCK_LEN);\r
1974         _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+RTW_KCK_LEN, kek, RTW_KEK_LEN);\r
1975         \r
1976 #if 0\r
1977         {\r
1978                 int i;\r
1979                 printk("\ntoFW KCK: ");\r
1980                 for(i=0;i<16; i++)\r
1981                         printk(" %02x ", kck[i]);\r
1982                 printk("\ntoFW KEK: ");\r
1983                 for(i=0;i<16; i++)\r
1984                         printk(" %02x ", kek[i]);\r
1985                 printk("\n");\r
1986         }\r
1987 #endif\r
1988 \r
1989         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n", \r
1990         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN));\r
1991 \r
1992         CurtPktPageNum = (u8)PageNum_128(TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN);\r
1993 \r
1994         TotalPageNum += CurtPktPageNum;\r
1995 \r
1996         BufIndex += (CurtPktPageNum*PageSize);\r
1997 \r
1998         //3(10) GTK Response\r
1999         RsvdPageLoc.LocGTKRsp= TotalPageNum;\r
2000         ConstructGTKResponse(\r
2001                 padapter, \r
2002                 &ReservedPagePacket[BufIndex],\r
2003                 &GTKLegnth\r
2004                 );\r
2005 \r
2006         rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], GTKLegnth, _FALSE, _FALSE, _TRUE);\r
2007 #if 0\r
2008         {\r
2009                 int gj;\r
2010                 printk("123GTK pkt=> \n");\r
2011                 for(gj=0; gj < GTKLegnth+TxDescLen; gj++) {\r
2012                         printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);\r
2013                         if ((gj + 1)%16==0)\r
2014                                 printk("\n");\r
2015                 }\r
2016                 printk(" <=end\n");\r
2017         }\r
2018 #endif\r
2019 \r
2020         //DBG_871X("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n", \r
2021         //      __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (TxDescLen + GTKLegnth));\r
2022 \r
2023         CurtPktPageNum = (u8)PageNum_128(TxDescLen + GTKLegnth);\r
2024 \r
2025         TotalPageNum += CurtPktPageNum;\r
2026 \r
2027         BufIndex += (CurtPktPageNum*PageSize);\r
2028 \r
2029         //below page is empty for GTK extension memory\r
2030         //3(11) GTK EXT MEM\r
2031         RsvdPageLoc.LocGTKEXTMEM= TotalPageNum;\r
2032 \r
2033         CurtPktPageNum = 2;\r
2034 \r
2035         TotalPageNum += CurtPktPageNum;\r
2036 \r
2037         TotalPacketLen = BufIndex-TxDescLen + 256; //extension memory for FW\r
2038 #else\r
2039         TotalPacketLen = BufIndex-TxDescLen + sizeof (union pn48); //IV len\r
2040 #endif //CONFIG_GTK_OL\r
2041         } else\r
2042 #endif //CONFIG_WOWLAN\r
2043         {\r
2044 #ifdef CONFIG_PNO_SUPPORT\r
2045                 if (pwrctl->pno_in_resume == _FALSE) {\r
2046                         //Probe Request\r
2047                         RsvdPageLoc.LocProbePacket = TotalPageNum;\r
2048                         ConstructProbeReq(\r
2049                                 padapter,\r
2050                                 &ReservedPagePacket[BufIndex],\r
2051                                 &ProbeReqLength);\r
2052 \r
2053                         rtl8723b_fill_fake_txdesc(padapter,\r
2054                                 &ReservedPagePacket[BufIndex-TxDescLen],\r
2055                                 ProbeReqLength, _FALSE, _FALSE, _FALSE);\r
2056 #ifdef CONFIG_PNO_SET_DEBUG\r
2057         {\r
2058                         int gj;\r
2059                         printk("probe req pkt=> \n");\r
2060                         for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) {\r
2061                                 printk(" %02x ",ReservedPagePacket[BufIndex- TxDescLen + gj]);\r
2062                                 if ((gj + 1)%8==0)\r
2063                                         printk("\n");\r
2064                         }\r
2065                         printk(" <=end\n");\r
2066         }\r
2067 #endif\r
2068                         CurtPktPageNum =\r
2069                                 (u8)PageNum_128(TxDescLen + ProbeReqLength);\r
2070 \r
2071                         TotalPageNum += CurtPktPageNum;\r
2072 \r
2073                         BufIndex += (CurtPktPageNum*PageSize);\r
2074 \r
2075                         //PNO INFO Page\r
2076                         RsvdPageLoc.LocPNOInfo = TotalPageNum;\r
2077                         ConstructPnoInfo(padapter, &ReservedPagePacket[BufIndex -TxDescLen], &PNOLength);\r
2078 #ifdef CONFIG_PNO_SET_DEBUG\r
2079         {\r
2080                         int gj;\r
2081                         printk("PNO pkt=> \n");\r
2082                         for(gj=0; gj < PNOLength; gj++) {\r
2083                                 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen +gj]);\r
2084                                 if ((gj + 1)%8==0)\r
2085                                         printk("\n");\r
2086                         }\r
2087                         printk(" <=end\n");\r
2088         }\r
2089 #endif\r
2090 \r
2091                         CurtPktPageNum = (u8)PageNum_128(PNOLength);\r
2092                         TotalPageNum += CurtPktPageNum;\r
2093                         BufIndex += (CurtPktPageNum*PageSize);\r
2094 \r
2095                         //SSID List Page\r
2096                         RsvdPageLoc.LocSSIDInfo = TotalPageNum;\r
2097                         ConstructSSIDList(padapter, &ReservedPagePacket[BufIndex-TxDescLen], &SSIDLegnth);\r
2098 #ifdef CONFIG_PNO_SET_DEBUG\r
2099         {\r
2100                         int gj;\r
2101                         printk("SSID list pkt=> \n");\r
2102                         for(gj=0; gj < SSIDLegnth; gj++) {\r
2103                                 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);\r
2104                                 if ((gj + 1)%8==0)\r
2105                                         printk("\n");\r
2106                         }\r
2107                         printk(" <=end\n");\r
2108         }\r
2109 #endif\r
2110                         CurtPktPageNum = (u8)PageNum_128(SSIDLegnth);\r
2111                         TotalPageNum += CurtPktPageNum;\r
2112                         BufIndex += (CurtPktPageNum*PageSize);\r
2113 \r
2114                         //Scan Info Page\r
2115                         RsvdPageLoc.LocScanInfo = TotalPageNum;\r
2116                         ConstructScanInfo(padapter, &ReservedPagePacket[BufIndex-TxDescLen], &ScanInfoLength);\r
2117 #ifdef CONFIG_PNO_SET_DEBUG\r
2118         {\r
2119                         int gj;\r
2120                         printk("Scan info pkt=> \n");\r
2121                         for(gj=0; gj < ScanInfoLength; gj++) {\r
2122                                 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);\r
2123                                 if ((gj + 1)%8==0)\r
2124                                         printk("\n");\r
2125                         }\r
2126                         printk(" <=end\n");\r
2127         }\r
2128 #endif\r
2129                         CurtPktPageNum = (u8)PageNum_128(ScanInfoLength);\r
2130                         TotalPageNum += CurtPktPageNum;\r
2131                         BufIndex += (CurtPktPageNum*PageSize);\r
2132 \r
2133                         TotalPacketLen = BufIndex + ScanInfoLength;\r
2134                 } else {\r
2135                 TotalPacketLen = BufIndex + BTQosNullLength;\r
2136         }\r
2137 #else //CONFIG_PNO_SUPPORT\r
2138                 TotalPacketLen = BufIndex + BTQosNullLength;\r
2139 #endif\r
2140         }\r
2141 \r
2142         if(TotalPacketLen > MaxRsvdPageBufSize)\r
2143         {\r
2144                 DBG_871X("%s(): ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",__FUNCTION__,\r
2145                         TotalPacketLen,MaxRsvdPageBufSize);\r
2146                 goto error;\r
2147         }\r
2148         else\r
2149         {\r
2150                 // update attribute\r
2151                 pattrib = &pcmdframe->attrib;\r
2152                 update_mgntframe_attrib(padapter, pattrib);\r
2153                 pattrib->qsel = 0x10;\r
2154                 pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;\r
2155 #ifdef CONFIG_PCI_HCI\r
2156                 dump_mgntframe(padapter, pcmdframe);\r
2157 #else\r
2158                 dump_mgntframe_and_wait(padapter, pcmdframe, 100);\r
2159 #endif\r
2160         }\r
2161 \r
2162         DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", __FUNCTION__,TotalPacketLen,TotalPageNum);\r
2163         if(check_fwstate(pmlmepriv, _FW_LINKED)) {\r
2164         rtl8723b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);\r
2165                 rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);\r
2166         } else {\r
2167                 rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);\r
2168 #ifdef CONFIG_PNO_SUPPORT\r
2169                 if(pwrctl->pno_in_resume)\r
2170                         rtl8723b_set_FwScanOffloadInfo_cmd(padapter,\r
2171                                         &RsvdPageLoc, 0);\r
2172                 else\r
2173                         rtl8723b_set_FwScanOffloadInfo_cmd(padapter,\r
2174                                         &RsvdPageLoc, 1);\r
2175 #endif\r
2176         }\r
2177         return;\r
2178 \r
2179 error:\r
2180 \r
2181         rtw_free_xmitframe(pxmitpriv, pcmdframe);\r
2182 }\r
2183 \r
2184 #ifdef CONFIG_AP_WOWLAN\r
2185 //\r
2186 //Description: Fill the reserved packets that FW will use to RSVD page.\r
2187 //Now we just send 2 types packet to rsvd page. (1)Beacon, (2)ProbeRsp.\r
2188 //\r
2189 //Input: bDLFinished    \r
2190 //\r
2191 //FALSE: At the first time we will send all the packets as a large packet to Hw,\r
2192 //       so we need to set the packet length to total lengh.\r
2193 //\r
2194 //TRUE: At the second time, we should send the first packet (default:beacon)\r
2195 //      to Hw again and set the lengh in descriptor to the real beacon lengh.\r
2196 // 2009.10.15 by tynli.\r
2197 static void rtl8723b_set_AP_FwRsvdPagePkt(PADAPTER padapter,\r
2198                 BOOLEAN bDLFinished)\r
2199 {\r
2200         PHAL_DATA_TYPE pHalData;\r
2201         struct xmit_frame       *pcmdframe;\r
2202         struct pkt_attrib       *pattrib;\r
2203         struct xmit_priv        *pxmitpriv;\r
2204         struct mlme_ext_priv    *pmlmeext;\r
2205         struct mlme_ext_info    *pmlmeinfo;\r
2206         struct pwrctrl_priv *pwrctl;\r
2207         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;\r
2208         u32     BeaconLength=0, ProbeRspLength=0;\r
2209         u8      *ReservedPagePacket;\r
2210         u8      TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;\r
2211         u8      TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;\r
2212         u16     BufIndex, PageSize = 128;\r
2213         u32     TotalPacketLen = 0, MaxRsvdPageBufSize=0;\r
2214         RSVDPAGE_LOC    RsvdPageLoc;\r
2215 #ifdef DBG_CONFIG_ERROR_DETECT\r
2216         struct sreset_priv *psrtpriv;\r
2217 #endif // DBG_CONFIG_ERROR_DETECT\r
2218 \r
2219         //DBG_871X("%s---->\n", __FUNCTION__);\r
2220 \r
2221         pHalData = GET_HAL_DATA(padapter);\r
2222 #ifdef DBG_CONFIG_ERROR_DETECT\r
2223         psrtpriv = &pHalData->srestpriv;\r
2224 #endif\r
2225         pxmitpriv = &padapter->xmitpriv;\r
2226         pmlmeext = &padapter->mlmeextpriv;\r
2227         pmlmeinfo = &pmlmeext->mlmext_info;\r
2228         pwrctl = adapter_to_pwrctl(padapter);\r
2229 \r
2230         RsvdPageNum = BCNQ_PAGE_NUM_8723B + WOWLAN_PAGE_NUM_8723B;\r
2231         MaxRsvdPageBufSize = RsvdPageNum*PageSize;\r
2232 \r
2233         pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);\r
2234         if (pcmdframe == NULL) {\r
2235                 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);\r
2236                 return;\r
2237         }\r
2238 \r
2239         ReservedPagePacket = pcmdframe->buf_addr;\r
2240         _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));\r
2241 \r
2242         //3 (1) beacon\r
2243         BufIndex = TxDescOffset;\r
2244         ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);\r
2245 \r
2246         // When we count the first page size, we need to reserve description size for the RSVD\r
2247         // packet, it will be filled in front of the packet in TXPKTBUF.\r
2248         CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);\r
2249         //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware\r
2250         if (CurtPktPageNum == 1)\r
2251         {\r
2252                 CurtPktPageNum += 1;\r
2253         }\r
2254         TotalPageNum += CurtPktPageNum;\r
2255 \r
2256         BufIndex += (CurtPktPageNum*PageSize);\r
2257 \r
2258         //2 (4) probe response\r
2259         RsvdPageLoc.LocProbeRsp = TotalPageNum;\r
2260         ConstructProbeRsp(\r
2261                 padapter,\r
2262                 &ReservedPagePacket[BufIndex],\r
2263                 &ProbeRspLength,\r
2264                 get_my_bssid(&pmlmeinfo->network),\r
2265                 _FALSE);\r
2266         rtl8723b_fill_fake_txdesc(padapter,\r
2267                         &ReservedPagePacket[BufIndex-TxDescLen],\r
2268                         ProbeRspLength,\r
2269                         _FALSE, _FALSE, _FALSE);\r
2270 \r
2271         DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",\r
2272                 __func__, &ReservedPagePacket[BufIndex-TxDescLen],\r
2273                 (ProbeRspLength+TxDescLen));\r
2274 \r
2275         CurtPktPageNum = (u8)PageNum_128(TxDescLen + ProbeRspLength);\r
2276 \r
2277         TotalPageNum += CurtPktPageNum;\r
2278 \r
2279         BufIndex += (CurtPktPageNum*PageSize);\r
2280 \r
2281         TotalPacketLen = BufIndex + ProbeRspLength;\r
2282 \r
2283         if (TotalPacketLen > MaxRsvdPageBufSize) {\r
2284                 DBG_871X("%s(): ERROR: The rsvd page size is not enough \\r
2285                                 !!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",\r
2286                                 __func__, TotalPacketLen,MaxRsvdPageBufSize);\r
2287                 goto error;\r
2288         } else {\r
2289                 // update attribute\r
2290                 pattrib = &pcmdframe->attrib;\r
2291                 update_mgntframe_attrib(padapter, pattrib);\r
2292                 pattrib->qsel = 0x10;\r
2293                 pattrib->pktlen = TotalPacketLen - TxDescOffset;\r
2294                 pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;\r
2295 #ifdef CONFIG_PCI_HCI\r
2296                 dump_mgntframe(padapter, pcmdframe);\r
2297 #else\r
2298                 dump_mgntframe_and_wait(padapter, pcmdframe, 100);\r
2299 #endif\r
2300         }\r
2301 \r
2302         DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", __FUNCTION__,TotalPacketLen,TotalPageNum);\r
2303         rtl8723b_set_ap_wow_rsvdpage_cmd(padapter, &RsvdPageLoc);\r
2304 \r
2305         return;\r
2306 error:\r
2307         rtw_free_xmitframe(pxmitpriv, pcmdframe);\r
2308 }\r
2309 #endif //CONFIG_AP_WOWLAN\r
2310 \r
2311 void rtl8723b_download_rsvd_page(PADAPTER padapter, u8 mstatus)\r
2312 {\r
2313         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);\r
2314         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
2315         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
2316         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);\r
2317         BOOLEAN         bcn_valid = _FALSE;\r
2318         u8      DLBcnCount=0;\r
2319         u32 poll = 0;\r
2320         u8 val8;\r
2321 \r
2322 _func_enter_;\r
2323 \r
2324         DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d mstatus(%x)\n",\r
2325                 FUNC_ADPT_ARG(padapter), get_iface_type(padapter), mstatus);\r
2326 \r
2327         if(mstatus == RT_MEDIA_CONNECT)\r
2328         {\r
2329                 BOOLEAN bRecover = _FALSE;\r
2330                 u8 v8;\r
2331 \r
2332                 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.\r
2333                 // Suggested by filen. Added by tynli.\r
2334                 rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));\r
2335 \r
2336                 // set REG_CR bit 8\r
2337                 v8 = rtw_read8(padapter, REG_CR+1);\r
2338                 v8 |= BIT(0); // ENSWBCN\r
2339                 rtw_write8(padapter,  REG_CR+1, v8);\r
2340 \r
2341                 // Disable Hw protection for a time which revserd for Hw sending beacon.\r
2342                 // Fix download reserved page packet fail that access collision with the protection time.\r
2343                 // 2010.05.11. Added by tynli.\r
2344                 val8 = rtw_read8(padapter, REG_BCN_CTRL);\r
2345                 val8 &= ~BIT(3);\r
2346                 val8 |= BIT(4);\r
2347                 rtw_write8(padapter, REG_BCN_CTRL, val8);\r
2348 \r
2349                 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.\r
2350                 if (pHalData->RegFwHwTxQCtrl & BIT(6))\r
2351                         bRecover = _TRUE;\r
2352 \r
2353                 // To tell Hw the packet is not a real beacon frame.\r
2354                 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl & ~BIT(6));\r
2355                 pHalData->RegFwHwTxQCtrl &= ~BIT(6);\r
2356 \r
2357                 // Clear beacon valid check bit.\r
2358                 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);\r
2359                 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);\r
2360 \r
2361                 DLBcnCount = 0;\r
2362                 poll = 0;\r
2363                 do\r
2364                 {\r
2365 #ifdef CONFIG_AP_WOWLAN\r
2366                         if (pwrpriv->wowlan_ap_mode)\r
2367                                 rtl8723b_set_AP_FwRsvdPagePkt(padapter, 0);\r
2368                         else\r
2369                                 rtl8723b_set_FwRsvdPagePkt(padapter, 0);\r
2370 #else\r
2371                         // download rsvd page.\r
2372                         rtl8723b_set_FwRsvdPagePkt(padapter, 0);\r
2373 #endif\r
2374                         DLBcnCount++;\r
2375                         do\r
2376                         {\r
2377                                 rtw_yield_os();\r
2378                                 //rtw_mdelay_os(10);\r
2379                                 // check rsvd page download OK.\r
2380                                 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid));\r
2381                                 poll++;\r
2382                         } while(!bcn_valid && (poll%10)!=0 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);\r
2383                         \r
2384                 }while(!bcn_valid && DLBcnCount<=100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);\r
2385 \r
2386                 if(padapter->bSurpriseRemoved || padapter->bDriverStopped)\r
2387                 {\r
2388                 }\r
2389                 else if(!bcn_valid)\r
2390                         DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",\r
2391                                 ADPT_ARG(padapter) ,DLBcnCount, poll);\r
2392                 else {\r
2393                         struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);\r
2394                         pwrctl->fw_psmode_iface_id = padapter->iface_id;\r
2395                         DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",\r
2396                                 ADPT_ARG(padapter), DLBcnCount, poll);\r
2397                 }\r
2398 \r
2399                 // 2010.05.11. Added by tynli.\r
2400                 val8 = rtw_read8(padapter, REG_BCN_CTRL);\r
2401                 val8 |= BIT(3);\r
2402                 val8 &= ~BIT(4);\r
2403                 rtw_write8(padapter, REG_BCN_CTRL, val8);\r
2404 \r
2405                 // To make sure that if there exists an adapter which would like to send beacon.\r
2406                 // If exists, the origianl value of 0x422[6] will be 1, we should check this to\r
2407                 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause\r
2408                 // the beacon cannot be sent by HW.\r
2409                 // 2010.06.23. Added by tynli.\r
2410                 if(bRecover)\r
2411                 {\r
2412                         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl | BIT(6));\r
2413                         pHalData->RegFwHwTxQCtrl |= BIT(6);\r
2414                 }\r
2415 \r
2416                 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.\r
2417                 v8 = rtw_read8(padapter, REG_CR+1);\r
2418                 v8 &= ~BIT(0); // ~ENSWBCN\r
2419                 rtw_write8(padapter, REG_CR+1, v8);\r
2420         }\r
2421 \r
2422 _func_exit_;\r
2423 }\r
2424 \r
2425 void rtl8723b_set_rssi_cmd(_adapter*padapter, u8 *param)\r
2426 {\r
2427         rtl8723b_set_FwRssiSetting_cmd(padapter, param);\r
2428 }\r
2429 \r
2430 void rtl8723b_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus)\r
2431 {\r
2432         struct sta_info *psta = NULL;\r
2433         struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);\r
2434         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;\r
2435 \r
2436         if(mstatus == 1)\r
2437                 rtl8723b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);\r
2438 }\r
2439 \r
2440 //arg[0] = macid\r
2441 //arg[1] = raid\r
2442 //arg[2] = shortGIrate\r
2443 //arg[3] = init_rate\r
2444 void rtl8723b_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8* arg, u8 rssi_level)\r
2445 {\r
2446         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);\r
2447         struct mlme_ext_priv    *pmlmeext = &pAdapter->mlmeextpriv;\r
2448         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
2449         struct sta_info *psta;\r
2450         u8 mac_id = arg[0];\r
2451         u8 raid = arg[1];\r
2452         u8 shortGI = arg[2];\r
2453         u8 bw;\r
2454         u32 mask = bitmap&0x0FFFFFFF;\r
2455 \r
2456         psta = pmlmeinfo->FW_sta_info[mac_id].psta;\r
2457         if(psta == NULL)\r
2458         {\r
2459                 return;\r
2460         }\r
2461 \r
2462         bw = psta->bw_mode;\r
2463 \r
2464         if(rssi_level != DM_RATR_STA_INIT)\r
2465                 mask = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, mac_id, mask, rssi_level);               \r
2466 \r
2467         DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask);\r
2468         rtl8723b_set_FwMacIdConfig_cmd(pAdapter, mac_id, raid, bw, shortGI, mask);\r
2469 }\r
2470 \r
2471 #if 0\r
2472 void rtl8723b_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack)\r
2473 {\r
2474         rtl8723b_set_FwAPReqRPT_cmd(padapter, need_ack);\r
2475 }\r
2476 #endif\r
2477 \r
2478 #ifdef CONFIG_BT_COEXIST\r
2479 static void ConstructBtNullFunctionData(\r
2480         PADAPTER padapter,\r
2481         u8 *pframe,\r
2482         u32 *pLength,\r
2483         u8 *StaAddr,\r
2484         u8 bQoS,\r
2485         u8 AC,\r
2486         u8 bEosp,\r
2487         u8 bForcePowerSave)\r
2488 {\r
2489         struct rtw_ieee80211_hdr *pwlanhdr;\r
2490         u16 *fctrl;\r
2491         u32 pktlen;\r
2492         struct mlme_ext_priv *pmlmeext;\r
2493         struct mlme_ext_info *pmlmeinfo;\r
2494         u8 bssid[ETH_ALEN];\r
2495 \r
2496 \r
2497         DBG_871X("+" FUNC_ADPT_FMT ": qos=%d eosp=%d ps=%d\n",\r
2498                 FUNC_ADPT_ARG(padapter), bQoS, bEosp, bForcePowerSave);\r
2499 \r
2500         pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;\r
2501         pmlmeext = &padapter->mlmeextpriv;\r
2502         pmlmeinfo = &pmlmeext->mlmext_info;\r
2503 \r
2504         if (NULL == StaAddr)\r
2505         {\r
2506                 _rtw_memcpy(bssid, myid(&padapter->eeprompriv), ETH_ALEN);\r
2507                 StaAddr = bssid;\r
2508         }\r
2509 \r
2510         fctrl = &pwlanhdr->frame_ctl;\r
2511         *fctrl = 0;\r
2512         if (bForcePowerSave)\r
2513                 SetPwrMgt(fctrl);\r
2514 \r
2515         SetFrDs(fctrl);\r
2516         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);\r
2517         _rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);\r
2518         _rtw_memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);\r
2519 \r
2520         SetDuration(pwlanhdr, 0);\r
2521         SetSeqNum(pwlanhdr, 0);\r
2522 \r
2523         if (bQoS == _TRUE)\r
2524         {\r
2525                 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;\r
2526 \r
2527                 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);\r
2528 \r
2529                 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;\r
2530                 SetPriority(&pwlanqoshdr->qc, AC);\r
2531                 SetEOSP(&pwlanqoshdr->qc, bEosp);\r
2532 \r
2533                 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);\r
2534         }\r
2535         else\r
2536         {\r
2537                 SetFrameSubType(pframe, WIFI_DATA_NULL);\r
2538 \r
2539                 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);\r
2540         }\r
2541 \r
2542         *pLength = pktlen;\r
2543 }\r
2544 \r
2545 static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter)\r
2546 {\r
2547         PHAL_DATA_TYPE pHalData;\r
2548         struct xmit_frame *pcmdframe;   \r
2549         struct pkt_attrib *pattrib;\r
2550         struct xmit_priv *pxmitpriv;\r
2551         struct mlme_ext_priv *pmlmeext;\r
2552         struct mlme_ext_info *pmlmeinfo;\r
2553         u32     BeaconLength = 0;\r
2554         u32     BTQosNullLength = 0;\r
2555         u8 *ReservedPagePacket;\r
2556         u8 TxDescLen, TxDescOffset;\r
2557         u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;\r
2558         u16     BufIndex, PageSize;\r
2559         u32     TotalPacketLen, MaxRsvdPageBufSize=0;\r
2560         RSVDPAGE_LOC RsvdPageLoc;\r
2561 \r
2562 \r
2563 //      DBG_8192C("+" FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));\r
2564 \r
2565         pHalData = GET_HAL_DATA(padapter);\r
2566         pxmitpriv = &padapter->xmitpriv;\r
2567         pmlmeext = &padapter->mlmeextpriv;\r
2568         pmlmeinfo = &pmlmeext->mlmext_info;\r
2569         TxDescLen = TXDESC_SIZE;\r
2570         TxDescOffset = TXDESC_OFFSET;\r
2571         PageSize = PAGE_SIZE_TX_8723B;\r
2572 \r
2573         RsvdPageNum = BCNQ_PAGE_NUM_8723B;\r
2574         MaxRsvdPageBufSize = RsvdPageNum*PageSize;\r
2575 \r
2576         pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);\r
2577         if (pcmdframe == NULL) {\r
2578                 DBG_8192C("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);\r
2579                 return;\r
2580         }\r
2581 \r
2582         ReservedPagePacket = pcmdframe->buf_addr;\r
2583         _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));\r
2584 \r
2585         //3 (1) beacon\r
2586         BufIndex = TxDescOffset;\r
2587         ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);\r
2588 \r
2589         // When we count the first page size, we need to reserve description size for the RSVD\r
2590         // packet, it will be filled in front of the packet in TXPKTBUF.\r
2591         CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);\r
2592         //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware\r
2593         if (CurtPktPageNum == 1)\r
2594         {\r
2595                 CurtPktPageNum += 1;\r
2596         }\r
2597         TotalPageNum += CurtPktPageNum;\r
2598 \r
2599         BufIndex += (CurtPktPageNum*PageSize);\r
2600 \r
2601         // Jump to lastest page\r
2602         if (BufIndex < (MaxRsvdPageBufSize - PageSize))\r
2603         {\r
2604                 BufIndex = TxDescOffset + (MaxRsvdPageBufSize - PageSize);\r
2605                 TotalPageNum = BCNQ_PAGE_NUM_8723B - 1;\r
2606         }\r
2607 \r
2608         //3 (6) BT Qos null data\r
2609         RsvdPageLoc.LocBTQosNull = TotalPageNum;\r
2610         ConstructBtNullFunctionData(\r
2611                 padapter,\r
2612                 &ReservedPagePacket[BufIndex],\r
2613                 &BTQosNullLength,\r
2614                 NULL,\r
2615                 _TRUE, 0, 0, _FALSE);\r
2616         rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);\r
2617 \r
2618         CurtPktPageNum = (u8)PageNum_128(TxDescLen + BTQosNullLength);\r
2619 \r
2620         TotalPageNum += CurtPktPageNum;\r
2621 \r
2622         TotalPacketLen = BufIndex + BTQosNullLength;\r
2623         if (TotalPacketLen > MaxRsvdPageBufSize)\r
2624         {\r
2625                 DBG_8192C(FUNC_ADPT_FMT ": ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",\r
2626                         FUNC_ADPT_ARG(padapter), TotalPacketLen, MaxRsvdPageBufSize);\r
2627                 goto error;\r
2628         }\r
2629 \r
2630         // update attribute\r
2631         pattrib = &pcmdframe->attrib;\r
2632         update_mgntframe_attrib(padapter, pattrib);\r
2633         pattrib->qsel = 0x10;\r
2634         pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;\r
2635 #ifdef CONFIG_PCI_HCI\r
2636         dump_mgntframe(padapter, pcmdframe);\r
2637 #else\r
2638         dump_mgntframe_and_wait(padapter, pcmdframe, 100);\r
2639 #endif\r
2640 \r
2641 //      DBG_8192C(FUNC_ADPT_FMT ": Set RSVD page location to Fw, TotalPacketLen(%d), TotalPageNum(%d)\n",\r
2642 //              FUNC_ADPT_ARG(padapter), TotalPacketLen, TotalPageNum);\r
2643         rtl8723b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);\r
2644         rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);\r
2645 \r
2646         return;\r
2647 \r
2648 error:\r
2649         rtw_free_xmitframe(pxmitpriv, pcmdframe);\r
2650 }\r
2651 \r
2652 void rtl8723b_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter)\r
2653 {\r
2654         PHAL_DATA_TYPE pHalData;\r
2655         struct mlme_ext_priv *pmlmeext;\r
2656         struct mlme_ext_info *pmlmeinfo;\r
2657         u8 bRecover = _FALSE;\r
2658         u8 bcn_valid = _FALSE;\r
2659         u8 DLBcnCount = 0;\r
2660         u32 poll = 0;\r
2661         u8 val8;\r
2662 \r
2663 \r
2664         DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d fw_state=0x%08X\n",\r
2665                 FUNC_ADPT_ARG(padapter), get_iface_type(padapter), get_fwstate(&padapter->mlmepriv));\r
2666 \r
2667 #ifdef CONFIG_DEBUG\r
2668         if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _FALSE)\r
2669         {\r
2670                 DBG_8192C(FUNC_ADPT_FMT ": [WARNING] not in AP mode!!\n",\r
2671                         FUNC_ADPT_ARG(padapter));\r
2672         }\r
2673 #endif // CONFIG_DEBUG\r
2674 \r
2675         pHalData = GET_HAL_DATA(padapter);\r
2676         pmlmeext = &padapter->mlmeextpriv;\r
2677         pmlmeinfo = &pmlmeext->mlmext_info;\r
2678 \r
2679         // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.\r
2680         // Suggested by filen. Added by tynli.\r
2681         rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));\r
2682         \r
2683         // set REG_CR bit 8\r
2684         val8 = rtw_read8(padapter, REG_CR+1);\r
2685         val8 |= BIT(0); // ENSWBCN\r
2686         rtw_write8(padapter,  REG_CR+1, val8);\r
2687         \r
2688         // Disable Hw protection for a time which revserd for Hw sending beacon.\r
2689         // Fix download reserved page packet fail that access collision with the protection time.\r
2690         // 2010.05.11. Added by tynli.\r
2691         val8 = rtw_read8(padapter, REG_BCN_CTRL);\r
2692         val8 &= ~BIT(3);\r
2693         val8 |= BIT(4);\r
2694         rtw_write8(padapter, REG_BCN_CTRL, val8);\r
2695 \r
2696         // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.\r
2697         if (pHalData->RegFwHwTxQCtrl & BIT(6))\r
2698                 bRecover = _TRUE;\r
2699 \r
2700         // To tell Hw the packet is not a real beacon frame.\r
2701         pHalData->RegFwHwTxQCtrl &= ~BIT(6);\r
2702         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);\r
2703 \r
2704         // Clear beacon valid check bit.\r
2705         rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);\r
2706         rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);\r
2707 \r
2708         DLBcnCount = 0;\r
2709         poll = 0;\r
2710         do {\r
2711                 SetFwRsvdPagePkt_BTCoex(padapter);\r
2712                 DLBcnCount++;\r
2713                 do {\r
2714                         rtw_yield_os();\r
2715 //                      rtw_mdelay_os(10);\r
2716                         // check rsvd page download OK.\r
2717                         rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, &bcn_valid);\r
2718                         poll++;\r
2719                 } while (!bcn_valid && (poll%10)!=0 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);\r
2720         } while (!bcn_valid && (DLBcnCount<=100) && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);\r
2721 \r
2722         if (_TRUE == bcn_valid)\r
2723         {\r
2724                 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);\r
2725                 pwrctl->fw_psmode_iface_id = padapter->iface_id;\r
2726                 DBG_8192C(ADPT_FMT": DL RSVD page success! DLBcnCount:%d, poll:%d\n",\r
2727                         ADPT_ARG(padapter), DLBcnCount, poll);\r
2728         }\r
2729         else\r
2730         {\r
2731                 DBG_8192C(ADPT_FMT": DL RSVD page fail! DLBcnCount:%d, poll:%d\n",\r
2732                         ADPT_ARG(padapter), DLBcnCount, poll);\r
2733                 DBG_8192C(ADPT_FMT": DL RSVD page fail! bSurpriseRemoved=%d\n",\r
2734                         ADPT_ARG(padapter), padapter->bSurpriseRemoved);\r
2735                 DBG_8192C(ADPT_FMT": DL RSVD page fail! bDriverStopped=%d\n",\r
2736                         ADPT_ARG(padapter), padapter->bDriverStopped);\r
2737         }\r
2738 \r
2739         // 2010.05.11. Added by tynli.\r
2740         val8 = rtw_read8(padapter, REG_BCN_CTRL);\r
2741         val8 |= BIT(3);\r
2742         val8 &= ~BIT(4);\r
2743         rtw_write8(padapter, REG_BCN_CTRL, val8);\r
2744 \r
2745         // To make sure that if there exists an adapter which would like to send beacon.\r
2746         // If exists, the origianl value of 0x422[6] will be 1, we should check this to\r
2747         // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause\r
2748         // the beacon cannot be sent by HW.\r
2749         // 2010.06.23. Added by tynli.\r
2750         if (bRecover)\r
2751         {\r
2752                 pHalData->RegFwHwTxQCtrl |= BIT(6);\r
2753                 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);\r
2754         }\r
2755 \r
2756         // Clear CR[8] or beacon packet will not be send to TxBuf anymore.\r
2757         val8 = rtw_read8(padapter, REG_CR+1);\r
2758         val8 &= ~BIT(0); // ~ENSWBCN\r
2759         rtw_write8(padapter, REG_CR+1, val8);\r
2760 }\r
2761 #endif // CONFIG_BT_COEXIST\r
2762 \r
2763 #ifdef CONFIG_P2P\r
2764 void rtl8723b_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state)\r
2765 {\r
2766         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);\r
2767         struct pwrctrl_priv             *pwrpriv = adapter_to_pwrctl(padapter);\r
2768         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );\r
2769         struct P2P_PS_Offload_t *p2p_ps_offload = (struct P2P_PS_Offload_t      *)(&pHalData->p2p_ps_offload);\r
2770         u8      i;\r
2771 \r
2772 _func_enter_;\r
2773 \r
2774 #if 1\r
2775         switch(p2p_ps_state)\r
2776         {\r
2777                 case P2P_PS_DISABLE:\r
2778                         DBG_8192C("P2P_PS_DISABLE \n");\r
2779                         _rtw_memset(p2p_ps_offload, 0 ,1);\r
2780                         break;\r
2781                 case P2P_PS_ENABLE:\r
2782                         DBG_8192C("P2P_PS_ENABLE \n");\r
2783                         // update CTWindow value.\r
2784                         if( pwdinfo->ctwindow > 0 )\r
2785                         {\r
2786                                 p2p_ps_offload->CTWindow_En = 1;\r
2787                                 rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);\r
2788                         }\r
2789 \r
2790                         // hw only support 2 set of NoA\r
2791                         for( i=0 ; i<pwdinfo->noa_num ; i++)\r
2792                         {\r
2793                                 // To control the register setting for which NOA\r
2794                                 rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));\r
2795                                 if(i == 0)\r
2796                                         p2p_ps_offload->NoA0_En = 1;\r
2797                                 else\r
2798                                         p2p_ps_offload->NoA1_En = 1;\r
2799 \r
2800                                 // config P2P NoA Descriptor Register\r
2801                                 //DBG_8192C("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]);\r
2802                                 rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);\r
2803 \r
2804                                 //DBG_8192C("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]);\r
2805                                 rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);\r
2806 \r
2807                                 //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]);\r
2808                                 rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);\r
2809 \r
2810                                 //DBG_8192C("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]);\r
2811                                 rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);\r
2812                         }\r
2813 \r
2814                         if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) )\r
2815                         {\r
2816                                 // rst p2p circuit\r
2817                                 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));\r
2818 \r
2819                                 p2p_ps_offload->Offload_En = 1;\r
2820 \r
2821                                 if(pwdinfo->role == P2P_ROLE_GO)\r
2822                                 {\r
2823                                         p2p_ps_offload->role= 1;\r
2824                                         p2p_ps_offload->AllStaSleep = 0;\r
2825                                 }\r
2826                                 else\r
2827                                 {\r
2828                                         p2p_ps_offload->role= 0;\r
2829                                 }\r
2830 \r
2831                                 p2p_ps_offload->discovery = 0;\r
2832                         }\r
2833                         break;\r
2834                 case P2P_PS_SCAN:\r
2835                         DBG_8192C("P2P_PS_SCAN \n");\r
2836                         p2p_ps_offload->discovery = 1;\r
2837                         break;\r
2838                 case P2P_PS_SCAN_DONE:\r
2839                         DBG_8192C("P2P_PS_SCAN_DONE \n");\r
2840                         p2p_ps_offload->discovery = 0;\r
2841                         pwdinfo->p2p_ps_state = P2P_PS_ENABLE;\r
2842                         break;\r
2843                 default:\r
2844                         break;\r
2845         }\r
2846 \r
2847         FillH2CCmd8723B(padapter, H2C_8723B_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);\r
2848 #endif\r
2849 \r
2850 _func_exit_;\r
2851 \r
2852 }\r
2853 #endif //CONFIG_P2P\r
2854 \r
2855 \r
2856 #ifdef CONFIG_TSF_RESET_OFFLOAD\r
2857 /*\r
2858         ask FW to Reset sync register at Beacon early interrupt\r
2859 */\r
2860 u8 rtl8723b_reset_tsf(_adapter *padapter, u8 reset_port )\r
2861 {\r
2862         u8      buf[2];\r
2863         u8      res=_SUCCESS;\r
2864 \r
2865 _func_enter_;\r
2866         if (IFACE_PORT0==reset_port) {\r
2867                 buf[0] = 0x1; buf[1] = 0;\r
2868 \r
2869         } else{\r
2870                 buf[0] = 0x0; buf[1] = 0x1;\r
2871         }\r
2872         FillH2CCmd8723B(padapter, H2C_8723B_RESET_TSF, 2, buf);\r
2873 _func_exit_;\r
2874 \r
2875         return res;\r
2876 }\r
2877 #endif  // CONFIG_TSF_RESET_OFFLOAD\r
2878 \r