Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81bcd112 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge c7c46b9e on remote branch

Change-Id: I137d56902aa10e621d40c8a6fcc5afeb8ae66a26
parents c2206dd1 c7c46b9e
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -1572,6 +1572,10 @@ struct hdd_cache_channels {
	struct hdd_cache_channel_info *channel_info;
};

#ifdef FEATURE_WLAN_SW_PTA
#define WLAN_WAIT_TIME_SW_PTA 1000
#endif

struct hdd_context_s
{
   /** Global VOS context  */
@@ -1791,6 +1795,8 @@ struct hdd_context_s

    v_BOOL_t btCoexModeSet;
    v_BOOL_t isPnoEnable;
    bool     is_sco_enabled;
    bool     is_bt_enabled;
    macAddrSpoof_t spoofMacAddr;
    /* flag to decide if driver need to scan DFS channels or not */
    v_BOOL_t  disable_dfs_flag;
@@ -1863,6 +1869,9 @@ struct hdd_context_s
    struct hdd_cache_channels *original_channels;
    struct mutex cache_channel_lock;
    bool force_rsne_override;
#ifdef FEATURE_WLAN_SW_PTA
    struct completion sw_pta_comp;
#endif
};

/* Use to notify the TDLS or BTCOEX is mode enable */
@@ -2425,4 +2434,30 @@ static inline void hdd_fill_last_rx(hdd_adapter_t *adapter)
#else
void hdd_fill_last_rx(hdd_adapter_t *adapter);
#endif

#ifdef FEATURE_WLAN_SW_PTA
/**
 * hdd_process_bt_sco_profile - process BT SCO profile
 * @hdd_ctx: pointer to HDD context
 * @bt_enabled: status of BT
 * @bt_sco: status of SCO
 *
 * Return: 0 on success, error on failure
 */
int hdd_process_bt_sco_profile(hdd_context_t *hdd_ctx,
			       bool bt_enabled, bool bt_sco);

/**
 * hdd_is_sw_pta_enabled - is sw pta enabled
 * @hdd_ctx: pointer to HDD context
 *
 * Return: bool
 */
bool hdd_is_sw_pta_enabled(hdd_context_t *hdd_ctx);
#else
static inline bool hdd_is_sw_pta_enabled(hdd_context_t *hdd_ctx)
{
	return 0;
}
#endif
#endif    // end #if !defined( WLAN_HDD_MAIN_H )
+37 −0
Original line number Diff line number Diff line
@@ -620,6 +620,13 @@ static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
};
#endif /* WLAN_NL80211_TESTMODE */
#ifdef FEATURE_WLAN_SW_PTA
bool hdd_is_sw_pta_enabled(hdd_context_t *hdd_ctx)
{
	return hdd_ctx->cfg_ini->is_sw_pta_enabled;
}
#endif
#ifdef FEATURE_WLAN_CH_AVOID
/*
 * FUNCTION: wlan_hdd_send_avoid_freq_event
@@ -15805,6 +15812,19 @@ int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
    }
    mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
    /**
     * If sw pta is enabled, scan should not allowed.
     * Returning error makes framework to trigger scan continuously
     * for every second, so indicating framework that scan is aborted
     * and return success.
     */
    if (hdd_is_sw_pta_enabled(pHddCtx) && pHddCtx->is_sco_enabled) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  FL("BT SCO operation in progress"));
        hdd_cfg80211_scan_done(pAdapter, request, true);
        return 0;
    }
    /* Check if scan is allowed at this point of time.
     */
    if (TRUE == pHddCtx->btCoexModeSet)
@@ -16323,6 +16343,14 @@ int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
        return -EINVAL;
    }
    /**
     * If sw pta is enabled, new connections should not allowed.
     */
    if (hdd_is_sw_pta_enabled(pHddCtx) && pHddCtx->is_sco_enabled) {
        hddLog(VOS_TRACE_LEVEL_ERROR, "%s: BT SCO operation in progress",
               __func__);
        return -EINVAL;
    }
    pRoamProfile = &pWextState->roamProfile;
@@ -20078,6 +20106,15 @@ void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
    }
    spin_unlock(&pHddCtx->schedScan_lock);
    /**
     * If sw pta is enabled, scan results should not send to framework.
     */
    if (hdd_is_sw_pta_enabled(pHddCtx) && pHddCtx->is_sco_enabled) {
        VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
                  FL("BT SCO operation in progress"));
        return;
    }
    ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
    if (0 > ret)
