prima: TDLS Off Channel ioctl support
TDLS Off Channel ioctl support host side implementation.
This ioctl will provide the parameters to f/w for switching
to target channel as needed by certification test.
Change-Id: Iebff803bec5fd56acc0272cb1d1c1b7f1c77c0a8
CRs-Fixed: 703740
diff --git a/CORE/HDD/inc/wlan_hdd_tdls.h b/CORE/HDD/inc/wlan_hdd_tdls.h
index ec38dfc..d402d50 100644
--- a/CORE/HDD/inc/wlan_hdd_tdls.h
+++ b/CORE/HDD/inc/wlan_hdd_tdls.h
@@ -341,4 +341,6 @@
int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer,
cfg80211_exttdls_callback callback);
+// tdlsoffchan
+hddTdlsPeer_t *wlan_hdd_tdls_get_first_connected_peer(hdd_adapter_t *pAdapter);
#endif // __HDD_TDSL_H
diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c
index e9728e6..0fb765b 100644
--- a/CORE/HDD/src/wlan_hdd_wext.c
+++ b/CORE/HDD/src/wlan_hdd_wext.c
@@ -121,6 +121,14 @@
extern int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand);
+// tdlsoffchan
+#ifdef FEATURE_WLAN_TDLS
+static int iw_set_tdlsoffchannel(hdd_context_t *pHddCtx, int offchannel);
+static int iw_set_tdlssecoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset);
+static int iw_set_tdlsoffchannelmode(hdd_adapter_t *pAdapter, int offchanmode);
+static int tdlsOffCh = 1;
+static int tdlsOffChBwOffset = 0;
+#endif
static int ioctl_debug;
module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
@@ -154,6 +162,12 @@
#define WE_SET_MAX_TX_POWER_5_0 12
/* Private IOCTL for debug connection issues */
#define WE_SET_DEBUG_LOG 13
+// tdlsoffchan
+#ifdef FEATURE_WLAN_TDLS
+#define WE_SET_TDLS_OFF_CHAN 14
+#define WE_SET_TDLS_SEC_OFF_CHAN_OFFSET 15
+#define WE_SET_TDLS_OFF_CHAN_MODE 16
+#endif
/* Private ioctls and their sub-ioctls */
#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
@@ -246,7 +260,6 @@
#define MAX_VAR_ARGS 7
#endif
-
/* Private ioctls (with no sub-ioctls) */
/* note that they must be odd so that they have "get" semantics */
#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV + 9)
@@ -4421,6 +4434,31 @@
sme_UpdateConnectDebug(pHddCtx->hHal, set_value);
break;
}
+#ifdef FEATURE_WLAN_TDLS
+ case WE_SET_TDLS_OFF_CHAN:
+ {
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Tdls offchannel num %d",
+ __func__, set_value);
+ ret = iw_set_tdlsoffchannel(pHddCtx, set_value);
+ break;
+ }
+ case WE_SET_TDLS_SEC_OFF_CHAN_OFFSET:
+ {
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Tdls sec offchan offset %d",
+ __func__, set_value);
+ ret = iw_set_tdlssecoffchanneloffset(pHddCtx, set_value);
+ break;
+ }
+ case WE_SET_TDLS_OFF_CHAN_MODE:
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Tdls offchannel mode %d",
+ __func__, set_value);
+ ret = iw_set_tdlsoffchannelmode(pAdapter, set_value);
+ break;
+ }
+#endif
default:
{
@@ -7440,6 +7478,161 @@
return VOS_STATUS_SUCCESS;
}/*iw_set_power_params*/
+// tdlsoffchan
+#ifdef FEATURE_WLAN_TDLS
+
+static int iw_set_tdlsoffchannel(hdd_context_t *pHddCtx, int offchannel)
+{
+ if (offchannel < 0 || offchannel > 165)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Invalid tdls off channel %u",
+ __func__, offchannel);
+ return -1;
+
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls off channel from %d to %d",
+ __func__, tdlsOffCh, offchannel);
+
+ tdlsOffCh = offchannel;
+ return 0;
+}
+
+static int iw_set_tdlssecoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset)
+{
+ if (offchanoffset == 0)
+ {
+ tdlsOffChBwOffset = 0;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls secondary off channel offset to %u",
+ __func__, tdlsOffChBwOffset);
+
+ return 0;
+
+ }
+
+ if ( offchanoffset == 40 )
+ {
+ tdlsOffChBwOffset = 1;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls secondary off channel offset to %u",
+ __func__, tdlsOffChBwOffset);
+
+ return 0;
+
+ }
+ if (offchanoffset == -40)
+ {
+ tdlsOffChBwOffset = 3;
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls secondary off channel offset to %u",
+ __func__, tdlsOffChBwOffset);
+
+ return 0;
+
+ }
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s: Invalid tdls secondary off channel offset %d",
+ __func__, offchanoffset);
+ return -1;
+}
+
+static int iw_set_tdlsoffchannelmode(hdd_adapter_t *pAdapter, int offchanmode)
+{
+ hddTdlsPeer_t *connPeer = NULL;
+ hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
+ hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
+
+ if (offchanmode < 0 || offchanmode > 4)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: Invalid tdls off channel mode %d",
+ __func__, offchanmode);
+ return -1;
+ }
+
+ if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: tdls off channel mode req in not associated state %d",
+ __func__, offchanmode);
+ return -1;
+ }
+
+ if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
+ eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)
+ {
+ /* Send TDLS Channel Switch Request to connected peer */
+ connPeer = wlan_hdd_tdls_get_first_connected_peer(pAdapter);
+ if (NULL == connPeer) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s: No TDLS Connected Peer", __func__);
+ return -1;
+ }
+ }
+ else
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
+ "%s: TDLS Connection not supported", __func__);
+ return -1;
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ ("%s: TDLS Channel Switch in swmode=%d"),
+ __func__, offchanmode);
+
+ switch (offchanmode)
+ {
+ case 1:/*Enable*/
+ case 2:/*Disable*/
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: change tdls off channel mode %d tdls_off_channel %d offchanoffset %d ",
+ __func__, offchanmode, tdlsOffCh, tdlsOffChBwOffset);
+ if (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel)
+ {
+
+ sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId, connPeer->peerMac,
+ tdlsOffCh, tdlsOffChBwOffset,
+ offchanmode);
+ }
+ else
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: TDLS Off Channel not supported", __func__);
+ return -1;
+ }
+ break;
+ }
+ case 3:
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: change tdls off channel mode %d REJREQ 3 tdls_off_channel %d offchanoffset %d ",
+ __func__, offchanmode, tdlsOffCh, tdlsOffChBwOffset);
+
+ break;
+ }
+ case 4:
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "%s: change tdls off channel mode %d UNSOLRESP 4 tdls_off_channel %d offchanoffset %d ",
+ __func__, offchanmode, tdlsOffCh, tdlsOffChBwOffset);
+ break;
+ }
+ default:
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: change tdls off channel mode %d Not SET 0 tdls_off_channel %d offchanoffset %d ",
+ __func__, offchanmode, tdlsOffCh, tdlsOffChBwOffset);
+ break;
+ }
+
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change tdls off channel mode to %u",
+ __func__, offchanmode);
+ return 0;
+}
+
+#endif
+
// Define the Wireless Extensions to the Linux Network Device structure
// A number of these routines are NULL (meaning they are not implemented.)
@@ -7626,6 +7819,23 @@
{ WE_SET_DEBUG_LOG,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
0, "setDbgLvl" },
+#ifdef FEATURE_WLAN_TDLS
+ {
+ WE_SET_TDLS_OFF_CHAN,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "tdlsoffchan" },
+ {
+ WE_SET_TDLS_SEC_OFF_CHAN_OFFSET,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "tdlsecchnoffst" },
+ {
+ WE_SET_TDLS_OFF_CHAN_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
+ 0,
+ "tdlsoffchnmode" },
+#endif
/* handlers for main ioctl */
{ WLAN_PRIV_SET_NONE_GET_INT,
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 3640bf3..8a32e8c 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -4204,6 +4204,22 @@
tANI_U8 sessionId; // Session ID
tANI_U32 txCompleteStatus;
} tSirMgmtTxCompletionInd, *tpSirMgmtTxCompletionInd;
+
+//tdlsoffchan
+/* TDLS Channel Switch struct SME-->PE */
+typedef struct
+{
+ tANI_U16 messageType; //eWNI_SME_TDLS_CHANNEL_SWITCH_REQ
+ tANI_U16 length;
+ tANI_U8 sessionId; // Session ID
+ tANI_U16 transactionId; // Transaction ID for cmd
+ tANI_U8 tdlsOffCh; // Target Off Channel
+ tANI_U8 tdlsOffChBwOffset;// Target Off Channel Bandwidth offset
+ tANI_U8 tdlsSwMode; // TDLS Off Channel Mode
+ tSirMacAddr bssid; // For multi-session, for PE to locate peSession ID
+ tSirMacAddr peerMac;
+}tSirTdlsChanSwitch, *tpSirTdlsChanSwitch;
+
#endif /* FEATURE_WLAN_TDLS */
#ifdef FEATURE_WLAN_TDLS_INTERNAL
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index a588cc3..30441d7 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -336,6 +336,8 @@
eWNI_SME_MGMT_FRM_TX_COMPLETION_IND,
eWNI_SME_TDLS_LINK_ESTABLISH_REQ,
eWNI_SME_TDLS_LINK_ESTABLISH_RSP,
+// tdlsoffchan
+ eWNI_SME_TDLS_CHANNEL_SWITCH_REQ,
#endif
//NOTE: If you are planning to add more mesages, please make sure that
//SIR_LIM_ITC_MSG_TYPES_BEGIN is moved appropriately. It is set as
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index d46083e..d396e78 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -675,6 +675,13 @@
#endif /* WLAN_FEATURE_EXTSCAN */
+#ifdef FEATURE_WLAN_TDLS
+/// PE <-> HAL TDLS messages
+// tdlsoffchan
+#define SIR_HAL_TDLS_CHAN_SWITCH_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 258)
+#define SIR_HAL_TDLS_CHAN_SWITCH_REQ_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 259)
+#endif
+
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
// CFG message types
#define SIR_CFG_MSG_TYPES_BEGIN (SIR_CFG_MODULE_ID << 8)
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 8eb6250..144c09f 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1468,6 +1468,8 @@
case eWNI_SME_TDLS_ADD_STA_REQ:
case eWNI_SME_TDLS_DEL_STA_REQ:
case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
+// tdlsoffchan
+ case eWNI_SME_TDLS_CHANNEL_SWITCH_REQ:
#endif
#ifdef FEATURE_WLAN_TDLS_INTERNAL
case eWNI_SME_TDLS_DISCOVERY_START_REQ:
diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
index 9b55421..714baf7 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -5750,6 +5750,10 @@
case eWNI_SME_TDLS_LINK_ESTABLISH_REQ:
limProcesSmeTdlsLinkEstablishReq(pMac, pMsgBuf);
break;
+// tdlsoffchan
+ case eWNI_SME_TDLS_CHANNEL_SWITCH_REQ:
+ limProcesSmeTdlsChanSwitchReq(pMac, pMsgBuf);
+ break;
#endif
#ifdef FEATURE_WLAN_TDLS_INTERNAL
case eWNI_SME_TDLS_DISCOVERY_START_REQ:
diff --git a/CORE/MAC/src/pe/lim/limProcessTdls.c b/CORE/MAC/src/pe/lim/limProcessTdls.c
index b1bbd57..8a2a5ba 100644
--- a/CORE/MAC/src/pe/lim/limProcessTdls.c
+++ b/CORE/MAC/src/pe/lim/limProcessTdls.c
@@ -5851,3 +5851,118 @@
}
#endif
+// tdlsoffchan
+/*
+ * Process Channel Switch from SME.
+ */
+tSirRetStatus limProcesSmeTdlsChanSwitchReq(tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf)
+{
+ /* get all discovery request parameters */
+ tSirTdlsChanSwitch *pTdlsChanSwitch = (tSirTdlsChanSwitch*) pMsgBuf ;
+ tpPESession psessionEntry;
+ tANI_U8 sessionId;
+ tpTdlsChanSwitchParams pMsgTdlsChanSwitch;
+ tSirMsgQ msg;
+ tANI_U16 peerIdx = 0;
+ tpDphHashNode pStaDs = NULL;
+
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
+ ("TDLS Channel Switch Recieved on peer:" MAC_ADDRESS_STR),
+ MAC_ADDR_ARRAY(pTdlsChanSwitch->peerMac));
+
+ psessionEntry = peFindSessionByBssid(pMac,
+ pTdlsChanSwitch->bssid,
+ &sessionId);
+ if (psessionEntry == NULL)
+ {
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
+ "PE Session does not exist for given sme sessionId %d",
+ pTdlsChanSwitch->sessionId);
+ return eSIR_FAILURE;
+ }
+
+ /* check if we are in proper state to work as TDLS client */
+ if (psessionEntry->limSystemRole != eLIM_STA_ROLE)
+ {
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
+ "TDLS Channel Switch received in wrong system Role %d",
+ psessionEntry->limSystemRole);
+ goto lim_tdls_chan_switch_error;
+ }
+
+ /*
+ * if we are still good, go ahead and check if we are in proper state to
+ * do TDLS discovery req/rsp/....frames.
+ */
+ if ((psessionEntry->limSmeState != eLIM_SME_ASSOCIATED_STATE) &&
+ (psessionEntry->limSmeState != eLIM_SME_LINK_EST_STATE))
+ {
+
+ limLog(pMac, LOGE, "TDLS Channel Switch received in invalid LIMsme state (%d)",
+ psessionEntry->limSmeState);
+ goto lim_tdls_chan_switch_error;
+ }
+
+ pStaDs = dphLookupHashEntry(pMac, pTdlsChanSwitch->peerMac, &peerIdx,
+ &psessionEntry->dph.dphHashTable) ;
+ if ( NULL == pStaDs )
+ {
+ limLog( pMac, LOGE, FL( "pStaDs is NULL" ));
+ goto lim_tdls_chan_switch_error;
+
+ }
+ pMsgTdlsChanSwitch = vos_mem_malloc(sizeof( tTdlsChanSwitchParams ));
+ if ( NULL == pMsgTdlsChanSwitch )
+ {
+ limLog( pMac, LOGE,
+ FL( "Unable to allocate memory TDLS Channel Switch" ));
+ return eSIR_MEM_ALLOC_FAILED;
+ }
+
+ vos_mem_set( (tANI_U8 *)pMsgTdlsChanSwitch, sizeof(tpTdlsChanSwitchParams), 0);
+
+ pMsgTdlsChanSwitch->staIdx = pStaDs->staIndex;
+ pMsgTdlsChanSwitch->tdlsOffCh = pTdlsChanSwitch->tdlsOffCh;
+ pMsgTdlsChanSwitch->tdlsOffChBwOffset = pTdlsChanSwitch->tdlsOffChBwOffset;
+ pMsgTdlsChanSwitch->tdlsSwMode = pTdlsChanSwitch->tdlsSwMode;
+ pMsgTdlsChanSwitch->operClass = limGetOPClassFromChannel(
+ pMac->scan.countryCodeCurrent,
+ pTdlsChanSwitch->tdlsOffCh,
+ pTdlsChanSwitch->tdlsOffChBwOffset);
+ if(pMsgTdlsChanSwitch->operClass == 0)
+ {
+
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR,
+ "Invalid Operating class 0 !!!");
+ goto lim_tdls_chan_switch_error;
+ }
+ else
+ {
+
+ VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_INFO,
+ "%s: TDLS Channel Switch params: staIdx %d class %d ch %d bw %d mode %d",
+ __func__,
+ pMsgTdlsChanSwitch->staIdx,
+ pMsgTdlsChanSwitch->operClass,
+ pMsgTdlsChanSwitch->tdlsOffCh,
+ pMsgTdlsChanSwitch->tdlsOffChBwOffset,
+ pMsgTdlsChanSwitch->tdlsSwMode);
+ }
+
+ msg.type = WDA_SET_TDLS_CHAN_SWITCH_REQ;
+ msg.reserved = 0;
+ msg.bodyptr = pMsgTdlsChanSwitch;
+ msg.bodyval = 0;
+ if(eSIR_SUCCESS != wdaPostCtrlMsg(pMac, &msg))
+ {
+ limLog(pMac, LOGE, FL("halPostMsgApi failed\n"));
+ goto lim_tdls_chan_switch_error;
+ }
+
+ return eSIR_SUCCESS;
+
+lim_tdls_chan_switch_error:
+ return eSIR_FAILURE;
+}
+
diff --git a/CORE/MAC/src/pe/lim/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h
index 39e76de..e4ae419 100644
--- a/CORE/MAC/src/pe/lim/limTypes.h
+++ b/CORE/MAC/src/pe/lim/limTypes.h
@@ -741,7 +741,10 @@
eHalStatus limProcessTdlsAddStaRsp(tpAniSirGlobal pMac, void *msg, tpPESession);
tSirRetStatus limSendTdlsTeardownFrame(tpAniSirGlobal pMac,
tSirMacAddr peerMac, tANI_U16 reason, tANI_U8 responder, tpPESession psessionEntry,
- tANI_U8 *addIe, tANI_U16 addIeLen);
+ tANI_U8 *addIe, tANI_U16 addIeLen);
+// tdlsoffchan
+tSirRetStatus limProcesSmeTdlsChanSwitchReq(tpAniSirGlobal pMac,
+ tANI_U32 *pMsgBuf);
#endif
// Algorithms & Link Monitoring related functions
diff --git a/CORE/SME/inc/smeInside.h b/CORE/SME/inc/smeInside.h
index 839b800..a7115c8 100644
--- a/CORE/SME/inc/smeInside.h
+++ b/CORE/SME/inc/smeInside.h
@@ -154,6 +154,16 @@
{
tSirMacAddr peerMac;
} tTdlsDelStaCmdInfo;
+
+// tdlsoffchan
+typedef struct TdlsChanSwitchInfo
+{
+ tSirMacAddr peerMac;
+ tANI_U8 tdlsOffCh;
+ tANI_U8 tdlsOffChBwOffset;
+ tANI_U8 tdlsSwMode;
+} tTdlsChanSwitchCmdInfo;
+
#ifdef FEATURE_WLAN_TDLS_INTERNAL
typedef struct TdlsDisReqCmdinfo
{
@@ -190,6 +200,7 @@
tTdlsSendMgmtCmdInfo tdlsSendMgmtCmdInfo;
tTdlsAddStaCmdInfo tdlsAddStaCmdInfo;
tTdlsDelStaCmdInfo tdlsDelStaCmdInfo;
+ tTdlsChanSwitchCmdInfo tdlsChanSwitchCmdInfo; //tdlsoffchan
}u;
} tTdlsCmd;
#endif /* FEATURE_WLAN_TDLS */
@@ -306,8 +317,14 @@
eHalStatus csrTdlsDelPeerSta(tHalHandle hHal, tANI_U8 sessionId, tSirMacAddr peerMac);
eHalStatus csrTdlsProcessCmd(tpAniSirGlobal pMac,tSmeCmd *pCommand );
eHalStatus csrTdlsProcessLinkEstablish( tpAniSirGlobal pMac, tSmeCmd *cmd );
-eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac,v_U16_t msg_type,
- void *pMsgBuf);
+eHalStatus csrTdlsProcessChanSwitchReq(tpAniSirGlobal pMac, tSmeCmd *cmd ); //tdlsoffchan
+eHalStatus tdlsMsgProcessor(tpAniSirGlobal pMac,v_U16_t msg_type, void *pMsgBuf);
+VOS_STATUS csrTdlsSendChanSwitchReq(tHalHandle hHal,
+ tANI_U8 sessionId,
+ tSirMacAddr peerMac,
+ tANI_S32 tdlsOffCh,
+ tANI_S32 tdlsOffChBwOffset,
+ tANI_U8 tdlsSwMode);
#ifdef FEATURE_WLAN_TDLS_INTERNAL
eHalStatus csrTdlsDiscoveryReq(tHalHandle hHal, tANI_U8 sessionId,
tCsrTdlsDisRequest *tdlsDisReq);
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index a2c9527..abbefd1 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -81,6 +81,7 @@
eSmeCommandTdlsAddPeer,
eSmeCommandTdlsDelPeer,
eSmeCommandTdlsLinkEstablish,
+ eSmeCommandTdlsChannelSwitch, // tdlsoffchan
#ifdef FEATURE_WLAN_TDLS_INTERNAL
eSmeCommandTdlsDiscovery,
eSmeCommandTdlsLinkSetup,
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 798fc4a..353fddb 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -3413,4 +3413,13 @@
eHalStatus sme_getBcnMissRate(tHalHandle, tANI_U8, void *, void *);
tANI_BOOLEAN sme_Is11dCountrycode(tHalHandle hHal);
+
+// tdlsoffchan
+VOS_STATUS sme_SendTdlsChanSwitchReq(tHalHandle hHal,
+ tANI_U8 sessionId,
+ tSirMacAddr peerMac,
+ tANI_S32 tdlsOffCh,
+ tANI_S32 tdlsOffChBwOffset,
+ tANI_U8 tdlsSwMode);
+
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/csr/csrTdlsProcess.c b/CORE/SME/src/csr/csrTdlsProcess.c
index 6a52320..bc1be31 100644
--- a/CORE/SME/src/csr/csrTdlsProcess.c
+++ b/CORE/SME/src/csr/csrTdlsProcess.c
@@ -360,6 +360,53 @@
return status ;
}
+
+//tdlsoffchan
+/*
+ * TDLS request API, called from HDD to Send Channel Switch Parameters
+ */
+VOS_STATUS csrTdlsSendChanSwitchReq(tHalHandle hHal,
+ tANI_U8 sessionId,
+ tSirMacAddr peerMac,
+ tANI_S32 tdlsOffCh,
+ tANI_S32 tdlsOffChBwOffset,
+ tANI_U8 tdlsSwMode)
+{
+ tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
+ tSmeCmd *tdlsChanSwitchCmd;
+ eHalStatus status = eHAL_STATUS_FAILURE ;
+
+ //If connected and in Infra. Only then allow this
+ if( CSR_IS_SESSION_VALID( pMac, sessionId ) &&
+ csrIsConnStateConnectedInfra( pMac, sessionId ) &&
+ (NULL != peerMac) )
+ {
+ tdlsChanSwitchCmd = csrGetCommandBuffer(pMac) ;
+
+ if(tdlsChanSwitchCmd)
+ {
+ tTdlsChanSwitchCmdInfo *tdlsChanSwitchCmdInfo =
+ &tdlsChanSwitchCmd->u.tdlsCmd.u.tdlsChanSwitchCmdInfo;
+
+ tdlsChanSwitchCmd->sessionId = sessionId;
+
+ vos_mem_copy(tdlsChanSwitchCmdInfo->peerMac,
+ peerMac, sizeof(tSirMacAddr));
+ tdlsChanSwitchCmdInfo->tdlsOffCh = tdlsOffCh;
+ tdlsChanSwitchCmdInfo->tdlsOffChBwOffset = tdlsOffChBwOffset;
+ tdlsChanSwitchCmdInfo->tdlsSwMode = tdlsSwMode;
+
+ tdlsChanSwitchCmd->command = eSmeCommandTdlsChannelSwitch;
+ tdlsChanSwitchCmd->u.tdlsCmd.size = sizeof(tTdlsChanSwitchCmdInfo) ;
+ smePushCommand(pMac, tdlsChanSwitchCmd, FALSE) ;
+ status = eHAL_STATUS_SUCCESS ;
+ }
+ }
+
+ return status ;
+}
+
+
#ifdef FEATURE_WLAN_TDLS_INTERNAL
/*
* TDLS request API, called from HDD to enable TDLS discovery request
@@ -734,6 +781,16 @@
}
}
break;
+// tdlsoffchan
+ case eSmeCommandTdlsChannelSwitch:
+ {
+ status = csrTdlsProcessChanSwitchReq( pMac, cmd );
+ if(HAL_STATUS_SUCCESS( status ) )
+ {
+ status = eANI_BOOLEAN_FALSE ;
+ }
+ }
+ break;
#ifdef FEATURE_WLAN_TDLS_INTERNAL
case eSmeCommandTdlsDiscovery:
{
@@ -916,6 +973,51 @@
return status;
}
+// tdlsoffchan
+eHalStatus csrTdlsProcessChanSwitchReq( tpAniSirGlobal pMac, tSmeCmd *cmd )
+{
+ tTdlsChanSwitchCmdInfo *tdlsChanSwitchCmdInfo = &cmd->u.tdlsCmd.u.tdlsChanSwitchCmdInfo ;
+ tSirTdlsChanSwitch *tdlsChanSwitch = NULL ;
+ eHalStatus status = eHAL_STATUS_FAILURE;
+ tCsrRoamSession *pSession = CSR_GET_SESSION( pMac, cmd->sessionId );
+
+ if (NULL == pSession)
+ {
+ smsLog( pMac, LOGE, FL("pSession is NULL"));
+ return eHAL_STATUS_FAILURE;
+ }
+
+ tdlsChanSwitch = vos_mem_malloc(sizeof(tSirTdlsChanSwitch));
+ if (tdlsChanSwitch == NULL)
+ {
+ smsLog( pMac, LOGE, FL("alloc failed \n") );
+ VOS_ASSERT(0) ;
+ return status ;
+ }
+ tdlsChanSwitch->sessionId = cmd->sessionId;
+ //Using dialog as transactionId. This can be used to match response with request
+ tdlsChanSwitch->transactionId = 0;
+ vos_mem_copy( tdlsChanSwitch->peerMac,
+ tdlsChanSwitchCmdInfo->peerMac, sizeof(tSirMacAddr));
+ vos_mem_copy(tdlsChanSwitch->bssid, pSession->pConnectBssDesc->bssId,
+ sizeof (tSirMacAddr));
+
+ tdlsChanSwitch->tdlsOffCh = tdlsChanSwitchCmdInfo->tdlsOffCh;
+ tdlsChanSwitch->tdlsOffChBwOffset = tdlsChanSwitchCmdInfo->tdlsOffChBwOffset;
+ tdlsChanSwitch->tdlsSwMode = tdlsChanSwitchCmdInfo->tdlsSwMode;
+
+ // Send the request to PE.
+ smsLog( pMac, LOGE, "sending TDLS Channel Switch to PE \n" );
+ status = tdlsSendMessage(pMac, eWNI_SME_TDLS_CHANNEL_SWITCH_REQ,
+ (void *)tdlsChanSwitch,
+ sizeof(tSirTdlsChanSwitch));
+ if (!HAL_STATUS_SUCCESS( status ) )
+ {
+ smsLog( pMac, LOGE, FL("Failed to send request to MAC\n"));
+ }
+ return status;
+}
+
#ifdef FEATURE_WLAN_TDLS_INTERNAL
/*
* Find specific TDLS peer (based on peer MAC address).
@@ -1162,6 +1264,7 @@
csrTdlsRemoveSmeCmd(pMac, eSmeCommandTdlsLinkEstablish);
break;
}
+
#ifdef FEATURE_WLAN_TDLS_INTERNAL
case eWNI_SME_TDLS_DISCOVERY_START_RSP:
{
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 08a93a2..c51ae21 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1014,6 +1014,7 @@
case eSmeCommandTdlsAddPeer:
case eSmeCommandTdlsDelPeer:
case eSmeCommandTdlsLinkEstablish:
+ case eSmeCommandTdlsChannelSwitch: // tdlsoffchan
#ifdef FEATURE_WLAN_TDLS_INTERNAL
case eSmeCommandTdlsDiscovery:
case eSmeCommandTdlsLinkSetup:
@@ -9798,6 +9799,38 @@
return status ;
}
+// tdlsoffchan
+
+/* ---------------------------------------------------------------------------
+ \fn sme_SendTdlsChanSwitchReq
+ \brief API to send TDLS management frames.
+
+ \param peerMac - peer's Mac Adress.
+ \param tdlsLinkEstablishParams - TDLS Peer Link Establishment Parameters
+ \- return VOS_STATUS_SUCCES
+ -------------------------------------------------------------------------*/
+VOS_STATUS sme_SendTdlsChanSwitchReq(tHalHandle hHal,
+ tANI_U8 sessionId,
+ tSirMacAddr peerMac,
+ tANI_S32 tdlsOffCh,
+ tANI_S32 tdlsOffChBwOffset,
+ tANI_U8 tdlsSwMode)
+{
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+ status = sme_AcquireGlobalLock( &pMac->sme );
+
+ if ( HAL_STATUS_SUCCESS( status ) )
+ {
+ status = csrTdlsSendChanSwitchReq(hHal, sessionId, peerMac,
+ tdlsOffCh, tdlsOffChBwOffset,
+ tdlsSwMode);
+ }
+ sme_ReleaseGlobalLock( &pMac->sme );
+ return status ;
+}
+
/* ---------------------------------------------------------------------------
\fn sme_SendTdlsMgmtFrame
\brief API to send TDLS management frames.
diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h
index ba0b003..1bcd624 100644
--- a/CORE/WDA/inc/legacy/halMsgApi.h
+++ b/CORE/WDA/inc/legacy/halMsgApi.h
@@ -1353,6 +1353,17 @@
tANI_U32 status;
}tTdlsLinkEstablishParams, *tpTdlsLinkEstablishParams;
+// tdlsoffchan
+typedef struct sTdlsChanSwitchParams
+{
+ tANI_U16 staIdx;
+ tANI_U8 tdlsOffCh; // Target Off Channel
+ tANI_U8 tdlsOffChBwOffset;// Target Off Channel Bandwidth offset
+ tANI_U8 tdlsSwMode; // TDLS Off Channel Mode
+ tANI_U8 operClass; //Operating class corresponding to target channel
+ tANI_U32 status;
+}tTdlsChanSwitchParams, *tpTdlsChanSwitchParams;
+
static inline void halGetTxTSFtimer(tpAniSirGlobal pMac,
tSirMacTimeStamp *pTime)
{
diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h
index ebe8fd1..5878028 100644
--- a/CORE/WDA/inc/wlan_qct_wda.h
+++ b/CORE/WDA/inc/wlan_qct_wda.h
@@ -1213,6 +1213,11 @@
#define WDA_LINK_LAYER_STATS_RESULTS_RSP SIR_HAL_LL_STATS_RESULTS_RSP
#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
+#ifdef FEATURE_WLAN_TDLS
+// tdlsoffchan
+#define WDA_SET_TDLS_CHAN_SWITCH_REQ SIR_HAL_TDLS_CHAN_SWITCH_REQ
+#define WDA_SET_TDLS_CHAN_SWITCH_REQ_RSP SIR_HAL_TDLS_CHAN_SWITCH_REQ_RSP
+#endif
tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg);
eHalStatus WDA_SetRegDomain(void * clientCtxt, v_REGDOMAIN_t regId,
diff --git a/CORE/WDA/src/wlan_qct_wda.c b/CORE/WDA/src/wlan_qct_wda.c
index e92cf42..3375449 100644
--- a/CORE/WDA/src/wlan_qct_wda.c
+++ b/CORE/WDA/src/wlan_qct_wda.c
@@ -7525,7 +7525,110 @@
}
return CONVERT_WDI2VOS_STATUS(status);
}
-#endif
+
+// tdlsoffchan
+void WDA_SetTDLSChanSwitchReqParamsCallback(WDI_SetTdlsChanSwitchReqResp *wdiSetTdlsChanSwitchReqRsp,
+ void* pUserData)
+{
+ tWDA_ReqParams *pWdaParams = (tWDA_ReqParams *)pUserData;
+ tWDA_CbContext *pWDA = NULL;
+ tTdlsChanSwitchParams *pTdlsChanSwitchParams;
+
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "<------ %s " ,__func__);
+ if(NULL == pWdaParams)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pWdaParams received NULL", __func__);
+ vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+ VOS_ASSERT(0) ;
+ return ;
+ }
+ pWDA = (tWDA_CbContext *) pWdaParams->pWdaContext;
+
+ pTdlsChanSwitchParams = (tTdlsChanSwitchParams *)pWdaParams->wdaMsgParam ;
+ if( NULL == pTdlsChanSwitchParams || pWDA == NULL )
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: pTdlsChanSwitchParams "
+ "received NULL " ,__func__);
+ VOS_ASSERT(0);
+ vos_mem_free(pWdaParams->wdaWdiApiMsgParam);
+ vos_mem_free(pWdaParams);
+ return ;
+ }
+ pTdlsChanSwitchParams->status = CONVERT_WDI2SIR_STATUS(
+ wdiSetTdlsChanSwitchReqRsp->wdiStatus);
+ vos_mem_free(pTdlsChanSwitchParams) ;
+ vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ;
+ vos_mem_free(pWdaParams);
+ /* send response to UMAC
+ WDA_SendMsg(pWDA, WDA_SET_TDLS_CHAN_SWITCH_REQ_RSP, pTdlsChanSwitchParams, 0) ;*/
+
+ return ;
+}
+VOS_STATUS WDA_ProcessSetTdlsChanSwitchReq(tWDA_CbContext *pWDA,
+ tTdlsChanSwitchParams *pTdlsChanSwitchParams)
+{
+ WDI_Status status = WDI_STATUS_SUCCESS ;
+ WDI_SetTDLSChanSwitchReqParamsType *wdiSetTDLSChanSwitchReqParam =
+ (WDI_SetTDLSChanSwitchReqParamsType *)vos_mem_malloc(
+ sizeof(WDI_SetTDLSChanSwitchReqParamsType));
+ tWDA_ReqParams *pWdaParams = NULL;
+
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
+ "Enter: %s ",__func__);
+ if(NULL == wdiSetTDLSChanSwitchReqParam)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ pWdaParams = (tWDA_ReqParams *)vos_mem_malloc(sizeof(tWDA_ReqParams)) ;
+ if(NULL == pWdaParams)
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "%s: VOS MEM Alloc Failure", __func__);
+ vos_mem_free(pTdlsChanSwitchParams);
+ vos_mem_free(wdiSetTDLSChanSwitchReqParam);
+ VOS_ASSERT(0);
+ return VOS_STATUS_E_NOMEM;
+ }
+ wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.staIdx =
+ pTdlsChanSwitchParams->staIdx;
+ wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.isOffchannelInitiator =
+ pTdlsChanSwitchParams->tdlsSwMode;
+ wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.targetOperClass =
+ pTdlsChanSwitchParams->operClass;
+ wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.targetChannel =
+ pTdlsChanSwitchParams->tdlsOffCh;
+ wdiSetTDLSChanSwitchReqParam->wdiTDLSChanSwitchReqInfo.secondaryChannelOffset =
+ pTdlsChanSwitchParams->tdlsOffChBwOffset;
+
+
+ /* Store msg pointer from PE, as this will be used for response */
+ pWdaParams->wdaMsgParam = (void *)pTdlsChanSwitchParams ;
+ /* store Params pass it to WDI */
+ pWdaParams->wdaWdiApiMsgParam = (void *)wdiSetTDLSChanSwitchReqParam ;
+ pWdaParams->pWdaContext = pWDA;
+ status = WDI_SetTDLSChanSwitchReq(wdiSetTDLSChanSwitchReqParam,
+ (WDI_SetTDLSChanSwitchReqParamsRspCb)
+ WDA_SetTDLSChanSwitchReqParamsCallback,
+ pWdaParams);
+ if(IS_WDI_STATUS_FAILURE(status))
+ {
+ VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_ERROR,
+ "Failure in TDLS Channel Switch Req WDI API, free all the memory" );
+ vos_mem_free(pWdaParams->wdaWdiApiMsgParam) ;
+ vos_mem_free(pWdaParams->wdaMsgParam);
+ vos_mem_free(pWdaParams);
+ }
+ return CONVERT_WDI2VOS_STATUS(status);
+}
+#endif /*FEATURE_WLAN_TDLS*/
#ifdef WLAN_FEATURE_VOWIFI_11R
@@ -13054,6 +13157,14 @@
(tANI_U8*)pMsg->bodyptr);
break;
}
+// tdlsoffchan
+#ifdef FEATURE_WLAN_TDLS
+ case WDA_SET_TDLS_CHAN_SWITCH_REQ:
+ {
+ WDA_ProcessSetTdlsChanSwitchReq(pWDA, (tTdlsChanSwitchParams *)pMsg->bodyptr);
+ break;
+ }
+#endif
default:
{
VOS_TRACE( VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_INFO,
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi.h b/CORE/WDI/CP/inc/wlan_qct_wdi.h
index 59a88f2..d1bb97a 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi.h
@@ -3544,7 +3544,6 @@
void* pUserData;
}WDI_SetTDLSLinkEstablishReqParamsType;
-
typedef struct
{
/*Result of the operation*/
@@ -3554,6 +3553,37 @@
wpt_uint16 uStaIdx;
}WDI_SetTdlsLinkEstablishReqResp;
+
+
+typedef struct
+{
+ /*STA Index*/
+ wpt_uint8 staIdx;
+ /* if this is 1, self is initiator otherwise responder only*/
+ wpt_uint8 isOffchannelInitiator;
+ /*TDLS off channel related params */
+ wpt_uint8 targetOperClass;
+ wpt_uint8 targetChannel;
+ wpt_uint8 secondaryChannelOffset;
+ wpt_uint8 reserved[64];
+}WDI_SetTDLSChanSwitchReqInfoType;
+
+typedef struct
+{
+ WDI_SetTDLSChanSwitchReqInfoType wdiTDLSChanSwitchReqInfo;
+ WDI_ReqStatusCb wdiReqStatusCB;
+ void* pUserData;
+}WDI_SetTDLSChanSwitchReqParamsType;
+
+
+typedef struct
+{
+ /*Result of the operation*/
+ WDI_Status wdiStatus;
+
+ /*STA Idx*/
+ wpt_uint16 uStaIdx;
+}WDI_SetTdlsChanSwitchReqResp;
/*---------------------------------------------------------------------------
WDI_SetAddSTASelfParamsType
---------------------------------------------------------------------------*/
@@ -6645,6 +6675,28 @@
void* pUserData);
/*---------------------------------------------------------------------------
+ WDI_SetTDLSChanSwitchReqParamsRspCb
+
+ DESCRIPTION
+
+ This callback is invoked by DAL when it has received a TDLS Link Establish Req response from
+ the underlying device.
+
+ PARAMETERS
+
+ IN
+ wdiStatus: response status received from HAL
+ pUserData: user data
+
+
+
+ RETURN VALUE
+ The result code associated with performing the operation
+---------------------------------------------------------------------------*/
+typedef void (*WDI_SetTDLSChanSwitchReqParamsRspCb)(WDI_SetTdlsChanSwitchReqResp *
+ wdiSetTdlsChanSwitchReqRsp,
+ void* pUserData);
+/*---------------------------------------------------------------------------
WDI_SetPwrSaveCfgCb
DESCRIPTION
@@ -8824,6 +8876,13 @@
void* pUserData
);
+WDI_Status
+WDI_SetTDLSChanSwitchReq
+(
+ WDI_SetTDLSChanSwitchReqParamsType* pwdiTDLSChanSwitchReqParams,
+ WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchRReqRspCb,
+ void* pUserData
+);
/*========================================================================
Power Save APIs
diff --git a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
index 062217c..eb6ec89 100644
--- a/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
+++ b/CORE/WDI/CP/inc/wlan_qct_wdi_i.h
@@ -462,6 +462,7 @@
WDI_EXTSCAN_SET_SIGNF_RSSI_CHANGE_REQ = 99,
WDI_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_REQ = 100,
#endif
+
WDI_MAX_REQ,
/*Send a suspend Indication down to HAL*/
@@ -499,6 +500,7 @@
/* csa channel switch req*/
WDI_CH_SWITCH_REQ_V1,
+ WDI_TDLS_CHAN_SWITCH_REQ,
/*Keep adding the indications to the max request
such that we keep them sepparate */
@@ -861,6 +863,7 @@
WDI_HAL_EXTSCAN_BSSID_HOTLIST_RESULT_IND = WDI_HAL_IND_MIN + 24,
WDI_HAL_EXTSCAN_SIG_RSSI_RESULT_IND = WDI_HAL_IND_MIN + 25,
#endif
+ WDI_TDLS_CHAN_SWITCH_REQ_RESP = WDI_HAL_IND_MIN + 28,
WDI_MAX_RESP
}WDI_ResponseEnumType;
@@ -2401,6 +2404,21 @@
);
/**
+ @brief Process tdls channel switch request
+
+ @param pWDICtx: pointer to the WLAN DAL context
+ pEventData: pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessTdlsChanSwitchReq
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+);
+/**
@brief Process Enter IMPS Request function (called when
Main FSM allows it)
@@ -3852,6 +3870,24 @@
WDI_EventInfoType* pEventData
);
+
+ /**
+ @brief Process TDLS Chan Switch Req Rsp function (called when a response
+ is being received over the bus from HAL)
+
+ @param pWDICtx: pointer to the WLAN DAL context
+ pEventData: pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessChanSwitchReqRsp
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+);
+
/**
@brief Process Nv download(called when a response
is being received over the bus from HAL)
diff --git a/CORE/WDI/CP/src/wlan_qct_wdi.c b/CORE/WDI/CP/src/wlan_qct_wdi.c
index f0bc1fe..2ee834a 100644
--- a/CORE/WDI/CP/src/wlan_qct_wdi.c
+++ b/CORE/WDI/CP/src/wlan_qct_wdi.c
@@ -478,6 +478,11 @@
WDI_ProcessHT40OBSSStopScanInd, /*WDI_STOP_HT40_OBSS_SCAN_IND */
WDI_ProcessChannelSwitchReq_V1, /* WDI_CH_SWITCH_REQ_V1*/
+#ifdef FEATURE_WLAN_TDLS
+ WDI_ProcessTdlsChanSwitchReq, /* WDI_TDLS_CHAN_SWITCH_REQ */
+#else
+ NULL,
+#endif
};
@@ -783,6 +788,11 @@
NULL,
NULL,
#endif /* WLAN_FEATURE_EXTSCAN */
+#ifdef FEATURE_WLAN_TDLS
+ WDI_ProcessChanSwitchReqRsp, /*WDI_TDLS_CHAN_SWITCH_REQ_RESP*/
+#else
+ NULL,
+#endif
};
@@ -1040,6 +1050,7 @@
CASE_RETURN_STRING( WDI_P2P_GO_NOTICE_OF_ABSENCE_REQ );
#ifdef FEATURE_WLAN_TDLS
CASE_RETURN_STRING( WDI_TDLS_LINK_ESTABLISH_REQ );
+ CASE_RETURN_STRING( WDI_TDLS_CHAN_SWITCH_REQ );
#endif
CASE_RETURN_STRING( WDI_ENTER_IMPS_REQ );
CASE_RETURN_STRING( WDI_EXIT_IMPS_REQ );
@@ -1171,6 +1182,7 @@
CASE_RETURN_STRING( WDI_P2P_GO_NOTICE_OF_ABSENCE_RESP );
#ifdef FEATURE_WLAN_TDLS
CASE_RETURN_STRING( WDI_TDLS_LINK_ESTABLISH_REQ_RESP );
+ CASE_RETURN_STRING( WDI_TDLS_CHAN_SWITCH_REQ_RESP);
CASE_RETURN_STRING( WDI_HAL_TDLS_IND );
#endif
CASE_RETURN_STRING( WDI_ENTER_IMPS_RESP );
@@ -5899,6 +5911,67 @@
return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
}/*WDI_SetTDLSLinkEstablishReq*/
+
+//tdlsoffchan
+/**
+ @brief WDI_SetTDLSChanSwitchReq will be called when the
+ upper MAC wants to send TDLS Chan Switch Request Parameters
+ Upon the call of this API the WLAN DAL will
+ pack and send the TDLS Link Establish Request message to the
+ lower RIVA sub-system if DAL is in state STARTED.
+
+ In state BUSY this request will be queued. Request won't
+ be allowed in any other state.
+
+
+ @param pwdiTDLSChanSwitchReqParams: TDLS Peer Parameters
+ for Link Establishment (Used for TDLS Off Channel ...)
+
+ wdiTDLSChanSwitchReqRspCb: callback for passing back the
+ response of the TDLS Chan Switch request received
+ from the device
+
+ pUserData: user data will be passed back with the
+ callback
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_SetTDLSChanSwitchReq
+(
+ WDI_SetTDLSChanSwitchReqParamsType* pwdiTDLSChanSwitchReqParams,
+ WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchRReqRspCb,
+ void* pUserData
+)
+{
+ WDI_EventInfoType wdiEventData;
+ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ /*------------------------------------------------------------------------
+ Sanity Check
+ ------------------------------------------------------------------------*/
+ if ( eWLAN_PAL_FALSE == gWDIInitialized )
+ {
+ WPAL_TRACE(eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_ERROR,
+ "WDI API call before module is initialized - Fail request");
+
+ return WDI_STATUS_E_NOT_ALLOWED;
+ }
+
+ /*------------------------------------------------------------------------
+ Fill in Event data and post to the Main FSM
+ ------------------------------------------------------------------------*/
+ wdiEventData.wdiRequest = WDI_TDLS_CHAN_SWITCH_REQ;
+ wdiEventData.pEventData = pwdiTDLSChanSwitchReqParams;
+ wdiEventData.uEventDataSize = sizeof(*pwdiTDLSChanSwitchReqParams);
+ wdiEventData.pCBfnc = wdiTDLSChanSwitchRReqRspCb;
+ wdiEventData.pUserData = pUserData;
+
+ return WDI_PostMainEvent(&gWDICb, WDI_REQUEST_EVENT, &wdiEventData);
+
+}/*WDI_SetTDLSChanSwitchReq*/
+
#endif
/**
@@ -13425,7 +13498,87 @@
}/*WDI_ProcessTdlsLinkEstablishReq*/
-#endif
+/**
+ @brief sends the channel switch command to f/w (called when Main FSM
+ allows it)
+
+ @param pWDICtx: pointer to the WLAN DAL context
+ pEventData: pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessTdlsChanSwitchReq
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+)
+{
+ WDI_SetTDLSChanSwitchReqParamsType* pwdiTDLSChanSwitchReqParams;
+ WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchReqRspCb;
+ wpt_uint8* pSendBuffer = NULL;
+ wpt_uint16 usDataOffset = 0;
+ wpt_uint16 usSendSize = 0;
+ //WDI_Status wdiStatus;
+ tTDLSChanSwitchReqType halSetTDLSChanSwitchParams;
+ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ /*-------------------------------------------------------------------------
+ Sanity check
+ -------------------------------------------------------------------------*/
+ if (( NULL == pEventData ) ||
+ ( NULL == pEventData->pEventData))
+ {
+ WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+ pwdiTDLSChanSwitchReqParams =
+ (WDI_SetTDLSChanSwitchReqParamsType*)pEventData->pEventData;
+ wdiTDLSChanSwitchReqRspCb =
+ (WDI_SetTDLSChanSwitchReqParamsRspCb)pEventData->pCBfnc;
+
+ /*-----------------------------------------------------------------------
+ Get message buffer
+ -----------------------------------------------------------------------*/
+ if (( WDI_STATUS_SUCCESS != WDI_GetMessageBuffer( pWDICtx,
+ WDI_TDLS_CHAN_SWITCH_REQ,
+ sizeof(halSetTDLSChanSwitchParams),
+ &pSendBuffer, &usDataOffset, &usSendSize))||
+ ( usSendSize < (usDataOffset + sizeof(halSetTDLSChanSwitchParams) )))
+ {
+ WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "Unable to get send buffer in Channel Switch REQ %p %p %p",
+ pEventData, pwdiTDLSChanSwitchReqParams, wdiTDLSChanSwitchReqRspCb);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ halSetTDLSChanSwitchParams.staIdx =
+ pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.staIdx;
+ halSetTDLSChanSwitchParams.isOffchannelInitiator =
+ pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.isOffchannelInitiator;
+ halSetTDLSChanSwitchParams.targetOperClass =
+ pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.targetOperClass;
+ halSetTDLSChanSwitchParams.targetChannel =
+ pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.targetChannel;
+ halSetTDLSChanSwitchParams.secondaryChannelOffset =
+ pwdiTDLSChanSwitchReqParams->wdiTDLSChanSwitchReqInfo.secondaryChannelOffset;
+ wpalMemoryCopy( pSendBuffer+usDataOffset,
+ &halSetTDLSChanSwitchParams,
+ sizeof(halSetTDLSChanSwitchParams));
+
+ pWDICtx->wdiReqStatusCB = NULL;
+ pWDICtx->pReqStatusUserData = NULL;
+
+ return WDI_SendMsg( pWDICtx, pSendBuffer, usSendSize,
+ wdiTDLSChanSwitchReqRspCb, pEventData->pUserData,
+ WDI_TDLS_CHAN_SWITCH_REQ_RESP);
+}/*WDI_ProcessTdlsChanSwitchReq*/
+
+#endif /*FEATURE_WLAN_TDLS*/
@@ -19020,6 +19173,72 @@
return WDI_STATUS_SUCCESS;
}/*WDI_ProcessLinkEstablishReqRsp*/
+
+
+
+/**
+ @brief Process TDLS Chan switch Rsp function (called
+ when a response is being received over the bus from HAL)
+
+ @param pWDICtx: pointer to the WLAN DAL context
+ pEventData: pointer to the event information structure
+
+ @see
+ @return Result of the function call
+*/
+WDI_Status
+WDI_ProcessChanSwitchReqRsp
+(
+ WDI_ControlBlockType* pWDICtx,
+ WDI_EventInfoType* pEventData
+)
+{
+ eHalStatus halStatus;
+ WDI_SetTDLSChanSwitchReqParamsRspCb wdiTDLSChanSwitchReqParamsRspCb;
+ tTDLSChanSwitchRespMsg halTdlsChanSwitchRespMsg;
+ WDI_SetTdlsChanSwitchReqResp wdiSetTdlsChanSwitchReqResp;
+
+ /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+ /*-------------------------------------------------------------------------
+ Sanity check
+ -------------------------------------------------------------------------*/
+ if (( NULL == pWDICtx ) || ( NULL == pEventData ) ||
+ ( NULL == pEventData->pEventData))
+ {
+ WPAL_TRACE( eWLAN_MODULE_DAL_CTRL, eWLAN_PAL_TRACE_LEVEL_WARN,
+ "%s: Invalid parameters", __func__);
+ WDI_ASSERT(0);
+ return WDI_STATUS_E_FAILURE;
+ }
+
+ /*-------------------------------------------------------------------------
+ Extract indication and send it to UMAC
+ -------------------------------------------------------------------------*/
+ wpalMemoryCopy( &halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams,
+ pEventData->pEventData,
+ sizeof(halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams) );
+
+ wdiTDLSChanSwitchReqParamsRspCb = (WDI_SetTDLSChanSwitchReqParamsRspCb)pWDICtx->pfncRspCB;
+
+ /*-------------------------------------------------------------------------
+ Extract response and send it to UMAC
+ -------------------------------------------------------------------------*/
+ wpalMemoryCopy( &halStatus,
+ pEventData->pEventData,
+ sizeof(halStatus));
+
+ wdiSetTdlsChanSwitchReqResp.wdiStatus = WDI_HAL_2_WDI_STATUS(halStatus);
+ wdiSetTdlsChanSwitchReqResp.uStaIdx = halTdlsChanSwitchRespMsg.tdlsChanSwitchRespParams.staIdx;
+
+ /*Notify UMAC*/
+ wdiTDLSChanSwitchReqParamsRspCb( &wdiSetTdlsChanSwitchReqResp, pWDICtx->pRspCBUserData );
+
+ return WDI_STATUS_SUCCESS;
+}/*WDI_ProcessChanSwitchReqRsp*/
+
+
+
#endif
/**
@@ -23440,6 +23659,8 @@
#ifdef FEATURE_WLAN_TDLS
case WDI_TDLS_LINK_ESTABLISH_REQ:
return WLAN_HAL_TDLS_LINK_ESTABLISHED_REQ;
+ case WDI_TDLS_CHAN_SWITCH_REQ:
+ return WLAN_HAL_TDLS_CHAN_SWITCH_REQ;
#endif
case WDI_ENTER_IMPS_REQ:
return WLAN_HAL_ENTER_IMPS_REQ;
@@ -23735,6 +23956,8 @@
#ifdef FEATURE_WLAN_TDLS
case WLAN_HAL_TDLS_LINK_ESTABLISHED_RSP:
return WDI_TDLS_LINK_ESTABLISH_REQ_RESP;
+ case WLAN_HAL_TDLS_CHAN_SWITCH_RSP:
+ return WDI_TDLS_CHAN_SWITCH_REQ_RESP;
case WLAN_HAL_TDLS_IND:
return WDI_HAL_TDLS_IND;
#endif
@@ -30301,6 +30524,7 @@
return WDI_STATUS_SUCCESS;
}
+
#endif /* FEATURE_WLAN_CH_AVOID */
/**