From 736e13d6ba310621f0605c1cdf576c76e5bc90b0 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Mon, 20 Mar 2017 14:34:11 +0800 Subject: [PATCH 01/19] qcacmn: TDLS component: os_if layer Implement TDLS related cfg80211 interface functions Change-Id: I3ef38f670902ff486cad7c55473ce5805473aa17 CRs-Fixed: 2011330 --- inc/wlan_cfg80211_tdls.h | 126 ++++++++++ src/wlan_cfg80211_tdls.c | 526 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 652 insertions(+) create mode 100644 inc/wlan_cfg80211_tdls.h create mode 100644 src/wlan_cfg80211_tdls.c diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h new file mode 100644 index 000000000000..42eab3865b16 --- /dev/null +++ b/inc/wlan_cfg80211_tdls.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: declares driver functions interfacing with linux kernel + */ + +#ifndef _WLAN_CFG80211_TDLS_H_ +#define _WLAN_CFG80211_TDLS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct osif_tdls_vdev - OS tdls vdev private structure + * @tdls_add_peer_comp: Completion to add tdls peer + * @tdls_del_peer_comp: Completion to delete tdls peer + * @tdls_mgmt_comp: Completion to send tdls mgmt packets + * @tdls_link_establish_req_comp: Completion to establish link, sync to + * send establish params to firmware, not used today. + * @tdls_add_peer_status: Peer status after add peer + * @mgmt_tx_completion_status: Tdls mgmt frames TX completion status code + */ +struct osif_tdls_vdev { + struct completion tdls_add_peer_comp; + struct completion tdls_del_peer_comp; + struct completion tdls_mgmt_comp; + struct completion tdls_link_establish_req_comp; + QDF_STATUS tdls_add_peer_status; + uint32_t mgmt_tx_completion_status; +}; + +/** + * wlan_cfg80211_tdls_priv_init() - API to initialize tdls os private + * @osif_priv: vdev os private + * + * API to initialize tdls os private + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv); + +/** + * wlan_cfg80211_tdls_priv_deinit() - API to deinitialize tdls os private + * @osif_priv: vdev os private + * + * API to deinitialize tdls os private + * + * Return: None + */ +void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv); + +/** + * wlan_cfg80211_tdls_add_peer() - process cfg80211 add TDLS peer request + * @pdev: pdev object + * @dev: Pointer to net device + * @mac: MAC address for TDLS peer + * + * Return: 0 for success; negative errno otherwise + */ +int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, + struct net_device *dev, const uint8_t *mac); + +/** + * wlan_cfg80211_tdls_update_peer() - process cfg80211 update TDLS peer request + * @pdev: pdev object + * @dev: Pointer to net device + * @mac: MAC address for TDLS peer + * @params: Pointer to station parameters + * + * Return: 0 for success; negative errno otherwise + */ +int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, + struct net_device *dev, + const uint8_t *mac, + struct station_parameters *params); +/** + * wlan_cfg80211_tdls_oper() - process cfg80211 operation on an TDLS peer + * @pdev: pdev object + * @dev: net device + * @peer: MAC address of the TDLS peer + * @oper: cfg80211 TDLS operation + * + * Return: 0 on success; negative errno otherwise + */ +int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, + struct net_device *dev, + const uint8_t *peer, + enum nl80211_tdls_operation oper); + +/** + * wlan_cfg80211_tdls_event_callback() - callback for tdls module + * @userdata: user data + * @type: request callback type + * @param: passed parameter + * + * This is used by TDLS to sync with os interface + * + * Return: None + */ +void wlan_cfg80211_tdls_event_callback(void *userdata, + enum tdls_event_type type, + struct tdls_osif_indication *param); +#endif diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c new file mode 100644 index 000000000000..cee276852202 --- /dev/null +++ b/src/wlan_cfg80211_tdls.c @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: defines driver functions interfacing with linux kernel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_CHANNEL (NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS) + +QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv) +{ + struct osif_tdls_vdev *tdls_priv; + + cfg80211_debug("initialize tdls os if layer private structure"); + tdls_priv = qdf_mem_malloc(sizeof(*tdls_priv)); + if (!tdls_priv) { + cfg80211_err("failed to allocate memory for tdls_priv"); + return QDF_STATUS_E_NOMEM; + } + init_completion(&tdls_priv->tdls_add_peer_comp); + init_completion(&tdls_priv->tdls_del_peer_comp); + init_completion(&tdls_priv->tdls_mgmt_comp); + init_completion(&tdls_priv->tdls_link_establish_req_comp); + + osif_priv->osif_tdls = tdls_priv; + + return QDF_STATUS_SUCCESS; +} + +void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv) +{ + cfg80211_debug("deinitialize tdls os if layer private structure"); + if (osif_priv->osif_tdls) + qdf_mem_free(osif_priv->osif_tdls); + osif_priv->osif_tdls = NULL; +} + +int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, + struct net_device *dev, const uint8_t *mac) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_add_peer_params *add_peer_req; + int status; + struct vdev_osif_priv *osif_priv; + struct osif_tdls_vdev *tdls_priv; + unsigned long rc; + + cfg80211_debug("Add TDLS peer " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(mac)); + vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, + WLAN_OSIF_ID); + if (vdev == NULL) { + cfg80211_err("vdev object is NULL"); + return -EIO; + } + + add_peer_req = qdf_mem_malloc(sizeof(*add_peer_req)); + if (!add_peer_req) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + cfg80211_err("Failed to allocate tdls add peer request mem"); + return -EINVAL; + } + + wlan_vdev_obj_lock(vdev); + osif_priv = wlan_vdev_get_ospriv(vdev); + tdls_priv = osif_priv->osif_tdls; + + add_peer_req->vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + + qdf_mem_copy(add_peer_req->peer_addr, mac, QDF_MAC_ADDR_SIZE); + + reinit_completion(&tdls_priv->tdls_add_peer_comp); + status = ucfg_tdls_add_peer(vdev, add_peer_req); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("ucfg_tdls_add_peer returned err %d", status); + status = -EIO; + goto error; + } + + rc = wait_for_completion_timeout( + &tdls_priv->tdls_add_peer_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA)); + if (!rc) { + cfg80211_err("timeout for tdls add peer indication %ld", rc); + status = -EPERM; + goto error; + } + + if (QDF_IS_STATUS_ERROR(tdls_priv->tdls_add_peer_status)) { + cfg80211_err("tdls add peer failed, status:%d", + tdls_priv->tdls_add_peer_status); + status = -EPERM; + } +error: + qdf_mem_free(add_peer_req); + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + return status; +} + +static bool +is_duplicate_channel(uint8_t *arr, int index, uint8_t match) +{ + int i; + + for (i = 0; i < index; i++) { + if (arr[i] == match) + return true; + } + return false; +} + +static void +tdls_calc_channels_from_staparams(struct tdls_update_peer_params *req_info, + struct station_parameters *params) +{ + int i = 0, j = 0, k = 0, no_of_channels = 0; + int num_unique_channels; + int next; + uint8_t *dest_chans; + const uint8_t *src_chans; + + dest_chans = req_info->supported_channels; + src_chans = params->supported_channels; + + /* Convert (first channel , number of channels) tuple to + * the total list of channels. This goes with the assumption + * that if the first channel is < 14, then the next channels + * are an incremental of 1 else an incremental of 4 till the number + * of channels. + */ + for (i = 0; i < params->supported_channels_len && + j < WLAN_MAC_MAX_SUPP_CHANNELS; i += 2) { + int wifi_chan_index; + + if (!is_duplicate_channel(dest_chans, j, src_chans[i])) + dest_chans[j] = src_chans[i]; + else + continue; + + wifi_chan_index = ((dest_chans[j] <= WLAN_CHANNEL_14) ? 1 : 4); + no_of_channels = src_chans[i + 1]; + + cfg80211_debug("i:%d,j:%d,k:%d,[%d]:%d,index:%d,chans_num: %d", + i, j, k, j, + dest_chans[j], + wifi_chan_index, + no_of_channels); + + for (k = 1; k <= no_of_channels && + j < WLAN_MAC_MAX_SUPP_CHANNELS - 1; k++) { + next = dest_chans[j] + wifi_chan_index; + + if (!is_duplicate_channel(dest_chans, j + 1, next)) + dest_chans[j + 1] = next; + else + continue; + + cfg80211_debug("i: %d, j: %d, k: %d, [%d]: %d", + i, j, k, j + 1, dest_chans[j + 1]); + j += 1; + } + } + num_unique_channels = j + 1; + cfg80211_debug("Unique Channel List: supported_channels "); + for (i = 0; i < num_unique_channels; i++) + cfg80211_debug("[%d]: %d,", i, dest_chans[i]); + + if (MAX_CHANNEL < num_unique_channels) + num_unique_channels = MAX_CHANNEL; + req_info->supported_channels_len = num_unique_channels; + cfg80211_debug("After removing duplcates supported_channels_len: %d", + req_info->supported_channels_len); +} + +static void +wlan_cfg80211_tdls_extract_params(struct tdls_update_peer_params *req_info, + struct station_parameters *params) +{ + int i; + + cfg80211_debug("sta cap %d, uapsd_queue %d, max_sp %d", + params->capability, + params->uapsd_queues, params->max_sp); + + if (!req_info) { + cfg80211_err("reg_info is NULL"); + return; + } + req_info->capability = params->capability; + req_info->uapsd_queues = params->uapsd_queues; + req_info->max_sp = params->max_sp; + + if (params->supported_channels_len) + tdls_calc_channels_from_staparams(req_info, params); + + qdf_mem_copy(req_info->supported_oper_classes, + params->supported_oper_classes, + params->supported_oper_classes_len); + req_info->supported_oper_classes_len = + params->supported_oper_classes_len; + + if (params->ext_capab_len) + qdf_mem_copy(req_info->extn_capability, params->ext_capab, + sizeof(req_info->extn_capability)); + + if (params->ht_capa) { + req_info->htcap_present = 1; + qdf_mem_copy(&req_info->ht_cap, params->ht_capa, + sizeof(struct htcap_cmn_ie)); + } + + req_info->supported_rates_len = params->supported_rates_len; + + /* Note : The Maximum sizeof supported_rates sent by the Supplicant is + * 32. The supported_rates array , for all the structures propogating + * till Add Sta to the firmware has to be modified , if the supplicant + * (ieee80211) is modified to send more rates. + */ + + /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES + */ + if (req_info->supported_rates_len > WLAN_MAC_MAX_SUPP_RATES) + req_info->supported_rates_len = WLAN_MAC_MAX_SUPP_RATES; + + if (req_info->supported_rates_len) { + qdf_mem_copy(req_info->supported_rates, + params->supported_rates, + req_info->supported_rates_len); + cfg80211_debug("Supported Rates with Length %d", + req_info->supported_rates_len); + + for (i = 0; i < req_info->supported_rates_len; i++) + cfg80211_debug("[%d]: %0x", i, + req_info->supported_rates[i]); + } + + if (params->vht_capa) { + req_info->vhtcap_present = 1; + qdf_mem_copy(&req_info->vht_cap, params->vht_capa, + sizeof(struct vhtcap)); + } + + if (params->ht_capa || params->vht_capa || + (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))) + req_info->is_qos_wmm_sta = true; +} + +int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, + struct net_device *dev, + const uint8_t *mac, + struct station_parameters *params) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_update_peer_params *req_info; + int status; + struct vdev_osif_priv *osif_priv; + struct osif_tdls_vdev *tdls_priv; + unsigned long rc; + + cfg80211_debug("Update TDLS peer " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(mac)); + vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, + WLAN_OSIF_ID); + if (vdev == NULL) { + cfg80211_err("vdev object is NULL"); + return -EIO; + } + + req_info = qdf_mem_malloc(sizeof(*req_info)); + if (!req_info) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + cfg80211_err("Failed to allocate tdls add peer request mem"); + return -EINVAL; + } + wlan_cfg80211_tdls_extract_params(req_info, params); + + wlan_vdev_obj_lock(vdev); + osif_priv = wlan_vdev_get_ospriv(vdev); + tdls_priv = osif_priv->osif_tdls; + + req_info->vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + qdf_mem_copy(req_info->peer_addr, mac, QDF_MAC_ADDR_SIZE); + + reinit_completion(&tdls_priv->tdls_add_peer_comp); + status = ucfg_tdls_update_peer(vdev, req_info); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("ucfg_tdls_update_peer returned err %d", status); + status = -EIO; + goto error; + } + + rc = wait_for_completion_timeout( + &tdls_priv->tdls_add_peer_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA)); + if (!rc) { + cfg80211_err("timeout for tdls update peer indication %ld", rc); + status = -EPERM; + goto error; + } + + if (QDF_IS_STATUS_ERROR(tdls_priv->tdls_add_peer_status)) { + cfg80211_err("tdls update peer failed, status:%d", + tdls_priv->tdls_add_peer_status); + status = -EPERM; + } +error: + qdf_mem_free(req_info); + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + return status; +} + +static char *tdls_oper_to_str(enum nl80211_tdls_operation oper) +{ + switch (oper) { + case NL80211_TDLS_ENABLE_LINK: + return "TDLS_ENABLE_LINK"; + case NL80211_TDLS_DISABLE_LINK: + return "TDLS_DISABLE_LINK"; + case NL80211_TDLS_TEARDOWN: + return "TDLS_TEARDOWN"; + case NL80211_TDLS_SETUP: + return "TDLS_SETUP"; + default: + return "UNKNOWN:ERR"; + } +} + +static enum tdls_command_type tdls_oper_to_cmd(enum nl80211_tdls_operation oper) +{ + if (oper == NL80211_TDLS_ENABLE_LINK) + return TDLS_CMD_ENABLE_LINK; + else if (oper == NL80211_TDLS_DISABLE_LINK) + return TDLS_CMD_DISABLE_LINK; + else if (oper == NL80211_TDLS_TEARDOWN) + return TDLS_CMD_REMOVE_FORCE_PEER; + else if (oper == NL80211_TDLS_SETUP) + return TDLS_CMD_CONFIG_FORCE_PEER; + else + return 0; +} + +int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, + struct net_device *dev, + const uint8_t *peer, + enum nl80211_tdls_operation oper) +{ + struct wlan_objmgr_vdev *vdev; + struct vdev_osif_priv *osif_priv; + struct osif_tdls_vdev *tdls_priv; + int status; + unsigned long rc; + enum tdls_command_type cmd; + + if (NL80211_TDLS_DISCOVERY_REQ == oper) { + cfg80211_warn( + "We don't support in-driver setup/teardown/discovery"); + return -ENOTSUPP; + } + + vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, + dev->dev_addr, + WLAN_OSIF_ID); + if (vdev == NULL) { + cfg80211_err("vdev object is NULL"); + return -EIO; + } + + cfg80211_debug("%s start", tdls_oper_to_str(oper)); + cmd = tdls_oper_to_cmd(oper); + switch (oper) { + case NL80211_TDLS_ENABLE_LINK: + case NL80211_TDLS_TEARDOWN: + case NL80211_TDLS_SETUP: + status = ucfg_tdls_oper(vdev, peer, cmd); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("%s fail %d", + tdls_oper_to_str(oper), status); + status = -EIO; + goto error; + } + break; + case NL80211_TDLS_DISABLE_LINK: + wlan_vdev_obj_lock(vdev); + osif_priv = wlan_vdev_get_ospriv(vdev); + tdls_priv = osif_priv->osif_tdls; + wlan_vdev_obj_unlock(vdev); + reinit_completion(&tdls_priv->tdls_del_peer_comp); + status = ucfg_tdls_oper(vdev, peer, cmd); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("ucfg_tdls_disable_link fail %d", status); + status = -EIO; + goto error; + } + + rc = wait_for_completion_timeout( + &tdls_priv->tdls_del_peer_comp, + msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA)); + if (!rc) { + cfg80211_err("timeout for tdls disable link %ld", rc); + status = -EPERM; + } + break; + default: + cfg80211_err("unsupported event %d", oper); + status = -ENOTSUPP; + } + +error: + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + + return status; +} + +static void +wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication *ind) +{ + struct vdev_osif_priv *osif_vdev; + + wlan_vdev_obj_lock(ind->vdev); + osif_vdev = wlan_vdev_get_ospriv(ind->vdev); + wlan_vdev_obj_unlock(ind->vdev); + + cfg80211_info("Implicit TDLS, request Send Discovery request"); + cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, + ind->peer_mac, NL80211_TDLS_DISCOVERY_REQ, + false, GFP_KERNEL); +} + +static void +wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication *ind) +{ + struct vdev_osif_priv *osif_vdev; + + wlan_vdev_obj_lock(ind->vdev); + osif_vdev = wlan_vdev_get_ospriv(ind->vdev); + wlan_vdev_obj_unlock(ind->vdev); + + cfg80211_info("Indication to request TDLS setup"); + cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, + ind->peer_mac, NL80211_TDLS_SETUP, false, + GFP_KERNEL); +} + +static void +wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication *ind) +{ + struct vdev_osif_priv *osif_vdev; + + wlan_vdev_obj_lock(ind->vdev); + osif_vdev = wlan_vdev_get_ospriv(ind->vdev); + wlan_vdev_obj_unlock(ind->vdev); + + cfg80211_info("Teardown reason %d", ind->reason); + cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, + ind->peer_mac, NL80211_TDLS_TEARDOWN, + ind->reason, GFP_KERNEL); +} + +void wlan_cfg80211_tdls_event_callback(void *user_data, + enum tdls_event_type type, + struct tdls_osif_indication *ind) +{ + struct vdev_osif_priv *osif_vdev; + struct osif_tdls_vdev *tdls_priv; + + if (!ind || !ind->vdev) { + cfg80211_err("ind: %p", ind); + return; + } + wlan_vdev_obj_lock(ind->vdev); + osif_vdev = wlan_vdev_get_ospriv(ind->vdev); + tdls_priv = osif_vdev->osif_tdls; + wlan_vdev_obj_unlock(ind->vdev); + + switch (type) { + case TDLS_EVENT_ADD_PEER: + tdls_priv->tdls_add_peer_status = ind->status; + complete(&tdls_priv->tdls_add_peer_comp); + break; + case TDLS_EVENT_DEL_PEER: + complete(&tdls_priv->tdls_del_peer_comp); + break; + case TDLS_EVENT_DISCOVERY_REQ: + wlan_cfg80211_tdls_indicate_discovery(ind); + break; + case TDLS_EVENT_TEARDOWN_REQ: + wlan_cfg80211_tdls_indicate_teardown(ind); + break; + case TDLS_EVENT_SETUP_REQ: + wlan_cfg80211_tdls_indicate_setup(ind); + break; + default: + break; + } +} From 84ddd1f69917f81394757ea69cc7cbef918e7dc6 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Sun, 26 Mar 2017 18:52:47 -0700 Subject: [PATCH 02/19] qcacmn: Add os_if changes for tdls management Add os interface changes to send tdls management frames to tdls component Change-Id: Ib675e4b089a88ad618f918d9992a777c7221b34c CRs-Fixed: 2034220 --- inc/wlan_cfg80211_tdls.h | 68 ++++++++++++ src/wlan_cfg80211_tdls.c | 232 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 300 insertions(+) diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h index 42eab3865b16..c4efaadb3ec2 100644 --- a/inc/wlan_cfg80211_tdls.h +++ b/inc/wlan_cfg80211_tdls.h @@ -33,6 +33,9 @@ #include #include + +#define TDLS_VDEV_MAGIC 0x54444c53 /* "TDLS" */ + /** * struct osif_tdls_vdev - OS tdls vdev private structure * @tdls_add_peer_comp: Completion to add tdls peer @@ -52,6 +55,26 @@ struct osif_tdls_vdev { uint32_t mgmt_tx_completion_status; }; +/** + * enum qca_wlan_vendor_tdls_trigger_mode_vdev_map: Maps the user space TDLS + * trigger mode in the host driver. + * @WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT: TDLS Connection and + * disconnection handled by user space. + * @WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT: TDLS connection and + * disconnection controlled by host driver based on data traffic. + * @WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL: TDLS connection and + * disconnection jointly controlled by user space and host driver. + */ +enum qca_wlan_vendor_tdls_trigger_mode_vdev_map { + WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT = + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT, + WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT = + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT, + WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL = + ((QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT | + QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT) << 1), +}; + /** * wlan_cfg80211_tdls_priv_init() - API to initialize tdls os private * @osif_priv: vdev os private @@ -96,6 +119,17 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, struct net_device *dev, const uint8_t *mac, struct station_parameters *params); + +/** + * wlan_cfg80211_tdls_configure_mode() - configure tdls mode + * @vdev: vdev obj manager + * @trigger_mode: tdls trgger mode + * + * Return: 0 for success; negative errno otherwise + */ +int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev, + uint32_t trigger_mode); + /** * wlan_cfg80211_tdls_oper() - process cfg80211 operation on an TDLS peer * @pdev: pdev object @@ -110,6 +144,27 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, const uint8_t *peer, enum nl80211_tdls_operation oper); +/** + * wlan_cfg80211_tdls_mgmt() - process tdls management frames from the supplicant + * @pdev: pdev object + * @dev: net device + * @peer: MAC address of the TDLS peer + * @action_code: type of TDLS mgmt frame to be sent + * @dialog_token: dialog token used in the frame + * @status_code: status to be incuded in the frame + * @peer_capability: peer capability information + * @buf: additional IEs to be included + * @len: lenght of additional Ies + * @oper: cfg80211 TDLS operation + * + * Return: 0 on success; negative errno otherwise + */ +int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, + struct net_device *dev, const uint8_t *peer, + uint8_t action_code, uint8_t dialog_token, + uint16_t status_code, uint32_t peer_capability, + const uint8_t *buf, size_t len); + /** * wlan_cfg80211_tdls_event_callback() - callback for tdls module * @userdata: user data @@ -123,4 +178,17 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, void wlan_cfg80211_tdls_event_callback(void *userdata, enum tdls_event_type type, struct tdls_osif_indication *param); + +/** + * wlan_cfg80211_tdls_rx_callback() - Callback for rx mgmt frame + * @user_data: pointer to soc object + * @rx_frame: RX mgmt frame information + * + * This callback will be used to rx frames in os interface. + * + * Return: None + */ +void wlan_cfg80211_tdls_rx_callback(void *user_data, + struct tdls_rx_mgmt_frame *rx_frame); + #endif diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index cee276852202..714b5f594b02 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -36,6 +36,9 @@ #define MAX_CHANNEL (NUM_24GHZ_CHANNELS + NUM_5GHZ_CHANNELS) + +#define TDLS_MAX_NO_OF_2_4_CHANNELS 14 + QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv) { struct osif_tdls_vdev *tdls_priv; @@ -370,6 +373,41 @@ static enum tdls_command_type tdls_oper_to_cmd(enum nl80211_tdls_operation oper) return 0; } +int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev, + uint32_t trigger_mode) +{ + enum tdls_feature_mode tdls_mode; + struct tdls_set_mode_params set_mode_params; + int status; + + if (!vdev) + return -EINVAL; + + switch (trigger_mode) { + case WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT: + tdls_mode = TDLS_SUPPORT_IMP_MODE; + break; + case WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL: + tdls_mode = TDLS_SUPPORT_EXT_CONTROL; + break; + case WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT: + tdls_mode = TDLS_SUPPORT_IMP_MODE; + break; + default: + cfg80211_err("Invalid TDLS trigger mode"); + return -EINVAL; + } + + cfg80211_notice("cfg80211 tdls trigger mode %d", trigger_mode); + set_mode_params.source = TDLS_SET_MODE_SOURCE_USER; + set_mode_params.tdls_mode = tdls_mode; + set_mode_params.update_last = false; + set_mode_params.vdev = vdev; + + status = ucfg_tdls_set_operating_mode(&set_mode_params); + return status; +} + int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, struct net_device *dev, const uint8_t *peer, @@ -442,6 +480,196 @@ error: return status; } +void wlan_cfg80211_tdls_rx_callback(void *user_data, + struct tdls_rx_mgmt_frame *rx_frame) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev; + struct vdev_osif_priv *osif_priv; + struct wireless_dev *wdev; + uint16_t freq; + + cfg80211_debug("user data:%p, vdev id:%d, rssi:%d, buf:%p, len:%d", + user_data, rx_frame->vdev_id, rx_frame->rx_rssi, + rx_frame->buf, rx_frame->frame_len); + + psoc = user_data; + if (!psoc) { + cfg80211_err("psoc is null"); + return; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + rx_frame->vdev_id, WLAN_TDLS_NB_ID); + if (!vdev) { + cfg80211_err("vdev is null"); + return; + } + + wlan_vdev_obj_lock(vdev); + osif_priv = wlan_vdev_get_ospriv(vdev); + wlan_vdev_obj_unlock(vdev); + if (!osif_priv) { + cfg80211_err("osif_priv is null"); + goto fail; + } + + wdev = osif_priv->wdev; + if (!wdev) { + cfg80211_err("wdev is null"); + goto fail; + } + + if (rx_frame->rx_chan <= TDLS_MAX_NO_OF_2_4_CHANNELS) + freq = ieee80211_channel_to_frequency( + rx_frame->rx_chan, NL80211_BAND_2GHZ); + else + freq = ieee80211_channel_to_frequency( + rx_frame->rx_chan, NL80211_BAND_5GHZ); + + cfg80211_notice("Indicate frame over nl80211, vdev id:%d, idx:%d", + rx_frame->vdev_id, wdev->netdev->ifindex); + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, + NL80211_RXMGMT_FLAG_ANSWERED); +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0)) + cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, + NL80211_RXMGMT_FLAG_ANSWERED, GFP_ATOMIC); +#else + cfg80211_rx_mgmt(wdev, freq, rx_frame->rx_rssi * 100, + rx_frame->buf, rx_frame->frame_len, GFP_ATOMIC); +#endif /* LINUX_VERSION_CODE */ +fail: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + +int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, + struct net_device *dev, const uint8_t *peer_mac, + uint8_t action_code, uint8_t dialog_token, + uint16_t status_code, uint32_t peer_capability, + const uint8_t *buf, size_t len) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_action_frame_request mgmt_req; + struct vdev_osif_priv *osif_priv; + struct osif_tdls_vdev *tdls_priv; + int status; + unsigned long rc; + int max_sta_failed = 0; + struct tdls_validate_action_req chk_frame; + struct tdls_set_responder_req set_responder; + + vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, + dev->dev_addr, + WLAN_OSIF_ID); + if (vdev == NULL) { + cfg80211_err("vdev object is NULL"); + return -EIO; + } + + wlan_vdev_obj_lock(vdev); + osif_priv = wlan_vdev_get_ospriv(vdev); + wlan_vdev_obj_unlock(vdev); + + tdls_priv = osif_priv->osif_tdls; + + /* make sure doesn't call send_mgmt() while it is pending */ + if (TDLS_VDEV_MAGIC == tdls_priv->mgmt_tx_completion_status) { + cfg80211_err(QDF_MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY", + QDF_MAC_ADDR_ARRAY(peer_mac), action_code); + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + return -EBUSY; + } + + /* Reset TDLS VDEV magic */ + tdls_priv->mgmt_tx_completion_status = TDLS_VDEV_MAGIC; + + + /*prepare the request */ + + /* Validate the management Request */ + chk_frame.vdev = vdev; + chk_frame.action_code = action_code; + qdf_mem_copy(chk_frame.peer_mac, peer_mac, QDF_MAC_ADDR_SIZE); + chk_frame.dialog_token = dialog_token; + chk_frame.action_code = action_code; + chk_frame.status_code = status_code; + chk_frame.len = len; + chk_frame.max_sta_failed = max_sta_failed; + + mgmt_req.chk_frame = &chk_frame; + + mgmt_req.vdev = vdev; + mgmt_req.vdev_id = wlan_vdev_get_id(vdev); + mgmt_req.session_id = mgmt_req.vdev_id; + /* populate management req params */ + qdf_mem_copy(mgmt_req.tdls_mgmt.peer_mac.bytes, + peer_mac, QDF_MAC_ADDR_SIZE); + mgmt_req.tdls_mgmt.dialog = dialog_token; + mgmt_req.tdls_mgmt.frame_type = action_code; + mgmt_req.tdls_mgmt.len = len; + mgmt_req.tdls_mgmt.peer_capability = peer_capability; + mgmt_req.tdls_mgmt.status_code = chk_frame.status_code; + + /*populate the additional IE's */ + mgmt_req.cmd_buf = buf; + mgmt_req.len = len; + + reinit_completion(&tdls_priv->tdls_mgmt_comp); + status = ucfg_tdls_send_mgmt_frame(&mgmt_req); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("ucfg_tdls_send_mgmt failed err %d", status); + status = -EIO; + tdls_priv->mgmt_tx_completion_status = false; + goto error_mgmt_req; + } + + cfg80211_info("Wait for tdls_mgmt_comp. Timeout %u ms", + WAIT_TIME_FOR_TDLS_MGMT); + + rc = wait_for_completion_timeout( + &tdls_priv->tdls_mgmt_comp, + msecs_to_jiffies(WAIT_TIME_FOR_TDLS_MGMT)); + + if ((0 == rc) || (true != tdls_priv->mgmt_tx_completion_status)) { + cfg80211_err("%s rc %ld mgmtTxCompletionStatus %u", + !rc ? "Mgmt Tx Completion timed out" : + "Mgmt Tx Completion failed", + rc, tdls_priv->mgmt_tx_completion_status); + + tdls_priv->mgmt_tx_completion_status = false; + status = -EINVAL; + goto error_mgmt_req; + } + + cfg80211_info("Mgmt Tx Completion status %ld TxCompletion %u", + rc, tdls_priv->mgmt_tx_completion_status); + + if (chk_frame.max_sta_failed) { + status = max_sta_failed; + goto error_mgmt_req; + } + + if (TDLS_SETUP_RESPONSE == action_code || + TDLS_SETUP_CONFIRM == action_code) { + qdf_mem_copy(set_responder.peer_mac, peer_mac, + QDF_MAC_ADDR_SIZE); + set_responder.vdev = vdev; + if (TDLS_SETUP_RESPONSE == action_code) + set_responder.responder = false; + if (TDLS_SETUP_CONFIRM == action_code) + set_responder.responder = true; + ucfg_tdls_responder(&set_responder); + } + +error_mgmt_req: + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + return status; +} + static void wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication *ind) { @@ -504,6 +732,10 @@ void wlan_cfg80211_tdls_event_callback(void *user_data, wlan_vdev_obj_unlock(ind->vdev); switch (type) { + case TDLS_EVENT_MGMT_TX_ACK_CNF: + tdls_priv->mgmt_tx_completion_status = ind->status; + complete(&tdls_priv->tdls_mgmt_comp); + break; case TDLS_EVENT_ADD_PEER: tdls_priv->tdls_add_peer_status = ind->status; complete(&tdls_priv->tdls_add_peer_comp); From 0d7f2bb901fad3bdc6638c074b95ec226abdc463 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 17 Apr 2017 21:53:42 -0700 Subject: [PATCH 03/19] qcacmn: Add TDLS off channel changes for TDLS UMAC Add TDLS offchannel and related osif changes in TDLS UMAC component. Change-Id: Ic562709eb8a6361322860c4f7333633a7894af99 CRs-Fixed: 2034220 --- inc/wlan_cfg80211_tdls.h | 74 ++++++++++++++++++++++++++++++++++++++ src/wlan_cfg80211_tdls.c | 76 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 147 insertions(+), 3 deletions(-) diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h index c4efaadb3ec2..812c8bccfc9c 100644 --- a/inc/wlan_cfg80211_tdls.h +++ b/inc/wlan_cfg80211_tdls.h @@ -33,6 +33,7 @@ #include #include +#ifdef CONVERGED_TDLS_ENABLE #define TDLS_VDEV_MAGIC 0x54444c53 /* "TDLS" */ @@ -51,6 +52,7 @@ struct osif_tdls_vdev { struct completion tdls_del_peer_comp; struct completion tdls_mgmt_comp; struct completion tdls_link_establish_req_comp; + struct completion tdls_teardown_comp; QDF_STATUS tdls_add_peer_status; uint32_t mgmt_tx_completion_status; }; @@ -191,4 +193,76 @@ void wlan_cfg80211_tdls_event_callback(void *userdata, void wlan_cfg80211_tdls_rx_callback(void *user_data, struct tdls_rx_mgmt_frame *rx_frame); +/** + * hdd_notify_sta_connect() - notify sta connect to TDLS + * @session_id: pointer to soc object + * @tdls_chan_swit_prohibited: indicates channel switch capability + * @tdls_prohibited: indicates tdls allowed or not + * @vdev: vdev object manager + * + * Notify sta connect event to TDLS component + * + * Return: None + */ +void +hdd_notify_sta_connect(uint8_t session_id, + bool tdls_chan_swit_prohibited, + bool tdls_prohibited, + struct wlan_objmgr_vdev *vdev); + +/** + * hdd_notify_sta_disconnect() - notify sta disconnect to TDLS + * @session_id: pointer to soc object + * @lfr_roam: indicate, whether disconnect due to lfr roam + * @vdev: vdev object manager + * + * Notify sta disconnect event to TDLS component + * + * Return: None + */ +void hdd_notify_sta_disconnect(uint8_t session_id, + bool lfr_roam, + struct wlan_objmgr_vdev *vdev); + +/** + * hdd_notify_teardown_tdls_links() - notify TDLS to teardown links + * @vdev: vdev object manager + * + * Notify tdls to teardown all the links, due to certain events + * in the system + * + * Return: None + */ +void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev); + +#else +static inline void +hdd_notify_sta_connect(uint8_t session_id, + bool tdls_chan_swit_prohibited, + bool tdls_prohibited, + struct wlan_objmgr_vdev *vdev) +{ +} + +static inline +void hdd_notify_sta_disconnect(uint8_t session_id, + bool lfr_roam, + struct wlan_objmgr_vdev *vdev) +{ + +} + +static inline +int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev, + uint32_t trigger_mode) +{ + return 0; +} + +static inline +void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev) +{ + +} +#endif #endif diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 714b5f594b02..238d27ba0f75 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -53,6 +53,7 @@ QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv) init_completion(&tdls_priv->tdls_del_peer_comp); init_completion(&tdls_priv->tdls_mgmt_comp); init_completion(&tdls_priv->tdls_link_establish_req_comp); + init_completion(&tdls_priv->tdls_teardown_comp); osif_priv->osif_tdls = tdls_priv; @@ -67,6 +68,72 @@ void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv) osif_priv->osif_tdls = NULL; } +void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev) +{ + struct vdev_osif_priv *osif_priv; + struct osif_tdls_vdev *tdls_priv; + QDF_STATUS status; + unsigned long rc; + + if (!vdev) + return; + + wlan_vdev_obj_lock(vdev); + osif_priv = wlan_vdev_get_ospriv(vdev); + wlan_vdev_obj_unlock(vdev); + + tdls_priv = osif_priv->osif_tdls; + + reinit_completion(&tdls_priv->tdls_teardown_comp); + status = ucfg_tdls_teardown_links(vdev); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("ucfg_tdls_teardown_links failed err %d", status); + return; + } + + cfg80211_info("Wait for tdls teardown completion. Timeout %u ms", + WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS); + + rc = wait_for_completion_timeout( + &tdls_priv->tdls_teardown_comp, + msecs_to_jiffies(WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS)); + + if (0 == rc) { + cfg80211_err(" Teardown Completion timed out rc: %ld", rc); + return; + } + + cfg80211_info("TDLS teardown completion status %ld ", rc); +} + +void +hdd_notify_sta_connect(uint8_t session_id, + bool tdls_chan_swit_prohibited, + bool tdls_prohibited, + struct wlan_objmgr_vdev *vdev) +{ + struct tdls_sta_notify_params notify_info; + + notify_info.session_id = session_id; + notify_info.vdev = vdev; + notify_info.tdls_chan_swit_prohibited = tdls_chan_swit_prohibited; + notify_info.tdls_prohibited = tdls_prohibited; + ucfg_tdls_notify_sta_connect(¬ify_info); + +} + +void hdd_notify_sta_disconnect(uint8_t session_id, + bool lfr_roam, + struct wlan_objmgr_vdev *vdev) +{ + struct tdls_sta_notify_params notify_info; + + notify_info.session_id = session_id; + notify_info.lfr_roam = lfr_roam; + notify_info.vdev = vdev; + ucfg_tdls_notify_sta_disconnect(¬ify_info); + +} int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, struct net_device *dev, const uint8_t *mac) { @@ -385,14 +452,14 @@ int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev, switch (trigger_mode) { case WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT: - tdls_mode = TDLS_SUPPORT_IMP_MODE; - break; + tdls_mode = TDLS_SUPPORT_EXP_TRIG_ONLY; + return 0; case WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL: tdls_mode = TDLS_SUPPORT_EXT_CONTROL; break; case WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT: tdls_mode = TDLS_SUPPORT_IMP_MODE; - break; + return 0; default: cfg80211_err("Invalid TDLS trigger mode"); return -EINVAL; @@ -752,6 +819,9 @@ void wlan_cfg80211_tdls_event_callback(void *user_data, case TDLS_EVENT_SETUP_REQ: wlan_cfg80211_tdls_indicate_setup(ind); break; + case TDLS_EVENT_TEARDOWN_LINKS_DONE: + complete(&tdls_priv->tdls_teardown_comp); + break; default: break; } From 74ffd94a250f869818a1599a390145afe578afeb Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 21 Jun 2017 08:21:58 +0530 Subject: [PATCH 04/19] qcacmn: Remove vdev/peer locks for trivial APIs Remove vdev/peer locks from trivial API's. This follows the changes from which the lock requirement from few simple APIs are removed. Change-Id: I9972d51dfd1a42bdedbfd0fd4e67af03d030a1f5 CRs-Fixed: 2060880 --- src/wlan_cfg80211_tdls.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 238d27ba0f75..7aa155afcbc6 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -78,9 +78,7 @@ void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev) if (!vdev) return; - wlan_vdev_obj_lock(vdev); osif_priv = wlan_vdev_get_ospriv(vdev); - wlan_vdev_obj_unlock(vdev); tdls_priv = osif_priv->osif_tdls; @@ -160,12 +158,9 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, return -EINVAL; } - wlan_vdev_obj_lock(vdev); osif_priv = wlan_vdev_get_ospriv(vdev); tdls_priv = osif_priv->osif_tdls; - add_peer_req->vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); qdf_mem_copy(add_peer_req->peer_addr, mac, QDF_MAC_ADDR_SIZE); @@ -374,12 +369,9 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, } wlan_cfg80211_tdls_extract_params(req_info, params); - wlan_vdev_obj_lock(vdev); osif_priv = wlan_vdev_get_ospriv(vdev); tdls_priv = osif_priv->osif_tdls; - req_info->vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); qdf_mem_copy(req_info->peer_addr, mac, QDF_MAC_ADDR_SIZE); reinit_completion(&tdls_priv->tdls_add_peer_comp); @@ -516,10 +508,8 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, } break; case NL80211_TDLS_DISABLE_LINK: - wlan_vdev_obj_lock(vdev); osif_priv = wlan_vdev_get_ospriv(vdev); tdls_priv = osif_priv->osif_tdls; - wlan_vdev_obj_unlock(vdev); reinit_completion(&tdls_priv->tdls_del_peer_comp); status = ucfg_tdls_oper(vdev, peer, cmd); if (QDF_IS_STATUS_ERROR(status)) { @@ -573,9 +563,7 @@ void wlan_cfg80211_tdls_rx_callback(void *user_data, return; } - wlan_vdev_obj_lock(vdev); osif_priv = wlan_vdev_get_ospriv(vdev); - wlan_vdev_obj_unlock(vdev); if (!osif_priv) { cfg80211_err("osif_priv is null"); goto fail; @@ -637,9 +625,7 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, return -EIO; } - wlan_vdev_obj_lock(vdev); osif_priv = wlan_vdev_get_ospriv(vdev); - wlan_vdev_obj_unlock(vdev); tdls_priv = osif_priv->osif_tdls; @@ -742,9 +728,7 @@ wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication *ind) { struct vdev_osif_priv *osif_vdev; - wlan_vdev_obj_lock(ind->vdev); osif_vdev = wlan_vdev_get_ospriv(ind->vdev); - wlan_vdev_obj_unlock(ind->vdev); cfg80211_info("Implicit TDLS, request Send Discovery request"); cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, @@ -757,9 +741,7 @@ wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication *ind) { struct vdev_osif_priv *osif_vdev; - wlan_vdev_obj_lock(ind->vdev); osif_vdev = wlan_vdev_get_ospriv(ind->vdev); - wlan_vdev_obj_unlock(ind->vdev); cfg80211_info("Indication to request TDLS setup"); cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, @@ -772,9 +754,7 @@ wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication *ind) { struct vdev_osif_priv *osif_vdev; - wlan_vdev_obj_lock(ind->vdev); osif_vdev = wlan_vdev_get_ospriv(ind->vdev); - wlan_vdev_obj_unlock(ind->vdev); cfg80211_info("Teardown reason %d", ind->reason); cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, @@ -793,10 +773,8 @@ void wlan_cfg80211_tdls_event_callback(void *user_data, cfg80211_err("ind: %p", ind); return; } - wlan_vdev_obj_lock(ind->vdev); osif_vdev = wlan_vdev_get_ospriv(ind->vdev); tdls_priv = osif_vdev->osif_tdls; - wlan_vdev_obj_unlock(ind->vdev); switch (type) { case TDLS_EVENT_MGMT_TX_ACK_CNF: From ba8219da59f1a9e53ab57493fb12087f9a542508 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 6 Jun 2017 19:40:03 -0700 Subject: [PATCH 05/19] qcacmn: Restructure TDLS function to fix the compilation issue When TDLS disabled at the build level, it triggers build failures in some of the projects, which does not support TDLS feature. Restructure the TDLS function to avoid build failures, when TDLS is not enabled. Change-Id: I3b63546f22d0187fb42d400fd7e15ff7a3d64653 CRs-Fixed: 2056022 --- inc/wlan_cfg80211_tdls.h | 15 +++++++++++++++ src/wlan_cfg80211_tdls.c | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h index 812c8bccfc9c..9dc2da3bfc02 100644 --- a/inc/wlan_cfg80211_tdls.h +++ b/inc/wlan_cfg80211_tdls.h @@ -193,6 +193,16 @@ void wlan_cfg80211_tdls_event_callback(void *userdata, void wlan_cfg80211_tdls_rx_callback(void *user_data, struct tdls_rx_mgmt_frame *rx_frame); +/** + * hdd_notify_tdls_reset_adapter() - notify reset adapter to TDLS + * @vdev: vdev object manager + * + * Notify hdd reset adapter to TDLS component + * + * Return: None + */ +void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev); + /** * hdd_notify_sta_connect() - notify sta connect to TDLS * @session_id: pointer to soc object @@ -236,6 +246,11 @@ void hdd_notify_sta_disconnect(uint8_t session_id, void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev); #else +static inline void +hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev) +{ +} + static inline void hdd_notify_sta_connect(uint8_t session_id, bool tdls_chan_swit_prohibited, diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 7aa155afcbc6..27803c75ea6e 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -104,6 +104,11 @@ void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev) cfg80211_info("TDLS teardown completion status %ld ", rc); } +void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev) +{ + ucfg_tdls_notify_reset_adapter(vdev); +} + void hdd_notify_sta_connect(uint8_t session_id, bool tdls_chan_swit_prohibited, From 3583d566d26252a2415560de4e0123e3bd4a64aa Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 24 Jul 2017 18:20:11 -0700 Subject: [PATCH 06/19] qcacmn: Fix the invalid MAC address config issue in TDLS When an invalid mac address(all zeros 00:00:00:00:00:00) sent to the host via user configuration, it triggers the crash in the system. Add checks to reject the invalid mac address configuration in TDLS. Change-Id: I340f581e7011f78faf5f58c10f7b6eec15ea2940 CRs-Fixed: 2068026 --- src/wlan_cfg80211_tdls.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 27803c75ea6e..c4878226a5f2 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -39,6 +39,19 @@ #define TDLS_MAX_NO_OF_2_4_CHANNELS 14 +static int wlan_cfg80211_tdls_validate_mac_addr(const uint8_t *mac) +{ + static const uint8_t temp_mac[QDF_MAC_ADDR_SIZE] = {0}; + + if (!qdf_mem_cmp(mac, temp_mac, QDF_MAC_ADDR_SIZE)) { + cfg80211_debug("Invalid Mac address " QDF_MAC_ADDRESS_STR " cmd declined.", + QDF_MAC_ADDR_ARRAY(mac)); + return -EINVAL; + } + + return 0; +} + QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv) { struct osif_tdls_vdev *tdls_priv; @@ -147,6 +160,11 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, struct osif_tdls_vdev *tdls_priv; unsigned long rc; + status = wlan_cfg80211_tdls_validate_mac_addr(mac); + + if (status) + return status; + cfg80211_debug("Add TDLS peer " QDF_MAC_ADDRESS_STR, QDF_MAC_ADDR_ARRAY(mac)); vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, @@ -357,6 +375,11 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, struct osif_tdls_vdev *tdls_priv; unsigned long rc; + status = wlan_cfg80211_tdls_validate_mac_addr(mac); + + if (status) + return status; + cfg80211_debug("Update TDLS peer " QDF_MAC_ADDRESS_STR, QDF_MAC_ADDR_ARRAY(mac)); vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, @@ -484,6 +507,11 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, unsigned long rc; enum tdls_command_type cmd; + status = wlan_cfg80211_tdls_validate_mac_addr(peer); + + if (status) + return status; + if (NL80211_TDLS_DISCOVERY_REQ == oper) { cfg80211_warn( "We don't support in-driver setup/teardown/discovery"); @@ -622,6 +650,11 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, struct tdls_validate_action_req chk_frame; struct tdls_set_responder_req set_responder; + status = wlan_cfg80211_tdls_validate_mac_addr(peer_mac); + + if (status) + return status; + vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, WLAN_OSIF_ID); From b4b4eb8df3168e4719ae8579c3fa35782db923db Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 18 Sep 2017 10:11:16 -0700 Subject: [PATCH 07/19] qcacmn: os_if: Replace instances of unadorned %p Replace instances of unadorned %p in os_if. Change-Id: Iddbd3deb6562e462358ed7bd0f51b18a027eee5a CRs-Fixed: 2111274 --- src/wlan_cfg80211_tdls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index c4878226a5f2..08fc91b1bcdc 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -579,7 +579,7 @@ void wlan_cfg80211_tdls_rx_callback(void *user_data, struct wireless_dev *wdev; uint16_t freq; - cfg80211_debug("user data:%p, vdev id:%d, rssi:%d, buf:%p, len:%d", + cfg80211_debug("user data:%pK, vdev id:%d, rssi:%d, buf:%pK, len:%d", user_data, rx_frame->vdev_id, rx_frame->rx_rssi, rx_frame->buf, rx_frame->frame_len); @@ -808,7 +808,7 @@ void wlan_cfg80211_tdls_event_callback(void *user_data, struct osif_tdls_vdev *tdls_priv; if (!ind || !ind->vdev) { - cfg80211_err("ind: %p", ind); + cfg80211_err("ind: %pK", ind); return; } osif_vdev = wlan_vdev_get_ospriv(ind->vdev); From 58d8a1fa36e9478e90488b7cdbb5ee7bcbb51403 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 10 Oct 2017 01:36:39 -0700 Subject: [PATCH 08/19] qcacmn: Fix TDLS set state cmd sequence in concurrent TDLS connections TDLS set state cmd to firmware is going out of sequence, if STA is disconnected, when concurrent TDLS connections are active. This out of sequence causes crash in the firmware. Fix the out of sequence issue, by grouping all the TDLS delete peer commands into one single command. Change-Id: Idd315d544c46bcf063881bff5be70cb5d9ad0ea2 CRs-Fixed: 2123838 --- inc/wlan_cfg80211_tdls.h | 3 +++ src/wlan_cfg80211_tdls.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h index 9dc2da3bfc02..404495cc8141 100644 --- a/inc/wlan_cfg80211_tdls.h +++ b/inc/wlan_cfg80211_tdls.h @@ -224,6 +224,7 @@ hdd_notify_sta_connect(uint8_t session_id, * hdd_notify_sta_disconnect() - notify sta disconnect to TDLS * @session_id: pointer to soc object * @lfr_roam: indicate, whether disconnect due to lfr roam + * @bool user_disconnect: disconnect from user space * @vdev: vdev object manager * * Notify sta disconnect event to TDLS component @@ -232,6 +233,7 @@ hdd_notify_sta_connect(uint8_t session_id, */ void hdd_notify_sta_disconnect(uint8_t session_id, bool lfr_roam, + bool user_disconnect, struct wlan_objmgr_vdev *vdev); /** @@ -262,6 +264,7 @@ hdd_notify_sta_connect(uint8_t session_id, static inline void hdd_notify_sta_disconnect(uint8_t session_id, bool lfr_roam, + bool user_disconnect, struct wlan_objmgr_vdev *vdev) { diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 08fc91b1bcdc..837c062abfa2 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -140,6 +140,7 @@ hdd_notify_sta_connect(uint8_t session_id, void hdd_notify_sta_disconnect(uint8_t session_id, bool lfr_roam, + bool user_disconnect, struct wlan_objmgr_vdev *vdev) { struct tdls_sta_notify_params notify_info; @@ -147,6 +148,7 @@ void hdd_notify_sta_disconnect(uint8_t session_id, notify_info.session_id = session_id; notify_info.lfr_roam = lfr_roam; notify_info.vdev = vdev; + notify_info.user_disconnect = user_disconnect; ucfg_tdls_notify_sta_disconnect(¬ify_info); } From 28c82c3f428a1c653755faa35d904a89637d9532 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 14 Nov 2017 17:19:29 -0800 Subject: [PATCH 09/19] qcacmn: Add TDLS user command getTDLSPeers Add TDLS user command getTDLSPeers for TDLS functional verification Change-Id: Ia02461a364ca604672d728f7dad7c3537e78f067 CRs-Fixed: 2146626 --- inc/wlan_cfg80211_tdls.h | 16 ++++++++++++ src/wlan_cfg80211_tdls.c | 56 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h index 404495cc8141..7c313cf3d494 100644 --- a/inc/wlan_cfg80211_tdls.h +++ b/inc/wlan_cfg80211_tdls.h @@ -44,8 +44,11 @@ * @tdls_mgmt_comp: Completion to send tdls mgmt packets * @tdls_link_establish_req_comp: Completion to establish link, sync to * send establish params to firmware, not used today. + * @tdls_teardown_comp: tdls teardown completion event + * @tdls_user_cmd_comp: tdls user command completion event * @tdls_add_peer_status: Peer status after add peer * @mgmt_tx_completion_status: Tdls mgmt frames TX completion status code + * @tdls_user_cmd_len: tdls user command written buffer length */ struct osif_tdls_vdev { struct completion tdls_add_peer_comp; @@ -53,8 +56,10 @@ struct osif_tdls_vdev { struct completion tdls_mgmt_comp; struct completion tdls_link_establish_req_comp; struct completion tdls_teardown_comp; + struct completion tdls_user_cmd_comp; QDF_STATUS tdls_add_peer_status; uint32_t mgmt_tx_completion_status; + uint32_t tdls_user_cmd_len; }; /** @@ -146,6 +151,17 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, const uint8_t *peer, enum nl80211_tdls_operation oper); +/** + * wlan_cfg80211_tdls_get_all_peers() - get all the TDLS peers from the list + * @vdev: vdev object + * @buf: output buffer + * @buflen: valid length of the output error + * + * Return: length of the output buffer + */ +int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, + char *buf, int buflen); + /** * wlan_cfg80211_tdls_mgmt() - process tdls management frames from the supplicant * @pdev: pdev object diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 837c062abfa2..03614e6874d1 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -67,6 +67,7 @@ QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv) init_completion(&tdls_priv->tdls_mgmt_comp); init_completion(&tdls_priv->tdls_link_establish_req_comp); init_completion(&tdls_priv->tdls_teardown_comp); + init_completion(&tdls_priv->tdls_user_cmd_comp); osif_priv->osif_tdls = tdls_priv; @@ -636,6 +637,56 @@ fail: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); } +int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, + char *buf, int buflen) +{ + struct vdev_osif_priv *osif_priv; + struct osif_tdls_vdev *tdls_priv; + int32_t len; + QDF_STATUS status; + unsigned long rc; + + if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID) != + QDF_STATUS_SUCCESS) { + len = scnprintf(buf, buflen, + "\nNo TDLS VDEV is null\n"); + return len; + } + + osif_priv = wlan_vdev_get_ospriv(vdev); + tdls_priv = osif_priv->osif_tdls; + + reinit_completion(&tdls_priv->tdls_user_cmd_comp); + status = ucfg_tdls_get_all_peers(vdev, buf, buflen); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("ucfg_tdls_get_all_peers failed err %d", status); + len = scnprintf(buf, buflen, + "\nucfg_tdls_send_mgmt failed\n"); + goto error_get_tdls_peers; + } + + cfg80211_info("Wait for tdls_user_cmd_comp. Timeout %u ms", + WAIT_TIME_FOR_TDLS_USER_CMD); + + rc = wait_for_completion_timeout( + &tdls_priv->tdls_user_cmd_comp, + msecs_to_jiffies(WAIT_TIME_FOR_TDLS_USER_CMD)); + + if (0 == rc) { + cfg80211_err("TDLS user cmd get all peers timed out rc %ld", + rc); + len = scnprintf(buf, buflen, + "\nTDLS user cmd get all peers timed out\n"); + goto error_get_tdls_peers; + } + + len = tdls_priv->tdls_user_cmd_len; + +error_get_tdls_peers: + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + return len; +} + int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, struct net_device *dev, const uint8_t *peer_mac, uint8_t action_code, uint8_t dialog_token, @@ -840,6 +891,11 @@ void wlan_cfg80211_tdls_event_callback(void *user_data, case TDLS_EVENT_TEARDOWN_LINKS_DONE: complete(&tdls_priv->tdls_teardown_comp); break; + case TDLS_EVENT_USER_CMD: + tdls_priv->tdls_user_cmd_len = ind->status; + complete(&tdls_priv->tdls_user_cmd_comp); + break; + default: break; } From 5ef3b6fc5f0130519e3f41a630ed2c1d5d120fb1 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Fri, 21 Jul 2017 18:02:02 +0800 Subject: [PATCH 10/19] qcacmn: Dynamic antenna switch in TDLS operation Support dynamic antenna switch in TDLS: 1. If TDLS NSS is configured to be 1x1, TDLS connections not teardown; 2. When antenna mode switched from 2x2 to 1x1, TDLS connections teared down and EAGAIN returned; When antenna mode switched from 1x1 to 2x2, TDLS connections is still teardown, but success in one trial. Change-Id: I1877002122a96dc8f40c796f8a1b938199d3b67a CRs-Fixed: 2080461 --- inc/wlan_cfg80211_tdls.h | 15 +++++++++++++- src/wlan_cfg80211_tdls.c | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h index 7c313cf3d494..42adf4fec767 100644 --- a/inc/wlan_cfg80211_tdls.h +++ b/inc/wlan_cfg80211_tdls.h @@ -44,11 +44,13 @@ * @tdls_mgmt_comp: Completion to send tdls mgmt packets * @tdls_link_establish_req_comp: Completion to establish link, sync to * send establish params to firmware, not used today. - * @tdls_teardown_comp: tdls teardown completion event + * @tdls_teardown_comp: Completion to teardown tdls peer * @tdls_user_cmd_comp: tdls user command completion event + * @tdls_antenna_switch_comp: Completion to switch antenna * @tdls_add_peer_status: Peer status after add peer * @mgmt_tx_completion_status: Tdls mgmt frames TX completion status code * @tdls_user_cmd_len: tdls user command written buffer length + * @tdls_antenna_switch_status: return status after antenna switch */ struct osif_tdls_vdev { struct completion tdls_add_peer_comp; @@ -57,9 +59,11 @@ struct osif_tdls_vdev { struct completion tdls_link_establish_req_comp; struct completion tdls_teardown_comp; struct completion tdls_user_cmd_comp; + struct completion tdls_antenna_switch_comp; QDF_STATUS tdls_add_peer_status; uint32_t mgmt_tx_completion_status; uint32_t tdls_user_cmd_len; + int tdls_antenna_switch_status; }; /** @@ -183,6 +187,15 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, uint16_t status_code, uint32_t peer_capability, const uint8_t *buf, size_t len); +/** + * wlan_tdls_antenna_switch() - process tdls antenna switch + * @vdev: vdev object + * @mode: antenna mode + * + * Return: 0 on success; -EAGAIN to retry + */ +int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode); + /** * wlan_cfg80211_tdls_event_callback() - callback for tdls module * @userdata: user data diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 03614e6874d1..7ff9690610fa 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -68,6 +68,7 @@ QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv) init_completion(&tdls_priv->tdls_link_establish_req_comp); init_completion(&tdls_priv->tdls_teardown_comp); init_completion(&tdls_priv->tdls_user_cmd_comp); + init_completion(&tdls_priv->tdls_antenna_switch_comp); osif_priv->osif_tdls = tdls_priv; @@ -814,6 +815,47 @@ error_mgmt_req: return status; } +int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode) +{ + struct vdev_osif_priv *osif_priv; + struct osif_tdls_vdev *tdls_priv; + int ret; + unsigned long rc; + + if (!vdev) { + cfg80211_err("vdev is NULL"); + return -EAGAIN; + } + wlan_objmgr_vdev_get_ref(vdev, WLAN_OSIF_ID); + + osif_priv = wlan_vdev_get_ospriv(vdev); + tdls_priv = osif_priv->osif_tdls; + + reinit_completion(&tdls_priv->tdls_antenna_switch_comp); + ret = ucfg_tdls_antenna_switch(vdev, mode); + if (QDF_IS_STATUS_ERROR(ret)) { + cfg80211_err("ucfg_tdls_antenna_switch failed err %d", ret); + ret = -EAGAIN; + goto error; + } + + rc = wait_for_completion_timeout( + &tdls_priv->tdls_antenna_switch_comp, + msecs_to_jiffies(WAIT_TIME_FOR_TDLS_ANTENNA_SWITCH)); + if (!rc) { + cfg80211_err("timeout for tdls antenna switch %ld", rc); + ret = -EAGAIN; + goto error; + } + + ret = tdls_priv->tdls_antenna_switch_status; + cfg80211_debug("tdls antenna switch status:%d", ret); +error: + wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); + + return ret; +} + static void wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication *ind) { @@ -896,6 +938,9 @@ void wlan_cfg80211_tdls_event_callback(void *user_data, complete(&tdls_priv->tdls_user_cmd_comp); break; + case TDLS_EVENT_ANTENNA_SWITCH: + tdls_priv->tdls_antenna_switch_status = ind->status; + complete(&tdls_priv->tdls_antenna_switch_comp); default: break; } From 77f47d78efcdd7d9190dc355c64c5908b01f8317 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Fri, 1 Dec 2017 10:32:28 -0800 Subject: [PATCH 11/19] qcacmn: Add validity check in tdls deinit path Add validity check in TDLS deinit path to avoid the crash. Change-Id: Id1b782c22346182e182e55557aa41dda99aa4c43 CRs-Fixed: 2151078 --- src/wlan_cfg80211_tdls.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 7ff9690610fa..2e2a3bb90f9d 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -78,6 +78,10 @@ QDF_STATUS wlan_cfg80211_tdls_priv_init(struct vdev_osif_priv *osif_priv) void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv) { cfg80211_debug("deinitialize tdls os if layer private structure"); + if (!osif_priv) { + cfg80211_err("OS private structure of vdev is null "); + return; + } if (osif_priv->osif_tdls) qdf_mem_free(osif_priv->osif_tdls); osif_priv->osif_tdls = NULL; From a6540eed2c1a6f7bfe625e26d01a55084c58c46e Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 25 Jan 2018 11:46:31 -0800 Subject: [PATCH 12/19] qcacmn: Replace QDF_MAC_ADDRESS_STR QDF_MAC_ADDRESS_STR has been depreciated in favor of QDF_MAC_ADDR_STR. Replace all usages with the new macro. Change-Id: I534923783a32288f7861caf9ae52ca3aac965809 CRs-Fixed: 2179126 --- src/wlan_cfg80211_tdls.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 2e2a3bb90f9d..03a8a55c9be9 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -44,7 +44,7 @@ static int wlan_cfg80211_tdls_validate_mac_addr(const uint8_t *mac) static const uint8_t temp_mac[QDF_MAC_ADDR_SIZE] = {0}; if (!qdf_mem_cmp(mac, temp_mac, QDF_MAC_ADDR_SIZE)) { - cfg80211_debug("Invalid Mac address " QDF_MAC_ADDRESS_STR " cmd declined.", + cfg80211_debug("Invalid Mac address " QDF_MAC_ADDR_STR " cmd declined.", QDF_MAC_ADDR_ARRAY(mac)); return -EINVAL; } @@ -173,7 +173,7 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, if (status) return status; - cfg80211_debug("Add TDLS peer " QDF_MAC_ADDRESS_STR, + cfg80211_debug("Add TDLS peer " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac)); vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, WLAN_OSIF_ID); @@ -388,7 +388,7 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, if (status) return status; - cfg80211_debug("Update TDLS peer " QDF_MAC_ADDRESS_STR, + cfg80211_debug("Update TDLS peer " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac)); vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, WLAN_OSIF_ID); @@ -727,7 +727,7 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, /* make sure doesn't call send_mgmt() while it is pending */ if (TDLS_VDEV_MAGIC == tdls_priv->mgmt_tx_completion_status) { - cfg80211_err(QDF_MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY", + cfg80211_err(QDF_MAC_ADDR_STR " action %d couldn't sent, as one is pending. return EBUSY", QDF_MAC_ADDR_ARRAY(peer_mac), action_code); wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); return -EBUSY; From 98db4cb1fd56f9eb5e7b508d27425560c99c9e7b Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 6 May 2018 15:40:42 -0700 Subject: [PATCH 13/19] qcacmn: Fix typo "lenght" Replace typo "lenght" with correct spelling "length". Change-Id: Ieea0c547c61248e510835d16a9fa55ace486df23 CRs-Fixed: 2238309 --- inc/wlan_cfg80211_tdls.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h index 42adf4fec767..92ba83d78150 100644 --- a/inc/wlan_cfg80211_tdls.h +++ b/inc/wlan_cfg80211_tdls.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -176,7 +176,7 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, * @status_code: status to be incuded in the frame * @peer_capability: peer capability information * @buf: additional IEs to be included - * @len: lenght of additional Ies + * @len: length of additional Ies * @oper: cfg80211 TDLS operation * * Return: 0 on success; negative errno otherwise From db91f687713bd73c5a3a60bb298555b46e9b3dce Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Tue, 17 Jul 2018 13:23:46 +0530 Subject: [PATCH 14/19] qcacmn: Change log levels in scan component Change log level for few scm and cfg80211 logs from info to debug. Change-Id: I595ddd54c51a601fa2e985c8a221c5dea2e698d8 CRs-Fixed: 2279511 --- src/wlan_cfg80211_tdls.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 03a8a55c9be9..59fd0ef3db3d 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -108,8 +108,8 @@ void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev) return; } - cfg80211_info("Wait for tdls teardown completion. Timeout %u ms", - WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS); + cfg80211_debug("Wait for tdls teardown completion. Timeout %u ms", + WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS); rc = wait_for_completion_timeout( &tdls_priv->tdls_teardown_comp, @@ -120,7 +120,7 @@ void hdd_notify_teardown_tdls_links(struct wlan_objmgr_vdev *vdev) return; } - cfg80211_info("TDLS teardown completion status %ld ", rc); + cfg80211_debug("TDLS teardown completion status %ld ", rc); } void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev) @@ -670,8 +670,8 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, goto error_get_tdls_peers; } - cfg80211_info("Wait for tdls_user_cmd_comp. Timeout %u ms", - WAIT_TIME_FOR_TDLS_USER_CMD); + cfg80211_debug("Wait for tdls_user_cmd_comp. Timeout %u ms", + WAIT_TIME_FOR_TDLS_USER_CMD); rc = wait_for_completion_timeout( &tdls_priv->tdls_user_cmd_comp, @@ -776,8 +776,8 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, goto error_mgmt_req; } - cfg80211_info("Wait for tdls_mgmt_comp. Timeout %u ms", - WAIT_TIME_FOR_TDLS_MGMT); + cfg80211_debug("Wait for tdls_mgmt_comp. Timeout %u ms", + WAIT_TIME_FOR_TDLS_MGMT); rc = wait_for_completion_timeout( &tdls_priv->tdls_mgmt_comp, @@ -794,8 +794,8 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, goto error_mgmt_req; } - cfg80211_info("Mgmt Tx Completion status %ld TxCompletion %u", - rc, tdls_priv->mgmt_tx_completion_status); + cfg80211_debug("Mgmt Tx Completion status %ld TxCompletion %u", + rc, tdls_priv->mgmt_tx_completion_status); if (chk_frame.max_sta_failed) { status = max_sta_failed; @@ -867,7 +867,7 @@ wlan_cfg80211_tdls_indicate_discovery(struct tdls_osif_indication *ind) osif_vdev = wlan_vdev_get_ospriv(ind->vdev); - cfg80211_info("Implicit TDLS, request Send Discovery request"); + cfg80211_debug("Implicit TDLS, request Send Discovery request"); cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, ind->peer_mac, NL80211_TDLS_DISCOVERY_REQ, false, GFP_KERNEL); @@ -880,7 +880,7 @@ wlan_cfg80211_tdls_indicate_setup(struct tdls_osif_indication *ind) osif_vdev = wlan_vdev_get_ospriv(ind->vdev); - cfg80211_info("Indication to request TDLS setup"); + cfg80211_debug("Indication to request TDLS setup"); cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, ind->peer_mac, NL80211_TDLS_SETUP, false, GFP_KERNEL); @@ -893,7 +893,7 @@ wlan_cfg80211_tdls_indicate_teardown(struct tdls_osif_indication *ind) osif_vdev = wlan_vdev_get_ospriv(ind->vdev); - cfg80211_info("Teardown reason %d", ind->reason); + cfg80211_debug("Teardown reason %d", ind->reason); cfg80211_tdls_oper_request(osif_vdev->wdev->netdev, ind->peer_mac, NL80211_TDLS_TEARDOWN, ind->reason, GFP_KERNEL); From 30f5fabfd547df93a804f8fabe2a649e3ed1239f Mon Sep 17 00:00:00 2001 From: Jingxiang Ge Date: Fri, 13 Jul 2018 15:16:03 +0800 Subject: [PATCH 15/19] qcacmn: Fix use after free for vdev in tdls When disconnect happens, TDLS_NOTIFY_STA_DISCONNECTION will be send to scheduler_thread, in bad case, it is processed after 3s later, and the vdev passed in notify msg has been freed in the period, invalid vdev causes invalid memory access. change as below: 1.1 Get vdev ref before send msg 1.2 register callback for release ref 1.3 send msg to scheduler_thread 1.4 process tdls notify msg and call callback function. Change-Id: I2b03db8b30db623796f2e8299f14ee31e28efb91 CRs-Fixed: 2275019 --- src/wlan_cfg80211_tdls.c | 63 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index 59fd0ef3db3d..e3e532791263 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -128,20 +128,55 @@ void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev) ucfg_tdls_notify_reset_adapter(vdev); } +static void hdd_notify_sta_connect_callback(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + cfg80211_err("vdev is NULL"); + return; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + void hdd_notify_sta_connect(uint8_t session_id, bool tdls_chan_swit_prohibited, bool tdls_prohibited, struct wlan_objmgr_vdev *vdev) { - struct tdls_sta_notify_params notify_info; + struct tdls_sta_notify_params notify_info = {0}; + QDF_STATUS status; + + if (!vdev) { + cfg80211_err("vdev is NULL"); + return; + } + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("can't get vdev"); + return; + } notify_info.session_id = session_id; notify_info.vdev = vdev; notify_info.tdls_chan_swit_prohibited = tdls_chan_swit_prohibited; notify_info.tdls_prohibited = tdls_prohibited; - ucfg_tdls_notify_sta_connect(¬ify_info); + notify_info.callback = hdd_notify_sta_connect_callback; + status = ucfg_tdls_notify_sta_connect(¬ify_info); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("ucfg_tdls_notify_sta_connect failed"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } +} +static void hdd_notify_sta_disconnect_callback(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + cfg80211_err("vdev is NULL"); + return; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); } void hdd_notify_sta_disconnect(uint8_t session_id, @@ -149,14 +184,32 @@ void hdd_notify_sta_disconnect(uint8_t session_id, bool user_disconnect, struct wlan_objmgr_vdev *vdev) { - struct tdls_sta_notify_params notify_info; + struct tdls_sta_notify_params notify_info = {0}; + QDF_STATUS status; + + if (!vdev) { + cfg80211_err("vdev is NULL"); + return; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("can't get vdev"); + return; + } notify_info.session_id = session_id; notify_info.lfr_roam = lfr_roam; + notify_info.tdls_chan_swit_prohibited = false; + notify_info.tdls_prohibited = false; notify_info.vdev = vdev; notify_info.user_disconnect = user_disconnect; - ucfg_tdls_notify_sta_disconnect(¬ify_info); - + notify_info.callback = hdd_notify_sta_disconnect_callback; + status = ucfg_tdls_notify_sta_disconnect(¬ify_info); + if (QDF_IS_STATUS_ERROR(status)) { + cfg80211_err("ucfg_tdls_notify_sta_disconnect failed"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } } int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, struct net_device *dev, const uint8_t *mac) From de6fc0aa1125bc16ea6488616c4c65611d681fed Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 24 Oct 2018 15:08:00 +0800 Subject: [PATCH 16/19] qcacmn: Fix potential resource leak when post msg in TDLS Fix potentail memory leak when post message in TDLS module: 1. Add flush callback to hanlde memory free and release reference count; 2. Check the return status when post message and free the resource for failure case. Change-Id: I0a693ccb5704509a4220f26e024ce8c6c823890c CRs-Fixed: 2341652 --- src/wlan_cfg80211_tdls.c | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index e3e532791263..b1e376c4a0e9 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -128,16 +128,6 @@ void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev) ucfg_tdls_notify_reset_adapter(vdev); } -static void hdd_notify_sta_connect_callback(struct wlan_objmgr_vdev *vdev) -{ - if (!vdev) { - cfg80211_err("vdev is NULL"); - return; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); -} - void hdd_notify_sta_connect(uint8_t session_id, bool tdls_chan_swit_prohibited, @@ -161,22 +151,7 @@ hdd_notify_sta_connect(uint8_t session_id, notify_info.vdev = vdev; notify_info.tdls_chan_swit_prohibited = tdls_chan_swit_prohibited; notify_info.tdls_prohibited = tdls_prohibited; - notify_info.callback = hdd_notify_sta_connect_callback; - status = ucfg_tdls_notify_sta_connect(¬ify_info); - if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_notify_sta_connect failed"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); - } -} - -static void hdd_notify_sta_disconnect_callback(struct wlan_objmgr_vdev *vdev) -{ - if (!vdev) { - cfg80211_err("vdev is NULL"); - return; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + ucfg_tdls_notify_sta_connect(¬ify_info); } void hdd_notify_sta_disconnect(uint8_t session_id, @@ -204,12 +179,7 @@ void hdd_notify_sta_disconnect(uint8_t session_id, notify_info.tdls_prohibited = false; notify_info.vdev = vdev; notify_info.user_disconnect = user_disconnect; - notify_info.callback = hdd_notify_sta_disconnect_callback; - status = ucfg_tdls_notify_sta_disconnect(¬ify_info); - if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_notify_sta_disconnect failed"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); - } + ucfg_tdls_notify_sta_disconnect(¬ify_info); } int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, struct net_device *dev, const uint8_t *mac) From 6cca937c9c709a0e33cee529cedae8bdd81380c3 Mon Sep 17 00:00:00 2001 From: Min Liu Date: Mon, 10 Sep 2018 18:23:43 +0800 Subject: [PATCH 17/19] qcacmn: Use vdev instead of pdev as parameter For the case that there is leakage of vdev due to incorrect reference count usage, and another vdev for the adapter is created, get ref of vdev by mac address might get the incorrect vdev object since both vdevs will have the same mac address and the leak one will be first matched since it is created first. To address this issue, use vdev pointer in adapter instead of pdev as input parameter of related functions. Change-Id: I855497358b5dabf3fc5c0f71a859dd7cae1b450a CRs-Fixed: 2312155 --- inc/wlan_cfg80211_tdls.h | 32 ++++++++---------- src/wlan_cfg80211_tdls.c | 72 ++++++---------------------------------- 2 files changed, 23 insertions(+), 81 deletions(-) diff --git a/inc/wlan_cfg80211_tdls.h b/inc/wlan_cfg80211_tdls.h index 92ba83d78150..c4c6b1c6f8ba 100644 --- a/inc/wlan_cfg80211_tdls.h +++ b/inc/wlan_cfg80211_tdls.h @@ -108,26 +108,23 @@ void wlan_cfg80211_tdls_priv_deinit(struct vdev_osif_priv *osif_priv); /** * wlan_cfg80211_tdls_add_peer() - process cfg80211 add TDLS peer request - * @pdev: pdev object - * @dev: Pointer to net device + * @vdev: vdev object * @mac: MAC address for TDLS peer * * Return: 0 for success; negative errno otherwise */ -int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, - struct net_device *dev, const uint8_t *mac); +int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev, + const uint8_t *mac); /** * wlan_cfg80211_tdls_update_peer() - process cfg80211 update TDLS peer request - * @pdev: pdev object - * @dev: Pointer to net device + * @vdev: vdev object * @mac: MAC address for TDLS peer * @params: Pointer to station parameters * * Return: 0 for success; negative errno otherwise */ -int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, - struct net_device *dev, +int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev, const uint8_t *mac, struct station_parameters *params); @@ -143,15 +140,13 @@ int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev, /** * wlan_cfg80211_tdls_oper() - process cfg80211 operation on an TDLS peer - * @pdev: pdev object - * @dev: net device + * @vdev: vdev object * @peer: MAC address of the TDLS peer * @oper: cfg80211 TDLS operation * * Return: 0 on success; negative errno otherwise */ -int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, - struct net_device *dev, +int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev, const uint8_t *peer, enum nl80211_tdls_operation oper); @@ -168,8 +163,7 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, /** * wlan_cfg80211_tdls_mgmt() - process tdls management frames from the supplicant - * @pdev: pdev object - * @dev: net device + * @vdev: vdev object * @peer: MAC address of the TDLS peer * @action_code: type of TDLS mgmt frame to be sent * @dialog_token: dialog token used in the frame @@ -181,11 +175,11 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, * * Return: 0 on success; negative errno otherwise */ -int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, - struct net_device *dev, const uint8_t *peer, - uint8_t action_code, uint8_t dialog_token, - uint16_t status_code, uint32_t peer_capability, - const uint8_t *buf, size_t len); +int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev, + const uint8_t *peer, + uint8_t action_code, uint8_t dialog_token, + uint16_t status_code, uint32_t peer_capability, + const uint8_t *buf, size_t len); /** * wlan_tdls_antenna_switch() - process tdls antenna switch diff --git a/src/wlan_cfg80211_tdls.c b/src/wlan_cfg80211_tdls.c index b1e376c4a0e9..6a04713f4de5 100644 --- a/src/wlan_cfg80211_tdls.c +++ b/src/wlan_cfg80211_tdls.c @@ -181,10 +181,10 @@ void hdd_notify_sta_disconnect(uint8_t session_id, notify_info.user_disconnect = user_disconnect; ucfg_tdls_notify_sta_disconnect(¬ify_info); } -int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, - struct net_device *dev, const uint8_t *mac) + +int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_vdev *vdev, + const uint8_t *mac) { - struct wlan_objmgr_vdev *vdev; struct tdls_add_peer_params *add_peer_req; int status; struct vdev_osif_priv *osif_priv; @@ -198,16 +198,9 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, cfg80211_debug("Add TDLS peer " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac)); - vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, - WLAN_OSIF_ID); - if (vdev == NULL) { - cfg80211_err("vdev object is NULL"); - return -EIO; - } add_peer_req = qdf_mem_malloc(sizeof(*add_peer_req)); if (!add_peer_req) { - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); cfg80211_err("Failed to allocate tdls add peer request mem"); return -EINVAL; } @@ -242,7 +235,6 @@ int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, } error: qdf_mem_free(add_peer_req); - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); return status; } @@ -394,12 +386,10 @@ wlan_cfg80211_tdls_extract_params(struct tdls_update_peer_params *req_info, req_info->is_qos_wmm_sta = true; } -int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, - struct net_device *dev, +int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_vdev *vdev, const uint8_t *mac, struct station_parameters *params) { - struct wlan_objmgr_vdev *vdev; struct tdls_update_peer_params *req_info; int status; struct vdev_osif_priv *osif_priv; @@ -413,16 +403,9 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, cfg80211_debug("Update TDLS peer " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac)); - vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, dev->dev_addr, - WLAN_OSIF_ID); - if (vdev == NULL) { - cfg80211_err("vdev object is NULL"); - return -EIO; - } req_info = qdf_mem_malloc(sizeof(*req_info)); if (!req_info) { - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); cfg80211_err("Failed to allocate tdls add peer request mem"); return -EINVAL; } @@ -457,7 +440,6 @@ int wlan_cfg80211_tdls_update_peer(struct wlan_objmgr_pdev *pdev, } error: qdf_mem_free(req_info); - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); return status; } @@ -526,12 +508,10 @@ int wlan_cfg80211_tdls_configure_mode(struct wlan_objmgr_vdev *vdev, return status; } -int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, - struct net_device *dev, +int wlan_cfg80211_tdls_oper(struct wlan_objmgr_vdev *vdev, const uint8_t *peer, enum nl80211_tdls_operation oper) { - struct wlan_objmgr_vdev *vdev; struct vdev_osif_priv *osif_priv; struct osif_tdls_vdev *tdls_priv; int status; @@ -549,14 +529,6 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, return -ENOTSUPP; } - vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, - dev->dev_addr, - WLAN_OSIF_ID); - if (vdev == NULL) { - cfg80211_err("vdev object is NULL"); - return -EIO; - } - cfg80211_debug("%s start", tdls_oper_to_str(oper)); cmd = tdls_oper_to_cmd(oper); switch (oper) { @@ -596,8 +568,6 @@ int wlan_cfg80211_tdls_oper(struct wlan_objmgr_pdev *pdev, } error: - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); - return status; } @@ -674,13 +644,6 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; unsigned long rc; - if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_OSIF_ID) != - QDF_STATUS_SUCCESS) { - len = scnprintf(buf, buflen, - "\nNo TDLS VDEV is null\n"); - return len; - } - osif_priv = wlan_vdev_get_ospriv(vdev); tdls_priv = osif_priv->osif_tdls; @@ -711,17 +674,15 @@ int wlan_cfg80211_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, len = tdls_priv->tdls_user_cmd_len; error_get_tdls_peers: - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); return len; } -int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, - struct net_device *dev, const uint8_t *peer_mac, - uint8_t action_code, uint8_t dialog_token, - uint16_t status_code, uint32_t peer_capability, - const uint8_t *buf, size_t len) +int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_vdev *vdev, + const uint8_t *peer_mac, + uint8_t action_code, uint8_t dialog_token, + uint16_t status_code, uint32_t peer_capability, + const uint8_t *buf, size_t len) { - struct wlan_objmgr_vdev *vdev; struct tdls_action_frame_request mgmt_req; struct vdev_osif_priv *osif_priv; struct osif_tdls_vdev *tdls_priv; @@ -736,14 +697,6 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, if (status) return status; - vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(pdev, - dev->dev_addr, - WLAN_OSIF_ID); - if (vdev == NULL) { - cfg80211_err("vdev object is NULL"); - return -EIO; - } - osif_priv = wlan_vdev_get_ospriv(vdev); tdls_priv = osif_priv->osif_tdls; @@ -752,7 +705,6 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, if (TDLS_VDEV_MAGIC == tdls_priv->mgmt_tx_completion_status) { cfg80211_err(QDF_MAC_ADDR_STR " action %d couldn't sent, as one is pending. return EBUSY", QDF_MAC_ADDR_ARRAY(peer_mac), action_code); - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); return -EBUSY; } @@ -838,7 +790,6 @@ int wlan_cfg80211_tdls_mgmt(struct wlan_objmgr_pdev *pdev, } error_mgmt_req: - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); return status; } @@ -853,7 +804,6 @@ int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode) cfg80211_err("vdev is NULL"); return -EAGAIN; } - wlan_objmgr_vdev_get_ref(vdev, WLAN_OSIF_ID); osif_priv = wlan_vdev_get_ospriv(vdev); tdls_priv = osif_priv->osif_tdls; @@ -878,8 +828,6 @@ int wlan_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode) ret = tdls_priv->tdls_antenna_switch_status; cfg80211_debug("tdls antenna switch status:%d", ret); error: - wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID); - return ret; } From 83edbc80fe3ea1aceb3e363ee974b02eacddb21b Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 15:51:25 +0530 Subject: [PATCH 18/19] Move os_if/linxu/tdls to components/os_if/linux/tdls Change-Id: I89891b041b9ead12fec9c4fa86bad991326b5b28 --- {inc => components/os_if/linux/tdls/inc}/wlan_cfg80211_tdls.h | 0 {src => components/os_if/linux/tdls/src}/wlan_cfg80211_tdls.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {inc => components/os_if/linux/tdls/inc}/wlan_cfg80211_tdls.h (100%) rename {src => components/os_if/linux/tdls/src}/wlan_cfg80211_tdls.c (100%) diff --git a/inc/wlan_cfg80211_tdls.h b/components/os_if/linux/tdls/inc/wlan_cfg80211_tdls.h similarity index 100% rename from inc/wlan_cfg80211_tdls.h rename to components/os_if/linux/tdls/inc/wlan_cfg80211_tdls.h diff --git a/src/wlan_cfg80211_tdls.c b/components/os_if/linux/tdls/src/wlan_cfg80211_tdls.c similarity index 100% rename from src/wlan_cfg80211_tdls.c rename to components/os_if/linux/tdls/src/wlan_cfg80211_tdls.c From ec542fe9bd4a884f3a9c2ac8388a3e0a0de45656 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 16:14:01 +0530 Subject: [PATCH 19/19] Move to os_if/tdls Change-Id: I4f48da96ff9e3d726cffd4f1795657c9ada2429e --- {components/os_if/linux => os_if}/tdls/inc/wlan_cfg80211_tdls.h | 0 {components/os_if/linux => os_if}/tdls/src/wlan_cfg80211_tdls.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {components/os_if/linux => os_if}/tdls/inc/wlan_cfg80211_tdls.h (100%) rename {components/os_if/linux => os_if}/tdls/src/wlan_cfg80211_tdls.c (100%) diff --git a/components/os_if/linux/tdls/inc/wlan_cfg80211_tdls.h b/os_if/tdls/inc/wlan_cfg80211_tdls.h similarity index 100% rename from components/os_if/linux/tdls/inc/wlan_cfg80211_tdls.h rename to os_if/tdls/inc/wlan_cfg80211_tdls.h diff --git a/components/os_if/linux/tdls/src/wlan_cfg80211_tdls.c b/os_if/tdls/src/wlan_cfg80211_tdls.c similarity index 100% rename from components/os_if/linux/tdls/src/wlan_cfg80211_tdls.c rename to os_if/tdls/src/wlan_cfg80211_tdls.c