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