tdls.c 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009
  1. /*
  2. ** Id: tdls.c#1
  3. */
  4. /*! \file tdls.c
  5. \brief This file includes IEEE802.11z TDLS support.
  6. */
  7. /*
  8. ** Log: tdls.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
  24. #include "tdls.h"
  25. #include "gl_cfg80211.h"
  26. #include "queue.h"
  27. /*******************************************************************************
  28. * C O N S T A N T S
  29. ********************************************************************************
  30. */
  31. /* The list of valid data rates. */
  32. /* The list of valid data rates. */
  33. /*******************************************************************************
  34. * F U N C T I O N D E C L A R A T I O N S
  35. ********************************************************************************
  36. */
  37. /*******************************************************************************
  38. * P R I V A T E D A T A
  39. ********************************************************************************
  40. */
  41. static BOOLEAN fgIsPtiTimeoutSkip = FALSE;
  42. /*******************************************************************************
  43. * P R I V A T E F U N C T I O N S
  44. ********************************************************************************
  45. */
  46. #define ELEM_ID_LINK_IDENTIFIER_LENGTH 16
  47. #define TDLS_KEY_TIMEOUT_INTERVAL 43200
  48. #define UNREACH_ABLE 25
  49. #define TDLS_REASON_CODE_UNREACHABLE 25
  50. #define TDLS_REASON_CODE_UNSPECIFIED 26
  51. #define WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE 25
  52. #define WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED 26
  53. UINT_8 g_arTdlsLink[MAXNUM_TDLS_PEER] = {
  54. 0,
  55. 0,
  56. 0,
  57. 0
  58. };
  59. /*----------------------------------------------------------------------------*/
  60. /*!
  61. * \brief This routine is called to hadel TDLS link oper from nl80211.
  62. *
  63. * \param[in] pvAdapter Pointer to the Adapter structure.
  64. * \param[in]
  65. * \param[in]
  66. * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
  67. *
  68. * \retval WLAN_STATUS_SUCCESS
  69. * \retval WLAN_STATUS_INVALID_LENGTH
  70. */
  71. /*----------------------------------------------------------------------------*/
  72. UINT_32 TdlsexLinkMgt(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen)
  73. {
  74. /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
  75. STA_RECORD_T *prStaRec;
  76. P_BSS_INFO_T prBssInfo;
  77. TDLS_CMD_LINK_MGT_T *prCmd;
  78. prCmd = (TDLS_CMD_LINK_MGT_T *) pvSetBuffer;
  79. prBssInfo = prAdapter->prAisBssInfo;
  80. #if 1
  81. /* AIS only */
  82. if (prBssInfo->eCurrentOPMode == OP_MODE_INFRASTRUCTURE) {
  83. prStaRec = prBssInfo->prStaRecOfAP;
  84. if (prStaRec == NULL)
  85. return 0;
  86. } else {
  87. return -EINVAL;
  88. }
  89. #endif
  90. prStaRec = prBssInfo->prStaRecOfAP;
  91. switch (prCmd->ucActionCode) {
  92. case TDLS_FRM_ACTION_DISCOVERY_REQ:
  93. if (prStaRec == NULL)
  94. return 0;
  95. if (TdlsDataFrameSend_DISCOVERY_REQ(prAdapter,
  96. prStaRec,
  97. prCmd->aucPeer,
  98. prCmd->ucActionCode,
  99. prCmd->ucDialogToken,
  100. prCmd->u2StatusCode,
  101. (UINT_8 *) (prCmd->aucSecBuf),
  102. prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
  103. return -1;
  104. }
  105. break;
  106. case TDLS_FRM_ACTION_SETUP_REQ:
  107. if (prStaRec == NULL)
  108. return 0;
  109. prStaRec = cnmGetTdlsPeerByAddress(prAdapter, prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeer);
  110. g_arTdlsLink[prStaRec->ucTdlsIndex] = 0;
  111. if (TdlsDataFrameSend_SETUP_REQ(prAdapter,
  112. prStaRec,
  113. prCmd->aucPeer,
  114. prCmd->ucActionCode,
  115. prCmd->ucDialogToken,
  116. prCmd->u2StatusCode,
  117. (UINT_8 *) (prCmd->aucSecBuf),
  118. prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
  119. return -1;
  120. }
  121. break;
  122. case TDLS_FRM_ACTION_SETUP_RSP:
  123. /* fix sigma bug 5.2.4.2, 5.2.4.7, we sent Status code decline,
  124. * but the sigma recogniezis it as scucess, and it will fail */
  125. /* if(prCmd->u2StatusCode != 0) */
  126. if (prBssInfo->fgTdlsIsProhibited)
  127. return 0;
  128. if (TdlsDataFrameSend_SETUP_RSP(prAdapter,
  129. prStaRec,
  130. prCmd->aucPeer,
  131. prCmd->ucActionCode,
  132. prCmd->ucDialogToken,
  133. prCmd->u2StatusCode,
  134. (UINT_8 *) (prCmd->aucSecBuf),
  135. prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
  136. return -1;
  137. }
  138. break;
  139. case TDLS_FRM_ACTION_DISCOVERY_RSP:
  140. if (TdlsDataFrameSend_DISCOVERY_RSP(prAdapter,
  141. prStaRec,
  142. prCmd->aucPeer,
  143. prCmd->ucActionCode,
  144. prCmd->ucDialogToken,
  145. prCmd->u2StatusCode,
  146. (UINT_8 *) (prCmd->aucSecBuf),
  147. prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
  148. return -1;
  149. }
  150. break;
  151. case TDLS_FRM_ACTION_CONFIRM:
  152. if (TdlsDataFrameSend_CONFIRM(prAdapter,
  153. prStaRec,
  154. prCmd->aucPeer,
  155. prCmd->ucActionCode,
  156. prCmd->ucDialogToken,
  157. prCmd->u2StatusCode,
  158. (UINT_8 *) (prCmd->aucSecBuf),
  159. prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
  160. return -1;
  161. }
  162. break;
  163. case TDLS_FRM_ACTION_TEARDOWN:
  164. prStaRec = cnmGetTdlsPeerByAddress(prAdapter, prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeer);
  165. if (prCmd->u2StatusCode == TDLS_REASON_CODE_UNREACHABLE)
  166. g_arTdlsLink[prStaRec->ucTdlsIndex] = 0;
  167. if (TdlsDataFrameSend_TearDown(prAdapter,
  168. prStaRec,
  169. prCmd->aucPeer,
  170. prCmd->ucActionCode,
  171. prCmd->ucDialogToken,
  172. prCmd->u2StatusCode,
  173. (UINT_8 *) (prCmd->aucSecBuf),
  174. prCmd->u4SecBufLen) != TDLS_STATUS_SUCCESS) {
  175. return -1;
  176. }
  177. break;
  178. default:
  179. return -EINVAL;
  180. }
  181. return 0;
  182. }
  183. /*----------------------------------------------------------------------------*/
  184. /*!
  185. * \brief This routine is called to hadel TDLS link mgt from nl80211.
  186. *
  187. * \param[in] pvAdapter Pointer to the Adapter structure.
  188. * \param[in]
  189. * \param[in]
  190. * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
  191. *
  192. * \retval WLAN_STATUS_SUCCESS
  193. * \retval WLAN_STATUS_INVALID_LENGTH
  194. */
  195. /*----------------------------------------------------------------------------*/
  196. UINT_32 TdlsexLinkOper(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen)
  197. {
  198. /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
  199. UINT_16 i;
  200. STA_RECORD_T *prStaRec;
  201. TDLS_CMD_LINK_OPER_T *prCmd;
  202. prCmd = (TDLS_CMD_LINK_OPER_T *) pvSetBuffer;
  203. switch (prCmd->oper) {
  204. case TDLS_ENABLE_LINK:
  205. for (i = 0; i < MAXNUM_TDLS_PEER; i++) {
  206. if (!g_arTdlsLink[i]) {
  207. g_arTdlsLink[i] = 1;
  208. prStaRec =
  209. cnmGetTdlsPeerByAddress(prAdapter,
  210. prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeerMac);
  211. prStaRec->ucTdlsIndex = i;
  212. break;
  213. }
  214. }
  215. break;
  216. case TDLS_DISABLE_LINK:
  217. prStaRec = cnmGetTdlsPeerByAddress(prAdapter, prAdapter->prAisBssInfo->ucBssIndex, prCmd->aucPeerMac);
  218. g_arTdlsLink[prStaRec->ucTdlsIndex] = 0;
  219. if (IS_DLS_STA(prStaRec))
  220. cnmStaRecFree(prAdapter, prStaRec);
  221. break;
  222. default:
  223. return 0;
  224. }
  225. return 0;
  226. }
  227. /*----------------------------------------------------------------------------*/
  228. /*!
  229. * \brief This routine is called to append general IEs.
  230. *
  231. * \param[in] pvAdapter Pointer to the Adapter structure.
  232. * \param[in]
  233. *
  234. * \retval append length
  235. */
  236. /*----------------------------------------------------------------------------*/
  237. UINT_32 TdlsFrameGeneralIeAppend(ADAPTER_T *prAdapter, STA_RECORD_T *prStaRec, UINT_8 *pPkt)
  238. {
  239. GLUE_INFO_T *prGlueInfo;
  240. BSS_INFO_T *prBssInfo;
  241. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  242. UINT_32 u4NonHTPhyType;
  243. UINT_16 u2SupportedRateSet;
  244. UINT_8 aucAllSupportedRates[RATE_NUM_SW] = { 0 }; /* 6628 RATE_NUM -> 6630 RATE_NUM_SW */
  245. UINT_8 ucAllSupportedRatesLen;
  246. UINT_8 ucSupRatesLen;
  247. UINT_8 ucExtSupRatesLen;
  248. UINT_32 u4PktLen, u4IeLen;
  249. /* init */
  250. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  251. prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
  252. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  253. u4PktLen = 0;
  254. /* 3. Frame Formation - (5) Supported Rates element */
  255. /* use all sup rate we can support */
  256. u4NonHTPhyType = prStaRec->ucNonHTBasicPhyType;
  257. u2SupportedRateSet = rNonHTPhyAttributes[u4NonHTPhyType].u2SupportedRateSet;
  258. rateGetDataRatesFromRateSet(u2SupportedRateSet, 0, aucAllSupportedRates, &ucAllSupportedRatesLen);
  259. ucSupRatesLen = ((ucAllSupportedRatesLen > ELEM_MAX_LEN_SUP_RATES) ?
  260. ELEM_MAX_LEN_SUP_RATES : ucAllSupportedRatesLen);
  261. ucExtSupRatesLen = ucAllSupportedRatesLen - ucSupRatesLen;
  262. if (ucSupRatesLen) {
  263. SUP_RATES_IE(pPkt)->ucId = ELEM_ID_SUP_RATES;
  264. SUP_RATES_IE(pPkt)->ucLength = ucSupRatesLen;
  265. kalMemCopy(SUP_RATES_IE(pPkt)->aucSupportedRates, aucAllSupportedRates, ucSupRatesLen);
  266. u4IeLen = IE_SIZE(pPkt);
  267. pPkt += u4IeLen;
  268. u4PktLen += u4IeLen;
  269. }
  270. /* 3. Frame Formation - (7) Extended sup rates element */
  271. if (ucExtSupRatesLen) {
  272. EXT_SUP_RATES_IE(pPkt)->ucId = ELEM_ID_EXTENDED_SUP_RATES;
  273. EXT_SUP_RATES_IE(pPkt)->ucLength = ucExtSupRatesLen;
  274. kalMemCopy(EXT_SUP_RATES_IE(pPkt)->aucExtSupportedRates,
  275. &aucAllSupportedRates[ucSupRatesLen], ucExtSupRatesLen);
  276. u4IeLen = IE_SIZE(pPkt);
  277. pPkt += u4IeLen;
  278. u4PktLen += u4IeLen;
  279. }
  280. /* 3. Frame Formation - (8) Supported channels element */
  281. SUPPORTED_CHANNELS_IE(pPkt)->ucId = ELEM_ID_SUP_CHS;
  282. SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 2;
  283. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[0] = 1;
  284. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[1] = 13;
  285. if (prAdapter->fgEnable5GBand == TRUE) {
  286. SUPPORTED_CHANNELS_IE(pPkt)->ucLength = 10;
  287. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[2] = 36;
  288. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[3] = 4;
  289. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[4] = 52;
  290. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[5] = 4;
  291. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[6] = 149;
  292. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[7] = 4;
  293. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[8] = 165;
  294. SUPPORTED_CHANNELS_IE(pPkt)->ucChannelNum[9] = 1;
  295. }
  296. u4IeLen = IE_SIZE(pPkt);
  297. pPkt += u4IeLen;
  298. u4PktLen += u4IeLen;
  299. return u4PktLen;
  300. }
  301. /*******************************************************************************
  302. * P U B L I C F U N C T I O N S
  303. ********************************************************************************
  304. */
  305. /*!
  306. * \brief This routine is called to transmit a TDLS data frame.
  307. *
  308. * \param[in] pvAdapter Pointer to the Adapter structure.
  309. * \param[in]
  310. * \param[in]
  311. * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
  312. *
  313. * \retval WLAN_STATUS_SUCCESS
  314. * \retval WLAN_STATUS_INVALID_LENGTH
  315. */
  316. /*----------------------------------------------------------------------------*/
  317. WLAN_STATUS
  318. TdlsDataFrameSend_TearDown(ADAPTER_T *prAdapter,
  319. STA_RECORD_T *prStaRec,
  320. UINT_8 *pPeerMac,
  321. UINT_8 ucActionCode,
  322. UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
  323. {
  324. GLUE_INFO_T *prGlueInfo;
  325. BSS_INFO_T *prBssInfo;
  326. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  327. struct sk_buff *prMsduInfo;
  328. UINT_8 *pPkt;
  329. UINT_32 u4PktLen, u4IeLen;
  330. UINT_16 ReasonCode;
  331. /* allocate/init packet */
  332. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  333. prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
  334. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  335. u4PktLen = 0;
  336. prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
  337. if (prMsduInfo == NULL)
  338. return TDLS_STATUS_RESOURCES;
  339. prMsduInfo->dev = prGlueInfo->prDevHandler;
  340. if (prMsduInfo->dev == NULL) {
  341. kalPacketFree(prGlueInfo, prMsduInfo);
  342. return TDLS_STATUS_FAIL;
  343. }
  344. /* make up frame content */
  345. /* 1. 802.3 header */
  346. kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  347. pPkt += TDLS_FME_MAC_ADDR_LEN;
  348. kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
  349. pPkt += TDLS_FME_MAC_ADDR_LEN;
  350. *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
  351. pPkt += 2;
  352. u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2;
  353. /* 2. payload type */
  354. *pPkt = TDLS_FRM_PAYLOAD_TYPE;
  355. pPkt++;
  356. u4PktLen++;
  357. /* 3. Frame Formation - (1) Category */
  358. *pPkt = TDLS_FRM_CATEGORY;
  359. pPkt++;
  360. u4PktLen++;
  361. /* 3. Frame Formation - (2) Action */
  362. *pPkt = ucActionCode;
  363. pPkt++;
  364. u4PktLen++;
  365. /* 3. Frame Formation - status code */
  366. ReasonCode = u2StatusCode;
  367. kalMemCopy(pPkt, &ReasonCode, 2);
  368. pPkt = pPkt + 2;
  369. u4PktLen = u4PktLen + 2;
  370. if (pAppendIe != NULL) {
  371. if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) ||
  372. ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && (prStaRec != NULL))) {
  373. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  374. LR_TDLS_FME_FIELD_FILL(AppendIeLen);
  375. }
  376. }
  377. /* 7. Append Supported Operating Classes IE */
  378. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  379. /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
  380. u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
  381. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  382. }
  383. /* 3. Frame Formation - (16) Link identifier element */
  384. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
  385. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
  386. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
  387. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
  388. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pPeerMac, 6);
  389. u4IeLen = IE_SIZE(pPkt);
  390. pPkt += u4IeLen;
  391. u4PktLen += u4IeLen;
  392. /* 5. Update packet length */
  393. prMsduInfo->len = u4PktLen;
  394. /* if(u2StatusCode == UNREACH_ABLE ){ */
  395. /* g_arTdlsLink[prStaRec->ucTdlsIndex] = FALSE; */
  396. /* } */
  397. /* 5. send the data frame */
  398. wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
  399. return TDLS_STATUS_SUCCESS;
  400. }
  401. /*!
  402. * \brief This routine is called to transmit a TDLS data frame.
  403. *
  404. * \param[in] pvAdapter Pointer to the Adapter structure.
  405. * \param[in]
  406. * \param[in]
  407. * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
  408. *
  409. * \retval WLAN_STATUS_SUCCESS
  410. * \retval WLAN_STATUS_INVALID_LENGTH
  411. */
  412. /*----------------------------------------------------------------------------*/
  413. WLAN_STATUS /* TDLS_STATUS */
  414. TdlsDataFrameSend_SETUP_REQ(ADAPTER_T *prAdapter,
  415. STA_RECORD_T *prStaRec,
  416. UINT_8 *pPeerMac,
  417. UINT_8 ucActionCode,
  418. UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
  419. {
  420. GLUE_INFO_T *prGlueInfo;
  421. BSS_INFO_T *prBssInfo;
  422. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  423. struct sk_buff *prMsduInfo;
  424. UINT_8 *pPkt;
  425. UINT_32 u4PktLen, u4IeLen;
  426. BOOLEAN fg40mAllowed;
  427. UINT_16 u2CapInfo;
  428. /* allocate/init packet */
  429. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  430. prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
  431. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  432. u4PktLen = 0;
  433. prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
  434. if (prMsduInfo == NULL)
  435. return TDLS_STATUS_RESOURCES;
  436. prMsduInfo->dev = prGlueInfo->prDevHandler;
  437. if (prMsduInfo->dev == NULL) {
  438. kalPacketFree(prGlueInfo, prMsduInfo);
  439. return TDLS_STATUS_FAIL;
  440. }
  441. /* make up frame content */
  442. /* 1. 802.3 header */
  443. kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  444. pPkt += TDLS_FME_MAC_ADDR_LEN;
  445. kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
  446. pPkt += TDLS_FME_MAC_ADDR_LEN;
  447. *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
  448. pPkt += 2;
  449. u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2;
  450. /* 2. payload type */
  451. *pPkt = TDLS_FRM_PAYLOAD_TYPE;
  452. pPkt++;
  453. u4PktLen++;
  454. /* 3. Frame Formation - (1) Category */
  455. *pPkt = TDLS_FRM_CATEGORY;
  456. pPkt++;
  457. u4PktLen++;
  458. /* 3. Frame Formation - (2) Action */
  459. *pPkt = ucActionCode;
  460. pPkt++;
  461. u4PktLen++;
  462. /* 3. Frame Formation - (3) Dialog token */
  463. *pPkt = ucDialogToken;
  464. pPkt++;
  465. u4PktLen++;
  466. /* 3. Frame Formation - (4) Capability */
  467. u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
  468. WLAN_SET_FIELD_16(pPkt, u2CapInfo);
  469. pPkt = pPkt + 2;
  470. u4PktLen = u4PktLen + 2;
  471. /* 4. Append general IEs */
  472. u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt);
  473. pPkt += u4IeLen;
  474. u4PktLen += u4IeLen;
  475. /* 4. Append extra IEs */
  476. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  477. pPkt += AppendIeLen;
  478. u4PktLen += AppendIeLen;
  479. /* 3. Frame Formation - (10) Extended capabilities element */
  480. EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
  481. EXT_CAP_IE(pPkt)->ucLength = 5;
  482. /* 0320 !! */
  483. EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
  484. EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
  485. EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
  486. EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
  487. EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0xFF; /* bit32 ~ bit39 */
  488. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
  489. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
  490. EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
  491. /* EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; *//* bit24 ~ bit31 */
  492. u4IeLen = IE_SIZE(pPkt);
  493. pPkt += u4IeLen;
  494. u4PktLen += u4IeLen;
  495. /* HT capability IE append 0122 */
  496. HT_CAP_IE(pPkt)->ucId = ELEM_ID_HT_CAP;
  497. HT_CAP_IE(pPkt)->ucLength = 26;
  498. /* 3. Frame Formation - (14) HT capabilities element */
  499. if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N)) {
  500. /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */
  501. if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucBssIndex))
  502. fg40mAllowed = TRUE;
  503. else
  504. fg40mAllowed = FALSE;
  505. /* Add HT IE *//* try to reuse p2p path */
  506. u4IeLen = rlmFillHtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
  507. pPkt += u4IeLen;
  508. u4PktLen += u4IeLen;
  509. /* 0320 !! check newest driver !!! */
  510. }
  511. /* check */
  512. /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
  513. TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
  514. TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
  515. TIMEOUT_INTERVAL_IE(pPkt)->ucType = 2; /* IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; */
  516. TIMEOUT_INTERVAL_IE(pPkt)->u4Value = TDLS_KEY_TIMEOUT_INTERVAL; /* htonl(prCmd->u4Timeout); */
  517. u4IeLen = IE_SIZE(pPkt);
  518. pPkt += u4IeLen;
  519. u4PktLen += u4IeLen;
  520. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  521. /*
  522. bit0 = 1: The Information Request field is used to indicate that a
  523. transmitting STA is requesting the recipient to transmit a 20/40 BSS
  524. Coexistence Management frame with the transmitting STA as the
  525. recipient.
  526. bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
  527. that receives this information or reports of this information from
  528. operating a 20/40 MHz BSS.
  529. bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
  530. a receiving AP from operating its BSS as a 20/40 MHz BSS.
  531. */
  532. BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
  533. BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
  534. BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
  535. LR_TDLS_FME_FIELD_FILL(3);
  536. }
  537. if (pAppendIe != NULL) {
  538. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  539. LR_TDLS_FME_FIELD_FILL(AppendIeLen);
  540. }
  541. /* 7. Append Supported Operating Classes IE */
  542. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  543. /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
  544. u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
  545. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  546. }
  547. /* 3. Frame Formation - (16) Link identifier element */
  548. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
  549. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
  550. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
  551. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
  552. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pPeerMac, 6);
  553. u4IeLen = IE_SIZE(pPkt);
  554. pPkt += u4IeLen;
  555. u4PktLen += u4IeLen;
  556. /* 3. Frame Formation - (17) WMM Information element */
  557. /* HT WMM IE append */
  558. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  559. /* Add WMM IE *//* try to reuse p2p path */
  560. u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
  561. pPkt += u4IeLen;
  562. u4PktLen += u4IeLen;
  563. }
  564. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  565. u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt);
  566. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  567. }
  568. #if CFG_SUPPORT_802_11AC
  569. if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AC) {
  570. /* Add VHT IE *//* try to reuse p2p path */
  571. u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
  572. pPkt += u4IeLen;
  573. u4PktLen += u4IeLen;
  574. }
  575. #endif
  576. /* 5. Update packet length */
  577. prMsduInfo->len = u4PktLen;
  578. DBGLOG(TDLS, INFO, "\n\n\n wlanHardStartXmit\n\n\n");
  579. /* 5. send the data frame */
  580. wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
  581. /* wlanTx ??? */
  582. return TDLS_STATUS_SUCCESS;
  583. }
  584. WLAN_STATUS
  585. TdlsDataFrameSend_SETUP_RSP(ADAPTER_T *prAdapter,
  586. STA_RECORD_T *prStaRec,
  587. UINT_8 *pPeerMac,
  588. UINT_8 ucActionCode,
  589. UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
  590. {
  591. GLUE_INFO_T *prGlueInfo;
  592. BSS_INFO_T *prBssInfo;
  593. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  594. struct sk_buff *prMsduInfo;
  595. UINT_8 *pPkt;
  596. UINT_32 u4PktLen, u4IeLen;
  597. UINT_16 u2CapInfo;
  598. UINT_16 StatusCode;
  599. BOOLEAN fg40mAllowed;
  600. /* allocate/init packet */
  601. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  602. prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
  603. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  604. u4PktLen = 0;
  605. prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
  606. if (prMsduInfo == NULL)
  607. return TDLS_STATUS_RESOURCES;
  608. prMsduInfo->dev = prGlueInfo->prDevHandler;
  609. if (prMsduInfo->dev == NULL) {
  610. kalPacketFree(prGlueInfo, prMsduInfo);
  611. return TDLS_STATUS_FAIL;
  612. }
  613. /* make up frame content */
  614. /* 1. 802.3 header */
  615. kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  616. pPkt += TDLS_FME_MAC_ADDR_LEN;
  617. kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
  618. pPkt += TDLS_FME_MAC_ADDR_LEN;
  619. *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
  620. pPkt += 2;
  621. u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2;
  622. /* 2. payload type */
  623. *pPkt = TDLS_FRM_PAYLOAD_TYPE;
  624. pPkt++;
  625. u4PktLen++;
  626. /* 3. Frame Formation - (1) Category */
  627. *pPkt = TDLS_FRM_CATEGORY;
  628. pPkt++;
  629. u4PktLen++;
  630. /* 3. Frame Formation - (2) Action */
  631. *pPkt = ucActionCode;
  632. pPkt++;
  633. u4PktLen++;
  634. /* 3. Frame Formation - status code */
  635. StatusCode = u2StatusCode;
  636. kalMemCopy(pPkt, &StatusCode, 2);
  637. pPkt = pPkt + 2;
  638. u4PktLen = u4PktLen + 2;
  639. /* 3. Frame Formation - (3) Dialog token */
  640. *pPkt = ucDialogToken;
  641. pPkt++;
  642. u4PktLen++;
  643. /* 3. Frame Formation - (4) Capability */
  644. u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
  645. WLAN_SET_FIELD_16(pPkt, u2CapInfo);
  646. pPkt = pPkt + 2;
  647. u4PktLen = u4PktLen + 2;
  648. /* 4. Append general IEs */
  649. u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt);
  650. pPkt += u4IeLen;
  651. u4PktLen += u4IeLen;
  652. /* 4. Append extra IEs */
  653. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  654. pPkt += AppendIeLen;
  655. u4PktLen += AppendIeLen;
  656. /* 3. Frame Formation - (10) Extended capabilities element */
  657. EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
  658. EXT_CAP_IE(pPkt)->ucLength = 5;
  659. EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
  660. EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
  661. EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
  662. EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
  663. EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0xFF; /* bit32 ~ bit39 */
  664. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
  665. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
  666. EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
  667. /* EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; *//* bit24 ~ bit31 */
  668. u4IeLen = IE_SIZE(pPkt);
  669. pPkt += u4IeLen;
  670. u4PktLen += u4IeLen;
  671. /* HT capability IE append */
  672. HT_CAP_IE(pPkt)->ucId = ELEM_ID_HT_CAP;
  673. HT_CAP_IE(pPkt)->ucLength = 26;
  674. /* 3. Frame Formation - (14) HT capabilities element */
  675. if ((prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11N)) {
  676. /* TODO: prAdapter->rWifiVar.rConnSettings.uc5GBandwidthMode */
  677. if (cnmBss40mBwPermitted(prAdapter, prBssInfo->ucBssIndex))
  678. fg40mAllowed = TRUE;
  679. else
  680. fg40mAllowed = FALSE;
  681. /* Add HT IE *//* try to reuse p2p path */
  682. u4IeLen = rlmFillHtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
  683. pPkt += u4IeLen;
  684. u4PktLen += u4IeLen;
  685. }
  686. /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
  687. TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
  688. TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
  689. TIMEOUT_INTERVAL_IE(pPkt)->ucType = 2; /* IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; */
  690. TIMEOUT_INTERVAL_IE(pPkt)->u4Value = TDLS_KEY_TIMEOUT_INTERVAL; /* htonl(prCmd->u4Timeout); */
  691. u4IeLen = IE_SIZE(pPkt);
  692. pPkt += u4IeLen;
  693. u4PktLen += u4IeLen;
  694. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  695. /*
  696. bit0 = 1: The Information Request field is used to indicate that a
  697. transmitting STA is requesting the recipient to transmit a 20/40 BSS
  698. Coexistence Management frame with the transmitting STA as the
  699. recipient.
  700. bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
  701. that receives this information or reports of this information from
  702. operating a 20/40 MHz BSS.
  703. bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
  704. a receiving AP from operating its BSS as a 20/40 MHz BSS.
  705. */
  706. BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
  707. BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
  708. BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
  709. LR_TDLS_FME_FIELD_FILL(3);
  710. }
  711. if (pAppendIe != NULL) {
  712. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  713. LR_TDLS_FME_FIELD_FILL(AppendIeLen);
  714. }
  715. /* 7. Append Supported Operating Classes IE */
  716. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  717. /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
  718. u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
  719. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  720. }
  721. /* 3. Frame Formation - (16) Link identifier element */
  722. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
  723. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
  724. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
  725. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pPeerMac, 6); /* prAdapter->rMyMacAddr */
  726. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); /* pPeerMac */
  727. u4IeLen = IE_SIZE(pPkt);
  728. pPkt += u4IeLen;
  729. u4PktLen += u4IeLen;
  730. /* HT WMM IE append */
  731. /* HT WMM IE append */
  732. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  733. /* Add WMM IE *//* try to reuse p2p path */
  734. u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
  735. pPkt += u4IeLen;
  736. u4PktLen += u4IeLen;
  737. }
  738. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  739. u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt);
  740. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  741. }
  742. #if CFG_SUPPORT_802_11AC
  743. if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AC) {
  744. /* Add VHT IE *//* try to reuse p2p path */
  745. u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
  746. pPkt += u4IeLen;
  747. u4PktLen += u4IeLen;
  748. }
  749. #endif
  750. /* 5. Update packet length */
  751. prMsduInfo->len = u4PktLen;
  752. /* 5. send the data frame */
  753. wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
  754. return TDLS_STATUS_SUCCESS;
  755. }
  756. WLAN_STATUS
  757. TdlsDataFrameSend_CONFIRM(ADAPTER_T *prAdapter,
  758. STA_RECORD_T *prStaRec,
  759. UINT_8 *pPeerMac,
  760. UINT_8 ucActionCode,
  761. UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
  762. {
  763. GLUE_INFO_T *prGlueInfo;
  764. BSS_INFO_T *prBssInfo;
  765. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  766. struct sk_buff *prMsduInfo;
  767. UINT_8 *pPkt;
  768. UINT_32 u4PktLen, u4IeLen;
  769. UINT_16 StatusCode;
  770. /* allocate/init packet */
  771. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  772. prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
  773. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  774. u4PktLen = 0;
  775. prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
  776. if (prMsduInfo == NULL)
  777. return TDLS_STATUS_RESOURCES;
  778. prMsduInfo->dev = prGlueInfo->prDevHandler;
  779. if (prMsduInfo->dev == NULL) {
  780. kalPacketFree(prGlueInfo, prMsduInfo);
  781. return TDLS_STATUS_FAIL;
  782. }
  783. /* make up frame content */
  784. /* 1. 802.3 header */
  785. kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  786. pPkt += TDLS_FME_MAC_ADDR_LEN;
  787. kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
  788. pPkt += TDLS_FME_MAC_ADDR_LEN;
  789. *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
  790. pPkt += 2;
  791. u4PktLen += TDLS_FME_MAC_ADDR_LEN * 2 + 2;
  792. /* 2. payload type */
  793. *pPkt = TDLS_FRM_PAYLOAD_TYPE;
  794. pPkt++;
  795. u4PktLen++;
  796. /* 3. Frame Formation - (1) Category */
  797. *pPkt = TDLS_FRM_CATEGORY;
  798. pPkt++;
  799. u4PktLen++;
  800. /* 3. Frame Formation - (2) Action */
  801. *pPkt = ucActionCode;
  802. pPkt++;
  803. u4PktLen++;
  804. /* 3. Frame Formation - status code */
  805. StatusCode = u2StatusCode; /* 0; //u2StatusCode; //ahiu 0224 */
  806. kalMemCopy(pPkt, &StatusCode, 2);
  807. pPkt = pPkt + 2;
  808. u4PktLen = u4PktLen + 2;
  809. /* 3. Frame Formation - (3) Dialog token */
  810. *pPkt = ucDialogToken;
  811. pPkt++;
  812. u4PktLen++;
  813. /* 4. Append extra IEs */
  814. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  815. pPkt += AppendIeLen;
  816. u4PktLen += AppendIeLen;
  817. /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
  818. TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
  819. TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
  820. TIMEOUT_INTERVAL_IE(pPkt)->ucType = 2;
  821. TIMEOUT_INTERVAL_IE(pPkt)->u4Value = TDLS_KEY_TIMEOUT_INTERVAL; /* htonl(prCmd->u4Timeout); */
  822. u4IeLen = IE_SIZE(pPkt);
  823. pPkt += u4IeLen;
  824. u4PktLen += u4IeLen;
  825. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  826. /*
  827. bit0 = 1: The Information Request field is used to indicate that a
  828. transmitting STA is requesting the recipient to transmit a 20/40 BSS
  829. Coexistence Management frame with the transmitting STA as the
  830. recipient.
  831. bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
  832. that receives this information or reports of this information from
  833. operating a 20/40 MHz BSS.
  834. bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
  835. a receiving AP from operating its BSS as a 20/40 MHz BSS.
  836. */
  837. BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
  838. BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
  839. BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
  840. LR_TDLS_FME_FIELD_FILL(3);
  841. }
  842. if (pAppendIe != NULL) {
  843. if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) ||
  844. ((ucActionCode == TDLS_FRM_ACTION_TEARDOWN) && (prStaRec != NULL))) {
  845. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  846. LR_TDLS_FME_FIELD_FILL(AppendIeLen);
  847. }
  848. }
  849. /* 7. Append Supported Operating Classes IE */
  850. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  851. /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
  852. u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
  853. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  854. }
  855. /* 3. Frame Formation - (16) Link identifier element */
  856. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
  857. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
  858. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
  859. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, prAdapter->rMyMacAddr, 6);
  860. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pPeerMac, 6);
  861. u4IeLen = IE_SIZE(pPkt);
  862. pPkt += u4IeLen;
  863. u4PktLen += u4IeLen;
  864. /* HT WMM IE append */
  865. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  866. /* Add WMM IE *//* try to reuse p2p path */
  867. u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
  868. pPkt += u4IeLen;
  869. u4PktLen += u4IeLen;
  870. }
  871. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  872. u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt);
  873. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  874. }
  875. /* 5. Update packet length */
  876. prMsduInfo->len = u4PktLen;
  877. /* 5. send the data frame */
  878. wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
  879. return TDLS_STATUS_SUCCESS;
  880. }
  881. /*
  882. * \brief This routine is called to transmit a TDLS data frame.
  883. *
  884. * \param[in] pvAdapter Pointer to the Adapter structure.
  885. * \param[in]
  886. * \param[in]
  887. * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
  888. *
  889. * \retval WLAN_STATUS_SUCCESS
  890. * \retval WLAN_STATUS_INVALID_LENGTH
  891. */
  892. /*----------------------------------------------------------------------------*/
  893. WLAN_STATUS /* TDLS_STATUS */
  894. TdlsDataFrameSend_DISCOVERY_REQ(ADAPTER_T *prAdapter,
  895. STA_RECORD_T *prStaRec,
  896. UINT_8 *pPeerMac,
  897. UINT_8 ucActionCode,
  898. UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
  899. {
  900. GLUE_INFO_T *prGlueInfo;
  901. BSS_INFO_T *prBssInfo;
  902. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  903. struct sk_buff *prMsduInfo;
  904. MSDU_INFO_T *prMsduInfoMgmt;
  905. UINT_8 *pPkt, *pucInitiator, *pucResponder;
  906. UINT_32 u4PktLen, u4IeLen;
  907. UINT_16 u2CapInfo;
  908. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  909. if (prStaRec != NULL)
  910. prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
  911. else
  912. return TDLS_STATUS_FAIL;
  913. /* allocate/init packet */
  914. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  915. u4PktLen = 0;
  916. prMsduInfo = NULL;
  917. prMsduInfoMgmt = NULL;
  918. /* make up frame content */
  919. if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RSP) {
  920. /* TODO: reduce 1600 to correct size */
  921. prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
  922. if (prMsduInfo == NULL)
  923. return TDLS_STATUS_RESOURCES;
  924. prMsduInfo->dev = prGlueInfo->prDevHandler;
  925. if (prMsduInfo->dev == NULL) {
  926. kalPacketFree(prGlueInfo, prMsduInfo);
  927. return TDLS_STATUS_FAIL;
  928. }
  929. /* 1. 802.3 header */
  930. kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  931. LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
  932. kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
  933. LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
  934. *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
  935. LR_TDLS_FME_FIELD_FILL(2);
  936. /* 2. payload type */
  937. *pPkt = TDLS_FRM_PAYLOAD_TYPE;
  938. LR_TDLS_FME_FIELD_FILL(1);
  939. /* 3. Frame Formation - (1) Category */
  940. *pPkt = TDLS_FRM_CATEGORY;
  941. LR_TDLS_FME_FIELD_FILL(1);
  942. } else {
  943. WLAN_MAC_HEADER_T *prHdr;
  944. prMsduInfoMgmt = (MSDU_INFO_T *)
  945. cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
  946. if (prMsduInfoMgmt == NULL)
  947. return TDLS_STATUS_RESOURCES;
  948. pPkt = (UINT_8 *) prMsduInfoMgmt->prPacket;
  949. prHdr = (WLAN_MAC_HEADER_T *) pPkt;
  950. /* 1. 802.11 header */
  951. prHdr->u2FrameCtrl = MAC_FRAME_ACTION;
  952. prHdr->u2DurationID = 0;
  953. kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  954. kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
  955. kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN);
  956. prHdr->u2SeqCtrl = 0;
  957. LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T));
  958. /* Frame Formation - (1) Category */
  959. *pPkt = CATEGORY_PUBLIC_ACTION;
  960. LR_TDLS_FME_FIELD_FILL(1);
  961. }
  962. /* 3. Frame Formation - (2) Action */
  963. *pPkt = ucActionCode;
  964. LR_TDLS_FME_FIELD_FILL(1);
  965. /* 3. Frame Formation - Status Code */
  966. switch (ucActionCode) {
  967. case TDLS_FRM_ACTION_SETUP_RSP:
  968. case TDLS_FRM_ACTION_CONFIRM:
  969. case TDLS_FRM_ACTION_TEARDOWN:
  970. WLAN_SET_FIELD_16(pPkt, u2StatusCode);
  971. LR_TDLS_FME_FIELD_FILL(2);
  972. break;
  973. }
  974. /* 3. Frame Formation - (3) Dialog token */
  975. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  976. *pPkt = ucDialogToken;
  977. LR_TDLS_FME_FIELD_FILL(1);
  978. }
  979. /* Fill elements */
  980. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  981. /*
  982. Capability
  983. Support Rates
  984. Extended Support Rates
  985. Supported Channels
  986. HT Capabilities
  987. WMM Information Element
  988. Extended Capabilities
  989. Link Identifier
  990. RSNIE
  991. FTIE
  992. Timeout Interval
  993. */
  994. if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) {
  995. /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */
  996. u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
  997. WLAN_SET_FIELD_16(pPkt, u2CapInfo);
  998. LR_TDLS_FME_FIELD_FILL(2);
  999. /* 4. Append general IEs */
  1000. /*
  1001. TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode
  1002. must be CONFIG_BW_20_40M.
  1003. TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if
  1004. Tdls 20/40 is enabled.
  1005. */
  1006. u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt);
  1007. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  1008. /* 5. Frame Formation - Extended capabilities element */
  1009. EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
  1010. EXT_CAP_IE(pPkt)->ucLength = 5;
  1011. EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
  1012. EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
  1013. EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
  1014. EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
  1015. EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */
  1016. /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */
  1017. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
  1018. /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */
  1019. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
  1020. /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */
  1021. EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
  1022. u4IeLen = IE_SIZE(pPkt);
  1023. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  1024. } else {
  1025. /* 5. Frame Formation - WMM Information element */
  1026. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  1027. /* Add WMM IE *//* try to reuse p2p path */
  1028. u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
  1029. pPkt += u4IeLen;
  1030. u4PktLen += u4IeLen;
  1031. }
  1032. }
  1033. }
  1034. /* 6. Frame Formation - 20/40 BSS Coexistence */
  1035. /*
  1036. Follow WiFi test plan, add 20/40 element to request/response/confirm.
  1037. */
  1038. #if 0
  1039. if (prGlueInfo->fgTdlsIs2040Supported == TRUE) {
  1040. /*
  1041. bit0 = 1: The Information Request field is used to indicate that a
  1042. transmitting STA is requesting the recipient to transmit a 20/40 BSS
  1043. Coexistence Management frame with the transmitting STA as the
  1044. recipient.
  1045. bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
  1046. that receives this information or reports of this information from
  1047. operating a 20/40 MHz BSS.
  1048. bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
  1049. a receiving AP from operating its BSS as a 20/40 MHz BSS.
  1050. */
  1051. BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
  1052. BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
  1053. BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
  1054. LR_TDLS_FME_FIELD_FILL(3);
  1055. }
  1056. #endif
  1057. /* 6. Frame Formation - HT Operation element */
  1058. /* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */
  1059. /* LR_TDLS_FME_FIELD_FILL(u4IeLen); */
  1060. /* 7. Frame Formation - Link identifier element */
  1061. /* Note: Link ID sequence must be correct; Or the calculated MIC will be error */
  1062. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
  1063. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
  1064. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
  1065. switch (ucActionCode) {
  1066. case TDLS_FRM_ACTION_SETUP_REQ:
  1067. case TDLS_FRM_ACTION_CONFIRM:
  1068. case TDLS_FRM_ACTION_DISCOVERY_RSP:
  1069. default:
  1070. /* we are initiator */
  1071. pucInitiator = prBssInfo->aucOwnMacAddr;
  1072. pucResponder = pPeerMac;
  1073. if (prStaRec != NULL)
  1074. prStaRec->flgTdlsIsInitiator = TRUE;
  1075. break;
  1076. case TDLS_FRM_ACTION_SETUP_RSP:
  1077. /* peer is initiator */
  1078. pucInitiator = pPeerMac;
  1079. pucResponder = prBssInfo->aucOwnMacAddr;
  1080. if (prStaRec != NULL)
  1081. prStaRec->flgTdlsIsInitiator = FALSE;
  1082. break;
  1083. case TDLS_FRM_ACTION_TEARDOWN:
  1084. if (prStaRec != NULL) {
  1085. if (prStaRec->flgTdlsIsInitiator == TRUE) {
  1086. /* we are initiator */
  1087. pucInitiator = prBssInfo->aucOwnMacAddr;
  1088. pucResponder = pPeerMac;
  1089. } else {
  1090. /* peer is initiator */
  1091. pucInitiator = pPeerMac;
  1092. pucResponder = prBssInfo->aucOwnMacAddr;
  1093. }
  1094. } else {
  1095. /* peer is initiator */
  1096. pucInitiator = pPeerMac;
  1097. pucResponder = prBssInfo->aucOwnMacAddr;
  1098. }
  1099. break;
  1100. }
  1101. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pucInitiator, 6);
  1102. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, pucResponder, 6);
  1103. u4IeLen = IE_SIZE(pPkt);
  1104. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  1105. /* 8. Append security IEs */
  1106. if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) {
  1107. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  1108. LR_TDLS_FME_FIELD_FILL(AppendIeLen);
  1109. }
  1110. /* 10. send the data or management frame */
  1111. if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RSP) {
  1112. /* 9. Update packet length */
  1113. prMsduInfo->len = u4PktLen;
  1114. wlanHardStartXmit(prMsduInfo, prMsduInfo->dev);
  1115. } else {
  1116. prMsduInfoMgmt->ucPacketType = TX_PACKET_TYPE_MGMT;
  1117. prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
  1118. prMsduInfoMgmt->ucBssIndex = prBssInfo->ucBssIndex;
  1119. prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
  1120. prMsduInfoMgmt->fgIs802_1x = FALSE;
  1121. prMsduInfoMgmt->fgIs802_11 = TRUE;
  1122. prMsduInfoMgmt->u2FrameLength = u4PktLen;
  1123. prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
  1124. prMsduInfoMgmt->pfTxDoneHandler = NULL;
  1125. /* Send them to HW queue */
  1126. nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt);
  1127. }
  1128. return TDLS_STATUS_SUCCESS;
  1129. }
  1130. WLAN_STATUS
  1131. TdlsDataFrameSend_DISCOVERY_RSP(ADAPTER_T *prAdapter,
  1132. STA_RECORD_T *prStaRec,
  1133. UINT_8 *pPeerMac,
  1134. UINT_8 ucActionCode,
  1135. UINT_8 ucDialogToken, UINT_16 u2StatusCode, UINT_8 *pAppendIe, UINT_32 AppendIeLen)
  1136. {
  1137. GLUE_INFO_T *prGlueInfo;
  1138. BSS_INFO_T *prBssInfo;
  1139. PM_PROFILE_SETUP_INFO_T *prPmProfSetupInfo;
  1140. struct sk_buff *prMsduInfo;
  1141. MSDU_INFO_T *prMsduInfoMgmt;
  1142. UINT_8 *pPkt, *pucInitiator, *pucResponder;
  1143. UINT_32 u4PktLen, u4IeLen;
  1144. UINT_16 u2CapInfo;
  1145. prGlueInfo = (GLUE_INFO_T *) prAdapter->prGlueInfo;
  1146. /* sanity check */
  1147. if (prStaRec != NULL)
  1148. prBssInfo = prAdapter->prAisBssInfo; /* AIS only */
  1149. else
  1150. return TDLS_STATUS_FAIL;
  1151. /* allocate/init packet */
  1152. prPmProfSetupInfo = &prBssInfo->rPmProfSetupInfo;
  1153. u4PktLen = 0;
  1154. prMsduInfo = NULL;
  1155. prMsduInfoMgmt = NULL;
  1156. /* make up frame content */
  1157. if (ucActionCode != TDLS_FRM_ACTION_DISCOVERY_RSP) {
  1158. /* TODO: reduce 1600 to correct size */
  1159. prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
  1160. if (prMsduInfo == NULL)
  1161. return TDLS_STATUS_RESOURCES;
  1162. prMsduInfo->dev = prGlueInfo->prDevHandler;
  1163. if (prMsduInfo->dev == NULL) {
  1164. kalPacketFree(prGlueInfo, prMsduInfo);
  1165. return TDLS_STATUS_FAIL;
  1166. }
  1167. /* 1. 802.3 header */
  1168. kalMemCopy(pPkt, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  1169. LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
  1170. kalMemCopy(pPkt, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
  1171. LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
  1172. *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
  1173. LR_TDLS_FME_FIELD_FILL(2);
  1174. /* 2. payload type */
  1175. *pPkt = TDLS_FRM_PAYLOAD_TYPE;
  1176. LR_TDLS_FME_FIELD_FILL(1);
  1177. /* 3. Frame Formation - (1) Category */
  1178. *pPkt = TDLS_FRM_CATEGORY;
  1179. LR_TDLS_FME_FIELD_FILL(1);
  1180. } else {
  1181. WLAN_MAC_HEADER_T *prHdr;
  1182. prMsduInfoMgmt = (MSDU_INFO_T *)
  1183. cnmMgtPktAlloc(prAdapter, PUBLIC_ACTION_MAX_LEN);
  1184. if (prMsduInfoMgmt == NULL)
  1185. return TDLS_STATUS_RESOURCES;
  1186. pPkt = (UINT_8 *) prMsduInfoMgmt->prPacket;
  1187. prHdr = (WLAN_MAC_HEADER_T *) pPkt;
  1188. /* 1. 802.11 header */
  1189. prHdr->u2FrameCtrl = MAC_FRAME_ACTION;
  1190. prHdr->u2DurationID = 0;
  1191. kalMemCopy(prHdr->aucAddr1, pPeerMac, TDLS_FME_MAC_ADDR_LEN);
  1192. kalMemCopy(prHdr->aucAddr2, prBssInfo->aucOwnMacAddr, TDLS_FME_MAC_ADDR_LEN);
  1193. kalMemCopy(prHdr->aucAddr3, prBssInfo->aucBSSID, TDLS_FME_MAC_ADDR_LEN);
  1194. prHdr->u2SeqCtrl = 0;
  1195. LR_TDLS_FME_FIELD_FILL(sizeof(WLAN_MAC_HEADER_T));
  1196. /* Frame Formation - (1) Category */
  1197. *pPkt = CATEGORY_PUBLIC_ACTION;
  1198. LR_TDLS_FME_FIELD_FILL(1);
  1199. }
  1200. /* 3. Frame Formation - (2) Action */
  1201. *pPkt = ucActionCode;
  1202. LR_TDLS_FME_FIELD_FILL(1);
  1203. /* 3. Frame Formation - Status Code */
  1204. switch (ucActionCode) {
  1205. case TDLS_FRM_ACTION_SETUP_RSP:
  1206. case TDLS_FRM_ACTION_CONFIRM:
  1207. case TDLS_FRM_ACTION_TEARDOWN:
  1208. WLAN_SET_FIELD_16(pPkt, u2StatusCode);
  1209. LR_TDLS_FME_FIELD_FILL(2);
  1210. break;
  1211. }
  1212. /* 3. Frame Formation - (3) Dialog token */
  1213. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  1214. *pPkt = ucDialogToken;
  1215. LR_TDLS_FME_FIELD_FILL(1);
  1216. }
  1217. /* Fill elements */
  1218. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  1219. /*
  1220. Capability
  1221. Support Rates
  1222. Extended Support Rates
  1223. Supported Channels
  1224. HT Capabilities
  1225. WMM Information Element
  1226. Extended Capabilities
  1227. Link Identifier
  1228. RSNIE
  1229. FTIE
  1230. Timeout Interval
  1231. */
  1232. if (ucActionCode != TDLS_FRM_ACTION_CONFIRM) {
  1233. /* 3. Frame Formation - (4) Capability: 0x31 0x04, privacy bit will be set */
  1234. u2CapInfo = assocBuildCapabilityInfo(prAdapter, prStaRec);
  1235. WLAN_SET_FIELD_16(pPkt, u2CapInfo);
  1236. LR_TDLS_FME_FIELD_FILL(2);
  1237. /* 4. Append general IEs */
  1238. /*
  1239. TODO check HT: prAdapter->rWifiVar.rConnSettings.uc2G4BandwidthMode
  1240. must be CONFIG_BW_20_40M.
  1241. TODO check HT: HT_CAP_INFO_40M_INTOLERANT must be clear if
  1242. Tdls 20/40 is enabled.
  1243. */
  1244. u4IeLen = TdlsFrameGeneralIeAppend(prAdapter, prStaRec, pPkt);
  1245. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  1246. /* 5. Frame Formation - Extended capabilities element */
  1247. EXT_CAP_IE(pPkt)->ucId = ELEM_ID_EXTENDED_CAP;
  1248. EXT_CAP_IE(pPkt)->ucLength = 5;
  1249. EXT_CAP_IE(pPkt)->aucCapabilities[0] = 0x00; /* bit0 ~ bit7 */
  1250. EXT_CAP_IE(pPkt)->aucCapabilities[1] = 0x00; /* bit8 ~ bit15 */
  1251. EXT_CAP_IE(pPkt)->aucCapabilities[2] = 0x00; /* bit16 ~ bit23 */
  1252. EXT_CAP_IE(pPkt)->aucCapabilities[3] = 0x00; /* bit24 ~ bit31 */
  1253. EXT_CAP_IE(pPkt)->aucCapabilities[4] = 0x00; /* bit32 ~ bit39 */
  1254. /* if (prCmd->ucExCap & TDLS_EX_CAP_PEER_UAPSD) */
  1255. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((28 - 24));
  1256. /* if (prCmd->ucExCap & TDLS_EX_CAP_CHAN_SWITCH) */
  1257. EXT_CAP_IE(pPkt)->aucCapabilities[3] |= BIT((30 - 24));
  1258. /* if (prCmd->ucExCap & TDLS_EX_CAP_TDLS) */
  1259. EXT_CAP_IE(pPkt)->aucCapabilities[4] |= BIT((37 - 32));
  1260. u4IeLen = IE_SIZE(pPkt);
  1261. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  1262. } else {
  1263. /* 5. Frame Formation - WMM Information element */
  1264. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  1265. /* Add WMM IE *//* try to reuse p2p path */
  1266. u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
  1267. pPkt += u4IeLen;
  1268. u4PktLen += u4IeLen;
  1269. }
  1270. }
  1271. }
  1272. /* 6. Frame Formation - 20/40 BSS Coexistence */
  1273. /*
  1274. Follow WiFi test plan, add 20/40 element to request/response/confirm.
  1275. */
  1276. #if 0
  1277. if (prGlueInfo->fgTdlsIs2040Supported == TRUE) {
  1278. /*
  1279. bit0 = 1: The Information Request field is used to indicate that a
  1280. transmitting STA is requesting the recipient to transmit a 20/40 BSS
  1281. Coexistence Management frame with the transmitting STA as the
  1282. recipient.
  1283. bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
  1284. that receives this information or reports of this information from
  1285. operating a 20/40 MHz BSS.
  1286. bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
  1287. a receiving AP from operating its BSS as a 20/40 MHz BSS.
  1288. */
  1289. BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
  1290. BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
  1291. BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
  1292. LR_TDLS_FME_FIELD_FILL(3);
  1293. }
  1294. #endif
  1295. /* 6. Frame Formation - HT Operation element */
  1296. /* u4IeLen = rlmFillHtOpIeBody(prBssInfo, pPkt); */
  1297. /* LR_TDLS_FME_FIELD_FILL(u4IeLen); */
  1298. /* 7. Frame Formation - Link identifier element */
  1299. /* Note: Link ID sequence must be correct; Or the calculated MIC will be error */
  1300. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
  1301. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
  1302. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
  1303. switch (ucActionCode) {
  1304. case TDLS_FRM_ACTION_SETUP_REQ:
  1305. case TDLS_FRM_ACTION_CONFIRM:
  1306. default:
  1307. /* we are initiator */
  1308. pucInitiator = prBssInfo->aucOwnMacAddr;
  1309. pucResponder = pPeerMac;
  1310. if (prStaRec != NULL)
  1311. prStaRec->flgTdlsIsInitiator = TRUE;
  1312. break;
  1313. case TDLS_FRM_ACTION_DISCOVERY_RSP:
  1314. case TDLS_FRM_ACTION_SETUP_RSP:
  1315. /* peer is initiator */
  1316. pucInitiator = pPeerMac;
  1317. pucResponder = prBssInfo->aucOwnMacAddr;
  1318. if (prStaRec != NULL)
  1319. prStaRec->flgTdlsIsInitiator = FALSE;
  1320. break;
  1321. case TDLS_FRM_ACTION_TEARDOWN:
  1322. if (prStaRec != NULL) {
  1323. if (prStaRec->flgTdlsIsInitiator == TRUE) {
  1324. /* we are initiator */
  1325. pucInitiator = prBssInfo->aucOwnMacAddr;
  1326. pucResponder = pPeerMac;
  1327. } else {
  1328. /* peer is initiator */
  1329. pucInitiator = pPeerMac;
  1330. pucResponder = prBssInfo->aucOwnMacAddr;
  1331. }
  1332. } else {
  1333. /* peer is initiator */
  1334. pucInitiator = pPeerMac;
  1335. pucResponder = prBssInfo->aucOwnMacAddr;
  1336. }
  1337. break;
  1338. }
  1339. /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
  1340. TIMEOUT_INTERVAL_IE(pPkt)->ucId = ELEM_ID_TIMEOUT_INTERVAL;
  1341. TIMEOUT_INTERVAL_IE(pPkt)->ucLength = 5;
  1342. TIMEOUT_INTERVAL_IE(pPkt)->ucType = 2; /* IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME; */
  1343. TIMEOUT_INTERVAL_IE(pPkt)->u4Value = TDLS_KEY_TIMEOUT_INTERVAL; /* htonl(prCmd->u4Timeout); */
  1344. u4IeLen = IE_SIZE(pPkt);
  1345. pPkt += u4IeLen;
  1346. u4PktLen += u4IeLen;
  1347. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  1348. /*
  1349. bit0 = 1: The Information Request field is used to indicate that a
  1350. transmitting STA is requesting the recipient to transmit a 20/40 BSS
  1351. Coexistence Management frame with the transmitting STA as the
  1352. recipient.
  1353. bit1 = 0: The Forty MHz Intolerant field is set to 1 to prohibit an AP
  1354. that receives this information or reports of this information from
  1355. operating a 20/40 MHz BSS.
  1356. bit2 = 0: The 20 MHz BSS Width Request field is set to 1 to prohibit
  1357. a receiving AP from operating its BSS as a 20/40 MHz BSS.
  1358. */
  1359. BSS_20_40_COEXIST_IE(pPkt)->ucId = ELEM_ID_20_40_BSS_COEXISTENCE;
  1360. BSS_20_40_COEXIST_IE(pPkt)->ucLength = 1;
  1361. BSS_20_40_COEXIST_IE(pPkt)->ucData = 0x01;
  1362. LR_TDLS_FME_FIELD_FILL(3);
  1363. }
  1364. if (pAppendIe != NULL) {
  1365. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  1366. LR_TDLS_FME_FIELD_FILL(AppendIeLen);
  1367. }
  1368. /* 7. Append Supported Operating Classes IE */
  1369. if (ucActionCode != TDLS_FRM_ACTION_TEARDOWN) {
  1370. /* Note: if we do not put the IE, Marvell STA will decline our TDLS setup request */
  1371. u4IeLen = rlmDomainSupOperatingClassIeFill(pPkt);
  1372. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  1373. }
  1374. /* 3. Frame Formation - (16) Link identifier element */
  1375. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucId = ELEM_ID_LINK_IDENTIFIER;
  1376. TDLS_LINK_IDENTIFIER_IE(pPkt)->ucLength = 18;
  1377. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aBSSID, prBssInfo->aucBSSID, 6);
  1378. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aInitiator, pPeerMac, 6); /* prAdapter->rMyMacAddr */
  1379. kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt)->aResponder, prAdapter->rMyMacAddr, 6); /* pPeerMac */
  1380. u4IeLen = IE_SIZE(pPkt);
  1381. pPkt += u4IeLen;
  1382. u4PktLen += u4IeLen;
  1383. /* HT WMM IE append */
  1384. /* HT WMM IE append */
  1385. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  1386. /* Add WMM IE *//* try to reuse p2p path */
  1387. u4IeLen = mqmGenerateWmmInfoIEByStaRec(prAdapter, prBssInfo, prStaRec, pPkt);
  1388. pPkt += u4IeLen;
  1389. u4PktLen += u4IeLen;
  1390. }
  1391. if (IS_FEATURE_ENABLED(prAdapter->rWifiVar.ucQoS)) {
  1392. u4IeLen = mqmGenerateWmmParamIEByParam(prAdapter, prBssInfo, pPkt);
  1393. LR_TDLS_FME_FIELD_FILL(u4IeLen);
  1394. }
  1395. #if CFG_SUPPORT_802_11AC
  1396. if (prAdapter->rWifiVar.ucAvailablePhyTypeSet & PHY_TYPE_SET_802_11AC) {
  1397. /* Add VHT IE *//* try to reuse p2p path */
  1398. u4IeLen = rlmFillVhtCapIEByAdapter(prAdapter, prBssInfo, pPkt);
  1399. pPkt += u4IeLen;
  1400. u4PktLen += u4IeLen;
  1401. }
  1402. #endif
  1403. /* 8. Append security IEs */
  1404. if ((ucActionCode != TDLS_FRM_ACTION_TEARDOWN) && (pAppendIe != NULL)) {
  1405. kalMemCopy(pPkt, pAppendIe, AppendIeLen);
  1406. LR_TDLS_FME_FIELD_FILL(AppendIeLen);
  1407. }
  1408. prMsduInfoMgmt->ucPacketType = TX_PACKET_TYPE_MGMT;
  1409. prMsduInfoMgmt->ucStaRecIndex = prBssInfo->prStaRecOfAP->ucIndex;
  1410. prMsduInfoMgmt->ucBssIndex = prBssInfo->ucBssIndex;
  1411. prMsduInfoMgmt->ucMacHeaderLength = WLAN_MAC_MGMT_HEADER_LEN;
  1412. prMsduInfoMgmt->fgIs802_1x = FALSE;
  1413. prMsduInfoMgmt->fgIs802_11 = TRUE;
  1414. prMsduInfoMgmt->u2FrameLength = u4PktLen;
  1415. prMsduInfoMgmt->ucTxSeqNum = nicIncreaseTxSeqNum(prAdapter);
  1416. prMsduInfoMgmt->pfTxDoneHandler = NULL;
  1417. /* Send them to HW queue */
  1418. nicTxEnqueueMsdu(prAdapter, prMsduInfoMgmt);
  1419. return TDLS_STATUS_SUCCESS;
  1420. }
  1421. /*----------------------------------------------------------------------------*/
  1422. /*! \brief This routine is called to send a command to TDLS module.
  1423. *
  1424. * \param[in] prGlueInfo Pointer to the Adapter structure
  1425. * \param[in] prInBuf A pointer to the command string buffer
  1426. * \param[in] u4InBufLen The length of the buffer
  1427. * \param[out] None
  1428. *
  1429. * \retval None
  1430. */
  1431. /*----------------------------------------------------------------------------*/
  1432. VOID TdlsexEventHandle(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
  1433. {
  1434. UINT_32 u4EventId;
  1435. DBGLOG(TDLS, INFO, "TdlsexEventHandle\n");
  1436. /* sanity check */
  1437. if ((prGlueInfo == NULL) || (prInBuf == NULL))
  1438. return; /* shall not be here */
  1439. /* handle */
  1440. u4EventId = *(UINT_32 *) prInBuf;
  1441. u4InBufLen -= 4;
  1442. switch (u4EventId) {
  1443. case TDLS_HOST_EVENT_TEAR_DOWN:
  1444. DBGLOG(TDLS, INFO, "TDLS_HOST_EVENT_TEAR_DOWN\n");
  1445. TdlsEventTearDown(prGlueInfo, prInBuf + 4, u4InBufLen);
  1446. break;
  1447. case TDLS_HOST_EVENT_TX_DONE:
  1448. break;
  1449. }
  1450. }
  1451. /*----------------------------------------------------------------------------*/
  1452. /*! \brief This routine is called to do tear down.
  1453. *
  1454. * \param[in] prGlueInfo Pointer to the Adapter structure
  1455. * \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId
  1456. * \param[in] u4InBufLen The length of the buffer
  1457. * \param[out] None
  1458. *
  1459. * \retval None
  1460. *
  1461. */
  1462. /*----------------------------------------------------------------------------*/
  1463. VOID TdlsEventTearDown(GLUE_INFO_T *prGlueInfo, UINT_8 *prInBuf, UINT_32 u4InBufLen)
  1464. {
  1465. STA_RECORD_T *prStaRec;
  1466. UINT_16 u2ReasonCode = 0;
  1467. UINT_32 u4TearDownSubId;
  1468. UINT_8 *pMac, aucZeroMac[6];
  1469. /* init */
  1470. u4TearDownSubId = *(UINT_32 *) prInBuf;
  1471. kalMemZero(aucZeroMac, sizeof(aucZeroMac));
  1472. pMac = aucZeroMac;
  1473. prStaRec = cnmGetStaRecByIndex(prGlueInfo->prAdapter, *(prInBuf + 4));
  1474. if (prStaRec != NULL)
  1475. pMac = prStaRec->aucMacAddr;
  1476. /* handle */
  1477. /* sanity check */
  1478. if (prStaRec == NULL)
  1479. return;
  1480. if (fgIsPtiTimeoutSkip == TRUE) {
  1481. /* skip PTI timeout event */
  1482. if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT)
  1483. return;
  1484. }
  1485. if (u4TearDownSubId == TDLS_HOST_EVENT_TD_PTI_TIMEOUT) {
  1486. DBGLOG(TDLS, INFO, "TDLS_HOST_EVENT_TD_PTI_TIMEOUT TDLS_REASON_CODE_UNSPECIFIED\n");
  1487. u2ReasonCode = TDLS_REASON_CODE_UNSPECIFIED;
  1488. cfg80211_tdls_oper_request(prGlueInfo->prDevHandler,
  1489. prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN,
  1490. WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, GFP_ATOMIC);
  1491. }
  1492. if (u4TearDownSubId == TDLS_HOST_EVENT_TD_AGE_TIMEOUT) {
  1493. DBGLOG(TDLS, INFO, "TDLS_HOST_EVENT_TD_AGE_TIMEOUT TDLS_REASON_CODE_UNREACHABLE\n");
  1494. u2ReasonCode = TDLS_REASON_CODE_UNREACHABLE;
  1495. cfg80211_tdls_oper_request(prGlueInfo->prDevHandler,
  1496. prStaRec->aucMacAddr, NL80211_TDLS_TEARDOWN,
  1497. WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE, GFP_ATOMIC);
  1498. }
  1499. DBGLOG(TDLS, INFO, "\n\n u2ReasonCode = %u\n\n", u2ReasonCode);
  1500. /*
  1501. modify the value when supplicant sends tear down to us in TdlsexMgmtCtrl(), not here
  1502. we want to send tear down to AP (not peer) if PTI timeout or AGE timeout.
  1503. */
  1504. /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */
  1505. }
  1506. #if 0
  1507. /*----------------------------------------------------------------------------*/
  1508. /*! \brief This routine is called to send a TDLS event to supplicant.
  1509. *
  1510. * \param[in] prGlueInfo Pointer to the Adapter structure
  1511. * \param[in] prInBuf A pointer to the command string buffer
  1512. * \param[in] u4InBufLen The length of the buffer
  1513. * \param[out] None
  1514. *
  1515. * \retval None
  1516. *
  1517. */
  1518. /*----------------------------------------------------------------------------*/
  1519. VOID tdls_oper_request(struct net_device *dev, const u8 *peer, u16 oper, u16 reason_code, gfp_t gfp)
  1520. {
  1521. GLUE_INFO_T *prGlueInfo;
  1522. ADAPTER_T *prAdapter;
  1523. struct sk_buff *prMsduInfo;
  1524. UINT_8 *pPkt;
  1525. UINT_32 u4PktLen;
  1526. /* sanity check */
  1527. if ((dev == NULL) || (peer == NULL))
  1528. return; /* shall not be here */
  1529. /* init */
  1530. prGlueInfo = *((P_GLUE_INFO_T *) netdev_priv(dev));
  1531. prAdapter = prGlueInfo->prAdapter;
  1532. u4PktLen = 0;
  1533. /* allocate/init packet */
  1534. prMsduInfo = kalPacketAlloc(prGlueInfo, 1600, &pPkt);
  1535. if (prMsduInfo == NULL)
  1536. return;
  1537. prMsduInfo->dev = dev;
  1538. /* make up frame content */
  1539. /* 1. 802.3 header */
  1540. kalMemCopy(pPkt, prAdapter->rMyMacAddr, TDLS_FME_MAC_ADDR_LEN);
  1541. LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
  1542. kalMemCopy(pPkt, peer, TDLS_FME_MAC_ADDR_LEN);
  1543. LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN);
  1544. *(UINT_16 *) pPkt = htons(TDLS_FRM_PROT_TYPE);
  1545. LR_TDLS_FME_FIELD_FILL(2);
  1546. /* 2. payload type */
  1547. *pPkt = TDLS_FRM_PAYLOAD_TYPE;
  1548. LR_TDLS_FME_FIELD_FILL(1);
  1549. /* 3. Frame Formation - (1) Category */
  1550. *pPkt = TDLS_FRM_CATEGORY;
  1551. LR_TDLS_FME_FIELD_FILL(1);
  1552. /* 3. Frame Formation - (2) Action */
  1553. *pPkt = TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT;
  1554. LR_TDLS_FME_FIELD_FILL(1);
  1555. /* 3. Frame Formation - (3) Operation */
  1556. *pPkt = oper;
  1557. LR_TDLS_FME_FIELD_FILL(1);
  1558. /* 3. Frame Formation - (4) Reason Code */
  1559. *pPkt = reason_code;
  1560. *(pPkt + 1) = 0x00;
  1561. LR_TDLS_FME_FIELD_FILL(2);
  1562. /* 3. Frame Formation - (5) Peer MAC */
  1563. kalMemCopy(pPkt, peer, 6);
  1564. LR_TDLS_FME_FIELD_FILL(6);
  1565. /* 4. Update packet length */
  1566. prMsduInfo->len = u4PktLen;
  1567. /* pass to OS */
  1568. TdlsCmdTestRxIndicatePkts(prGlueInfo, prMsduInfo);
  1569. }
  1570. /*----------------------------------------------------------------------------*/
  1571. /*!
  1572. * \brief This routine is called to indicate packets to upper layer.
  1573. *
  1574. * \param[in] prGlueInfo Pointer to the Adapter structure
  1575. * \param[in] prSkb A pointer to the received packet
  1576. *
  1577. * \retval None
  1578. *
  1579. */
  1580. /*----------------------------------------------------------------------------*/
  1581. VOID TdlsCmdTestRxIndicatePkts(GLUE_INFO_T *prGlueInfo, struct sk_buff *prSkb)
  1582. {
  1583. struct net_device *prNetDev;
  1584. /* init */
  1585. prNetDev = prGlueInfo->prDevHandler;
  1586. prGlueInfo->rNetDevStats.rx_bytes += prSkb->len;
  1587. prGlueInfo->rNetDevStats.rx_packets++;
  1588. /* pass to upper layer */
  1589. prNetDev->last_rx = jiffies;
  1590. prSkb->protocol = eth_type_trans(prSkb, prNetDev);
  1591. prSkb->dev = prNetDev;
  1592. if (!in_interrupt())
  1593. netif_rx_ni(prSkb); /* only in non-interrupt context */
  1594. else
  1595. netif_rx(prSkb);
  1596. }
  1597. #endif
  1598. VOID TdlsBssExtCapParse(P_STA_RECORD_T prStaRec, P_UINT_8 pucIE)
  1599. {
  1600. UINT_8 *pucIeExtCap;
  1601. /* sanity check */
  1602. if ((prStaRec == NULL) || (pucIE == NULL))
  1603. return;
  1604. if (IE_ID(pucIE) != ELEM_ID_EXTENDED_CAP)
  1605. return;
  1606. /*
  1607. from bit0 ~
  1608. bit 38: TDLS Prohibited
  1609. The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The
  1610. field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is
  1611. allowed.
  1612. */
  1613. if (IE_LEN(pucIE) < 5)
  1614. return; /* we need 39/8 = 5 bytes */
  1615. /* init */
  1616. prStaRec->fgTdlsIsProhibited = FALSE;
  1617. prStaRec->fgTdlsIsChSwProhibited = FALSE;
  1618. /* parse */
  1619. pucIeExtCap = pucIE + 2;
  1620. pucIeExtCap += 4; /* shift to the byte we care about */
  1621. if ((*pucIeExtCap) && BIT(38 - 32))
  1622. prStaRec->fgTdlsIsProhibited = TRUE;
  1623. if ((*pucIeExtCap) && BIT(39 - 32))
  1624. prStaRec->fgTdlsIsChSwProhibited = TRUE;
  1625. }
  1626. /*----------------------------------------------------------------------------*/
  1627. /*!
  1628. * \brief Generate CMD_ID_SET_TDLS_CH_SW command
  1629. *
  1630. * \param[in]
  1631. *
  1632. * \return none
  1633. */
  1634. /*----------------------------------------------------------------------------*/
  1635. WLAN_STATUS
  1636. TdlsSendChSwControlCmd(P_ADAPTER_T prAdapter, PVOID pvSetBuffer, UINT_32 u4SetBufferLen, PUINT_32 pu4SetInfoLen)
  1637. {
  1638. CMD_TDLS_CH_SW_T rCmdTdlsChSwCtrl;
  1639. ASSERT(prAdapter);
  1640. /* send command packet for scan */
  1641. kalMemZero(&rCmdTdlsChSwCtrl, sizeof(CMD_TDLS_CH_SW_T));
  1642. rCmdTdlsChSwCtrl.fgIsTDLSChSwProhibit = prAdapter->prAisBssInfo->fgTdlsIsChSwProhibited;
  1643. wlanSendSetQueryCmd(prAdapter,
  1644. CMD_ID_SET_TDLS_CH_SW,
  1645. TRUE,
  1646. FALSE, FALSE, NULL, NULL, sizeof(CMD_TDLS_CH_SW_T), (PUINT_8)&rCmdTdlsChSwCtrl, NULL, 0);
  1647. return TDLS_STATUS_SUCCESS;
  1648. }
  1649. #endif /* CFG_SUPPORT_TDLS */
  1650. /* End of tdls.c */