diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c index ad9ace313f70..6c0204407a52 100644 --- a/core/cds/src/cds_api.c +++ b/core/cds/src/cds_api.c @@ -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); diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 817887f1e9f6..4e513d6e569f 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -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); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index b6d9e5721d8a..af0d983eb9bf 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -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; diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 2049c828646c..ab2965b91f94 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -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) {