+155 −104
Original line number Diff line number Diff line
@@ -214,9 +214,6 @@ static VOS_STATUS hdd_parse_ese_beacon_req(tANI_U8 *pValue,
//wait time for beacon miss rate.
#define BCN_MISS_RATE_TIME 500
//max size for BT profile indication cmd
#define MAX_USER_COMMAND_SIZE_BT_PROFILE_IND_CMD 24
/*
 * Android DRIVER command structures
 */
@@ -250,19 +247,6 @@ static int hdd_ParseIBSSTXFailEventParams(tANI_U8 *pValue,
static int hdd_ParseUserParams(tANI_U8 *pValue, tANI_U8 **ppArg);
#endif /* WLAN_FEATURE_RMC */
#ifdef FEATURE_WLAN_SW_PTA
/* BT profile sysfile entry obj */
static struct kobject *driver_kobject;
static ssize_t hdd_sysfs_bt_profile_ind_cmd_store(struct kobject *kobj,
                                                  struct kobj_attribute *attr,
                                                  const char *buf,
                                                  size_t count);
static struct kobj_attribute bt_profile_attribute =
    __ATTR(bt_profile, 0220, NULL,
           hdd_sysfs_bt_profile_ind_cmd_store);
#endif
void wlan_hdd_restart_timer_cb(v_PVOID_t usrDataForCallback);
void hdd_set_wlan_suspend_mode(bool suspend);
void hdd_set_vowifi_mode(hdd_context_t *hdd_ctx, bool enable);
@@ -3909,130 +3893,198 @@ int hdd_get_disable_ch_list(hdd_context_t *hdd_ctx, tANI_U8 *buf,
}
#ifdef FEATURE_WLAN_SW_PTA
static void hdd_sysfs_bt_profile_create(hdd_context_t* hdd_ctx)
static void hdd_sco_resp_callback(uint8_t sco_status)
{
	if(!hdd_ctx->cfg_ini->is_sw_pta_enabled)
		return;
	hdd_context_t *hdd_ctx = NULL;
	v_CONTEXT_t vos_ctx = NULL;
	driver_kobject = kobject_create_and_add(WLAN_MODULE_NAME, kernel_kobj);
	if (!driver_kobject) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s:could not allocate driver kobject",
		       __func__);
	vos_ctx = vos_get_global_context(VOS_MODULE_ID_SYS, NULL);
	if (!vos_ctx) {
		hddLog(VOS_TRACE_LEVEL_FATAL,
		       "%s: Global VOS context is Null", __func__);
		return;
	}
	if(sysfs_create_file(driver_kobject, &bt_profile_attribute.attr))
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s:Failed to create BT profile sysfs entry", __func__);
	/* Get the HDD context. */
	hdd_ctx = (hdd_context_t*)vos_get_context(VOS_MODULE_ID_HDD, vos_ctx);
	if (!hdd_ctx) {
		hddLog(VOS_TRACE_LEVEL_FATAL,
		       "%s: HDD context is Null", __func__);
		return;
	}
static void hdd_sysfs_bt_profile_destroy(hdd_context_t* hdd_ctx)
{
	if(!hdd_ctx->cfg_ini->is_sw_pta_enabled)
		return;
	hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Response status %d",
	       __func__, sco_status);
	sysfs_remove_file(driver_kobject, &bt_profile_attribute.attr);
	if (driver_kobject) {
		kobject_put(driver_kobject);
		driver_kobject = NULL;
	if (sco_status) {
		hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid sco status %d",
		       __func__, sco_status);
		return;
	}
	complete(&hdd_ctx->sw_pta_comp);
}
static int hdd_sysfs_validate_and_copy_buf(char *dest_buf, size_t dest_buf_size,
					   char const *source_buf,
					   size_t source_buf_size)
int hdd_process_bt_sco_profile(hdd_context_t *hdd_ctx,
			       bool bt_enabled, bool bt_sco)
{
	if (source_buf_size > (dest_buf_size - 1)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s:Command length is larger than %zu bytes",
			   __func__, dest_buf_size);
	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hdd_ctx->hHal);
	uint8_t no_of_states_changed = 0;
	hdd_station_ctx_t *hdd_sta_ctx;
	eConnectionState conn_state;
	hdd_adapter_t *adapter;
	eHalStatus hal_status;
	bool sco_status;
	int rc;
	if (!mac_ctx) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mac_ctx got NULL", __func__);
		return -EINVAL;
	}
	/* sysfs already provides kernel space buffer so copy from user
	 * is not needed. Doing this extra copy operation just to ensure
	 * the local buf is properly null-terminated.
	/**
	 * At a time only one status can be changed compared to
	 * previous command (BT_ENABLED/SCO)
	 * If no.of states changed is greater than one it is
	 * an invalid command.
	 */
	strlcpy(dest_buf, source_buf, dest_buf_size);
	if (bt_enabled != hdd_ctx->is_bt_enabled)
		no_of_states_changed++;
	/* default 'echo' cmd takes new line character to here */
	if (dest_buf[source_buf_size - 1] == '\n')
		dest_buf[source_buf_size - 1] = '\0';
	if (bt_sco != hdd_ctx->is_sco_enabled)
		no_of_states_changed++;
	return 0;
	if (no_of_states_changed > 1) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Multiple states changed",
		       __func__);
		return -EINVAL;
	}
