wlan: TDLS Integration from Dev32Sta
Support for TDLS discovery, setup and teardown.
Exit BMPS while in active TDLS link and enable back afterwards.
Change-Id: Ic653c5369cb0b61e04e9a8be5e7f625ab7160365
CR-Fixed: 426223
(cherry picked from commit 698ba2a565d4ccf0d6a570eab18f79e1dea10a1d)
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 0cca8f4..44d72bc 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -81,6 +81,9 @@
#include "bap_hdd_misc.h"
#endif
#include <qc_sap_ioctl.h>
+#ifdef FEATURE_WLAN_TDLS
+#include "wlan_hdd_tdls.h"
+#endif
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -466,6 +469,11 @@
| WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
| WIPHY_FLAG_OFFCHAN_TX;
#endif
+#ifdef FEATURE_WLAN_TDLS
+ wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
+ | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
+#endif
+
/* even with WIPHY_FLAG_CUSTOM_REGULATORY,
driver can still register regulatory callback and
it will get CRDA setting in wiphy->band[], but
@@ -6000,8 +6008,54 @@
static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
struct net_device *dev, u8 *mac, struct station_parameters *params)
{
- // TODO: Implement this later.
+#ifdef FEATURE_WLAN_TDLS
+ hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+ u32 mask, set;
+ VOS_STATUS status;
ENTER();
+
+ if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "Invalid arguments");
+ return -EINVAL;
+ }
+
+ if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
+ FALSE == sme_IsFeatureSupportedByFW(TDLS))
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "TDLS Disabled in INI OR not enabled in FW.\
+ Cannot process TDLS commands \n");
+ return -ENOTSUPP;
+ }
+
+ mask = params->sta_flags_mask;
+
+ set = params->sta_flags_set;
+
+
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "Add Station Request Mask = 0x%x set = 0x%x\n", mask, set);
+
+ if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
+ if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "Add TDLS peer");
+
+
+ status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId, mac);
+
+ if (VOS_STATUS_SUCCESS != status) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_AddTdlsPeerSta failed!", __func__);
+ }
+ }
+ }
+#endif
+
return 0;
}
@@ -6150,6 +6204,139 @@
}
#endif
+#ifdef FEATURE_WLAN_TDLS
+static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
+ u8 *peer, u8 action_code, u8 dialog_token,
+ u16 status_code, const u8 *buf, size_t len)
+{
+
+ hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+ u8 *buf_1;
+ size_t len_1 = len;
+ u8 peerMac[6];
+ VOS_STATUS status;
+
+ if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "Invalid arguments");
+ return -EINVAL;
+ }
+
+ if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
+ FALSE == sme_IsFeatureSupportedByFW(TDLS))
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "TDLS Disabled in INI OR not enabled in FW.\
+ Cannot process TDLS commands \n");
+ return -ENOTSUPP;
+ }
+ vos_mem_copy( peerMac, peer, 6);
+
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "Request to send TDLS management: action = %d, status = %d, \
+ len = %d", action_code, status_code, len);
+
+ buf_1 = vos_mem_malloc(len);
+ if(buf_1 == NULL) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: malloc failed!", __func__);
+ return -ENOMEM;
+ }
+ vos_mem_copy(buf_1, buf, len);
+
+ status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
+ peerMac, action_code, dialog_token, status_code, buf_1, len_1);
+
+ if (VOS_STATUS_SUCCESS != status) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_SendTdlsMgmtFrame failed!", __func__);
+ }
+
+ vos_mem_free(buf_1);
+
+ return 0;
+}
+
+static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
+ u8 *peer, enum nl80211_tdls_operation oper)
+{
+ hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *pHddCtx = wiphy_priv(wiphy);
+
+ if( NULL == pHddCtx || NULL == pHddCtx->cfg_ini )
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "Invalid arguments");
+ return -EINVAL;
+ }
+
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "Request for TDLS oper: %d", (int)oper);
+
+ if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
+ FALSE == sme_IsFeatureSupportedByFW(TDLS))
+ {
+ VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "TDLS Disabled in INI OR not enabled in FW.\
+ Cannot process TDLS commands \n");
+ return -ENOTSUPP;
+ }
+
+ switch (oper) {
+ case NL80211_TDLS_ENABLE_LINK:
+ {
+ v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
+ v_U8_t my_peer[6];
+ v_U8_t ucSTAId;
+ VOS_STATUS status;
+
+ if (peer) {
+ vos_mem_copy(my_peer, peer, 6);
+ ucSTAId = wlan_hdd_findTdlsPeer(my_peer);
+
+ hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
+ "%s: set key for peer %2x:%2x:%2x:%2x:%2x:%2x",
+ __func__, peer[0], peer[1],
+ peer[2], peer[3],
+ peer[4], peer[5] );
+
+ if (-1 == ucSTAId ) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, "wlan_hdd_findTdlsPeer failed" );
+ return 0;
+ }
+
+ status = WLANTL_ChangeSTAState( pVosContext, ucSTAId,
+ WLANTL_STA_AUTHENTICATED );
+
+ if (0 != status) {
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ "%s: WLANTL_ChangeSTAState failed, returned %d",
+ __func__, status);
+ return status;
+ }
+ } else {
+ hddLog(VOS_TRACE_LEVEL_WARN, "wlan_hdd_cfg80211_add_key: peer NULL" );
+ }
+ }
+ break;
+ case NL80211_TDLS_DISABLE_LINK:
+ sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
+ pAdapter->sessionId, peer );
+ return 0;
+ case NL80211_TDLS_TEARDOWN:
+ case NL80211_TDLS_SETUP:
+ case NL80211_TDLS_DISCOVERY_REQ:
+ /* We don't support in-driver setup/teardown/discovery */
+ return -ENOTSUPP;
+ default:
+ return -ENOTSUPP;
+ }
+ return 0;
+}
+#endif
+
/* cfg80211_ops */
static struct cfg80211_ops wlan_hdd_cfg80211_ops =
{
@@ -6202,6 +6389,10 @@
#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
.update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
#endif
+#ifdef FEATURE_WLAN_TDLS
+ .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
+ .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
+#endif
};
#endif // CONFIG_CFG80211