add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8723au / hal / rtl8723a / rtl8723a_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 _RTL8723A_CMD_C_\r
21 \r
22 #include <drv_conf.h>\r
23 #include <osdep_service.h>\r
24 #include <drv_types.h>\r
25 #include <recv_osdep.h>\r
26 #include <cmd_osdep.h>\r
27 #include <mlme_osdep.h>\r
28 #include <rtw_byteorder.h>\r
29 #include <circ_buf.h>\r
30 #include <rtw_ioctl_set.h>\r
31 \r
32 #include <rtl8723a_hal.h>\r
33 \r
34 \r
35 #define RTL92C_MAX_H2C_BOX_NUMS 4\r
36 #define RTL92C_MAX_CMD_LEN      5\r
37 #define MESSAGE_BOX_SIZE                4\r
38 #define EX_MESSAGE_BOX_SIZE     2\r
39 \r
40 \r
41 static u8 _is_fw_read_cmd_down(_adapter* padapter, u8 msgbox_num)\r
42 {\r
43         u8      read_down = _FALSE;\r
44         int     retry_cnts = 100;\r
45 \r
46         u8 valid;\r
47 \r
48         //DBG_8192C(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num);\r
49 \r
50         do{\r
51                 valid = rtw_read8(padapter,REG_HMETFR) & BIT(msgbox_num);\r
52 \r
53                 if(0 == valid ){\r
54                         read_down = _TRUE;\r
55                 }\r
56         }while( (!read_down) && (retry_cnts--));\r
57 \r
58         return read_down;\r
59 \r
60 }\r
61 \r
62 \r
63 /*****************************************\r
64 * H2C Msg format :\r
65 *| 31 - 8               |7              | 6 - 0 |\r
66 *| h2c_msg      |Ext_bit        |CMD_ID |\r
67 *\r
68 ******************************************/\r
69 s32 FillH2CCmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)\r
70 {\r
71         u8 bcmd_down = _FALSE;\r
72         s32 retry_cnts = 100;\r
73         u8 h2c_box_num;\r
74         u32     msgbox_addr;\r
75         u32 msgbox_ex_addr;\r
76         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);\r
77         u32     h2c_cmd = 0;\r
78         u16     h2c_cmd_ex = 0;\r
79         s32 ret = _FAIL;\r
80 \r
81 _func_enter_;\r
82 \r
83         padapter = GET_PRIMARY_ADAPTER(padapter);               \r
84         pHalData = GET_HAL_DATA(padapter);\r
85 \r
86         _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);\r
87 \r
88         if (!pCmdBuffer) {\r
89                 goto exit;\r
90         }\r
91         if (CmdLen > RTL92C_MAX_CMD_LEN) {\r
92                 goto exit;\r
93         }\r
94         if (padapter->bSurpriseRemoved == _TRUE)\r
95                 goto exit;\r
96 \r
97         //pay attention to if  race condition happened in  H2C cmd setting.\r
98         do{\r
99                 h2c_box_num = pHalData->LastHMEBoxNum;\r
100 \r
101                 if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){\r
102                         DBG_8192C(" fw read cmd failed...\n");\r
103                         goto exit;\r
104                 }\r
105 \r
106                 if(CmdLen<=3)\r
107                 {\r
108                         _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen );\r
109                 }\r
110                 else{\r
111                         _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer, EX_MESSAGE_BOX_SIZE);\r
112                         _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer+2,( CmdLen-EX_MESSAGE_BOX_SIZE));\r
113                         *(u8*)(&h2c_cmd) |= BIT(7);\r
114                 }\r
115 \r
116                 *(u8*)(&h2c_cmd) |= ElementID;\r
117 \r
118                 if(h2c_cmd & BIT(7)){\r
119                         msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num *EX_MESSAGE_BOX_SIZE);\r
120                         h2c_cmd_ex = le16_to_cpu( h2c_cmd_ex );\r
121                         rtw_write16(padapter, msgbox_ex_addr, h2c_cmd_ex);\r
122                 }\r
123                 msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *MESSAGE_BOX_SIZE);\r
124                 h2c_cmd = le32_to_cpu( h2c_cmd );\r
125                 rtw_write32(padapter,msgbox_addr, h2c_cmd);\r
126 \r
127                 bcmd_down = _TRUE;\r
128 \r
129                 //DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n"\r
130                 //      ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex);\r
131 \r
132                 pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL92C_MAX_H2C_BOX_NUMS;\r
133 \r
134         }while((!bcmd_down) && (retry_cnts--));\r
135 \r
136         ret = _SUCCESS;\r
137 \r
138 exit:\r
139 \r
140         _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);     \r
141 \r
142 _func_exit_;\r
143 \r
144         return ret;\r
145 }\r
146 \r
147 u8 rtl8192c_h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)\r
148 {\r
149         u8 ElementID, CmdLen;\r
150         u8 *pCmdBuffer;\r
151         struct cmd_msg_parm  *pcmdmsg;\r
152 \r
153         if(!pbuf)\r
154                 return H2C_PARAMETERS_ERROR;\r
155 \r
156         pcmdmsg = (struct cmd_msg_parm*)pbuf;\r
157         ElementID = pcmdmsg->eid;\r
158         CmdLen = pcmdmsg->sz;\r
159         pCmdBuffer = pcmdmsg->buf;\r
160 \r
161         FillH2CCmd(padapter, ElementID, CmdLen, pCmdBuffer);\r
162 \r
163         return H2C_SUCCESS;\r
164 }\r
165 \r
166 #if defined(CONFIG_AUTOSUSPEND) && defined(SUPPORT_HW_RFOFF_DETECTED)\r
167 u8 rtl8192c_set_FwSelectSuspend_cmd(_adapter *padapter ,u8 bfwpoll, u16 period)\r
168 {\r
169         u8      res=_SUCCESS;\r
170         struct H2C_SS_RFOFF_PARAM param;\r
171         DBG_8192C("==>%s bfwpoll(%x)\n",__FUNCTION__,bfwpoll);\r
172         param.gpio_period = period;//Polling GPIO_11 period time\r
173         param.ROFOn = (_TRUE == bfwpoll)?1:0;\r
174         FillH2CCmd(padapter, SELECTIVE_SUSPEND_ROF_CMD, sizeof(param), (u8*)(&param));          \r
175         return res;\r
176 }\r
177 #endif //CONFIG_AUTOSUSPEND && SUPPORT_HW_RFOFF_DETECTED\r
178 \r
179 u8 rtl8192c_set_rssi_cmd(_adapter*padapter, u8 *param)\r
180 {\r
181         u8      res=_SUCCESS;\r
182 \r
183 _func_enter_;\r
184 \r
185         *((u32*) param ) = cpu_to_le32( *((u32*) param ) );\r
186 \r
187         FillH2CCmd(padapter, RSSI_SETTING_EID, 3, param);\r
188 \r
189 _func_exit_;\r
190 \r
191         return res;\r
192 }\r
193 \r
194 u8 rtl8192c_set_raid_cmd(_adapter*padapter, u32 mask, u8 arg)\r
195 {\r
196         u8      buf[5];\r
197         u8      res=_SUCCESS;\r
198 \r
199 _func_enter_;\r
200 \r
201         _rtw_memset(buf, 0, 5);\r
202         mask = cpu_to_le32( mask );\r
203         _rtw_memcpy(buf, &mask, 4);\r
204         buf[4]  = arg;\r
205 \r
206         FillH2CCmd(padapter, MACID_CONFIG_EID, 5, buf);\r
207 \r
208 _func_exit_;\r
209 \r
210         return res;\r
211 \r
212 }\r
213 \r
214 //bitmap[0:27] = tx_rate_bitmap\r
215 //bitmap[28:31]= Rate Adaptive id\r
216 //arg[0:4] = macid\r
217 //arg[5] = Short GI\r
218 void rtl8192c_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8 arg, u8 rssi_level)\r
219 {\r
220         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(pAdapter);\r
221 \r
222         u8 macid = arg&0x1f;\r
223         \r
224 #ifdef CONFIG_ODM_REFRESH_RAMASK\r
225         u8 raid = (bitmap>>28) & 0x0f;\r
226         bitmap &=0x0fffffff;    \r
227         if(rssi_level != DM_RATR_STA_INIT)\r
228                 bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, macid, bitmap, rssi_level);    \r
229         \r
230         bitmap |= ((raid<<28)&0xf0000000);\r
231 #endif //CONFIG_ODM_REFRESH_RAMASK\r
232         \r
233 \r
234         if(pHalData->fw_ractrl == _TRUE)\r
235         {\r
236                 rtl8192c_set_raid_cmd(pAdapter, bitmap, arg);\r
237         }\r
238         else\r
239         {\r
240                 u8 init_rate, shortGIrate=_FALSE;\r
241 \r
242                 init_rate = get_highest_rate_idx(bitmap&0x0fffffff)&0x3f;\r
243 \r
244                 \r
245                 shortGIrate = (arg&BIT(5)) ? _TRUE:_FALSE;\r
246 \r
247                 if (shortGIrate==_TRUE)\r
248                         init_rate |= BIT(6);\r
249 \r
250                 rtw_write8(pAdapter, (REG_INIDATA_RATE_SEL+macid), (u8)init_rate);\r
251         }\r
252 \r
253 }\r
254 \r
255 void rtl8723a_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode)\r
256 {\r
257         SETPWRMODE_PARM H2CSetPwrMode;\r
258         struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);\r
259 \r
260 _func_enter_;\r
261 \r
262         H2CSetPwrMode.Mode = Mode;\r
263         H2CSetPwrMode.SmartPS = pwrpriv->smart_ps;\r
264         H2CSetPwrMode.AwakeInterval = 1;\r
265         H2CSetPwrMode.bAllQueueUAPSD = padapter->registrypriv.uapsd_enable;\r
266 \r
267         if(0 == Mode)\r
268         {\r
269                 /* Leave LPS, set BcnAntMode to 0 */\r
270                 H2CSetPwrMode.BcnAntMode = 0;\r
271         }\r
272         else \r
273         {\r
274                 H2CSetPwrMode.BcnAntMode = pwrpriv->bcn_ant_mode;\r
275         }\r
276 \r
277         DBG_871X("%s: Mode=%d SmartPS=%d UAPSD=%d BcnMode=0x%02x\n", __FUNCTION__,\r
278                 H2CSetPwrMode.Mode, H2CSetPwrMode.SmartPS, H2CSetPwrMode.bAllQueueUAPSD, H2CSetPwrMode.BcnAntMode);\r
279 \r
280         FillH2CCmd(padapter, SET_PWRMODE_EID, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode);\r
281 \r
282 _func_exit_;\r
283 }\r
284 \r
285 \r
286 void rtl8723a_set_FwMediaStatus_cmd(PADAPTER padapter, u16 mstatus_rpt )\r
287 {\r
288         u8 opmode,macid;\r
289         u16 mst_rpt = cpu_to_le16 (mstatus_rpt);\r
290         u32 reg_macid_no_link = REG_MACID_NO_LINK;\r
291         opmode = (u8) mst_rpt;\r
292         macid = (u8)(mst_rpt >> 8)  ;\r
293         DBG_871X("### %s: MStatus=%x MACID=%d \n", __FUNCTION__,opmode,macid);\r
294 \r
295         //Delete select macid (MACID 0~63) from queue list.\r
296         if(opmode == 1)// 1:connect\r
297         {\r
298                 rtw_write32(padapter,reg_macid_no_link, (rtw_read32(padapter,reg_macid_no_link) & (~BIT(macid))));\r
299         }\r
300         else//0: disconnect\r
301         {\r
302                 rtw_write32(padapter,reg_macid_no_link, (rtw_read32(padapter,reg_macid_no_link)|BIT(macid)));\r
303         }\r
304 }\r
305 \r
306 \r
307 void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)\r
308 {\r
309         struct rtw_ieee80211_hdr        *pwlanhdr;\r
310         u16                                     *fctrl;\r
311         u32                                     rate_len, pktlen;\r
312         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
313         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
314         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);\r
315         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
316 \r
317 \r
318         //DBG_871X("%s\n", __FUNCTION__);\r
319 \r
320         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;\r
321 \r
322         fctrl = &(pwlanhdr->frame_ctl);\r
323         *(fctrl) = 0;\r
324 \r
325         _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);\r
326         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
327         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);\r
328 \r
329         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);\r
330         //pmlmeext->mgnt_seq++;\r
331         SetFrameSubType(pframe, WIFI_BEACON);\r
332 \r
333         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);\r
334         pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);\r
335 \r
336         //timestamp will be inserted by hardware\r
337         pframe += 8;\r
338         pktlen += 8;\r
339 \r
340         // beacon interval: 2 bytes\r
341         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);\r
342 \r
343         pframe += 2;\r
344         pktlen += 2;\r
345 \r
346         // capability info: 2 bytes\r
347         _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);\r
348 \r
349         pframe += 2;\r
350         pktlen += 2;\r
351 \r
352         if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)\r
353         {\r
354                 //DBG_871X("ie len=%d\n", cur_network->IELength);\r
355                 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);\r
356                 _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);\r
357 \r
358                 goto _ConstructBeacon;\r
359         }\r
360 \r
361         //below for ad-hoc mode\r
362 \r
363         // SSID\r
364         pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);\r
365 \r
366         // supported rates...\r
367         rate_len = rtw_get_rateset_len(cur_network->SupportedRates);\r
368         pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);\r
369 \r
370         // DS parameter set\r
371         pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);\r
372 \r
373         if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)\r
374         {\r
375                 u32 ATIMWindow;\r
376                 // IBSS Parameter Set...\r
377                 //ATIMWindow = cur->Configuration.ATIMWindow;\r
378                 ATIMWindow = 0;\r
379                 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);\r
380         }\r
381 \r
382 \r
383         //todo: ERP IE\r
384 \r
385 \r
386         // EXTERNDED SUPPORTED RATE\r
387         if (rate_len > 8)\r
388         {\r
389                 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);\r
390         }\r
391 \r
392 \r
393         //todo:HT for adhoc\r
394 \r
395 _ConstructBeacon:\r
396 \r
397         if ((pktlen + TXDESC_SIZE) > 512)\r
398         {\r
399                 DBG_871X("beacon frame too large\n");\r
400                 return;\r
401         }\r
402 \r
403         *pLength = pktlen;\r
404 \r
405         //DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen);\r
406 \r
407 }\r
408 \r
409 void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength)\r
410 {\r
411         struct rtw_ieee80211_hdr        *pwlanhdr;\r
412         u16                                     *fctrl;\r
413         u32                                     pktlen;\r
414         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
415         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
416 \r
417         //DBG_871X("%s\n", __FUNCTION__);\r
418 \r
419         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;\r
420 \r
421         // Frame control.\r
422         fctrl = &(pwlanhdr->frame_ctl);\r
423         *(fctrl) = 0;\r
424         SetPwrMgt(fctrl);\r
425         SetFrameSubType(pframe, WIFI_PSPOLL);\r
426 \r
427         // AID.\r
428         SetDuration(pframe, (pmlmeinfo->aid | 0xc000));\r
429 \r
430         // BSSID.\r
431         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
432 \r
433         // TA.\r
434         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
435 \r
436         *pLength = 16;\r
437 }\r
438 \r
439 void ConstructNullFunctionData(\r
440         PADAPTER padapter,\r
441         u8              *pframe,\r
442         u32             *pLength,\r
443         u8              *StaAddr,\r
444         u8              bQoS,\r
445         u8              AC,\r
446         u8              bEosp,\r
447         u8              bForcePowerSave)\r
448 {\r
449         struct rtw_ieee80211_hdr        *pwlanhdr;\r
450         u16                                             *fctrl;\r
451         u32                                             pktlen;\r
452         struct mlme_priv                *pmlmepriv = &padapter->mlmepriv;\r
453         struct wlan_network             *cur_network = &pmlmepriv->cur_network;\r
454         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
455         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
456 \r
457 \r
458         //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);\r
459 \r
460         pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;\r
461 \r
462         fctrl = &pwlanhdr->frame_ctl;\r
463         *(fctrl) = 0;\r
464         if (bForcePowerSave)\r
465         {\r
466                 SetPwrMgt(fctrl);\r
467         }\r
468 \r
469         switch(cur_network->network.InfrastructureMode)\r
470         {\r
471                 case Ndis802_11Infrastructure:\r
472                         SetToDs(fctrl);\r
473                         _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
474                         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
475                         _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);\r
476                         break;\r
477                 case Ndis802_11APMode:\r
478                         SetFrDs(fctrl);\r
479                         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);\r
480                         _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
481                         _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
482                         break;\r
483                 case Ndis802_11IBSS:\r
484                 default:\r
485                         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);\r
486                         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);\r
487                         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);\r
488                         break;\r
489         }\r
490 \r
491         SetSeqNum(pwlanhdr, 0);\r
492 \r
493         if (bQoS == _TRUE) {\r
494                 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;\r
495 \r
496                 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);\r
497 \r
498                 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;\r
499                 SetPriority(&pwlanqoshdr->qc, AC);\r
500                 SetEOSP(&pwlanqoshdr->qc, bEosp);\r
501 \r
502                 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);\r
503         } else {\r
504                 SetFrameSubType(pframe, WIFI_DATA_NULL);\r
505 \r
506                 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);\r
507         }\r
508 \r
509         *pLength = pktlen;\r
510 }\r
511 \r
512 void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID)\r
513 {\r
514         struct rtw_ieee80211_hdr        *pwlanhdr;\r
515         u16                                     *fctrl;\r
516         u8                                      *mac, *bssid;\r
517         u32                                     pktlen;\r
518         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
519         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
520         WLAN_BSSID_EX           *cur_network = &(pmlmeinfo->network);\r
521 \r
522 \r
523         //DBG_871X("%s\n", __FUNCTION__);\r
524 \r
525         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;\r
526 \r
527         mac = myid(&(padapter->eeprompriv));\r
528         bssid = cur_network->MacAddress;\r
529 \r
530         fctrl = &(pwlanhdr->frame_ctl);\r
531         *(fctrl) = 0;\r
532         _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);\r
533         _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);\r
534         _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);\r
535 \r
536         SetSeqNum(pwlanhdr, 0);\r
537         SetFrameSubType(fctrl, WIFI_PROBERSP);\r
538 \r
539         pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);\r
540         pframe += pktlen;\r
541 \r
542         if(cur_network->IELength>MAX_IE_SZ)\r
543                 return;\r
544 \r
545         _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);\r
546         pframe += cur_network->IELength;\r
547         pktlen += cur_network->IELength;\r
548 \r
549         *pLength = pktlen;\r
550 }\r
551 \r
552 // To check if reserved page content is destroyed by beacon beacuse beacon is too large.\r
553 // 2010.06.23. Added by tynli.\r
554 VOID\r
555 CheckFwRsvdPageContent(\r
556         IN      PADAPTER                Adapter\r
557 )\r
558 {\r
559         HAL_DATA_TYPE*  pHalData = GET_HAL_DATA(Adapter);\r
560         u32     MaxBcnPageNum;\r
561 \r
562         if(pHalData->FwRsvdPageStartOffset != 0)\r
563         {\r
564                 /*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize);\r
565                 RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset),\r
566                         ("CheckFwRsvdPageContent(): The reserved page content has been"\\r
567                         "destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!",\r
568                         MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/\r
569         }\r
570 }\r
571 \r
572 //\r
573 // Description: Fill the reserved packets that FW will use to RSVD page.\r
574 //                      Now we just send 4 types packet to rsvd page.\r
575 //                      (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.\r
576 //      Input:\r
577 //          bDLFinished - FALSE: At the first time we will send all the packets as a large packet to Hw,\r
578 //                                              so we need to set the packet length to total lengh.\r
579 //                            TRUE: At the second time, we should send the first packet (default:beacon)\r
580 //                                              to Hw again and set the lengh in descriptor to the real beacon lengh.\r
581 // 2009.10.15 by tynli.\r
582 static void SetFwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished)\r
583 {\r
584         PHAL_DATA_TYPE pHalData;\r
585         struct xmit_frame       *pmgntframe;\r
586         struct pkt_attrib       *pattrib;\r
587         struct xmit_priv        *pxmitpriv;\r
588         struct mlme_ext_priv    *pmlmeext;\r
589         struct mlme_ext_info    *pmlmeinfo;\r
590         u32     BeaconLength, ProbeRspLength, PSPollLength;\r
591         u32     NullDataLength, QosNullLength, BTQosNullLength;\r
592         u8      *ReservedPagePacket;\r
593         u8      PageNum, PageNeed, TxDescLen;\r
594         u16     BufIndex;\r
595         u32     TotalPacketLen;\r
596         RSVDPAGE_LOC    RsvdPageLoc;\r
597 \r
598 \r
599         DBG_871X("%s\n", __FUNCTION__);\r
600 \r
601         ReservedPagePacket = (u8*)rtw_zmalloc(1000);\r
602         if (ReservedPagePacket == NULL) {\r
603                 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);\r
604                 return;\r
605         }\r
606 \r
607         pHalData = GET_HAL_DATA(padapter);\r
608         pxmitpriv = &padapter->xmitpriv;\r
609         pmlmeext = &padapter->mlmeextpriv;\r
610         pmlmeinfo = &pmlmeext->mlmext_info;\r
611 \r
612         TxDescLen = TXDESC_SIZE;\r
613         PageNum = 0;\r
614 \r
615         //3 (1) beacon\r
616         BufIndex = TXDESC_OFFSET;\r
617         ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);\r
618 \r
619         // When we count the first page size, we need to reserve description size for the RSVD\r
620         // packet, it will be filled in front of the packet in TXPKTBUF.\r
621         PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength);\r
622         // To reserved 2 pages for beacon buffer. 2010.06.24.\r
623         if (PageNeed == 1)\r
624                 PageNeed += 1;\r
625         PageNum += PageNeed;\r
626         pHalData->FwRsvdPageStartOffset = PageNum;\r
627 \r
628         BufIndex += PageNeed*128;\r
629 \r
630         //3 (2) ps-poll\r
631         RsvdPageLoc.LocPsPoll = PageNum;\r
632         ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength);\r
633         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE, _FALSE);\r
634 \r
635         PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength);\r
636         PageNum += PageNeed;\r
637 \r
638         BufIndex += PageNeed*128;\r
639 \r
640         //3 (3) null data\r
641         RsvdPageLoc.LocNullData = PageNum;\r
642         ConstructNullFunctionData(\r
643                 padapter,\r
644                 &ReservedPagePacket[BufIndex],\r
645                 &NullDataLength,\r
646                 get_my_bssid(&pmlmeinfo->network),\r
647                 _FALSE, 0, 0, _FALSE);\r
648         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, _FALSE, _FALSE);\r
649 \r
650         PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength);\r
651         PageNum += PageNeed;\r
652 \r
653         BufIndex += PageNeed*128;\r
654 \r
655         //3 (4) probe response\r
656         RsvdPageLoc.LocProbeRsp = PageNum;\r
657         ConstructProbeRsp(\r
658                 padapter,\r
659                 &ReservedPagePacket[BufIndex],\r
660                 &ProbeRspLength,\r
661                 get_my_bssid(&pmlmeinfo->network),\r
662                 _FALSE);\r
663         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE, _FALSE);\r
664 \r
665         PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength);\r
666         PageNum += PageNeed;\r
667 \r
668         BufIndex += PageNeed*128;\r
669 \r
670         //3 (5) Qos null data\r
671         RsvdPageLoc.LocQosNull = PageNum;\r
672         ConstructNullFunctionData(\r
673                 padapter, \r
674                 &ReservedPagePacket[BufIndex],\r
675                 &QosNullLength,\r
676                 get_my_bssid(&pmlmeinfo->network),\r
677                 _TRUE, 0, 0, _FALSE);\r
678         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, _FALSE, _FALSE);\r
679 \r
680         PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength);\r
681         PageNum += PageNeed;\r
682 \r
683         BufIndex += PageNeed*128;\r
684 \r
685         //3 (6) BT Qos null data\r
686         RsvdPageLoc.LocBTQosNull = PageNum;\r
687         ConstructNullFunctionData(\r
688                 padapter, \r
689                 &ReservedPagePacket[BufIndex],\r
690                 &BTQosNullLength,\r
691                 get_my_bssid(&pmlmeinfo->network),\r
692                 _TRUE, 0, 0, _FALSE);\r
693         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE);\r
694 \r
695         TotalPacketLen = BufIndex + BTQosNullLength;\r
696 \r
697         pmgntframe = alloc_mgtxmitframe(pxmitpriv);\r
698         if (pmgntframe == NULL)\r
699                 goto exit;\r
700 \r
701         // update attribute\r
702         pattrib = &pmgntframe->attrib;\r
703         update_mgntframe_attrib(padapter, pattrib);\r
704         pattrib->qsel = 0x10;\r
705         pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET;\r
706         _rtw_memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen);\r
707 \r
708         rtw_hal_mgnt_xmit(padapter, pmgntframe);\r
709 \r
710         DBG_871X("%s: Set RSVD page location to Fw\n", __FUNCTION__);\r
711         FillH2CCmd(padapter, RSVD_PAGE_EID, sizeof(RsvdPageLoc), (u8*)&RsvdPageLoc);\r
712 \r
713 exit:\r
714         rtw_mfree(ReservedPagePacket, 1000);\r
715 }\r
716 \r
717 void rtl8723a_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus)\r
718 {\r
719         JOINBSSRPT_PARM JoinBssRptParm;\r
720         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);\r
721         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);\r
722         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);\r
723 \r
724 _func_enter_;\r
725 \r
726         DBG_871X("%s mstatus(%x)\n", __FUNCTION__,mstatus);\r
727 \r
728         if(mstatus == 1)\r
729         {\r
730                 BOOLEAN bRecover = _FALSE;\r
731                 u8 v8;\r
732         \r
733                 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.\r
734                 // Suggested by filen. Added by tynli.\r
735                 rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));\r
736                 // Do not set TSF again here or vWiFi beacon DMA INT will not work.\r
737                 //correct_TSF(padapter, pmlmeext);\r
738                 // Hw sequende enable by dedault. 2010.06.23. by tynli.\r
739                 //rtw_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF));\r
740                 //rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF);\r
741 \r
742                 // set REG_CR bit 8\r
743                 v8 = rtw_read8(padapter, REG_CR+1);\r
744                 v8 |= BIT(0); // ENSWBCN\r
745                 rtw_write8(padapter,  REG_CR+1, v8);\r
746 \r
747                 // Disable Hw protection for a time which revserd for Hw sending beacon.\r
748                 // Fix download reserved page packet fail that access collision with the protection time.\r
749                 // 2010.05.11. Added by tynli.\r
750 //                      SetBcnCtrlReg(padapter, 0, BIT(3));\r
751 //                      SetBcnCtrlReg(padapter, BIT(4), 0);\r
752                 SetBcnCtrlReg(padapter, BIT(4), BIT(3));\r
753 \r
754                 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.\r
755                 if (pHalData->RegFwHwTxQCtrl & BIT(6))\r
756                         bRecover = _TRUE;\r
757 \r
758                 // To tell Hw the packet is not a real beacon frame.\r
759                 //U1bTmp = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2);\r
760                 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl & ~BIT(6));\r
761                 pHalData->RegFwHwTxQCtrl &= ~BIT(6);\r
762                 SetFwRsvdPagePkt(padapter, 0);\r
763 \r
764                 // 2010.05.11. Added by tynli.\r
765 //                      SetBcnCtrlReg(padapter, BIT3, 0);\r
766 //                      SetBcnCtrlReg(padapter, 0, BIT4);\r
767                 SetBcnCtrlReg(padapter, BIT(3), BIT(4));\r
768 \r
769                 // To make sure that if there exists an adapter which would like to send beacon.\r
770                 // If exists, the origianl value of 0x422[6] will be 1, we should check this to\r
771                 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause\r
772                 // the beacon cannot be sent by HW.\r
773                 // 2010.06.23. Added by tynli.\r
774                 if(bRecover)\r
775                 {\r
776                         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl | BIT(6));\r
777                         pHalData->RegFwHwTxQCtrl |= BIT(6);\r
778                 }\r
779 \r
780                 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.\r
781                 v8 = rtw_read8(padapter, REG_CR+1);\r
782                 v8 &= ~BIT(0); // ~ENSWBCN\r
783                 rtw_write8(padapter, REG_CR+1, v8);\r
784         }\r
785 \r
786         JoinBssRptParm.OpMode = mstatus;\r
787 \r
788         FillH2CCmd(padapter, JOINBSS_RPT_EID, sizeof(JoinBssRptParm), (u8 *)&JoinBssRptParm);\r
789 \r
790 _func_exit_;\r
791 }\r
792 \r
793 #ifdef CONFIG_BT_COEXIST\r
794 static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter)\r
795 {\r
796         PHAL_DATA_TYPE pHalData;\r
797         struct xmit_frame       *pmgntframe;\r
798         struct pkt_attrib       *pattrib;\r
799         struct xmit_priv        *pxmitpriv;\r
800         struct mlme_ext_priv    *pmlmeext;\r
801         struct mlme_ext_info    *pmlmeinfo;\r
802         u8      fakemac[6]={0x00,0xe0,0x4c,0x00,0x00,0x00};\r
803         u32     BeaconLength, ProbeRspLength, PSPollLength;\r
804         u32     NullDataLength, QosNullLength, BTQosNullLength;\r
805         u8      *ReservedPagePacket;\r
806         u8      PageNum, PageNeed, TxDescLen;\r
807         u16     BufIndex;\r
808         u32     TotalPacketLen;\r
809         RSVDPAGE_LOC    RsvdPageLoc;\r
810 \r
811 \r
812         DBG_871X("+%s\n", __FUNCTION__);\r
813 \r
814         ReservedPagePacket = (u8*)rtw_zmalloc(1024);\r
815         if (ReservedPagePacket == NULL) {\r
816                 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);\r
817                 return;\r
818         }\r
819 \r
820         pHalData = GET_HAL_DATA(padapter);\r
821         pxmitpriv = &padapter->xmitpriv;\r
822         pmlmeext = &padapter->mlmeextpriv;\r
823         pmlmeinfo = &pmlmeext->mlmext_info;\r
824 \r
825         TxDescLen = TXDESC_SIZE;\r
826         PageNum = 0;\r
827 \r
828         //3 (1) beacon\r
829         BufIndex = TXDESC_OFFSET;\r
830 #if 0\r
831         ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);\r
832 \r
833         // When we count the first page size, we need to reserve description size for the RSVD\r
834         // packet, it will be filled in front of the packet in TXPKTBUF.\r
835         PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength);\r
836         // To reserved 2 pages for beacon buffer. 2010.06.24.\r
837         if (PageNeed == 1)\r
838                 PageNeed += 1;\r
839 #else\r
840         // skip Beacon Packet\r
841         PageNeed = 3;\r
842 #endif\r
843 \r
844         PageNum += PageNeed;\r
845         pHalData->FwRsvdPageStartOffset = PageNum;\r
846 \r
847         BufIndex += PageNeed*128;\r
848 \r
849         //3 (2) ps-poll\r
850 #if 0 // skip\r
851         RsvdPageLoc.LocPsPoll = PageNum;\r
852         ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength);\r
853         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE, _FALSE);\r
854 \r
855         PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength);\r
856         PageNum += PageNeed;\r
857 \r
858         BufIndex += PageNeed*128;\r
859 #endif\r
860 \r
861         //3 (3) null data\r
862         RsvdPageLoc.LocNullData = PageNum;\r
863         ConstructNullFunctionData(\r
864                 padapter,\r
865                 &ReservedPagePacket[BufIndex],\r
866                 &NullDataLength,\r
867                 fakemac,\r
868                 _FALSE, 0, 0, _FALSE);\r
869         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, _FALSE, _FALSE);\r
870 \r
871         PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength);\r
872         PageNum += PageNeed;\r
873 \r
874         BufIndex += PageNeed*128;\r
875 \r
876         //3 (4) probe response\r
877 #if 0 // skip\r
878         RsvdPageLoc.LocProbeRsp = PageNum;\r
879         ConstructProbeRsp(\r
880                 padapter,\r
881                 &ReservedPagePacket[BufIndex],\r
882                 &ProbeRspLength,\r
883                 get_my_bssid(&pmlmeinfo->network),\r
884                 _FALSE);\r
885         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE, _FALSE);\r
886 \r
887         PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength);\r
888         PageNum += PageNeed;\r
889 \r
890         BufIndex += PageNeed*128;\r
891 #endif\r
892 \r
893         //3 (5) Qos null data\r
894 #if 0 // skip\r
895         RsvdPageLoc.LocQosNull = PageNum;\r
896         ConstructNullFunctionData(\r
897                 padapter, \r
898                 &ReservedPagePacket[BufIndex],\r
899                 &QosNullLength,\r
900                 get_my_bssid(&pmlmeinfo->network),\r
901                 _TRUE, 0, 0, _FALSE);\r
902         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, _FALSE, _FALSE);\r
903 \r
904         PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength);\r
905         PageNum += PageNeed;\r
906 \r
907         BufIndex += PageNeed*128;\r
908 #endif\r
909 \r
910         //3 (6) BT Qos null data\r
911         RsvdPageLoc.LocBTQosNull = PageNum;\r
912         ConstructNullFunctionData(\r
913                 padapter, \r
914                 &ReservedPagePacket[BufIndex],\r
915                 &BTQosNullLength,\r
916                 fakemac,\r
917                 _TRUE, 0, 0, _FALSE);\r
918         rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE);\r
919 \r
920         TotalPacketLen = BufIndex + BTQosNullLength;\r
921 \r
922         pmgntframe = alloc_mgtxmitframe(pxmitpriv);\r
923         if (pmgntframe == NULL)\r
924                 goto exit;\r
925 \r
926         // update attribute\r
927         pattrib = &pmgntframe->attrib;\r
928         update_mgntframe_attrib(padapter, pattrib);\r
929         pattrib->qsel = 0x10;\r
930         pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET;\r
931         _rtw_memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen);\r
932 \r
933         rtw_hal_mgnt_xmit(padapter, pmgntframe);\r
934 \r
935         DBG_8192C("%s: Set RSVD page location to Fw\n", __FUNCTION__);\r
936         FillH2CCmd(padapter, RSVD_PAGE_EID, sizeof(RsvdPageLoc), (u8*)&RsvdPageLoc);\r
937 \r
938 exit:\r
939         rtw_mfree(ReservedPagePacket, 1024);\r
940 }\r
941 \r
942 void rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(PADAPTER padapter)\r
943 {\r
944         PHAL_DATA_TYPE pHalData;\r
945         u8 bRecover = _FALSE;\r
946 \r
947 \r
948         DBG_8192C("+%s\n", __FUNCTION__);\r
949 \r
950         pHalData = GET_HAL_DATA(padapter);\r
951 \r
952         // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.\r
953         if (pHalData->RegFwHwTxQCtrl & BIT(6))\r
954                 bRecover = _TRUE;\r
955 \r
956         // To tell Hw the packet is not a real beacon frame.\r
957         pHalData->RegFwHwTxQCtrl &= ~BIT(6);\r
958         rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);\r
959         SetFwRsvdPagePkt_BTCoex(padapter);\r
960 \r
961         // To make sure that if there exists an adapter which would like to send beacon.\r
962         // If exists, the origianl value of 0x422[6] will be 1, we should check this to\r
963         // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause\r
964         // the beacon cannot be sent by HW.\r
965         // 2010.06.23. Added by tynli.\r
966         if (bRecover)\r
967         {\r
968                 pHalData->RegFwHwTxQCtrl |= BIT(6);\r
969                 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);\r
970         }\r
971 }\r
972 #endif\r
973 \r
974 #ifdef CONFIG_P2P_PS\r
975 void rtl8192c_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state)\r
976 {\r
977         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);\r
978         struct pwrctrl_priv             *pwrpriv = adapter_to_pwrctl(padapter);\r
979         struct wifidirect_info  *pwdinfo = &( padapter->wdinfo );\r
980         struct P2P_PS_Offload_t *p2p_ps_offload = &pHalData->p2p_ps_offload;\r
981         u8      i;\r
982 \r
983 _func_enter_;\r
984 \r
985         switch(p2p_ps_state)\r
986         {\r
987                 case P2P_PS_DISABLE:\r
988                         DBG_8192C("P2P_PS_DISABLE \n");\r
989                         _rtw_memset(p2p_ps_offload, 0 ,1);\r
990                         break;\r
991                 case P2P_PS_ENABLE:\r
992                         DBG_8192C("P2P_PS_ENABLE \n");\r
993                         // update CTWindow value.\r
994                         if( pwdinfo->ctwindow > 0 )\r
995                         {\r
996                                 p2p_ps_offload->CTWindow_En = 1;\r
997                                 rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);\r
998                         }\r
999 \r
1000                         // hw only support 2 set of NoA\r
1001                         for( i=0 ; i<pwdinfo->noa_num ; i++)\r
1002                         {\r
1003                                 // To control the register setting for which NOA\r
1004                                 rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));\r
1005                                 if(i == 0)\r
1006                                         p2p_ps_offload->NoA0_En = 1;\r
1007                                 else\r
1008                                         p2p_ps_offload->NoA1_En = 1;\r
1009 \r
1010                                 // config P2P NoA Descriptor Register\r
1011                                 //DBG_8192C("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]);\r
1012                                 rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);\r
1013 \r
1014                                 //DBG_8192C("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]);\r
1015                                 rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);\r
1016 \r
1017                                 //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]);\r
1018                                 rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);\r
1019 \r
1020                                 //DBG_8192C("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]);\r
1021                                 rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);\r
1022                         }\r
1023 \r
1024                         if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) )\r
1025                         {\r
1026                                 // rst p2p circuit\r
1027                                 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));\r
1028 \r
1029                                 p2p_ps_offload->Offload_En = 1;\r
1030 \r
1031                                 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))\r
1032                                 {\r
1033                                         p2p_ps_offload->role= 1;\r
1034                                         p2p_ps_offload->AllStaSleep = 0;\r
1035                                 }\r
1036                                 else\r
1037                                 {\r
1038                                         p2p_ps_offload->role= 0;\r
1039                                 }\r
1040 \r
1041                                 p2p_ps_offload->discovery = 0;\r
1042                         }\r
1043                         break;\r
1044                 case P2P_PS_SCAN:\r
1045                         DBG_8192C("P2P_PS_SCAN \n");\r
1046                         p2p_ps_offload->discovery = 1;\r
1047                         break;\r
1048                 case P2P_PS_SCAN_DONE:\r
1049                         DBG_8192C("P2P_PS_SCAN_DONE \n");\r
1050                         p2p_ps_offload->discovery = 0;\r
1051                         pwdinfo->p2p_ps_state = P2P_PS_ENABLE;\r
1052                         break;\r
1053                 default:\r
1054                         break;\r
1055         }\r
1056 \r
1057         FillH2CCmd(padapter, P2P_PS_OFFLOAD_EID, 1, (u8 *)p2p_ps_offload);\r
1058 \r
1059 _func_exit_;\r
1060 \r
1061 }\r
1062 #endif //CONFIG_P2P_PS\r
1063 \r
1064 #ifdef CONFIG_IOL\r
1065 #include <rtw_iol.h>\r
1066 #ifdef CONFIG_USB_HCI\r
1067 #include <usb_ops.h>\r
1068 #endif\r
1069 int rtl8192c_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)\r
1070 {\r
1071         IO_OFFLOAD_LOC  IoOffloadLoc;\r
1072         u32 start_time = rtw_get_current_time();\r
1073         u32 passing_time_ms;\r
1074         u8 polling_ret;\r
1075         int ret = _FAIL;\r
1076 \r
1077         if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)\r
1078                 goto exit;\r
1079 #ifdef CONFIG_USB_HCI\r
1080         {\r
1081                 struct pkt_attrib       *pattrib = &xmit_frame->attrib;         \r
1082                 if(rtw_usb_bulk_size_boundary(adapter,TXDESC_SIZE+pattrib->last_txcmdsz))\r
1083                 {\r
1084                         if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS)\r
1085                                 goto exit;\r
1086                 }                       \r
1087         }\r
1088 #endif //CONFIG_USB_HCI \r
1089 \r
1090         \r
1091         dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms);\r
1092 \r
1093         IoOffloadLoc.LocCmd = 0;\r
1094         if(_SUCCESS != FillH2CCmd(adapter, H2C_92C_IO_OFFLOAD, sizeof(IO_OFFLOAD_LOC), (u8 *)&IoOffloadLoc))\r
1095                 goto exit;\r
1096 \r
1097         //polling if the IO offloading is done\r
1098         while( (passing_time_ms=rtw_get_passing_time_ms(start_time)) <= max_wating_ms) {\r
1099                 #if 0 //C2H\r
1100                 if(0xff == rtw_read8(adapter, REG_C2HEVT_CLEAR))\r
1101                         break;\r
1102                 #else// 0x1c3\r
1103                 if(0x00 != (polling_ret=rtw_read8(adapter, 0x1c3)))\r
1104                         break;\r
1105                 #endif\r
1106                 rtw_msleep_os(5);\r
1107         }\r
1108         #if 0 //debug\r
1109         DBG_871X("IOL %s, polling_ret:0x%02x, 0x1c0=0x%08x, 0x1c4=0x%08x, 0x1cc=0x%08x, 0x1e8=0x%08x, 0x130=0x%08x, 0x134=0x%08x\n"\r
1110                         , polling_ret==0xff?"success":"error"\r
1111                         , polling_ret\r
1112                         , rtw_read32(adapter, 0x1c0)\r
1113                         , rtw_read32(adapter, 0x1c4)\r
1114                         , rtw_read32(adapter, 0x1cc)\r
1115                         , rtw_read32(adapter, 0x1e8)\r
1116                         , rtw_read32(adapter, 0x130)\r
1117                         , rtw_read32(adapter, 0x134)\r
1118         );\r
1119         rtw_write32(adapter, 0x1c0, 0x0);\r
1120         #endif\r
1121 \r
1122         if(polling_ret == 0xff)\r
1123                 ret =_SUCCESS;\r
1124         else {\r
1125                 DBG_871X("IOL %s, polling_ret:0x%02x\n"\r
1126                         //", 0x1c0=0x%08x, 0x1c4=0x%08x, 0x1cc=0x%08x, 0x1e8=0x%08x, 0x130=0x%08x, 0x134=0x%08x\n"\r
1127                         , polling_ret==0xff?"success":"error"\r
1128                         , polling_ret\r
1129                         //, rtw_read32(adapter, 0x1c0)\r
1130                         //, rtw_read32(adapter, 0x1c4)\r
1131                         //, rtw_read32(adapter, 0x1cc)\r
1132                         //, rtw_read32(adapter, 0x1e8)\r
1133                         //, rtw_read32(adapter, 0x130)\r
1134                         //, rtw_read32(adapter, 0x134)\r
1135                 );\r
1136                 #if 0 //debug\r
1137                 rtw_write16(adapter, 0x1c4, 0x0000); \r
1138                 rtw_msleep_os(10);\r
1139                 DBG_871X("after reset, 0x1c4=0x%08x\n", rtw_read32(adapter, 0x1c4));\r
1140                 #endif\r
1141 \r
1142         }\r
1143 \r
1144         {\r
1145                 #if 0 //C2H\r
1146                 u32 c2h_evt;\r
1147                 int i;\r
1148                 c2h_evt = rtw_read32(adapter, REG_C2HEVT_MSG_NORMAL);\r
1149                 DBG_871X("%s io-offloading complete, in %ums: 0x%08x\n", __FUNCTION__, passing_time_ms, c2h_evt);\r
1150                 rtw_write8(adapter, REG_C2HEVT_CLEAR, 0x0);\r
1151                 #else// 0x1c3\r
1152                 //DBG_871X("%s IOF complete in %ums\n", __FUNCTION__, passing_time_ms);\r
1153                 rtw_write8(adapter, 0x1c3, 0x0);\r
1154                 #endif\r
1155         }\r
1156 \r
1157 exit:\r
1158         return ret;\r
1159 \r
1160 }\r
1161 #endif //CONFIG_IOL\r
1162 \r
1163 #ifdef CONFIG_TSF_RESET_OFFLOAD\r
1164 /*\r
1165         ask FW to Reset sync register at Beacon early interrupt\r
1166 */\r
1167 u8 rtl8723c_reset_tsf(_adapter *padapter, u8 reset_port )\r
1168 {       \r
1169         u8      buf[2];\r
1170         u8      res=_SUCCESS;\r
1171         \r
1172 _func_enter_;\r
1173         if (IFACE_PORT0==reset_port) {\r
1174                 buf[0] = 0x1; buf[1] = 0;\r
1175         \r
1176         } else{\r
1177                 buf[0] = 0x0; buf[1] = 0x1;\r
1178         }\r
1179         FillH2CCmd(padapter, H2C_RESET_TSF, 2, buf);\r
1180 _func_exit_;\r
1181 \r
1182         return res;\r
1183 }\r
1184 #endif  // CONFIG_TSF_RESET_OFFLOAD\r
1185 \r