6 \brief This file includes IEEE802.11z TDLS support.
13 * 11 13 2013 vend_samp.lin
18 /*******************************************************************************
19 * C O M P I L E R F L A G S
20 ********************************************************************************
23 /*******************************************************************************
24 * E X T E R N A L R E F E R E N C E S
25 ********************************************************************************
29 #if (CFG_SUPPORT_TDLS == 1)
32 #include "gl_cfg80211.h"
33 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
34 #include <uapi/linux/nl80211.h>
36 /*******************************************************************************
38 ********************************************************************************
41 /*******************************************************************************
42 * F U N C T I O N D E C L A R A T I O N S
43 ********************************************************************************
46 TdlsCmdTestRxIndicatePkts (
47 GLUE_INFO_T
*prGlueInfo
,
54 P_GLUE_INFO_T prGlueInfo
,
60 TdlsCmdTestChSwProhibitedBitSet(
61 P_GLUE_INFO_T prGlueInfo
,
67 TdlsCmdTestChSwReqRecv(
68 P_GLUE_INFO_T prGlueInfo
,
74 TdlsCmdTestChSwRspRecv(
75 P_GLUE_INFO_T prGlueInfo
,
81 TdlsCmdTestChSwTimeoutSkip(
82 P_GLUE_INFO_T prGlueInfo
,
88 TdlsCmdTestDataContSend(
89 GLUE_INFO_T
*prGlueInfo
,
96 P_GLUE_INFO_T prGlueInfo
,
103 P_GLUE_INFO_T prGlueInfo
,
110 P_GLUE_INFO_T prGlueInfo
,
116 TdlsCmdTestDiscoveryReqRecv(
117 GLUE_INFO_T
*prGlueInfo
,
123 TdlsCmdTestKeepAliveSkip(
124 P_GLUE_INFO_T prGlueInfo
,
130 TdlsCmdTestProhibitedBitSet(
131 P_GLUE_INFO_T prGlueInfo
,
137 TdlsCmdTestPtiReqRecv(
138 P_GLUE_INFO_T prGlueInfo
,
144 TdlsCmdTestPtiRspRecv(
145 P_GLUE_INFO_T prGlueInfo
,
151 TdlsCmdTestPtiTxDoneFail(
152 P_GLUE_INFO_T prGlueInfo
,
159 P_GLUE_INFO_T prGlueInfo
,
165 TdlsCmdTestSetupConfirmRecv(
166 GLUE_INFO_T
*prGlueInfo
,
172 TdlsCmdTestSetupReqRecv(
173 GLUE_INFO_T
*prGlueInfo
,
179 TdlsCmdTestSetupRspRecv(
180 GLUE_INFO_T
*prGlueInfo
,
187 P_GLUE_INFO_T prGlueInfo
,
193 TdlsCmdTestTearDownRecv(
194 GLUE_INFO_T
*prGlueInfo
,
200 TdlsCmdTestTxFailSkip(
201 P_GLUE_INFO_T prGlueInfo
,
207 TdlsCmdTestTxTdlsFrame(
208 P_GLUE_INFO_T prGlueInfo
,
215 P_GLUE_INFO_T prGlueInfo
,
221 TdlsCmdTestTxFmeSetupReqBufTranslate(
224 PARAM_CUSTOM_TDLS_CMD_STRUC_T
*prCmd
228 TdlsCmdTestUpdatePeer(
229 P_GLUE_INFO_T prGlueInfo
,
236 P_GLUE_INFO_T prGlueInfo
,
242 TdlsTimerTestDataContSend(
243 ADAPTER_T
*prAdapter
,
249 ADAPTER_T
*prAdapter
,
251 UINT_32 u4SetBufferLen
,
252 UINT_32
*pu4SetInfoLen
257 ADAPTER_T
*prAdapter
,
259 UINT_32 u4SetBufferLen
,
260 UINT_32
*pu4SetInfoLen
265 ADAPTER_T
*prAdapter
,
267 UINT_32 u4SetBufferLen
,
268 UINT_32
*pu4SetInfoLen
273 ADAPTER_T
*prAdapter
,
275 UINT_32 u4SetBufferLen
,
276 UINT_32
*pu4SetInfoLen
281 ADAPTER_T
*prAdapter
,
283 UINT_32 u4SetBufferLen
,
284 UINT_32
*pu4SetInfoLen
289 ADAPTER_T
*prAdapter
,
291 UINT_32 u4SetBufferLen
,
292 UINT_32
*pu4SetInfoLen
296 TdlsTestTearDownRecv(
297 ADAPTER_T
*prAdapter
,
299 UINT_32 u4SetBufferLen
,
300 UINT_32
*pu4SetInfoLen
305 ADAPTER_T
*prAdapter
,
307 UINT_32 u4SetBufferLen
,
308 UINT_32
*pu4SetInfoLen
313 ADAPTER_T
*prAdapter
,
315 UINT_32 u4SetBufferLen
,
316 UINT_32
*pu4SetInfoLen
320 TdlsTestTdlsFrameSend(
321 ADAPTER_T
*prAdapter
,
323 UINT_32 u4SetBufferLen
,
324 UINT_32
*pu4SetInfoLen
329 ADAPTER_T
*prAdapter
,
331 UINT_32 u4SetBufferLen
,
332 UINT_32
*pu4SetInfoLen
336 TdlsTestKeepAliveSkip(
337 ADAPTER_T
*prAdapter
,
339 UINT_32 u4SetBufferLen
,
340 UINT_32
*pu4SetInfoLen
344 TdlsTestChSwTimeoutSkip(
345 ADAPTER_T
*prAdapter
,
347 UINT_32 u4SetBufferLen
,
348 UINT_32
*pu4SetInfoLen
353 ADAPTER_T
*prAdapter
,
355 UINT_32 u4SetBufferLen
,
356 UINT_32
*pu4SetInfoLen
361 ADAPTER_T
*prAdapter
,
363 UINT_32 u4SetBufferLen
,
364 UINT_32
*pu4SetInfoLen
369 P_GLUE_INFO_T prGlueInfo
,
376 GLUE_INFO_T
*prGlueInfo
,
382 TdlsCmdKeyInfoDisplay(
383 GLUE_INFO_T
*prGlueInfo
,
389 TdlsCmdMibParamUpdate(
390 P_GLUE_INFO_T prGlueInfo
,
397 P_GLUE_INFO_T prGlueInfo
,
404 P_GLUE_INFO_T prGlueInfo
,
411 ADAPTER_T
*prAdapter
,
413 UINT_32 u4SetBufferLen
,
414 UINT_32
*pu4SetInfoLen
419 ADAPTER_T
*prAdapter
,
421 UINT_32 u4SetBufferLen
,
422 UINT_32
*pu4SetInfoLen
426 TdlsLinkHistoryRecord(
427 GLUE_INFO_T
*prGlueInfo
,
428 BOOLEAN fgIsTearDown
,
436 TdlsLinkHistoryRecordUpdate(
437 GLUE_INFO_T
*prGlueInfo
,
439 TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus
,
445 ADAPTER_T
*prAdapter
,
447 UINT_32 u4SetBufferLen
,
448 UINT_32
*pu4SetInfoLen
453 ADAPTER_T
*prAdapter
,
455 UINT_32 u4SetBufferLen
,
456 UINT_32
*pu4SetInfoLen
461 ADAPTER_T
*prAdapter
,
463 UINT_32 u4SetBufferLen
,
464 UINT_32
*pu4SetInfoLen
469 GLUE_INFO_T
*prGlueInfo
,
476 GLUE_INFO_T
*prGlueInfo
,
481 #endif /* TDLS_CFG_CMD_TEST */
483 /*******************************************************************************
484 * P R I V A T E D A T A
485 ********************************************************************************
487 static BOOLEAN fgIsPtiTimeoutSkip
= FALSE
;
490 /*******************************************************************************
491 * P R I V A T E F U N C T I O N S
492 ********************************************************************************
495 /*----------------------------------------------------------------------------*/
497 * \brief This routine is called to indicate packets to upper layer.
499 * \param[in] prGlueInfo Pointer to the Adapter structure
500 * \param[in] prSkb A pointer to the received packet
505 /*----------------------------------------------------------------------------*/
507 TdlsCmdTestRxIndicatePkts (
508 GLUE_INFO_T
*prGlueInfo
,
509 struct sk_buff
*prSkb
512 struct net_device
*prNetDev
;
516 prNetDev
= prGlueInfo
->prDevHandler
;
517 prGlueInfo
->rNetDevStats
.rx_bytes
+= prSkb
->len
;
518 prGlueInfo
->rNetDevStats
.rx_packets
++;
520 /* pass to upper layer */
521 prNetDev
->last_rx
= jiffies
;
522 prSkb
->protocol
= eth_type_trans(prSkb
, prNetDev
);
523 prSkb
->dev
= prNetDev
;
525 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
527 netif_rx_ni(prSkb
); /* only in non-interrupt context */
538 #if TDLS_CFG_CMD_TEST
540 #define LR_TDLS_FME_FIELD_FILL(__Len) \
544 /*----------------------------------------------------------------------------*/
545 /*! \brief This routine is called to add a TDLS peer.
547 * \param[in] prGlueInfo Pointer to the Adapter structure
548 * \param[in] prInBuf A pointer to the command string buffer
549 * \param[in] u4InBufLen The length of the buffer
554 * EX: iwpriv wlan0 set_str_cmd 0_2_[Responder MAC]
556 iwpriv wlan0 set_str_cmd 0_2_00:11:22:33:44:01
558 /*----------------------------------------------------------------------------*/
561 P_GLUE_INFO_T prGlueInfo
,
566 PARAM_CUSTOM_TDLS_CMD_STRUC_T rCmd
;
567 struct wireless_dev
*prWdev
;
571 kalMemZero(&rCmd
, sizeof(rCmd
));
573 /* parse arguments */
574 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.arRspAddr
);
577 rCmd
.rPeerInfo
.supported_rates
= NULL
;
578 rCmd
.rPeerInfo
.ht_capa
= &rCmd
.rHtCapa
;
579 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
580 rCmd
.rPeerInfo
.vht_capa
= &rCmd
.rVhtCapa
;
582 rCmd
.rPeerInfo
.sta_flags_set
= BIT(NL80211_STA_FLAG_TDLS_PEER
);
584 /* send command to wifi task to handle */
585 prWdev
= prGlueInfo
->prDevHandler
->ieee80211_ptr
;
586 mtk_cfg80211_add_station(\
587 prWdev
->wiphy
, (void *)0x1, rCmd
.arRspAddr
, &rCmd
.rPeerInfo
);
591 /*----------------------------------------------------------------------------*/
592 /*! \brief This routine is called to simulate to set the TDLS Prohibited bit.
594 * \param[in] prGlueInfo Pointer to the Adapter structure
595 * \param[in] prInBuf A pointer to the command string buffer
596 * \param[in] u4InBufLen The length of the buffer
601 * EX: iwpriv wlan0 set_str_cmd 0_16_[Enable/Disable]_[Set/Clear]
603 iwpriv wlan0 set_str_cmd 0_16_1_1
605 /*----------------------------------------------------------------------------*/
607 TdlsCmdTestChSwProhibitedBitSet(
608 P_GLUE_INFO_T prGlueInfo
,
613 extern BOOLEAN flgTdlsTestExtCapElm
;
614 extern UINT8 aucTdlsTestExtCapElm
[];
615 TDLS_CMD_CORE_T rCmd
;
618 /* parse arguments */
619 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
620 rCmd
.Content
.rCmdProhibit
.fgIsEnable
= \
621 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
622 rCmd
.Content
.rCmdProhibit
.fgIsSet
= \
623 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
625 DBGLOG(TDLS
, INFO
, ("%s: fgIsEnable = %d\n",
626 __FUNCTION__
, rCmd
.Content
.rCmdProhibit
.fgIsEnable
));
628 /* command to do this */
629 flgTdlsTestExtCapElm
= rCmd
.Content
.rCmdProhibit
.fgIsEnable
;
631 aucTdlsTestExtCapElm
[0] = ELEM_ID_EXTENDED_CAP
;
632 aucTdlsTestExtCapElm
[1] = 5;
633 aucTdlsTestExtCapElm
[2] = 0;
634 aucTdlsTestExtCapElm
[3] = 0;
635 aucTdlsTestExtCapElm
[4] = 0;
636 aucTdlsTestExtCapElm
[5] = 0;
637 aucTdlsTestExtCapElm
[6] = (rCmd
.Content
.rCmdProhibit
.fgIsSet
<< 7); /* bit39 */
641 /*----------------------------------------------------------------------------*/
642 /*! \brief This routine is called to receive a channel switch request from the peer.
644 * \param[in] prGlueInfo Pointer to the Adapter structure
645 * \param[in] prInBuf A pointer to the command string buffer
646 * \param[in] u4InBufLen The length of the buffer
651 * EX: iwpriv wlan0 set_str_cmd 0_1_5_[TDLS Peer MAC]_[Chan]_[RegulatoryClass]_
652 [SecondaryChannelOffset]_[SwitchTime]_[SwitchTimeout]
654 iwpriv wlan0 set_str_cmd 0_1_5_00:11:22:33:44:01_1_255_0_15000_30000
656 RegulatoryClass: TODO (reference to Annex I of 802.11n spec.)
657 Secondary Channel Offset: 0 (SCN - no secondary channel)
658 1 (SCA - secondary channel above)
659 2 (SCB - secondary channel below)
660 SwitchTime: units of microseconds
663 /*----------------------------------------------------------------------------*/
665 TdlsCmdTestChSwReqRecv(
666 P_GLUE_INFO_T prGlueInfo
,
672 TDLS_CMD_CORE_T rCmd
;
676 /* parse arguments */
677 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.aucPeerMac
);
679 rCmd
.Content
.rCmdChStReqRcv
.u4Chan
= \
680 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
681 rCmd
.Content
.rCmdChStReqRcv
.u4RegClass
= \
682 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
683 rCmd
.Content
.rCmdChStReqRcv
.u4SecChanOff
= \
684 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
685 rCmd
.Content
.rCmdChStReqRcv
.u4SwitchTime
= \
686 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
687 rCmd
.Content
.rCmdChStReqRcv
.u4SwitchTimeout
= \
688 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
690 DBGLOG(TDLS
, INFO
, ("%s: ["MACSTR
"] u4Chan=%u u4RegClass=%u"
691 " u4SecChanOff=%u u4SwitchTime=%u u4SwitchTimeout=%u\n",
692 __FUNCTION__
, MAC2STR(rCmd
.aucPeerMac
),
693 (UINT32
)rCmd
.Content
.rCmdChStReqRcv
.u4Chan
,
694 (UINT32
)rCmd
.Content
.rCmdChStReqRcv
.u4RegClass
,
695 (UINT32
)rCmd
.Content
.rCmdChStReqRcv
.u4SecChanOff
,
696 (UINT32
)rCmd
.Content
.rCmdChStReqRcv
.u4SwitchTime
,
697 (UINT32
)rCmd
.Content
.rCmdChStReqRcv
.u4SwitchTimeout
));
699 /* command to do this */
700 rStatus
= kalIoctl(prGlueInfo
,
710 if (rStatus
!= WLAN_STATUS_SUCCESS
)
712 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
718 /*----------------------------------------------------------------------------*/
719 /*! \brief This routine is called to receive a channel switch response from the peer.
721 * \param[in] prGlueInfo Pointer to the Adapter structure
722 * \param[in] prInBuf A pointer to the command string buffer
723 * \param[in] u4InBufLen The length of the buffer
728 * EX: iwpriv wlan0 set_str_cmd 0_1_6_[TDLS Peer MAC]_[Chan]_
729 [SwitchTime]_[SwitchTimeout]_[StatusCode]
731 iwpriv wlan0 set_str_cmd 0_1_6_00:11:22:33:44:01_11_15000_30000_0
733 RegulatoryClass: TODO (reference to Annex I of 802.11n spec.)
734 Secondary Channel Offset: 0 (SCN - no secondary channel)
735 1 (SCA - secondary channel above)
736 2 (SCB - secondary channel below)
737 SwitchTime: units of microseconds
740 /*----------------------------------------------------------------------------*/
742 TdlsCmdTestChSwRspRecv(
743 P_GLUE_INFO_T prGlueInfo
,
749 TDLS_CMD_CORE_T rCmd
;
753 /* parse arguments */
754 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.aucPeerMac
);
756 rCmd
.Content
.rCmdChStRspRcv
.u4Chan
= \
757 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
758 rCmd
.Content
.rCmdChStRspRcv
.u4SwitchTime
= \
759 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
760 rCmd
.Content
.rCmdChStRspRcv
.u4SwitchTimeout
= \
761 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
762 rCmd
.Content
.rCmdChStRspRcv
.u4StatusCode
= \
763 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
765 DBGLOG(TDLS
, INFO
, ("%s: ["MACSTR
"] u4Chan=%u "
766 " u4SwitchTime=%u u4SwitchTimeout=%u u4StatusCode=%u\n",
767 __FUNCTION__
, MAC2STR(rCmd
.aucPeerMac
),
768 (UINT32
)rCmd
.Content
.rCmdChStRspRcv
.u4Chan
,
769 (UINT32
)rCmd
.Content
.rCmdChStRspRcv
.u4SwitchTime
,
770 (UINT32
)rCmd
.Content
.rCmdChStRspRcv
.u4SwitchTimeout
,
771 (UINT32
)rCmd
.Content
.rCmdChStRspRcv
.u4StatusCode
));
773 /* command to do this */
774 rStatus
= kalIoctl(prGlueInfo
,
784 if (rStatus
!= WLAN_STATUS_SUCCESS
)
786 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
792 /*----------------------------------------------------------------------------*/
793 /*! \brief This routine is called to inform firmware to skip channel switch timeout function.
795 * \param[in] prGlueInfo Pointer to the Adapter structure
796 * \param[in] prInBuf A pointer to the command string buffer
797 * \param[in] u4InBufLen The length of the buffer
802 * EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]
804 iwpriv wlan0 set_str_cmd 0_11_1
806 /*----------------------------------------------------------------------------*/
808 TdlsCmdTestChSwTimeoutSkip(
809 P_GLUE_INFO_T prGlueInfo
,
815 TDLS_CMD_CORE_T rCmd
;
819 /* parse arguments */
820 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
821 rCmd
.Content
.rCmdKeepAliveSkip
.fgIsEnable
= \
822 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
824 DBGLOG(TDLS
, INFO
, ("%s: fgIsEnable = %d\n",
825 __FUNCTION__
, rCmd
.Content
.rCmdKeepAliveSkip
.fgIsEnable
));
827 /* command to do this */
828 rStatus
= kalIoctl(prGlueInfo
,
829 TdlsTestChSwTimeoutSkip
,
838 if (rStatus
!= WLAN_STATUS_SUCCESS
)
840 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
846 /*----------------------------------------------------------------------------*/
847 /*! \brief This routine is called to send a data frame to the peer periodically.
849 * \param[in] prGlueInfo Pointer to the Adapter structure
850 * \param[in] prInBuf A pointer to the command string buffer
851 * \param[in] u4InBufLen The length of the buffer
857 /*----------------------------------------------------------------------------*/
858 static TIMER_T rTdlsTimerTestDataSend
;
859 static UINT_8 aucTdlsTestDataSPeerMac
[6];
860 static UINT_16 u2TdlsTestDataSInterval
;
863 TdlsCmdTestDataContSend(
864 GLUE_INFO_T
*prGlueInfo
,
869 ADAPTER_T
*prAdapter
;
874 prAdapter
= prGlueInfo
->prAdapter
;
876 /* parse arguments */
877 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, aucTdlsTestDataSPeerMac
);
878 u2TdlsTestDataSInterval
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
879 fgIsEnabled
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
881 cnmTimerStopTimer(prAdapter
, &rTdlsTimerTestDataSend
);
883 if (fgIsEnabled
== FALSE
)
885 /* stop test timer */
889 /* re-init test timer */
890 cnmTimerInitTimer(prAdapter
,
891 &rTdlsTimerTestDataSend
,
892 (PFN_MGMT_TIMEOUT_FUNC
)TdlsTimerTestDataContSend
,
895 cnmTimerStartTimer(prAdapter
,
896 &rTdlsTimerTestDataSend
,
897 u2TdlsTestDataSInterval
);
901 /*----------------------------------------------------------------------------*/
902 /*! \brief This routine is called to receive a data frame from the peer.
904 * \param[in] prGlueInfo Pointer to the Adapter structure
905 * \param[in] prInBuf A pointer to the command string buffer
906 * \param[in] u4InBufLen The length of the buffer
911 * EX: iwpriv wlan0 set_str_cmd 0_0_x80_[TDLS Peer MAC]_[PM]_[UP]_[EOSP]_[IsNull]
913 iwpriv wlan0 set_str_cmd 0_1_x80_00:11:22:33:44:01_0_0_0_0
915 /*----------------------------------------------------------------------------*/
918 P_GLUE_INFO_T prGlueInfo
,
924 TDLS_CMD_CORE_T rCmd
;
928 /* parse arguments */
929 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.aucPeerMac
);
930 rCmd
.Content
.rCmdDatRcv
.u4PM
= \
931 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
932 rCmd
.Content
.rCmdDatRcv
.u4UP
= \
933 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
934 rCmd
.Content
.rCmdDatRcv
.u4EOSP
= \
935 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
936 rCmd
.Content
.rCmdDatRcv
.u4IsNull
= \
937 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
940 ("<tdls_cmd> %s: ["MACSTR
"] PM(%u) UP(%u) EOSP(%u) NULL(%u)\n",
941 __FUNCTION__
, MAC2STR(rCmd
.aucPeerMac
),
942 (UINT32
)rCmd
.Content
.rCmdDatRcv
.u4PM
,
943 (UINT32
)rCmd
.Content
.rCmdDatRcv
.u4UP
,
944 (UINT32
)rCmd
.Content
.rCmdDatRcv
.u4EOSP
,
945 (UINT32
)rCmd
.Content
.rCmdDatRcv
.u4IsNull
));
947 /* command to do this */
948 rStatus
= kalIoctl(prGlueInfo
,
958 if (rStatus
!= WLAN_STATUS_SUCCESS
)
960 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
966 /*----------------------------------------------------------------------------*/
967 /*! \brief This routine is called to send a data frame to the peer.
969 * \param[in] prGlueInfo Pointer to the Adapter structure
970 * \param[in] prInBuf A pointer to the command string buffer
971 * \param[in] u4InBufLen The length of the buffer
976 * EX: iwpriv wlan0 set_str_cmd 0_4_[Responder MAC]_[tx status]
978 iwpriv wlan0 set_str_cmd 0_4_00:11:22:33:44:01_0
980 /*----------------------------------------------------------------------------*/
983 P_GLUE_INFO_T prGlueInfo
,
988 P_ADAPTER_T prAdapter
;
989 struct sk_buff
*prMsduInfo
;
996 prAdapter
= prGlueInfo
->prAdapter
;
998 /* parse arguments */
999 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, MAC
);
1000 ucTxStatus
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1002 /* allocate a data frame */
1003 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1000, &prPkt
);
1004 if (prMsduInfo
== NULL
)
1006 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s allocate pkt fail!\n",
1012 prMsduInfo
->dev
= prGlueInfo
->prDevHandler
;
1013 if (prMsduInfo
->dev
== NULL
)
1015 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s prMsduInfo->dev == NULL!\n",
1017 kalPacketFree(prGlueInfo
, prMsduInfo
);
1022 prMsduInfo
->len
= 1000;
1023 kalMemZero(prMsduInfo
->data
, 100); /* for QoS field */
1024 kalMemCopy(prMsduInfo
->data
, MAC
, 6);
1025 kalMemCopy(prMsduInfo
->data
+6, prAdapter
->rMyMacAddr
, 6);
1026 *(UINT_16
*)(prMsduInfo
->data
+12) = 0x0800;
1028 /* simulate OS to send the packet */
1029 wlanHardStartXmit(prMsduInfo
, prMsduInfo
->dev
);
1033 /*----------------------------------------------------------------------------*/
1034 /*! \brief This routine is called to simulate to set the TDLS Prohibited bit.
1036 * \param[in] prGlueInfo Pointer to the Adapter structure
1037 * \param[in] prInBuf A pointer to the command string buffer
1038 * \param[in] u4InBufLen The length of the buffer
1043 * EX: iwpriv wlan0 set_str_cmd 0_16_[mili seconds]
1045 iwpriv wlan0 set_str_cmd 0_19_1000
1047 /*----------------------------------------------------------------------------*/
1050 P_GLUE_INFO_T prGlueInfo
,
1058 u4Delay
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1059 DBGLOG(TDLS
, INFO
, ("%s: Delay = %d\n",
1060 __FUNCTION__
, u4Delay
));
1066 /*----------------------------------------------------------------------------*/
1067 /*! \brief This routine is called to receive a test discovery request frame command.
1069 * \param[in] prGlueInfo Pointer to the Adapter structure
1070 * \param[in] prInBuf A pointer to the command string buffer
1071 * \param[in] u4InBufLen The length of the buffer
1076 * EX: iwpriv wlan0 set_str_cmd 0_1_10_[DialogToken]_[Peer MAC]_[BSSID]
1078 iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01
1079 iwpriv wlan0 set_str_cmd 0_1_10_1_00:11:22:33:44:01_00:22:33:44:11:22
1081 /*----------------------------------------------------------------------------*/
1083 TdlsCmdTestDiscoveryReqRecv(
1084 GLUE_INFO_T
*prGlueInfo
,
1089 ADAPTER_T
*prAdapter
;
1090 P_BSS_INFO_T prBssInfo
;
1091 struct sk_buff
*prMsduInfo
;
1093 UINT_32 u4PktLen
, u4IeLen
;
1094 UINT_8 ucDialogToken
, aucPeerMac
[6], aucBSSID
[6], aucZeroMac
[6];
1097 /* parse arguments */
1098 ucDialogToken
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1099 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, aucPeerMac
);
1101 kalMemZero(aucZeroMac
, sizeof(aucZeroMac
));
1102 kalMemZero(aucBSSID
, sizeof(aucBSSID
));
1103 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, aucBSSID
);
1106 ("<tdls_fme> %s: DialogToken=%d from "MACSTR
"\n",
1107 __FUNCTION__
, ucDialogToken
, MAC2STR(aucPeerMac
)));
1109 /* allocate/init packet */
1110 prAdapter
= prGlueInfo
->prAdapter
;
1111 prBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
1114 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1600, &pPkt
);
1115 if (prMsduInfo
== NULL
) {
1116 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: allocate pkt fail\n", __FUNCTION__
));
1120 prMsduInfo
->dev
= prGlueInfo
->prDevHandler
;
1121 if (prMsduInfo
->dev
== NULL
)
1123 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: MsduInfo->dev == NULL\n", __FUNCTION__
));
1124 kalPacketFree(prGlueInfo
, prMsduInfo
);
1128 /* make up frame content */
1129 /* 1. 802.3 header */
1130 kalMemCopy(pPkt
, prAdapter
->rMyMacAddr
, TDLS_FME_MAC_ADDR_LEN
);
1131 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
1132 kalMemCopy(pPkt
, aucPeerMac
, TDLS_FME_MAC_ADDR_LEN
);
1133 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
1134 *(UINT_16
*)pPkt
= htons(TDLS_FRM_PROT_TYPE
);
1135 LR_TDLS_FME_FIELD_FILL(2);
1137 /* 2. payload type */
1138 *pPkt
= TDLS_FRM_PAYLOAD_TYPE
;
1139 LR_TDLS_FME_FIELD_FILL(1);
1141 /* 3. Frame Formation - (1) Category */
1142 *pPkt
= TDLS_FRM_CATEGORY
;
1143 LR_TDLS_FME_FIELD_FILL(1);
1145 /* 3. Frame Formation - (2) Action */
1146 *pPkt
= TDLS_FRM_ACTION_DISCOVERY_REQ
;
1147 LR_TDLS_FME_FIELD_FILL(1);
1149 /* 3. Frame Formation - (3) Dialog token */
1150 *pPkt
= ucDialogToken
;
1151 LR_TDLS_FME_FIELD_FILL(1);
1153 /* 3. Frame Formation - (16) Link identifier element */
1154 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucId
= ELEM_ID_LINK_IDENTIFIER
;
1155 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucLength
= 18;
1157 if (kalMemCmp(aucBSSID
, aucZeroMac
, 6) == 0)
1158 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aBSSID
, prBssInfo
->aucBSSID
, 6);
1160 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aBSSID
, aucBSSID
, 6);
1162 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aInitiator
, aucPeerMac
, 6);
1163 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aResponder
, prAdapter
->rMyMacAddr
, 6);
1165 u4IeLen
= IE_SIZE(pPkt
);
1166 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1168 /* 4. Update packet length */
1169 prMsduInfo
->len
= u4PktLen
;
1170 dumpMemory8(ANDROID_LOG_INFO
, prMsduInfo
->data
, u4PktLen
);
1173 TdlsCmdTestRxIndicatePkts(prGlueInfo
, prMsduInfo
);
1177 /*----------------------------------------------------------------------------*/
1178 /*! \brief This routine is called to inform firmware to skip keep alive function.
1180 * \param[in] prGlueInfo Pointer to the Adapter structure
1181 * \param[in] prInBuf A pointer to the command string buffer
1182 * \param[in] u4InBufLen The length of the buffer
1187 * EX: iwpriv wlan0 set_str_cmd 0_10_[Enable/Disable]
1189 iwpriv wlan0 set_str_cmd 0_10_1
1191 /*----------------------------------------------------------------------------*/
1193 TdlsCmdTestKeepAliveSkip(
1194 P_GLUE_INFO_T prGlueInfo
,
1199 WLAN_STATUS rStatus
;
1200 TDLS_CMD_CORE_T rCmd
;
1204 /* parse arguments */
1205 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
1206 rCmd
.Content
.rCmdKeepAliveSkip
.fgIsEnable
= \
1207 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1209 DBGLOG(TDLS
, INFO
, ("%s: fgIsEnable = %d\n",
1210 __FUNCTION__
, rCmd
.Content
.rCmdKeepAliveSkip
.fgIsEnable
));
1212 /* command to do this */
1213 rStatus
= kalIoctl(prGlueInfo
,
1214 TdlsTestKeepAliveSkip
,
1223 if (rStatus
!= WLAN_STATUS_SUCCESS
)
1225 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
1231 /*----------------------------------------------------------------------------*/
1232 /*! \brief This routine is called to simulate to set the TDLS Prohibited bit.
1234 * \param[in] prGlueInfo Pointer to the Adapter structure
1235 * \param[in] prInBuf A pointer to the command string buffer
1236 * \param[in] u4InBufLen The length of the buffer
1241 * EX: iwpriv wlan0 set_str_cmd 0_11_[Enable/Disable]_[Set/Clear]
1243 iwpriv wlan0 set_str_cmd 0_13_1_1
1245 /*----------------------------------------------------------------------------*/
1247 TdlsCmdTestProhibitedBitSet(
1248 P_GLUE_INFO_T prGlueInfo
,
1253 extern BOOLEAN flgTdlsTestExtCapElm
;
1254 extern UINT8 aucTdlsTestExtCapElm
[];
1255 TDLS_CMD_CORE_T rCmd
;
1258 /* parse arguments */
1259 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
1260 rCmd
.Content
.rCmdProhibit
.fgIsEnable
= \
1261 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1262 rCmd
.Content
.rCmdProhibit
.fgIsSet
= \
1263 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1265 DBGLOG(TDLS
, INFO
, ("%s: fgIsEnable = %d\n",
1266 __FUNCTION__
, rCmd
.Content
.rCmdProhibit
.fgIsEnable
));
1268 /* command to do this */
1269 flgTdlsTestExtCapElm
= rCmd
.Content
.rCmdProhibit
.fgIsEnable
;
1271 aucTdlsTestExtCapElm
[0] = ELEM_ID_EXTENDED_CAP
;
1272 aucTdlsTestExtCapElm
[1] = 5;
1273 aucTdlsTestExtCapElm
[2] = 0;
1274 aucTdlsTestExtCapElm
[3] = 0;
1275 aucTdlsTestExtCapElm
[4] = 0;
1276 aucTdlsTestExtCapElm
[5] = 0;
1277 aucTdlsTestExtCapElm
[6] = (rCmd
.Content
.rCmdProhibit
.fgIsSet
<< 6); /* bit38 */
1281 /*----------------------------------------------------------------------------*/
1282 /*! \brief This routine is called to receive a PTI request from the AP.
1284 * \param[in] prGlueInfo Pointer to the Adapter structure
1285 * \param[in] prInBuf A pointer to the command string buffer
1286 * \param[in] u4InBufLen The length of the buffer
1291 * EX: iwpriv wlan0 set_str_cmd 0_1_4_[TDLS Peer MAC]_[Dialog Token]
1293 iwpriv wlan0 set_str_cmd 0_1_4_00:11:22:33:44:01_0
1295 /*----------------------------------------------------------------------------*/
1297 TdlsCmdTestPtiReqRecv(
1298 P_GLUE_INFO_T prGlueInfo
,
1303 WLAN_STATUS rStatus
;
1304 TDLS_CMD_CORE_T rCmd
;
1308 /* parse arguments */
1309 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.aucPeerMac
);
1311 rCmd
.Content
.rCmdPtiRspRcv
.u4DialogToken
= \
1312 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1314 DBGLOG(TDLS
, INFO
, ("%s: ["MACSTR
"] u4DialogToken = %u\n",
1315 __FUNCTION__
, MAC2STR(rCmd
.aucPeerMac
),
1316 (UINT32
)rCmd
.Content
.rCmdPtiRspRcv
.u4DialogToken
));
1318 /* command to do this */
1319 rStatus
= kalIoctl(prGlueInfo
,
1329 if (rStatus
!= WLAN_STATUS_SUCCESS
)
1331 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
1337 /*----------------------------------------------------------------------------*/
1338 /*! \brief This routine is called to receive a PTI response from the peer.
1340 * \param[in] prGlueInfo Pointer to the Adapter structure
1341 * \param[in] prInBuf A pointer to the command string buffer
1342 * \param[in] u4InBufLen The length of the buffer
1347 * EX: iwpriv wlan0 set_str_cmd 0_1_9_[TDLS Peer MAC]_[Dialog Token]_[PM]
1349 iwpriv wlan0 set_str_cmd 0_1_9_00:11:22:33:44:01_0_1
1351 /*----------------------------------------------------------------------------*/
1353 TdlsCmdTestPtiRspRecv(
1354 P_GLUE_INFO_T prGlueInfo
,
1359 WLAN_STATUS rStatus
;
1360 TDLS_CMD_CORE_T rCmd
;
1364 /* parse arguments */
1365 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.aucPeerMac
);
1367 rCmd
.Content
.rCmdPtiRspRcv
.u4DialogToken
= \
1368 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1369 rCmd
.Content
.rCmdPtiRspRcv
.u4PM
= \
1370 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1372 DBGLOG(TDLS
, INFO
, ("%s: ["MACSTR
"] u4DialogToken = %u %u\n",
1373 __FUNCTION__
, MAC2STR(rCmd
.aucPeerMac
),
1374 (UINT32
)rCmd
.Content
.rCmdPtiRspRcv
.u4DialogToken
,
1375 (UINT32
)rCmd
.Content
.rCmdPtiRspRcv
.u4PM
));
1377 /* command to do this */
1378 rStatus
= kalIoctl(prGlueInfo
,
1388 if (rStatus
!= WLAN_STATUS_SUCCESS
)
1390 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
1396 /*----------------------------------------------------------------------------*/
1397 /*! \brief This routine is called to inform firmware to simulate PTI tx done fail case.
1399 * \param[in] prGlueInfo Pointer to the Adapter structure
1400 * \param[in] prInBuf A pointer to the command string buffer
1401 * \param[in] u4InBufLen The length of the buffer
1406 * EX: iwpriv wlan0 set_str_cmd 0_21_[Enable/Disable]
1408 iwpriv wlan0 set_str_cmd 0_21_1
1410 /*----------------------------------------------------------------------------*/
1412 TdlsCmdTestPtiTxDoneFail(
1413 P_GLUE_INFO_T prGlueInfo
,
1418 WLAN_STATUS rStatus
;
1419 TDLS_CMD_CORE_T rCmd
;
1423 /* parse arguments */
1424 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
1425 rCmd
.Content
.rCmdPtiTxFail
.fgIsEnable
= \
1426 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1428 DBGLOG(TDLS
, INFO
, ("%s: fgIsEnable = %d\n",
1429 __FUNCTION__
, rCmd
.Content
.rCmdPtiTxFail
.fgIsEnable
));
1431 /* command to do this */
1432 rStatus
= kalIoctl(prGlueInfo
,
1442 if (rStatus
!= WLAN_STATUS_SUCCESS
)
1444 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
1450 /*----------------------------------------------------------------------------*/
1451 /*! \brief This routine is called to receive a test frame.
1453 * \param[in] prGlueInfo Pointer to the Adapter structure
1454 * \param[in] prInBuf A pointer to the command string buffer
1455 * \param[in] u4InBufLen The length of the buffer
1461 /*----------------------------------------------------------------------------*/
1464 P_GLUE_INFO_T prGlueInfo
,
1469 // PARAM_CUSTOM_TDLS_CMD_STRUC_T rCmd;
1470 // TDLS_STATUS u4Status;
1472 // UINT_32 u4BufLen;
1475 /* parse sub-command */
1476 u4Subcmd
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1477 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> test rv frame sub command = %u\n",
1480 /* parse command arguments */
1483 case TDLS_FRM_ACTION_SETUP_REQ
:
1484 /* simulate to receive a setup request frame */
1485 TdlsCmdTestSetupReqRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1488 case TDLS_FRM_ACTION_SETUP_RSP
:
1489 /* simulate to receive a setup response frame */
1490 TdlsCmdTestSetupRspRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1493 case TDLS_FRM_ACTION_CONFIRM
:
1494 /* simulate to receive a setup confirm frame */
1495 TdlsCmdTestSetupConfirmRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1498 case TDLS_FRM_ACTION_TEARDOWN
:
1499 /* simulate to receive a tear down frame */
1500 TdlsCmdTestTearDownRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1503 case TDLS_FRM_ACTION_PTI
:
1504 /* simulate to receive a PTI request frame */
1505 TdlsCmdTestPtiReqRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1508 case TDLS_FRM_ACTION_PTI_RSP
:
1509 /* simulate to receive a PTI response frame */
1510 TdlsCmdTestPtiRspRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1513 case TDLS_FRM_DATA_TEST_DATA
:
1514 /* simulate to receive a DATA frame */
1515 TdlsCmdTestDataRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1518 case TDLS_FRM_ACTION_CHAN_SWITCH_REQ
:
1519 /* simulate to receive a channel switch request frame */
1520 TdlsCmdTestChSwReqRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1523 case TDLS_FRM_ACTION_CHAN_SWITCH_RSP
:
1524 /* simulate to receive a channel switch response frame */
1525 TdlsCmdTestChSwRspRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1528 case TDLS_FRM_ACTION_DISCOVERY_REQ
:
1529 /* simulate to receive a discovery request frame */
1530 TdlsCmdTestDiscoveryReqRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
1534 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> wrong test rv frame sub command\n"));
1538 // if (u4Status != TDLS_STATUS_SUCCESS)
1540 // DBGLOG(TDLS, ERROR, ("<tdls_cmd> command parse fail\n"));
1544 /* send command to wifi task to handle */
1546 kalIoctl(prGlueInfo
,
1549 sizeof(PARAM_CUSTOM_TDLS_CMD_STRUC_T
),
1559 /*----------------------------------------------------------------------------*/
1560 /*! \brief This routine is called to receive a test setup confirm frame command.
1562 * \param[in] prGlueInfo Pointer to the Adapter structure
1563 * \param[in] prInBuf A pointer to the command string buffer
1564 * \param[in] u4InBufLen The length of the buffer
1569 * EX: iwpriv wlan0 set_str_cmd 0_1_2_[DialogToken]_[StatusCode]_[Peer MAC]
1571 iwpriv wlan0 set_str_cmd 0_1_2_1_0_00:11:22:33:44:01
1573 /*----------------------------------------------------------------------------*/
1575 TdlsCmdTestSetupConfirmRecv(
1576 GLUE_INFO_T
*prGlueInfo
,
1581 ADAPTER_T
*prAdapter
;
1582 P_BSS_INFO_T prBssInfo
;
1583 PM_PROFILE_SETUP_INFO_T
*prPmProfSetupInfo
;
1584 struct sk_buff
*prMsduInfo
;
1586 UINT_32 u4PktLen
, u4IeLen
;
1587 UINT_8 ucDialogToken
, ucStatusCode
, aucPeerMac
[6];
1590 /* parse arguments */
1591 ucDialogToken
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1592 ucStatusCode
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1593 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, aucPeerMac
);
1596 ("<tdls_fme> %s: DialogToken=%d StatusCode=%d from "MACSTR
"\n",
1597 __FUNCTION__
, ucDialogToken
, ucStatusCode
, MAC2STR(aucPeerMac
)));
1599 /* allocate/init packet */
1600 prAdapter
= prGlueInfo
->prAdapter
;
1601 prBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
1602 prPmProfSetupInfo
= &prBssInfo
->rPmProfSetupInfo
;
1605 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1600, &pPkt
);
1606 if (prMsduInfo
== NULL
) {
1607 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: allocate pkt fail\n", __FUNCTION__
));
1611 prMsduInfo
->dev
= prGlueInfo
->prDevHandler
;
1612 if (prMsduInfo
->dev
== NULL
)
1614 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: MsduInfo->dev == NULL\n", __FUNCTION__
));
1615 kalPacketFree(prGlueInfo
, prMsduInfo
);
1619 /* make up frame content */
1620 /* 1. 802.3 header */
1621 kalMemCopy(pPkt
, prAdapter
->rMyMacAddr
, TDLS_FME_MAC_ADDR_LEN
);
1622 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
1623 kalMemCopy(pPkt
, aucPeerMac
, TDLS_FME_MAC_ADDR_LEN
);
1624 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
1625 *(UINT_16
*)pPkt
= htons(TDLS_FRM_PROT_TYPE
);
1626 LR_TDLS_FME_FIELD_FILL(2);
1628 /* 2. payload type */
1629 *pPkt
= TDLS_FRM_PAYLOAD_TYPE
;
1630 LR_TDLS_FME_FIELD_FILL(1);
1632 /* 3. Frame Formation - (1) Category */
1633 *pPkt
= TDLS_FRM_CATEGORY
;
1634 LR_TDLS_FME_FIELD_FILL(1);
1636 /* 3. Frame Formation - (2) Action */
1637 *pPkt
= TDLS_FRM_ACTION_CONFIRM
;
1638 LR_TDLS_FME_FIELD_FILL(1);
1640 /* 3. Frame Formation - (3) Status Code */
1641 *pPkt
= ucStatusCode
;
1643 LR_TDLS_FME_FIELD_FILL(2);
1645 /* 3. Frame Formation - (4) Dialog token */
1646 *pPkt
= ucDialogToken
;
1647 LR_TDLS_FME_FIELD_FILL(1);
1649 /* 3. Frame Formation - (17) WMM Information element */
1650 if (prAdapter
->rWifiVar
.fgSupportQoS
)
1652 u4IeLen
= mqmGenerateWmmParamIEByParam(\
1653 prAdapter
, prBssInfo
, pPkt
);
1654 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1657 /* 3. Frame Formation - (16) Link identifier element */
1658 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucId
= ELEM_ID_LINK_IDENTIFIER
;
1659 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucLength
= ELEM_LEN_LINK_IDENTIFIER
;
1661 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aBSSID
, prBssInfo
->aucBSSID
, 6);
1662 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aInitiator
, aucPeerMac
, 6);
1663 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aResponder
, prAdapter
->rMyMacAddr
, 6);
1665 u4IeLen
= IE_SIZE(pPkt
);
1666 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1668 /* 4. Update packet length */
1669 prMsduInfo
->len
= u4PktLen
;
1670 dumpMemory8(ANDROID_LOG_INFO
, prMsduInfo
->data
, u4PktLen
);
1673 TdlsCmdTestRxIndicatePkts(prGlueInfo
, prMsduInfo
);
1677 /*----------------------------------------------------------------------------*/
1678 /*! \brief This routine is called to receive a test setup request frame command.
1680 * \param[in] prGlueInfo Pointer to the Adapter structure
1681 * \param[in] prInBuf A pointer to the command string buffer
1682 * \param[in] u4InBufLen The length of the buffer
1687 * EX: iwpriv wlan0 set_str_cmd 0_1_0_[DialogToken]_[Peer MAC]_[BSSID]
1689 iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01
1690 iwpriv wlan0 set_str_cmd 0_1_0_1_00:11:22:33:44:01_00:22:33:44:11:22
1692 /*----------------------------------------------------------------------------*/
1694 TdlsCmdTestSetupReqRecv(
1695 GLUE_INFO_T
*prGlueInfo
,
1700 ADAPTER_T
*prAdapter
;
1701 P_BSS_INFO_T prBssInfo
;
1702 struct sk_buff
*prMsduInfo
;
1704 UINT_32 u4PktLen
, u4IeLen
;
1705 UINT_8 ucDialogToken
, aucPeerMac
[6], aucBSSID
[6], aucZeroMac
[6];
1709 /* parse arguments */
1710 ucDialogToken
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1711 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, aucPeerMac
);
1713 kalMemZero(aucZeroMac
, sizeof(aucZeroMac
));
1714 kalMemZero(aucBSSID
, sizeof(aucBSSID
));
1715 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, aucBSSID
);
1718 ("<tdls_fme> %s: DialogToken=%d from "MACSTR
"\n",
1719 __FUNCTION__
, ucDialogToken
, MAC2STR(aucPeerMac
)));
1721 /* allocate/init packet */
1722 prAdapter
= prGlueInfo
->prAdapter
;
1723 prBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
1726 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1600, &pPkt
);
1727 if (prMsduInfo
== NULL
) {
1728 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: allocate pkt fail\n", __FUNCTION__
));
1732 prMsduInfo
->dev
= prGlueInfo
->prDevHandler
;
1733 if (prMsduInfo
->dev
== NULL
)
1735 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: MsduInfo->dev == NULL\n", __FUNCTION__
));
1736 kalPacketFree(prGlueInfo
, prMsduInfo
);
1740 /* make up frame content */
1741 /* 1. 802.3 header */
1742 kalMemCopy(pPkt
, prAdapter
->rMyMacAddr
, TDLS_FME_MAC_ADDR_LEN
);
1743 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
1744 kalMemCopy(pPkt
, aucPeerMac
, TDLS_FME_MAC_ADDR_LEN
);
1745 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
1746 *(UINT_16
*)pPkt
= htons(TDLS_FRM_PROT_TYPE
);
1747 LR_TDLS_FME_FIELD_FILL(2);
1749 /* 2. payload type */
1750 *pPkt
= TDLS_FRM_PAYLOAD_TYPE
;
1751 LR_TDLS_FME_FIELD_FILL(1);
1753 /* 3. Frame Formation - (1) Category */
1754 *pPkt
= TDLS_FRM_CATEGORY
;
1755 LR_TDLS_FME_FIELD_FILL(1);
1757 /* 3. Frame Formation - (2) Action */
1758 *pPkt
= TDLS_FRM_ACTION_SETUP_REQ
;
1759 LR_TDLS_FME_FIELD_FILL(1);
1761 /* 3. Frame Formation - (3) Dialog token */
1762 *pPkt
= ucDialogToken
;
1763 LR_TDLS_FME_FIELD_FILL(1);
1765 /* 3. Frame Formation - (4) Capability */
1766 u2CapInfo
= assocBuildCapabilityInfo(prAdapter
, NULL
);
1767 WLAN_SET_FIELD_16(pPkt
, u2CapInfo
);
1768 LR_TDLS_FME_FIELD_FILL(2);
1770 /* 4. Append general IEs */
1771 u4IeLen
= TdlsFrameGeneralIeAppend(prAdapter
, NULL
, 0, pPkt
);
1772 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1774 /* 3. Frame Formation - (10) Extended capabilities element */
1775 EXT_CAP_IE(pPkt
)->ucId
= ELEM_ID_EXTENDED_CAP
;
1776 EXT_CAP_IE(pPkt
)->ucLength
= 5;
1778 EXT_CAP_IE(pPkt
)->aucCapabilities
[0] = 0x00; /* bit0 ~ bit7 */
1779 EXT_CAP_IE(pPkt
)->aucCapabilities
[1] = 0x00; /* bit8 ~ bit15 */
1780 EXT_CAP_IE(pPkt
)->aucCapabilities
[2] = 0x00; /* bit16 ~ bit23 */
1781 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] = 0x00; /* bit24 ~ bit31 */
1782 EXT_CAP_IE(pPkt
)->aucCapabilities
[4] = 0x00; /* bit32 ~ bit39 */
1784 /* TDLS_EX_CAP_PEER_UAPSD */
1785 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] |= BIT((28-24));
1786 /* TDLS_EX_CAP_CHAN_SWITCH */
1787 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] |= BIT((30-24));
1788 /* TDLS_EX_CAP_TDLS */
1789 EXT_CAP_IE(pPkt
)->aucCapabilities
[4] |= BIT((37-32));
1791 u4IeLen
= IE_SIZE(pPkt
);
1792 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1794 /* 3. Frame Formation - (16) Link identifier element */
1795 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucId
= ELEM_ID_LINK_IDENTIFIER
;
1796 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucLength
= 18;
1798 if (kalMemCmp(aucBSSID
, aucZeroMac
, 6) == 0)
1799 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aBSSID
, prBssInfo
->aucBSSID
, 6);
1801 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aBSSID
, aucBSSID
, 6);
1803 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aInitiator
, aucPeerMac
, 6);
1804 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aResponder
, prAdapter
->rMyMacAddr
, 6);
1806 u4IeLen
= IE_SIZE(pPkt
);
1807 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1809 /* 4. Update packet length */
1810 prMsduInfo
->len
= u4PktLen
;
1811 dumpMemory8(ANDROID_LOG_INFO
, prMsduInfo
->data
, u4PktLen
);
1814 TdlsCmdTestRxIndicatePkts(prGlueInfo
, prMsduInfo
);
1818 /*----------------------------------------------------------------------------*/
1819 /*! \brief This routine is called to receive a test setup response frame command.
1821 * \param[in] prGlueInfo Pointer to the Adapter structure
1822 * \param[in] prInBuf A pointer to the command string buffer
1823 * \param[in] u4InBufLen The length of the buffer
1828 * EX: iwpriv wlan0 set_str_cmd 0_1_1_[DialogToken]_[StatusCode]_[Peer MAC]
1830 iwpriv wlan0 set_str_cmd 0_1_1_1_0_00:11:22:33:44:01
1832 /*----------------------------------------------------------------------------*/
1834 TdlsCmdTestSetupRspRecv(
1835 GLUE_INFO_T
*prGlueInfo
,
1840 ADAPTER_T
*prAdapter
;
1841 P_BSS_INFO_T prBssInfo
;
1842 struct sk_buff
*prMsduInfo
;
1844 UINT_32 u4PktLen
, u4IeLen
;
1845 UINT_8 ucDialogToken
, ucStatusCode
, aucPeerMac
[6];
1849 /* parse arguments */
1850 ucDialogToken
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1851 ucStatusCode
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1852 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, aucPeerMac
);
1855 ("<tdls_fme> %s: DialogToken=%d StatusCode=%d from "MACSTR
"\n",
1856 __FUNCTION__
, ucDialogToken
, ucStatusCode
, MAC2STR(aucPeerMac
)));
1858 /* allocate/init packet */
1859 prAdapter
= prGlueInfo
->prAdapter
;
1860 prBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
1863 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1600, &pPkt
);
1864 if (prMsduInfo
== NULL
) {
1865 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: allocate pkt fail\n", __FUNCTION__
));
1869 prMsduInfo
->dev
= prGlueInfo
->prDevHandler
;
1870 if (prMsduInfo
->dev
== NULL
)
1872 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: MsduInfo->dev == NULL\n", __FUNCTION__
));
1873 kalPacketFree(prGlueInfo
, prMsduInfo
);
1877 /* make up frame content */
1878 /* 1. 802.3 header */
1879 kalMemCopy(pPkt
, prAdapter
->rMyMacAddr
, TDLS_FME_MAC_ADDR_LEN
);
1880 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
1881 kalMemCopy(pPkt
, aucPeerMac
, TDLS_FME_MAC_ADDR_LEN
);
1882 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
1883 *(UINT_16
*)pPkt
= htons(TDLS_FRM_PROT_TYPE
);
1884 LR_TDLS_FME_FIELD_FILL(2);
1886 /* 2. payload type */
1887 *pPkt
= TDLS_FRM_PAYLOAD_TYPE
;
1888 LR_TDLS_FME_FIELD_FILL(1);
1890 /* 3. Frame Formation - (1) Category */
1891 *pPkt
= TDLS_FRM_CATEGORY
;
1892 LR_TDLS_FME_FIELD_FILL(1);
1894 /* 3. Frame Formation - (2) Action */
1895 *pPkt
= TDLS_FRM_ACTION_SETUP_RSP
;
1896 LR_TDLS_FME_FIELD_FILL(1);
1898 /* 3. Frame Formation - (3) Status Code */
1899 *pPkt
= ucStatusCode
;
1901 LR_TDLS_FME_FIELD_FILL(2);
1903 /* 3. Frame Formation - (4) Dialog token */
1904 *pPkt
= ucDialogToken
;
1905 LR_TDLS_FME_FIELD_FILL(1);
1907 /* 3. Frame Formation - (5) Capability */
1908 u2CapInfo
= assocBuildCapabilityInfo(prAdapter
, NULL
);
1909 WLAN_SET_FIELD_16(pPkt
, u2CapInfo
);
1910 LR_TDLS_FME_FIELD_FILL(2);
1912 /* 4. Append general IEs */
1913 u4IeLen
= TdlsFrameGeneralIeAppend(prAdapter
, NULL
, 0, pPkt
);
1914 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1916 /* 3. Frame Formation - (10) Extended capabilities element */
1917 EXT_CAP_IE(pPkt
)->ucId
= ELEM_ID_EXTENDED_CAP
;
1918 EXT_CAP_IE(pPkt
)->ucLength
= 5;
1920 EXT_CAP_IE(pPkt
)->aucCapabilities
[0] = 0x00; /* bit0 ~ bit7 */
1921 EXT_CAP_IE(pPkt
)->aucCapabilities
[1] = 0x00; /* bit8 ~ bit15 */
1922 EXT_CAP_IE(pPkt
)->aucCapabilities
[2] = 0x00; /* bit16 ~ bit23 */
1923 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] = 0x00; /* bit24 ~ bit31 */
1924 EXT_CAP_IE(pPkt
)->aucCapabilities
[4] = 0x00; /* bit32 ~ bit39 */
1926 /* TDLS_EX_CAP_PEER_UAPSD */
1927 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] |= BIT((28-24));
1928 /* TDLS_EX_CAP_CHAN_SWITCH */
1929 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] |= BIT((30-24));
1930 /* TDLS_EX_CAP_TDLS */
1931 EXT_CAP_IE(pPkt
)->aucCapabilities
[4] |= BIT((37-32));
1933 u4IeLen
= IE_SIZE(pPkt
);
1934 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1936 /* 3. Frame Formation - (16) Link identifier element */
1937 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucId
= ELEM_ID_LINK_IDENTIFIER
;
1938 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucLength
= ELEM_LEN_LINK_IDENTIFIER
;
1940 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aBSSID
, prBssInfo
->aucBSSID
, 6);
1941 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aInitiator
, prAdapter
->rMyMacAddr
, 6);
1942 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aResponder
, aucPeerMac
, 6);
1944 u4IeLen
= IE_SIZE(pPkt
);
1945 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
1947 /* 4. Update packet length */
1948 prMsduInfo
->len
= u4PktLen
;
1949 dumpMemory8(ANDROID_LOG_INFO
, prMsduInfo
->data
, u4PktLen
);
1952 TdlsCmdTestRxIndicatePkts(prGlueInfo
, prMsduInfo
);
1956 /*----------------------------------------------------------------------------*/
1957 /*! \brief This routine is called to inform firmware to skip channel switch timeout function.
1959 * \param[in] prGlueInfo Pointer to the Adapter structure
1960 * \param[in] prInBuf A pointer to the command string buffer
1961 * \param[in] u4InBufLen The length of the buffer
1966 * EX: iwpriv wlan0 set_str_cmd 0_14_[Enable/Disable]
1968 iwpriv wlan0 set_str_cmd 0_14_0
1970 /*----------------------------------------------------------------------------*/
1972 TdlsCmdTestScanCtrl(
1973 P_GLUE_INFO_T prGlueInfo
,
1978 WLAN_STATUS rStatus
;
1979 TDLS_CMD_CORE_T rCmd
;
1983 /* parse arguments */
1984 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
1985 rCmd
.Content
.rCmdScanSkip
.fgIsEnable
= \
1986 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
1988 DBGLOG(TDLS
, INFO
, ("%s: fgIsEnable = %d\n",
1989 __FUNCTION__
, rCmd
.Content
.rCmdScanSkip
.fgIsEnable
));
1991 /* command to do this */
1992 rStatus
= kalIoctl(prGlueInfo
,
2002 if (rStatus
!= WLAN_STATUS_SUCCESS
)
2004 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
2010 /*----------------------------------------------------------------------------*/
2011 /*! \brief This routine is called to receive a test tear down frame command.
2013 * \param[in] prGlueInfo Pointer to the Adapter structure
2014 * \param[in] prInBuf A pointer to the command string buffer
2015 * \param[in] u4InBufLen The length of the buffer
2020 * EX: iwpriv wlan0 set_str_cmd 0_1_3_[IsInitiator]_[ReasonCode]_[Peer MAC]_[Where]
2022 Where 0 (From driver) or 1 (From FW)
2024 iwpriv wlan0 set_str_cmd 0_1_3_1_26_00:11:22:33:44:01_0
2026 /*----------------------------------------------------------------------------*/
2028 TdlsCmdTestTearDownRecv(
2029 GLUE_INFO_T
*prGlueInfo
,
2034 ADAPTER_T
*prAdapter
;
2035 P_BSS_INFO_T prBssInfo
;
2036 struct sk_buff
*prMsduInfo
;
2038 UINT_32 u4PktLen
, u4IeLen
;
2039 BOOLEAN fgIsInitiator
;
2040 UINT_8 ucReasonCode
, aucPeerMac
[6];
2041 BOOLEAN fgIsFromWhich
;
2042 WLAN_STATUS rStatus
;
2043 TDLS_CMD_CORE_T rCmd
;
2047 /* parse arguments */
2048 fgIsInitiator
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
2049 ucReasonCode
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
2050 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, aucPeerMac
);
2051 fgIsFromWhich
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
2054 ("<tdls_fme> %s: ReasonCode=%d from "MACSTR
" %d\n",
2055 __FUNCTION__
, ucReasonCode
, MAC2STR(aucPeerMac
), fgIsFromWhich
));
2057 if (fgIsFromWhich
== 0)
2059 /* allocate/init packet */
2060 prAdapter
= prGlueInfo
->prAdapter
;
2061 prBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
2064 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1600, &pPkt
);
2065 if (prMsduInfo
== NULL
) {
2066 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: allocate pkt fail\n", __FUNCTION__
));
2070 prMsduInfo
->dev
= prGlueInfo
->prDevHandler
;
2071 if (prMsduInfo
->dev
== NULL
)
2073 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: MsduInfo->dev == NULL\n", __FUNCTION__
));
2074 kalPacketFree(prGlueInfo
, prMsduInfo
);
2078 /* make up frame content */
2079 /* 1. 802.3 header */
2080 kalMemCopy(pPkt
, prAdapter
->rMyMacAddr
, TDLS_FME_MAC_ADDR_LEN
);
2081 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
2082 kalMemCopy(pPkt
, aucPeerMac
, TDLS_FME_MAC_ADDR_LEN
);
2083 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
2084 *(UINT_16
*)pPkt
= htons(TDLS_FRM_PROT_TYPE
);
2085 LR_TDLS_FME_FIELD_FILL(2);
2087 /* 2. payload type */
2088 *pPkt
= TDLS_FRM_PAYLOAD_TYPE
;
2089 LR_TDLS_FME_FIELD_FILL(1);
2091 /* 3. Frame Formation - (1) Category */
2092 *pPkt
= TDLS_FRM_CATEGORY
;
2093 LR_TDLS_FME_FIELD_FILL(1);
2095 /* 3. Frame Formation - (2) Action */
2096 *pPkt
= TDLS_FRM_ACTION_TEARDOWN
;
2097 LR_TDLS_FME_FIELD_FILL(1);
2099 /* 3. Frame Formation - (3) Reason Code */
2100 *pPkt
= ucReasonCode
;
2102 LR_TDLS_FME_FIELD_FILL(2);
2104 /* 3. Frame Formation - (16) Link identifier element */
2105 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucId
= ELEM_ID_LINK_IDENTIFIER
;
2106 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucLength
= ELEM_LEN_LINK_IDENTIFIER
;
2108 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aBSSID
, prBssInfo
->aucBSSID
, 6);
2109 if (fgIsInitiator
== 1)
2111 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aInitiator
, aucPeerMac
, 6);
2112 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aResponder
, prAdapter
->rMyMacAddr
, 6);
2116 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aInitiator
, prAdapter
->rMyMacAddr
, 6);
2117 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aResponder
, aucPeerMac
, 6);
2120 u4IeLen
= IE_SIZE(pPkt
);
2121 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
2123 /* 4. Update packet length */
2124 prMsduInfo
->len
= u4PktLen
;
2125 dumpMemory8(ANDROID_LOG_INFO
, prMsduInfo
->data
, u4PktLen
);
2128 TdlsCmdTestRxIndicatePkts(prGlueInfo
, prMsduInfo
);
2132 kalMemZero(&rCmd
, sizeof(rCmd
));
2133 kalMemCopy(rCmd
.aucPeerMac
, aucPeerMac
, 6);
2134 rCmd
.Content
.rCmdTearDownRcv
.u4ReasonCode
= (UINT32
)ucReasonCode
;
2136 /* command to do this */
2137 rStatus
= kalIoctl(prGlueInfo
,
2138 TdlsTestTearDownRecv
,
2147 if (rStatus
!= WLAN_STATUS_SUCCESS
)
2149 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
2156 /*----------------------------------------------------------------------------*/
2157 /*! \brief This routine is called to inform firmware to skip tx fail case.
2159 * \param[in] prGlueInfo Pointer to the Adapter structure
2160 * \param[in] prInBuf A pointer to the command string buffer
2161 * \param[in] u4InBufLen The length of the buffer
2166 * EX: iwpriv wlan0 set_str_cmd 0_7_[Enable/Disable]
2168 iwpriv wlan0 set_str_cmd 0_7_1
2170 /*----------------------------------------------------------------------------*/
2172 TdlsCmdTestTxFailSkip(
2173 P_GLUE_INFO_T prGlueInfo
,
2178 WLAN_STATUS rStatus
;
2179 TDLS_CMD_CORE_T rCmd
;
2183 /* parse arguments */
2184 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
2185 rCmd
.Content
.rCmdTxFailSkip
.fgIsEnable
= \
2186 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
2188 DBGLOG(TDLS
, INFO
, ("%s: fgIsEnable = %d\n",
2189 __FUNCTION__
, rCmd
.Content
.rCmdTxFailSkip
.fgIsEnable
));
2191 /* command to do this */
2192 rStatus
= kalIoctl(prGlueInfo
,
2202 if (rStatus
!= WLAN_STATUS_SUCCESS
)
2204 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
2210 /*----------------------------------------------------------------------------*/
2211 /*! \brief This routine is called to send a test frame command to wifi task.
2213 * \param[in] prGlueInfo Pointer to the Adapter structure
2214 * \param[in] prInBuf A pointer to the command string buffer
2215 * \param[in] u4InBufLen The length of the buffer
2220 * EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC]
2222 iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01
2224 * EX: iwpriv wlan0 set_str_cmd 0_12_2_[FrameType]_[DialogToken]_[Peer MAC]
2226 iwpriv wlan0 set_str_cmd 0_12_2_0_1_00:11:22:33:44:01
2228 /*----------------------------------------------------------------------------*/
2230 TdlsCmdTestTxTdlsFrame(
2231 P_GLUE_INFO_T prGlueInfo
,
2236 PARAM_CUSTOM_TDLS_CMD_STRUC_T rCmd
;
2241 /* parse sub-command */
2242 u4Subcmd
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
2243 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> test tx tdls frame sub command = %u\n",
2246 /* parse command arguments */
2247 rCmd
.ucFmeType
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4BufLen
);
2251 case TDLS_FRM_ACTION_SETUP_REQ
:
2252 case TDLS_FRM_ACTION_SETUP_RSP
:
2253 case TDLS_FRM_ACTION_CONFIRM
:
2254 rCmd
.ucToken
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4BufLen
);
2255 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.arRspAddr
);
2257 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> setup FmeType=%d Token=%d to "
2259 rCmd
.ucFmeType
, rCmd
.ucToken
,
2260 MAC2STR(rCmd
.arRspAddr
)));
2264 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> wrong test tx frame sub command\n"));
2268 /* send command to wifi task to handle */
2269 kalIoctl(prGlueInfo
,
2270 TdlsTestTdlsFrameSend
,
2272 sizeof(PARAM_CUSTOM_TDLS_CMD_STRUC_T
),
2281 /*----------------------------------------------------------------------------*/
2282 /*! \brief This routine is called to send a test frame command to wifi task.
2284 * \param[in] prGlueInfo Pointer to the Adapter structure
2285 * \param[in] prInBuf A pointer to the command string buffer
2286 * \param[in] u4InBufLen The length of the buffer
2291 * EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_
2292 [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_
2293 [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_
2294 [Timeout]_[Peer MAC]
2296 iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01
2298 /*----------------------------------------------------------------------------*/
2301 P_GLUE_INFO_T prGlueInfo
,
2306 PARAM_CUSTOM_TDLS_CMD_STRUC_T rCmd
;
2307 TDLS_STATUS u4Status
;
2312 /* parse sub-command */
2313 u4Subcmd
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
2314 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> test tx frame sub command = %u\n",
2317 /* parse command arguments */
2320 case TDLS_FRM_ACTION_SETUP_REQ
:
2321 u4Status
= TdlsCmdTestTxFmeSetupReqBufTranslate(
2322 prInBuf
, u4InBufLen
, &rCmd
);
2326 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> wrong test tx frame sub command\n"));
2330 if (u4Status
!= TDLS_STATUS_SUCCESS
)
2332 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> command parse fail\n"));
2336 /* send command to wifi task to handle */
2337 kalIoctl(prGlueInfo
,
2340 sizeof(PARAM_CUSTOM_TDLS_CMD_STRUC_T
),
2349 /*----------------------------------------------------------------------------*/
2351 * @brief Parse the TDLS test frame command, setup request
2353 * @param CmdBuf Pointer to the buffer.
2354 * @param BufLen Record buffer length.
2355 * @param CmdTspec Pointer to the structure.
2357 * @retval WLAN_STATUS_SUCCESS: Translate OK.
2358 * @retval WLAN_STATUS_FAILURE: Translate fail.
2359 * @usage iwpriv wlan0 set_str_cmd [tdls]_[command]
2361 * EX: iwpriv wlan0 set_str_cmd 0_0_0_[FrameType]_[DialogToken]_[Cap]_[ExCap]_
2362 [SupRate0]_[SupRate1]_[SupRate2]_[SupRate3]_
2363 [SupChan0]_[SupChan1]_[SupChan2]_[SupChan3]_
2364 [Timeout]_[Peer MAC]
2366 iwpriv wlan0 set_str_cmd 0_0_0_0_1_1_7_0_0_0_0_0_0_0_0_300_00:11:22:33:44:01
2368 /*----------------------------------------------------------------------------*/
2370 TdlsCmdTestTxFmeSetupReqBufTranslate(
2373 PARAM_CUSTOM_TDLS_CMD_STRUC_T
*prCmd
2376 // dumpMemory8(ANDROID_LOG_INFO, pCmdBuf, u4BufLen);
2378 prCmd
->ucFmeType
= CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2379 prCmd
->ucToken
= CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2380 prCmd
->u2Cap
= CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2381 prCmd
->ucExCap
= CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2382 prCmd
->arSupRate
[0] = CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2383 prCmd
->arSupRate
[1] = CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2384 prCmd
->arSupRate
[2] = CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2385 prCmd
->arSupRate
[3] = CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2386 prCmd
->arSupChan
[0] = CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2387 prCmd
->arSupChan
[1] = CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2388 prCmd
->arSupChan
[2] = CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2389 prCmd
->arSupChan
[3] = CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2390 prCmd
->u4Timeout
= CmdStringDecParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
);
2391 CmdStringMacParse(pCmdBuf
, &pCmdBuf
, &u4BufLen
, prCmd
->arRspAddr
);
2393 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> command content =\n"));
2394 DBGLOG(TDLS
, INFO
, ("\tPeer MAC = "MACSTR
"\n", MAC2STR(prCmd
->arRspAddr
)));
2395 DBGLOG(TDLS
, INFO
, ("\tToken = %u, Cap = 0x%x, ExCap = 0x%x, Timeout = %us "
2397 (UINT32
)prCmd
->ucToken
, prCmd
->u2Cap
, prCmd
->ucExCap
,
2398 (UINT32
)prCmd
->u4Timeout
, (UINT32
)prCmd
->ucFmeType
));
2399 DBGLOG(TDLS
, INFO
, ("\tSupRate = 0x%x %x %x %x\n",
2400 prCmd
->arSupRate
[0], prCmd
->arSupRate
[1],
2401 prCmd
->arSupRate
[2], prCmd
->arSupRate
[3]));
2402 DBGLOG(TDLS
, INFO
, ("\tSupChan = %d %d %d %d\n",
2403 prCmd
->arSupChan
[0], prCmd
->arSupChan
[1],
2404 prCmd
->arSupChan
[2], prCmd
->arSupChan
[3]));
2406 return TDLS_STATUS_SUCCESS
;
2410 /*----------------------------------------------------------------------------*/
2411 /*! \brief This routine is called to update a TDLS peer.
2413 * \param[in] prGlueInfo Pointer to the Adapter structure
2414 * \param[in] prInBuf A pointer to the command string buffer
2415 * \param[in] u4InBufLen The length of the buffer
2420 * EX: iwpriv wlan0 set_str_cmd 0_3_[Responder MAC]
2422 iwpriv wlan0 set_str_cmd 0_3_00:11:22:33:44:01
2424 /*----------------------------------------------------------------------------*/
2426 TdlsCmdTestUpdatePeer(
2427 P_GLUE_INFO_T prGlueInfo
,
2432 PARAM_CUSTOM_TDLS_CMD_STRUC_T rCmd
;
2433 struct wireless_dev
*prWdev
;
2437 kalMemZero(&rCmd
, sizeof(rCmd
));
2439 /* parse arguments */
2440 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.arRspAddr
);
2443 rCmd
.rPeerInfo
.supported_rates
= rCmd
.arSupRate
;
2444 rCmd
.rPeerInfo
.ht_capa
= &rCmd
.rHtCapa
;
2445 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
2446 rCmd
.rPeerInfo
.vht_capa
= &rCmd
.rVhtCapa
;
2448 rCmd
.rPeerInfo
.sta_flags_set
= BIT(NL80211_STA_FLAG_TDLS_PEER
);
2449 rCmd
.rPeerInfo
.uapsd_queues
= 0xf; /* all AC */
2450 rCmd
.rPeerInfo
.max_sp
= 0; /* delivery all packets */
2452 /* send command to wifi task to handle */
2453 prWdev
= prGlueInfo
->prDevHandler
->ieee80211_ptr
;
2454 mtk_cfg80211_add_station(\
2455 prWdev
->wiphy
, (void *)0x1, rCmd
.arRspAddr
, &rCmd
.rPeerInfo
);
2458 TdlsexCfg80211TdlsOper(\
2459 prWdev
->wiphy
, (void *)0x1, rCmd
.arRspAddr
, NL80211_TDLS_ENABLE_LINK
);
2463 /*----------------------------------------------------------------------------*/
2464 /*! \brief This routine is called to receive a Null frame from the peer.
2466 * \param[in] prAdapter Pointer to the Adapter structure
2467 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
2468 * \param[in] u4SetBufferLen The length of the set buffer
2469 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2470 * bytes read from the set buffer. If the call failed due to invalid length of
2471 * the set buffer, returns the amount of storage needed.
2473 * \retval TDLS_STATUS_xx
2475 * EX: iwpriv wlan0 set_str_cmd 0_5_[Responder MAC]_[PM bit]
2477 iwpriv wlan0 set_str_cmd 0_5_00:11:22:33:44:01_1
2479 /*----------------------------------------------------------------------------*/
2481 TdlsCmdTestNullRecv(
2482 P_GLUE_INFO_T prGlueInfo
,
2487 WLAN_STATUS rStatus
;
2488 TDLS_CMD_CORE_T rCmd
;
2492 /* parse arguments */
2493 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.aucPeerMac
);
2494 rCmd
.Content
.rCmdNullRcv
.u4PM
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
2496 DBGLOG(TDLS
, INFO
, ("%s: ["MACSTR
"] u4PM = %u\n",
2497 __FUNCTION__
, MAC2STR(rCmd
.aucPeerMac
),
2498 (UINT32
)rCmd
.Content
.rCmdNullRcv
.u4PM
));
2500 /* command to do this */
2501 rStatus
= kalIoctl(prGlueInfo
,
2511 if (rStatus
!= WLAN_STATUS_SUCCESS
)
2513 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
2519 /*----------------------------------------------------------------------------*/
2520 /*! \brief This routine is called to send a data frame to the peer periodically.
2522 * \param[in] prAdapter Pointer to the Adapter structure
2523 * \param[in] u4Param no use
2528 * EX: iwpriv wlan0 set_str_cmd 0_15_[Responder MAC]_[Interval: ms]_[Enable/Disable]
2530 iwpriv wlan0 set_str_cmd 0_15_00:11:22:33:44:01_5000_1
2532 /*----------------------------------------------------------------------------*/
2534 TdlsTimerTestDataContSend(
2535 ADAPTER_T
*prAdapter
,
2539 GLUE_INFO_T
*prGlueInfo
;
2540 struct sk_buff
*prMsduInfo
;
2545 prGlueInfo
= prAdapter
->prGlueInfo
;
2547 /* allocate a data frame */
2548 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1000, &prPkt
);
2549 if (prMsduInfo
== NULL
)
2551 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s allocate pkt fail!\n",
2557 prMsduInfo
->dev
= prGlueInfo
->prDevHandler
;
2558 if (prMsduInfo
->dev
== NULL
)
2560 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s prMsduInfo->dev == NULL!\n",
2562 kalPacketFree(prGlueInfo
, prMsduInfo
);
2567 prMsduInfo
->len
= 1000;
2568 kalMemCopy(prMsduInfo
->data
, aucTdlsTestDataSPeerMac
, 6);
2569 kalMemCopy(prMsduInfo
->data
+6, prAdapter
->rMyMacAddr
, 6);
2570 *(UINT_16
*)(prMsduInfo
->data
+12) = 0x0800;
2572 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s try to send a data frame to "MACSTR
"\n",
2573 __FUNCTION__
, MAC2STR(aucTdlsTestDataSPeerMac
)));
2575 /* simulate OS to send the packet */
2576 wlanHardStartXmit(prMsduInfo
, prMsduInfo
->dev
);
2578 /* restart test timer */
2579 cnmTimerStartTimer(prAdapter
,
2580 &rTdlsTimerTestDataSend
,
2581 u2TdlsTestDataSInterval
);
2585 /*----------------------------------------------------------------------------*/
2586 /*! \brief This routine is called to receive a Channel Switch Request frame.
2588 * \param[in] prAdapter Pointer to the Adapter structure
2589 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
2590 * \param[in] u4SetBufferLen The length of the set buffer
2591 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2592 * bytes read from the set buffer. If the call failed due to invalid length of
2593 * the set buffer, returns the amount of storage needed.
2595 * \retval TDLS_STATUS_xx
2598 /*----------------------------------------------------------------------------*/
2600 TdlsTestChStReqRecv(
2601 ADAPTER_T
*prAdapter
,
2603 UINT_32 u4SetBufferLen
,
2604 UINT_32
*pu4SetInfoLen
2607 TDLS_CMD_CORE_T
*prCmdContent
;
2608 WLAN_STATUS rStatus
;
2611 /* init command buffer */
2612 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
2613 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_CHSW_REQ
;
2615 /* send the command */
2616 rStatus
= wlanSendSetQueryCmd (
2617 prAdapter
, /* prAdapter */
2618 CMD_ID_TDLS_CORE
, /* ucCID */
2619 TRUE
, /* fgSetQuery */
2620 FALSE
, /* fgNeedResp */
2621 FALSE
, /* fgIsOid */
2623 NULL
, /* pfCmdTimeoutHandler */
2624 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
2625 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
2626 NULL
, /* pvSetQueryBuffer */
2627 0 /* u4SetQueryBufferLen */
2630 if (rStatus
!= WLAN_STATUS_PENDING
)
2632 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
2634 return TDLS_STATUS_RESOURCES
;
2637 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
2638 return TDLS_STATUS_SUCCESS
;
2642 /*----------------------------------------------------------------------------*/
2643 /*! \brief This routine is called to receive a Channel Switch Response frame.
2645 * \param[in] prAdapter Pointer to the Adapter structure
2646 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
2647 * \param[in] u4SetBufferLen The length of the set buffer
2648 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2649 * bytes read from the set buffer. If the call failed due to invalid length of
2650 * the set buffer, returns the amount of storage needed.
2652 * \retval TDLS_STATUS_xx
2655 /*----------------------------------------------------------------------------*/
2657 TdlsTestChStRspRecv(
2658 ADAPTER_T
*prAdapter
,
2660 UINT_32 u4SetBufferLen
,
2661 UINT_32
*pu4SetInfoLen
2664 TDLS_CMD_CORE_T
*prCmdContent
;
2665 WLAN_STATUS rStatus
;
2668 /* init command buffer */
2669 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
2670 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_CHSW_RSP
;
2672 /* send the command */
2673 rStatus
= wlanSendSetQueryCmd (
2674 prAdapter
, /* prAdapter */
2675 CMD_ID_TDLS_CORE
, /* ucCID */
2676 TRUE
, /* fgSetQuery */
2677 FALSE
, /* fgNeedResp */
2678 FALSE
, /* fgIsOid */
2680 NULL
, /* pfCmdTimeoutHandler */
2681 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
2682 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
2683 NULL
, /* pvSetQueryBuffer */
2684 0 /* u4SetQueryBufferLen */
2687 if (rStatus
!= WLAN_STATUS_PENDING
)
2689 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
2691 return TDLS_STATUS_RESOURCES
;
2694 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
2695 return TDLS_STATUS_SUCCESS
;
2699 /*----------------------------------------------------------------------------*/
2701 * \brief This routine is called to send a test frame.
2703 * \param[in] prAdapter Pointer to the Adapter structure
2704 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
2705 * \param[in] u4SetBufferLen The length of the set buffer
2706 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2707 * bytes read from the set buffer. If the call failed due to invalid length of
2708 * the set buffer, returns the amount of storage needed.
2710 * \retval TDLS_STATUS_xx
2713 /*----------------------------------------------------------------------------*/
2716 ADAPTER_T
*prAdapter
,
2718 UINT_32 u4SetBufferLen
,
2719 UINT_32
*pu4SetInfoLen
2722 GLUE_INFO_T
*prGlueInfo
;
2723 PARAM_CUSTOM_TDLS_CMD_STRUC_T
*prCmd
;
2724 P_BSS_INFO_T prBssInfo
;
2725 struct sk_buff
*prMsduInfo
;
2727 UINT_32 u4PktLen
, u4IeLen
;
2732 ASSERT(pvSetBuffer
);
2733 ASSERT(pu4SetInfoLen
);
2735 DBGLOG(TDLS
, INFO
, ("<tdls_fme> %s\n", __FUNCTION__
));
2737 if(u4SetBufferLen
== 0)
2738 return TDLS_STATUS_INVALID_LENGTH
;
2740 /* allocate/init packet */
2741 prGlueInfo
= (GLUE_INFO_T
*)prAdapter
->prGlueInfo
;
2742 prCmd
= (PARAM_CUSTOM_TDLS_CMD_STRUC_T
*)pvSetBuffer
;
2743 prBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
2744 *pu4SetInfoLen
= u4SetBufferLen
;
2747 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1600, &pPkt
);
2748 if (prMsduInfo
== NULL
) {
2749 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: allocate pkt fail\n", __FUNCTION__
));
2750 return TDLS_STATUS_RESOURCES
;
2753 prMsduInfo
->dev
= prGlueInfo
->prDevHandler
;
2754 if (prMsduInfo
->dev
== NULL
)
2756 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: MsduInfo->dev == NULL\n", __FUNCTION__
));
2757 kalPacketFree(prGlueInfo
, prMsduInfo
);
2758 return TDLS_STATUS_FAILURE
;
2761 /* make up frame content */
2762 /* 1. 802.3 header */
2763 kalMemCopy(pPkt
, prCmd
->arRspAddr
, TDLS_FME_MAC_ADDR_LEN
);
2764 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
2765 kalMemCopy(pPkt
, prAdapter
->rMyMacAddr
, TDLS_FME_MAC_ADDR_LEN
);
2766 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
2767 *(UINT_16
*)pPkt
= htons(TDLS_FRM_PROT_TYPE
);
2768 LR_TDLS_FME_FIELD_FILL(2);
2770 /* 2. payload type */
2771 *pPkt
= TDLS_FRM_PAYLOAD_TYPE
;
2772 LR_TDLS_FME_FIELD_FILL(1);
2774 /* 3. Frame Formation - (1) Category */
2775 *pPkt
= TDLS_FRM_CATEGORY
;
2776 LR_TDLS_FME_FIELD_FILL(1);
2778 /* 3. Frame Formation - (2) Action */
2779 *pPkt
= prCmd
->ucFmeType
;
2780 LR_TDLS_FME_FIELD_FILL(1);
2782 /* 3. Frame Formation - (3) Dialog token */
2783 *pPkt
= prCmd
->ucToken
;
2784 LR_TDLS_FME_FIELD_FILL(1);
2786 /* 3. Frame Formation - (4) Capability */
2787 WLAN_SET_FIELD_16(pPkt
, prCmd
->u2Cap
);
2788 LR_TDLS_FME_FIELD_FILL(2);
2790 /* 4. Append general IEs */
2791 u4IeLen
= TdlsFrameGeneralIeAppend(prAdapter
, NULL
, 0, pPkt
);
2792 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
2794 /* 3. Frame Formation - (10) Extended capabilities element */
2795 EXT_CAP_IE(pPkt
)->ucId
= ELEM_ID_EXTENDED_CAP
;
2796 EXT_CAP_IE(pPkt
)->ucLength
= 5;
2798 EXT_CAP_IE(pPkt
)->aucCapabilities
[0] = 0x00; /* bit0 ~ bit7 */
2799 EXT_CAP_IE(pPkt
)->aucCapabilities
[1] = 0x00; /* bit8 ~ bit15 */
2800 EXT_CAP_IE(pPkt
)->aucCapabilities
[2] = 0x00; /* bit16 ~ bit23 */
2801 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] = 0x00; /* bit24 ~ bit31 */
2802 EXT_CAP_IE(pPkt
)->aucCapabilities
[4] = 0x00; /* bit32 ~ bit39 */
2804 if (prCmd
->ucExCap
& TDLS_EX_CAP_PEER_UAPSD
)
2805 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] |= BIT((28-24));
2806 if (prCmd
->ucExCap
& TDLS_EX_CAP_CHAN_SWITCH
)
2807 EXT_CAP_IE(pPkt
)->aucCapabilities
[3] |= BIT((30-24));
2808 if (prCmd
->ucExCap
& TDLS_EX_CAP_TDLS
)
2809 EXT_CAP_IE(pPkt
)->aucCapabilities
[4] |= BIT((37-32));
2811 u4IeLen
= IE_SIZE(pPkt
);
2812 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
2814 /* 3. Frame Formation - (12) Timeout interval element (TPK Key Lifetime) */
2815 TIMEOUT_INTERVAL_IE(pPkt
)->ucId
= ELEM_ID_TIMEOUT_INTERVAL
;
2816 TIMEOUT_INTERVAL_IE(pPkt
)->ucLength
= 5;
2818 TIMEOUT_INTERVAL_IE(pPkt
)->ucType
= IE_TIMEOUT_INTERVAL_TYPE_KEY_LIFETIME
;
2819 TIMEOUT_INTERVAL_IE(pPkt
)->u4Value
= htonl(prCmd
->u4Timeout
);
2821 u4IeLen
= IE_SIZE(pPkt
);
2822 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
2824 /* 3. Frame Formation - (16) Link identifier element */
2825 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucId
= ELEM_ID_LINK_IDENTIFIER
;
2826 TDLS_LINK_IDENTIFIER_IE(pPkt
)->ucLength
= ELEM_LEN_LINK_IDENTIFIER
;
2828 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aBSSID
, prBssInfo
->aucBSSID
, 6);
2829 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aInitiator
, prAdapter
->rMyMacAddr
, 6);
2830 kalMemCopy(TDLS_LINK_IDENTIFIER_IE(pPkt
)->aResponder
, prCmd
->arRspAddr
, 6);
2832 u4IeLen
= IE_SIZE(pPkt
);
2833 LR_TDLS_FME_FIELD_FILL(u4IeLen
);
2835 /* 4. Update packet length */
2836 prMsduInfo
->len
= u4PktLen
;
2837 dumpMemory8(ANDROID_LOG_INFO
, prMsduInfo
->data
, u4PktLen
);
2839 /* 5. send the data frame */
2840 wlanHardStartXmit(prMsduInfo
, prMsduInfo
->dev
);
2841 return TDLS_STATUS_SUCCESS
;
2845 /*----------------------------------------------------------------------------*/
2846 /*! \brief This routine is called to receive a NULL frame.
2848 * \param[in] prAdapter Pointer to the Adapter structure
2849 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
2850 * \param[in] u4SetBufferLen The length of the set buffer
2851 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2852 * bytes read from the set buffer. If the call failed due to invalid length of
2853 * the set buffer, returns the amount of storage needed.
2855 * \retval TDLS_STATUS_xx
2858 /*----------------------------------------------------------------------------*/
2861 ADAPTER_T
*prAdapter
,
2863 UINT_32 u4SetBufferLen
,
2864 UINT_32
*pu4SetInfoLen
2867 TDLS_CMD_CORE_T
*prCmdContent
;
2868 WLAN_STATUS rStatus
;
2871 /* init command buffer */
2872 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
2873 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_NULL_RCV
;
2875 /* send the command */
2876 rStatus
= wlanSendSetQueryCmd (
2877 prAdapter
, /* prAdapter */
2878 CMD_ID_TDLS_CORE
, /* ucCID */
2879 TRUE
, /* fgSetQuery */
2880 FALSE
, /* fgNeedResp */
2881 FALSE
, /* fgIsOid */
2883 NULL
, /* pfCmdTimeoutHandler */
2884 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
2885 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
2886 NULL
, /* pvSetQueryBuffer */
2887 0 /* u4SetQueryBufferLen */
2890 if (rStatus
!= WLAN_STATUS_PENDING
)
2892 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
2894 return TDLS_STATUS_RESOURCES
;
2897 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
2898 return TDLS_STATUS_SUCCESS
;
2902 /*----------------------------------------------------------------------------*/
2903 /*! \brief This routine is called to receive a PTI frame.
2905 * \param[in] prAdapter Pointer to the Adapter structure
2906 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
2907 * \param[in] u4SetBufferLen The length of the set buffer
2908 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2909 * bytes read from the set buffer. If the call failed due to invalid length of
2910 * the set buffer, returns the amount of storage needed.
2912 * \retval TDLS_STATUS_xx
2915 /*----------------------------------------------------------------------------*/
2918 ADAPTER_T
*prAdapter
,
2920 UINT_32 u4SetBufferLen
,
2921 UINT_32
*pu4SetInfoLen
2924 TDLS_CMD_CORE_T
*prCmdContent
;
2925 WLAN_STATUS rStatus
;
2928 /* init command buffer */
2929 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
2930 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_PTI_REQ
;
2932 /* send the command */
2933 rStatus
= wlanSendSetQueryCmd (
2934 prAdapter
, /* prAdapter */
2935 CMD_ID_TDLS_CORE
, /* ucCID */
2936 TRUE
, /* fgSetQuery */
2937 FALSE
, /* fgNeedResp */
2938 FALSE
, /* fgIsOid */
2940 NULL
, /* pfCmdTimeoutHandler */
2941 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
2942 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
2943 NULL
, /* pvSetQueryBuffer */
2944 0 /* u4SetQueryBufferLen */
2947 if (rStatus
!= WLAN_STATUS_PENDING
)
2949 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
2951 return TDLS_STATUS_RESOURCES
;
2954 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
2955 return TDLS_STATUS_SUCCESS
;
2959 /*----------------------------------------------------------------------------*/
2960 /*! \brief This routine is called to receive a PTI response frame.
2962 * \param[in] prAdapter Pointer to the Adapter structure
2963 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
2964 * \param[in] u4SetBufferLen The length of the set buffer
2965 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
2966 * bytes read from the set buffer. If the call failed due to invalid length of
2967 * the set buffer, returns the amount of storage needed.
2969 * \retval TDLS_STATUS_xx
2972 /*----------------------------------------------------------------------------*/
2975 ADAPTER_T
*prAdapter
,
2977 UINT_32 u4SetBufferLen
,
2978 UINT_32
*pu4SetInfoLen
2981 TDLS_CMD_CORE_T
*prCmdContent
;
2982 WLAN_STATUS rStatus
;
2985 /* init command buffer */
2986 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
2987 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_PTI_RSP
;
2989 /* send the command */
2990 rStatus
= wlanSendSetQueryCmd (
2991 prAdapter
, /* prAdapter */
2992 CMD_ID_TDLS_CORE
, /* ucCID */
2993 TRUE
, /* fgSetQuery */
2994 FALSE
, /* fgNeedResp */
2995 FALSE
, /* fgIsOid */
2997 NULL
, /* pfCmdTimeoutHandler */
2998 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
2999 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3000 NULL
, /* pvSetQueryBuffer */
3001 0 /* u4SetQueryBufferLen */
3004 if (rStatus
!= WLAN_STATUS_PENDING
)
3006 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3008 return TDLS_STATUS_RESOURCES
;
3011 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3012 return TDLS_STATUS_SUCCESS
;
3016 /*----------------------------------------------------------------------------*/
3017 /*! \brief This routine is called to receive a Tear Down frame.
3019 * \param[in] prAdapter Pointer to the Adapter structure
3020 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3021 * \param[in] u4SetBufferLen The length of the set buffer
3022 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3023 * bytes read from the set buffer. If the call failed due to invalid length of
3024 * the set buffer, returns the amount of storage needed.
3026 * \retval TDLS_STATUS_xx
3029 /*----------------------------------------------------------------------------*/
3031 TdlsTestTearDownRecv(
3032 ADAPTER_T
*prAdapter
,
3034 UINT_32 u4SetBufferLen
,
3035 UINT_32
*pu4SetInfoLen
3038 TDLS_CMD_CORE_T
*prCmdContent
;
3039 WLAN_STATUS rStatus
;
3042 /* init command buffer */
3043 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
3044 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_TEAR_DOWN
;
3046 /* send the command */
3047 rStatus
= wlanSendSetQueryCmd (
3048 prAdapter
, /* prAdapter */
3049 CMD_ID_TDLS_CORE
, /* ucCID */
3050 TRUE
, /* fgSetQuery */
3051 FALSE
, /* fgNeedResp */
3052 FALSE
, /* fgIsOid */
3054 NULL
, /* pfCmdTimeoutHandler */
3055 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
3056 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3057 NULL
, /* pvSetQueryBuffer */
3058 0 /* u4SetQueryBufferLen */
3061 if (rStatus
!= WLAN_STATUS_PENDING
)
3063 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3065 return TDLS_STATUS_RESOURCES
;
3068 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3069 return TDLS_STATUS_SUCCESS
;
3073 /*----------------------------------------------------------------------------*/
3074 /*! \brief This routine is called to receive a data frame.
3076 * \param[in] prAdapter Pointer to the Adapter structure
3077 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3078 * \param[in] u4SetBufferLen The length of the set buffer
3079 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3080 * bytes read from the set buffer. If the call failed due to invalid length of
3081 * the set buffer, returns the amount of storage needed.
3083 * \retval TDLS_STATUS_xx
3086 /*----------------------------------------------------------------------------*/
3089 ADAPTER_T
*prAdapter
,
3091 UINT_32 u4SetBufferLen
,
3092 UINT_32
*pu4SetInfoLen
3095 TDLS_CMD_CORE_T
*prCmdContent
;
3096 WLAN_STATUS rStatus
;
3099 /* init command buffer */
3100 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
3101 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_DATA_RCV
;
3103 /* send the command */
3104 rStatus
= wlanSendSetQueryCmd (
3105 prAdapter
, /* prAdapter */
3106 CMD_ID_TDLS_CORE
, /* ucCID */
3107 TRUE
, /* fgSetQuery */
3108 FALSE
, /* fgNeedResp */
3109 FALSE
, /* fgIsOid */
3111 NULL
, /* pfCmdTimeoutHandler */
3112 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
3113 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3114 NULL
, /* pvSetQueryBuffer */
3115 0 /* u4SetQueryBufferLen */
3118 if (rStatus
!= WLAN_STATUS_PENDING
)
3120 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3122 return TDLS_STATUS_RESOURCES
;
3125 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3126 return TDLS_STATUS_SUCCESS
;
3130 /*----------------------------------------------------------------------------*/
3131 /*! \brief This routine is called to skip PTI tx fail status.
3133 * \param[in] prAdapter Pointer to the Adapter structure
3134 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3135 * \param[in] u4SetBufferLen The length of the set buffer
3136 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3137 * bytes read from the set buffer. If the call failed due to invalid length of
3138 * the set buffer, returns the amount of storage needed.
3140 * \retval TDLS_STATUS_xx
3143 /*----------------------------------------------------------------------------*/
3146 ADAPTER_T
*prAdapter
,
3148 UINT_32 u4SetBufferLen
,
3149 UINT_32
*pu4SetInfoLen
3152 TDLS_CMD_CORE_T
*prCmdContent
;
3153 WLAN_STATUS rStatus
;
3156 /* init command buffer */
3157 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
3158 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_PTI_TX_FAIL
;
3160 /* send the command */
3161 rStatus
= wlanSendSetQueryCmd (
3162 prAdapter
, /* prAdapter */
3163 CMD_ID_TDLS_CORE
, /* ucCID */
3164 TRUE
, /* fgSetQuery */
3165 FALSE
, /* fgNeedResp */
3166 FALSE
, /* fgIsOid */
3168 NULL
, /* pfCmdTimeoutHandler */
3169 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
3170 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3171 NULL
, /* pvSetQueryBuffer */
3172 0 /* u4SetQueryBufferLen */
3175 if (rStatus
!= WLAN_STATUS_PENDING
)
3177 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3179 return TDLS_STATUS_RESOURCES
;
3182 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3183 return TDLS_STATUS_SUCCESS
;
3188 /*----------------------------------------------------------------------------*/
3190 * \brief This routine is called to send a TDLS action frame.
3192 * \param[in] prAdapter Pointer to the Adapter structure
3193 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3194 * \param[in] u4SetBufferLen The length of the set buffer
3195 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3196 * bytes read from the set buffer. If the call failed due to invalid length of
3197 * the set buffer, returns the amount of storage needed.
3199 * \retval TDLS_STATUS_xx
3201 * EX: iwpriv wlan0 set_str_cmd 0_12_0_[FrameType]_[DialogToken]_[Peer MAC]
3203 iwpriv wlan0 set_str_cmd 0_12_0_0_1_00:11:22:33:44:01
3205 /*----------------------------------------------------------------------------*/
3207 TdlsTestTdlsFrameSend(
3208 ADAPTER_T
*prAdapter
,
3210 UINT_32 u4SetBufferLen
,
3211 UINT_32
*pu4SetInfoLen
3214 GLUE_INFO_T
*prGlueInfo
;
3215 PARAM_CUSTOM_TDLS_CMD_STRUC_T
*prCmd
;
3216 struct wireless_dev
*prWdev
;
3221 ASSERT(pvSetBuffer
);
3222 ASSERT(pu4SetInfoLen
);
3224 DBGLOG(TDLS
, INFO
, ("<tdls_fme> %s\n", __FUNCTION__
));
3226 if(u4SetBufferLen
== 0)
3227 return TDLS_STATUS_INVALID_LENGTH
;
3229 /* allocate/init packet */
3230 prGlueInfo
= (GLUE_INFO_T
*)prAdapter
->prGlueInfo
;
3231 prCmd
= (PARAM_CUSTOM_TDLS_CMD_STRUC_T
*)pvSetBuffer
;
3232 prWdev
= (struct wireless_dev
*)prGlueInfo
->prDevHandler
->ieee80211_ptr
;
3234 TdlsexCfg80211TdlsMgmt(prWdev
->wiphy
,
3240 NULL
, /* open/none */
3243 return TDLS_STATUS_SUCCESS
;
3247 /*----------------------------------------------------------------------------*/
3248 /*! \brief This routine is called to skip tx fail status. So always success in tx done in firmware.
3250 * \param[in] prAdapter Pointer to the Adapter structure
3251 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3252 * \param[in] u4SetBufferLen The length of the set buffer
3253 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3254 * bytes read from the set buffer. If the call failed due to invalid length of
3255 * the set buffer, returns the amount of storage needed.
3257 * \retval TDLS_STATUS_xx
3260 /*----------------------------------------------------------------------------*/
3263 ADAPTER_T
*prAdapter
,
3265 UINT_32 u4SetBufferLen
,
3266 UINT_32
*pu4SetInfoLen
3269 TDLS_CMD_CORE_T
*prCmdContent
;
3270 WLAN_STATUS rStatus
;
3273 /* init command buffer */
3274 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
3275 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_TX_FAIL_SKIP
;
3277 /* send the command */
3278 rStatus
= wlanSendSetQueryCmd (
3279 prAdapter
, /* prAdapter */
3280 CMD_ID_TDLS_CORE
, /* ucCID */
3281 TRUE
, /* fgSetQuery */
3282 FALSE
, /* fgNeedResp */
3283 FALSE
, /* fgIsOid */
3285 NULL
, /* pfCmdTimeoutHandler */
3286 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
3287 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3288 NULL
, /* pvSetQueryBuffer */
3289 0 /* u4SetQueryBufferLen */
3292 if (rStatus
!= WLAN_STATUS_PENDING
)
3294 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3296 return TDLS_STATUS_RESOURCES
;
3299 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3300 return TDLS_STATUS_SUCCESS
;
3305 /*----------------------------------------------------------------------------*/
3306 /*! \brief This routine is called to skip to do keep alive function in firmware.
3308 * \param[in] prAdapter Pointer to the Adapter structure
3309 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3310 * \param[in] u4SetBufferLen The length of the set buffer
3311 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3312 * bytes read from the set buffer. If the call failed due to invalid length of
3313 * the set buffer, returns the amount of storage needed.
3315 * \retval TDLS_STATUS_xx
3318 /*----------------------------------------------------------------------------*/
3320 TdlsTestKeepAliveSkip(
3321 ADAPTER_T
*prAdapter
,
3323 UINT_32 u4SetBufferLen
,
3324 UINT_32
*pu4SetInfoLen
3327 TDLS_CMD_CORE_T
*prCmdContent
;
3328 WLAN_STATUS rStatus
;
3331 /* init command buffer */
3332 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
3333 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_KEEP_ALIVE_SKIP
;
3335 /* send the command */
3336 rStatus
= wlanSendSetQueryCmd (
3337 prAdapter
, /* prAdapter */
3338 CMD_ID_TDLS_CORE
, /* ucCID */
3339 TRUE
, /* fgSetQuery */
3340 FALSE
, /* fgNeedResp */
3341 FALSE
, /* fgIsOid */
3343 NULL
, /* pfCmdTimeoutHandler */
3344 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
3345 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3346 NULL
, /* pvSetQueryBuffer */
3347 0 /* u4SetQueryBufferLen */
3350 if (rStatus
!= WLAN_STATUS_PENDING
)
3352 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3354 return TDLS_STATUS_RESOURCES
;
3357 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3358 return TDLS_STATUS_SUCCESS
;
3362 /*----------------------------------------------------------------------------*/
3363 /*! \brief This routine is called to skip channel switch timeout.
3365 * \param[in] prAdapter Pointer to the Adapter structure
3366 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3367 * \param[in] u4SetBufferLen The length of the set buffer
3368 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3369 * bytes read from the set buffer. If the call failed due to invalid length of
3370 * the set buffer, returns the amount of storage needed.
3372 * \retval TDLS_STATUS_xx
3375 /*----------------------------------------------------------------------------*/
3377 TdlsTestChSwTimeoutSkip(
3378 ADAPTER_T
*prAdapter
,
3380 UINT_32 u4SetBufferLen
,
3381 UINT_32
*pu4SetInfoLen
3384 TDLS_CMD_CORE_T
*prCmdContent
;
3385 WLAN_STATUS rStatus
;
3388 /* init command buffer */
3389 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
3390 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_CHSW_TIMEOUT_SKIP
;
3392 /* send the command */
3393 rStatus
= wlanSendSetQueryCmd (
3394 prAdapter
, /* prAdapter */
3395 CMD_ID_TDLS_CORE
, /* ucCID */
3396 TRUE
, /* fgSetQuery */
3397 FALSE
, /* fgNeedResp */
3398 FALSE
, /* fgIsOid */
3400 NULL
, /* pfCmdTimeoutHandler */
3401 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
3402 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3403 NULL
, /* pvSetQueryBuffer */
3404 0 /* u4SetQueryBufferLen */
3407 if (rStatus
!= WLAN_STATUS_PENDING
)
3409 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3411 return TDLS_STATUS_RESOURCES
;
3414 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3415 return TDLS_STATUS_SUCCESS
;
3419 /*----------------------------------------------------------------------------*/
3420 /*! \brief This routine is called to skip scan request.
3422 * \param[in] prAdapter Pointer to the Adapter structure
3423 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3424 * \param[in] u4SetBufferLen The length of the set buffer
3425 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3426 * bytes read from the set buffer. If the call failed due to invalid length of
3427 * the set buffer, returns the amount of storage needed.
3429 * \retval TDLS_STATUS_xx
3432 /*----------------------------------------------------------------------------*/
3435 ADAPTER_T
*prAdapter
,
3437 UINT_32 u4SetBufferLen
,
3438 UINT_32
*pu4SetInfoLen
3441 TDLS_CMD_CORE_T
*prCmdContent
;
3442 WLAN_STATUS rStatus
;
3445 /* init command buffer */
3446 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
3447 prCmdContent
->u4Command
= TDLS_CORE_CMD_TEST_SCAN_SKIP
;
3449 /* send the command */
3450 rStatus
= wlanSendSetQueryCmd (
3451 prAdapter
, /* prAdapter */
3452 CMD_ID_TDLS_CORE
, /* ucCID */
3453 TRUE
, /* fgSetQuery */
3454 FALSE
, /* fgNeedResp */
3455 FALSE
, /* fgIsOid */
3457 NULL
, /* pfCmdTimeoutHandler */
3458 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
3459 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3460 NULL
, /* pvSetQueryBuffer */
3461 0 /* u4SetQueryBufferLen */
3464 if (rStatus
!= WLAN_STATUS_PENDING
)
3466 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3468 return TDLS_STATUS_RESOURCES
;
3471 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3472 return TDLS_STATUS_SUCCESS
;
3476 #endif /* TDLS_CFG_CMD_TEST */
3479 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
3480 /*----------------------------------------------------------------------------*/
3481 /*! \brief This routine is called to send a TDLS event to supplicant.
3483 * \param[in] prGlueInfo Pointer to the Adapter structure
3484 * \param[in] prInBuf A pointer to the command string buffer
3485 * \param[in] u4InBufLen The length of the buffer
3491 /*----------------------------------------------------------------------------*/
3492 void cfg80211_tdls_oper_request(
3493 struct net_device
*dev
,
3500 GLUE_INFO_T
*prGlueInfo
;
3501 ADAPTER_T
*prAdapter
;
3502 struct sk_buff
*prMsduInfo
;
3508 if ((dev
== NULL
) || (peer
== NULL
))
3509 return; /* shall not be here */
3512 ("<tdls_fme> %s: Oper=%d ReasonCode=%d from "MACSTR
"\n",
3513 __FUNCTION__
, oper
, reason_code
, MAC2STR(peer
)));
3516 prGlueInfo
= *((P_GLUE_INFO_T
*) netdev_priv(dev
));
3517 prAdapter
= prGlueInfo
->prAdapter
;
3520 /* allocate/init packet */
3521 prMsduInfo
= kalPacketAlloc(prGlueInfo
, 1600, &pPkt
);
3522 if (prMsduInfo
== NULL
) {
3523 DBGLOG(TDLS
, ERROR
, ("<tdls_cmd> %s: allocate pkt fail\n", __FUNCTION__
));
3526 prMsduInfo
->dev
= dev
;
3528 /* make up frame content */
3529 /* 1. 802.3 header */
3530 kalMemCopy(pPkt
, prAdapter
->rMyMacAddr
, TDLS_FME_MAC_ADDR_LEN
);
3531 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
3532 kalMemCopy(pPkt
, peer
, TDLS_FME_MAC_ADDR_LEN
);
3533 LR_TDLS_FME_FIELD_FILL(TDLS_FME_MAC_ADDR_LEN
);
3534 *(UINT_16
*)pPkt
= htons(TDLS_FRM_PROT_TYPE
);
3535 LR_TDLS_FME_FIELD_FILL(2);
3537 /* 2. payload type */
3538 *pPkt
= TDLS_FRM_PAYLOAD_TYPE
;
3539 LR_TDLS_FME_FIELD_FILL(1);
3541 /* 3. Frame Formation - (1) Category */
3542 *pPkt
= TDLS_FRM_CATEGORY
;
3543 LR_TDLS_FME_FIELD_FILL(1);
3545 /* 3. Frame Formation - (2) Action */
3546 *pPkt
= TDLS_FRM_ACTION_EVENT_TEAR_DOWN_TO_SUPPLICANT
;
3547 LR_TDLS_FME_FIELD_FILL(1);
3549 /* 3. Frame Formation - (3) Operation */
3551 LR_TDLS_FME_FIELD_FILL(1);
3553 /* 3. Frame Formation - (4) Reason Code */
3554 *pPkt
= reason_code
;
3556 LR_TDLS_FME_FIELD_FILL(2);
3558 /* 3. Frame Formation - (5) Peer MAC */
3559 kalMemCopy(pPkt
, peer
, 6);
3560 LR_TDLS_FME_FIELD_FILL(6);
3562 /* 4. Update packet length */
3563 prMsduInfo
->len
= u4PktLen
;
3564 dumpMemory8(ANDROID_LOG_INFO
, prMsduInfo
->data
, u4PktLen
);
3567 TdlsCmdTestRxIndicatePkts(prGlueInfo
, prMsduInfo
);
3569 #endif /* LINUX_VERSION_CODE */
3572 /*----------------------------------------------------------------------------*/
3573 /*! \brief This routine is called to configure channel switch parameters.
3575 * \param[in] prAdapter Pointer to the Adapter structure
3576 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
3577 * \param[in] u4SetBufferLen The length of the set buffer
3578 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
3579 * bytes read from the set buffer. If the call failed due to invalid length of
3580 * the set buffer, returns the amount of storage needed.
3582 * \retval TDLS_STATUS_xx
3585 /*----------------------------------------------------------------------------*/
3588 ADAPTER_T
*prAdapter
,
3590 UINT_32 u4SetBufferLen
,
3591 UINT_32
*pu4SetInfoLen
3594 TDLS_CMD_CORE_T
*prCmdContent
;
3595 WLAN_STATUS rStatus
;
3598 /* init command buffer */
3599 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
3600 prCmdContent
->u4Command
= TDLS_CORE_CMD_CHSW_CONF
;
3602 /* send the command */
3603 rStatus
= wlanSendSetQueryCmd (
3604 prAdapter
, /* prAdapter */
3605 CMD_ID_TDLS_CORE
, /* ucCID */
3606 TRUE
, /* fgSetQuery */
3607 FALSE
, /* fgNeedResp */
3608 FALSE
, /* fgIsOid */
3610 NULL
, /* pfCmdTimeoutHandler */
3611 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
3612 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
3613 NULL
, /* pvSetQueryBuffer */
3614 0 /* u4SetQueryBufferLen */
3617 if (rStatus
!= WLAN_STATUS_PENDING
)
3619 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
3621 return TDLS_STATUS_RESOURCES
;
3624 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
3625 return TDLS_STATUS_SUCCESS
;
3629 /*----------------------------------------------------------------------------*/
3630 /*! \brief This routine is called to update channel switch parameters.
3632 * \param[in] prGlueInfo Pointer to the Adapter structure
3633 * \param[in] prInBuf A pointer to the command string buffer
3634 * \param[in] u4InBufLen The length of the buffer
3639 * EX: iwpriv wlan0 set_str_cmd 0_9_[TDLS Peer MAC]_
3640 [NetworkTypeIndex]_[1 (Enable) or (0) Disable]_[1 (Start) or 0 (Stop)]_
3641 [RegClass]_[Chan]_[SecChanOff]_[1 (Reqular) or (0) One Shot]
3643 RegulatoryClass: TODO (reference to Annex I of 802.11n spec.)
3644 Secondary Channel Offset: 0 (SCN - no secondary channel)
3645 1 (SCA - secondary channel above)
3646 2 (SCB - secondary channel below)
3647 SwitchTime: units of microseconds
3649 iwpriv wlan0 set_str_cmd 0_9_00:11:22:33:44:01_0_1_0_0_1_0_0
3651 /*----------------------------------------------------------------------------*/
3654 P_GLUE_INFO_T prGlueInfo
,
3659 WLAN_STATUS rStatus
;
3660 TDLS_CMD_CORE_T rCmd
;
3664 /* parse arguments */
3665 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.aucPeerMac
);
3667 rCmd
.Content
.rCmdChSwConf
.ucNetTypeIndex
= \
3668 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3669 rCmd
.Content
.rCmdChSwConf
.fgIsChSwEnabled
= \
3670 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3671 rCmd
.Content
.rCmdChSwConf
.fgIsChSwStarted
= \
3672 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3673 rCmd
.Content
.rCmdChSwConf
.ucRegClass
= \
3674 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3675 rCmd
.Content
.rCmdChSwConf
.ucTargetChan
= \
3676 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3677 rCmd
.Content
.rCmdChSwConf
.ucSecChanOff
= \
3678 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3679 rCmd
.Content
.rCmdChSwConf
.fgIsChSwRegular
= \
3680 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3683 ("%s: "MACSTR
" ucNetTypeIndex=%d, fgIsChSwEnabled=%d, fgIsChSwStarted=%d "
3684 "RegClass=%d, TargetChan=%d, SecChanOff=%d, Regular=%d\n",
3685 __FUNCTION__
, MAC2STR(rCmd
.aucPeerMac
),
3686 rCmd
.Content
.rCmdChSwConf
.ucNetTypeIndex
,
3687 rCmd
.Content
.rCmdChSwConf
.fgIsChSwEnabled
,
3688 rCmd
.Content
.rCmdChSwConf
.fgIsChSwStarted
,
3689 rCmd
.Content
.rCmdChSwConf
.ucRegClass
,
3690 rCmd
.Content
.rCmdChSwConf
.ucTargetChan
,
3691 rCmd
.Content
.rCmdChSwConf
.ucSecChanOff
,
3692 rCmd
.Content
.rCmdChSwConf
.fgIsChSwRegular
));
3694 /* command to do this */
3695 rStatus
= kalIoctl(prGlueInfo
,
3705 if (rStatus
!= WLAN_STATUS_SUCCESS
)
3707 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
3713 /*----------------------------------------------------------------------------*/
3714 /*! \brief This routine is called to display TDLS related informations.
3716 * \param[in] prGlueInfo Pointer to the Adapter structure
3717 * \param[in] prInBuf A pointer to the command string buffer
3718 * \param[in] u4InBufLen The length of the buffer
3723 * EX: iwpriv wlan0 set_str_cmd 0_18_[Peer MAC]_[Network Interface ID]_[IsClear]
3725 Network Interface ID: reference to ENUM_NETWORK_TYPE_INDEX_T
3727 typedef enum _ENUM_NETWORK_TYPE_INDEX_T {
3728 NETWORK_TYPE_AIS_INDEX = 0,
3729 NETWORK_TYPE_P2P_INDEX,
3730 NETWORK_TYPE_BOW_INDEX,
3731 NETWORK_TYPE_INDEX_NUM
3732 } ENUM_NETWORK_TYPE_INDEX_T;
3734 iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0
3736 /*----------------------------------------------------------------------------*/
3739 GLUE_INFO_T
*prGlueInfo
,
3744 WLAN_STATUS rStatus
;
3745 TDLS_CMD_CORE_T rCmd
;
3749 /* parse arguments */
3750 kalMemZero(&rCmd
, sizeof(rCmd
));
3752 CmdStringMacParse(prInBuf
, &prInBuf
, &u4InBufLen
, rCmd
.aucPeerMac
);
3753 rCmd
.ucNetTypeIndex
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3754 rCmd
.Content
.rCmdInfoDisplay
.fgIsToClearAllHistory
= \
3755 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3757 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: Command PeerMac="MACSTR
" in BSS%u\n",
3758 __FUNCTION__
, MAC2STR(rCmd
.aucPeerMac
), rCmd
.ucNetTypeIndex
));
3760 /* command to do this */
3761 rStatus
= kalIoctl(prGlueInfo
,
3771 if (rStatus
!= WLAN_STATUS_SUCCESS
)
3773 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
3779 /*----------------------------------------------------------------------------*/
3780 /*! \brief This routine is called to display key related informations.
3782 * \param[in] prGlueInfo Pointer to the Adapter structure
3783 * \param[in] prInBuf A pointer to the command string buffer
3784 * \param[in] u4InBufLen The length of the buffer
3789 * EX: iwpriv wlan0 set_str_cmd 0_20
3791 iwpriv wlan0 set_str_cmd 0_20
3793 /*----------------------------------------------------------------------------*/
3795 TdlsCmdKeyInfoDisplay(
3796 GLUE_INFO_T
*prGlueInfo
,
3801 WLAN_STATUS rStatus
;
3802 TDLS_CMD_CORE_T rCmd
;
3806 /* parse arguments */
3807 kalMemZero(&rCmd
, sizeof(rCmd
));
3809 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s\n", __FUNCTION__
));
3811 /* command to do this */
3812 rStatus
= kalIoctl(prGlueInfo
,
3822 if (rStatus
!= WLAN_STATUS_SUCCESS
)
3824 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
3830 /*----------------------------------------------------------------------------*/
3831 /*! \brief This routine is called to update MIB parameters.
3833 * \param[in] prGlueInfo Pointer to the Adapter structure
3834 * \param[in] prInBuf A pointer to the command string buffer
3835 * \param[in] u4InBufLen The length of the buffer
3840 * EX: iwpriv wlan0 set_str_cmd 0_6_[TdlsEn]_[UapsdEn]_[PsmEn]_[PtiWin]_[CWCap]_
3841 [AckMisRetry]_[RspTimeout]_[CWPbDelay]_[DRWin]_[LowestAcInt]
3843 iwpriv wlan0 set_str_cmd 0_6_1_1_0_1_1_3_5_1000_2_1
3845 reference to TDLS_CMD_CORE_MIB_PARAM_UPDATE_T
3847 /*----------------------------------------------------------------------------*/
3849 TdlsCmdMibParamUpdate(
3850 P_GLUE_INFO_T prGlueInfo
,
3855 WLAN_STATUS rStatus
;
3856 TDLS_CMD_CORE_T rCmd
;
3861 kalMemZero(&rCmd
, sizeof(rCmd
));
3863 /* parse arguments */
3864 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TunneledDirectLinkSetupImplemented
= \
3865 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3866 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated
= \
3867 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3868 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSPeerPSMActivated
= \
3869 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3870 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSPeerUAPSDIndicationWindow
= \
3871 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3872 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSChannelSwitchingActivated
= \
3873 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3874 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit
= \
3875 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3876 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSResponseTimeout
= \
3877 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3878 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSProbeDelay
= \
3879 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3880 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSDiscoveryRequestWindow
= \
3881 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3882 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSACDeterminationInterval
= \
3883 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3885 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> MIB param = %d %d %d %d %d %d %d %d %d %d \n",
3886 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TunneledDirectLinkSetupImplemented
,
3887 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSPeerUAPSDBufferSTAActivated
,
3888 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSPeerPSMActivated
,
3889 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSPeerUAPSDIndicationWindow
,
3890 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSChannelSwitchingActivated
,
3891 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSPeerSTAMissingAckRetryLimit
,
3892 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSResponseTimeout
,
3893 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSProbeDelay
,
3894 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSDiscoveryRequestWindow
,
3895 rCmd
.Content
.rCmdMibUpdate
.Tdlsdot11TDLSACDeterminationInterval
));
3897 /* command to do this */
3898 rStatus
= kalIoctl(prGlueInfo
,
3908 if (rStatus
!= WLAN_STATUS_SUCCESS
)
3910 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
3916 /*----------------------------------------------------------------------------*/
3917 /*! \brief This routine is called to update setup parameters.
3919 * \param[in] prGlueInfo Pointer to the Adapter structure
3920 * \param[in] prInBuf A pointer to the command string buffer
3921 * \param[in] u4InBufLen The length of the buffer
3926 * EX: iwpriv wlan0 set_str_cmd 0_17_[20/40 Support]
3928 iwpriv wlan0 set_str_cmd 0_17_1
3930 /*----------------------------------------------------------------------------*/
3933 P_GLUE_INFO_T prGlueInfo
,
3938 WLAN_STATUS rStatus
;
3939 TDLS_CMD_CORE_T rCmd
;
3943 /* parse arguments */
3944 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
3946 rCmd
.Content
.rCmdSetupConf
.fgIs2040Supported
= \
3947 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
3949 DBGLOG(TDLS
, INFO
, ("%s: rCmdSetupConf=%d\n",
3950 __FUNCTION__
, rCmd
.Content
.rCmdSetupConf
.fgIs2040Supported
));
3952 /* command to do this */
3953 prGlueInfo
->rTdlsLink
.fgIs2040Sup
= rCmd
.Content
.rCmdSetupConf
.fgIs2040Supported
;
3955 rStatus
= kalIoctl(prGlueInfo
,
3965 if (rStatus
!= WLAN_STATUS_SUCCESS
)
3967 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
3973 /*----------------------------------------------------------------------------*/
3974 /*! \brief This routine is called to update UAPSD parameters.
3976 * \param[in] prGlueInfo Pointer to the Adapter structure
3977 * \param[in] prInBuf A pointer to the command string buffer
3978 * \param[in] u4InBufLen The length of the buffer
3983 * EX: iwpriv wlan0 set_str_cmd 0_8_[SP timeout skip]_[PTI timeout skip]
3985 iwpriv wlan0 set_str_cmd 0_8_1_1
3987 /*----------------------------------------------------------------------------*/
3990 P_GLUE_INFO_T prGlueInfo
,
3995 WLAN_STATUS rStatus
;
3996 TDLS_CMD_CORE_T rCmd
;
4000 /* parse arguments */
4001 kalMemZero(rCmd
.aucPeerMac
, sizeof(rCmd
.aucPeerMac
));
4003 /* UAPSD Service Period */
4004 rCmd
.Content
.rCmdUapsdConf
.fgIsSpTimeoutSkip
= \
4005 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
4006 rCmd
.Content
.rCmdUapsdConf
.fgIsPtiTimeoutSkip
= \
4007 CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
4008 /* PTI Service Period */
4009 fgIsPtiTimeoutSkip
= rCmd
.Content
.rCmdUapsdConf
.fgIsPtiTimeoutSkip
;
4011 DBGLOG(TDLS
, INFO
, ("%s: fgIsSpTimeoutSkip=%d, fgIsPtiTimeoutSkip=%d\n",
4012 __FUNCTION__
, rCmd
.Content
.rCmdUapsdConf
.fgIsSpTimeoutSkip
,
4013 fgIsPtiTimeoutSkip
));
4015 /* command to do this */
4016 rStatus
= kalIoctl(prGlueInfo
,
4026 if (rStatus
!= WLAN_STATUS_SUCCESS
)
4028 DBGLOG(TDLS
, ERROR
, ("%s kalIoctl fail:%x\n", __FUNCTION__
, rStatus
));
4034 /*----------------------------------------------------------------------------*/
4035 /*! \brief This routine is called to display TDLS all information.
4037 * \param[in] prAdapter Pointer to the Adapter structure
4038 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
4039 * \param[in] u4SetBufferLen The length of the set buffer
4040 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
4041 * bytes read from the set buffer. If the call failed due to invalid length of
4042 * the set buffer, returns the amount of storage needed.
4044 * \retval TDLS_STATUS_xx
4046 * iwpriv wlan0 set_str_cmd 0_18_00:00:00:00:00:00_0_0
4049 /*----------------------------------------------------------------------------*/
4052 ADAPTER_T
*prAdapter
,
4054 UINT_32 u4SetBufferLen
,
4055 UINT_32
*pu4SetInfoLen
4058 GLUE_INFO_T
*prGlueInfo
;
4059 TDLS_CMD_CORE_T
*prCmdContent
;
4060 STA_RECORD_T
*prStaRec
;
4061 TDLS_INFO_LINK_T
*prLink
;
4064 BOOLEAN fgIsListAll
;
4067 UINT8 ucNetTypeIndex
;
4071 prGlueInfo
= prAdapter
->prGlueInfo
;
4072 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
4076 kalMemZero(ucMacZero
, sizeof(ucMacZero
));
4077 ucNetTypeIndex
= NETWORK_TYPE_AIS_INDEX
;
4079 /* display common information */
4080 DBGLOG(TDLS
, TRACE
, ("TDLS common:\n"));
4081 DBGLOG(TDLS
, TRACE
, ("\t\trFreeSwRfbList=%u\n",
4082 (UINT32
)prAdapter
->rRxCtrl
.rFreeSwRfbList
.u4NumElem
));
4083 DBGLOG(TDLS
, TRACE
, ("\t\tjiffies=%u %ums (HZ=%d)\n", (UINT32
)jiffies
,
4084 (UINT32
)kalGetTimeTick(), HZ
));
4086 /* display disconnection history information */
4087 DBGLOG(TDLS
, TRACE
, ("TDLS link history: %d\n",
4088 prGlueInfo
->rTdlsLink
.u4LinkIdx
));
4090 for(u4HisIdx
= prGlueInfo
->rTdlsLink
.u4LinkIdx
+1;
4091 u4HisIdx
< TDLS_LINK_HISTORY_MAX
;
4094 prLink
= &prGlueInfo
->rTdlsLink
.rLinkHistory
[u4HisIdx
];
4096 if (kalMemCmp(prLink
->aucPeerMac
, ucMacZero
, 6) == 0)
4097 continue; /* skip all zero */
4100 ("\t\t%d. "MACSTR
": jiffies start(%lu %ums) jiffies end(%lu %ums) "
4101 "Reason(%u) fromUs(%u) Dup(%u) HT(%u)\n",
4103 MAC2STR(prLink
->aucPeerMac
),
4104 prLink
->jiffies_start
, jiffies_to_msecs(prLink
->jiffies_start
),
4105 prLink
->jiffies_end
, jiffies_to_msecs(prLink
->jiffies_end
),
4106 prLink
->ucReasonCode
,
4109 (prLink
->ucHtCap
& TDLS_INFO_LINK_HT_CAP_SUP
)));
4111 if (prLink
->ucHtCap
& TDLS_INFO_LINK_HT_CAP_SUP
)
4114 ("\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n",
4115 prLink
->ucHtBa
[0], prLink
->ucHtBa
[1],
4116 prLink
->ucHtBa
[2], prLink
->ucHtBa
[3],
4117 prLink
->ucHtBa
[4], prLink
->ucHtBa
[5],
4118 prLink
->ucHtBa
[6], prLink
->ucHtBa
[7]));
4122 u4HisIdx
<= prGlueInfo
->rTdlsLink
.u4LinkIdx
;
4125 prLink
= &prGlueInfo
->rTdlsLink
.rLinkHistory
[u4HisIdx
];
4127 if (kalMemCmp(prLink
->aucPeerMac
, ucMacZero
, 6) == 0)
4128 continue; /* skip all zero, use continue, not break */
4131 ("\t\t%d. "MACSTR
": jiffies start(%lu %ums) jiffies end(%lu %ums) "
4132 "Reason(%u) fromUs(%u) Dup(%u) HT(%u)\n",
4134 MAC2STR(prLink
->aucPeerMac
),
4135 prLink
->jiffies_start
, jiffies_to_msecs(prLink
->jiffies_start
),
4136 prLink
->jiffies_end
, jiffies_to_msecs(prLink
->jiffies_end
),
4137 prLink
->ucReasonCode
,
4140 (prLink
->ucHtCap
& TDLS_INFO_LINK_HT_CAP_SUP
)));
4142 if (prLink
->ucHtCap
& TDLS_INFO_LINK_HT_CAP_SUP
)
4145 ("\t\t\tBA (0x%x %x %x %x %x %x %x %x)\n",
4146 prLink
->ucHtBa
[0], prLink
->ucHtBa
[1],
4147 prLink
->ucHtBa
[2], prLink
->ucHtBa
[3],
4148 prLink
->ucHtBa
[4], prLink
->ucHtBa
[5],
4149 prLink
->ucHtBa
[6], prLink
->ucHtBa
[7]));
4152 DBGLOG(TDLS
, TRACE
, ("\n"));
4154 /* display link information */
4155 if (prCmdContent
!= NULL
)
4157 if (kalMemCmp(prCmdContent
->aucPeerMac
, ucMacZero
, 6) != 0)
4159 prStaRec
= cnmGetStaRecByAddress(prAdapter
,
4160 prCmdContent
->ucNetTypeIndex
, prCmdContent
->aucPeerMac
);
4161 if (prStaRec
== NULL
)
4165 ucNetTypeIndex
= prCmdContent
->ucNetTypeIndex
;
4170 if (fgIsListAll
== TRUE
)
4172 /* list all TDLS peers */
4173 prStaRec
= cnmStaTheTypeGet(prAdapter
, ucNetTypeIndex
,
4174 STA_TYPE_TDLS_PEER
, &u4StartIdx
);
4175 if (prStaRec
== NULL
)
4179 DBGLOG(TDLS
, TRACE
, ("-------- TDLS %d: 0x"MACSTR
"\n",
4180 u4PeerNum
, MAC2STR(prStaRec
->aucMacAddr
)));
4181 DBGLOG(TDLS
, TRACE
, ("\t\t\t State %d, PM %d, Cap 0x%x\n",
4182 prStaRec
->ucStaState
, prStaRec
->fgIsInPS
, prStaRec
->u2CapInfo
));
4183 DBGLOG(TDLS
, TRACE
, ("\t\t\t SetupDisable %d, ChSwDisable %d\n",
4184 prStaRec
->fgTdlsIsProhibited
, prStaRec
->fgTdlsIsChSwProhibited
));
4186 if (fgIsListAll
== FALSE
)
4187 break; /* only list one */
4190 /* check if we need to clear all histories */
4191 if ((prCmdContent
!= NULL
) &&
4192 (prCmdContent
->Content
.rCmdInfoDisplay
.fgIsToClearAllHistory
== TRUE
))
4194 kalMemZero(&prGlueInfo
->rTdlsLink
, sizeof(prGlueInfo
->rTdlsLink
));
4195 prGlueInfo
->rTdlsLink
.u4LinkIdx
= TDLS_LINK_HISTORY_MAX
-1;
4198 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
4199 return TDLS_STATUS_SUCCESS
;
4203 /*----------------------------------------------------------------------------*/
4204 /*! \brief This routine is called to display key information.
4206 * \param[in] prAdapter Pointer to the Adapter structure
4207 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
4208 * \param[in] u4SetBufferLen The length of the set buffer
4209 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
4210 * bytes read from the set buffer. If the call failed due to invalid length of
4211 * the set buffer, returns the amount of storage needed.
4213 * \retval TDLS_STATUS_xx
4216 /*----------------------------------------------------------------------------*/
4219 ADAPTER_T
*prAdapter
,
4221 UINT_32 u4SetBufferLen
,
4222 UINT_32
*pu4SetInfoLen
4225 TDLS_CMD_CORE_T
*prCmdContent
;
4226 WLAN_STATUS rStatus
;
4229 /* init command buffer */
4230 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
4231 prCmdContent
->u4Command
= TDLS_CORE_CMD_KEY_INFO
;
4233 /* send the command */
4234 rStatus
= wlanSendSetQueryCmd (
4235 prAdapter
, /* prAdapter */
4236 CMD_ID_TDLS_CORE
, /* ucCID */
4237 TRUE
, /* fgSetQuery */
4238 FALSE
, /* fgNeedResp */
4239 FALSE
, /* fgIsOid */
4241 NULL
, /* pfCmdTimeoutHandler */
4242 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
4243 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
4244 NULL
, /* pvSetQueryBuffer */
4245 0 /* u4SetQueryBufferLen */
4248 if (rStatus
!= WLAN_STATUS_PENDING
)
4250 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
4252 return TDLS_STATUS_RESOURCES
;
4255 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
4256 return TDLS_STATUS_SUCCESS
;
4260 /*----------------------------------------------------------------------------*/
4261 /*! \brief This routine is called to record a disconnection event.
4263 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure
4264 * \param[in] fgIsTearDown TRUE: the link is torn down
4265 * \param[in] pucPeerMac Pointer to the MAC of the TDLS peer
4266 * \param[in] fgIsFromUs TRUE: tear down is from us
4267 * \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE)
4271 /*----------------------------------------------------------------------------*/
4273 TdlsLinkHistoryRecord(
4274 GLUE_INFO_T
*prGlueInfo
,
4275 BOOLEAN fgIsTearDown
,
4278 UINT16 u2ReasonCode
,
4282 TDLS_INFO_LINK_T
*prLink
;
4286 ("<tdls_evt> %s: record history for "MACSTR
" %d %d %d %d\n",
4287 __FUNCTION__
, MAC2STR(pucPeerMac
), prGlueInfo
->rTdlsLink
.u4LinkIdx
,
4288 fgIsTearDown
, fgIsFromUs
, u2ReasonCode
));
4290 /* check duplicate one */
4291 if (prGlueInfo
->rTdlsLink
.u4LinkIdx
>= TDLS_LINK_HISTORY_MAX
)
4294 ("<tdls_evt> %s: u4LinkIdx >= TDLS_LINK_HISTORY_MAX\n",
4298 prGlueInfo
->rTdlsLink
.u4LinkIdx
= 0;
4301 prLink
= &prGlueInfo
->rTdlsLink
.rLinkHistory
[\
4302 prGlueInfo
->rTdlsLink
.u4LinkIdx
];
4304 if (kalMemCmp(&prLink
->aucPeerMac
, pucPeerMac
, 6) == 0)
4306 if ((prLink
->ucReasonCode
== u2ReasonCode
) &&
4307 (prLink
->fgIsFromUs
== fgIsFromUs
))
4309 /* same Peer MAC, Reason Code, Trigger source */
4310 if (fgIsTearDown
== TRUE
)
4312 if (prLink
->jiffies_end
!= 0)
4314 /* already torn down */
4315 prLink
->ucDupCount
++;
4322 prLink
->ucDupCount
++;
4328 /* search old entry */
4329 if (fgIsTearDown
== TRUE
)
4331 /* TODO: need to search all entries to find it if we support multiple TDLS link design */
4332 if (kalMemCmp(&prLink
->aucPeerMac
, pucPeerMac
, 6) != 0)
4334 /* error! can not find the link entry */
4336 ("<tdls_evt> %s: cannot find the same entry!!!\n",
4341 prLink
->jiffies_end
= jiffies
;
4342 prLink
->ucReasonCode
= (UINT8
)u2ReasonCode
;
4343 prLink
->fgIsFromUs
= fgIsFromUs
;
4347 /* record new one */
4348 prGlueInfo
->rTdlsLink
.u4LinkIdx
++;
4349 if (prGlueInfo
->rTdlsLink
.u4LinkIdx
>= TDLS_LINK_HISTORY_MAX
)
4350 prGlueInfo
->rTdlsLink
.u4LinkIdx
= 0;
4352 prLink
= &prGlueInfo
->rTdlsLink
.rLinkHistory
[\
4353 prGlueInfo
->rTdlsLink
.u4LinkIdx
];
4355 prLink
->jiffies_start
= jiffies
;
4356 prLink
->jiffies_end
= 0;
4357 kalMemCopy(&prLink
->aucPeerMac
, pucPeerMac
, 6);
4358 prLink
->ucReasonCode
= 0;
4359 prLink
->fgIsFromUs
= (UINT8
)fgIsFromUs
;
4360 prLink
->ucDupCount
= 0;
4362 if (prOthers
!= NULL
)
4364 /* record other parameters */
4365 TDLS_LINK_HIS_OTHERS_T
*prHisOthers
;
4366 prHisOthers
= (TDLS_LINK_HIS_OTHERS_T
*)prOthers
;
4367 if (prHisOthers
->fgIsHt
== TRUE
)
4368 prLink
->ucHtCap
|= TDLS_INFO_LINK_HT_CAP_SUP
;
4374 /*----------------------------------------------------------------------------*/
4375 /*! \brief This routine is called to update a disconnection event.
4377 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure
4378 * \param[in] pucPeerMac Pointer to the MAC of the TDLS peer
4379 * \param[in] eFmeStatus TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME
4380 * \param[in] pInfo other information
4384 /*----------------------------------------------------------------------------*/
4386 TdlsLinkHistoryRecordUpdate(
4387 GLUE_INFO_T
*prGlueInfo
,
4389 TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus
,
4393 TDLS_INFO_LINK_T
*prLink
;
4399 if ((eFmeStatus
< TDLS_HOST_EVENT_SF_BA
) ||
4400 (eFmeStatus
> TDLS_HOST_EVENT_SF_BA_RSP_DECLINE
))
4402 /* do not care these frames */
4407 ("<tdls_evt> %s: update history for "MACSTR
" %d %d\n",
4408 __FUNCTION__
, MAC2STR(pucPeerMac
), prGlueInfo
->rTdlsLink
.u4LinkIdx
,
4412 u4LinkIdx
= prGlueInfo
->rTdlsLink
.u4LinkIdx
;
4413 prLink
= &prGlueInfo
->rTdlsLink
.rLinkHistory
[u4LinkIdx
];
4415 /* TODO: need to search all entries to find it if we support multiple TDLS link design */
4416 if (kalMemCmp(&prLink
->aucPeerMac
, pucPeerMac
, 6) != 0)
4418 /* error! can not find the link entry */
4420 ("<tdls_evt> %s: cannot find the same entry!!!\n",
4426 u4Tid
= *(UINT32
*)pInfo
;
4429 case TDLS_HOST_EVENT_SF_BA
:
4430 prLink
->ucHtBa
[u4Tid
] |= TDLS_INFO_LINK_HT_BA_SETUP
;
4433 case TDLS_HOST_EVENT_SF_BA_OK
:
4434 prLink
->ucHtBa
[u4Tid
] |= TDLS_INFO_LINK_HT_BA_SETUP_OK
;
4437 case TDLS_HOST_EVENT_SF_BA_DECLINE
:
4438 prLink
->ucHtBa
[u4Tid
] |= TDLS_INFO_LINK_HT_BA_SETUP_DECLINE
;
4441 case TDLS_HOST_EVENT_SF_BA_PEER
:
4442 prLink
->ucHtBa
[u4Tid
] |= TDLS_INFO_LINK_HT_BA_PEER
;
4445 case TDLS_HOST_EVENT_SF_BA_RSP_OK
:
4446 prLink
->ucHtBa
[u4Tid
] |= TDLS_INFO_LINK_HT_BA_RSP_OK
;
4449 case TDLS_HOST_EVENT_SF_BA_RSP_DECLINE
:
4450 prLink
->ucHtBa
[u4Tid
] |= TDLS_INFO_LINK_HT_BA_RSP_DECLINE
;
4454 /* display TDLS link history */
4455 TdlsInfoDisplay(prGlueInfo
->prAdapter
, NULL
, 0, NULL
);
4459 /*----------------------------------------------------------------------------*/
4460 /*! \brief This routine is called to configure TDLS MIB parameters.
4462 * \param[in] prAdapter Pointer to the Adapter structure
4463 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
4464 * \param[in] u4SetBufferLen The length of the set buffer
4465 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
4466 * bytes read from the set buffer. If the call failed due to invalid length of
4467 * the set buffer, returns the amount of storage needed.
4469 * \retval TDLS_STATUS_xx
4472 /*----------------------------------------------------------------------------*/
4475 ADAPTER_T
*prAdapter
,
4477 UINT_32 u4SetBufferLen
,
4478 UINT_32
*pu4SetInfoLen
4481 TDLS_CMD_CORE_T
*prCmdContent
;
4482 WLAN_STATUS rStatus
;
4485 /* init command buffer */
4486 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
4487 prCmdContent
->u4Command
= TDLS_CORE_CMD_MIB_UPDATE
;
4489 /* send the command */
4490 rStatus
= wlanSendSetQueryCmd (
4491 prAdapter
, /* prAdapter */
4492 CMD_ID_TDLS_CORE
, /* ucCID */
4493 TRUE
, /* fgSetQuery */
4494 FALSE
, /* fgNeedResp */
4495 FALSE
, /* fgIsOid */
4497 NULL
, /* pfCmdTimeoutHandler */
4498 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
4499 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
4500 NULL
, /* pvSetQueryBuffer */
4501 0 /* u4SetQueryBufferLen */
4504 if (rStatus
!= WLAN_STATUS_PENDING
)
4506 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
4508 return TDLS_STATUS_RESOURCES
;
4511 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
4512 return TDLS_STATUS_SUCCESS
;
4516 /*----------------------------------------------------------------------------*/
4517 /*! \brief This routine is called to configure TDLS SETUP parameters.
4519 * \param[in] prAdapter Pointer to the Adapter structure
4520 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
4521 * \param[in] u4SetBufferLen The length of the set buffer
4522 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
4523 * bytes read from the set buffer. If the call failed due to invalid length of
4524 * the set buffer, returns the amount of storage needed.
4526 * \retval TDLS_STATUS_xx
4529 /*----------------------------------------------------------------------------*/
4532 ADAPTER_T
*prAdapter
,
4534 UINT_32 u4SetBufferLen
,
4535 UINT_32
*pu4SetInfoLen
4538 TDLS_CMD_CORE_T
*prCmdContent
;
4539 WLAN_STATUS rStatus
;
4542 /* init command buffer */
4543 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
4544 prCmdContent
->u4Command
= TDLS_CORE_CMD_SETUP_CONF
;
4546 /* send the command */
4547 rStatus
= wlanSendSetQueryCmd (
4548 prAdapter
, /* prAdapter */
4549 CMD_ID_TDLS_CORE
, /* ucCID */
4550 TRUE
, /* fgSetQuery */
4551 FALSE
, /* fgNeedResp */
4552 FALSE
, /* fgIsOid */
4554 NULL
, /* pfCmdTimeoutHandler */
4555 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
4556 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
4557 NULL
, /* pvSetQueryBuffer */
4558 0 /* u4SetQueryBufferLen */
4561 if (rStatus
!= WLAN_STATUS_PENDING
)
4563 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
4565 return TDLS_STATUS_RESOURCES
;
4568 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
4569 return TDLS_STATUS_SUCCESS
;
4573 /*----------------------------------------------------------------------------*/
4574 /*! \brief This routine is called to configure UAPSD parameters.
4576 * \param[in] prAdapter Pointer to the Adapter structure
4577 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
4578 * \param[in] u4SetBufferLen The length of the set buffer
4579 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
4580 * bytes read from the set buffer. If the call failed due to invalid length of
4581 * the set buffer, returns the amount of storage needed.
4583 * \retval TDLS_STATUS_xx
4586 /*----------------------------------------------------------------------------*/
4589 ADAPTER_T
*prAdapter
,
4591 UINT_32 u4SetBufferLen
,
4592 UINT_32
*pu4SetInfoLen
4595 TDLS_CMD_CORE_T
*prCmdContent
;
4596 WLAN_STATUS rStatus
;
4599 /* init command buffer */
4600 prCmdContent
= (TDLS_CMD_CORE_T
*)pvSetBuffer
;
4601 prCmdContent
->u4Command
= TDLS_CORE_CMD_UAPSD_CONF
;
4603 /* send the command */
4604 rStatus
= wlanSendSetQueryCmd (
4605 prAdapter
, /* prAdapter */
4606 CMD_ID_TDLS_CORE
, /* ucCID */
4607 TRUE
, /* fgSetQuery */
4608 FALSE
, /* fgNeedResp */
4609 FALSE
, /* fgIsOid */
4611 NULL
, /* pfCmdTimeoutHandler */
4612 sizeof(TDLS_CMD_CORE_T
), /* u4SetQueryInfoLen */
4613 (PUINT_8
) prCmdContent
, /* pucInfoBuffer */
4614 NULL
, /* pvSetQueryBuffer */
4615 0 /* u4SetQueryBufferLen */
4618 if (rStatus
!= WLAN_STATUS_PENDING
)
4620 DBGLOG(TDLS
, ERROR
, ("%s wlanSendSetQueryCmd allocation fail!\n",
4622 return TDLS_STATUS_RESOURCES
;
4625 DBGLOG(TDLS
, INFO
, ("%s cmd ok.\n", __FUNCTION__
));
4626 return TDLS_STATUS_SUCCESS
;
4630 /*----------------------------------------------------------------------------*/
4631 /*! \brief This routine is called to update frame status.
4633 * \param[in] prGlueInfo Pointer to the Adapter structure
4634 * \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId
4635 * \param[in] u4InBufLen The length of the buffer
4641 /*----------------------------------------------------------------------------*/
4644 GLUE_INFO_T
*prGlueInfo
,
4649 TDLS_EVENT_HOST_SUBID_SPECIFIC_FRAME eFmeStatus
;
4650 STA_RECORD_T
*prStaRec
;
4655 u4Tid
= *(UINT32
*)prInBuf
;
4656 prInBuf
+= 4; /* skip u4EventSubId */
4659 prStaRec
= cnmGetStaRecByIndex(prGlueInfo
->prAdapter
, *prInBuf
);
4660 if ((prStaRec
== NULL
) || (!IS_TDLS_STA(prStaRec
)))
4665 eFmeStatus
= *prInBuf
;
4666 TdlsLinkHistoryRecordUpdate(prGlueInfo
, prStaRec
->aucMacAddr
,
4667 eFmeStatus
, &u4Tid
);
4671 /*----------------------------------------------------------------------------*/
4672 /*! \brief This routine is called to collect TDLS statistics from firmware.
4674 * \param[in] prGlueInfo Pointer to the Adapter structure
4675 * \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId
4676 * \param[in] u4InBufLen The length of the buffer
4682 /*----------------------------------------------------------------------------*/
4684 TdlsEventStatistics(
4685 GLUE_INFO_T
*prGlueInfo
,
4690 STA_RECORD_T
*prStaRec
;
4691 STAT_CNT_INFO_FW_T
*prStat
;
4696 prStaRec
= cnmGetStaRecByIndex(prGlueInfo
->prAdapter
, *prInBuf
);
4697 if ((prStaRec
== NULL
) || (!IS_TDLS_STA(prStaRec
)))
4700 prInBuf
+= 4; /* skip prStaRec->ucIndex */
4702 /* update statistics */
4703 kalMemCopy(&prStaRec
->rTdlsStatistics
.rFw
, prInBuf
,\
4704 sizeof(prStaRec
->rTdlsStatistics
.rFw
));
4706 /* display statistics */
4707 prStat
= &prStaRec
->rTdlsStatistics
.rFw
;
4709 DBGLOG(TDLS
, TRACE
, ("<tdls_evt> peer ["MACSTR
"] statistics:\n",
4710 MAC2STR(prStaRec
->aucMacAddr
)));
4711 DBGLOG(TDLS
, TRACE
, ("\t\tT%d %d %d (P%d %d) (%dus) - E%d 0x%x - R%d (P%d)\n",
4712 prStat
->u4NumOfTx
, prStat
->u4NumOfTxOK
, prStat
->u4NumOfTxRetry
,
4713 prStat
->u4NumOfPtiRspTxOk
, prStat
->u4NumOfPtiRspTxErr
,
4714 prStat
->u4TxDoneAirTimeMax
,
4715 prStat
->u4NumOfTxErr
, prStat
->u4TxErrBitmap
,
4716 prStat
->u4NumOfRx
, prStat
->u4NumOfPtiRspRx
));
4718 DBGLOG(TDLS
, TRACE
, ("\t\t"));
4720 for(u4RateId
=prStat
->u4TxRateOkHisId
;
4721 u4RateId
<STAT_CNT_INFO_MAX_TX_RATE_OK_HIS_NUM
;
4724 printk("%d(%d) ", prStat
->aucTxRateOkHis
[u4RateId
][0],
4725 prStat
->aucTxRateOkHis
[u4RateId
][1]);
4728 u4RateId
<prStat
->u4TxRateOkHisId
;
4731 printk("%d(%d) ", prStat
->aucTxRateOkHis
[u4RateId
][0],
4732 prStat
->aucTxRateOkHis
[u4RateId
][1]);
4741 /*----------------------------------------------------------------------------*/
4742 /*! \brief This routine is called to do tear down.
4744 * \param[in] prGlueInfo Pointer to the Adapter structure
4745 * \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId
4746 * \param[in] u4InBufLen The length of the buffer
4752 /*----------------------------------------------------------------------------*/
4755 GLUE_INFO_T
*prGlueInfo
,
4760 STA_RECORD_T
*prStaRec
;
4761 UINT16 u2ReasonCode
;
4762 UINT32 u4TearDownSubId
;
4763 UINT8
*pMac
, aucZeroMac
[6];
4767 u4TearDownSubId
= *(UINT32
*)prInBuf
;
4768 kalMemZero(aucZeroMac
, sizeof(aucZeroMac
));
4771 prStaRec
= cnmGetStaRecByIndex(prGlueInfo
->prAdapter
, *(prInBuf
+4));
4772 if (prStaRec
!= NULL
)
4773 pMac
= prStaRec
->aucMacAddr
;
4776 if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_PTI_TIMEOUT
)
4778 DBGLOG(TDLS
, WARN
, ("<tdls_evt> %s: peer ["MACSTR
"] Reason=PTI timeout\n",
4779 __FUNCTION__
, MAC2STR(pMac
)));
4781 else if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_AGE_TIMEOUT
)
4783 DBGLOG(TDLS
, WARN
, ("<tdls_evt> %s: peer ["MACSTR
"] Reason=AGE timeout\n",
4784 __FUNCTION__
, MAC2STR(pMac
)));
4788 DBGLOG(TDLS
, WARN
, ("<tdls_evt> %s: peer ["MACSTR
"] Reason=%d\n",
4789 __FUNCTION__
, MAC2STR(pMac
), u4TearDownSubId
));
4793 if (prStaRec
== NULL
)
4796 if (fgIsPtiTimeoutSkip
== TRUE
)
4798 /* skip PTI timeout event */
4799 if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_PTI_TIMEOUT
)
4801 DBGLOG(TDLS
, WARN
, ("<tdls_evt> %s: skip PTI timeout\n",
4807 /* record history */
4808 if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_AGE_TIMEOUT
)
4809 u2ReasonCode
= TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT
;
4810 else if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_PTI_TIMEOUT
)
4811 u2ReasonCode
= TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT
;
4812 else if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_PTI_SEND_FAIL
)
4813 u2ReasonCode
= TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_FAIL
;
4814 else if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_PTI_SEND_MAX_FAIL
)
4815 u2ReasonCode
= TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_SEND_MAX_FAIL
;
4816 else if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_WRONG_NETWORK_IDX
)
4817 u2ReasonCode
= TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_WRONG_NETWORK_IDX
;
4818 else if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_NON_STATE3
)
4819 u2ReasonCode
= TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_NON_STATE3
;
4820 else if (u4TearDownSubId
== TDLS_HOST_EVENT_TD_LOST_TEAR_DOWN
)
4821 u2ReasonCode
= TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_LOST_TEAR_DOWN
;
4824 /* shall not be here */
4825 u2ReasonCode
= TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_UNKNOWN
;
4828 TdlsLinkHistoryRecord(prGlueInfo
, TRUE
, prStaRec
->aucMacAddr
, TRUE
,
4829 u2ReasonCode
, NULL
);
4831 /* correct correct reason code for PTI or AGE timeout to supplicant */
4832 if ((u2ReasonCode
== TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_AGE_TIMEOUT
) ||
4833 (u2ReasonCode
== TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_PTI_TIMEOUT
))
4835 u2ReasonCode
= TDLS_REASON_CODE_UNREACHABLE
;
4838 /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */
4839 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
4840 cfg80211_tdls_oper_request(prGlueInfo
->prDevHandler
,
4841 prStaRec
->aucMacAddr
, TDLS_FRM_ACTION_TEARDOWN
, u2ReasonCode
, GFP_ATOMIC
);
4843 cfg80211_tdls_oper_request(prGlueInfo
->prDevHandler
,
4844 prStaRec
->aucMacAddr
, NL80211_TDLS_TEARDOWN
, u2ReasonCode
, GFP_ATOMIC
);
4849 /*----------------------------------------------------------------------------*/
4850 /*! \brief This routine is called to do tx down.
4852 * \param[in] prGlueInfo Pointer to the Adapter structure
4853 * \param[in] prInBuf A pointer to the command string buffer, from u4EventSubId
4854 * \param[in] u4InBufLen The length of the buffer
4860 /*----------------------------------------------------------------------------*/
4863 GLUE_INFO_T
*prGlueInfo
,
4873 ucErrStatus
= *(UINT32
*)prInBuf
;
4875 pucFmeHdr
= prInBuf
+4; /* skip ucErrStatus */
4877 if (ucErrStatus
== 0)
4880 ("<tdls_evt> %s: OK to tx a TDLS action:",
4886 ("<tdls_evt> %s: fail to tx a TDLS action (err=0x%x):",
4887 __FUNCTION__
, ucErrStatus
));
4890 /* dump TX packet content from wlan header */
4891 for(u4FmeIdx
=0; u4FmeIdx
<(u4InBufLen
-4); u4FmeIdx
++)
4893 if ((u4FmeIdx
% 16) == 0)
4898 printk("%02x ", *pucFmeHdr
++);
4905 /*******************************************************************************
4906 * P U B L I C F U N C T I O N S
4907 ********************************************************************************
4910 /*----------------------------------------------------------------------------*/
4911 /*! \brief This routine is called to parse TDLS Extended Capabilities element.
4913 * \param[in] prGlueInfo Pointer to the Adapter structure
4914 * \param[in] prInBuf A pointer to the command string buffer
4915 * \param[in] u4InBufLen The length of the buffer
4920 /*----------------------------------------------------------------------------*/
4922 TdlsexBssExtCapParse(
4923 STA_RECORD_T
*prStaRec
,
4927 UINT_8
*pucIeExtCap
;
4931 if ((prStaRec
== NULL
) || (pucIE
== NULL
))
4934 if (IE_ID(pucIE
) != ELEM_ID_EXTENDED_CAP
)
4940 bit 38: TDLS Prohibited
4941 The TDLS Prohibited subfield indicates whether the use of TDLS is prohibited. The
4942 field is set to 1 to indicate that TDLS is prohibited and to 0 to indicate that TDLS is
4945 if (IE_LEN(pucIE
) < 5)
4946 return; /* we need 39/8 = 5 bytes */
4949 prStaRec
->fgTdlsIsProhibited
= FALSE
;
4950 prStaRec
->fgTdlsIsChSwProhibited
= FALSE
;
4953 pucIeExtCap
= pucIE
+ 2;
4954 pucIeExtCap
+= 4; /* shift to the byte we care about */
4956 if ((*pucIeExtCap
) && BIT(38-32))
4957 prStaRec
->fgTdlsIsProhibited
= TRUE
;
4958 if ((*pucIeExtCap
) && BIT(39-32))
4959 prStaRec
->fgTdlsIsChSwProhibited
= TRUE
;
4962 ("<tdls> %s: AP ["MACSTR
"] tdls prohibit bit=%d %d\n",
4964 MAC2STR(prStaRec
->aucMacAddr
),
4965 prStaRec
->fgTdlsIsProhibited
,
4966 prStaRec
->fgTdlsIsChSwProhibited
));
4970 /*----------------------------------------------------------------------------*/
4972 * \brief This routine is called to transmit a TDLS data frame from nl80211.
4974 * \param[in] pvAdapter Pointer to the Adapter structure.
4977 * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
4979 * \retval WLAN_STATUS_SUCCESS
4980 * \retval WLAN_STATUS_INVALID_LENGTH
4982 /*----------------------------------------------------------------------------*/
4984 TdlsexCfg80211TdlsMgmt(
4985 struct wiphy
*wiphy
,
4986 struct net_device
*dev
,
4995 ADAPTER_T
*prAdapter
;
4996 GLUE_INFO_T
*prGlueInfo
;
4997 BSS_INFO_T
*prAisBssInfo
;
4998 WLAN_STATUS rStatus
;
5000 TDLS_MGMT_TX_INFO
*prMgmtTxInfo
;
5004 Have correct behavior for STAUT receiving TDLS Setup Request after sending TDLS
5005 Set Request and before receiving TDLS Setup Response:
5006 -- Source Address of received Request is higher than own MAC address
5007 -- Source Address of received Request is lower than own MAC address
5009 ==> STA with larger MAC address will send the response frame.
5011 Supplicant will do this in wpa_tdls_process_tpk_m1().
5015 if ((wiphy
== NULL
) || (peer
== NULL
))
5018 ("<tdls_cfg> %s: wrong 0x%p 0x%p!\n",
5019 __FUNCTION__
, wiphy
, peer
));
5023 DBGLOG(TDLS
, INFO
, ("<tdls_cfg> %s: ["MACSTR
"] %d %d %d 0x%p %u\n",
5024 __FUNCTION__
, MAC2STR(peer
),
5025 action_code
, dialog_token
, status_code
, buf
, (UINT32
)len
));
5028 prGlueInfo
= (GLUE_INFO_T
*) wiphy_priv(wiphy
);
5029 if (prGlueInfo
== NULL
)
5032 ("<tdls_cfg> %s: wrong prGlueInfo 0x%p!\n",
5033 __FUNCTION__
, prGlueInfo
));
5037 prAdapter
= prGlueInfo
->prAdapter
;
5038 if (prAdapter
->fgTdlsIsSup
== FALSE
)
5041 ("<tdls_cfg> %s: firmware TDLS is not supported!\n",
5046 prAisBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
5047 if (prAisBssInfo
->fgTdlsIsProhibited
== TRUE
)
5049 /* do not send anything if TDLS is prohibited in the BSS */
5053 prMgmtTxInfo
= kalMemAlloc(sizeof(TDLS_MGMT_TX_INFO
), VIR_MEM_TYPE
);
5054 if (prMgmtTxInfo
== NULL
)
5057 ("<tdls_cfg> %s: allocate fail!\n",
5062 kalMemZero(prMgmtTxInfo
, sizeof(TDLS_MGMT_TX_INFO
));
5065 kalMemCopy(prMgmtTxInfo
->aucPeer
, peer
, 6);
5066 prMgmtTxInfo
->ucActionCode
= action_code
;
5067 prMgmtTxInfo
->ucDialogToken
= dialog_token
;
5068 prMgmtTxInfo
->u2StatusCode
= status_code
;
5072 if (len
> sizeof(prMgmtTxInfo
->aucSecBuf
))
5074 kalMemFree(prMgmtTxInfo
, VIR_MEM_TYPE
, sizeof(TDLS_MGMT_TX_INFO
));
5077 prMgmtTxInfo
->u4SecBufLen
= len
;
5078 kalMemCopy(prMgmtTxInfo
->aucSecBuf
, buf
, len
);
5081 /* send the TDLS action data frame */
5082 rStatus
= kalIoctl(prGlueInfo
,
5085 sizeof(TDLS_MGMT_TX_INFO
),
5093 clear all content to avoid any bug if we dont yet execute TdlsexMgmtCtrl()
5094 then kalIoctl finishes
5096 kalMemZero(prMgmtTxInfo
, sizeof(TDLS_MGMT_TX_INFO
));
5098 if (rStatus
!= WLAN_STATUS_SUCCESS
)
5101 ("%s enable or disable link fail:%x\n", __FUNCTION__
, rStatus
));
5102 kalMemFree(prMgmtTxInfo
, VIR_MEM_TYPE
, sizeof(TDLS_MGMT_TX_INFO
));
5106 kalMemFree(prMgmtTxInfo
, VIR_MEM_TYPE
, sizeof(TDLS_MGMT_TX_INFO
));
5111 /*----------------------------------------------------------------------------*/
5113 * \brief This routine is called to enable or disable TDLS link from upper layer.
5115 * \param[in] pvAdapter Pointer to the Adapter structure.
5118 * \param[in] buf includes RSN IE + FT IE + Lifetimeout IE
5120 * \retval WLAN_STATUS_SUCCESS
5121 * \retval WLAN_STATUS_INVALID_LENGTH
5123 /*----------------------------------------------------------------------------*/
5125 TdlsexCfg80211TdlsOper(
5126 struct wiphy
*wiphy
,
5127 struct net_device
*dev
,
5129 enum nl80211_tdls_operation oper
5132 ADAPTER_T
*prAdapter
;
5133 GLUE_INFO_T
*prGlueInfo
;
5134 WLAN_STATUS rStatus
;
5136 TDLS_CMD_LINK_T rCmdLink
;
5142 DBGLOG(TDLS
, ERROR
, ("<tdls_cfg> %s: peer == NULL!\n", __FUNCTION__
));
5146 DBGLOG(TDLS
, INFO
, ("<tdls_cfg> %s: ["MACSTR
"] %d %d\n",
5147 __FUNCTION__
, MAC2STR(peer
), oper
,
5148 (wiphy
->flags
& WIPHY_FLAG_SUPPORTS_TDLS
)));
5150 if (!(wiphy
->flags
& WIPHY_FLAG_SUPPORTS_TDLS
))
5154 prGlueInfo
= (GLUE_INFO_T
*) wiphy_priv(wiphy
);
5155 if (prGlueInfo
== NULL
)
5158 ("<tdls_cfg> %s: wrong prGlueInfo 0x%p!\n",
5159 __FUNCTION__
, prGlueInfo
));
5162 prAdapter
= prGlueInfo
->prAdapter
;
5163 kalMemCopy(rCmdLink
.aucPeerMac
, peer
, sizeof(rCmdLink
.aucPeerMac
));
5164 rCmdLink
.fgIsEnabled
= FALSE
;
5167 enum nl80211_tdls_operation {
5168 NL80211_TDLS_DISCOVERY_REQ,
5170 NL80211_TDLS_TEARDOWN,
5171 NL80211_TDLS_ENABLE_LINK,
5172 NL80211_TDLS_DISABLE_LINK,
5178 case NL80211_TDLS_ENABLE_LINK
:
5179 rCmdLink
.fgIsEnabled
= TRUE
;
5182 case NL80211_TDLS_DISABLE_LINK
:
5183 rCmdLink
.fgIsEnabled
= FALSE
;
5186 case NL80211_TDLS_TEARDOWN
:
5187 case NL80211_TDLS_SETUP
:
5188 case NL80211_TDLS_DISCOVERY_REQ
:
5189 /* we do not support setup/teardown/discovery from driver */
5196 /* enable or disable TDLS link */
5197 rStatus
= kalIoctl(prGlueInfo
,
5200 sizeof(TDLS_CMD_LINK_T
),
5207 if (rStatus
!= WLAN_STATUS_SUCCESS
)
5210 ("%s enable or disable link fail:%x\n", __FUNCTION__
, rStatus
));
5218 /*----------------------------------------------------------------------------*/
5219 /*! \brief This routine is called to send a command to TDLS module.
5221 * \param[in] prGlueInfo Pointer to the Adapter structure
5222 * \param[in] prInBuf A pointer to the command string buffer
5223 * \param[in] u4InBufLen The length of the buffer
5228 /*----------------------------------------------------------------------------*/
5231 P_GLUE_INFO_T prGlueInfo
,
5239 /* parse TDLS sub-command */
5240 u4Subcmd
= CmdStringDecParse(prInBuf
, &prInBuf
, &u4InBufLen
);
5241 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> sub command = %u\n", (UINT32
)u4Subcmd
));
5243 /* handle different sub-command */
5246 #if TDLS_CFG_CMD_TEST /* only for unit test */
5247 case TDLS_CMD_TEST_TX_FRAME
:
5248 /* simulate to send a TDLS frame */
5249 TdlsCmdTestTxFrame(prGlueInfo
, prInBuf
, u4InBufLen
);
5252 case TDLS_CMD_TEST_TX_TDLS_FRAME
:
5253 /* simulate to send a TDLS frame from supplicant */
5254 TdlsCmdTestTxTdlsFrame(prGlueInfo
, prInBuf
, u4InBufLen
);
5257 case TDLS_CMD_TEST_RCV_FRAME
:
5258 /* simulate to receive a TDLS frame */
5259 TdlsCmdTestRvFrame(prGlueInfo
, prInBuf
, u4InBufLen
);
5262 case TDLS_CMD_TEST_PEER_ADD
:
5263 /* simulate to add a TDLS peer */
5264 TdlsCmdTestAddPeer(prGlueInfo
, prInBuf
, u4InBufLen
);
5267 case TDLS_CMD_TEST_PEER_UPDATE
:
5268 /* simulate to update a TDLS peer */
5269 TdlsCmdTestUpdatePeer(prGlueInfo
, prInBuf
, u4InBufLen
);
5272 case TDLS_CMD_TEST_DATA_FRAME
:
5273 /* simulate to send a data frame to the peer */
5274 TdlsCmdTestDataSend(prGlueInfo
, prInBuf
, u4InBufLen
);
5277 case TDLS_CMD_TEST_RCV_NULL
:
5278 /* simulate to receive a QoS null frame from the peer */
5279 TdlsCmdTestNullRecv(prGlueInfo
, prInBuf
, u4InBufLen
);
5282 case TDLS_CMD_TEST_SKIP_TX_FAIL
:
5283 /* command firmware to skip tx fail case */
5284 TdlsCmdTestTxFailSkip(prGlueInfo
, prInBuf
, u4InBufLen
);
5287 case TDLS_CMD_TEST_SKIP_KEEP_ALIVE
:
5288 /* command firmware to skip keep alive function */
5289 TdlsCmdTestKeepAliveSkip(prGlueInfo
, prInBuf
, u4InBufLen
);
5292 case TDLS_CMD_TEST_SKIP_CHSW_TIMEOUT
:
5293 /* command firmware to skip channel switch timeout function */
5294 TdlsCmdTestChSwTimeoutSkip(prGlueInfo
, prInBuf
, u4InBufLen
);
5297 case TDLS_CMD_TEST_PROHIBIT_SET_IN_AP
:
5298 /* simulate to set Prohibited Bit in AP */
5299 TdlsCmdTestProhibitedBitSet(prGlueInfo
, prInBuf
, u4InBufLen
);
5302 case TDLS_CMD_TEST_SCAN_DISABLE
:
5303 /* command to disable scan request to do channel switch */
5304 TdlsCmdTestScanCtrl(prGlueInfo
, prInBuf
, u4InBufLen
);
5307 case TDLS_CMD_TEST_DATA_FRAME_CONT
:
5308 /* simulate to send a data frame to the peer periodically */
5309 TdlsCmdTestDataContSend(prGlueInfo
, prInBuf
, u4InBufLen
);
5312 case TDLS_CMD_TEST_CH_SW_PROHIBIT_SET_IN_AP
:
5313 /* simulate to set channel switch Prohibited Bit in AP */
5314 TdlsCmdTestChSwProhibitedBitSet(prGlueInfo
, prInBuf
, u4InBufLen
);
5317 case TDLS_CMD_TEST_DELAY
:
5319 TdlsCmdTestDelay(prGlueInfo
, prInBuf
, u4InBufLen
);
5322 case TDLS_CMD_TEST_PTI_TX_FAIL
:
5323 /* simulate the tx done fail for PTI */
5324 TdlsCmdTestPtiTxDoneFail(prGlueInfo
, prInBuf
, u4InBufLen
);
5326 #endif /* TDLS_CFG_CMD_TEST */
5328 case TDLS_CMD_MIB_UPDATE
:
5329 /* update MIB parameters */
5330 TdlsCmdMibParamUpdate(prGlueInfo
, prInBuf
, u4InBufLen
);
5333 case TDLS_CMD_UAPSD_CONF
:
5334 /* config UAPSD parameters */
5335 TdlsCmdUapsdConf(prGlueInfo
, prInBuf
, u4InBufLen
);
5338 case TDLS_CMD_CH_SW_CONF
:
5339 /* enable or disable or start or stop channel switch function */
5340 TdlsCmdChSwConf(prGlueInfo
, prInBuf
, u4InBufLen
);
5343 case TDLS_CMD_SETUP_CONF
:
5344 /* config setup parameters */
5345 TdlsCmdSetupConf(prGlueInfo
, prInBuf
, u4InBufLen
);
5349 /* display all TDLS information */
5350 TdlsCmdInfoDisplay(prGlueInfo
, prInBuf
, u4InBufLen
);
5353 case TDLS_CMD_KEY_INFO
:
5354 /* display key information */
5355 TdlsCmdKeyInfoDisplay(prGlueInfo
, prInBuf
, u4InBufLen
);
5364 /*----------------------------------------------------------------------------*/
5365 /*! \brief This routine is called to record a disconnection event.
5367 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure
5368 * \param[in] fgIsTearDown TRUE: tear down
5369 * \param[in] pucPeerMac Pointer to the MAC of the TDLS peer
5370 * \param[in] fgIsFromUs TRUE: tear down is from us
5371 * \param[in] u2ReasonCode Disconnection reason (TDLS_REASON_CODE)
5376 /*----------------------------------------------------------------------------*/
5378 TdlsexLinkHistoryRecord(
5379 GLUE_INFO_T
*prGlueInfo
,
5380 BOOLEAN fgIsTearDown
,
5387 if ((prGlueInfo
== NULL
) || (pucPeerMac
== NULL
))
5391 ("<tdls_evt> %s: Rcv a inform from "MACSTR
" %d %d\n",
5392 __FUNCTION__
, MAC2STR(pucPeerMac
), fgIsFromUs
, u2ReasonCode
));
5395 TdlsLinkHistoryRecord(prGlueInfo
, fgIsTearDown
, pucPeerMac
,\
5396 fgIsFromUs
, u2ReasonCode
, NULL
);
5400 /*----------------------------------------------------------------------------*/
5401 /*! \brief This routine is called to send a command to TDLS module.
5403 * \param[in] prGlueInfo Pointer to the Adapter structure
5404 * \param[in] prInBuf A pointer to the command string buffer
5405 * \param[in] u4InBufLen The length of the buffer
5410 /*----------------------------------------------------------------------------*/
5413 GLUE_INFO_T
*prGlueInfo
,
5422 if ((prGlueInfo
== NULL
) || (prInBuf
== NULL
))
5423 return; /* shall not be here */
5426 u4EventId
= *(UINT32
*)prInBuf
;
5430 ("<tdls> %s: Rcv a event: %d\n", __FUNCTION__
, u4EventId
));
5434 case TDLS_HOST_EVENT_TEAR_DOWN
:
5435 TdlsEventTearDown(prGlueInfo
, prInBuf
+4, u4InBufLen
);
5438 case TDLS_HOST_EVENT_TX_DONE
:
5439 TdlsEventTxDone(prGlueInfo
, prInBuf
+4, u4InBufLen
);
5442 case TDLS_HOST_EVENT_FME_STATUS
:
5443 TdlsEventFmeStatus(prGlueInfo
, prInBuf
+4, u4InBufLen
);
5446 case TDLS_HOST_EVENT_STATISTICS
:
5447 TdlsEventStatistics(prGlueInfo
, prInBuf
+4, u4InBufLen
);
5453 /*----------------------------------------------------------------------------*/
5455 * @brief This function is used to initialize variables in TDLS.
5457 * \param[in] prAdapter Pointer to the Adapter structure
5459 * @return TDLS_STATUS_SUCCESS: do not set key and key infor. is queued
5460 TDLS_STATUS_FAILURE: set key
5462 /*----------------------------------------------------------------------------*/
5465 ADAPTER_T
*prAdapter
,
5466 PARAM_KEY_T
*prNewKey
5469 STA_RECORD_T
*prStaRec
;
5473 if ((prAdapter
== NULL
) || (prNewKey
== NULL
))
5474 return TDLS_STATUS_FAILURE
;
5477 supplicant will set key before updating station & enabling the link so we need to
5478 backup the key information and set key when link is enabled
5480 prStaRec
= cnmGetStaRecByAddress(\
5481 prAdapter
, NETWORK_TYPE_AIS_INDEX
, prNewKey
->arBSSID
);
5482 if ((prStaRec
!= NULL
) && IS_TDLS_STA(prStaRec
))
5484 DBGLOG(TDLS
, TRACE
, ("<tdls> %s: ["MACSTR
"] queue key (len=%d) "
5485 "until link is enabled\n",
5486 __FUNCTION__
, MAC2STR(prNewKey
->arBSSID
),
5487 (UINT32
)prNewKey
->u4KeyLength
));
5489 if (prStaRec
->ucStaState
== STA_STATE_3
)
5491 DBGLOG(TDLS
, TRACE
, ("<tdls> %s: ["MACSTR
"] tear down the link "
5492 "due to STA_STATE_3\n",
5493 __FUNCTION__
, MAC2STR(prNewKey
->arBSSID
)));
5496 TdlsLinkHistoryRecord(prAdapter
->prGlueInfo
, TRUE
,
5497 prStaRec
->aucMacAddr
, TRUE
,
5498 TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY
, NULL
);
5500 /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */
5501 cfg80211_tdls_oper_request(prAdapter
->prGlueInfo
->prDevHandler
,
5502 prStaRec
->aucMacAddr
, TDLS_FRM_ACTION_TEARDOWN
,
5503 TDLS_REASON_CODE_UNSPECIFIED
, GFP_ATOMIC
);
5504 return TDLS_STATUS_SUCCESS
;
5507 /* backup the key */
5508 kalMemCopy(&prStaRec
->rTdlsKeyTemp
, prNewKey
, sizeof(prStaRec
->rTdlsKeyTemp
));
5509 return TDLS_STATUS_SUCCESS
;
5512 return TDLS_STATUS_FAILURE
;
5516 /*----------------------------------------------------------------------------*/
5518 * @brief This function is used to initialize variables in TDLS.
5520 * \param[in] prAdapter Pointer to the Adapter structure
5524 /*----------------------------------------------------------------------------*/
5527 ADAPTER_T
*prAdapter
5530 GLUE_INFO_T
*prGlueInfo
;
5534 prGlueInfo
= (GLUE_INFO_T
*)prAdapter
->prGlueInfo
;
5537 kalMemZero(&prGlueInfo
->rTdlsLink
, sizeof(prGlueInfo
->rTdlsLink
));
5541 /*----------------------------------------------------------------------------*/
5543 * \brief This routine is called to get any peer is in power save.
5545 * \param[in] prAdapter Pointer to the Adapter structure
5547 * \retval TRUE (at least one peer is in power save)
5549 /*----------------------------------------------------------------------------*/
5551 TdlsexIsAnyPeerInPowerSave(
5552 ADAPTER_T
*prAdapter
5555 STA_RECORD_T
*prStaRec
;
5556 UINT32 u4StaId
, u4StartIdx
;
5559 for(u4StaId
=0, u4StartIdx
=0; u4StaId
<CFG_STA_REC_NUM
; u4StaId
++)
5561 /* list all TDLS peers */
5562 prStaRec
= cnmStaTheTypeGet(prAdapter
, NETWORK_TYPE_AIS_INDEX
,
5563 STA_TYPE_TDLS_PEER
, &u4StartIdx
);
5564 if (prStaRec
== NULL
)
5567 if (prStaRec
->fgIsInPS
== TRUE
)
5569 printk("<tx> yes, at least one peer is in ps\n");
5578 /*----------------------------------------------------------------------------*/
5580 * \brief This routine is called to enable or disable a TDLS link.
5582 * \param[in] prAdapter Pointer to the Adapter structure
5583 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
5584 * \param[in] u4SetBufferLen The length of the set buffer
5585 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
5586 * bytes read from the set buffer. If the call failed due to invalid length of
5587 * the set buffer, returns the amount of storage needed.
5589 * \retval TDLS_STATUS_xx
5591 /*----------------------------------------------------------------------------*/
5594 ADAPTER_T
*prAdapter
,
5596 UINT_32 u4SetBufferLen
,
5597 UINT_32
*pu4SetInfoLen
5600 GLUE_INFO_T
*prGlueInfo
;
5601 TDLS_CMD_LINK_T
*prCmd
;
5602 BSS_INFO_T
*prBssInfo
;
5603 STA_RECORD_T
*prStaRec
;
5604 TDLS_LINK_HIS_OTHERS_T rHisOthers
;
5608 if ((prAdapter
== NULL
) || (pvSetBuffer
== NULL
) || (pu4SetInfoLen
== NULL
))
5611 ("<tdls_cmd> %s: sanity fail!\n", __FUNCTION__
));
5612 return TDLS_STATUS_FAILURE
;
5616 prGlueInfo
= (GLUE_INFO_T
*)prAdapter
->prGlueInfo
;
5617 *pu4SetInfoLen
= sizeof(TDLS_CMD_LINK_T
);
5618 prCmd
= (TDLS_CMD_LINK_T
*)pvSetBuffer
;
5620 /* search old entry */
5621 prStaRec
= cnmGetStaRecByAddress(prAdapter
,
5622 (UINT_8
) NETWORK_TYPE_AIS_INDEX
,
5624 if (prStaRec
== NULL
)
5626 DBGLOG(TDLS
, ERROR
, ("<tdls_cfg> %s: cannot find the peer! "MACSTR
"\n",
5627 __FUNCTION__
, MAC2STR(prCmd
->aucPeerMac
)));
5628 return TDLS_STATUS_FAILURE
;
5631 if (prCmd
->fgIsEnabled
== TRUE
)
5633 cnmStaRecChangeState(prAdapter
, prStaRec
, STA_STATE_3
);
5634 DBGLOG(TDLS
, TRACE
, ("<tdls_cfg> %s: NL80211_TDLS_ENABLE_LINK\n",
5637 /* update key information after cnmStaRecChangeState(STA_STATE_3) */
5638 prStaRec
->fgTdlsInSecurityMode
= FALSE
;
5640 if (prStaRec
->rTdlsKeyTemp
.u4Length
> 0)
5642 UINT_32 u4BufLen
; /* no use */
5644 DBGLOG(TDLS
, INFO
, ("<tdls_cfg> %s: key len=%d\n",
5645 __FUNCTION__
, (UINT32
)prStaRec
->rTdlsKeyTemp
.u4Length
));
5648 reminder the function that we are CIPHER_SUITE_CCMP,
5649 do not change cipher type to CIPHER_SUITE_WEP128
5651 _wlanoidSetAddKey(prAdapter
, &prStaRec
->rTdlsKeyTemp
,
5652 prStaRec
->rTdlsKeyTemp
.u4Length
, FALSE
, CIPHER_SUITE_CCMP
,
5655 /* clear the temp key */
5656 prStaRec
->fgTdlsInSecurityMode
= TRUE
;
5657 kalMemZero(&prStaRec
->rTdlsKeyTemp
, sizeof(prStaRec
->rTdlsKeyTemp
));
5660 /* check if we need to disable channel switch function */
5661 prBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[prStaRec
->ucNetTypeIndex
]);
5662 if (prBssInfo
->fgTdlsIsChSwProhibited
== TRUE
)
5664 TDLS_CMD_CORE_T rCmd
;
5665 kalMemZero(&rCmd
, sizeof(TDLS_CMD_CORE_T
));
5666 rCmd
.Content
.rCmdChSwConf
.ucNetTypeIndex
= prStaRec
->ucNetTypeIndex
;
5667 rCmd
.Content
.rCmdChSwConf
.fgIsChSwEnabled
= FALSE
;
5668 kalMemCopy(rCmd
.aucPeerMac
, prStaRec
->aucMacAddr
, 6);
5669 TdlsChSwConf(prAdapter
, &rCmd
, 0, 0);
5671 DBGLOG(TDLS
, INFO
, ("<tdls_cfg> %s: disable channel switch\n",
5675 TDLS_LINK_INCREASE(prGlueInfo
);
5678 if (prStaRec
->ucDesiredPhyTypeSet
& PHY_TYPE_SET_802_11N
)
5679 rHisOthers
.fgIsHt
= TRUE
;
5681 rHisOthers
.fgIsHt
= FALSE
;
5683 TdlsLinkHistoryRecord(prAdapter
->prGlueInfo
, FALSE
,
5684 prStaRec
->aucMacAddr
, !prStaRec
->flgTdlsIsInitiator
, 0, &rHisOthers
);
5688 cnmStaRecChangeState(prAdapter
, prStaRec
, STA_STATE_1
);
5689 cnmStaRecFree(prAdapter
, prStaRec
, TRUE
); /* release to other TDLS peers */
5690 DBGLOG(TDLS
, TRACE
, ("<tdls_cfg> %s: NL80211_TDLS_DISABLE_LINK\n",
5693 TDLS_LINK_DECREASE(prGlueInfo
);
5694 //while(1); //sample debug
5697 /* work-around link count */
5698 if ((TDLS_LINK_COUNT(prGlueInfo
) < 0) ||
5699 (TDLS_LINK_COUNT(prGlueInfo
) > 1))
5701 /* ERROR case: work-around to recount by searching all station records */
5704 TDLS_LINK_COUNT_RESET(prGlueInfo
);
5706 for(u4Idx
=0; u4Idx
<CFG_STA_REC_NUM
; u4Idx
++)
5708 prStaRec
= &prAdapter
->arStaRec
[u4Idx
];
5710 if (prStaRec
->fgIsInUse
&&
5711 IS_TDLS_STA(prStaRec
))
5713 TDLS_LINK_INCREASE(prGlueInfo
);
5717 if (TDLS_LINK_COUNT(prGlueInfo
) > 1)
5719 /* number of links is still > 1 */
5720 DBGLOG(TDLS
, INFO
, ("<tdls_cfg> %s: cTdlsLinkCnt %d > 1?\n",
5721 __FUNCTION__
, TDLS_LINK_COUNT(prGlueInfo
)));
5723 TDLS_LINK_COUNT_RESET(prGlueInfo
);
5725 /* free all TDLS links */
5726 for(u4Idx
=0; u4Idx
<CFG_STA_REC_NUM
; u4Idx
++)
5728 prStaRec
= &prAdapter
->arStaRec
[u4Idx
];
5730 if (prStaRec
->fgIsInUse
&&
5731 IS_TDLS_STA(prStaRec
))
5733 cnmStaRecFree(prAdapter
, prStaRec
, TRUE
);
5737 /* maybe inform supplicant ? */
5741 /* display TDLS link history */
5742 TdlsInfoDisplay(prAdapter
, NULL
, 0, NULL
);
5744 return TDLS_STATUS_SUCCESS
;
5748 /*----------------------------------------------------------------------------*/
5750 * \brief This routine is called to send a TDLS action data frame.
5752 * \param[in] prAdapter Pointer to the Adapter structure
5753 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
5754 * \param[in] u4SetBufferLen The length of the set buffer
5755 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
5756 * bytes read from the set buffer. If the call failed due to invalid length of
5757 * the set buffer, returns the amount of storage needed.
5759 * \retval TDLS_STATUS_xx
5761 /*----------------------------------------------------------------------------*/
5764 ADAPTER_T
*prAdapter
,
5766 UINT_32 u4SetBufferLen
,
5767 UINT_32
*pu4SetInfoLen
5770 GLUE_INFO_T
*prGlueInfo
;
5771 TDLS_MGMT_TX_INFO
*prMgmtTxInfo
;
5772 STA_RECORD_T
*prStaRec
;
5776 if ((prAdapter
== NULL
) || (pvSetBuffer
== NULL
) || (pu4SetInfoLen
== NULL
))
5779 ("<tdls_cmd> %s: sanity fail!\n", __FUNCTION__
));
5780 return TDLS_STATUS_FAILURE
;
5784 prGlueInfo
= (GLUE_INFO_T
*)prAdapter
->prGlueInfo
;
5785 *pu4SetInfoLen
= sizeof(TDLS_MGMT_TX_INFO
);
5786 prMgmtTxInfo
= (TDLS_MGMT_TX_INFO
*)pvSetBuffer
;
5788 switch(prMgmtTxInfo
->ucActionCode
)
5790 case TDLS_FRM_ACTION_DISCOVERY_RESPONSE
:
5794 case TDLS_FRM_ACTION_SETUP_REQ
:
5795 prStaRec
= cnmGetStaRecByAddress(prAdapter
,
5796 (UINT_8
) NETWORK_TYPE_AIS_INDEX
,
5797 prMgmtTxInfo
->aucPeer
);
5798 if ((prStaRec
!= NULL
) && (prStaRec
->ucStaState
== STA_STATE_3
))
5800 /* rekey? we reject re-setup link currently */
5801 /* TODO: Still can setup link during rekey */
5804 return success to avoid supplicant clear TDLS entry;
5805 Or we cannot send out any TDLS tear down frame to the peer
5808 ("<tdls_cmd> %s: skip new setup on the exist link!\n",
5810 return TDLS_STATUS_SUCCESS
;
5816 case TDLS_FRM_ACTION_SETUP_RSP
:
5817 case TDLS_FRM_ACTION_CONFIRM
:
5818 case TDLS_FRM_ACTION_TEARDOWN
:
5819 prStaRec
= cnmGetStaRecByAddress(prAdapter
,
5820 (UINT_8
) NETWORK_TYPE_AIS_INDEX
,
5821 prMgmtTxInfo
->aucPeer
);
5822 #if 0 /* in some cases, the prStaRec is still NULL */
5824 EX: if a peer sends us a TDLS setup request with wrong BSSID,
5825 supplicant will not call TdlsexPeerAdd() to create prStaRec and
5826 supplicant will send a TDLS setup response with status code 7.
5828 So in the case, prStaRec will be NULL.
5830 if (prStaRec
== NULL
)
5833 ("<tdls_cfg> %s: cannot find the peer!\n",
5841 TODO: Discovery response frame
5842 Note that the TDLS Discovery Response frame is not a TDLS frame but a 11
5843 Public Action frame.
5844 In WiFi TDLS Tech Minutes June 8 2010.doc,
5845 a public action frame (i.e. it is no longer an encapsulated data frame)
5850 ("<tdls_cfg> %s: wrong action_code %d!\n",
5851 __FUNCTION__
, prMgmtTxInfo
->ucActionCode
));
5852 return TDLS_STATUS_FAILURE
;
5855 /* send the TDLS data frame */
5856 if (prStaRec
!= NULL
)
5858 DBGLOG(TDLS
, INFO
, ("<tdls_cfg> %s: ["MACSTR
"] ps=%d status=%d\n",
5859 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
),
5860 prStaRec
->fgIsInPS
, prMgmtTxInfo
->u2StatusCode
));
5862 if (prMgmtTxInfo
->ucActionCode
== TDLS_FRM_ACTION_TEARDOWN
)
5864 /* record disconnect history */
5865 TdlsLinkHistoryRecord(prGlueInfo
, TRUE
, prMgmtTxInfo
->aucPeer
,
5866 TRUE
, prMgmtTxInfo
->u2StatusCode
, NULL
);
5870 return TdlsDataFrameSend(
5873 prMgmtTxInfo
->aucPeer
,
5874 prMgmtTxInfo
->ucActionCode
,
5875 prMgmtTxInfo
->ucDialogToken
,
5876 prMgmtTxInfo
->u2StatusCode
,
5877 (UINT_8
*)prMgmtTxInfo
->aucSecBuf
,
5878 prMgmtTxInfo
->u4SecBufLen
);
5882 /*----------------------------------------------------------------------------*/
5884 * \brief This routine is called to add a peer record.
5886 * \param[in] prAdapter Pointer to the Adapter structure
5887 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
5888 * \param[in] u4SetBufferLen The length of the set buffer
5889 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
5890 * bytes read from the set buffer. If the call failed due to invalid length of
5891 * the set buffer, returns the amount of storage needed.
5893 * \retval TDLS_STATUS_xx
5895 /*----------------------------------------------------------------------------*/
5898 ADAPTER_T
*prAdapter
,
5900 UINT_32 u4SetBufferLen
,
5901 UINT_32
*pu4SetInfoLen
5904 GLUE_INFO_T
*prGlueInfo
;
5905 TDLS_CMD_PEER_ADD_T
*prCmd
;
5906 BSS_INFO_T
*prAisBssInfo
;
5907 STA_RECORD_T
*prStaRec
;
5908 UINT_8 ucNonHTPhyTypeSet
;
5910 OS_SYSTIME rCurTime
;
5914 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s\n", __FUNCTION__
));
5916 if ((prAdapter
== NULL
) || (pvSetBuffer
== NULL
) || (pu4SetInfoLen
== NULL
))
5919 ("<tdls_cmd> %s: sanity fail!\n", __FUNCTION__
));
5920 return TDLS_STATUS_FAILURE
;
5924 prGlueInfo
= (GLUE_INFO_T
*)prAdapter
->prGlueInfo
;
5925 *pu4SetInfoLen
= sizeof(TDLS_CMD_PEER_ADD_T
);
5926 prCmd
= (TDLS_CMD_PEER_ADD_T
*)pvSetBuffer
;
5927 prAisBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
5930 /* search old entry */
5931 prStaRec
= cnmGetStaRecByAddress(prAdapter
,
5932 (UINT_8
) NETWORK_TYPE_AIS_INDEX
,
5935 /* check if any TDLS link exists because we only support one TDLS link currently */
5936 if (prStaRec
== NULL
)
5938 /* the MAC is new peer */
5939 prStaRec
= cnmStaTheTypeGet(prAdapter
, NETWORK_TYPE_AIS_INDEX
,
5940 STA_TYPE_TDLS_PEER
, &u4StartIdx
);
5942 if (prStaRec
!= NULL
)
5944 /* a building TDLS link exists */
5946 ("<tdls_cmd> %s: one TDLS link setup ["MACSTR
"] is going...\n",
5947 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
)));
5949 if (prStaRec
->ucStaState
!= STA_STATE_3
)
5952 GET_CURRENT_SYSTIME(&rCurTime
);
5954 if (CHECK_FOR_TIMEOUT(rCurTime
, prStaRec
->rTdlsSetupStartTime
,
5955 SEC_TO_SYSTIME(TDLS_SETUP_TIMEOUT_SEC
)))
5957 /* free the StaRec */
5958 cnmStaRecFree(prAdapter
, prStaRec
, TRUE
);
5961 ("<tdls_cmd> %s: free going TDLS link setup ["MACSTR
"]\n",
5962 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
)));
5964 /* handle new setup */
5968 return TDLS_STATUS_FAILURE
;
5972 /* the TDLS is built and works fine, reject new one */
5973 return TDLS_STATUS_FAILURE
;
5979 if (prStaRec
->ucStaState
== STA_STATE_3
)
5981 /* the peer exists, maybe TPK lifetime expired, supplicant wants to renew key */
5982 TdlsLinkHistoryRecord(prAdapter
->prGlueInfo
, TRUE
,
5983 prStaRec
->aucMacAddr
, TRUE
,
5984 TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_REKEY
, NULL
);
5986 /* 16 Nov 21:49 2012 http://permalink.gmane.org/gmane.linux.kernel.wireless.general/99712 */
5987 cfg80211_tdls_oper_request(prAdapter
->prGlueInfo
->prDevHandler
,
5988 prStaRec
->aucMacAddr
, TDLS_FRM_ACTION_TEARDOWN
,
5989 TDLS_REASON_CODE_UNSPECIFIED
, GFP_ATOMIC
);
5992 ("<tdls_cmd> %s: re-setup link for ["MACSTR
"] maybe re-key?\n",
5993 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
)));
5994 return TDLS_STATUS_FAILURE
;
5999 create new entry if not exist
6002 (1) send TDLS setup request
6003 wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0);
6004 create a station record with STA_STATE_1.
6005 (2) got TDLS setup response and send TDLS setup confirm
6006 wpa_tdls_enable_link()
6007 update a station record with STA_STATE_3.
6010 (1) got TDLS setup request
6011 wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0);
6012 create a station record with STA_STATE_1.
6013 (2) send TDLS setup response
6014 (3) got TDLS setup confirm
6015 wpa_tdls_enable_link()
6016 update a station record with STA_STATE_3.
6018 if (prStaRec
== NULL
)
6020 prStaRec
= cnmStaRecAlloc(prAdapter
, (UINT_8
) NETWORK_TYPE_AIS_INDEX
);
6022 if (prStaRec
== NULL
)
6024 /* shall not be here */
6026 ("<tdls_cmd> %s: alloc prStaRec fail!\n", __FUNCTION__
));
6027 return TDLS_STATUS_RESOURCES
;
6030 /* init the prStaRec */
6031 /* prStaRec will be zero first in cnmStaRecAlloc() */
6032 COPY_MAC_ADDR(prStaRec
->aucMacAddr
, prCmd
->aucPeerMac
);
6034 // cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_1);
6039 if ((prStaRec
->ucStaState
> STA_STATE_1
) && (IS_TDLS_STA(prStaRec
)))
6042 test plan: The STAUT should locally tear down existing TDLS direct link and
6043 respond with Set up Response frame.
6045 cnmStaRecChangeState(prAdapter
, prStaRec
, STA_STATE_1
);
6050 /* reference to bssCreateStaRecFromBssDesc() and use our best capability */
6051 /* reference to assocBuildReAssocReqFrameCommonIEs() to fill elements */
6053 /* prStaRec->u2CapInfo */
6054 /* TODO: Need to parse elements from setup request frame */
6055 prStaRec
->u2OperationalRateSet
= prAisBssInfo
->u2OperationalRateSet
;
6056 prStaRec
->u2BSSBasicRateSet
= prAisBssInfo
->u2BSSBasicRateSet
;
6057 prStaRec
->u2DesiredNonHTRateSet
= prAdapter
->rWifiVar
.ucAvailablePhyTypeSet
;
6058 prStaRec
->ucPhyTypeSet
= prAisBssInfo
->ucPhyTypeSet
;
6059 prStaRec
->eStaType
= STA_TYPE_TDLS_PEER
;
6061 prStaRec
->ucDesiredPhyTypeSet
= /*prStaRec->ucPhyTypeSet & */
6062 prAdapter
->rWifiVar
.ucAvailablePhyTypeSet
;
6063 ucNonHTPhyTypeSet
= prStaRec
->ucDesiredPhyTypeSet
& PHY_TYPE_SET_802_11ABG
;
6065 /* check for Target BSS's non HT Phy Types */
6066 if (ucNonHTPhyTypeSet
)
6068 if (ucNonHTPhyTypeSet
& PHY_TYPE_BIT_ERP
)
6070 prStaRec
->ucNonHTBasicPhyType
= PHY_TYPE_ERP_INDEX
;
6072 else if (ucNonHTPhyTypeSet
& PHY_TYPE_BIT_OFDM
)
6074 prStaRec
->ucNonHTBasicPhyType
= PHY_TYPE_OFDM_INDEX
;
6076 else /* if (ucNonHTPhyTypeSet & PHY_TYPE_HR_DSSS_INDEX) */
6078 prStaRec
->ucNonHTBasicPhyType
= PHY_TYPE_HR_DSSS_INDEX
;
6081 prStaRec
->fgHasBasicPhyType
= TRUE
;
6085 /* use mandatory for 11N only BSS */
6086 // ASSERT(prStaRec->ucPhyTypeSet & PHY_TYPE_SET_802_11N);
6088 prStaRec
->ucNonHTBasicPhyType
= PHY_TYPE_HR_DSSS_INDEX
;
6089 prStaRec
->fgHasBasicPhyType
= FALSE
;
6092 /* update non HT Desired Rate Set */
6094 P_CONNECTION_SETTINGS_T prConnSettings
;
6096 prConnSettings
= &(prAdapter
->rWifiVar
.rConnSettings
);
6097 prStaRec
->u2DesiredNonHTRateSet
=\
6098 (prStaRec
->u2OperationalRateSet
& prConnSettings
->u2DesiredNonHTRateSet
);
6101 #if 0 /* TdlsexPeerAdd() will be called before we receive setup rsp in TdlsexRxFrameHandle() */
6102 /* check if the add is from the same peer in the 1st unhandled setup request frame */
6103 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: ["MACSTR
"] ["MACSTR
"]\n",
6104 __FUNCTION__
, MAC2STR(prGlueInfo
->aucTdlsHtPeerMac
),
6105 MAC2STR(prCmd
->aucPeerMac
)));
6107 if (kalMemCmp(prGlueInfo
->aucTdlsHtPeerMac
, prCmd
->aucPeerMac
, 6) == 0)
6109 /* copy the HT capability from its setup request */
6110 kalMemCopy(&prStaRec
->rTdlsHtCap
,
6111 &prGlueInfo
->rTdlsHtCap
, sizeof(IE_HT_CAP_T
));
6113 prStaRec
->ucPhyTypeSet
|= PHY_TYPE_SET_802_11N
;
6114 prStaRec
->u2DesiredNonHTRateSet
|= BIT(RATE_HT_PHY_INDEX
);
6117 kalMemZero(&prGlueInfo
->rTdlsHtCap
, sizeof(prStaRec
->rTdlsHtCap
));
6118 kalMemZero(prGlueInfo
->aucTdlsHtPeerMac
, sizeof(prGlueInfo
->aucTdlsHtPeerMac
));
6120 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: peer is a HT device\n", __FUNCTION__
));
6124 /* update WMM: must support due to UAPSD in TDLS link */
6125 prStaRec
->fgIsWmmSupported
= TRUE
;
6126 prStaRec
->fgIsUapsdSupported
= TRUE
;
6128 /* update station record to firmware */
6129 cnmStaRecChangeState(prAdapter
, prStaRec
, STA_STATE_1
);
6132 GET_CURRENT_SYSTIME(&prStaRec
->rTdlsSetupStartTime
);
6134 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: create a peer ["MACSTR
"]\n",
6135 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
)));
6137 return TDLS_STATUS_SUCCESS
;
6141 /*----------------------------------------------------------------------------*/
6143 * \brief This routine is called to update a peer record.
6145 * \param[in] prAdapter Pointer to the Adapter structure
6146 * \param[in] pvSetBuffer A pointer to the buffer that holds the data to be set
6147 * \param[in] u4SetBufferLen The length of the set buffer
6148 * \param[out] pu4SetInfoLen If the call is successful, returns the number of
6149 * bytes read from the set buffer. If the call failed due to invalid length of
6150 * the set buffer, returns the amount of storage needed.
6152 * \retval TDLS_STATUS_xx
6154 /*----------------------------------------------------------------------------*/
6157 ADAPTER_T
*prAdapter
,
6159 UINT_32 u4SetBufferLen
,
6160 UINT_32
*pu4SetInfoLen
6163 GLUE_INFO_T
*prGlueInfo
;
6164 TDLS_CMD_PEER_UPDATE_T
*prCmd
;
6165 BSS_INFO_T
*prAisBssInfo
;
6166 STA_RECORD_T
*prStaRec
;
6167 IE_HT_CAP_T
*prHtCap
;
6171 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s\n", __FUNCTION__
));
6173 if ((prAdapter
== NULL
) || (pvSetBuffer
== NULL
) || (pu4SetInfoLen
== NULL
))
6176 ("<tdls_cmd> %s: sanity fail!\n", __FUNCTION__
));
6177 return TDLS_STATUS_FAILURE
;
6181 prGlueInfo
= (GLUE_INFO_T
*)prAdapter
->prGlueInfo
;
6182 *pu4SetInfoLen
= sizeof(TDLS_CMD_PEER_ADD_T
);
6183 prCmd
= (TDLS_CMD_PEER_UPDATE_T
*)pvSetBuffer
;
6184 prAisBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[NETWORK_TYPE_AIS_INDEX
]);
6186 /* search old entry */
6187 prStaRec
= cnmGetStaRecByAddress(prAdapter
,
6188 (UINT_8
) NETWORK_TYPE_AIS_INDEX
,
6192 create new entry if not exist
6195 (1) send TDLS setup request
6196 wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0);
6197 create a station record with STA_STATE_1.
6198 (2) got TDLS setup response and send TDLS setup confirm
6199 wpa_tdls_enable_link()
6200 update a station record with STA_STATE_3.
6203 (1) got TDLS setup request
6204 wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0, NULL, 0);
6205 create a station record with STA_STATE_1.
6206 (2) send TDLS setup response
6207 (3) got TDLS setup confirm
6208 wpa_tdls_enable_link()
6209 update a station record with STA_STATE_3.
6211 if ((prStaRec
== NULL
) || (prStaRec
->fgIsInUse
== 0))
6214 ("<tdls_cmd> %s: cannot find the peer!\n", __FUNCTION__
));
6215 return TDLS_STATUS_FAILURE
;
6218 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: update a peer ["MACSTR
"] %d -> %d, 0x%x\n",
6219 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
),
6220 prStaRec
->ucStaState
, STA_STATE_3
, prStaRec
->eStaType
));
6222 if (!IS_TDLS_STA(prStaRec
))
6225 ("<tdls_cmd> %s: peer is not TDLS one!\n", __FUNCTION__
));
6226 return TDLS_STATUS_FAILURE
;
6229 /* check if the add is from the same peer in the 1st unhandled setup request frame */
6230 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: ["MACSTR
"] ["MACSTR
"]\n",
6231 __FUNCTION__
, MAC2STR(prGlueInfo
->aucTdlsHtPeerMac
),
6232 MAC2STR(prCmd
->aucPeerMac
)));
6234 if (kalMemCmp(prGlueInfo
->aucTdlsHtPeerMac
, prCmd
->aucPeerMac
, 6) == 0)
6236 /* copy the HT capability from its setup request */
6237 kalMemCopy(&prStaRec
->rTdlsHtCap
,
6238 &prGlueInfo
->rTdlsHtCap
, sizeof(IE_HT_CAP_T
));
6240 prStaRec
->ucPhyTypeSet
|= PHY_TYPE_SET_802_11N
;
6241 prStaRec
->u2DesiredNonHTRateSet
|= BIT(RATE_HT_PHY_INDEX
);
6244 kalMemZero(&prGlueInfo
->rTdlsHtCap
, sizeof(prStaRec
->rTdlsHtCap
));
6245 kalMemZero(prGlueInfo
->aucTdlsHtPeerMac
, sizeof(prGlueInfo
->aucTdlsHtPeerMac
));
6247 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: peer is a HT device\n", __FUNCTION__
));
6250 /* update the record join time. */
6251 GET_CURRENT_SYSTIME(&prStaRec
->rUpdateTime
);
6253 /* update Station Record - Status/Reason Code */
6254 prStaRec
->u2StatusCode
= prCmd
->u2StatusCode
;
6256 /* prStaRec->ucStaState shall be STA_STATE_1 */
6258 prStaRec
->u2CapInfo
= prCmd
->u2Capability
;
6259 /* prStaRec->u2OperationalRateSet */
6260 prStaRec
->u2AssocId
= 0; /* no use */
6261 prStaRec
->u2ListenInterval
= 0; /* unknown */
6262 /* prStaRec->ucDesiredPhyTypeSet */
6263 /* prStaRec->u2DesiredNonHTRateSet */
6264 /* prStaRec->u2BSSBasicRateSet */
6265 /* prStaRec->ucMcsSet */
6266 /* prStaRec->fgSupMcs32 */
6267 /* prStaRec->u2HtCapInfo */
6268 prStaRec
->fgIsQoS
= TRUE
;
6269 prStaRec
->fgIsUapsdSupported
= (prCmd
->UapsdBitmap
== 0)?FALSE
:TRUE
;
6270 /* prStaRec->ucAmpduParam */
6271 /* prStaRec->u2HtExtendedCap */
6272 prStaRec
->u4TxBeamformingCap
= 0; /* no use */
6273 prStaRec
->ucAselCap
= 0; /* no use */
6274 prStaRec
->ucRCPI
= 0;
6275 prStaRec
->ucBmpTriggerAC
= prCmd
->UapsdBitmap
;
6276 prStaRec
->ucBmpDeliveryAC
= prCmd
->UapsdBitmap
;
6277 prStaRec
->ucUapsdSp
= prCmd
->UapsdMaxSp
;
6280 #if (TDLS_CFG_HT_SUP == 1)
6281 if (prCmd
->fgIsSupHt
== FALSE
)
6283 /* no HT IE is from supplicant so we use the backup */
6284 prHtCap
= (IE_HT_CAP_T
*) &prStaRec
->rTdlsHtCap
;
6286 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: ["MACSTR
"] update ht ie 0x%x\n",
6287 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
), prHtCap
->ucId
));
6289 if (prHtCap
->ucId
== ELEM_ID_HT_CAP
)
6291 prStaRec
->ucMcsSet
= prHtCap
->rSupMcsSet
.aucRxMcsBitmask
[0];
6292 prStaRec
->fgSupMcs32
=
6293 (prHtCap
->rSupMcsSet
.aucRxMcsBitmask
[32/8] & BIT(0)) ?
6296 prStaRec
->u2HtCapInfo
= prHtCap
->u2HtCapInfo
;
6297 prStaRec
->ucAmpduParam
= prHtCap
->ucAmpduParam
;
6298 prStaRec
->u2HtExtendedCap
= prHtCap
->u2HtExtendedCap
;
6299 prStaRec
->u4TxBeamformingCap
= prHtCap
->u4TxBeamformingCap
;
6300 prStaRec
->ucAselCap
= prHtCap
->ucAselCap
;
6301 prStaRec
->ucDesiredPhyTypeSet
|= PHY_TYPE_SET_802_11N
;
6306 /* TODO: use the HT IE from supplicant */
6308 #endif /* TDLS_CFG_HT_SUP */
6310 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: UAPSD 0x%x %d MCS=0x%x\n",
6311 __FUNCTION__
, prCmd
->UapsdBitmap
, prCmd
->UapsdMaxSp
,
6312 prStaRec
->ucMcsSet
));
6314 // cnmStaRecChangeState(prAdapter, prStaRec, STA_STATE_3);
6316 DBGLOG(TDLS
, INFO
, ("<tdls_cmd> %s: update a peer ["MACSTR
"]\n",
6317 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
)));
6319 return TDLS_STATUS_SUCCESS
;
6323 /*----------------------------------------------------------------------------*/
6325 * \brief This routine is called to check if we need to drop a TDLS action frame.
6327 * \param[in] *pPkt Pointer to the struct sk_buff->data.
6333 /*----------------------------------------------------------------------------*/
6336 GLUE_INFO_T
*prGlueInfo
,
6340 ADAPTER_T
*prAdapter
;
6345 if ((pPkt
== NULL
) || (*(pPkt
+12) != 0x89) || (*(pPkt
+13) != 0x0d))
6346 return FALSE
; /* not TDLS data frame htons(0x890d) */
6348 #if 0 /* supplicant handles this check */
6349 if (prStaRec
== NULL
)
6350 return FALSE
; /* shall not be here */
6353 ("<tdls_fme> %s: Rcv a TDLS action frame (id=%d) %d %d\n",
6354 __FUNCTION__
, *(pPkt
+13+4),
6355 prStaRec
->fgTdlsIsProhibited
, fgIsPtiTimeoutSkip
));
6357 /* check if TDLS Prohibited bit is set in AP's beacon */
6358 if (prStaRec
->fgTdlsIsProhibited
== TRUE
)
6362 ucActionId
= *(pPkt
+12+2+2); /* skip dst, src MAC, type, payload type, category */
6364 if (fgIsPtiTimeoutSkip
== TRUE
)
6366 /* also skip any tear down frame from the peer */
6367 if (ucActionId
== TDLS_FRM_ACTION_TEARDOWN
)
6371 prAdapter
= prGlueInfo
->prAdapter
;
6373 ("<tdls_fme> %s: Rcv a TDLS action frame %d (%u)\n",
6374 __FUNCTION__
, ucActionId
,
6375 (UINT32
)prAdapter
->rRxCtrl
.rFreeSwRfbList
.u4NumElem
));
6377 if (ucActionId
== TDLS_FRM_ACTION_TEARDOWN
)
6380 ("<tdls_fme> %s: Rcv a TDLS tear down frame %d, will DISABLE link\n",
6381 __FUNCTION__
, *(pPkt
+13+4))); /* reason code */
6383 /* record disconnect history */
6384 TdlsLinkHistoryRecord(prGlueInfo
, TRUE
, pPkt
+6, FALSE
, *(pPkt
+13+4), NULL
);
6386 /* inform tear down to supplicant only in OPEN/NONE mode */
6388 we need to tear down the link manually; or supplicant will display
6389 "No FTIE in TDLS Teardown" and it will not tear down the link
6391 cfg80211_tdls_oper_request(prGlueInfo
->prDevHandler
,
6392 pPkt
+6, TDLS_FRM_ACTION_TEARDOWN
, *(pPkt
+13+4), GFP_ATOMIC
);
6395 #if 0 /* pass all to supplicant except same thing is handled in supplicant */
6396 if (((*(pPkt
+13+3)) == TDLS_FRM_ACTION_PTI
) ||
6397 ((*(pPkt
+13+3)) == TDLS_FRM_ACTION_CHAN_SWITCH_REQ
) ||
6398 ((*(pPkt
+13+3)) == TDLS_FRM_ACTION_CHAN_SWITCH_RSP
) ||
6399 ((*(pPkt
+13+3)) == TDLS_FRM_ACTION_PTI_RSP
))
6409 /*----------------------------------------------------------------------------*/
6410 /*! \brief This routine is called to parse some IEs in the setup frame from the peer.
6412 * \param[in] prGlueInfo Pointer to the Adapter structure
6413 * \param[in] pPkt Pointer to the ethernet packet
6418 /*----------------------------------------------------------------------------*/
6420 TdlsexRxFrameHandle(
6421 GLUE_INFO_T
*prGlueInfo
,
6426 ADAPTER_T
*prAdapter
;
6427 STA_RECORD_T
*prStaRec
;
6429 UINT8
*pucPeerMac
, ucElmId
, ucElmLen
;
6434 if ((prGlueInfo
== NULL
) || (pPkt
== NULL
) ||
6435 (*(pPkt
+12) != 0x89) || (*(pPkt
+13) != 0x0d))
6440 ucActionId
= *(pPkt
+12+2+2); /* skip dst, src MAC, type, payload type, category */
6442 if ((ucActionId
!= TDLS_FRM_ACTION_SETUP_REQ
) &&
6443 (ucActionId
!= TDLS_FRM_ACTION_SETUP_RSP
))
6449 prAdapter
= prGlueInfo
->prAdapter
;
6450 pucPeerMac
= pPkt
+6;
6451 s2FmeLen
= (INT16
)u2PktLen
;
6454 ("<tdls_fme> %s: get a setup frame %d from "MACSTR
"\n",
6455 __FUNCTION__
, ucActionId
, MAC2STR(pucPeerMac
)));
6457 if (ucActionId
== TDLS_FRM_ACTION_SETUP_REQ
)
6458 pPkt
+= 12+2+2+1+1+2; /* skip action, dialog token, capability */
6460 pPkt
+= 12+2+2+1+2+1+2; /* skip action, status code, dialog token, capability */
6462 /* check station record */
6463 prStaRec
= cnmGetStaRecByAddress(prGlueInfo
->prAdapter
,
6464 (UINT_8
)NETWORK_TYPE_AIS_INDEX
, pucPeerMac
);
6466 if (prStaRec
== NULL
)
6468 prStaRec
= cnmStaRecAlloc(prAdapter
, (UINT_8
) NETWORK_TYPE_AIS_INDEX
);
6470 if (prStaRec
== NULL
)
6472 /* TODO: only one TDLS entry, need to free old one if timeout */
6474 ("<tdls_cmd> %s: alloc prStaRec fail!\n", __FUNCTION__
));
6478 /* init the prStaRec */
6479 /* prStaRec will be zero first in cnmStaRecAlloc() */
6480 COPY_MAC_ADDR(prStaRec
->aucMacAddr
, pucPeerMac
);
6482 cnmStaRecChangeState(prAdapter
, prStaRec
, STA_STATE_1
);
6485 /* backup HT IE to station record */
6486 /* TODO: Maybe our TDLS only supports non-11n */
6494 case ELEM_ID_HT_CAP
: /* 0x2d */
6495 /* backup the HT IE of 1st unhandled setup request frame */
6496 if (prGlueInfo
->rTdlsHtCap
.ucId
== 0x00)
6498 kalMemCopy(prGlueInfo
->aucTdlsHtPeerMac
, pucPeerMac
, 6);
6499 kalMemCopy(&prGlueInfo
->rTdlsHtCap
, pPkt
-2, ucElmLen
+2);
6502 cannot backup in prStaRec; or
6504 1. we build a TDLS link
6505 2. peer re-sends setup req
6506 3. we backup HT cap element
6507 4. supplicant disables the link
6508 5. we clear the prStaRec
6512 ("<tdls_fme> %s: "MACSTR
": find a HT IE\n",
6513 __FUNCTION__
, MAC2STR(pucPeerMac
)));
6517 case ELEM_ID_EXTENDED_CAP
:
6518 /* TODO: backup the extended capability IE */
6523 s2FmeLen
-= (2+ucElmLen
);
6528 /*----------------------------------------------------------------------------*/
6529 /*! \brief This routine is called to get the TDLS station record.
6531 * \param[in] prGlueInfo Pointer to the Adapter structure
6532 * \param[in] prInBuf A pointer to the command string buffer
6533 * \param[in] u4InBufLen The length of the buffer
6536 * \retval TDLS_STATUS_SUCCESS: this is TDLS packet
6537 * TDLS_STATUS_FAILURE: this is not TDLS packet
6539 /*----------------------------------------------------------------------------*/
6542 ADAPTER_T
*prAdapter
,
6543 MSDU_INFO_T
*prMsduInfo
6546 BSS_INFO_T
*prBssInfo
;
6547 STA_RECORD_T
*prStaRec
;
6552 if (prAdapter
->prGlueInfo
== NULL
)
6553 return TDLS_STATUS_FAILURE
;
6554 if (TDLS_IS_NO_LINK_GOING(prAdapter
->prGlueInfo
))
6555 return TDLS_STATUS_FAILURE
;
6557 if ((prAdapter
== NULL
) || (prMsduInfo
== NULL
))
6558 return TDLS_STATUS_FAILURE
;
6561 prMsduInfo
->ucStaRecIndex
= STA_REC_INDEX_NOT_FOUND
;
6562 Status
= TDLS_STATUS_SUCCESS
;
6564 /* get record by ether dest */
6565 prStaRec
= cnmGetStaRecByAddress(prAdapter
,
6566 (UINT_8
) NETWORK_TYPE_AIS_INDEX
,
6567 prMsduInfo
->aucEthDestAddr
);
6570 TDLS Setup Request frames, TDLS Setup Response frames and TDLS Setup Confirm
6571 frames shall be transmitted through the AP and shall not be transmitted to a group
6574 1. In first time, prStaRec == NULL or prStaRec->ucStaState != STA_STATE_3,
6575 we will send them to AP;
6576 2. When link is still on, if you command to send TDLS setup from supplicant,
6577 supplicant will DISABLE LINK first, prStaRec will be NULL then send TDLS
6578 setup frame to the peer.
6582 if ((prStaRec
!= NULL
) &&
6583 (prStaRec
->ucStaState
== STA_STATE_3
) &&
6584 (IS_TDLS_STA(prStaRec
)))
6587 TDLS Test Case 5.3 Tear Down
6588 Automatically sends TDLS Teardown frame to STA 2 via AP
6590 11.21.5 TDLS Direct Link Teardown
6591 The TDLS Teardown frame shall be sent over the direct path and the reason
6592 code shall be set to "TDLS 40 direct link teardown for unspecified reason",
6593 except when the TDLS peer STA is unreachable via the TDLS direct link,
6594 in which case, the TDLS Teardown frame shall be sent through the AP and
6595 the reason code shall be set to "TDLS direct link teardown due to TDLS peer
6596 STA unreachable via the TDLS direct link".
6598 // if (prStaRec->fgIsInPS == TRUE)
6601 check if the packet is tear down:
6602 we do not want to use PTI to indicate the tear down and
6603 we want to send the tear down to AP then AP help us to send it
6605 struct sk_buff
*prSkb
;
6607 UINT_16 u2EtherTypeLen
;
6609 prSkb
= (struct sk_buff
*) prMsduInfo
->prPacket
;
6612 UINT8 ucActionCode
, ucReasonCode
;
6616 u2EtherTypeLen
= (pEth
[ETH_TYPE_LEN_OFFSET
] << 8) |\
6617 (pEth
[ETH_TYPE_LEN_OFFSET
+ 1]);
6618 ucActionCode
= pEth
[ETH_TYPE_LEN_OFFSET
+1+3];
6619 ucReasonCode
= pEth
[ETH_TYPE_LEN_OFFSET
+1+4] |\
6620 (pEth
[ETH_TYPE_LEN_OFFSET
+1+5] << 8);
6622 /* TDLS_REASON_CODE_UNREACHABLE: keep alive fail or PTI timeout */
6623 if ((u2EtherTypeLen
== TDLS_FRM_PROT_TYPE
) &&
6624 (ucActionCode
== TDLS_FRM_ACTION_TEARDOWN
) &&
6625 (ucReasonCode
== TDLS_REASON_CODE_UNREACHABLE
))
6628 when we cannot reach the peer,
6629 we need AP's help to send the tear down frame
6631 prBssInfo
= &(prAdapter
->rWifiVar
.arBssInfo
[\
6632 NETWORK_TYPE_AIS_INDEX
]);
6633 prStaRec
= prBssInfo
->prStaRecOfAP
;
6634 if (prStaRec
== NULL
)
6636 Status
= TDLS_STATUS_FAILURE
;
6641 /* change status code */
6642 pEth
[ETH_TYPE_LEN_OFFSET
+1+4] = \
6643 TDLS_REASON_CODE_UNREACHABLE
;
6649 prMsduInfo
->ucStaRecIndex
= prStaRec
->ucIndex
;
6653 DBGLOG(TDLS
, INFO
, ("<tdls> %s: (Status=%x) ["MACSTR
"] ucStaRecIndex = %d!\n",
6654 __FUNCTION__
, (INT32
)Status
, MAC2STR(prMsduInfo
->aucEthDestAddr
),
6655 prMsduInfo
->ucStaRecIndex
));
6660 /*----------------------------------------------------------------------------*/
6662 * @brief This function is used to check if we suffer timeout for TX quota empty case.
6664 * \param[in] prAdapter Pointer to the Adapter structure
6668 /*----------------------------------------------------------------------------*/
6671 GLUE_INFO_T
*prGlueInfo
,
6672 STA_RECORD_T
*prStaRec
,
6676 OS_SYSTIME rCurTime
;
6680 if (!IS_TDLS_STA(prStaRec
))
6686 prStaRec
->rTdlsTxQuotaEmptyTime
= 0;
6690 /* work-around: check if the no free quota case is too long */
6691 GET_CURRENT_SYSTIME(&rCurTime
);
6693 if (prStaRec
->rTdlsTxQuotaEmptyTime
== 0)
6695 prStaRec
->rTdlsTxQuotaEmptyTime
= rCurTime
;
6699 if (CHECK_FOR_TIMEOUT(rCurTime
, prStaRec
->rTdlsTxQuotaEmptyTime
,
6700 SEC_TO_SYSTIME(TDLS_TX_QUOTA_EMPTY_TIMEOUT
)))
6702 /* tear down the link */
6704 ("<tdls> %s: ["MACSTR
"] TX quota empty timeout!\n",
6705 __FUNCTION__
, MAC2STR(prStaRec
->aucMacAddr
)));
6707 /* record disconnect history */
6708 TdlsLinkHistoryRecord(prGlueInfo
, TRUE
, prStaRec
->aucMacAddr
,
6709 TRUE
, TDLS_REASON_CODE_MTK_DIS_BY_US_DUE_TO_TX_QUOTA_EMPTY
, NULL
);
6711 /* inform tear down to supplicant only in OPEN/NONE mode */
6713 we need to tear down the link manually; or supplicant will display
6714 "No FTIE in TDLS Teardown" and it will not tear down the link
6716 cfg80211_tdls_oper_request(prGlueInfo
->prDevHandler
,
6717 prStaRec
->aucMacAddr
, TDLS_FRM_ACTION_TEARDOWN
,
6718 TDLS_REASON_CODE_UNREACHABLE
, GFP_ATOMIC
);
6724 /*----------------------------------------------------------------------------*/
6726 * @brief This function is used to un-initialize variables in TDLS.
6728 * \param[in] prAdapter Pointer to the Adapter structure
6732 /*----------------------------------------------------------------------------*/
6735 ADAPTER_T
*prAdapter
6738 #if TDLS_CFG_CMD_TEST
6739 cnmTimerStopTimer(prAdapter
, &rTdlsTimerTestDataSend
);
6740 #endif /* TDLS_CFG_CMD_TEST */
6744 #endif /* CFG_SUPPORT_TDLS */