qcacld-3.0: Fix to make common change intf api for ibss/sta/p2pcli

Current code is using seperate change interface for IBSS and
STA/P2PCLI.

Fix the API such that IBSS/STA/P2PCLI all can use same API.

Change-Id: I7a1d9fa3ef42091fcb7f71d95b604e3dceb8da50
CRs-Fixed: 973626
This commit is contained in:
Krunal Soni 2016-02-03 16:08:37 -08:00 • committed by Vishwajith Upendra
commit 8c37e32104
4 changed files with 93 additions and 144 deletions

View file

@ -1545,6 +1545,9 @@ QDF_STATUS cds_get_vdev_types(enum tQDF_ADAPTER_MODE mode, uint32_t *type,
case QDF_OCB_MODE:
*type = WMI_VDEV_TYPE_OCB;
break;
case QDF_IBSS_MODE:
*type = WMI_VDEV_TYPE_IBSS;
break;
default:
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
"Invalid device mode %d", mode);

View file

@ -5903,63 +5903,61 @@ static int __wlan_hdd_cfg80211_change_bss(struct wiphy *wiphy,
return ret;
}
static int
wlan_hdd_change_iface_to_adhoc(struct net_device *ndev,
tCsrRoamProfile *pRoamProfile,
enum nl80211_iftype type)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
struct hdd_config *pConfig = pHddCtx->config;
struct wireless_dev *wdev = ndev->ieee80211_ptr;
pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
pRoamProfile->phyMode =
hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
pAdapter->device_mode = WLAN_HDD_IBSS;
wdev->iftype = type;
return 0;
}
static int wlan_hdd_change_iface_to_sta_mode(struct net_device *ndev,
/**
* wlan_hdd_change_client_iface_to_new_mode() - to change iface to provided mode
* @ndev: pointer to net device provided by supplicant
* @type: type of the interface, upper layer wanted to change
*
* Upper layer provides the new interface mode that needs to be changed
* for given net device
*
* Return: success or failure in terms of integer value
*/
static int wlan_hdd_change_client_iface_to_new_mode(struct net_device *ndev,
enum nl80211_iftype type)
{
hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev);
hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
struct hdd_config *config = hdd_ctx->config;
hdd_wext_state_t *wext;
struct wireless_dev *wdev;
QDF_STATUS status;
ENTER();
if (test_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags)) {
if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) {
hddLog(LOG1, FL("ACS is in progress, don't change iface!"));
return 0;
}
wdev = ndev->ieee80211_ptr;
hdd_stop_adapter(pHddCtx, pAdapter, true);
hdd_deinit_adapter(pHddCtx, pAdapter, true);
hdd_stop_adapter(hdd_ctx, adapter, true);
hdd_deinit_adapter(hdd_ctx, adapter, true);
wdev->iftype = type;
/*Check for sub-string p2p to confirm its a p2p interface */
if (NULL != strnstr(ndev->name, "p2p", 3)) {
pAdapter->device_mode =
adapter->device_mode =
(type == NL80211_IFTYPE_STATION) ?
WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
} else if (type == NL80211_IFTYPE_ADHOC) {
adapter->device_mode = WLAN_HDD_IBSS;
} else {
pAdapter->device_mode =
adapter->device_mode =
(type == NL80211_IFTYPE_STATION) ?
WLAN_HDD_INFRA_STATION : WLAN_HDD_P2P_CLIENT;
}
memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
hdd_set_station_ops(pAdapter->dev);
status = hdd_init_station_mode(pAdapter);
wext = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
wext->roamProfile.pAddIEScan = pAdapter->scan_info.scanAddIE.addIEdata;
memset(&adapter->sessionCtx, 0, sizeof(adapter->sessionCtx));
hdd_set_station_ops(adapter->dev);
status = hdd_init_station_mode(adapter);
wext = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
wext->roamProfile.pAddIEScan = adapter->scan_info.scanAddIE.addIEdata;
wext->roamProfile.nAddIEScanLength =
pAdapter->scan_info.scanAddIE.length;
adapter->scan_info.scanAddIE.length;
if (type == NL80211_IFTYPE_ADHOC) {
wext->roamProfile.BSSType = eCSR_BSS_TYPE_START_IBSS;
wext->roamProfile.phyMode =
hdd_cfg_xlate_to_csr_phy_mode(config->dot11Mode);
}
EXIT();
return status;
}
@ -6009,8 +6007,6 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
tCsrRoamProfile *pRoamProfile = NULL;
eCsrRoamBssType LastBSSType;
struct hdd_config *pConfig = NULL;
eMib_dot11DesiredBssType connectedBssType;
unsigned long rc;
QDF_STATUS vstatus;
int status;
@ -6062,24 +6058,28 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
switch (type) {
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
vstatus = wlan_hdd_change_iface_to_sta_mode(ndev, type);
case NL80211_IFTYPE_ADHOC:
if (type == NL80211_IFTYPE_ADHOC) {
wlan_hdd_tdls_exit(pAdapter);
hdd_deregister_tx_flow_control(pAdapter);
hddLog(LOG1,
FL("Setting interface Type to ADHOC"));
}
vstatus = wlan_hdd_change_client_iface_to_new_mode(ndev,
type);
if (vstatus != QDF_STATUS_SUCCESS)
return -EINVAL;
hdd_register_tx_flow_control(pAdapter,
/*
* for ibss interface type flow control is not required
* so don't register tx flow control
*/
if (type != NL80211_IFTYPE_ADHOC)
hdd_register_tx_flow_control(pAdapter,
hdd_tx_resume_timer_expired_handler,
hdd_tx_resume_cb);
goto done;
case NL80211_IFTYPE_ADHOC:
wlan_hdd_tdls_exit(pAdapter);
hdd_deregister_tx_flow_control(pAdapter);
hddLog(LOG1, FL("Setting interface Type to ADHOC"));
wlan_hdd_change_iface_to_adhoc(ndev, pRoamProfile,
type);
break;
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_P2P_GO:
{
@ -6162,7 +6162,8 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
case NL80211_IFTYPE_STATION:
case NL80211_IFTYPE_P2P_CLIENT:
case NL80211_IFTYPE_ADHOC:
status = wlan_hdd_change_iface_to_sta_mode(ndev, type);
status = wlan_hdd_change_client_iface_to_new_mode(ndev,
type);
if (status != QDF_STATUS_SUCCESS)
return status;
@ -6196,35 +6197,6 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
pAdapter->device_mode);
return -EOPNOTSUPP;
}
if (LastBSSType != pRoamProfile->BSSType) {
/* Interface type changed update in wiphy structure */
wdev->iftype = type;
/* The BSS mode changed, We need to issue disconnect
if connected or in IBSS disconnect state */
if (hdd_conn_get_connected_bss_type
(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType)
|| (eCSR_BSS_TYPE_START_IBSS == LastBSSType)) {
/* Need to issue a disconnect to CSR. */
INIT_COMPLETION(pAdapter->disconnect_comp_var);
if (QDF_STATUS_SUCCESS ==
sme_roam_disconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId,
eCSR_DISCONNECT_REASON_UNSPECIFIED)) {
rc = wait_for_completion_timeout(&pAdapter->
disconnect_comp_var,
msecs_to_jiffies
(WLAN_WAIT_TIME_DISCONNECT));
if (!rc) {
hddLog(LOGE,
FL
("Wait on disconnect_comp_var failed"));
}
}
}
}
done:
/* Set bitmask based on updated value */
cds_set_concurrency_mode(pAdapter->device_mode);

