| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009 |
- /*
- ** Id: tdls.c#1
- */
- /*! \file tdls.c
- \brief This file includes IEEE802.11z TDLS support.
- */
- /*
- ** Log: tdls.c
- *
- * 11 13 2013 vend_samp.lin
- * NULL
- * Initial version.
- */
- /*******************************************************************************
- * C O M P I L E R F L A G S
- ********************************************************************************
- */
- /*******************************************************************************
- * E X T E R N A L R E F E R E N C E S
- ********************************************************************************
- */
- #include "precomp.h"
- #if CFG_SUPPORT_TDLS
- #include "tdls.h"
- #include "gl_cfg80211.h"
- #include "queue.h"
- /*******************************************************************************
- * C O N S T A N T S
- ********************************************************************************
- */
- /* The list of valid data rates. */
- /* The list of valid data rates. */
- /*******************************************************************************
- * F U N C T I O N D E C L A R A T I O N S
- ********************************************************************************
- */
- /*******************************************************************************
- * P R I V A T E D A T A
- ********************************************************************************
- */
- static BOOLEAN fgIsPtiTimeoutSkip = FALSE;
- /*******************************************************************************
- * P R I V A T E F U N C T I O N S
- ********************************************************************************
- */
- #define ELEM_ID_LINK_IDENTIFIER_LENGTH 16
- #define TDLS_KEY_TIMEOUT_INTERVAL 43200
- #define UNREACH_ABLE 25
- #define TDLS_REASON_CODE_UNREACHABLE 25
- #define TDLS_REASON_CODE_UNSPECIFIED 26
- #define WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE 25
- #define WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED 26
- UINT_8 g_arTdlsLink[MAXNUM_TDLS_PEER] = {
- 0,
- 0,
- 0,
- 0
- };
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief This routine is called to hadel TDLS link oper from nl80211.
- *
- * \param[in] pvAdapter Pointer to the Adapter structure.
- * \param[in]
- * \param[in]
- * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
- *
- * \retval WLAN_STATUS_SUCCESS
- * \retval WLAN_STATUS_INVALID_LENGTH
- */
- /*----------------------------------------------------------------------------*/
- UINT_32 TdlsexLinkMgt(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen)
- {
- /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
- STA_RECORD_T *prStaRec;
- P_BSS_INFO_T prBssInfo;
- TDLS_CMD_LINK_MGT_T *prCmd;
- prCmd = (TDLS_CMD_LINK_MGT_T *) pvSetBuffer;
- prBssInfo = prAdapter->prAisBssInfo;
- #if 1
- /* AIS only */
- if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) {
- prStaRec = prBssInfo->prStaRecOfAP;
- if (prStaRec == NULL)
- return 0;
- } else {
- return -EINVAL;
- }
- #endif
- prStaRec = prBssInfo->prStaRecOfAP;
- switch (prCmd->ucActionCode) {
- case TDLS_FRM_ACTION_DISCOVERY_REQ:
- if (prStaRec == NULL)
- return 0;
- if (TdlsDataFrameSend_DISCOVERY_REQ(prAdapter,
- prStaRec,
- prCmd->aucPeer,
- prCmd->ucActionCode,
- prCmd->ucDialogToken,
- prCmd->u2StatusCode,
- (UINT_8 *) (prCmd->aucSecBuf),
- prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
- return -1;
- }
- break;
- case TDLS_FRM_ACTION_SETUP_REQ:
- if (prStaRec == NULL)
- return 0;
- prStaRec = cnmGetTdlsPeerByAddress(prAdapter, prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeer);
- g_arTdlsLink[prStaRec->ucTdlsIndex] = 0;
- if (TdlsDataFrameSend_SETUP_REQ(prAdapter,
- prStaRec,
- prCmd->aucPeer,
- prCmd->ucActionCode,
- prCmd->ucDialogToken,
- prCmd->u2StatusCode,
- (UINT_8 *) (prCmd->aucSecBuf),
- prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
- return -1;
- }
- break;
- case TDLS_FRM_ACTION_SETUP_RSP:
- /* fix sigma bug 5.2.4.2, 5.2.4.7, we sent Status code decline,
- * but the sigma recogniezis it as scucess, and it will fail */
- /* if(prCmd->u2StatusCode != 0) */
- if (prBssInfo->fgTdlsIsProhibited)
- return 0;
- if (TdlsDataFrameSend_SETUP_RSP(prAdapter,
- prStaRec,
- prCmd->aucPeer,
- prCmd->ucActionCode,
- prCmd->ucDialogToken,
- prCmd->u2StatusCode,
- (UINT_8 *) (prCmd->aucSecBuf),
- prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
- return -1;
- }
- break;
- case TDLS_FRM_ACTION_DISCOVERY_RSP:
- if (TdlsDataFrameSend_DISCOVERY_RSP(prAdapter,
- prStaRec,
- prCmd->aucPeer,
- prCmd->ucActionCode,
- prCmd->ucDialogToken,
- prCmd->u2StatusCode,
- (UINT_8 *) (prCmd->aucSecBuf),
- prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
- return -1;
- }
- break;
- case TDLS_FRM_ACTION_CONFIRM:
- if (TdlsDataFrameSend_CONFIRM(prAdapter,
- prStaRec,
- prCmd->aucPeer,
- prCmd->ucActionCode,
- prCmd->ucDialogToken,
- prCmd->u2StatusCode,
- (UINT_8 *) (prCmd->aucSecBuf),
- prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
- return -1;
- }
- break;
- case TDLS_FRM_ACTION_TEARDOWN:
- prStaRec = cnmGetTdlsPeerByAddress(prAdapter, prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeer);
- if (prCmd->u2StatusCode == TDLS_REASON_CODE_UNREACHABLE)
- g_arTdlsLink[prStaRec->ucTdlsIndex] = 0;
- if (TdlsDataFrameSend_TearDown(prAdapter,
- prStaRec,
- prCmd->aucPeer,
- prCmd->ucActionCode,
- prCmd->ucDialogToken,
- prCmd->u2StatusCode,
- (UINT_8 *) (prCmd->aucSecBuf),
- prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
- return -1;
- }
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief This routine is called to hadel TDLS link mgt from nl80211.
- *
- * \param[in] pvAdapter Pointer to the Adapter structure.
- * \param[in]
- * \param[in]
- * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
- *
- * \retval WLAN_STATUS_SUCCESS
- * \retval WLAN_STATUS_INVALID_LENGTH
- */
- /*----------------------------------------------------------------------------*/
- UINT_32 TdlsexLinkOper(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen)
- {
- /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
- UINT_16 i;
- STA_RECORD_T *prStaRec;
- TDLS_CMD_LINK_OPER_T *prCmd;
- prCmd = (TDLS_CMD_LINK_OPER_T *) pvSetBuffer;
- switch (prCmd->oper) {
- case TDLS_ENABLE_LINK:
- for (i = 0; i < MAXNUM_TDLS_PEER; i++) {
- if (!g_arTdlsLink[i]) {
- g_arTdlsLink[i] = 1;
- prStaRec =
- cnmGetTdlsPeerByAddress(prAdapter,
- prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeerMac);
- prStaRec->ucTdlsIndex = i;
- break;
- }
- }
- break;
- case TDLS_DISABLE_LINK:
- prStaRec = cnmGetTdlsPeerByAddress(prAdapter, prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeerMac);
- g_arTdlsLink[prStaRec->ucTdlsIndex] = 0;
- if (IS_DLS_STA(prStaRec))
- cnmStaRecFree(prAdapter, prStaRec);
- break;
- default:
- return 0;
- }
- return 0;
- }
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief This routine is called to append general IEs.
- *
- * \param[in] pvAdapter Pointer to the Adapter structure.
- * \param[in]
- *
- * \retval append length
- */
- /*----------------------------------------------------------------------------*/
- UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_8 *pPkt)
- {
- GLUE_INFO_T *prGlueInfo;
- BSS_INFO_T *prBssInfo;
- PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
- UINT_32 u4NonHTPhyType;
- UINT_16 u2SupportedRateSet;
- UINT_8 aucAllSupportedRates[RATE_NUM_SW] = { 0 }; /* 6628 RATE_NUM -> 6630 RATE_NUM_SW */
- UINT_8 ucAllSupportedRatesLen;
- UINT_8 ucSupRatesLen;
- UINT_8 ucExtSupRatesLen;
- UINT_32 u4PktLen, u4IeLen;
- /* init */
- prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
- prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
- prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
- u4PktLen = 0;
- /* 3. Frame Formation - (5) Supported Rates element */
- /* use all sup rate we can support */
- u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType;
- u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet;
- rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, aucAllSupportedRates, &ucAllSupportedRatesLen);
- ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ?
- ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen);
- ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen;
- if (ucSupRatesLen) {
- SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES;
- SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen;
- kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen);
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- /* 3. Frame Formation - (7) Extended sup rates element */
- if (ucExtSupRatesLen) {
- EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
- EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen;
- kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates,
- &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen);
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- /* 3. Frame Formation - (8) Supported channels element */
- SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS;
- SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 13;
- if (prAdapter->fgEnable5GBand == TRUE) {
- SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165;
- SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 1;
- }
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- return u4PktLen;
- }
- /*******************************************************************************
- * P U B L I C F U N C T I O N S
- ********************************************************************************
- */
- /*!
- * \brief This routine is called to transmit a TDLS data frame.
- *
- * \param[in] pvAdapter Pointer to the Adapter structure.
- * \param[in]
- * \param[in]
- * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
- *
- * \retval WLAN_STATUS_SUCCESS
- * \retval WLAN_STATUS_INVALID_LENGTH
- */
- /*----------------------------------------------------------------------------*/
- WLAN_STATUS
- TdlsDataFrameSend_TearDown(ADAPTER_T *prAdapter,
- STA_RECORD_T *prStaRec,
- UINT_8 *pPeerMac,
- UINT_8 ucActionCode,
- UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
- {
- GLUE_INFO_T *prGlueInfo;
- BSS_INFO_T *prBssInfo;
- PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
- struct sk_buff *prMsduInfo;
- UINT_8 *pPkt;
- UINT_32 u4PktLen, u4IeLen;
- UINT_16 ReasonCode;
- /* allocate/init packet */
- prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
- prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
- prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
- u4PktLen = 0;
- prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
- if (prMsduInfo == NULL)
- return TDLS_STATUS_RESOURCES;
- prMsduInfo->dev = prGlueInfo->prDevHandler;
- if (prMsduInfo->dev == NULL) {
- kalPacketFree(prGlueInfo, prMsduInfo);
- return TDLS_STATUS_FAIL;
- }
- /* make up frame content */
- /* 1. 802.3 header */
- kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
- pPkt += TDLS_FME_MAC_ADDR_LEN;
- kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
- pPkt += TDLS_FME_MAC_ADDR_LEN;
- *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
- pPkt += 2;
- u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2;
- /* 2. payload type */
- *pPkt = TDLS_FRM_PAYLOAD_TYPE;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (1) Category */
- *pPkt = TDLS_FRM_CATEGORY;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (2) Action */
- *pPkt = ucActionCode;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - status code */
- ReasonCode = u2StatusCode;
- kalMemCopy(pPkt, &ReasonCode, 2);
- pPkt = pPkt + 2;
- u4PktLen = u4PktLen + 2;
- if (pAppendIe != NULL) {
- if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) ||
- ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && (prStaRec != NULL))) {
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- LR_TDLS_FME_FIELD_FILL(AppendIeLen);
- }
- }
- /* 7. Append Supported Operating Classes IE */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
- u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- /* 3. Frame Formation - (16) Link identifier element */
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pPeerMac, 6);
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* 5. Update packet length */
- prMsduInfo->len = u4PktLen;
- /* if(u2StatusCode == UNREACH_ABLE ){ */
- /* g_arTdlsLink[prStaRec->ucTdlsIndex] = FALSE; */
- /* } */
- /* 5. send the data frame */
- wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
- return TDLS_STATUS_SUCCESS;
- }
- /*!
- * \brief This routine is called to transmit a TDLS data frame.
- *
- * \param[in] pvAdapter Pointer to the Adapter structure.
- * \param[in]
- * \param[in]
- * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
- *
- * \retval WLAN_STATUS_SUCCESS
- * \retval WLAN_STATUS_INVALID_LENGTH
- */
- /*----------------------------------------------------------------------------*/
- WLAN_STATUS /* TDLS_STATUS */
- TdlsDataFrameSend_SETUP_REQ(ADAPTER_T *prAdapter,
- STA_RECORD_T *prStaRec,
- UINT_8 *pPeerMac,
- UINT_8 ucActionCode,
- UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
- {
- GLUE_INFO_T *prGlueInfo;
- BSS_INFO_T *prBssInfo;
- PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
- struct sk_buff *prMsduInfo;
- UINT_8 *pPkt;
- UINT_32 u4PktLen, u4IeLen;
- BOOLEAN fg40mAllowed;
- UINT_16 u2CapInfo;
- /* allocate/init packet */
- prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
- prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
- prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
- u4PktLen = 0;
- prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
- if (prMsduInfo == NULL)
- return TDLS_STATUS_RESOURCES;
- prMsduInfo->dev = prGlueInfo->prDevHandler;
- if (prMsduInfo->dev == NULL) {
- kalPacketFree(prGlueInfo, prMsduInfo);
- return TDLS_STATUS_FAIL;
- }
- /* make up frame content */
- /* 1. 802.3 header */
- kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
- pPkt += TDLS_FME_MAC_ADDR_LEN;
- kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
- pPkt += TDLS_FME_MAC_ADDR_LEN;
- *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
- pPkt += 2;
- u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2;
- /* 2. payload type */
- *pPkt = TDLS_FRM_PAYLOAD_TYPE;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (1) Category */
- *pPkt = TDLS_FRM_CATEGORY;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (2) Action */
- *pPkt = ucActionCode;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (3) Dialog token */
- *pPkt = ucDialogToken;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (4) Capability */
- u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
- WLAN_SET_FIELD_16(pPkt, u2CapInfo);
- pPkt = pPkt + 2;
- u4PktLen = u4PktLen + 2;
- /* 4. Append general IEs */
- u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* 4. Append extra IEs */
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- pPkt += AppendIeLen;
- u4PktLen += AppendIeLen;
- /* 3. Frame Formation - (10) Extended capabilities element */
- EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
- EXT_CAP_IE(pPkt)->ucLength = 5;
- /* 0320 !! */
- EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
- EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
- EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
- EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0xFF; /* bit32 ~ bit39 */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
- EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
- EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
- /* EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; *//* bit24 ~ bit31 */
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* HT capability IE append 0122 */
- HT_CAP_IE(pPkt)->ucId = ELEM_ID_HT_CAP;
- HT_CAP_IE(pPkt)->ucLength = 26;
- /* 3. Frame Formation - (14) HT capabilities element */
- if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N)) {
- /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */
- if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucBssIndex))
- fg40mAllowed = TRUE;
- else
- fg40mAllowed = FALSE;
- /* Add HT IE *//* try to reuse p2p path */
- u4IeLen = rlmFillHtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* 0320 !! check newest driver !!! */
- }
- /* check */
- /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
- TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
- TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
- TIMEOUT_INTERVAL_IE(pPkt)->ucType = 2; /* IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; */
- TIMEOUT_INTERVAL_IE(pPkt)->u4Value = TDLS_KEY_TIMEOUT_INTERVAL; /* htonl(prCmd->u4Timeout); */
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /*
- bit0 = 1: The Information Request field is used to indicate that a
- transmitting STA is requesting the recipient to transmit a 20/40 BSS
- Coexistence Management frame with the transmitting STA as the
- recipient.
- bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
- that receives this information or reports of this information from
- operating a 20/40 MHz BSS.
- bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
- a receiving AP from operating its BSS as a 20/40 MHz BSS.
- */
- BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
- BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
- BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
- LR_TDLS_FME_FIELD_FILL(3);
- }
- if (pAppendIe != NULL) {
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- LR_TDLS_FME_FIELD_FILL(AppendIeLen);
- }
- /* 7. Append Supported Operating Classes IE */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
- u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- /* 3. Frame Formation - (16) Link identifier element */
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pPeerMac, 6);
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* 3. Frame Formation - (17) WMM Information element */
- /* HT WMM IE append */
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- /* Add WMM IE *//* try to reuse p2p path */
- u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- #if CFG_SUPPORT_802_11AC
- if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AC) {
- /* Add VHT IE *//* try to reuse p2p path */
- u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- #endif
- /* 5. Update packet length */
- prMsduInfo->len = u4PktLen;
- DBGLOG(TDLS, INFO, "\n\n\n wlanHardStartXmit\n\n\n");
- /* 5. send the data frame */
- wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
- /* wlanTx ??? */
- return TDLS_STATUS_SUCCESS;
- }
- WLAN_STATUS
- TdlsDataFrameSend_SETUP_RSP(ADAPTER_T *prAdapter,
- STA_RECORD_T *prStaRec,
- UINT_8 *pPeerMac,
- UINT_8 ucActionCode,
- UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
- {
- GLUE_INFO_T *prGlueInfo;
- BSS_INFO_T *prBssInfo;
- PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
- struct sk_buff *prMsduInfo;
- UINT_8 *pPkt;
- UINT_32 u4PktLen, u4IeLen;
- UINT_16 u2CapInfo;
- UINT_16 StatusCode;
- BOOLEAN fg40mAllowed;
- /* allocate/init packet */
- prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
- prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
- prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
- u4PktLen = 0;
- prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
- if (prMsduInfo == NULL)
- return TDLS_STATUS_RESOURCES;
- prMsduInfo->dev = prGlueInfo->prDevHandler;
- if (prMsduInfo->dev == NULL) {
- kalPacketFree(prGlueInfo, prMsduInfo);
- return TDLS_STATUS_FAIL;
- }
- /* make up frame content */
- /* 1. 802.3 header */
- kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
- pPkt += TDLS_FME_MAC_ADDR_LEN;
- kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
- pPkt += TDLS_FME_MAC_ADDR_LEN;
- *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
- pPkt += 2;
- u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2;
- /* 2. payload type */
- *pPkt = TDLS_FRM_PAYLOAD_TYPE;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (1) Category */
- *pPkt = TDLS_FRM_CATEGORY;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (2) Action */
- *pPkt = ucActionCode;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - status code */
- StatusCode = u2StatusCode;
- kalMemCopy(pPkt, &StatusCode, 2);
- pPkt = pPkt + 2;
- u4PktLen = u4PktLen + 2;
- /* 3. Frame Formation - (3) Dialog token */
- *pPkt = ucDialogToken;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (4) Capability */
- u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
- WLAN_SET_FIELD_16(pPkt, u2CapInfo);
- pPkt = pPkt + 2;
- u4PktLen = u4PktLen + 2;
- /* 4. Append general IEs */
- u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* 4. Append extra IEs */
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- pPkt += AppendIeLen;
- u4PktLen += AppendIeLen;
- /* 3. Frame Formation - (10) Extended capabilities element */
- EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
- EXT_CAP_IE(pPkt)->ucLength = 5;
- EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
- EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
- EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
- EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0xFF; /* bit32 ~ bit39 */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
- EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
- EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
- /* EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; *//* bit24 ~ bit31 */
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* HT capability IE append */
- HT_CAP_IE(pPkt)->ucId = ELEM_ID_HT_CAP;
- HT_CAP_IE(pPkt)->ucLength = 26;
- /* 3. Frame Formation - (14) HT capabilities element */
- if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N)) {
- /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */
- if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucBssIndex))
- fg40mAllowed = TRUE;
- else
- fg40mAllowed = FALSE;
- /* Add HT IE *//* try to reuse p2p path */
- u4IeLen = rlmFillHtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
- TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
- TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
- TIMEOUT_INTERVAL_IE(pPkt)->ucType = 2; /* IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; */
- TIMEOUT_INTERVAL_IE(pPkt)->u4Value = TDLS_KEY_TIMEOUT_INTERVAL; /* htonl(prCmd->u4Timeout); */
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /*
- bit0 = 1: The Information Request field is used to indicate that a
- transmitting STA is requesting the recipient to transmit a 20/40 BSS
- Coexistence Management frame with the transmitting STA as the
- recipient.
- bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
- that receives this information or reports of this information from
- operating a 20/40 MHz BSS.
- bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
- a receiving AP from operating its BSS as a 20/40 MHz BSS.
- */
- BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
- BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
- BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
- LR_TDLS_FME_FIELD_FILL(3);
- }
- if (pAppendIe != NULL) {
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- LR_TDLS_FME_FIELD_FILL(AppendIeLen);
- }
- /* 7. Append Supported Operating Classes IE */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
- u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- /* 3. Frame Formation - (16) Link identifier element */
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pPeerMac, 6); /* prAdapter->rMyMacAddr */
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); /* pPeerMac */
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* HT WMM IE append */
- /* HT WMM IE append */
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- /* Add WMM IE *//* try to reuse p2p path */
- u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- #if CFG_SUPPORT_802_11AC
- if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AC) {
- /* Add VHT IE *//* try to reuse p2p path */
- u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- #endif
- /* 5. Update packet length */
- prMsduInfo->len = u4PktLen;
- /* 5. send the data frame */
- wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
- return TDLS_STATUS_SUCCESS;
- }
- WLAN_STATUS
- TdlsDataFrameSend_CONFIRM(ADAPTER_T *prAdapter,
- STA_RECORD_T *prStaRec,
- UINT_8 *pPeerMac,
- UINT_8 ucActionCode,
- UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
- {
- GLUE_INFO_T *prGlueInfo;
- BSS_INFO_T *prBssInfo;
- PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
- struct sk_buff *prMsduInfo;
- UINT_8 *pPkt;
- UINT_32 u4PktLen, u4IeLen;
- UINT_16 StatusCode;
- /* allocate/init packet */
- prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
- prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
- prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
- u4PktLen = 0;
- prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
- if (prMsduInfo == NULL)
- return TDLS_STATUS_RESOURCES;
- prMsduInfo->dev = prGlueInfo->prDevHandler;
- if (prMsduInfo->dev == NULL) {
- kalPacketFree(prGlueInfo, prMsduInfo);
- return TDLS_STATUS_FAIL;
- }
- /* make up frame content */
- /* 1. 802.3 header */
- kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
- pPkt += TDLS_FME_MAC_ADDR_LEN;
- kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
- pPkt += TDLS_FME_MAC_ADDR_LEN;
- *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
- pPkt += 2;
- u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2;
- /* 2. payload type */
- *pPkt = TDLS_FRM_PAYLOAD_TYPE;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (1) Category */
- *pPkt = TDLS_FRM_CATEGORY;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - (2) Action */
- *pPkt = ucActionCode;
- pPkt++;
- u4PktLen++;
- /* 3. Frame Formation - status code */
- StatusCode = u2StatusCode; /* 0; //u2StatusCode; //ahiu 0224 */
- kalMemCopy(pPkt, &StatusCode, 2);
- pPkt = pPkt + 2;
- u4PktLen = u4PktLen + 2;
- /* 3. Frame Formation - (3) Dialog token */
- *pPkt = ucDialogToken;
- pPkt++;
- u4PktLen++;
- /* 4. Append extra IEs */
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- pPkt += AppendIeLen;
- u4PktLen += AppendIeLen;
- /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
- TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
- TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
- TIMEOUT_INTERVAL_IE(pPkt)->ucType = 2;
- TIMEOUT_INTERVAL_IE(pPkt)->u4Value = TDLS_KEY_TIMEOUT_INTERVAL; /* htonl(prCmd->u4Timeout); */
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /*
- bit0 = 1: The Information Request field is used to indicate that a
- transmitting STA is requesting the recipient to transmit a 20/40 BSS
- Coexistence Management frame with the transmitting STA as the
- recipient.
- bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
- that receives this information or reports of this information from
- operating a 20/40 MHz BSS.
- bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
- a receiving AP from operating its BSS as a 20/40 MHz BSS.
- */
- BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
- BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
- BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
- LR_TDLS_FME_FIELD_FILL(3);
- }
- if (pAppendIe != NULL) {
- if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) ||
- ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && (prStaRec != NULL))) {
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- LR_TDLS_FME_FIELD_FILL(AppendIeLen);
- }
- }
- /* 7. Append Supported Operating Classes IE */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
- u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- /* 3. Frame Formation - (16) Link identifier element */
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pPeerMac, 6);
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* HT WMM IE append */
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- /* Add WMM IE *//* try to reuse p2p path */
- u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- /* 5. Update packet length */
- prMsduInfo->len = u4PktLen;
- /* 5. send the data frame */
- wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
- return TDLS_STATUS_SUCCESS;
- }
- /*
- * \brief This routine is called to transmit a TDLS data frame.
- *
- * \param[in] pvAdapter Pointer to the Adapter structure.
- * \param[in]
- * \param[in]
- * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
- *
- * \retval WLAN_STATUS_SUCCESS
- * \retval WLAN_STATUS_INVALID_LENGTH
- */
- /*----------------------------------------------------------------------------*/
- WLAN_STATUS /* TDLS_STATUS */
- TdlsDataFrameSend_DISCOVERY_REQ(ADAPTER_T *prAdapter,
- STA_RECORD_T *prStaRec,
- UINT_8 *pPeerMac,
- UINT_8 ucActionCode,
- UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
- {
- GLUE_INFO_T *prGlueInfo;
- BSS_INFO_T *prBssInfo;
- PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
- struct sk_buff *prMsduInfo;
- MSDU_INFO_T *prMsduInfoMgmt;
- UINT_8 *pPkt, *pucInitiator, *pucResponder;
- UINT_32 u4PktLen, u4IeLen;
- UINT_16 u2CapInfo;
- prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
- if (prStaRec != NULL)
- prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
- else
- return TDLS_STATUS_FAIL;
- /* allocate/init packet */
- prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
- u4PktLen = 0;
- prMsduInfo = NULL;
- prMsduInfoMgmt = NULL;
- /* make up frame content */
- if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RSP) {
- /* TODO: reduce 1600 to correct size */
- prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
- if (prMsduInfo == NULL)
- return TDLS_STATUS_RESOURCES;
- prMsduInfo->dev = prGlueInfo->prDevHandler;
- if (prMsduInfo->dev == NULL) {
- kalPacketFree(prGlueInfo, prMsduInfo);
- return TDLS_STATUS_FAIL;
- }
- /* 1. 802.3 header */
- kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
- LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
- kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
- LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
- *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
- LR_TDLS_FME_FIELD_FILL(2);
- /* 2. payload type */
- *pPkt = TDLS_FRM_PAYLOAD_TYPE;
- LR_TDLS_FME_FIELD_FILL(1);
- /* 3. Frame Formation - (1) Category */
- *pPkt = TDLS_FRM_CATEGORY;
- LR_TDLS_FME_FIELD_FILL(1);
- } else {
- WLAN_MAC_HEADER_T *prHdr;
- prMsduInfoMgmt = (MSDU_INFO_T *)
- cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
- if (prMsduInfoMgmt == NULL)
- return TDLS_STATUS_RESOURCES;
- pPkt = (UINT_8 *) prMsduInfoMgmt->prPacket;
- prHdr = (WLAN_MAC_HEADER_T *) pPkt;
- /* 1. 802.11 header */
- prHdr->u2FrameCtrl = MAC_FRAME_ACTION;
- prHdr->u2DurationID = 0;
- kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
- kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
- kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN);
- prHdr->u2SeqCtrl = 0;
- LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T));
- /* Frame Formation - (1) Category */
- *pPkt = CATEGORY_PUBLIC_ACTION;
- LR_TDLS_FME_FIELD_FILL(1);
- }
- /* 3. Frame Formation - (2) Action */
- *pPkt = ucActionCode;
- LR_TDLS_FME_FIELD_FILL(1);
- /* 3. Frame Formation - Status Code */
- switch (ucActionCode) {
- case TDLS_FRM_ACTION_SETUP_RSP:
- case TDLS_FRM_ACTION_CONFIRM:
- case TDLS_FRM_ACTION_TEARDOWN:
- WLAN_SET_FIELD_16(pPkt, u2StatusCode);
- LR_TDLS_FME_FIELD_FILL(2);
- break;
- }
- /* 3. Frame Formation - (3) Dialog token */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- *pPkt = ucDialogToken;
- LR_TDLS_FME_FIELD_FILL(1);
- }
- /* Fill elements */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /*
- Capability
- Support Rates
- Extended Support Rates
- Supported Channels
- HT Capabilities
- WMM Information Element
- Extended Capabilities
- Link Identifier
- RSNIE
- FTIE
- Timeout Interval
- */
- if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) {
- /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */
- u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
- WLAN_SET_FIELD_16(pPkt, u2CapInfo);
- LR_TDLS_FME_FIELD_FILL(2);
- /* 4. Append general IEs */
- /*
- TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode
- must be CONFIG_BW_20_40M.
- TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if
- Tdls 20/40 is enabled.
- */
- u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- /* 5. Frame Formation - Extended capabilities element */
- EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
- EXT_CAP_IE(pPkt)->ucLength = 5;
- EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
- EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
- EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
- EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */
- /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
- /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
- /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */
- EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
- u4IeLen = IE_SIZE(pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- } else {
- /* 5. Frame Formation - WMM Information element */
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- /* Add WMM IE *//* try to reuse p2p path */
- u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- }
- }
- /* 6. Frame Formation - 20/40 BSS Coexistence */
- /*
- Follow WiFi test plan, add 20/40 element to request/response/confirm.
- */
- #if 0
- if (prGlueInfo->fgTdlsIs2040Supported == TRUE) {
- /*
- bit0 = 1: The Information Request field is used to indicate that a
- transmitting STA is requesting the recipient to transmit a 20/40 BSS
- Coexistence Management frame with the transmitting STA as the
- recipient.
- bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
- that receives this information or reports of this information from
- operating a 20/40 MHz BSS.
- bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
- a receiving AP from operating its BSS as a 20/40 MHz BSS.
- */
- BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
- BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
- BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
- LR_TDLS_FME_FIELD_FILL(3);
- }
- #endif
- /* 6. Frame Formation - HT Operation element */
- /* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */
- /* LR_TDLS_FME_FIELD_FILL(u4IeLen); */
- /* 7. Frame Formation - Link identifier element */
- /* Note: Link ID sequence must be correct; Or the calculated MIC will be error */
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
- switch (ucActionCode) {
- case TDLS_FRM_ACTION_SETUP_REQ:
- case TDLS_FRM_ACTION_CONFIRM:
- case TDLS_FRM_ACTION_DISCOVERY_RSP:
- default:
- /* we are initiator */
- pucInitiator = prBssInfo->aucOwnMacAddr;
- pucResponder = pPeerMac;
- if (prStaRec != NULL)
- prStaRec->flgTdlsIsInitiator = TRUE;
- break;
- case TDLS_FRM_ACTION_SETUP_RSP:
- /* peer is initiator */
- pucInitiator = pPeerMac;
- pucResponder = prBssInfo->aucOwnMacAddr;
- if (prStaRec != NULL)
- prStaRec->flgTdlsIsInitiator = FALSE;
- break;
- case TDLS_FRM_ACTION_TEARDOWN:
- if (prStaRec != NULL) {
- if (prStaRec->flgTdlsIsInitiator == TRUE) {
- /* we are initiator */
- pucInitiator = prBssInfo->aucOwnMacAddr;
- pucResponder = pPeerMac;
- } else {
- /* peer is initiator */
- pucInitiator = pPeerMac;
- pucResponder = prBssInfo->aucOwnMacAddr;
- }
- } else {
- /* peer is initiator */
- pucInitiator = pPeerMac;
- pucResponder = prBssInfo->aucOwnMacAddr;
- }
- break;
- }
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6);
- u4IeLen = IE_SIZE(pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- /* 8. Append security IEs */
- if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) {
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- LR_TDLS_FME_FIELD_FILL(AppendIeLen);
- }
- /* 10. send the data or management frame */
- if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RSP) {
- /* 9. Update packet length */
- prMsduInfo->len = u4PktLen;
- wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
- } else {
- prMsduInfoMgmt->ucPacketType = TX_PACKET_TYPE_MGMT;
- prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
- prMsduInfoMgmt->ucBssIndex = prBssInfo->ucBssIndex;
- prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
- prMsduInfoMgmt->fgIs802_1x = FALSE;
- prMsduInfoMgmt->fgIs802_11 = TRUE;
- prMsduInfoMgmt->u2FrameLength = u4PktLen;
- prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
- prMsduInfoMgmt->pfTxDoneHandler = NULL;
- /* Send them to HW queue */
- nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt);
- }
- return TDLS_STATUS_SUCCESS;
- }
- WLAN_STATUS
- TdlsDataFrameSend_DISCOVERY_RSP(ADAPTER_T *prAdapter,
- STA_RECORD_T *prStaRec,
- UINT_8 *pPeerMac,
- UINT_8 ucActionCode,
- UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
- {
- GLUE_INFO_T *prGlueInfo;
- BSS_INFO_T *prBssInfo;
- PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
- struct sk_buff *prMsduInfo;
- MSDU_INFO_T *prMsduInfoMgmt;
- UINT_8 *pPkt, *pucInitiator, *pucResponder;
- UINT_32 u4PktLen, u4IeLen;
- UINT_16 u2CapInfo;
- prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
- /* sanity check */
- if (prStaRec != NULL)
- prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
- else
- return TDLS_STATUS_FAIL;
- /* allocate/init packet */
- prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
- u4PktLen = 0;
- prMsduInfo = NULL;
- prMsduInfoMgmt = NULL;
- /* make up frame content */
- if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RSP) {
- /* TODO: reduce 1600 to correct size */
- prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
- if (prMsduInfo == NULL)
- return TDLS_STATUS_RESOURCES;
- prMsduInfo->dev = prGlueInfo->prDevHandler;
- if (prMsduInfo->dev == NULL) {
- kalPacketFree(prGlueInfo, prMsduInfo);
- return TDLS_STATUS_FAIL;
- }
- /* 1. 802.3 header */
- kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
- LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
- kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
- LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
- *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
- LR_TDLS_FME_FIELD_FILL(2);
- /* 2. payload type */
- *pPkt = TDLS_FRM_PAYLOAD_TYPE;
- LR_TDLS_FME_FIELD_FILL(1);
- /* 3. Frame Formation - (1) Category */
- *pPkt = TDLS_FRM_CATEGORY;
- LR_TDLS_FME_FIELD_FILL(1);
- } else {
- WLAN_MAC_HEADER_T *prHdr;
- prMsduInfoMgmt = (MSDU_INFO_T *)
- cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
- if (prMsduInfoMgmt == NULL)
- return TDLS_STATUS_RESOURCES;
- pPkt = (UINT_8 *) prMsduInfoMgmt->prPacket;
- prHdr = (WLAN_MAC_HEADER_T *) pPkt;
- /* 1. 802.11 header */
- prHdr->u2FrameCtrl = MAC_FRAME_ACTION;
- prHdr->u2DurationID = 0;
- kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
- kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
- kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN);
- prHdr->u2SeqCtrl = 0;
- LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T));
- /* Frame Formation - (1) Category */
- *pPkt = CATEGORY_PUBLIC_ACTION;
- LR_TDLS_FME_FIELD_FILL(1);
- }
- /* 3. Frame Formation - (2) Action */
- *pPkt = ucActionCode;
- LR_TDLS_FME_FIELD_FILL(1);
- /* 3. Frame Formation - Status Code */
- switch (ucActionCode) {
- case TDLS_FRM_ACTION_SETUP_RSP:
- case TDLS_FRM_ACTION_CONFIRM:
- case TDLS_FRM_ACTION_TEARDOWN:
- WLAN_SET_FIELD_16(pPkt, u2StatusCode);
- LR_TDLS_FME_FIELD_FILL(2);
- break;
- }
- /* 3. Frame Formation - (3) Dialog token */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- *pPkt = ucDialogToken;
- LR_TDLS_FME_FIELD_FILL(1);
- }
- /* Fill elements */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /*
- Capability
- Support Rates
- Extended Support Rates
- Supported Channels
- HT Capabilities
- WMM Information Element
- Extended Capabilities
- Link Identifier
- RSNIE
- FTIE
- Timeout Interval
- */
- if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) {
- /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */
- u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
- WLAN_SET_FIELD_16(pPkt, u2CapInfo);
- LR_TDLS_FME_FIELD_FILL(2);
- /* 4. Append general IEs */
- /*
- TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode
- must be CONFIG_BW_20_40M.
- TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if
- Tdls 20/40 is enabled.
- */
- u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- /* 5. Frame Formation - Extended capabilities element */
- EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
- EXT_CAP_IE(pPkt)->ucLength = 5;
- EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
- EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
- EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
- EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */
- /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
- /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */
- EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
- /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */
- EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
- u4IeLen = IE_SIZE(pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- } else {
- /* 5. Frame Formation - WMM Information element */
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- /* Add WMM IE *//* try to reuse p2p path */
- u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- }
- }
- /* 6. Frame Formation - 20/40 BSS Coexistence */
- /*
- Follow WiFi test plan, add 20/40 element to request/response/confirm.
- */
- #if 0
- if (prGlueInfo->fgTdlsIs2040Supported == TRUE) {
- /*
- bit0 = 1: The Information Request field is used to indicate that a
- transmitting STA is requesting the recipient to transmit a 20/40 BSS
- Coexistence Management frame with the transmitting STA as the
- recipient.
- bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
- that receives this information or reports of this information from
- operating a 20/40 MHz BSS.
- bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
- a receiving AP from operating its BSS as a 20/40 MHz BSS.
- */
- BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
- BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
- BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
- LR_TDLS_FME_FIELD_FILL(3);
- }
- #endif
- /* 6. Frame Formation - HT Operation element */
- /* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */
- /* LR_TDLS_FME_FIELD_FILL(u4IeLen); */
- /* 7. Frame Formation - Link identifier element */
- /* Note: Link ID sequence must be correct; Or the calculated MIC will be error */
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
- switch (ucActionCode) {
- case TDLS_FRM_ACTION_SETUP_REQ:
- case TDLS_FRM_ACTION_CONFIRM:
- default:
- /* we are initiator */
- pucInitiator = prBssInfo->aucOwnMacAddr;
- pucResponder = pPeerMac;
- if (prStaRec != NULL)
- prStaRec->flgTdlsIsInitiator = TRUE;
- break;
- case TDLS_FRM_ACTION_DISCOVERY_RSP:
- case TDLS_FRM_ACTION_SETUP_RSP:
- /* peer is initiator */
- pucInitiator = pPeerMac;
- pucResponder = prBssInfo->aucOwnMacAddr;
- if (prStaRec != NULL)
- prStaRec->flgTdlsIsInitiator = FALSE;
- break;
- case TDLS_FRM_ACTION_TEARDOWN:
- if (prStaRec != NULL) {
- if (prStaRec->flgTdlsIsInitiator == TRUE) {
- /* we are initiator */
- pucInitiator = prBssInfo->aucOwnMacAddr;
- pucResponder = pPeerMac;
- } else {
- /* peer is initiator */
- pucInitiator = pPeerMac;
- pucResponder = prBssInfo->aucOwnMacAddr;
- }
- } else {
- /* peer is initiator */
- pucInitiator = pPeerMac;
- pucResponder = prBssInfo->aucOwnMacAddr;
- }
- break;
- }
- /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
- TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
- TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
- TIMEOUT_INTERVAL_IE(pPkt)->ucType = 2; /* IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; */
- TIMEOUT_INTERVAL_IE(pPkt)->u4Value = TDLS_KEY_TIMEOUT_INTERVAL; /* htonl(prCmd->u4Timeout); */
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /*
- bit0 = 1: The Information Request field is used to indicate that a
- transmitting STA is requesting the recipient to transmit a 20/40 BSS
- Coexistence Management frame with the transmitting STA as the
- recipient.
- bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
- that receives this information or reports of this information from
- operating a 20/40 MHz BSS.
- bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
- a receiving AP from operating its BSS as a 20/40 MHz BSS.
- */
- BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
- BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
- BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
- LR_TDLS_FME_FIELD_FILL(3);
- }
- if (pAppendIe != NULL) {
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- LR_TDLS_FME_FIELD_FILL(AppendIeLen);
- }
- /* 7. Append Supported Operating Classes IE */
- if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
- /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
- u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- /* 3. Frame Formation - (16) Link identifier element */
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
- TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pPeerMac, 6); /* prAdapter->rMyMacAddr */
- kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); /* pPeerMac */
- u4IeLen = IE_SIZE(pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- /* HT WMM IE append */
- /* HT WMM IE append */
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- /* Add WMM IE *//* try to reuse p2p path */
- u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
- u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt);
- LR_TDLS_FME_FIELD_FILL(u4IeLen);
- }
- #if CFG_SUPPORT_802_11AC
- if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AC) {
- /* Add VHT IE *//* try to reuse p2p path */
- u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
- pPkt += u4IeLen;
- u4PktLen += u4IeLen;
- }
- #endif
- /* 8. Append security IEs */
- if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) {
- kalMemCopy(pPkt, pAppendIe, AppendIeLen);
- LR_TDLS_FME_FIELD_FILL(AppendIeLen);
- }
- prMsduInfoMgmt->ucPacketType = TX_PACKET_TYPE_MGMT;
- prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
- prMsduInfoMgmt->ucBssIndex = prBssInfo->ucBssIndex;
- prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
- prMsduInfoMgmt->fgIs802_1x = FALSE;
- prMsduInfoMgmt->fgIs802_11 = TRUE;
- prMsduInfoMgmt->u2FrameLength = u4PktLen;
- prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
- prMsduInfoMgmt->pfTxDoneHandler = NULL;
- /* Send them to HW queue */
- nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt);
- return TDLS_STATUS_SUCCESS;
- }
- /*----------------------------------------------------------------------------*/
- /*! \brief This routine is called to send a command to TDLS module.
- *
- * \param[in] prGlueInfo Pointer to the Adapter structure
- * \param[in] prInBuf A pointer to the command string buffer
- * \param[in] u4InBufLen The length of the buffer
- * \param[out] None
- *
- * \retval None
- */
- /*----------------------------------------------------------------------------*/
- VOID TdlsexEventHandle(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
- {
- UINT_32 u4EventId;
- DBGLOG(TDLS, INFO, "TdlsexEventHandle\n");
- /* sanity check */
- if ((prGlueInfo == NULL) || (prInBuf == NULL))
- return; /* shall not be here */
- /* handle */
- u4EventId = *(UINT_32 *) prInBuf;
- u4InBufLen -= 4;
- switch (u4EventId) {
- case TDLS_HOST_EVENT_TEAR_DOWN:
- DBGLOG(TDLS, INFO, "TDLS_HOST_EVENT_TEAR_DOWN\n");
- TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen);
- break;
- case TDLS_HOST_EVENT_TX_DONE:
- break;
- }
- }
- /*----------------------------------------------------------------------------*/
- /*! \brief This routine is called to do tear down.
- *
- * \param[in] prGlueInfo Pointer to the Adapter structure
- * \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId
- * \param[in] u4InBufLen The length of the buffer
- * \param[out] None
- *
- * \retval None
- *
- */
- /*----------------------------------------------------------------------------*/
- VOID TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
- {
- STA_RECORD_T *prStaRec;
- UINT_16 u2ReasonCode = 0;
- UINT_32 u4TearDownSubId;
- UINT_8 *pMac, aucZeroMac[6];
- /* init */
- u4TearDownSubId = *(UINT_32 *) prInBuf;
- kalMemZero(aucZeroMac, sizeof(aucZeroMac));
- pMac = aucZeroMac;
- prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *(prInBuf + 4));
- if (prStaRec != NULL)
- pMac = prStaRec->aucMacAddr;
- /* handle */
- /* sanity check */
- if (prStaRec == NULL)
- return;
- if (fgIsPtiTimeoutSkip == TRUE) {
- /* skip PTI timeout event */
- if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT)
- return;
- }
- if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) {
- DBGLOG(TDLS, INFO, "TDLS_HOST_EVENT_TD_PTI_TIMEOUT TDLS_REASON_CODE_UNSPECIFIED\n");
- u2ReasonCode = TDLS_REASON_CODE_UNSPECIFIED;
- cfg80211_tdls_oper_request(prGlueInfo->prDevHandler,
- prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN,
- WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, GFP_ATOMIC);
- }
- if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) {
- DBGLOG(TDLS, INFO, "TDLS_HOST_EVENT_TD_AGE_TIMEOUT TDLS_REASON_CODE_UNREACHABLE\n");
- u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE;
- cfg80211_tdls_oper_request(prGlueInfo->prDevHandler,
- prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN,
- WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, GFP_ATOMIC);
- }
- DBGLOG(TDLS, INFO, "\n\n u2ReasonCode = %u\n\n", u2ReasonCode);
- /*
- modify the value when supplicant sends tear down to us in TdlsexMgmtCtrl(), not here
- we want to send tear down to AP (not peer) if PTI timeout or AGE timeout.
- */
- /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */
- }
- #if 0
- /*----------------------------------------------------------------------------*/
- /*! \brief This routine is called to send a TDLS event to supplicant.
- *
- * \param[in] prGlueInfo Pointer to the Adapter structure
- * \param[in] prInBuf A pointer to the command string buffer
- * \param[in] u4InBufLen The length of the buffer
- * \param[out] None
- *
- * \retval None
- *
- */
- /*----------------------------------------------------------------------------*/
- VOID tdls_oper_request(struct net_device *dev, const u8 *peer, u16 oper, u16 reason_code, gfp_t gfp)
- {
- GLUE_INFO_T *prGlueInfo;
- ADAPTER_T *prAdapter;
- struct sk_buff *prMsduInfo;
- UINT_8 *pPkt;
- UINT_32 u4PktLen;
- /* sanity check */
- if ((dev == NULL) || (peer == NULL))
- return; /* shall not be here */
- /* init */
- prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
- prAdapter = prGlueInfo->prAdapter;
- u4PktLen = 0;
- /* allocate/init packet */
- prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
- if (prMsduInfo == NULL)
- return;
- prMsduInfo->dev = dev;
- /* make up frame content */
- /* 1. 802.3 header */
- kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
- LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
- kalMemCopy(pPkt, peer, TDLS_FME_MAC_ADDR_LEN);
- LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
- *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
- LR_TDLS_FME_FIELD_FILL(2);
- /* 2. payload type */
- *pPkt = TDLS_FRM_PAYLOAD_TYPE;
- LR_TDLS_FME_FIELD_FILL(1);
- /* 3. Frame Formation - (1) Category */
- *pPkt = TDLS_FRM_CATEGORY;
- LR_TDLS_FME_FIELD_FILL(1);
- /* 3. Frame Formation - (2) Action */
- *pPkt = TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT;
- LR_TDLS_FME_FIELD_FILL(1);
- /* 3. Frame Formation - (3) Operation */
- *pPkt = oper;
- LR_TDLS_FME_FIELD_FILL(1);
- /* 3. Frame Formation - (4) Reason Code */
- *pPkt = reason_code;
- *(pPkt + 1) = 0x00;
- LR_TDLS_FME_FIELD_FILL(2);
- /* 3. Frame Formation - (5) Peer MAC */
- kalMemCopy(pPkt, peer, 6);
- LR_TDLS_FME_FIELD_FILL(6);
- /* 4. Update packet length */
- prMsduInfo->len = u4PktLen;
- /* pass to OS */
- TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo);
- }
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief This routine is called to indicate packets to upper layer.
- *
- * \param[in] prGlueInfo Pointer to the Adapter structure
- * \param[in] prSkb A pointer to the received packet
- *
- * \retval None
- *
- */
- /*----------------------------------------------------------------------------*/
- VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb)
- {
- struct net_device *prNetDev;
- /* init */
- prNetDev = prGlueInfo->prDevHandler;
- prGlueInfo->rNetDevStats.rx_bytes += prSkb->len;
- prGlueInfo->rNetDevStats.rx_packets++;
- /* pass to upper layer */
- prNetDev->last_rx = jiffies;
- prSkb->protocol = eth_type_trans(prSkb, prNetDev);
- prSkb->dev = prNetDev;
- if (!in_interrupt())
- netif_rx_ni(prSkb); /* only in non-interrupt context */
- else
- netif_rx(prSkb);
- }
- #endif
- VOID TdlsBssExtCapParse(P_STA_RECORD_T prStaRec, P_UINT_8 pucIE)
- {
- UINT_8 *pucIeExtCap;
- /* sanity check */
- if ((prStaRec == NULL) || (pucIE == NULL))
- return;
- if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP)
- return;
- /*
- from bit0 ~
- bit 38: TDLS Prohibited
- The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The
- field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is
- allowed.
- */
- if (IE_LEN(pucIE) < 5)
- return; /* we need 39/8 = 5 bytes */
- /* init */
- prStaRec->fgTdlsIsProhibited = FALSE;
- prStaRec->fgTdlsIsChSwProhibited = FALSE;
- /* parse */
- pucIeExtCap = pucIE + 2;
- pucIeExtCap += 4; /* shift to the byte we care about */
- if ((*pucIeExtCap) && BIT(38 - 32))
- prStaRec->fgTdlsIsProhibited = TRUE;
- if ((*pucIeExtCap) && BIT(39 - 32))
- prStaRec->fgTdlsIsChSwProhibited = TRUE;
- }
- /*----------------------------------------------------------------------------*/
- /*!
- * \brief Generate CMD_ID_SET_TDLS_CH_SW command
- *
- * \param[in]
- *
- * \return none
- */
- /*----------------------------------------------------------------------------*/
- WLAN_STATUS
- TdlsSendChSwControlCmd(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen)
- {
- CMD_TDLS_CH_SW_T rCmdTdlsChSwCtrl;
- ASSERT(prAdapter);
- /* send command packet for scan */
- kalMemZero(&rCmdTdlsChSwCtrl, sizeof(CMD_TDLS_CH_SW_T));
- rCmdTdlsChSwCtrl.fgIsTDLSChSwProhibit = prAdapter->prAisBssInfo->fgTdlsIsChSwProhibited;
- wlanSendSetQueryCmd(prAdapter,
- CMD_ID_SET_TDLS_CH_SW,
- TRUE,
- FALSE, FALSE, NULL, NULL, sizeof(CMD_TDLS_CH_SW_T), (PUINT_8)&rCmdTdlsChSwCtrl, NULL, 0);
- return TDLS_STATUS_SUCCESS;
- }
- #endif /* CFG_SUPPORT_TDLS */
- /* End of tdls.c */
|