8feb6f545153781303df3c34d94f6f8b0af84da4
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / mt5931_kk / drv_wlan / mgmt / p2p_func.c
1 #include "precomp.h"
2 #ifdef CFG_DUAL_ANTENNA
3 #include "mtk_porting.h"
4 #include "dual_ant_bwcs.h"
5 #endif
6
7
8 APPEND_VAR_ATTRI_ENTRY_T txAssocRspAttributesTable[] = {
9      { (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS)   ,    NULL,                           p2pFuncAppendAttriStatusForAssocRsp        }  /* 0 */                 // Status
10     ,{ (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING),    NULL,                           p2pFuncAppendAttriExtListenTiming   }  /* 8 */
11 };
12
13
14 APPEND_VAR_IE_ENTRY_T txProbeRspIETable[] = {
15     { (ELEM_HDR_LEN + (RATE_NUM - ELEM_MAX_LEN_SUP_RATES)), NULL,                           bssGenerateExtSuppRate_IE   }   /* 50 */
16    ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_ERP),                    NULL,                           rlmRspGenerateErpIE         }   /* 42 */
17    ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_CAP),                 NULL,                           rlmRspGenerateHtCapIE       }   /* 45 */
18    ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_HT_OP),                  NULL,                           rlmRspGenerateHtOpIE        }   /* 61 */
19    ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_RSN),                    NULL,                           rsnGenerateRSNIE            }   /* 48 */
20    ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_OBSS_SCAN),              NULL,                           rlmRspGenerateObssScanIE    }   /* 74 */
21    ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_EXT_CAP),                NULL,                           rlmRspGenerateExtCapIE      }   /* 127 */
22    ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_WPA),                    NULL,                           rsnGenerateWpaNoneIE        }   /* 221 */
23    ,{ (ELEM_HDR_LEN + ELEM_MAX_LEN_WMM_PARAM),              NULL,                           mqmGenerateWmmParamIE       }   /* 221 */
24 };
25
26 /*----------------------------------------------------------------------------*/
27 /*!
28 * @brief Function for requesting scan. There is an option to do ACTIVE or PASSIVE scan.
29 *
30 * @param eScanType - Specify the scan type of the scan request. It can be an ACTIVE/PASSIVE
31 *                                  Scan.
32 *              eChannelSet - Specify the prefered channel set.
33 *                                    A FULL scan would request a legacy full channel normal scan.(usually ACTIVE).
34 *                                    A P2P_SOCIAL scan would scan 1+6+11 channels.(usually ACTIVE)
35 *                                    A SPECIFIC scan would only 1/6/11 channels scan. (Passive Listen/Specific Search)
36 *               ucChannelNum - A specific channel number. (Only when channel is specified)
37 *               eBand - A specific band. (Only when channel is specified)
38 *
39 *
40 * @return (none)
41 */
42 /*----------------------------------------------------------------------------*/
43 VOID
44 p2pFuncRequestScan (
45     IN P_ADAPTER_T prAdapter,
46     IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo
47     )
48 {
49
50     P_MSG_SCN_SCAN_REQ prScanReq = (P_MSG_SCN_SCAN_REQ)NULL;
51
52     DEBUGFUNC("p2pFuncRequestScan()");
53
54     do {
55         ASSERT_BREAK((prAdapter != NULL) &&
56                         (prScanReqInfo != NULL));
57
58         if (prScanReqInfo->eChannelSet == SCAN_CHANNEL_SPECIFIED) {
59             ASSERT_BREAK(prScanReqInfo->ucNumChannelList > 0);
60             DBGLOG(P2P, LOUD, ("P2P Scan Request Channel:%d\n", prScanReqInfo->arScanChannelList[0].ucChannelNum));
61         }
62
63         prScanReq = (P_MSG_SCN_SCAN_REQ)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_REQ));
64         if (!prScanReq) {
65             ASSERT(0); // Can't trigger SCAN FSM
66             break;
67         }
68
69         prScanReq->rMsgHdr.eMsgId    = MID_P2P_SCN_SCAN_REQ;
70         prScanReq->ucSeqNum          = ++prScanReqInfo->ucSeqNumOfScnMsg;
71         prScanReq->ucNetTypeIndex    = (UINT_8)NETWORK_TYPE_P2P_INDEX;
72         prScanReq->eScanType        = prScanReqInfo->eScanType;
73         prScanReq->eScanChannel     = prScanReqInfo->eChannelSet;
74         prScanReq->u2IELen = 0;
75
76         /* Copy IE for Probe Request. */
77         kalMemCopy(prScanReq->aucIE, prScanReqInfo->aucIEBuf, prScanReqInfo->u4BufLength);
78         prScanReq->u2IELen = (UINT_16)prScanReqInfo->u4BufLength;
79
80         prScanReq->u2ChannelDwellTime = prScanReqInfo->u2PassiveDewellTime;
81
82         switch (prScanReqInfo->eChannelSet) {
83         case SCAN_CHANNEL_SPECIFIED:
84             {
85                 UINT_32 u4Idx = 0;
86                 P_RF_CHANNEL_INFO_T prDomainInfo = (P_RF_CHANNEL_INFO_T)prScanReqInfo->arScanChannelList;
87
88                 if (prScanReqInfo->ucNumChannelList > MAXIMUM_OPERATION_CHANNEL_LIST) {
89                     prScanReqInfo->ucNumChannelList = MAXIMUM_OPERATION_CHANNEL_LIST;
90                 }
91
92
93                 for (u4Idx = 0; u4Idx < prScanReqInfo->ucNumChannelList; u4Idx++) {
94                     prScanReq->arChnlInfoList[u4Idx].ucChannelNum = prDomainInfo->ucChannelNum;
95                     prScanReq->arChnlInfoList[u4Idx].eBand = prDomainInfo->eBand;
96                     prDomainInfo++;
97                 }
98
99                 prScanReq->ucChannelListNum = prScanReqInfo->ucNumChannelList;
100             }
101         case SCAN_CHANNEL_FULL:
102         case SCAN_CHANNEL_2G4:
103         case SCAN_CHANNEL_P2P_SOCIAL:
104             {
105                 UINT_8 aucP2pSsid[] = P2P_WILDCARD_SSID;
106
107                 COPY_SSID(prScanReq->aucSSID,
108                                     prScanReq->ucSSIDLength,
109                                     prScanReqInfo->rSsidStruct.aucSsid,
110                                     prScanReqInfo->rSsidStruct.ucSsidLen);
111
112                 /* For compatible. */
113                 if (EQUAL_SSID(aucP2pSsid, P2P_WILDCARD_SSID_LEN, prScanReq->aucSSID, prScanReq->ucSSIDLength)) {
114                     prScanReq->ucSSIDType = SCAN_REQ_SSID_P2P_WILDCARD;
115                 }
116                 else if (prScanReq->ucSSIDLength != 0) {
117                     prScanReq->ucSSIDType = SCAN_REQ_SSID_SPECIFIED;
118                 }
119             }
120             break;
121         default:
122             /* Currently there is no other scan channel set. */
123             ASSERT(FALSE);
124             break;
125         }
126
127         mboxSendMsg(prAdapter,
128                     MBOX_ID_0,
129                     (P_MSG_HDR_T)prScanReq,
130                     MSG_SEND_METHOD_BUF);
131
132     } while (FALSE);
133
134     return;
135 } /* p2pFuncRequestScan */
136
137 VOID
138 p2pFuncCancelScan (
139     IN P_ADAPTER_T prAdapter,
140     IN P_P2P_SCAN_REQ_INFO_T prScanInfo
141     )
142 {
143     P_MSG_SCN_SCAN_CANCEL prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL)NULL;
144
145     do {
146         ASSERT_BREAK((prAdapter != NULL) && (prScanInfo != NULL));
147
148         if (!prScanInfo->fgIsScanRequest) {
149             break;
150         }
151
152
153         if (prScanInfo->ucSeqNumOfScnMsg) {
154             /* There is a channel privilege on hand. */
155             DBGLOG(P2P, TRACE, ("P2P Cancel Scan\n"));
156
157             prScanCancelMsg = (P_MSG_SCN_SCAN_CANCEL)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_SCN_SCAN_CANCEL));
158             if (!prScanCancelMsg) {
159                 /* Buffer not enough, can not cancel scan request. */
160                 DBGLOG(P2P, TRACE, ("Buffer not enough, can not cancel scan.\n"));
161                 ASSERT(FALSE);
162                 break;
163             }
164
165             prScanCancelMsg->rMsgHdr.eMsgId = MID_P2P_SCN_SCAN_CANCEL;
166             prScanCancelMsg->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
167             prScanCancelMsg->ucSeqNum = prScanInfo->ucSeqNumOfScnMsg++;
168             prScanCancelMsg->fgIsChannelExt = FALSE;
169             prScanInfo->fgIsScanRequest = FALSE;
170
171             mboxSendMsg(prAdapter,
172                                 MBOX_ID_0,
173                                 (P_MSG_HDR_T)prScanCancelMsg,
174                                 MSG_SEND_METHOD_BUF);
175
176
177         }
178
179
180     } while (FALSE);
181
182     return;
183 } /* p2pFuncCancelScan */
184
185
186 VOID
187 p2pFuncSwitchOPMode (
188     IN P_ADAPTER_T prAdapter,
189     IN P_BSS_INFO_T prP2pBssInfo,
190     IN ENUM_OP_MODE_T eOpMode,
191     IN BOOLEAN fgSyncToFW
192     )
193 {
194     do {
195         ASSERT_BREAK((prAdapter != NULL) &&
196                                             (prP2pBssInfo != NULL) &&
197                                             (eOpMode < OP_MODE_NUM));
198
199         if (prP2pBssInfo->eCurrentOPMode != eOpMode) {
200             DBGLOG(P2P, TRACE, ("p2pFuncSwitchOPMode: Switch to from %d, to %d.\n", prP2pBssInfo->eCurrentOPMode, eOpMode));
201
202             switch (prP2pBssInfo->eCurrentOPMode) {
203             case OP_MODE_ACCESS_POINT:
204                 p2pFuncDissolve(prAdapter, prP2pBssInfo, TRUE, REASON_CODE_DEAUTH_LEAVING_BSS);
205 printk("p2pFuncSwitchOPMode p2pFsmRunEventStopAP");
206                 p2pFsmRunEventStopAP(prAdapter, NULL);
207                 break;
208             default:
209                 break;
210             }
211
212
213
214             prP2pBssInfo->eIntendOPMode = eOpMode;
215             prP2pBssInfo->eCurrentOPMode = eOpMode;
216             switch (eOpMode) {
217             case OP_MODE_INFRASTRUCTURE:
218                 DBGLOG(P2P, TRACE, ("p2pFuncSwitchOPMode: Switch to Client.\n"));
219             case OP_MODE_ACCESS_POINT:
220 //                if (!IS_BSS_ACTIVE(prP2pBssInfo)) {
221 //                    SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX);
222 //                    nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
223 //                }
224
225                 /* Change interface address. */
226                 if (eOpMode == OP_MODE_ACCESS_POINT) {
227                     DBGLOG(P2P, TRACE, ("p2pFuncSwitchOPMode: Switch to AP.\n"));
228                     prP2pBssInfo->ucSSIDLen = 0;
229                 }
230
231                 COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucInterfaceAddress);
232                 COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucInterfaceAddress);
233
234
235                 break;
236             case OP_MODE_P2P_DEVICE:
237                 {
238                     /* Change device address. */
239                     DBGLOG(P2P, TRACE, ("p2pFuncSwitchOPMode: Switch back to P2P Device.\n"));
240
241 //                    if (!IS_BSS_ACTIVE(prP2pBssInfo)) {
242 //                        SET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX);
243 //                        nicActivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
244 //                    }
245
246                     p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
247
248                     COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prAdapter->rWifiVar.aucDeviceAddress);
249                     COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAdapter->rWifiVar.aucDeviceAddress);
250
251
252                 }
253                 break;
254             default:
255 //                if (IS_BSS_ACTIVE(prP2pBssInfo)) {
256 //                    UNSET_NET_ACTIVE(prAdapter, NETWORK_TYPE_P2P_INDEX);
257                     
258 //                    nicDeactivateNetwork(prAdapter, NETWORK_TYPE_P2P_INDEX);
259 //                }
260                 ASSERT(FALSE);
261                 break;
262             }
263
264             if (1) {
265                 P2P_DISCONNECT_INFO rP2PDisInfo;
266
267                 rP2PDisInfo.ucRole = 2;
268                 wlanSendSetQueryCmd(prAdapter,
269                                 CMD_ID_P2P_ABORT,
270                                 TRUE,
271                                 FALSE,
272                                 FALSE,
273                                 NULL,
274                                 NULL,
275                                 sizeof(P2P_DISCONNECT_INFO),
276                                 (PUINT_8)&rP2PDisInfo,
277                                 NULL,
278                                 0);
279             }
280
281
282             DBGLOG(P2P, TRACE, ("The device address is changed to " MACSTR " \n", MAC2STR(prP2pBssInfo->aucOwnMacAddr)));
283             DBGLOG(P2P, TRACE, ("The BSSID is changed to " MACSTR " \n", MAC2STR(prP2pBssInfo->aucBSSID)));
284
285             /* Update BSS INFO to FW. */
286             if ((fgSyncToFW) && (eOpMode != OP_MODE_ACCESS_POINT)) {
287                 nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
288             }
289         }
290
291     } while (FALSE);
292
293     return;
294 } /* p2pFuncSwitchOPMode */
295
296
297
298 /*----------------------------------------------------------------------------*/
299 /*!
300 * @brief This function will start a P2P Group Owner and send Beacon Frames.
301 *
302 * @param (none)
303 *
304 * @return (none)
305 */
306 /*----------------------------------------------------------------------------*/
307 VOID
308 p2pFuncStartGO (
309     IN P_ADAPTER_T prAdapter,
310     IN P_BSS_INFO_T prBssInfo,
311     IN PUINT_8 pucSsidBuf,
312     IN UINT_8 ucSsidLen,
313     IN UINT_8 ucChannelNum,
314     IN ENUM_BAND_T eBand,
315     IN ENUM_CHNL_EXT_T eSco,
316     IN BOOLEAN fgIsPureAP
317     )
318 {
319     do {
320         ASSERT_BREAK((prAdapter != NULL) && (prBssInfo != NULL));
321
322         //ASSERT(prBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT);
323
324         DBGLOG(P2P, TRACE, ("p2pFuncStartGO:\n"));
325
326         /* AP mode started. */
327         p2pFuncSwitchOPMode(prAdapter, prBssInfo, prBssInfo->eIntendOPMode, FALSE);
328
329         prBssInfo->eIntendOPMode = OP_MODE_NUM;
330
331         //4 <1.1> Assign SSID
332         COPY_SSID(prBssInfo->aucSSID,
333                         prBssInfo->ucSSIDLen,
334                         pucSsidBuf,
335                         ucSsidLen);
336
337         DBGLOG(P2P, TRACE, ("GO SSID:%s \n", prBssInfo->aucSSID));
338
339         //4 <1.2> Clear current AP's STA_RECORD_T and current AID
340         prBssInfo->prStaRecOfAP = (P_STA_RECORD_T)NULL;
341         prBssInfo->u2AssocId = 0;
342
343
344         //4 <1.3> Setup Channel, Band and Phy Attributes
345         prBssInfo->ucPrimaryChannel = ucChannelNum;
346         prBssInfo->eBand = eBand;
347         prBssInfo->eBssSCO = eSco;
348
349         DBGLOG(P2P, TRACE, ("GO Channel:%d \n", ucChannelNum));
350
351
352         if (prBssInfo->eBand == BAND_5G) {
353             prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AN); /* Depend on eBand */
354             prBssInfo->ucConfigAdHocAPMode = AP_MODE_11A; /* Depend on eCurrentOPMode and ucPhyTypeSet */
355         }
356         else if (fgIsPureAP) {
357             prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11BGN); /* Depend on eBand */
358             prBssInfo->ucConfigAdHocAPMode = AP_MODE_MIXED_11BG; /* Depend on eCurrentOPMode and ucPhyTypeSet */
359         }
360         else {
361             prBssInfo->ucPhyTypeSet = (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11GN); /* Depend on eBand */
362             prBssInfo->ucConfigAdHocAPMode = AP_MODE_11G_P2P; /* Depend on eCurrentOPMode and ucPhyTypeSet */
363         }
364
365
366         prBssInfo->ucNonHTBasicPhyType = (UINT_8)
367                     rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].ePhyTypeIndex;
368         prBssInfo->u2BSSBasicRateSet =
369                     rNonHTApModeAttributes[prBssInfo->ucConfigAdHocAPMode].u2BSSBasicRateSet;
370         prBssInfo->u2OperationalRateSet =
371                     rNonHTPhyAttributes[prBssInfo->ucNonHTBasicPhyType].u2SupportedRateSet;
372
373         if (prBssInfo->ucAllSupportedRatesLen == 0) {
374             rateGetDataRatesFromRateSet(prBssInfo->u2OperationalRateSet,
375                                         prBssInfo->u2BSSBasicRateSet,
376                                         prBssInfo->aucAllSupportedRates,
377                                         &prBssInfo->ucAllSupportedRatesLen);
378         }
379
380         //4 <1.5> Setup MIB for current BSS
381         prBssInfo->u2ATIMWindow = 0;
382         prBssInfo->ucBeaconTimeoutCount = 0;
383
384         //3 <2> Update BSS_INFO_T common part
385 #if CFG_SUPPORT_AAA
386         if (!fgIsPureAP) {
387             prBssInfo->fgIsProtection = TRUE; /* Always enable protection at P2P GO */
388             kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP);
389         }
390         else {
391             if (kalP2PGetCipher(prAdapter->prGlueInfo))
392                 prBssInfo->fgIsProtection = TRUE;
393         }
394
395         // 20120106 frog: I want separate OP_Mode & Beacon TX Function.
396         //p2pFuncSwitchOPMode(prAdapter, prBssInfo, OP_MODE_ACCESS_POINT, FALSE);
397
398         bssInitForAP(prAdapter, prBssInfo, FALSE);
399
400         nicQmUpdateWmmParms(prAdapter, NETWORK_TYPE_P2P_INDEX);
401 #endif /* CFG_SUPPORT_AAA */
402
403
404         //3 <3> Set MAC HW
405         //4 <3.1> Setup channel and bandwidth
406         rlmBssInitForAPandIbss(prAdapter, prBssInfo);
407
408         //4 <3.2> Reset HW TSF Update Mode and Beacon Mode
409         nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
410
411         //4 <3.3> Update Beacon again for network phy type confirmed.
412         bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX);
413
414         //4 <3.4> Setup BSSID
415         nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX);
416
417     } while (FALSE);
418 #ifdef CFG_DUAL_ANTENNA
419         printk("p2pFuncStartGO\n");
420 #endif
421
422
423     return;
424 } /* p2pFuncStartGO() */
425
426
427
428
429 /*----------------------------------------------------------------------------*/
430 /*!
431 * \brief    This function is to inform CNM that channel privilege
432 *           has been released
433 *
434 * \param[in] prAdapter  Pointer of ADAPTER_T
435 *
436 * \return none
437 */
438 /*----------------------------------------------------------------------------*/
439 VOID
440 p2pFuncReleaseCh (
441     IN P_ADAPTER_T prAdapter,
442     IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo
443     )
444 {
445     P_MSG_CH_ABORT_T prMsgChRelease = (P_MSG_CH_ABORT_T)NULL;
446
447     DEBUGFUNC("p2pFuncReleaseCh()");
448
449     do {
450         ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL));
451
452         if (!prChnlReqInfo->fgIsChannelRequested) {
453             break;
454         }
455         else {
456             DBGLOG(P2P, TRACE, ("P2P Release Channel\n"));
457             prChnlReqInfo->fgIsChannelRequested = FALSE;
458         }
459
460          /* 1. return channel privilege to CNM immediately */
461         prMsgChRelease = (P_MSG_CH_ABORT_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_ABORT_T));
462         if (!prMsgChRelease) {
463             ASSERT(0); // Can't release Channel to CNM
464             break;
465         }
466
467         prMsgChRelease->rMsgHdr.eMsgId  = MID_MNY_CNM_CH_ABORT;
468         prMsgChRelease->ucNetTypeIndex  = NETWORK_TYPE_P2P_INDEX;
469         prMsgChRelease->ucTokenID       = prChnlReqInfo->ucSeqNumOfChReq++;
470
471         mboxSendMsg(prAdapter,
472                     MBOX_ID_0,
473                     (P_MSG_HDR_T) prMsgChRelease,
474                     MSG_SEND_METHOD_BUF);
475
476     } while (FALSE);
477
478     return;
479 } /* p2pFuncReleaseCh */
480
481
482 /*----------------------------------------------------------------------------*/
483 /*!
484 * @brief Process of CHANNEL_REQ_JOIN Initial. Enter CHANNEL_REQ_JOIN State.
485 *
486 * @param (none)
487 *
488 * @return (none)
489 */
490 /*----------------------------------------------------------------------------*/
491 VOID
492 p2pFuncAcquireCh (
493     IN P_ADAPTER_T prAdapter,
494     IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo
495     )
496 {
497     P_MSG_CH_REQ_T prMsgChReq = (P_MSG_CH_REQ_T)NULL;
498
499     do {
500         ASSERT_BREAK((prAdapter != NULL) && (prChnlReqInfo != NULL));
501
502         p2pFuncReleaseCh(prAdapter, prChnlReqInfo);
503
504         /* send message to CNM for acquiring channel */
505         prMsgChReq = (P_MSG_CH_REQ_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_CH_REQ_T));
506
507         if (!prMsgChReq) {
508             ASSERT(0); // Can't indicate CNM for channel acquiring
509             break;
510         }
511
512         prMsgChReq->rMsgHdr.eMsgId      = MID_MNY_CNM_CH_REQ;
513         prMsgChReq->ucNetTypeIndex      = NETWORK_TYPE_P2P_INDEX;
514         prMsgChReq->ucTokenID           = ++prChnlReqInfo->ucSeqNumOfChReq;
515         prMsgChReq->eReqType            = CH_REQ_TYPE_JOIN;
516         prMsgChReq->u4MaxInterval       = prChnlReqInfo->u4MaxInterval;
517
518         prMsgChReq->ucPrimaryChannel    = prChnlReqInfo->ucReqChnlNum;
519         prMsgChReq->eRfSco              = prChnlReqInfo->eChnlSco;
520         prMsgChReq->eRfBand             = prChnlReqInfo->eBand;
521
522         kalMemZero(prMsgChReq->aucBSSID, MAC_ADDR_LEN);
523
524         /* Channel request join BSSID. */
525
526         mboxSendMsg(prAdapter,
527                     MBOX_ID_0,
528                     (P_MSG_HDR_T) prMsgChReq,
529                     MSG_SEND_METHOD_BUF);
530
531         prChnlReqInfo->fgIsChannelRequested = TRUE;
532
533     } while (FALSE);
534
535     return;
536 } /* p2pFuncAcquireCh */
537
538 #if 0
539 WLAN_STATUS
540 p2pFuncBeaconUpdate(
541     IN P_ADAPTER_T prAdapter,
542     IN PUINT_8 pucBcnHdr,
543     IN UINT_32 u4HdrLen,
544     IN PUINT_8 pucBcnBody,
545     IN UINT_32 u4BodyLen,
546     IN UINT_32 u4DtimPeriod,
547     IN UINT_32 u4BcnInterval)
548 {
549     WLAN_STATUS rResultStatus = WLAN_STATUS_INVALID_DATA;
550     P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T)NULL;
551     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
552     P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T)NULL;
553     PUINT_8 pucTIMBody = (PUINT_8)NULL;
554     UINT_16 u2FrameLength = 0, UINT_16 u2OldBodyLen = 0;
555     UINT_8 aucIEBuf[MAX_IE_LENGTH];
556
557     do {
558         ASSERT_BREAK(prAdapter != NULL);
559
560         prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
561         prBcnMsduInfo = prP2pBssInfo->prBeacon
562
563         ASSERT_BREAK(prBcnMsduInfo != NULL);
564
565         /* TODO: Find TIM IE pointer. */
566         prBcnFrame = prBcnMsduInfo->prPacket;
567
568         ASSERT_BREAK(prBcnFrame != NULL);
569
570         do {
571             /* Ori header. */
572             UINT_16 u2IELength = 0, u2Offset = 0;
573             PUINT_8 pucIEBuf = prBcnFrame->aucInfoElem;
574
575             u2IELength = prBcnMsduInfo->u2FrameLength - prBcnMsduInfo->ucMacHeaderLength;
576
577             IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) {
578                 if ((IE_ID(pucIEBuf) == ELEM_ID_TIM) ||
579                         ((IE_ID(pucIEBuf) > ELEM_ID_IBSS_PARAM_SET))  {
580                     pucTIMBody = pucIEBuf;
581                     break
582                 }
583                 u2FrameLength += IE_SIZE(pucIEBuf);
584             }
585
586             if (pucTIMBody == NULL) {
587                 pucTIMBody = pucIEBuf;
588             }
589
590              /* Body not change. */
591             u2OldBodyLen = (UINT_16)((UINT_32)pucTIMBody - (UINT_32)prBcnFrame->aucInfoElem);
592
593             // Move body.
594             kalMemCmp(aucIEBuf, pucTIMBody, u2OldBodyLen);
595         } while (FALSE);
596
597
598         if (pucBcnHdr) {
599             kalMemCopy(prBcnMsduInfo->prPacket, pucBcnHdr, u4HdrLen);
600
601             pucTIMBody = (PUINT_8)((UINT_32)prBcnMsduInfo->prPacket + u4HdrLen);
602
603             prBcnMsduInfo->ucMacHeaderLength = (WLAN_MAC_MGMT_HEADER_LEN +
604                 (TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN));
605
606             u2FrameLength = u4HdrLen; /* Header + Partial Body. */
607
608         }
609         else {
610             /* Header not change. */
611             u2FrameLength += prBcnMsduInfo->ucMacHeaderLength;
612         }
613
614
615         if (pucBcnBody) {
616             kalMemCopy(pucTIMBody, pucBcnBody, u4BodyLen);
617             u2FrameLength += (UINT_16)u4BodyLen;
618         }
619         else {
620             kalMemCopy(pucTIMBody, aucIEBuf, u2OldBodyLen);
621             u2FrameLength += u2OldBodyLen;
622         }
623
624         /* Frame Length */
625         prBcnMsduInfo->u2FrameLength = u2FrameLength;
626
627         prBcnMsduInfo->fgIs802_11 = TRUE;
628         prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
629
630         prP2pBssInfo->u2BeaconInterval = (UINT_16)u4BcnInterval;
631         prP2pBssInfo->ucDTIMPeriod = (UINT_8)u4DtimPeriod;
632         prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo;
633         prBcnMsduInfo->ucPacketType = 3;
634
635         rResultStatus = nicUpdateBeaconIETemplate(prAdapter,
636                                         IE_UPD_METHOD_UPDATE_ALL,
637                                         NETWORK_TYPE_P2P_INDEX,
638                                         prP2pBssInfo->u2CapInfo,
639                                         (PUINT_8)prBcnFrame->aucInfoElem,
640                                         prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem));
641
642         if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
643             /* AP is created, Beacon Update. */
644             nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX);
645
646             nicPmIndicateBssCreated(prAdapter, NETWORK_TYPE_P2P_INDEX);
647         }
648
649     } while (FALSE);
650
651     return rResultStatus;
652 } /* p2pFuncBeaconUpdate */
653
654 #else
655 WLAN_STATUS
656 p2pFuncBeaconUpdate (
657     IN P_ADAPTER_T prAdapter,
658     IN P_BSS_INFO_T prP2pBssInfo,
659     IN P_P2P_BEACON_UPDATE_INFO_T prBcnUpdateInfo,
660     IN PUINT_8 pucNewBcnHdr,
661     IN UINT_32 u4NewHdrLen,
662     IN PUINT_8 pucNewBcnBody,
663     IN UINT_32 u4NewBodyLen
664     )
665 {
666     WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
667     P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T)NULL;
668     P_MSDU_INFO_T prBcnMsduInfo = (P_MSDU_INFO_T)NULL;
669     PUINT_8 pucIEBuf = (PUINT_8)NULL;
670     UINT_8 aucIEBuf[MAX_IE_LENGTH];
671
672     do {
673         ASSERT_BREAK((prAdapter != NULL) &&
674                 (prP2pBssInfo != NULL) &&
675                 (prBcnUpdateInfo != NULL));
676
677         prBcnMsduInfo = prP2pBssInfo->prBeacon;
678
679 #if DBG
680         if (prBcnUpdateInfo->pucBcnHdr != NULL) {
681             ASSERT((UINT_32)prBcnUpdateInfo->pucBcnHdr == ((UINT_32)prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD));
682         }
683
684         if (prBcnUpdateInfo->pucBcnBody != NULL) {
685             ASSERT((UINT_32)prBcnUpdateInfo->pucBcnBody == ((UINT_32)prBcnUpdateInfo->pucBcnHdr + (UINT_32)prBcnUpdateInfo->u4BcnHdrLen));
686         }
687 #endif
688         prBcnFrame = (P_WLAN_BEACON_FRAME_T)((UINT_32)prBcnMsduInfo->prPacket + MAC_TX_RESERVED_FIELD);
689
690         if (!pucNewBcnBody) {
691             /* Old body. */
692             pucNewBcnBody = prBcnUpdateInfo->pucBcnBody;
693             ASSERT(u4NewBodyLen == 0);
694             u4NewBodyLen = prBcnUpdateInfo->u4BcnBodyLen;
695         }
696         else {
697             prBcnUpdateInfo->u4BcnBodyLen = u4NewBodyLen;
698         }
699
700         /* Temp buffer body part. */
701         kalMemCopy(aucIEBuf, pucNewBcnBody, u4NewBodyLen);
702
703         if (pucNewBcnHdr) {
704             kalMemCopy(prBcnFrame, pucNewBcnHdr, u4NewHdrLen);
705             prBcnUpdateInfo->pucBcnHdr = (PUINT_8)prBcnFrame;
706             prBcnUpdateInfo->u4BcnHdrLen = u4NewHdrLen;
707         }
708
709         pucIEBuf = (PUINT_8)((UINT_32)prBcnUpdateInfo->pucBcnHdr + (UINT_32)prBcnUpdateInfo->u4BcnHdrLen);
710         kalMemCopy(pucIEBuf, aucIEBuf, u4NewBodyLen);
711         prBcnUpdateInfo->pucBcnBody = pucIEBuf;
712
713         /* Frame Length */
714         prBcnMsduInfo->u2FrameLength = (UINT_16)(prBcnUpdateInfo->u4BcnHdrLen + prBcnUpdateInfo->u4BcnBodyLen);
715
716         prBcnMsduInfo->ucPacketType = 3;
717         prBcnMsduInfo->fgIs802_11 = TRUE;
718         prBcnMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
719
720
721         /* Update BSS INFO related information. */
722         COPY_MAC_ADDR(prP2pBssInfo->aucOwnMacAddr, prBcnFrame->aucSrcAddr);
723         COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prBcnFrame->aucBSSID);
724         prP2pBssInfo->u2CapInfo = prBcnFrame->u2CapInfo;
725
726         p2pFuncParseBeaconContent(prAdapter,
727                             prP2pBssInfo,
728                             (PUINT_8)prBcnFrame->aucInfoElem,
729                             (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)));
730
731 #if 1
732         //bssUpdateBeaconContent(prAdapter, NETWORK_TYPE_P2P_INDEX);
733 #else
734         nicUpdateBeaconIETemplate(prAdapter,
735                                         IE_UPD_METHOD_UPDATE_ALL,
736                                         NETWORK_TYPE_P2P_INDEX,
737                                         prBcnFrame->u2CapInfo,
738                                         (PUINT_8)prBcnFrame->aucInfoElem,
739                                         (prBcnMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem)));
740 #endif
741     } while (FALSE);
742
743     return rWlanStatus;
744 } /* p2pFuncBeaconUpdate */
745
746 #endif
747
748 // TODO: We do not apply IE in deauth frame set from upper layer now.
749 WLAN_STATUS
750 p2pFuncDeauth (
751     IN P_ADAPTER_T prAdapter,
752     IN PUINT_8 pucPeerMacAddr,
753     IN UINT_16 u2ReasonCode,
754     IN PUINT_8 pucIEBuf,
755     IN UINT_16 u2IELen,
756     IN BOOLEAN fgSendDeauth
757     )
758 {
759     WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE;
760     P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T)NULL;
761     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
762     BOOLEAN fgIsStaFound = FALSE;
763
764     do {
765         ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL));
766
767         prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
768
769         prCliStaRec = cnmGetStaRecByAddress(prAdapter,
770                                                     NETWORK_TYPE_P2P_INDEX,
771                                                     pucPeerMacAddr);
772
773         switch (prP2pBssInfo->eCurrentOPMode) {
774         case OP_MODE_ACCESS_POINT:
775             {
776                 P_LINK_T prStaRecOfClientList = (P_LINK_T)NULL;
777                 P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T)NULL;
778
779                 prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList);
780
781                 LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) {
782                     if ((UINT_32)prCliStaRec == (UINT_32)prLinkEntry) {
783                         LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry);
784                         fgIsStaFound = TRUE;
785                         break;
786                     }
787                 }
788
789             }
790             break;
791         case OP_MODE_INFRASTRUCTURE:
792             ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP);
793             if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) {
794                 break;
795             }
796             prP2pBssInfo->prStaRecOfAP = NULL;
797             fgIsStaFound = TRUE;
798             break;
799         default:
800             break;
801         }
802
803         if (fgIsStaFound) {
804             p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDeauth, u2ReasonCode);
805         }
806
807         rWlanStatus = WLAN_STATUS_SUCCESS;
808     } while (FALSE);
809
810     return rWlanStatus;
811 } /* p2pFuncDeauth */
812
813 // TODO: We do not apply IE in disassoc frame set from upper layer now.
814 WLAN_STATUS
815 p2pFuncDisassoc (
816     IN P_ADAPTER_T prAdapter,
817     IN PUINT_8 pucPeerMacAddr,
818     IN UINT_16 u2ReasonCode,
819     IN PUINT_8 pucIEBuf,
820     IN UINT_16 u2IELen,
821     IN BOOLEAN fgSendDisassoc
822     )
823 {
824     WLAN_STATUS rWlanStatus = WLAN_STATUS_FAILURE;
825     P_STA_RECORD_T prCliStaRec = (P_STA_RECORD_T)NULL;
826     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
827     BOOLEAN fgIsStaFound = FALSE;
828
829     do {
830         ASSERT_BREAK((prAdapter != NULL) && (pucPeerMacAddr != NULL));
831
832         prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
833
834         prCliStaRec = cnmGetStaRecByAddress(prAdapter,
835                                                     NETWORK_TYPE_P2P_INDEX,
836                                                     pucPeerMacAddr);
837
838         switch (prP2pBssInfo->eCurrentOPMode) {
839         case OP_MODE_ACCESS_POINT:
840             {
841                 P_LINK_T prStaRecOfClientList = (P_LINK_T)NULL;
842                 P_LINK_ENTRY_T prLinkEntry = (P_LINK_ENTRY_T)NULL;
843
844                 prStaRecOfClientList = &(prP2pBssInfo->rStaRecOfClientList);
845
846                 LINK_FOR_EACH(prLinkEntry, prStaRecOfClientList) {
847                     if ((UINT_32)prCliStaRec == (UINT_32)prLinkEntry) {
848                         LINK_REMOVE_KNOWN_ENTRY(prStaRecOfClientList, &prCliStaRec->rLinkEntry);
849                         fgIsStaFound = TRUE;
850                         //p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode);
851                         break;
852                     }
853                 }
854
855             }
856             break;
857         case OP_MODE_INFRASTRUCTURE:
858             ASSERT(prCliStaRec == prP2pBssInfo->prStaRecOfAP);
859             if (prCliStaRec != prP2pBssInfo->prStaRecOfAP) {
860                 break;
861             }
862
863             //p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode);
864             prP2pBssInfo->prStaRecOfAP = NULL;
865             fgIsStaFound = TRUE;
866             break;
867         default:
868             break;
869         }
870
871         if (fgIsStaFound) {
872                         
873             p2pFuncDisconnect(prAdapter, prCliStaRec, fgSendDisassoc, u2ReasonCode);
874             //20120830 moved into p2pFuncDisconnect().
875             //cnmStaRecFree(prAdapter, prCliStaRec, TRUE);
876
877         }
878
879         rWlanStatus = WLAN_STATUS_SUCCESS;
880     } while (FALSE);
881
882     return rWlanStatus;
883 } /* p2pFuncDisassoc */
884
885 /*----------------------------------------------------------------------------*/
886 /*!
887 * @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.)
888 *              1. GC: Disconnect from AP. (Send Deauth)
889 *              2. GO: Disconnect all STA
890 *
891 * @param[in] prAdapter   Pointer to the adapter structure.
892 *
893 * @return (none)
894 */
895 /*----------------------------------------------------------------------------*/
896 VOID
897 p2pFuncDissolve (
898     IN P_ADAPTER_T prAdapter,
899     IN P_BSS_INFO_T prP2pBssInfo,
900     IN BOOLEAN fgSendDeauth,
901     IN UINT_16 u2ReasonCode
902     )
903 {
904     DEBUGFUNC("p2pFuncDissolve()");
905
906     do {
907
908         ASSERT_BREAK((prAdapter != NULL) && (prP2pBssInfo != NULL));
909
910         switch (prP2pBssInfo->eCurrentOPMode) {
911         case OP_MODE_INFRASTRUCTURE:
912             /* Reset station record status. */
913             if (prP2pBssInfo->prStaRecOfAP) {
914                 kalP2PGCIndicateConnectionStatus(prAdapter->prGlueInfo, 
915                                 NULL,
916                                 NULL,
917                                 0,
918                                 REASON_CODE_DEAUTH_LEAVING_BSS);
919                 
920                 // 2012/02/14 frog: After formation before join group, prStaRecOfAP is NULL.
921                 p2pFuncDisconnect(prAdapter,
922                             prP2pBssInfo->prStaRecOfAP,
923                             fgSendDeauth,
924                             u2ReasonCode);
925             }
926
927             /* Fix possible KE when RX Beacon & call nicPmIndicateBssConnected(). hit prStaRecOfAP == NULL. */
928             p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
929
930             prP2pBssInfo->prStaRecOfAP = NULL;
931
932             break;
933         case OP_MODE_ACCESS_POINT:
934             /* Under AP mode, we would net send deauthentication frame to each STA.
935               * We only stop the Beacon & let all stations timeout.
936               */
937             {
938                 P_LINK_T prStaRecOfClientList = (P_LINK_T)NULL;
939
940                 /* Send deauth. */
941                 authSendDeauthFrame(prAdapter,
942                                 NULL,
943                                 (P_SW_RFB_T)NULL,
944                                 u2ReasonCode,
945                                 (PFN_TX_DONE_HANDLER)NULL);
946
947                 prStaRecOfClientList = &prP2pBssInfo->rStaRecOfClientList;
948
949                 while (!LINK_IS_EMPTY(prStaRecOfClientList)) {
950                     P_STA_RECORD_T prCurrStaRec;
951
952                     LINK_REMOVE_HEAD(prStaRecOfClientList, prCurrStaRec, P_STA_RECORD_T);
953
954                     /* Indicate to Host. */
955                     //kalP2PGOStationUpdate(prAdapter->prGlueInfo, prCurrStaRec, FALSE);
956
957                     p2pFuncDisconnect(prAdapter, prCurrStaRec, TRUE, u2ReasonCode);
958
959                 }
960
961             }
962
963             break;
964         default:
965             return;  // 20110420 -- alreay in Device Mode.
966         }
967
968         /* Make the deauth frame send to FW ASAP. */
969         wlanAcquirePowerControl(prAdapter);
970         wlanProcessCommandQueue(prAdapter, &prAdapter->prGlueInfo->rCmdQueue);
971         wlanReleasePowerControl(prAdapter);
972
973         kalMdelay(100);
974
975         /* Change Connection Status. */
976         p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
977
978     } while (FALSE);
979
980     return;
981 } /* p2pFuncDissolve */
982
983
984 /*----------------------------------------------------------------------------*/
985 /*!
986 * @brief This function is called to dissolve from group or one group. (Would not change P2P FSM.)
987 *              1. GC: Disconnect from AP. (Send Deauth)
988 *              2. GO: Disconnect all STA
989 *
990 * @param[in] prAdapter   Pointer to the adapter structure.
991 *
992 * @return (none)
993 */
994 /*----------------------------------------------------------------------------*/
995 VOID
996 p2pFuncDisconnect (
997     IN P_ADAPTER_T prAdapter,
998     IN P_STA_RECORD_T prStaRec,
999     IN BOOLEAN fgSendDeauth,
1000     IN UINT_16 u2ReasonCode
1001     )
1002 {
1003     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
1004     ENUM_PARAM_MEDIA_STATE_T eOriMediaStatus;
1005
1006     DBGLOG(P2P, TRACE, ("p2pFuncDisconnect()"));
1007
1008     do {
1009         ASSERT_BREAK((prAdapter != NULL) && (prStaRec != NULL));
1010
1011         prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
1012         eOriMediaStatus = prP2pBssInfo->eConnectionState;
1013
1014         /* Indicate disconnect. */
1015         // TODO:
1016 //        kalP2PGOStationUpdate
1017 //        kalP2PGCIndicateConnectionStatus
1018         //p2pIndicationOfMediaStateToHost(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED, prStaRec->aucMacAddr);
1019         if (prP2pBssInfo->eCurrentOPMode == OP_MODE_ACCESS_POINT) {
1020             kalP2PGOStationUpdate(prAdapter->prGlueInfo, prStaRec, FALSE);
1021         }
1022
1023         if (fgSendDeauth) {
1024             /* Send deauth. */
1025             authSendDeauthFrame(prAdapter,
1026                         prStaRec,
1027                         (P_SW_RFB_T)NULL,
1028                         u2ReasonCode,
1029                         (PFN_TX_DONE_HANDLER)p2pFsmRunEventDeauthTxDone);
1030         }
1031         else {
1032             /* Change station state. */
1033             cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
1034
1035             /* Reset Station Record Status. */
1036             p2pFuncResetStaRecStatus(prAdapter, prStaRec);
1037
1038             cnmStaRecFree(prAdapter, prStaRec, TRUE);
1039
1040             if ((prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) ||
1041                     (prP2pBssInfo->rStaRecOfClientList.u4NumElem == 0)) {
1042                 DBGLOG(P2P, TRACE, ("No More Client, Media Status DISCONNECTED\n"));
1043                 p2pChangeMediaState(prAdapter, PARAM_MEDIA_STATE_DISCONNECTED);
1044             }
1045
1046             if (eOriMediaStatus != prP2pBssInfo->eConnectionState) {
1047                 /* Update Disconnected state to FW. */
1048                 nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
1049             }
1050
1051         }
1052
1053         if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) {
1054             /* GO: It would stop Beacon TX. GC: Stop all BSS related PS function. */
1055             nicPmIndicateBssAbort(prAdapter, NETWORK_TYPE_P2P_INDEX);
1056
1057             /* Reset RLM related field of BSSINFO. */
1058             rlmBssAborted(prAdapter, prP2pBssInfo);
1059         }
1060
1061     } while (FALSE);
1062
1063     return;
1064
1065 } /* p2pFuncDisconnect */
1066
1067
1068
1069
1070
1071
1072 WLAN_STATUS
1073 p2pFuncTxMgmtFrame (
1074     IN P_ADAPTER_T prAdapter,
1075     IN P_P2P_MGMT_TX_REQ_INFO_T prMgmtTxReqInfo,
1076     IN P_MSDU_INFO_T prMgmtTxMsdu,
1077     IN UINT_64 u8Cookie
1078     )
1079 {
1080     WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
1081     P_MSDU_INFO_T prTxMsduInfo = (P_MSDU_INFO_T)NULL;
1082     P_WLAN_MAC_HEADER_T prWlanHdr = (P_WLAN_MAC_HEADER_T)NULL;
1083     P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
1084
1085     do {
1086         ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxReqInfo != NULL));
1087
1088         if (prMgmtTxReqInfo->fgIsMgmtTxRequested) {
1089
1090             // 1. prMgmtTxReqInfo->prMgmtTxMsdu != NULL
1091             /* Packet on driver, not done yet, drop it. */
1092             if ((prTxMsduInfo = prMgmtTxReqInfo->prMgmtTxMsdu) != NULL) {
1093
1094                 kalP2PIndicateMgmtTxStatus(prAdapter->prGlueInfo,
1095                                 prMgmtTxReqInfo->u8Cookie,
1096                                 FALSE,
1097                                 prTxMsduInfo->prPacket,
1098                                 (UINT_32)prTxMsduInfo->u2FrameLength);
1099
1100                 // Leave it to TX Done handler.
1101                 //cnmMgtPktFree(prAdapter, prTxMsduInfo);
1102                 prMgmtTxReqInfo->prMgmtTxMsdu = NULL;
1103             }
1104
1105             // 2. prMgmtTxReqInfo->prMgmtTxMsdu == NULL
1106             /* Packet transmitted, wait tx done. (cookie issue) */
1107             // 20120105 frog - use another u8cookie to store this value.
1108
1109         }
1110
1111         ASSERT(prMgmtTxReqInfo->prMgmtTxMsdu == NULL);
1112
1113
1114
1115         prWlanHdr = (P_WLAN_MAC_HEADER_T)((UINT_32)prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD);
1116         prStaRec = cnmGetStaRecByAddress(prAdapter, NETWORK_TYPE_P2P_INDEX, prWlanHdr->aucAddr1);
1117         prMgmtTxMsdu->ucNetworkType = (UINT_8)NETWORK_TYPE_P2P_INDEX;
1118
1119         switch (prWlanHdr->u2FrameCtrl & MASK_FRAME_TYPE) {
1120         case MAC_FRAME_PROBE_RSP:
1121             prMgmtTxMsdu = p2pFuncProcessP2pProbeRsp(prAdapter, prMgmtTxMsdu);
1122             break;
1123         default:
1124             break;
1125         }
1126
1127
1128
1129         prMgmtTxReqInfo->u8Cookie = u8Cookie;
1130         prMgmtTxReqInfo->prMgmtTxMsdu = prMgmtTxMsdu;
1131         prMgmtTxReqInfo->fgIsMgmtTxRequested = TRUE;
1132
1133         prMgmtTxMsdu->eSrc = TX_PACKET_MGMT;
1134         prMgmtTxMsdu->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
1135         prMgmtTxMsdu->ucStaRecIndex =  (prStaRec != NULL)?(prStaRec->ucIndex):(0xFF);
1136         if (prStaRec != NULL) {
1137             DBGLOG(P2P, TRACE, ("Mgmt with station record: "MACSTR" .\n", MAC2STR(prStaRec->aucMacAddr)));
1138         }
1139
1140
1141         prMgmtTxMsdu->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN; // TODO: undcertain.
1142         prMgmtTxMsdu->fgIs802_1x = FALSE;
1143         prMgmtTxMsdu->fgIs802_11 = TRUE;
1144         prMgmtTxMsdu->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
1145         prMgmtTxMsdu->pfTxDoneHandler = p2pFsmRunEventMgmtFrameTxDone;
1146         prMgmtTxMsdu->fgIsBasicRate = TRUE;
1147         DBGLOG(P2P, TRACE, ("Mgmt seq NO. %d .\n", prMgmtTxMsdu->ucTxSeqNum));
1148
1149         nicTxEnqueueMsdu(prAdapter, prMgmtTxMsdu);
1150
1151     } while (FALSE);
1152
1153     return rWlanStatus;
1154 } /* p2pFuncTxMgmtFrame */
1155
1156
1157
1158 VOID
1159 p2pFuncSetChannel (
1160     IN P_ADAPTER_T prAdapter,
1161     IN P_RF_CHANNEL_INFO_T prRfChannelInfo
1162     )
1163 {
1164     P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL;
1165
1166     do {
1167         ASSERT_BREAK((prAdapter != NULL) && (prRfChannelInfo != NULL));
1168
1169         prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
1170
1171         prP2pConnSettings->ucOperatingChnl = prRfChannelInfo->ucChannelNum;
1172         prP2pConnSettings->eBand = prRfChannelInfo->eBand;
1173
1174
1175     } while (FALSE);
1176
1177     return;
1178 }
1179 /* p2pFuncSetChannel */
1180
1181
1182
1183 /*----------------------------------------------------------------------------*/
1184 /*!
1185 * @brief Retry JOIN for AUTH_MODE_AUTO_SWITCH
1186 *
1187 * @param[in] prStaRec       Pointer to the STA_RECORD_T
1188 *
1189 * @retval TRUE      We will retry JOIN
1190 * @retval FALSE     We will not retry JOIN
1191 */
1192 /*----------------------------------------------------------------------------*/
1193 BOOLEAN
1194 p2pFuncRetryJOIN (
1195     IN P_ADAPTER_T prAdapter,
1196     IN P_STA_RECORD_T prStaRec,
1197     IN P_P2P_JOIN_INFO_T prJoinInfo
1198     )
1199 {
1200     P_MSG_JOIN_REQ_T prJoinReqMsg = (P_MSG_JOIN_REQ_T)NULL;
1201     BOOLEAN fgRetValue = FALSE;
1202
1203     do {
1204         ASSERT_BREAK((prAdapter != NULL) &&
1205                             (prStaRec != NULL) &&
1206                             (prJoinInfo != NULL));
1207
1208         /* Retry other AuthType if possible */
1209         if (!prJoinInfo->ucAvailableAuthTypes) {
1210             break;
1211         }
1212
1213         if (prJoinInfo->ucAvailableAuthTypes &
1214             (UINT_8)AUTH_TYPE_SHARED_KEY) {
1215
1216             DBGLOG(P2P, INFO, ("RETRY JOIN INIT: Retry Authentication with AuthType == SHARED_KEY.\n"));
1217
1218             prJoinInfo->ucAvailableAuthTypes &=
1219                 ~(UINT_8)AUTH_TYPE_SHARED_KEY;
1220
1221             prStaRec->ucAuthAlgNum = (UINT_8)AUTH_ALGORITHM_NUM_SHARED_KEY;
1222         }
1223         else {
1224             DBGLOG(P2P, ERROR, ("RETRY JOIN INIT: Retry Authentication with Unexpected AuthType.\n"));
1225             ASSERT(0);
1226             break;
1227         }
1228
1229         prJoinInfo->ucAvailableAuthTypes = 0; /* No more available Auth Types */
1230
1231         /* Trigger SAA to start JOIN process. */
1232         prJoinReqMsg = (P_MSG_JOIN_REQ_T)cnmMemAlloc(prAdapter, RAM_TYPE_MSG, sizeof(MSG_JOIN_REQ_T));
1233         if (!prJoinReqMsg) {
1234             ASSERT(0); // Can't trigger SAA FSM
1235             break;
1236         }
1237
1238         prJoinReqMsg->rMsgHdr.eMsgId = MID_P2P_SAA_FSM_START;
1239         prJoinReqMsg->ucSeqNum = ++prJoinInfo->ucSeqNumOfReqMsg;
1240         prJoinReqMsg->prStaRec = prStaRec;
1241
1242         mboxSendMsg(prAdapter,
1243                 MBOX_ID_0,
1244                 (P_MSG_HDR_T) prJoinReqMsg,
1245                 MSG_SEND_METHOD_BUF);
1246
1247
1248         fgRetValue = TRUE;
1249     } while (FALSE);
1250
1251     return fgRetValue;
1252
1253
1254
1255 }/* end of p2pFuncRetryJOIN() */
1256
1257
1258
1259
1260
1261 /*----------------------------------------------------------------------------*/
1262 /*!
1263 * @brief This function will update the contain of BSS_INFO_T for AIS network once
1264 *        the association was completed.
1265 *
1266 * @param[in] prStaRec               Pointer to the STA_RECORD_T
1267 * @param[in] prAssocRspSwRfb        Pointer to SW RFB of ASSOC RESP FRAME.
1268 *
1269 * @return (none)
1270 */
1271 /*----------------------------------------------------------------------------*/
1272 VOID
1273 p2pFuncUpdateBssInfoForJOIN (
1274     IN P_ADAPTER_T prAdapter,
1275     IN P_BSS_DESC_T prBssDesc,
1276     IN P_STA_RECORD_T prStaRec,
1277     IN P_SW_RFB_T prAssocRspSwRfb
1278     )
1279 {
1280     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
1281     P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL;
1282     P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T)NULL;
1283     UINT_16 u2IELength;
1284     PUINT_8 pucIE;
1285
1286     DEBUGFUNC("p2pUpdateBssInfoForJOIN()");
1287
1288     ASSERT(prAdapter);
1289     ASSERT(prStaRec);
1290     ASSERT(prAssocRspSwRfb);
1291
1292     prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
1293     prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
1294     prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T) prAssocRspSwRfb->pvHeader;
1295
1296     DBGLOG(P2P, INFO, ("Update P2P_BSS_INFO_T and apply settings to MAC\n"));
1297
1298     //3 <1> Update BSS_INFO_T from AIS_FSM_INFO_T or User Settings
1299     //4 <1.1> Setup Operation Mode
1300     prP2pBssInfo->eCurrentOPMode = OP_MODE_INFRASTRUCTURE;
1301
1302     //4 <1.2> Setup SSID
1303     COPY_SSID(prP2pBssInfo->aucSSID,
1304               prP2pBssInfo->ucSSIDLen,
1305               prP2pConnSettings->aucSSID,
1306               prP2pConnSettings->ucSSIDLen);
1307
1308     if (prBssDesc == NULL) {
1309         /* Target BSS NULL. */
1310         DBGLOG(P2P, TRACE,("Target BSS NULL\n"));
1311         return;
1312     }
1313
1314
1315     if (UNEQUAL_MAC_ADDR(prBssDesc->aucBSSID, prAssocRspFrame->aucBSSID)) {
1316         ASSERT(FALSE);
1317     }
1318
1319     //4 <1.3> Setup Channel, Band
1320     prP2pBssInfo->ucPrimaryChannel = prBssDesc->ucChannelNum;
1321     prP2pBssInfo->eBand = prBssDesc->eBand;
1322
1323
1324     //3 <2> Update BSS_INFO_T from STA_RECORD_T
1325     //4 <2.1> Save current AP's STA_RECORD_T and current AID
1326     prP2pBssInfo->prStaRecOfAP = prStaRec;
1327     prP2pBssInfo->u2AssocId = prStaRec->u2AssocId;
1328
1329     //4 <2.2> Setup Capability
1330     prP2pBssInfo->u2CapInfo = prStaRec->u2CapInfo; /* Use AP's Cap Info as BSS Cap Info */
1331
1332     if (prP2pBssInfo->u2CapInfo & CAP_INFO_SHORT_PREAMBLE) {
1333         prP2pBssInfo->fgIsShortPreambleAllowed = TRUE;
1334     }
1335     else {
1336         prP2pBssInfo->fgIsShortPreambleAllowed = FALSE;
1337     }
1338
1339     //4 <2.3> Setup PHY Attributes and Basic Rate Set/Operational Rate Set
1340     prP2pBssInfo->ucPhyTypeSet = prStaRec->ucDesiredPhyTypeSet;
1341
1342     prP2pBssInfo->ucNonHTBasicPhyType = prStaRec->ucNonHTBasicPhyType;
1343
1344     prP2pBssInfo->u2OperationalRateSet = prStaRec->u2OperationalRateSet;
1345     prP2pBssInfo->u2BSSBasicRateSet = prStaRec->u2BSSBasicRateSet;
1346
1347
1348     //3 <3> Update BSS_INFO_T from SW_RFB_T (Association Resp Frame)
1349     //4 <3.1> Setup BSSID
1350     COPY_MAC_ADDR(prP2pBssInfo->aucBSSID, prAssocRspFrame->aucBSSID);
1351
1352
1353     u2IELength = (UINT_16) ((prAssocRspSwRfb->u2PacketLen - prAssocRspSwRfb->u2HeaderLen) -
1354         (OFFSET_OF(WLAN_ASSOC_RSP_FRAME_T, aucInfoElem[0]) - WLAN_MAC_MGMT_HEADER_LEN));
1355     pucIE = prAssocRspFrame->aucInfoElem;
1356
1357
1358     //4 <3.2> Parse WMM and setup QBSS flag
1359     /* Parse WMM related IEs and configure HW CRs accordingly */
1360     mqmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength);
1361
1362     prP2pBssInfo->fgIsQBSS = prStaRec->fgIsQoS;
1363
1364     //3 <4> Update BSS_INFO_T from BSS_DESC_T
1365     ASSERT(prBssDesc);
1366
1367     prBssDesc->fgIsConnecting = FALSE;
1368     prBssDesc->fgIsConnected = TRUE;
1369
1370     //4 <4.1> Setup MIB for current BSS
1371     prP2pBssInfo->u2BeaconInterval = prBssDesc->u2BeaconInterval;
1372     /* NOTE: Defer ucDTIMPeriod updating to when beacon is received after connection */
1373     prP2pBssInfo->ucDTIMPeriod = 0;
1374     prP2pBssInfo->u2ATIMWindow = 0;
1375
1376     prP2pBssInfo->ucBeaconTimeoutCount = AIS_BEACON_TIMEOUT_COUNT_INFRA;
1377
1378     //4 <4.2> Update HT information and set channel
1379     /* Record HT related parameters in rStaRec and rBssInfo
1380      * Note: it shall be called before nicUpdateBss()
1381      */
1382     rlmProcessAssocRsp(prAdapter, prAssocRspSwRfb, pucIE, u2IELength);
1383
1384     //4 <4.3> Sync with firmware for BSS-INFO
1385     nicUpdateBss(prAdapter, NETWORK_TYPE_P2P_INDEX);
1386
1387     //4 <4.4> *DEFER OPERATION* nicPmIndicateBssConnected() will be invoked
1388     //inside scanProcessBeaconAndProbeResp() after 1st beacon is received
1389
1390     return;
1391 } /* end of p2pUpdateBssInfoForJOIN() */
1392
1393
1394
1395 /*----------------------------------------------------------------------------*/
1396 /*!
1397 * @brief This function will validate the Rx Auth Frame and then return
1398 *        the status code to AAA to indicate if need to perform following actions
1399 *        when the specified conditions were matched.
1400 *
1401 * @param[in] prAdapter          Pointer to the Adapter structure.
1402 * @param[in] prSwRfb            Pointer to SW RFB data structure.
1403 * @param[in] pprStaRec          Pointer to pointer of STA_RECORD_T structure.
1404 * @param[out] pu2StatusCode     The Status Code of Validation Result
1405 *
1406 * @retval TRUE      Reply the Auth
1407 * @retval FALSE     Don't reply the Auth
1408 */
1409 /*----------------------------------------------------------------------------*/
1410 BOOLEAN
1411 p2pFuncValidateAuth (
1412     IN P_ADAPTER_T prAdapter,
1413     IN P_SW_RFB_T prSwRfb,
1414     IN PP_STA_RECORD_T pprStaRec,
1415     OUT PUINT_16 pu2StatusCode
1416     )
1417 {
1418     BOOLEAN fgReplyAuth = TRUE;
1419     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
1420     P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
1421     P_WLAN_AUTH_FRAME_T prAuthFrame = (P_WLAN_AUTH_FRAME_T)NULL;
1422
1423    DBGLOG(P2P, TRACE, ("p2pValidate Authentication Frame\n"))
1424
1425     do {
1426         ASSERT_BREAK((prAdapter != NULL) &&
1427                                     (prSwRfb != NULL) &&
1428                                     (pprStaRec != NULL) &&
1429                                     (pu2StatusCode != NULL));
1430
1431         /* P2P 3.2.8 */
1432         *pu2StatusCode = STATUS_CODE_REQ_DECLINED;
1433
1434         prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
1435         prAuthFrame = (P_WLAN_AUTH_FRAME_T)prSwRfb->pvHeader;
1436
1437
1438         if (prP2pBssInfo->eCurrentOPMode != OP_MODE_ACCESS_POINT) {
1439             /* We are not under AP Mode yet. */
1440             fgReplyAuth = FALSE;
1441             DBGLOG(P2P, WARN, ("Current OP mode is not under AP mode. (%d)\n", prP2pBssInfo->eCurrentOPMode));
1442             break;
1443         }
1444
1445         prStaRec = cnmGetStaRecByAddress(prAdapter,
1446                             (UINT_8) NETWORK_TYPE_P2P_INDEX,
1447                             prAuthFrame->aucSrcAddr);
1448
1449         if (!prStaRec) {
1450             prStaRec = cnmStaRecAlloc(prAdapter,
1451                             (UINT_8) NETWORK_TYPE_P2P_INDEX);
1452
1453             /* TODO(Kevin): Error handling of allocation of STA_RECORD_T for
1454              * exhausted case and do removal of unused STA_RECORD_T.
1455              */
1456             /* Sent a message event to clean un-used STA_RECORD_T. */
1457             ASSERT(prStaRec);
1458
1459             COPY_MAC_ADDR(prStaRec->aucMacAddr, prAuthFrame->aucSrcAddr);
1460
1461             prSwRfb->ucStaRecIdx = prStaRec->ucIndex;
1462
1463             prStaRec->u2BSSBasicRateSet = prP2pBssInfo->u2BSSBasicRateSet;
1464
1465             prStaRec->u2DesiredNonHTRateSet = RATE_SET_ERP_P2P;
1466
1467             prStaRec->u2OperationalRateSet = RATE_SET_ERP_P2P;
1468             prStaRec->ucPhyTypeSet = PHY_TYPE_SET_802_11GN;
1469             prStaRec->eStaType = STA_TYPE_P2P_GC;
1470
1471             /* NOTE(Kevin): Better to change state here, not at TX Done */
1472             cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
1473         }
1474         else {
1475             prSwRfb->ucStaRecIdx = prStaRec->ucIndex;
1476
1477             if ((prStaRec->ucStaState > STA_STATE_1) && (IS_STA_IN_P2P(prStaRec))) {
1478
1479                 cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
1480
1481                 p2pFuncResetStaRecStatus(prAdapter, prStaRec);
1482
1483                 bssRemoveStaRecFromClientList(prAdapter, prP2pBssInfo, prStaRec);
1484             }
1485
1486         }
1487
1488         if (prP2pBssInfo->rStaRecOfClientList.u4NumElem > P2P_MAXIMUM_CLIENT_COUNT ||
1489             kalP2PMaxClients(prAdapter->prGlueInfo, prP2pBssInfo->rStaRecOfClientList.u4NumElem)) {
1490             /* GROUP limit full. */
1491             /* P2P 3.2.8 */
1492             DBGLOG(P2P, WARN, ("Group Limit Full. (%d)\n", (INT_16)prP2pBssInfo->rStaRecOfClientList.u4NumElem));
1493             cnmStaRecFree(prAdapter, prStaRec, FALSE);
1494             break;
1495         }
1496         else {
1497             /* Hotspot Blacklist */
1498             if(prAuthFrame->aucSrcAddr) {
1499                 if(kalP2PCmpBlackList(prAdapter->prGlueInfo, prAuthFrame->aucSrcAddr)) {
1500                     fgReplyAuth = FALSE;
1501                     return fgReplyAuth;
1502                 }
1503             }       
1504         }
1505
1506         //prStaRec->eStaType = STA_TYPE_INFRA_CLIENT;
1507         prStaRec->eStaType = STA_TYPE_P2P_GC;
1508
1509         prStaRec->ucNetTypeIndex = NETWORK_TYPE_P2P_INDEX;
1510
1511         /* Update Station Record - Status/Reason Code */
1512         prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
1513
1514         prStaRec->ucJoinFailureCount = 0;
1515
1516         *pprStaRec = prStaRec;
1517
1518         *pu2StatusCode = STATUS_CODE_SUCCESSFUL;
1519
1520     } while (FALSE);
1521
1522
1523     return fgReplyAuth;
1524
1525 } /* p2pFuncValidateAuth */
1526
1527
1528
1529
1530 VOID
1531 p2pFuncResetStaRecStatus (
1532     IN P_ADAPTER_T prAdapter,
1533     IN P_STA_RECORD_T prStaRec
1534     )
1535 {
1536     do {
1537         if ((prAdapter == NULL) || (prStaRec == NULL)) {
1538             ASSERT(FALSE);
1539             break;
1540         }
1541
1542
1543         prStaRec->u2StatusCode = STATUS_CODE_SUCCESSFUL;
1544         prStaRec->u2ReasonCode = REASON_CODE_RESERVED;
1545         prStaRec->ucJoinFailureCount = 0;
1546         prStaRec->fgTransmitKeyExist = FALSE;
1547
1548         prStaRec->fgSetPwrMgtBit = FALSE;
1549
1550     } while (FALSE);
1551
1552     return;
1553 } /* p2pFuncResetStaRecStatus */
1554
1555
1556
1557 /*----------------------------------------------------------------------------*/
1558 /*!
1559 * @brief The function is used to initialize the value of the connection settings for
1560 *        P2P network
1561 *
1562 * @param (none)
1563 *
1564 * @return (none)
1565 */
1566 /*----------------------------------------------------------------------------*/
1567 VOID
1568 p2pFuncInitConnectionSettings (
1569     IN P_ADAPTER_T prAdapter,
1570     IN P_P2P_CONNECTION_SETTINGS_T prP2PConnSettings
1571     )
1572 {
1573     P_DEVICE_TYPE_T prDevType;
1574     UINT_8 aucDefaultDevName[] = P2P_DEFAULT_DEV_NAME;
1575     UINT_8 aucWfaOui[] = VENDOR_OUI_WFA;
1576
1577     ASSERT(prP2PConnSettings);
1578
1579     /* Setup Default Device Name */
1580     prP2PConnSettings->ucDevNameLen = P2P_DEFAULT_DEV_NAME_LEN;
1581     kalMemCopy(prP2PConnSettings->aucDevName, aucDefaultDevName, sizeof(aucDefaultDevName));
1582
1583     /* Setup Primary Device Type (Big-Endian) */
1584     prDevType = &prP2PConnSettings->rPrimaryDevTypeBE;
1585
1586     prDevType->u2CategoryId = HTONS(P2P_DEFAULT_PRIMARY_CATEGORY_ID);
1587     prDevType->u2SubCategoryId = HTONS(P2P_DEFAULT_PRIMARY_SUB_CATEGORY_ID);
1588
1589     prDevType->aucOui[0] = aucWfaOui[0];
1590     prDevType->aucOui[1] = aucWfaOui[1];
1591     prDevType->aucOui[2] = aucWfaOui[2];
1592     prDevType->aucOui[3] = VENDOR_OUI_TYPE_WPS;
1593
1594     /* Setup Secondary Device Type */
1595     prP2PConnSettings->ucSecondaryDevTypeCount = 0;
1596
1597     /* Setup Default Config Method */
1598     prP2PConnSettings->eConfigMethodSelType = ENUM_CONFIG_METHOD_SEL_AUTO;
1599     prP2PConnSettings->u2ConfigMethodsSupport = P2P_DEFAULT_CONFIG_METHOD;
1600     prP2PConnSettings->u2TargetConfigMethod = 0;
1601     prP2PConnSettings->u2LocalConfigMethod = 0;
1602     prP2PConnSettings->fgIsPasswordIDRdy = FALSE;
1603
1604     /* For Device Capability */
1605     prP2PConnSettings->fgSupportServiceDiscovery = FALSE;
1606     prP2PConnSettings->fgSupportClientDiscoverability = TRUE;
1607     prP2PConnSettings->fgSupportConcurrentOperation = TRUE;
1608     prP2PConnSettings->fgSupportInfraManaged = FALSE;
1609     prP2PConnSettings->fgSupportInvitationProcedure = FALSE;
1610
1611     /* For Group Capability */
1612 #if CFG_SUPPORT_PERSISTENT_GROUP
1613     prP2PConnSettings->fgSupportPersistentP2PGroup = TRUE;
1614 #else
1615     prP2PConnSettings->fgSupportPersistentP2PGroup = FALSE;
1616 #endif
1617     prP2PConnSettings->fgSupportIntraBSSDistribution = TRUE;
1618     prP2PConnSettings->fgSupportCrossConnection = TRUE;
1619     prP2PConnSettings->fgSupportPersistentReconnect = FALSE;
1620
1621     prP2PConnSettings->fgSupportOppPS = FALSE;
1622     prP2PConnSettings->u2CTWindow = P2P_CTWINDOW_DEFAULT;
1623
1624     /* For Connection Settings. */
1625     prP2PConnSettings->eAuthMode = AUTH_MODE_OPEN;
1626
1627     prP2PConnSettings->prTargetP2pDesc = NULL;
1628     prP2PConnSettings->ucSSIDLen = 0;
1629
1630     /* Misc */
1631     prP2PConnSettings->fgIsScanReqIssued = FALSE;
1632     prP2PConnSettings->fgIsServiceDiscoverIssued = FALSE;
1633     prP2PConnSettings->fgP2pGroupLimit = FALSE;
1634     prP2PConnSettings->ucOperatingChnl = 0;
1635     prP2PConnSettings->ucListenChnl = 0;
1636     prP2PConnSettings->ucTieBreaker = (UINT_8)(kalRandomNumber() & 0x1);
1637
1638     prP2PConnSettings->eFormationPolicy = ENUM_P2P_FORMATION_POLICY_AUTO;
1639
1640     return;
1641 } /* p2pFuncInitConnectionSettings */
1642
1643
1644
1645
1646
1647 /*----------------------------------------------------------------------------*/
1648 /*!
1649 * @brief This function will validate the Rx Assoc Req Frame and then return
1650 *        the status code to AAA to indicate if need to perform following actions
1651 *        when the specified conditions were matched.
1652 *
1653 * @param[in] prAdapter          Pointer to the Adapter structure.
1654 * @param[in] prSwRfb            Pointer to SW RFB data structure.
1655 * @param[out] pu2StatusCode     The Status Code of Validation Result
1656 *
1657 * @retval TRUE      Reply the Assoc Resp
1658 * @retval FALSE     Don't reply the Assoc Resp
1659 */
1660 /*----------------------------------------------------------------------------*/
1661 BOOLEAN
1662 p2pFuncValidateAssocReq (
1663     IN P_ADAPTER_T prAdapter,
1664     IN P_SW_RFB_T prSwRfb,
1665     OUT PUINT_16 pu2StatusCode
1666     )
1667 {
1668     BOOLEAN fgReplyAssocResp = TRUE;
1669     P_WLAN_ASSOC_REQ_FRAME_T prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T)NULL;
1670     P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
1671     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
1672 #if CFG_SUPPORT_WFD
1673     P_WFD_CFG_SETTINGS_T prWfdCfgSettings = (P_WFD_CFG_SETTINGS_T)NULL;
1674     P_WFD_ATTRIBUTE_T prWfdAttribute = (P_WFD_ATTRIBUTE_T)NULL;
1675     BOOLEAN fgNeedFree = FALSE;
1676 #endif
1677
1678
1679     /* TODO(Kevin): Call P2P functions to check ..
1680                     2. Check we can accept connection from thsi peer
1681                        a. If we are in PROVISION state, only accept the peer we do the GO formation previously.
1682                        b. If we are in OPERATION state, only accept the other peer when P2P_GROUP_LIMIT is 0.
1683                     3. Check Black List here.
1684      */
1685
1686     do {
1687         ASSERT_BREAK((prAdapter != NULL) &&
1688                                         (prSwRfb != NULL) &&
1689                                         (pu2StatusCode != NULL));
1690
1691         *pu2StatusCode = STATUS_CODE_REQ_DECLINED;
1692         prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
1693         prAssocReqFrame = (P_WLAN_ASSOC_REQ_FRAME_T)prSwRfb->pvHeader;
1694
1695         prStaRec = cnmGetStaRecByIndex(prAdapter, prSwRfb->ucStaRecIdx);
1696
1697         if (prStaRec == NULL) {
1698             /* Station record should be ready while RX AUTH frame. */
1699             fgReplyAssocResp = FALSE;
1700             ASSERT(FALSE);
1701             break;
1702         }
1703         else {
1704             prStaRec->ucRCPI = prSwRfb->prHifRxHdr->ucRcpi;
1705         }
1706
1707         prStaRec->u2DesiredNonHTRateSet &= prP2pBssInfo->u2OperationalRateSet;
1708         prStaRec->ucDesiredPhyTypeSet = prStaRec->ucPhyTypeSet & prP2pBssInfo->ucPhyTypeSet;
1709
1710         if (prStaRec->ucDesiredPhyTypeSet == 0) {
1711             /* The station only support 11B rate. */
1712             *pu2StatusCode = STATUS_CODE_ASSOC_DENIED_RATE_NOT_SUPPORTED;
1713             break;
1714         }
1715
1716 #if CFG_SUPPORT_WFD && 1
1717         //LOG_FUNC("Skip check WFD IE becasue some API is not ready\n"); /* Eddie */
1718         if (!prAdapter->rWifiVar.prP2pFsmInfo) {
1719             fgReplyAssocResp = FALSE;
1720             ASSERT(FALSE);
1721             break;
1722         }
1723         
1724         prWfdCfgSettings = &prAdapter->rWifiVar.prP2pFsmInfo->rWfdConfigureSettings;
1725         DBGLOG(P2P, INFO,("Current WfdCfgSettings wfd_en %u wfd_info 0x%x  wfd_policy 0x%x wfd_flag 0x%x\n", 
1726                 prWfdCfgSettings->ucWfdEnable, prWfdCfgSettings->u2WfdDevInfo, 
1727                 prWfdCfgSettings->u4WfdPolicy, prWfdCfgSettings->u4WfdFlag)); /* Eddie */
1728         if (prWfdCfgSettings->ucWfdEnable) {
1729             if (prWfdCfgSettings->u4WfdPolicy & BIT(6)) {
1730                 /* Rejected all. */
1731                 break;
1732             }
1733             else {
1734                 
1735                 //UINT_16 u2AttriListLen = 0;
1736                 UINT_16 u2WfdDevInfo = 0;
1737                 P_WFD_DEVICE_INFORMATION_IE_T prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T)NULL;
1738                 
1739                 //fgNeedFree = p2pFuncGetAttriList(prAdapter,
1740                 //                VENDOR_OUI_TYPE_WFD,
1741                 //                (PUINT_8)prAssocReqFrame->aucInfoElem,
1742                 //                (prSwRfb->u2PacketLen - OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)),
1743                 //                (PPUINT_8)&prWfdAttribute,
1744                 //                &u2AttriListLen);
1745
1746                 prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T)
1747                                         p2pFuncGetSpecAttri(prAdapter,
1748                                                      VENDOR_OUI_TYPE_WFD,
1749                                                      (PUINT_8)prAssocReqFrame->aucInfoElem,
1750                                                      (prSwRfb->u2PacketLen - OFFSET_OF(WLAN_ASSOC_REQ_FRAME_T, aucInfoElem)),
1751                                                      WFD_ATTRI_ID_DEV_INFO);
1752
1753                 if ((prWfdCfgSettings->u4WfdPolicy & BIT(5)) && (prAttriWfdDevInfo != NULL)) {
1754                     /* Rejected with WFD IE. */
1755                     break;
1756                 }
1757
1758                 if ((prWfdCfgSettings->u4WfdPolicy & BIT(0)) && (prAttriWfdDevInfo == NULL)) {
1759                     /* Rejected without WFD IE. */
1760                     break;
1761                 }
1762
1763                 if (prAttriWfdDevInfo != NULL) {
1764
1765                     //prAttriWfdDevInfo = (P_WFD_DEVICE_INFORMATION_IE_T)p2pFuncGetSpecAttri(prAdapter,
1766                     //                                                               VENDOR_OUI_TYPE_WFD,
1767                     //                                                                (PUINT_8)prWfdAttribute, 
1768                     //                                                                u2AttriListLen, 
1769                     //                                                                WFD_ATTRI_ID_DEV_INFO);
1770                     //if (prAttriWfdDevInfo == NULL) {
1771                     //    /* No such attribute. */
1772                     //    break;
1773                     //}
1774
1775                     WLAN_GET_FIELD_BE16(&prAttriWfdDevInfo->u2WfdDevInfo, &u2WfdDevInfo);
1776                     DBGLOG(P2P, INFO,("RX Assoc Req WFD Info:0x%x.\n", u2WfdDevInfo));
1777                     
1778                     if ((prWfdCfgSettings->u4WfdPolicy & BIT(1)) && ((u2WfdDevInfo & 0x3) == 0x0)) {
1779                         /* Rejected because of SOURCE. */
1780                         break;
1781                     }
1782
1783                     if ((prWfdCfgSettings->u4WfdPolicy & BIT(2)) && ((u2WfdDevInfo & 0x3) == 0x1)) {
1784                         /* Rejected because of Primary Sink. */
1785                         break;
1786                     }
1787
1788                     if ((prWfdCfgSettings->u4WfdPolicy & BIT(3)) && ((u2WfdDevInfo & 0x3) == 0x2)) {
1789                         /* Rejected because of Secondary Sink. */
1790                         break;
1791                     }
1792
1793                     if ((prWfdCfgSettings->u4WfdPolicy & BIT(4)) && ((u2WfdDevInfo & 0x3) == 0x3)) {
1794                         /* Rejected because of Source & Primary Sink. */
1795                         break;
1796                     }
1797
1798                     /* Check role */
1799
1800                     if(prWfdCfgSettings->u4WfdFlag & WFD_FLAGS_DEV_INFO_VALID) {
1801
1802                         if((prWfdCfgSettings->u2WfdDevInfo & BITS(0,1)) == 0x3) {
1803                             //P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T prMsgWfdCfgUpdate = (P_MSG_WFD_CONFIG_SETTINGS_CHANGED_T)NULL;
1804                             UINT_16 u2DevInfo = prWfdCfgSettings->u2WfdDevInfo;
1805
1806                            /* We may change role here if we are dual role */
1807
1808                             if((u2WfdDevInfo & BITS(0,1)) == 0x00 /* Peer is Source*/) {
1809                                 DBGLOG(P2P, INFO,("WFD: Switch role to primary sink\n"));
1810
1811                                 prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0,1);
1812                                 prWfdCfgSettings->u2WfdDevInfo |= 0x1;
1813
1814                                 /* event to annonce the role is chanaged to P-Sink */
1815                      
1816                             }
1817                             else if((u2WfdDevInfo & BITS(0,1)) == 0x01 /* Peer is P-Sink */) {
1818
1819                                 DBGLOG(P2P, INFO,("WFD: Switch role to source\n"));
1820                                 prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0,1);
1821                                 /* event to annonce the role is chanaged to Source */
1822                            }
1823                            else {
1824
1825                                 DBGLOG(P2P, INFO,("WFD: Peer role is wrong type(dev 0x%x)\n", (u2DevInfo)));
1826                                 DBGLOG(P2P, INFO,("WFD: Switch role to source\n"));
1827                                 prWfdCfgSettings->u2WfdDevInfo &= ~BITS(0,1);
1828                                 /* event to annonce the role is chanaged to Source */
1829                            }
1830
1831                             p2pFsmRunEventWfdSettingUpdate (prAdapter,NULL);
1832
1833                         } /* Dual role p2p->wfd_params->WfdDevInfo */
1834                     } /* WFD_FLAG_DEV_INFO_VALID */
1835
1836
1837                 }
1838                 else {
1839                     /* Without WFD IE. 
1840                                      * Do nothing. Accept the connection request.
1841                                      */
1842                 }
1843             }
1844
1845         } /* ucWfdEnable */
1846
1847 #endif
1848
1849         *pu2StatusCode = STATUS_CODE_SUCCESSFUL;
1850
1851     } while (FALSE);
1852
1853 #if CFG_SUPPORT_WFD
1854     if ((prWfdAttribute) && (fgNeedFree)) {
1855         kalMemFree(prWfdAttribute, VIR_MEM_TYPE, WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE);
1856     }
1857 #endif
1858
1859     return fgReplyAssocResp;
1860
1861 } /* p2pFuncValidateAssocReq */
1862
1863
1864
1865
1866 /*----------------------------------------------------------------------------*/
1867 /*!
1868 * @brief This function is used to check the P2P IE
1869 *
1870 *
1871 * @return none
1872 */
1873 /*----------------------------------------------------------------------------*/
1874 BOOLEAN
1875 p2pFuncParseCheckForP2PInfoElem (
1876     IN  P_ADAPTER_T prAdapter,
1877     IN  PUINT_8 pucBuf,
1878     OUT PUINT_8 pucOuiType
1879     )
1880 {
1881     UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
1882     P_IE_WFA_T prWfaIE = (P_IE_WFA_T)NULL;
1883
1884     do {
1885         ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL) && (pucOuiType != NULL));
1886
1887         prWfaIE = (P_IE_WFA_T)pucBuf;
1888
1889         if (IE_LEN(pucBuf) <= ELEM_MIN_LEN_WFA_OUI_TYPE_SUBTYPE) {
1890             break;
1891         }
1892         else if (prWfaIE->aucOui[0] != aucWfaOui[0] ||
1893                  prWfaIE->aucOui[1] != aucWfaOui[1] ||
1894                  prWfaIE->aucOui[2] != aucWfaOui[2]) {
1895             break;
1896         }
1897
1898         *pucOuiType = prWfaIE->ucOuiType;
1899
1900         return TRUE;
1901     } while (FALSE);
1902
1903     return FALSE;
1904 } /* p2pFuncParseCheckForP2PInfoElem */
1905
1906
1907
1908
1909 /*----------------------------------------------------------------------------*/
1910 /*!
1911 * @brief This function will validate the Rx Probe Request Frame and then return
1912 *        result to BSS to indicate if need to send the corresponding Probe Response
1913 *        Frame if the specified conditions were matched.
1914 *
1915 * @param[in] prAdapter          Pointer to the Adapter structure.
1916 * @param[in] prSwRfb            Pointer to SW RFB data structure.
1917 * @param[out] pu4ControlFlags   Control flags for replying the Probe Response
1918 *
1919 * @retval TRUE      Reply the Probe Response
1920 * @retval FALSE     Don't reply the Probe Response
1921 */
1922 /*----------------------------------------------------------------------------*/
1923 BOOLEAN
1924 p2pFuncValidateProbeReq (
1925     IN P_ADAPTER_T prAdapter,
1926     IN P_SW_RFB_T prSwRfb,
1927     OUT PUINT_32 pu4ControlFlags
1928     )
1929 {
1930     BOOLEAN fgIsReplyProbeRsp = FALSE;
1931     P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
1932
1933     DEBUGFUNC("p2pFuncValidateProbeReq");
1934
1935     do {
1936
1937         ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
1938
1939         prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
1940
1941         if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_PROBE_REQ) {
1942             /* Leave the probe response to p2p_supplicant. */
1943             kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb);
1944         }
1945
1946     } while (FALSE);
1947
1948     return fgIsReplyProbeRsp;
1949
1950 } /* end of p2pFuncValidateProbeReq() */
1951
1952
1953
1954 /*----------------------------------------------------------------------------*/
1955 /*!
1956 * @brief This function will validate the Rx Probe Request Frame and then return
1957 *        result to BSS to indicate if need to send the corresponding Probe Response
1958 *        Frame if the specified conditions were matched.
1959 *
1960 * @param[in] prAdapter          Pointer to the Adapter structure.
1961 * @param[in] prSwRfb            Pointer to SW RFB data structure.
1962 * @param[out] pu4ControlFlags   Control flags for replying the Probe Response
1963 *
1964 * @retval TRUE      Reply the Probe Response
1965 * @retval FALSE     Don't reply the Probe Response
1966 */
1967 /*----------------------------------------------------------------------------*/
1968 VOID
1969 p2pFuncValidateRxActionFrame (
1970     IN P_ADAPTER_T prAdapter,
1971     IN P_SW_RFB_T prSwRfb
1972     )
1973 {
1974     P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
1975
1976     DEBUGFUNC("p2pFuncValidateProbeReq");
1977
1978     do {
1979
1980         ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
1981
1982         prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
1983
1984         if (prP2pFsmInfo->u4P2pPacketFilter & PARAM_PACKET_FILTER_ACTION_FRAME) {
1985             /* Leave the probe response to p2p_supplicant. */
1986             kalP2PIndicateRxMgmtFrame(prAdapter->prGlueInfo, prSwRfb);
1987         }
1988
1989     } while (FALSE);
1990
1991     return;
1992
1993 } /* p2pFuncValidateRxMgmtFrame */
1994
1995
1996
1997
1998 BOOLEAN
1999 p2pFuncIsAPMode (
2000     IN P_P2P_FSM_INFO_T prP2pFsmInfo
2001     )
2002 {
2003     if (prP2pFsmInfo) {
2004         return prP2pFsmInfo->fgIsApMode;
2005     }
2006     else {
2007         return FALSE;
2008     }
2009 }
2010 /* p2pFuncIsAPMode */
2011
2012
2013
2014 VOID
2015 p2pFuncParseBeaconContent (
2016     IN P_ADAPTER_T prAdapter,
2017     IN P_BSS_INFO_T prP2pBssInfo,
2018     IN PUINT_8 pucIEInfo,
2019     IN UINT_32 u4IELen
2020     )
2021 {
2022     PUINT_8 pucIE = (PUINT_8)NULL;
2023     UINT_16 u2Offset = 0;
2024     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
2025     BOOL    ucNewSecMode = FALSE;
2026     BOOL    ucOldSecMode = FALSE;
2027
2028     do {
2029         ASSERT_BREAK((prAdapter != NULL) &&
2030                         (prP2pBssInfo != NULL));
2031
2032         if (u4IELen == 0) {
2033             break;
2034         }
2035
2036         prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
2037         prP2pSpecificBssInfo->u2AttributeLen = 0;
2038
2039         ASSERT_BREAK(pucIEInfo != NULL);
2040
2041         pucIE = pucIEInfo;
2042
2043         ucOldSecMode = kalP2PGetCipher(prAdapter->prGlueInfo);
2044
2045         IE_FOR_EACH(pucIE, u4IELen, u2Offset) {
2046             switch (IE_ID(pucIE)) {
2047             case ELEM_ID_SSID:   /* 0 */ /* V */ /* Done */
2048                 {
2049                     DBGLOG(P2P, TRACE, ("SSID update\n"));
2050
2051                     /* Update when starting GO. */
2052                     COPY_SSID(prP2pBssInfo->aucSSID,
2053                                                 prP2pBssInfo->ucSSIDLen,
2054                                                 SSID_IE(pucIE)->aucSSID,
2055                                                 SSID_IE(pucIE)->ucLength);
2056
2057                     COPY_SSID(prP2pSpecificBssInfo->aucGroupSsid,
2058                                                 prP2pSpecificBssInfo->u2GroupSsidLen,
2059                                                 SSID_IE(pucIE)->aucSSID,
2060                                                 SSID_IE(pucIE)->ucLength);
2061
2062                 }
2063                 break;
2064             case ELEM_ID_SUP_RATES:  /* 1 */ /* V */ /* Done */
2065                 {
2066                     DBGLOG(P2P, TRACE, ("Support Rate IE\n"));
2067                     kalMemCopy(prP2pBssInfo->aucAllSupportedRates,
2068                                     SUP_RATES_IE(pucIE)->aucSupportedRates,
2069                                     SUP_RATES_IE(pucIE)->ucLength);
2070
2071                     prP2pBssInfo->ucAllSupportedRatesLen = SUP_RATES_IE(pucIE)->ucLength;
2072
2073                     DBGLOG_MEM8(P2P, TRACE, SUP_RATES_IE(pucIE)->aucSupportedRates, SUP_RATES_IE(pucIE)->ucLength);
2074                 }
2075                 break;
2076             case ELEM_ID_DS_PARAM_SET: /* 3 */ /* V */ /* Done */
2077                 {
2078                     P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
2079
2080                     DBGLOG(P2P, TRACE, ("DS PARAM IE\n"));
2081
2082                     ASSERT(prP2pConnSettings->ucOperatingChnl == DS_PARAM_IE(pucIE)->ucCurrChnl);
2083
2084                     if (prP2pConnSettings->eBand != BAND_2G4) {
2085                         ASSERT(FALSE);
2086                         break;
2087                     }
2088
2089                     //prP2pBssInfo->ucPrimaryChannel = DS_PARAM_IE(pucIE)->ucCurrChnl;
2090
2091                     //prP2pBssInfo->eBand = BAND_2G4;
2092                 }
2093                 break;
2094             case ELEM_ID_TIM: /* 5 */ /* V */
2095                 DBGLOG(P2P, TRACE, ("TIM IE\n"));
2096                 TIM_IE(pucIE)->ucDTIMPeriod = prP2pBssInfo->ucDTIMPeriod;
2097                 break;
2098             case ELEM_ID_ERP_INFO:  /* 42 */    /* V */
2099                 {
2100 #if 1
2101                     /* This IE would dynamic change due to FW detection change is required. */
2102                     DBGLOG(P2P, TRACE, ("ERP IE will be over write by driver\n"));
2103                     DBGLOG(P2P, TRACE, ("    ucERP: %x. \n", ERP_INFO_IE(pucIE)->ucERP));
2104
2105 #else
2106                     /* This IE would dynamic change due to FW detection change is required. */
2107                     DBGLOG(P2P, TRACE, ("ERP IE.\n"));
2108
2109                     prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11GN;
2110
2111                     ASSERT(prP2pBssInfo->eBand == BAND_2G4);
2112
2113                     prP2pBssInfo->fgObssErpProtectMode = ((ERP_INFO_IE(pucIE)->ucERP & ERP_INFO_USE_PROTECTION)? TRUE : FALSE);
2114
2115                     prP2pBssInfo->fgErpProtectMode = ((ERP_INFO_IE(pucIE)->ucERP & (ERP_INFO_USE_PROTECTION | ERP_INFO_NON_ERP_PRESENT))? TRUE : FALSE);
2116 #endif
2117
2118                 }
2119                 break;
2120             case ELEM_ID_HT_CAP:    /* 45 */    /* V */
2121                 {
2122 #if 1
2123                     DBGLOG(P2P, TRACE, ("HT CAP IE would be overwritten by driver\n"));
2124
2125                     DBGLOG(P2P, TRACE, ("HT Cap Info:%x, AMPDU Param:%x\n", HT_CAP_IE(pucIE)->u2HtCapInfo, HT_CAP_IE(pucIE)->ucAmpduParam));
2126
2127                     DBGLOG(P2P, TRACE, ("HT Extended Cap Info:%x, TX Beamforming Cap Info:%lx, Ant Selection Cap Info%x \n",
2128                                                                                             HT_CAP_IE(pucIE)->u2HtExtendedCap,
2129                                                                                             HT_CAP_IE(pucIE)->u4TxBeamformingCap,
2130                                                                                             HT_CAP_IE(pucIE)->ucAselCap));
2131 #else
2132                     prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N;
2133
2134                     /* u2HtCapInfo */
2135                     if ((HT_CAP_IE(pucIE)->u2HtCapInfo &
2136                             (HT_CAP_INFO_SUP_CHNL_WIDTH | HT_CAP_INFO_SHORT_GI_40M | HT_CAP_INFO_DSSS_CCK_IN_40M)) == 0) {
2137                         prP2pBssInfo->fgAssoc40mBwAllowed = FALSE;
2138                     }
2139                     else {
2140                         prP2pBssInfo->fgAssoc40mBwAllowed = TRUE;
2141                     }
2142
2143                     if ((HT_CAP_IE(pucIE)->u2HtCapInfo &
2144                             (HT_CAP_INFO_SHORT_GI_20M | HT_CAP_INFO_SHORT_GI_40M)) == 0) {
2145                         prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = TRUE;
2146                     }
2147                     else {
2148                         prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled = FALSE;
2149                     }
2150
2151                     /* ucAmpduParam */
2152                     DBGLOG(P2P, TRACE, ("AMPDU setting from supplicant:0x%x, & default value:0x%x\n", (UINT_8)HT_CAP_IE(pucIE)->ucAmpduParam, (UINT_8)AMPDU_PARAM_DEFAULT_VAL));
2153
2154                     /* rSupMcsSet */
2155                     /* Can do nothing. the field is default value from other configuration. */
2156                     //HT_CAP_IE(pucIE)->rSupMcsSet;
2157
2158                     /* u2HtExtendedCap */
2159                     ASSERT(HT_CAP_IE(pucIE)->u2HtExtendedCap == (HT_EXT_CAP_DEFAULT_VAL & ~(HT_EXT_CAP_PCO | HT_EXT_CAP_PCO_TRANS_TIME_NONE)));
2160
2161                     /* u4TxBeamformingCap */
2162                     ASSERT(HT_CAP_IE(pucIE)->u4TxBeamformingCap == TX_BEAMFORMING_CAP_DEFAULT_VAL);
2163
2164                     /* ucAselCap */
2165                     ASSERT(HT_CAP_IE(pucIE)->ucAselCap == ASEL_CAP_DEFAULT_VAL);
2166 #endif
2167                 }
2168                 break;
2169             case ELEM_ID_RSN: /* 48 */  /* V */
2170                                 {
2171                                         RSN_INFO_T rRsnIe;
2172
2173                 DBGLOG(P2P, TRACE, ("RSN IE\n"));
2174                 kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_CCMP);
2175                 ucNewSecMode = TRUE;
2176
2177                                         if (rsnParseRsnIE(prAdapter, RSN_IE(pucIE), &rRsnIe)) {
2178                                                 prP2pBssInfo = &prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX];
2179                                             prP2pBssInfo->u4RsnSelectedGroupCipher = RSN_CIPHER_SUITE_CCMP;
2180                                             prP2pBssInfo->u4RsnSelectedPairwiseCipher = RSN_CIPHER_SUITE_CCMP;
2181                                             prP2pBssInfo->u4RsnSelectedAKMSuite = RSN_AKM_SUITE_PSK;
2182                                                 prP2pBssInfo->u2RsnSelectedCapInfo = rRsnIe.u2RsnCap;
2183                                         }
2184                 }
2185                 break;
2186             case ELEM_ID_EXTENDED_SUP_RATES:   /* 50 */   /* V */
2187                 /* Be attention, ELEM_ID_SUP_RATES should be placed before ELEM_ID_EXTENDED_SUP_RATES. */
2188                 DBGLOG(P2P, TRACE, ("Ex Support Rate IE\n"));
2189                 kalMemCopy(&(prP2pBssInfo->aucAllSupportedRates[prP2pBssInfo->ucAllSupportedRatesLen]),
2190                                     EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates,
2191                                     EXT_SUP_RATES_IE(pucIE)->ucLength);
2192
2193                 DBGLOG_MEM8(P2P, TRACE, EXT_SUP_RATES_IE(pucIE)->aucExtSupportedRates, EXT_SUP_RATES_IE(pucIE)->ucLength);
2194
2195                 prP2pBssInfo->ucAllSupportedRatesLen += EXT_SUP_RATES_IE(pucIE)->ucLength;
2196                 break;
2197             case ELEM_ID_HT_OP: /* 61 */        /* V */   // TODO:
2198                 {
2199 #if 1
2200                     DBGLOG(P2P, TRACE, ("HT OP IE would be overwritten by driver\n"));
2201
2202                     DBGLOG(P2P, TRACE, ("    Primary Channel: %x, Info1: %x, Info2: %x, Info3: %x\n",
2203                                                                         HT_OP_IE(pucIE)->ucPrimaryChannel,
2204                                                                         HT_OP_IE(pucIE)->ucInfo1,
2205                                                                         HT_OP_IE(pucIE)->u2Info2,
2206                                                                         HT_OP_IE(pucIE)->u2Info3));
2207 #else
2208                     UINT_16 u2Info2 = 0;
2209                     prP2pBssInfo->ucPhyTypeSet |= PHY_TYPE_SET_802_11N;
2210
2211                     DBGLOG(P2P, TRACE, ("HT OP IE\n"));
2212
2213                     /* ucPrimaryChannel. */
2214                     ASSERT(HT_OP_IE(pucIE)->ucPrimaryChannel == prP2pBssInfo->ucPrimaryChannel);
2215
2216                     /* ucInfo1 */
2217                     prP2pBssInfo->ucHtOpInfo1 = HT_OP_IE(pucIE)->ucInfo1;
2218
2219                     /* u2Info2 */
2220                     u2Info2 = HT_OP_IE(pucIE)->u2Info2;
2221
2222                     if (u2Info2 & HT_OP_INFO2_NON_GF_HT_STA_PRESENT) {
2223                         ASSERT(prP2pBssInfo->eGfOperationMode != GF_MODE_NORMAL);
2224                         u2Info2 &= ~HT_OP_INFO2_NON_GF_HT_STA_PRESENT;
2225                     }
2226
2227                     if (u2Info2 & HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT) {
2228                         prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER;
2229                         u2Info2 &= ~HT_OP_INFO2_OBSS_NON_HT_STA_PRESENT;
2230                     }
2231
2232                     switch (u2Info2 & HT_OP_INFO2_HT_PROTECTION) {
2233                     case HT_PROTECT_MODE_NON_HT:
2234                         prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NON_HT;
2235                         break;
2236                     case HT_PROTECT_MODE_NON_MEMBER:
2237                         prP2pBssInfo->eHtProtectMode = HT_PROTECT_MODE_NONE;
2238                         prP2pBssInfo->eObssHtProtectMode = HT_PROTECT_MODE_NON_MEMBER;
2239                         break;
2240                     default:
2241                         prP2pBssInfo->eHtProtectMode = HT_OP_IE(pucIE)->u2Info2;
2242                         break;
2243                     }
2244
2245                     /* u2Info3 */
2246                     prP2pBssInfo->u2HtOpInfo3 = HT_OP_IE(pucIE)->u2Info3;
2247
2248                     /* aucBasicMcsSet */
2249                     DBGLOG_MEM8(P2P, TRACE, HT_OP_IE(pucIE)->aucBasicMcsSet, 16);
2250 #endif
2251                 }
2252                 break;
2253             case ELEM_ID_OBSS_SCAN_PARAMS: /* 74 */     /* V */
2254                 {
2255                     DBGLOG(P2P, TRACE, ("ELEM_ID_OBSS_SCAN_PARAMS IE would be replaced by driver\n"));
2256                 }
2257                 break;
2258             case ELEM_ID_EXTENDED_CAP: /* 127 */  /* V */
2259                 {
2260                     DBGLOG(P2P, TRACE, ("ELEM_ID_EXTENDED_CAP IE would be replaced by driver\n"));
2261                 }
2262                 break;
2263             case ELEM_ID_VENDOR: /* 221 */ /* V */
2264                 DBGLOG(P2P, TRACE, ("Vender Specific IE\n"));
2265                 {
2266                     UINT_8 ucOuiType;
2267                     UINT_16 u2SubTypeVersion;
2268                     if (rsnParseCheckForWFAInfoElem(prAdapter, pucIE, &ucOuiType, &u2SubTypeVersion)) {
2269                         if ((ucOuiType == VENDOR_OUI_TYPE_WPA) &&
2270                                 (u2SubTypeVersion == VERSION_WPA)) {
2271                             kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_TKIP);
2272                             ucNewSecMode = TRUE;
2273                                                         kalMemCopy(prP2pSpecificBssInfo->aucWpaIeBuffer,pucIE,
2274                                                         IE_SIZE(pucIE));
2275                                                         prP2pSpecificBssInfo->u2WpaIeLen=IE_SIZE(pucIE);
2276                         }
2277                         else if ((ucOuiType == VENDOR_OUI_TYPE_WPS)) {
2278                             kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 0, pucIE, IE_SIZE(pucIE));
2279                         }
2280
2281
2282                         // WMM here.
2283                     }
2284                     else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIE, &ucOuiType)) {
2285                         // TODO Store the whole P2P IE & generate later.
2286                         // Be aware that there may be one or more P2P IE.
2287                         if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
2288                             kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[prP2pSpecificBssInfo->u2AttributeLen],
2289                                             pucIE,
2290                                             IE_SIZE(pucIE));
2291
2292                             prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE);
2293                         }
2294                        else if(ucOuiType == VENDOR_OUI_TYPE_WFD) {
2295                                                         
2296                             kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[prP2pSpecificBssInfo->u2AttributeLen],
2297                                             pucIE,
2298                                             IE_SIZE(pucIE));
2299
2300                             prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE);
2301                                                         }
2302                     }
2303                     else {
2304
2305
2306                         kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[prP2pSpecificBssInfo->u2AttributeLen],
2307                                             pucIE,
2308                                             IE_SIZE(pucIE));
2309
2310                         prP2pSpecificBssInfo->u2AttributeLen += IE_SIZE(pucIE);
2311                         DBGLOG(P2P, TRACE, ("Driver unprocessed Vender Specific IE\n"));
2312                         ASSERT(FALSE);
2313                     }
2314
2315                     // TODO: Store other Vender IE except for WMM Param.
2316                 }
2317                 break;
2318             default:
2319                 DBGLOG(P2P, TRACE, ("Unprocessed element ID:%d \n", IE_ID(pucIE)));
2320                 break;
2321             }
2322         }
2323
2324         if (!ucNewSecMode && ucOldSecMode)
2325             kalP2PSetCipher(prAdapter->prGlueInfo, IW_AUTH_CIPHER_NONE);
2326
2327     } while (FALSE);
2328
2329     return;
2330 } /* p2pFuncParseBeaconContent */
2331
2332
2333
2334
2335 P_BSS_DESC_T
2336 p2pFuncKeepOnConnection (
2337     IN P_ADAPTER_T prAdapter,
2338     IN P_P2P_CONNECTION_REQ_INFO_T prConnReqInfo,
2339     IN P_P2P_CHNL_REQ_INFO_T prChnlReqInfo,
2340     IN P_P2P_SCAN_REQ_INFO_T prScanReqInfo
2341     )
2342 {
2343     P_BSS_DESC_T prTargetBss = (P_BSS_DESC_T)NULL;
2344     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
2345
2346     do {
2347         ASSERT_BREAK((prAdapter != NULL) &&
2348                 (prConnReqInfo != NULL) &&
2349                 (prChnlReqInfo != NULL) &&
2350                 (prScanReqInfo != NULL));
2351
2352         prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
2353
2354         if (prP2pBssInfo->eCurrentOPMode != OP_MODE_INFRASTRUCTURE) {
2355             break;
2356         }
2357
2358         // Update connection request information.
2359         ASSERT(prConnReqInfo->fgIsConnRequest == TRUE);
2360
2361         /* Find BSS Descriptor first. */
2362         prTargetBss =  scanP2pSearchDesc(prAdapter,
2363                                                                         prP2pBssInfo,
2364                                                                         prConnReqInfo);
2365
2366         if (prTargetBss == NULL) {
2367             /* Update scan parameter... to scan target device. */
2368             prScanReqInfo->ucNumChannelList = 1;
2369             prScanReqInfo->eScanType = SCAN_TYPE_ACTIVE_SCAN;
2370             prScanReqInfo->eChannelSet = SCAN_CHANNEL_FULL;
2371             prScanReqInfo->u4BufLength = 0;  /* Prevent other P2P ID in IE. */
2372             prScanReqInfo->fgIsAbort = TRUE;
2373         }
2374         else {
2375             prChnlReqInfo->u8Cookie = 0;
2376             prChnlReqInfo->ucReqChnlNum = prTargetBss->ucChannelNum;
2377             prChnlReqInfo->eBand = prTargetBss->eBand;
2378             prChnlReqInfo->eChnlSco = prTargetBss->eSco;
2379             prChnlReqInfo->u4MaxInterval = AIS_JOIN_CH_REQUEST_INTERVAL;
2380             prChnlReqInfo->eChannelReqType = CHANNEL_REQ_TYPE_GC_JOIN_REQ;
2381         }
2382
2383     } while (FALSE);
2384
2385     return prTargetBss;
2386 } /* p2pFuncKeepOnConnection */
2387
2388 /* Currently Only for ASSOC Response Frame. */
2389 VOID
2390 p2pFuncStoreAssocRspIEBuffer (
2391     IN P_ADAPTER_T prAdapter,
2392     IN P_SW_RFB_T prSwRfb
2393     )
2394 {
2395     P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
2396     P_P2P_JOIN_INFO_T prJoinInfo = (P_P2P_JOIN_INFO_T)NULL;
2397     P_WLAN_ASSOC_RSP_FRAME_T prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T)NULL;
2398     INT_16 i2IELen = 0;
2399
2400     do {
2401         ASSERT_BREAK((prAdapter != NULL) && (prSwRfb != NULL));
2402
2403         prAssocRspFrame = (P_WLAN_ASSOC_RSP_FRAME_T)prSwRfb->pvHeader;
2404
2405         if (prAssocRspFrame->u2FrameCtrl != MAC_FRAME_ASSOC_RSP) {
2406             break;
2407         }
2408
2409         i2IELen = prSwRfb->u2PacketLen - (WLAN_MAC_HEADER_LEN +
2410                                                                     CAP_INFO_FIELD_LEN +
2411                                                                     STATUS_CODE_FIELD_LEN +
2412                                                                     AID_FIELD_LEN);
2413
2414
2415         if (i2IELen <= 0) {
2416             break;
2417         }
2418
2419         prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
2420         prJoinInfo = &(prP2pFsmInfo->rJoinInfo);
2421         prJoinInfo->u4BufLength = (UINT_32)i2IELen;
2422
2423         kalMemCopy(prJoinInfo->aucIEBuf, prAssocRspFrame->aucInfoElem, prJoinInfo->u4BufLength);
2424
2425     } while (FALSE);
2426
2427
2428     return;
2429 } /* p2pFuncStoreAssocRspIEBuffer */
2430
2431
2432
2433
2434 /*----------------------------------------------------------------------------*/
2435 /*!
2436 * \brief This routine is called to set Packet Filter.
2437 *
2438 * \param[in] prAdapter      Pointer to the Adapter structure.
2439 * \param[in] pvSetBuffer    Pointer to the buffer that holds the data to be set.
2440 * \param[in] u4SetBufferLen The length of the set buffer.
2441 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2442 *                           bytes read from the set buffer. If the call failed
2443 *                           due to invalid length of the set buffer, returns
2444 *                           the amount of storage needed.
2445 *
2446 * \retval WLAN_STATUS_SUCCESS
2447 * \retval WLAN_STATUS_INVALID_LENGTH
2448 * \retval WLAN_STATUS_NOT_SUPPORTED
2449 * \retval WLAN_STATUS_ADAPTER_NOT_READY
2450 */
2451 /*----------------------------------------------------------------------------*/
2452 VOID
2453 p2pFuncMgmtFrameRegister (
2454     IN P_ADAPTER_T  prAdapter,
2455     IN  UINT_16 u2FrameType,
2456     IN BOOLEAN fgIsRegistered,
2457     OUT PUINT_32 pu4P2pPacketFilter
2458     )
2459 {
2460     UINT_32 u4NewPacketFilter = 0;
2461
2462     DEBUGFUNC("p2pFuncMgmtFrameRegister");
2463
2464     do {
2465         ASSERT_BREAK(prAdapter != NULL);
2466
2467         if (pu4P2pPacketFilter) {
2468             u4NewPacketFilter = *pu4P2pPacketFilter;
2469         }
2470
2471         switch (u2FrameType) {
2472         case MAC_FRAME_PROBE_REQ:
2473             if (fgIsRegistered) {
2474                 u4NewPacketFilter |= PARAM_PACKET_FILTER_PROBE_REQ;
2475                 DBGLOG(P2P, TRACE, ("Open packet filer probe request\n"));
2476             }
2477             else {
2478                 u4NewPacketFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ;
2479                 DBGLOG(P2P, TRACE, ("Close packet filer probe request\n"));
2480             }
2481             break;
2482         case MAC_FRAME_ACTION:
2483             if (fgIsRegistered) {
2484                 u4NewPacketFilter |= PARAM_PACKET_FILTER_ACTION_FRAME;
2485                 DBGLOG(P2P, TRACE, ("Open packet filer action frame.\n"));
2486             }
2487             else {
2488                 u4NewPacketFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME;
2489                 DBGLOG(P2P, TRACE, ("Close packet filer action frame.\n"));
2490             }
2491             break;
2492         default:
2493             DBGLOG(P2P, TRACE, ("Ask frog to add code for mgmt:%x\n", u2FrameType));
2494             break;
2495         }
2496
2497         if (pu4P2pPacketFilter) {
2498             *pu4P2pPacketFilter = u4NewPacketFilter;
2499         }
2500
2501 //        u4NewPacketFilter |= prAdapter->u4OsPacketFilter;
2502
2503         prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK;
2504         prAdapter->u4OsPacketFilter |= u4NewPacketFilter;
2505
2506         DBGLOG(P2P, TRACE, ("P2P Set PACKET filter:0x%lx\n", prAdapter->u4OsPacketFilter));
2507
2508         wlanSendSetQueryCmd(prAdapter,
2509                 CMD_ID_SET_RX_FILTER,
2510                 TRUE,
2511                 FALSE,
2512                 FALSE,
2513                 nicCmdEventSetCommon,
2514                 nicOidCmdTimeoutCommon,
2515                 sizeof(UINT_32),
2516                 (PUINT_8)&prAdapter->u4OsPacketFilter,
2517                 &u4NewPacketFilter,
2518                 sizeof(u4NewPacketFilter)
2519                 );
2520
2521     } while (FALSE);
2522
2523     return;
2524 }   /* p2pFuncMgmtFrameRegister */
2525
2526
2527 VOID
2528 p2pFuncUpdateMgmtFrameRegister (
2529     IN P_ADAPTER_T prAdapter,
2530     IN UINT_32 u4OsFilter
2531     )
2532 {
2533
2534     do {
2535
2536         prAdapter->rWifiVar.prP2pFsmInfo->u4P2pPacketFilter = u4OsFilter;
2537
2538         if ((prAdapter->u4OsPacketFilter & PARAM_PACKET_FILTER_P2P_MASK) ^ u4OsFilter) {
2539
2540             prAdapter->u4OsPacketFilter &= ~PARAM_PACKET_FILTER_P2P_MASK;
2541
2542             prAdapter->u4OsPacketFilter |= (u4OsFilter & PARAM_PACKET_FILTER_P2P_MASK);
2543             
2544             wlanSendSetQueryCmd(prAdapter,
2545                     CMD_ID_SET_RX_FILTER,
2546                     TRUE,
2547                     FALSE,
2548                     FALSE,
2549                     nicCmdEventSetCommon,
2550                     nicOidCmdTimeoutCommon,
2551                     sizeof(UINT_32),
2552                     (PUINT_8)&prAdapter->u4OsPacketFilter,
2553                     &u4OsFilter,
2554                     sizeof(u4OsFilter)
2555                     );
2556             DBGLOG(P2P, TRACE, ("P2P Set PACKET filter:0x%lx\n", prAdapter->u4OsPacketFilter));
2557         }
2558         
2559     } while (FALSE);
2560
2561     
2562
2563     
2564     return;
2565 } /* p2pFuncUpdateMgmtFrameRegister */
2566
2567
2568 VOID
2569 p2pFuncGetStationInfo (
2570     IN P_ADAPTER_T prAdapter,
2571     IN PUINT_8 pucMacAddr,
2572     OUT P_P2P_STATION_INFO_T prStaInfo
2573     )
2574 {
2575
2576     do {
2577         ASSERT_BREAK((prAdapter != NULL) &&
2578                                     (pucMacAddr != NULL) &&
2579                                     (prStaInfo != NULL));
2580
2581         prStaInfo->u4InactiveTime = 0;
2582         prStaInfo->u4RxBytes = 0;
2583         prStaInfo->u4TxBytes = 0;
2584         prStaInfo->u4RxPackets = 0;
2585         prStaInfo->u4TxPackets = 0;
2586         // TODO:
2587
2588     } while (FALSE);
2589
2590     return;
2591 } /* p2pFuncGetStationInfo */
2592
2593
2594 BOOLEAN
2595 p2pFuncGetAttriList (
2596     IN P_ADAPTER_T prAdapter,
2597     IN UINT_8 ucOuiType,
2598     IN PUINT_8 pucIE,
2599     IN UINT_16 u2IELength,
2600     OUT PPUINT_8 ppucAttriList,
2601     OUT PUINT_16 pu2AttriListLen
2602     )
2603 {
2604     BOOLEAN fgIsAllocMem = FALSE;
2605     UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
2606     UINT_16 u2Offset = 0;
2607     P_IE_P2P_T prIe = (P_IE_P2P_T)NULL;
2608     PUINT_8 pucAttriListStart = (PUINT_8)NULL;
2609     UINT_16 u2AttriListLen = 0, u2BufferSize = 0;
2610     BOOLEAN fgBackupAttributes = FALSE;
2611     
2612     do {
2613         ASSERT_BREAK((prAdapter != NULL) && 
2614                         (pucIE != NULL) &&
2615                         (u2IELength != 0) &&
2616                         (ppucAttriList != NULL) &&
2617                         (pu2AttriListLen != NULL));
2618
2619         if(ppucAttriList) {
2620             *ppucAttriList = NULL;
2621         }
2622         if(pu2AttriListLen) {
2623             *pu2AttriListLen = 0;
2624         }
2625
2626         if (ucOuiType == VENDOR_OUI_TYPE_WPS){
2627             aucWfaOui[0] = 0x00;
2628             aucWfaOui[1] = 0x50;
2629             aucWfaOui[2] = 0xF2;
2630         }
2631         else if ((ucOuiType != VENDOR_OUI_TYPE_P2P) 
2632 #if CFG_SUPPORT_WFD
2633                 && (ucOuiType != VENDOR_OUI_TYPE_WFD)
2634 #endif
2635                 ) {
2636             DBGLOG(P2P, INFO, ("Not supported OUI Type to parsing 0x%x\n", ucOuiType));
2637             break;
2638         }
2639
2640
2641         IE_FOR_EACH(pucIE, u2IELength, u2Offset) {
2642             if (ELEM_ID_VENDOR == IE_ID(pucIE)) {
2643                 prIe = (P_IE_P2P_T)pucIE;
2644
2645                 if (prIe->ucLength <= P2P_OUI_TYPE_LEN) {
2646                     continue;
2647                     
2648                 }
2649
2650                 if ((prIe->aucOui[0] == aucWfaOui[0]) &&
2651                         (prIe->aucOui[1] == aucWfaOui[1]) &&
2652                         (prIe->aucOui[2] == aucWfaOui[2]) &&
2653                         (ucOuiType == prIe->ucOuiType)) {
2654
2655                     if (!pucAttriListStart) {
2656                         pucAttriListStart = &prIe->aucP2PAttributes[0];
2657                         if (prIe->ucLength > P2P_OUI_TYPE_LEN) {
2658                             u2AttriListLen = (UINT_16)(prIe->ucLength - P2P_OUI_TYPE_LEN);
2659                         }
2660                         else {
2661                             ASSERT(FALSE);
2662                         }
2663                     }
2664                     else {
2665 /* More than 2 attributes. */
2666                         UINT_16 u2CopyLen;
2667
2668                         if (FALSE == fgBackupAttributes) {
2669                             P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;;
2670                             
2671                             fgBackupAttributes = TRUE;
2672                             if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
2673                                 kalMemCopy(&prP2pSpecificBssInfo->aucAttributesCache[0],
2674                                        pucAttriListStart,
2675                                        u2AttriListLen);
2676
2677                                 pucAttriListStart = &prP2pSpecificBssInfo->aucAttributesCache[0];
2678
2679                                 u2BufferSize = P2P_MAXIMUM_ATTRIBUTE_LEN;
2680                             }
2681                             else if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
2682                                 kalMemCopy(&prP2pSpecificBssInfo->aucWscAttributesCache[0],
2683                                        pucAttriListStart,
2684                                        u2AttriListLen);
2685                                 pucAttriListStart = &prP2pSpecificBssInfo->aucWscAttributesCache[0];
2686
2687                                 u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE;
2688                             }
2689 #if CFG_SUPPORT_WFD
2690                             else if (ucOuiType == VENDOR_OUI_TYPE_WFD) {
2691                                 PUINT_8 pucTmpBuf = (PUINT_8)NULL;
2692                                 pucTmpBuf = (PUINT_8)kalMemAlloc(WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE, VIR_MEM_TYPE);
2693
2694                                 if (pucTmpBuf != NULL) {
2695                                     fgIsAllocMem = TRUE;
2696                                 }
2697                                 else {
2698                                     /* Can't alloca memory for WFD IE relocate. */
2699                                     ASSERT(FALSE);
2700                                     break;
2701                                 }
2702
2703                                 kalMemCopy(pucTmpBuf,
2704                                        pucAttriListStart,
2705                                        u2AttriListLen);
2706                                 
2707                                 pucAttriListStart = pucTmpBuf;
2708
2709                                 u2BufferSize = WPS_MAXIMUM_ATTRIBUTES_CACHE_SIZE;
2710                             }
2711 #endif
2712                             else {
2713                                 fgBackupAttributes = FALSE;
2714                             }
2715                         }
2716
2717                         u2CopyLen = (UINT_16)(prIe->ucLength - P2P_OUI_TYPE_LEN);
2718
2719                         if ((u2AttriListLen + u2CopyLen) > u2BufferSize) {
2720                         
2721                             u2CopyLen = u2BufferSize - u2AttriListLen;
2722                         
2723                             DBGLOG(P2P, WARN, ("Length of received P2P attributes > maximum cache size.\n"));
2724
2725                         }
2726                         
2727                         if (u2CopyLen) {
2728                             kalMemCopy((PUINT_8)((UINT_32)pucAttriListStart + (UINT_32)u2AttriListLen), 
2729                                         &prIe->aucP2PAttributes[0],
2730                                         u2CopyLen);
2731                             
2732                             u2AttriListLen += u2CopyLen;
2733                         }
2734                         
2735                     
2736                     }
2737                 } /* prIe->aucOui */
2738             } /* ELEM_ID_VENDOR */
2739         } /* IE_FOR_EACH */
2740
2741        
2742     } while (FALSE);
2743
2744     if (pucAttriListStart) {
2745         PUINT_8 pucAttribute = pucAttriListStart;
2746         DBGLOG(P2P, LOUD, ("Checking Attribute Length.\n"));
2747         if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
2748             P2P_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset);
2749         }
2750         else if (ucOuiType == VENDOR_OUI_TYPE_WFD) {
2751         }
2752         else if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
2753             /* Big Endian: WSC, WFD. */
2754             WSC_ATTRI_FOR_EACH(pucAttribute, u2AttriListLen, u2Offset) {
2755             DBGLOG(P2P, LOUD, ("Attribute ID:%d, Length:%d.\n",
2756                                     WSC_ATTRI_ID(pucAttribute),
2757                                     WSC_ATTRI_LEN(pucAttribute)));
2758             }
2759         }
2760         else {
2761         }
2762
2763         ASSERT(u2Offset == u2AttriListLen);
2764     
2765         *ppucAttriList = pucAttriListStart;
2766         *pu2AttriListLen = u2AttriListLen;
2767     
2768     }
2769     else {
2770         *ppucAttriList = (PUINT_8)NULL;
2771         *pu2AttriListLen = 0;
2772     }
2773
2774     return fgIsAllocMem;
2775 } /* p2pFuncGetAttriList */
2776
2777
2778 P_MSDU_INFO_T
2779 p2pFuncProcessP2pProbeRsp (
2780     IN P_ADAPTER_T prAdapter,
2781     IN P_MSDU_INFO_T prMgmtTxMsdu
2782     )
2783 {
2784     P_MSDU_INFO_T prRetMsduInfo = prMgmtTxMsdu;
2785     P_WLAN_PROBE_RSP_FRAME_T prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T)NULL;
2786     PUINT_8 pucIEBuf = (PUINT_8)NULL;
2787     UINT_16 u2Offset = 0, u2IELength = 0, u2ProbeRspHdrLen = 0;
2788     BOOLEAN fgIsP2PIE = FALSE, fgIsWSCIE = FALSE;
2789     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
2790     UINT_16 u2EstimateSize = 0, u2EstimatedExtraIELen = 0;
2791     UINT_32 u4IeArraySize = 0, u4Idx = 0;
2792
2793
2794     do {
2795         ASSERT_BREAK((prAdapter != NULL) && (prMgmtTxMsdu != NULL));
2796
2797         prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
2798
2799         //3 Make sure this is probe response frame.
2800         prProbeRspFrame = (P_WLAN_PROBE_RSP_FRAME_T)((UINT_32)prMgmtTxMsdu->prPacket + MAC_TX_RESERVED_FIELD);
2801         ASSERT_BREAK((prProbeRspFrame->u2FrameCtrl & MASK_FRAME_TYPE) == MAC_FRAME_PROBE_RSP);
2802
2803         //3 Get the importent P2P IE.
2804         u2ProbeRspHdrLen = (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN);
2805         pucIEBuf = prProbeRspFrame->aucInfoElem;
2806         u2IELength = prMgmtTxMsdu->u2FrameLength - u2ProbeRspHdrLen;
2807
2808 #if CFG_SUPPORT_WFD
2809         prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen = 0;
2810 #endif
2811
2812         IE_FOR_EACH(pucIEBuf, u2IELength, u2Offset) {
2813             switch (IE_ID(pucIEBuf)) {
2814             case ELEM_ID_SSID:
2815                 {
2816
2817
2818                     COPY_SSID(prP2pBssInfo->aucSSID,
2819                                     prP2pBssInfo->ucSSIDLen,
2820                                     SSID_IE(pucIEBuf)->aucSSID,
2821                                     SSID_IE(pucIEBuf)->ucLength);
2822                 }
2823                 break;
2824             case ELEM_ID_VENDOR:
2825                 {
2826                     UINT_8 ucOuiType = 0;
2827                     UINT_16 u2SubTypeVersion = 0;
2828 #if! CFG_SUPPORT_WFD
2829                     
2830                     if (rsnParseCheckForWFAInfoElem(prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) {
2831                         if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
2832                             kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 2, pucIEBuf, IE_SIZE(pucIEBuf));
2833                             fgIsWSCIE = TRUE;
2834                         }
2835
2836
2837                     }
2838
2839
2840                     else if (p2pFuncParseCheckForP2PInfoElem(prAdapter, pucIEBuf, &ucOuiType)) {
2841                         if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
2842                             //2 Note(frog): I use WSC IE buffer for Probe Request to store the P2P IE for Probe Response.
2843                             kalP2PUpdateWSC_IE(prAdapter->prGlueInfo, 1, pucIEBuf, IE_SIZE(pucIEBuf));
2844                             fgIsP2PIE = TRUE;
2845                         }
2846
2847
2848                     }
2849
2850                     else {
2851                         if((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen+IE_SIZE(pucIEBuf))<512) {
2852                             kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, pucIEBuf, IE_SIZE(pucIEBuf));
2853                             prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += IE_SIZE(pucIEBuf);
2854                         }
2855                     }
2856 #else
2857                     /* Eddie May be WFD */
2858                    if (rsnParseCheckForWFAInfoElem(prAdapter, pucIEBuf, &ucOuiType, &u2SubTypeVersion)) {
2859                                 if(ucOuiType == VENDOR_OUI_TYPE_WMM) {
2860                                                 break;
2861                                  }
2862                                         
2863                         }
2864                             if((prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen+IE_SIZE(pucIEBuf))<1024) {
2865                                         kalMemCopy(prAdapter->prGlueInfo->prP2PInfo->aucVenderIE + prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen
2866                                                 , pucIEBuf, IE_SIZE(pucIEBuf));
2867                                         prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen += IE_SIZE(pucIEBuf);
2868                                 }
2869 #endif
2870
2871
2872                 }
2873                 break;
2874             default:
2875                 break;
2876             }
2877
2878
2879         }
2880
2881
2882
2883         //3 Check the total size & current frame.
2884         u2EstimateSize = WLAN_MAC_MGMT_HEADER_LEN + \
2885                         TIMESTAMP_FIELD_LEN + \
2886                         BEACON_INTERVAL_FIELD_LEN + \
2887                         CAP_INFO_FIELD_LEN + \
2888                         (ELEM_HDR_LEN + ELEM_MAX_LEN_SSID) + \
2889                         (ELEM_HDR_LEN + ELEM_MAX_LEN_SUP_RATES) + \
2890                         (ELEM_HDR_LEN + ELEM_MAX_LEN_DS_PARAMETER_SET);
2891
2892         u2EstimatedExtraIELen = 0;
2893
2894         u4IeArraySize = sizeof(txProbeRspIETable)/sizeof(APPEND_VAR_IE_ENTRY_T);
2895         for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) {
2896             if (txProbeRspIETable[u4Idx].u2EstimatedFixedIELen) {
2897                 u2EstimatedExtraIELen += txProbeRspIETable[u4Idx].u2EstimatedFixedIELen;
2898             }
2899
2900
2901             else {
2902                 ASSERT(txProbeRspIETable[u4Idx].pfnCalculateVariableIELen);
2903
2904                 u2EstimatedExtraIELen += (UINT_16)(txProbeRspIETable[u4Idx].pfnCalculateVariableIELen(prAdapter,
2905                                                                                                                                 NETWORK_TYPE_P2P_INDEX,
2906                                                                                                                                 NULL));
2907             }
2908
2909
2910         }
2911
2912
2913
2914         if (fgIsWSCIE) {
2915             u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2);
2916         }
2917
2918         if (fgIsP2PIE) {
2919             u2EstimatedExtraIELen += kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1);
2920         }
2921
2922
2923 #if CFG_SUPPORT_WFD
2924          u2EstimatedExtraIELen += prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen;
2925 #endif   
2926       
2927
2928
2929
2930         if ((u2EstimateSize += u2EstimatedExtraIELen) > (prRetMsduInfo->u2FrameLength)) {
2931             prRetMsduInfo = cnmMgtPktAlloc(prAdapter, u2EstimateSize);
2932
2933             if (prRetMsduInfo == NULL) {
2934                 DBGLOG(P2P, WARN, ("No packet for sending new probe response, use original one\n"));
2935                 prRetMsduInfo = prMgmtTxMsdu;
2936                 break;
2937             }
2938
2939
2940
2941             prRetMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
2942         }
2943
2944
2945
2946         //3 Compose / Re-compose probe response frame.
2947         bssComposeBeaconProbeRespFrameHeaderAndFF(
2948                                                         (PUINT_8)((UINT_32)(prRetMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD),
2949                                                         prProbeRspFrame->aucDestAddr,
2950                                                         prProbeRspFrame->aucSrcAddr,
2951                                                         prProbeRspFrame->aucBSSID,
2952                                                         prProbeRspFrame->u2BeaconInterval,
2953                                                         prProbeRspFrame->u2CapInfo);
2954
2955         prRetMsduInfo->u2FrameLength = (WLAN_MAC_MGMT_HEADER_LEN + TIMESTAMP_FIELD_LEN + BEACON_INTERVAL_FIELD_LEN + CAP_INFO_FIELD_LEN);
2956
2957         bssBuildBeaconProbeRespFrameCommonIEs(prRetMsduInfo,
2958                                                 prP2pBssInfo,
2959                                                 prProbeRspFrame->aucDestAddr);
2960
2961
2962         for (u4Idx = 0; u4Idx < u4IeArraySize; u4Idx++) {
2963             if (txProbeRspIETable[u4Idx].pfnAppendIE) {
2964                 txProbeRspIETable[u4Idx].pfnAppendIE(prAdapter, prRetMsduInfo);
2965             }
2966
2967
2968         }
2969
2970
2971
2972         if (fgIsWSCIE) {
2973             kalP2PGenWSC_IE(prAdapter->prGlueInfo,
2974                                 2,
2975                                 (PUINT_8)((UINT_32)prRetMsduInfo->prPacket + (UINT_32)prRetMsduInfo->u2FrameLength));
2976
2977             prRetMsduInfo->u2FrameLength += (UINT_16)kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 2);
2978         }
2979
2980         if (fgIsP2PIE) {
2981             kalP2PGenWSC_IE(prAdapter->prGlueInfo,
2982                                 1,
2983                                 (PUINT_8)((UINT_32)prRetMsduInfo->prPacket + (UINT_32)prRetMsduInfo->u2FrameLength));
2984
2985             prRetMsduInfo->u2FrameLength += (UINT_16)kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 1);
2986         }
2987
2988
2989 #if CFG_SUPPORT_WFD
2990         if(prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen>0) {
2991             kalMemCopy((PUINT_8)((UINT_32)prRetMsduInfo->prPacket + (UINT_32)prRetMsduInfo->u2FrameLength), 
2992                     prAdapter->prGlueInfo->prP2PInfo->aucVenderIE, prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen);
2993             prRetMsduInfo->u2FrameLength += (UINT_16) prAdapter->prGlueInfo->prP2PInfo->u2VenderIELen;
2994         }
2995 #endif
2996
2997
2998     } while (FALSE);
2999
3000     if (prRetMsduInfo != prMgmtTxMsdu) {
3001         cnmMgtPktFree(prAdapter, prMgmtTxMsdu);
3002     }
3003
3004
3005
3006     return prRetMsduInfo;
3007 } /* p2pFuncProcessP2pProbeRsp */
3008
3009
3010 #if 0 //LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
3011 UINT_32
3012 p2pFuncCalculateExtra_IELenForBeacon (
3013     IN P_ADAPTER_T prAdapter,
3014     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
3015     IN P_STA_RECORD_T prStaRec
3016     )
3017 {
3018
3019
3020     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
3021     UINT_32 u4IELen = 0;
3022
3023     do {
3024         ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX));
3025
3026         if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) {
3027             break;
3028         }
3029
3030         prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
3031
3032         u4IELen = prP2pSpeBssInfo->u2IELenForBCN;
3033
3034     } while (FALSE);
3035
3036     return u4IELen;
3037 } /* p2pFuncCalculateP2p_IELenForBeacon */
3038
3039 VOID
3040 p2pFuncGenerateExtra_IEForBeacon (
3041     IN P_ADAPTER_T prAdapter,
3042     IN P_MSDU_INFO_T prMsduInfo
3043     )
3044 {
3045     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
3046     PUINT_8 pucIEBuf = (PUINT_8)NULL;
3047
3048     do {
3049         ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
3050
3051         prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
3052
3053         if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) {
3054
3055
3056             break;
3057         }
3058
3059         pucIEBuf = (PUINT_8)((UINT_32)prMsduInfo->prPacket + (UINT_32)prMsduInfo->u2FrameLength);
3060
3061         kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucBeaconIECache, prP2pSpeBssInfo->u2IELenForBCN);
3062
3063         prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2IELenForBCN;
3064
3065     } while (FALSE);
3066
3067     return;
3068 } /* p2pFuncGenerateExtra_IEForBeacon */
3069
3070
3071 #else
3072 UINT_32
3073 p2pFuncCalculateP2p_IELenForBeacon (
3074     IN P_ADAPTER_T prAdapter,
3075     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
3076     IN P_STA_RECORD_T prStaRec
3077     )
3078 {
3079     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
3080     UINT_32 u4IELen = 0;
3081
3082     do {
3083         ASSERT_BREAK((prAdapter != NULL) && (eNetTypeIndex == NETWORK_TYPE_P2P_INDEX));
3084
3085         if (!prAdapter->fgIsP2PRegistered) {
3086             break;
3087         }
3088
3089
3090
3091         if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) {
3092             break;
3093         }
3094
3095         prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
3096
3097         u4IELen = prP2pSpeBssInfo->u2AttributeLen;
3098
3099     } while (FALSE);
3100
3101     return u4IELen;
3102 } /* p2pFuncCalculateP2p_IELenForBeacon */
3103
3104
3105 VOID
3106 p2pFuncGenerateP2p_IEForBeacon (
3107     IN P_ADAPTER_T prAdapter,
3108     IN P_MSDU_INFO_T prMsduInfo
3109     )
3110 {
3111     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpeBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
3112     PUINT_8 pucIEBuf = (PUINT_8)NULL;
3113
3114     do {
3115         ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
3116
3117         if (!prAdapter->fgIsP2PRegistered) {
3118             break;
3119         }
3120
3121
3122         prP2pSpeBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
3123
3124         if (p2pFuncIsAPMode(prAdapter->rWifiVar.prP2pFsmInfo)) {
3125
3126
3127             break;
3128         }
3129
3130         pucIEBuf = (PUINT_8)((UINT_32)prMsduInfo->prPacket + (UINT_32)prMsduInfo->u2FrameLength);
3131
3132         kalMemCopy(pucIEBuf, prP2pSpeBssInfo->aucAttributesCache, prP2pSpeBssInfo->u2AttributeLen);
3133
3134         prMsduInfo->u2FrameLength += prP2pSpeBssInfo->u2AttributeLen;
3135
3136     } while (FALSE);
3137
3138     return;
3139 } /* p2pFuncGenerateP2p_IEForBeacon */
3140
3141
3142
3143
3144
3145 UINT_32
3146 p2pFuncCalculateWSC_IELenForBeacon (
3147     IN P_ADAPTER_T prAdapter,
3148     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
3149     IN P_STA_RECORD_T prStaRec
3150     )
3151 {
3152     if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) {
3153         return 0;
3154     }
3155
3156     return kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0);
3157 } /* p2pFuncCalculateP2p_IELenForBeacon */
3158
3159
3160 VOID
3161 p2pFuncGenerateWSC_IEForBeacon (
3162     IN P_ADAPTER_T prAdapter,
3163     IN P_MSDU_INFO_T prMsduInfo
3164     )
3165 {
3166     PUINT_8               pucBuffer;
3167     UINT_16               u2IELen = 0;
3168     ASSERT(prAdapter);
3169     ASSERT(prMsduInfo);
3170
3171     if (prMsduInfo->ucNetworkType != NETWORK_TYPE_P2P_INDEX) {
3172         return;
3173     }
3174
3175     u2IELen = (UINT_16)kalP2PCalWSC_IELen(prAdapter->prGlueInfo, 0);
3176
3177     pucBuffer = (PUINT_8)((UINT_32)prMsduInfo->prPacket +
3178                           (UINT_32)prMsduInfo->u2FrameLength);
3179
3180     ASSERT(pucBuffer);
3181
3182     // TODO: Check P2P FSM State.
3183     kalP2PGenWSC_IE(prAdapter->prGlueInfo,
3184                    0,
3185                    pucBuffer);
3186
3187     prMsduInfo->u2FrameLength += u2IELen;
3188
3189     return;
3190 } /* p2pFuncGenerateP2p_IEForBeacon */
3191
3192 #endif
3193 /*----------------------------------------------------------------------------*/
3194 /*!
3195 * @brief This function is used to calculate P2P IE length for Beacon frame.
3196 *
3197 * @param[in] eNetTypeIndex      Specify which network
3198 * @param[in] prStaRec           Pointer to the STA_RECORD_T
3199 *
3200 * @return The length of P2P IE added
3201 */
3202 /*----------------------------------------------------------------------------*/
3203 UINT_32
3204 p2pFuncCalculateP2p_IELenForAssocRsp (
3205     IN P_ADAPTER_T prAdapter,
3206     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
3207     IN P_STA_RECORD_T prStaRec
3208     )
3209 {
3210
3211     if (eNetTypeIndex != NETWORK_TYPE_P2P_INDEX) {
3212         return 0;
3213     }
3214
3215     return p2pFuncCalculateP2P_IELen(prAdapter,
3216                                 eNetTypeIndex,
3217                                 prStaRec,
3218                                 txAssocRspAttributesTable,
3219                                 sizeof(txAssocRspAttributesTable)/sizeof(APPEND_VAR_ATTRI_ENTRY_T));
3220
3221 } /* p2pFuncCalculateP2p_IELenForAssocRsp */
3222
3223
3224
3225
3226
3227
3228 /*----------------------------------------------------------------------------*/
3229 /*!
3230 * @brief This function is used to generate P2P IE for Beacon frame.
3231 *
3232 * @param[in] prMsduInfo             Pointer to the composed MSDU_INFO_T.
3233 *
3234 * @return none
3235 */
3236 /*----------------------------------------------------------------------------*/
3237 VOID
3238 p2pFuncGenerateP2p_IEForAssocRsp (
3239     IN P_ADAPTER_T prAdapter,
3240     IN P_MSDU_INFO_T prMsduInfo
3241     )
3242 {
3243     P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
3244     P_STA_RECORD_T prStaRec = (P_STA_RECORD_T)NULL;
3245
3246     do {
3247         ASSERT_BREAK((prAdapter != NULL) && (prMsduInfo != NULL));
3248
3249         prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
3250
3251         prStaRec = cnmGetStaRecByIndex(prAdapter, prMsduInfo->ucStaRecIndex);
3252
3253         if (IS_STA_P2P_TYPE(prStaRec)) {
3254             DBGLOG(P2P, TRACE, ("Generate NULL P2P IE for Assoc Rsp.\n"));
3255
3256             p2pFuncGenerateP2P_IE(prAdapter,
3257                     TRUE,
3258                     &prMsduInfo->u2FrameLength,
3259                     prMsduInfo->prPacket,
3260                     1500,
3261                     txAssocRspAttributesTable,
3262                     sizeof(txAssocRspAttributesTable)/sizeof(APPEND_VAR_ATTRI_ENTRY_T));
3263         }
3264         else {
3265
3266
3267             DBGLOG(P2P, TRACE, ("Legacy device, no P2P IE.\n"));
3268         }
3269
3270     } while (FALSE);
3271
3272     return;
3273
3274 } /* p2pFuncGenerateP2p_IEForAssocRsp */
3275
3276
3277
3278
3279 UINT_32
3280 p2pFuncCalculateP2P_IELen (
3281     IN P_ADAPTER_T prAdapter,
3282     IN ENUM_NETWORK_TYPE_INDEX_T eNetTypeIndex,
3283     IN P_STA_RECORD_T prStaRec,
3284     IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[],
3285     IN UINT_32 u4AttriTableSize
3286     )
3287 {
3288
3289
3290     UINT_32 u4OverallAttriLen, u4Dummy;
3291     UINT_16 u2EstimatedFixedAttriLen;
3292     UINT_32 i;
3293
3294
3295     /* Overall length of all Attributes */
3296     u4OverallAttriLen = 0;
3297
3298     for (i = 0; i < u4AttriTableSize; i++) {
3299         u2EstimatedFixedAttriLen = arAppendAttriTable[i].u2EstimatedFixedAttriLen;
3300
3301         if (u2EstimatedFixedAttriLen) {
3302             u4OverallAttriLen += u2EstimatedFixedAttriLen;
3303         }
3304         else {
3305             ASSERT(arAppendAttriTable[i].pfnCalculateVariableAttriLen);
3306
3307             u4OverallAttriLen +=
3308                 arAppendAttriTable[i].pfnCalculateVariableAttriLen(prAdapter, prStaRec);
3309         }
3310     }
3311
3312     u4Dummy = u4OverallAttriLen;
3313     u4OverallAttriLen += P2P_IE_OUI_HDR;
3314
3315     for (;(u4Dummy > P2P_MAXIMUM_ATTRIBUTE_LEN);) {
3316         u4OverallAttriLen += P2P_IE_OUI_HDR;
3317         u4Dummy -= P2P_MAXIMUM_ATTRIBUTE_LEN;
3318     }
3319
3320     return u4OverallAttriLen;
3321 } /* p2pFuncCalculateP2P_IELen */
3322
3323
3324 VOID
3325 p2pFuncGenerateP2P_IE (
3326     IN P_ADAPTER_T prAdapter,
3327     IN BOOLEAN fgIsAssocFrame,
3328     IN PUINT_16 pu2Offset,
3329     IN PUINT_8 pucBuf,
3330     IN UINT_16 u2BufSize,
3331     IN APPEND_VAR_ATTRI_ENTRY_T arAppendAttriTable[],
3332     IN UINT_32 u4AttriTableSize
3333     )
3334 {
3335     PUINT_8 pucBuffer = (PUINT_8)NULL;
3336     P_IE_P2P_T prIeP2P = (P_IE_P2P_T)NULL;
3337     UINT_32 u4OverallAttriLen;
3338     UINT_32 u4AttriLen;
3339     UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
3340     UINT_8 aucTempBuffer[P2P_MAXIMUM_ATTRIBUTE_LEN];
3341     UINT_32 i;
3342
3343
3344     do {
3345         ASSERT_BREAK((prAdapter != NULL) && (pucBuf != NULL));
3346
3347         pucBuffer = (PUINT_8)((UINT_32)pucBuf + (*pu2Offset));
3348
3349         ASSERT_BREAK(pucBuffer != NULL);
3350
3351         /* Check buffer length is still enough. */
3352         ASSERT_BREAK((u2BufSize - (*pu2Offset)) >= P2P_IE_OUI_HDR);
3353
3354         prIeP2P = (P_IE_P2P_T)pucBuffer;
3355
3356         prIeP2P->ucId = ELEM_ID_P2P;
3357
3358         prIeP2P->aucOui[0] = aucWfaOui[0];
3359         prIeP2P->aucOui[1] = aucWfaOui[1];
3360         prIeP2P->aucOui[2] = aucWfaOui[2];
3361         prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P;
3362
3363         (*pu2Offset) += P2P_IE_OUI_HDR;
3364
3365         /* Overall length of all Attributes */
3366         u4OverallAttriLen = 0;
3367
3368
3369         for (i = 0; i < u4AttriTableSize; i++) {
3370
3371             if (arAppendAttriTable[i].pfnAppendAttri) {
3372                 u4AttriLen = arAppendAttriTable[i].pfnAppendAttri(prAdapter, fgIsAssocFrame, pu2Offset, pucBuf, u2BufSize);
3373
3374                 u4OverallAttriLen += u4AttriLen;
3375
3376                 if (u4OverallAttriLen > P2P_MAXIMUM_ATTRIBUTE_LEN) {
3377                     u4OverallAttriLen -= P2P_MAXIMUM_ATTRIBUTE_LEN;
3378
3379                     prIeP2P->ucLength = (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN);
3380
3381                     pucBuffer = (PUINT_8)((UINT_32)prIeP2P + (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN));
3382
3383                     prIeP2P = (P_IE_P2P_T)((UINT_32)prIeP2P +
3384                             (ELEM_HDR_LEN + (VENDOR_OUI_TYPE_LEN + P2P_MAXIMUM_ATTRIBUTE_LEN)));
3385
3386                     kalMemCopy(aucTempBuffer, pucBuffer, u4OverallAttriLen);
3387
3388                     prIeP2P->ucId = ELEM_ID_P2P;
3389
3390                     prIeP2P->aucOui[0] = aucWfaOui[0];
3391                     prIeP2P->aucOui[1] = aucWfaOui[1];
3392                     prIeP2P->aucOui[2] = aucWfaOui[2];
3393                     prIeP2P->ucOuiType = VENDOR_OUI_TYPE_P2P;
3394
3395                     kalMemCopy(prIeP2P->aucP2PAttributes, aucTempBuffer, u4OverallAttriLen);
3396                     (*pu2Offset) += P2P_IE_OUI_HDR;
3397                 }
3398
3399             }
3400
3401         }
3402
3403         prIeP2P->ucLength = (UINT_8)(VENDOR_OUI_TYPE_LEN + u4OverallAttriLen);
3404
3405
3406     } while (FALSE);
3407
3408     return;
3409 } /* p2pFuncGenerateP2P_IE */
3410
3411 UINT_32
3412 p2pFuncAppendAttriStatusForAssocRsp (
3413     IN P_ADAPTER_T prAdapter,
3414     IN BOOLEAN fgIsAssocFrame,
3415     IN PUINT_16 pu2Offset,
3416     IN PUINT_8 pucBuf,
3417     IN UINT_16 u2BufSize
3418     )
3419 {
3420     PUINT_8 pucBuffer;
3421     P_P2P_ATTRI_STATUS_T prAttriStatus;
3422     P_P2P_CONNECTION_SETTINGS_T prP2pConnSettings = (P_P2P_CONNECTION_SETTINGS_T)NULL;
3423     UINT_32 u4AttriLen = 0;
3424
3425     ASSERT(prAdapter);
3426     ASSERT(pucBuf);
3427
3428     prP2pConnSettings = prAdapter->rWifiVar.prP2PConnSettings;
3429
3430     if (fgIsAssocFrame) {
3431         return u4AttriLen;
3432     }
3433
3434     // TODO: For assoc request P2P IE check in driver & return status in P2P IE.
3435
3436     pucBuffer = (PUINT_8)((UINT_32)pucBuf +
3437                             (UINT_32)(*pu2Offset));
3438
3439     ASSERT(pucBuffer);
3440     prAttriStatus = (P_P2P_ATTRI_STATUS_T)pucBuffer;
3441
3442     ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16)u4AttriLen));
3443
3444
3445
3446
3447     prAttriStatus->ucId = P2P_ATTRI_ID_STATUS;
3448     WLAN_SET_FIELD_16(&prAttriStatus->u2Length, P2P_ATTRI_MAX_LEN_STATUS);
3449
3450     prAttriStatus->ucStatusCode = P2P_STATUS_FAIL_PREVIOUS_PROTOCOL_ERR;
3451
3452     u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_STATUS);
3453
3454     (*pu2Offset) += (UINT_16)u4AttriLen;
3455
3456     return u4AttriLen;
3457 } /* p2pFuncAppendAttriStatusForAssocRsp */
3458
3459 UINT_32
3460 p2pFuncAppendAttriExtListenTiming (
3461     IN P_ADAPTER_T prAdapter,
3462     IN BOOLEAN fgIsAssocFrame,
3463     IN PUINT_16 pu2Offset,
3464     IN PUINT_8 pucBuf,
3465     IN UINT_16 u2BufSize
3466     )
3467 {
3468     UINT_32 u4AttriLen = 0;
3469     P_P2P_ATTRI_EXT_LISTEN_TIMING_T prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T)NULL;
3470     P_P2P_SPECIFIC_BSS_INFO_T prP2pSpecificBssInfo = (P_P2P_SPECIFIC_BSS_INFO_T)NULL;
3471     PUINT_8 pucBuffer = NULL;
3472
3473     ASSERT(prAdapter);
3474     ASSERT(pucBuf);
3475
3476     if (fgIsAssocFrame) {
3477         return u4AttriLen;
3478     }
3479
3480     // TODO: For extend listen timing.
3481
3482     prP2pSpecificBssInfo = prAdapter->rWifiVar.prP2pSpecificBssInfo;
3483
3484     u4AttriLen = (P2P_ATTRI_HDR_LEN + P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING);
3485
3486     ASSERT(u2BufSize >= ((*pu2Offset) + (UINT_16)u4AttriLen));
3487
3488     pucBuffer = (PUINT_8)((UINT_32)pucBuf +
3489                             (UINT_32)(*pu2Offset));
3490
3491     ASSERT(pucBuffer);
3492
3493     prP2pExtListenTiming = (P_P2P_ATTRI_EXT_LISTEN_TIMING_T)pucBuffer;
3494
3495     prP2pExtListenTiming->ucId = P2P_ATTRI_ID_EXT_LISTEN_TIMING;
3496     WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2Length, P2P_ATTRI_MAX_LEN_EXT_LISTEN_TIMING);
3497     WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailInterval, prP2pSpecificBssInfo->u2AvailabilityInterval);
3498     WLAN_SET_FIELD_16(&prP2pExtListenTiming->u2AvailPeriod, prP2pSpecificBssInfo->u2AvailabilityPeriod);
3499
3500     (*pu2Offset) += (UINT_16)u4AttriLen;
3501
3502     return u4AttriLen;
3503 } /* p2pFuncAppendAttriExtListenTiming */
3504
3505
3506 P_IE_HDR_T
3507 p2pFuncGetSpecIE (
3508     IN P_ADAPTER_T prAdapter,
3509     IN PUINT_8 pucIEBuf,
3510     IN UINT_16 u2BufferLen,
3511     IN UINT_8 ucElemID,
3512     IN PBOOLEAN pfgIsMore
3513     )
3514 {
3515     P_IE_HDR_T prTargetIE = (P_IE_HDR_T)NULL;
3516     PUINT_8 pucIE = (PUINT_8)NULL;
3517     UINT_16 u2Offset = 0;
3518     
3519     if (pfgIsMore) {
3520             *pfgIsMore = FALSE;
3521     }
3522     
3523     do {
3524         ASSERT_BREAK((prAdapter != NULL) 
3525                 && (pucIEBuf != NULL));
3526
3527         pucIE = pucIEBuf;
3528
3529         IE_FOR_EACH(pucIE, u2BufferLen, u2Offset) {
3530             if (IE_ID(pucIE) == ucElemID) {
3531                 if ((prTargetIE) && (pfgIsMore)) {
3532
3533
3534                     *pfgIsMore = TRUE;
3535                     break;
3536                 }
3537                 else {
3538                     prTargetIE = (P_IE_HDR_T)pucIE;
3539
3540                     if (pfgIsMore == NULL) {
3541                         break;
3542                     }
3543
3544
3545                 }
3546
3547
3548             }
3549         }
3550
3551     } while (FALSE);
3552
3553     return prTargetIE;
3554 } /* p2pFuncGetSpecIE */
3555
3556
3557
3558 P_ATTRIBUTE_HDR_T
3559 p2pFuncGetSpecAttri (
3560     IN P_ADAPTER_T prAdapter,
3561     IN UINT_8 ucOuiType,
3562     IN PUINT_8 pucIEBuf,
3563     IN UINT_16 u2BufferLen,
3564     IN UINT_16 u2AttriID
3565     )
3566 {
3567     P_IE_P2P_T prP2pIE = (P_IE_P2P_T)NULL;
3568     P_ATTRIBUTE_HDR_T prTargetAttri = (P_ATTRIBUTE_HDR_T)NULL;
3569     BOOLEAN fgIsMore = FALSE;
3570     PUINT_8 pucIE = (PUINT_8)NULL, pucAttri = (PUINT_8)NULL;
3571     UINT_16 u2OffsetAttri = 0;
3572     UINT_16 u2BufferLenLeft = 0;
3573     UINT_8 aucWfaOui[] = VENDOR_OUI_WFA_SPECIFIC;
3574
3575
3576     DBGLOG(P2P, INFO, ("Check AssocReq Oui type %u attri %u for len %u\n",ucOuiType, u2AttriID, u2BufferLen));
3577
3578     do {
3579         ASSERT_BREAK((prAdapter != NULL) 
3580                 && (pucIEBuf != NULL));
3581
3582         u2BufferLenLeft = u2BufferLen;
3583         pucIE = pucIEBuf;        
3584         do {
3585             fgIsMore = FALSE;
3586             prP2pIE = (P_IE_P2P_T)p2pFuncGetSpecIE(prAdapter,
3587                                             pucIE,
3588                                             u2BufferLenLeft,
3589                                             ELEM_ID_VENDOR,
3590                                             &fgIsMore);
3591
3592             if (prP2pIE) {
3593
3594                 ASSERT(prP2pIE>pucIE);
3595
3596                 u2BufferLenLeft = u2BufferLen - (UINT_16)(  ((UINT_32)prP2pIE) - ((UINT_32)pucIEBuf));
3597
3598                 DBGLOG(P2P, INFO, ("Find vendor id %u len %u oui %u more %u LeftLen %u\n",
3599                         IE_ID(prP2pIE), IE_LEN(prP2pIE), prP2pIE->ucOuiType, fgIsMore, u2BufferLenLeft));
3600
3601                 if(IE_LEN(prP2pIE) > P2P_OUI_TYPE_LEN) {
3602
3603                 if (prP2pIE->ucOuiType == ucOuiType) {
3604                     switch (ucOuiType) {
3605                     case VENDOR_OUI_TYPE_WPS:
3606                         aucWfaOui[0] = 0x00;
3607                         aucWfaOui[1] = 0x50;
3608                         aucWfaOui[2] = 0xF2;
3609                         break;
3610                     case VENDOR_OUI_TYPE_P2P:
3611                         break;
3612                     case VENDOR_OUI_TYPE_WPA:
3613                     case VENDOR_OUI_TYPE_WMM:
3614                     case VENDOR_OUI_TYPE_WFD:
3615                     default:
3616                         break;
3617                     }
3618
3619
3620
3621                         if ((prP2pIE->aucOui[0] == aucWfaOui[0]) 
3622                               && (prP2pIE->aucOui[1] == aucWfaOui[1]) 
3623                               && (prP2pIE->aucOui[2] == aucWfaOui[2]) 
3624                                 ) {
3625
3626                             u2OffsetAttri = 0;
3627                         pucAttri = prP2pIE->aucP2PAttributes;
3628
3629                         if (ucOuiType == VENDOR_OUI_TYPE_WPS) {
3630                                 WSC_ATTRI_FOR_EACH(pucAttri, (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) {
3631                                     //LOG_FUNC("WSC: attri id=%u len=%u\n",WSC_ATTRI_ID(pucAttri), WSC_ATTRI_LEN(pucAttri));
3632                                     if (WSC_ATTRI_ID(pucAttri) == u2AttriID) {
3633                                     prTargetAttri = (P_ATTRIBUTE_HDR_T)pucAttri;
3634                                     break;
3635                                 }
3636
3637
3638                             }
3639
3640
3641                         }
3642
3643
3644                         else if (ucOuiType == VENDOR_OUI_TYPE_P2P) {
3645                                 P2P_ATTRI_FOR_EACH(pucAttri, (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) {
3646                                     //LOG_FUNC("P2P: attri id=%u len=%u\n",ATTRI_ID(pucAttri), ATTRI_LEN(pucAttri));
3647                                     if (ATTRI_ID(pucAttri) == (UINT_8)u2AttriID) {
3648                                     prTargetAttri = (P_ATTRIBUTE_HDR_T)pucAttri;
3649                                     break;
3650                                 }
3651
3652
3653                             }
3654
3655
3656                         }
3657
3658                             else if (ucOuiType == VENDOR_OUI_TYPE_WFD) {
3659                                 WFD_ATTRI_FOR_EACH(pucAttri, (IE_LEN(prP2pIE) - P2P_OUI_TYPE_LEN), u2OffsetAttri) {
3660                                     //DBGLOG(P2P, INFO, ("WFD: attri id=%u len=%u\n",WFD_ATTRI_ID(pucAttri), WFD_ATTRI_LEN(pucAttri)));
3661                                     if (ATTRI_ID(pucAttri) == (UINT_8)u2AttriID) {
3662                                         prTargetAttri = (P_ATTRIBUTE_HDR_T)pucAttri;
3663                                         break;
3664                                     }
3665
3666                         }
3667                     }
3668                             else {
3669                                 // Possible or else.
3670                 }
3671
3672             }
3673
3674                     } /* ucOuiType */
3675
3676                 } /* P2P_OUI_TYPE_LEN */ 
3677             
3678                 pucIE = (PUINT_8)(((UINT_32)prP2pIE) + IE_SIZE(prP2pIE));
3679
3680             } /* prP2pIE */
3681                 
3682         } while (prP2pIE && fgIsMore && u2BufferLenLeft);
3683
3684     } while (FALSE);
3685
3686     return prTargetAttri;
3687 }
3688 /* p2pFuncGetSpecAttri */
3689
3690
3691 WLAN_STATUS
3692 p2pFuncGenerateBeaconProbeRsp (
3693     IN P_ADAPTER_T prAdapter,
3694     IN P_BSS_INFO_T prBssInfo,
3695     IN P_MSDU_INFO_T prMsduInfo,
3696     IN BOOLEAN fgIsProbeRsp
3697     )
3698 {
3699     WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
3700     P_WLAN_BEACON_FRAME_T prBcnFrame = (P_WLAN_BEACON_FRAME_T)NULL;
3701 //    P_APPEND_VAR_IE_ENTRY_T prAppendIeTable = (P_APPEND_VAR_IE_ENTRY_T)NULL;
3702
3703
3704     do {
3705
3706         ASSERT_BREAK((prAdapter != NULL) &&
3707                                 (prBssInfo != NULL) &&
3708                                 (prMsduInfo != NULL));
3709
3710
3711 //        txBcnIETable
3712
3713 //        txProbeRspIETable
3714
3715
3716
3717         prBcnFrame = (P_WLAN_BEACON_FRAME_T)prMsduInfo->prPacket;
3718     
3719         return nicUpdateBeaconIETemplate(prAdapter,
3720                     IE_UPD_METHOD_UPDATE_ALL,
3721                     NETWORK_TYPE_P2P_INDEX,
3722                     prBssInfo->u2CapInfo,
3723                     (PUINT_8)prBcnFrame->aucInfoElem,
3724                     prMsduInfo->u2FrameLength - OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem));
3725     
3726     } while (FALSE);
3727
3728     return rWlanStatus;
3729 } /* p2pFuncGenerateBeaconProbeRsp */
3730
3731
3732 WLAN_STATUS
3733 p2pFuncComposeBeaconProbeRspTemplate (
3734     IN P_ADAPTER_T prAdapter,
3735     IN PUINT_8 pucBcnBuffer,
3736     IN UINT_32 u4BcnBufLen,
3737     IN BOOLEAN fgIsProbeRsp,
3738     IN P_P2P_PROBE_RSP_UPDATE_INFO_T prP2pProbeRspInfo,
3739     IN BOOLEAN fgSynToFW
3740     )
3741 {
3742     WLAN_STATUS rWlanStatus = WLAN_STATUS_SUCCESS;
3743     P_MSDU_INFO_T prMsduInfo = (P_MSDU_INFO_T)NULL;
3744     P_WLAN_MAC_HEADER_T prWlanBcnFrame = (P_WLAN_MAC_HEADER_T)NULL;
3745     P_BSS_INFO_T prP2pBssInfo = (P_BSS_INFO_T)NULL;
3746     
3747     PUINT_8 pucBuffer = (PUINT_8)NULL;
3748     
3749     do {
3750         ASSERT_BREAK((prAdapter != NULL) && (pucBcnBuffer != NULL));
3751
3752         prWlanBcnFrame = (P_WLAN_MAC_HEADER_T)pucBcnBuffer;
3753
3754         if ((prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_BEACON) && (!fgIsProbeRsp)) {
3755             rWlanStatus = WLAN_STATUS_INVALID_DATA;
3756             break;
3757         }
3758
3759
3760         else if (prWlanBcnFrame->u2FrameCtrl != MAC_FRAME_PROBE_RSP) {
3761             rWlanStatus = WLAN_STATUS_INVALID_DATA;
3762             break;
3763         }
3764
3765
3766
3767
3768         if (fgIsProbeRsp) {
3769             ASSERT_BREAK(prP2pProbeRspInfo != NULL);
3770
3771             if (!prP2pProbeRspInfo->prProbeRspMsduTemplate) {
3772                 cnmMgtPktFree(prAdapter, prP2pProbeRspInfo->prProbeRspMsduTemplate);
3773             }
3774
3775             prP2pProbeRspInfo->prProbeRspMsduTemplate = cnmMgtPktAlloc(prAdapter, u4BcnBufLen);
3776
3777             prMsduInfo = prP2pProbeRspInfo->prProbeRspMsduTemplate;
3778
3779             prMsduInfo->eSrc = TX_PACKET_MGMT;
3780             prMsduInfo->ucStaRecIndex = 0xFF;
3781             prMsduInfo->ucNetworkType = NETWORK_TYPE_P2P_INDEX;
3782
3783         }
3784         else {
3785             prP2pBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_P2P_INDEX]);
3786             prMsduInfo = prP2pBssInfo->prBeacon;
3787
3788             if (prMsduInfo == NULL) {
3789                 rWlanStatus = WLAN_STATUS_FAILURE;
3790                 break;
3791             }
3792
3793             if (u4BcnBufLen > (OFFSET_OF(WLAN_BEACON_FRAME_T, aucInfoElem[0]) + MAX_IE_LENGTH)) {
3794                 /* Unexpected error, buffer overflow. */
3795                 ASSERT(FALSE);
3796                 break;
3797             }
3798
3799
3800         }
3801
3802
3803         
3804         pucBuffer = (PUINT_8)((UINT_32)(prMsduInfo->prPacket) + MAC_TX_RESERVED_FIELD);
3805
3806         kalMemCopy(pucBuffer, pucBcnBuffer, u4BcnBufLen);
3807
3808         prMsduInfo->fgIs802_11 = TRUE;
3809         prMsduInfo->u2FrameLength = (UINT_16)u4BcnBufLen;
3810
3811         if (fgSynToFW) {
3812             rWlanStatus = p2pFuncGenerateBeaconProbeRsp(prAdapter, prP2pBssInfo, prMsduInfo, fgIsProbeRsp);
3813         }
3814
3815
3816     } while (FALSE);
3817
3818     return rWlanStatus;
3819
3820 } /* p2pFuncComposeBeaconTemplate */
3821
3822 BOOLEAN
3823 p2pFuncIsChannelGrant (
3824     IN P_ADAPTER_T prAdapter
3825     )
3826 {
3827     P_P2P_FSM_INFO_T prP2pFsmInfo = (P_P2P_FSM_INFO_T)NULL;
3828
3829     if (prAdapter == NULL)
3830         return FALSE;
3831
3832     prP2pFsmInfo = prAdapter->rWifiVar.prP2pFsmInfo;
3833
3834
3835     if (prP2pFsmInfo == NULL) 
3836         return FALSE;
3837
3838     return (prP2pFsmInfo->eCurrentState == P2P_STATE_CHNL_ON_HAND);
3839     
3840 } /* p2pFuncIsChannelGrant */
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861