static ssize_t __hdd_sysfs_bt_profile_ind_cmd_store(hdd_context_t *hdd_ctx,
						    const char *buf,
						    size_t count)
{
	char buf_local[MAX_USER_COMMAND_SIZE_BT_PROFILE_IND_CMD + 1];
	char *sptr, *token, *profile, *profile_mode;
	int ret;
	INIT_COMPLETION(hdd_ctx->sw_pta_comp);
	ENTER();
	if (wlan_hdd_validate_context(hdd_ctx))
	if (bt_enabled != hdd_ctx->is_bt_enabled) {
		hal_status = sme_bt_req(hdd_ctx->hHal,
					hdd_sco_resp_callback,
					adapter->sessionId, bt_enabled);
		if (!HAL_STATUS_SUCCESS(hal_status)) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s: Error sending sme sco indication request",
			       __func__);
			return -EINVAL;
		}
	ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local),
					      buf, count);
	if (ret)
		rc = wait_for_completion_timeout(&hdd_ctx->sw_pta_comp,
				msecs_to_jiffies(WLAN_WAIT_TIME_SW_PTA));
		if (!rc) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       FL("Target response timed out for sw_pta_comp"));
			return -EINVAL;
		}
	sptr = buf_local;
	/* Get BT profile */
	token = strsep(&sptr, " ");
		hdd_ctx->is_bt_enabled = bt_enabled;
		return 0;
	}
	if (!token)
		return -EINVAL;
	profile = token;
	if (bt_sco) {
		if (hdd_ctx->is_sco_enabled) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s: BT SCO is already enabled", __func__);
			return 0;
		}
		sco_status = true;
	} else {
		if (!hdd_ctx->is_sco_enabled) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s: BT SCO is already disabled", __func__);
			return 0;
		}
		sco_status = false;
	}
	token = NULL;
	/* Get BT profile mode */
	token = strsep(&sptr, " ");
	hal_status = sme_sco_req(hdd_ctx->hHal,
				 hdd_sco_resp_callback,
				 adapter->sessionId, sco_status);
	if (!HAL_STATUS_SUCCESS(hal_status)) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: Error sending sme sco indication request",
		       __func__);
		return -EINVAL;
	}
	if (!token)
	rc = wait_for_completion_timeout(&hdd_ctx->sw_pta_comp,
			msecs_to_jiffies(WLAN_WAIT_TIME_SW_PTA));
	if (!rc) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       FL("Target response timed out for sw_pta_comp"));
		return -EINVAL;
	}
	profile_mode = token;
	if (!bt_sco) {
		hdd_ctx->is_sco_enabled = false;
		mac_ctx->isCoexScoIndSet = 0;
		return 0;
	}
	hddLog(VOS_TRACE_LEVEL_INFO, "%s:profile = %s, profile_mode = %s",
	       __func__, profile, profile_mode);
	adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
	if (!adapter) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: No station adapter to enable bt sco", __func__);
		return -EINVAL;
	}
	EXIT();
	return count;
	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
	if (!hdd_sta_ctx) {
		hddLog(VOS_TRACE_LEVEL_ERROR,
		       "%s: No station context to enable bt sco", __func__);
		return -EINVAL;
	}