View file

@ -2012,6 +2012,35 @@ static QDF_STATUS hdd_sme_close_session_callback(void *pContext)
return QDF_STATUS_SUCCESS;
}
/**
* hdd_check_and_init_tdls() - check and init TDLS operation for desired mode
* @adapter: pointer to device adapter
* @type: type of interface
*
* This routine will check the mode of adapter and if it is required then it
* will initialize the TDLS operations
*
* Return: QDF_STATUS
*/
#ifdef FEATURE_WLAN_TDLS
static QDF_STATUS hdd_check_and_init_tdls(hdd_adapter_t *adapter, uint32_t type)
{
if (QDF_IBSS_MODE != type) {
if (0 != wlan_hdd_tdls_init(adapter)) {
hddLog(LOGE, FL("wlan_hdd_tdls_init failed"));
return QDF_STATUS_E_FAILURE;
}
set_bit(TDLS_INIT_DONE, &adapter->event_flags);
}
return QDF_STATUS_SUCCESS;
}
#else
static QDF_STATUS hdd_check_and_init_tdls(hdd_adapter_t *adapter, uint32_t type)
{
return QDF_STATUS_SUCCESS;
}
#endif
QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter)
{
struct net_device *pWlanDev = adapter->dev;
@ -2105,14 +2134,9 @@ QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter)
FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"),
ret_val);
}
#ifdef FEATURE_WLAN_TDLS
if (0 != wlan_hdd_tdls_init(adapter)) {
status = QDF_STATUS_E_FAILURE;
hddLog(LOGE, FL("wlan_hdd_tdls_init failed"));
status = hdd_check_and_init_tdls(adapter, type);
if (status != QDF_STATUS_SUCCESS)
goto error_tdls_init;
}
set_bit(TDLS_INIT_DONE, &adapter->event_flags);
#endif
return QDF_STATUS_SUCCESS;

