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