static ssize_t hdd_sysfs_bt_profile_ind_cmd_store(struct kobject *kobj,
						  struct kobj_attribute *attr,
						  const char *buf,
						  size_t count)
{
	hdd_context_t *pHddCtx = NULL;
	ssize_t err_size = 0;
	if (wlan_hdd_scan_abort(adapter)) {
		hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Error aborting scan request",
		       __func__);
		return -EINVAL;
	}
	pHddCtx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD,
			vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
	hdd_ctx->is_sco_enabled = true;
	mac_ctx->isCoexScoIndSet = 1;
	if (!pHddCtx) {
		hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
	conn_state = hdd_sta_ctx->conn_info.connState;
	if (eConnectionState_Connecting == conn_state ||
	    smeNeighborMiddleOfRoaming(hdd_sta_ctx) ||
	    (eConnectionState_Associated == conn_state &&
	      sme_is_sta_key_exchange_in_progress(hdd_ctx->hHal,
						  adapter->sessionId)))
		sme_abortConnection(hdd_ctx->hHal,
				    adapter->sessionId);
	if (hdd_connIsConnected(hdd_sta_ctx)) {
		hal_status = sme_teardown_link_with_ap(mac_ctx,
						       adapter->sessionId);
		if (!HAL_STATUS_SUCCESS(hal_status)) {
			hddLog(VOS_TRACE_LEVEL_ERROR,
			       "%s: Error while Teardown link wih AP",
			       __func__);
			return -EINVAL;
		}
	}
	err_size = __hdd_sysfs_bt_profile_ind_cmd_store(pHddCtx, buf, count);
	return 0;
}
static void hdd_init_sw_pta(hdd_context_t *hdd_ctx)
{
	init_completion(&hdd_ctx->sw_pta_comp);
}
	return err_size;
static void hdd_deinit_sw_pta(hdd_context_t *hdd_ctx)
{
	complete(&hdd_ctx->sw_pta_comp);
}
#else
static inline
void hdd_sysfs_bt_profile_create(hdd_context_t* pHddCtx)
static void hdd_init_sw_pta(hdd_context_t *hdd_ctx)
{
}
static inline
void hdd_sysfs_bt_profile_destroy(hdd_context_t* pHddCtx)
static void hdd_deinit_sw_pta(hdd_context_t *hdd_ctx)
{
}
#endif
@@ -8277,8 +8329,6 @@ int __hdd_open(struct net_device *dev)
		  "%s: session already exist for station mode", __func__);
   }
   hdd_sysfs_bt_profile_create(pHddCtx);
   set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
   if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) 
   {
@@ -8456,8 +8506,6 @@ int __hdd_stop (struct net_device *dev)
       wlan_hdd_stop_mon(pHddCtx, true);
   }
   hdd_sysfs_bt_profile_destroy(pHddCtx);
   hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disabling OS Tx queues", __func__);
   /* Disable TX on the interface, after this hard_start_xmit() will not
@@ -12639,6 +12687,7 @@ void hdd_wlan_exit(hdd_context_t *pHddCtx)
      wlan_hdd_ftm_close(pHddCtx);
      goto free_hdd_ctx;
   }
   hdd_deinit_sw_pta(pHddCtx);
   /* DeRegister with platform driver as client for Suspend/Resume */
   vosStatus = hddDeregisterPmOps(pHddCtx);
@@ -14759,6 +14808,8 @@ int hdd_wlan_startup(struct device *dev )
   hdd_assoc_registerFwdEapolCB(pVosContext);
   mutex_init(&pHddCtx->cache_channel_lock);
   hdd_init_sw_pta(pHddCtx);
   goto success;
err_open_cesium_nl_sock:
+1 −0
Original line number Diff line number Diff line
@@ -406,6 +406,7 @@ enum eWniMsgTypes
    eWNI_SME_SEND_SAE_MSG,
#ifdef FEATURE_WLAN_SW_PTA
    eWNI_SME_SW_PTA_RESP,
    eWNI_SME_TEARDOWN_LINK_WITH_AP,
#endif
    eWNI_SME_MSG_TYPES_END
};
+12 −0
Original line number Diff line number Diff line
@@ -283,6 +283,18 @@ struct sir_mgmt_msg {
    uint8_t *data;
};

#ifdef FEATURE_WLAN_SW_PTA
/**
 * struct sir_teardown_link - Struct used to tear down link with AP
 * @type: Message type
 * @session_id: session id
 */
struct sir_teardown_link {
    uint16_t type;
    uint8_t session_id;
};
#endif

/// Message queue definitions
//  msgtype(2bytes) reserved(2bytes) bodyptr(4bytes) bodyval(4bytes)
//  NOTE tSirMsgQ should be always multiples of WORD(4Bytes)
Loading