View file

@ -1557,7 +1557,7 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
if (((self_sta_req->type == WMI_VDEV_TYPE_AP) &&
(self_sta_req->sub_type == WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE)) ||
(self_sta_req->type == WMI_VDEV_TYPE_OCB)) {
WMA_LOGA("P2P Device: creating self peer %pM, vdev_id %hu",
WMA_LOGA("Creating self peer %pM, vdev_id %hu",
self_sta_req->self_mac_addr, self_sta_req->session_id);
status = wma_create_peer(wma_handle, txrx_pdev,
txrx_vdev_handle,
@ -2776,11 +2776,8 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
struct wma_target_req *msg;
uint8_t vdev_id, peer_id;
QDF_STATUS status;
struct add_sta_self_params add_sta_self_param;
struct del_sta_self_params del_sta_param;
tSetBssKeyParams key_info;
struct sir_hw_mode_params hw_mode = {0};
struct qdf_mac_addr *mac_addr;
vdev = wma_find_vdev_by_addr(wma, add_bss->selfMacAddr, &vdev_id);
if (!vdev) {
@ -2797,63 +2794,16 @@ static void wma_add_bss_ibss_mode(tp_wma_handle wma, tpAddBssParams add_bss)
}
wma_set_bss_rate_flags(&wma->interfaces[vdev_id], add_bss);
/* only change vdev type to ibss during 1st time join_ibss handling */
if (false == wma_is_vdev_in_ibss_mode(wma, vdev_id)) {
WMA_LOGD("%s: vdev found for vdev id %d. deleting the vdev",
__func__, vdev_id);
/* remove peers on the existing non-ibss vdev */
ol_txrx_remove_peers_for_vdev_no_lock(vdev,
(ol_txrx_vdev_peer_remove_cb)wma_remove_peer, wma);
mac_addr = ol_txrx_get_vdev_struct_mac_addr(vdev);
if (mac_addr == NULL) {
WMA_LOGE("%s: mac_addr is NULL for vdev with id %d",
__func__, vdev_id);
goto send_fail_resp;
}
/* remove the non-ibss vdev */
qdf_copy_macaddr(
(struct qdf_mac_addr *) &(del_sta_param.self_mac_addr),
mac_addr);
del_sta_param.session_id = vdev_id;
del_sta_param.status = 0;
wma_vdev_detach(wma, &del_sta_param, 0);
/* create new vdev for ibss */
qdf_copy_macaddr((struct qdf_mac_addr *) &
(add_sta_self_param.self_mac_addr),
(struct qdf_mac_addr *) &(add_bss->selfMacAddr));
add_sta_self_param.session_id = vdev_id;
add_sta_self_param.type = WMI_VDEV_TYPE_IBSS;
add_sta_self_param.sub_type = 0;
add_sta_self_param.status = 0;
vdev = wma_vdev_attach(wma, &add_sta_self_param, 0);
if (!vdev) {
WMA_LOGE("%s: Failed to create vdev", __func__);
goto send_fail_resp;
}
/* Register with TxRx Module for Data Ack Complete Cb */
ol_txrx_data_tx_cb_set(vdev, wma_data_tx_ack_comp_hdlr, wma);
WMA_LOGA("new IBSS vdev created with mac %pM",
add_bss->selfMacAddr);
/* create ibss bss peer */
status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr,
WMI_PEER_TYPE_DEFAULT, vdev_id,
false);
if (status != QDF_STATUS_SUCCESS) {
WMA_LOGE("%s: Failed to create peer", __func__);
goto send_fail_resp;
}
WMA_LOGA("IBSS BSS peer created with mac %pM",
add_bss->selfMacAddr);
/* create ibss bss peer */
status = wma_create_peer(wma, pdev, vdev, add_bss->selfMacAddr,
WMI_PEER_TYPE_DEFAULT, vdev_id,
false);
if (status != QDF_STATUS_SUCCESS) {
WMA_LOGE("%s: Failed to create peer", __func__);
goto send_fail_resp;
}
WMA_LOGA("IBSS BSS peer created with mac %pM",
add_bss->selfMacAddr);
peer = ol_txrx_find_peer_by_addr(pdev, add_bss->selfMacAddr, &peer_id);
if (!peer) {