tdls_com.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. /*
  2. ** Id: tdls_com.c#1
  3. */
  4. /*! \file tdls_com.c
  5. \brief This file includes IEEE802.11z TDLS main support.
  6. */
  7. /*
  8. ** Log: tdls_com.c
  9. *
  10. * 11 13 2013 vend_samp.lin
  11. * NULL
  12. * Initial version.
  13. */
  14. /*******************************************************************************
  15. * C O M P I L E R F L A G S
  16. ********************************************************************************
  17. */
  18. /*******************************************************************************
  19. * E X T E R N A L R E F E R E N C E S
  20. ********************************************************************************
  21. */
  22. #include "precomp.h"
  23. #if (CFG_SUPPORT_TDLS == 1)
  24. #include "tdls.h"
  25. /*******************************************************************************
  26. * C O N S T A N T S
  27. ********************************************************************************
  28. */
  29. /*******************************************************************************
  30. * F U N C T I O N D E C L A R A T I O N S
  31. ********************************************************************************
  32. */
  33. /*******************************************************************************
  34. * P R I V A T E D A T A
  35. ********************************************************************************
  36. */
  37. /*******************************************************************************
  38. * P R I V A T E F U N C T I O N S
  39. ********************************************************************************
  40. */
  41. /*----------------------------------------------------------------------------*/
  42. /*!
  43. * \brief This routine is called to append general IEs.
  44. *
  45. * \param[in] pvAdapter Pointer to the Adapter structure.
  46. * \param[in] prStaRec Pointer to the STA_RECORD_T structure.
  47. * \param[in] u2StatusCode Status code.
  48. * \param[in] pPkt Pointer to the frame body
  49. *
  50. * \retval append length
  51. */
  52. /*----------------------------------------------------------------------------*/
  53. UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_16 u2StatusCode, UINT_8 *pPkt)
  54. {
  55. GLUE_INFO_T *prGlueInfo;
  56. BSS_INFO_T *prBssInfo;
  57. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  58. UINT_32 u4NonHTPhyType;
  59. UINT_16 u2SupportedRateSet;
  60. UINT_8 aucAllSupportedRates[RATE_NUM] = { 0 };
  61. UINT_8 ucAllSupportedRatesLen;
  62. UINT_8 ucSupRatesLen;
  63. UINT_8 ucExtSupRatesLen;
  64. UINT_32 u4PktLen, u4IeLen;
  65. BOOLEAN fg40mAllowed;
  66. /* reference to assocBuildReAssocReqFrameCommonIEs() */
  67. /* init */
  68. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  69. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
  70. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  71. u4PktLen = 0;
  72. /* 3. Frame Formation - (5) Supported Rates element */
  73. /* use all sup rate we can support */
  74. if (prStaRec != NULL)
  75. u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType;
  76. else
  77. u4NonHTPhyType = PHY_TYPE_ERP_INDEX; /* default */
  78. u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet;
  79. if (prStaRec != NULL) {
  80. u2SupportedRateSet &= prStaRec->u2OperationalRateSet;
  81. if (u2SupportedRateSet == 0)
  82. u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet;
  83. }
  84. rateGetDataRatesFromRateSet(u2SupportedRateSet,
  85. prBssInfo->u2BSSBasicRateSet, aucAllSupportedRates, &ucAllSupportedRatesLen);
  86. ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ?
  87. ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen);
  88. ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen;
  89. if (ucSupRatesLen) {
  90. SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES;
  91. SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen;
  92. kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen);
  93. u4IeLen = IE_SIZE(pPkt);
  94. pPkt += u4IeLen;
  95. u4PktLen += u4IeLen;
  96. }
  97. /* 3. Frame Formation - (7) Extended sup rates element */
  98. if (ucExtSupRatesLen) {
  99. EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
  100. EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen;
  101. kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates,
  102. &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen);
  103. u4IeLen = IE_SIZE(pPkt);
  104. pPkt += u4IeLen;
  105. u4PktLen += u4IeLen;
  106. }
  107. /* 3. Frame Formation - (8) Supported channels element */
  108. /*
  109. The Supported channels element is included in Request frame and also in Response
  110. frame if Status Code 0 (successful).
  111. */
  112. if (u2StatusCode == 0) {
  113. SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS;
  114. SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2;
  115. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1;
  116. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 11;
  117. #if CFG_SUPPORT_DFS
  118. if (prAdapter->fgEnable5GBand == TRUE) {
  119. /* 5G support */
  120. SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10;
  121. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36;
  122. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4;
  123. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52;
  124. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4;
  125. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149;
  126. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4;
  127. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165;
  128. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 4;
  129. }
  130. #endif /* CFG_SUPPORT_DFS */
  131. u4IeLen = IE_SIZE(pPkt);
  132. pPkt += u4IeLen;
  133. u4PktLen += u4IeLen;
  134. }
  135. /* 3. Frame Formation - (14) HT capabilities element */
  136. /* no need to check AP capability */
  137. /* if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N) && */
  138. /*
  139. after we set ucPhyTypeSet to PHY_TYPE_SET_802_11N in TdlsexRxFrameHandle(),
  140. supplicant will disable link if exists and we will clear prStaRec.
  141. finally, prStaRec->ucPhyTypeSet will also be 0
  142. so we have a fix in TdlsexPeerAdd().
  143. */
  144. if (!prStaRec || (prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N)) {
  145. /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */
  146. #if 0 /* always support */
  147. if (prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode == CONFIG_BW_20M)
  148. fg40mAllowed = FALSE;
  149. else
  150. #endif
  151. fg40mAllowed = TRUE;
  152. u4IeLen = rlmFillHtCapIEByParams(fg40mAllowed,
  153. prAdapter->rWifiVar.rConnSettings.fgRxShortGIDisabled,
  154. prAdapter->rWifiVar.u8SupportRxSgi20,
  155. prAdapter->rWifiVar.u8SupportRxSgi40,
  156. prAdapter->rWifiVar.u8SupportRxGf,
  157. prAdapter->rWifiVar.u8SupportRxSTBC, prBssInfo->eCurrentOPMode, pPkt);
  158. pPkt += u4IeLen;
  159. u4PktLen += u4IeLen;
  160. }
  161. /* 3. Frame Formation - (17) WMM Information element */
  162. /* always support */
  163. /* if (prAdapter->rWifiVar.fgSupportQoS) */
  164. {
  165. /* force to support all UAPSD in TDLS link */
  166. u4IeLen = mqmGenerateWmmInfoIEByParam(TRUE /*prAdapter->rWifiVar.fgSupportUAPSD */ ,
  167. 0xf /*prPmProfSetupInfo->ucBmpDeliveryAC */ ,
  168. 0xf /*prPmProfSetupInfo->ucBmpTriggerAC */ ,
  169. WMM_MAX_SP_LENGTH_ALL /*prPmProfSetupInfo->ucUapsdSp */ ,
  170. pPkt);
  171. pPkt += u4IeLen;
  172. u4PktLen += u4IeLen;
  173. }
  174. return u4PktLen;
  175. }
  176. /*----------------------------------------------------------------------------*/
  177. /*!
  178. * \brief This routine is called to transmit a TDLS data frame (setup req/rsp/confirm and tear down).
  179. *
  180. * \param[in] pvAdapter Pointer to the Adapter structure.
  181. * \param[in] prStaRec Pointer to the STA_RECORD_T structure.
  182. * \param[in] pPeerMac Pointer to the MAC of the TDLS peer
  183. * \param[in] ucActionCode TDLS Action
  184. * \param[in] ucDialogToken Dialog token
  185. * \param[in] u2StatusCode Status code
  186. * \param[in] pAppendIe Others IEs (here are security IEs from supplicant)
  187. * \param[in] AppendIeLen IE length of others IEs
  188. *
  189. * \retval TDLS_STATUS_xx
  190. */
  191. /*----------------------------------------------------------------------------*/
  192. TDLS_STATUS
  193. TdlsDataFrameSend(ADAPTER_T *prAdapter,
  194. STA_RECORD_T *prStaRec,
  195. UINT_8 *pPeerMac,
  196. UINT_8 ucActionCode,
  197. UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
  198. {
  199. #define LR_TDLS_FME_FIELD_FILL(__Len) \
  200. do { \
  201. pPkt += __Len; \
  202. u4PktLen += __Len; \
  203. } while (0)
  204. GLUE_INFO_T *prGlueInfo;
  205. BSS_INFO_T *prBssInfo;
  206. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  207. struct sk_buff *prMsduInfo;
  208. MSDU_INFO_T *prMsduInfoMgmt;
  209. UINT8 *pPkt, *pucInitiator, *pucResponder;
  210. UINT32 u4PktLen, u4IeLen;
  211. UINT16 u2CapInfo;
  212. /* UINT8 *pPktTemp; */
  213. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  214. DBGLOG(TDLS, INFO, "<tdls_fme> %s: 2040=%d\n", __func__, prGlueInfo->rTdlsLink.fgIs2040Sup);
  215. /* sanity check */
  216. if (prStaRec != NULL) {
  217. if (prStaRec->ucNetTypeIndex >= NETWORK_TYPE_INDEX_NUM) {
  218. DBGLOG(TDLS, ERROR,
  219. "<tdls_cmd> %s: net index %d fail\n", __func__, prStaRec->ucNetTypeIndex);
  220. return TDLS_STATUS_FAILURE;
  221. }
  222. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[prStaRec->ucNetTypeIndex]);
  223. } else {
  224. /* prStaRec maybe NULL in setup request */
  225. prBssInfo = &(prAdapter->rWifiVar.arBssInfo[NETWORK_TYPE_AIS_INDEX]);
  226. }
  227. /* allocate/init packet */
  228. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  229. u4PktLen = 0;
  230. prMsduInfo = NULL;
  231. prMsduInfoMgmt = NULL;
  232. /* make up frame content */
  233. if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) {
  234. /*
  235. The STAUT will not respond to a TDLS Discovery Request Frame with different BSSID.
  236. Supplicant will check this in wpa_tdls_process_discovery_request().
  237. */
  238. /* TODO: reduce 1600 to correct size */
  239. prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
  240. if (prMsduInfo == NULL) {
  241. DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate pkt fail\n", __func__);
  242. return TDLS_STATUS_RESOURCES;
  243. }
  244. prMsduInfo->dev = prGlueInfo->prDevHandler;
  245. if (prMsduInfo->dev == NULL) {
  246. DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: MsduInfo->dev == NULL\n", __func__);
  247. kalPacketFree(prGlueInfo, prMsduInfo);
  248. return TDLS_STATUS_FAILURE;
  249. }
  250. /* 1. 802.3 header */
  251. /* pPktTemp = pPkt; */
  252. kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  253. LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
  254. kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
  255. LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
  256. *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
  257. LR_TDLS_FME_FIELD_FILL(2);
  258. /* 2. payload type */
  259. *pPkt = TDLS_FRM_PAYLOAD_TYPE;
  260. LR_TDLS_FME_FIELD_FILL(1);
  261. /* 3. Frame Formation - (1) Category */
  262. *pPkt = TDLS_FRM_CATEGORY;
  263. LR_TDLS_FME_FIELD_FILL(1);
  264. } else {
  265. /* discovery response */
  266. WLAN_MAC_HEADER_T *prHdr;
  267. prMsduInfoMgmt = (MSDU_INFO_T *)
  268. cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
  269. if (prMsduInfoMgmt == NULL) {
  270. DBGLOG(TDLS, ERROR, "<tdls_cmd> %s: allocate mgmt pkt fail\n", __func__);
  271. return TDLS_STATUS_RESOURCES;
  272. }
  273. pPkt = (UINT8 *) prMsduInfoMgmt->prPacket;
  274. prHdr = (WLAN_MAC_HEADER_T *) pPkt;
  275. /* 1. 802.11 header */
  276. prHdr->u2FrameCtrl = MAC_FRAME_ACTION;
  277. prHdr->u2DurationID = 0;
  278. kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  279. kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
  280. kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN);
  281. prHdr->u2SeqCtrl = 0;
  282. LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T));
  283. /* Frame Formation - (1) Category */
  284. *pPkt = CATEGORY_PUBLIC_ACTION;
  285. LR_TDLS_FME_FIELD_FILL(1);
  286. }
  287. /* 3. Frame Formation - (2) Action */
  288. *pPkt = ucActionCode;
  289. LR_TDLS_FME_FIELD_FILL(1);
  290. /* 3. Frame Formation - Status Code */
  291. switch (ucActionCode) {
  292. case TDLS_FRM_ACTION_SETUP_RSP:
  293. case TDLS_FRM_ACTION_CONFIRM:
  294. case TDLS_FRM_ACTION_TEARDOWN:
  295. WLAN_SET_FIELD_16(pPkt, u2StatusCode);
  296. LR_TDLS_FME_FIELD_FILL(2);
  297. break;
  298. }
  299. /* 3. Frame Formation - (3) Dialog token */
  300. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  301. *pPkt = ucDialogToken;
  302. LR_TDLS_FME_FIELD_FILL(1);
  303. }
  304. /* Fill elements */
  305. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  306. /*
  307. Capability
  308. Support Rates
  309. Extended Support Rates
  310. Supported Channels
  311. HT Capabilities
  312. WMM Information Element
  313. Extended Capabilities
  314. Link Identifier
  315. RSNIE
  316. FTIE
  317. Timeout Interval
  318. */
  319. if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) {
  320. /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */
  321. u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
  322. WLAN_SET_FIELD_16(pPkt, u2CapInfo);
  323. LR_TDLS_FME_FIELD_FILL(2);
  324. /* 4. Append general IEs */
  325. /*
  326. TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode
  327. must be CONFIG_BW_20_40M.
  328. TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if
  329. Tdls 20/40 is enabled.
  330. */
  331. u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, u2StatusCode, pPkt);
  332. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  333. /* 5. Frame Formation - Extended capabilities element */
  334. EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
  335. EXT_CAP_IE(pPkt)->ucLength = 5;
  336. EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
  337. EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
  338. EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
  339. EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
  340. EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */
  341. /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */
  342. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
  343. /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */
  344. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
  345. /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */
  346. EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
  347. u4IeLen = IE_SIZE(pPkt);
  348. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  349. } else {
  350. /* 5. Frame Formation - WMM Parameter element */
  351. if (prAdapter->rWifiVar.fgSupportQoS) {
  352. u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter,
  353. prBssInfo, pPkt, OP_MODE_INFRASTRUCTURE);
  354. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  355. }
  356. }
  357. }
  358. /* 6. Frame Formation - 20/40 BSS Coexistence */
  359. /*
  360. Follow WiFi test plan, add 20/40 element to request/response/confirm.
  361. */
  362. /* if (prGlueInfo->rTdlsLink.fgIs2040Sup == TRUE) */ /* force to enable */
  363. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  364. /*
  365. bit0 = 1: The Information Request field is used to indicate that a
  366. transmitting STA is requesting the recipient to transmit a 20/40 BSS
  367. Coexistence Management frame with the transmitting STA as the
  368. recipient.
  369. bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
  370. that receives this information or reports of this information from
  371. operating a 20/40 MHz BSS.
  372. bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
  373. a receiving AP from operating its BSS as a 20/40 MHz BSS.
  374. */
  375. BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
  376. BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
  377. BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
  378. LR_TDLS_FME_FIELD_FILL(3);
  379. }
  380. /* 6. Frame Formation - HT Operation element */
  381. /* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */
  382. /* LR_TDLS_FME_FIELD_FILL(u4IeLen); */
  383. /* 7. Frame Formation - Link identifier element */
  384. /* Note1: Link ID sequence must be correct; Or the calculated MIC will be error */
  385. /*
  386. Note2: When we receive a setup request with link ID, Marvell will send setup response
  387. to the peer in link ID, not the SA in the WLAN header.
  388. */
  389. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
  390. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = ELEM_LEN_LINK_IDENTIFIER;
  391. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
  392. switch (ucActionCode) {
  393. case TDLS_FRM_ACTION_SETUP_REQ:
  394. case TDLS_FRM_ACTION_CONFIRM:
  395. default:
  396. /* we are initiator */
  397. pucInitiator = prBssInfo->aucOwnMacAddr;
  398. pucResponder = pPeerMac;
  399. if (prStaRec != NULL)
  400. prStaRec->flgTdlsIsInitiator = TRUE;
  401. break;
  402. case TDLS_FRM_ACTION_SETUP_RSP:
  403. case TDLS_FRM_ACTION_DISCOVERY_RESPONSE:
  404. /* peer is initiator */
  405. pucInitiator = pPeerMac;
  406. pucResponder = prBssInfo->aucOwnMacAddr;
  407. if (prStaRec != NULL)
  408. prStaRec->flgTdlsIsInitiator = FALSE;
  409. break;
  410. case TDLS_FRM_ACTION_TEARDOWN:
  411. if (prStaRec != NULL) {
  412. if (prStaRec->flgTdlsIsInitiator == TRUE) {
  413. /* we are initiator */
  414. pucInitiator = prBssInfo->aucOwnMacAddr;
  415. pucResponder = pPeerMac;
  416. } else {
  417. /* peer is initiator */
  418. pucInitiator = pPeerMac;
  419. pucResponder = prBssInfo->aucOwnMacAddr;
  420. }
  421. } else {
  422. /* peer is initiator */
  423. pucInitiator = pPeerMac;
  424. pucResponder = prBssInfo->aucOwnMacAddr;
  425. }
  426. break;
  427. }
  428. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6);
  429. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6);
  430. u4IeLen = IE_SIZE(pPkt);
  431. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  432. /* 8. Append security IEs */
  433. /*
  434. 11.21.5 TDLS Direct Link Teardown
  435. If the STA has security enabled on the link 37 with the AP, then the FTIE shall be
  436. included in the TDLS Teardown frame.
  437. For ralink station, it can accept our tear down without FTIE but marvell station.
  438. */
  439. /* if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) */
  440. if (pAppendIe != NULL) {
  441. if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) ||
  442. ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) &&
  443. (prStaRec != NULL) && (prStaRec->fgTdlsInSecurityMode == TRUE))) {
  444. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  445. LR_TDLS_FME_FIELD_FILL(AppendIeLen);
  446. }
  447. }
  448. /* 7. Append Supported Operating Classes IE */
  449. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  450. /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
  451. u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
  452. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  453. }
  454. /* 11. send the data or management frame */
  455. if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RESPONSE) {
  456. #if 0
  457. /*
  458. Note1: remember to modify our MAC & AP MAC & peer MAC in LINK ID
  459. Note2: dialog token in rsp & confirm must be same as sender.
  460. */
  461. #if 1
  462. /* example for Ralink's and Broadcom's TDLS setup request frame in open/none */
  463. if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) {
  464. #if 0
  465. /* mediatek */
  466. char buffer[] = { 0x31, 0x04,
  467. 0x01, 0x08, 0x02, 0x04, 0x0b, 0x16, 0xc, 0x12, 0x18, 0x24,
  468. 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c,
  469. 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01,
  470. 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  471. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  472. 0x00, 0x00, 0x00, 0x00,
  473. 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f,
  474. 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20,
  475. 0x48, 0x01, 0x01,
  476. 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33,
  477. 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
  478. 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19,
  479. 0x1b, 0x1c, 0x1e, 0x20, 0x21,
  480. 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e
  481. };
  482. #endif
  483. #if 1
  484. /* ralink *//* from capability */
  485. char buffer[] = { 0x21, 0x04,
  486. 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c,
  487. 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00,
  488. 0x32, 0x04, 0x0c, 0x18, 0x30, 0x60,
  489. 0x24, 0x06, 0x01, 0x0b, 0x24, 0x08, 0x95, 0x04,
  490. 0x7f, 0x05, 0x01, 0x00, 0x00, 0x50, 0x20,
  491. 0x3b, 0x10, 0x20, 0x01, 0x02, 0x03, 0x04, 0x0c, 0x16, 0x17, 0x18, 0x19,
  492. 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21,
  493. 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  494. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
  495. 0x00, 0x00, 0x00, 0x00,
  496. 0x48, 0x01, 0x01,
  497. 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
  498. 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
  499. 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f
  500. };
  501. #endif
  502. #if 0
  503. /* 6630 */
  504. char buffer[] = { 0x01, 0x01,
  505. 0x01, 0x04, 0x02, 0x04, 0x0b, 0x16,
  506. 0x24, 0x02, 0x01, 0x0d,
  507. 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0xff,
  508. 0x2d, 0x1a, 0x61, 0x01, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  509. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  510. 0x00, 0x00, 0x00, 0x00,
  511. 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00,
  512. 0x48, 0x01, 0x01,
  513. 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19,
  514. 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21,
  515. 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e,
  516. 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
  517. 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
  518. 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x01, 0x00, 0x00,
  519. 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60,
  520. 0x00, 0x00, 0x00,
  521. 0xbf, 0x0c, 0x30, 0x01, 0x80, 0x03, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff,
  522. 0x00, 0x00
  523. };
  524. #endif
  525. pPktTemp += 18;
  526. memcpy(pPktTemp, buffer, sizeof(buffer));
  527. u4PktLen = 18 + sizeof(buffer);
  528. }
  529. #endif
  530. #if 1
  531. if (ucActionCode == TDLS_FRM_ACTION_CONFIRM) {
  532. /* Note: dialog token must be same as request */
  533. #if 1
  534. /* ralink */
  535. char buffer[] = { 0x00,
  536. 0x01, 0x2d, 0x1a, 0x6e, 0x00, 0x17, 0xff, 0x00, 0x00, 0x00,
  537. 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  538. 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
  539. 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
  540. 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
  541. 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x00, 0x03,
  542. 0xa4, 0x00, 0x00, 0x27, 0xa4, 0x00, 0x00, 0x42, 0x43, 0x5e, 0x00,
  543. 0x62, 0x32, 0x2f, 0x00
  544. };
  545. #endif
  546. #if 0
  547. /* 6630 */
  548. char buffer[] = { 0x00,
  549. 0x01,
  550. 0x38, 0x05, 0x02, 0xc0, 0xa8, 0x00, 0x00,
  551. 0x48, 0x01, 0x01,
  552. 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19,
  553. 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21,
  554. 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e,
  555. 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
  556. 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
  557. 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00,
  558. 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x80, 0x3f, 0x00, 0x00,
  559. 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60,
  560. 0x00, 0x00, 0x00
  561. };
  562. #endif
  563. #if 0
  564. /* A/D die */
  565. char buffer[] = { 0x00,
  566. 0x01,
  567. 0xdd, 0x18, 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01, 0x0f, 0x6b, 0x00, 0x00,
  568. 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x60,
  569. 0x00, 0x00, 0x00 0x65, 0x12, 0x00, 0x0c, 0x43, 0x31, 0x35, 0x97, 0x00, 0x11, 0x22, 0x33,
  570. 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
  571. 0x38, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19, 0x1b,
  572. 0x1c, 0x1e, 0x20, 0x21,
  573. 0x07, 0x06, 0x55, 0x53, 0x20, 0x01, 0x0b, 0x1e
  574. };
  575. #endif
  576. pPktTemp += 18;
  577. memcpy(pPktTemp, buffer, sizeof(buffer));
  578. u4PktLen = 18 + sizeof(buffer);
  579. }
  580. #endif
  581. #else
  582. #if 0
  583. /* for test in open/none */
  584. if (ucActionCode == TDLS_FRM_ACTION_SETUP_REQ) {
  585. char buffer[] = { 0x01, 0x04,
  586. 0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x12, 0x24, 0x48, 0x6c,
  587. 0x07, 0x06, 0x55, 0x53, 0x20, 0xdd, 0x20, 0x00,
  588. 0x32, 0x04, 0x30, 0x48, 0x60, 0x6c,
  589. 0x24, 0x0a, 0x01, 0x0b, 0x24, 0x04, 0x34, 0x04, 0x95, 0x04, 0xa5, 0x01,
  590. 0x2d, 0x1a, 0x72, 0x11, 0x03, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  591. 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  592. 0x00, 0x00, 0x00, 0x00,
  593. 0xdd, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x0f,
  594. 0x7f, 0x05, 0x00, 0x00, 0x00, 0x50, 0x20,
  595. 0x48, 0x01, 0x01,
  596. 0x65, 0x12, 0x00, 0x0c, 0x43, 0x44, 0x0b, 0x1a, 0x00, 0x11, 0x22, 0x33,
  597. 0x44, 0x05, 0x00, 0x22, 0x58, 0x00, 0xcc, 0x0f,
  598. 0x3b, 0x0d, 0x0c, 0x01, 0x02, 0x03, 0x05, 0x16, 0x17, 0x19,
  599. 0x1b, 0x1c, 0x1e, 0x20, 0x21
  600. };
  601. pPktTemp += 18;
  602. memcpy(pPktTemp, buffer, sizeof(buffer));
  603. u4PktLen = 18 + sizeof(buffer);
  604. }
  605. #endif
  606. #endif /* 0 */
  607. /* 9. Update packet length */
  608. prMsduInfo->len = u4PktLen;
  609. dumpMemory8(prMsduInfo->data, u4PktLen);
  610. wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
  611. } else {
  612. /*
  613. A TDLS capable STA that receives a TDLS Discovery Request frame is required to
  614. send the response "to the requesting STA, via the direct path."
  615. However, prior to establishment of the direct link, the responding STA may not
  616. know the rate capabilities of the requesting STA. In this case, the responding
  617. STA shall send the TDLS Discovery Response frame using a rate from the
  618. BSSBasicRateSet of the BSS to which the STA is currently associated.
  619. */
  620. prMsduInfoMgmt->ucPacketType = HIF_TX_PACKET_TYPE_MGMT;
  621. prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
  622. prMsduInfoMgmt->ucNetworkType = prBssInfo->ucNetTypeIndex;
  623. prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
  624. prMsduInfoMgmt->fgIs802_1x = FALSE;
  625. prMsduInfoMgmt->fgIs802_11 = TRUE;
  626. prMsduInfoMgmt->u2FrameLength = u4PktLen;
  627. prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
  628. prMsduInfoMgmt->pfTxDoneHandler = NULL;
  629. prMsduInfoMgmt->fgIsBasicRate = TRUE; /* use basic rate */
  630. /* Send them to HW queue */
  631. nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt);
  632. }
  633. return TDLS_STATUS_SUCCESS;
  634. }
  635. #endif /* CFG_SUPPORT_TDLS */
  636. /* End of tdls_com.c */