From 53531c5b9ba0df2930822bf06c254cc4690b0476 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 16 Feb 2017 11:39:12 +0800 Subject: [PATCH 001/404] qcacmn: Initialization of P2P component Defines main APIs and data structures. Initial basic frame work of P2P component. Change-Id: I08d2e2cec734ddc535d88996f7d5ece5ef3d270a CRs-Fixed: 1099441 --- core/inc/wlan_p2p_main.h | 293 +++++++++++++ core/inc/wlan_p2p_off_chan_tx.h | 112 +++++ core/inc/wlan_p2p_roc.h | 136 ++++++ core/src/wlan_p2p_main.c | 526 ++++++++++++++++++++++++ core/src/wlan_p2p_off_chan_tx.c | 47 +++ core/src/wlan_p2p_roc.c | 39 ++ dispatcher/inc/wlan_p2p_public_struct.h | 182 ++++++++ dispatcher/inc/wlan_p2p_tgt_api.h | 125 ++++++ dispatcher/inc/wlan_p2p_ucfg_api.h | 265 ++++++++++++ dispatcher/src/wlan_p2p_tgt_api.c | 66 +++ dispatcher/src/wlan_p2p_ucfg_api.c | 101 +++++ 11 files changed, 1892 insertions(+) create mode 100644 core/inc/wlan_p2p_main.h create mode 100644 core/inc/wlan_p2p_off_chan_tx.h create mode 100644 core/inc/wlan_p2p_roc.h create mode 100644 core/src/wlan_p2p_main.c create mode 100644 core/src/wlan_p2p_off_chan_tx.c create mode 100644 core/src/wlan_p2p_roc.c create mode 100644 dispatcher/inc/wlan_p2p_public_struct.h create mode 100644 dispatcher/inc/wlan_p2p_tgt_api.h create mode 100644 dispatcher/inc/wlan_p2p_ucfg_api.h create mode 100644 dispatcher/src/wlan_p2p_tgt_api.c create mode 100644 dispatcher/src/wlan_p2p_ucfg_api.c diff --git a/core/inc/wlan_p2p_main.h b/core/inc/wlan_p2p_main.h new file mode 100644 index 000000000000..23daf7f2f2f5 --- /dev/null +++ b/core/inc/wlan_p2p_main.h @@ -0,0 +1,293 @@ +/* + * 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 main P2P functions & structures + */ + +#ifndef _WLAN_P2P_MAIN_H_ +#define _WLAN_P2P_MAIN_H_ + +#include +#include +#include + +#define P2P_MAX_NOA_DESC 4 +#define MAX_QUEUE_LENGTH 20 + +#define p2p_log(level, args...) \ + QDF_TRACE(QDF_MODULE_ID_P2P, level, ## args) +#define p2p_logl(level, format, args...) \ + p2p_log(level, FL(format), ## args) + +#define p2p_debug(format, args ...) \ + p2p_logl(QDF_TRACE_LEVEL_DEBUG, format, ## args) +#define p2p_info(format, args ...) \ + p2p_logl(QDF_TRACE_LEVEL_INFO, format, ## args) +#define p2p_warn(format, args ...) \ + p2p_logl(QDF_TRACE_LEVEL_WARN, format, ## args) +#define p2p_err(format, args ...) \ + p2p_logl(QDF_TRACE_LEVEL_ERROR, format, ## args) +#define p2p_alert(format, args ...) \ + p2p_logl(QDF_TRACE_LEVEL_FATAL, format, ## args) + +struct scheduler_msg; +struct p2p_tx_cnf; +struct p2p_rx_mgmt_frame; +struct p2p_lo_event; +struct p2p_start_param; + +/** + * enum p2p_cmd_type - P2P request type + * @P2P_ROC_REQ: P2P roc request + * @P2P_CANCEL_ROC_REQ: Cancel P2P roc request + * @P2P_MGMT_TX: P2P tx action frame request + * @P2P_MGMT_TX_CANCEL: Cancel tx action frame request + */ +enum p2p_cmd_type { + P2P_ROC_REQ = 0, + P2P_CANCEL_ROC_REQ, + P2P_MGMT_TX, + P2P_MGMT_TX_CANCEL, +}; + +/** + * enum p2p_event_type - P2P event type + * @P2P_EVENT_SCAN_EVENT: P2P scan event + * @P2P_EVENT_MGMT_TX_ACK_CNF: P2P mgmt tx confirm frame + * @P2P_EVENT_RX_MGMT: P2P rx mgmt frame + * @P2P_EVENT_LO_STOPPED: P2P listen offload stopped event + * @P2P_EVENT_NOA: P2P noa event + */ +enum p2p_event_type { + P2P_EVENT_SCAN_EVENT = 0, + P2P_EVENT_MGMT_TX_ACK_CNF, + P2P_EVENT_RX_MGMT, + P2P_EVENT_LO_STOPPED, + P2P_EVENT_NOA, +}; + +/** + * struct noa_descriptor - noa descriptor + * @type_count: 255: continuous schedule, 0: reserved + * @duration: Absent period duration in micro seconds + * @interval: Absent period interval in micro seconds + * @start_time: 32 bit tsf time when in starts + */ +struct noa_descriptor { + uint8_t type_count; + uint32_t duration; + uint32_t interval; + uint32_t start_time; +}; + +/** + * struct p2p_noa_info - p2p noa information + * @index: Identifies instance of NOA su element + * @opps_ps: Opps ps state of the AP + * @ct_window: Ct window in TUs + * @num_descriptors: Number of NOA descriptors + * @noa_desc: Noa descriptors + * @vdev_id: Vdev id + */ +struct p2p_noa_info { + uint8_t index; + uint8_t opps_ps; + uint8_t ct_window; + uint8_t num_desc; + struct noa_descriptor noa_desc[P2P_MAX_NOA_DESC]; + uint32_t vdev_id; +}; + +/** + * struct p2p_tx_conf_event - p2p tx confirm event + * @p2p_soc_obj: p2p soc private object + * @tx_cnf: p2p tx confirm structure + */ +struct p2p_tx_conf_event { + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_tx_cnf *tx_cnf; +}; + +/** + * struct p2p_rx_mgmt_event - p2p rx mgmt frame event + * @p2p_soc_obj: p2p soc private object + * @rx_mgmt: p2p rx mgmt frame structure + */ +struct p2p_rx_mgmt_event { + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_rx_mgmt_frame *rx_mgmt; +}; + +/** + * struct p2p_lo_stop_event - p2p listen offload stop event + * @p2p_soc_obj: p2p soc private object + * @lo_event: p2p lo stop structure + */ +struct p2p_lo_stop_event { + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_lo_event *lo_event; +}; + +/** + * struct p2p_noa_event - p2p noa event + * @p2p_soc_obj: p2p soc private object + * @noa_info: p2p noa information structure + */ +struct p2p_noa_event { + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_noa_info *noa_info; +}; + +/** + * struct p2p_soc_priv_obj - Per SoC p2p private object + * @soc: Pointer to SoC context + * @roc_q: Queue for pending roc requests + * @tx_q_roc: Queue for tx frames waiting for RoC + * @tx_q_ack: Queue for tx frames waiting for ack + * @scan_req_id: Scan requestor id + * @start_param: Start parameters, include callbacks and user + * data to HDD + * @cancel_roc_done: Cancel roc done event + */ +struct p2p_soc_priv_obj { + struct wlan_objmgr_psoc *soc; + qdf_list_t roc_q; + qdf_list_t tx_q_roc; + qdf_list_t tx_q_ack; + uint16_t scan_req_id; + struct p2p_start_param *start_param; + qdf_event_t cancel_roc_done; +}; + +/** + * struct p2p_vdev_priv_obj - Per vdev p2p private object + * @vdev: Pointer to vdev context + * @noa_info: NoA information + */ +struct p2p_vdev_priv_obj { + struct wlan_objmgr_vdev *vdev; + struct p2p_noa_info *noa_info; +}; + +/** + * p2p_component_init() - P2P component initialization + * + * This function registers psoc/vdev create/delete handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_component_init(void); + +/** + * p2p_component_deinit() - P2P component de-init + * + * This function deregisters psoc/vdev create/delete handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_component_deinit(void); + +/** + * p2p_psoc_open() - Open P2P component + * @soc: soc context + * + * This function initialize p2p psoc object + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_psoc_open(struct wlan_objmgr_psoc *soc); + +/** + * p2p_psoc_close() - Close P2P component + * @soc: soc context + * + * This function de-init p2p psoc object. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_psoc_close(struct wlan_objmgr_psoc *soc); + +/** + * p2p_psoc_start() - Start P2P component + * @soc: soc context + * @req: P2P start parameters + * + * This function sets up layer call back in p2p psoc object + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, + struct p2p_start_param *req); + +/** + * p2p_psoc_stop() - Stop P2P component + * @soc: soc context + * + * This function clears up layer call back in p2p psoc object. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc); + +/** + * p2p_process_cmd() - Process P2P messages in OS interface queue + * @msg: message information + * + * This function is main handler for P2P messages in OS interface + * queue, it gets called by message scheduler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg); + +/** + * p2p_process_evt() - Process P2P messages in target interface queue + * @msg: message information + * + * This function is main handler for P2P messages in target interface + * queue, it gets called by message scheduler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_evt(struct scheduler_msg *msg); + +/** + * p2p_process_lo_stop() - Process lo stop event + * @lo_stop_event: listen offload stop event information + * + * This function handles listen offload stop event and deliver this + * event to HDD layer by registered callback. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_lo_stop( + struct p2p_lo_stop_event *lo_stop_event); + +/** + * p2p_process_noa() - Process noa event + * @noa_event: noa event information + * + * This function handles noa event and save noa information in p2p + * vdev object. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event); + +#endif /* _WLAN_P2P_MAIN_H_ */ diff --git a/core/inc/wlan_p2p_off_chan_tx.h b/core/inc/wlan_p2p_off_chan_tx.h new file mode 100644 index 000000000000..6b5af43007cd --- /dev/null +++ b/core/inc/wlan_p2p_off_chan_tx.h @@ -0,0 +1,112 @@ +/* + * 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 off channel tx API & structures + */ + +#ifndef _WLAN_P2P_OFF_CHAN_TX_H_ +#define _WLAN_P2P_OFF_CHAN_TX_H_ + +#include +#include + +struct p2p_soc_priv_obj; +struct cancel_roc_context; +struct p2p_tx_conf_event; +struct p2p_rx_mgmt_event; + +/** + * struct tx_action_context - tx action frame context + * @node: Node for next element in the list + * @p2p_soc_obj: Pointer to SoC global p2p private object + * @vdev_id: Vdev id on which this request has come + * @scan_id: Scan id given by scan component for this roc req + * @action_cookie: Action cookie + * @chan: Chan for which this tx has been requested + * @buf: tx buffer + * @buf_len: Length of tx buffer + * @off_chan: Is this off channel tx + * @no_cck: Required cck or not + * @no_ack: Required ack or not + * @duration: Duration for the RoC + * @tx_timer: RoC timer + */ +struct tx_action_context { + qdf_list_node_t node; + struct p2p_soc_priv_obj *p2p_soc_obj; + int vdev_id; + int scan_id; + uint64_t action_cookie; + uint8_t chan; + uint8_t *buf; + int buf_len; + bool off_chan; + bool no_cck; + bool no_ack; + uint32_t duration; + qdf_mc_timer_t tx_timer; +}; + +/** + * p2p_process_mgmt_tx() - Process mgmt frame tx request + * @tx_ctx: tx context + * + * This function handles mgmt frame tx request. It will call API from + * mgmt txrx component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx); + +/** + * p2p_process_mgmt_tx_cancel() - Process cancel mgmt frame tx request + * @cancel_tx: cancel tx context + * + * This function cancel mgmt frame tx request by cookie. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_mgmt_tx_cancel( + struct cancel_roc_context *cancel_tx); + +/** + * p2p_process_mgmt_tx_ack_cnf() - Process tx ack event + * @tx_cnf_event: tx confirmation event information + * + * This function mgmt frame tx confirmation. It will deliver this + * event to HDD + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_mgmt_tx_ack_cnf( + struct p2p_tx_conf_event *tx_cnf_event); + +/** + * p2p_process_rx_mgmt() - Process rx mgmt frame event + * @rx_mgmt_event: rx mgmt frame event information + * + * This function mgmt frame rx mgmt frame event. It will deliver this + * event to HDD + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_rx_mgmt( + struct p2p_rx_mgmt_event *rx_mgmt_event); + +#endif /* _WLAN_P2P_OFF_CHAN_TX_H_ */ diff --git a/core/inc/wlan_p2p_roc.h b/core/inc/wlan_p2p_roc.h new file mode 100644 index 000000000000..b166d7ae35bf --- /dev/null +++ b/core/inc/wlan_p2p_roc.h @@ -0,0 +1,136 @@ +/* + * 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 RoC API & structures + */ + +#ifndef _WLAN_P2P_ROC_H_ +#define _WLAN_P2P_ROC_H_ + +#include +#include + +#define P2P_EVENT_PROPOGATE_TIME 10 + +struct wlan_objmgr_vdev; +struct scan_event; + +/** + * enum roc_type - user requested or off channel tx + * @USER_REQUESTED: Requested by supplicant + * @OFF_CHANNEL_TX: Issued internally for off channel tx + */ +enum roc_type { + USER_REQUESTED, + OFF_CHANNEL_TX, +}; + +/** + * enum roc_state - P2P RoC state + * @ROC_STATE_IDLE: RoC not yet started or completed + * @ROC_STATE_REQUESTED: Sent scan command to scan manager + * @ROC_STATE_STARTED: Got started event from scan manager + * @ROC_STATE_ON_CHAN: Got foreign channel event from SCM + * @ROC_STATE_CANCEL_IN_PROG: Requested abort scan to SCM + * @ROC_STATE_INVALID: We should not come to this state + */ +enum roc_state { + ROC_STATE_IDLE = 0, + ROC_STATE_REQUESTED, + ROC_STATE_STARTED, + ROC_STATE_ON_CHAN, + ROC_STATE_CANCEL_IN_PROG, + ROC_STATE_INVALID, +}; + +/** + * struct p2p_roc_context - RoC request context + * @node: Node for next element in the list + * @p2p_soc_obj: Pointer to SoC global p2p private object + * @vdev_id: Vdev id on which this request has come + * @scan_id: Scan id given by scan component for this roc req + * @cookie: Cookie which is given to supplicant for this roc req + * @chan: Chan for which this RoC has been requested + * @phy_mode: PHY mode + * @duration: Duration for the RoC + * @roc_type: RoC type User requested or internal + * @roc_timer: RoC timer + * @roc_state: Roc state + */ +struct p2p_roc_context { + qdf_list_node_t node; + struct p2p_soc_priv_obj *p2p_soc_obj; + uint32_t vdev_id; + uint32_t scan_id; + uint64_t cookie; + uint8_t chan; + uint8_t phy_mode; + uint32_t duration; + enum roc_type roc_type; + qdf_mc_timer_t roc_timer; + enum roc_state roc_state; +}; + +/** + * struct cancel_roc_context - p2p cancel roc context + * @p2p_soc_obj: Pointer to SoC global p2p private object + * @cookie: Cookie which is given by supplicant + */ +struct cancel_roc_context { + struct p2p_soc_priv_obj *p2p_soc_obj; + uint64_t cookie; +}; + +/** + * p2p_process_roc_req() - Process roc request + * @roc_ctx: roc request context + * + * This function handles roc request. It will call API from scan/mgmt + * txrx component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx); + +/** + * p2p_process_cancel_roc_req() - Process cancel roc request + * @cancel_roc_ctx: cancel roc request context + * + * This function cancel roc request by cookie. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_process_cancel_roc_req( + struct cancel_roc_context *cancel_roc_ctx); + +/** + * p2p_scan_event_cb() - Process scan event + * @vdev: vdev associated to this scan event + * @event: event type + * @arg: registered arguments + * + * This function handles P2P scan event and deliver P2P event to HDD + * layer by registered callback. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +void p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, + struct scan_event *event, void *arg); + +#endif /* _WLAN_P2P_ROC_H_ */ diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c new file mode 100644 index 000000000000..fb8fac1b83e0 --- /dev/null +++ b/core/src/wlan_p2p_main.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: This file contains main P2P function definitions + */ + +#include +#include +#include +#include +#include +#include +#include "wlan_p2p_public_struct.h" +#include "wlan_p2p_ucfg_api.h" +#include "wlan_p2p_tgt_api.h" +#include "../inc/wlan_p2p_main.h" +#include "../inc/wlan_p2p_roc.h" +#include "../inc/wlan_p2p_off_chan_tx.h" + +/** + * p2p_psoc_obj_create_notification() - Function to allocate per P2P + * soc private object + * @soc: soc context + * @data: Pointer to data + * + * This function gets called from object manager when psoc is being + * created and creates p2p soc context. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_psoc_obj_create_notification( + struct wlan_objmgr_psoc *soc, void *data) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + QDF_STATUS status; + + if (soc == NULL) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = qdf_mem_malloc(sizeof(*p2p_soc_obj)); + if (p2p_soc_obj == NULL) { + p2p_err("Failed to allocate p2p soc private object"); + return QDF_STATUS_E_NOMEM; + } + p2p_soc_obj->soc = soc; + + status = wlan_objmgr_psoc_component_obj_attach(soc, + WLAN_UMAC_COMP_P2P, p2p_soc_obj, + QDF_STATUS_SUCCESS); + if (status != QDF_STATUS_SUCCESS) { + qdf_mem_free(p2p_soc_obj); + p2p_err("Failed to attach p2p component, %d", status); + return status; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_psoc_obj_destroy_notification() - Free soc private object + * @soc: soc context + * @data: Pointer to data + * + * This function gets called from object manager when psoc is being + * deleted and delete p2p soc context. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_psoc_obj_destroy_notification( + struct wlan_objmgr_psoc *soc, void *data) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + QDF_STATUS status; + + if (soc == NULL) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (p2p_soc_obj == NULL) { + p2p_err("p2p soc private object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_psoc_component_obj_detach(soc, + WLAN_UMAC_COMP_P2P, p2p_soc_obj); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to detach p2p component, %d", status); + return status; + } + qdf_mem_free(p2p_soc_obj); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_vdev_obj_create_notification() - Allocate per p2p vdev object + * @vdev: vdev context + * @data: Pointer to data + * + * This function gets called from object manager when vdev is being + * created and creates p2p vdev context. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_vdev_obj_create_notification( + struct wlan_objmgr_vdev *vdev, void *data) +{ + struct p2p_vdev_priv_obj *p2p_vdev_obj; + QDF_STATUS status; + + if (vdev == NULL) { + p2p_err("vdev context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_vdev_obj = qdf_mem_malloc(sizeof(*p2p_vdev_obj)); + if (p2p_vdev_obj == NULL) { + p2p_err("Failed to allocate p2p vdev object"); + return QDF_STATUS_E_NOMEM; + } + p2p_vdev_obj->vdev = vdev; + status = wlan_objmgr_vdev_component_obj_attach(vdev, + WLAN_UMAC_COMP_P2P, p2p_vdev_obj, + QDF_STATUS_SUCCESS); + if (status != QDF_STATUS_SUCCESS) { + qdf_mem_free(p2p_vdev_obj); + p2p_err("Failed to attach p2p component to vdev, %d", + status); + return status; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_vdev_obj_destroy_notification() - Free per P2P vdev object + * @vdev: vdev context + * @data: Pointer to data + * + * This function gets called from object manager when vdev is being + * deleted and delete p2p vdev context. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_vdev_obj_destroy_notification( + struct wlan_objmgr_vdev *vdev, void *data) +{ + struct p2p_vdev_priv_obj *p2p_vdev_obj; + QDF_STATUS status; + + if (vdev == NULL) { + p2p_err("vdev context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_P2P); + if (p2p_vdev_obj == NULL) { + p2p_err("p2p vdev object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_vdev_component_obj_detach(vdev, + WLAN_UMAC_COMP_P2P, p2p_vdev_obj); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to detach p2p component, %d", status); + return status; + } + + qdf_mem_free(p2p_vdev_obj); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_component_init(void) +{ + QDF_STATUS status; + + status = wlan_objmgr_register_psoc_create_handler( + WLAN_UMAC_COMP_P2P, + p2p_psoc_obj_create_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to register p2p obj create handler"); + goto err_reg_psoc_create; + } + + status = wlan_objmgr_register_psoc_delete_handler( + WLAN_UMAC_COMP_P2P, + p2p_psoc_obj_destroy_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to register p2p obj delete handler"); + goto err_reg_psoc_delete; + } + + status = wlan_objmgr_register_vdev_create_handler( + WLAN_UMAC_COMP_P2P, + p2p_vdev_obj_create_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to register p2p vdev create handler"); + goto err_reg_vdev_create; + } + + status = wlan_objmgr_register_vdev_delete_handler( + WLAN_UMAC_COMP_P2P, + p2p_vdev_obj_destroy_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to register p2p vdev delete handler"); + goto err_reg_vdev_delete; + } + + p2p_debug("Register p2p obj handler successful"); + + return QDF_STATUS_SUCCESS; +err_reg_vdev_delete: + wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_P2P, + p2p_vdev_obj_create_notification, NULL); +err_reg_vdev_create: + wlan_objmgr_unregister_psoc_delete_handler(WLAN_UMAC_COMP_P2P, + p2p_psoc_obj_destroy_notification, NULL); +err_reg_psoc_delete: + wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_P2P, + p2p_psoc_obj_create_notification, NULL); +err_reg_psoc_create: + return status; +} + +QDF_STATUS p2p_component_deinit(void) +{ + QDF_STATUS status; + QDF_STATUS ret_status = QDF_STATUS_SUCCESS; + + status = wlan_objmgr_unregister_vdev_create_handler( + WLAN_UMAC_COMP_P2P, + p2p_vdev_obj_create_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to unregister p2p vdev create handler, %d", + status); + ret_status = status; + } + + status = wlan_objmgr_unregister_vdev_delete_handler( + WLAN_UMAC_COMP_P2P, + p2p_vdev_obj_destroy_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to unregister p2p vdev delete handler, %d", + status); + ret_status = status; + } + + status = wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_P2P, + p2p_psoc_obj_create_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to unregister p2p obj create handler, %d", + status); + ret_status = status; + } + + status = wlan_objmgr_unregister_psoc_delete_handler( + WLAN_UMAC_COMP_P2P, + p2p_psoc_obj_destroy_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to unregister p2p obj delete handler, %d", + status); + ret_status = status; + } + + p2p_debug("Unregister p2p obj handler complete"); + + return ret_status; +} + +QDF_STATUS p2p_psoc_open(struct wlan_objmgr_psoc *soc) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + if (soc == NULL) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (p2p_soc_obj == NULL) { + p2p_err("p2p soc priviate object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + qdf_list_create(&p2p_soc_obj->roc_q, MAX_QUEUE_LENGTH); + qdf_list_create(&p2p_soc_obj->tx_q_roc, MAX_QUEUE_LENGTH); + qdf_list_create(&p2p_soc_obj->tx_q_ack, MAX_QUEUE_LENGTH); + qdf_event_create(&p2p_soc_obj->cancel_roc_done); + /*TODO, register scan event, wmi lo and noa event */ + + p2p_debug("p2p psoc object open successful"); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_psoc_close(struct wlan_objmgr_psoc *soc) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + if (soc == NULL) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (p2p_soc_obj == NULL) { + p2p_err("p2p soc object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + qdf_list_destroy(&p2p_soc_obj->roc_q); + qdf_list_destroy(&p2p_soc_obj->tx_q_roc); + qdf_list_destroy(&p2p_soc_obj->tx_q_ack); + /*TODO, ucfg_scan_clear_requestor_id(soc, p2p_soc_obj->scan_req_id);*/ + + p2p_debug("p2p psoc object close successful"); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, + struct p2p_start_param *req) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_start_param *start_param; + + if (soc == NULL) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (p2p_soc_obj == NULL) { + p2p_err("P2P soc object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + start_param = qdf_mem_malloc(sizeof(*start_param)); + if (start_param == NULL) { + p2p_err("Failed to allocate start params"); + return QDF_STATUS_E_NOMEM; + } + start_param->rx_cb = req->rx_cb; + start_param->rx_cb_data = req->rx_cb_data; + start_param->event_cb = req->event_cb; + start_param->event_cb_data = req->event_cb_data; + start_param->tx_cnf_cb = req->tx_cnf_cb; + start_param->tx_cnf_cb_data = req->tx_cnf_cb_data; + start_param->lo_event_cb = req->lo_event_cb; + start_param->lo_event_cb_data = req->lo_event_cb_data; + p2p_soc_obj->start_param = start_param; + + p2p_debug("p2p psoc start successful"); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_start_param *start_param; + + if (soc == NULL) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (p2p_soc_obj == NULL) { + p2p_err("P2P soc object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + start_param = p2p_soc_obj->start_param; + p2p_soc_obj->start_param = NULL; + if (start_param == NULL) { + p2p_err("start parameters is NULL"); + return QDF_STATUS_E_FAILURE; + } + + start_param->rx_cb = NULL; + start_param->rx_cb_data = NULL; + start_param->event_cb = NULL; + start_param->event_cb_data = NULL; + start_param->tx_cnf_cb = NULL; + start_param->tx_cnf_cb_data = NULL; + qdf_mem_free(start_param); + + p2p_debug("p2p psoc stop successful"); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg) +{ + QDF_STATUS status; + + p2p_info("msg type %d", msg->type); + if (msg->bodyptr == NULL) { + p2p_err("Invalid message body"); + return QDF_STATUS_E_INVAL; + } + switch (msg->type) { + case P2P_ROC_REQ: + status = p2p_process_roc_req( + (struct p2p_roc_context *) + msg->bodyptr); + break; + case P2P_CANCEL_ROC_REQ: + status = p2p_process_cancel_roc_req( + (struct cancel_roc_context *) + msg->bodyptr); + break; + case P2P_MGMT_TX: + status = p2p_process_mgmt_tx( + (struct tx_action_context *) + msg->bodyptr); + break; + case P2P_MGMT_TX_CANCEL: + status = p2p_process_mgmt_tx_cancel( + (struct cancel_roc_context *) + msg->bodyptr); + break; + default: + p2p_err("drop unexpected message received %d", + msg->type); + status = QDF_STATUS_E_INVAL; + break; + } + + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + + return status; +} + +QDF_STATUS p2p_process_evt(struct scheduler_msg *msg) +{ + QDF_STATUS status; + + p2p_info("msg type %d", msg->type); + if (msg->bodyptr == NULL) { + p2p_err("Invalid message body"); + return QDF_STATUS_E_INVAL; + } + + switch (msg->type) { + case P2P_EVENT_MGMT_TX_ACK_CNF: + status = p2p_process_mgmt_tx_ack_cnf( + (struct p2p_tx_conf_event *) + msg->bodyptr); + break; + case P2P_EVENT_RX_MGMT: + status = p2p_process_rx_mgmt( + (struct p2p_rx_mgmt_event *) + msg->bodyptr); + break; + case P2P_EVENT_LO_STOPPED: + status = p2p_process_lo_stop( + (struct p2p_lo_stop_event *) + msg->bodyptr); + break; + case P2P_EVENT_NOA: + status = p2p_process_noa( + (struct p2p_noa_event *) + msg->bodyptr); + break; + default: + p2p_err("Drop unexpected message received %d", + msg->type); + status = QDF_STATUS_E_INVAL; + break; + } + + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + + return status; +} + +QDF_STATUS p2p_process_lo_stop( + struct p2p_lo_stop_event *lo_stop_event) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event) +{ + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c new file mode 100644 index 000000000000..649bcb894fb2 --- /dev/null +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -0,0 +1,47 @@ +/* + * 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: This file contains off channel tx API definitions + */ + +#include +#include "../inc/wlan_p2p_off_chan_tx.h" + +QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_process_mgmt_tx_cancel( + struct cancel_roc_context *cancel_tx) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_process_mgmt_tx_ack_cnf( + struct p2p_tx_conf_event *tx_cnf_event) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_process_rx_mgmt( + struct p2p_rx_mgmt_event *rx_mgmt_event) +{ + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c new file mode 100644 index 000000000000..29399c4007dd --- /dev/null +++ b/core/src/wlan_p2p_roc.c @@ -0,0 +1,39 @@ +/* + * 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: This file contains RoC API definitions + */ + +#include "../inc/wlan_p2p_roc.h" + +QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_process_cancel_roc_req( + struct cancel_roc_context *cancel_roc_ctx) +{ + return QDF_STATUS_SUCCESS; +} + +void p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, + struct scan_event *event, void *arg) +{ +} diff --git a/dispatcher/inc/wlan_p2p_public_struct.h b/dispatcher/inc/wlan_p2p_public_struct.h new file mode 100644 index 000000000000..97bd3b305a60 --- /dev/null +++ b/dispatcher/inc/wlan_p2p_public_struct.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2011-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: Contains p2p public data structure definations + */ + +#ifndef _WLAN_P2P_PUBLIC_STRUCT_H_ +#define _WLAN_P2P_PUBLIC_STRUCT_H_ + +#include + +/** + * struct p2p_roc_req - P2P roc request + * @vdev_id: Vdev id on which this request has come + * @chan: Chan for which this RoC has been requested + * @phy_mode: PHY mode + * @duration: Duration for the RoC + */ +struct p2p_roc_req { + uint32_t vdev_id; + uint32_t chan; + uint32_t phy_mode; + uint32_t duration; +}; + +/** + * enum p2p_roc_event - P2P RoC event + * @ROC_EVENT_READY_ON_CHAN: RoC has started now + * @ROC_EVENT_COMPLETED: RoC has been completed + * @ROC_EVENT_INAVLID: Invalid event + */ +enum p2p_roc_event { + ROC_EVENT_READY_ON_CHAN = 0, + ROC_EVENT_COMPLETED, + ROC_EVENT_INAVLID, +}; + +/** + * struct p2p_event - p2p event + * @vdev_id: Vdev id + * @roc_event: RoC event + * @cookie: Cookie which is given to supplicant for this roc req + * @chan: Chan for which this RoC has been requested + * @duration: Duration for the RoC + */ +struct p2p_event { + uint32_t vdev_id; + enum p2p_roc_event roc_event; + uint64_t cookie; + uint32_t chan; + uint32_t duration; +}; + +/** + * struct p2p_rx_mgmt_frame - rx mgmt frame structure + * @frame_len: Frame length + * @rx_chan: RX channel + * @vdev_id: Vdev id + * @frm_type: Frame type + * @rx_rssi: RX rssi + * @buf: Buffer address + */ +struct p2p_rx_mgmt_frame { + uint32_t frame_len; + uint32_t rx_chan; + uint32_t vdev_id; + uint32_t frm_type; + uint32_t rx_rssi; + uint8_t buf[1]; +}; + +/** + * struct p2p_tx_cnf - tx confirm structure + * @vdev_id: Vdev id + * @action_cookie: TX cookie for this action frame + * @buf_len: Frame length + * @status: TX status + * @buf: Buffer address + */ +struct p2p_tx_cnf { + uint32_t vdev_id; + uint64_t action_cookie; + uint32_t buf_len; + uint32_t status; + uint8_t *buf; +}; + +/** + * struct p2p_mgmt_tx - p2p mgmt tx structure + * @vdev_id: Vdev id + * @chan: Chan for which this RoC has been requested + * @wait: Duration for the RoC + * @len: Length of tx buffer + * @no_cck: Required cck or not + * @dont_wait_for_ack: Wait for ack or not + * @buf: TX buffer + */ +struct p2p_mgmt_tx { + uint32_t vdev_id; + uint32_t chan; + uint32_t wait; + uint32_t len; + uint32_t no_cck; + uint32_t dont_wait_for_ack; + const uint8_t *buf; +}; + +/** + * struct p2p_ps_config + * @vdev_id: Vdev id + * @opp_ps: Opportunistic power save + * @ct_window: CT window + * @count: Count + * @duration: Duration + * @interval: Interval + * @single_noa_duration: Single shot noa duration + * @ps_selection: power save selection + */ +struct p2p_ps_config { + uint32_t vdev_id; + uint32_t opp_ps; + uint32_t ct_window; + uint32_t count; + uint32_t duration; + uint32_t interval; + uint32_t single_noa_duration; + uint32_t ps_selection; +}; + +/** + * struct p2p_lo_start - p2p listen offload start + * @vdev_id: Vdev id + * @ctl_flags: Control flag + * @freq: P2P listen frequency + * @period: Listen offload period + * @interval: Listen offload interval + * @count: Number listen offload intervals + * @dev_types_len: Device types length + * @probe_resp_len: Probe response template length + * @device_types: Device types + * @probe_resp_tmplt: Probe response template + */ +struct p2p_lo_start { + uint32_t vdev_id; + uint32_t ctl_flags; + uint32_t freq; + uint32_t period; + uint32_t interval; + uint32_t count; + uint32_t dev_types_len; + uint32_t probe_resp_len; + uint8_t *device_types; + uint8_t *probe_resp_tmplt; +}; + +/** + * struct p2p_lo_event + * @vdev_id: Vdev id + * @reason_code: reason code + */ +struct p2p_lo_event { + uint32_t vdev_id; + uint32_t reason_code; +}; + +#endif /* _WLAN_P2P_PUBLIC_STRUCT_H_ */ diff --git a/dispatcher/inc/wlan_p2p_tgt_api.h b/dispatcher/inc/wlan_p2p_tgt_api.h new file mode 100644 index 000000000000..133443ca3f1f --- /dev/null +++ b/dispatcher/inc/wlan_p2p_tgt_api.h @@ -0,0 +1,125 @@ +/* + * 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: Contains p2p south bound interface definitions + */ + +#ifndef _WLAN_P2P_TGT_API_H_ +#define _WLAN_P2P_TGT_API_H_ + +#include + +struct scan_event; +struct wlan_objmgr_psoc; +struct wlan_objmgr_peer; +enum mgmt_frame_type; + +/** + * tgt_p2p_scan_event_cb() - Callback for scan event + * @vdev: vdev id + * @event: event type + * @arg: registered arguments + * + * This function gets called from scan component when getting P2P + * scan event. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_scan_event_cb(uint8_t vdev, + struct scan_event *event, void *arg); + +/** + * tgt_p2p_mgmt_download_comp_cb() - Callback for mgmt frame tx + * complete + * @context: tx context + * @buf: buffer address + * @free: need to free or not + * + * This function gets called from mgmt tx/rx component when mgmt + * frame tx complete. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_mgmt_download_comp_cb(void *context, + qdf_nbuf_t buf, bool free); + +/** + * tgt_p2p_mgmt_ota_comp_cb() - Callback for mgmt frame tx ack + * @context: tx context + * @buf: buffer address + * @status: tx status + * @tx_compl_params: tx complete parameters + * + * This function gets called from mgmt tx/rx component when getting + * mgmt frame tx ack. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, + uint32_t status, void *tx_compl_params); + +/** + * tgt_p2p_mgmt_frame_rx_cb() - Callback for rx mgmt frame + * @psoc: soc context + * @peer: peer context + * @buf: rx buffer + * @params: rx parameters + * @frm_type: frame type + * + * This function gets called from mgmt tx/rx component when rx mgmt + * frame. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_mgmt_frame_rx_cb( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, + qdf_nbuf_t buf, void *params, + enum mgmt_frame_type frm_type); + +/** + * tgt_p2p_noa_event_cb() - Callback for noa event + * @data: + * @event_buf: event buffer + * @len: buffer length + * + * This function gets called from WMI when triggered WMI event + * WMI_P2P_NOA_EVENTID. + * + * Return: 0 - success + * others - failure + */ +int tgt_p2p_noa_event_cb(void *data, uint8_t *event_buf, + uint32_t len); + +/** + * tgt_p2p_lo_event_cb() - Listen offload stop request + * @data: + * @event_buf: event buffer + * @len: buffer length + * + * This function gets called from WMI when triggered WMI event + * WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID. + * + * Return: 0 - success + * others - failure + */ +int tgt_p2p_lo_event_cb(void *data, uint8_t *event_buf, uint32_t len); + +#endif /* _WLAN_P2P_TGT_API_H_ */ diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/dispatcher/inc/wlan_p2p_ucfg_api.h new file mode 100644 index 000000000000..185d9491c077 --- /dev/null +++ b/dispatcher/inc/wlan_p2p_ucfg_api.h @@ -0,0 +1,265 @@ +/* + * 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: Contains p2p north bound interface definitions + */ + +#ifndef _WLAN_P2P_UCFG_API_H_ +#define _WLAN_P2P_UCFG_API_H_ + +#include + +struct wlan_objmgr_psoc; +struct p2p_roc_req; +struct p2p_event; +struct p2p_rx_mgmt_frame; +struct p2p_tx_cnf; +struct p2p_mgmt_tx; +struct p2p_ps_config; +struct p2p_lo_start; +struct p2p_lo_event; + +/** + * p2p_rx_callback() - Callback for rx mgmt frame + * @user_data: user data associated to this rx mgmt frame. + * @rx_frame: RX mgmt frame + * + * This callback will be used to give rx frames to hdd. + * + * Return: None + */ +typedef void (*p2p_rx_callback)(void *user_data, + struct p2p_rx_mgmt_frame *rx_frame); + +/** + * p2p_action_tx_cnf_callback() - Callback for tx confirmation + * @user_data: user data associated to this tx confirmation + * @tx_cnf: tx confirmation information + * + * This callback will be used to give tx mgmt frame confirmation to + * hdd. + * + * Return: None + */ +typedef void (*p2p_action_tx_cnf_callback)(void *user_data, + struct p2p_tx_cnf *tx_cnf); + +/** + * p2p_lo_event_callback() - Callback for listen offload event + * @user_data: user data associated to this lo event + * @p2p_lo_event: listen offload event information + * + * This callback will be used to give listen offload event to hdd. + * + * Return: None + */ +typedef void (*p2p_lo_event_callback)(void *user_data, + struct p2p_lo_event *p2p_lo_event); + +/** + * p2p_event_callback() - Callback for P2P event + * @user_data: user data associated to this p2p event + * @p2p_event: p2p event information + * + * This callback will be used to give p2p event to hdd. + * + * Return: None + */ +typedef void (*p2p_event_callback)(void *user_data, + struct p2p_event *p2p_event); + +/** + * struct p2p_start_param - p2p soc start parameters. Below callbacks + * will be registered by the HDD + * @rx_callback: Function pointer to hdd rx callback. This + * function will be used to give rx frames to hdd + * @rx_cb_data: RX callback user data + * @event_cb: Founction pointer to hdd p2p event callback. + * This function will be used to give p2p event + * to hdd + * @event_cb_data: Pointer to p2p event callback user data + * @tx_cnf_cb: Function pointer to hdd tx confirm callback. + * This function will be used to give tx confirm + * to hdd + * @tx_cnf_cb_data: Pointer to p2p tx confirm callback user data + * @lo_event_cb: Founction pointer to p2p listen offload + * callback. This function will be used to give + * listen offload stopped event to hdd + * @lo_event_cb_data: Pointer to p2p listen offload callback user data + */ +struct p2p_start_param { + p2p_rx_callback rx_cb; + void *rx_cb_data; + p2p_event_callback event_cb; + void *event_cb_data; + p2p_action_tx_cnf_callback tx_cnf_cb; + void *tx_cnf_cb_data; + p2p_lo_event_callback lo_event_cb; + void *lo_event_cb_data; +}; + +/** + * ucfg_p2p_init() - P2P component initialization + * + * This function gets called when dispatcher initializing. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_init(void); + +/** + * ucfg_p2p_deinit() - P2P component de-init + * + * This function gets called when dispatcher de-init. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_deinit(void); + +/** + * ucfg_p2p_psoc_open() - Open P2P component + * @soc: soc context + * + * This function gets called when dispatcher opening. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_psoc_open(struct wlan_objmgr_psoc *soc); + +/** + * ucfg_p2p_psoc_close() - Close P2P component + * @soc: soc context + * + * This function gets called when dispatcher closing. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_psoc_close(struct wlan_objmgr_psoc *soc); + +/** + * ucfg_p2p_psoc_start() - Start P2P component + * @soc: soc context + * @req: P2P start parameters + * + * This function gets called when up layer starting up. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_psoc_start(struct wlan_objmgr_psoc *soc, + struct p2p_start_param *req); + +/** + * ucfg_p2p_psoc_stop() - Stop P2P component + * @soc: soc context + * + * This function gets called when up layer exit. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_psoc_stop(struct wlan_objmgr_psoc *soc); + +/** + * ucfg_p2p_roc_req() - Roc request + * @soc: soc context + * @roc_req: Roc request parameters + * @cookie: return cookie to caller + * + * This function delivers roc request to P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, + struct p2p_roc_req *roc_req, uint64_t *cookie); + +/** + * ucfg_p2p_roc_cancel_req() - Cancel roc request + * @soc: soc context + * @cookie: Find out the roc request by cookie + * + * This function delivers cancel roc request to P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, + uint64_t cookie); + +/** + * ucfg_p2p_mgmt_tx() - Mgmt frame tx request + * @soc: soc context + * @mgmt_frm: TX mgmt frame parameters + * @cookie: Return the cookie to caller + * + * This function delivers mgmt frame tx request to P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, + struct p2p_mgmt_tx *mgmt_frm, uint64_t *cookie); + +/** + * ucfg_p2p_mgmt_tx_cancel() - Cancel mgmt frame tx request + * @soc: soc context + * @cookie: Find out the mgmt tx request by cookie + * + * This function delivers cancel mgmt frame tx request request to P2P + * component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, + uint64_t cookie); + +/** + * ucfg_p2p_set_ps() - P2P set power save + * @soc: soc context + * @ps_config: power save configure + * + * This function delivers p2p power save request to P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, + struct p2p_ps_config *ps_config); + +/** + * ucfg_p2p_lo_start() - Listen offload start request + * @soc: soc context + * @p2p_lo_start: lo start parameters + * + * This function delivers listen offload start request to P2P + * component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc, + struct p2p_lo_start *p2p_lo_start); + +/** + * ucfg_p2p_lo_stop() - Listen offload stop request + * @soc: soc context + * @vdev_id: vdev id + * + * This function delivers listen offload stop request to P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc, + uint32_t vdev_id); + +#endif /* _WLAN_P2P_UCFG_API_H_ */ diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c new file mode 100644 index 000000000000..d22b325d06c1 --- /dev/null +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -0,0 +1,66 @@ +/* + * 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: This file contains p2p south bound interface definitions + */ + +#include +#include +#include "wlan_p2p_tgt_api.h" +#include "../../core/inc/wlan_p2p_main.h" + +QDF_STATUS tgt_p2p_scan_event_cb(uint8_t vdev, + struct scan_event *event, void *arg) +{ + /* call p2p_process_scan_event directly*/ + /* since this is from target thread */ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_p2p_mgmt_download_comp_cb(void *context, + qdf_nbuf_t buf, bool free) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, + uint32_t status, void *tx_compl_params) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_p2p_mgmt_frame_rx_cb( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, + qdf_nbuf_t buf, void *params, + enum mgmt_frame_type frm_type) +{ + return QDF_STATUS_SUCCESS; +} + +int tgt_p2p_noa_event_cb(void *data, uint8_t *event_buf, + uint32_t len) +{ + return 0; +} + +int tgt_p2p_lo_event_cb(void *data, uint8_t *event_buf, uint32_t len) +{ + return 0; +} diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c new file mode 100644 index 000000000000..8f2fd599f23e --- /dev/null +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -0,0 +1,101 @@ +/* + * 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: This file contains p2p north bound interface definitions + */ + +#include +#include "wlan_p2p_ucfg_api.h" +#include "wlan_p2p_public_struct.h" +#include "../../core/inc/wlan_p2p_main.h" +#include "../../core/inc/wlan_p2p_roc.h" +#include "../../core/inc/wlan_p2p_off_chan_tx.h" + +QDF_STATUS ucfg_p2p_init(void) +{ + return p2p_component_init(); +} + +QDF_STATUS ucfg_p2p_deinit(void) +{ + return p2p_component_deinit(); +} + +QDF_STATUS ucfg_p2p_psoc_open(struct wlan_objmgr_psoc *soc) +{ + return p2p_psoc_open(soc); +} + +QDF_STATUS ucfg_p2p_psoc_close(struct wlan_objmgr_psoc *soc) +{ + return p2p_psoc_close(soc); +} + +QDF_STATUS ucfg_p2p_psoc_start(struct wlan_objmgr_psoc *soc, + struct p2p_start_param *req) +{ + return p2p_psoc_start(soc, req); +} + +QDF_STATUS ucfg_p2p_psoc_stop(struct wlan_objmgr_psoc *soc) +{ + return p2p_psoc_stop(soc); +} + +QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, + struct p2p_roc_req *roc_req, uint64_t *cookie) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, + uint64_t cookie) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, + struct p2p_mgmt_tx *mgmt_frm, uint64_t *cookie) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, + uint64_t cookie) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, + struct p2p_ps_config *ps_config) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc, + struct p2p_lo_start *p2p_lo_start) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc, + uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} From 6a8f07ff7a39f23e2900d1870ca5178e5a8e4cda Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 15 Feb 2017 16:59:48 -0800 Subject: [PATCH 002/404] qcacmn: restructure policy manager component Initial changes to move policy manager to host common. Also restructure the functionalities. CRs-Fixed: 2009818 Change-Id: I163fe1f92be07dc4bc6380d889e26ce5d75e5671 --- inc/wlan_policy_mgr_api.h | 1612 ++++++++++++++++++++++++ inc/wlan_policy_mgr_public_struct.h | 930 ++++++++++++++ src/wlan_policy_mgr_action.c | 224 ++++ src/wlan_policy_mgr_core.c | 638 ++++++++++ src/wlan_policy_mgr_get_set_utils.c | 346 +++++ src/wlan_policy_mgr_i.h | 374 ++++++ src/wlan_policy_mgr_init_deinit.c | 314 +++++ src/wlan_policy_mgr_pcl.c | 172 +++ src/wlan_policy_mgr_tables_1x1_dbs_i.h | 1015 +++++++++++++++ src/wlan_policy_mgr_tables_2x2_dbs_i.h | 1392 ++++++++++++++++++++ src/wlan_policy_mgr_tables_no_dbs_i.h | 909 +++++++++++++ 11 files changed, 7926 insertions(+) create mode 100644 inc/wlan_policy_mgr_api.h create mode 100644 inc/wlan_policy_mgr_public_struct.h create mode 100644 src/wlan_policy_mgr_action.c create mode 100644 src/wlan_policy_mgr_core.c create mode 100644 src/wlan_policy_mgr_get_set_utils.c create mode 100644 src/wlan_policy_mgr_i.h create mode 100644 src/wlan_policy_mgr_init_deinit.c create mode 100644 src/wlan_policy_mgr_pcl.c create mode 100644 src/wlan_policy_mgr_tables_1x1_dbs_i.h create mode 100644 src/wlan_policy_mgr_tables_2x2_dbs_i.h create mode 100644 src/wlan_policy_mgr_tables_no_dbs_i.h diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h new file mode 100644 index 000000000000..bb00b936ed38 --- /dev/null +++ b/inc/wlan_policy_mgr_api.h @@ -0,0 +1,1612 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_POLICY_MGR_API_H +#define __WLAN_POLICY_MGR_API_H + +/** + * DOC: wlan_policy_mgr_api.h + * + * Concurrenct Connection Management entity + */ + +/* Include files */ +#include "qdf_types.h" +#include "qdf_status.h" +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_policy_mgr_public_struct.h" + +typedef const enum policy_mgr_pcl_type + pm_dbs_pcl_second_connection_table_type + [PM_MAX_ONE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE]; + +typedef const enum policy_mgr_pcl_type + pm_dbs_pcl_third_connection_table_type + [PM_MAX_TWO_CONNECTION_MODE][PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE]; + +typedef const enum policy_mgr_conc_next_action + policy_mgr_next_action_two_connection_table_type + [PM_MAX_ONE_CONNECTION_MODE][POLICY_MGR_MAX_BAND]; + +typedef const enum policy_mgr_conc_next_action + policy_mgr_next_action_three_connection_table_type + [PM_MAX_TWO_CONNECTION_MODE][POLICY_MGR_MAX_BAND]; + +/** + * policy_mgr_set_concurrency_mode() - To set concurrency mode + * @mode: adapter mode + * + * This routine is called to set the concurrency mode + * + * Return: NONE + */ +void policy_mgr_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode); + +/** + * policy_mgr_clear_concurrency_mode() - To clear concurrency mode + * @mode: adapter mode + * + * This routine is called to clear the concurrency mode + * + * Return: NONE + */ +void policy_mgr_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode); + +/** + * policy_mgr_get_connection_count() - provides the count of + * current connections + * @psoc: PSOC object information + * + * This function provides the count of current connections + * + * Return: connection count + */ +uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_concurrency_mode() - return concurrency mode + * + * This routine is used to retrieve concurrency mode + * + * Return: uint32_t value of concurrency mask + */ +uint32_t policy_mgr_get_concurrency_mode(void); + +/** + * policy_mgr_search_and_check_for_session_conc() - Checks if + * concurrecy is allowed + * @psoc: PSOC object information + * @session_id: Session id + * @roam_profile: Pointer to the roam profile + * + * Searches and gets the channel number from the scan results and checks if + * concurrency is allowed for the given session ID + * + * Non zero channel number if concurrency is allowed, zero otherwise + */ +uint8_t policy_mgr_search_and_check_for_session_conc( + struct wlan_objmgr_psoc *psoc, + uint8_t session_id, void *roam_profile); + +/** + * policy_mgr_check_for_session_conc() - Check if concurrency is + * allowed for a session + * @psoc: PSOC object information + * @session_id: Session ID + * @channel: Channel number + * + * Checks if connection is allowed for a given session_id + * + * True if the concurrency is allowed, false otherwise + */ +bool policy_mgr_check_for_session_conc( + struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel); + +/** + * policy_mgr_handle_conc_multiport() - to handle multiport concurrency + * @session_id: Session ID + * @channel: Channel number + * + * This routine will handle STA side concurrency when policy manager + * is enabled. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_handle_conc_multiport( + struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel); + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * policy_mgr_check_concurrent_intf_and_restart_sap() - Check + * concurrent change intf + * @psoc: PSOC object information + * + * Checks the concurrent change interface and restarts SAP + * Return: None + */ +void policy_mgr_check_concurrent_intf_and_restart_sap( + struct wlan_objmgr_psoc *psoc); +#else +static inline void policy_mgr_check_concurrent_intf_and_restart_sap( + struct wlan_objmgr_psoc *psoc) +{ + +} +#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ + +/** + * policy_mgr_is_mcc_in_24G() - Function to check for MCC in 2.4GHz + * @psoc: PSOC object information + * + * This function is used to check for MCC operation in 2.4GHz band. + * STA, P2P and SAP adapters are only considered. + * + * Return: Non zero value if MCC is detected in 2.4GHz band + * + */ +uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_set_mas() - Function to set MAS value to UMAC + * @psoc: PSOC object information + * @mas_value: 0-Disable, 1-Enable MAS + * + * This function passes down the value of MAS to UMAC + * + * Return: Configuration message posting status, SUCCESS or Fail + * + */ +int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, uint8_t mas_value); + +/** + * policy_mgr_set_mcc_p2p_quota() - Function to set quota for P2P + * @psoc: PSOC object information + * @set_value: Qouta value for the interface + * + * This function is used to set the quota for P2P cases + * + * Return: Configuration message posting status, SUCCESS or Fail + * + */ +int policy_mgr_set_mcc_p2p_quota(struct wlan_objmgr_psoc *psoc, + uint32_t set_value); + +/** + * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval + * @psoc: PSOC object information + * + * Updates the beacon parameters of the GO in MCC scenario + * + * Return: Success or Failure depending on the overall function behavior + */ +QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_go_set_mcc_p2p_quota() - Function to set quota for P2P GO + * @psoc: PSOC object information + * @set_value: Qouta value for the interface + * + * This function is used to set the quota for P2P GO cases + * + * Return: Configuration message posting status, SUCCESS or Fail + * + */ +int policy_mgr_go_set_mcc_p2p_quota(struct wlan_objmgr_psoc *psoc, + uint32_t set_value); + +/** + * policy_mgr_set_mcc_latency() - Set MCC latency + * @psoc: PSOC object information + * @set_value: Latency value + * + * Sets the MCC latency value during STA-P2P concurrency + * + * Return: None + */ +void policy_mgr_set_mcc_latency(struct wlan_objmgr_psoc *psoc, int set_value); +#if defined(FEATURE_WLAN_MCC_TO_SCC_SWITCH) +/** + * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA + * @psoc: PSOC object information + * @hdd_ap_ctx: AP context + * + * Invoke the callback function to change SAP channel using (E)CSA + * + * Return: None + */ +void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc); +#else +static inline void policy_mgr_change_sap_channel_with_csa( + struct wlan_objmgr_psoc *psoc) +{ + +} +#endif + +/** + * policy_mgr_incr_active_session() - increments the number of active sessions + * @psoc: PSOC object information + * @mode: Adapter mode + * @session_id: session ID for the connection session + * + * This function increments the number of active sessions maintained per device + * mode. In the case of STA/P2P CLI/IBSS upon connection indication it is + * incremented; In the case of SAP/P2P GO upon bss start it is incremented + * + * Return: None + */ +void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode, uint8_t sessionId); + +/** + * policy_mgr_decr_active_session() - decrements the number of active sessions + * @psoc: PSOC object information + * @mode: Adapter mode + * @session_id: session ID for the connection session + * + * This function decrements the number of active sessions maintained per device + * mode. In the case of STA/P2P CLI/IBSS upon disconnection it is decremented + * In the case of SAP/P2P GO upon bss stop it is decremented + * + * Return: None + */ +void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode, uint8_t sessionId); + +/** + * policy_mgr_decr_session_set_pcl() - Decrement session count and set PCL + * @psoc: PSOC object information + * @mode: Adapter mode + * @session_id: Session id + * + * Decrements the active session count and sets the PCL if a STA connection + * exists + * + * Return: None + */ +void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode, uint8_t session_id); + +/** + * policy_mgr_get_channel() - provide channel number of given mode and vdevid + * @psoc: PSOC object information + * @mode: given mode + * @vdev_id: pointer to vdev_id + * + * This API will provide channel number of matching mode and vdevid. + * If vdev_id is NULL then it will match only mode + * If vdev_id is not NULL the it will match both mode and vdev_id + * + * Return: channel number + */ +uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, uint32_t *vdev_id); + +/** + * policy_mgr_get_pcl() - provides the preferred channel list for + * new connection + * @psoc: PSOC object information + * @mode: Device mode + * @pcl_channels: PCL channels + * @len: lenght of the PCL + * @pcl_weight: Weights of the PCL + * @weight_len: Max length of the weights list + * + * This function provides the preferred channel list on which + * policy manager wants the new connection to come up. Various + * connection decision making entities will using this function + * to query the PCL info + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *pcl_channels, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len); + +/** + * policy_mgr_update_with_safe_channel_list() - provides the safe + * channel list + * @pcl_channels: channel list + * @len: length of the list + * @weight_list: Weights of the PCL + * @weight_len: Max length of the weights list + * + * This function provides the safe channel list from the list + * provided after consulting the channel avoidance list + * + * Return: None + */ +void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels, + uint32_t *len, uint8_t *weight_list, uint32_t weight_len); + +/** + * policy_mgr_get_nondfs_preferred_channel() - to get non-dfs preferred channel + * for given mode + * @psoc: PSOC object information + * @mode: mode for which preferred non-dfs channel is requested + * @for_existing_conn: flag to indicate if preferred channel is requested + * for existing connection + * + * this routine will return non-dfs channel + * 1) for getting non-dfs preferred channel, first we check if there are any + * other connection exist whose channel is non-dfs. if yes then return that + * channel so that we can accommodate upto 3 mode concurrency. + * 2) if there no any other connection present then query concurrency module + * to give preferred channel list. once we get preferred channel list, loop + * through list to find first non-dfs channel from ascending order. + * + * Return: uint8_t non-dfs channel + */ +uint8_t policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, bool for_existing_conn); + +/** + * policy_mgr_is_any_nondfs_chnl_present() - Find any non-dfs + * channel from conc table + * @psoc: PSOC object information + * @channel: pointer to channel which needs to be filled + * + * In-case if any connection is already present whose channel is none dfs then + * return that channel + * + * Return: true up-on finding non-dfs channel else false + */ +bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, + uint8_t *channel); + +/** + * policy_mgr_is_any_dfs_beaconing_session_present() - to find + * if any DFS session + * @psoc: PSOC object information + * @channel: pointer to channel number that needs to filled + * + * If any beaconing session such as SAP or GO present and it is on DFS channel + * then this function will return true + * + * Return: true if session is on DFS or false if session is on non-dfs channel + */ +bool policy_mgr_is_any_dfs_beaconing_session_present( + struct wlan_objmgr_psoc *psoc, uint8_t *channel); + +/** + * policy_mgr_allow_concurrency() - Check for allowed concurrency + * combination + * @psoc: PSOC object information + * @mode: new connection mode + * @channel: channel on which new connection is coming up + * @bw: Bandwidth requested by the connection (optional) + * + * When a new connection is about to come up check if current + * concurrency combination including the new connection is + * allowed or not based on the HW capability + * + * Return: True/False + */ +bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, enum hw_mode_bandwidth bw); + +/** + * policy_mgr_get_first_connection_pcl_table_index() - provides the + * row index to firstConnectionPclTable to get to the correct + * pcl + * @psoc: PSOC object information + * + * This function provides the row index to + * firstConnectionPclTable. The index is the preference config. + * + * Return: table index + */ +enum policy_mgr_conc_priority_mode + policy_mgr_get_first_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_second_connection_pcl_table_index() - provides the + * row index to secondConnectionPclTable to get to the correct + * pcl + * @psoc: PSOC object information + * + * This function provides the row index to + * secondConnectionPclTable. The index is derived based on + * current connection, band on which it is on & chain mask it is + * using, as obtained from pm_conc_connection_list. + * + * Return: table index + */ +enum policy_mgr_one_connection_mode + policy_mgr_get_second_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_third_connection_pcl_table_index() - provides the + * row index to thirdConnectionPclTable to get to the correct + * pcl + * @psoc: PSOC object information + * + * This function provides the row index to + * thirdConnectionPclTable. The index is derived based on + * current connection, band on which it is on & chain mask it is + * using, as obtained from pm_conc_connection_list. + * + * Return: table index + */ +enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_incr_connection_count() - adds the new connection to + * the current connections list + * @psoc: PSOC object information + * @vdev_id: vdev id + * + * + * This function adds the new connection to the current + * connections list + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_incr_connection_count(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id); + +/** + * policy_mgr_update_connection_info() - updates the existing + * connection in the current connections list + * @psoc: PSOC object information + * @vdev_id: vdev id + * + * + * This function adds the new connection to the current + * connections list + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id); + +/** + * policy_mgr_decr_connection_count() - remove the old connection + * from the current connections list + * @psoc: PSOC object information + * @vdev_id: vdev id of the old connection + * + * + * This function removes the old connection from the current + * connections list + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id); + +/** + * policy_mgr_current_connections_update() - initiates actions + * needed on current connections once channel has been decided + * for the new connection + * @psoc: PSOC object information + * @session_id: Session id + * @channel: Channel on which new connection will be + * @reason: Reason for which connection update is required + * + * This function initiates initiates actions + * needed on current connections once channel has been decided + * for the new connection. Notifies UMAC & FW as well + * + * Return: QDF_STATUS enum + */ +QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, uint8_t channel, + enum policy_mgr_conn_update_reason); + +/** + * policy_mgr_is_ibss_conn_exist() - to check if IBSS connection already present + * @psoc: PSOC object information + * @ibss_channel: pointer to ibss channel which needs to be filled + * + * this routine will check if IBSS connection already exist or no. If it + * exist then this routine will return true and fill the ibss_channel value. + * + * Return: true if ibss connection exist else false + */ +bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, + uint8_t *ibss_channel); + +/** + * policy_mgr_get_conn_info() - get the current connections list + * @len: lenght of the list + * + * This function returns a pointer to the current connections + * list + * + * Return: pointer to connection list + */ +struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info( + uint32_t *len); +#ifdef MPC_UT_FRAMEWORK +/** + * policy_mgr_incr_connection_count_utfw() - adds the new + * connection to the current connections list + * @psoc: PSOC object information + * @vdev_id: vdev id + * @tx_streams: number of transmit spatial streams + * @rx_streams: number of receive spatial streams + * @chain_mask: chain mask + * @type: connection type + * @sub_type: connection subtype + * @channelid: channel number + * @mac_id: mac id + * + * This function adds the new connection to the current + * connections list + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, + uint32_t chain_mask, uint32_t type, uint32_t sub_type, + uint32_t channelid, uint32_t mac_id); + +/** + * policy_mgr_update_connection_info_utfw() - updates the + * existing connection in the current connections list + * @psoc: PSOC object information + * @vdev_id: vdev id + * @tx_streams: number of transmit spatial streams + * @rx_streams: number of receive spatial streams + * @chain_mask: chain mask + * @type: connection type + * @sub_type: connection subtype + * @channelid: channel number + * @mac_id: mac id + * + * This function updates the connection to the current + * connections list + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_update_connection_info_utfw(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, + uint32_t chain_mask, uint32_t type, uint32_t sub_type, + uint32_t channelid, uint32_t mac_id); + +/** + * policy_mgr_decr_connection_count_utfw() - remove the old + * connection from the current connections list + * @psoc: PSOC object information + * @del_all: delete all entries + * @vdev_id: vdev id + * + * This function removes the old connection from the current + * connections list + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, + uint32_t del_all, uint32_t vdev_id); + +/** + * policy_mgr_get_pcl_from_first_conn_table() - Get PCL for new + * connection from first connection table + * @type: Connection mode of type 'policy_mgr_con_mode' + * @sys_pref: System preference + * + * Get the PCL for a new connection + * + * Return: PCL channels enum + */ +enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table( + enum policy_mgr_con_mode type, + enum policy_mgr_conc_priority_mode sys_pref); + +/** + * policy_mgr_get_pcl_from_second_conn_table() - Get PCL for new + * connection from second connection table + * @idx: index into first connection table + * @type: Connection mode of type 'policy_mgr_con_mode' + * @sys_pref: System preference + * @dbs_capable: if HW DBS capable + * + * Get the PCL for a new connection + * + * Return: PCL channels enum + */ +enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table( + enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type, + enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable); + +/** + * policy_mgr_get_pcl_from_third_conn_table() - Get PCL for new + * connection from third connection table + * @idx: index into second connection table + * @type: Connection mode of type 'policy_mgr_con_mode' + * @sys_pref: System preference + * @dbs_capable: if HW DBS capable + * + * Get the PCL for a new connection + * + * Return: PCL channels enum + */ +enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table( + enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type, + enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable); +#else +static inline QDF_STATUS policy_mgr_incr_connection_count_utfw( + struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, + uint32_t tx_streams, uint32_t rx_streams, + uint32_t chain_mask, uint32_t type, uint32_t sub_type, + uint32_t channelid, uint32_t mac_id) +{ + return QDF_STATUS_SUCCESS; +} +static inline QDF_STATUS policy_mgr_update_connection_info_utfw( + struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, + uint32_t tx_streams, uint32_t rx_streams, + uint32_t chain_mask, uint32_t type, uint32_t sub_type, + uint32_t channelid, uint32_t mac_id) +{ + return QDF_STATUS_SUCCESS; +} +static inline QDF_STATUS policy_mgr_decr_connection_count_utfw( + struct wlan_objmgr_psoc *psoc, uint32_t del_all, + uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * policy_mgr_convert_device_mode_to_qdf_type() - provides the + * type translation from HDD to policy manager type + * @device_mode: Generic connection mode type + * + * + * This function provides the type translation + * + * Return: policy_mgr_con_mode enum + */ +enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( + enum tQDF_ADAPTER_MODE device_mode); + +/** + * policy_mgr_pdev_set_hw_mode() - Set HW mode command to FW + * @psoc: PSOC object information + * @session_id: Session ID + * @mac0_ss: MAC0 spatial stream configuration + * @mac0_bw: MAC0 bandwidth configuration + * @mac1_ss: MAC1 spatial stream configuration + * @mac1_bw: MAC1 bandwidth configuration + * @dbs: HW DBS capability + * @dfs: HW Agile DFS capability + * @sbs: HW SBS capability + * @reason: Reason for connection update + * + * Sends the set hw mode request to FW + * + * e.g.: To configure 2x2_80 + * mac0_ss = HW_MODE_SS_2x2, mac0_bw = HW_MODE_80_MHZ + * mac1_ss = HW_MODE_SS_0x0, mac1_bw = HW_MODE_BW_NONE + * dbs = HW_MODE_DBS_NONE, dfs = HW_MODE_AGILE_DFS_NONE, + * sbs = HW_MODE_SBS_NONE + * e.g.: To configure 1x1_80_1x1_40 (DBS) + * mac0_ss = HW_MODE_SS_1x1, mac0_bw = HW_MODE_80_MHZ + * mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ + * dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS_NONE, + * sbs = HW_MODE_SBS_NONE + * e.g.: To configure 1x1_80_1x1_40 (Agile DFS) + * mac0_ss = HW_MODE_SS_1x1, mac0_bw = HW_MODE_80_MHZ + * mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ + * dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS, + * sbs = HW_MODE_SBS_NONE + * + * Return: Success if the message made it down to the next layer + */ +QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, + enum hw_mode_ss_config mac0_ss, + enum hw_mode_bandwidth mac0_bw, + enum hw_mode_ss_config mac1_ss, + enum hw_mode_bandwidth mac1_bw, + enum hw_mode_dbs_capab dbs, + enum hw_mode_agile_dfs_capab dfs, + enum hw_mode_sbs_capab sbs, + enum policy_mgr_conn_update_reason reason); + +/** + * policy_mgr_nss_update_cback() - callback invoked by other + * component to provide nss update request status + * @psoc: PSOC object information + * @tx_status: tx completion status for updated beacon with new + * nss value + * @vdev_id: vdev id for the specific connection + * @next_action: next action to happen at policy mgr after + * beacon update + * @reason: Reason for nss update + * + * This function is the callback registered with SME at nss + * update request time + * + * Return: None + */ +typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, + uint8_t tx_status, + uint8_t vdev_id, + uint8_t next_action, + enum policy_mgr_conn_update_reason reason); + +/** + * struct policy_mgr_sme_cbacks - SME Callbacks to be invoked + * from policy manager + * @sme_get_valid_channels: Get valid channel list + * @sme_get_nss_for_vdev: Get the allowed nss value for the vdev + * @sme_soc_set_dual_mac_config: Set the dual MAC scan & FW + * config + * @sme_pdev_set_hw_mode: Set the new HW mode to FW + * @sme_pdev_set_pcl: Set new PCL to FW + * @sme_nss_update_request: Update NSS value to FW + */ +struct policy_mgr_sme_cbacks { + QDF_STATUS (*sme_get_valid_channels)(uint8_t *chan_list, + uint32_t *list_len); + void (*sme_get_nss_for_vdev)(enum tQDF_ADAPTER_MODE, + uint8_t *nss_2g, uint8_t *nss_5g); + QDF_STATUS (*sme_soc_set_dual_mac_config)( + struct policy_mgr_dual_mac_config msg); + QDF_STATUS (*sme_pdev_set_hw_mode)(struct policy_mgr_hw_mode msg); + QDF_STATUS (*sme_pdev_set_pcl)(struct policy_mgr_pcl_list msg); + QDF_STATUS (*sme_nss_update_request)(uint32_t vdev_id, + uint8_t new_nss, policy_mgr_nss_update_cback cback, + uint8_t next_action, struct wlan_objmgr_psoc *psoc, + enum policy_mgr_conn_update_reason reason); +}; + +/** + * struct policy_mgr_tdls_cbacks - TDLS Callbacks to be invoked + * from policy manager + * @set_tdls_ct_mode: Set the tdls connection tracker mode + * @check_is_tdls_allowed: check if tdls allowed or not + */ +struct policy_mgr_tdls_cbacks { + void (*set_tdls_ct_mode)(struct wlan_objmgr_psoc *psoc); + bool (*check_is_tdls_allowed)(enum tQDF_ADAPTER_MODE device_mode); +}; + +/** + * struct policy_mgr_cdp_cbacks - CDP Callbacks to be invoked + * from policy manager + * @cdp_update_mac_id: update mac_id for vdev + */ +struct policy_mgr_cdp_cbacks { + void (*cdp_update_mac_id)(struct wlan_objmgr_psoc *soc, + uint8_t vdev_id, uint8_t mac_id); +}; + +/** + * struct policy_mgr_wma_cbacks - WMA Callbacks to be invoked + * from policy manager + * @wma_get_connection_info: Get the connection related info + * from wma table + * @wma_is_service_enabled: check if certain service is enabled + * by FW + */ +struct policy_mgr_wma_cbacks { + QDF_STATUS (*wma_get_connection_info)(uint8_t vdev_id, + struct policy_mgr_vdev_entry_info *conn_table_entry); + bool (*wma_is_service_enabled)(WMI_SERVICE service_type); +}; + +/** + * policy_mgr_need_opportunistic_upgrade() - Tells us if we really + * need an upgrade to 2x2 + * @psoc: PSOC object information + * This function returns if updrade to 2x2 is needed + * + * Return: PM_NOP = upgrade is not needed, otherwise upgrade is + * needed + */ +enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_next_actions() - initiates actions needed on current + * connections once channel has been decided for the new + * connection + * @psoc: PSOC object information + * @session_id: Session id + * @action: action to be executed + * @reason: Reason for connection update + * + * This function initiates initiates actions + * needed on current connections once channel has been decided + * for the new connection. Notifies UMAC & FW as well + * + * Return: QDF_STATUS enum + */ +QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, + enum policy_mgr_conc_next_action action, + enum policy_mgr_conn_update_reason reason); + +/** + * policy_mgr_set_dual_mac_scan_config() - Set the dual MAC scan config + * @psoc: PSOC object information + * @dbs_val: Value of DBS bit + * @dbs_plus_agile_scan_val: Value of DBS plus agile scan bit + * @single_mac_scan_with_dbs_val: Value of Single MAC scan with DBS + * + * Set the values of scan config. For FW mode config, the existing values + * will be retained + * + * Return: None + */ +void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc, + uint8_t dbs_val, + uint8_t dbs_plus_agile_scan_val, + uint8_t single_mac_scan_with_dbs_val); + +/** + * policy_mgr_set_dual_mac_fw_mode_config() - Set the dual mac FW mode config + * @psoc: PSOC object information + * @dbs: DBS bit + * @dfs: Agile DFS bit + * + * Set the values of fw mode config. For scan config, the existing values + * will be retain. + * + * Return: None + */ +void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc, + uint8_t dbs, uint8_t dfs); + +/** + * policy_mgr_soc_set_dual_mac_cfg_cb() - Callback for set dual mac config + * @status: Status of set dual mac config + * @scan_config: Current scan config whose status is the first param + * @fw_mode_config: Current FW mode config whose status is the first param + * + * Callback on setting the dual mac configuration + * + * Return: None + */ +void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, + uint32_t scan_config, uint32_t fw_mode_config); + +/** + * policy_mgr_map_concurrency_mode() - to map concurrency mode + * between sme and hdd + * @old_mode: sme provided adapter mode + * @new_mode: hdd provided concurrency mode + * + * This routine will map concurrency mode between sme and hdd + * + * Return: true or false + */ +bool policy_mgr_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, + enum policy_mgr_con_mode *new_mode); + +/** + * policy_mgr_get_channel_from_scan_result() - to get channel from scan result + * @psoc: PSOC object information + * @roam_profile: pointer to roam profile + * @channel: channel to be filled + * + * This routine gets channel which most likely a candidate to which STA + * will make connection. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_channel_from_scan_result( + struct wlan_objmgr_psoc *psoc, + void *roam_profile, uint8_t *channel); + +/** + * policy_mgr_concurrent_open_sessions_running() - Checks for + * concurrent open session + * + * Checks if more than one open session is running for all the allowed modes + * in the driver + * + * Return: True if more than one open session exists, False otherwise + */ +bool policy_mgr_concurrent_open_sessions_running(void); + +/** + * policy_mgr_max_concurrent_connections_reached() - Check if + * max conccurrency is reached + * @psoc: PSOC object information + * Checks for presence of concurrency where more than one connection exists + * + * Return: True if the max concurrency is reached, False otherwise + * + * Example: + * STA + STA (wlan0 and wlan1 are connected) - returns true + * STA + STA (wlan0 connected and wlan1 disconnected) - returns false + * DUT with P2P-GO + P2P-CLIENT connection) - returns true + * + */ +bool policy_mgr_max_concurrent_connections_reached( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_clear_concurrent_session_count() - Clear active session count + * @psoc: PSOC object information + * Clears the active session count for all modes + * + * Return: None + */ +void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_is_multiple_active_sta_sessions() - Check for + * multiple STA connections + * + * Checks if multiple active STA connection are in the driver + * + * Return: True if multiple STA sessions are present, False otherwise + * + */ +bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_is_sta_active_connection_exists() - Check if a STA + * connection is active + * + * Checks if there is atleast one active STA connection in the driver + * + * Return: True if an active STA session is present, False otherwise + */ +bool policy_mgr_is_sta_active_connection_exists(void); + +/** + * policy_mgr_concurrent_beaconing_sessions_running() - Checks + * for concurrent beaconing entities + * + * Checks if multiple beaconing sessions are running i.e., if SAP or GO or IBSS + * are beaconing together + * + * Return: True if multiple entities are beaconing together, False otherwise + */ +bool policy_mgr_concurrent_beaconing_sessions_running(void); + +/** + * policy_mgr_wait_for_connection_update() - Wait for hw mode + * command to get processed + * @psoc: PSOC object information + * Waits for CONNECTION_UPDATE_TIMEOUT duration until the set hw mode + * response sets the event connection_update_done_evt + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_wait_for_connection_update( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_reset_connection_update() - Reset connection + * update event + * @psoc: PSOC object information + * Resets the concurrent connection update event + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_set_connection_update() - Set connection update + * event + * @psoc: PSOC object information + * Sets the concurrent connection update event + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_restart_opportunistic_timer() - Restarts opportunistic timer + * @psoc: PSOC object information + * @check_state: check timer state if this flag is set, else restart + * irrespective of state + * + * Restarts opportunistic timer for DBS_OPPORTUNISTIC_TIME seconds. + * Check if current state is RUNNING if check_state is set, else + * restart the timer irrespective of state. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_restart_opportunistic_timer( + struct wlan_objmgr_psoc *psoc, bool check_state); + +/** + * policy_mgr_modify_sap_pcl_based_on_mandatory_channel() - + * Modify SAPs PCL based on mandatory channel list + * @psoc: PSOC object information + * @pcl_list_org: Pointer to the preferred channel list to be trimmed + * @weight_list_org: Pointer to the weights of the preferred channel list + * @pcl_len_org: Pointer to the length of the preferred chanel list + * + * Modifies the preferred channel list of SAP based on the mandatory channel + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( + struct wlan_objmgr_psoc *psoc, uint8_t *pcl_list_org, + uint8_t *weight_list_org, uint32_t *pcl_len_org); + +/** + * policy_mgr_update_and_wait_for_connection_update() - Update and wait for + * connection update + * @psoc: PSOC object information + * @session_id: Session id + * @channel: Channel number + * @reason: Reason for connection update + * + * Update the connection to either single MAC or dual MAC and wait for the + * update to complete + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_update_and_wait_for_connection_update( + struct wlan_objmgr_psoc *psoc, uint8_t session_id, + uint8_t channel, enum policy_mgr_conn_update_reason reason); + +/** + * policy_mgr_is_sap_mandatory_channel_set() - Checks if SAP + * mandatory channel is set + * @psoc: PSOC object information + * Checks if any mandatory channel is set for SAP operation + * + * Return: True if mandatory channel is set, false otherwise + */ +bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_list_has_24GHz_channel() - Check if list contains 2.4GHz channels + * @channel_list: Channel list + * @list_len: Length of the channel list + * + * Checks if the channel list contains atleast one 2.4GHz channel + * + * Return: True if 2.4GHz channel is present, false otherwise + */ +bool policy_mgr_list_has_24GHz_channel(uint8_t *channel_list, + uint32_t list_len); + +/** + * policy_mgr_get_valid_chans() - Get the valid channel list + * @psoc: PSOC object information + * @chan_list: Pointer to the valid channel list + * @list_len: Pointer to the length of the valid channel list + * + * Gets the valid channel list filtered by band + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, + uint8_t *chan_list, uint32_t *list_len); + +/** + * policy_mgr_get_nss_for_vdev() - Get the allowed nss value for the + * vdev + * @psoc: PSOC object information + * @dev_mode: connection type. + * @nss2g: Pointer to the 2G Nss parameter. + * @nss5g: Pointer to the 5G Nss parameter. + * + * Fills the 2G and 5G Nss values based on connection type. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *nss_2g, uint8_t *nss_5g); + +/** + * policy_mgr_get_sap_mandatory_channel() - Get the mandatory channel for SAP + * @psoc: PSOC object information + * @chan: Pointer to the SAP mandatory channel + * + * Gets the mandatory channel for SAP operation + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, + uint32_t *chan); + +/** + * policy_mgr_set_sap_mandatory_channels() - Set the mandatory channel for SAP + * @psoc: PSOC object information + * @channels: Channel list to be set + * @len: Length of the channel list + * + * Sets the channels for the mandatory channel list along with the length of + * of the channel list. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, + uint8_t *channels, uint32_t len); +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * policy_mgr_register_sap_restart_channel_switch_cb() - + * Register callback for SAP channel switch without restart + * @psoc: PSOC object information + * @sap_restart_chan_switch_cb: Callback to perform channel switch + * + * Registers callback to perform channel switch without having to actually + * restart the beaconing entity + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( + struct wlan_objmgr_psoc *psoc, + void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)); + +/** + * policy_mgr_deregister_sap_restart_channel_switch_cb() - + * De-Register callback for SAP channel switch without restart + * @psoc: PSOC object information + * De Registers callback to perform channel switch + * + * Return: QDF_STATUS Enumeration + */ +QDF_STATUS policy_mgr_deregister_sap_restart_channel_switch_cb( + struct wlan_objmgr_psoc *psoc); +#endif + +/** + * policy_mgr_is_any_mode_active_on_band_along_with_session() - + * Check if any connection mode is active on a band along with + * the given session + * @psoc: PSOC object information + * @session_id: Session along which active sessions are looked for + * @band: Operating frequency band of the connection + * POLICY_MGR_BAND_24: Looks for active connection on 2.4 GHz only + * POLICY_MGR_BAND_5: Looks for active connection on 5 GHz only + * + * Checks if any of the connection mode is active on a given frequency band + * + * Return: True if any connection is active on a given band, false otherwise + */ +bool policy_mgr_is_any_mode_active_on_band_along_with_session( + struct wlan_objmgr_psoc *psoc, uint8_t session_id, + enum policy_mgr_band band); + +/** + * policy_mgr_get_mac_id_by_session_id() - Get MAC ID for a given session ID + * @psoc: PSOC object information + * @session_id: Session ID + * @mac_id: Pointer to the MAC ID + * + * Gets the MAC ID for a given session ID + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint8_t *mac_id); + +/** + * policy_mgr_get_mcc_session_id_on_mac() - Get MCC session's ID + * @psoc: PSOC object information + * @mac_id: MAC ID on which MCC session needs to be found + * @session_id: Session with which MCC combination needs to be found + * @mcc_session_id: Pointer to the MCC session ID + * + * Get the session ID of the MCC interface + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, + uint8_t mac_id, uint8_t session_id, + uint8_t *mcc_session_id); + +/** + * policy_mgr_get_mcc_operating_channel() - Get the MCC channel + * @psoc: PSOC object information + * @session_id: Session ID with which MCC is being done + * + * Gets the MCC channel for a given session ID. + * + * Return: '0' (INVALID_CHANNEL_ID) or valid channel number + */ +uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, + uint8_t session_id); + +/** + * policy_mgr_get_pcl_for_existing_conn() - Get PCL for existing connection + * @psoc: PSOC object information + * @mode: Connection mode of type 'policy_mgr_con_mode' + * @pcl_ch: Pointer to the PCL + * @len: Pointer to the length of the PCL + * @pcl_weight: Pointer to the weights of the PCL + * @weight_len: Max length of the weights list + * + * Get the PCL for an existing connection + * + * Return: None + */ +QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *pcl_ch, uint32_t *len, + uint8_t *weight_list, uint32_t weight_len); + +/** + * policy_mgr_get_valid_chan_weights() - Get the weightage for + * all valid channels + * @psoc: PSOC object information + * @weight: Pointer to the structure containing pcl, saved channel list and + * weighed channel list + * + * Provides the weightage for all valid channels. This compares the PCL list + * with the valid channel list. The channels present in the PCL get their + * corresponding weightage and the non-PCL channels get the default weightage + * of WEIGHT_OF_NON_PCL_CHANNELS. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_pcl_chan_weights *weight); + +/** + * policy_mgr_set_hw_mode_on_channel_switch() - Set hw mode + * after channel switch + * @session_id: Session ID + * + * Sets hw mode after doing a channel switch + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( + struct wlan_objmgr_psoc *psoc, uint8_t session_id); + +/** + * policy_mgr_set_do_hw_mode_change_flag() - Set flag to indicate hw mode change + * @psoc: PSOC object information + * @flag: Indicate if hw mode change is required or not + * + * Set the flag to indicate whether a hw mode change is required after a + * vdev up or not. Flag value of true indicates that a hw mode change is + * required after vdev up. + * + * Return: None + */ +void policy_mgr_set_do_hw_mode_change_flag(struct wlan_objmgr_psoc *psoc, + bool flag); + +/** + * policy_mgr_is_hw_mode_change_after_vdev_up() - Check if hw + * mode change is needed + * @psoc: PSOC object information + * Returns the flag which indicates if a hw mode change is required after + * vdev up. + * + * Return: True if hw mode change is required, false otherwise + */ +bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_checkn_update_hw_mode_single_mac_mode() - Set hw_mode to SMM + * if required + * @psoc: PSOC object information + * @channel: channel number for the new STA connection + * + * After the STA disconnection, if the hw_mode is in DBS and the new STA + * connection is coming in the band in which existing connections are + * present, then this function stops the dbs opportunistic timer and sets + * the hw_mode to Single MAC mode (SMM). + * + * Return: None + */ +void policy_mgr_checkn_update_hw_mode_single_mac_mode( + struct wlan_objmgr_psoc *psoc, uint8_t channel); + +/** + * policy_mgr_dump_connection_status_info() - Dump the concurrency information + * @psoc: PSOC object information + * Prints the concurrency information such as tx/rx spatial stream, chainmask, + * etc. + * + * Return: None + */ +void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_mode_specific_connection_count() - provides the + * count of connections of specific mode + * @psoc: PSOC object information + * @mode: type of connection + * @list: To provide the indices on pm_conc_connection_list + * (optional) + * + * This function provides the count of current connections + * + * Return: connection count of specific type + */ +uint32_t policy_mgr_mode_specific_connection_count( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t *list); + +/** + * policy_mgr_hw_mode_transition_cb() - Callback for HW mode + * transition from FW + * @old_hw_mode_index: Old HW mode index + * @new_hw_mode_index: New HW mode index + * @num_vdev_mac_entries: Number of vdev-mac id mapping that follows + * @vdev_mac_map: vdev-mac id map. This memory will be freed by the caller. + * So, make local copy if needed. + * + * Provides the old and new HW mode index set by the FW + * + * Return: None + */ +void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, + uint32_t new_hw_mode_index, + uint32_t num_vdev_mac_entries, + struct policy_mgr_vdev_mac_map *vdev_mac_map, + struct wlan_objmgr_psoc *context); + +/** + * policy_mgr_current_concurrency_is_mcc() - To check the current + * concurrency combination if it is doing MCC + * @psoc: PSOC object information + * This routine is called to check if it is doing MCC + * + * Return: True - MCC, False - Otherwise + */ +bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_register_sme_cb() - register SME callbacks + * @psoc: PSOC object information + * @sme_cbacks: function pointers from SME + * + * API, allows SME to register callbacks to be invoked by policy + * mgr + * + * Return: SUCCESS, + * Failure (if registration fails) + */ +QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_sme_cbacks *sme_cbacks); + +/** + * policy_mgr_register_tdls_cb() - register TDLS callbacks + * @psoc: PSOC object information + * @tdls_cbacks: function pointers from TDLS + * + * API, allows TDLS to register callbacks to be invoked by + * policy mgr + * + * Return: SUCCESS, + * Failure (if registration fails) + */ +QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_tdls_cbacks *tdls_cbacks); + +/** + * policy_mgr_register_cdp_cb() - register CDP callbacks + * @psoc: PSOC object information + * @cdp_cbacks: function pointers from CDP + * + * API, allows CDP to register callbacks to be invoked by + * policy mgr + * + * Return: SUCCESS, + * Failure (if registration fails) + */ +QDF_STATUS policy_mgr_register_cdp_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_cdp_cbacks *cdp_cbacks); + +/** + * policy_mgr_register_wma_cb() - register WMA callbacks + * @psoc: PSOC object information + * @wma_cbacks: function pointers from WMA + * + * API, allows WMA to register callbacks to be invoked by policy + * mgr + * + * Return: SUCCESS, + * Failure (if registration fails) + */ +QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_wma_cbacks *wma_cbacks); + +/** + * policy_mgr_is_dbs_enable() - Check if master DBS control is enabled + * @psoc: PSOC object information + * Checks if the master DBS control is enabled. This will be used + * to override any other DBS capability + * + * Return: True if master DBS control is enabled + */ +bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_is_hw_dbs_capable() - Check if HW is DBS capable + * @psoc: PSOC object information + * Checks if the HW is DBS capable + * + * Return: true if the HW is DBS capable + */ +bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_is_hw_sbs_capable() - Check if HW is SBS capable + * @psoc: PSOC object information + * Checks if the HW is SBS capable + * + * Return: true if the HW is SBS capable + */ +bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_is_current_hwmode_dbs() - Check if current hw mode is DBS + * @psoc: PSOC object information + * Checks if current hardware mode of the system is DBS or no + * + * Return: true or false + */ +bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_is_hw_dbs_2x2_capable() - if hardware is capable of dbs 2x2 + * @psoc: PSOC object information + * This function checks if hw_modes supported are always capable of + * DBS 2x2. + * true: DBS 2x2 can always be supported + * false: hw_modes support DBS 1x1 as well + * + * Return: true - DBS2x2, false - DBS1x1 + */ +bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_init() - Policy Manager component initialization + * routine + * + * Return - QDF Status + */ +QDF_STATUS policy_mgr_init(void); + +/** + * policy_mgr_deinit() - Policy Manager component + * de-initialization routine + * + * Return - QDF Status + */ +QDF_STATUS policy_mgr_deinit(void); + +/** + * policy_mgr_psoc_enable() - Policy Manager component + * enable routine + * @psoc: PSOC object information + * + * Return - QDF Status + */ +QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_psoc_disable() - Policy Manager component + * disable routine + * @psoc: PSOC object information + * + * Return - QDF Status + */ +QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_psoc_open() - Policy Manager component + * open routine + * @psoc: PSOC object information + * + * Return - QDF Status + */ +QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_psoc_close() - Policy Manager component + * close routine + * @psoc: PSOC object information + * + * Return - QDF Status + */ +QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_num_dbs_hw_modes() - Get number of HW mode + * @psoc: PSOC object information + * Fetches the number of DBS HW modes returned by the FW + * + * Return: Negative value on error or returns the number of DBS HW modes + */ +int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_dbs_hw_modes() - Get the DBS HW modes for userspace + * @psoc: PSOC object information + * @one_by_one_dbs: 1x1 DBS capability of HW + * @two_by_two_dbs: 2x2 DBS capability of HW + * + * Provides the DBS HW mode capability such as whether + * 1x1 DBS, 2x2 DBS is supported by the HW or not. + * + * Return: Failure in case of error and 0 on success + * one_by_one_dbs/two_by_two_dbs will be false, + * if they are not supported. + * one_by_one_dbs/two_by_two_dbs will be true, + * if they are supported. + * false values of one_by_one_dbs/two_by_two_dbs, + * indicate DBS is disabled + */ +QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc, + bool *one_by_one_dbs, bool *two_by_two_dbs); + +/** + * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case + * @data: Pointer to STA adapter + * + * Restarts the SAP interface in STA-AP concurrency scenario + * + * Restart: None + */ +void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data); + +/** + * policy_mgr_get_current_hw_mode() - Get current HW mode params + * @psoc: PSOC object information + * @hw_mode: HW mode parameters + * + * Provides the current HW mode parameters if the HW mode is initialized + * in the driver + * + * Return: Success if the current HW mode params are successfully populated + */ +QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_hw_mode_params *hw_mode); + +/** + * policy_mgr_get_dbs_plus_agile_scan_config() - Get DBS plus agile scan bit + * @psoc: PSOC object information + * Gets the DBS plus agile scan bit of concurrent_scan_config_bits + * + * Return: 0 or 1 to indicate the DBS plus agile scan bit + */ +bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_single_mac_scan_with_dfs_config() - Get Single + * MAC scan with DFS bit + * @psoc: PSOC object information + * Gets the Single MAC scan with DFS bit of concurrent_scan_config_bits + * + * Return: 0 or 1 to indicate the Single MAC scan with DFS bit + */ +bool policy_mgr_get_single_mac_scan_with_dfs_config( + struct wlan_objmgr_psoc *psoc); +#endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h new file mode 100644 index 000000000000..15abfb4e3e6f --- /dev/null +++ b/inc/wlan_policy_mgr_public_struct.h @@ -0,0 +1,930 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_POLICY_MGR_PUBLIC_STRUCT_H +#define __WLAN_POLICY_MGR_PUBLIC_STRUCT_H + +/** + * DOC: wlan_policy_mgr_public_struct.h + * + * Concurrenct Connection Management entity + */ + +/* Include files */ +#include "wmi_unified.h" + +#define POLICY_MGR_MAX_CHANNEL_LIST 128 + +/** + * enum hw_mode_ss_config - Possible spatial stream configuration + * @HW_MODE_SS_0x0: Unused Tx and Rx of MAC + * @HW_MODE_SS_1x1: 1 Tx SS and 1 Rx SS + * @HW_MODE_SS_2x2: 2 Tx SS and 2 Rx SS + * @HW_MODE_SS_3x3: 3 Tx SS and 3 Rx SS + * @HW_MODE_SS_4x4: 4 Tx SS and 4 Rx SS + * + * Note: Right now only 1x1 and 2x2 are being supported. Other modes should + * be added when supported. Asymmetric configuration like 1x2, 2x1 are also + * not supported now. But, they are still valid. Right now, Tx/Rx SS support is + * 4 bits long. So, we can go upto 15x15 + */ +enum hw_mode_ss_config { + HW_MODE_SS_0x0, + HW_MODE_SS_1x1, + HW_MODE_SS_2x2, + HW_MODE_SS_3x3, + HW_MODE_SS_4x4, +}; + +/** + * enum hw_mode_dbs_capab - DBS HW mode capability + * @HW_MODE_DBS_NONE: Non DBS capable + * @HW_MODE_DBS: DBS capable + */ +enum hw_mode_dbs_capab { + HW_MODE_DBS_NONE, + HW_MODE_DBS, +}; + +/** + * enum hw_mode_agile_dfs_capab - Agile DFS HW mode capability + * @HW_MODE_AGILE_DFS_NONE: Non Agile DFS capable + * @HW_MODE_AGILE_DFS: Agile DFS capable + */ +enum hw_mode_agile_dfs_capab { + HW_MODE_AGILE_DFS_NONE, + HW_MODE_AGILE_DFS, +}; + +/** + * enum hw_mode_sbs_capab - SBS HW mode capability + * @HW_MODE_SBS_NONE: Non SBS capable + * @HW_MODE_SBS: SBS capable + */ +enum hw_mode_sbs_capab { + HW_MODE_SBS_NONE, + HW_MODE_SBS, +}; + +/** + * enum policy_mgr_pcl_group_id - Identifies the pcl groups to be used + * @POLICY_MGR_PCL_GROUP_ID1_ID2: Use weights of group1 and group2 + * @POLICY_MGR_PCL_GROUP_ID2_ID3: Use weights of group2 and group3 + * @POLICY_MGR_PCL_GROUP_ID3_ID4: Use weights of group3 and group4 + * + * Since maximum of three groups are possible, this will indicate which + * PCL group needs to be used. + */ +enum policy_mgr_pcl_group_id { + POLICY_MGR_PCL_GROUP_ID1_ID2, + POLICY_MGR_PCL_GROUP_ID2_ID3, + POLICY_MGR_PCL_GROUP_ID3_ID4, +}; + +/** + * policy_mgr_pcl_channel_order - Order in which the PCL is requested + * @POLICY_MGR_PCL_ORDER_NONE: no order + * @POLICY_MGR_PCL_ORDER_24G_THEN_5G: 2.4 Ghz channel followed by 5 Ghz channel + * @POLICY_MGR_PCL_ORDER_5G_THEN_2G: 5 Ghz channel followed by 2.4 Ghz channel + * + * Order in which the PCL is requested + */ +enum policy_mgr_pcl_channel_order { + POLICY_MGR_PCL_ORDER_NONE, + POLICY_MGR_PCL_ORDER_24G_THEN_5G, + POLICY_MGR_PCL_ORDER_5G_THEN_2G, +}; + +/** + * enum policy_mgr_max_rx_ss - Maximum number of receive spatial streams + * @POLICY_MGR_RX_NSS_1: Receive Nss = 1 + * @POLICY_MGR_RX_NSS_2: Receive Nss = 2 + * @POLICY_MGR_RX_NSS_3: Receive Nss = 3 + * @POLICY_MGR_RX_NSS_4: Receive Nss = 4 + * @POLICY_MGR_RX_NSS_5: Receive Nss = 5 + * @POLICY_MGR_RX_NSS_6: Receive Nss = 6 + * @POLICY_MGR_RX_NSS_7: Receive Nss = 7 + * @POLICY_MGR_RX_NSS_8: Receive Nss = 8 + * + * Indicates the maximum number of spatial streams that the STA can receive + */ +enum policy_mgr_max_rx_ss { + POLICY_MGR_RX_NSS_1 = 0, + POLICY_MGR_RX_NSS_2 = 1, + POLICY_MGR_RX_NSS_3 = 2, + POLICY_MGR_RX_NSS_4 = 3, + POLICY_MGR_RX_NSS_5 = 4, + POLICY_MGR_RX_NSS_6 = 5, + POLICY_MGR_RX_NSS_7 = 6, + POLICY_MGR_RX_NSS_8 = 7, + POLICY_MGR_RX_NSS_MAX, +}; + +/** + * enum policy_mgr_chain_mode - Chain Mask tx & rx combination. + * + * @POLICY_MGR_ONE_ONE: One for Tx, One for Rx + * @POLICY_MGR_TWO_TWO: Two for Tx, Two for Rx + * @POLICY_MGR_MAX_NO_OF_CHAIN_MODE: Max place holder + * + * These are generic IDs that identify the various roles + * in the software system + */ +enum policy_mgr_chain_mode { + POLICY_MGR_ONE_ONE = 0, + POLICY_MGR_TWO_TWO, + POLICY_MGR_MAX_NO_OF_CHAIN_MODE +}; + +/** + * enum policy_mgr_conc_priority_mode - t/p, powersave, latency. + * + * @PM_THROUGHPUT: t/p is the priority + * @PM_POWERSAVE: powersave is the priority + * @PM_LATENCY: latency is the priority + * @PM_MAX_CONC_PRIORITY_MODE: Max place holder + * + * These are generic IDs that identify the various roles + * in the software system + */ +enum policy_mgr_conc_priority_mode { + PM_THROUGHPUT = 0, + PM_POWERSAVE, + PM_LATENCY, + PM_MAX_CONC_PRIORITY_MODE +}; + +/** + * enum policy_mgr_con_mode - concurrency mode for PCL table + * + * @PM_STA_MODE: station mode + * @PM_SAP_MODE: SAP mode + * @PM_P2P_CLIENT_MODE: P2P client mode + * @PM_P2P_GO_MODE: P2P Go mode + * @PM_IBSS_MODE: IBSS mode + * @PM_MAX_NUM_OF_MODE: max value place holder + */ +enum policy_mgr_con_mode { + PM_STA_MODE = 0, + PM_SAP_MODE, + PM_P2P_CLIENT_MODE, + PM_P2P_GO_MODE, + PM_IBSS_MODE, + PM_MAX_NUM_OF_MODE +}; + +/** + * enum policy_mgr_mac_use - MACs that are used + * @POLICY_MGR_MAC0: Only MAC0 is used + * @POLICY_MGR_MAC1: Only MAC1 is used + * @POLICY_MGR_MAC0_AND_MAC1: Both MAC0 and MAC1 are used + */ +enum policy_mgr_mac_use { + POLICY_MGR_MAC0 = 1, + POLICY_MGR_MAC1 = 2, + POLICY_MGR_MAC0_AND_MAC1 = 3 +}; + +/** + * enum policy_mgr_pcl_type - Various types of Preferred channel list (PCL). + * + * @PM_NONE: No channel preference + * @PM_24G: 2.4 Ghz channels only + * @PM_5G: 5 Ghz channels only + * @PM_SCC_CH: SCC channel only + * @PM_MCC_CH: MCC channels only + * @PM_SBS_CH: SBS channels only + * @PM_SCC_CH_24G: SCC channel & 2.4 Ghz channels + * @PM_SCC_CH_5G: SCC channel & 5 Ghz channels + * @PM_24G_SCC_CH: 2.4 Ghz channels & SCC channel + * @PM_5G_SCC_CH: 5 Ghz channels & SCC channel + * @PM_SCC_ON_5_SCC_ON_24_24G: SCC channel on 5 Ghz, SCC + * channel on 2.4 Ghz & 2.4 Ghz channels + * @PM_SCC_ON_5_SCC_ON_24_5G: SCC channel on 5 Ghz, SCC channel + * on 2.4 Ghz & 5 Ghz channels + * @PM_SCC_ON_24_SCC_ON_5_24G: SCC channel on 2.4 Ghz, SCC + * channel on 5 Ghz & 2.4 Ghz channels + * @PM_SCC_ON_24_SCC_ON_5_5G: SCC channel on 2.4 Ghz, SCC + * channel on 5 Ghz & 5 Ghz channels + * @PM_SCC_ON_5_SCC_ON_24: SCC channel on 5 Ghz, SCC channel on + * 2.4 Ghz + * @PM_SCC_ON_24_SCC_ON_5: SCC channel on 2.4 Ghz, SCC channel + * on 5 Ghz + * @PM_MCC_CH_24G: MCC channels & 2.4 Ghz channels + * @PM_MCC_CH_5G: MCC channels & 5 Ghz channels + * @PM_24G_MCC_CH: 2.4 Ghz channels & MCC channels + * @PM_5G_MCC_CH: 5 Ghz channels & MCC channels + * @PM_SBS_CH_5G: SBS channels & rest of 5 Ghz channels + * @PM_24G_SCC_CH_SBS_CH: 2.4 Ghz channels, SCC channel & SBS channels + * @PM_24G_SCC_CH_SBS_CH_5G: 2.4 Ghz channels, SCC channel, + * SBS channels & rest of the 5G channels + * @PM_24G_SBS_CH_MCC_CH: 2.4 Ghz channels, SBS channels & MCC channels + * @PM_MAX_PCL_TYPE: Max place holder + * + * These are generic IDs that identify the various roles + * in the software system + */ +enum policy_mgr_pcl_type { + PM_NONE = 0, + PM_24G, + PM_5G, + PM_SCC_CH, + PM_MCC_CH, + PM_SBS_CH, + PM_SCC_CH_24G, + PM_SCC_CH_5G, + PM_24G_SCC_CH, + PM_5G_SCC_CH, + PM_SCC_ON_5_SCC_ON_24_24G, + PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_24_SCC_ON_5_24G, + PM_SCC_ON_24_SCC_ON_5_5G, + PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_24_SCC_ON_5, + PM_MCC_CH_24G, + PM_MCC_CH_5G, + PM_24G_MCC_CH, + PM_5G_MCC_CH, + PM_SBS_CH_5G, + PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH_5G, + PM_24G_SBS_CH_MCC_CH, + + PM_MAX_PCL_TYPE +}; + +/** + * enum policy_mgr_one_connection_mode - Combination of first connection + * type, band & spatial stream used. + * + * @PM_STA_24_1x1: STA connection using 1x1@2.4 Ghz + * @PM_STA_24_2x2: STA connection using 2x2@2.4 Ghz + * @PM_STA_5_1x1: STA connection using 1x1@5 Ghz + * @PM_STA_5_2x2: STA connection using 2x2@5 Ghz + * @PM_P2P_CLI_24_1x1: P2P Client connection using 1x1@2.4 Ghz + * @PM_P2P_CLI_24_2x2: P2P Client connection using 2x2@2.4 Ghz + * @PM_P2P_CLI_5_1x1: P2P Client connection using 1x1@5 Ghz + * @PM_P2P_CLI_5_2x2: P2P Client connection using 2x2@5 Ghz + * @PM_P2P_GO_24_1x1: P2P GO connection using 1x1@2.4 Ghz + * @PM_P2P_GO_24_2x2: P2P GO connection using 2x2@2.4 Ghz + * @PM_P2P_GO_5_1x1: P2P GO connection using 1x1@5 Ghz + * @PM_P2P_GO_5_2x2: P2P GO connection using 2x2@5 Ghz + * @PM_SAP_24_1x1: SAP connection using 1x1@2.4 Ghz + * @PM_SAP_24_2x2: SAP connection using 2x2@2.4 Ghz + * @PM_SAP_5_1x1: SAP connection using 1x1@5 Ghz + * @PM_SAP_5_1x1: SAP connection using 2x2@5 Ghz + * @PM_IBSS_24_1x1: IBSS connection using 1x1@2.4 Ghz + * @PM_IBSS_24_2x2: IBSS connection using 2x2@2.4 Ghz + * @PM_IBSS_5_1x1: IBSS connection using 1x1@5 Ghz + * @PM_IBSS_5_2x2: IBSS connection using 2x2@5 Ghz + * @PM_MAX_ONE_CONNECTION_MODE: Max place holder + * + * These are generic IDs that identify the various roles + * in the software system + */ +enum policy_mgr_one_connection_mode { + PM_STA_24_1x1 = 0, + PM_STA_24_2x2, + PM_STA_5_1x1, + PM_STA_5_2x2, + PM_P2P_CLI_24_1x1, + PM_P2P_CLI_24_2x2, + PM_P2P_CLI_5_1x1, + PM_P2P_CLI_5_2x2, + PM_P2P_GO_24_1x1, + PM_P2P_GO_24_2x2, + PM_P2P_GO_5_1x1, + PM_P2P_GO_5_2x2, + PM_SAP_24_1x1, + PM_SAP_24_2x2, + PM_SAP_5_1x1, + PM_SAP_5_2x2, + PM_IBSS_24_1x1, + PM_IBSS_24_2x2, + PM_IBSS_5_1x1, + PM_IBSS_5_2x2, + + PM_MAX_ONE_CONNECTION_MODE +}; + +/** + * enum policy_mgr_two_connection_mode - Combination of first two + * connections type, concurrency state, band & spatial stream + * used. + * + * @PM_STA_SAP_SCC_24_1x1: STA & SAP connection on SCC using + * 1x1@2.4 Ghz + * @PM_STA_SAP_SCC_24_2x2: STA & SAP connection on SCC using + * 2x2@2.4 Ghz + * @PM_STA_SAP_MCC_24_1x1: STA & SAP connection on MCC using + * 1x1@2.4 Ghz + * @PM_STA_SAP_MCC_24_2x2: STA & SAP connection on MCC using + * 2x2@2.4 Ghz + * @PM_STA_SAP_SCC_5_1x1: STA & SAP connection on SCC using + * 1x1@5 Ghz + * @PM_STA_SAP_SCC_5_2x2: STA & SAP connection on SCC using + * 2x2@5 Ghz + * @PM_STA_SAP_MCC_5_1x1: STA & SAP connection on MCC using + * 1x1@5 Ghz + * @PM_STA_SAP_MCC_5_2x2: STA & SAP connection on MCC using + * 2x2@5 Ghz + * @PM_STA_SAP_DBS_1x1: STA & SAP connection on DBS using 1x1 + * @PM_STA_SAP_DBS_2x2: STA & SAP connection on DBS using 2x2 + * @PM_STA_SAP_SBS_5_1x1: STA & SAP connection on 5G SBS using 1x1 + * @PM_STA_P2P_GO_SCC_24_1x1: STA & P2P GO connection on SCC + * using 1x1@2.4 Ghz + * @PM_STA_P2P_GO_SCC_24_2x2: STA & P2P GO connection on SCC + * using 2x2@2.4 Ghz + * @PM_STA_P2P_GO_MCC_24_1x1: STA & P2P GO connection on MCC + * using 1x1@2.4 Ghz + * @PM_STA_P2P_GO_MCC_24_2x2: STA & P2P GO connection on MCC + * using 2x2@2.4 Ghz + * @PM_STA_P2P_GO_SCC_5_1x1: STA & P2P GO connection on SCC + * using 1x1@5 Ghz + * @PM_STA_P2P_GO_SCC_5_2x2: STA & P2P GO connection on SCC + * using 2x2@5 Ghz + * @PM_STA_P2P_GO_MCC_5_1x1: STA & P2P GO connection on MCC + * using 1x1@5 Ghz + * @PM_STA_P2P_GO_MCC_5_2x2: STA & P2P GO connection on MCC + * using 2x2@5 Ghz + * @PM_STA_P2P_GO_DBS_1x1: STA & P2P GO connection on DBS using + * 1x1 + * @PM_STA_P2P_GO_DBS_2x2: STA & P2P GO connection on DBS using + * 2x2 + * @PM_STA_P2P_GO_SBS_5_1x1: STA & P2P GO connection on 5G SBS + * using 1x1 + * @PM_STA_P2P_CLI_SCC_24_1x1: STA & P2P CLI connection on SCC + * using 1x1@2.4 Ghz + * @PM_STA_P2P_CLI_SCC_24_2x2: STA & P2P CLI connection on SCC + * using 2x2@2.4 Ghz + * @PM_STA_P2P_CLI_MCC_24_1x1: STA & P2P CLI connection on MCC + * using 1x1@2.4 Ghz + * @PM_STA_P2P_CLI_MCC_24_2x2: STA & P2P CLI connection on MCC + * using 2x2@2.4 Ghz + * @PM_STA_P2P_CLI_SCC_5_1x1: STA & P2P CLI connection on SCC + * using 1x1@5 Ghz + * @PM_STA_P2P_CLI_SCC_5_2x2: STA & P2P CLI connection on SCC + * using 2x2@5 Ghz + * @PM_STA_P2P_CLI_MCC_5_1x1: STA & P2P CLI connection on MCC + * using 1x1@5 Ghz + * @PM_STA_P2P_CLI_MCC_5_2x2: STA & P2P CLI connection on MCC + * using 2x2@5 Ghz + * @PM_STA_P2P_CLI_DBS_1x1: STA & P2P CLI connection on DBS + * using 1x1 + * @PM_STA_P2P_CLI_DBS_2x2: STA & P2P CLI connection on DBS + * using 2x2 + * @PM_STA_P2P_CLI_SBS_5_1x1: STA & P2P CLI connection on 5G + * SBS using 1x1 + * @PM_P2P_GO_P2P_CLI_SCC_24_1x1: P2P GO & CLI connection on + * SCC using 1x1@2.4 Ghz + * @PM_P2P_GO_P2P_CLI_SCC_24_2x2: P2P GO & CLI connection on + * SCC using 2x2@2.4 Ghz + * @PM_P2P_GO_P2P_CLI_MCC_24_1x1: P2P GO & CLI connection on + * MCC using 1x1@2.4 Ghz + * @PM_P2P_GO_P2P_CLI_MCC_24_2x2: P2P GO & CLI connection on + * MCC using 2x2@2.4 Ghz + * @PM_P2P_GO_P2P_CLI_SCC_5_1x1: P2P GO & CLI connection on + * SCC using 1x1@5 Ghz + * @PM_P2P_GO_P2P_CLI_SCC_5_2x2: P2P GO & CLI connection on + * SCC using 2x2@5 Ghz + * @PM_P2P_GO_P2P_CLI_MCC_5_1x1: P2P GO & CLI connection on + * MCC using 1x1@5 Ghz + * @PM_P2P_GO_P2P_CLI_MCC_5_2x2: P2P GO & CLI connection on + * MCC using 2x2@5 Ghz + * @PM_P2P_GO_P2P_CLI_DBS_1x1: P2P GO & CLI connection on DBS + * using 1x1 + * @PM_P2P_GO_P2P_CLI_DBS_2x2: P2P GO & P2P CLI connection + * on DBS using 2x2 + * @PM_P2P_GO_P2P_CLI_SBS_5_1x1: P2P GO & P2P CLI connection + * on 5G SBS using 1x1 + * @PM_P2P_GO_SAP_SCC_24_1x1: P2P GO & SAP connection on + * SCC using 1x1@2.4 Ghz + * @PM_P2P_GO_SAP_SCC_24_2x2: P2P GO & SAP connection on + * SCC using 2x2@2.4 Ghz + * @PM_P2P_GO_SAP_MCC_24_1x1: P2P GO & SAP connection on + * MCC using 1x1@2.4 Ghz + * @PM_P2P_GO_SAP_MCC_24_2x2: P2P GO & SAP connection on + * MCC using 2x2@2.4 Ghz + * @PM_P2P_GO_SAP_SCC_5_1x1: P2P GO & SAP connection on + * SCC using 1x1@5 Ghz + * @PM_P2P_GO_SAP_SCC_5_2x2: P2P GO & SAP connection on + * SCC using 2x2@5 Ghz + * @PM_P2P_GO_SAP_MCC_5_1x1: P2P GO & SAP connection on + * MCC using 1x1@5 Ghz + * @PM_P2P_GO_SAP_MCC_5_2x2: P2P GO & SAP connection on + * MCC using 2x2@5 Ghz + * @PM_P2P_GO_SAP_DBS_1x1: P2P GO & SAP connection on DBS using + * 1x1 + * @PM_P2P_GO_SAP_DBS_2x2: P2P GO & SAP connection on DBS using + * 2x2 + * @PM_P2P_GO_SAP_SBS_5_1x1: P2P GO & SAP connection on 5G SBS + * using 1x1 + * @PM_P2P_CLI_SAP_SCC_24_1x1: CLI & SAP connection on SCC using + * 1x1@2.4 Ghz + * @PM_P2P_CLI_SAP_SCC_24_2x2: CLI & SAP connection on SCC using + * 2x2@2.4 Ghz + * @PM_P2P_CLI_SAP_MCC_24_1x1: CLI & SAP connection on MCC using + * 1x1@2.4 Ghz + * @PM_P2P_CLI_SAP_MCC_24_2x2: CLI & SAP connection on MCC using + * 2x2@2.4 Ghz + * @PM_P2P_CLI_SAP_SCC_5_1x1: CLI & SAP connection on SCC using + * 1x1@5 Ghz + * @PM_P2P_CLI_SAP_SCC_5_2x2: CLI & SAP connection on SCC using + * 2x2@5 Ghz + * @PM_P2P_CLI_SAP_MCC_5_1x1: CLI & SAP connection on MCC using + * 1x1@5 Ghz + * @PM_P2P_CLI_SAP_MCC_5_2x2: CLI & SAP connection on MCC using + * 2x2@5 Ghz + * @POLICY_MGR_P2P_STA_SAP_MCC_24_5_1x1: CLI and SAP connecting on MCC + * in 2.4 and 5GHz 1x1 + * @POLICY_MGR_P2P_STA_SAP_MCC_24_5_2x2: CLI and SAP connecting on MCC + * in 2.4 and 5GHz 2x2 + * @PM_P2P_CLI_SAP_DBS_1x1,: CLI & SAP connection on DBS using 1x1 + * @PM_P2P_CLI_SAP_DBS_2x2: P2P CLI & SAP connection on DBS using + * 2x2 + * @PM_P2P_CLI_SAP_SBS_5_1x1: P2P CLI & SAP connection on 5G SBS + * using 1x1 + * @PM_SAP_SAP_SCC_24_1x1: SAP & SAP connection on + * SCC using 1x1@2.4 Ghz + * @PM_SAP_SAP_SCC_24_2x2: SAP & SAP connection on + * SCC using 2x2@2.4 Ghz + * @PM_SAP_SAP_MCC_24_1x1: SAP & SAP connection on + * MCC using 1x1@2.4 Ghz + * @PM_SAP_SAP_MCC_24_2x2: SAP & SAP connection on + * MCC using 2x2@2.4 Ghz + * @PM_SAP_SAP_SCC_5_1x1: SAP & SAP connection on + * SCC using 1x1@5 Ghz + * @PM_SAP_SAP_SCC_5_2x2: SAP & SAP connection on + * SCC using 2x2@5 Ghz + * @PM_SAP_SAP_MCC_5_1x1: SAP & SAP connection on + * MCC using 1x1@5 Ghz + * @PM_SAP_SAP_MCC_5_2x2: SAP & SAP connection on + * MCC using 2x2@5 Ghz + * @PM_SAP_SAP_MCC_24_5_1x1: SAP & SAP connection on + * MCC in 2.4 and 5GHz 1x1 + * @PM_SAP_SAP_MCC_24_5_2x2: SAP & SAP connection on + * MCC in 2.4 and 5GHz 2x2 + * @PM_SAP_SAP_DBS_1x1: SAP & SAP connection on DBS using + * 1x1 + * @PM_SAP_SAP_DBS_2x2: SAP & SAP connection on DBS using 2x2 + * @PM_SAP_SAP_SBS_5_1x1: SAP & SAP connection on 5G SBS using 1x1 + * @PM_STA_STA_SCC_24_1x1: STA & STA connection on + * SCC using 1x1@2.4 Ghz + * @PM_STA_STA_SCC_24_2x2: STA & STA connection on + * SCC using 2x2@2.4 Ghz + * @PM_STA_STA_MCC_24_1x1: STA & STA connection on + * MCC using 1x1@2.4 Ghz + * @PM_STA_STA_MCC_24_2x2: STA & STA connection on + * MCC using 2x2@2.4 Ghz + * @PM_STA_STA_SCC_5_1x1: STA & STA connection on + * SCC using 1x1@5 Ghz + * @PM_STA_STA_SCC_5_2x2: STA & STA connection on + * SCC using 2x2@5 Ghz + * @PM_STA_STA_MCC_5_1x1: STA & STA connection on + * MCC using 1x1@5 Ghz + * @PM_STA_STA_MCC_5_2x2: STA & STA connection on + * MCC using 2x2@5 Ghz + * @PM_STA_STA_MCC_24_5_1x1: STA & STA connection on + * MCC in 2.4 and 5GHz 1x1 + * @PM_STA_STA_MCC_24_5_2x2: STA & STA connection on + * MCC in 2.4 and 5GHz 2x2 + * @PM_STA_STA_DBS_1x1: STA & STA connection on DBS using + * 1x1 + * @PM_STA_STA_DBS_2x2: STA & STA connection on DBS using 2x2 + * @PM_STA_STA_SBS_5_1x1: STA & STA connection on 5G SBS using 1x1 + * + * These are generic IDs that identify the various roles in the + * software system + */ +enum policy_mgr_two_connection_mode { + PM_STA_SAP_SCC_24_1x1 = 0, + PM_STA_SAP_SCC_24_2x2, + PM_STA_SAP_MCC_24_1x1, + PM_STA_SAP_MCC_24_2x2, + PM_STA_SAP_SCC_5_1x1, + PM_STA_SAP_SCC_5_2x2, + PM_STA_SAP_MCC_5_1x1, + PM_STA_SAP_MCC_5_2x2, + PM_STA_SAP_MCC_24_5_1x1, + PM_STA_SAP_MCC_24_5_2x2, + PM_STA_SAP_DBS_1x1, + PM_STA_SAP_DBS_2x2, + PM_STA_SAP_SBS_5_1x1, + PM_STA_P2P_GO_SCC_24_1x1, + PM_STA_P2P_GO_SCC_24_2x2, + PM_STA_P2P_GO_MCC_24_1x1, + PM_STA_P2P_GO_MCC_24_2x2, + PM_STA_P2P_GO_SCC_5_1x1, + PM_STA_P2P_GO_SCC_5_2x2, + PM_STA_P2P_GO_MCC_5_1x1, + PM_STA_P2P_GO_MCC_5_2x2, + PM_STA_P2P_GO_MCC_24_5_1x1, + PM_STA_P2P_GO_MCC_24_5_2x2, + PM_STA_P2P_GO_DBS_1x1, + PM_STA_P2P_GO_DBS_2x2, + PM_STA_P2P_GO_SBS_5_1x1, + PM_STA_P2P_CLI_SCC_24_1x1, + PM_STA_P2P_CLI_SCC_24_2x2, + PM_STA_P2P_CLI_MCC_24_1x1, + PM_STA_P2P_CLI_MCC_24_2x2, + PM_STA_P2P_CLI_SCC_5_1x1, + PM_STA_P2P_CLI_SCC_5_2x2, + PM_STA_P2P_CLI_MCC_5_1x1, + PM_STA_P2P_CLI_MCC_5_2x2, + PM_STA_P2P_CLI_MCC_24_5_1x1, + PM_STA_P2P_CLI_MCC_24_5_2x2, + PM_STA_P2P_CLI_DBS_1x1, + PM_STA_P2P_CLI_DBS_2x2, + PM_STA_P2P_CLI_SBS_5_1x1, + PM_P2P_GO_P2P_CLI_SCC_24_1x1, + PM_P2P_GO_P2P_CLI_SCC_24_2x2, + PM_P2P_GO_P2P_CLI_MCC_24_1x1, + PM_P2P_GO_P2P_CLI_MCC_24_2x2, + PM_P2P_GO_P2P_CLI_SCC_5_1x1, + PM_P2P_GO_P2P_CLI_SCC_5_2x2, + PM_P2P_GO_P2P_CLI_MCC_5_1x1, + PM_P2P_GO_P2P_CLI_MCC_5_2x2, + PM_P2P_GO_P2P_CLI_MCC_24_5_1x1, + PM_P2P_GO_P2P_CLI_MCC_24_5_2x2, + PM_P2P_GO_P2P_CLI_DBS_1x1, + PM_P2P_GO_P2P_CLI_DBS_2x2, + PM_P2P_GO_P2P_CLI_SBS_5_1x1, + PM_P2P_GO_SAP_SCC_24_1x1, + PM_P2P_GO_SAP_SCC_24_2x2, + PM_P2P_GO_SAP_MCC_24_1x1, + PM_P2P_GO_SAP_MCC_24_2x2, + PM_P2P_GO_SAP_SCC_5_1x1, + PM_P2P_GO_SAP_SCC_5_2x2, + PM_P2P_GO_SAP_MCC_5_1x1, + PM_P2P_GO_SAP_MCC_5_2x2, + PM_P2P_GO_SAP_MCC_24_5_1x1, + PM_P2P_GO_SAP_MCC_24_5_2x2, + PM_P2P_GO_SAP_DBS_1x1, + PM_P2P_GO_SAP_DBS_2x2, + PM_P2P_GO_SAP_SBS_5_1x1, + PM_P2P_CLI_SAP_SCC_24_1x1, + PM_P2P_CLI_SAP_SCC_24_2x2, + PM_P2P_CLI_SAP_MCC_24_1x1, + PM_P2P_CLI_SAP_MCC_24_2x2, + PM_P2P_CLI_SAP_SCC_5_1x1, + PM_P2P_CLI_SAP_SCC_5_2x2, + PM_P2P_CLI_SAP_MCC_5_1x1, + PM_P2P_CLI_SAP_MCC_5_2x2, + PM_P2P_CLI_SAP_MCC_24_5_1x1, + PM_P2P_CLI_SAP_MCC_24_5_2x2, + PM_P2P_CLI_SAP_DBS_1x1, + PM_P2P_CLI_SAP_DBS_2x2, + PM_P2P_CLI_SAP_SBS_5_1x1, + PM_SAP_SAP_SCC_24_1x1, + PM_SAP_SAP_SCC_24_2x2, + PM_SAP_SAP_MCC_24_1x1, + PM_SAP_SAP_MCC_24_2x2, + PM_SAP_SAP_SCC_5_1x1, + PM_SAP_SAP_SCC_5_2x2, + PM_SAP_SAP_MCC_5_1x1, + PM_SAP_SAP_MCC_5_2x2, + PM_SAP_SAP_MCC_24_5_1x1, + PM_SAP_SAP_MCC_24_5_2x2, + PM_SAP_SAP_DBS_1x1, + PM_SAP_SAP_DBS_2x2, + PM_SAP_SAP_SBS_5_1x1, + PM_STA_STA_SCC_24_1x1, + PM_STA_STA_SCC_24_2x2, + PM_STA_STA_MCC_24_1x1, + PM_STA_STA_MCC_24_2x2, + PM_STA_STA_SCC_5_1x1, + PM_STA_STA_SCC_5_2x2, + PM_STA_STA_MCC_5_1x1, + PM_STA_STA_MCC_5_2x2, + PM_STA_STA_MCC_24_5_1x1, + PM_STA_STA_MCC_24_5_2x2, + PM_STA_STA_DBS_1x1, + PM_STA_STA_DBS_2x2, + PM_STA_STA_SBS_5_1x1, + + PM_MAX_TWO_CONNECTION_MODE +}; + +/** + * enum policy_mgr_conc_next_action - actions to be taken on old + * connections. + * + * @PM_NOP: No action + * @PM_DBS: switch to DBS mode + * @PM_DBS_DOWNGRADE: switch to DBS mode & downgrade to 1x1 + * @PM_DBS_UPGRADE: switch to DBS mode & upgrade to 2x2 + * @PM_SINGLE_MAC: switch to MCC/SCC mode + * @PM_SINGLE_MAC_UPGRADE: switch to MCC/SCC mode & upgrade to 2x2 + * @PM_SBS: switch to SBS mode + * @PM_SBS_DOWNGRADE: switch to SBS mode & downgrade to 1x1 + * @PM_MAX_CONC_PRIORITY_MODE: Max place holder + * + * These are generic IDs that identify the various roles + * in the software system + */ +enum policy_mgr_conc_next_action { + PM_NOP = 0, + PM_DBS, + PM_DBS_DOWNGRADE, + PM_DBS_UPGRADE, + PM_SINGLE_MAC, + PM_SINGLE_MAC_UPGRADE, + PM_SBS, + PM_SBS_DOWNGRADE, + + PM_MAX_CONC_NEXT_ACTION +}; + +/** + * enum policy_mgr_band - wifi band. + * + * @POLICY_MGR_BAND_24: 2.4 Ghz band + * @POLICY_MGR_BAND_5: 5 Ghz band + * @POLICY_MGR_MAX_BAND: Max place holder + * + * These are generic IDs that identify the various roles + * in the software system + */ +enum policy_mgr_band { + POLICY_MGR_BAND_24 = 0, + POLICY_MGR_BAND_5, + POLICY_MGR_MAX_BAND +}; + +/** + * enum policy_mgr_conn_update_reason: Reason for conc connection update + * @POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN: Set probable operating channel + * @POLICY_MGR_UPDATE_REASON_JOIN_IBSS: Join IBSS + * @POLICY_MGR_UPDATE_REASON_UT: Unit test related + * @POLICY_MGR_UPDATE_REASON_START_AP: Start AP + * @POLICY_MGR_UPDATE_REASON_NORMAL_STA: Connection to Normal STA + * @POLICY_MGR_UPDATE_REASON_HIDDEN_STA: Connection to Hidden STA + * @POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC: Opportunistic HW mode update + * @POLICY_MGR_UPDATE_REASON_NSS_UPDATE: NSS update + * @POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH: Channel switch + * @POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA: Channel switch for STA + */ +enum policy_mgr_conn_update_reason { + POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN, + POLICY_MGR_UPDATE_REASON_JOIN_IBSS, + POLICY_MGR_UPDATE_REASON_UT, + POLICY_MGR_UPDATE_REASON_START_AP, + POLICY_MGR_UPDATE_REASON_NORMAL_STA, + POLICY_MGR_UPDATE_REASON_HIDDEN_STA, + POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC, + POLICY_MGR_UPDATE_REASON_NSS_UPDATE, + POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH, + POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA, + POLICY_MGR_UPDATE_REASON_PRE_CAC, +}; + +/** + * enum hw_mode_bandwidth - bandwidth of wifi channel. + * + * @HW_MODE_5_MHZ: 5 Mhz bandwidth + * @HW_MODE_10_MHZ: 10 Mhz bandwidth + * @HW_MODE_20_MHZ: 20 Mhz bandwidth + * @HW_MODE_40_MHZ: 40 Mhz bandwidth + * @HW_MODE_80_MHZ: 80 Mhz bandwidth + * @HW_MODE_80_PLUS_80_MHZ: 80 Mhz plus 80 Mhz bandwidth + * @HW_MODE_160_MHZ: 160 Mhz bandwidth + * @HW_MODE_MAX_BANDWIDTH: Max place holder + * + * These are generic IDs that identify the various roles + * in the software system + */ +enum hw_mode_bandwidth { + HW_MODE_BW_NONE, + HW_MODE_5_MHZ, + HW_MODE_10_MHZ, + HW_MODE_20_MHZ, + HW_MODE_40_MHZ, + HW_MODE_80_MHZ, + HW_MODE_80_PLUS_80_MHZ, + HW_MODE_160_MHZ, + HW_MODE_MAX_BANDWIDTH +}; + +/** + * enum set_hw_mode_status - Status of set HW mode command + * @SET_HW_MODE_STATUS_OK: command successful + * @SET_HW_MODE_STATUS_EINVAL: Requested invalid hw_mode + * @SET_HW_MODE_STATUS_ECANCELED: HW mode change cancelled + * @SET_HW_MODE_STATUS_ENOTSUP: HW mode not supported + * @SET_HW_MODE_STATUS_EHARDWARE: HW mode change prevented by hardware + * @SET_HW_MODE_STATUS_EPENDING: HW mode change is pending + * @SET_HW_MODE_STATUS_ECOEX: HW mode change conflict with Coex + */ +enum set_hw_mode_status { + SET_HW_MODE_STATUS_OK, + SET_HW_MODE_STATUS_EINVAL, + SET_HW_MODE_STATUS_ECANCELED, + SET_HW_MODE_STATUS_ENOTSUP, + SET_HW_MODE_STATUS_EHARDWARE, + SET_HW_MODE_STATUS_EPENDING, + SET_HW_MODE_STATUS_ECOEX, +}; + +/** + * struct policy_mgr_conc_connection_info - information of all existing + * connections in the wlan system + * + * @mode: connection type + * @chan: channel of the connection + * @bw: channel bandwidth used for the connection + * @mac: The HW mac it is running + * @chain_mask: The original capability advertised by HW + * @original_nss: nss negotiated at connection time + * @vdev_id: vdev id of the connection + * @in_use: if the table entry is active + */ +struct policy_mgr_conc_connection_info { + enum policy_mgr_con_mode mode; + uint8_t chan; + enum hw_mode_bandwidth bw; + uint8_t mac; + enum policy_mgr_chain_mode chain_mask; + uint32_t original_nss; + uint32_t vdev_id; + bool in_use; +}; + +/** + * struct policy_mgr_hw_mode_params - HW mode params + * @mac0_tx_ss: MAC0 Tx spatial stream + * @mac0_rx_ss: MAC0 Rx spatial stream + * @mac1_tx_ss: MAC1 Tx spatial stream + * @mac1_rx_ss: MAC1 Rx spatial stream + * @mac0_bw: MAC0 bandwidth + * @mac1_bw: MAC1 bandwidth + * @dbs_cap: DBS capabality + * @agile_dfs_cap: Agile DFS capabality + */ +struct policy_mgr_hw_mode_params { + uint8_t mac0_tx_ss; + uint8_t mac0_rx_ss; + uint8_t mac1_tx_ss; + uint8_t mac1_rx_ss; + uint8_t mac0_bw; + uint8_t mac1_bw; + uint8_t dbs_cap; + uint8_t agile_dfs_cap; + uint8_t sbs_cap; +}; + +/** + * struct policy_mgr_vdev_mac_map - vdev id-mac id map + * @vdev_id: VDEV id + * @mac_id: MAC id + */ +struct policy_mgr_vdev_mac_map { + uint32_t vdev_id; + uint32_t mac_id; +}; + +/** + * struct policy_mgr_dual_mac_config - Dual MAC configuration + * @scan_config: Scan configuration + * @fw_mode_config: FW mode configuration + * @set_dual_mac_cb: Callback function to be executed on response to the command + */ +struct policy_mgr_dual_mac_config { + uint32_t scan_config; + uint32_t fw_mode_config; + void *set_dual_mac_cb; +}; + +/** + * struct policy_mgr_hw_mode - Format of set HW mode + * @hw_mode_index: Index of HW mode to be set + * @set_hw_mode_cb: HDD set HW mode callback + * @reason: Reason for HW mode change + * @session_id: Session id + */ +struct policy_mgr_hw_mode { + uint32_t hw_mode_index; + void *set_hw_mode_cb; + enum policy_mgr_conn_update_reason reason; + uint32_t session_id; +}; + +/** + * struct policy_mgr_pcl_list - Format of PCL + * @pcl_list: List of preferred channels + * @weight_list: Weights of the PCL + * @pcl_len: Number of channels in the PCL + */ +struct policy_mgr_pcl_list { + uint8_t pcl_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint8_t weight_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint32_t pcl_len; +}; + +/** + * struct policy_mgr_pcl_chan_weights - Params to get the valid weighed list + * @pcl_list: Preferred channel list already sorted in the order of preference + * @pcl_len: Length of the PCL + * @saved_chan_list: Valid channel list updated as part of + * WMA_UPDATE_CHAN_LIST_REQ + * @saved_num_chan: Length of the valid channel list + * @weighed_valid_list: Weights of the valid channel list. This will have one + * to one mapping with valid_chan_list. FW expects channel order and size to be + * as per the list provided in WMI_SCAN_CHAN_LIST_CMDID. + * @weight_list: Weights assigned by policy manager + */ +struct policy_mgr_pcl_chan_weights { + uint8_t pcl_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint32_t pcl_len; + uint8_t saved_chan_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint32_t saved_num_chan; + uint8_t weighed_valid_list[POLICY_MGR_MAX_CHANNEL_LIST]; + uint8_t weight_list[POLICY_MGR_MAX_CHANNEL_LIST]; +}; + +/** + * struct policy_mgr_vdev_entry_info - vdev related param to be + * used by policy manager + * @type: type + * @sub_type: sub type + * @mhz: channel frequency in MHz + * @chan_width: channel bandwidth + * @mac_id: the mac on which vdev is on + */ +struct policy_mgr_vdev_entry_info { + uint32_t type; + uint32_t sub_type; + uint32_t mhz; + uint32_t chan_width; + uint32_t mac_id; +}; + +/** + * struct dbs_hw_mode_info - WLAN_DBS_HW_MODES_TLV Format + * @tlv_header: TLV header, TLV tag and len; tag equals WMITLV_TAG_ARRAY_UINT32 + * @hw_mode_list: WLAN_DBS_HW_MODE_LIST entries + */ +struct dbs_hw_mode_info { + uint32_t tlv_header; + uint32_t *hw_mode_list; +}; + +/** + * struct extended_caps - new extended caps given by firmware + * @num_hw_modes: number of hardware modes for current SOC + * @each_hw_mode_cap: hw mode id to phy id mapping + * @each_phy_cap_per_hwmode: PHY's caps for each hw mode + * @num_phy_for_hal_reg_cap: number of phy for hal reg cap + * @hw_mode_to_mac_cap_map: map between hw_mode to capabilities + */ +struct extended_caps { + WMI_SOC_MAC_PHY_HW_MODE_CAPS num_hw_modes; + WMI_HW_MODE_CAPABILITIES *each_hw_mode_cap; + WMI_MAC_PHY_CAPABILITIES *each_phy_cap_per_hwmode; + WMI_SOC_HAL_REG_CAPABILITIES num_phy_for_hal_reg_cap; + WMI_HAL_REG_CAPABILITIES_EXT *each_phy_hal_reg_cap; + struct hw_mode_idx_to_mac_cap_idx *hw_mode_to_mac_cap_map; +}; + +/** + * struct dual_mac_config - Dual MAC configurations + * @prev_scan_config: Previous scan configuration + * @prev_fw_mode_config: Previous FW mode configuration + * @cur_scan_config: Current scan configuration + * @cur_fw_mode_config: Current FW mode configuration + * @req_scan_config: Requested scan configuration + * @req_fw_mode_config: Requested FW mode configuration + */ +struct dual_mac_config { + uint32_t prev_scan_config; + uint32_t prev_fw_mode_config; + uint32_t cur_scan_config; + uint32_t cur_fw_mode_config; + uint32_t req_scan_config; + uint32_t req_fw_mode_config; +}; + +#endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c new file mode 100644 index 000000000000..3673a01b101c --- /dev/null +++ b/src/wlan_policy_mgr_action.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * DOC: wlan_policy_mgr_action.c + * + * WLAN Concurrenct Connection Management APIs + * + */ + +/* Include files */ + +#include "wlan_policy_mgr_api.h" +#include "wlan_policy_mgr_tables_no_dbs_i.h" +#include "wlan_policy_mgr_i.h" +#include "qdf_types.h" +#include "qdf_trace.h" +#include "wlan_objmgr_global_obj.h" + +enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) + (struct wlan_objmgr_psoc *psoc); + +void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, + uint32_t new_hw_mode_index, + uint32_t num_vdev_mac_entries, + struct policy_mgr_vdev_mac_map *vdev_mac_map, + struct wlan_objmgr_psoc *context) +{ +} + +QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, + enum hw_mode_ss_config mac0_ss, + enum hw_mode_bandwidth mac0_bw, + enum hw_mode_ss_config mac1_ss, + enum hw_mode_bandwidth mac1_bw, + enum hw_mode_dbs_capab dbs, + enum hw_mode_agile_dfs_capab dfs, + enum hw_mode_sbs_capab sbs, + enum policy_mgr_conn_update_reason reason) +{ + return QDF_STATUS_SUCCESS; +} + +enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( + struct wlan_objmgr_psoc *psoc) +{ + return PM_NOP; +} + +QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_update_and_wait_for_connection_update( + struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + uint8_t channel, + enum policy_mgr_conn_update_reason reason) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, + uint8_t channel, + enum policy_mgr_conn_update_reason reason) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, + uint32_t session_id, + enum policy_mgr_conc_next_action action, + enum policy_mgr_conn_update_reason reason) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint8_t channel) +{ + return QDF_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) +{ + return; +} + +void policy_mgr_check_concurrent_intf_and_restart_sap( + struct wlan_objmgr_psoc *psoc) +{ + return; +} +#endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc) +{ + return; +} +#endif + +QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_restart_opportunistic_timer( + struct wlan_objmgr_psoc *psoc, bool check_state) +{ + return QDF_STATUS_SUCCESS; +} + +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( + struct wlan_objmgr_psoc *psoc, + void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_deregister_sap_restart_channel_switch_cb( + struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +#endif + +QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( + struct wlan_objmgr_psoc *psoc, uint8_t session_id) +{ + return QDF_STATUS_SUCCESS; +} + +void policy_mgr_checkn_update_hw_mode_single_mac_mode( + struct wlan_objmgr_psoc *psoc, uint8_t channel) +{ +} + +#ifdef MPC_UT_FRAMEWORK +QDF_STATUS policy_mgr_update_connection_info_utfw( + struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, + uint32_t chain_mask, uint32_t type, uint32_t sub_type, + uint32_t channelid, uint32_t mac_id) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, uint32_t tx_streams, uint32_t rx_streams, + uint32_t chain_mask, uint32_t type, uint32_t sub_type, + uint32_t channelid, uint32_t mac_id) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, + uint32_t del_all, uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table( + enum policy_mgr_con_mode type, + enum policy_mgr_conc_priority_mode sys_pref) +{ + return PM_NONE; +} + +enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table( + enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type, + enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable) +{ + return PM_NONE; +} + +enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table( + enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type, + enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable) +{ + return PM_NONE; +} +#endif diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c new file mode 100644 index 000000000000..379a04bd2349 --- /dev/null +++ b/src/wlan_policy_mgr_core.c @@ -0,0 +1,638 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * DOC: wlan_policy_mgr_core.c + * + * WLAN Concurrenct Connection Management functions + * + */ + +/* Include files */ + +#include "wlan_policy_mgr_i.h" +#include "qdf_types.h" +#include "qdf_trace.h" +#include "wlan_objmgr_global_obj.h" + +#define POLICY_MGR_MAX_CON_STRING_LEN 100 + +struct policy_mgr_conc_connection_info + pm_conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + +struct policy_mgr_psoc_priv_obj *policy_mgr_get_context( + struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + pm_ctx = (struct policy_mgr_psoc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_POLICY_MGR); + return pm_ctx; +} + +/** + * policy_mgr_get_updated_scan_config() - Get the updated scan configuration + * @scan_config: Pointer containing the updated scan config + * @dbs_scan: 0 or 1 indicating if DBS scan needs to be enabled/disabled + * @dbs_plus_agile_scan: 0 or 1 indicating if DBS plus agile scan needs to be + * enabled/disabled + * @single_mac_scan_with_dfs: 0 or 1 indicating if single MAC scan with DFS + * needs to be enabled/disabled + * + * Takes the current scan configuration and set the necessary scan config + * bits to either 0/1 and provides the updated value to the caller who + * can use this to pass it on to the FW + * + * Return: 0 on success + */ +QDF_STATUS policy_mgr_get_updated_scan_config( + struct wlan_objmgr_psoc *psoc, + uint32_t *scan_config, + bool dbs_scan, + bool dbs_plus_agile_scan, + bool single_mac_scan_with_dfs) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * policy_mgr_get_updated_fw_mode_config() - Get the updated fw mode configuration + * @fw_mode_config: Pointer containing the updated fw mode config + * @dbs: 0 or 1 indicating if DBS needs to be enabled/disabled + * @agile_dfs: 0 or 1 indicating if agile DFS needs to be enabled/disabled + * + * Takes the current fw mode configuration and set the necessary fw mode config + * bits to either 0/1 and provides the updated value to the caller who + * can use this to pass it on to the FW + * + * Return: 0 on success + */ +QDF_STATUS policy_mgr_get_updated_fw_mode_config( + struct wlan_objmgr_psoc *psoc, + uint32_t *fw_mode_config, + bool dbs, + bool agile_dfs) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * policy_mgr_is_dual_mac_disabled_in_ini() - Check if dual mac is disabled in INI + * + * Checks if the dual mac feature is disabled in INI + * + * Return: true if the dual mac feature is disabled from INI + */ +bool policy_mgr_is_dual_mac_disabled_in_ini( + struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +/** + * policy_mgr_get_dbs_config() - Get DBS bit + * + * Gets the DBS bit of fw_mode_config_bits + * + * Return: 0 or 1 to indicate the DBS bit + */ +bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +/** + * policy_mgr_get_agile_dfs_config() - Get Agile DFS bit + * + * Gets the Agile DFS bit of fw_mode_config_bits + * + * Return: 0 or 1 to indicate the Agile DFS bit + */ +bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +/** + * policy_mgr_get_dbs_scan_config() - Get DBS scan bit + * + * Gets the DBS scan bit of concurrent_scan_config_bits + * + * Return: 0 or 1 to indicate the DBS scan bit + */ +bool policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +/** + * policy_mgr_get_tx_rx_ss_from_config() - Get Tx/Rx spatial stream from HW mode config + * @mac_ss: Config which indicates the HW mode as per 'hw_mode_ss_config' + * @tx_ss: Contains the Tx spatial stream + * @rx_ss: Contains the Rx spatial stream + * + * Returns the number of spatial streams of Tx and Rx + * + * Return: None + */ +void policy_mgr_get_tx_rx_ss_from_config(enum hw_mode_ss_config mac_ss, + uint32_t *tx_ss, uint32_t *rx_ss) +{ + switch (mac_ss) { + case HW_MODE_SS_0x0: + *tx_ss = 0; + *rx_ss = 0; + break; + case HW_MODE_SS_1x1: + *tx_ss = 1; + *rx_ss = 1; + break; + case HW_MODE_SS_2x2: + *tx_ss = 2; + *rx_ss = 2; + break; + case HW_MODE_SS_3x3: + *tx_ss = 3; + *rx_ss = 3; + break; + case HW_MODE_SS_4x4: + *tx_ss = 4; + *rx_ss = 4; + break; + default: + *tx_ss = 0; + *rx_ss = 0; + } +} + +/** + * policy_mgr_get_matching_hw_mode_index() - Get matching HW mode index + * @psoc: psoc handle + * @mac0_tx_ss: Number of tx spatial streams of MAC0 + * @mac0_rx_ss: Number of rx spatial streams of MAC0 + * @mac0_bw: Bandwidth of MAC0 of type 'hw_mode_bandwidth' + * @mac1_tx_ss: Number of tx spatial streams of MAC1 + * @mac1_rx_ss: Number of rx spatial streams of MAC1 + * @mac1_bw: Bandwidth of MAC1 of type 'hw_mode_bandwidth' + * @dbs: DBS capability of type 'hw_mode_dbs_capab' + * @dfs: Agile DFS capability of type 'hw_mode_agile_dfs_capab' + * @sbs: SBS capability of type 'hw_mode_sbs_capab' + * + * Fetches the HW mode index corresponding to the HW mode provided + * + * Return: Positive hw mode index in case a match is found or a negative + * value, otherwise + */ +int8_t policy_mgr_get_matching_hw_mode_index( + struct wlan_objmgr_psoc *psoc, + uint32_t mac0_tx_ss, uint32_t mac0_rx_ss, + enum hw_mode_bandwidth mac0_bw, + uint32_t mac1_tx_ss, uint32_t mac1_rx_ss, + enum hw_mode_bandwidth mac1_bw, + enum hw_mode_dbs_capab dbs, + enum hw_mode_agile_dfs_capab dfs, + enum hw_mode_sbs_capab sbs) +{ + return 0; +} + +/** + * policy_mgr_get_hw_mode_from_dbs_hw_list() - Get hw_mode index + * @mac0_ss: MAC0 spatial stream configuration + * @mac0_bw: MAC0 bandwidth configuration + * @mac1_ss: MAC1 spatial stream configuration + * @mac1_bw: MAC1 bandwidth configuration + * @dbs: HW DBS capability + * @dfs: HW Agile DFS capability + * @sbs: HW SBS capability + * + * Get the HW mode index corresponding to the HW modes spatial stream, + * bandwidth, DBS, Agile DFS and SBS capability + * + * Return: Index number if a match is found or -negative value if not found + */ +int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list( + struct wlan_objmgr_psoc *psoc, + enum hw_mode_ss_config mac0_ss, + enum hw_mode_bandwidth mac0_bw, + enum hw_mode_ss_config mac1_ss, + enum hw_mode_bandwidth mac1_bw, + enum hw_mode_dbs_capab dbs, + enum hw_mode_agile_dfs_capab dfs, + enum hw_mode_sbs_capab sbs) +{ + return 0; +} + +/** + * policy_mgr_get_hw_mode_from_idx() - Get HW mode based on index + * @idx: HW mode index + * @hw_mode: HW mode params + * + * Fetches the HW mode parameters + * + * Return: Success if hw mode is obtained and the hw mode params + */ +QDF_STATUS policy_mgr_get_hw_mode_from_idx( + struct wlan_objmgr_psoc *psoc, + uint32_t idx, + struct policy_mgr_hw_mode_params *hw_mode) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * policy_mgr_get_old_and_new_hw_index() - Get the old and new HW index + * @old_hw_mode_index: Value at this pointer contains the old HW mode index + * Default value when not configured is POLICY_MGR_DEFAULT_HW_MODE_INDEX + * @new_hw_mode_index: Value at this pointer contains the new HW mode index + * Default value when not configured is POLICY_MGR_DEFAULT_HW_MODE_INDEX + * + * Get the old and new HW index configured in the driver + * + * Return: Failure in case the HW mode indices cannot be fetched and Success + * otherwise. When no HW mode transition has happened the values of + * old_hw_mode_index and new_hw_mode_index will be the same. + */ +QDF_STATUS policy_mgr_get_old_and_new_hw_index( + struct wlan_objmgr_psoc *psoc, + uint32_t *old_hw_mode_index, + uint32_t *new_hw_mode_index) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * policy_mgr_update_conc_list() - Update the concurrent connection list + * @conn_index: Connection index + * @mode: Mode + * @chan: Channel + * @bw: Bandwidth + * @mac: Mac id + * @chain_mask: Chain mask + * @vdev_id: vdev id + * @in_use: Flag to indicate if the index is in use or not + * + * Updates the index value of the concurrent connection list + * + * Return: None + */ +void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, + uint32_t conn_index, + enum policy_mgr_con_mode mode, + uint8_t chan, + enum hw_mode_bandwidth bw, + uint8_t mac, + enum policy_mgr_chain_mode chain_mask, + uint32_t original_nss, + uint32_t vdev_id, + bool in_use) +{ +} + +/** + * policy_mgr_store_and_del_conn_info() - Store and del a connection info + * @mode: Mode whose entry has to be deleted + * @info: Struture pointer where the connection info will be saved + * + * Saves the connection info corresponding to the provided mode + * and deleted that corresponding entry based on vdev from the + * connection info structure + * + * Return: None + */ +void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + struct policy_mgr_conc_connection_info *info) +{ +} + +/** + * policy_mgr_restore_deleted_conn_info() - Restore connection info + * @info: Saved connection info that is to be restored + * + * Restores the connection info of STA that was saved before + * updating the PCL to the FW + * + * Return: None + */ +void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_conc_connection_info *info) +{ +} + +/** + * policy_mgr_update_hw_mode_conn_info() - Update connection info based on HW mode + * @num_vdev_mac_entries: Number of vdev-mac id entries that follow + * @vdev_mac_map: Mapping of vdev-mac id + * @hw_mode: HW mode + * + * Updates the connection info parameters based on the new HW mode + * + * Return: None + */ +void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc, + uint32_t num_vdev_mac_entries, + struct policy_mgr_vdev_mac_map *vdev_mac_map, + struct policy_mgr_hw_mode_params hw_mode) +{ +} + +/** + * policy_mgr_pdev_set_hw_mode_cb() - Callback for set hw mode + * @status: Status + * @cfgd_hw_mode_index: Configured HW mode index + * @num_vdev_mac_entries: Number of vdev-mac id mapping that follows + * @vdev_mac_map: vdev-mac id map. This memory will be freed by the caller. + * So, make local copy if needed. + * + * Provides the status and configured hw mode index set + * by the FW + * + * Return: None + */ +void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, + uint32_t cfgd_hw_mode_index, + uint32_t num_vdev_mac_entries, + struct policy_mgr_vdev_mac_map *vdev_mac_map, + void *context) +{ +} + +/** + * policy_mgr_dump_current_concurrency() - To dump the current + * concurrency combination + * + * This routine is called to dump the concurrency info + * + * Return: None + */ +void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc) +{ +} + +/** + * policy_mgr_pdev_set_pcl() - Sets PCL to FW + * @mode: adapter mode + * + * Fetches the PCL and sends the PCL to SME + * module which in turn will send the WMI + * command WMI_PDEV_SET_PCL_CMDID to the fw + * + * Return: None + */ +void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode) +{ +} + + +/** + * policy_mgr_set_pcl_for_existing_combo() - Set PCL for existing connection + * @mode: Connection mode of type 'policy_mgr_con_mode' + * + * Set the PCL for an existing connection + * + * Return: None + */ +void policy_mgr_set_pcl_for_existing_combo( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) +{ +} + +/** + * pm_dbs_opportunistic_timer_handler() - handler of + * dbs_opportunistic_timer + * @data: context + * + * handler for dbs_opportunistic_timer + * + * Return: None + */ +void pm_dbs_opportunistic_timer_handler(void *data) +{ +} + +/** + * policy_mgr_get_mode() - Get mode from type and subtype + * @type: type + * @subtype: subtype + * + * Get the concurrency mode from the type and subtype + * of the interface + * + * Return: policy_mgr_con_mode + */ +enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type, + uint8_t subtype) +{ + return PM_MAX_NUM_OF_MODE; +} + +/** + * policy_mgr_get_channel_list() - provides the channel list + * suggestion for new connection + * @pcl: The preferred channel list enum + * @pcl_channels: PCL channels + * @len: length of the PCL + * @mode: concurrency mode for which channel list is requested + * @pcl_weights: Weights of the PCL + * @weight_len: Max length of the weight list + * + * This function provides the actual channel list based on the + * current regulatory domain derived using preferred channel + * list enum obtained from one of the pcl_table + * + * Return: Channel List + */ +QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_pcl_type pcl, + uint8_t *pcl_channels, uint32_t *len, + enum policy_mgr_con_mode mode, + uint8_t *pcl_weights, uint32_t weight_len) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * policy_mgr_disallow_mcc() - Check for mcc + * + * @channel: channel on which new connection is coming up + * + * When a new connection is about to come up check if current + * concurrency combination including the new connection is + * causing MCC + * + * Return: True/False + */ +bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, + uint8_t channel) +{ + return false; +} + +/** + * policy_mgr_allow_new_home_channel() - Check for allowed number of + * home channels + * @channel: channel on which new connection is coming up + * @num_connections: number of current connections + * + * When a new connection is about to come up check if current + * concurrency combination including the new connection is + * allowed or not based on the HW capability + * + * Return: True/False + */ +bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, + uint8_t channel, uint32_t num_connections) +{ + return true; +} + +/** + * policy_mgr_vht160_conn_exist() - to check if we have a connection + * already using vht160 or vht80+80 + * + * This routine will check if vht160 connection already exist or + * no. If it exist then this routine will return true. + * + * Return: true if vht160 connection exist else false + */ +bool policy_mgr_vht160_conn_exist(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +/** + * policy_mgr_is_5g_channel_allowed() - check if 5g channel is allowed + * @channel: channel number which needs to be validated + * @list: list of existing connections. + * @mode: mode against which channel needs to be validated + * + * This API takes the channel as input and compares with existing + * connection channels. If existing connection's channel is DFS channel + * and provided channel is 5G channel then don't allow concurrency to + * happen as MCC with DFS channel is not yet supported + * + * Return: true if 5G channel is allowed, false if not allowed + * + */ +bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, + uint8_t channel, uint32_t *list, + enum policy_mgr_con_mode mode) +{ + return true; +} + +/** + * policy_mgr_complete_action() - initiates actions needed on + * current connections once channel has been decided for the new + * connection + * @new_nss: the new nss value + * @next_action: next action to happen at policy mgr after + * beacon update + * @reason: Reason for connection update + * @session_id: Session id + * + * This function initiates initiates actions + * needed on current connections once channel has been decided + * for the new connection. Notifies UMAC & FW as well + * + * Return: QDF_STATUS enum + */ +QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, + uint8_t new_nss, uint8_t next_action, + enum policy_mgr_conn_update_reason reason, + uint32_t session_id) +{ + return QDF_STATUS_SUCCESS; +} + +enum policy_mgr_con_mode policy_mgr_get_mode_by_vdev_id( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ + return PM_MAX_NUM_OF_MODE; +} + +/** + * policy_mgr_init_connection_update() - Initialize connection + * update event + * @pm_ctx: policy mgr context + * + * Initializes the concurrent connection update event + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_init_connection_update( + struct policy_mgr_psoc_priv_obj *pm_ctx) +{ + return QDF_STATUS_SUCCESS; +} + +/** + * policy_mgr_get_current_pref_hw_mode_dbs_2x2() - Get the current preferred hw mode + * + * Get the preferred hw mode based on the current connection combinations + * + * Return: No change (PM_NOP), MCC (PM_SINGLE_MAC), + * DBS (PM_DBS), SBS (PM_SBS) + */ +enum policy_mgr_conc_next_action + policy_mgr_get_current_pref_hw_mode_dbs_2x2( + struct wlan_objmgr_psoc *psoc) +{ + return PM_NOP; +} + +/** + * policy_mgr_get_current_pref_hw_mode_dbs_1x1() - Get the current preferred hw mode + * + * Get the preferred hw mode based on the current connection combinations + * + * Return: No change (PM_NOP), MCC (PM_SINGLE_MAC_UPGRADE), + * DBS (PM_DBS_DOWNGRADE) + */ +enum policy_mgr_conc_next_action + policy_mgr_get_current_pref_hw_mode_dbs_1x1( + struct wlan_objmgr_psoc *psoc) +{ + return PM_NOP; +} + +/** + * policy_mgr_reset_sap_mandatory_channels() - Reset the SAP mandatory channels + * + * Resets the SAP mandatory channel list and the length of the list + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_reset_sap_mandatory_channels( + struct policy_mgr_psoc_priv_obj *pm_ctx) +{ + return QDF_STATUS_SUCCESS; +} diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c new file mode 100644 index 000000000000..52a4b0a2ce20 --- /dev/null +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * DOC: wlan_policy_mgr_get_set_utils.c + * + * WLAN Concurrenct Connection Management APIs + * + */ + +/* Include files */ + +#include "wlan_policy_mgr_api.h" +#include "wlan_policy_mgr_i.h" +#include "qdf_types.h" +#include "qdf_trace.h" +#include "wlan_objmgr_global_obj.h" + +bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +bool policy_mgr_get_single_mac_scan_with_dfs_config( + struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} + +bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) +{ + return true; +} + +QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc, + bool *one_by_one_dbs, bool *two_by_two_dbs) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_hw_mode_params *hw_mode) +{ + return QDF_STATUS_SUCCESS; +} + +bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} + +uint32_t policy_mgr_mode_specific_connection_count( + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint32_t *list) +{ + return 0; +} + +void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, + uint32_t scan_config, + uint32_t fw_mode_config) +{ + policy_mgr_notice("Status:%d for scan_config:%x fw_mode_config:%x", + status, scan_config, fw_mode_config); +} + +void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc, + uint8_t dbs_val, + uint8_t dbs_plus_agile_scan_val, + uint8_t single_mac_scan_with_dbs_val) +{ +} + +void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc, + uint8_t dbs, uint8_t dfs) +{ +} + +bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) +{ + return true; +} + +void policy_mgr_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode) +{ + return; +} + +void policy_mgr_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode) +{ + return; +} + +void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode, + uint8_t session_id) +{ +} + +void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode, + uint8_t session_id) +{ +} + +QDF_STATUS policy_mgr_incr_connection_count( + struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +bool policy_mgr_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, + enum policy_mgr_con_mode *new_mode) +{ + return true; +} + +bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, + uint8_t *ibss_channel) +{ + return QDF_STATUS_SUCCESS; +} + +bool policy_mgr_max_concurrent_connections_reached( + struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, enum hw_mode_bandwidth bw) +{ + return true; +} + +uint32_t policy_mgr_get_concurrency_mode(void) +{ + return 0; +} + +QDF_STATUS policy_mgr_get_channel_from_scan_result( + struct wlan_objmgr_psoc *psoc, + void *roam_profile, uint8_t *channel) +{ + return QDF_STATUS_SUCCESS; +} + +uint8_t policy_mgr_search_and_check_for_session_conc( + struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + void *roam_profile) +{ + return 0; +} + +bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint8_t channel) +{ + return true; +} + +uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} + +int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, uint8_t mas_value) +{ + return 0; +} + +int32_t policy_mgr_set_mcc_p2p_quota(struct wlan_objmgr_psoc *psoc, + uint32_t set_value) +{ + return 0; +} + +QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( + struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +int32_t policy_mgr_go_set_mcc_p2p_quota(struct wlan_objmgr_psoc *psoc, + uint32_t set_value) +{ + return 0; +} + +void policy_mgr_set_mcc_latency(struct wlan_objmgr_psoc *psoc, int set_value) +{ + return; +} + +struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(uint32_t *len) +{ + return NULL; +} + +enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( + enum tQDF_ADAPTER_MODE device_mode) +{ + return PM_MAX_NUM_OF_MODE; +} + +bool policy_mgr_concurrent_open_sessions_running(void) +{ + return true; +} + +bool policy_mgr_concurrent_beaconing_sessions_running(void) +{ + return true; +} + + +void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc) +{ +} + +bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +bool policy_mgr_is_sta_active_connection_exists(void) +{ + return true; +} + +bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, + uint8_t *channel) +{ + return true; +} + +bool policy_mgr_is_any_dfs_beaconing_session_present( + struct wlan_objmgr_psoc *psoc, uint8_t *channel) +{ + return true; +} + +QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *nss_2g, uint8_t *nss_5g) +{ + return QDF_STATUS_SUCCESS; +} + +void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc) +{ +} + +bool policy_mgr_is_any_mode_active_on_band_along_with_session( + struct wlan_objmgr_psoc *psoc, + uint8_t session_id, + enum policy_mgr_band band) +{ + return true; +} + +QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint8_t *mac_id) +{ + return QDF_STATUS_E_FAILURE; +} + +QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, + uint8_t mac_id, uint8_t session_id, + uint8_t *mcc_session_id) +{ + return QDF_STATUS_E_FAILURE; +} + +uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, + uint8_t session_id) +{ + return 0; +} + +void policy_mgr_set_do_hw_mode_change_flag(struct wlan_objmgr_psoc *psoc, + bool flag) +{ +} + +bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc) +{ + return false; +} diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h new file mode 100644 index 000000000000..272e8ca67c95 --- /dev/null +++ b/src/wlan_policy_mgr_i.h @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef WLAN_POLICY_MGR_I_H +#define WLAN_POLICY_MGR_I_H + +#include "wlan_policy_mgr_api.h" +#include "qdf_event.h" +#include "qdf_mc_timer.h" +#include "qdf_lock.h" +#include "qdf_defer.h" + +#define MAX_NUMBER_OF_CONC_CONNECTIONS 3 +#define DBS_OPPORTUNISTIC_TIME 10 +#ifdef QCA_WIFI_3_0_EMU +#define CONNECTION_UPDATE_TIMEOUT 3000 +#else +#define CONNECTION_UPDATE_TIMEOUT 1000 +#endif + +/** + * Some max value greater than the max length of the channel list + */ +#define MAX_WEIGHT_OF_PCL_CHANNELS 255 +/** + * Some fixed weight difference between the groups + */ +#define PCL_GROUPS_WEIGHT_DIFFERENCE 20 + +/** + * Currently max, only 3 groups are possible as per 'enum policy_mgr_pcl_type'. + * i.e., in a PCL only 3 groups of channels can be present + * e.g., SCC channel on 2.4 Ghz, SCC channel on 5 Ghz & 5 Ghz channels. + * Group 1 has highest priority, group 2 has the next higher priority + * and so on. + */ +#define WEIGHT_OF_GROUP1_PCL_CHANNELS MAX_WEIGHT_OF_PCL_CHANNELS +#define WEIGHT_OF_GROUP2_PCL_CHANNELS \ + (WEIGHT_OF_GROUP1_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) +#define WEIGHT_OF_GROUP3_PCL_CHANNELS \ + (WEIGHT_OF_GROUP2_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) +#define WEIGHT_OF_GROUP4_PCL_CHANNELS \ + (WEIGHT_OF_GROUP3_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) + +#define WEIGHT_OF_NON_PCL_CHANNELS 1 +#define WEIGHT_OF_DISALLOWED_CHANNELS 0 + +/** + * Policy Mgr hardware mode list bit-mask definitions. + * Bits 4:0, 31:29 are unused. + * + * The below definitions are added corresponding to WMI DBS HW mode + * list to make it independent of firmware changes for WMI definitions. + * Currently these definitions have dependency with BIT positions of + * the existing WMI macros. Thus, if the BIT positions are changed for + * WMI macros, then these macros' BIT definitions are also need to be + * changed. + */ +#define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS (28) +#define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS (24) +#define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS (20) +#define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS (16) +#define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS (12) +#define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS (8) +#define POLICY_MGR_HW_MODE_DBS_MODE_BITPOS (7) +#define POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS (6) +#define POLICY_MGR_HW_MODE_SBS_MODE_BITPOS (5) + +#define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_MASK \ + (0xf << POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS) +#define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_MASK \ + (0xf << POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS) +#define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_MASK \ + (0xf << POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS) +#define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_MASK \ + (0xf << POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS) +#define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_MASK \ + (0xf << POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS) +#define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_MASK \ + (0xf << POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS) +#define POLICY_MGR_HW_MODE_DBS_MODE_MASK \ + (0x1 << POLICY_MGR_HW_MODE_DBS_MODE_BITPOS) +#define POLICY_MGR_HW_MODE_AGILE_DFS_MODE_MASK \ + (0x1 << POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS) +#define POLICY_MGR_HW_MODE_SBS_MODE_MASK \ + (0x1 << POLICY_MGR_HW_MODE_SBS_MODE_BITPOS) + +#define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS,\ + 4, value) +#define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS,\ + 4, value) +#define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS,\ + 4, value) +#define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS,\ + 4, value) +#define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS,\ + 4, value) +#define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS,\ + 4, value) +#define POLICY_MGR_HW_MODE_DBS_MODE_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_DBS_MODE_BITPOS,\ + 1, value) +#define POLICY_MGR_HW_MODE_AGILE_DFS_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS,\ + 1, value) +#define POLICY_MGR_HW_MODE_SBS_MODE_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_SBS_MODE_BITPOS,\ + 1, value) + +#define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_MASK) >> \ + POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS) +#define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_MASK) >> \ + POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS) +#define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_MASK) >> \ + POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS) +#define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_MASK) >> \ + POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS) +#define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_MASK) >> \ + POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS) +#define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_MASK) >> \ + POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS) +#define POLICY_MGR_HW_MODE_DBS_MODE_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_DBS_MODE_MASK) >> \ + POLICY_MGR_HW_MODE_DBS_MODE_BITPOS) +#define POLICY_MGR_HW_MODE_AGILE_DFS_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_AGILE_DFS_MODE_MASK) >> \ + POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS) +#define POLICY_MGR_HW_MODE_SBS_MODE_GET(hw_mode) \ + ((hw_mode & POLICY_MGR_HW_MODE_SBS_MODE_MASK) >> \ + POLICY_MGR_HW_MODE_SBS_MODE_BITPOS) + +#define POLICY_MGR_DEFAULT_HW_MODE_INDEX 0xFFFF + +#define policy_mgr_log(level, args...) \ + QDF_TRACE(QDF_MODULE_ID_POLICY_MGR, level, ## args) +#define policy_mgr_logfl(level, format, args...) \ + policy_mgr_log(level, FL(format), ## args) + +#define policy_mgr_alert(format, args...) \ + policy_mgr_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) +#define policy_mgr_err(format, args...) \ + policy_mgr_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) +#define policy_mgr_warn(format, args...) \ + policy_mgr_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) +#define policy_mgr_notice(format, args...) \ + policy_mgr_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) +#define policy_mgr_info(format, args...) \ + policy_mgr_logfl(QDF_TRACE_LEVEL_INFO_HIGH, format, ## args) +#define policy_mgr_debug(format, args...) \ + policy_mgr_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) + +#define PM_CONC_CONNECTION_LIST_VALID_INDEX(index) \ + ((MAX_NUMBER_OF_CONC_CONNECTIONS > index) && \ + (pm_conc_connection_list[index].in_use)) + +/** + * struct policy_mgr_psoc_priv_obj - Policy manager private data + * @psoc: pointer to PSOC object information + * @connection_update_done_evt: qdf event to synchronize + * connection activities + * @qdf_conc_list_lock: To protect connection table + * @dbs_opportunistic_timer: Timer to drop down to Single Mac + * Mode opportunistically + * @sap_restart_chan_switch_cb: Callback for channel switch + * notification for SAP + * @sme_cbacks: callbacks to be registered by SME for + * interaction with Policy Manager + * @wma_cbacks: callbacks to be registered by SME for + * interaction with Policy Manager + * @tdls_cbacks: callbacks to be registered by SME for + * interaction with Policy Manager + * @cdp_cbacks: callbacks to be registered by SME for + * interaction with Policy Manager + * @sap_mandatory_channels: The user preferred master list on + * which SAP can be brought up. This + * mandatory channel list would be as per + * OEMs preference & conforming to the + * regulatory/other considerations + * @sap_mandatory_channels_len: Length of the SAP mandatory + * channel list + * @do_hw_mode_change: Flag to check if HW mode change is needed + * after vdev is up. Especially used after + * channel switch related vdev restart + * @concurrency_mode: active concurrency combination + * @no_of_open_sessions: Number of active vdevs + * @no_of_active_sessions: Number of active connections + * @sta_ap_intf_check_work: delayed sap restart work + * @num_dbs_hw_modes: Number of different HW modes supported + * @hw_mode: List of HW modes supported + * @old_hw_mode_index: Old HW mode from hw_mode table + * @new_hw_mode_index: New HW mode from hw_mode table + * @phy_caps: PHY capability advertised by FW + * @enable2x2: 2x2 chain mask user config + * @gMaxConcurrentActiveSessions: Max concurrenct active + * connections user config + * @conc_system_pref: System preference of t/p, power or latancy + * for Preferred Channel List table, user + * config + * @dual_mac_cfg: DBS configuration currenctly used by FW for + * scan & connections + */ +struct policy_mgr_psoc_priv_obj { + struct wlan_objmgr_psoc *psoc; + qdf_event_t connection_update_done_evt; + qdf_mutex_t qdf_conc_list_lock; + qdf_mc_timer_t dbs_opportunistic_timer; + void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t); + struct policy_mgr_sme_cbacks sme_cbacks; + struct policy_mgr_wma_cbacks wma_cbacks; + struct policy_mgr_tdls_cbacks tdls_cbacks; + struct policy_mgr_cdp_cbacks cdp_cbacks; + uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; + uint32_t sap_mandatory_channels_len; + bool do_hw_mode_change; + uint32_t concurrency_mode; + uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE]; + uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE]; + qdf_work_t sta_ap_intf_check_work; + uint32_t num_dbs_hw_modes; + struct dbs_hw_mode_info hw_mode; + uint32_t old_hw_mode_index; + uint32_t new_hw_mode_index; + struct extended_caps phy_caps; + bool enable2x2; + uint8_t gMaxConcurrentActiveSessions; + uint8_t conc_system_pref; + struct dual_mac_config dual_mac_cfg; +}; + +struct policy_mgr_psoc_priv_obj *policy_mgr_get_context( + struct wlan_objmgr_psoc *psoc); +QDF_STATUS policy_mgr_get_updated_scan_config( + struct wlan_objmgr_psoc *psoc, + uint32_t *scan_config, + bool dbs_scan, + bool dbs_plus_agile_scan, + bool single_mac_scan_with_dfs); +QDF_STATUS policy_mgr_get_updated_fw_mode_config( + struct wlan_objmgr_psoc *psoc, + uint32_t *fw_mode_config, + bool dbs, + bool agile_dfs); +bool policy_mgr_is_dual_mac_disabled_in_ini( + struct wlan_objmgr_psoc *psoc); +bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc); +bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc); +bool policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc *psoc); +void policy_mgr_get_tx_rx_ss_from_config(enum hw_mode_ss_config mac_ss, + uint32_t *tx_ss, uint32_t *rx_ss); +int8_t policy_mgr_get_matching_hw_mode_index( + struct wlan_objmgr_psoc *psoc, + uint32_t mac0_tx_ss, uint32_t mac0_rx_ss, + enum hw_mode_bandwidth mac0_bw, + uint32_t mac1_tx_ss, uint32_t mac1_rx_ss, + enum hw_mode_bandwidth mac1_bw, + enum hw_mode_dbs_capab dbs, + enum hw_mode_agile_dfs_capab dfs, + enum hw_mode_sbs_capab sbs); +int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list( + struct wlan_objmgr_psoc *psoc, + enum hw_mode_ss_config mac0_ss, + enum hw_mode_bandwidth mac0_bw, + enum hw_mode_ss_config mac1_ss, + enum hw_mode_bandwidth mac1_bw, + enum hw_mode_dbs_capab dbs, + enum hw_mode_agile_dfs_capab dfs, + enum hw_mode_sbs_capab sbs); +QDF_STATUS policy_mgr_get_hw_mode_from_idx( + struct wlan_objmgr_psoc *psoc, + uint32_t idx, + struct policy_mgr_hw_mode_params *hw_mode); +QDF_STATUS policy_mgr_get_old_and_new_hw_index( + struct wlan_objmgr_psoc *psoc, + uint32_t *old_hw_mode_index, + uint32_t *new_hw_mode_index); +void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, + uint32_t conn_index, + enum policy_mgr_con_mode mode, + uint8_t chan, + enum hw_mode_bandwidth bw, + uint8_t mac, + enum policy_mgr_chain_mode chain_mask, + uint32_t original_nss, + uint32_t vdev_id, + bool in_use); +void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + struct policy_mgr_conc_connection_info *info); +void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_conc_connection_info *info); +void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc, + uint32_t num_vdev_mac_entries, + struct policy_mgr_vdev_mac_map *vdev_mac_map, + struct policy_mgr_hw_mode_params hw_mode); +void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, + uint32_t cfgd_hw_mode_index, + uint32_t num_vdev_mac_entries, + struct policy_mgr_vdev_mac_map *vdev_mac_map, + void *context); +void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc); +void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode); +void policy_mgr_set_pcl_for_existing_combo( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); +void pm_dbs_opportunistic_timer_handler(void *data); +enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type, + uint8_t subtype); +QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_pcl_type pcl, + uint8_t *pcl_channels, uint32_t *len, + enum policy_mgr_con_mode mode, + uint8_t *pcl_weights, uint32_t weight_len); +bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, + uint8_t channel); +bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, + uint8_t channel, uint32_t num_connections); +bool policy_mgr_vht160_conn_exist(struct wlan_objmgr_psoc *psoc); +bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, + uint8_t channel, uint32_t *list, + enum policy_mgr_con_mode mode); +QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, + uint8_t new_nss, uint8_t next_action, + enum policy_mgr_conn_update_reason reason, + uint32_t session_id); +enum policy_mgr_con_mode policy_mgr_get_mode_by_vdev_id( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); +QDF_STATUS policy_mgr_init_connection_update( + struct policy_mgr_psoc_priv_obj *pm_ctx); +enum policy_mgr_conc_next_action + policy_mgr_get_current_pref_hw_mode_dbs_2x2( + struct wlan_objmgr_psoc *psoc); +enum policy_mgr_conc_next_action + policy_mgr_get_current_pref_hw_mode_dbs_1x1( + struct wlan_objmgr_psoc *psoc); +QDF_STATUS policy_mgr_reset_sap_mandatory_channels( + struct policy_mgr_psoc_priv_obj *pm_ctx); +#endif diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c new file mode 100644 index 000000000000..862e12a462f3 --- /dev/null +++ b/src/wlan_policy_mgr_init_deinit.c @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * DOC: wlan_policy_mgr_init_deinit.c + * + * WLAN Concurrenct Connection Management APIs + * + */ + +/* Include files */ + +#include "wlan_policy_mgr_api.h" +#include "wlan_policy_mgr_tables_1x1_dbs_i.h" +#include "wlan_policy_mgr_tables_2x2_dbs_i.h" +#include "wlan_policy_mgr_i.h" +#include "qdf_types.h" +#include "qdf_trace.h" +#include "wlan_objmgr_global_obj.h" + +static QDF_STATUS policy_mgr_psoc_obj_create_cb(struct wlan_objmgr_psoc *psoc, + void *data) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS policy_mgr_psoc_obj_delete_cb(struct wlan_objmgr_psoc *psoc, + void *data) +{ + return QDF_STATUS_SUCCESS; +} + +static void policy_mgr_psoc_obj_status_cb(struct wlan_objmgr_psoc *psoc, + void *data, QDF_STATUS status) +{ + return; +} + +static QDF_STATUS policy_mgr_vdev_obj_create_cb(struct wlan_objmgr_vdev *vdev, + void *data) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS policy_mgr_vdev_obj_delete_cb(struct wlan_objmgr_vdev *vdev, + void *data) +{ + return QDF_STATUS_SUCCESS; +} + +static void policy_mgr_vdev_obj_status_cb(struct wlan_objmgr_vdev *vdev, + void *data, QDF_STATUS status) +{ + return; +} + +QDF_STATUS policy_mgr_init(void) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + status = wlan_objmgr_register_psoc_create_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_create_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to register psoc obj create cback"); + goto err_psoc_create; + } + + status = wlan_objmgr_register_psoc_destroy_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_delete_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to register psoc obj delete cback"); + goto err_psoc_delete; + } + + status = wlan_objmgr_register_psoc_status_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_status_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to register psoc obj status cback"); + goto err_psoc_status; + } + + status = wlan_objmgr_register_vdev_create_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_create_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to register vdev obj create cback"); + goto err_vdev_create; + } + + status = wlan_objmgr_register_vdev_destroy_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_delete_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to register vdev obj delete cback"); + goto err_vdev_delete; + } + + status = wlan_objmgr_register_vdev_status_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_status_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to register vdev obj status cback"); + goto err_vdev_status; + } + + policy_mgr_notice("Callbacks registered with obj mgr"); + + return QDF_STATUS_SUCCESS; + +err_vdev_status: + wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_delete_cb, NULL); +err_vdev_delete: + wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_create_cb, NULL); +err_vdev_create: + wlan_objmgr_unregister_psoc_status_handler(WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_status_cb, NULL); +err_psoc_status: + wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_delete_cb, NULL); +err_psoc_delete: + wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_create_cb, NULL); +err_psoc_create: + return status; +} + +QDF_STATUS policy_mgr_deinit(void) +{ + QDF_STATUS status; + + status = wlan_objmgr_unregister_psoc_create_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_create_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to deregister psoc obj create cback"); + + status = wlan_objmgr_unregister_psoc_destroy_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_delete_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to deregister psoc obj delete cback"); + + status = wlan_objmgr_unregister_psoc_status_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_psoc_obj_status_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to deregister psoc obj status cback"); + + status = wlan_objmgr_unregister_vdev_create_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_create_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to deregister vdev obj create cback"); + + status = wlan_objmgr_unregister_vdev_destroy_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_delete_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to deregister vdev obj delete cback"); + + status = wlan_objmgr_unregister_vdev_status_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_status_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to deregister vdev obj status cback"); + + policy_mgr_info("deregistered callbacks with obj mgr successfully"); + + return status; +} + +QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc) +{ + /* placeholder for now */ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) +{ + /* placeholder for now */ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_sme_cbacks *sme_cbacks) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->sme_cbacks.sme_get_nss_for_vdev = + sme_cbacks->sme_get_nss_for_vdev; + pm_ctx->sme_cbacks.sme_get_valid_channels = + sme_cbacks->sme_get_valid_channels; + pm_ctx->sme_cbacks.sme_nss_update_request = + sme_cbacks->sme_nss_update_request; + pm_ctx->sme_cbacks.sme_pdev_set_hw_mode = + sme_cbacks->sme_pdev_set_hw_mode; + pm_ctx->sme_cbacks.sme_pdev_set_pcl = + sme_cbacks->sme_pdev_set_pcl; + pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config = + sme_cbacks->sme_soc_set_dual_mac_config; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_wma_cbacks *wma_cbacks) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->wma_cbacks.wma_get_connection_info = + wma_cbacks->wma_get_connection_info; + pm_ctx->wma_cbacks.wma_is_service_enabled = + wma_cbacks->wma_is_service_enabled; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_register_cdp_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_cdp_cbacks *cdp_cbacks) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->cdp_cbacks.cdp_update_mac_id = + cdp_cbacks->cdp_update_mac_id; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_tdls_cbacks *tdls_cbacks) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->tdls_cbacks.check_is_tdls_allowed = + tdls_cbacks->check_is_tdls_allowed; + pm_ctx->tdls_cbacks.set_tdls_ct_mode = + tdls_cbacks->set_tdls_ct_mode; + + return QDF_STATUS_SUCCESS; +} diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c new file mode 100644 index 000000000000..62cd7b380a28 --- /dev/null +++ b/src/wlan_policy_mgr_pcl.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +/** + * DOC: wlan_policy_mgr_pcl.c + * + * WLAN Concurrenct Connection Management APIs + * + */ + +/* Include files */ + +#include "wlan_policy_mgr_api.h" +#include "wlan_policy_mgr_tables_no_dbs_i.h" +#include "wlan_policy_mgr_i.h" +#include "qdf_types.h" +#include "qdf_trace.h" +#include "wlan_objmgr_global_obj.h" + +/** + * first_connection_pcl_table - table which provides PCL for the + * very first connection in the system + */ +const enum policy_mgr_pcl_type +first_connection_pcl_table[PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE] = { + [PM_STA_MODE] = {PM_NONE, PM_NONE, PM_NONE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G }, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G }, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G }, + [PM_IBSS_MODE] = {PM_NONE, PM_NONE, PM_NONE}, +}; + +pm_dbs_pcl_second_connection_table_type + *second_connection_pcl_dbs_table; +pm_dbs_pcl_third_connection_table_type + *third_connection_pcl_dbs_table; +policy_mgr_next_action_two_connection_table_type + *next_action_two_connection_table; +policy_mgr_next_action_three_connection_table_type + *next_action_three_connection_table; + +QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *pcl_ch, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len) +{ + return QDF_STATUS_SUCCESS; +} + +void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode, + uint8_t session_id) +{ +} + +void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels, + uint32_t *len, uint8_t *weight_list, uint32_t weight_len) +{ + return; +} + +uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, uint32_t *vdev_id) +{ + return 0; +} + +QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t *pcl_channels, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len) +{ + return QDF_STATUS_SUCCESS; +} + +enum policy_mgr_conc_priority_mode + policy_mgr_get_first_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc) +{ + return PM_MAX_CONC_PRIORITY_MODE; +} + +enum policy_mgr_one_connection_mode + policy_mgr_get_second_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc) +{ + return PM_MAX_ONE_CONNECTION_MODE; +} + +enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index( + struct wlan_objmgr_psoc *psoc) +{ + return PM_MAX_TWO_CONNECTION_MODE; +} + +uint8_t +policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + bool for_existing_conn) +{ + return 0; +} + +QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, + uint8_t *chan_list, uint32_t *list_len) +{ + return QDF_STATUS_SUCCESS; +} + +bool policy_mgr_list_has_24GHz_channel(uint8_t *channel_list, + uint32_t list_len) +{ + return false; +} + +QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, + uint8_t *channels, uint32_t len) +{ + return QDF_STATUS_SUCCESS; +} + +bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc) +{ + return false; +} + +QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( + struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_list_org, + uint8_t *weight_list_org, + uint32_t *pcl_len_org) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, + uint32_t *chan) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_pcl_chan_weights *weight) +{ + return QDF_STATUS_SUCCESS; +} diff --git a/src/wlan_policy_mgr_tables_1x1_dbs_i.h b/src/wlan_policy_mgr_tables_1x1_dbs_i.h new file mode 100644 index 000000000000..caaedaf05431 --- /dev/null +++ b/src/wlan_policy_mgr_tables_1x1_dbs_i.h @@ -0,0 +1,1015 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_POLICY_MGR_TABLES_1X1_DBS_H +#define __WLAN_POLICY_MGR_TABLES_1X1_DBS_H + +#include "wlan_policy_mgr_api.h" + +/** + * second_connection_pcl_dbs_1x1_table - table which provides PCL + * for the 2nd connection, when we have a connection already in + * the system (with DBS supported by HW) + */ +pm_dbs_pcl_second_connection_table_type +pm_second_connection_pcl_dbs_1x1_table = { + [PM_STA_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = {PM_5G, PM_5G, PM_5G } }, + + [PM_STA_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = {PM_5G, PM_5G, PM_5G } }, + + [PM_STA_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = {PM_24G, PM_24G, PM_24G } }, + + [PM_STA_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = {PM_24G, PM_24G, PM_24G } }, + + [PM_P2P_CLI_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_SCC_CH_24G, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH, PM_24G_SCC_CH, PM_24G_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH, PM_24G_SCC_CH, PM_24G_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, +}; + +/** + * third_connection_pcl_dbs_table - table which provides PCL for + * the 3rd connection, when we have two connections already in + * the system (with DBS supported by HW) + */ +static pm_dbs_pcl_third_connection_table_type +pm_third_connection_pcl_dbs_1x1_table = { + [PM_STA_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_DBS_1x1] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_DBS_1x1] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_GO_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_IBSS_MODE] = {PM_NONE, PM_NONE, PM_NONE} }, + + [PM_STA_P2P_CLI_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_GO_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_DBS_1x1] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_GO_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + +}; + +/** + * next_action_two_connection_table - table which provides next + * action while a new connection is coming up, with one + * connection already in the system + */ +static policy_mgr_next_action_two_connection_table_type + pm_next_action_two_connection_dbs_1x1_table = { + [PM_STA_24_1x1] = {PM_NOP, PM_DBS}, + [PM_STA_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_STA_5_1x1] = {PM_DBS, PM_NOP}, + [PM_STA_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_P2P_CLI_24_1x1] = {PM_NOP, PM_DBS}, + [PM_P2P_CLI_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_P2P_CLI_5_1x1] = {PM_DBS, PM_NOP}, + [PM_P2P_CLI_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_24_1x1] = {PM_NOP, PM_DBS}, + [PM_P2P_GO_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_P2P_GO_5_1x1] = {PM_DBS, PM_NOP}, + [PM_P2P_GO_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_SAP_24_1x1] = {PM_NOP, PM_DBS}, + [PM_SAP_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_SAP_5_1x1] = {PM_DBS, PM_NOP}, + [PM_SAP_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_IBSS_24_1x1] = {PM_NOP, PM_DBS}, + [PM_IBSS_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_IBSS_5_1x1] = {PM_DBS, PM_NOP}, + [PM_IBSS_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, +}; + +/** + * next_action_three_connection_table - table which provides next + * action while a new connection is coming up, with two + * connections already in the system + */ +static policy_mgr_next_action_three_connection_table_type + pm_next_action_three_connection_dbs_1x1_table = { + [PM_STA_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_STA_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_STA_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_STA_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_STA_SAP_SCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_STA_SAP_SCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_STA_SAP_MCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_STA_SAP_MCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_STA_SAP_MCC_24_5_1x1] = {PM_DBS, PM_DBS}, + [PM_STA_SAP_MCC_24_5_2x2] = {PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE}, + [PM_STA_SAP_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_SCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_STA_P2P_GO_SCC_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_STA_P2P_GO_MCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_STA_P2P_GO_MCC_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_STA_P2P_GO_SCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_STA_P2P_GO_SCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_STA_P2P_GO_MCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_STA_P2P_GO_MCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_STA_P2P_GO_MCC_24_5_1x1] = {PM_DBS, PM_DBS}, + [PM_STA_P2P_GO_MCC_24_5_2x2] = { + PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE}, + [PM_STA_P2P_GO_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_STA_P2P_CLI_SCC_24_2x2] = { + PM_NOP, PM_DBS_DOWNGRADE}, + [PM_STA_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_STA_P2P_CLI_MCC_24_2x2] = { + PM_NOP, PM_DBS_DOWNGRADE}, + [PM_STA_P2P_CLI_SCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_STA_P2P_CLI_SCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_STA_P2P_CLI_MCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_STA_P2P_CLI_MCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_STA_P2P_CLI_MCC_24_5_1x1] = {PM_DBS, PM_DBS}, + [PM_STA_P2P_CLI_MCC_24_5_2x2] = { + PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE}, + [PM_STA_P2P_CLI_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = { + PM_NOP, PM_DBS_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = { + PM_NOP, PM_DBS_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {PM_DBS, PM_DBS}, + [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = { + PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_P2P_GO_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_P2P_GO_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_P2P_GO_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_P2P_GO_SAP_SCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_P2P_GO_SAP_SCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_SAP_MCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_P2P_GO_SAP_MCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_SAP_MCC_24_5_1x1] = {PM_DBS, PM_DBS}, + [PM_P2P_GO_SAP_MCC_24_5_2x2] = { + PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE}, + [PM_P2P_GO_SAP_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_CLI_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_P2P_CLI_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_P2P_CLI_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_P2P_CLI_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS_DOWNGRADE}, + [PM_P2P_CLI_SAP_SCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_P2P_CLI_SAP_SCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_5_2x2] = {PM_DBS_DOWNGRADE, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_24_5_1x1] = {PM_DBS, PM_DBS}, + [PM_P2P_CLI_SAP_MCC_24_5_2x2] = {PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE}, + [PM_P2P_CLI_SAP_DBS_1x1] = {PM_NOP, PM_NOP}, + +}; + +#endif diff --git a/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/src/wlan_policy_mgr_tables_2x2_dbs_i.h new file mode 100644 index 000000000000..3f8b8c4a7329 --- /dev/null +++ b/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -0,0 +1,1392 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_POLICY_MGR_TABLES_2X2_DBS_H +#define __WLAN_POLICY_MGR_TABLESY_2X2_DBS_H + +#include "wlan_policy_mgr_api.h" + +/** + * second_connection_pcl_dbs_2x2_table - table which provides PCL + * for the 2nd connection, when we have a connection already in + * the system (with DBS supported by HW) + * This table consolidates selection for P2PCLI, P2PGO, STA, SAP + * into the single set of STA entries for 2.4G and 5G. + */ +static pm_dbs_pcl_second_connection_table_type +pm_second_connection_pcl_dbs_2x2_table = { + [PM_STA_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = {PM_5G, PM_5G, PM_5G} }, + + [PM_STA_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = {PM_5G, PM_5G, PM_5G} }, + + [PM_STA_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_IBSS_MODE] = {PM_24G, PM_24G, PM_24G} }, + + [PM_STA_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_IBSS_MODE] = {PM_24G, PM_24G, PM_24G} }, + + [PM_P2P_CLI_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_SAP_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_SAP_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_SAP_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + [PM_SAP_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_IBSS_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE} }, + + + [PM_IBSS_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_5_1x1] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_5_2x2] = { + [PM_STA_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + +}; + +/** + * third_connection_pcl_dbs_table - table which provides PCL for + * the 3rd connection, when we have two connections already in + * the system (with DBS supported by HW) + */ +static pm_dbs_pcl_third_connection_table_type +pm_third_connection_pcl_dbs_2x2_table = { + [PM_STA_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, + PM_24G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_DBS_1x1] = { + [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_DBS_2x2] = { + [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_SAP_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_P2P_GO_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_DBS_1x1] = { + [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_DBS_2x2] = { + [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_SAP_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, + PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_DBS_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = { PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_DBS_1x1] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_DBS_2x2] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, }, + + [PM_STA_P2P_CLI_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_DBS_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH_5G, + PM_SCC_CH_24G}, + [PM_SAP_MODE] = { + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH_5G, + PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH_SBS_CH_5G, + PM_24G_SCC_CH_SBS_CH_5G}, + [PM_P2P_GO_MODE] = { + PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH_SBS_CH_5G, + PM_24G_SCC_CH_SBS_CH_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH_5G, + PM_SCC_CH_24G}, + [PM_SAP_MODE] = { + PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH_5G, + PM_SCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH_SBS_CH_5G, + PM_24G_SCC_CH_SBS_CH_5G}, + [PM_P2P_GO_MODE] = { + PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH_SBS_CH_5G, + PM_24G_SCC_CH_SBS_CH_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, + PM_24G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, PM_24G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G_MCC_CH, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G_MCC_CH, + PM_24G_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G_MCC_CH, PM_24G_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_DBS_1x1] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_GO_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_DBS_2x2] = { + [PM_STA_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_GO_MODE] = { + PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, + PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_SAP_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_P2P_GO_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = { + PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = { + PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = { + PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, }, + + [PM_STA_STA_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_DBS_1x1] = { + [PM_STA_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_DBS_2x2] = { + [PM_STA_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_STA_SBS_5_1x1] = { + [PM_STA_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_SAP_MODE] = { + PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + +}; + +/** + * next_action_two_connection_table - table which provides next + * action while a new connection is coming up, with one + * connection already in the system + */ +static policy_mgr_next_action_two_connection_table_type + pm_next_action_two_connection_dbs_2x2_table = { + [PM_STA_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_P2P_CLI_24_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_CLI_24_2x2] = {PM_NOP, PM_NOP}, + [PM_P2P_CLI_5_1x1] = {PM_DBS, PM_SBS}, + [PM_P2P_CLI_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_P2P_GO_24_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_24_2x2] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_5_1x1] = {PM_DBS, PM_SBS}, + [PM_P2P_GO_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_SAP_24_1x1] = {PM_NOP, PM_DBS}, + [PM_SAP_24_2x2] = {PM_NOP, PM_DBS}, + [PM_SAP_5_1x1] = {PM_DBS, PM_SBS}, + [PM_SAP_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_IBSS_24_1x1] = {PM_NOP, PM_NOP}, + [PM_IBSS_24_2x2] = {PM_NOP, PM_NOP}, + [PM_IBSS_5_1x1] = {PM_DBS, PM_NOP}, + [PM_IBSS_5_2x2] = {PM_DBS, PM_NOP}, +}; + +/** + * next_action_three_connection_table - table which provides next + * action while a new connection is coming up, with two + * connections already in the system + */ +static policy_mgr_next_action_three_connection_table_type + pm_next_action_three_connection_dbs_2x2_table = { + [PM_STA_SAP_SCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_SAP_SCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_SAP_MCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_SAP_MCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_SAP_SCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_SAP_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_STA_SAP_MCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_SAP_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_STA_SAP_MCC_24_5_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_SAP_MCC_24_5_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_SAP_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_SAP_DBS_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_SAP_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP}, + + [PM_STA_P2P_GO_SCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_SCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_MCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_MCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_SCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_P2P_GO_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_STA_P2P_GO_MCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_P2P_GO_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_STA_P2P_GO_MCC_24_5_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_MCC_24_5_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_DBS_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_GO_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP}, + + [PM_STA_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_SCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_P2P_CLI_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_STA_P2P_CLI_MCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_P2P_CLI_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_STA_P2P_CLI_MCC_24_5_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_MCC_24_5_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_DBS_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_P2P_CLI_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP}, + + [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_DBS_2x2] = {PM_NOP, PM_NOP}, + [PM_P2P_GO_P2P_CLI_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP}, + + [PM_STA_STA_SCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_STA_SCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_STA_MCC_24_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_STA_MCC_24_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_STA_SCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_STA_SCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_STA_STA_MCC_5_1x1] = {PM_DBS, PM_SBS}, + [PM_STA_STA_MCC_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, + [PM_STA_STA_MCC_24_5_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_STA_MCC_24_5_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_STA_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_STA_STA_DBS_2x2] = {PM_NOP, PM_NOP}, + [PM_STA_STA_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP}, + +}; + +#endif diff --git a/src/wlan_policy_mgr_tables_no_dbs_i.h b/src/wlan_policy_mgr_tables_no_dbs_i.h new file mode 100644 index 000000000000..cddd184cf939 --- /dev/null +++ b/src/wlan_policy_mgr_tables_no_dbs_i.h @@ -0,0 +1,909 @@ +/* + * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * + * Previously licensed under the ISC license by Qualcomm Atheros, Inc. + * + * + * 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. + */ + +/* + * This file was originally distributed by Qualcomm Atheros, Inc. + * under proprietary terms before Copyright ownership was assigned + * to the Linux Foundation. + */ + +#ifndef __WLAN_POLICY_MGR_TABLES_NO_DBS_H +#define __WLAN_POLICY_MGR_TABLES_NO_DBS_H + +#include "wlan_policy_mgr_api.h" + +/** + * second_connection_pcl_nodbs_table - table which provides PCL + * for the 2nd connection, when we have a connection already in + * the system (with DBS not supported by HW) + */ +static const enum policy_mgr_pcl_type +second_connection_pcl_nodbs_table[PM_MAX_ONE_CONNECTION_MODE] + [PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE] = { + [PM_STA_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_24_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_24_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_24_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_24_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_IBSS_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, +}; + +/** + * third_connection_pcl_nodbs_table - table which provides PCL + * for the 3rd connection, when we have two connections already + * in the system (with DBS not supported by HW) + */ +static const enum policy_mgr_pcl_type +third_connection_pcl_nodbs_table[PM_MAX_TWO_CONNECTION_MODE] + [PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE] = { + [PM_STA_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_SAP_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = { + PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = { + PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_GO_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_STA_P2P_CLI_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = { + PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = { + PM_5G_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_SAP_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_SAP_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_P2P_GO_MODE] = {PM_MCC_CH, PM_MCC_CH, PM_MCC_CH}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_P2P_CLI_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_GO_SAP_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + + [PM_P2P_CLI_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_P2P_CLI_SAP_DBS_1x1] = { + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + +}; + +#endif From 60958fd69a6ae194b7b7940234d1b14d380f5c7a Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 3 Mar 2017 11:04:29 -0800 Subject: [PATCH 003/404] qcacmn: initialization of policy manager component Initialization related function definitions for policy manager component. Change-Id: I60122bac847c1cfbe8dba6aea8bbeb6391cf500b CRs-Fixed: 2009818 --- src/wlan_policy_mgr_i.h | 18 ++++ src/wlan_policy_mgr_init_deinit.c | 160 ++++++++++++++++++++++++++++-- 2 files changed, 169 insertions(+), 9 deletions(-) diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 272e8ca67c95..2a0252bc05fd 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -189,6 +189,24 @@ ((MAX_NUMBER_OF_CONC_CONNECTIONS > index) && \ (pm_conc_connection_list[index].in_use)) +extern struct policy_mgr_conc_connection_info + pm_conc_connection_list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + +extern const enum policy_mgr_pcl_type + first_connection_pcl_table[PM_MAX_NUM_OF_MODE] + [PM_MAX_CONC_PRIORITY_MODE]; +extern pm_dbs_pcl_second_connection_table_type + *second_connection_pcl_dbs_table; +extern pm_dbs_pcl_third_connection_table_type + *third_connection_pcl_dbs_table; +extern policy_mgr_next_action_two_connection_table_type + *next_action_two_connection_table; +extern policy_mgr_next_action_three_connection_table_type + *next_action_three_connection_table; +extern enum policy_mgr_conc_next_action + (*policy_mgr_get_current_pref_hw_mode_ptr) + (struct wlan_objmgr_psoc *psoc); + /** * struct policy_mgr_psoc_priv_obj - Policy manager private data * @psoc: pointer to PSOC object information diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 862e12a462f3..a7e10cb4aeef 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -45,12 +45,36 @@ static QDF_STATUS policy_mgr_psoc_obj_create_cb(struct wlan_objmgr_psoc *psoc, void *data) { + struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; + + policy_mgr_ctx = qdf_mem_malloc( + sizeof(struct policy_mgr_psoc_priv_obj)); + if (!policy_mgr_ctx) { + policy_mgr_err("memory allocation failed"); + return QDF_STATUS_E_FAILURE; + } + + policy_mgr_ctx->psoc = psoc; + + wlan_objmgr_psoc_component_obj_attach(psoc, + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_ctx, + QDF_STATUS_SUCCESS); + return QDF_STATUS_SUCCESS; } -static QDF_STATUS policy_mgr_psoc_obj_delete_cb(struct wlan_objmgr_psoc *psoc, +static QDF_STATUS policy_mgr_psoc_obj_destroy_cb(struct wlan_objmgr_psoc *psoc, void *data) { + struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; + + policy_mgr_ctx = policy_mgr_get_context(psoc); + wlan_objmgr_psoc_component_obj_detach(psoc, + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_ctx); + qdf_mem_free(policy_mgr_ctx); + return QDF_STATUS_SUCCESS; } @@ -66,7 +90,7 @@ static QDF_STATUS policy_mgr_vdev_obj_create_cb(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } -static QDF_STATUS policy_mgr_vdev_obj_delete_cb(struct wlan_objmgr_vdev *vdev, +static QDF_STATUS policy_mgr_vdev_obj_destroy_cb(struct wlan_objmgr_vdev *vdev, void *data) { return QDF_STATUS_SUCCESS; @@ -92,7 +116,7 @@ QDF_STATUS policy_mgr_init(void) status = wlan_objmgr_register_psoc_destroy_handler( WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_psoc_obj_delete_cb, + policy_mgr_psoc_obj_destroy_cb, NULL); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed to register psoc obj delete cback"); @@ -119,7 +143,7 @@ QDF_STATUS policy_mgr_init(void) status = wlan_objmgr_register_vdev_destroy_handler( WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_vdev_obj_delete_cb, + policy_mgr_vdev_obj_destroy_cb, NULL); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed to register vdev obj delete cback"); @@ -141,7 +165,7 @@ QDF_STATUS policy_mgr_init(void) err_vdev_status: wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_vdev_obj_delete_cb, NULL); + policy_mgr_vdev_obj_destroy_cb, NULL); err_vdev_delete: wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR, policy_mgr_vdev_obj_create_cb, NULL); @@ -150,7 +174,7 @@ err_vdev_create: policy_mgr_psoc_obj_status_cb, NULL); err_psoc_status: wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_psoc_obj_delete_cb, NULL); + policy_mgr_psoc_obj_destroy_cb, NULL); err_psoc_delete: wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_POLICY_MGR, policy_mgr_psoc_obj_create_cb, NULL); @@ -171,7 +195,7 @@ QDF_STATUS policy_mgr_deinit(void) status = wlan_objmgr_unregister_psoc_destroy_handler( WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_psoc_obj_delete_cb, + policy_mgr_psoc_obj_destroy_cb, NULL); if (status != QDF_STATUS_SUCCESS) policy_mgr_err("Failed to deregister psoc obj delete cback"); @@ -192,7 +216,7 @@ QDF_STATUS policy_mgr_deinit(void) status = wlan_objmgr_unregister_vdev_destroy_handler( WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_vdev_obj_delete_cb, + policy_mgr_vdev_obj_destroy_cb, NULL); if (status != QDF_STATUS_SUCCESS) policy_mgr_err("Failed to deregister vdev obj delete cback"); @@ -223,12 +247,130 @@ QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) { + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + policy_mgr_debug("Initializing the policy manager"); + + /* init pm_conc_connection_list */ + qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list)); + + /* init dbs_opportunistic_timer */ + status = qdf_mc_timer_init(&pm_ctx->dbs_opportunistic_timer, + QDF_TIMER_TYPE_SW, + pm_dbs_opportunistic_timer_handler, + (void *)psoc); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("Failed to init DBS opportunistic timer"); + return status; + } + + /* init connection_update_done_evt */ + status = policy_mgr_init_connection_update(pm_ctx); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("connection_update_done_evt init failed"); + return status; + } + + pm_ctx->do_hw_mode_change = false; + + /* reset sap mandatory channels */ + status = policy_mgr_reset_sap_mandatory_channels(pm_ctx); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to reset mandatory channels"); + return status; + } + + /* init PCL table & function pointers based on HW capability */ + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + policy_mgr_get_current_pref_hw_mode_ptr = + policy_mgr_get_current_pref_hw_mode_dbs_2x2; + else + policy_mgr_get_current_pref_hw_mode_ptr = + policy_mgr_get_current_pref_hw_mode_dbs_1x1; + + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + second_connection_pcl_dbs_table = + &pm_second_connection_pcl_dbs_2x2_table; + else + second_connection_pcl_dbs_table = + &pm_second_connection_pcl_dbs_1x1_table; + + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + third_connection_pcl_dbs_table = + &pm_third_connection_pcl_dbs_2x2_table; + else + third_connection_pcl_dbs_table = + &pm_third_connection_pcl_dbs_1x1_table; + + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + next_action_two_connection_table = + &pm_next_action_two_connection_dbs_2x2_table; + else + next_action_two_connection_table = + &pm_next_action_two_connection_dbs_1x1_table; + + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + next_action_three_connection_table = + &pm_next_action_three_connection_dbs_2x2_table; + else + next_action_three_connection_table = + &pm_next_action_three_connection_dbs_1x1_table; + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + /* destroy connection_update_done_evt */ + if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy + (&pm_ctx->connection_update_done_evt))) { + policy_mgr_err("Failed to destroy connection_update_done_evt"); + status = QDF_STATUS_E_FAILURE; + QDF_ASSERT(0); + } + + /* deallocate dbs_opportunistic_timer */ + if (QDF_TIMER_STATE_RUNNING == + qdf_mc_timer_get_current_state( + &pm_ctx->dbs_opportunistic_timer)) { + qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); + } + + if (!QDF_IS_STATUS_SUCCESS(qdf_mc_timer_destroy( + &pm_ctx->dbs_opportunistic_timer))) { + policy_mgr_err("Cannot deallocate dbs opportunistic timer"); + status = QDF_STATUS_E_FAILURE; + QDF_ASSERT(0); + } + + /* reset sap mandatory channels */ + if (QDF_IS_STATUS_ERROR( + policy_mgr_reset_sap_mandatory_channels(pm_ctx))) { + policy_mgr_err("failed to reset sap mandatory channels"); + status = QDF_STATUS_E_FAILURE; + QDF_ASSERT(0); + } + + /* deinit pm_conc_connection_list */ + qdf_mem_zero(pm_conc_connection_list, sizeof(pm_conc_connection_list)); + + return status; } QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, From 88c1dd0509252c2d87b652411053b0d932c3f0e9 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Sun, 5 Mar 2017 20:36:03 +0800 Subject: [PATCH 004/404] qcacmn: Align frameworks of P2P component to convergence policy Remove include folder of P2P core. Move P2P structures about noa and listen offload to public since wmi just can be used in target interface layer. Add more logs. Change-Id: If9a78d02c8c970daf09ea09be05a80dd4ed4c553 CRs-Fixed: 2006243 --- core/src/wlan_p2p_main.c | 98 +++++++++++++++++++++--- core/{inc => src}/wlan_p2p_main.h | 43 ++--------- core/src/wlan_p2p_off_chan_tx.c | 2 +- core/{inc => src}/wlan_p2p_off_chan_tx.h | 0 core/src/wlan_p2p_roc.c | 2 +- core/{inc => src}/wlan_p2p_roc.h | 4 +- dispatcher/inc/wlan_p2p_public_struct.h | 38 ++++++++- dispatcher/inc/wlan_p2p_tgt_api.h | 50 ++++++------ dispatcher/src/wlan_p2p_tgt_api.c | 27 ++++--- dispatcher/src/wlan_p2p_ucfg_api.c | 10 +-- 10 files changed, 173 insertions(+), 101 deletions(-) rename core/{inc => src}/wlan_p2p_main.h (86%) rename core/{inc => src}/wlan_p2p_off_chan_tx.h (100%) rename core/{inc => src}/wlan_p2p_roc.h (98%) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index fb8fac1b83e0..9d62e5b6a0a5 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -29,9 +29,59 @@ #include "wlan_p2p_public_struct.h" #include "wlan_p2p_ucfg_api.h" #include "wlan_p2p_tgt_api.h" -#include "../inc/wlan_p2p_main.h" -#include "../inc/wlan_p2p_roc.h" -#include "../inc/wlan_p2p_off_chan_tx.h" +#include "wlan_p2p_main.h" +#include "wlan_p2p_roc.h" +#include "wlan_p2p_off_chan_tx.h" + +/** + * p2p_get_cmd_type_str() - parse cmd to string + * @cmd_type: P2P cmd type + * + * This function parse P2P cmd to string. + * + * Return: command string + */ +static char *p2p_get_cmd_type_str(enum p2p_cmd_type cmd_type) +{ + switch (cmd_type) { + case P2P_ROC_REQ: + return "P2P roc request"; + case P2P_CANCEL_ROC_REQ: + return "P2P cancel roc request"; + case P2P_MGMT_TX: + return "P2P mgmt tx request"; + case P2P_MGMT_TX_CANCEL: + return "P2P cancel mgmt tx request"; + default: + return "Invalid P2P command"; + } +} + +/** + * p2p_get_event_type_str() - parase event to string + * @event_type: P2P event type + * + * This function parse P2P event to string. + * + * Return: event string + */ +static char *p2p_get_event_type_str(enum p2p_event_type event_type) +{ + switch (event_type) { + case P2P_EVENT_SCAN_EVENT: + return "P2P scan event"; + case P2P_EVENT_MGMT_TX_ACK_CNF: + return "P2P mgmt tx ack event"; + case P2P_EVENT_RX_MGMT: + return "P2P mgmt rx event"; + case P2P_EVENT_LO_STOPPED: + return "P2P lo stop event"; + case P2P_EVENT_NOA: + return "P2P noa event"; + default: + return "Invalid P2P event"; + } +} /** * p2p_psoc_obj_create_notification() - Function to allocate per P2P @@ -60,6 +110,7 @@ static QDF_STATUS p2p_psoc_obj_create_notification( p2p_err("Failed to allocate p2p soc private object"); return QDF_STATUS_E_NOMEM; } + p2p_soc_obj->soc = soc; status = wlan_objmgr_psoc_component_obj_attach(soc, @@ -71,6 +122,8 @@ static QDF_STATUS p2p_psoc_obj_create_notification( return status; } + p2p_info("p2p soc object create successful, %p", p2p_soc_obj); + return QDF_STATUS_SUCCESS; } @@ -102,12 +155,17 @@ static QDF_STATUS p2p_psoc_obj_destroy_notification( return QDF_STATUS_E_FAILURE; } + p2p_soc_obj->soc = NULL; + status = wlan_objmgr_psoc_component_obj_detach(soc, WLAN_UMAC_COMP_P2P, p2p_soc_obj); if (status != QDF_STATUS_SUCCESS) { p2p_err("Failed to detach p2p component, %d", status); return status; } + + p2p_info("destroy p2p soc object, %p", p2p_soc_obj); + qdf_mem_free(p2p_soc_obj); return QDF_STATUS_SUCCESS; @@ -139,7 +197,9 @@ static QDF_STATUS p2p_vdev_obj_create_notification( p2p_err("Failed to allocate p2p vdev object"); return QDF_STATUS_E_NOMEM; } + p2p_vdev_obj->vdev = vdev; + status = wlan_objmgr_vdev_component_obj_attach(vdev, WLAN_UMAC_COMP_P2P, p2p_vdev_obj, QDF_STATUS_SUCCESS); @@ -150,6 +210,8 @@ static QDF_STATUS p2p_vdev_obj_create_notification( return status; } + p2p_info("p2p vdev object create successful, %p", p2p_vdev_obj); + return QDF_STATUS_SUCCESS; } @@ -181,6 +243,8 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( return QDF_STATUS_E_FAILURE; } + p2p_vdev_obj->vdev = NULL; + status = wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_P2P, p2p_vdev_obj); if (status != QDF_STATUS_SUCCESS) { @@ -188,6 +252,12 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( return status; } + p2p_info("destroy p2p vdev object, p2p vdev obj:%p, noa info:%p", + p2p_vdev_obj, p2p_vdev_obj->noa_info); + + if (p2p_vdev_obj->noa_info) + qdf_mem_free(p2p_vdev_obj->noa_info); + qdf_mem_free(p2p_vdev_obj); return QDF_STATUS_SUCCESS; @@ -206,7 +276,7 @@ QDF_STATUS p2p_component_init(void) goto err_reg_psoc_create; } - status = wlan_objmgr_register_psoc_delete_handler( + status = wlan_objmgr_register_psoc_destroy_handler( WLAN_UMAC_COMP_P2P, p2p_psoc_obj_destroy_notification, NULL); @@ -224,7 +294,7 @@ QDF_STATUS p2p_component_init(void) goto err_reg_vdev_create; } - status = wlan_objmgr_register_vdev_delete_handler( + status = wlan_objmgr_register_vdev_destroy_handler( WLAN_UMAC_COMP_P2P, p2p_vdev_obj_destroy_notification, NULL); @@ -240,7 +310,7 @@ err_reg_vdev_delete: wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_P2P, p2p_vdev_obj_create_notification, NULL); err_reg_vdev_create: - wlan_objmgr_unregister_psoc_delete_handler(WLAN_UMAC_COMP_P2P, + wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_P2P, p2p_psoc_obj_destroy_notification, NULL); err_reg_psoc_delete: wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_P2P, @@ -264,7 +334,7 @@ QDF_STATUS p2p_component_deinit(void) ret_status = status; } - status = wlan_objmgr_unregister_vdev_delete_handler( + status = wlan_objmgr_unregister_vdev_destroy_handler( WLAN_UMAC_COMP_P2P, p2p_vdev_obj_destroy_notification, NULL); @@ -284,7 +354,7 @@ QDF_STATUS p2p_component_deinit(void) ret_status = status; } - status = wlan_objmgr_unregister_psoc_delete_handler( + status = wlan_objmgr_unregister_psoc_destroy_handler( WLAN_UMAC_COMP_P2P, p2p_psoc_obj_destroy_notification, NULL); @@ -299,7 +369,7 @@ QDF_STATUS p2p_component_deinit(void) return ret_status; } -QDF_STATUS p2p_psoc_open(struct wlan_objmgr_psoc *soc) +QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) { struct p2p_soc_priv_obj *p2p_soc_obj; @@ -326,7 +396,7 @@ QDF_STATUS p2p_psoc_open(struct wlan_objmgr_psoc *soc) return QDF_STATUS_SUCCESS; } -QDF_STATUS p2p_psoc_close(struct wlan_objmgr_psoc *soc) +QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) { struct p2p_soc_priv_obj *p2p_soc_obj; @@ -431,7 +501,9 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg) { QDF_STATUS status; - p2p_info("msg type %d", msg->type); + p2p_info("msg type %d, %s", msg->type, + p2p_get_cmd_type_str(msg->type)); + if (msg->bodyptr == NULL) { p2p_err("Invalid message body"); return QDF_STATUS_E_INVAL; @@ -474,7 +546,9 @@ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg) { QDF_STATUS status; - p2p_info("msg type %d", msg->type); + p2p_info("msg type %d, %s", msg->type, + p2p_get_event_type_str(msg->type)); + if (msg->bodyptr == NULL) { p2p_err("Invalid message body"); return QDF_STATUS_E_INVAL; diff --git a/core/inc/wlan_p2p_main.h b/core/src/wlan_p2p_main.h similarity index 86% rename from core/inc/wlan_p2p_main.h rename to core/src/wlan_p2p_main.h index 23daf7f2f2f5..6b6a35506d21 100644 --- a/core/inc/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -27,8 +27,8 @@ #include #include -#define P2P_MAX_NOA_DESC 4 #define MAX_QUEUE_LENGTH 20 +#define P2P_MODULE_NAME "P2P" #define p2p_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_P2P, level, ## args) @@ -51,6 +51,7 @@ struct p2p_tx_cnf; struct p2p_rx_mgmt_frame; struct p2p_lo_event; struct p2p_start_param; +struct p2p_noa_info; /** * enum p2p_cmd_type - P2P request type @@ -82,38 +83,6 @@ enum p2p_event_type { P2P_EVENT_NOA, }; -/** - * struct noa_descriptor - noa descriptor - * @type_count: 255: continuous schedule, 0: reserved - * @duration: Absent period duration in micro seconds - * @interval: Absent period interval in micro seconds - * @start_time: 32 bit tsf time when in starts - */ -struct noa_descriptor { - uint8_t type_count; - uint32_t duration; - uint32_t interval; - uint32_t start_time; -}; - -/** - * struct p2p_noa_info - p2p noa information - * @index: Identifies instance of NOA su element - * @opps_ps: Opps ps state of the AP - * @ct_window: Ct window in TUs - * @num_descriptors: Number of NOA descriptors - * @noa_desc: Noa descriptors - * @vdev_id: Vdev id - */ -struct p2p_noa_info { - uint8_t index; - uint8_t opps_ps; - uint8_t ct_window; - uint8_t num_desc; - struct noa_descriptor noa_desc[P2P_MAX_NOA_DESC]; - uint32_t vdev_id; -}; - /** * struct p2p_tx_conf_event - p2p tx confirm event * @p2p_soc_obj: p2p soc private object @@ -204,24 +173,24 @@ QDF_STATUS p2p_component_init(void); QDF_STATUS p2p_component_deinit(void); /** - * p2p_psoc_open() - Open P2P component + * p2p_psoc_object_open() - Open P2P component * @soc: soc context * * This function initialize p2p psoc object * * Return: QDF_STATUS_SUCCESS - in case of success */ -QDF_STATUS p2p_psoc_open(struct wlan_objmgr_psoc *soc); +QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc); /** - * p2p_psoc_close() - Close P2P component + * p2p_psoc_object_close() - Close P2P component * @soc: soc context * * This function de-init p2p psoc object. * * Return: QDF_STATUS_SUCCESS - in case of success */ -QDF_STATUS p2p_psoc_close(struct wlan_objmgr_psoc *soc); +QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc); /** * p2p_psoc_start() - Start P2P component diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 649bcb894fb2..99ceaff00ab1 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -21,7 +21,7 @@ */ #include -#include "../inc/wlan_p2p_off_chan_tx.h" +#include "wlan_p2p_off_chan_tx.h" QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) { diff --git a/core/inc/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h similarity index 100% rename from core/inc/wlan_p2p_off_chan_tx.h rename to core/src/wlan_p2p_off_chan_tx.h diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 29399c4007dd..62fcb2f21d90 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -20,7 +20,7 @@ * DOC: This file contains RoC API definitions */ -#include "../inc/wlan_p2p_roc.h" +#include "wlan_p2p_roc.h" QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx) { diff --git a/core/inc/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h similarity index 98% rename from core/inc/wlan_p2p_roc.h rename to core/src/wlan_p2p_roc.h index b166d7ae35bf..af733c0673ff 100644 --- a/core/inc/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -122,13 +122,13 @@ QDF_STATUS p2p_process_cancel_roc_req( /** * p2p_scan_event_cb() - Process scan event * @vdev: vdev associated to this scan event - * @event: event type + * @event: event information * @arg: registered arguments * * This function handles P2P scan event and deliver P2P event to HDD * layer by registered callback. * - * Return: QDF_STATUS_SUCCESS - in case of success + * Return: None */ void p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, struct scan_event *event, void *arg); diff --git a/dispatcher/inc/wlan_p2p_public_struct.h b/dispatcher/inc/wlan_p2p_public_struct.h index 97bd3b305a60..c17d5a940156 100644 --- a/dispatcher/inc/wlan_p2p_public_struct.h +++ b/dispatcher/inc/wlan_p2p_public_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * 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 @@ -25,6 +25,8 @@ #include +#define P2P_MAX_NOA_DESC 4 + /** * struct p2p_roc_req - P2P roc request * @vdev_id: Vdev id on which this request has come @@ -171,7 +173,7 @@ struct p2p_lo_start { /** * struct p2p_lo_event - * @vdev_id: Vdev id + * @vdev_id: vdev id * @reason_code: reason code */ struct p2p_lo_event { @@ -179,4 +181,36 @@ struct p2p_lo_event { uint32_t reason_code; }; +/** + * struct noa_descriptor - noa descriptor + * @type_count: 255: continuous schedule, 0: reserved + * @duration: Absent period duration in micro seconds + * @interval: Absent period interval in micro seconds + * @start_time: 32 bit tsf time when in starts + */ +struct noa_descriptor { + uint32_t type_count; + uint32_t duration; + uint32_t interval; + uint32_t start_time; +}; + +/** + * struct p2p_noa_info - p2p noa information + * @index: identifies instance of NOA su element + * @opps_ps: opps ps state of the AP + * @ct_window: ct window in TUs + * @vdev_id: vdev id + * @num_descriptors: number of NOA descriptors + * @noa_desc: noa descriptors + */ +struct p2p_noa_info { + uint32_t index; + uint32_t opps_ps; + uint32_t ct_window; + uint32_t vdev_id; + uint32_t num_desc; + struct noa_descriptor noa_desc[P2P_MAX_NOA_DESC]; +}; + #endif /* _WLAN_P2P_PUBLIC_STRUCT_H_ */ diff --git a/dispatcher/inc/wlan_p2p_tgt_api.h b/dispatcher/inc/wlan_p2p_tgt_api.h index 133443ca3f1f..b5dc946ac92b 100644 --- a/dispatcher/inc/wlan_p2p_tgt_api.h +++ b/dispatcher/inc/wlan_p2p_tgt_api.h @@ -28,20 +28,23 @@ struct scan_event; struct wlan_objmgr_psoc; struct wlan_objmgr_peer; +struct p2p_noa_info; +struct p2p_lo_event; +struct mgmt_rx_event_params; enum mgmt_frame_type; /** * tgt_p2p_scan_event_cb() - Callback for scan event - * @vdev: vdev id - * @event: event type + * @vdev: vdev object + * @event: event information * @arg: registered arguments * * This function gets called from scan component when getting P2P * scan event. * - * Return: QDF_STATUS_SUCCESS - in case of success + * Return: None */ -QDF_STATUS tgt_p2p_scan_event_cb(uint8_t vdev, +void tgt_p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, struct scan_event *event, void *arg); /** @@ -79,7 +82,7 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, * @psoc: soc context * @peer: peer context * @buf: rx buffer - * @params: rx parameters + * @mgmt_rx_params: mgmt rx parameters * @frm_type: frame type * * This function gets called from mgmt tx/rx component when rx mgmt @@ -87,39 +90,32 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, * * Return: QDF_STATUS_SUCCESS - in case of success */ -QDF_STATUS tgt_p2p_mgmt_frame_rx_cb( - struct wlan_objmgr_psoc *psoc, - struct wlan_objmgr_peer *peer, - qdf_nbuf_t buf, void *params, +QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, qdf_nbuf_t buf, + struct mgmt_rx_event_params *mgmt_rx_params, enum mgmt_frame_type frm_type); - /** * tgt_p2p_noa_event_cb() - Callback for noa event - * @data: - * @event_buf: event buffer - * @len: buffer length + * @psoc: soc object + * @event_info: noa event information * - * This function gets called from WMI when triggered WMI event - * WMI_P2P_NOA_EVENTID. + * This function gets called from target interface. * - * Return: 0 - success - * others - failure + * Return: QDF_STATUS_SUCCESS - in case of success */ -int tgt_p2p_noa_event_cb(void *data, uint8_t *event_buf, - uint32_t len); +QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, + struct p2p_noa_info *event_info); /** * tgt_p2p_lo_event_cb() - Listen offload stop request - * @data: - * @event_buf: event buffer - * @len: buffer length + * @psoc: soc object + * @event_info: lo stop event buffer * - * This function gets called from WMI when triggered WMI event - * WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID. + * This function gets called from target interface. * - * Return: 0 - success - * others - failure + * Return: QDF_STATUS_SUCCESS - in case of success */ -int tgt_p2p_lo_event_cb(void *data, uint8_t *event_buf, uint32_t len); +QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, + struct p2p_lo_event *event_info); #endif /* _WLAN_P2P_TGT_API_H_ */ diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index d22b325d06c1..b87af0bed613 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -22,15 +22,14 @@ #include #include +#include #include "wlan_p2p_tgt_api.h" -#include "../../core/inc/wlan_p2p_main.h" +#include "wlan_p2p_public_struct.h" +#include "../../core/src/wlan_p2p_main.h" -QDF_STATUS tgt_p2p_scan_event_cb(uint8_t vdev, +void tgt_p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, struct scan_event *event, void *arg) { - /* call p2p_process_scan_event directly*/ - /* since this is from target thread */ - return QDF_STATUS_SUCCESS; } QDF_STATUS tgt_p2p_mgmt_download_comp_cb(void *context, @@ -45,22 +44,22 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, return QDF_STATUS_SUCCESS; } -QDF_STATUS tgt_p2p_mgmt_frame_rx_cb( - struct wlan_objmgr_psoc *psoc, - struct wlan_objmgr_peer *peer, - qdf_nbuf_t buf, void *params, +QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, qdf_nbuf_t buf, + struct mgmt_rx_event_params *mgmt_rx_params, enum mgmt_frame_type frm_type) { return QDF_STATUS_SUCCESS; } -int tgt_p2p_noa_event_cb(void *data, uint8_t *event_buf, - uint32_t len) +QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, + struct p2p_noa_info *event_info) { - return 0; + return QDF_STATUS_SUCCESS; } -int tgt_p2p_lo_event_cb(void *data, uint8_t *event_buf, uint32_t len) +QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, + struct p2p_lo_event *event_info) { - return 0; + return QDF_STATUS_SUCCESS; } diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 8f2fd599f23e..86e98fcc5881 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -20,12 +20,12 @@ * DOC: This file contains p2p north bound interface definitions */ +#include #include +#include #include "wlan_p2p_ucfg_api.h" #include "wlan_p2p_public_struct.h" -#include "../../core/inc/wlan_p2p_main.h" -#include "../../core/inc/wlan_p2p_roc.h" -#include "../../core/inc/wlan_p2p_off_chan_tx.h" +#include "../../core/src/wlan_p2p_main.h" QDF_STATUS ucfg_p2p_init(void) { @@ -39,12 +39,12 @@ QDF_STATUS ucfg_p2p_deinit(void) QDF_STATUS ucfg_p2p_psoc_open(struct wlan_objmgr_psoc *soc) { - return p2p_psoc_open(soc); + return p2p_psoc_object_open(soc); } QDF_STATUS ucfg_p2p_psoc_close(struct wlan_objmgr_psoc *soc) { - return p2p_psoc_close(soc); + return p2p_psoc_object_close(soc); } QDF_STATUS ucfg_p2p_psoc_start(struct wlan_objmgr_psoc *soc, From e9c1e42ffa0e5c96451dcd4b4e648848b9e0b2ab Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Mon, 13 Mar 2017 10:27:10 -0700 Subject: [PATCH 005/404] qcacmn: Avoid new connection while HW mode change is issued In the case of concurrency, when the session decrements, the opportunistic timer is started. After a while, when the opportunistic time is expired, and the hw mode change for SMM is issued, and the same time new interface comes up, then the new connection forms MCC with the existing connection instead of forming DBS. The change is to avoid the race condition to form MCC instead of DBS. Change-Id: I33ad8a76bdca2f17b09c0d2f072b46cba8d376f8 CRs-Fixed: 2009818 --- inc/wlan_policy_mgr_api.h | 39 +++++++++++++++++++++++++++++ inc/wlan_policy_mgr_public_struct.h | 18 +++++++++++++ src/wlan_policy_mgr_action.c | 17 +++++++++++++ src/wlan_policy_mgr_i.h | 3 +++ 4 files changed, 77 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index bb00b936ed38..6c252331efbf 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1609,4 +1609,43 @@ bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc); */ bool policy_mgr_get_single_mac_scan_with_dfs_config( struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_set_hw_mode_change_in_progress() - Set value + * corresponding to policy_mgr_hw_mode_change that indicate if + * HW mode change is in progress + * @psoc: PSOC object information + * @value: Indicate if hw mode change is in progress + * + * Set the value corresponding to policy_mgr_hw_mode_change that + * indicated if hw mode change is in progress. + * + * Return: None + */ +void policy_mgr_set_hw_mode_change_in_progress( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value); + +/** + * policy_mgr_is_hw_mode_change_in_progress() - Check if HW mode + * change is in progress. + * @psoc: PSOC object information + * + * Returns the corresponding policy_mgr_hw_mode_change value. + * + * Return: policy_mgr_hw_mode_change value. + */ +enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_hw_mode_change_from_hw_mode_index() - Get + * matching HW mode from index + * @psoc: PSOC object information + * @hw_mode_index: HW mode index + * Returns the corresponding policy_mgr_hw_mode_change HW mode. + * + * Return: policy_mgr_hw_mode_change value. + */ +enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( + struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 15abfb4e3e6f..46781b545bd1 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -749,6 +749,24 @@ enum set_hw_mode_status { SET_HW_MODE_STATUS_ECOEX, }; +/** + * enum policy_mgr_hw_mode_change - identify the HW mode switching to. + * + * @POLICY_MGR_HW_MODE_NOT_IN_PROGRESS: HW mode change not in progress + * @POLICY_MGR_SMM_IN_PROGRESS: switching to SMM mode + * @POLICY_MGR_DBS_IN_PROGRESS: switching to DBS mode + * @POLICY_MGR_SBS_IN_PROGRESS: switching to SBS mode + * + * These are generic IDs that identify the various roles + * in the software system + */ +enum policy_mgr_hw_mode_change { + POLICY_MGR_HW_MODE_NOT_IN_PROGRESS = 0, + POLICY_MGR_SMM_IN_PROGRESS, + POLICY_MGR_DBS_IN_PROGRESS, + POLICY_MGR_SBS_IN_PROGRESS +}; + /** * struct policy_mgr_conc_connection_info - information of all existing * connections in the wlan system diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 3673a01b101c..41f994c0d241 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -177,6 +177,23 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( { } +void policy_mgr_set_hw_mode_change_in_progress( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value) +{ +} + +enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress( + struct wlan_objmgr_psoc *psoc) +{ + return POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; +} + +enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( + struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index) +{ + return POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; +} + #ifdef MPC_UT_FRAMEWORK QDF_STATUS policy_mgr_update_connection_info_utfw( struct wlan_objmgr_psoc *psoc, diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 2a0252bc05fd..333ef1eb6bf6 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -252,6 +252,8 @@ extern enum policy_mgr_conc_next_action * config * @dual_mac_cfg: DBS configuration currenctly used by FW for * scan & connections + * @hw_mode_change_in_progress: This is to track if HW mode + * change is in progress */ struct policy_mgr_psoc_priv_obj { struct wlan_objmgr_psoc *psoc; @@ -279,6 +281,7 @@ struct policy_mgr_psoc_priv_obj { uint8_t gMaxConcurrentActiveSessions; uint8_t conc_system_pref; struct dual_mac_config dual_mac_cfg; + uint32_t hw_mode_change_in_progress; }; struct policy_mgr_psoc_priv_obj *policy_mgr_get_context( From 86af550319c3cb5196c65026393ba73256410abe Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Mon, 13 Mar 2017 14:04:17 -0700 Subject: [PATCH 006/404] qcacmn: Rename utility function in policy manager component Rename utility function is_scan_simultaneous_capable in policy manager component from wma. Change-Id: I8f9ad162c491dca7b32290fd224fce40d192fd23 CRs-Fixed: 2009818 --- inc/wlan_policy_mgr_api.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 6c252331efbf..c3f5dd4d1a21 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1648,4 +1648,22 @@ enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress( */ enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index); + +/** + * policy_mgr_is_scan_simultaneous_capable() - Check if scan + * parallelization is supported or not + * @psoc: PSOC object information + * currently scan parallelization feature support is dependent on DBS but + * it can be independent in future. + * + * Return: True if master DBS control is enabled + */ +static inline bool policy_mgr_is_scan_simultaneous_capable( + struct wlan_objmgr_psoc *psoc) +{ + if (policy_mgr_is_hw_dbs_capable(psoc)) + return true; + + return false; +} #endif /* __WLAN_POLICY_MGR_API_H */ From 3e06abdcab120bd182fbc89b858ea54946d98a5a Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 14 Mar 2017 10:20:30 -0700 Subject: [PATCH 007/404] qcacmn: Map regulatory macros to legacy regulatory Map regulatory macros used by policy manager to legacy APIs. Change-Id: Ib1ab408094a02648ba9796619ab14d5800db1217 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_i.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 333ef1eb6bf6..d9b3873d9ced 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -33,6 +33,31 @@ #include "qdf_mc_timer.h" #include "qdf_lock.h" #include "qdf_defer.h" +#include + +enum cds_band_type { + CDS_BAND_ALL = 0, + CDS_BAND_2GHZ = 1, + CDS_BAND_5GHZ = 2 +}; +extern uint32_t cds_chan_to_freq(uint8_t chan); +extern uint8_t cds_freq_to_chan(uint32_t freq); +extern enum cds_band_type cds_chan_to_band(uint32_t chan); + +#define WLAN_REG_IS_24GHZ_CH(ch) CDS_IS_CHANNEL_24GHZ(ch) +#define WLAN_REG_IS_5GHZ_CH(ch) CDS_IS_CHANNEL_5GHZ(ch) +#define WLAN_REG_IS_SAME_BAND_CHANNELS(ch1, ch2) \ + CDS_IS_SAME_BAND_CHANNELS(ch1, ch2) +#define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ + CDS_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) +#define wlan_reg_is_dfs_ch(psoc, ch) CDS_IS_DFS_CH(ch) +#define WLAN_REG_MAX_24GHZ_CH_NUM CDS_MAX_24GHZ_CHANNEL_NUMBER +#define reg_chan_to_freq(chan_num) cds_chan_to_freq(chan_num) +#define reg_freq_to_chan(freq) cds_freq_to_chan(freq) +#define reg_chan_to_band(chan_num) cds_chan_to_band(chan_num) +#define BAND_2G CDS_BAND_2GHZ +#define BAND_5G CDS_BAND_5GHZ +#define BAND_ALL CDS_BAND_ALL #define MAX_NUMBER_OF_CONC_CONNECTIONS 3 #define DBS_OPPORTUNISTIC_TIME 10 From 181378a7509c7ed534c2dcdd17688f3975aa83c8 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 7 Mar 2017 15:57:59 -0800 Subject: [PATCH 008/404] qcacmn: Preferred Channel List derivation logic Define Preferred Channel List (PCL) derivation functions. Change-Id: Ic3c64043c723c8d309be1a1d0abf7574d60d2184 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_pcl.c | 1210 ++++++++++++++++++++++++++++++++++++- 1 file changed, 1204 insertions(+), 6 deletions(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 62cd7b380a28..f85fc0c618f2 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -41,6 +41,7 @@ #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" +#define PM_24_GHZ_CHANNEL_6 (6) /** * first_connection_pcl_table - table which provides PCL for the * very first connection in the system @@ -69,13 +70,67 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, uint8_t *pcl_ch, uint32_t *len, uint8_t *pcl_weight, uint32_t weight_len) { - return QDF_STATUS_SUCCESS; + struct policy_mgr_conc_connection_info info; + + QDF_STATUS status = QDF_STATUS_SUCCESS; + + policy_mgr_notice("get pcl for existing conn:%d", mode); + + if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { + /* Check, store and temp delete the mode's parameter */ + policy_mgr_store_and_del_conn_info(psoc, mode, &info); + /* Get the PCL */ + status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, + pcl_weight, weight_len); + policy_mgr_notice("Get PCL to FW for mode:%d", mode); + /* Restore the connection info */ + policy_mgr_restore_deleted_conn_info(psoc, &info); + } + + return status; } void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, enum tQDF_ADAPTER_MODE mode, uint8_t session_id) { + QDF_STATUS qdf_status; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + policy_mgr_decr_active_session(psoc, mode, session_id); + /* + * After the removal of this connection, we need to check if + * a STA connection still exists. The reason for this is that + * if one or more STA exists, we need to provide the updated + * PCL to the FW for cases like LFR. + * + * Since policy_mgr_get_pcl provides PCL list based on the new + * connection that is going to come up, we will find the + * existing STA entry, save it and delete it temporarily. + * After this we will get PCL as though as new STA connection + * is coming up. This will give the exact PCL that needs to be + * given to the FW. After setting the PCL, we need to restore + * the entry that we have saved before. + */ + policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE); + /* do we need to change the HW mode */ + if (policy_mgr_need_opportunistic_upgrade(psoc)) { + /* let's start the timer */ + qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); + qdf_status = qdf_mc_timer_start( + &pm_ctx->dbs_opportunistic_timer, + DBS_OPPORTUNISTIC_TIME * 1000); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) + policy_mgr_err("Failed to start dbs opportunistic timer"); + } + + return; } void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels, @@ -87,6 +142,34 @@ void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels, uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t *vdev_id) { + uint32_t idx = 0; + uint8_t chan; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return 0; + } + + if (mode >= PM_MAX_NUM_OF_MODE) { + policy_mgr_err("incorrect mode"); + return 0; + } + + for (idx = 0; idx < MAX_NUMBER_OF_CONC_CONNECTIONS; idx++) { + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if ((pm_conc_connection_list[idx].mode == mode) && + (!vdev_id || (*vdev_id == + pm_conc_connection_list[idx].vdev_id)) + && pm_conc_connection_list[idx].in_use) { + chan = pm_conc_connection_list[idx].chan; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return chan; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + } + return 0; } @@ -95,6 +178,121 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels, uint32_t *len, uint8_t *pcl_weight, uint32_t weight_len) { + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t num_connections = 0, i; + enum policy_mgr_conc_priority_mode first_index = 0; + enum policy_mgr_one_connection_mode second_index = 0; + enum policy_mgr_two_connection_mode third_index = 0; + enum policy_mgr_pcl_type pcl = PM_NONE; + enum policy_mgr_conc_priority_mode conc_system_pref = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("context is NULL"); + return status; + } + + /* find the current connection state from pm_conc_connection_list*/ + num_connections = policy_mgr_get_connection_count(psoc); + policy_mgr_debug("connections:%d pref:%d requested mode:%d", + num_connections, pm_ctx->conc_system_pref, mode); + + switch (pm_ctx->conc_system_pref) { + case 0: + conc_system_pref = PM_THROUGHPUT; + break; + case 1: + conc_system_pref = PM_POWERSAVE; + break; + case 2: + conc_system_pref = PM_LATENCY; + break; + default: + policy_mgr_err("unknown conc_system_pref value %d", + pm_ctx->conc_system_pref); + break; + } + + switch (num_connections) { + case 0: + first_index = + policy_mgr_get_first_connection_pcl_table_index(psoc); + pcl = first_connection_pcl_table[mode][first_index]; + break; + case 1: + second_index = + policy_mgr_get_second_connection_pcl_table_index(psoc); + if (PM_MAX_ONE_CONNECTION_MODE == second_index) { + policy_mgr_err("couldn't find index for 2nd connection pcl table"); + return status; + } + if (policy_mgr_is_hw_dbs_capable(psoc) == true) { + pcl = (*second_connection_pcl_dbs_table) + [second_index][mode][conc_system_pref]; + } else { + pcl = second_connection_pcl_nodbs_table + [second_index][mode][conc_system_pref]; + } + + break; + case 2: + third_index = + policy_mgr_get_third_connection_pcl_table_index(psoc); + if (PM_MAX_TWO_CONNECTION_MODE == third_index) { + policy_mgr_err( + "couldn't find index for 3rd connection pcl table"); + return status; + } + if (policy_mgr_is_hw_dbs_capable(psoc) == true) { + pcl = (*third_connection_pcl_dbs_table) + [third_index][mode][conc_system_pref]; + } else { + pcl = third_connection_pcl_nodbs_table + [third_index][mode][conc_system_pref]; + } + break; + default: + policy_mgr_err("unexpected num_connections value %d", + num_connections); + break; + } + + policy_mgr_debug("index1:%d index2:%d index3:%d pcl:%d dbs:%d", + first_index, second_index, third_index, + pcl, policy_mgr_is_hw_dbs_capable(psoc)); + + /* once the PCL enum is obtained find out the exact channel list with + * help from sme_get_cfg_valid_channels + */ + status = policy_mgr_get_channel_list(psoc, pcl, pcl_channels, len, mode, + pcl_weight, weight_len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get channel list:%d", status); + return status; + } + + policy_mgr_debug("pcl len:%d", *len); + for (i = 0; i < *len; i++) { + policy_mgr_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); + } + + if ((mode == PM_SAP_MODE) && + policy_mgr_is_sap_mandatory_channel_set(psoc)) { + status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel( + psoc, pcl_channels, pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get modified pcl for SAP"); + return status; + } + policy_mgr_debug("modified pcl len:%d", *len); + for (i = 0; i < *len; i++) + policy_mgr_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); + + } + return QDF_STATUS_SUCCESS; } @@ -102,21 +300,763 @@ enum policy_mgr_conc_priority_mode policy_mgr_get_first_connection_pcl_table_index( struct wlan_objmgr_psoc *psoc) { - return PM_MAX_CONC_PRIORITY_MODE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("context is NULL"); + return PM_THROUGHPUT; + } + + if (pm_ctx->conc_system_pref >= PM_MAX_CONC_PRIORITY_MODE) + return PM_THROUGHPUT; + + return pm_ctx->conc_system_pref; } enum policy_mgr_one_connection_mode policy_mgr_get_second_connection_pcl_table_index( struct wlan_objmgr_psoc *psoc) { - return PM_MAX_ONE_CONNECTION_MODE; + enum policy_mgr_one_connection_mode index = PM_MAX_ONE_CONNECTION_MODE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return index; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (PM_STA_MODE == pm_conc_connection_list[0].mode) { + if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_24_1x1; + else + index = PM_STA_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_5_1x1; + else + index = PM_STA_5_2x2; + } + } else if (PM_SAP_MODE == pm_conc_connection_list[0].mode) { + if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_24_1x1; + else + index = PM_SAP_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_5_1x1; + else + index = PM_SAP_5_2x2; + } + } else if (PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) { + if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_24_1x1; + else + index = PM_P2P_CLI_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_5_1x1; + else + index = PM_P2P_CLI_5_2x2; + } + } else if (PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) { + if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_24_1x1; + else + index = PM_P2P_GO_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_5_1x1; + else + index = PM_P2P_GO_5_2x2; + } + } else if (PM_IBSS_MODE == pm_conc_connection_list[0].mode) { + if (WLAN_REG_IS_24GHZ_CH(pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_IBSS_24_1x1; + else + index = PM_IBSS_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_IBSS_5_1x1; + else + index = PM_IBSS_5_2x2; + } + } + + policy_mgr_debug("mode:%d chan:%d chain:%d index:%d", + pm_conc_connection_list[0].mode, + pm_conc_connection_list[0].chan, + pm_conc_connection_list[0].chain_mask, index); + + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_cli_sap(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_SAP_SCC_24_1x1; + else + index = PM_P2P_CLI_SAP_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_SAP_SCC_5_1x1; + else + index = PM_P2P_CLI_SAP_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_SAP_MCC_24_1x1; + else + index = PM_P2P_CLI_SAP_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_SAP_MCC_5_1x1; + else + index = PM_P2P_CLI_SAP_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_SAP_MCC_24_5_1x1; + else + index = PM_P2P_CLI_SAP_MCC_24_5_2x2; + } + /* SBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_SAP_SBS_5_1x1; + } + /* DBS */ + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_SAP_DBS_1x1; + else + index = PM_P2P_CLI_SAP_DBS_2x2; + } + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_sta_sap(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_SAP_SCC_24_1x1; + else + index = PM_STA_SAP_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_SAP_SCC_5_1x1; + else + index = PM_STA_SAP_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_SAP_MCC_24_1x1; + else + index = PM_STA_SAP_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_SAP_MCC_5_1x1; + else + index = PM_STA_SAP_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_SAP_MCC_24_5_1x1; + else + index = PM_STA_SAP_MCC_24_5_2x2; + } + /* SBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_SAP_SBS_5_1x1; + } + /* DBS */ + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_SAP_DBS_1x1; + else + index = PM_STA_SAP_DBS_2x2; + } + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_sap_sap(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_SAP_SCC_24_1x1; + else + index = PM_SAP_SAP_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_SAP_SCC_5_1x1; + else + index = PM_SAP_SAP_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_SAP_MCC_24_1x1; + else + index = PM_SAP_SAP_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_SAP_MCC_5_1x1; + else + index = PM_SAP_SAP_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_SAP_MCC_24_5_1x1; + else + index = PM_SAP_SAP_MCC_24_5_2x2; + } + /* SBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_SAP_SBS_5_1x1; + } + /* DBS */ + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_SAP_DBS_1x1; + else + index = PM_SAP_SAP_DBS_2x2; + } + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_sta_go(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + if (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_GO_SCC_24_1x1; + else + index = PM_STA_P2P_GO_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_GO_SCC_5_1x1; + else + index = PM_STA_P2P_GO_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_GO_MCC_24_1x1; + else + index = PM_STA_P2P_GO_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_GO_MCC_5_1x1; + else + index = PM_STA_P2P_GO_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_GO_MCC_24_5_1x1; + else + index = PM_STA_P2P_GO_MCC_24_5_2x2; + } + /* SBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_GO_SBS_5_1x1; + } + /* DBS */ + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_GO_DBS_1x1; + else + index = PM_STA_P2P_GO_DBS_2x2; + } + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_sta_cli(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + if (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_CLI_SCC_24_1x1; + else + index = PM_STA_P2P_CLI_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_CLI_SCC_5_1x1; + else + index = PM_STA_P2P_CLI_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_CLI_MCC_24_1x1; + else + index = PM_STA_P2P_CLI_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_CLI_MCC_5_1x1; + else + index = PM_STA_P2P_CLI_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_CLI_MCC_24_5_1x1; + else + index = PM_STA_P2P_CLI_MCC_24_5_2x2; + } + /* SBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_CLI_SBS_5_1x1; + } + /* DBS */ + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_CLI_DBS_1x1; + else + index = PM_STA_P2P_CLI_DBS_2x2; + } + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_go_cli(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_CLI_SCC_24_1x1; + else + index = PM_P2P_GO_P2P_CLI_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_CLI_SCC_5_1x1; + else + index = PM_P2P_GO_P2P_CLI_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_CLI_MCC_24_1x1; + else + index = PM_P2P_GO_P2P_CLI_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_CLI_MCC_5_1x1; + else + index = PM_P2P_GO_P2P_CLI_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_CLI_MCC_24_5_1x1; + else + index = PM_P2P_GO_P2P_CLI_MCC_24_5_2x2; + } + /* SBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_CLI_SBS_5_1x1; + } + /* DBS */ + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_CLI_DBS_1x1; + else + index = PM_P2P_GO_P2P_CLI_DBS_2x2; + } + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_go_sap(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_SAP_SCC_24_1x1; + else + index = PM_P2P_GO_SAP_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_SAP_SCC_5_1x1; + else + index = PM_P2P_GO_SAP_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_SAP_MCC_24_1x1; + else + index = PM_P2P_GO_SAP_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_SAP_MCC_5_1x1; + else + index = PM_P2P_GO_SAP_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_SAP_MCC_24_5_1x1; + else + index = PM_P2P_GO_SAP_MCC_24_5_2x2; + } + /* SBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_SAP_SBS_5_1x1; + } + /* DBS */ + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_SAP_DBS_1x1; + else + index = PM_P2P_GO_SAP_DBS_2x2; + } + + return index; +} + +static enum policy_mgr_two_connection_mode + policy_mgr_get_third_connection_pcl_table_index_sta_sta(void) +{ + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + /* SCC */ + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + if (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[0].chan)) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_STA_SCC_24_1x1; + else + index = PM_STA_STA_SCC_24_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_STA_SCC_5_1x1; + else + index = PM_STA_STA_SCC_5_2x2; + } + /* MCC */ + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_STA_MCC_24_1x1; + else + index = PM_STA_STA_MCC_24_2x2; + } else if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_STA_MCC_5_1x1; + else + index = PM_STA_STA_MCC_5_2x2; + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_STA_MCC_24_5_1x1; + else + index = PM_STA_STA_MCC_24_5_2x2; + } + /* SBS */ + } else if (pm_conc_connection_list[0].mac != + pm_conc_connection_list[1].mac) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[1].chan))) { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_STA_SBS_5_1x1; + } + /* DBS */ + } else { + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_STA_DBS_1x1; + else + index = PM_STA_STA_DBS_2x2; + } + + return index; } enum policy_mgr_two_connection_mode policy_mgr_get_third_connection_pcl_table_index( struct wlan_objmgr_psoc *psoc) { - return PM_MAX_TWO_CONNECTION_MODE; + enum policy_mgr_two_connection_mode index = PM_MAX_TWO_CONNECTION_MODE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return index; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) && + (PM_SAP_MODE == pm_conc_connection_list[1].mode)) || + ((PM_SAP_MODE == pm_conc_connection_list[0].mode) && + (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode))) + index = + policy_mgr_get_third_connection_pcl_table_index_cli_sap(); + else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && + (PM_SAP_MODE == pm_conc_connection_list[1].mode)) || + ((PM_SAP_MODE == pm_conc_connection_list[0].mode) && + (PM_STA_MODE == pm_conc_connection_list[1].mode))) + index = + policy_mgr_get_third_connection_pcl_table_index_sta_sap(); + else if ((PM_SAP_MODE == pm_conc_connection_list[0].mode) && + (PM_SAP_MODE == pm_conc_connection_list[1].mode)) + index = + policy_mgr_get_third_connection_pcl_table_index_sap_sap(); + else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && + (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)) || + ((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) && + (PM_STA_MODE == pm_conc_connection_list[1].mode))) + index = + policy_mgr_get_third_connection_pcl_table_index_sta_go(); + else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && + (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)) || + ((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) && + (PM_STA_MODE == pm_conc_connection_list[1].mode))) + index = + policy_mgr_get_third_connection_pcl_table_index_sta_cli(); + else if (((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) && + (PM_P2P_CLIENT_MODE == pm_conc_connection_list[1].mode)) || + ((PM_P2P_CLIENT_MODE == pm_conc_connection_list[0].mode) && + (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode))) + index = + policy_mgr_get_third_connection_pcl_table_index_go_cli(); + else if (((PM_SAP_MODE == pm_conc_connection_list[0].mode) && + (PM_P2P_GO_MODE == pm_conc_connection_list[1].mode)) || + ((PM_P2P_GO_MODE == pm_conc_connection_list[0].mode) && + (PM_SAP_MODE == pm_conc_connection_list[1].mode))) + index = + policy_mgr_get_third_connection_pcl_table_index_go_sap(); + else if (((PM_STA_MODE == pm_conc_connection_list[0].mode) && + (PM_STA_MODE == pm_conc_connection_list[1].mode)) || + ((PM_STA_MODE == pm_conc_connection_list[0].mode) && + (PM_STA_MODE == pm_conc_connection_list[1].mode))) + index = + policy_mgr_get_third_connection_pcl_table_index_sta_sta(); + + policy_mgr_debug("mode0:%d mode1:%d chan0:%d chan1:%d chain:%d index:%d", + pm_conc_connection_list[0].mode, + pm_conc_connection_list[1].mode, + pm_conc_connection_list[0].chan, + pm_conc_connection_list[1].chan, + pm_conc_connection_list[0].chain_mask, index); + + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return index; } uint8_t @@ -124,30 +1064,144 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, bool for_existing_conn) { - return 0; + uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; + uint8_t pcl_weight[QDF_MAX_NUM_CHAN]; + + /* + * in worst case if we can't find any channel at all + * then return 2.4G channel, so atleast we won't fall + * under 5G MCC scenario + */ + uint8_t channel = PM_24_GHZ_CHANNEL_6; + uint32_t i, pcl_len; + + if (true == for_existing_conn) { + /* + * First try to see if there is any non-dfs channel already + * present in current connection table. If yes then return + * that channel + */ + if (true == policy_mgr_is_any_nondfs_chnl_present( + psoc, &channel)) + return channel; + + if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl_for_existing_conn( + psoc, mode, + &pcl_channels[0], &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) + return channel; + } else { + if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl(psoc, mode, + &pcl_channels[0], &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) + return channel; + } + + for (i = 0; i < pcl_len; i++) { + if (wlan_reg_is_dfs_ch(psoc, pcl_channels[i])) { + continue; + } else { + channel = pcl_channels[i]; + break; + } + } + + return channel; } QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, uint8_t *chan_list, uint32_t *list_len) { + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + *list_len = 0; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (!pm_ctx->sme_cbacks.sme_get_valid_channels) { + policy_mgr_err("sme_get_valid_chans callback is NULL"); + return QDF_STATUS_E_FAILURE; + } + + *list_len = QDF_MAX_NUM_CHAN; + status = pm_ctx->sme_cbacks.sme_get_valid_channels( + chan_list, list_len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Error in getting valid channels"); + *list_len = 0; + return status; + } + return QDF_STATUS_SUCCESS; } bool policy_mgr_list_has_24GHz_channel(uint8_t *channel_list, uint32_t list_len) { + uint32_t i; + + for (i = 0; i < list_len; i++) { + if (WLAN_REG_IS_24GHZ_CH(channel_list[i])) + return true; + } + return false; } QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, uint8_t *channels, uint32_t len) { + uint32_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (!len) { + policy_mgr_err("No mandatory freq/chan configured"); + return QDF_STATUS_E_FAILURE; + } + + if (!policy_mgr_list_has_24GHz_channel(channels, len)) { + policy_mgr_err("2.4GHz channels missing, this is not expected"); + return QDF_STATUS_E_FAILURE; + } + + policy_mgr_debug("mandatory chan length:%d", + pm_ctx->sap_mandatory_channels_len); + + for (i = 0; i < len; i++) { + pm_ctx->sap_mandatory_channels[i] = channels[i]; + policy_mgr_debug("chan:%d", pm_ctx->sap_mandatory_channels[i]); + } + + pm_ctx->sap_mandatory_channels_len = len; + return QDF_STATUS_SUCCESS; } bool policy_mgr_is_sap_mandatory_channel_set(struct wlan_objmgr_psoc *psoc) { - return false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + if (pm_ctx->sap_mandatory_channels_len) + return true; + else + return false; } QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( @@ -156,17 +1210,161 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( uint8_t *weight_list_org, uint32_t *pcl_len_org) { + uint32_t i, j, pcl_len = 0; + uint8_t pcl_list[QDF_MAX_NUM_CHAN]; + uint8_t weight_list[QDF_MAX_NUM_CHAN]; + bool found; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (!pm_ctx->sap_mandatory_channels_len) + return QDF_STATUS_SUCCESS; + + if (!policy_mgr_list_has_24GHz_channel(pm_ctx->sap_mandatory_channels, + pm_ctx->sap_mandatory_channels_len)) { + policy_mgr_err("fav channel list is missing 2.4GHz channels"); + return QDF_STATUS_E_FAILURE; + } + + for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) + policy_mgr_debug("fav chan:%d", + pm_ctx->sap_mandatory_channels[i]); + + for (i = 0; i < *pcl_len_org; i++) { + found = false; + for (j = 0; j < pm_ctx->sap_mandatory_channels_len; j++) { + if (pcl_list_org[i] == + pm_ctx->sap_mandatory_channels[j]) { + found = true; + break; + } + } + if (found) { + pcl_list[pcl_len] = pcl_list_org[i]; + weight_list[pcl_len++] = weight_list_org[i]; + } + } + + qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org)); + qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org)); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); + qdf_mem_copy(weight_list_org, weight_list, pcl_len); + *pcl_len_org = pcl_len; + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, uint32_t *chan) { + QDF_STATUS status; + struct policy_mgr_pcl_list pcl; + + qdf_mem_zero(&pcl, sizeof(pcl)); + + status = policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, + pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Unable to get PCL for SAP"); + return status; + } + + /* No existing SAP connection and hence a new SAP connection might be + * coming up. + */ + if (!pcl.pcl_len) { + policy_mgr_notice("policy_mgr_get_pcl_for_existing_conn returned no pcl"); + status = policy_mgr_get_pcl(psoc, PM_SAP_MODE, + pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, + QDF_ARRAY_SIZE(pcl.weight_list)); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Unable to get PCL for SAP: policy_mgr_get_pcl"); + return status; + } + } + + status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel( + psoc, pcl.pcl_list, + pcl.weight_list, + &pcl.pcl_len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Unable to modify SAP PCL"); + return status; + } + + *chan = pcl.pcl_list[0]; + policy_mgr_notice("mandatory channel:%d", *chan); + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, struct policy_mgr_pcl_chan_weights *weight) { + uint32_t i, j; + struct policy_mgr_conc_connection_info info; + + if (!weight->pcl_list) { + policy_mgr_err("Invalid pcl"); + return QDF_STATUS_E_FAILURE; + } + + if (!weight->saved_chan_list) { + policy_mgr_err("Invalid valid channel list"); + return QDF_STATUS_E_FAILURE; + } + + if (!weight->weighed_valid_list) { + policy_mgr_err("Invalid weighed valid channel list"); + return QDF_STATUS_E_FAILURE; + } + + qdf_mem_set(weight->weighed_valid_list, QDF_MAX_NUM_CHAN, + WEIGHT_OF_DISALLOWED_CHANNELS); + + if (policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, NULL) > 0) { + /* + * Store the STA mode's parameter and temporarily delete it + * from the concurrency table. This way the allow concurrency + * check can be used as though a new connection is coming up, + * allowing to detect the disallowed channels. + */ + policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, &info); + /* + * There is a small window between releasing the above lock + * and acquiring the same in policy_mgr_allow_concurrency, + * below! + */ + for (i = 0; i < weight->saved_num_chan; i++) { + if (policy_mgr_allow_concurrency(psoc, PM_STA_MODE, + weight->saved_chan_list[i], + HW_MODE_20_MHZ)) { + weight->weighed_valid_list[i] = + WEIGHT_OF_NON_PCL_CHANNELS; + } + } + + /* Restore the connection info */ + policy_mgr_restore_deleted_conn_info(psoc, &info); + } + + for (i = 0; i < weight->saved_num_chan; i++) { + for (j = 0; j < weight->pcl_len; j++) { + if (weight->saved_chan_list[i] == weight->pcl_list[j]) { + weight->weighed_valid_list[i] = + weight->weight_list[j]; + break; + } + } + } + return QDF_STATUS_SUCCESS; } From 3ee7f1f818ad4006864e24ebc1ecd0b904eb308b Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 7 Mar 2017 20:58:50 -0800 Subject: [PATCH 009/404] qcacmn: Define core functions of policy manager component Define core functions for policy manager component. Change-Id: Ifc9bc2165065226757cd4aa379a205870b2a2174 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_core.c | 2036 +++++++++++++++++++++++++++++++++++- src/wlan_policy_mgr_i.h | 1 + 2 files changed, 2016 insertions(+), 21 deletions(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 379a04bd2349..8aed7d8c994f 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -76,11 +76,28 @@ QDF_STATUS policy_mgr_get_updated_scan_config( bool dbs_plus_agile_scan, bool single_mac_scan_with_dfs) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + *scan_config = pm_ctx->dual_mac_cfg.cur_scan_config; + + WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(*scan_config, dbs_scan); + WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET(*scan_config, + dbs_plus_agile_scan); + WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET(*scan_config, + single_mac_scan_with_dfs); + + policy_mgr_debug("scan_config:%x ", *scan_config); return QDF_STATUS_SUCCESS; } /** - * policy_mgr_get_updated_fw_mode_config() - Get the updated fw mode configuration + * policy_mgr_get_updated_fw_mode_config() - Get the updated fw + * mode configuration * @fw_mode_config: Pointer containing the updated fw mode config * @dbs: 0 or 1 indicating if DBS needs to be enabled/disabled * @agile_dfs: 0 or 1 indicating if agile DFS needs to be enabled/disabled @@ -97,11 +114,25 @@ QDF_STATUS policy_mgr_get_updated_fw_mode_config( bool dbs, bool agile_dfs) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + *fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config; + + WMI_DBS_FW_MODE_CFG_DBS_SET(*fw_mode_config, dbs); + WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET(*fw_mode_config, agile_dfs); + + policy_mgr_debug("fw_mode_config:%x ", *fw_mode_config); return QDF_STATUS_SUCCESS; } /** - * policy_mgr_is_dual_mac_disabled_in_ini() - Check if dual mac is disabled in INI + * policy_mgr_is_dual_mac_disabled_in_ini() - Check if dual mac + * is disabled in INI * * Checks if the dual mac feature is disabled in INI * @@ -110,7 +141,7 @@ QDF_STATUS policy_mgr_get_updated_fw_mode_config( bool policy_mgr_is_dual_mac_disabled_in_ini( struct wlan_objmgr_psoc *psoc) { - return false; + return wlan_objmgr_psoc_get_dual_mac_disable(psoc); } /** @@ -122,7 +153,22 @@ bool policy_mgr_is_dual_mac_disabled_in_ini( */ bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc) { - return false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t fw_mode_config; + + if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) + return false; + + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + /* We take that it is disabled and proceed */ + return false; + } + fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config; + + return WMI_DBS_FW_MODE_CFG_DBS_GET(fw_mode_config); } /** @@ -134,7 +180,22 @@ bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc) */ bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc) { - return false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t fw_mode_config; + + if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) + return false; + + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + /* We take that it is disabled and proceed */ + return false; + } + fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config; + + return WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_mode_config); } /** @@ -146,11 +207,27 @@ bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc) */ bool policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc *psoc) { - return false; + uint32_t scan_config; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) + return false; + + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + /* We take that it is disabled and proceed */ + return false; + } + scan_config = pm_ctx->dual_mac_cfg.cur_scan_config; + + return WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config); } /** - * policy_mgr_get_tx_rx_ss_from_config() - Get Tx/Rx spatial stream from HW mode config + * policy_mgr_get_tx_rx_ss_from_config() - Get Tx/Rx spatial + * stream from HW mode config * @mac_ss: Config which indicates the HW mode as per 'hw_mode_ss_config' * @tx_ss: Contains the Tx spatial stream * @rx_ss: Contains the Rx spatial stream @@ -217,7 +294,75 @@ int8_t policy_mgr_get_matching_hw_mode_index( enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs) { - return 0; + uint32_t i; + uint32_t t_mac0_tx_ss, t_mac0_rx_ss, t_mac0_bw; + uint32_t t_mac1_tx_ss, t_mac1_rx_ss, t_mac1_bw; + uint32_t dbs_mode, agile_dfs_mode, sbs_mode; + int8_t found = -EINVAL; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return found; + } + + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + t_mac0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (t_mac0_tx_ss != mac0_tx_ss) + continue; + + t_mac0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (t_mac0_rx_ss != mac0_rx_ss) + continue; + + t_mac0_bw = POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + /* + * Firmware advertises max bw capability as CBW 80+80 + * for single MAC. Thus CBW 20/40/80 should also be + * supported, if CBW 80+80 is supported. + */ + if (t_mac0_bw < mac0_bw) + continue; + + t_mac1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (t_mac1_tx_ss != mac1_tx_ss) + continue; + + t_mac1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (t_mac1_rx_ss != mac1_rx_ss) + continue; + + t_mac1_bw = POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (t_mac1_bw < mac1_bw) + continue; + + dbs_mode = POLICY_MGR_HW_MODE_DBS_MODE_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (dbs_mode != dbs) + continue; + + agile_dfs_mode = POLICY_MGR_HW_MODE_AGILE_DFS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (agile_dfs_mode != dfs) + continue; + + sbs_mode = POLICY_MGR_HW_MODE_SBS_MODE_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (sbs_mode != sbs) + continue; + + found = i; + policy_mgr_notice("hw_mode index %d found", i); + break; + } + return found; } /** @@ -245,7 +390,25 @@ int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list( enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs) { - return 0; + uint32_t mac0_tx_ss, mac0_rx_ss; + uint32_t mac1_tx_ss, mac1_rx_ss; + + policy_mgr_get_tx_rx_ss_from_config(mac0_ss, &mac0_tx_ss, &mac0_rx_ss); + policy_mgr_get_tx_rx_ss_from_config(mac1_ss, &mac1_tx_ss, &mac1_rx_ss); + + policy_mgr_notice("MAC0: TxSS=%d, RxSS=%d, BW=%d", + mac0_tx_ss, mac0_rx_ss, mac0_bw); + policy_mgr_notice("MAC1: TxSS=%d, RxSS=%d, BW=%d", + mac1_tx_ss, mac1_rx_ss, mac1_bw); + policy_mgr_notice("DBS=%d, Agile DFS=%d, SBS=%d", + dbs, dfs, sbs); + + return policy_mgr_get_matching_hw_mode_index(psoc, mac0_tx_ss, + mac0_rx_ss, + mac0_bw, + mac1_tx_ss, mac1_rx_ss, + mac1_bw, + dbs, dfs, sbs); } /** @@ -262,6 +425,37 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx( uint32_t idx, struct policy_mgr_hw_mode_params *hw_mode) { + uint32_t param; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (idx > pm_ctx->num_dbs_hw_modes) { + policy_mgr_err("Invalid index"); + return QDF_STATUS_E_FAILURE; + } + + if (!pm_ctx->num_dbs_hw_modes) { + policy_mgr_err("No dbs hw modes available"); + return QDF_STATUS_E_FAILURE; + } + + param = pm_ctx->hw_mode.hw_mode_list[idx]; + + hw_mode->mac0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param); + hw_mode->mac0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param); + hw_mode->mac0_bw = POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param); + hw_mode->mac1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param); + hw_mode->mac1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param); + hw_mode->mac1_bw = POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param); + hw_mode->dbs_cap = POLICY_MGR_HW_MODE_DBS_MODE_GET(param); + hw_mode->agile_dfs_cap = POLICY_MGR_HW_MODE_AGILE_DFS_GET(param); + hw_mode->sbs_cap = POLICY_MGR_HW_MODE_SBS_MODE_GET(param); + return QDF_STATUS_SUCCESS; } @@ -283,6 +477,17 @@ QDF_STATUS policy_mgr_get_old_and_new_hw_index( uint32_t *old_hw_mode_index, uint32_t *new_hw_mode_index) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_INVAL; + } + + *old_hw_mode_index = pm_ctx->old_hw_mode_index; + *new_hw_mode_index = pm_ctx->new_hw_mode_index; + return QDF_STATUS_SUCCESS; } @@ -312,6 +517,32 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, bool in_use) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + if (conn_index >= MAX_NUMBER_OF_CONC_CONNECTIONS) { + policy_mgr_err("Number of connections exceeded conn_index: %d", + conn_index); + return; + } + pm_conc_connection_list[conn_index].mode = mode; + pm_conc_connection_list[conn_index].chan = chan; + pm_conc_connection_list[conn_index].bw = bw; + pm_conc_connection_list[conn_index].mac = mac; + pm_conc_connection_list[conn_index].chain_mask = chain_mask; + pm_conc_connection_list[conn_index].original_nss = original_nss; + pm_conc_connection_list[conn_index].vdev_id = vdev_id; + pm_conc_connection_list[conn_index].in_use = in_use; + + policy_mgr_dump_connection_status_info(psoc); + if (pm_ctx->cdp_cbacks.cdp_update_mac_id) + pm_ctx->cdp_cbacks.cdp_update_mac_id(psoc, vdev_id, mac); + } /** @@ -329,6 +560,42 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, struct policy_mgr_conc_connection_info *info) { + uint32_t conn_index = 0; + bool found = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (mode == pm_conc_connection_list[conn_index].mode) { + found = true; + break; + } + conn_index++; + } + + if (!found) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_err("Mode:%d not available in the conn info", mode); + return; + } + + /* Storing the STA entry which will be temporarily deleted */ + *info = pm_conc_connection_list[conn_index]; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + /* Deleting the STA entry */ + policy_mgr_decr_connection_count(psoc, info->vdev_id); + + policy_mgr_notice("Stored %d (%d), deleted STA entry with vdev id %d, index %d", + info->vdev_id, info->mode, info->vdev_id, conn_index); + + /* Caller should set the PCL and restore the STA entry in conn info */ } /** @@ -343,10 +610,33 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, struct policy_mgr_conc_connection_info *info) { + uint32_t conn_index; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + conn_index = policy_mgr_get_connection_count(psoc); + if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) { + policy_mgr_err("Failed to restore the deleted information %d/%d", + conn_index, MAX_NUMBER_OF_CONC_CONNECTIONS); + return; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + pm_conc_connection_list[conn_index] = *info; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + policy_mgr_notice("Restored the deleleted conn info, vdev:%d, index:%d", + info->vdev_id, conn_index); } /** - * policy_mgr_update_hw_mode_conn_info() - Update connection info based on HW mode + * policy_mgr_update_hw_mode_conn_info() - Update connection + * info based on HW mode * @num_vdev_mac_entries: Number of vdev-mac id entries that follow * @vdev_mac_map: Mapping of vdev-mac id * @hw_mode: HW mode @@ -360,6 +650,42 @@ void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc, struct policy_mgr_vdev_mac_map *vdev_mac_map, struct policy_mgr_hw_mode_params hw_mode) { + uint32_t i, conn_index, found; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < num_vdev_mac_entries; i++) { + conn_index = 0; + found = 0; + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (vdev_mac_map[i].vdev_id == + pm_conc_connection_list[conn_index].vdev_id) { + found = 1; + break; + } + conn_index++; + } + if (found) { + pm_conc_connection_list[conn_index].mac = + vdev_mac_map[i].mac_id; + policy_mgr_notice("vdev:%d, mac:%d", + pm_conc_connection_list[conn_index].vdev_id, + pm_conc_connection_list[conn_index].mac); + if (pm_ctx->cdp_cbacks.cdp_update_mac_id) + pm_ctx->cdp_cbacks.cdp_update_mac_id( + psoc, + vdev_mac_map[i].vdev_id, + vdev_mac_map[i].mac_id); + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_dump_connection_status_info(psoc); } /** @@ -381,6 +707,278 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, struct policy_mgr_vdev_mac_map *vdev_mac_map, void *context) { + QDF_STATUS ret; + struct policy_mgr_hw_mode_params hw_mode; + uint32_t i; + + if (status != SET_HW_MODE_STATUS_OK) { + policy_mgr_err("Set HW mode failed with status %d", status); + return; + } + + if (!vdev_mac_map) { + policy_mgr_err("vdev_mac_map is NULL"); + return; + } + + policy_mgr_notice("cfgd_hw_mode_index=%d", cfgd_hw_mode_index); + + for (i = 0; i < num_vdev_mac_entries; i++) + policy_mgr_notice("vdev_id:%d mac_id:%d", + vdev_mac_map[i].vdev_id, + vdev_mac_map[i].mac_id); + + ret = policy_mgr_get_hw_mode_from_idx(context, cfgd_hw_mode_index, + &hw_mode); + if (ret != QDF_STATUS_SUCCESS) { + policy_mgr_err("Get HW mode failed: %d", ret); + return; + } + + policy_mgr_notice("MAC0: TxSS:%d, RxSS:%d, Bw:%d", + hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, hw_mode.mac0_bw); + policy_mgr_notice("MAC1: TxSS:%d, RxSS:%d, Bw:%d", + hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, hw_mode.mac1_bw); + policy_mgr_notice("DBS:%d, Agile DFS:%d, SBS:%d", + hw_mode.dbs_cap, hw_mode.agile_dfs_cap, hw_mode.sbs_cap); + + /* update pm_conc_connection_list */ + policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries, + vdev_mac_map, + hw_mode); + + ret = policy_mgr_set_connection_update(context); + if (!QDF_IS_STATUS_SUCCESS(ret)) + policy_mgr_err("ERROR: set connection_update_done event failed"); + + return; +} + +/** + * policy_mgr_dump_current_concurrency_one_connection() - To dump the + * current concurrency info with one connection + * @cc_mode: connection string + * @length: Maximum size of the string + * + * This routine is called to dump the concurrency info + * + * Return: length of the string + */ +static uint32_t policy_mgr_dump_current_concurrency_one_connection( + char *cc_mode, uint32_t length) +{ + uint32_t count = 0; + enum policy_mgr_con_mode mode; + + mode = pm_conc_connection_list[0].mode; + + switch (mode) { + case PM_STA_MODE: + count = strlcat(cc_mode, "STA", + length); + break; + case PM_SAP_MODE: + count = strlcat(cc_mode, "SAP", + length); + break; + case PM_P2P_CLIENT_MODE: + count = strlcat(cc_mode, "P2P CLI", + length); + break; + case PM_P2P_GO_MODE: + count = strlcat(cc_mode, "P2P GO", + length); + break; + case PM_IBSS_MODE: + count = strlcat(cc_mode, "IBSS", + length); + break; + default: + policy_mgr_err("unexpected mode %d", mode); + break; + } + + return count; +} + +/** + * policy_mgr_dump_current_concurrency_two_connection() - To dump the + * current concurrency info with two connections + * @cc_mode: connection string + * @length: Maximum size of the string + * + * This routine is called to dump the concurrency info + * + * Return: length of the string + */ +static uint32_t policy_mgr_dump_current_concurrency_two_connection( + char *cc_mode, uint32_t length) +{ + uint32_t count = 0; + enum policy_mgr_con_mode mode; + + mode = pm_conc_connection_list[1].mode; + + switch (mode) { + case PM_STA_MODE: + count = policy_mgr_dump_current_concurrency_one_connection( + cc_mode, length); + count += strlcat(cc_mode, "+STA", + length); + break; + case PM_SAP_MODE: + count = policy_mgr_dump_current_concurrency_one_connection( + cc_mode, length); + count += strlcat(cc_mode, "+SAP", + length); + break; + case PM_P2P_CLIENT_MODE: + count = policy_mgr_dump_current_concurrency_one_connection( + cc_mode, length); + count += strlcat(cc_mode, "+P2P CLI", + length); + break; + case PM_P2P_GO_MODE: + count = policy_mgr_dump_current_concurrency_one_connection( + cc_mode, length); + count += strlcat(cc_mode, "+P2P GO", + length); + break; + case PM_IBSS_MODE: + count = policy_mgr_dump_current_concurrency_one_connection( + cc_mode, length); + count += strlcat(cc_mode, "+IBSS", + length); + break; + default: + policy_mgr_err("unexpected mode %d", mode); + break; + } + + return count; +} + +/** + * policy_mgr_dump_current_concurrency_three_connection() - To dump the + * current concurrency info with three connections + * @cc_mode: connection string + * @length: Maximum size of the string + * + * This routine is called to dump the concurrency info + * + * Return: length of the string + */ +static uint32_t policy_mgr_dump_current_concurrency_three_connection( + char *cc_mode, uint32_t length) +{ + uint32_t count = 0; + enum policy_mgr_con_mode mode; + + mode = pm_conc_connection_list[2].mode; + + switch (mode) { + case PM_STA_MODE: + count = policy_mgr_dump_current_concurrency_two_connection( + cc_mode, length); + count += strlcat(cc_mode, "+STA", + length); + break; + case PM_SAP_MODE: + count = policy_mgr_dump_current_concurrency_two_connection( + cc_mode, length); + count += strlcat(cc_mode, "+SAP", + length); + break; + case PM_P2P_CLIENT_MODE: + count = policy_mgr_dump_current_concurrency_two_connection( + cc_mode, length); + count += strlcat(cc_mode, "+P2P CLI", + length); + break; + case PM_P2P_GO_MODE: + count = policy_mgr_dump_current_concurrency_two_connection( + cc_mode, length); + count += strlcat(cc_mode, "+P2P GO", + length); + break; + case PM_IBSS_MODE: + count = policy_mgr_dump_current_concurrency_two_connection( + cc_mode, length); + count += strlcat(cc_mode, "+IBSS", + length); + break; + default: + policy_mgr_err("unexpected mode %d", mode); + break; + } + + return count; +} + +/** + * policy_mgr_dump_dbs_concurrency() - To dump the dbs concurrency + * combination + * @cc_mode: connection string + * + * This routine is called to dump the concurrency info + * + * Return: None + */ +static void policy_mgr_dump_dbs_concurrency(struct wlan_objmgr_psoc *psoc, + char *cc_mode, uint32_t length) +{ + char buf[4] = {0}; + uint8_t mac = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + strlcat(cc_mode, " DBS", length); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) + strlcat(cc_mode, + " with SCC for 1st two connections on mac ", + length); + else + strlcat(cc_mode, + " with MCC for 1st two connections on mac ", + length); + mac = pm_conc_connection_list[0].mac; + } + if (pm_conc_connection_list[0].mac == pm_conc_connection_list[2].mac) { + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[2].chan) + strlcat(cc_mode, + " with SCC for 1st & 3rd connections on mac ", + length); + else + strlcat(cc_mode, + " with MCC for 1st & 3rd connections on mac ", + length); + mac = pm_conc_connection_list[0].mac; + } + if (pm_conc_connection_list[1].mac == pm_conc_connection_list[2].mac) { + if (pm_conc_connection_list[1].chan == + pm_conc_connection_list[2].chan) + strlcat(cc_mode, + " with SCC for 2nd & 3rd connections on mac ", + length); + else + strlcat(cc_mode, + " with MCC for 2nd & 3rd connections on mac ", + length); + mac = pm_conc_connection_list[1].mac; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + snprintf(buf, sizeof(buf), "%d ", mac); + strlcat(cc_mode, buf, length); } /** @@ -393,6 +991,72 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, */ void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc) { + uint32_t num_connections = 0; + char cc_mode[POLICY_MGR_MAX_CON_STRING_LEN] = {0}; + uint32_t count = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + num_connections = policy_mgr_get_connection_count(psoc); + + switch (num_connections) { + case 1: + policy_mgr_dump_current_concurrency_one_connection(cc_mode, + sizeof(cc_mode)); + policy_mgr_err("%s Standalone", cc_mode); + break; + case 2: + count = policy_mgr_dump_current_concurrency_two_connection( + cc_mode, sizeof(cc_mode)); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) { + strlcat(cc_mode, " SCC", sizeof(cc_mode)); + } else if (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) { + strlcat(cc_mode, " MCC", sizeof(cc_mode)); + } else + strlcat(cc_mode, " DBS", sizeof(cc_mode)); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_err("%s", cc_mode); + break; + case 3: + count = policy_mgr_dump_current_concurrency_three_connection( + cc_mode, sizeof(cc_mode)); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if ((pm_conc_connection_list[0].chan == + pm_conc_connection_list[1].chan) && + (pm_conc_connection_list[0].chan == + pm_conc_connection_list[2].chan)){ + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + strlcat(cc_mode, " SCC", + sizeof(cc_mode)); + } else if ((pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) + && (pm_conc_connection_list[0].mac == + pm_conc_connection_list[2].mac)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + strlcat(cc_mode, " MCC on single MAC", + sizeof(cc_mode)); + } else { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_dump_dbs_concurrency(psoc, cc_mode, + sizeof(cc_mode)); + } + policy_mgr_err("%s", cc_mode); + break; + default: + policy_mgr_err("unexpected num_connections value %d", + num_connections); + break; + } + + return; } /** @@ -408,6 +1072,55 @@ void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc) void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, enum tQDF_ADAPTER_MODE mode) { + QDF_STATUS status; + enum policy_mgr_con_mode con_mode; + struct policy_mgr_pcl_list pcl; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + pcl.pcl_len = 0; + + switch (mode) { + case QDF_STA_MODE: + con_mode = PM_STA_MODE; + break; + case QDF_P2P_CLIENT_MODE: + con_mode = PM_P2P_CLIENT_MODE; + break; + case QDF_P2P_GO_MODE: + con_mode = PM_P2P_GO_MODE; + break; + case QDF_SAP_MODE: + con_mode = PM_SAP_MODE; + break; + case QDF_IBSS_MODE: + con_mode = PM_IBSS_MODE; + break; + default: + policy_mgr_err("Unable to set PCL to FW: %d", mode); + return; + } + + policy_mgr_debug("get pcl to set it to the FW"); + + status = policy_mgr_get_pcl(psoc, con_mode, + pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Unable to set PCL to FW, Get PCL failed"); + return; + } + + status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(pcl); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Send soc set PCL to SME failed"); + else + policy_mgr_notice("Set PCL to FW for mode:%d", mode); } @@ -422,6 +1135,39 @@ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, void policy_mgr_set_pcl_for_existing_combo( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) { + struct policy_mgr_conc_connection_info info; + enum tQDF_ADAPTER_MODE pcl_mode; + + switch (mode) { + case PM_STA_MODE: + pcl_mode = QDF_STA_MODE; + break; + case PM_SAP_MODE: + pcl_mode = QDF_SAP_MODE; + break; + case PM_P2P_CLIENT_MODE: + pcl_mode = QDF_P2P_CLIENT_MODE; + break; + case PM_P2P_GO_MODE: + pcl_mode = QDF_P2P_GO_MODE; + break; + case PM_IBSS_MODE: + pcl_mode = QDF_IBSS_MODE; + break; + default: + policy_mgr_err("Invalid mode to set PCL"); + return; + }; + + if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { + /* Check, store and temp delete the mode's parameter */ + policy_mgr_store_and_del_conn_info(psoc, mode, &info); + /* Set the PCL to the FW since connection got updated */ + policy_mgr_pdev_set_pcl(psoc, pcl_mode); + policy_mgr_notice("Set PCL to FW for mode:%d", mode); + /* Restore the connection info */ + policy_mgr_restore_deleted_conn_info(psoc, &info); + } } /** @@ -435,6 +1181,60 @@ void policy_mgr_set_pcl_for_existing_combo( */ void pm_dbs_opportunistic_timer_handler(void *data) { + enum policy_mgr_conc_next_action action = PM_NOP; + struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)data; + + if (!psoc) { + policy_mgr_err("Invalid Context"); + return; + } + + /* if we still need it */ + action = policy_mgr_need_opportunistic_upgrade(psoc); + policy_mgr_notice("action:%d", action); + if (action) { + /* lets call for action */ + /* session id is being used only + * in hidden ssid case for now. + * So, session id 0 is ok here. + */ + policy_mgr_next_actions(psoc, 0, action, + POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC); + } +} + +/** + * policy_mgr_get_connection_for_vdev_id() - provides the + * perticular connection with the requested vdev id + * @vdev_id: vdev id of the connection + * + * This function provides the specific connection with the + * requested vdev id + * + * Return: index in the connection table + */ +static uint32_t policy_mgr_get_connection_for_vdev_id( + struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) +{ + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return conn_index; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) && + pm_conc_connection_list[conn_index].in_use) { + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return conn_index; } /** @@ -450,7 +1250,347 @@ void pm_dbs_opportunistic_timer_handler(void *data) enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type, uint8_t subtype) { - return PM_MAX_NUM_OF_MODE; + enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE; + + if (type == WMI_VDEV_TYPE_AP) { + switch (subtype) { + case 0: + mode = PM_SAP_MODE; + break; + case WMI_UNIFIED_VDEV_SUBTYPE_P2P_GO: + mode = PM_P2P_GO_MODE; + break; + default: + policy_mgr_err("Unknown subtype %d for type %d", + subtype, type); + break; + } + } else if (type == WMI_VDEV_TYPE_STA) { + switch (subtype) { + case 0: + mode = PM_STA_MODE; + break; + case WMI_UNIFIED_VDEV_SUBTYPE_P2P_CLIENT: + mode = PM_P2P_CLIENT_MODE; + break; + default: + policy_mgr_err("Unknown subtype %d for type %d", + subtype, type); + break; + } + } else if (type == WMI_VDEV_TYPE_IBSS) { + mode = PM_IBSS_MODE; + } else { + policy_mgr_err("Unknown type %d", type); + } + + return mode; +} + +/** + * policy_mgr_get_bw() - Get channel bandwidth type used by WMI + * @chan_width: channel bandwidth type defined by host + * + * Get the channel bandwidth type used by WMI + * + * Return: hw_mode_bandwidth + */ +enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width) +{ + enum hw_mode_bandwidth bw = HW_MODE_BW_NONE; + + switch (chan_width) { + case CH_WIDTH_20MHZ: + bw = HW_MODE_20_MHZ; + break; + case CH_WIDTH_40MHZ: + bw = HW_MODE_40_MHZ; + break; + case CH_WIDTH_80MHZ: + bw = HW_MODE_80_MHZ; + break; + case CH_WIDTH_160MHZ: + bw = HW_MODE_160_MHZ; + break; + case CH_WIDTH_80P80MHZ: + bw = HW_MODE_80_PLUS_80_MHZ; + break; + case CH_WIDTH_5MHZ: + bw = HW_MODE_5_MHZ; + break; + case CH_WIDTH_10MHZ: + bw = HW_MODE_10_MHZ; + break; + default: + policy_mgr_err("Unknown channel BW type %d", chan_width); + break; + } + + return bw; +} + +/** + * policy_mgr_get_sbs_channels() - provides the sbs channel(s) + * with respect to current connection(s) + * @channels: the channel(s) on which current connection(s) is + * @len: Number of channels + * @pcl_weight: Pointer to the weights of PCL + * @weight_len: Max length of the weight list + * @index: Index from which the weight list needs to be populated + * @group_id: Next available groups for weight assignment + * @available_5g_channels: List of available 5g channels + * @available_5g_channels_len: Length of the 5g channels list + * @add_5g_channels: If this flag is true append 5G channel list as well + * + * This function provides the channel(s) on which current + * connection(s) is/are + * + * Return: QDF_STATUS + */ + +static QDF_STATUS policy_mgr_get_sbs_channels(uint8_t *channels, + uint32_t *len, uint8_t *pcl_weight, uint32_t weight_len, + uint32_t *index, enum policy_mgr_pcl_group_id group_id, + uint8_t *available_5g_channels, + uint32_t available_5g_channels_len, + bool add_5g_channels) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint32_t conn_index = 0, num_channels = 0; + uint32_t num_5g_channels = 0, cur_5g_channel = 0; + uint8_t remaining_5g_Channels[QDF_MAX_NUM_CHAN] = {}; + uint32_t remaining_channel_index = 0; + uint32_t j = 0, i = 0, weight1, weight2; + + if ((NULL == channels) || (NULL == len)) { + policy_mgr_err("channels or len is NULL"); + status = QDF_STATUS_E_FAILURE; + return status; + } + + if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) { + weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS; + } else if (group_id == POLICY_MGR_PCL_GROUP_ID2_ID3) { + weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS; + } else { + weight1 = WEIGHT_OF_GROUP3_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP4_PCL_CHANNELS; + } + + policy_mgr_debug("weight1=%d weight2=%d index=%d ", + weight1, weight2, *index); + + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if ((WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[conn_index].chan)) + && (pm_conc_connection_list[conn_index].in_use)) { + num_5g_channels++; + cur_5g_channel = + pm_conc_connection_list[conn_index].chan; + } + conn_index++; + } + + conn_index = 0; + if (num_5g_channels > 1) { + /* This case we are already in SBS so return the channels */ + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + channels[num_channels++] = + pm_conc_connection_list[conn_index++].chan; + if (*index < weight_len) + pcl_weight[(*index)++] = weight1; + } + *len = num_channels; + /* fix duplicate issue later */ + if (add_5g_channels) + for (j = 0; j < available_5g_channels_len; j++) + remaining_5g_Channels[ + remaining_channel_index++] = + available_5g_channels[j]; + } else { + /* Get list of valid sbs channels for the current + * connected channel + */ + for (j = 0; j < available_5g_channels_len; j++) { + if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS( + cur_5g_channel, available_5g_channels[j])) { + channels[num_channels++] = + available_5g_channels[j]; + } else { + remaining_5g_Channels[ + remaining_channel_index++] = + available_5g_channels[j]; + continue; + } + if (*index < weight_len) + pcl_weight[(*index)++] = weight1; + } + *len = num_channels; + } + + if (add_5g_channels) { + qdf_mem_copy(channels+num_channels, remaining_5g_Channels, + remaining_channel_index); + *len += remaining_channel_index; + for (i = 0; ((i < remaining_channel_index) + && (i < weight_len)); i++) + pcl_weight[i] = weight2; + } + + return status; +} + + +/** + * policy_mgr_get_connection_channels() - provides the channel(s) + * on which current connection(s) is + * @channels: the channel(s) on which current connection(s) is + * @len: Number of channels + * @order: no order OR 2.4 Ghz channel followed by 5 Ghz + * channel OR 5 Ghz channel followed by 2.4 Ghz channel + * @skip_dfs_channel: if this flag is true then skip the dfs channel + * @pcl_weight: Pointer to the weights of PCL + * @weight_len: Max length of the weight list + * @index: Index from which the weight list needs to be populated + * @group_id: Next available groups for weight assignment + * + * + * This function provides the channel(s) on which current + * connection(s) is/are + * + * Return: QDF_STATUS + */ +static +QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, + uint8_t *channels, + uint32_t *len, enum policy_mgr_pcl_channel_order order, + bool skip_dfs_channel, + uint8_t *pcl_weight, uint32_t weight_len, + uint32_t *index, enum policy_mgr_pcl_group_id group_id) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint32_t conn_index = 0, num_channels = 0; + uint32_t weight1, weight2; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + + if ((NULL == channels) || (NULL == len)) { + policy_mgr_err("channels or len is NULL"); + status = QDF_STATUS_E_FAILURE; + return status; + } + + /* POLICY_MGR_PCL_GROUP_ID1_ID2 indicates that all three weights are + * available for assignment. i.e., WEIGHT_OF_GROUP1_PCL_CHANNELS, + * WEIGHT_OF_GROUP2_PCL_CHANNELS and WEIGHT_OF_GROUP3_PCL_CHANNELS + * are all available. Since in this function only two weights are + * assigned at max, only group1 and group2 weights are considered. + * + * The other possible group id POLICY_MGR_PCL_GROUP_ID2_ID3 indicates + * group1 was assigned the weight WEIGHT_OF_GROUP1_PCL_CHANNELS and + * only weights WEIGHT_OF_GROUP2_PCL_CHANNELS and + * WEIGHT_OF_GROUP3_PCL_CHANNELS are available for further weight + * assignments. + * + * e.g., when order is POLICY_MGR_PCL_ORDER_24G_THEN_5G and group id is + * POLICY_MGR_PCL_GROUP_ID2_ID3, WEIGHT_OF_GROUP2_PCL_CHANNELS is + * assigned to 2.4GHz channels and the weight + * WEIGHT_OF_GROUP3_PCL_CHANNELS is assigned to the 5GHz channels. + */ + if (group_id == POLICY_MGR_PCL_GROUP_ID1_ID2) { + weight1 = WEIGHT_OF_GROUP1_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP2_PCL_CHANNELS; + } else { + weight1 = WEIGHT_OF_GROUP2_PCL_CHANNELS; + weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (POLICY_MGR_PCL_ORDER_NONE == order) { + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (skip_dfs_channel && wlan_reg_is_dfs_ch(psoc, + pm_conc_connection_list[conn_index].chan)) { + conn_index++; + } else if (*index < weight_len) { + channels[num_channels++] = + pm_conc_connection_list[conn_index++].chan; + pcl_weight[(*index)++] = weight1; + } else { + conn_index++; + } + } + *len = num_channels; + } else if (POLICY_MGR_PCL_ORDER_24G_THEN_5G == order) { + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[conn_index].chan) + && (*index < weight_len)) { + channels[num_channels++] = + pm_conc_connection_list[conn_index++].chan; + pcl_weight[(*index)++] = weight1; + } else { + conn_index++; + } + } + conn_index = 0; + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (skip_dfs_channel && wlan_reg_is_dfs_ch(psoc, + pm_conc_connection_list[conn_index].chan)) { + conn_index++; + } else if (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[conn_index].chan) + && (*index < weight_len)) { + channels[num_channels++] = + pm_conc_connection_list[conn_index++].chan; + pcl_weight[(*index)++] = weight2; + } else { + conn_index++; + } + } + *len = num_channels; + } else if (POLICY_MGR_PCL_ORDER_5G_THEN_2G == order) { + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (skip_dfs_channel && wlan_reg_is_dfs_ch(psoc, + pm_conc_connection_list[conn_index].chan)) { + conn_index++; + } else if (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[conn_index].chan) + && (*index < weight_len)) { + channels[num_channels++] = + pm_conc_connection_list[conn_index++].chan; + pcl_weight[(*index)++] = weight1; + } else { + conn_index++; + } + } + conn_index = 0; + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[conn_index].chan) + && (*index < weight_len)) { + channels[num_channels++] = + pm_conc_connection_list[conn_index++].chan; + pcl_weight[(*index)++] = weight2; + + } else { + conn_index++; + } + } + *len = num_channels; + } else { + policy_mgr_err("unknown order %d", order); + status = QDF_STATUS_E_FAILURE; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return status; } /** @@ -475,7 +1615,422 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t *pcl_weights, uint32_t weight_len) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t num_channels = 0; + uint32_t sbs_num_channels = 0; + uint32_t chan_index = 0, chan_index_24 = 0, chan_index_5 = 0; + uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0}; + uint8_t channel_list_24[QDF_MAX_NUM_CHAN] = {0}; + uint8_t channel_list_5[QDF_MAX_NUM_CHAN] = {0}; + uint8_t sbs_channel_list[QDF_MAX_NUM_CHAN] = {0}; + bool skip_dfs_channel = false; + uint32_t i = 0, j = 0; + + if ((NULL == pcl_channels) || (NULL == len)) { + policy_mgr_err("pcl_channels or len is NULL"); + return status; + } + + if (PM_MAX_PCL_TYPE == pcl) { + /* msg */ + policy_mgr_err("pcl is invalid"); + return status; + } + + if (PM_NONE == pcl) { + /* msg */ + policy_mgr_notice("pcl is 0"); + return QDF_STATUS_SUCCESS; + } + /* get the channel list for current domain */ + status = policy_mgr_get_valid_chans(psoc, channel_list, &num_channels); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Error in getting valid channels"); + return status; + } + + /* + * if you have atleast one STA connection then don't fill DFS channels + * in the preferred channel list + */ + if (((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) && + (policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, NULL) > 0)) { + policy_mgr_notice("STA present, skip DFS channels from pcl for SAP/Go"); + skip_dfs_channel = true; + } + + /* Let's divide the list in 2.4 & 5 Ghz lists */ + while ((chan_index < QDF_MAX_NUM_CHAN) && + (channel_list[chan_index] <= 11) && + (chan_index_24 < QDF_MAX_NUM_CHAN)) + channel_list_24[chan_index_24++] = channel_list[chan_index++]; + if ((chan_index < QDF_MAX_NUM_CHAN) && + (channel_list[chan_index] == 12) && + (chan_index_24 < QDF_MAX_NUM_CHAN)) { + channel_list_24[chan_index_24++] = channel_list[chan_index++]; + if ((chan_index < QDF_MAX_NUM_CHAN) && + (channel_list[chan_index] == 13) && + (chan_index_24 < QDF_MAX_NUM_CHAN)) { + channel_list_24[chan_index_24++] = + channel_list[chan_index++]; + if ((chan_index < QDF_MAX_NUM_CHAN) && + (channel_list[chan_index] == 14) && + (chan_index_24 < QDF_MAX_NUM_CHAN)) + channel_list_24[chan_index_24++] = + channel_list[chan_index++]; + } + } + + while ((chan_index < num_channels) && + (chan_index_5 < QDF_MAX_NUM_CHAN)) { + if ((true == skip_dfs_channel) && + wlan_reg_is_dfs_ch(psoc, channel_list[chan_index])) { + chan_index++; + continue; + } + channel_list_5[chan_index_5++] = channel_list[chan_index++]; + } + + num_channels = 0; + sbs_num_channels = 0; + /* In the below switch case, the channel list is populated based on the + * pcl. e.g., if the pcl is PM_SCC_CH_24G, the SCC channel group is + * populated first followed by the 2.4GHz channel group. Along with + * this, the weights are also populated in the same order for each of + * these groups. There are three weight groups: + * WEIGHT_OF_GROUP1_PCL_CHANNELS, WEIGHT_OF_GROUP2_PCL_CHANNELS and + * WEIGHT_OF_GROUP3_PCL_CHANNELS. + * + * e.g., if pcl is PM_SCC_ON_5_SCC_ON_24_24G: scc on 5GHz (group1) + * channels take the weight WEIGHT_OF_GROUP1_PCL_CHANNELS, scc on 2.4GHz + * (group2) channels take the weight WEIGHT_OF_GROUP2_PCL_CHANNELS and + * 2.4GHz (group3) channels take the weight + * WEIGHT_OF_GROUP3_PCL_CHANNELS. + * + * When the weight to be assigned to the group is known along with the + * number of channels, the weights are directly assigned to the + * pcl_weights list. But, the channel list is populated using + * policy_mgr_get_connection_channels(), the order of weights to be used + * is passed as an argument to the function + * policy_mgr_get_connection_channels() using + * 'enum policy_mgr_pcl_group_id' which indicates the next available + * weights to be used and policy_mgr_get_connection_channels() will take + * care of the weight assignments. + * + * e.g., 'enum policy_mgr_pcl_group_id' value of + * POLICY_MGR_PCL_GROUP_ID2_ID3 indicates that the next available groups + * for weight assignment are WEIGHT_OF_GROUP2_PCL_CHANNELS and + * WEIGHT_OF_GROUP3_PCL_CHANNELS and that the + * weight WEIGHT_OF_GROUP1_PCL_CHANNELS was already allocated. + * So, in the same example, when order is + * POLICY_MGR_PCL_ORDER_24G_THEN_5G, + * policy_mgr_get_connection_channels() will assign the weight + * WEIGHT_OF_GROUP2_PCL_CHANNELS to 2.4GHz channels and assign the + * weight WEIGHT_OF_GROUP3_PCL_CHANNELS to 5GHz channels. + */ + switch (pcl) { + case PM_24G: + chan_index_24 = QDF_MIN(chan_index_24, weight_len); + qdf_mem_copy(pcl_channels, channel_list_24, + chan_index_24); + *len = chan_index_24; + for (i = 0; i < *len; i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; + break; + case PM_5G: + chan_index_5 = QDF_MIN(chan_index_5, weight_len); + qdf_mem_copy(pcl_channels, channel_list_5, + chan_index_5); + *len = chan_index_5; + for (i = 0; i < *len; i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_CH: + case PM_MCC_CH: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, num_channels); + *len = num_channels; + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_CH_24G: + case PM_MCC_CH_24G: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, num_channels); + *len = num_channels; + chan_index_24 = QDF_MIN((num_channels + chan_index_24), + weight_len) - num_channels; + qdf_mem_copy(&pcl_channels[num_channels], + channel_list_24, chan_index_24); + *len += chan_index_24; + for (j = 0; j < chan_index_24; i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; + + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_CH_5G: + case PM_MCC_CH_5G: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, + num_channels); + *len = num_channels; + chan_index_5 = QDF_MIN((num_channels + chan_index_5), + weight_len) - num_channels; + qdf_mem_copy(&pcl_channels[num_channels], + channel_list_5, chan_index_5); + *len += chan_index_5; + for (j = 0; j < chan_index_5; i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; + break; + case PM_24G_SCC_CH: + case PM_24G_MCC_CH: + chan_index_24 = QDF_MIN(chan_index_24, weight_len); + qdf_mem_copy(pcl_channels, channel_list_24, + chan_index_24); + *len = chan_index_24; + for (i = 0; i < chan_index_24; i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID2_ID3); + qdf_mem_copy(&pcl_channels[chan_index_24], + channel_list, num_channels); + *len += num_channels; + status = QDF_STATUS_SUCCESS; + break; + case PM_5G_SCC_CH: + case PM_5G_MCC_CH: + chan_index_5 = QDF_MIN(chan_index_5, weight_len); + qdf_mem_copy(pcl_channels, channel_list_5, + chan_index_5); + *len = chan_index_5; + for (i = 0; i < chan_index_5; i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID2_ID3); + qdf_mem_copy(&pcl_channels[chan_index_5], + channel_list, num_channels); + *len += num_channels; + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_ON_24_SCC_ON_5: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, + POLICY_MGR_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, + num_channels); + *len = num_channels; + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_ON_5_SCC_ON_24: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, + POLICY_MGR_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, num_channels); + *len = num_channels; + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_ON_24_SCC_ON_5_24G: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, + POLICY_MGR_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, num_channels); + *len = num_channels; + chan_index_24 = QDF_MIN((num_channels + chan_index_24), + weight_len) - num_channels; + qdf_mem_copy(&pcl_channels[num_channels], + channel_list_24, chan_index_24); + *len += chan_index_24; + for (j = 0; j < chan_index_24; i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_ON_24_SCC_ON_5_5G: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, + POLICY_MGR_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, num_channels); + *len = num_channels; + chan_index_5 = QDF_MIN((num_channels + chan_index_5), + weight_len) - num_channels; + qdf_mem_copy(&pcl_channels[num_channels], + channel_list_5, chan_index_5); + *len += chan_index_5; + for (j = 0; j < chan_index_5; i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_ON_5_SCC_ON_24_24G: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, + POLICY_MGR_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, num_channels); + *len = num_channels; + chan_index_24 = QDF_MIN((num_channels + chan_index_24), + weight_len) - num_channels; + qdf_mem_copy(&pcl_channels[num_channels], + channel_list_24, chan_index_24); + *len += chan_index_24; + for (j = 0; j < chan_index_24; i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; + break; + case PM_SCC_ON_5_SCC_ON_24_5G: + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, + POLICY_MGR_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID1_ID2); + qdf_mem_copy(pcl_channels, channel_list, num_channels); + *len = num_channels; + chan_index_5 = QDF_MIN((num_channels + chan_index_5), + weight_len) - num_channels; + qdf_mem_copy(&pcl_channels[num_channels], + channel_list_5, chan_index_5); + *len += chan_index_5; + for (j = 0; j < chan_index_5; i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; + break; + case PM_24G_SCC_CH_SBS_CH: + qdf_mem_copy(pcl_channels, channel_list_24, + chan_index_24); + *len = chan_index_24; + for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID2_ID3); + qdf_mem_copy(&pcl_channels[chan_index_24], + channel_list, num_channels); + *len += num_channels; + if (policy_mgr_is_hw_sbs_capable(psoc)) { + policy_mgr_get_sbs_channels( + sbs_channel_list, &sbs_num_channels, pcl_weights, + weight_len, &i, POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, false); + qdf_mem_copy( + &pcl_channels[chan_index_24 + num_channels], + sbs_channel_list, sbs_num_channels); + *len += sbs_num_channels; + } + status = QDF_STATUS_SUCCESS; + break; + case PM_24G_SCC_CH_SBS_CH_5G: + qdf_mem_copy(pcl_channels, channel_list_24, + chan_index_24); + *len = chan_index_24; + for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID2_ID3); + qdf_mem_copy(&pcl_channels[chan_index_24], + channel_list, num_channels); + *len += num_channels; + if (policy_mgr_is_hw_sbs_capable(psoc)) { + policy_mgr_get_sbs_channels( + sbs_channel_list, &sbs_num_channels, pcl_weights, + weight_len, &i, POLICY_MGR_PCL_GROUP_ID3_ID4, + channel_list_5, chan_index_5, true); + qdf_mem_copy( + &pcl_channels[chan_index_24 + num_channels], + sbs_channel_list, sbs_num_channels); + *len += sbs_num_channels; + } else { + qdf_mem_copy( + &pcl_channels[chan_index_24 + num_channels], + channel_list_5, chan_index_5); + *len += chan_index_5; + for (i = chan_index_24 + num_channels; + ((i < *len) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; + } + status = QDF_STATUS_SUCCESS; + break; + case PM_24G_SBS_CH_MCC_CH: + qdf_mem_copy(pcl_channels, channel_list_24, + chan_index_24); + *len = chan_index_24; + for (i = 0; ((i < chan_index_24) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + if (policy_mgr_is_hw_sbs_capable(psoc)) { + policy_mgr_get_sbs_channels( + sbs_channel_list, &sbs_num_channels, pcl_weights, + weight_len, &i, POLICY_MGR_PCL_GROUP_ID2_ID3, + channel_list_5, chan_index_5, false); + qdf_mem_copy(&pcl_channels[num_channels], + sbs_channel_list, sbs_num_channels); + *len += sbs_num_channels; + } + policy_mgr_get_connection_channels(psoc, + channel_list, &num_channels, POLICY_MGR_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + POLICY_MGR_PCL_GROUP_ID2_ID3); + qdf_mem_copy(&pcl_channels[chan_index_24], + channel_list, num_channels); + *len += num_channels; + status = QDF_STATUS_SUCCESS; + break; + case PM_SBS_CH_5G: + if (policy_mgr_is_hw_sbs_capable(psoc)) { + policy_mgr_get_sbs_channels( + sbs_channel_list, &sbs_num_channels, pcl_weights, + weight_len, &i, POLICY_MGR_PCL_GROUP_ID1_ID2, + channel_list_5, chan_index_5, true); + qdf_mem_copy(&pcl_channels[num_channels], + sbs_channel_list, sbs_num_channels); + *len += sbs_num_channels; + } else { + qdf_mem_copy(pcl_channels, channel_list_5, + chan_index_5); + *len = chan_index_5; + for (i = 0; ((i < *len) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; + } + status = QDF_STATUS_SUCCESS; + break; + default: + policy_mgr_err("unknown pcl value %d", pcl); + break; + } + + if ((*len != 0) && (*len != i)) + policy_mgr_notice("pcl len (%d) and weight list len mismatch (%d)", + *len, i); + + /* check the channel avoidance list */ + policy_mgr_update_with_safe_channel_list(pcl_channels, len, + pcl_weights, weight_len); + + return status; } /** @@ -492,7 +2047,35 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, uint8_t channel) { - return false; + uint32_t index = 0; + bool match = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return match; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(index)) { + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + if (pm_conc_connection_list[index].chan != + channel) { + match = true; + break; + } + } else if (WLAN_REG_IS_5GHZ_CH + (pm_conc_connection_list[index].chan)) { + if (pm_conc_connection_list[index].chan != channel) { + match = true; + break; + } + } + index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return match; } /** @@ -510,7 +2093,44 @@ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, uint8_t channel, uint32_t num_connections) { - return true; + bool status = true; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if ((num_connections == 2) && + (pm_conc_connection_list[0].chan != + pm_conc_connection_list[1].chan) && + (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac)) { + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + if ((channel != pm_conc_connection_list[0].chan) && + (channel != pm_conc_connection_list[1].chan)) { + policy_mgr_err("don't allow 3rd home channel on same MAC"); + status = false; + } + } else if (((WLAN_REG_IS_24GHZ_CH(channel)) && + (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[1].chan))) || + ((WLAN_REG_IS_5GHZ_CH(channel)) && + (WLAN_REG_IS_5GHZ_CH + (pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH + (pm_conc_connection_list[1].chan)))) { + policy_mgr_err("don't allow 3rd home channel on same MAC"); + status = false; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return status; } /** @@ -524,7 +2144,31 @@ bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, */ bool policy_mgr_vht160_conn_exist(struct wlan_objmgr_psoc *psoc) { - return false; + uint32_t conn_index; + bool status = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (pm_conc_connection_list[conn_index].in_use && + ((pm_conc_connection_list[conn_index].bw == + HW_MODE_80_PLUS_80_MHZ) || + (pm_conc_connection_list[conn_index].bw == + HW_MODE_160_MHZ))) { + status = true; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return status; } /** @@ -545,9 +2189,77 @@ bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, uint8_t channel, uint32_t *list, enum policy_mgr_con_mode mode) { + uint32_t index = 0, count = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + count = policy_mgr_mode_specific_connection_count(psoc, mode, list); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (index < count) { + if (wlan_reg_is_dfs_ch(psoc, + pm_conc_connection_list[list[index]].chan) && + WLAN_REG_IS_5GHZ_CH(channel) && + (channel != + pm_conc_connection_list[list[index]].chan)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_err("don't allow MCC if SAP/GO on DFS channel"); + return false; + } + index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return true; } +/** + * policy_mgr_nss_update_cb() - callback from SME confirming nss + * update + * @hdd_ctx: HDD Context + * @tx_status: tx completion status for updated beacon with new + * nss value + * @vdev_id: vdev id for the specific connection + * @next_action: next action to happen at policy mgr after + * beacon update + * @reason: Reason for nss update + * + * This function is the callback registered with SME at nss + * update request time + * + * Return: None + */ +static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, + uint8_t tx_status, + uint8_t vdev_id, + uint8_t next_action, + enum policy_mgr_conn_update_reason reason) +{ + uint32_t conn_index = 0; + + if (QDF_STATUS_SUCCESS != tx_status) + policy_mgr_err("nss update failed(%d) for vdev %d", + tx_status, vdev_id); + + /* + * Check if we are ok to request for HW mode change now + */ + conn_index = policy_mgr_get_connection_for_vdev_id(psoc, vdev_id); + if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) { + policy_mgr_err("connection not found for vdev %d", vdev_id); + return; + } + + policy_mgr_debug("nss update successful for vdev:%d", vdev_id); + policy_mgr_next_actions(psoc, vdev_id, next_action, reason); + + return; +} + /** * policy_mgr_complete_action() - initiates actions needed on * current connections once channel has been decided for the new @@ -569,14 +2281,115 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason, uint32_t session_id) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t index, count; + uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t conn_index = 0; + uint32_t vdev_id; + uint32_t original_nss; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + policy_mgr_err("driver isn't dbs capable, no further action needed"); + return QDF_STATUS_E_NOSUPPORT; + } + + /* policy_mgr_complete_action() is called by policy_mgr_next_actions(). + * All other callers of policy_mgr_next_actions() have taken mutex + * protection. So, not taking any lock inside + * policy_mgr_complete_action() during pm_conc_connection_list access. + */ + count = policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_GO_MODE, list); + for (index = 0; index < count; index++) { + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + vdev_id = pm_conc_connection_list[list[index]].vdev_id; + original_nss = + pm_conc_connection_list[list[index]].original_nss; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + conn_index = policy_mgr_get_connection_for_vdev_id( + psoc, vdev_id); + if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) { + policy_mgr_err("connection not found for vdev %d", + vdev_id); + continue; + } + + if (2 == original_nss) { + status = pm_ctx->sme_cbacks.sme_nss_update_request( + vdev_id, new_nss, + policy_mgr_nss_update_cb, + next_action, psoc, reason); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("sme_nss_update_request() failed for vdev %d", + vdev_id); + } + } + } + + count = policy_mgr_mode_specific_connection_count(psoc, + PM_SAP_MODE, list); + for (index = 0; index < count; index++) { + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + vdev_id = pm_conc_connection_list[list[index]].vdev_id; + original_nss = + pm_conc_connection_list[list[index]].original_nss; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + conn_index = policy_mgr_get_connection_for_vdev_id( + psoc, vdev_id); + if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) { + policy_mgr_err("connection not found for vdev %d", + vdev_id); + continue; + } + if (2 == original_nss) { + status = pm_ctx->sme_cbacks.sme_nss_update_request( + vdev_id, new_nss, + policy_mgr_nss_update_cb, + next_action, psoc, reason); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("sme_nss_update_request() failed for vdev %d", + vdev_id); + } + } + } + if (!QDF_IS_STATUS_SUCCESS(status)) + status = policy_mgr_next_actions(psoc, session_id, + next_action, reason); + + return status; } enum policy_mgr_con_mode policy_mgr_get_mode_by_vdev_id( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) { - return PM_MAX_NUM_OF_MODE; + enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t conn_index; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return mode; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) + if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) && + pm_conc_connection_list[conn_index].in_use){ + mode = pm_conc_connection_list[conn_index].mode; + break; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return mode; } /** @@ -591,11 +2404,21 @@ enum policy_mgr_con_mode policy_mgr_get_mode_by_vdev_id( QDF_STATUS policy_mgr_init_connection_update( struct policy_mgr_psoc_priv_obj *pm_ctx) { + QDF_STATUS qdf_status; + + qdf_status = qdf_event_create(&pm_ctx->connection_update_done_evt); + + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + policy_mgr_err("init event failed"); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; } /** - * policy_mgr_get_current_pref_hw_mode_dbs_2x2() - Get the current preferred hw mode + * policy_mgr_get_current_pref_hw_mode_dbs_2x2() - Get the + * current preferred hw mode * * Get the preferred hw mode based on the current connection combinations * @@ -606,11 +2429,106 @@ enum policy_mgr_conc_next_action policy_mgr_get_current_pref_hw_mode_dbs_2x2( struct wlan_objmgr_psoc *psoc) { - return PM_NOP; + uint32_t num_connections; + uint8_t band1, band2, band3; + struct policy_mgr_hw_mode_params hw_mode; + QDF_STATUS status; + + status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("policy_mgr_get_current_hw_mode failed"); + return PM_NOP; + } + + num_connections = policy_mgr_get_connection_count(psoc); + + policy_mgr_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d", + pm_conc_connection_list[0].chan, + pm_conc_connection_list[1].chan, + pm_conc_connection_list[2].chan, num_connections, + hw_mode.dbs_cap); + + /* If the band of operation of both the MACs is the same, + * single MAC is preferred, otherwise DBS is preferred. + */ + switch (num_connections) { + case 1: + band1 = reg_chan_to_band(pm_conc_connection_list[0].chan); + if (band1 == BAND_2G) + return PM_DBS; + else + return PM_NOP; + case 2: + band1 = reg_chan_to_band(pm_conc_connection_list[0].chan); + band2 = reg_chan_to_band(pm_conc_connection_list[1].chan); + if ((band1 == BAND_2G) || + (band2 == BAND_2G)) { + if (!hw_mode.dbs_cap) + return PM_DBS; + else + return PM_NOP; + } else if ((band1 == BAND_5G) && + (band2 == BAND_5G)) { + if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS( + pm_conc_connection_list[0].chan, + pm_conc_connection_list[1].chan)) { + if (!hw_mode.sbs_cap) + return PM_SBS; + else + return PM_NOP; + } else { + if (hw_mode.sbs_cap || hw_mode.dbs_cap) + return PM_SINGLE_MAC; + else + return PM_NOP; + } + } else + return PM_NOP; + case 3: + band1 = reg_chan_to_band(pm_conc_connection_list[0].chan); + band2 = reg_chan_to_band(pm_conc_connection_list[1].chan); + band3 = reg_chan_to_band(pm_conc_connection_list[2].chan); + if ((band1 == BAND_2G) || + (band2 == BAND_2G) || + (band3 == BAND_2G)) { + if (!hw_mode.dbs_cap) + return PM_DBS; + else + return PM_NOP; + } else if ((band1 == BAND_5G) && + (band2 == BAND_5G) && + (band3 == BAND_5G)) { + if (WLAN_REG_IS_CHANNEL_VALID_5G_SBS( + pm_conc_connection_list[0].chan, + pm_conc_connection_list[2].chan) && + WLAN_REG_IS_CHANNEL_VALID_5G_SBS( + pm_conc_connection_list[1].chan, + pm_conc_connection_list[2].chan) && + WLAN_REG_IS_CHANNEL_VALID_5G_SBS( + pm_conc_connection_list[0].chan, + pm_conc_connection_list[1].chan)) { + if (!hw_mode.sbs_cap) + return PM_SBS; + else + return PM_NOP; + } else { + if (hw_mode.sbs_cap || hw_mode.dbs_cap) + return PM_SINGLE_MAC; + else + return PM_NOP; + } + } else + return PM_NOP; + default: + policy_mgr_err("unexpected num_connections value %d", + num_connections); + return PM_NOP; + } } /** - * policy_mgr_get_current_pref_hw_mode_dbs_1x1() - Get the current preferred hw mode + * policy_mgr_get_current_pref_hw_mode_dbs_1x1() - Get the + * current preferred hw mode * * Get the preferred hw mode based on the current connection combinations * @@ -621,7 +2539,79 @@ enum policy_mgr_conc_next_action policy_mgr_get_current_pref_hw_mode_dbs_1x1( struct wlan_objmgr_psoc *psoc) { - return PM_NOP; + uint32_t num_connections; + uint8_t band1, band2, band3; + struct policy_mgr_hw_mode_params hw_mode; + QDF_STATUS status; + enum policy_mgr_conc_next_action next_action; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return PM_NOP; + } + + status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("policy_mgr_get_current_hw_mode failed"); + return PM_NOP; + } + + num_connections = policy_mgr_get_connection_count(psoc); + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d", + pm_conc_connection_list[0].chan, + pm_conc_connection_list[1].chan, + pm_conc_connection_list[2].chan, num_connections, + hw_mode.dbs_cap); + + /* If the band of operation of both the MACs is the same, + * single MAC is preferred, otherwise DBS is preferred. + */ + switch (num_connections) { + case 1: + /* The driver would already be in the required hw mode */ + next_action = PM_NOP; + break; + case 2: + band1 = reg_chan_to_band(pm_conc_connection_list[0].chan); + band2 = reg_chan_to_band(pm_conc_connection_list[1].chan); + if ((band1 == band2) && (hw_mode.dbs_cap)) + next_action = PM_SINGLE_MAC_UPGRADE; + else if ((band1 != band2) && (!hw_mode.dbs_cap)) + next_action = PM_DBS_DOWNGRADE; + else + next_action = PM_NOP; + + break; + + case 3: + band1 = reg_chan_to_band(pm_conc_connection_list[0].chan); + band2 = reg_chan_to_band(pm_conc_connection_list[1].chan); + band3 = reg_chan_to_band(pm_conc_connection_list[2].chan); + if (((band1 == band2) && (band2 == band3)) && + (hw_mode.dbs_cap)) { + next_action = PM_SINGLE_MAC_UPGRADE; + } else if (((band1 != band2) || (band2 != band3) || + (band1 != band3)) && + (!hw_mode.dbs_cap)) { + next_action = PM_DBS_DOWNGRADE; + } else { + next_action = PM_NOP; + } + break; + default: + policy_mgr_err("unexpected num_connections value %d", + num_connections); + next_action = PM_NOP; + break; + } + + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return next_action; } /** @@ -634,5 +2624,9 @@ enum policy_mgr_conc_next_action QDF_STATUS policy_mgr_reset_sap_mandatory_channels( struct policy_mgr_psoc_priv_obj *pm_ctx) { + pm_ctx->sap_mandatory_channels_len = 0; + qdf_mem_zero(pm_ctx->sap_mandatory_channels, + QDF_ARRAY_SIZE(pm_ctx->sap_mandatory_channels)); + return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index d9b3873d9ced..0787042f2ed3 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -387,6 +387,7 @@ void policy_mgr_set_pcl_for_existing_combo( void pm_dbs_opportunistic_timer_handler(void *data); enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type, uint8_t subtype); +enum hw_mode_bandwidth policy_mgr_get_bw(enum phy_ch_width chan_width); QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, enum policy_mgr_pcl_type pcl, uint8_t *pcl_channels, uint32_t *len, From 5ae4c436e6e5617c0ecc7a18a6936a380a300115 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 8 Mar 2017 09:15:15 -0800 Subject: [PATCH 010/404] qcacmn: Define DBS action functions of policy manager component Define DBS & concurrency action functions for policy manager component. Change-Id: I86cfb364e4753825ef650dc00a38d5226aa110ee CRs-Fixed: 2009818 --- src/wlan_policy_mgr_action.c | 723 ++++++++++++++++++++++++++++++++++- 1 file changed, 714 insertions(+), 9 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 41f994c0d241..3cd97c828bb1 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -50,6 +50,43 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, struct policy_mgr_vdev_mac_map *vdev_mac_map, struct wlan_objmgr_psoc *context) { + QDF_STATUS status; + struct policy_mgr_hw_mode_params hw_mode; + uint32_t i; + + if (!vdev_mac_map) { + policy_mgr_err("vdev_mac_map is NULL"); + return; + } + + policy_mgr_notice("old_hw_mode_index=%d, new_hw_mode_index=%d", + old_hw_mode_index, new_hw_mode_index); + + for (i = 0; i < num_vdev_mac_entries; i++) + policy_mgr_notice("vdev_id:%d mac_id:%d", + vdev_mac_map[i].vdev_id, + vdev_mac_map[i].mac_id); + + status = policy_mgr_get_hw_mode_from_idx(context, + new_hw_mode_index, &hw_mode); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Get HW mode failed: %d", status); + return; + } + + policy_mgr_notice("MAC0: TxSS:%d, RxSS:%d, Bw:%d", + hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, hw_mode.mac0_bw); + policy_mgr_notice("MAC1: TxSS:%d, RxSS:%d, Bw:%d", + hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, hw_mode.mac1_bw); + policy_mgr_notice("DBS:%d, Agile DFS:%d, SBS:%d", + hw_mode.dbs_cap, hw_mode.agile_dfs_cap, hw_mode.sbs_cap); + + /* update pm_conc_connection_list */ + policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries, + vdev_mac_map, + hw_mode); + + return; } QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, @@ -63,18 +100,199 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, enum hw_mode_sbs_capab sbs, enum policy_mgr_conn_update_reason reason) { + int8_t hw_mode_index; + struct policy_mgr_hw_mode msg; + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + /* + * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't + * allow to request FW for 2x2 + */ + if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->enable2x2)) { + policy_mgr_notice("2x2 is not allowed downgrading to 1x1 for mac0"); + mac0_ss = HW_MODE_SS_1x1; + } + if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->enable2x2)) { + policy_mgr_notice("2x2 is not allowed downgrading to 1x1 for mac1"); + mac1_ss = HW_MODE_SS_1x1; + } + + hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc, + mac0_ss, mac0_bw, mac1_ss, mac1_bw, dbs, dfs, sbs); + if (hw_mode_index < 0) { + policy_mgr_err("Invalid HW mode index obtained"); + return QDF_STATUS_E_FAILURE; + } + + msg.hw_mode_index = hw_mode_index; + msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb; + msg.reason = reason; + msg.session_id = session_id; + + policy_mgr_notice("set hw mode to sme: hw_mode_index: %d session:%d reason:%d", + msg.hw_mode_index, msg.session_id, msg.reason); + + status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to set hw mode to SME"); + return status; + } + return QDF_STATUS_SUCCESS; } enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( struct wlan_objmgr_psoc *psoc) { - return PM_NOP; + uint32_t conn_index; + enum policy_mgr_conc_next_action upgrade = PM_NOP; + uint8_t mac = 0; + struct policy_mgr_hw_mode_params hw_mode; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + goto done; + } + + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + policy_mgr_err("driver isn't dbs capable, no further action needed"); + goto done; + } + + status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("policy_mgr_get_current_hw_mode failed"); + goto done; + } + if (!hw_mode.dbs_cap) { + policy_mgr_notice("current HW mode is non-DBS capable"); + goto done; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + /* Are both mac's still in use */ + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + policy_mgr_debug("index:%d mac:%d in_use:%d chan:%d org_nss:%d", + conn_index, + pm_conc_connection_list[conn_index].mac, + pm_conc_connection_list[conn_index].in_use, + pm_conc_connection_list[conn_index].chan, + pm_conc_connection_list[conn_index].original_nss); + if ((pm_conc_connection_list[conn_index].mac == 0) && + pm_conc_connection_list[conn_index].in_use) { + mac |= POLICY_MGR_MAC0; + if (POLICY_MGR_MAC0_AND_MAC1 == mac) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + goto done; + } + } else if ((pm_conc_connection_list[conn_index].mac == 1) && + pm_conc_connection_list[conn_index].in_use) { + mac |= POLICY_MGR_MAC1; + if (POLICY_MGR_MAC0_AND_MAC1 == mac) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + goto done; + } + } + } + /* Let's request for single MAC mode */ + upgrade = PM_SINGLE_MAC; + /* Is there any connection had an initial connection with 2x2 */ + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].original_nss == 2) && + pm_conc_connection_list[conn_index].in_use) { + upgrade = PM_SINGLE_MAC_UPGRADE; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + goto done; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + +done: + return upgrade; } QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t conn_index = 0; + bool found = false; + struct policy_mgr_vdev_entry_info conn_table_entry; + enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE; + uint8_t nss_2g, nss_5g; + enum policy_mgr_con_mode mode; + uint8_t chan; + uint32_t nss = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) { + /* debug msg */ + found = true; + break; + } + conn_index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + if (!found) { + /* err msg */ + policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list", + vdev_id); + return status; + } + + status = pm_ctx->wma_cbacks.wma_get_connection_info( + vdev_id, &conn_table_entry); + if (QDF_STATUS_SUCCESS != status) { + policy_mgr_err("can't find vdev_id %d in connection table", + vdev_id); + return status; + } + mode = policy_mgr_get_mode(conn_table_entry.type, + conn_table_entry.sub_type); + chan = reg_freq_to_chan(conn_table_entry.mhz); + status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g); + if (QDF_IS_STATUS_SUCCESS(status)) { + if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) || + (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1))) + chain_mask = POLICY_MGR_TWO_TWO; + else + chain_mask = POLICY_MGR_ONE_ONE; + nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g; + } else { + policy_mgr_err("Error in getting nss"); + } + + policy_mgr_debug("update PM connection table for vdev:%d", vdev_id); + + /* add the entry */ + policy_mgr_update_conc_list(psoc, conn_index, + mode, + chan, + policy_mgr_get_bw(conn_table_entry.chan_width), + conn_table_entry.mac_id, + chain_mask, + nss, vdev_id, true); + return QDF_STATUS_SUCCESS; } @@ -84,6 +302,31 @@ QDF_STATUS policy_mgr_update_and_wait_for_connection_update( uint8_t channel, enum policy_mgr_conn_update_reason reason) { + QDF_STATUS status; + + policy_mgr_debug("session:%d channel:%d reason:%d", + session_id, channel, reason); + + status = policy_mgr_reset_connection_update(psoc); + if (QDF_IS_STATUS_ERROR(status)) + policy_mgr_err("clearing event failed"); + + status = policy_mgr_current_connections_update(psoc, + session_id, channel, reason); + if (QDF_STATUS_E_FAILURE == status) { + policy_mgr_err("connections update failed"); + return QDF_STATUS_E_FAILURE; + } + + /* Wait only when status is success */ + if (QDF_IS_STATUS_SUCCESS(status)) { + status = policy_mgr_wait_for_connection_update(psoc); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("qdf wait for event failed"); + return QDF_STATUS_E_FAILURE; + } + } + return QDF_STATUS_SUCCESS; } @@ -92,7 +335,78 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, uint8_t channel, enum policy_mgr_conn_update_reason reason) { - return QDF_STATUS_SUCCESS; + enum policy_mgr_conc_next_action next_action = PM_NOP; + uint32_t num_connections = 0; + enum policy_mgr_one_connection_mode second_index = 0; + enum policy_mgr_two_connection_mode third_index = 0; + enum policy_mgr_band band; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + policy_mgr_err("driver isn't dbs capable, no further action needed"); + return QDF_STATUS_E_NOSUPPORT; + } + if (WLAN_REG_IS_24GHZ_CH(channel)) + band = POLICY_MGR_BAND_24; + else + band = POLICY_MGR_BAND_5; + + num_connections = policy_mgr_get_connection_count(psoc); + + policy_mgr_debug("num_connections=%d channel=%d", + num_connections, channel); + + switch (num_connections) { + case 0: + if (band == POLICY_MGR_BAND_24) + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + next_action = PM_DBS; + else + next_action = PM_NOP; + else + next_action = PM_NOP; + break; + case 1: + second_index = + policy_mgr_get_second_connection_pcl_table_index(psoc); + if (PM_MAX_ONE_CONNECTION_MODE == second_index) { + policy_mgr_err( + "couldn't find index for 2nd connection next action table"); + goto done; + } + next_action = + (*next_action_two_connection_table)[second_index][band]; + break; + case 2: + third_index = + policy_mgr_get_third_connection_pcl_table_index(psoc); + if (PM_MAX_TWO_CONNECTION_MODE == third_index) { + policy_mgr_err( + "couldn't find index for 3rd connection next action table"); + goto done; + } + next_action = (*next_action_three_connection_table) + [third_index][band]; + break; + default: + policy_mgr_err("unexpected num_connections value %d", + num_connections); + break; + } + + if (PM_NOP != next_action) + status = policy_mgr_next_actions(psoc, session_id, + next_action, reason); + else + status = QDF_STATUS_E_NOSUPPORT; + + policy_mgr_debug( + "idx2=%d idx3=%d next_action=%d, band=%d status=%d reason=%d session_id=%d", + second_index, third_index, next_action, band, status, + reason, session_id); + +done: + return status; } QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, @@ -100,13 +414,164 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, enum policy_mgr_conc_next_action action, enum policy_mgr_conn_update_reason reason) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct policy_mgr_hw_mode_params hw_mode; + + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + policy_mgr_err("driver isn't dbs capable, no further action needed"); + return QDF_STATUS_E_NOSUPPORT; + } + + /* check for the current HW index to see if really need any action */ + status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("policy_mgr_get_current_hw_mode failed"); + return status; + } + /** + * if already in DBS no need to request DBS. Might be needed + * to extend the logic when multiple dbs HW mode is available + */ + if ((((PM_DBS_DOWNGRADE == action) || (PM_DBS == action) || + (PM_DBS_UPGRADE == action)) + && hw_mode.dbs_cap)) { + policy_mgr_err("driver is already in %s mode, no further action needed", + (hw_mode.dbs_cap) ? "dbs" : "non dbs"); + return QDF_STATUS_E_ALREADY; + } + + if ((PM_SBS == action) || (action == PM_SBS_DOWNGRADE)) { + if (!policy_mgr_is_hw_sbs_capable(psoc)) { + /* No action */ + policy_mgr_notice("firmware is not sbs capable"); + return QDF_STATUS_SUCCESS; + } + /* check if current mode is already SBS nothing to be + * done + */ + + } + + switch (action) { + case PM_DBS_DOWNGRADE: + /* + * check if we have a beaconing entity that is using 2x2. If yes, + * update the beacon template & notify FW. Once FW confirms + * beacon updated, send down the HW mode change req + */ + status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, + PM_DBS, reason, session_id); + break; + case PM_DBS: + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + status = policy_mgr_pdev_set_hw_mode(psoc, session_id, + HW_MODE_SS_2x2, + HW_MODE_80_MHZ, + HW_MODE_SS_2x2, HW_MODE_40_MHZ, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE, + reason); + else + status = policy_mgr_pdev_set_hw_mode(psoc, session_id, + HW_MODE_SS_1x1, + HW_MODE_80_MHZ, + HW_MODE_SS_1x1, HW_MODE_40_MHZ, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE, + reason); + break; + case PM_SINGLE_MAC_UPGRADE: + /* + * change the HW mode first before the NSS upgrade + */ + status = policy_mgr_pdev_set_hw_mode(psoc, session_id, + HW_MODE_SS_2x2, + HW_MODE_80_MHZ, + HW_MODE_SS_0x0, HW_MODE_BW_NONE, + HW_MODE_DBS_NONE, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE, + reason); + /* + * check if we have a beaconing entity that advertised 2x2 + * intially. If yes, update the beacon template & notify FW. + * Once FW confirms beacon updated, send the HW mode change req + */ + status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_2, + PM_SINGLE_MAC, reason, session_id); + break; + case PM_SINGLE_MAC: + status = policy_mgr_pdev_set_hw_mode(psoc, session_id, + HW_MODE_SS_2x2, + HW_MODE_80_MHZ, + HW_MODE_SS_0x0, HW_MODE_BW_NONE, + HW_MODE_DBS_NONE, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE, + reason); + break; + case PM_DBS_UPGRADE: + status = policy_mgr_pdev_set_hw_mode(psoc, session_id, + HW_MODE_SS_2x2, + HW_MODE_80_MHZ, + HW_MODE_SS_2x2, HW_MODE_80_MHZ, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE, + reason); + + status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_2, + PM_DBS, reason, session_id); + break; + case PM_SBS_DOWNGRADE: + status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, + PM_SBS, reason, session_id); + break; + case PM_SBS: + status = policy_mgr_pdev_set_hw_mode(psoc, session_id, + HW_MODE_SS_1x1, + HW_MODE_80_MHZ, + HW_MODE_SS_1x1, HW_MODE_80_MHZ, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS, + reason); + break; + default: + policy_mgr_err("unexpected action value %d", action); + status = QDF_STATUS_E_FAILURE; + break; + } + + return status; } QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status; + + if (!policy_mgr_check_for_session_conc(psoc, session_id, channel)) { + policy_mgr_err("Conc not allowed for the session %d", + session_id); + return QDF_STATUS_E_FAILURE; + } + + status = policy_mgr_reset_connection_update(psoc); + if (!QDF_IS_STATUS_SUCCESS(status)) + policy_mgr_err("clearing event failed"); + + status = policy_mgr_current_connections_update(psoc, session_id, + channel, + POLICY_MGR_UPDATE_REASON_NORMAL_STA); + if (QDF_STATUS_E_FAILURE == status) { + policy_mgr_err("connections update failed"); + return status; + } + + return status; } #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH @@ -131,23 +596,99 @@ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc) QDF_STATUS policy_mgr_wait_for_connection_update(struct wlan_objmgr_psoc *psoc) { + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *policy_mgr_context; + + policy_mgr_context = policy_mgr_get_context(psoc); + if (!policy_mgr_context) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + status = qdf_wait_single_event( + &policy_mgr_context->connection_update_done_evt, + CONNECTION_UPDATE_TIMEOUT); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("wait for event failed"); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc) { + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *policy_mgr_context; + + policy_mgr_context = policy_mgr_get_context(psoc); + if (!policy_mgr_context) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + status = qdf_event_reset( + &policy_mgr_context->connection_update_done_evt); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("clear event failed"); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc) { + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *policy_mgr_context; + + policy_mgr_context = policy_mgr_get_context(psoc); + if (!policy_mgr_context) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + status = qdf_event_set(&policy_mgr_context->connection_update_done_evt); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("set event failed"); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_restart_opportunistic_timer( struct wlan_objmgr_psoc *psoc, bool check_state) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; + + policy_mgr_ctx = policy_mgr_get_context(psoc); + if (!policy_mgr_ctx) { + policy_mgr_err("Invalid context"); + return status; + } + + if (check_state && + QDF_TIMER_STATE_RUNNING != + policy_mgr_ctx->dbs_opportunistic_timer.state) + return status; + + qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer); + + status = qdf_mc_timer_start( + &policy_mgr_ctx->dbs_opportunistic_timer, + DBS_OPPORTUNISTIC_TIME * 1000); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("failed to start opportunistic timer"); + return status; + } + + return status; } #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH @@ -155,12 +696,32 @@ QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( struct wlan_objmgr_psoc *psoc, void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)) { + struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; + + policy_mgr_ctx = policy_mgr_get_context(psoc); + if (!policy_mgr_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + policy_mgr_ctx->sap_restart_chan_switch_cb = sap_restart_chan_switch_cb; + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_deregister_sap_restart_channel_switch_cb( struct wlan_objmgr_psoc *psoc) { + struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; + + policy_mgr_ctx = policy_mgr_get_context(psoc); + if (!policy_mgr_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + policy_mgr_ctx->sap_restart_chan_switch_cb = NULL; + return QDF_STATUS_SUCCESS; } @@ -169,12 +730,77 @@ QDF_STATUS policy_mgr_deregister_sap_restart_channel_switch_cb( QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( struct wlan_objmgr_psoc *psoc, uint8_t session_id) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_E_FAILURE, qdf_status; + enum policy_mgr_conc_next_action action; + + if (!policy_mgr_is_hw_dbs_capable(psoc)) { + policy_mgr_err("PM/DBS is disabled"); + return status; + } + + action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc); + if ((action != PM_DBS_DOWNGRADE) && + (action != PM_SINGLE_MAC_UPGRADE)) { + policy_mgr_err("Invalid action: %d", action); + status = QDF_STATUS_SUCCESS; + goto done; + } + + policy_mgr_notice("action:%d session id:%d", action, session_id); + + /* Opportunistic timer is started, PM will check if MCC upgrade can be + * done on timer expiry. This avoids any possible ping pong effect + * as well. + */ + if (action == PM_SINGLE_MAC_UPGRADE) { + qdf_status = policy_mgr_restart_opportunistic_timer( + psoc, false); + if (QDF_IS_STATUS_SUCCESS(qdf_status)) + policy_mgr_notice("opportunistic timer for MCC upgrade"); + goto done; + } + + /* For DBS, we want to move right away to DBS mode */ + status = policy_mgr_next_actions(psoc, session_id, action, + POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("no set hw mode command was issued"); + goto done; + } +done: + /* success must be returned only when a set hw mode was done */ + return status; } void policy_mgr_checkn_update_hw_mode_single_mac_mode( struct wlan_objmgr_psoc *psoc, uint8_t channel) { + uint8_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + if (pm_conc_connection_list[i].in_use) + if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, + pm_conc_connection_list[i].chan)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_notice("DBS required"); + return; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + if (QDF_TIMER_STATE_RUNNING == + pm_ctx->dbs_opportunistic_timer.state) + qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); + + pm_dbs_opportunistic_timer_handler((void *)psoc); } void policy_mgr_set_hw_mode_change_in_progress( @@ -201,6 +827,39 @@ QDF_STATUS policy_mgr_update_connection_info_utfw( uint32_t chain_mask, uint32_t type, uint32_t sub_type, uint32_t channelid, uint32_t mac_id) { + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t conn_index = 0, found = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) { + /* debug msg */ + found = 1; + break; + } + conn_index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + if (!found) { + /* err msg */ + policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list", + vdev_id); + return status; + } + policy_mgr_notice("--> updating entry at index[%d]", conn_index); + + policy_mgr_update_conc_list(psoc, conn_index, + policy_mgr_get_mode(type, sub_type), + channelid, HW_MODE_20_MHZ, + mac_id, chain_mask, 0, vdev_id, true); + return QDF_STATUS_SUCCESS; } @@ -209,12 +868,41 @@ QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, uint32_t chain_mask, uint32_t type, uint32_t sub_type, uint32_t channelid, uint32_t mac_id) { + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t conn_index = 0; + + conn_index = policy_mgr_get_connection_count(psoc); + if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) { + /* err msg */ + policy_mgr_err("exceeded max connection limit %d", + MAX_NUMBER_OF_CONC_CONNECTIONS); + return status; + } + policy_mgr_notice("--> filling entry at index[%d]", conn_index); + + policy_mgr_update_conc_list(psoc, conn_index, + policy_mgr_get_mode(type, sub_type), + channelid, HW_MODE_20_MHZ, + mac_id, chain_mask, 0, vdev_id, true); + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, uint32_t del_all, uint32_t vdev_id) { + QDF_STATUS status; + + if (del_all) { + status = policy_mgr_psoc_enable(psoc); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("Policy manager initialization failed"); + return QDF_STATUS_E_FAILURE; + } + } else { + policy_mgr_decr_connection_count(psoc, vdev_id); + } + return QDF_STATUS_SUCCESS; } @@ -222,20 +910,37 @@ enum policy_mgr_pcl_type policy_mgr_get_pcl_from_first_conn_table( enum policy_mgr_con_mode type, enum policy_mgr_conc_priority_mode sys_pref) { - return PM_NONE; + if ((sys_pref >= PM_MAX_CONC_PRIORITY_MODE) || + (type >= PM_MAX_NUM_OF_MODE)) + return PM_MAX_PCL_TYPE; + return first_connection_pcl_table[type][sys_pref]; } enum policy_mgr_pcl_type policy_mgr_get_pcl_from_second_conn_table( enum policy_mgr_one_connection_mode idx, enum policy_mgr_con_mode type, enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable) { - return PM_NONE; + if ((idx >= PM_MAX_ONE_CONNECTION_MODE) || + (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) || + (type >= PM_MAX_NUM_OF_MODE)) + return PM_MAX_PCL_TYPE; + if (dbs_capable) + return (*second_connection_pcl_dbs_table)[idx][type][sys_pref]; + else + return second_connection_pcl_nodbs_table[idx][type][sys_pref]; } enum policy_mgr_pcl_type policy_mgr_get_pcl_from_third_conn_table( enum policy_mgr_two_connection_mode idx, enum policy_mgr_con_mode type, enum policy_mgr_conc_priority_mode sys_pref, uint8_t dbs_capable) { - return PM_NONE; + if ((idx >= PM_MAX_TWO_CONNECTION_MODE) || + (sys_pref >= PM_MAX_CONC_PRIORITY_MODE) || + (type >= PM_MAX_NUM_OF_MODE)) + return PM_MAX_PCL_TYPE; + if (dbs_capable) + return (*third_connection_pcl_dbs_table)[idx][type][sys_pref]; + else + return third_connection_pcl_nodbs_table[idx][type][sys_pref]; } #endif From 58a0b196321d3e8dd85c77bbb0969036d9bcbf8e Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 8 Mar 2017 09:56:33 -0800 Subject: [PATCH 011/404] qcacmn: Define utility functions of policy manager component Part 1 Define utility functions for policy manager component. Change-Id: I78d48c6347e7f7d8ebebeaf85c807ba6b1b044e0 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_get_set_utils.c | 412 +++++++++++++++++++++++++++- 1 file changed, 406 insertions(+), 6 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 52a4b0a2ce20..1309ff00fa41 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -42,60 +42,352 @@ bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc) { - return false; + uint32_t scan_config; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) + return false; + + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + /* We take that it is disabled and proceed */ + return false; + } + scan_config = pm_ctx->dual_mac_cfg.cur_scan_config; + + return WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config); } bool policy_mgr_get_single_mac_scan_with_dfs_config( struct wlan_objmgr_psoc *psoc) { - return false; + uint32_t scan_config; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) + return false; + + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + /* We take that it is disabled and proceed */ + return false; + } + scan_config = pm_ctx->dual_mac_cfg.cur_scan_config; + + return WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config); } int8_t policy_mgr_get_num_dbs_hw_modes(struct wlan_objmgr_psoc *psoc) { - return 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return -EINVAL; + } + return pm_ctx->num_dbs_hw_modes; } bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) { + uint32_t param, i, found = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + if (!policy_mgr_is_dbs_enable(psoc)) { + policy_mgr_notice("DBS is disabled"); + return false; + } + + policy_mgr_notice("DBS service bit map: %d", + pm_ctx->wma_cbacks.wma_is_service_enabled( + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); + + /* The agreement with FW is that: To know if the target is DBS + * capable, DBS needs to be supported both in the HW mode list + * and in the service ready event + */ + if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) + return false; + + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + param = pm_ctx->hw_mode.hw_mode_list[i]; + policy_mgr_notice("HW param: %x", param); + if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) { + policy_mgr_notice("HW (%d) is DBS capable", i); + found = 1; + break; + } + } + + if (found) + return true; + return false; } bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) { + uint32_t param, i, found = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + policy_mgr_notice("SBS service bit map: %d", + pm_ctx->wma_cbacks.wma_is_service_enabled( + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); + + /* The agreement with FW is that: To know if the target is SBS + * capable, SBS needs to be supported both in the HW mode list + * and DBS needs to be supported in the service ready event + */ + if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) + return false; + + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + param = pm_ctx->hw_mode.hw_mode_list[i]; + policy_mgr_notice("HW param: %x", param); + if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) { + policy_mgr_notice("HW (%d) is SBS capable", i); + found = 1; + break; + } + } + + if (found) + return true; + return true; } QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc, bool *one_by_one_dbs, bool *two_by_two_dbs) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t i; + int8_t found_one_by_one = -EINVAL, found_two_by_two = -EINVAL; + uint32_t conf1_tx_ss, conf1_rx_ss; + uint32_t conf2_tx_ss, conf2_rx_ss; + + *one_by_one_dbs = false; + *two_by_two_dbs = false; + + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + policy_mgr_err("HW is not DBS capable"); + /* Caller will understand that DBS is disabled */ + return QDF_STATUS_SUCCESS; + + } + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + /* To check 1x1 capability */ + policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_1x1, + &conf1_tx_ss, &conf1_rx_ss); + /* To check 2x2 capability */ + policy_mgr_get_tx_rx_ss_from_config(HW_MODE_SS_2x2, + &conf2_tx_ss, &conf2_rx_ss); + + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + uint32_t t_conf0_tx_ss, t_conf0_rx_ss; + uint32_t t_conf1_tx_ss, t_conf1_rx_ss; + uint32_t dbs_mode; + + t_conf0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + t_conf0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + t_conf1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + t_conf1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + dbs_mode = POLICY_MGR_HW_MODE_DBS_MODE_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + + if (((((t_conf0_tx_ss == conf1_tx_ss) && + (t_conf0_rx_ss == conf1_rx_ss)) || + ((t_conf1_tx_ss == conf1_tx_ss) && + (t_conf1_rx_ss == conf1_rx_ss))) && + (dbs_mode == HW_MODE_DBS)) && + (found_one_by_one < 0)) { + found_one_by_one = i; + policy_mgr_notice("1x1 hw_mode index %d found", i); + /* Once an entry is found, need not check for 1x1 + * again + */ + continue; + } + + if (((((t_conf0_tx_ss == conf2_tx_ss) && + (t_conf0_rx_ss == conf2_rx_ss)) || + ((t_conf1_tx_ss == conf2_tx_ss) && + (t_conf1_rx_ss == conf2_rx_ss))) && + (dbs_mode == HW_MODE_DBS)) && + (found_two_by_two < 0)) { + found_two_by_two = i; + policy_mgr_notice("2x2 hw_mode index %d found", i); + /* Once an entry is found, need not check for 2x2 + * again + */ + continue; + } + } + + if (found_one_by_one >= 0) + *one_by_one_dbs = true; + if (found_two_by_two >= 0) + *two_by_two_dbs = true; + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc, struct policy_mgr_hw_mode_params *hw_mode) { + QDF_STATUS status; + uint32_t old_hw_index = 0, new_hw_index = 0; + + policy_mgr_notice("Get the current hw mode"); + + status = policy_mgr_get_old_and_new_hw_index(psoc, &old_hw_index, + &new_hw_index); + if (QDF_STATUS_SUCCESS != status) { + policy_mgr_err("Failed to get HW mode index"); + return QDF_STATUS_E_FAILURE; + } + + if (new_hw_index == POLICY_MGR_DEFAULT_HW_MODE_INDEX) { + policy_mgr_err("HW mode is not yet initialized"); + return QDF_STATUS_E_FAILURE; + } + + status = policy_mgr_get_hw_mode_from_idx(psoc, new_hw_index, hw_mode); + if (QDF_STATUS_SUCCESS != status) { + policy_mgr_err("Failed to get HW mode index"); + return QDF_STATUS_E_FAILURE; + } return QDF_STATUS_SUCCESS; } bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc) { + struct policy_mgr_hw_mode_params hw_mode; + + if (!policy_mgr_is_hw_dbs_capable(psoc)) + return false; + if (QDF_STATUS_SUCCESS != + policy_mgr_get_current_hw_mode(psoc, &hw_mode)) + return false; + if (hw_mode.dbs_cap) + return true; return false; } bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) + return false; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + policy_mgr_debug("DBS=%d", + WMI_DBS_FW_MODE_CFG_DBS_GET( + pm_ctx->dual_mac_cfg.cur_fw_mode_config)); + + if (WMI_DBS_FW_MODE_CFG_DBS_GET( + pm_ctx->dual_mac_cfg.cur_fw_mode_config)) + return true; + return false; } bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc) { - return false; + int i, param; + uint32_t dbs, tx_chain0, rx_chain0, tx_chain1, rx_chain1; + uint32_t final_min_rf_chains = 2; + uint32_t min_rf_chains, min_mac0_rf_chains, min_mac1_rf_chains; + bool is_dbs_found = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + param = pm_ctx->hw_mode.hw_mode_list[i]; + tx_chain0 = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param); + rx_chain0 = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param); + dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param); + tx_chain1 = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param); + rx_chain1 = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param); + + if (dbs) { + min_mac0_rf_chains = QDF_MIN(tx_chain0, rx_chain0); + min_mac1_rf_chains = QDF_MIN(tx_chain1, rx_chain1); + min_rf_chains = QDF_MIN(min_mac0_rf_chains, + min_mac1_rf_chains); + is_dbs_found = true; + } else { + continue; + } + final_min_rf_chains = QDF_MIN(final_min_rf_chains, + min_rf_chains); + } + if (false == is_dbs_found) + final_min_rf_chains = 0; + + return (final_min_rf_chains == 2) ? true : false; } uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc) { - return 0; + uint32_t conn_index, count = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return count; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (pm_conc_connection_list[conn_index].in_use) + count++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return count; } uint32_t policy_mgr_mode_specific_connection_count( @@ -103,7 +395,27 @@ uint32_t policy_mgr_mode_specific_connection_count( enum policy_mgr_con_mode mode, uint32_t *list) { - return 0; + uint32_t conn_index = 0, count = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return count; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].mode == mode) && + pm_conc_connection_list[conn_index].in_use) { + if (list != NULL) + list[count] = conn_index; + count++; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return count; } void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, @@ -119,11 +431,99 @@ void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc, uint8_t dbs_plus_agile_scan_val, uint8_t single_mac_scan_with_dbs_val) { + struct policy_mgr_dual_mac_config cfg; + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + /* Any non-zero positive value is treated as 1 */ + if (dbs_val != 0) + dbs_val = 1; + if (dbs_plus_agile_scan_val != 0) + dbs_plus_agile_scan_val = 1; + if (single_mac_scan_with_dbs_val != 0) + single_mac_scan_with_dbs_val = 1; + + status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config, + dbs_val, + dbs_plus_agile_scan_val, + single_mac_scan_with_dbs_val); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("policy_mgr_get_updated_scan_config failed %d", + status); + return; + } + + status = policy_mgr_get_updated_fw_mode_config(psoc, + &cfg.fw_mode_config, + policy_mgr_get_dbs_config(psoc), + policy_mgr_get_agile_dfs_config(psoc)); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d", + status); + return; + } + + cfg.set_dual_mac_cb = (void *)policy_mgr_soc_set_dual_mac_cfg_cb; + + policy_mgr_notice("scan_config:%x fw_mode_config:%x", + cfg.scan_config, cfg.fw_mode_config); + + status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status); } void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc, uint8_t dbs, uint8_t dfs) { + struct policy_mgr_dual_mac_config cfg; + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + /* Any non-zero positive value is treated as 1 */ + if (dbs != 0) + dbs = 1; + if (dfs != 0) + dfs = 1; + + status = policy_mgr_get_updated_scan_config(psoc, &cfg.scan_config, + policy_mgr_get_dbs_scan_config(psoc), + policy_mgr_get_dbs_plus_agile_scan_config(psoc), + policy_mgr_get_single_mac_scan_with_dfs_config(psoc)); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("policy_mgr_get_updated_scan_config failed %d", + status); + return; + } + + status = policy_mgr_get_updated_fw_mode_config(psoc, + &cfg.fw_mode_config, dbs, dfs); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("policy_mgr_get_updated_fw_mode_config failed %d", + status); + return; + } + + cfg.set_dual_mac_cb = (void *)policy_mgr_soc_set_dual_mac_cfg_cb; + + policy_mgr_notice("scan_config:%x fw_mode_config:%x", + cfg.scan_config, cfg.fw_mode_config); + + status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("sme_soc_set_dual_mac_config failed %d", status); } bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) From 9767070e336903ec0f3fdf5b41902faac168057e Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 8 Mar 2017 10:06:58 -0800 Subject: [PATCH 012/404] qcacmn: Define utility functions of policy manager component Part 2 Define utility functions for policy manager component. Change-Id: I080a4389504f6c3b0acb93fe9993da3ffd492f22 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_get_set_utils.c | 299 +++++++++++++++++++++++++++- 1 file changed, 296 insertions(+), 3 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 1309ff00fa41..f9ec5af2681f 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -528,7 +528,39 @@ void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc, bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) { - return true; + uint32_t num_connections = 0; + bool is_mcc = false; + + num_connections = policy_mgr_get_connection_count(psoc); + + switch (num_connections) { + case 1: + break; + case 2: + if ((pm_conc_connection_list[0].chan != + pm_conc_connection_list[1].chan) && + (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac)) { + is_mcc = true; + } + break; + case 3: + if ((pm_conc_connection_list[0].chan != + pm_conc_connection_list[1].chan) || + (pm_conc_connection_list[0].chan != + pm_conc_connection_list[2].chan) || + (pm_conc_connection_list[1].chan != + pm_conc_connection_list[2].chan)){ + is_mcc = true; + } + break; + default: + policy_mgr_err("unexpected num_connections value %d", + num_connections); + break; + } + + return is_mcc; } void policy_mgr_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode) @@ -545,41 +577,302 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, enum tQDF_ADAPTER_MODE mode, uint8_t session_id) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + /* + * Need to aquire mutex as entire functionality in this function + * is in critical section + */ + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + switch (mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_GO_MODE: + case QDF_SAP_MODE: + case QDF_IBSS_MODE: + pm_ctx->no_of_active_sessions[mode]++; + break; + default: + break; + } + + + policy_mgr_notice("No.# of active sessions for mode %d = %d", + mode, pm_ctx->no_of_active_sessions[mode]); + /* + * Get PCL logic makes use of the connection info structure. + * Let us set the PCL to the FW before updating the connection + * info structure about the new connection. + */ + if (mode == QDF_STA_MODE) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + /* Set PCL of STA to the FW */ + policy_mgr_pdev_set_pcl(psoc, mode); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + policy_mgr_notice("Set PCL of STA to FW"); + } + policy_mgr_incr_connection_count(psoc, session_id); + if ((policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + } + + /* set tdls connection tracker state */ + pm_ctx->tdls_cbacks.set_tdls_ct_mode(psoc); + policy_mgr_dump_current_concurrency(psoc); + + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, enum tQDF_ADAPTER_MODE mode, uint8_t session_id) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("context is NULL"); + return; + } + + switch (mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_GO_MODE: + case QDF_SAP_MODE: + case QDF_IBSS_MODE: + if (pm_ctx->no_of_active_sessions[mode]) + pm_ctx->no_of_active_sessions[mode]--; + break; + default: + break; + } + + policy_mgr_notice("No.# of active sessions for mode %d = %d", + mode, pm_ctx->no_of_active_sessions[mode]); + + policy_mgr_decr_connection_count(psoc, session_id); + + /* set tdls connection tracker state */ + pm_ctx->tdls_cbacks.set_tdls_ct_mode(psoc); + + policy_mgr_dump_current_concurrency(psoc); } QDF_STATUS policy_mgr_incr_connection_count( struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t conn_index; + struct policy_mgr_vdev_entry_info conn_table_entry; + enum policy_mgr_chain_mode chain_mask = POLICY_MGR_ONE_ONE; + uint8_t nss_2g = 0, nss_5g = 0; + enum policy_mgr_con_mode mode; + uint8_t chan; + uint32_t nss = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("context is NULL"); + return status; + } + + conn_index = policy_mgr_get_connection_count(psoc); + if (pm_ctx->gMaxConcurrentActiveSessions < conn_index) { + policy_mgr_err("exceeded max connection limit %d", + pm_ctx->gMaxConcurrentActiveSessions); + return status; + } + + status = pm_ctx->wma_cbacks.wma_get_connection_info( + vdev_id, &conn_table_entry); + if (QDF_STATUS_SUCCESS != status) { + policy_mgr_err("can't find vdev_id %d in connection table", + vdev_id); + return status; + } + mode = policy_mgr_get_mode(conn_table_entry.type, + conn_table_entry.sub_type); + chan = reg_freq_to_chan(conn_table_entry.mhz); + status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g); + if (QDF_IS_STATUS_SUCCESS(status)) { + if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) || + (WLAN_REG_IS_5GHZ_CH(chan) && (nss_5g > 1))) + chain_mask = POLICY_MGR_TWO_TWO; + else + chain_mask = POLICY_MGR_ONE_ONE; + nss = (WLAN_REG_IS_24GHZ_CH(chan)) ? nss_2g : nss_5g; + } else { + policy_mgr_err("Error in getting nss"); + } + + + /* add the entry */ + policy_mgr_update_conc_list(psoc, conn_index, + mode, + chan, + policy_mgr_get_bw(conn_table_entry.chan_width), + conn_table_entry.mac_id, + chain_mask, + nss, vdev_id, true); + policy_mgr_notice("Add at idx:%d vdev %d mac=%d", + conn_index, vdev_id, + conn_table_entry.mac_id); + return QDF_STATUS_SUCCESS; } QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t conn_index = 0, next_conn_index = 0; + bool found = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if (vdev_id == pm_conc_connection_list[conn_index].vdev_id) { + /* debug msg */ + found = true; + break; + } + conn_index++; + } + if (!found) { + policy_mgr_err("can't find vdev_id %d in pm_conc_connection_list", + vdev_id); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return status; + } + next_conn_index = conn_index + 1; + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(next_conn_index)) { + pm_conc_connection_list[conn_index].vdev_id = + pm_conc_connection_list[next_conn_index].vdev_id; + pm_conc_connection_list[conn_index].mode = + pm_conc_connection_list[next_conn_index].mode; + pm_conc_connection_list[conn_index].mac = + pm_conc_connection_list[next_conn_index].mac; + pm_conc_connection_list[conn_index].chan = + pm_conc_connection_list[next_conn_index].chan; + pm_conc_connection_list[conn_index].bw = + pm_conc_connection_list[next_conn_index].bw; + pm_conc_connection_list[conn_index].chain_mask = + pm_conc_connection_list[next_conn_index].chain_mask; + pm_conc_connection_list[conn_index].original_nss = + pm_conc_connection_list[next_conn_index].original_nss; + pm_conc_connection_list[conn_index].in_use = + pm_conc_connection_list[next_conn_index].in_use; + conn_index++; + next_conn_index++; + } + + /* clean up the entry */ + qdf_mem_zero(&pm_conc_connection_list[next_conn_index - 1], + sizeof(*pm_conc_connection_list)); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return QDF_STATUS_SUCCESS; } bool policy_mgr_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, enum policy_mgr_con_mode *new_mode) { - return true; + bool status = true; + + switch (*old_mode) { + + case QDF_STA_MODE: + *new_mode = PM_STA_MODE; + break; + case QDF_SAP_MODE: + *new_mode = PM_SAP_MODE; + break; + case QDF_P2P_CLIENT_MODE: + *new_mode = PM_P2P_CLIENT_MODE; + break; + case QDF_P2P_GO_MODE: + *new_mode = PM_P2P_GO_MODE; + break; + case QDF_IBSS_MODE: + *new_mode = PM_IBSS_MODE; + break; + default: + *new_mode = PM_MAX_NUM_OF_MODE; + status = false; + break; + } + + return status; } bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, uint8_t *ibss_channel) { - return QDF_STATUS_SUCCESS; + uint32_t count = 0, index = 0; + uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + bool status = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + if (NULL == ibss_channel) { + policy_mgr_err("Null pointer error"); + return false; + } + count = policy_mgr_mode_specific_connection_count( + psoc, PM_IBSS_MODE, list); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (count == 0) { + /* No IBSS connection */ + status = false; + } else if (count == 1) { + *ibss_channel = pm_conc_connection_list[list[index]].chan; + status = true; + } else { + *ibss_channel = pm_conc_connection_list[list[index]].chan; + policy_mgr_notice("Multiple IBSS connections, picking first one"); + status = true; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return status; } bool policy_mgr_max_concurrent_connections_reached( struct wlan_objmgr_psoc *psoc) { + uint8_t i = 0, j = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (NULL != pm_ctx) { + for (i = 0; i < QDF_MAX_NO_OF_MODE; i++) + j += pm_ctx->no_of_active_sessions[i]; + return j > + (pm_ctx-> + gMaxConcurrentActiveSessions - 1); + } + return false; } From 482d82bf143f48cb5a7f5b5eb90a75f3573897cb Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 8 Mar 2017 10:26:14 -0800 Subject: [PATCH 013/404] qcacmn: Define utility functions of policy manager component Part 3 Define utility functions for policy manager component. Change-Id: I2811b682f5b8e73ea6393dbe6db99a8f6ae077a1 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_get_set_utils.c | 597 +++++++++++++++++++++++++++- 1 file changed, 586 insertions(+), 11 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index f9ec5af2681f..570f1ae5b540 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -40,6 +40,9 @@ #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" +/* invalid channel id. */ +#define INVALID_CHANNEL_ID 0 + bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc) { uint32_t scan_config; @@ -876,11 +879,215 @@ bool policy_mgr_max_concurrent_connections_reached( return false; } +static bool policy_mgr_is_sub_20_mhz_enabled(void) +{ + return false; +} + bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t channel, enum hw_mode_bandwidth bw) { - return true; + uint32_t num_connections = 0, count = 0, index = 0; + bool status = false, match = false; + uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + struct policy_mgr_psoc_priv_obj *pm_ctx; + QDF_STATUS ret; + struct policy_mgr_pcl_list pcl; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + + + qdf_mem_zero(&pcl, sizeof(pcl)); + ret = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); + if (QDF_IS_STATUS_ERROR(ret)) { + policy_mgr_err("disallow connection:%d", ret); + goto done; + } + + /* find the current connection state from pm_conc_connection_list*/ + num_connections = policy_mgr_get_connection_count(psoc); + + if (num_connections && policy_mgr_is_sub_20_mhz_enabled()) { + policy_mgr_err("dont allow concurrency if Sub 20 MHz is enabled"); + status = false; + goto done; + } + + if (policy_mgr_max_concurrent_connections_reached(psoc)) { + policy_mgr_err("Reached max concurrent connections: %d", + pm_ctx->gMaxConcurrentActiveSessions); + goto done; + } + + if (channel) { + /* don't allow 3rd home channel on same MAC */ + if (!policy_mgr_allow_new_home_channel(psoc, + channel, num_connections)) + goto done; + + /* + * 1) DFS MCC is not yet supported + * 2) If you already have STA connection on 5G channel then + * don't allow any other persona to make connection on DFS + * channel because STA 5G + DFS MCC is not allowed. + * 3) If STA is on 2G channel and SAP is coming up on + * DFS channel then allow concurrency but make sure it is + * going to DBS and send PCL to firmware indicating that + * don't allow STA to roam to 5G channels. + */ + if (!policy_mgr_is_5g_channel_allowed(psoc, + channel, list, PM_P2P_GO_MODE)) + goto done; + if (!policy_mgr_is_5g_channel_allowed(psoc, + channel, list, PM_SAP_MODE)) + goto done; + + if ((PM_P2P_GO_MODE == mode) || (PM_SAP_MODE == mode)) { + if (wlan_reg_is_dfs_ch(psoc, channel)) + match = policy_mgr_disallow_mcc(psoc, channel); + } + if (true == match) { + policy_mgr_err("No MCC, SAP/GO about to come up on DFS channel"); + goto done; + } + } + + /* + * Check all IBSS+STA concurrencies + * + * don't allow IBSS + STA MCC + * don't allow IBSS + STA SCC if IBSS is on DFS channel + */ + count = policy_mgr_mode_specific_connection_count(psoc, + PM_STA_MODE, list); + if ((PM_IBSS_MODE == mode) && + (policy_mgr_mode_specific_connection_count(psoc, + PM_IBSS_MODE, list)) && count) { + policy_mgr_err("No 2nd IBSS, we already have STA + IBSS"); + goto done; + } + if ((PM_IBSS_MODE == mode) && + (wlan_reg_is_dfs_ch(psoc, channel)) && count) { + policy_mgr_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel"); + goto done; + } + if (PM_IBSS_MODE == mode) { + if (policy_mgr_is_hw_dbs_capable(psoc) == true) { + if (num_connections > 1) { + policy_mgr_err("No IBSS, we have concurrent connections already"); + goto done; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (PM_STA_MODE != pm_conc_connection_list[0].mode) { + policy_mgr_err("No IBSS, we've a non-STA connection"); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + goto done; + } + /* + * This logic protects STA and IBSS to come up on same + * band. If requirement changes then this condition + * needs to be removed + */ + if (channel && + (pm_conc_connection_list[0].chan != channel) && + WLAN_REG_IS_SAME_BAND_CHANNELS( + pm_conc_connection_list[0].chan, channel)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_err("No IBSS + STA MCC"); + goto done; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + } else if (num_connections) { + policy_mgr_err("No IBSS, we have one connection already"); + goto done; + } + } + + if ((PM_STA_MODE == mode) && + (policy_mgr_mode_specific_connection_count(psoc, + PM_IBSS_MODE, list)) && count) { + policy_mgr_err("No 2nd STA, we already have STA + IBSS"); + goto done; + } + + if ((PM_STA_MODE == mode) && + (policy_mgr_mode_specific_connection_count(psoc, + PM_IBSS_MODE, list))) { + if (policy_mgr_is_hw_dbs_capable(psoc) == true) { + if (num_connections > 1) { + policy_mgr_err("No 2nd STA, we already have IBSS concurrency"); + goto done; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (channel && + (wlan_reg_is_dfs_ch(psoc, + pm_conc_connection_list[0].chan)) + && (WLAN_REG_IS_5GHZ_CH(channel))) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel"); + goto done; + } + /* + * This logic protects STA and IBSS to come up on same + * band. If requirement changes then this condition + * needs to be removed + */ + if ((pm_conc_connection_list[0].chan != channel) && + WLAN_REG_IS_SAME_BAND_CHANNELS( + pm_conc_connection_list[0].chan, channel)) { + policy_mgr_err("No IBSS + STA MCC"); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + goto done; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + } else { + policy_mgr_err("No STA, we have IBSS connection already"); + goto done; + } + } + + /* don't allow two P2P GO on same band */ + if (channel && (mode == PM_P2P_GO_MODE) && num_connections) { + index = 0; + count = policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_GO_MODE, list); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (index < count) { + if (WLAN_REG_IS_SAME_BAND_CHANNELS(channel, + pm_conc_connection_list[list[index]].chan)) { + policy_mgr_err("Don't allow P2P GO on same band"); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + goto done; + } + index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + } + + /* don't allow concurrency on vht160 or vht 80+80 */ + if (num_connections && + ((bw == HW_MODE_80_PLUS_80_MHZ) || + (bw == HW_MODE_160_MHZ))) { + policy_mgr_err("No VHT160, we have one connection already"); + goto done; + } + + if (policy_mgr_vht160_conn_exist(psoc)) { + policy_mgr_err("VHT160/80+80 connection exists, no concurrency"); + goto done; + } + + + status = true; + +done: + return status; } uint32_t policy_mgr_get_concurrency_mode(void) @@ -900,18 +1107,105 @@ uint8_t policy_mgr_search_and_check_for_session_conc( uint8_t session_id, void *roam_profile) { - return 0; + uint8_t channel = 0; + QDF_STATUS status; + enum policy_mgr_con_mode mode; + bool ret; + + mode = policy_mgr_get_mode_by_vdev_id(psoc, session_id); + if (PM_MAX_NUM_OF_MODE == mode) { + policy_mgr_err("Invalid mode"); + return channel; + } + + status = policy_mgr_get_channel_from_scan_result(psoc, + roam_profile, &channel); + if ((QDF_STATUS_SUCCESS != status) || (channel == 0)) { + policy_mgr_err("%s error %d %d", + __func__, status, channel); + return 0; + } + + /* Take care of 160MHz and 80+80Mhz later */ + ret = policy_mgr_allow_concurrency(psoc, mode, channel, HW_MODE_20_MHZ); + if (false == ret) { + policy_mgr_err("Connection failed due to conc check fail"); + return 0; + } + + return channel; } bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel) { + enum policy_mgr_con_mode mode; + bool ret; + + mode = policy_mgr_get_mode_by_vdev_id(psoc, session_id); + if (PM_MAX_NUM_OF_MODE == mode) { + policy_mgr_err("Invalid mode"); + return false; + } + + if (channel == 0) { + policy_mgr_err("Invalid channel number 0"); + return false; + } + + /* Take care of 160MHz and 80+80Mhz later */ + ret = policy_mgr_allow_concurrency(psoc, mode, channel, HW_MODE_20_MHZ); + if (false == ret) { + policy_mgr_err("Connection failed due to conc check fail"); + return 0; + } + return true; } uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) { - return 0; + uint32_t num_connections = 0; + bool is_24G_mcc = false; + + num_connections = policy_mgr_get_connection_count(psoc); + + switch (num_connections) { + case 1: + break; + case 2: + if ((pm_conc_connection_list[0].chan != + pm_conc_connection_list[1].chan) && + (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) && + (pm_conc_connection_list[0].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM) && + (pm_conc_connection_list[1].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM)) + is_24G_mcc = true; + break; + case 3: + if (((pm_conc_connection_list[0].chan != + pm_conc_connection_list[1].chan) || + (pm_conc_connection_list[0].chan != + pm_conc_connection_list[2].chan) || + (pm_conc_connection_list[1].chan != + pm_conc_connection_list[2].chan)) && + (pm_conc_connection_list[0].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM) && + (pm_conc_connection_list[1].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM) && + (pm_conc_connection_list[2].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM)) + is_24G_mcc = true; + break; + default: + policy_mgr_err("unexpected num_connections value %d", + num_connections); + break; + } + + return is_24G_mcc; } int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, uint8_t mas_value) @@ -944,13 +1238,39 @@ void policy_mgr_set_mcc_latency(struct wlan_objmgr_psoc *psoc, int set_value) struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(uint32_t *len) { - return NULL; + struct policy_mgr_conc_connection_info *conn_ptr = + &pm_conc_connection_list[0]; + *len = MAX_NUMBER_OF_CONC_CONNECTIONS; + + return conn_ptr; } enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( enum tQDF_ADAPTER_MODE device_mode) { - return PM_MAX_NUM_OF_MODE; + enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE; + switch (device_mode) { + case QDF_STA_MODE: + mode = PM_STA_MODE; + break; + case QDF_P2P_CLIENT_MODE: + mode = PM_P2P_CLIENT_MODE; + break; + case QDF_P2P_GO_MODE: + mode = PM_P2P_GO_MODE; + break; + case QDF_SAP_MODE: + mode = PM_SAP_MODE; + break; + case QDF_IBSS_MODE: + mode = PM_IBSS_MODE; + break; + default: + policy_mgr_err("Unsupported mode (%d)", + device_mode); + } + + return mode; } bool policy_mgr_concurrent_open_sessions_running(void) @@ -966,11 +1286,20 @@ bool policy_mgr_concurrent_beaconing_sessions_running(void) void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc) { + uint8_t i = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (NULL != pm_ctx) { + for (i = 0; i < QDF_MAX_NO_OF_MODE; i++) + pm_ctx->no_of_active_sessions[i] = 0; + } } bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc) { - return false; + return policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, NULL) > 1; } bool policy_mgr_is_sta_active_connection_exists(void) @@ -981,24 +1310,129 @@ bool policy_mgr_is_sta_active_connection_exists(void) bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, uint8_t *channel) { - return true; + bool status = false; + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (pm_conc_connection_list[conn_index].in_use && + !wlan_reg_is_dfs_ch(psoc, + pm_conc_connection_list[conn_index].chan)) { + *channel = pm_conc_connection_list[conn_index].chan; + status = true; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return status; } bool policy_mgr_is_any_dfs_beaconing_session_present( struct wlan_objmgr_psoc *psoc, uint8_t *channel) { - return true; + struct policy_mgr_conc_connection_info *conn_info; + bool status = false; + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + conn_info = &pm_conc_connection_list[conn_index]; + if (conn_info->in_use && + wlan_reg_is_dfs_ch(psoc, conn_info->chan) && + (PM_SAP_MODE == conn_info->mode || + PM_P2P_GO_MODE == conn_info->mode)) { + *channel = pm_conc_connection_list[conn_index].chan; + status = true; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return status; } QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t *nss_2g, uint8_t *nss_5g) { + enum tQDF_ADAPTER_MODE dev_mode; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + switch (mode) { + case PM_STA_MODE: + dev_mode = QDF_STA_MODE; + break; + case PM_SAP_MODE: + dev_mode = QDF_SAP_MODE; + break; + case PM_P2P_CLIENT_MODE: + dev_mode = QDF_P2P_CLIENT_MODE; + break; + case PM_P2P_GO_MODE: + dev_mode = QDF_P2P_GO_MODE; + break; + case PM_IBSS_MODE: + dev_mode = QDF_IBSS_MODE; + break; + default: + policy_mgr_err("Invalid mode to get allowed NSS value"); + return QDF_STATUS_E_FAILURE; + }; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (!pm_ctx->sme_cbacks.sme_get_nss_for_vdev) { + policy_mgr_err("sme_get_nss_for_vdev callback is NULL"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->sme_cbacks.sme_get_nss_for_vdev( + dev_mode, nss_2g, nss_5g); + return QDF_STATUS_SUCCESS; } void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc) { + uint32_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + policy_mgr_debug("%d: use:%d vdev:%d mode:%d mac:%d chan:%d orig chainmask:%d orig nss:%d bw:%d", + i, pm_conc_connection_list[i].in_use, + pm_conc_connection_list[i].vdev_id, + pm_conc_connection_list[i].mode, + pm_conc_connection_list[i].mac, + pm_conc_connection_list[i].chan, + pm_conc_connection_list[i].chain_mask, + pm_conc_connection_list[i].original_nss, + pm_conc_connection_list[i].bw); + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } bool policy_mgr_is_any_mode_active_on_band_along_with_session( @@ -1006,12 +1440,73 @@ bool policy_mgr_is_any_mode_active_on_band_along_with_session( uint8_t session_id, enum policy_mgr_band band) { - return true; + uint32_t i; + bool status = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + status = false; + goto send_status; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + switch (band) { + case POLICY_MGR_BAND_24: + if ((pm_conc_connection_list[i].vdev_id != session_id) + && (pm_conc_connection_list[i].in_use) && + (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[i].chan))) { + status = true; + goto release_mutex_and_send_status; + } + break; + case POLICY_MGR_BAND_5: + if ((pm_conc_connection_list[i].vdev_id != session_id) + && (pm_conc_connection_list[i].in_use) && + (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[i].chan))) { + status = true; + goto release_mutex_and_send_status; + } + break; + default: + policy_mgr_err("Invalidband option:%d", band); + status = false; + goto release_mutex_and_send_status; + } + } +release_mutex_and_send_status: + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); +send_status: + return status; } QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t *mac_id) { + uint32_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + if ((pm_conc_connection_list[i].vdev_id == session_id) && + (pm_conc_connection_list[i].in_use)) { + *mac_id = pm_conc_connection_list[i].mac; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return QDF_STATUS_SUCCESS; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return QDF_STATUS_E_FAILURE; } @@ -1019,21 +1514,101 @@ QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, uint8_t mac_id, uint8_t session_id, uint8_t *mcc_session_id) { + uint32_t i; + uint8_t chan = pm_conc_connection_list[session_id].chan; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + if (pm_conc_connection_list[i].mac != mac_id) + continue; + if (pm_conc_connection_list[i].vdev_id == session_id) + continue; + /* Inter band or intra band MCC */ + if ((pm_conc_connection_list[i].chan != chan) && + (pm_conc_connection_list[i].in_use)) { + *mcc_session_id = pm_conc_connection_list[i].vdev_id; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return QDF_STATUS_SUCCESS; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return QDF_STATUS_E_FAILURE; } uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, uint8_t session_id) { - return 0; + uint8_t mac_id, mcc_session_id; + QDF_STATUS status; + uint8_t chan; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return INVALID_CHANNEL_ID; + } + + status = policy_mgr_get_mac_id_by_session_id(psoc, session_id, &mac_id); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get MAC ID"); + return INVALID_CHANNEL_ID; + } + + status = policy_mgr_get_mcc_session_id_on_mac(psoc, mac_id, session_id, + &mcc_session_id); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get MCC session ID"); + return INVALID_CHANNEL_ID; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + chan = pm_conc_connection_list[mcc_session_id].chan; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return chan; } void policy_mgr_set_do_hw_mode_change_flag(struct wlan_objmgr_psoc *psoc, bool flag) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + pm_ctx->do_hw_mode_change = flag; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + policy_mgr_debug("hw_mode_change_channel:%d", flag); } bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc) { - return false; + bool flag; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return INVALID_CHANNEL_ID; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + flag = pm_ctx->do_hw_mode_change; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return flag; } From ab488610071a991df7b11c077a3ce93744ed3f04 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 14 Mar 2017 14:43:24 -0700 Subject: [PATCH 014/404] qcacmn: Move PCL weight macros to api header file Move PCL weight macros to API header file. Change-Id: I3183dd8301cd971475d492791df89cd77af2943f CRs-Fixed: 2009818 --- inc/wlan_policy_mgr_public_struct.h | 27 +++++++++++++++++++++++++++ src/wlan_policy_mgr_i.h | 27 --------------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 46781b545bd1..9bd892f7d186 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -39,6 +39,33 @@ #define POLICY_MGR_MAX_CHANNEL_LIST 128 +/** + * Some max value greater than the max length of the channel list + */ +#define MAX_WEIGHT_OF_PCL_CHANNELS 255 +/** + * Some fixed weight difference between the groups + */ +#define PCL_GROUPS_WEIGHT_DIFFERENCE 20 + +/** + * Currently max, only 3 groups are possible as per 'enum policy_mgr_pcl_type'. + * i.e., in a PCL only 3 groups of channels can be present + * e.g., SCC channel on 2.4 Ghz, SCC channel on 5 Ghz & 5 Ghz channels. + * Group 1 has highest priority, group 2 has the next higher priority + * and so on. + */ +#define WEIGHT_OF_GROUP1_PCL_CHANNELS MAX_WEIGHT_OF_PCL_CHANNELS +#define WEIGHT_OF_GROUP2_PCL_CHANNELS \ + (WEIGHT_OF_GROUP1_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) +#define WEIGHT_OF_GROUP3_PCL_CHANNELS \ + (WEIGHT_OF_GROUP2_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) +#define WEIGHT_OF_GROUP4_PCL_CHANNELS \ + (WEIGHT_OF_GROUP3_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) + +#define WEIGHT_OF_NON_PCL_CHANNELS 1 +#define WEIGHT_OF_DISALLOWED_CHANNELS 0 + /** * enum hw_mode_ss_config - Possible spatial stream configuration * @HW_MODE_SS_0x0: Unused Tx and Rx of MAC diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 0787042f2ed3..591678859531 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -67,33 +67,6 @@ extern enum cds_band_type cds_chan_to_band(uint32_t chan); #define CONNECTION_UPDATE_TIMEOUT 1000 #endif -/** - * Some max value greater than the max length of the channel list - */ -#define MAX_WEIGHT_OF_PCL_CHANNELS 255 -/** - * Some fixed weight difference between the groups - */ -#define PCL_GROUPS_WEIGHT_DIFFERENCE 20 - -/** - * Currently max, only 3 groups are possible as per 'enum policy_mgr_pcl_type'. - * i.e., in a PCL only 3 groups of channels can be present - * e.g., SCC channel on 2.4 Ghz, SCC channel on 5 Ghz & 5 Ghz channels. - * Group 1 has highest priority, group 2 has the next higher priority - * and so on. - */ -#define WEIGHT_OF_GROUP1_PCL_CHANNELS MAX_WEIGHT_OF_PCL_CHANNELS -#define WEIGHT_OF_GROUP2_PCL_CHANNELS \ - (WEIGHT_OF_GROUP1_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) -#define WEIGHT_OF_GROUP3_PCL_CHANNELS \ - (WEIGHT_OF_GROUP2_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) -#define WEIGHT_OF_GROUP4_PCL_CHANNELS \ - (WEIGHT_OF_GROUP3_PCL_CHANNELS - PCL_GROUPS_WEIGHT_DIFFERENCE) - -#define WEIGHT_OF_NON_PCL_CHANNELS 1 -#define WEIGHT_OF_DISALLOWED_CHANNELS 0 - /** * Policy Mgr hardware mode list bit-mask definitions. * Bits 4:0, 31:29 are unused. From 6d47f3c412abbb278fc566e2cab6ba43c10df537 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 15 Mar 2017 19:12:20 +0800 Subject: [PATCH 015/404] qcacmn: Defines os and target interfaces Defines API and callbacks of os interface for P2P component. At the same time, defines API of target interface. Change-Id: Ice1c86ecba1f2410d965d9f84923589f229a1864 CRs-Fixed: 2013763 --- inc/wlan_cfg80211_p2p.h | 115 ++++++++++ src/wlan_cfg80211_p2p.c | 457 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 572 insertions(+) create mode 100644 inc/wlan_cfg80211_p2p.h create mode 100644 src/wlan_cfg80211_p2p.c diff --git a/inc/wlan_cfg80211_p2p.h b/inc/wlan_cfg80211_p2p.h new file mode 100644 index 000000000000..1c8484b8de4b --- /dev/null +++ b/inc/wlan_cfg80211_p2p.h @@ -0,0 +1,115 @@ +/* + * 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 P2P functions interfacing with linux kernel + */ + +#ifndef _WLAN_CFG80211_P2P_H_ +#define _WLAN_CFG80211_P2P_H_ + +#include + +struct wlan_objmgr_psoc; +struct wlan_objmgr_vdev; +struct ieee80211_channel; + +/** + * wlan_p2p_start() - start p2p component + * @psoc: soc object + * + * This function used to start P2P component and register events. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS wlan_p2p_start(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_p2p_stop() - stop p2p component + * @psoc: soc object + * + * This function used to stop P2P component and unregister events. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS wlan_p2p_stop(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_cfg80211_roc() - API to process cfg80211 roc request + * @vdev: Pointer to vdev object + * @chan: Pointer to channel + * @duration: Duration for this roc request + * @cookie: Pointer to return cookie to up layer + * + * API to trigger remain on channel request. It returns cookie + * as the identifier of roc. + * + * Return: 0 for success, non zero for failure + */ +int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, + struct ieee80211_channel *chan, uint32_t duration, + uint64_t *cookie); + +/** + * wlan_cfg80211_cancel_roc() - API to process cfg80211 cancel remain + * on channel request + * @vdev: Pointer to vdev object + * @cookie: Find out the roc request by cookie + * + * API to trigger cancel remain on channel request. + * + * Return: 0 for success, non zero for failure + */ +int wlan_cfg80211_cancel_roc(struct wlan_objmgr_vdev *vdev, + uint64_t cookie); + +/** + * wlan_cfg80211_mgmt_tx() - API to process cfg80211 mgmt tx request + * @vdev: Pointer to vdev object + * @chan: Pointer to channel + * @wait: wait time for this mgmt tx request + * @buf: TX buffer + * @len: Length of tx buffer + * @no_cck: Required cck or not + * @dont_wait_for_ack: Wait for ack or not + * @cookie: Return the cookie to caller + * + * API to trigger mgmt frame tx request. It returns cookie as the + * identifier of this tx. + * + * Return: 0 for success, non zero for failure + */ +int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, + struct ieee80211_channel *chan, bool offchan, uint32_t wait, + const uint8_t *buf, uint32_t len, bool no_cck, + bool dont_wait_for_ack, uint64_t *cookie); + +/** + * wlan_cfg80211_mgmt_tx_cancel() - API to process cfg80211 cancel to + * wait mgmt tx + * @vdev: Pointer to vdev object + * @cookie: Find out the mgmt tx request by cookie + * + * API to trigger cancel mgmt frame tx request. + * + * Return: 0 for success, non zero for failure + */ +int wlan_cfg80211_mgmt_tx_cancel(struct wlan_objmgr_vdev *vdev, + uint64_t cookie); + +#endif /* _WLAN_CFG80211_P2P_H_ */ diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c new file mode 100644 index 000000000000..8058a97f1bf5 --- /dev/null +++ b/src/wlan_cfg80211_p2p.c @@ -0,0 +1,457 @@ +/* + * 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 "wlan_cfg80211.h" +#include "wlan_cfg80211_p2p.h" + +#define MAX_NO_OF_2_4_CHANNELS 14 + +/** + * wlan_p2p_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 + */ +static void wlan_p2p_rx_callback(void *user_data, + struct p2p_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_P2P_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 <= 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_P2P_ID); +} + +/** + * wlan_p2p_action_tx_cnf_callback() - Callback for tx confirmation + * @user_data: pointer to soc object + * @tx_cnf: tx confirmation information + * + * This callback will be used to give tx mgmt frame confirmation to + * os interface. + * + * Return: None + */ +static void wlan_p2p_action_tx_cnf_callback(void *user_data, + struct p2p_tx_cnf *tx_cnf) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev; + struct vdev_osif_priv *osif_priv; + struct wireless_dev *wdev; + + cfg80211_info("user data:%p, action cookie:%llx, buf:%p, len:%d, tx status:%d", + user_data, tx_cnf->action_cookie, tx_cnf->buf, + tx_cnf->buf_len, tx_cnf->status); + + psoc = user_data; + if (!psoc) { + cfg80211_err("psoc is null"); + return; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + tx_cnf->vdev_id, WLAN_P2P_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("wireless dev is null"); + goto fail; + } + + cfg80211_mgmt_tx_status( + wdev, + tx_cnf->action_cookie, + tx_cnf->buf, tx_cnf->buf_len, + (bool)tx_cnf->status, GFP_KERNEL); +fail: + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); +} + +/** + * wlan_p2p_lo_event_callback() - Callback for listen offload event + * @user_data: pointer to soc object + * @p2p_lo_event: listen offload event information + * + * This callback will be used to give listen offload event to os interface. + * + * Return: None + */ +static void wlan_p2p_lo_event_callback(void *user_data, + struct p2p_lo_event *p2p_lo_event) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev; + struct vdev_osif_priv *osif_priv; + struct wireless_dev *wdev; + struct sk_buff *vendor_event; + + cfg80211_debug("user data:%p, vdev id:%d, reason code:%d", + user_data, p2p_lo_event->vdev_id, + p2p_lo_event->reason_code); + + psoc = user_data; + if (!psoc) { + cfg80211_err("psoc is null"); + return; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + p2p_lo_event->vdev_id, WLAN_P2P_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("wireless dev is null"); + goto fail; + } + + vendor_event = cfg80211_vendor_event_alloc(wdev->wiphy, NULL, + sizeof(uint32_t) + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX, + GFP_KERNEL); + if (!vendor_event) { + cfg80211_err("cfg80211_vendor_event_alloc failed"); + goto fail; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON, + p2p_lo_event->reason_code)) { + cfg80211_err("nla put failed"); + kfree_skb(vendor_event); + goto fail; + } + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + +fail: + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); +} + +/** + * wlan_p2p_event_callback() - Callback for P2P event + * @user_data: pointer to soc object + * @p2p_event: p2p event information + * + * This callback will be used to give p2p event to os interface. + * + * Return: None + */ +static void wlan_p2p_event_callback(void *user_data, + struct p2p_event *p2p_event) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_vdev *vdev; + struct ieee80211_channel *chan; + struct vdev_osif_priv *osif_priv; + struct wireless_dev *wdev; + + cfg80211_debug("user data:%p, vdev id:%d, event type:%d", + user_data, p2p_event->vdev_id, p2p_event->roc_event); + + psoc = user_data; + if (!psoc) { + cfg80211_err("psoc is null"); + return; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + p2p_event->vdev_id, WLAN_P2P_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("wireless dev is null"); + goto fail; + } + + chan = __ieee80211_get_channel(wdev->wiphy, + wlan_chan_to_freq(p2p_event->chan)); + if (p2p_event->roc_event == ROC_EVENT_READY_ON_CHAN) { + cfg80211_ready_on_channel(wdev, + p2p_event->cookie, chan, + p2p_event->duration, GFP_KERNEL); + } else if (p2p_event->roc_event == ROC_EVENT_COMPLETED) { + cfg80211_remain_on_channel_expired(wdev, + p2p_event->cookie, chan, GFP_KERNEL); + } else { + cfg80211_err("Invalid p2p event"); + } + +fail: + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); +} + +QDF_STATUS wlan_p2p_start(struct wlan_objmgr_psoc *psoc) +{ + struct p2p_start_param start_param; + + if (!psoc) { + cfg80211_err("psoc null"); + return QDF_STATUS_E_INVAL; + } + + start_param.rx_cb = wlan_p2p_rx_callback; + start_param.rx_cb_data = psoc; + start_param.event_cb = wlan_p2p_event_callback; + start_param.event_cb_data = psoc; + start_param.tx_cnf_cb = wlan_p2p_action_tx_cnf_callback; + start_param.tx_cnf_cb_data = psoc; + start_param.lo_event_cb = wlan_p2p_lo_event_callback; + start_param.lo_event_cb_data = psoc; + + return ucfg_p2p_psoc_start(psoc, &start_param); +} + +QDF_STATUS wlan_p2p_stop(struct wlan_objmgr_psoc *psoc) +{ + if (!psoc) { + cfg80211_err("psoc null"); + return QDF_STATUS_E_INVAL; + } + + return ucfg_p2p_psoc_stop(psoc); +} + +int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, + struct ieee80211_channel *chan, uint32_t duration, + uint64_t *cookie) +{ + struct p2p_roc_req roc_req; + struct wlan_objmgr_psoc *psoc; + uint8_t vdev_id; + + if (!vdev) { + cfg80211_err("invalid vdev object"); + return -EINVAL; + } + + if (!chan) { + cfg80211_err("invalid channel"); + return -EINVAL; + } + + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + cfg80211_err("psoc handle is NULL"); + return QDF_STATUS_E_INVAL; + } + + roc_req.chan = (uint32_t)wlan_freq_to_chan(chan->center_freq); + roc_req.duration = duration; + roc_req.vdev_id = (uint32_t)vdev_id; + + return qdf_status_to_os_return( + ucfg_p2p_roc_req(psoc, &roc_req, cookie)); +} + +int wlan_cfg80211_cancel_roc(struct wlan_objmgr_vdev *vdev, + uint64_t cookie) +{ + struct wlan_objmgr_psoc *psoc; + + if (!vdev) { + cfg80211_err("invalid vdev object"); + return -EINVAL; + } + + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + cfg80211_err("psoc handle is NULL"); + return QDF_STATUS_E_INVAL; + } + + return qdf_status_to_os_return( + ucfg_p2p_roc_cancel_req(psoc, cookie)); +} + +int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, + struct ieee80211_channel *chan, bool offchan, + unsigned int wait, + const uint8_t *buf, uint32_t len, bool no_cck, + bool dont_wait_for_ack, uint64_t *cookie) +{ + struct p2p_mgmt_tx mgmt_tx; + struct wlan_objmgr_psoc *psoc; + uint8_t vdev_id; + + if (!vdev) { + cfg80211_err("invalid vdev object"); + return -EINVAL; + } + + if (!chan) { + cfg80211_err("invalid channel"); + return -EINVAL; + } + + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + cfg80211_err("psoc handle is NULL"); + return QDF_STATUS_E_INVAL; + } + + mgmt_tx.vdev_id = (uint32_t)vdev_id; + mgmt_tx.chan = (uint32_t)wlan_freq_to_chan(chan->center_freq); + mgmt_tx.wait = wait; + mgmt_tx.len = len; + mgmt_tx.no_cck = (uint32_t)no_cck; + mgmt_tx.dont_wait_for_ack = (uint32_t)dont_wait_for_ack; + mgmt_tx.buf = buf; + + return qdf_status_to_os_return( + ucfg_p2p_mgmt_tx(psoc, &mgmt_tx, cookie)); +} + +int wlan_cfg80211_mgmt_tx_cancel(struct wlan_objmgr_vdev *vdev, + uint64_t cookie) +{ + struct wlan_objmgr_psoc *psoc; + + if (!vdev) { + cfg80211_err("invalid vdev object"); + return -EINVAL; + } + + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + cfg80211_err("psoc handle is NULL"); + return QDF_STATUS_E_INVAL; + } + + return qdf_status_to_os_return( + ucfg_p2p_mgmt_tx_cancel(psoc, cookie)); +} From 76b2a2f291098ff681ae99731bad27533ae43f4a Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 15 Mar 2017 19:12:20 +0800 Subject: [PATCH 016/404] qcacmn: Defines os and target interfaces Defines API and callbacks of os interface for P2P component. At the same time, defines API of target interface. Change-Id: Ice1c86ecba1f2410d965d9f84923589f229a1864 CRs-Fixed: 2013763 --- inc/target_if_p2p.h | 124 ++++++++++++++++++++ src/target_if_p2p.c | 279 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 403 insertions(+) create mode 100644 inc/target_if_p2p.h create mode 100644 src/target_if_p2p.c diff --git a/inc/target_if_p2p.h b/inc/target_if_p2p.h new file mode 100644 index 000000000000..9d3c33583a53 --- /dev/null +++ b/inc/target_if_p2p.h @@ -0,0 +1,124 @@ +/* + * 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: offload lmac interface APIs for P2P + */ + +#ifndef _TARGET_IF_P2P_H_ +#define _TARGET_IF_P2P_H_ + +#include + +struct wlan_objmgr_psoc; +struct p2p_ps_config; +struct p2p_lo_start; + +/** + * target_if_p2p_register_tx_ops() - Register P2P component TX OPS + * @tx_ops: lmac if transmit ops + * + * Return: None + */ +void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); + +/** + * target_if_p2p_register_lo_event_handler() - Register lo event handler + * @psoc: soc object + * @arg: additional argument + * + * Target interface API to register P2P listen offload event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_register_lo_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg); + +/** + * target_if_p2p_register_noa_event_handler() - Register noa event handler + * @psoc: soc object + * @arg: additional argument + * + * Target interface API to register P2P noa event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_register_noa_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg); + +/** + * target_if_p2p_unregister_lo_event_handler() - Unregister lo event handler + * @psoc: soc object + * @arg: additional argument + * + * Target interface API to unregister P2P listen offload event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_unregister_lo_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg); + +/** + * target_if_p2p_unregister_noa_event_handler() - Unregister noa event handler + * @psoc: soc object + * @arg: additional argument + * + * Target interface API to unregister P2P listen offload event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_unregister_noa_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg); + +/** + * target_if_p2p_set_ps() - Set power save + * @psoc: soc object + * @arg: additional argument + * + * Target interface API to set power save. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, + struct p2p_ps_config *ps_config); + +/** + * target_if_p2p_lo_start() - Start listen offload + * @psoc: soc object + * @lo_start: lo start information + * + * Target interface API to start listen offload. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, + struct p2p_lo_start *lo_start); + +/** + * target_if_p2p_lo_stop() - Stop listen offload + * @psoc: soc object + * @vdev_id: vdev id + * + * Target interface API to stop listen offload. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id); + +#endif /* _TARGET_IF_P2P_H_ */ diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c new file mode 100644 index 000000000000..9df8498ec270 --- /dev/null +++ b/src/target_if_p2p.c @@ -0,0 +1,279 @@ +/* + * 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: offload lmac interface APIs definitions for P2P + */ + +#include +#include +#include "target_if.h" +#include "target_if_p2p.h" + +static inline struct wlan_lmac_if_p2p_rx_ops * +target_if_psoc_get_p2p_rx_ops(struct wlan_objmgr_psoc *psoc) +{ + return &(psoc->soc_cb.rx_ops.p2p); +} + +/** + * target_p2p_lo_event_handler() - WMI callback for lo stop event + * @scn: + * @event_buf: event buffer + * @len: buffer length + * + * This function gets called from WMI when triggered wmi event + * wmi_p2p_lo_stop_event_id. + * + * Return: 0 - success + * others - failure + */ +static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, + uint32_t datalen) +{ + struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; + struct p2p_lo_event *event_info; + struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + target_if_info("scn:%p, data:%p, datalen:%d", scn, data, datalen); + + if (!scn || !data) { + target_if_err("scn: 0x%p, data: 0x%p", scn, data); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + target_if_err("null psoc"); + return -EINVAL; + } + + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + if (!wmi_handle) { + target_if_err("null wmi handle"); + return -EINVAL; + } + + event_info = qdf_mem_malloc(sizeof(*event_info)); + if (!event_info) { + target_if_err("Failed to allocate p2p lo event"); + return -ENOMEM; + } + + /*TODO, extract wmi lo stop event */ + + p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc); + if (p2p_rx_ops->lo_ev_handler) { + status = p2p_rx_ops->lo_ev_handler(psoc, event_info); + target_if_debug("call lo event handler, status:%d", + status); + } + + return qdf_status_to_os_return(status); +} + +/** + * target_p2p_noa_event_handler() - WMI callback for noa event + * @scn: + * @event_buf: event buffer + * @len: buffer length + * + * This function gets called from WMI when triggered WMI event + * wmi_p2p_noa_event_id. + * + * Return: 0 - success + * others - failure + */ +static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, + uint32_t datalen) +{ + struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; + struct p2p_noa_info *event_info; + struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + target_if_info("scn:%p, data:%p, datalen:%d", scn, data, datalen); + + if (!scn || !data) { + target_if_err("scn: 0x%p, data: 0x%p", scn, data); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + target_if_err("null psoc"); + return -EINVAL; + } + + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + if (!wmi_handle) { + target_if_err("null wmi handle"); + return -EINVAL; + } + + event_info = qdf_mem_malloc(sizeof(*event_info)); + if (!event_info) { + target_if_err("Failed to allocate p2p noa information"); + return -ENOMEM; + } + + /*TODO, extract wmi noa event */ + + p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc); + if (p2p_rx_ops->noa_ev_handler) { + status = p2p_rx_ops->noa_ev_handler(psoc, event_info); + target_if_debug("call noa event handler, status:%d", + status); + } + + return qdf_status_to_os_return(status); +} + +QDF_STATUS target_if_p2p_register_lo_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg) +{ + int status; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_info("psoc:%p, arg:%p", psoc, arg); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_register_event_handler(wmi_handle, + wmi_p2p_lo_stop_event_id, target_p2p_lo_event_handler, + WMI_RX_UMAC_CTX); + + target_if_info("wmi register lo event handle, status:%d", + status); + + return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; +} + +QDF_STATUS target_if_p2p_register_noa_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg) +{ + int status; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_info("psoc:%p, arg:%p", psoc, arg); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_register_event_handler(wmi_handle, + wmi_p2p_noa_event_id, target_p2p_noa_event_handler, + WMI_RX_UMAC_CTX); + + target_if_info("wmi register noa event handle, status:%d", + status); + + return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; +} + +QDF_STATUS target_if_p2p_unregister_lo_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg) +{ + int status; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_info("psoc:%p, arg:%p", psoc, arg); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_unregister_event_handler(wmi_handle, + wmi_p2p_lo_stop_event_id); + + target_if_info("wmi unregister lo event handle, status:%d", + status); + + return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; +} + +QDF_STATUS target_if_p2p_unregister_noa_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg) +{ + int status; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_info("psoc:%p, arg:%p", psoc, arg); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_unregister_event_handler(wmi_handle, + wmi_p2p_noa_event_id); + + target_if_info("wmi unregister noa event handle, status:%d", + status); + + return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; +} + +QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, + struct p2p_ps_config *ps_config) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, + struct p2p_lo_start *lo_start) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} + +void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ + struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops; + + if (!tx_ops) { + target_if_err("lmac tx_ops is null"); + return; + } + + p2p_tx_ops = &tx_ops->p2p; + p2p_tx_ops->set_ps = target_if_p2p_set_ps; + p2p_tx_ops->lo_start = target_if_p2p_lo_start; + p2p_tx_ops->lo_stop = target_if_p2p_lo_stop; + p2p_tx_ops->reg_lo_ev_handler = + target_if_p2p_register_lo_event_handler; + p2p_tx_ops->reg_noa_ev_handler = + target_if_p2p_register_noa_event_handler; + p2p_tx_ops->unreg_lo_ev_handler = + target_if_p2p_unregister_lo_event_handler; + p2p_tx_ops->unreg_noa_ev_handler = + target_if_p2p_unregister_noa_event_handler; +} From 7abbf5680c3a9d8061d6f38d0c11b6052271fc34 Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Thu, 2 Mar 2017 13:14:34 -0800 Subject: [PATCH 017/404] qcacmn: Remove legacy dependency from Policy Manager Part 1 Remove legacy dependency from Policy Manager component Part 1 Change-Id: I87a44714c02ed37923ce4a4c4818d2aef8bc6e2f CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 39 +++++-- src/wlan_policy_mgr_core.c | 15 +++ src/wlan_policy_mgr_get_set_utils.c | 163 +++++++++++++++++++++++++++- src/wlan_policy_mgr_i.h | 21 ++++ src/wlan_policy_mgr_init_deinit.c | 1 + 5 files changed, 226 insertions(+), 13 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index c3f5dd4d1a21..0c57170a6060 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -60,23 +60,27 @@ typedef const enum policy_mgr_conc_next_action /** * policy_mgr_set_concurrency_mode() - To set concurrency mode - * @mode: adapter mode + * @psoc: PSOC object data + * @mode: device mode * * This routine is called to set the concurrency mode * * Return: NONE */ -void policy_mgr_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode); +void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode); /** * policy_mgr_clear_concurrency_mode() - To clear concurrency mode - * @mode: adapter mode + * @psoc: PSOC object data + * @mode: device mode * * This routine is called to clear the concurrency mode * * Return: NONE */ -void policy_mgr_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode); +void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode); /** * policy_mgr_get_connection_count() - provides the count of @@ -174,20 +178,23 @@ uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc); /** * policy_mgr_set_mas() - Function to set MAS value to UMAC - * @psoc: PSOC object information - * @mas_value: 0-Disable, 1-Enable MAS + * @psoc: Pointer to psoc + * @mas_value: 0-Disable, 1-Enable MAS + * @dev_mode: device mode * * This function passes down the value of MAS to UMAC * * Return: Configuration message posting status, SUCCESS or Fail * */ -int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, uint8_t mas_value); +int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, + uint8_t mas_value, + enum tQDF_ADAPTER_MODE dev_mode); /** * policy_mgr_set_mcc_p2p_quota() - Function to set quota for P2P * @psoc: PSOC object information - * @set_value: Qouta value for the interface + * @set_value: Quota value for the interface * * This function is used to set the quota for P2P cases * @@ -772,6 +779,7 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, * @sme_pdev_set_hw_mode: Set the new HW mode to FW * @sme_pdev_set_pcl: Set new PCL to FW * @sme_nss_update_request: Update NSS value to FW + * @sme_set_mas: Set MCC adaptive scheduler value */ struct policy_mgr_sme_cbacks { QDF_STATUS (*sme_get_valid_channels)(uint8_t *chan_list, @@ -786,6 +794,7 @@ struct policy_mgr_sme_cbacks { uint8_t new_nss, policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason); + QDF_STATUS (*sme_set_mas) (uint32_t val); }; /** @@ -1666,4 +1675,18 @@ static inline bool policy_mgr_is_scan_simultaneous_capable( return false; } + +/** + * policy_mgr_is_mcc_adaptive_scheduler_enabled() - Function to + * gets the policy manager mcc adaptive scheduler enabled + * @psoc: PSOC object information + * + * This function gets the value mcc adaptive scheduler + * + * Return: true if MCC adaptive scheduler is set else false + * + */ +bool policy_mgr_is_mcc_adaptive_scheduler_enabled( + struct wlan_objmgr_psoc *psoc); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 8aed7d8c994f..21203484c0cd 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -144,6 +144,21 @@ bool policy_mgr_is_dual_mac_disabled_in_ini( return wlan_objmgr_psoc_get_dual_mac_disable(psoc); } +/** + * policy_mgr_is_mas_enabled_in_user_cfg() - Check if MCC + * adaptive scheduler is enabled in INI + * @psoc: PSOC object information + * + * Checks if MCC adaptive scheduler is enabled in INI + * + * Return: true if MCC adaptive scheduler is enabled in INI + */ +bool policy_mgr_is_mas_enabled_in_user_cfg( + struct wlan_objmgr_psoc *psoc) +{ + return false; +} + /** * policy_mgr_get_dbs_config() - Get DBS bit * diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 570f1ae5b540..9653559447ac 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -566,14 +566,82 @@ bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) return is_mcc; } -void policy_mgr_set_concurrency_mode(enum tQDF_ADAPTER_MODE mode) +/** + * policy_mgr_set_concurrency_mode() - To set concurrency mode + * @psoc: PSOC object data + * @mode: device mode + * + * This routine is called to set the concurrency mode + * + * Return: NONE + */ +void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode) { - return; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return; + } + + switch (mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_GO_MODE: + case QDF_SAP_MODE: + case QDF_IBSS_MODE: + case QDF_MONITOR_MODE: + pm_ctx->concurrency_mode |= (1 << mode); + pm_ctx->no_of_open_sessions[mode]++; + break; + default: + break; + } + + policy_mgr_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d", + pm_ctx->concurrency_mode, mode, + pm_ctx->no_of_open_sessions[mode]); } -void policy_mgr_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode) +/** + * policy_mgr_clear_concurrency_mode() - To clear concurrency mode + * @psoc: PSOC object data + * @mode: device mode + * + * This routine is called to clear the concurrency mode + * + * Return: NONE + */ +void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc, + enum tQDF_ADAPTER_MODE mode) { - return; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return; + } + + switch (mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_GO_MODE: + case QDF_SAP_MODE: + case QDF_MONITOR_MODE: + pm_ctx->no_of_open_sessions[mode]--; + if (!(pm_ctx->no_of_open_sessions[mode])) + pm_ctx->concurrency_mode &= (~(1 << mode)); + break; + default: + break; + } + + policy_mgr_info("concurrency_mode = 0x%x Number of open sessions for mode %d = %d", + pm_ctx->concurrency_mode, mode, + pm_ctx->no_of_open_sessions[mode]); } void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, @@ -1208,8 +1276,93 @@ uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) return is_24G_mcc; } -int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, uint8_t mas_value) +/** + * policy_mgr_is_mcc_adaptive_scheduler_enabled() - Function to + * gets the policy manager mcc adaptive scheduler enabled + * @psoc: PSOC object information + * + * This function gets the value mcc adaptive scheduler + * + * Return: true if MCC adaptive scheduler is set else false + * + */ +bool policy_mgr_is_mcc_adaptive_scheduler_enabled( + struct wlan_objmgr_psoc *psoc) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return false; + } + + return pm_ctx->enable_mcc_adaptive_scheduler ? true : false; +} + +/** + * policy_mgr_set_mas() - Function to set MAS value to UMAC + * @psoc: Pointer to psoc + * @mas_value: 0-Disable, 1-Enable MAS + * @dev_mode: device mode + * + * This function passes down the value of MAS to UMAC + * + * Return: Configuration message posting status, SUCCESS or Fail + * + */ +int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, + uint8_t mas_value, + enum tQDF_ADAPTER_MODE dev_mode) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + QDF_STATUS ret_status; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return -EFAULT; + } + + if (mas_value) { + if (policy_mgr_is_mas_enabled_in_user_cfg(psoc)) { + policy_mgr_info("Miracast is ON. Disable MAS and configure P2P quota"); + pm_ctx->enable_mcc_adaptive_scheduler = false; + ret_status = pm_ctx->sme_cbacks.sme_set_mas(false); + if (QDF_STATUS_SUCCESS != ret_status) { + policy_mgr_err("Failed to disable MAS"); + return -EBUSY; + } + } + + /* Config p2p quota */ + if (dev_mode == QDF_STA_MODE) + policy_mgr_set_mcc_p2p_quota(psoc, + 100 - POLICY_MGR_DEFAULT_MCC_P2P_QUOTA); + else if (dev_mode == QDF_P2P_GO_MODE) + policy_mgr_go_set_mcc_p2p_quota(psoc, + POLICY_MGR_DEFAULT_MCC_P2P_QUOTA); + else + policy_mgr_set_mcc_p2p_quota(psoc, + POLICY_MGR_DEFAULT_MCC_P2P_QUOTA); + } else { + policy_mgr_info("Miracast is OFF. Enable MAS and reset P2P quota"); + if (dev_mode == QDF_P2P_GO_MODE) + policy_mgr_go_set_mcc_p2p_quota(psoc, + POLICY_MGR_RESET_MCC_P2P_QUOTA); + else + policy_mgr_set_mcc_p2p_quota(psoc, + POLICY_MGR_RESET_MCC_P2P_QUOTA); + + if (policy_mgr_is_mas_enabled_in_user_cfg(psoc)) { + pm_ctx->enable_mcc_adaptive_scheduler = true; + ret_status = pm_ctx->sme_cbacks.sme_set_mas(true); + if (QDF_STATUS_SUCCESS != ret_status) { + policy_mgr_err("Unable to enable MAS"); + return -EBUSY; + } + } + } + return 0; } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 591678859531..b280caeac776 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -67,6 +67,12 @@ extern enum cds_band_type cds_chan_to_band(uint32_t chan); #define CONNECTION_UPDATE_TIMEOUT 1000 #endif +/** + * Some P2P quota calues for MCC + */ +#define POLICY_MGR_DEFAULT_MCC_P2P_QUOTA 70 +#define POLICY_MGR_RESET_MCC_P2P_QUOTA 50 + /** * Policy Mgr hardware mode list bit-mask definitions. * Bits 4:0, 31:29 are unused. @@ -252,6 +258,8 @@ extern enum policy_mgr_conc_next_action * scan & connections * @hw_mode_change_in_progress: This is to track if HW mode * change is in progress + * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler + * value from INI */ struct policy_mgr_psoc_priv_obj { struct wlan_objmgr_psoc *psoc; @@ -280,6 +288,7 @@ struct policy_mgr_psoc_priv_obj { uint8_t conc_system_pref; struct dual_mac_config dual_mac_cfg; uint32_t hw_mode_change_in_progress; + uint8_t enable_mcc_adaptive_scheduler; }; struct policy_mgr_psoc_priv_obj *policy_mgr_get_context( @@ -297,6 +306,18 @@ QDF_STATUS policy_mgr_get_updated_fw_mode_config( bool agile_dfs); bool policy_mgr_is_dual_mac_disabled_in_ini( struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_is_mas_enabled_in_user_cfg() - Check if MCC + * adaptive scheduler is enabled in INI + * @psoc: PSOC object information + * + * Checks if MCC adaptive scheduler is enabled in INI + * + * Return: true if MCC adaptive scheduler is enabled in INI + */ +bool policy_mgr_is_mas_enabled_in_user_cfg( + struct wlan_objmgr_psoc *psoc); bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc); bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc); bool policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc *psoc); diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index a7e10cb4aeef..927fc67a0295 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -396,6 +396,7 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, sme_cbacks->sme_pdev_set_pcl; pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config = sme_cbacks->sme_soc_set_dual_mac_config; + pm_ctx->sme_cbacks.sme_set_mas = sme_cbacks->sme_set_mas; return QDF_STATUS_SUCCESS; } From 8e3ee3676f4ecd0d8308c8fcf57feabd42eae83d Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Fri, 3 Mar 2017 20:02:10 -0800 Subject: [PATCH 018/404] qcacmn: Remove legacy dependency from Policy Manager Part 2 Remove legacy dependency from Policy Manager component Part 2 Change-Id: I26216e9b7fa0f75f144b5d8ef88be31fcb4224b5 CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 50 ++-------------- src/wlan_policy_mgr_get_set_utils.c | 89 ++++++++--------------------- src/wlan_policy_mgr_i.h | 6 -- src/wlan_policy_mgr_init_deinit.c | 3 +- 4 files changed, 31 insertions(+), 117 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 0c57170a6060..b9ec65aa8d70 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -176,57 +176,19 @@ static inline void policy_mgr_check_concurrent_intf_and_restart_sap( */ uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc); -/** - * policy_mgr_set_mas() - Function to set MAS value to UMAC - * @psoc: Pointer to psoc - * @mas_value: 0-Disable, 1-Enable MAS - * @dev_mode: device mode - * - * This function passes down the value of MAS to UMAC - * - * Return: Configuration message posting status, SUCCESS or Fail - * - */ -int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, - uint8_t mas_value, - enum tQDF_ADAPTER_MODE dev_mode); - -/** - * policy_mgr_set_mcc_p2p_quota() - Function to set quota for P2P - * @psoc: PSOC object information - * @set_value: Quota value for the interface - * - * This function is used to set the quota for P2P cases - * - * Return: Configuration message posting status, SUCCESS or Fail - * - */ -int policy_mgr_set_mcc_p2p_quota(struct wlan_objmgr_psoc *psoc, - uint32_t set_value); - /** * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval * @psoc: PSOC object information + * @vdev_id: vdev id + * @dev_mode: device mode * * Updates the beacon parameters of the GO in MCC scenario * * Return: Success or Failure depending on the overall function behavior */ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( - struct wlan_objmgr_psoc *psoc); - -/** - * policy_mgr_go_set_mcc_p2p_quota() - Function to set quota for P2P GO - * @psoc: PSOC object information - * @set_value: Qouta value for the interface - * - * This function is used to set the quota for P2P GO cases - * - * Return: Configuration message posting status, SUCCESS or Fail - * - */ -int policy_mgr_go_set_mcc_p2p_quota(struct wlan_objmgr_psoc *psoc, - uint32_t set_value); + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, enum tQDF_ADAPTER_MODE dev_mode); /** * policy_mgr_set_mcc_latency() - Set MCC latency @@ -779,7 +741,7 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, * @sme_pdev_set_hw_mode: Set the new HW mode to FW * @sme_pdev_set_pcl: Set new PCL to FW * @sme_nss_update_request: Update NSS value to FW - * @sme_set_mas: Set MCC adaptive scheduler value + * @sme_change_mcc_beacon_interval: Set MCC beacon interval to FW */ struct policy_mgr_sme_cbacks { QDF_STATUS (*sme_get_valid_channels)(uint8_t *chan_list, @@ -794,7 +756,7 @@ struct policy_mgr_sme_cbacks { uint8_t new_nss, policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason); - QDF_STATUS (*sme_set_mas) (uint32_t val); + QDF_STATUS (*sme_change_mcc_beacon_interval) (uint8_t session_id); }; /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 9653559447ac..be7a6fb3d3dc 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1300,90 +1300,47 @@ bool policy_mgr_is_mcc_adaptive_scheduler_enabled( } /** - * policy_mgr_set_mas() - Function to set MAS value to UMAC - * @psoc: Pointer to psoc - * @mas_value: 0-Disable, 1-Enable MAS - * @dev_mode: device mode + * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval + * @psoc: PSOC object information + * @vdev_id: vdev id + * @dev_mode: device mode * - * This function passes down the value of MAS to UMAC - * - * Return: Configuration message posting status, SUCCESS or Fail + * Updates the beacon parameters of the GO in MCC scenario * + * Return: Success or Failure depending on the overall function behavior */ -int32_t policy_mgr_set_mas(struct wlan_objmgr_psoc *psoc, - uint8_t mas_value, - enum tQDF_ADAPTER_MODE dev_mode) +QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, enum tQDF_ADAPTER_MODE dev_mode) { + QDF_STATUS status; struct policy_mgr_psoc_priv_obj *pm_ctx; - QDF_STATUS ret_status; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid context"); - return -EFAULT; + return QDF_STATUS_E_FAILURE; } - if (mas_value) { - if (policy_mgr_is_mas_enabled_in_user_cfg(psoc)) { - policy_mgr_info("Miracast is ON. Disable MAS and configure P2P quota"); - pm_ctx->enable_mcc_adaptive_scheduler = false; - ret_status = pm_ctx->sme_cbacks.sme_set_mas(false); - if (QDF_STATUS_SUCCESS != ret_status) { - policy_mgr_err("Failed to disable MAS"); - return -EBUSY; - } + policy_mgr_info("UPDATE Beacon Params"); + + if (QDF_SAP_MODE == dev_mode) { + if (!pm_ctx-> + sme_cbacks.sme_change_mcc_beacon_interval) { + policy_mgr_err("sme_change_mcc_beacon_interval callback is NULL"); + return QDF_STATUS_E_FAILURE; } - - /* Config p2p quota */ - if (dev_mode == QDF_STA_MODE) - policy_mgr_set_mcc_p2p_quota(psoc, - 100 - POLICY_MGR_DEFAULT_MCC_P2P_QUOTA); - else if (dev_mode == QDF_P2P_GO_MODE) - policy_mgr_go_set_mcc_p2p_quota(psoc, - POLICY_MGR_DEFAULT_MCC_P2P_QUOTA); - else - policy_mgr_set_mcc_p2p_quota(psoc, - POLICY_MGR_DEFAULT_MCC_P2P_QUOTA); - } else { - policy_mgr_info("Miracast is OFF. Enable MAS and reset P2P quota"); - if (dev_mode == QDF_P2P_GO_MODE) - policy_mgr_go_set_mcc_p2p_quota(psoc, - POLICY_MGR_RESET_MCC_P2P_QUOTA); - else - policy_mgr_set_mcc_p2p_quota(psoc, - POLICY_MGR_RESET_MCC_P2P_QUOTA); - - if (policy_mgr_is_mas_enabled_in_user_cfg(psoc)) { - pm_ctx->enable_mcc_adaptive_scheduler = true; - ret_status = pm_ctx->sme_cbacks.sme_set_mas(true); - if (QDF_STATUS_SUCCESS != ret_status) { - policy_mgr_err("Unable to enable MAS"); - return -EBUSY; - } + status = pm_ctx->sme_cbacks. + sme_change_mcc_beacon_interval(vdev_id); + if (status == QDF_STATUS_E_FAILURE) { + policy_mgr_err("Failed to update Beacon Params"); + return QDF_STATUS_E_FAILURE; } } - return 0; -} - -int32_t policy_mgr_set_mcc_p2p_quota(struct wlan_objmgr_psoc *psoc, - uint32_t set_value) -{ - return 0; -} - -QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( - struct wlan_objmgr_psoc *psoc) -{ return QDF_STATUS_SUCCESS; } -int32_t policy_mgr_go_set_mcc_p2p_quota(struct wlan_objmgr_psoc *psoc, - uint32_t set_value) -{ - return 0; -} - void policy_mgr_set_mcc_latency(struct wlan_objmgr_psoc *psoc, int set_value) { return; diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index b280caeac776..aef5d76712f6 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -67,12 +67,6 @@ extern enum cds_band_type cds_chan_to_band(uint32_t chan); #define CONNECTION_UPDATE_TIMEOUT 1000 #endif -/** - * Some P2P quota calues for MCC - */ -#define POLICY_MGR_DEFAULT_MCC_P2P_QUOTA 70 -#define POLICY_MGR_RESET_MCC_P2P_QUOTA 50 - /** * Policy Mgr hardware mode list bit-mask definitions. * Bits 4:0, 31:29 are unused. diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 927fc67a0295..425f5533f91b 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -396,7 +396,8 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, sme_cbacks->sme_pdev_set_pcl; pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config = sme_cbacks->sme_soc_set_dual_mac_config; - pm_ctx->sme_cbacks.sme_set_mas = sme_cbacks->sme_set_mas; + pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval = + sme_cbacks->sme_change_mcc_beacon_interval; return QDF_STATUS_SUCCESS; } From 0edce259a369c19faf6f26c5fe43fcca1a448c22 Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Mon, 6 Mar 2017 14:36:29 -0800 Subject: [PATCH 019/404] qcacmn: Remove legacy dependency from Policy Manager Part 3 Remove legacy dependency from Policy Manager component Part 3 Change-Id: I63f6330e0b4b172d8f78f3e93131e9fba3121f09 CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 39 ++++++++++++-------- src/wlan_policy_mgr_action.c | 31 ++++++++++++++-- src/wlan_policy_mgr_get_set_utils.c | 57 +++++++++++++++++++++++++---- src/wlan_policy_mgr_i.h | 2 +- src/wlan_policy_mgr_init_deinit.c | 4 ++ 5 files changed, 105 insertions(+), 28 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index b9ec65aa8d70..ba31e2674672 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -190,30 +190,27 @@ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, enum tQDF_ADAPTER_MODE dev_mode); -/** - * policy_mgr_set_mcc_latency() - Set MCC latency - * @psoc: PSOC object information - * @set_value: Latency value - * - * Sets the MCC latency value during STA-P2P concurrency - * - * Return: None - */ -void policy_mgr_set_mcc_latency(struct wlan_objmgr_psoc *psoc, int set_value); #if defined(FEATURE_WLAN_MCC_TO_SCC_SWITCH) /** * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA * @psoc: PSOC object information - * @hdd_ap_ctx: AP context + * @vdev_id: Vdev id + * @channel: Channel to change + * @ch_width: channel width to change * * Invoke the callback function to change SAP channel using (E)CSA * * Return: None */ -void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc); +void policy_mgr_change_sap_channel_with_csa( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t channel, + uint32_t ch_width); #else static inline void policy_mgr_change_sap_channel_with_csa( - struct wlan_objmgr_psoc *psoc) + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t channel, + uint32_t ch_width) { } @@ -757,6 +754,12 @@ struct policy_mgr_sme_cbacks { uint8_t next_action, struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason); QDF_STATUS (*sme_change_mcc_beacon_interval) (uint8_t session_id); + QDF_STATUS (*sme_get_ap_channel_from_scan_cache) ( + void *roam_profile, + void **scan_cache, + uint8_t *channel); + QDF_STATUS (*sme_scan_result_purge) ( + void *scan_result); }; /** @@ -938,23 +941,27 @@ void policy_mgr_clear_concurrent_session_count(struct wlan_objmgr_psoc *psoc); /** * policy_mgr_is_multiple_active_sta_sessions() - Check for * multiple STA connections + * @psoc: PSOC object information * * Checks if multiple active STA connection are in the driver * * Return: True if multiple STA sessions are present, False otherwise * */ -bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc); +bool policy_mgr_is_multiple_active_sta_sessions( + struct wlan_objmgr_psoc *psoc); /** * policy_mgr_is_sta_active_connection_exists() - Check if a STA * connection is active + * @psoc: PSOC object information * * Checks if there is atleast one active STA connection in the driver * * Return: True if an active STA session is present, False otherwise */ -bool policy_mgr_is_sta_active_connection_exists(void); +bool policy_mgr_is_sta_active_connection_exists( + struct wlan_objmgr_psoc *psoc); /** * policy_mgr_concurrent_beaconing_sessions_running() - Checks @@ -1137,7 +1144,7 @@ QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( struct wlan_objmgr_psoc *psoc, - void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)); + void (*sap_restart_chan_switch_cb)(uint8_t, uint32_t, uint32_t)); /** * policy_mgr_deregister_sap_restart_channel_switch_cb() - diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 3cd97c828bb1..bdf231553ed5 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -588,9 +588,34 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH -void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc) +/** + * policy_mgr_change_sap_channel_with_csa() - Move SAP channel using (E)CSA + * @psoc: PSOC object information + * @vdev_id: Vdev id + * @channel: Channel to change + * @ch_width: channel width to change + * + * Invoke the callback function to change SAP channel using (E)CSA + * + * Return: None + */ +void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t channel, + uint32_t ch_width) { - return; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return; + } + + if (pm_ctx->sap_restart_chan_switch_cb) { + policy_mgr_info("SAP change change without restart"); + pm_ctx->sap_restart_chan_switch_cb(vdev_id, + channel, ch_width); + } } #endif @@ -694,7 +719,7 @@ QDF_STATUS policy_mgr_restart_opportunistic_timer( #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( struct wlan_objmgr_psoc *psoc, - void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)) + void (*sap_restart_chan_switch_cb)(uint8_t, uint32_t, uint32_t)) { struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index be7a6fb3d3dc..e0df1842819e 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1163,11 +1163,46 @@ uint32_t policy_mgr_get_concurrency_mode(void) return 0; } +/** + * policy_mgr_get_channel_from_scan_result() - to get channel from scan result + * @psoc: PSOC object information + * @roam_profile: pointer to roam profile + * @channel: channel to be filled + * + * This routine gets channel which most likely a candidate to which STA + * will make connection. + * + * Return: QDF_STATUS + */ QDF_STATUS policy_mgr_get_channel_from_scan_result( struct wlan_objmgr_psoc *psoc, void *roam_profile, uint8_t *channel) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status; + void *scan_cache = NULL; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_INVAL; + } + + if (!roam_profile || !channel) { + policy_mgr_err("Invalid input parameters"); + return QDF_STATUS_E_INVAL; + } + + status = pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan_cache + (roam_profile, &scan_cache, channel); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Get AP channel failed"); + return status; + } + + status = pm_ctx->sme_cbacks.sme_scan_result_purge(scan_cache); + + return status; } uint8_t policy_mgr_search_and_check_for_session_conc( @@ -1341,11 +1376,6 @@ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( return QDF_STATUS_SUCCESS; } -void policy_mgr_set_mcc_latency(struct wlan_objmgr_psoc *psoc, int set_value) -{ - return; -} - struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(uint32_t *len) { struct policy_mgr_conc_connection_info *conn_ptr = @@ -1412,9 +1442,20 @@ bool policy_mgr_is_multiple_active_sta_sessions(struct wlan_objmgr_psoc *psoc) psoc, PM_STA_MODE, NULL) > 1; } -bool policy_mgr_is_sta_active_connection_exists(void) +/** + * policy_mgr_is_sta_active_connection_exists() - Check if a STA + * connection is active + * @psoc: PSOC object information + * + * Checks if there is atleast one active STA connection in the driver + * + * Return: True if an active STA session is present, False otherwise + */ +bool policy_mgr_is_sta_active_connection_exists( + struct wlan_objmgr_psoc *psoc) { - return true; + return (!policy_mgr_mode_specific_connection_count( + psoc, QDF_STA_MODE, NULL)) ? false : true; } bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index aef5d76712f6..bd0add049428 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -260,7 +260,7 @@ struct policy_mgr_psoc_priv_obj { qdf_event_t connection_update_done_evt; qdf_mutex_t qdf_conc_list_lock; qdf_mc_timer_t dbs_opportunistic_timer; - void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t); + void (*sap_restart_chan_switch_cb)(uint8_t, uint32_t, uint32_t); struct policy_mgr_sme_cbacks sme_cbacks; struct policy_mgr_wma_cbacks wma_cbacks; struct policy_mgr_tdls_cbacks tdls_cbacks; diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 425f5533f91b..6b09251bfe77 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -398,6 +398,10 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, sme_cbacks->sme_soc_set_dual_mac_config; pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval = sme_cbacks->sme_change_mcc_beacon_interval; + pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan_cache = + sme_cbacks->sme_get_ap_channel_from_scan_cache; + pm_ctx->sme_cbacks.sme_scan_result_purge = + sme_cbacks->sme_scan_result_purge; return QDF_STATUS_SUCCESS; } From 107d378bcb7fa1aad40d8111a0b99a27ae4d95d4 Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Mon, 6 Mar 2017 17:07:44 -0800 Subject: [PATCH 020/404] qcacmn: Remove legacy dependency from Policy Manager Part 4 Remove legacy dependency from Policy Manager component Part 4 Change-Id: I9b96a03031c27b87c9e74a3df512f6032051bd85 CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 19 +++-- src/wlan_policy_mgr_action.c | 15 +++- src/wlan_policy_mgr_core.c | 6 ++ src/wlan_policy_mgr_get_set_utils.c | 122 ++++++++++++++++------------ src/wlan_policy_mgr_i.h | 11 +++ 5 files changed, 114 insertions(+), 59 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index ba31e2674672..62a140fb6120 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -95,12 +95,13 @@ uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc); /** * policy_mgr_get_concurrency_mode() - return concurrency mode + * @psoc: PSOC object information * * This routine is used to retrieve concurrency mode * * Return: uint32_t value of concurrency mask */ -uint32_t policy_mgr_get_concurrency_mode(void); +uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc); /** * policy_mgr_search_and_check_for_session_conc() - Checks if @@ -150,15 +151,19 @@ QDF_STATUS policy_mgr_handle_conc_multiport( * policy_mgr_check_concurrent_intf_and_restart_sap() - Check * concurrent change intf * @psoc: PSOC object information + * @operation_channel: operation channel * * Checks the concurrent change interface and restarts SAP + * * Return: None */ void policy_mgr_check_concurrent_intf_and_restart_sap( - struct wlan_objmgr_psoc *psoc); + struct wlan_objmgr_psoc *psoc, + uint8_t operation_channel); #else static inline void policy_mgr_check_concurrent_intf_and_restart_sap( - struct wlan_objmgr_psoc *psoc) + struct wlan_objmgr_psoc *psoc, + uint8_t operation_channel) { } @@ -904,13 +909,15 @@ QDF_STATUS policy_mgr_get_channel_from_scan_result( /** * policy_mgr_concurrent_open_sessions_running() - Checks for * concurrent open session + * @psoc: PSOC object information * * Checks if more than one open session is running for all the allowed modes * in the driver * * Return: True if more than one open session exists, False otherwise */ -bool policy_mgr_concurrent_open_sessions_running(void); +bool policy_mgr_concurrent_open_sessions_running( + struct wlan_objmgr_psoc *psoc); /** * policy_mgr_max_concurrent_connections_reached() - Check if @@ -966,13 +973,15 @@ bool policy_mgr_is_sta_active_connection_exists( /** * policy_mgr_concurrent_beaconing_sessions_running() - Checks * for concurrent beaconing entities + * @psoc: PSOC object information * * Checks if multiple beaconing sessions are running i.e., if SAP or GO or IBSS * are beaconing together * * Return: True if multiple entities are beaconing together, False otherwise */ -bool policy_mgr_concurrent_beaconing_sessions_running(void); +bool policy_mgr_concurrent_beaconing_sessions_running( + struct wlan_objmgr_psoc *psoc); /** * policy_mgr_wait_for_connection_update() - Wait for hw mode diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index bdf231553ed5..dd6a622e22a0 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -577,13 +577,22 @@ QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) { - return; } +/** + * policy_mgr_check_concurrent_intf_and_restart_sap() - Check + * concurrent change intf + * @psoc: PSOC object information + * @operation_channel: operation channel + * + * Checks the concurrent change interface and restarts SAP + * + * Return: None + */ void policy_mgr_check_concurrent_intf_and_restart_sap( - struct wlan_objmgr_psoc *psoc) + struct wlan_objmgr_psoc *psoc, + uint8_t operation_channel) { - return; } #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 21203484c0cd..1b6c0b9b059e 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -159,6 +159,12 @@ bool policy_mgr_is_mas_enabled_in_user_cfg( return false; } +uint32_t policy_mgr_mcc_to_scc_switch_mode_in_user_cfg( + struct wlan_objmgr_psoc *psoc) +{ + return 0; +} + /** * policy_mgr_get_dbs_config() - Get DBS bit * diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index e0df1842819e..9fd56da450a5 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1158,9 +1158,28 @@ done: return status; } -uint32_t policy_mgr_get_concurrency_mode(void) +/** + * policy_mgr_get_concurrency_mode() - return concurrency mode + * @psoc: PSOC object information + * + * This routine is used to retrieve concurrency mode + * + * Return: uint32_t value of concurrency mask + */ +uint32_t policy_mgr_get_concurrency_mode(struct wlan_objmgr_psoc *psoc) { - return 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STA_MASK; + } + + policy_mgr_info("concurrency_mode: 0x%x", + pm_ctx->concurrency_mode); + + return pm_ctx->concurrency_mode; } /** @@ -1239,6 +1258,11 @@ uint8_t policy_mgr_search_and_check_for_session_conc( return channel; } +uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) +{ + return 0; +} + bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t channel) { @@ -1266,51 +1290,6 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, return true; } -uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) -{ - uint32_t num_connections = 0; - bool is_24G_mcc = false; - - num_connections = policy_mgr_get_connection_count(psoc); - - switch (num_connections) { - case 1: - break; - case 2: - if ((pm_conc_connection_list[0].chan != - pm_conc_connection_list[1].chan) && - (pm_conc_connection_list[0].mac == - pm_conc_connection_list[1].mac) && - (pm_conc_connection_list[0].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM) && - (pm_conc_connection_list[1].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM)) - is_24G_mcc = true; - break; - case 3: - if (((pm_conc_connection_list[0].chan != - pm_conc_connection_list[1].chan) || - (pm_conc_connection_list[0].chan != - pm_conc_connection_list[2].chan) || - (pm_conc_connection_list[1].chan != - pm_conc_connection_list[2].chan)) && - (pm_conc_connection_list[0].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM) && - (pm_conc_connection_list[1].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM) && - (pm_conc_connection_list[2].chan <= - WLAN_REG_MAX_24GHZ_CH_NUM)) - is_24G_mcc = true; - break; - default: - policy_mgr_err("unexpected num_connections value %d", - num_connections); - break; - } - - return is_24G_mcc; -} - /** * policy_mgr_is_mcc_adaptive_scheduler_enabled() - Function to * gets the policy manager mcc adaptive scheduler enabled @@ -1413,14 +1392,55 @@ enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( return mode; } -bool policy_mgr_concurrent_open_sessions_running(void) +/** + * policy_mgr_concurrent_open_sessions_running() - Checks for + * concurrent open session + * @psoc: PSOC object information + * + * Checks if more than one open session is running for all the allowed modes + * in the driver + * + * Return: True if more than one open session exists, False otherwise + */ +bool policy_mgr_concurrent_open_sessions_running( + struct wlan_objmgr_psoc *psoc) { - return true; + uint8_t i = 0; + uint8_t j = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return false; + } + + for (i = 0; i < QDF_MAX_NO_OF_MODE; i++) + j += pm_ctx->no_of_open_sessions[i]; + + return j > 1; } -bool policy_mgr_concurrent_beaconing_sessions_running(void) +/** + * policy_mgr_concurrent_beaconing_sessions_running() - Checks + * for concurrent beaconing entities + * @psoc: PSOC object information + * + * Checks if multiple beaconing sessions are running i.e., if SAP or GO or IBSS + * are beaconing together + * + * Return: True if multiple entities are beaconing together, False otherwise + */ +bool policy_mgr_concurrent_beaconing_sessions_running( + struct wlan_objmgr_psoc *psoc) { - return true; + return (policy_mgr_mode_specific_connection_count( + psoc, QDF_SAP_MODE, NULL) + + policy_mgr_mode_specific_connection_count( + psoc, QDF_P2P_GO_MODE, NULL) + + policy_mgr_mode_specific_connection_count( + psoc, QDF_IBSS_MODE, NULL) > 1) ? + true : false; } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index bd0add049428..0169b65fb18a 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -312,6 +312,17 @@ bool policy_mgr_is_dual_mac_disabled_in_ini( */ bool policy_mgr_is_mas_enabled_in_user_cfg( struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_mcc_to_scc_switch_mode_in_user_cfg() - MCC to SCC + * switch mode value in the user config + * @psoc: PSOC object information + * + * MCC to SCC switch mode value in user config + * + * Return: MCC to SCC switch mode value + */ +uint32_t policy_mgr_mcc_to_scc_switch_mode_in_user_cfg( + struct wlan_objmgr_psoc *psoc); bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc); bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc); bool policy_mgr_get_dbs_scan_config(struct wlan_objmgr_psoc *psoc); From 7e890d68b3042fc377d94bc923bd26c04a3376cf Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Thu, 2 Mar 2017 17:17:53 +0800 Subject: [PATCH 021/404] qcacmn: tdls module init and deinit tdls module init and deinit Change-Id: I751a948a46ac4e5148e35aa509fdbff25b6c5f3c CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 23 + core/src/wlan_tdls_cmds_process.h | 23 + core/src/wlan_tdls_ct.c | 23 + core/src/wlan_tdls_ct.h | 23 + core/src/wlan_tdls_main.c | 159 ++++++ core/src/wlan_tdls_main.h | 407 +++++++++++++++ core/src/wlan_tdls_mgmt.c | 23 + core/src/wlan_tdls_mgmt.h | 23 + core/src/wlan_tdls_txrx.c | 23 + core/src/wlan_tdls_txrx.h | 23 + dispatcher/inc/wlan_tdls_public_structs.h | 607 ++++++++++++++++++++++ dispatcher/inc/wlan_tdls_tgt_api.h | 23 + dispatcher/inc/wlan_tdls_ucfg_api.h | 78 +++ dispatcher/src/wlan_tdls_tgt_api.c | 23 + dispatcher/src/wlan_tdls_ucfg_api.c | 205 ++++++++ dispatcher/src/wlan_tdls_utils_api.c | 23 + 16 files changed, 1709 insertions(+) create mode 100644 core/src/wlan_tdls_cmds_process.c create mode 100644 core/src/wlan_tdls_cmds_process.h create mode 100644 core/src/wlan_tdls_ct.c create mode 100644 core/src/wlan_tdls_ct.h create mode 100644 core/src/wlan_tdls_main.c create mode 100644 core/src/wlan_tdls_main.h create mode 100644 core/src/wlan_tdls_mgmt.c create mode 100644 core/src/wlan_tdls_mgmt.h create mode 100644 core/src/wlan_tdls_txrx.c create mode 100644 core/src/wlan_tdls_txrx.h create mode 100644 dispatcher/inc/wlan_tdls_public_structs.h create mode 100644 dispatcher/inc/wlan_tdls_tgt_api.h create mode 100644 dispatcher/inc/wlan_tdls_ucfg_api.h create mode 100644 dispatcher/src/wlan_tdls_tgt_api.c create mode 100644 dispatcher/src/wlan_tdls_ucfg_api.c create mode 100644 dispatcher/src/wlan_tdls_utils_api.c diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c new file mode 100644 index 000000000000..7a6aa6cb4953 --- /dev/null +++ b/core/src/wlan_tdls_cmds_process.c @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_cmds_process.c + * + * TDLS north bound commands implementation + */ diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h new file mode 100644 index 000000000000..a90931846aba --- /dev/null +++ b/core/src/wlan_tdls_cmds_process.h @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_cmds_process.h + * + * TDLS north bound commands include file + */ diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c new file mode 100644 index 000000000000..851d0a199968 --- /dev/null +++ b/core/src/wlan_tdls_ct.c @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_ct.c + * + * TDLS connection tracker function definitions + */ diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h new file mode 100644 index 000000000000..473f2b556644 --- /dev/null +++ b/core/src/wlan_tdls_ct.h @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_ct.h + * + * TDLS connection tracker api declaration + */ diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c new file mode 100644 index 000000000000..eef8915fb300 --- /dev/null +++ b/core/src/wlan_tdls_main.c @@ -0,0 +1,159 @@ +/* + * 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: wlan_tdls_main.c + * + * TDLS core function definitions + */ + +#include "wlan_tdls_main.h" + +QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *tdls_soc_obj; + + tdls_soc_obj = qdf_mem_malloc(sizeof(*tdls_soc_obj)); + if (tdls_soc_obj == NULL) { + tdls_err("Failed to allocate memory for tdls object"); + return QDF_STATUS_E_NOMEM; + } + + tdls_soc_obj->soc = psoc; + + status = wlan_objmgr_psoc_component_obj_attach(psoc, + WLAN_UMAC_COMP_TDLS, + (void *)tdls_soc_obj, + QDF_STATUS_SUCCESS); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to attach psoc tdls component"); + qdf_mem_free(tdls_soc_obj); + } + + tdls_notice("TDLS obj attach to psoc successfully"); + + return status; +} + +QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *tdls_soc_obj; + + tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (tdls_soc_obj == NULL) { + tdls_err("Failed to get tdls obj in psoc"); + return QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_psoc_component_obj_detach(psoc, + WLAN_UMAC_COMP_TDLS, + tdls_soc_obj); + + if (QDF_IS_STATUS_ERROR(status)) + tdls_err("Failed to detach psoc tdls component"); + + qdf_mem_free(tdls_soc_obj); + + return status; +} + +static void tdls_vdev_init(struct tdls_vdev_priv_obj *vdev) +{ + uint8_t i; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + qdf_list_create(&vdev->peer_list[i], + WLAN_TDLS_PEER_SUB_LIST_SIZE); + } + + qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW, + NULL, vdev); + qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW, + NULL, vdev); +} + +QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, + void *arg) +{ + QDF_STATUS status; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + + tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && + wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) + return QDF_STATUS_SUCCESS; + + /* TODO: Add concurrency check */ + + tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj)); + if (tdls_vdev_obj == NULL) { + tdls_err("Failed to allocate memory for tdls vdev object"); + return QDF_STATUS_E_NOMEM; + } + + tdls_vdev_obj->vdev = vdev; + tdls_vdev_init(tdls_vdev_obj); + + status = wlan_objmgr_vdev_component_obj_attach(vdev, + WLAN_UMAC_COMP_TDLS, + (void *)tdls_vdev_obj, + QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to attach vdev tdls component"); + qdf_mem_free(tdls_vdev_obj); + } + + tdls_notice("tdls object attach to vdev successfully"); + + return status; +} + +QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, + void *arg) +{ + QDF_STATUS status; + void *tdls_vdev_obj; + + tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && + wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) + return QDF_STATUS_SUCCESS; + + tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); + if (tdls_vdev_obj == NULL) { + tdls_err("Failed to get tdls vdev object"); + return QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_vdev_component_obj_detach(vdev, + WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj); + if (QDF_IS_STATUS_ERROR(status)) + tdls_err("Failed to detach vdev tdls component"); + + qdf_mem_free(tdls_vdev_obj); + + return status; +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h new file mode 100644 index 000000000000..b85c74cc5f57 --- /dev/null +++ b/core/src/wlan_tdls_main.h @@ -0,0 +1,407 @@ +/* + * 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: wlan_tdls_main.h + * + * TDLS core function declaration + */ + +#if !defined(_WLAN_TDLS_MAIN_H_) +#define _WLAN_TDLS_MAIN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Bit mask flag for tdls_option to FW */ +#define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ +#define ENA_TDLS_BUFFER_STA (1 << 1) /* TDLS Buffer STA support */ +#define ENA_TDLS_SLEEP_STA (1 << 2) /* TDLS Sleep STA support */ + +#define tdls_log(level, args...) \ + QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) +#define tdls_logfl(level, format, args...) \ + tdls_log(level, FL(format), ## args) + +#define tdls_debug(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) +#define tdls_notice(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) +#define tdls_warn(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) +#define tdls_err(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) +#define tdls_alert(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) + +#define TDLS_IS_CONNECTED(peer) \ + ((TDLS_LINK_CONNECTED == (peer)->link_status) || \ + (TDLS_LINK_TEARING == (peer)->link_status)) + +#define SET_BIT(value, mask) ((value) |= (1 << (mask))) +#define CLEAR_BIT(value, mask) ((value) &= ~(1 << (mask))) +#define CHECK_BIT(value, mask) ((value) & (1 << (mask))) +/** + * struct tdls_conn_info - TDLS connection record + * @session_id: session id + * @sta_id: sta id + * @peer_mac: peer address + */ +struct tdls_conn_info { + uint8_t session_id; + uint8_t sta_id; + struct qdf_mac_addr peer_mac; +}; + +/** + * enum tdls_nss_transition_state - TDLS NSS transition states + * @TDLS_NSS_TRANSITION_UNKNOWN: default state + * @TDLS_NSS_TRANSITION_2x2_to_1x1: transition from 2x2 to 1x1 stream + * @TDLS_NSS_TRANSITION_1x1_to_2x2: transition from 1x1 to 2x2 stream + */ +enum tdls_nss_transition_state { + TDLS_NSS_TRANSITION_S_UNKNOWN = 0, + TDLS_NSS_TRANSITION_S_2x2_to_1x1, + TDLS_NSS_TRANSITION_S_1x1_to_2x2, +}; + +/** + * enum tdls_command_type - TDLS command type + * @TDLS_CMD_TX_ACTION: send tdls action frame + * @TDLS_CMD_ADD_STA: add tdls peer + * @TDLS_CMD_CHANGE_STA: change tdls peer + * @TDLS_CMD_ENABLE_LINK: enable tdls link + * @TDLS_CMD_DISABLE_LINK: disable tdls link + * @TDLS_CMD_CONFIG_FORCE_PEER: config external peer + * @TDLS_CMD_REMOVE_FORCE_PEER: remove external peer + * @TDLS_CMD_STATS_UPDATE: update tdls stats + * @TDLS_CMD_CONFIG_UPDATE: config tdls + */ +enum tdls_commmand_type { + TDLS_CMD_TX_ACTION = 1, + TDLS_CMD_ADD_STA, + TDLS_CMD_CHANGE_STA, + TDLS_CMD_ENABLE_LINK, + TDLS_CMD_DISABLE_LINK, + TDLS_CMD_CONFIG_FORCE_PEER, + TDLS_CMD_REMOVE_FORCE_PEER, + TDLS_CMD_STATS_UPDATE, + TDLS_CMD_CONFIG_UPDATE +}; + +/** + * struct tdls_conn_tracker_mac_table - connection tracker peer table + * @mac_address: peer mac address + * @tx_packet_cnt: number of tx pkts + * @rx_packet_cnt: number of rx pkts + * @peer_timestamp_ms: time stamp of latest peer traffic + */ +struct tdls_conn_tracker_mac_table { + struct qdf_mac_addr mac_address; + uint32_t tx_packet_cnt; + uint32_t rx_packet_cnt; + uint32_t peer_timestamp_ms; +}; + +/** + * struct tdls_set_state_db - to record set tdls state command, we need to + * set correct tdls state to firmware: + * 1. enable tdls in firmware before tdls connection; + * 2. disable tdls if concurrency happen, before disable tdls, all active peer + * should be deleted in firmware. + * + * @set_state_cnt: tdls set state count + * @vdev_id: vdev id of last set state command + */ +struct tdls_set_state_info { + uint8_t set_state_cnt; + uint8_t vdev_id; +}; + +/** + * struct tdls_psoc_priv_ctx - tdls context + * @soc: objmgr psoc + * @tdls_current_mode: current tdls mode + * @tdls_user_config_mode: user configure tdls mode + * @tdls_conn_info: this tdls_conn_info can be removed and we can use peer type + * of peer object to get the active tdls peers + * @tdls_configs: tdls user configure + * @max_num_tdls_sta: maximum TDLS station number allowed upon runtime condition + * @connected_peer_count: tdls peer connected count + * @tdls_off_channel: tdls off channel number + * @tdls_channel_offset: tdls channel offset + * @tdls_fw_off_chan_mode: tdls fw off channel mode + * @enable_tdls_connection_tracker: enable tdls connection tracker + * @tdls_external_peer_count: external tdls peer count + * @tdls_nss_switch_in_progress: tdls antenna switch in progress + * @tdls_nss_teardown_complete: tdls tear down complete + * @tdls_nss_transition_mode: tdls nss transition mode + * @tdls_teardown_peers_cnt: tdls tear down peer count + * @tdls_tx_cnf_cb: callback registered by hdd to receive the ack cnf + * @set_state_info: set tdls state info + * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb + * @tdls_event_cb: tdls event callback + * @tdls_evt_cb_data: tdls event user data + * @tx_q_ack: queue for tx frames waiting for ack + * @tdls_con_cap: tdls concurrency support + */ +struct tdls_soc_priv_obj { + struct wlan_objmgr_psoc *soc; + enum tdls_support_mode tdls_current_mode; + enum tdls_support_mode tdls_user_config_mode; + struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM]; + struct tdls_user_config tdls_configs; + uint16_t max_num_tdls_sta; + uint16_t connected_peer_count; + uint8_t tdls_off_channel; + uint16_t tdls_channel_offset; + int32_t tdls_fw_off_chan_mode; + bool enable_tdls_connection_tracker; + uint8_t tdls_external_peer_count; + bool tdls_nss_switch_in_progress; + bool tdls_nss_teardown_complete; + enum tdls_nss_transition_state tdls_nss_transition_mode; + int32_t tdls_teardown_peers_cnt; + struct tdls_set_state_info set_state_info; + tdls_tx_ack_cnf_callback tdls_tx_cnf_cb; + void *tx_ack_cnf_cb_data; + tdls_evt_callback tdls_event_cb; + void *tdls_evt_cb_data; + qdf_list_t tx_q_ack; + enum tdls_conc_cap tdls_con_cap; +}; + +/** + * struct tdls_vdev_priv_obj - tdls private vdev object + * @vdev: vdev objmgr object + * @peer_list: tdls peer list on this vdev + * @peer_update_timer: connection tracker timer + * @peer_dicovery_timer: peer discovery timer + * @threshold_config: threshold config + * @discovery_peer_cnt: discovery peer count + * @discovery_sent_cnt: discovery sent count + * @ap_rssi: ap rssi + * @curr_candidate: current candidate + * @ct_peer_table: linear mac address table for counting the packets + * @valid_mac_entries: number of valid mac entry in @ct_peer_mac_table + * @magic: magic + * @tx_queue: tx frame queue + */ +struct tdls_vdev_priv_obj { + struct wlan_objmgr_vdev *vdev; + qdf_list_t peer_list[WLAN_TDLS_PEER_LIST_SIZE]; + qdf_mc_timer_t peer_update_timer; + qdf_mc_timer_t peer_discovery_timer; + struct tdls_config_params threshold_config; + int32_t discovery_peer_cnt; + uint32_t discovery_sent_cnt; + int8_t ap_rssi; + struct tdls_peer *curr_candidate; + struct tdls_conn_tracker_mac_table + ct_peer_table[WLAN_TDLS_CT_TABLE_SIZE]; + uint8_t valid_mac_entries; + uint32_t magic; + qdf_list_t tx_queue; +}; + +/** + * struct tdls_peer - tdls peer data + * @node: node + * @vdev_priv: tdls vdev priv obj + * @peer_mac: peer mac address + * @sta_id: station identifier + * @rssi: rssi + * @tdls_support: tdls support + * @link_status: tdls link status + * @signature: signature + * @is_responder: is responder + * @discovery_processed: dicovery processed + * @discovery_attempt: discovery attempt + * @tx_pkt: tx packet + * @rx_pkt: rx packet + * @uapsd_queues: uapsd queues + * @max_sp: max sp + * @buf_sta_capable: is buffer sta + * @off_channel_capable: is offchannel supported flag + * @supported_channels_len: supported channels length + * @supported_channels: supported channels + * @supported_oper_classes_len: supported operation classes length + * @supported_oper_classes: supported operation classes + * @is_forced_peer: is forced peer + * @op_class_for_pref_off_chan: op class for preferred off channel + * @pref_off_chan_num: preferred off channel number + * @op_class_for_pref_off_chan_is_set: op class for preferred off channel set + * @peer_idle_timer: time to check idle traffic in tdls peers + * @is_peer_idle_timer_initialised: Flag to check idle timer init + * @spatial_streams: Number of TX/RX spatial streams for TDLS + * @reason: reason + * @state_change_notification: state change notification + * @qos: QOS capability of TDLS link + */ +struct tdls_peer { + qdf_list_node_t node; + struct tdls_vdev_priv_obj *vdev_priv; + struct qdf_mac_addr peer_mac; + uint16_t sta_id; + int8_t rssi; + enum tdls_peer_capab tdls_support; + enum tdls_link_status link_status; + uint8_t signature; + uint8_t is_responder; + uint8_t discovery_processed; + uint16_t discovery_attempt; + uint16_t tx_pkt; + uint16_t rx_pkt; + uint8_t uapsd_queues; + uint8_t max_sp; + uint8_t buf_sta_capable; + uint8_t off_channel_capable; + uint8_t supported_channels_len; + uint8_t supported_channels[WLAN_MAC_MAX_SUPP_CHANNELS]; + uint8_t supported_oper_classes_len; + uint8_t supported_oper_classes[WLAN_MAX_SUPP_OPER_CLASSES]; + bool is_forced_peer; + uint8_t op_class_for_pref_off_chan; + uint8_t pref_off_chan_num; + uint8_t op_class_for_pref_off_chan_is_set; + qdf_mc_timer_t peer_idle_timer; + bool is_peer_idle_timer_initialised; + uint8_t spatial_streams; + enum tdls_link_reason reason; + tdls_state_change_callback state_change_notification; + uint8_t qos; +}; + +/** + * wlan_vdev_get_tdls_soc_obj - private API to get tdls soc object from vdev + * @vdev: vdev object + * + * Return: tdls soc object + */ +static inline struct tdls_soc_priv_obj * +wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_psoc *psoc = + wlan_pdev_get_psoc(wlan_vdev_get_pdev(vdev)); + + return (struct tdls_soc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); +} + +/** + * wlan_psoc_get_tdls_soc_obj - private API to get tdls soc object from psoc + * @psoc: psoc object + * + * Return: tdls soc object + */ +static inline struct tdls_soc_priv_obj * +wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc) +{ + return (struct tdls_soc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); +} + +/** + * wlan_vdev_get_tdls_vdev_obj - private API to get tdls vdev object from vdev + * @vdev: vdev object + * + * Return: tdls vdev object + */ +static inline struct tdls_vdev_priv_obj * +wlan_vdev_get_tdls_vdev_obj(struct wlan_objmgr_vdev *vdev) +{ + return (struct tdls_vdev_priv_obj *) + wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); +} + +/** + * tdls_set_link_status - tdls set link status + * @vdev: vdev object + * @mac: mac address of tdls peer + * @link_status: tdls link status + * @link_reason: reason + */ +void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev, + const uint8_t *mac, + enum tdls_link_status link_status, + enum tdls_link_reason link_reason); +/** + * tdls_psoc_obj_create_notification() - tdls psoc create notification handler + * @psoc: psoc object + * @arg_list: Argument list + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list); + +/** + * tdls_psoc_obj_destroy_notification() - tdls psoc destroy notification handler + * @psoc: psoc object + * @arg_list: Argument list + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list); + +/** + * tdls_vdev_obj_create_notification() - tdls vdev create notification handler + * @vdev: vdev object + * @arg_list: Argument list + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, + void *arg_list); + +/** + * tdls_vdev_obj_destroy_notification() - tdls vdev destroy notification handler + * @vdev: vdev object + * @arg_list: Argument list + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, + void *arg_list); + +/** + * tdls_process_cmd() - tdls main command process function + * @msg: scheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg); + +/** + * tdls_process_evt() - tdls main event process function + * @msg: scheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_evt(struct scheduler_msg *msg); +#endif diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c new file mode 100644 index 000000000000..a8e5f8798076 --- /dev/null +++ b/core/src/wlan_tdls_mgmt.c @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_mgmt.c + * + * TDLS management frames implementation + */ diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h new file mode 100644 index 000000000000..1abd2484120e --- /dev/null +++ b/core/src/wlan_tdls_mgmt.h @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_mgmt.h + * + * TDLS management frames include file + */ diff --git a/core/src/wlan_tdls_txrx.c b/core/src/wlan_tdls_txrx.c new file mode 100644 index 000000000000..6ded57c974f8 --- /dev/null +++ b/core/src/wlan_tdls_txrx.c @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_txrx.c + * + * TDLS txrx function definitions + */ diff --git a/core/src/wlan_tdls_txrx.h b/core/src/wlan_tdls_txrx.h new file mode 100644 index 000000000000..b001ffe74599 --- /dev/null +++ b/core/src/wlan_tdls_txrx.h @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_txrx.h + * + * TDLS txrx api declaration + */ diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h new file mode 100644 index 000000000000..d9b5d8da985d --- /dev/null +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -0,0 +1,607 @@ +/* + * 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: wlan_tdls_public_structs.h + * + * TDLS public structure definations + */ + +#ifndef _WLAN_TDLS_STRUCTS_H_ +#define _WLAN_TDLS_STRUCTS_H_ +#include +#include +#include +#include +#include + +#define WLAN_TDLS_STA_MAX_NUM 8 +#define WLAN_TDLS_PEER_LIST_SIZE 256 +#define WLAN_TDLS_CT_TABLE_SIZE 8 +#define WLAN_TDLS_PEER_SUB_LIST_SIZE 10 +#define WLAN_MAC_MAX_EXTN_CAP 8 +#define WLAN_MAC_MAX_SUPP_CHANNELS 100 +#define WLAN_MAX_SUPP_OPER_CLASSES 32 +#define WLAN_MAC_MAX_SUPP_RATES 32 +#define ENABLE_CHANSWITCH 1 + +#define TDLS_STA_INDEX_CHECK(sta_id) \ + (((sta_id) >= 1) && ((sta_id) < 0xFF)) +/** + * enum tdls_conc_cap - tdls concurrency support + * @TDLS_SUPPORTED_ONLY_ON_STA: only support sta tdls + * @TDLS_SUPPORTED_ONLY_ON_P2P_CLIENT: only support p2p client tdls + */ +enum tdls_conc_cap { + TDLS_SUPPORTED_ONLY_ON_STA = 0, + TDLS_SUPPORTED_ONLY_ON_P2P_CLIENT, +}; + +/** + * enum tdls_peer_capab - tdls capability type + * @TDLS_CAP_NOT_SUPPORTED: tdls not supported + * @TDLS_CAP_UNKNOWN: unknown capability + * @TDLS_CAP_SUPPORTED: tdls capability supported + */ +enum tdls_peer_capab { + TDLS_CAP_NOT_SUPPORTED = -1, + TDLS_CAP_UNKNOWN = 0, + TDLS_CAP_SUPPORTED = 1, +}; + +/** + * enum tdls_link_status - tdls link status + * @TDLS_LINK_IDLE: tdls link idle + * @TDLS_LINK_DISCOVERING: tdls link discovering + * @TDLS_LINK_DISCOVERED: tdls link discovered + * @TDLS_LINK_CONNECTING: tdls link connecting + * @TDLS_LINK_CONNECTED: tdls link connected + * @TDLS_LINK_TEARING: tdls link tearing + */ +enum tdls_link_status { + TDLS_LINK_IDLE = 0, + TDLS_LINK_DISCOVERING, + TDLS_LINK_DISCOVERED, + TDLS_LINK_CONNECTING, + TDLS_LINK_CONNECTED, + TDLS_LINK_TEARING, +}; + +/** + * enum tdls_link_reason - tdls link reason + * @TDLS_LINK_SUCCESS: Success + * @TDLS_LINK_UNSPECIFIED: Unspecified reason + * @TDLS_LINK_NOT_SUPPORTED: Remote side doesn't support TDLS + * @TDLS_LINK_UNSUPPORTED_BAND: Remote side doesn't support this band + * @TDLS_LINK_NOT_BENEFICIAL: Going to AP is better than direct + * @TDLS_LINK_DROPPED_BY_REMOTE: Remote side doesn't want it anymore + */ +enum tdls_link_reason { + TDLS_LINK_SUCCESS, + TDLS_LINK_UNSPECIFIED = -1, + TDLS_LINK_NOT_SUPPORTED = -2, + TDLS_LINK_UNSUPPORTED_BAND = -3, + TDLS_LINK_NOT_BENEFICIAL = -4, + TDLS_LINK_DROPPED_BY_REMOTE = -5, +}; + +/** + * enum tdls_support_mode - TDLS support mode + * @TDLS_SUPPORT_DISABLED: Disabled in ini or FW + * @TDLS_SUPPORT_SUSPENDED: TDLS supported by ini and FW, but disabled + * temporarily due to off-channel operations or due to other reasons + * @TDLS_SUPPORT_EXP_TRIG_ONLY: Explicit trigger mode + * @TDLS_SUPPORT_IMP_MODE: Implicit mode + * @TDLS_SUPPORT_EXT_CONTROL: External control mode + */ +enum tdls_support_mode { + TDLS_SUPPORT_DISABLED = 0, + TDLS_SUPPORT_SUSPENDED, + TDLS_SUPPORT_EXP_TRIG_ONLY, + TDLS_SUPPORT_IMP_MODE, + TDLS_SUPPORT_EXT_CONTROL, +}; + +/** + * enum tdls_event_type - TDLS event type + * @TDLS_EVENT_VDEV_STATE_CHANGE: umac connect/disconnect event + * @TDLS_EVENT_MGMT_TX_ACK_CNF: tx tdls frame ack event + * @TDLS_EVENT_RX_MGMT: rx discovery response frame + * @TDLS_EVENT_ADD_PEER: add peer or update peer + * @TDLS_EVENT_DEL_PEER: delete peer + */ +enum tdls_event_type { + TDLS_EVENT_VDEV_STATE_CHANGE = 0, + TDLS_EVENT_MGMT_TX_ACK_CNF, + TDLS_EVENT_RX_MGMT, + TDLS_EVENT_ADD_PEER, + TDLS_EVENT_DEL_PEER, +}; + +/** + * enum tdls_state_t - tdls state + * + * @QCA_WIFI_HAL_TDLS_DISABLED: TDLS is not enabled, or is disabled now + * @QCA_WIFI_HAL_TDLS_ENABLED: TDLS is enabled, but not yet tried + * @QCA_WIFI_HAL_TDLS_ESTABLISHED: Direct link is established + * @QCA_WIFI_HAL_TDLS_ESTABLISHED_OFF_CHANNEL: Direct link established using MCC + * @QCA_WIFI_HAL_TDLS_DROPPED: Direct link was established, but is now dropped + * @QCA_WIFI_HAL_TDLS_FAILED: Direct link failed + */ +enum tdls_state_t { + QCA_WIFI_HAL_TDLS_S_DISABLED = 1, + QCA_WIFI_HAL_TDLS_S_ENABLED, + QCA_WIFI_HAL_TDLS_S_ESTABLISHED, + QCA_WIFI_HAL_TDLS_S_ESTABLISHED_OFF_CHANNEL, + QCA_WIFI_HAL_TDLS_S_DROPPED, + QCA_WIFI_HAL_TDLS_S_FAILED, +}; + +/** + * enum tdls_event_msg_type - TDLS event message type + * @TDLS_SHOULD_DISCOVER: should do discover + * @TDLS_SHOULD_TEARDOWN: notify teardown the link + * @TDLS_PEER_DISCONNECTED: tdls peer disconnected + * @TDLS_CONNECTION_TRACKER_NOTIFY: connection tracker notify + */ +enum tdls_event_msg_type { + TDLS_SHOULD_DISCOVER = 0, + TDLS_SHOULD_TEARDOWN, + TDLS_PEER_DISCONNECTED, + TDLS_CONNECTION_TRACKER_NOTIFY, +}; + +/** + * enum tdls_event_reason - TDLS event reason + * @TDLS_TEARDOWN_TX: + * @TDLS_TEARDOWN_RSSI: + * @TDLS_TEARDOWN_SCAN: + * @TDLS_TEARDOWN_PTR_TIMEOUT: + * @TDLS_TEARDOWN_BAD_PTR: + * @TDLS_TEARDOWN_NO_RSP: + * @TDLS_DISCONNECTED_PEER_DELETE: + * @TDLS_PEER_ENTER_BUF_STA: + * @TDLS_PEER_EXIT_BUF_STA: + * @TDLS_ENTER_BT_BUSY: + * @TDLS_EXIT_BT_BUSY: + * @DLS_SCAN_STARTED: + * @TDLS_SCAN_COMPLETED: + */ +enum tdls_event_reason { + TDLS_TEARDOWN_TX, + TDLS_TEARDOWN_RSSI, + TDLS_TEARDOWN_SCAN, + TDLS_TEARDOWN_PTR_TIMEOUT, + TDLS_TEARDOWN_BAD_PTR, + TDLS_TEARDOWN_NO_RSP, + TDLS_DISCONNECTED_PEER_DELETE, + TDLS_PEER_ENTER_BUF_STA, + TDLS_PEER_EXIT_BUF_STA, + TDLS_ENTER_BT_BUSY, + TDLS_EXIT_BT_BUSY, + TDLS_SCAN_STARTED, + TDLS_SCAN_COMPLETED, +}; + +/** + * struct tx_frame - tx frame + * @buf: frame buffer + * @buf_len: buffer length + * @tx_timer: tx send timer + */ +struct tx_frame { + uint8_t *buf; + size_t buf_len; + qdf_timer_t tx_timer; +}; + +/** + * enum tdls_feature_bit + * @TDLS_FEATURE_OFF_CHANNEL: tdls off channel + * @TDLS_FEATURE_WMM: tdls wmm + * @TDLS_FEATURE_BUFFER_STA: tdls buffer sta + * @TDLS_FEATURE_SLEEP_STA: tdls sleep sta feature + * @TDLS_FEATURE_SCAN: tdls scan + * @TDLS_FEATURE_ENABLE: tdls enabled + * @TDLS_FEAUTRE_IMPLICIT_TRIGGER: tdls implicit trigger + * @TDLS_FEATURE_EXTERNAL_CONTROL: tdls external control + */ +enum tdls_feature_bit { + TDLS_FEATURE_OFF_CHANNEL, + TDLS_FEATURE_WMM, + TDLS_FEATURE_BUFFER_STA, + TDLS_FEATURE_SLEEP_STA, + TDLS_FEATURE_SCAN, + TDLS_FEATURE_ENABLE, + TDLS_FEAUTRE_IMPLICIT_TRIGGER, + TDLS_FEATURE_EXTERNAL_CONTROL +}; + +#define TDLS_IS_OFF_CHANNEL_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_OFF_CHANNEL, flags) +#define TDLS_IS_WMM_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_WMM, flags) +#define TDLS_IS_BUFFER_STA_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_BUFFER_STA, flags) +#define TDLS_IS_SLEEP_STA_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_SLEEP_STA, flags) +#define TDLS_IS_SCAN_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_SCAN, flags) +#define TDLS_IS_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_ENABLE, flags) +#define TDLS_IS_IMPLICIT_TRIG_ENABLED(flags) \ + CHECK_BIT(TDLS_FEAUTRE_IMPLICIT_TRIGGER, flags) +#define TDLS_IS_EXTERNAL_CONTROL_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_EXTERNAL_CONTROL, flags) + +/** + * struct tdls_user_config - TDLS user configuration + * @tdls_tx_states_period: tdls tx states period + * @tdls_tx_pkt_threshold: tdls tx packets threshold + * @tdls_rx_pkt_threshold: tdls rx packets threshold + * @tdls_max_discovery_attempt: tdls discovery max times + * @tdls_idle_timeout: tdls idle timeout + * @tdls_idle_pkt_threshold: tdls idle packets threshold + * @tdls_rssi_trigger_threshold: tdls rssi trigger threshold + * @tdls_rssi_teardown_threshold: tdls rssi tear down threshold + * @tdls_rssi_delta: tdls rssi delta + * @tdls_uapsd_mask: tdls uapsd mask + * @tdls_uapsd_inactivity_time: tdls uapsd inactivity time + * @tdls_uapsd_pti_window: tdls peer traffic indication window + * @tdls_uapsd_ptr_timeout: tdls peer response timeout + * @tdls_feature_flags: tdls feature flags + * @tdls_pre_off_chan_num: tdls off channel number + * @tdls_pre_off_chan_bw: tdls off channel bandwidth + * @tdls_peer_kickout_threshold: sta kickout threshold for tdls peer + */ +struct tdls_user_config { + uint32_t tdls_tx_states_period; + uint32_t tdls_tx_pkt_threshold; + uint32_t tdls_rx_pkt_threshold; + uint32_t tdls_max_discovery_attempt; + uint32_t tdls_idle_timeoute; + uint32_t tdls_idle_pkt_threshold; + uint32_t tdls_rssi_trigger_threshold; + uint32_t tdls_rssi_teardown_threshold; + uint32_t tdls_rssi_delta; + uint32_t tdls_uapsd_mask; + uint32_t tdls_uapsd_inactivity_time; + uint32_t tdls_uapsd_pti_window; + uint32_t tdls_uapsd_ptr_timeout; + uint32_t tdls_feature_flags; + uint32_t tdls_pre_off_chan_num; + uint32_t tdls_pre_off_chan_bw; + uint32_t tdls_peer_kickout_threshold; +}; + +/** + * struct tdls_config_params - tdls configure paramets + * @tdls: tdls support mode + * @tx_period_t: tdls tx stats period + * @tx_packet_n: tdls tx packets number threshold + * @discovery_tries_n: tdls max discovery attempt count + * @idle_timeout_t: tdls idle time timeout + * @idle_packet_n: tdls idle pkt threshold + * @rssi_trigger_threshold: tdls rssi trigger threshold, checked before setup + * @rssi_teardown_threshold: tdls rssi teardown threshold + * @rssi_delta: rssi delta + */ +struct tdls_config_params { + uint32_t tdls; + uint32_t tx_period_t; + uint32_t tx_packet_n; + uint32_t discovery_tries_n; + uint32_t idle_timeout_t; + uint32_t idle_packet_n; + int32_t rssi_trigger_threshold; + int32_t rssi_teardown_threshold; + int32_t rssi_delta; +}; + +/** + * struct tdls_tx_cnf: tdls tx ack + * @vdev_id: vdev id + * @action_cookie: frame cookie + * @buf: frame buf + * @buf_len: buffer length + * @status: tx send status + */ +struct tdls_tx_cnf { + int vdev_id; + uint64_t action_cookie; + void *buf; + size_t buf_len; + int status; +}; + +/* This callback is used to report state change of peer to wpa_supplicant */ +typedef int (*tdls_state_change_callback)(const uint8_t *mac, + uint32_t opclass, + uint32_t channel, + uint32_t state, + int32_t reason, void *ctx); + +/* This callback is used to report events to os_if layer */ +typedef QDF_STATUS (*tdls_evt_callback) (void *data, + enum tdls_event_type ev_type, + void *event); + +/* prototype of callback registered by hdd to receive the ack cnf */ +typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, + struct tdls_tx_cnf *tx_ack_cnf_cb_data); + +/** + * struct tdls_start_params - tdls start params + * @tdls_event_cb: tdls event callback + * @tdls_evt_cb_data: tdls event data + * @ack_cnf_cb: tdls tx ack callback to indicate the tx status + * @tx_ack_cnf_cb_data: tdls tx ack user data + */ +struct tdls_start_params { + tdls_evt_callback tdls_event_cb; + void *tdls_evt_cb_data; + tdls_tx_ack_cnf_callback ack_cnf_cb; + void *tx_ack_cnf_cb_data; +}; + +/** + * struct tdls_add_peer_params - add peer request parameter + * @peer_addr: peer mac addr + * @peer_type: peer type + * @vdev_id: vdev id + */ +struct tdls_add_peer_params { + const uint8_t *peer_addr; + uint32_t peer_type; + uint32_t vdev_id; +}; + +/** + * struct tdls_add_peer_request - peer add request + * @vdev: vdev + * @add_peer_req: add peer request parameters + */ +struct tdls_add_peer_request { + struct wlan_objmgr_vdev *vdev; + struct tdls_add_peer_params add_peer_req; +}; + +/** + * struct tdls_del_peer_params - delete peer request parameter + * @peer_addr: peer mac addr + * @peer_type: peer type + * @vdev_id: vdev id + */ +struct tdls_del_peer_params { + const uint8_t *peer_addr; + uint32_t peer_type; + uint32_t vdev_id; +}; + +/** + * struct tdls_del_peer_request - peer delete request + * @vdev: vdev + * @del_peer_req: delete peer request parameters + */ +struct tdls_del_peer_request { + struct wlan_objmgr_vdev *vdev; + struct tdls_del_peer_params del_peer_req; +}; + +/** + * struct vhgmcsinfo - VHT MCS information + * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams + * @rx_highest: Indicates highest long GI VHT PPDU data rate + * STA can receive. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams + * @tx_highest: Indicates highest long GI VHT PPDU data rate + * STA can transmit. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest TX data rate supported. + */ +struct vhtmcsinfo { + uint16_t rx_mcs_map; + uint16_t rx_highest; + uint16_t tx_mcs_map; + uint16_t tx_highest; +}; + +/** + * struct vhtcap - VHT capabilities + * + * This structure is the "VHT capabilities element" as + * described in 802.11ac D3.0 8.4.2.160 + * @vht_cap_info: VHT capability info + * @supp_mcs: VHT MCS supported rates + */ +struct vhtcap { + uint32_t vht_capinfo; + struct vhtmcsinfo supp_mcs; +}; + +struct tdls_update_peer_params { + const uint8_t *peer_addr; + uint32_t peer_type; + uint32_t vdev_id; + uint16_t capability; + uint8_t extn_capability[WLAN_MAC_MAX_EXTN_CAP]; + uint8_t supported_rates_len; + uint8_t supported_rates[WLAN_MAC_MAX_SUPP_RATES]; + uint8_t htcap_present; + struct htcap_cmn_ie ht_cap; + uint8_t vhtcap_present; + struct vhtcap vht_cap; + uint8_t uapsd_queues; + uint8_t max_sp; + uint8_t supported_channels_len; + uint8_t supported_channels[WLAN_MAC_MAX_SUPP_CHANNELS]; + uint8_t supported_oper_classes_len; + uint8_t supported_oper_classes[WLAN_MAX_SUPP_OPER_CLASSES]; +}; + +struct tdls_update_peer_request { + struct wlan_objmgr_vdev *vdev; + struct tdls_update_peer_params update_peer_req; +}; + +/** + * struct tdls_info - tdls info + * + * @vdev_id: vdev id + * @tdls_state: tdls state + * @notification_interval_ms: notification interval in ms + * @tx_discovery_threshold: tx discovery threshold + * @tx_teardown_threshold: tx teardown threshold + * @rssi_teardown_threshold: rx teardown threshold + * @rssi_delta: rssi delta + * @tdls_options: tdls options + * @peer_traffic_ind_window: peer traffic indication window + * @peer_traffic_response_timeout: peer traffic response timeout + * @puapsd_mask: puapsd mask + * @puapsd_inactivity_time: puapsd inactivity time + * @puapsd_rx_frame_threshold: puapsd rx frame threshold + * @teardown_notification_ms: tdls teardown notification interval + * @tdls_peer_kickout_threshold: tdls packets threshold + * for peer kickout operation + */ +struct tdls_info { + uint32_t vdev_id; + uint32_t tdls_state; + uint32_t notification_interval_ms; + uint32_t tx_discovery_threshold; + uint32_t tx_teardown_threshold; + int32_t rssi_teardown_threshold; + int32_t rssi_delta; + uint32_t tdls_options; + uint32_t peer_traffic_ind_window; + uint32_t peer_traffic_response_timeout; + uint32_t puapsd_mask; + uint32_t puapsd_inactivity_time; + uint32_t puapsd_rx_frame_threshold; + uint32_t teardown_notification_ms; + uint32_t tdls_peer_kickout_threshold; +}; + +/** + * struct tdls_ch_params - channel parameters + * @chan_id: ID of the channel + * @pwr: power level + * @dfs_set: is dfs supported or not + * @half_rate: is the channel operating at 10MHz + * @quarter_rate: is the channel operating at 5MHz + */ +struct tdls_ch_params { + uint8_t chan_id; + uint8_t pwr; + bool dfs_set; + bool half_rate; + bool quarter_rate; +}; + +/** + * struct tdls_peer_params - TDLS peer capablities parameters + * @is_peer_responder: is peer responder or not + * @peer_uapsd_queue: peer uapsd queue + * @peer_max_sp: peer max SP value + * @peer_buff_sta_support: peer buffer sta supported or not + * @peer_off_chan_support: peer offchannel support + * @peer_curr_operclass: peer current operating class + * @self_curr_operclass: self current operating class + * @peer_chanlen: peer channel length + * @peer_chan: peer channel list + * @peer_oper_classlen: peer operating class length + * @peer_oper_class: peer operating class + * @pref_off_channum: peer offchannel number + * @pref_off_chan_bandwidth: peer offchannel bandwidth + * @opclass_for_prefoffchan: operating class for offchannel + */ +struct tdls_peer_params { + uint8_t is_peer_responder; + uint8_t peer_uapsd_queue; + uint8_t peer_max_sp; + uint8_t peer_buff_sta_support; + uint8_t peer_off_chan_support; + uint8_t peer_curr_operclass; + uint8_t self_curr_operclass; + uint8_t peer_chanlen; + struct tdls_ch_params peer_chan[WLAN_MAC_MAX_SUPP_CHANNELS]; + uint8_t peer_oper_classlen; + uint8_t peer_oper_class[WLAN_MAX_SUPP_OPER_CLASSES]; + uint8_t pref_off_channum; + uint8_t pref_off_chan_bandwidth; + uint8_t opclass_for_prefoffchan; +}; + +/** + * struct tdls_peer_update_params - TDLS peer state parameters + * @vdev_id: vdev id + * @peer_macaddr: peer mac address + * @peer_cap: peer capabality + */ +struct tdls_peer_update_params { + uint32_t vdev_id; + uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; + uint32_t peer_state; + struct tdls_peer_params peer_cap; +}; + +/** + * struct tdls_chan_switch_params - channel switch parameter structure + * @vdev_id: vdev ID + * @peer_mac_addr: Peer mac address + * @tdls_off_ch_bw_offset: Target off-channel bandwitdh offset + * @tdls_off_ch: Target Off Channel + * @oper_class: Operating class for target channel + * @is_responder: Responder or initiator + */ +struct tdls_chan_switch_params { + uint32_t vdev_id; + uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE]; + uint16_t tdls_off_ch_bw_offset; + uint8_t tdls_off_ch; + uint8_t tdls_sw_mode; + uint8_t oper_class; + uint8_t is_responder; +}; + +/** + * struct tdls_event_info - firmware tdls event + * @vdev_id: vdev id + * @peermac: peer mac address + * @message_type: message type + * @peer_reason: reason + */ +struct tdls_event_info { + uint8_t vdev_id; + struct qdf_mac_addr peermac; + uint16_t message_type; + uint32_t peer_reason; +}; + +/** + * struct tdls_event_notify - tdls event notify + * @vdev: vdev object + * @event: tdls event + */ +struct tdls_event_notify { + struct wlan_objmgr_vdev *vdev; + struct tdls_event_info event; +}; +#endif diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h new file mode 100644 index 000000000000..78454e0829f4 --- /dev/null +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_tgt_api.h + * + * TDLS south bound interface declaration + */ diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h new file mode 100644 index 000000000000..02d8c2beff03 --- /dev/null +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -0,0 +1,78 @@ +/* + * 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: wlan_tdls_ucfg_api.h + * + * TDLS north bound interface declaration + */ + +#if !defined(_WLAN_TDLS_UCFG_API_H_) +#define _WLAN_TDLS_UCFG_API_H_ + +#include +#include +#include + +/** + * ucfg_tdls_init() - TDLS module initialization API + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_init(void); + +/** + * ucfg_tdls_deinit() - TDLS module deinitilization API + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_deinit(void); + +/** + * ucfg_tdls_psoc_open() - TDLS module psoc open API + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_psoc_close() - TDLS module psoc close API + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_psoc_start() - TDLS module start + * @psoc: psoc object + * @req: tdls start paramets + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, + struct tdls_start_params *req); +/** + * ucfg_tdls_psoc_stop() - TDLS module stop + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc); +#endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c new file mode 100644 index 000000000000..864886bb4bb9 --- /dev/null +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_tgt_api.c + * + * TDLS south bound interface definitions + */ diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c new file mode 100644 index 000000000000..3d49c5adac75 --- /dev/null +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -0,0 +1,205 @@ +/* + * 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: wlan_tdls_ucfg_api.c + * + * TDLS north bound interface definitions + */ + +#include +#include "../../core/src/wlan_tdls_main.h" +#include +#include + +QDF_STATUS ucfg_tdls_init(void) +{ + QDF_STATUS status; + + tdls_notice("tdls module dispatcher init"); + status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_create_notification, NULL); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to register psoc create handler for tdls"); + return status; + } + + status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_destroy_notification, NULL); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to register psoc delete handler for tdls"); + goto fail_delete_psoc; + } + + status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_create_notification, NULL); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to register vdev create handler for tdls"); + goto fail_create_vdev; + } + + status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_destroy_notification, NULL); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to register vdev create handler for tdls"); + goto fail_delete_vdev; + } + tdls_notice("tdls module dispatcher init done"); + + return status; +fail_delete_vdev: + wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_create_notification, NULL); + +fail_create_vdev: + wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_destroy_notification, NULL); + +fail_delete_psoc: + wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_create_notification, NULL); + + return status; +} + +QDF_STATUS ucfg_tdls_deinit(void) +{ + QDF_STATUS ret; + + tdls_notice("tdls module dispatcher deinit"); + ret = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_create_notification, NULL); + if (QDF_IS_STATUS_ERROR(ret)) + tdls_err("Failed to unregister psoc create handler"); + + ret = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_destroy_notification, NULL); + if (QDF_IS_STATUS_ERROR(ret)) + tdls_err("Failed to unregister psoc delete handler"); + + ret = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_create_notification, NULL); + if (QDF_IS_STATUS_ERROR(ret)) + tdls_err("Failed to unregister vdev create handler"); + + ret = wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_destroy_notification, NULL); + + if (QDF_IS_STATUS_ERROR(ret)) + tdls_err("Failed to unregister vdev delete handler"); + + return ret; +} + +static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) +{ + uint8_t sta_idx; + + soc_obj->connected_peer_count = 0; + soc_obj->tdls_nss_switch_in_progress = false; + soc_obj->tdls_teardown_peers_cnt = 0; + soc_obj->tdls_nss_teardown_complete = false; + soc_obj->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_S_UNKNOWN; + soc_obj->tdls_user_config_mode = TDLS_SUPPORT_DISABLED; + soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; + + for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { + soc_obj->tdls_conn_info[sta_idx].sta_id = 0; + soc_obj->tdls_conn_info[sta_idx].session_id = 255; + qdf_mem_zero(&soc_obj->tdls_conn_info[sta_idx].peer_mac, + QDF_MAC_ADDR_SIZE); + } + soc_obj->enable_tdls_connection_tracker = false; + soc_obj->tdls_external_peer_count = 0; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *soc_obj; + + tdls_notice("tdls psoc open"); + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (soc_obj == NULL) { + tdls_err("Failed to get tdls psoc component"); + return QDF_STATUS_E_FAILURE; + } + + status = tdls_global_init(soc_obj); + + return status; +} + +QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, + struct tdls_start_params *req) +{ + struct tdls_soc_priv_obj *soc_obj; + + tdls_notice("tdls psoc start"); + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (soc_obj == NULL) { + tdls_err("Failed to get tdls psoc component"); + return QDF_STATUS_E_FAILURE; + } + + soc_obj->tdls_event_cb = req->tdls_event_cb; + soc_obj->tdls_evt_cb_data = req->tdls_evt_cb_data; + + soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; + soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc) +{ + struct tdls_soc_priv_obj *soc_obj = NULL; + + tdls_notice("tdls psoc stop"); + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (soc_obj == NULL) { + tdls_err("Failed to get tdls psoc component"); + return QDF_STATUS_E_FAILURE; + } + + soc_obj->tdls_event_cb = NULL; + soc_obj->tdls_evt_cb_data = NULL; + + soc_obj->tdls_tx_cnf_cb = NULL; + soc_obj->tx_ack_cnf_cb_data = NULL; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + tdls_notice("tdls psoc close"); + + return status; +} diff --git a/dispatcher/src/wlan_tdls_utils_api.c b/dispatcher/src/wlan_tdls_utils_api.c new file mode 100644 index 000000000000..2e9b2ad43ecd --- /dev/null +++ b/dispatcher/src/wlan_tdls_utils_api.c @@ -0,0 +1,23 @@ +/* + * 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: wlan_tdls_utils_api.c + * + * TDLS utility functions definitions + */ From 266613f3d9bdf8babd502f14ea62da6ed2d5e713 Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Mon, 13 Mar 2017 16:36:55 -0700 Subject: [PATCH 022/404] qcacmn: Remove legacy dependency from Policy Manager Part 5 Remove legacy dependency from Policy Manager component Part 5 Change-Id: I942e376eea4b370af5d0cd882b0beaa58012c48f CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 4 +- src/wlan_policy_mgr_action.c | 25 ++++++++ src/wlan_policy_mgr_get_set_utils.c | 90 ++++++++++++++++++++++------- 3 files changed, 95 insertions(+), 24 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 62a140fb6120..e601636c8a00 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -176,10 +176,10 @@ static inline void policy_mgr_check_concurrent_intf_and_restart_sap( * This function is used to check for MCC operation in 2.4GHz band. * STA, P2P and SAP adapters are only considered. * - * Return: Non zero value if MCC is detected in 2.4GHz band + * Return: True if mcc is detected in 2.4 Ghz, false otherwise * */ -uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc); +bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc); /** * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index dd6a622e22a0..31dd59904587 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -593,6 +593,31 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( struct wlan_objmgr_psoc *psoc, uint8_t operation_channel) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t mcc_to_scc_switch; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return; + } + + mcc_to_scc_switch = + policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); + policy_mgr_info("MCC to SCC switch: %d chan: %d", + mcc_to_scc_switch, operation_channel); + if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) +#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE + && !wlan_reg_is_dfs_ch(psoc, + operationChannel) +#endif + ) { + qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work, + policy_mgr_check_sta_ap_concurrent_ch_intf, + (void *)psoc); + qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work); + policy_mgr_info("Checking for Concurrent Change interference"); + } } #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 9fd56da450a5..992728ecb412 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1258,9 +1258,75 @@ uint8_t policy_mgr_search_and_check_for_session_conc( return channel; } -uint8_t policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) +/** + * policy_mgr_is_two_connection_mcc() - Check if MCC scenario + * when there are two connections + * + * If if MCC scenario when there are two connections + * + * Return: true or false + */ +static bool policy_mgr_is_two_connection_mcc(void) { - return 0; + return ((pm_conc_connection_list[0].chan != + pm_conc_connection_list[1].chan) && + (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac) && + (pm_conc_connection_list[0].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM) && + (pm_conc_connection_list[1].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM)) ? true : false; +} + +/** + * policy_mgr_is_three_connection_mcc() - Check if MCC scenario + * when there are three connections + * + * If if MCC scenario when there are three connections + * + * Return: true or false + */ +static bool policy_mgr_is_three_connection_mcc(void) +{ + return (((pm_conc_connection_list[0].chan != + pm_conc_connection_list[1].chan) || + (pm_conc_connection_list[0].chan != + pm_conc_connection_list[2].chan) || + (pm_conc_connection_list[1].chan != + pm_conc_connection_list[2].chan)) && + (pm_conc_connection_list[0].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM) && + (pm_conc_connection_list[1].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM) && + (pm_conc_connection_list[2].chan <= + WLAN_REG_MAX_24GHZ_CH_NUM)) ? true : false; +} + +bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc) +{ + uint32_t num_connections = 0; + bool is_24G_mcc = false; + + num_connections = policy_mgr_get_connection_count(psoc); + + switch (num_connections) { + case 1: + break; + case 2: + if (policy_mgr_is_two_connection_mcc()) + is_24G_mcc = true; + break; + case 3: + if (policy_mgr_is_three_connection_mcc()) + is_24G_mcc = true; + break; + default: + policy_mgr_err("unexpected num_connections value %d", + num_connections); + break; + } + + return is_24G_mcc; } bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, @@ -1290,16 +1356,6 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, return true; } -/** - * policy_mgr_is_mcc_adaptive_scheduler_enabled() - Function to - * gets the policy manager mcc adaptive scheduler enabled - * @psoc: PSOC object information - * - * This function gets the value mcc adaptive scheduler - * - * Return: true if MCC adaptive scheduler is set else false - * - */ bool policy_mgr_is_mcc_adaptive_scheduler_enabled( struct wlan_objmgr_psoc *psoc) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1313,16 +1369,6 @@ bool policy_mgr_is_mcc_adaptive_scheduler_enabled( return pm_ctx->enable_mcc_adaptive_scheduler ? true : false; } -/** - * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval - * @psoc: PSOC object information - * @vdev_id: vdev id - * @dev_mode: device mode - * - * Updates the beacon parameters of the GO in MCC scenario - * - * Return: Success or Failure depending on the overall function behavior - */ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, enum tQDF_ADAPTER_MODE dev_mode) From 544ce17b54b13aa84c9ba15e3a10ee1804e6c754 Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Tue, 14 Mar 2017 15:12:09 -0700 Subject: [PATCH 023/404] qcacmn: Remove legacy dependency from Policy Manager Part 6 Remove legacy dependency from Policy Manager component Part 6 Change-Id: I5136d82c2b30ba71df8c48165c4bc4b560aaee39 CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 72 ++++++++++++++ src/wlan_policy_mgr_action.c | 157 ++++++++++++++++++++++++++++-- src/wlan_policy_mgr_i.h | 27 +---- src/wlan_policy_mgr_init_deinit.c | 30 ++++++ 4 files changed, 253 insertions(+), 33 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index e601636c8a00..b2aaa3d0ff97 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -39,6 +39,33 @@ #include "qdf_status.h" #include "wlan_objmgr_psoc_obj.h" #include "wlan_policy_mgr_public_struct.h" +#include + +enum cds_band_type { + CDS_BAND_ALL = 0, + CDS_BAND_2GHZ = 1, + CDS_BAND_5GHZ = 2 +}; +extern uint32_t cds_chan_to_freq(uint8_t chan); +extern uint8_t cds_freq_to_chan(uint32_t freq); +extern enum cds_band_type cds_chan_to_band(uint32_t chan); + +#define WLAN_REG_IS_24GHZ_CH(ch) CDS_IS_CHANNEL_24GHZ(ch) +#define WLAN_REG_IS_5GHZ_CH(ch) CDS_IS_CHANNEL_5GHZ(ch) +#define WLAN_REG_IS_SAME_BAND_CHANNELS(ch1, ch2) \ + CDS_IS_SAME_BAND_CHANNELS(ch1, ch2) +#define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ + CDS_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) +#define wlan_reg_is_dfs_ch(psoc, ch) CDS_IS_DFS_CH(ch) +#define WLAN_REG_MAX_24GHZ_CH_NUM CDS_MAX_24GHZ_CHANNEL_NUMBER +#define reg_chan_to_freq(chan_num) cds_chan_to_freq(chan_num) +#define reg_freq_to_chan(freq) cds_freq_to_chan(freq) +#define reg_chan_to_band(chan_num) cds_chan_to_band(chan_num) +#define BAND_2G CDS_BAND_2GHZ +#define BAND_5G CDS_BAND_5GHZ +#define BAND_ALL CDS_BAND_ALL +#define wlan_reg_set_channel_params(channel, sec_ch, ch_params) \ + cds_set_channel_params(channel, sec_ch, ch_params) typedef const enum policy_mgr_pcl_type pm_dbs_pcl_second_connection_table_type @@ -152,6 +179,7 @@ QDF_STATUS policy_mgr_handle_conc_multiport( * concurrent change intf * @psoc: PSOC object information * @operation_channel: operation channel + * @vdev_id: vdev id of SAP * * Checks the concurrent change interface and restarts SAP * @@ -159,10 +187,12 @@ QDF_STATUS policy_mgr_handle_conc_multiport( */ void policy_mgr_check_concurrent_intf_and_restart_sap( struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t operation_channel); #else static inline void policy_mgr_check_concurrent_intf_and_restart_sap( struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t operation_channel) { @@ -733,6 +763,17 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, uint8_t next_action, enum policy_mgr_conn_update_reason reason); +/** + * struct check_cc_channel_work - Check concurrent interface + * channel to restart SAP work data + * @wlan_objmgr_psoc: PSOC object data + * @vdev_id: vdev id of sap + */ +struct check_cc_channel_work { + struct wlan_objmgr_psoc *psoc; + uint8_t vdev_id; +}; + /** * struct policy_mgr_sme_cbacks - SME Callbacks to be invoked * from policy manager @@ -767,6 +808,23 @@ struct policy_mgr_sme_cbacks { void *scan_result); }; +/** + * struct policy_mgr_hdd_cbacks - HDD Callbacks to be invoked + * from policy manager + * @sap_restart_chan_switch_cb: Restart SAP + * @wlan_hdd_get_channel_for_sap_restart: Get channel to restart + * SAP + */ +struct policy_mgr_hdd_cbacks { + void (*sap_restart_chan_switch_cb)(uint8_t, + uint32_t, uint32_t); + QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)( + uint8_t vdev_id, uint8_t *channel, + uint8_t *sec_ch, + struct ch_params_s *ch_params); +}; + + /** * struct policy_mgr_tdls_cbacks - TDLS Callbacks to be invoked * from policy manager @@ -1382,6 +1440,20 @@ bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc); QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, struct policy_mgr_sme_cbacks *sme_cbacks); +/** + * policy_mgr_register_hdd_cb() - register HDD callbacks + * @psoc: PSOC object information + * @hdd_cbacks: function pointers from HDD + * + * API, allows HDD to register callbacks to be invoked by policy + * mgr + * + * Return: SUCCESS, + * Failure (if registration fails) + */ +QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_hdd_cbacks *hdd_cbacks); + /** * policy_mgr_register_tdls_cb() - register TDLS callbacks * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 31dd59904587..b57bef7b163f 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -575,8 +575,144 @@ QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, } #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * policy_mgr_is_restart_sap_allowed() - Check if restart SAP + * allowed during SCC -> MCC switch + * @psoc: PSOC object data + * @mcc_to_scc_switch: MCC to SCC switch enabled user config + * + * Check if restart SAP allowed during SCC->MCC switch + * + * Restart: true or false + */ +static bool policy_mgr_is_restart_sap_allowed( + struct wlan_objmgr_psoc *psoc, + uint32_t mcc_to_scc_switch) +{ + if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) || + !(policy_mgr_concurrent_open_sessions_running(psoc) && + (policy_mgr_get_concurrency_mode(psoc) == + (QDF_STA_MASK | QDF_SAP_MASK)))) { + policy_mgr_err("MCC switch disabled or not concurrent STA/SAP"); + return false; + } + return true; +} + +/** + * policy_mgr_is_sap_channel_change_without_restart() - Check if + * SAP channel change allowed without restart + * @mcc_to_scc_switch: MCC to SCC switch enabled user config + * + * Check if SAP channel change allowed without restart + * + * Restart: true or false + */ +static bool policy_mgr_is_sap_channel_change_without_restart( + uint32_t mcc_to_scc_switch) { + if (mcc_to_scc_switch == + QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION || + mcc_to_scc_switch == + QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) { + policy_mgr_info("SAP chan change without restart allowed"); + return true; + } + return false; +} + +/** + * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case + * @data: Pointer check concurrent channel work data + * + * Restarts the SAP interface in STA-AP concurrency scenario + * + * Restart: None + */ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) { + struct check_cc_channel_work *cc_intf_work = + (struct check_cc_channel_work *) data; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t mcc_to_scc_switch; + struct wlan_objmgr_psoc *psoc; + QDF_STATUS status; + uint8_t channel, sec_ch; + struct ch_params_s ch_params; + + if (!cc_intf_work) { + policy_mgr_err("Invalid check channel interface work"); + goto work_done; + } + psoc = cc_intf_work->psoc; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + goto work_done; + } + mcc_to_scc_switch = + policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); + + policy_mgr_info("Concurrent open sessions running: %d", + policy_mgr_concurrent_open_sessions_running(psoc)); + + if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) + goto work_done; + + status = pm_ctx->hdd_cbacks. + wlan_hdd_get_channel_for_sap_restart( + cc_intf_work->vdev_id, &channel, + &sec_ch, &ch_params); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to get channel to restart SAP"); + goto work_done; + } + + if (channel == 0) { + policy_mgr_err("Invalid channel to restart SAP"); + goto work_done; + } + policy_mgr_info("SAP restarts due to MCC->SCC switch, new chan: %d", + channel); + + wlan_reg_set_channel_params(channel, sec_ch, &ch_params); + + if (policy_mgr_is_sap_channel_change_without_restart( + mcc_to_scc_switch) && + pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { + pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb( + cc_intf_work->vdev_id, channel, + ch_params.ch_width); + } + +work_done: + qdf_mem_free(cc_intf_work); + +} + +/** + * create_check_cc_channel_work() - Create Check concurrent intf + * channel work + * @psoc: PSOC object information + * + * Create check concurrent interface channel work + * + * Return: check concurrent channel interface work object + */ +static struct check_cc_channel_work *create_check_cc_channel_work( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) +{ + struct check_cc_channel_work *cc_intf_work; + + cc_intf_work = qdf_mem_malloc( + sizeof(struct check_cc_channel_work)); + if (NULL == cc_intf_work) { + policy_mgr_err("Falied to allocate check concurrent channel work"); + return NULL; + } + cc_intf_work->psoc = psoc; + cc_intf_work->vdev_id = vdev_id; + return cc_intf_work; } /** @@ -584,6 +720,7 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) * concurrent change intf * @psoc: PSOC object information * @operation_channel: operation channel + * @vdev_id: vdev id of SAP * * Checks the concurrent change interface and restarts SAP * @@ -591,10 +728,12 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) */ void policy_mgr_check_concurrent_intf_and_restart_sap( struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t operation_channel) { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t mcc_to_scc_switch; + struct check_cc_channel_work *cc_intf_work; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -612,9 +751,12 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( operationChannel) #endif ) { + cc_intf_work = create_check_cc_channel_work(psoc, vdev_id); + if (!cc_intf_work) + return; qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work, policy_mgr_check_sta_ap_concurrent_ch_intf, - (void *)psoc); + cc_intf_work); qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work); policy_mgr_info("Checking for Concurrent Change interference"); } @@ -645,9 +787,9 @@ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, return; } - if (pm_ctx->sap_restart_chan_switch_cb) { + if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { policy_mgr_info("SAP change change without restart"); - pm_ctx->sap_restart_chan_switch_cb(vdev_id, + pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(vdev_id, channel, ch_width); } } @@ -752,8 +894,8 @@ QDF_STATUS policy_mgr_restart_opportunistic_timer( #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( - struct wlan_objmgr_psoc *psoc, - void (*sap_restart_chan_switch_cb)(uint8_t, uint32_t, uint32_t)) + struct wlan_objmgr_psoc *psoc, + void (*sap_restart_chan_switch_cb)(uint8_t, uint32_t, uint32_t)) { struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; @@ -763,7 +905,8 @@ QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( return QDF_STATUS_E_FAILURE; } - policy_mgr_ctx->sap_restart_chan_switch_cb = sap_restart_chan_switch_cb; + policy_mgr_ctx->hdd_cbacks.sap_restart_chan_switch_cb = + sap_restart_chan_switch_cb; return QDF_STATUS_SUCCESS; } @@ -779,7 +922,7 @@ QDF_STATUS policy_mgr_deregister_sap_restart_channel_switch_cb( return QDF_STATUS_E_FAILURE; } - policy_mgr_ctx->sap_restart_chan_switch_cb = NULL; + policy_mgr_ctx->hdd_cbacks.sap_restart_chan_switch_cb = NULL; return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 0169b65fb18a..5f65da15d984 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -33,31 +33,6 @@ #include "qdf_mc_timer.h" #include "qdf_lock.h" #include "qdf_defer.h" -#include - -enum cds_band_type { - CDS_BAND_ALL = 0, - CDS_BAND_2GHZ = 1, - CDS_BAND_5GHZ = 2 -}; -extern uint32_t cds_chan_to_freq(uint8_t chan); -extern uint8_t cds_freq_to_chan(uint32_t freq); -extern enum cds_band_type cds_chan_to_band(uint32_t chan); - -#define WLAN_REG_IS_24GHZ_CH(ch) CDS_IS_CHANNEL_24GHZ(ch) -#define WLAN_REG_IS_5GHZ_CH(ch) CDS_IS_CHANNEL_5GHZ(ch) -#define WLAN_REG_IS_SAME_BAND_CHANNELS(ch1, ch2) \ - CDS_IS_SAME_BAND_CHANNELS(ch1, ch2) -#define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ - CDS_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) -#define wlan_reg_is_dfs_ch(psoc, ch) CDS_IS_DFS_CH(ch) -#define WLAN_REG_MAX_24GHZ_CH_NUM CDS_MAX_24GHZ_CHANNEL_NUMBER -#define reg_chan_to_freq(chan_num) cds_chan_to_freq(chan_num) -#define reg_freq_to_chan(freq) cds_freq_to_chan(freq) -#define reg_chan_to_band(chan_num) cds_chan_to_band(chan_num) -#define BAND_2G CDS_BAND_2GHZ -#define BAND_5G CDS_BAND_5GHZ -#define BAND_ALL CDS_BAND_ALL #define MAX_NUMBER_OF_CONC_CONNECTIONS 3 #define DBS_OPPORTUNISTIC_TIME 10 @@ -260,7 +235,7 @@ struct policy_mgr_psoc_priv_obj { qdf_event_t connection_update_done_evt; qdf_mutex_t qdf_conc_list_lock; qdf_mc_timer_t dbs_opportunistic_timer; - void (*sap_restart_chan_switch_cb)(uint8_t, uint32_t, uint32_t); + struct policy_mgr_hdd_cbacks hdd_cbacks; struct policy_mgr_sme_cbacks sme_cbacks; struct policy_mgr_wma_cbacks wma_cbacks; struct policy_mgr_tdls_cbacks tdls_cbacks; diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 6b09251bfe77..ab6dc3a6f408 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -406,6 +406,36 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +/** + * policy_mgr_register_hdd_cb() - register HDD callbacks + * @psoc: PSOC object information + * @hdd_cbacks: function pointers from HDD + * + * API, allows HDD to register callbacks to be invoked by policy + * mgr + * + * Return: SUCCESS, + * Failure (if registration fails) + */ +QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_hdd_cbacks *hdd_cbacks) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb = + hdd_cbacks->sap_restart_chan_switch_cb; + pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = + hdd_cbacks->wlan_hdd_get_channel_for_sap_restart; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc, struct policy_mgr_wma_cbacks *wma_cbacks) { From d16c4e562217d7ba520b42d3f93683c77b39cd73 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 6 Mar 2017 14:00:02 +0800 Subject: [PATCH 024/404] qcacmn: Private commands and wmi events for P2P Deliver private commands for P2P component. Registers and unregisters wmi events by target interface. Handles wmi events from target interface. Change-Id: Ic25f1c22ae1650f2b059b3fb428daa1b2e66b93c CRs-Fixed: 2015115 --- core/src/wlan_p2p_main.c | 245 +++++++++++++++++++++++++---- core/src/wlan_p2p_main.h | 35 +++++ dispatcher/inc/wlan_p2p_tgt_api.h | 44 ++++++ dispatcher/src/wlan_p2p_tgt_api.c | 148 +++++++++++++++++ dispatcher/src/wlan_p2p_ucfg_api.c | 69 +++++++- 5 files changed, 504 insertions(+), 37 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 9d62e5b6a0a5..faf753339940 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -100,13 +100,13 @@ static QDF_STATUS p2p_psoc_obj_create_notification( struct p2p_soc_priv_obj *p2p_soc_obj; QDF_STATUS status; - if (soc == NULL) { + if (!soc) { p2p_err("psoc context passed is NULL"); return QDF_STATUS_E_INVAL; } p2p_soc_obj = qdf_mem_malloc(sizeof(*p2p_soc_obj)); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("Failed to allocate p2p soc private object"); return QDF_STATUS_E_NOMEM; } @@ -122,7 +122,7 @@ static QDF_STATUS p2p_psoc_obj_create_notification( return status; } - p2p_info("p2p soc object create successful, %p", p2p_soc_obj); + p2p_debug("p2p soc object create successful, %p", p2p_soc_obj); return QDF_STATUS_SUCCESS; } @@ -143,14 +143,14 @@ static QDF_STATUS p2p_psoc_obj_destroy_notification( struct p2p_soc_priv_obj *p2p_soc_obj; QDF_STATUS status; - if (soc == NULL) { + if (!soc) { p2p_err("psoc context passed is NULL"); return QDF_STATUS_E_INVAL; } p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, WLAN_UMAC_COMP_P2P); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("p2p soc private object is NULL"); return QDF_STATUS_E_FAILURE; } @@ -164,7 +164,7 @@ static QDF_STATUS p2p_psoc_obj_destroy_notification( return status; } - p2p_info("destroy p2p soc object, %p", p2p_soc_obj); + p2p_debug("destroy p2p soc object, %p", p2p_soc_obj); qdf_mem_free(p2p_soc_obj); @@ -186,14 +186,25 @@ static QDF_STATUS p2p_vdev_obj_create_notification( { struct p2p_vdev_priv_obj *p2p_vdev_obj; QDF_STATUS status; + enum tQDF_ADAPTER_MODE mode; - if (vdev == NULL) { + if (!vdev) { p2p_err("vdev context passed is NULL"); return QDF_STATUS_E_INVAL; } - p2p_vdev_obj = qdf_mem_malloc(sizeof(*p2p_vdev_obj)); - if (p2p_vdev_obj == NULL) { + wlan_vdev_obj_lock(vdev); + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + p2p_debug("vdev mode:%d", mode); + if (mode != QDF_P2P_GO_MODE) { + p2p_debug("won't create p2p vdev private object if it is not GO"); + return QDF_STATUS_SUCCESS; + } + + p2p_vdev_obj = + qdf_mem_malloc(sizeof(*p2p_vdev_obj)); + if (!p2p_vdev_obj) { p2p_err("Failed to allocate p2p vdev object"); return QDF_STATUS_E_NOMEM; } @@ -210,7 +221,7 @@ static QDF_STATUS p2p_vdev_obj_create_notification( return status; } - p2p_info("p2p vdev object create successful, %p", p2p_vdev_obj); + p2p_debug("p2p vdev object create successful, %p", p2p_vdev_obj); return QDF_STATUS_SUCCESS; } @@ -230,17 +241,27 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( { struct p2p_vdev_priv_obj *p2p_vdev_obj; QDF_STATUS status; + enum tQDF_ADAPTER_MODE mode; - if (vdev == NULL) { + if (!vdev) { p2p_err("vdev context passed is NULL"); return QDF_STATUS_E_INVAL; } + wlan_vdev_obj_lock(vdev); + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + p2p_debug("vdev mode:%d", mode); + if (mode != QDF_P2P_GO_MODE) { + p2p_debug("no p2p vdev private object if it is not GO"); + return QDF_STATUS_SUCCESS; + } + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_P2P); - if (p2p_vdev_obj == NULL) { - p2p_err("p2p vdev object is NULL"); - return QDF_STATUS_E_FAILURE; + if (!p2p_vdev_obj) { + p2p_debug("p2p vdev object is NULL"); + return QDF_STATUS_SUCCESS; } p2p_vdev_obj->vdev = NULL; @@ -252,7 +273,7 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( return status; } - p2p_info("destroy p2p vdev object, p2p vdev obj:%p, noa info:%p", + p2p_debug("destroy p2p vdev object, p2p vdev obj:%p, noa info:%p", p2p_vdev_obj, p2p_vdev_obj->noa_info); if (p2p_vdev_obj->noa_info) @@ -263,6 +284,69 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( return QDF_STATUS_SUCCESS; } +/** + * p2p_send_noa_to_pe() - send noa information to pe + * @noa_info: vdev context + * + * This function sends noa information to pe since MCL layer need noa + * event. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_send_noa_to_pe(struct p2p_noa_info *noa_info) +{ + struct p2p_noa_attr *noa_attr; + struct scheduler_msg msg; + + if (!noa_info) { + p2p_err("noa info is null"); + return QDF_STATUS_E_INVAL; + } + + noa_attr = qdf_mem_malloc(sizeof(*noa_attr)); + if (!noa_attr) { + p2p_err("Failed to allocate memory for tSirP2PNoaAttr"); + return QDF_STATUS_E_NOMEM; + } + + noa_attr->index = noa_info->index; + noa_attr->opps_ps = noa_info->opps_ps; + noa_attr->ct_win = noa_info->ct_window; + if (!noa_info->num_desc) { + p2p_debug("Zero noa descriptors"); + } else { + p2p_debug("%d noa descriptors", noa_info->num_desc); + + noa_attr->noa1_count = + noa_info->noa_desc[0].type_count; + noa_attr->noa1_duration = + noa_info->noa_desc[0].duration; + noa_attr->noa1_interval = + noa_info->noa_desc[0].interval; + noa_attr->noa1_start_time = + noa_info->noa_desc[0].start_time; + if (noa_info->num_desc > 1) { + noa_attr->noa2_count = + noa_info->noa_desc[1].type_count; + noa_attr->noa2_duration = + noa_info->noa_desc[1].duration; + noa_attr->noa2_interval = + noa_info->noa_desc[1].interval; + noa_attr->noa2_start_time = + noa_info->noa_desc[1].start_time; + } + } + + p2p_debug("Sending P2P_NOA_ATTR_IND to pe"); + + msg.type = P2P_NOA_ATTR_IND; + msg.bodyval = 0; + msg.bodyptr = noa_attr; + scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS p2p_component_init(void) { QDF_STATUS status; @@ -373,14 +457,14 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) { struct p2p_soc_priv_obj *p2p_soc_obj; - if (soc == NULL) { + if (!soc) { p2p_err("psoc context passed is NULL"); return QDF_STATUS_E_INVAL; } p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, WLAN_UMAC_COMP_P2P); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("p2p soc priviate object is NULL"); return QDF_STATUS_E_FAILURE; } @@ -389,7 +473,6 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) qdf_list_create(&p2p_soc_obj->tx_q_roc, MAX_QUEUE_LENGTH); qdf_list_create(&p2p_soc_obj->tx_q_ack, MAX_QUEUE_LENGTH); qdf_event_create(&p2p_soc_obj->cancel_roc_done); - /*TODO, register scan event, wmi lo and noa event */ p2p_debug("p2p psoc object open successful"); @@ -400,22 +483,22 @@ QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) { struct p2p_soc_priv_obj *p2p_soc_obj; - if (soc == NULL) { + if (!soc) { p2p_err("psoc context passed is NULL"); return QDF_STATUS_E_INVAL; } p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, WLAN_UMAC_COMP_P2P); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("p2p soc object is NULL"); return QDF_STATUS_E_FAILURE; } - qdf_list_destroy(&p2p_soc_obj->roc_q); - qdf_list_destroy(&p2p_soc_obj->tx_q_roc); + qdf_event_destroy(&p2p_soc_obj->cancel_roc_done); qdf_list_destroy(&p2p_soc_obj->tx_q_ack); - /*TODO, ucfg_scan_clear_requestor_id(soc, p2p_soc_obj->scan_req_id);*/ + qdf_list_destroy(&p2p_soc_obj->tx_q_roc); + qdf_list_destroy(&p2p_soc_obj->roc_q); p2p_debug("p2p psoc object close successful"); @@ -428,20 +511,20 @@ QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_start_param *start_param; - if (soc == NULL) { + if (!soc) { p2p_err("psoc context passed is NULL"); return QDF_STATUS_E_INVAL; } p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, WLAN_UMAC_COMP_P2P); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("P2P soc object is NULL"); return QDF_STATUS_E_FAILURE; } start_param = qdf_mem_malloc(sizeof(*start_param)); - if (start_param == NULL) { + if (!start_param) { p2p_err("Failed to allocate start params"); return QDF_STATUS_E_NOMEM; } @@ -455,6 +538,10 @@ QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, start_param->lo_event_cb_data = req->lo_event_cb_data; p2p_soc_obj->start_param = start_param; + /* register p2p lo stop and noa event */ + tgt_p2p_register_lo_ev_handler(soc); + tgt_p2p_register_noa_ev_handler(soc); + p2p_debug("p2p psoc start successful"); return QDF_STATUS_SUCCESS; @@ -465,25 +552,29 @@ QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc) struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_start_param *start_param; - if (soc == NULL) { + if (!soc) { p2p_err("psoc context passed is NULL"); return QDF_STATUS_E_INVAL; } p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, WLAN_UMAC_COMP_P2P); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("P2P soc object is NULL"); return QDF_STATUS_E_FAILURE; } start_param = p2p_soc_obj->start_param; p2p_soc_obj->start_param = NULL; - if (start_param == NULL) { + if (!start_param) { p2p_err("start parameters is NULL"); return QDF_STATUS_E_FAILURE; } + /* unregister p2p lo stop and noa event */ + tgt_p2p_unregister_lo_ev_handler(soc); + tgt_p2p_unregister_noa_ev_handler(soc); + start_param->rx_cb = NULL; start_param->rx_cb_data = NULL; start_param->event_cb = NULL; @@ -501,10 +592,10 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg) { QDF_STATUS status; - p2p_info("msg type %d, %s", msg->type, + p2p_debug("msg type %d, %s", msg->type, p2p_get_cmd_type_str(msg->type)); - if (msg->bodyptr == NULL) { + if (!(msg->bodyptr)) { p2p_err("Invalid message body"); return QDF_STATUS_E_INVAL; } @@ -546,10 +637,10 @@ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg) { QDF_STATUS status; - p2p_info("msg type %d, %s", msg->type, + p2p_debug("msg type %d, %s", msg->type, p2p_get_event_type_str(msg->type)); - if (msg->bodyptr == NULL) { + if (!(msg->bodyptr)) { p2p_err("Invalid message body"); return QDF_STATUS_E_INVAL; } @@ -591,10 +682,96 @@ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg) QDF_STATUS p2p_process_lo_stop( struct p2p_lo_stop_event *lo_stop_event) { + struct p2p_lo_event *lo_evt; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_start_param *start_param; + + if (!lo_stop_event) { + p2p_err("invalid lo stop event"); + return QDF_STATUS_E_INVAL; + } + lo_evt = lo_stop_event->lo_event; + p2p_soc_obj = lo_stop_event->p2p_soc_obj; + + p2p_debug("vdev_id %d, reason %d", + lo_evt->vdev_id, lo_evt->reason_code); + + if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) { + p2p_err("Invalid p2p soc object or start parameters"); + return QDF_STATUS_E_INVAL; + } + start_param = p2p_soc_obj->start_param; + if (start_param->lo_event_cb) + start_param->lo_event_cb( + start_param->lo_event_cb_data, lo_evt); + else + p2p_err("Invalid p2p soc obj or hdd lo event callback"); + + qdf_mem_free(lo_evt); + return QDF_STATUS_SUCCESS; } QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct p2p_noa_info *noa_info; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + enum tQDF_ADAPTER_MODE mode; + + if (!noa_event) { + p2p_err("invalid noa event"); + return QDF_STATUS_E_INVAL; + } + noa_info = noa_event->noa_info; + p2p_soc_obj = noa_event->p2p_soc_obj; + psoc = p2p_soc_obj->soc; + + p2p_debug("psoc:%p, index:%d, opps_ps:%d, ct_window:%d, num_desc:%d, vdev_id:%d", + psoc, noa_info->index, noa_info->opps_ps, + noa_info->ct_window, noa_info->num_desc, + noa_info->vdev_id); + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + noa_info->vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_err("vdev obj is NULL"); + qdf_mem_free(noa_event->noa_info); + return QDF_STATUS_E_INVAL; + } + + wlan_vdev_obj_lock(vdev); + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + p2p_debug("vdev mode:%d", mode); + if (mode != QDF_P2P_GO_MODE) { + p2p_err("invalid p2p vdev mode:%d", mode); + status = QDF_STATUS_E_INVAL; + goto fail; + } + + /* must send noa to pe since of limitation*/ + p2p_send_noa_to_pe(noa_info); + + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_P2P); + if (!(p2p_vdev_obj->noa_info)) { + p2p_vdev_obj->noa_info = + qdf_mem_malloc(sizeof(struct p2p_noa_info)); + if (!(p2p_vdev_obj->noa_info)) { + p2p_err("Failed to allocate p2p noa info"); + status = QDF_STATUS_E_NOMEM; + goto fail; + } + } + qdf_mem_copy(p2p_vdev_obj->noa_info, noa_info, + sizeof(struct p2p_noa_info)); +fail: + qdf_mem_free(noa_event->noa_info); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return status; } diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 6b6a35506d21..7b2e0056563b 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -28,6 +28,7 @@ #include #define MAX_QUEUE_LENGTH 20 +#define P2P_NOA_ATTR_IND 0x1090 #define P2P_MODULE_NAME "P2P" #define p2p_log(level, args...) \ @@ -154,6 +155,40 @@ struct p2p_vdev_priv_obj { struct p2p_noa_info *noa_info; }; +/** + * struct p2p_noa_attr - p2p noa attribute + * @rsvd1: reserved bits 1 + * @opps_ps: opps ps state of the AP + * @ct_win: ct window in TUs + * @index: identifies instance of NOA su element + * @rsvd2: reserved bits 2 + * @noa1_count: interval count of noa1 + * @noa1_duration: absent period duration of noa1 + * @noa1_interval: absent period interval of noa1 + * @noa1_start_time: 32 bit tsf time of noa1 + * @rsvd3: reserved bits 3 + * @noa2_count: interval count of noa2 + * @noa2_duration: absent period duration of noa2 + * @noa2_interval: absent period interval of noa2 + * @noa2_start_time: 32 bit tsf time of noa2 + */ +struct p2p_noa_attr { + uint32_t rsvd1:16; + uint32_t ct_win:7; + uint32_t opps_ps:1; + uint32_t index:8; + uint32_t rsvd2:24; + uint32_t noa1_count:8; + uint32_t noa1_duration; + uint32_t noa1_interval; + uint32_t noa1_start_time; + uint32_t rsvd3:24; + uint32_t noa2_count:8; + uint32_t noa2_duration; + uint32_t noa2_interval; + uint32_t noa2_start_time; +}; + /** * p2p_component_init() - P2P component initialization * diff --git a/dispatcher/inc/wlan_p2p_tgt_api.h b/dispatcher/inc/wlan_p2p_tgt_api.h index b5dc946ac92b..5644f263ca1f 100644 --- a/dispatcher/inc/wlan_p2p_tgt_api.h +++ b/dispatcher/inc/wlan_p2p_tgt_api.h @@ -33,6 +33,50 @@ struct p2p_lo_event; struct mgmt_rx_event_params; enum mgmt_frame_type; +/** + * tgt_p2p_register_lo_ev_handler() - register lo event + * @psoc: soc object + * + * p2p tgt api to register listen offload event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_register_lo_ev_handler( + struct wlan_objmgr_psoc *psoc); + +/** + * tgt_p2p_register_noa_ev_handler() - register noa event + * @psoc: soc object + * + * p2p tgt api to register noa event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_register_noa_ev_handler( + struct wlan_objmgr_psoc *psoc); + +/** + * tgt_p2p_unregister_lo_ev_handler() - unregister lo event + * @psoc: soc object + * + * p2p tgt api to unregister listen offload event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_unregister_lo_ev_handler( + struct wlan_objmgr_psoc *psoc); + +/** + * tgt_p2p_unregister_noa_ev_handler() - unregister noa event + * @psoc: soc object + * + * p2p tgt api to unregister noa event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_unregister_noa_ev_handler( + struct wlan_objmgr_psoc *psoc); + /** * tgt_p2p_scan_event_cb() - Callback for scan event * @vdev: vdev object diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index b87af0bed613..e2ca5192273b 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -27,6 +27,72 @@ #include "wlan_p2p_public_struct.h" #include "../../core/src/wlan_p2p_main.h" +static inline struct wlan_lmac_if_p2p_tx_ops * +wlan_psoc_get_p2p_tx_ops(struct wlan_objmgr_psoc *psoc) +{ + return &(psoc->soc_cb.tx_ops.p2p); +} + +QDF_STATUS tgt_p2p_register_lo_ev_handler( + struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_ops = wlan_psoc_get_p2p_tx_ops(psoc); + if (p2p_ops && p2p_ops->reg_lo_ev_handler) { + status = p2p_ops->reg_lo_ev_handler(psoc, NULL); + p2p_debug("register lo event, status:%d", status); + } + + return status; +} + +QDF_STATUS tgt_p2p_register_noa_ev_handler( + struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_ops = wlan_psoc_get_p2p_tx_ops(psoc); + if (p2p_ops && p2p_ops->reg_noa_ev_handler) { + status = p2p_ops->reg_noa_ev_handler(psoc, NULL); + p2p_debug("register noa event, status:%d", status); + } + + return status; +} + +QDF_STATUS tgt_p2p_unregister_lo_ev_handler( + struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_ops = wlan_psoc_get_p2p_tx_ops(psoc); + if (p2p_ops && p2p_ops->unreg_lo_ev_handler) { + status = p2p_ops->unreg_lo_ev_handler(psoc, NULL); + p2p_debug("unregister lo event, status:%d", status); + } + + return status; +} + +QDF_STATUS tgt_p2p_unregister_noa_ev_handler( + struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_ops = wlan_psoc_get_p2p_tx_ops(psoc); + if (p2p_ops && p2p_ops->unreg_noa_ev_handler) { + status = p2p_ops->unreg_noa_ev_handler(psoc, NULL); + p2p_debug("unregister noa event, status:%d", status); + } + + return status; +} + void tgt_p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, struct scan_event *event, void *arg) { @@ -55,11 +121,93 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, struct p2p_noa_info *event_info) { + struct p2p_noa_event *noa_event; + struct scheduler_msg msg; + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_debug("soc:%p, event_info:%p", psoc, event_info); + + if (!psoc) { + p2p_err("psoc context passed is NULL"); + if (event_info) + qdf_mem_free(event_info); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("p2p soc object is NULL"); + if (event_info) + qdf_mem_free(event_info); + return QDF_STATUS_E_INVAL; + } + + if (!event_info) { + p2p_err("invalid noa event information"); + return QDF_STATUS_E_INVAL; + } + + noa_event = qdf_mem_malloc(sizeof(*noa_event)); + if (!noa_event) { + p2p_err("Failed to allocate p2p noa event"); + qdf_mem_free(event_info); + return QDF_STATUS_E_NOMEM; + } + + noa_event->p2p_soc_obj = p2p_soc_obj; + noa_event->noa_info = event_info; + msg.type = P2P_EVENT_NOA; + msg.bodyptr = noa_event; + msg.callback = p2p_process_evt; + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + return QDF_STATUS_SUCCESS; } QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, struct p2p_lo_event *event_info) { + struct p2p_lo_stop_event *lo_stop_event; + struct scheduler_msg msg; + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_debug("soc:%p, event_info:%p", psoc, event_info); + + if (!psoc) { + p2p_err("psoc context passed is NULL"); + if (event_info) + qdf_mem_free(event_info); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("p2p soc object is NULL"); + if (event_info) + qdf_mem_free(event_info); + return QDF_STATUS_E_INVAL; + } + + if (!event_info) { + p2p_err("invalid lo stop event information"); + return QDF_STATUS_E_INVAL; + } + + lo_stop_event = qdf_mem_malloc(sizeof(*lo_stop_event)); + if (!lo_stop_event) { + p2p_err("Failed to allocate p2p lo stop event"); + qdf_mem_free(event_info); + return QDF_STATUS_E_NOMEM; + } + + lo_stop_event->p2p_soc_obj = p2p_soc_obj; + lo_stop_event->lo_event = event_info; + msg.type = P2P_EVENT_LO_STOPPED; + msg.bodyptr = lo_stop_event; + msg.callback = p2p_process_evt; + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + return QDF_STATUS_SUCCESS; } diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 86e98fcc5881..375c0a3f87ac 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -27,6 +27,12 @@ #include "wlan_p2p_public_struct.h" #include "../../core/src/wlan_p2p_main.h" +static inline struct wlan_lmac_if_p2p_tx_ops * +ucfg_p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc) +{ + return &(psoc->soc_cb.tx_ops.p2p); +} + QDF_STATUS ucfg_p2p_init(void) { return p2p_component_init(); @@ -85,17 +91,74 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, struct p2p_ps_config *ps_config) { - return QDF_STATUS_SUCCESS; + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_debug("soc:%p, vdev_id:%d, opp_ps:%d, ct_window:%d, count:%d, duration:%d, duration:%d, ps_selection:%d", + soc, ps_config->vdev_id, ps_config->opp_ps, + ps_config->ct_window, ps_config->count, + ps_config->duration, ps_config->single_noa_duration, + ps_config->ps_selection); + + if (!soc) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc); + if (p2p_ops->set_ps) { + status = p2p_ops->set_ps(soc, ps_config); + p2p_debug("p2p set ps, status:%d", status); + } + + return status; } QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc, struct p2p_lo_start *p2p_lo_start) { - return QDF_STATUS_SUCCESS; + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_debug("soc:%p, vdev_id:%d, ctl_flags:%d, freq:%d, period:%d, interval:%d, count:%d, dev_types_len:%d, probe_resp_len:%d, device_types:%p, probe_resp_tmplt:%p", + soc, p2p_lo_start->vdev_id, p2p_lo_start->ctl_flags, + p2p_lo_start->freq, p2p_lo_start->period, + p2p_lo_start->interval, p2p_lo_start->count, + p2p_lo_start->dev_types_len, p2p_lo_start->probe_resp_len, + p2p_lo_start->device_types, p2p_lo_start->probe_resp_tmplt); + + if (!soc) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc); + if (p2p_ops->lo_start) { + status = p2p_ops->lo_start(soc, p2p_lo_start); + p2p_debug("p2p lo start, status:%d", status); + } + + return status; } QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc, uint32_t vdev_id) { - return QDF_STATUS_SUCCESS; + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_debug("soc:%p, vdev_id:%d", soc, vdev_id); + + if (!soc) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc); + if (p2p_ops->lo_stop) { + status = p2p_ops->lo_stop(soc, vdev_id); + p2p_debug("p2p lo stop, status:%d", status); + } + + return status; } From 01309adc5cef768e0a4a903546b159304b9c1089 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 15 Mar 2017 17:27:59 +0800 Subject: [PATCH 025/404] qcacmn: remain on channel Handles roc request, cancel roc reuqest and scan event in P2P component. Change-Id: I47085ddc3551e76ef042e9d72dc4b29de6c2b118 CRs-Fixed: 2006262 --- core/src/wlan_p2p_main.c | 20 +- core/src/wlan_p2p_roc.c | 714 ++++++++++++++++++++++++++++- core/src/wlan_p2p_roc.h | 44 ++ dispatcher/src/wlan_p2p_tgt_api.c | 2 + dispatcher/src/wlan_p2p_ucfg_api.c | 71 +++ 5 files changed, 845 insertions(+), 6 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index faf753339940..25e53727ab5d 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wlan_p2p_public_struct.h" #include "wlan_p2p_ucfg_api.h" #include "wlan_p2p_tgt_api.h" @@ -542,7 +543,13 @@ QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, tgt_p2p_register_lo_ev_handler(soc); tgt_p2p_register_noa_ev_handler(soc); - p2p_debug("p2p psoc start successful"); + /* register scan request id */ + p2p_soc_obj->scan_req_id = ucfg_scan_register_requester( + soc, P2P_MODULE_NAME, tgt_p2p_scan_event_cb, + p2p_soc_obj); + + p2p_debug("p2p psoc start successful, scan request id:%d", + p2p_soc_obj->scan_req_id); return QDF_STATUS_SUCCESS; } @@ -571,6 +578,12 @@ QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc) return QDF_STATUS_E_FAILURE; } + /* clean up queue of p2p psoc private object */ + p2p_cleanup_roc_queue(p2p_soc_obj); + + /* unrgister scan request id*/ + ucfg_scan_unregister_requester(soc, p2p_soc_obj->scan_req_id); + /* unregister p2p lo stop and noa event */ tgt_p2p_unregister_lo_ev_handler(soc); tgt_p2p_unregister_noa_ev_handler(soc); @@ -609,6 +622,7 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg) status = p2p_process_cancel_roc_req( (struct cancel_roc_context *) msg->bodyptr); + qdf_mem_free(msg->bodyptr); break; case P2P_MGMT_TX: status = p2p_process_mgmt_tx( @@ -619,6 +633,7 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg) status = p2p_process_mgmt_tx_cancel( (struct cancel_roc_context *) msg->bodyptr); + qdf_mem_free(msg->bodyptr); break; default: p2p_err("drop unexpected message received %d", @@ -627,9 +642,6 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg) break; } - qdf_mem_free(msg->bodyptr); - msg->bodyptr = NULL; - return status; } diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 62fcb2f21d90..fd588ebd5787 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -20,20 +20,730 @@ * DOC: This file contains RoC API definitions */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "wlan_p2p_public_struct.h" +#include "wlan_p2p_tgt_api.h" +#include "wlan_p2p_ucfg_api.h" #include "wlan_p2p_roc.h" +#include "wlan_p2p_main.h" +#include "wlan_p2p_off_chan_tx.h" + +/** + * p2p_mgmt_rx_ops() - register or unregister rx callback + * @psoc: psoc object + * @isregister: register if true, unregister if false + * + * This function registers or unregisters rx callback to mgmt txrx + * component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, + bool isregister) +{ + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; + QDF_STATUS status; + + p2p_debug("psoc:%p, is register rx:%d", psoc, isregister); + + frm_cb_info.frm_type = MGMT_PROBE_REQ; + frm_cb_info.mgmt_rx_cb = (mgmt_frame_rx_callback) + tgt_p2p_mgmt_frame_rx_cb; + + if (isregister) + status = wlan_mgmt_txrx_register_rx_cb(psoc, + WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); + else + status = wlan_mgmt_txrx_deregister_rx_cb(psoc, + WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); + + return status; +} + +/** + * p2p_scan_start() - Start scan + * @roc_ctx: remain on channel request + * + * This function trigger a start scan request to scan component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status; + struct scan_start_request *req; + struct wlan_objmgr_vdev *vdev; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc( + p2p_soc_obj->soc, roc_ctx->vdev_id, + WLAN_P2P_ID); + if (!vdev) { + p2p_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + p2p_err("failed to alloc scan start request"); + status = QDF_STATUS_E_NOMEM; + goto fail; + } + + ucfg_scan_init_default_params(vdev, req); + roc_ctx->scan_id = ucfg_scan_get_scan_id(p2p_soc_obj->soc); + req->vdev = vdev; + req->scan_req.scan_id = roc_ctx->scan_id; + req->scan_req.scan_req_id = p2p_soc_obj->scan_req_id; + req->scan_req.num_chan = 1; + req->scan_req.chan_list[0] = wlan_chan_to_freq(roc_ctx->chan); + req->scan_req.dwell_time_passive = roc_ctx->duration; + req->scan_req.dwell_time_active = 0; + qdf_set_macaddr_broadcast(&req->scan_req.bssid_list[0]); + + status = ucfg_scan_start(req); + + p2p_debug("start scan, scan req id:%d, scan id:%d, status:%d", + p2p_soc_obj->scan_req_id, roc_ctx->scan_id, status); +fail: + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return status; +} + +/** + * p2p_scan_abort() - Abort scan + * @roc_ctx: remain on channel request + * + * This function trigger an abort scan request to scan component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_scan_abort(struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status; + struct scan_cancel_request *req; + struct wlan_objmgr_vdev *vdev; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + p2p_debug("abort scan, scan req id:%d, scan id:%d", + p2p_soc_obj->scan_req_id, roc_ctx->scan_id); + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc( + p2p_soc_obj->soc, roc_ctx->vdev_id, + WLAN_P2P_ID); + if (!vdev) { + p2p_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + p2p_err("failed to alloc scan cancel request"); + status = QDF_STATUS_E_NOMEM; + goto fail; + } + + req->vdev = vdev; + req->cancel_req.requester = p2p_soc_obj->scan_req_id; + req->cancel_req.scan_id = roc_ctx->scan_id; + req->cancel_req.vdev_id = roc_ctx->vdev_id; + req->cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE; + + status = ucfg_scan_cancel(req); + + p2p_debug("abort scan, scan req id:%d, scan id:%d, status:%d", + p2p_soc_obj->scan_req_id, roc_ctx->scan_id, status); +fail: + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return status; +} + +/** + * p2p_execute_cancel_roc_req() - Execute cancel roc request + * @roc_ctx: remain on channel request + * + * This function stop roc timer, abort scan and unregister mgmt rx + * callbak. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_execute_cancel_roc_req( + struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + roc_ctx->roc_state = ROC_STATE_CANCEL_IN_PROG; + qdf_event_reset(&p2p_soc_obj->cancel_roc_done); + status = qdf_mc_timer_stop(&roc_ctx->roc_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to stop roc timer, roc %p", roc_ctx); + + status = p2p_scan_abort(roc_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to abort scan, status:%d", status); + } + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_roc_timeout() - Callback for roc timeout + * @pdata: pointer to p2p soc private object + * + * This function is callback for roc time out. + * + * Return: None + */ +static void p2p_roc_timeout(void *pdata) +{ + struct p2p_roc_context *roc_ctx; + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_debug("p2p soc obj:%p", pdata); + + p2p_soc_obj = pdata; + if (!p2p_soc_obj) { + p2p_err("Invalid p2p soc object"); + return; + } + + roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); + if (!roc_ctx) { + p2p_debug("No P2P roc is pending"); + return; + } + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + if (roc_ctx->roc_state == ROC_STATE_CANCEL_IN_PROG) { + p2p_err("Cancellation already in progress"); + return; + } + p2p_execute_cancel_roc_req(roc_ctx); +} + +/** + * p2p_execute_roc_req() - Execute roc request + * @roc_ctx: remain on channel request + * + * This function init roc timer, start scan and register mgmt rx + * callbak. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_execute_roc_req(struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status; + uint32_t go_num; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + status = qdf_mc_timer_init(&roc_ctx->roc_timer, + QDF_TIMER_TYPE_SW, p2p_roc_timeout, + p2p_soc_obj); + if (status != QDF_STATUS_SUCCESS) + return status; + + roc_ctx->roc_state = ROC_STATE_REQUESTED; + go_num = policy_mgr_mode_specific_connection_count( + p2p_soc_obj->soc, PM_P2P_GO_MODE, NULL); + p2p_debug("present go number:%d", go_num); + if (go_num) + roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_PRESENT; + else + roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_ABSENT; + + status = p2p_scan_start(roc_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to start scan, status:%d", status); + } + status = p2p_mgmt_rx_ops(roc_ctx->p2p_soc_obj->soc, true); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to register mgmt rx callback, status:%d", + status); + + return status; +} + +/** + * p2p_find_roc_ctx() - Find out roc context by cookie + * @p2p_soc_obj: p2p psoc private object + * @cookie: cookie is the key to find out roc context + * + * This function find out roc context by cookie from p2p psoc private + * object + * + * Return: Pointer to roc context - success + * NULL - failure + */ +static struct p2p_roc_context *p2p_find_roc_ctx( + struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie) +{ + struct p2p_roc_context *curr_roc_ctx; + qdf_list_node_t *tmp, *pos; + + p2p_debug("p2p soc obj:%p, cookie:%llx", p2p_soc_obj, cookie); + + list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { + curr_roc_ctx = list_entry(pos, struct p2p_roc_context, + node); + if ((uintptr_t) curr_roc_ctx == cookie) + return curr_roc_ctx; + } + + return NULL; +} + +/** + * p2p_send_roc_event() - Send roc event + * @roc_ctx: remain on channel request + * @evt: roc event information + * + * This function send out roc event to up layer. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_send_roc_event( + struct p2p_roc_context *roc_ctx, enum p2p_roc_event evt) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_event p2p_evt; + struct p2p_start_param *start_param; + + p2p_soc_obj = roc_ctx->p2p_soc_obj; + if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) { + p2p_err("Invalid p2p soc object or start parameters"); + return QDF_STATUS_E_INVAL; + } + start_param = p2p_soc_obj->start_param; + if (!(start_param->event_cb)) { + p2p_err("Invalid p2p event callback to up layer"); + return QDF_STATUS_E_INVAL; + } + + p2p_evt.vdev_id = roc_ctx->vdev_id; + p2p_evt.roc_event = evt; + p2p_evt.cookie = (uintptr_t)roc_ctx; + p2p_evt.chan = roc_ctx->chan; + p2p_evt.duration = roc_ctx->duration; + + p2p_debug("p2p soc_obj:%p, roc_ctx:%p, vdev_id:%d, roc_event:" + "%d, cookie:%llx, chan:%d, duration:%d", p2p_soc_obj, + roc_ctx, p2p_evt.vdev_id, p2p_evt.roc_event, + p2p_evt.cookie, p2p_evt.chan, p2p_evt.duration); + + start_param->event_cb(start_param->event_cb_data, &p2p_evt); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_process_scan_start_evt() - Process scan start event + * @roc_ctx: remain on channel request + * + * This function process scan start event. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_process_scan_start_evt( + struct p2p_roc_context *roc_ctx) +{ + roc_ctx->roc_state = ROC_STATE_STARTED; + p2p_debug("scan started, roc ctx:%p, scan id:%d", + roc_ctx, roc_ctx->scan_id); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_process_ready_on_channel_evt() - Process ready on channel event + * @roc_ctx: remain on channel request + * + * This function process ready on channel event. Starts roc timer. + * Indicates this event to up layer if this is user request roc. Sends + * mgmt frame if this is off channel rx roc. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_process_ready_on_channel_evt( + struct p2p_roc_context *roc_ctx) +{ + uint64_t cookie; + struct p2p_soc_priv_obj *p2p_soc_obj; + QDF_STATUS status; + + p2p_soc_obj = roc_ctx->p2p_soc_obj; + roc_ctx->roc_state = ROC_STATE_ON_CHAN; + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + status = qdf_mc_timer_start(&roc_ctx->roc_timer, + (roc_ctx->duration + P2P_EVENT_PROPOGATE_TIME)); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Remain on Channel timer start failed"); + if (roc_ctx->roc_type == USER_REQUESTED) { + p2p_debug("user required roc, send roc event"); + status = p2p_send_roc_event(roc_ctx, + ROC_EVENT_READY_ON_CHAN); + } else { + p2p_debug("roc for off chan tx, ready to send frame"); + cookie = (uintptr_t)roc_ctx; + /* ready to tx frame */ + } + + return status; +} + +/** + * p2p_process_scan_complete_evt() - Process scan complete event + * @roc_ctx: remain on channel request + * + * This function process scan complete event. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_process_scan_complete_evt( + struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status; + qdf_list_node_t *next_node; + uint32_t size; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + status = qdf_mc_timer_stop(&roc_ctx->roc_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to stop roc timer"); + status = qdf_mc_timer_destroy(&roc_ctx->roc_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to destroy roc timer"); + + status = p2p_mgmt_rx_ops(p2p_soc_obj->soc, false); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to deregister mgmt rx callback"); + + if (roc_ctx->roc_type == USER_REQUESTED) + status = p2p_send_roc_event(roc_ctx, + ROC_EVENT_COMPLETED); + + status = qdf_list_remove_node(&p2p_soc_obj->roc_q, + (qdf_list_node_t *)roc_ctx); + if (QDF_STATUS_SUCCESS != status) + p2p_err("Failed to remove roc req, status %d", status); + qdf_mem_free(roc_ctx); + qdf_event_set(&p2p_soc_obj->cancel_roc_done); + + size = qdf_list_size(&p2p_soc_obj->roc_q); + p2p_debug("P2P roc queue size is %d", status); + if (size > 0) { + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, + &next_node); + if (QDF_STATUS_SUCCESS != status) { + p2p_err("Failed to peek roc req from front, status %d", + status); + return status; + } + roc_ctx = qdf_container_of(next_node, + struct p2p_roc_context, node); + status = p2p_execute_roc_req(roc_ctx); + } + return status; +} + +/** + * p2p_process_scan_dequeue() - Process scan dequeue + * @roc_ctx: remain on channel request + * + * This function process scan dequeued event. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_process_scan_dequeue( + struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + if (roc_ctx->roc_state != ROC_STATE_CANCEL_IN_PROG) { + p2p_debug("invalid roc state, %d", roc_ctx->roc_state); + return QDF_STATUS_E_INVAL; + } + + if (QDF_TIMER_STATE_RUNNING != + qdf_mc_timer_get_current_state(&roc_ctx->roc_timer)) { + qdf_mc_timer_stop(&roc_ctx->roc_timer); + } + + status = qdf_mc_timer_destroy(&roc_ctx->roc_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("failed to destroy roc timer, roc ctx:%p, status:%d", + roc_ctx, status); + + status = qdf_list_remove_node(&p2p_soc_obj->roc_q, + (qdf_list_node_t *)roc_ctx); + if (status != QDF_STATUS_SUCCESS) + p2p_err("failed to remove roc context, roc ctx:%p, status:%d", + roc_ctx, status); + qdf_mem_free(roc_ctx); + + return status; +} + +struct p2p_roc_context *p2p_find_current_roc_ctx( + struct p2p_soc_priv_obj *p2p_soc_obj) +{ + struct p2p_roc_context *roc_ctx; + qdf_list_node_t *tmp, *pos; + + list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { + roc_ctx = list_entry(pos, struct p2p_roc_context, + node); + if (roc_ctx->roc_state != ROC_STATE_IDLE) { + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id" + ":%d, scan_id:%d, cookie:%llx, chan:" + "%d, phy_mode:%d, duration:%d, " + "roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, + roc_ctx->vdev_id, roc_ctx->scan_id, + roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + return roc_ctx; + } + } + + return NULL; +} + +QDF_STATUS p2p_restart_roc_timer(struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (QDF_TIMER_STATE_RUNNING == + qdf_mc_timer_get_current_state(&roc_ctx->roc_timer)) { + p2p_debug("roc timer is running"); + status = qdf_mc_timer_stop(&roc_ctx->roc_timer); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to stop roc timer"); + return status; + } + + status = qdf_mc_timer_start(&roc_ctx->roc_timer, + roc_ctx->duration); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Remain on Channel timer start failed"); + } + + return status; +} + +QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct p2p_roc_context *roc_ctx; + qdf_list_node_t *tmp, *pos; + unsigned long rc = 0; + + p2p_debug("clean up idle roc request, roc queue size:%d", + qdf_list_size(&p2p_soc_obj->roc_q)); + list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { + roc_ctx = list_entry(pos, struct p2p_roc_context, + node); + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, + roc_ctx->vdev_id, roc_ctx->scan_id, + roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + if (roc_ctx->roc_state == ROC_STATE_IDLE) { + status = qdf_list_remove_node( + &p2p_soc_obj->roc_q, + (qdf_list_node_t *)roc_ctx); + if (status == QDF_STATUS_SUCCESS) + qdf_mem_free(roc_ctx); + else + p2p_err("Failed to remove roc ctx from queue"); + } + } + + p2p_debug("clean up started roc request, roc queue size:%d", + qdf_list_size(&p2p_soc_obj->roc_q)); + list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { + roc_ctx = list_entry(pos, struct p2p_roc_context, + node); + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + if (roc_ctx->roc_state != ROC_STATE_IDLE) { + if (roc_ctx->roc_state != + ROC_STATE_CANCEL_IN_PROG) + p2p_execute_cancel_roc_req(roc_ctx); + + rc = qdf_wait_single_event( + &p2p_soc_obj->cancel_roc_done, + msecs_to_jiffies(P2P_WAIT_CANCEL_ROC)); + if (!rc) + p2p_err("Timeout occurred while waiting for RoC cancellation"); + } + } + + if (status != QDF_STATUS_SUCCESS || rc) { + p2p_err("failed to cleanup roc queue, status:%d, rc:%ld", + status, rc); + status = QDF_STATUS_E_FAILURE; + } + + return status; +} QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx) { - return QDF_STATUS_SUCCESS; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_roc_context *curr_roc_ctx; + QDF_STATUS status; + uint32_t size; + + p2p_soc_obj = roc_ctx->p2p_soc_obj; + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + status = qdf_list_insert_back(&p2p_soc_obj->roc_q, + &roc_ctx->node); + if (QDF_STATUS_SUCCESS != status) { + qdf_mem_free(roc_ctx); + p2p_err("Failed to insert roc req, status %d", status); + return status; + } + + size = qdf_list_size(&p2p_soc_obj->roc_q); + if (size == 1) { + status = p2p_execute_roc_req(roc_ctx); + } else if (size > 1) { + curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); + /*TODO, to handle extend roc */ + } + + return status; } QDF_STATUS p2p_process_cancel_roc_req( struct cancel_roc_context *cancel_roc_ctx) { - return QDF_STATUS_SUCCESS; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_roc_context *curr_roc_ctx; + QDF_STATUS status; + + p2p_soc_obj = cancel_roc_ctx->p2p_soc_obj; + curr_roc_ctx = p2p_find_roc_ctx(p2p_soc_obj, + cancel_roc_ctx->cookie); + + p2p_debug("p2p soc obj:%p, cookie:%llx, roc ctx:%p", + p2p_soc_obj, cancel_roc_ctx->cookie, curr_roc_ctx); + + if (!curr_roc_ctx) { + p2p_err("Failed to find roc req by cookie, cookie %llx", + cancel_roc_ctx->cookie); + return QDF_STATUS_E_INVAL; + } + + if (curr_roc_ctx->roc_state == ROC_STATE_IDLE) { + status = qdf_list_remove_node(&p2p_soc_obj->roc_q, + (qdf_list_node_t *)curr_roc_ctx); + if (status == QDF_STATUS_SUCCESS) + qdf_mem_free(curr_roc_ctx); + else + p2p_err("Failed to remove roc req, status %d", status); + } else if (curr_roc_ctx->roc_state == + ROC_STATE_CANCEL_IN_PROG) { + p2p_debug("Receive cancel roc req when roc req is canceling, cookie %llx", + cancel_roc_ctx->cookie); + status = QDF_STATUS_SUCCESS; + } else { + status = p2p_execute_cancel_roc_req(curr_roc_ctx); + } + + return status; } void p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, struct scan_event *event, void *arg) { + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_roc_context *curr_roc_ctx; + + p2p_debug("soc:%p, scan event:%d", arg, event->type); + + p2p_soc_obj = (struct p2p_soc_priv_obj *)arg; + if (!p2p_soc_obj) { + p2p_err("Invalid P2P context"); + return; + } + + curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); + if (!curr_roc_ctx) { + p2p_err("Failed to find valid P2P roc context"); + return; + } + switch (event->type) { + case SCAN_EVENT_TYPE_STARTED: + p2p_process_scan_start_evt(curr_roc_ctx); + break; + case SCAN_EVENT_TYPE_FOREIGN_CHANNEL: + p2p_process_ready_on_channel_evt(curr_roc_ctx); + break; + case SCAN_EVENT_TYPE_COMPLETED: + p2p_process_scan_complete_evt(curr_roc_ctx); + break; + case SCAN_EVENT_TYPE_DEQUEUED: + p2p_process_scan_dequeue(curr_roc_ctx); + break; + default: + p2p_err("invalid scan event, %d", event->type); + } } diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index af733c0673ff..736742748186 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -27,6 +27,15 @@ #include #define P2P_EVENT_PROPOGATE_TIME 10 +#define P2P_WAIT_CANCEL_ROC 1000 + +#ifdef QCA_WIFI_3_0_EMU +#define P2P_ROC_DURATION_MULTI_GO_PRESENT 2 +#define P2P_ROC_DURATION_MULTI_GO_ABSENT 3 +#else +#define P2P_ROC_DURATION_MULTI_GO_PRESENT 2 +#define P2P_ROC_DURATION_MULTI_GO_ABSENT 5 +#endif struct wlan_objmgr_vdev; struct scan_event; @@ -97,6 +106,41 @@ struct cancel_roc_context { uint64_t cookie; }; +/** + * p2p_find_current_roc_ctx() - Find out roc context in progressing + * @p2p_soc_obj: p2p psoc private object + * + * This function find out roc context in progressing from p2p psoc + * private object + * + * Return: Pointer to roc context - success + * NULL - failure + */ +struct p2p_roc_context *p2p_find_current_roc_ctx( + struct p2p_soc_priv_obj *p2p_soc_obj); + +/** + * p2p_restart_roc_timer() - Restarts roc timer + * @roc_ctx: remain on channel context + * + * This function restarts roc timer with updated duration. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_restart_roc_timer(struct p2p_roc_context *roc_ctx); + +/** + * p2p_cleanup_roc_queue() - Cleanup roc context in queue + * @p2p_soc_obj: p2p psoc private object + * + * This function cleanup roc context in queue, include the roc + * context in progressing. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_cleanup_roc_queue( + struct p2p_soc_priv_obj *p2p_soc_obj); + /** * p2p_process_roc_req() - Process roc request * @roc_ctx: roc request context diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index e2ca5192273b..d07c56c973e8 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -26,6 +26,7 @@ #include "wlan_p2p_tgt_api.h" #include "wlan_p2p_public_struct.h" #include "../../core/src/wlan_p2p_main.h" +#include "../../core/src/wlan_p2p_roc.h" static inline struct wlan_lmac_if_p2p_tx_ops * wlan_psoc_get_p2p_tx_ops(struct wlan_objmgr_psoc *psoc) @@ -96,6 +97,7 @@ QDF_STATUS tgt_p2p_unregister_noa_ev_handler( void tgt_p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, struct scan_event *event, void *arg) { + p2p_scan_event_cb(vdev, event, arg); } QDF_STATUS tgt_p2p_mgmt_download_comp_cb(void *context, diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 375c0a3f87ac..88b57ce7cc93 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -26,6 +26,7 @@ #include "wlan_p2p_ucfg_api.h" #include "wlan_p2p_public_struct.h" #include "../../core/src/wlan_p2p_main.h" +#include "../../core/src/wlan_p2p_roc.h" static inline struct wlan_lmac_if_p2p_tx_ops * ucfg_p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc) @@ -67,12 +68,82 @@ QDF_STATUS ucfg_p2p_psoc_stop(struct wlan_objmgr_psoc *soc) QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, struct p2p_roc_req *roc_req, uint64_t *cookie) { + struct scheduler_msg msg; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_roc_context *roc_ctx; + + p2p_debug("soc:%p, vdev_id:%d, chan:%d, phy_mode:%d, duration:%d", + soc, roc_req->vdev_id, roc_req->chan, + roc_req->phy_mode, roc_req->duration); + + if (!soc) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("P2P soc object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + roc_ctx = qdf_mem_malloc(sizeof(*roc_ctx)); + if (!roc_ctx) { + p2p_err("failed to allocate p2p roc context"); + return QDF_STATUS_E_NOMEM; + } + + *cookie = (uintptr_t)roc_ctx; + roc_ctx->p2p_soc_obj = p2p_soc_obj; + roc_ctx->vdev_id = roc_req->vdev_id; + roc_ctx->chan = roc_req->chan; + roc_ctx->phy_mode = roc_req->phy_mode; + roc_ctx->duration = roc_req->duration; + roc_ctx->roc_state = ROC_STATE_IDLE; + roc_ctx->roc_type = USER_REQUESTED; + msg.type = P2P_ROC_REQ; + msg.bodyptr = roc_ctx; + msg.callback = p2p_process_cmd; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + return QDF_STATUS_SUCCESS; } QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, uint64_t cookie) { + struct scheduler_msg msg; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct cancel_roc_context *cancel_roc; + + p2p_debug("soc:%p, cookie:0x%llx", soc, cookie); + + if (!soc) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("p2p soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + cancel_roc = qdf_mem_malloc(sizeof(*cancel_roc)); + if (!cancel_roc) { + p2p_err("failed to allocate cancel p2p roc"); + return QDF_STATUS_E_NOMEM; + } + + cancel_roc->p2p_soc_obj = p2p_soc_obj; + cancel_roc->cookie = cookie; + msg.type = P2P_CANCEL_ROC_REQ; + msg.bodyptr = cancel_roc; + msg.callback = p2p_process_cmd; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + return QDF_STATUS_SUCCESS; } From 47276d678541400efab69b803998efe84822270c Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 22 Mar 2017 13:18:15 +0800 Subject: [PATCH 026/404] qcacmn: mgmt frame txrx Modify P2P IE and tx mgmt frame. Handles tx confirm and rx frame events. Change-Id: I0c0ada2e12ee5ebdd3e8d7b7a6f2bd2af4357548 CRs-Fixed: 2015297 --- core/src/wlan_p2p_main.c | 1 + core/src/wlan_p2p_main.h | 3 + core/src/wlan_p2p_off_chan_tx.c | 1527 +++++++++++++++++++++++ core/src/wlan_p2p_off_chan_tx.h | 148 ++- core/src/wlan_p2p_roc.c | 1 + dispatcher/inc/wlan_p2p_public_struct.h | 2 + dispatcher/src/wlan_p2p_tgt_api.c | 133 ++ dispatcher/src/wlan_p2p_ucfg_api.c | 85 ++ 8 files changed, 1896 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 25e53727ab5d..96d472b510b8 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -579,6 +579,7 @@ QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc) } /* clean up queue of p2p psoc private object */ + p2p_cleanup_tx_queue(p2p_soc_obj); p2p_cleanup_roc_queue(p2p_soc_obj); /* unrgister scan request id*/ diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 7b2e0056563b..7f1ff9539a76 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -53,6 +53,7 @@ struct p2p_rx_mgmt_frame; struct p2p_lo_event; struct p2p_start_param; struct p2p_noa_info; +struct tx_action_context; /** * enum p2p_cmd_type - P2P request type @@ -88,10 +89,12 @@ enum p2p_event_type { * struct p2p_tx_conf_event - p2p tx confirm event * @p2p_soc_obj: p2p soc private object * @tx_cnf: p2p tx confirm structure + * @tx_ctx: tx context */ struct p2p_tx_conf_event { struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_tx_cnf *tx_cnf; + struct tx_action_context *tx_ctx; }; /** diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 99ceaff00ab1..45208cc1c158 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -20,28 +20,1555 @@ * DOC: This file contains off channel tx API definitions */ +#include +#include +#include #include +#include "wlan_p2p_public_struct.h" +#include "wlan_p2p_tgt_api.h" +#include "wlan_p2p_ucfg_api.h" +#include "wlan_p2p_roc.h" +#include "wlan_p2p_main.h" #include "wlan_p2p_off_chan_tx.h" +/** + * p2p_tx_context_check_valid() - check tx action context + * @tx_ctx: tx context + * + * This function check if tx action context and parameters are valid. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_tx_context_check_valid(struct tx_action_context *tx_ctx) +{ + struct wlan_objmgr_psoc *psoc; + struct p2p_soc_priv_obj *p2p_soc_obj; + + if (!tx_ctx) { + p2p_err("null tx action context"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = tx_ctx->p2p_soc_obj; + if (!p2p_soc_obj) { + p2p_err("null p2p soc private object"); + return QDF_STATUS_E_INVAL; + } + + psoc = p2p_soc_obj->soc; + if (!psoc) { + p2p_err("null p2p soc object"); + return QDF_STATUS_E_INVAL; + } + + if (!tx_ctx->buf) { + p2p_err("null tx buffer"); + return QDF_STATUS_E_INVAL; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_vdev_check_valid() - check vdev and vdev mode + * @tx_ctx: tx context + * + * This function check if vdev and vdev mode are valid. It will drop + * probe response in sta mode. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx) +{ + enum tQDF_ADAPTER_MODE mode; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct p2p_soc_priv_obj *p2p_soc_obj; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + p2p_soc_obj = tx_ctx->p2p_soc_obj; + psoc = p2p_soc_obj->soc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + tx_ctx->vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_err("null vdev object"); + return QDF_STATUS_E_INVAL; + } + + wlan_vdev_obj_lock(vdev); + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + p2p_debug("vdev mode:%d", mode); + + /* drop probe response for sta, go, sap */ + if ((mode == QDF_STA_MODE || + mode == QDF_SAP_MODE || + mode == QDF_P2P_GO_MODE) && + tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP) { + p2p_debug("drop probe response, mode:%d", mode); + status = QDF_STATUS_E_FAILURE; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return status; +} + +/** + * p2p_get_p2pie_ptr() - get the pointer to p2p ie + * @ie: source ie + * @ie_len: source ie length + * + * This function finds out p2p ie by p2p oui and return the pointer. + * + * Return: pointer to p2p ie + */ +static uint8_t *p2p_get_p2pie_ptr(uint8_t *ie, uint16_t ie_len) +{ + return wlan_get_vendor_ie_ptr_from_oui(P2P_OUI, + P2P_OUI_SIZE, ie, ie_len); +} + +/** + * p2p_get_p2pie_from_probe_rsp() - get the pointer to p2p ie from + * probe response + * @tx_ctx: tx context + * + * This function finds out p2p ie and return the pointer if it is a + * probe response frame. + * + * Return: pointer to p2p ie + */ +static uint8_t *p2p_get_p2pie_from_probe_rsp( + struct tx_action_context *tx_ctx) +{ + uint8_t *ie; + uint8_t *p2p_ie; + uint8_t *tmp_p2p_ie; + uint16_t ie_len; + + ie = tx_ctx->buf + PROBE_RSP_IE_OFFSET; + ie_len = tx_ctx->buf_len - PROBE_RSP_IE_OFFSET; + p2p_ie = p2p_get_p2pie_ptr(ie, ie_len); + while ((p2p_ie) && + (P2P_MAX_IE_LENGTH == p2p_ie[1])) { + ie_len = tx_ctx->buf_len - (p2p_ie - tx_ctx->buf); + if (ie_len > 2) { + ie = p2p_ie + P2P_MAX_IE_LENGTH + 2; + tmp_p2p_ie = p2p_get_p2pie_ptr(ie, ie_len); + } + + if (tmp_p2p_ie) { + p2p_ie = tmp_p2p_ie; + tmp_p2p_ie = NULL; + } else { + break; + } + } + + return p2p_ie; +} + +/** + * p2p_get_presence_noa_attr() - get the pointer to noa attr + * @pies: source ie + * @length: source ie length + * + * This function finds out noa attr by noa eid and return the pointer. + * + * Return: pointer to noa attr + */ +static uint8_t *p2p_get_presence_noa_attr(uint8_t *pies, int length) +{ + int left = length; + uint8_t *ptr = pies; + uint8_t elem_id; + uint16_t elem_len; + + p2p_debug("pies:%p, length:%d", pies, length); + + while (left >= 3) { + elem_id = ptr[0]; + elem_len = ((uint16_t) ptr[1]) | (ptr[2] << 8); + + left -= 3; + if (elem_len > left) { + p2p_err("****Invalid IEs, elem_len=%d left=%d*****", + elem_len, left); + return NULL; + } + if (elem_id == P2P_NOA_ATTR) + return ptr; + + left -= elem_len; + ptr += (elem_len + 3); + } + + return NULL; +} + +/** + * p2p_get_noa_attr_stream_in_mult_p2p_ies() - get the pointer to noa + * attr from multi p2p ie + * @noa_stream: noa stream + * @noa_len: noa stream length + * @overflow_len: overflow length + * + * This function finds out noa attr from multi p2p ies. + * + * Return: noa length + */ +static uint8_t p2p_get_noa_attr_stream_in_mult_p2p_ies(uint8_t *noa_stream, + uint8_t noa_len, uint8_t overflow_len) +{ + uint8_t overflow_p2p_stream[P2P_MAX_NOA_ATTR_LEN]; + + p2p_debug("noa_stream:%p, noa_len:%d, overflow_len:%d", + noa_stream, noa_len, overflow_len); + if ((noa_len <= (P2P_MAX_NOA_ATTR_LEN + P2P_IE_HEADER_LEN)) && + (noa_len >= overflow_len) && + (overflow_len <= P2P_MAX_NOA_ATTR_LEN)) { + qdf_mem_copy(overflow_p2p_stream, + noa_stream + noa_len - overflow_len, + overflow_len); + noa_stream[noa_len - overflow_len] = + P2P_EID_VENDOR; + noa_stream[noa_len - overflow_len + 1] = + overflow_len + P2P_OUI_SIZE; + qdf_mem_copy(noa_stream + noa_len - overflow_len + 2, + P2P_OUI, P2P_OUI_SIZE); + qdf_mem_copy(noa_stream + noa_len + 2 + P2P_OUI_SIZE - + overflow_len, overflow_p2p_stream, + overflow_len); + } + + return noa_len + P2P_IE_HEADER_LEN; +} + +/** + * p2p_get_vdev_noa_info() - get vdev noa information + * @tx_ctx: tx context + * + * This function gets vdev noa information + * + * Return: pointer to noa information + */ +static struct p2p_noa_info *p2p_get_vdev_noa_info( + struct tx_action_context *tx_ctx) +{ + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + enum tQDF_ADAPTER_MODE mode; + struct p2p_noa_info *noa_info = NULL; + + p2p_soc_obj = tx_ctx->p2p_soc_obj; + psoc = p2p_soc_obj->soc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + tx_ctx->vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_err("vdev obj is NULL"); + return NULL; + } + + wlan_vdev_obj_lock(vdev); + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + p2p_debug("vdev mode:%d", mode); + if (mode != QDF_P2P_GO_MODE) { + p2p_debug("invalid p2p vdev mode:%d", mode); + goto fail; + } + + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_P2P); + + if (!p2p_vdev_obj || !(p2p_vdev_obj->noa_info)) { + p2p_debug("null noa info"); + goto fail; + } + + noa_info = p2p_vdev_obj->noa_info; + +fail: + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return noa_info; +} + +/** + * p2p_get_noa_attr_stream() - get noa stream from p2p vdev object + * @tx_ctx: tx context + * @pnoa_stream: pointer to noa stream + * + * This function finds out noa stream from p2p vdev object + * + * Return: noa stream length + */ +static uint8_t p2p_get_noa_attr_stream( + struct tx_action_context *tx_ctx, uint8_t *pnoa_stream) +{ + struct p2p_noa_info *noa_info; + struct noa_descriptor *noa_desc_0; + struct noa_descriptor *noa_desc_1; + uint8_t *pbody = pnoa_stream; + uint8_t len = 0; + + noa_info = p2p_get_vdev_noa_info(tx_ctx); + if (!noa_info) { + p2p_debug("not valid noa information"); + return 0; + } + + noa_desc_0 = &(noa_info->noa_desc[0]); + noa_desc_1 = &(noa_info->noa_desc[1]); + if ((!(noa_desc_0->duration)) && + (!(noa_desc_1->duration)) && + (!noa_info->opps_ps)) { + p2p_debug("opps ps and duration are 0"); + return 0; + } + + pbody[0] = P2P_NOA_ATTR; + pbody[3] = noa_info->index; + pbody[4] = noa_info->ct_window | (noa_info->opps_ps << 7); + len = 5; + pbody += len; + + if (noa_desc_0->duration) { + *pbody = noa_desc_0->type_count; + pbody += 1; + len += 1; + + *((uint32_t *) (pbody)) = noa_desc_0->duration; + pbody += sizeof(uint32_t); + len += 4; + + *((uint32_t *) (pbody)) = noa_desc_0->interval; + pbody += sizeof(uint32_t); + len += 4; + + *((uint32_t *) (pbody)) = noa_desc_0->start_time; + pbody += sizeof(uint32_t); + len += 4; + } + + if (noa_desc_1->duration) { + *pbody = noa_desc_1->type_count; + pbody += 1; + len += 1; + + *((uint32_t *) (pbody)) = noa_desc_1->duration; + pbody += sizeof(uint32_t); + len += 4; + + *((uint32_t *) (pbody)) = noa_desc_1->interval; + pbody += sizeof(uint32_t); + len += 4; + + *((uint32_t *) (pbody)) = noa_desc_1->start_time; + pbody += sizeof(uint32_t); + len += 4; + } + + pbody = pnoa_stream + 1; + /* one byte for Attr and 2 bytes for length */ + *((uint16_t *) (pbody)) = len - 3; + + return len; +} + +/** + * p2p_update_noa_stream() - update noa stream + * @tx_ctx: tx context + * @p2p_ie: pointer to p2p ie + * @noa_attr: pointer to noa attr + * @total_len: pointer to total length of ie + * + * This function updates noa stream. + * + * Return: noa stream length + */ +static uint16_t p2p_update_noa_stream(struct tx_action_context *tx_ctx, + uint8_t *p2p_ie, uint8_t *noa_attr, uint32_t *total_len, + uint8_t *noa_stream) +{ + uint16_t noa_len; + uint16_t overflow_len; + uint8_t orig_len; + uint32_t nbytes_copy; + uint32_t buf_len = *total_len; + + noa_len = p2p_get_noa_attr_stream(tx_ctx, noa_stream); + if (noa_len <= 0) { + p2p_debug("do not find out noa attr"); + return 0; + } + + orig_len = p2p_ie[1]; + if (noa_attr) { + noa_len = noa_attr[1] | (noa_attr[2] << 8); + orig_len -= (noa_len + 1 + 2); + buf_len -= (noa_len + 1 + 2); + p2p_ie[1] = orig_len; + } + + if ((p2p_ie[1] + noa_len) > P2P_MAX_IE_LENGTH) { + overflow_len = p2p_ie[1] + noa_len - + P2P_MAX_IE_LENGTH; + noa_len = p2p_get_noa_attr_stream_in_mult_p2p_ies( + noa_stream, noa_len, overflow_len); + p2p_ie[1] = P2P_MAX_IE_LENGTH; + } else { + /* increment the length of P2P IE */ + p2p_ie[1] += noa_len; + } + + *total_len = buf_len; + nbytes_copy = (p2p_ie + orig_len + 2) - tx_ctx->buf; + + p2p_debug("noa_len=%d orig_len=%d p2p_ie=%p buf_len=%d nbytes copy=%d ", + noa_len, orig_len, p2p_ie, buf_len, nbytes_copy); + + return noa_len; +} + +/** + * p2p_set_ht_caps() - set ht capability + * @tx_ctx: tx context + * @num_bytes: number bytes + * + * This function sets ht capability + * + * Return: None + */ +static void p2p_set_ht_caps(struct tx_action_context *tx_ctx, + uint32_t num_bytes) +{ +} + +/** + * p2p_populate_mac_header() - update sequence number + * @tx_ctx: tx context + * + * This function updates sequence number of this mgmt frame + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_populate_mac_header( + struct tx_action_context *tx_ctx) +{ + struct wlan_seq_ctl *seq_ctl; + struct wlan_frame_hdr *wh; + struct wlan_objmgr_peer *peer; + struct wlan_objmgr_psoc *psoc; + void *mac_addr; + uint16_t seq_num; + + psoc = tx_ctx->p2p_soc_obj->soc; + + wh = (struct wlan_frame_hdr *)tx_ctx->buf; + mac_addr = wh->i_addr1; + peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_P2P_ID); + if (!peer) { + mac_addr = wh->i_addr2; + peer = wlan_objmgr_get_peer(psoc, mac_addr, + WLAN_P2P_ID); + } + + if (!peer) { + p2p_err("no valid peer"); + return QDF_STATUS_E_INVAL; + } + seq_num = (uint16_t)wlan_peer_mlme_get_next_seq_num(peer); + seq_ctl = (struct wlan_seq_ctl *)(tx_ctx->buf + + WLAN_SEQ_CTL_OFFSET); + seq_ctl->seq_num_lo = (seq_num & WLAN_LOW_SEQ_NUM_MASK); + seq_ctl->seq_num_hi = ((seq_num & WLAN_HIGH_SEQ_NUM_MASK) >> + WLAN_HIGH_SEQ_NUM_OFFSET); + + wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_set_protected_bit() - set protected bit + * @tx_ctx: tx context + * @frame: pointer to frame + * + * This function sets protected bit of this mgmt frame + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_set_protected_bit( + struct tx_action_context *tx_ctx, void *frame) +{ + return QDF_STATUS_E_INVAL; +} + +/** + * p2p_get_frame_type_str() - parse frame type to string + * @frame_info: frame information + * + * This function parse frame type to string. + * + * Return: command string + */ +static char *p2p_get_frame_type_str(struct p2p_frame_info *frame_info) +{ + if (frame_info->type == P2P_FRAME_NOT_SUPPORT) + return "Not support frame"; + + if (frame_info->sub_type == P2P_MGMT_NOT_SUPPORT) + return "Not support sub frame"; + + switch (frame_info->sub_type) { + case P2P_MGMT_PROBE_REQ: + return "P2P roc request"; + case P2P_MGMT_PROBE_RSP: + return "P2P cancel roc request"; + case P2P_MGMT_ACTION: + break; + default: + return "Invalid P2P command"; + } + + if (frame_info->action_type == P2P_ACTION_PRESENCE_RSP) + return "P2P action presence response"; + + switch (frame_info->public_action_type) { + case P2P_PUBLIC_ACTION_NEG_REQ: + return "GO negotiation request frame"; + case P2P_PUBLIC_ACTION_NEG_RSP: + return "GO negotiation response frame"; + case P2P_PUBLIC_ACTION_NEG_CNF: + return "GO negotiation confirm frame"; + case P2P_PUBLIC_ACTION_INVIT_REQ: + return "P2P invitation request"; + case P2P_PUBLIC_ACTION_INVIT_RSP: + return "P2P invitation response"; + case P2P_PUBLIC_ACTION_DEV_DIS_REQ: + return "Device discoverability request"; + case P2P_PUBLIC_ACTION_DEV_DIS_RSP: + return "Device discoverability response"; + case P2P_PUBLIC_ACTION_PROV_DIS_REQ: + return "Provision discovery request"; + case P2P_PUBLIC_ACTION_PROV_DIS_RSP: + return "Provision discovery response"; + case P2P_PUBLIC_ACTION_GAS_INIT_REQ: + return "GAS init request"; + case P2P_PUBLIC_ACTION_GAS_INIT_RSP: + return "GAS init response"; + case P2P_PUBLIC_ACTION_GAS_COMB_REQ: + return "GAS come back request"; + case P2P_PUBLIC_ACTION_GAS_COMB_RSP: + return "GAS come back response"; + default: + return "Not support action frame"; + } +} + +/** + * p2p_init_frame_info() - init frame information structure + * @frame_info: pointer to frame information + * + * This function init frame information structure. + * + * Return: None + */ +static void p2p_init_frame_info(struct p2p_frame_info *frame_info) +{ + frame_info->type = P2P_FRAME_NOT_SUPPORT; + frame_info->sub_type = P2P_MGMT_NOT_SUPPORT; + frame_info->public_action_type = + P2P_PUBLIC_ACTION_NOT_SUPPORT; + frame_info->action_type = P2P_ACTION_NOT_SUPPORT; +} + +/** + * p2p_get_frame_info() - get frame information from packet + * @tx_ctx: tx context + * + * This function gets frame information from packet. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_get_frame_info(struct tx_action_context *tx_ctx) +{ + uint8_t type; + uint8_t sub_type; + uint8_t action_type; + uint8_t *buf = tx_ctx->buf; + struct p2p_frame_info *frame_info = &(tx_ctx->frame_info); + + type = P2P_GET_TYPE_FRM_FC(buf[0]); + sub_type = P2P_GET_SUBTYPE_FRM_FC(buf[0]); + p2p_init_frame_info(frame_info); + if (type != P2P_FRAME_MGMT) { + p2p_err("just support mgmt frame"); + return QDF_STATUS_E_FAILURE; + } + + frame_info->type = P2P_FRAME_MGMT; + if (sub_type != P2P_MGMT_PROBE_RSP && + sub_type != P2P_MGMT_ACTION) { + p2p_err("not support sub type"); + return QDF_STATUS_E_FAILURE; + } + + if (sub_type == P2P_MGMT_PROBE_RSP) { + frame_info->sub_type = P2P_MGMT_PROBE_RSP; + p2p_debug("Probe Response"); + return QDF_STATUS_SUCCESS; + } + + if (sub_type == P2P_MGMT_PROBE_REQ) { + frame_info->sub_type = P2P_MGMT_PROBE_REQ; + p2p_debug("Probe Request"); + return QDF_STATUS_SUCCESS; + } + + frame_info->sub_type = P2P_MGMT_ACTION; + buf += P2P_ACTION_OFFSET; + if (buf[0] == P2P_PUBLIC_ACTION_FRAME && + buf[1] == P2P_PUBLIC_ACTION_VENDOR_SPECIFIC && + !qdf_mem_cmp(&buf[2], P2P_OUI, P2P_OUI_SIZE)) { + buf = tx_ctx->buf + + P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET; + action_type = buf[0]; + if (action_type >= P2P_PUBLIC_ACTION_NOT_SUPPORT) + frame_info->public_action_type = + P2P_PUBLIC_ACTION_NOT_SUPPORT; + else + frame_info->public_action_type = action_type; + } else if (buf[0] == P2P_ACTION_VENDOR_SPECIFIC_CATEGORY && + !qdf_mem_cmp(&buf[1], P2P_OUI, P2P_OUI_SIZE)) { + buf = tx_ctx->buf + + P2P_ACTION_FRAME_TYPE_OFFSET; + action_type = buf[0]; + if (action_type == P2P_ACTION_PRESENCE_RSP) + frame_info->action_type = + P2P_ACTION_PRESENCE_RSP; + } else { + p2p_debug("this is not vendor specific p2p action frame"); + return QDF_STATUS_SUCCESS; + } + + p2p_debug("%s", p2p_get_frame_type_str(frame_info)); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_packet_alloc() - allocate qdf nbuf + * @size: buffe size + * @data: pointer to qdf nbuf data point + * @ppPacket: pointer to qdf nbuf point + * + * This function allocates qdf nbuf. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_packet_alloc(uint16_t size, void **data, + void **ppPacket) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + qdf_nbuf_t nbuf; + + nbuf = qdf_nbuf_alloc(NULL, + roundup(size + P2P_TX_PKT_MIN_HEADROOM, 4), + P2P_TX_PKT_MIN_HEADROOM, sizeof(uint32_t), + false); + + if (nbuf != NULL) { + qdf_nbuf_put_tail(nbuf, size); + qdf_nbuf_set_protocol(nbuf, ETH_P_CONTROL); + *ppPacket = nbuf; + *data = qdf_nbuf_data(nbuf); + qdf_mem_set(*data, size, 0); + status = QDF_STATUS_SUCCESS; + } + + return status; +} + +/** + * p2p_send_tx_conf() - send tx confirm + * @tx_ctx: tx context + * @status: tx status + * + * This function send tx confirm to osif + * + * Return: QDF_STATUS_SUCCESS - pointer to tx context + */ +static QDF_STATUS p2p_send_tx_conf(struct tx_action_context *tx_ctx, + bool status) +{ + struct p2p_tx_cnf tx_cnf; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_start_param *start_param; + + p2p_soc_obj = tx_ctx->p2p_soc_obj; + + if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) { + p2p_err("Invalid p2p soc object or start parameters"); + return QDF_STATUS_E_INVAL; + } + + start_param = p2p_soc_obj->start_param; + if (!(start_param->tx_cnf_cb)) { + p2p_err("no tx confirm callback"); + return QDF_STATUS_E_INVAL; + } + + if (tx_ctx->no_ack) + tx_cnf.action_cookie = 0; + else + tx_cnf.action_cookie = (uintptr_t)tx_ctx; + + tx_cnf.vdev_id = tx_ctx->vdev_id; + tx_cnf.buf = tx_ctx->buf; + tx_cnf.buf_len = tx_ctx->buf_len; + tx_cnf.status = status ? 0 : 1; + + p2p_debug("soc:%p, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%p", + p2p_soc_obj->soc, tx_cnf.vdev_id, + tx_cnf.action_cookie, tx_cnf.buf_len, + tx_cnf.status, tx_cnf.buf); + + start_param->tx_cnf_cb(start_param->tx_cnf_cb_data, &tx_cnf); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_mgmt_tx() - call mgmt tx api + * @tx_ctx: tx context + * @buf_len: buffer length + * @packet: pointer to qdf nbuf + * @frame: pointer to qdf nbuf data + * + * This function call mgmt tx api to tx this action frame. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, + uint32_t buf_len, void *packet, uint8_t *frame) +{ + QDF_STATUS status; + mgmt_tx_download_comp_cb tx_comp_cb; + mgmt_ota_comp_cb tx_ota_comp_cb; + struct wlan_frame_hdr *wh; + struct wlan_objmgr_peer *peer; + struct wmi_mgmt_params mgmt_param; + struct wlan_objmgr_psoc *psoc; + void *mac_addr; + + psoc = tx_ctx->p2p_soc_obj->soc; + mgmt_param.tx_frame = packet; + mgmt_param.frm_len = buf_len; + mgmt_param.vdev_id = tx_ctx->vdev_id; + mgmt_param.pdata = frame; + mgmt_param.chanfreq = wlan_chan_to_freq(tx_ctx->chan); + + mgmt_param.qdf_ctx = wlan_psoc_get_qdf_dev(psoc); + if (!(mgmt_param.qdf_ctx)) { + p2p_err("qdf ctx is null"); + return QDF_STATUS_E_INVAL; + } + + wh = (struct wlan_frame_hdr *)frame; + mac_addr = wh->i_addr1; + peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_MGMT_NB_ID); + if (!peer) { + mac_addr = wh->i_addr2; + peer = wlan_objmgr_get_peer(psoc, mac_addr, + WLAN_MGMT_NB_ID); + } + + if (!peer) { + p2p_err("no valid peer"); + return QDF_STATUS_E_INVAL; + } + + if (tx_ctx->no_ack) { + tx_comp_cb = tgt_p2p_mgmt_download_comp_cb; + tx_ota_comp_cb = NULL; + } else { + tx_comp_cb = NULL; + tx_ota_comp_cb = tgt_p2p_mgmt_ota_comp_cb; + } + + p2p_debug("length:%d, vdev_id:%d, chanfreq:%d, no_ack:%d", + mgmt_param.frm_len, mgmt_param.vdev_id, + mgmt_param.chanfreq, tx_ctx->no_ack); + + status = wlan_mgmt_txrx_mgmt_frame_tx(peer, tx_ctx, + (qdf_nbuf_t)packet, + tx_comp_cb, tx_ota_comp_cb, + WLAN_UMAC_COMP_P2P, &mgmt_param); + + return status; +} + +/** + * p2p_roc_req_for_tx_action() - new a roc request for tx + * @tx_ctx: tx context + * + * This function new a roc request for tx and call roc api to process + * this new roc request. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_roc_req_for_tx_action( + struct tx_action_context *tx_ctx) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_roc_context *roc_ctx; + QDF_STATUS status; + + roc_ctx = qdf_mem_malloc(sizeof(struct p2p_roc_context)); + if (!roc_ctx) { + p2p_err("Failed to allocate p2p roc context"); + return QDF_STATUS_E_NOMEM; + } + + p2p_soc_obj = tx_ctx->p2p_soc_obj; + roc_ctx->p2p_soc_obj = p2p_soc_obj; + roc_ctx->vdev_id = tx_ctx->vdev_id; + roc_ctx->chan = tx_ctx->chan; + roc_ctx->duration = tx_ctx->duration; + roc_ctx->roc_state = ROC_STATE_IDLE; + roc_ctx->roc_type = OFF_CHANNEL_TX; + tx_ctx->roc_cookie = (uintptr_t)roc_ctx; + + p2p_debug("create roc request for off channel tx, tx ctx:%p, roc ctx:%p", + tx_ctx, roc_ctx); + + status = p2p_process_roc_req(roc_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("request roc for tx action frrame fail"); + qdf_mem_free(roc_ctx); + return status; + } + + status = qdf_list_insert_back(&p2p_soc_obj->tx_q_roc, + &tx_ctx->node); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to insert off chan tx context to wait roc req queue"); + + return status; +} + +/** + * p2p_find_tx_ctx() - find tx context by cookie + * @p2p_soc_obj: p2p soc object + * @cookie: cookie to this p2p tx context + * @is_roc_q: it is in waiting for roc queue + * @is_ack_q: it is in waiting for ack queue + * + * This function finds out tx context by cookie. + * + * Return: pointer to tx context + */ +static struct tx_action_context *p2p_find_tx_ctx( + struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie, + bool *is_roc_q, bool *is_ack_q) +{ + struct tx_action_context *cur_tx_ctx; + qdf_list_node_t *tmp, *pos; + *is_roc_q = false; + *is_ack_q = false; + + p2p_debug("Start to find tx ctx, p2p soc_obj:%p, cookie:%llx", + p2p_soc_obj, cookie); + + list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { + cur_tx_ctx = + list_entry(pos, struct tx_action_context, node); + if ((uintptr_t) cur_tx_ctx == cookie) { + *is_roc_q = true; + p2p_debug("find tx ctx, cookie:%llx", cookie); + return cur_tx_ctx; + } + } + + list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { + cur_tx_ctx = + list_entry(pos, struct tx_action_context, node); + if ((uintptr_t) cur_tx_ctx == cookie) { + *is_ack_q = true; + p2p_debug("find tx ctx, cookie:%llx", cookie); + return cur_tx_ctx; + } + } + + return NULL; +} + +/** + * p2p_find_tx_ctx_by_roc() - find tx context by roc + * @p2p_soc_obj: p2p soc object + * @cookie: cookie to roc context + * @is_roc_q: it is in waiting for roc queue + * @is_ack_q: it is in waiting for ack queue + * + * This function finds out tx context by roc context. + * + * Return: pointer to tx context + */ +static struct tx_action_context *p2p_find_tx_ctx_by_roc( + struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie, + bool *is_roc_q, bool *is_ack_q) +{ + struct tx_action_context *cur_tx_ctx; + qdf_list_node_t *tmp, *pos; + *is_roc_q = false; + *is_ack_q = false; + + p2p_debug("Start to find tx ctx, p2p soc_obj:%p, cookie:%llx", + p2p_soc_obj, cookie); + + list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { + cur_tx_ctx = + list_entry(pos, struct tx_action_context, node); + if (cur_tx_ctx->roc_cookie == cookie) { + *is_roc_q = true; + p2p_debug("find tx ctx, cookie:%llx", cookie); + return cur_tx_ctx; + } + } + + list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { + cur_tx_ctx = + list_entry(pos, struct tx_action_context, node); + if (cur_tx_ctx->roc_cookie == cookie) { + *is_ack_q = true; + p2p_debug("find tx ctx, cookie:%llx", cookie); + return cur_tx_ctx; + } + } + + return NULL; +} + +/** + * p2p_move_tx_context_to_ack_queue() - move tx context to tx_q_ack + * @tx_ctx: tx context + * + * This function moves tx context to waiting for ack queue. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_move_tx_context_to_ack_queue( + struct tx_action_context *tx_ctx) +{ + bool is_roc_q = false; + bool is_ack_q = false; + struct p2p_soc_priv_obj *p2p_soc_obj = tx_ctx->p2p_soc_obj; + struct tx_action_context *cur_tx_ctx; + QDF_STATUS status; + + p2p_debug("move tx context to wait for roc queue, %p", tx_ctx); + + cur_tx_ctx = p2p_find_tx_ctx(p2p_soc_obj, (uintptr_t)tx_ctx, + &is_roc_q, &is_ack_q); + if (cur_tx_ctx) { + if (is_roc_q) { + p2p_debug("find in wait for roc queue"); + status = qdf_list_remove_node( + &p2p_soc_obj->tx_q_roc, + (qdf_list_node_t *)tx_ctx); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to remove off chan tx context from wait roc req queue"); + } + + if (is_ack_q) { + p2p_err("Already in waiting for ack queue"); + return QDF_STATUS_SUCCESS; + } + } + + status = qdf_list_insert_back( + &p2p_soc_obj->tx_q_ack, + &tx_ctx->node); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to insert off chan tx context to wait ack req queue"); + + p2p_debug("insert tx context to wait for roc queue, status:%d", + status); + + return status; +} + +/** + * p2p_adjust_tx_wait() - adjust tx wait + * @tx_ctx: tx context + * + * This function adjust wait time of this tx context + * + * Return: None + */ +static void p2p_adjust_tx_wait(struct tx_action_context *tx_ctx) +{ + struct p2p_frame_info *frame_info; + + frame_info = &(tx_ctx->frame_info); + switch (frame_info->public_action_type) { + case P2P_PUBLIC_ACTION_NEG_RSP: + case P2P_PUBLIC_ACTION_PROV_DIS_RSP: + tx_ctx->duration += P2P_ACTION_FRAME_RSP_WAIT; + break; + case P2P_PUBLIC_ACTION_NEG_CNF: + case P2P_PUBLIC_ACTION_INVIT_RSP: + tx_ctx->duration += P2P_ACTION_FRAME_ACK_WAIT; + break; + default: + break; + } +} + +/** + * p2p_remove_tx_context() - remove tx ctx from queue + * @tx_ctx: tx context + * + * This function remove tx context from waiting for roc queue or + * waiting for ack queue. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_remove_tx_context( + struct tx_action_context *tx_ctx) +{ + bool is_roc_q = false; + bool is_ack_q = false; + struct tx_action_context *cur_tx_ctx; + uint64_t cookie = (uintptr_t)tx_ctx; + struct p2p_soc_priv_obj *p2p_soc_obj = tx_ctx->p2p_soc_obj; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_debug("tx context:%p", tx_ctx); + + cur_tx_ctx = p2p_find_tx_ctx(p2p_soc_obj, cookie, &is_roc_q, + &is_ack_q); + + /* for not off channel tx case, won't find from queue */ + if (!cur_tx_ctx) + p2p_debug("Do not find tx context from queue"); + + if (is_roc_q) { + status = qdf_list_remove_node( + &p2p_soc_obj->tx_q_roc, + (qdf_list_node_t *)cur_tx_ctx); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to tx context from wait roc req queue"); + } + + if (is_ack_q) { + status = qdf_list_remove_node( + &p2p_soc_obj->tx_q_ack, + (qdf_list_node_t *)cur_tx_ctx); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to tx context from wait ack req queue"); + } + + qdf_mem_free(tx_ctx->buf); + qdf_mem_free(tx_ctx); + + return status; +} + +/** + * p2p_tx_timeout() - Callback for tx timeout + * @pdata: pointer to tx context + * + * This function is callback for tx time out. + * + * Return: None + */ +static void p2p_tx_timeout(void *pdata) +{ + struct tx_action_context *tx_ctx = pdata; + + p2p_debug("pdata:%p", pdata); + + if (!tx_ctx) { + p2p_err("invalid tx context"); + return; + } + + qdf_mc_timer_destroy(&tx_ctx->tx_timer); + p2p_send_tx_conf(tx_ctx, false); + p2p_remove_tx_context(tx_ctx); +} + +/** + * p2p_enable_tx_timer() - enable tx timer + * @tx_ctx: tx context + * + * This function enable tx timer for action frame required ota tx. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_enable_tx_timer(struct tx_action_context *tx_ctx) +{ + QDF_STATUS status; + + p2p_debug("tx context:%p", tx_ctx); + + status = qdf_mc_timer_init(&tx_ctx->tx_timer, + QDF_TIMER_TYPE_SW, p2p_tx_timeout, + tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("failed to init tx timer"); + return status; + } + + status = qdf_mc_timer_start(&tx_ctx->tx_timer, + P2P_ACTION_FRAME_TX_TIMEOUT); + if (status != QDF_STATUS_SUCCESS) + p2p_err("tx timer start failed"); + + return status; +} + +/** + * p2p_disable_tx_timer() - disable tx timer + * @tx_ctx: tx context + * + * This function disable tx timer for action frame required ota tx. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_disable_tx_timer(struct tx_action_context *tx_ctx) +{ + QDF_STATUS status; + + p2p_debug("tx context:%p", tx_ctx); + + status = qdf_mc_timer_stop(&tx_ctx->tx_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to stop tx timer, status:%d", status); + + status = qdf_mc_timer_destroy(&tx_ctx->tx_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to destroy tx timer, status:%d", status); + + return status; +} + +/** + * p2p_execute_tx_action_frame() - execute tx action frame + * @tx_ctx: tx context + * + * This function modify p2p ie and tx this action frame. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_execute_tx_action_frame( + struct tx_action_context *tx_ctx) +{ + uint8_t *frame; + void *packet; + QDF_STATUS status; + uint8_t noa_len = 0; + uint8_t noa_stream[P2P_NOA_STREAM_ARR_SIZE]; + uint8_t orig_len = 0; + uint8_t *ie; + uint8_t ie_len; + uint8_t *p2p_ie = NULL; + uint8_t *presence_noa_attr = NULL; + uint32_t nbytes_copy; + uint32_t buf_len = tx_ctx->buf_len; + struct p2p_frame_info *frame_info; + + frame_info = &(tx_ctx->frame_info); + if (frame_info->sub_type == P2P_MGMT_PROBE_RSP) { + p2p_ie = p2p_get_p2pie_from_probe_rsp(tx_ctx); + } else if (frame_info->action_type == + P2P_ACTION_PRESENCE_RSP) { + ie = tx_ctx->buf + + P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET; + ie_len = tx_ctx->buf_len - + P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET; + p2p_ie = p2p_get_p2pie_ptr(ie, ie_len); + if (p2p_ie) { + /* extract the presence of NoA attribute inside + * P2P IE */ + ie = p2p_ie + P2P_IE_HEADER_LEN; + ie_len = p2p_ie[1]; + presence_noa_attr = p2p_get_presence_noa_attr( + ie, ie_len); + } + } + + if ((frame_info->sub_type != P2P_MGMT_NOT_SUPPORT) && + p2p_ie) { + orig_len = p2p_ie[1]; + noa_len = p2p_update_noa_stream(tx_ctx, p2p_ie, + presence_noa_attr, &buf_len, + noa_stream); + buf_len += noa_len; + } + + if (frame_info->sub_type == P2P_MGMT_PROBE_RSP) + p2p_set_ht_caps(tx_ctx, buf_len); + + /* Ok-- try to allocate some memory: */ + status = p2p_packet_alloc((uint16_t) buf_len, (void **)&frame, + (void **)&packet); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to allocate %d bytes for a Probe Request.", + buf_len); + return status; + } + + /* + * Add sequence number to action frames + * Frames are handed over in .11 format by supplicant already + */ + p2p_populate_mac_header(tx_ctx); + + if ((noa_len > 0) + && (noa_len < (P2P_MAX_NOA_ATTR_LEN + + P2P_IE_HEADER_LEN))) { + /* Add 2 bytes for length and Arribute field */ + nbytes_copy = (p2p_ie + orig_len + 2) - tx_ctx->buf; + qdf_mem_copy(frame, tx_ctx->buf, nbytes_copy); + qdf_mem_copy((frame + nbytes_copy), noa_stream, + noa_len); + qdf_mem_copy((frame + nbytes_copy + noa_len), + tx_ctx->buf + nbytes_copy, + buf_len - nbytes_copy - noa_len); + } else { + qdf_mem_copy(frame, tx_ctx->buf, buf_len); + } + + p2p_set_protected_bit(tx_ctx, frame); + status = p2p_mgmt_tx(tx_ctx, buf_len, packet, frame); + if (status == QDF_STATUS_SUCCESS) { + if (tx_ctx->no_ack) { + p2p_send_tx_conf(tx_ctx, true); + p2p_remove_tx_context(tx_ctx); + } else { + p2p_enable_tx_timer(tx_ctx); + p2p_move_tx_context_to_ack_queue(tx_ctx); + } + } else { + p2p_err("failed to tx mgmt frame"); + qdf_nbuf_free(packet); + } + + return status; +} + +void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) +{ + struct tx_action_context *tx_ctx; + qdf_list_node_t *tmp, *pos; + + p2p_debug("dump tx queue wait for roc, p2p soc obj:%p, size:%d", + p2p_soc_obj, qdf_list_size(&p2p_soc_obj->tx_q_roc)); + list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { + tx_ctx = list_entry(pos, struct tx_action_context, + node); + p2p_debug("p2p soc object:%p, tx ctx:%p, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%p, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", + p2p_soc_obj, tx_ctx, + tx_ctx->vdev_id, tx_ctx->scan_id, + tx_ctx->roc_cookie, tx_ctx->chan, + tx_ctx->buf, tx_ctx->buf_len, + tx_ctx->off_chan, tx_ctx->no_cck, + tx_ctx->no_ack, tx_ctx->duration); + } + + p2p_debug("dump tx queue wait for ack, size:%d", + qdf_list_size(&p2p_soc_obj->tx_q_ack)); + list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { + tx_ctx = list_entry(pos, struct tx_action_context, + node); + p2p_debug("p2p soc object:%p, tx_ctx:%p, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%p, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", + p2p_soc_obj, tx_ctx, + tx_ctx->vdev_id, tx_ctx->scan_id, + tx_ctx->roc_cookie, tx_ctx->chan, + tx_ctx->buf, tx_ctx->buf_len, + tx_ctx->off_chan, tx_ctx->no_cck, + tx_ctx->no_ack, tx_ctx->duration); + } +} + +QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj, + uint64_t cookie) +{ + bool is_roc_q = false; + bool is_ack_q = false; + struct tx_action_context *cur_tx_ctx; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + cur_tx_ctx = p2p_find_tx_ctx_by_roc(p2p_soc_obj, cookie, + &is_roc_q, &is_ack_q); + p2p_debug("tx_ctx:%p, is_roc_q:%d, is_ack_q:%d", cur_tx_ctx, + is_roc_q, is_ack_q); + if (cur_tx_ctx) { + if (is_roc_q) { + status = p2p_execute_tx_action_frame(cur_tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_send_tx_conf(cur_tx_ctx, false); + p2p_remove_tx_context(cur_tx_ctx); + } + } + if (is_ack_q) { + p2p_err("Already sent and waiting for ack"); + status = QDF_STATUS_SUCCESS; + } + } else { + p2p_err("Failed to find tx ctx by cookie, cookie %llx", + cookie); + status = QDF_STATUS_E_INVAL; + } + + return status; +} + +QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct tx_action_context *curr_tx_ctx; + qdf_list_node_t *tmp, *pos; + + p2p_debug("clean up tx queue wait for roc, size:%d", + qdf_list_size(&p2p_soc_obj->tx_q_roc)); + list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { + curr_tx_ctx = list_entry(pos, + struct tx_action_context, node); + status = qdf_list_remove_node(&p2p_soc_obj->tx_q_roc, + (qdf_list_node_t *)curr_tx_ctx); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to remove tx ctx from tx wait for roc queue"); + p2p_send_tx_conf(curr_tx_ctx, false); + qdf_mem_free(curr_tx_ctx->buf); + qdf_mem_free(curr_tx_ctx); + } + + p2p_debug("clean up tx queue wait for ack, size:%d", + qdf_list_size(&p2p_soc_obj->tx_q_ack)); + list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { + curr_tx_ctx = list_entry(pos, + struct tx_action_context, node); + status = qdf_list_remove_node(&p2p_soc_obj->tx_q_ack, + (qdf_list_node_t *)curr_tx_ctx); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to remove tx ctx from tx wait for ack queue"); + p2p_disable_tx_timer(curr_tx_ctx); + p2p_send_tx_conf(curr_tx_ctx, false); + qdf_mem_free(curr_tx_ctx->buf); + qdf_mem_free(curr_tx_ctx); + } + + return status; +} + QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) { + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_roc_context *curr_roc_ctx; + uint64_t rc = 1; + QDF_STATUS status; + + status = p2p_tx_context_check_valid(tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("invalid tx action context"); + if (tx_ctx) { + if (tx_ctx->buf) { + p2p_send_tx_conf(tx_ctx, false); + qdf_mem_free(tx_ctx->buf); + } + qdf_mem_free(tx_ctx); + } + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = tx_ctx->p2p_soc_obj; + + p2p_debug("soc:%p, tx_ctx:%p, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%p, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", + p2p_soc_obj->soc, tx_ctx, tx_ctx->vdev_id, + tx_ctx->scan_id, tx_ctx->roc_cookie, tx_ctx->chan, + tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan, + tx_ctx->no_cck, tx_ctx->no_ack, tx_ctx->duration); + + status = p2p_get_frame_info(tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("unsupport frame"); + status = QDF_STATUS_E_INVAL; + goto fail; + } + + status = p2p_vdev_check_valid(tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("invalid vdev or vdev mode"); + status = QDF_STATUS_E_INVAL; + goto fail; + } + + /* Do not wait for ack for probe response */ + if (tx_ctx->frame_info.sub_type == P2P_MGMT_PROBE_RSP && + !(tx_ctx->no_ack)) { + p2p_debug("Force set no ack to 1"); + tx_ctx->no_ack = 1; + } + + if (!tx_ctx->off_chan) { + status = p2p_execute_tx_action_frame(tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("execute tx fail"); + goto fail; + } else + return QDF_STATUS_SUCCESS; + } + + /* For off channel tx case */ + curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); + if (curr_roc_ctx && (curr_roc_ctx->chan == tx_ctx->chan)) { + if (curr_roc_ctx->roc_state == + ROC_STATE_CANCEL_IN_PROG) { + /* wait for roc canceling done */ + rc = qdf_wait_single_event( + &p2p_soc_obj->cancel_roc_done, + msecs_to_jiffies(P2P_WAIT_CANCEL_ROC)); + if (!rc) + p2p_err("Timeout occurred while waiting for RoC cancellation"); + } else { + p2p_adjust_tx_wait(tx_ctx); + status = p2p_restart_roc_timer(curr_roc_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("restart roc timer fail"); + goto fail; + } + status = p2p_execute_tx_action_frame(tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("execute tx fail"); + goto fail; + } else + return QDF_STATUS_SUCCESS; + } + } + + status = p2p_roc_req_for_tx_action(tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to request roc before off chan tx"); + goto fail; + } + return QDF_STATUS_SUCCESS; + +fail: + p2p_send_tx_conf(tx_ctx, false); + qdf_mem_free(tx_ctx->buf); + qdf_mem_free(tx_ctx); + + return status; } QDF_STATUS p2p_process_mgmt_tx_cancel( struct cancel_roc_context *cancel_tx) { + bool is_roc_q = false; + bool is_ack_q = false; + struct tx_action_context *cur_tx_ctx; + struct cancel_roc_context cancel_roc; + + p2p_debug("cookie:0x%llx", cancel_tx->cookie); + + cur_tx_ctx = p2p_find_tx_ctx(cancel_tx->p2p_soc_obj, + cancel_tx->cookie, &is_roc_q, &is_ack_q); + if (cur_tx_ctx) { + if (is_roc_q) { + cancel_roc.p2p_soc_obj = + cancel_tx->p2p_soc_obj; + cancel_roc.cookie = + cur_tx_ctx->roc_cookie; + return p2p_process_cancel_roc_req(&cancel_roc); + } + if (is_ack_q) { + /*Has tx action frame, waiting for ack*/ + p2p_debug("Waiting for ack, cookie %llx", + cancel_tx->cookie); + } + } else { + p2p_err("Failed to find tx ctx by cookie, cookie %llx", + cancel_tx->cookie); + return QDF_STATUS_E_INVAL; + } + return QDF_STATUS_SUCCESS; } QDF_STATUS p2p_process_mgmt_tx_ack_cnf( struct p2p_tx_conf_event *tx_cnf_event) { + struct p2p_tx_cnf *tx_cnf; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_start_param *start_param; + + p2p_soc_obj = tx_cnf_event->p2p_soc_obj; + tx_cnf = tx_cnf_event->tx_cnf; + + if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) { + p2p_err("Invalid p2p soc object or start parameters"); + qdf_mem_free(tx_cnf); + return QDF_STATUS_E_INVAL; + } + + p2p_debug("soc:%p, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%p", + p2p_soc_obj->soc, tx_cnf->vdev_id, + tx_cnf->action_cookie, tx_cnf->buf_len, + tx_cnf->status, tx_cnf->buf); + + /* disable tx timer */ + p2p_disable_tx_timer(tx_cnf_event->tx_ctx); + + start_param = p2p_soc_obj->start_param; + if (start_param->tx_cnf_cb) + start_param->tx_cnf_cb(start_param->tx_cnf_cb_data, + tx_cnf); + else + p2p_debug("Got tx conf, but no valid up layer callback"); + + p2p_remove_tx_context(tx_cnf_event->tx_ctx); + qdf_mem_free(tx_cnf); + return QDF_STATUS_SUCCESS; } QDF_STATUS p2p_process_rx_mgmt( struct p2p_rx_mgmt_event *rx_mgmt_event) { + struct p2p_rx_mgmt_frame *rx_mgmt; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct p2p_start_param *start_param; + + p2p_soc_obj = rx_mgmt_event->p2p_soc_obj; + rx_mgmt = rx_mgmt_event->rx_mgmt; + + if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) { + p2p_err("Invalid psoc object or start parameters"); + qdf_mem_free(rx_mgmt); + return QDF_STATUS_E_INVAL; + } + + p2p_debug("soc:%p, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%p", + p2p_soc_obj->soc, rx_mgmt->frame_len, + rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, + rx_mgmt->rx_rssi, rx_mgmt->buf); + + start_param = p2p_soc_obj->start_param; + if (start_param->rx_cb) + start_param->rx_cb(start_param->rx_cb_data, rx_mgmt); + else + p2p_debug("rx mgmt, but no valid up layer callback"); + + qdf_mem_free(rx_mgmt); + return QDF_STATUS_SUCCESS; } diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index 6b5af43007cd..ea7cf4966dc1 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -26,18 +26,122 @@ #include #include +#define P2P_EID_VENDOR 0xdd +#define P2P_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7F +#define P2P_PUBLIC_ACTION_FRAME 0x4 +#define P2P_MAC_MGMT_ACTION 0xD +#define P2P_PUBLIC_ACTION_VENDOR_SPECIFIC 0x9 +#define P2P_NOA_ATTR 0xC + +#define P2P_MAX_NOA_ATTR_LEN 31 +#define P2P_IE_HEADER_LEN 6 +#define P2P_MAX_IE_LENGTH 255 +#define P2P_ACTION_OFFSET 24 +#define P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET 30 +#define P2P_ACTION_FRAME_TYPE_OFFSET 29 +#define PROBE_RSP_IE_OFFSET 36 + +#define P2P_TX_PKT_MIN_HEADROOM (64) + +#define P2P_OUI "\x50\x6f\x9a\x09" +#define P2P_OUI_SIZE 4 + +#define P2P_ACTION_FRAME_RSP_WAIT 500 +#define P2P_ACTION_FRAME_ACK_WAIT 300 +#define P2P_ACTION_FRAME_TX_TIMEOUT 2000 + +#define P2P_NOA_STREAM_ARR_SIZE (P2P_MAX_NOA_ATTR_LEN + (2 * P2P_IE_HEADER_LEN)) + +#define P2P_GET_TYPE_FRM_FC(__fc__) (((__fc__) & 0x0F) >> 2) +#define P2P_GET_SUBTYPE_FRM_FC(__fc__) (((__fc__) & 0xF0) >> 4) + struct p2p_soc_priv_obj; struct cancel_roc_context; struct p2p_tx_conf_event; struct p2p_rx_mgmt_event; +/** + * enum p2p_frame_type - frame type + * @P2P_FRAME_MGMT: mgmt frame + * @P2P_FRAME_NOT_SUPPORT: not support frame type + */ +enum p2p_frame_type { + P2P_FRAME_MGMT = 0, + P2P_FRAME_NOT_SUPPORT, +}; + +/** + * enum p2p_frame_sub_type - frame sub type + * @P2P_MGMT_PROBE_REQ: probe request frame + * @P2P_MGMT_PROBE_RSP: probe response frame + * @P2P_MGMT_ACTION: action frame + * @P2P_MGMT_NOT_SUPPORT: not support sub frame type + */ +enum p2p_frame_sub_type { + P2P_MGMT_PROBE_REQ = 4, + P2P_MGMT_PROBE_RSP, + P2P_MGMT_ACTION = 13, + P2P_MGMT_NOT_SUPPORT, +}; + +/** + * enum p2p_public_action_type - public action frame type + * @P2P_PUBLIC_ACTION_NEG_REQ: go negotiation request frame + * @P2P_PUBLIC_ACTION_NEG_RSP: go negotiation response frame + * @P2P_PUBLIC_ACTION_NEG_CNF: go negotiation confirm frame + * @P2P_PUBLIC_ACTION_INVIT_REQ: p2p invitation request frame + * @P2P_PUBLIC_ACTION_INVIT_RSP: p2p invitation response frame + * @P2P_PUBLIC_ACTION_DEV_DIS_REQ: device discoverability request + * @P2P_PUBLIC_ACTION_DEV_DIS_RSP: device discoverability response + * @P2P_PUBLIC_ACTION_PROV_DIS_REQ: provision discovery request + * @P2P_PUBLIC_ACTION_PROV_DIS_RSP: provision discovery response + * @P2P_PUBLIC_ACTION_GAS_INIT_REQ: gas initial request, + * @P2P_PUBLIC_ACTION_GAS_INIT_RSP: gas initial response + * @P2P_PUBLIC_ACTION_GAS_COMB_REQ: gas comeback request + * @P2P_PUBLIC_ACTION_GAS_COMB_RSP: gas comeback response + * @P2P_PUBLIC_ACTION_NOT_SUPPORT: not support p2p public action frame + */ +enum p2p_public_action_type { + P2P_PUBLIC_ACTION_NEG_REQ = 0, + P2P_PUBLIC_ACTION_NEG_RSP, + P2P_PUBLIC_ACTION_NEG_CNF, + P2P_PUBLIC_ACTION_INVIT_REQ, + P2P_PUBLIC_ACTION_INVIT_RSP, + P2P_PUBLIC_ACTION_DEV_DIS_REQ, + P2P_PUBLIC_ACTION_DEV_DIS_RSP, + P2P_PUBLIC_ACTION_PROV_DIS_REQ, + P2P_PUBLIC_ACTION_PROV_DIS_RSP, + P2P_PUBLIC_ACTION_GAS_INIT_REQ = 10, + P2P_PUBLIC_ACTION_GAS_INIT_RSP, + P2P_PUBLIC_ACTION_GAS_COMB_REQ, + P2P_PUBLIC_ACTION_GAS_COMB_RSP, + P2P_PUBLIC_ACTION_NOT_SUPPORT, +}; + +/** + * enum p2p_action_type - p2p action frame type + * @P2P_ACTION_PRESENCE_RSP: presence response frame + * @P2P_ACTION_NOT_SUPPORT: not support action frame type + */ +enum p2p_action_type { + P2P_ACTION_PRESENCE_RSP = 2, + P2P_ACTION_NOT_SUPPORT, +}; + +struct p2p_frame_info { + enum p2p_frame_type type; + enum p2p_frame_sub_type sub_type; + enum p2p_public_action_type public_action_type; + enum p2p_action_type action_type; +}; + /** * struct tx_action_context - tx action frame context * @node: Node for next element in the list * @p2p_soc_obj: Pointer to SoC global p2p private object * @vdev_id: Vdev id on which this request has come * @scan_id: Scan id given by scan component for this roc req - * @action_cookie: Action cookie + * @roc_cookie: Cookie for remain on channel request * @chan: Chan for which this tx has been requested * @buf: tx buffer * @buf_len: Length of tx buffer @@ -46,13 +150,14 @@ struct p2p_rx_mgmt_event; * @no_ack: Required ack or not * @duration: Duration for the RoC * @tx_timer: RoC timer + * @frame_info: Frame type information */ struct tx_action_context { qdf_list_node_t node; struct p2p_soc_priv_obj *p2p_soc_obj; int vdev_id; int scan_id; - uint64_t action_cookie; + uint64_t roc_cookie; uint8_t chan; uint8_t *buf; int buf_len; @@ -61,8 +166,43 @@ struct tx_action_context { bool no_ack; uint32_t duration; qdf_mc_timer_t tx_timer; + struct p2p_frame_info frame_info; }; +/** + * p2p_dump_tx_queue() - dump tx queue + * @p2p_soc_obj: p2p soc private object + * + * This function dumps tx queue and output details about tx context in + * queue. + * + * Return: None + */ +void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj); + +/** + * p2p_ready_to_tx_frame() - dump tx queue + * @p2p_soc_obj: p2p soc private object + * @cookie: cookie is pointer to roc + * + * This function find out the tx context in wait for roc queue and tx + * this frame. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj, + uint64_t cookie); + +/** + * p2p_cleanup_tx_queue() - cleanup tx queue + * @p2p_soc_obj: p2p soc private object + * + * This function cleanup wait for roc queue and wait for ack queue. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj); + /** * p2p_process_mgmt_tx() - Process mgmt frame tx request * @tx_ctx: tx context @@ -90,7 +230,7 @@ QDF_STATUS p2p_process_mgmt_tx_cancel( * @tx_cnf_event: tx confirmation event information * * This function mgmt frame tx confirmation. It will deliver this - * event to HDD + * event to up layer * * Return: QDF_STATUS_SUCCESS - in case of success */ @@ -102,7 +242,7 @@ QDF_STATUS p2p_process_mgmt_tx_ack_cnf( * @rx_mgmt_event: rx mgmt frame event information * * This function mgmt frame rx mgmt frame event. It will deliver this - * event to HDD + * event to up layer * * Return: QDF_STATUS_SUCCESS - in case of success */ diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index fd588ebd5787..9c32eb61172e 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -419,6 +419,7 @@ static QDF_STATUS p2p_process_ready_on_channel_evt( p2p_debug("roc for off chan tx, ready to send frame"); cookie = (uintptr_t)roc_ctx; /* ready to tx frame */ + p2p_ready_to_tx_frame(p2p_soc_obj, cookie); } return status; diff --git a/dispatcher/inc/wlan_p2p_public_struct.h b/dispatcher/inc/wlan_p2p_public_struct.h index c17d5a940156..febd25f75f24 100644 --- a/dispatcher/inc/wlan_p2p_public_struct.h +++ b/dispatcher/inc/wlan_p2p_public_struct.h @@ -111,6 +111,7 @@ struct p2p_tx_cnf { * @len: Length of tx buffer * @no_cck: Required cck or not * @dont_wait_for_ack: Wait for ack or not + * @off_chan: Off channel tx or not * @buf: TX buffer */ struct p2p_mgmt_tx { @@ -120,6 +121,7 @@ struct p2p_mgmt_tx { uint32_t len; uint32_t no_cck; uint32_t dont_wait_for_ack; + uint32_t off_chan; const uint8_t *buf; }; diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index d07c56c973e8..96fcf15bbf34 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -23,10 +23,19 @@ #include #include #include +#include +#include +#include +#include +#include #include "wlan_p2p_tgt_api.h" #include "wlan_p2p_public_struct.h" #include "../../core/src/wlan_p2p_main.h" #include "../../core/src/wlan_p2p_roc.h" +#include "../../core/src/wlan_p2p_off_chan_tx.h" + +#define IEEE80211_FC0_TYPE_MASK 0x0c +#define P2P_NOISE_FLOOR_DBM_DEFAULT (-96) static inline struct wlan_lmac_if_p2p_tx_ops * wlan_psoc_get_p2p_tx_ops(struct wlan_objmgr_psoc *psoc) @@ -103,12 +112,59 @@ void tgt_p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, QDF_STATUS tgt_p2p_mgmt_download_comp_cb(void *context, qdf_nbuf_t buf, bool free) { + p2p_debug("conext:%p, buf:%p, free:%d", context, + qdf_nbuf_data(buf), free); + + qdf_nbuf_free(buf); + return QDF_STATUS_SUCCESS; } QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, uint32_t status, void *tx_compl_params) { + struct p2p_tx_cnf *tx_cnf; + struct p2p_tx_conf_event *tx_conf_event; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct tx_action_context *tx_ctx; + struct scheduler_msg msg; + + p2p_debug("context:%p, buf:%p, status:%d, tx complete params:%p", + context, buf, status, tx_compl_params); + + if (!context) { + p2p_err("invalid context"); + return QDF_STATUS_E_INVAL; + } + tx_ctx = (struct tx_action_context *)context; + p2p_soc_obj = tx_ctx->p2p_soc_obj; + + tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event)); + if (tx_conf_event == NULL) { + p2p_err("Failed to allocate tx cnf event"); + return QDF_STATUS_E_NOMEM; + } + + tx_cnf = qdf_mem_malloc(sizeof(*tx_cnf)); + if (tx_cnf == NULL) { + p2p_err("Failed to allocate tx cnf"); + return QDF_STATUS_E_NOMEM; + } + + qdf_nbuf_free(buf); + tx_cnf->vdev_id = tx_ctx->vdev_id; + tx_cnf->action_cookie = (uintptr_t)tx_ctx; + tx_cnf->buf = tx_ctx->buf; + tx_cnf->buf_len = tx_ctx->buf_len; + tx_cnf->status = status; + tx_conf_event->p2p_soc_obj = p2p_soc_obj; + tx_conf_event->tx_cnf = tx_cnf; + tx_conf_event->tx_ctx = tx_ctx; + msg.type = P2P_EVENT_MGMT_TX_ACK_CNF; + msg.bodyptr = tx_conf_event; + msg.callback = p2p_process_evt; + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + return QDF_STATUS_SUCCESS; } @@ -117,6 +173,83 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, struct mgmt_rx_event_params *mgmt_rx_params, enum mgmt_frame_type frm_type) { + struct p2p_rx_mgmt_frame *rx_mgmt; + struct p2p_rx_mgmt_event *rx_mgmt_event; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct scheduler_msg msg; + struct wlan_frame_hdr *wh; + struct wlan_objmgr_vdev *vdev; + struct p2p_roc_context *roc_ctx; + uint32_t vdev_id; + uint8_t *pdata; + + p2p_debug("psoc:%p, peer:%p, type:%d", psoc, peer, frm_type); + + if (!mgmt_rx_params) { + p2p_err("mgmt rx params is NULL"); + qdf_nbuf_free(buf); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_P2P); + if (p2p_soc_obj == NULL) { + p2p_err("p2p ctx is NULL, drop this frame"); + return QDF_STATUS_E_FAILURE; + } + + if (peer == NULL) { + roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); + if (roc_ctx == NULL) { + p2p_err("current roc ctx is null, can't get vdev id"); + return QDF_STATUS_E_FAILURE; + } else { + vdev_id = roc_ctx->vdev_id; + } + } else { + wlan_peer_obj_lock(peer); + vdev = wlan_peer_get_vdev(peer); + wlan_peer_obj_unlock(peer); + if (vdev == NULL) { + p2p_err("vdev is NULL in peer, drop this frame"); + return QDF_STATUS_E_FAILURE; + } + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + } + + rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event)); + if (rx_mgmt_event == NULL) { + p2p_err("Failed to allocate rx mgmt event"); + return QDF_STATUS_E_NOMEM; + } + + rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) + + mgmt_rx_params->buf_len); + if (rx_mgmt == NULL) { + p2p_err("Failed to allocate rx mgmt frame"); + return QDF_STATUS_E_NOMEM; + } + + wh = (struct wlan_frame_hdr *)qdf_nbuf_data(buf); + pdata = (uint8_t *)qdf_nbuf_data(buf); + rx_mgmt->frame_len = mgmt_rx_params->buf_len; + rx_mgmt->rx_chan = mgmt_rx_params->channel; + rx_mgmt->vdev_id = vdev_id; + rx_mgmt->frm_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + rx_mgmt->rx_rssi = mgmt_rx_params->snr + + P2P_NOISE_FLOOR_DBM_DEFAULT; + rx_mgmt_event->rx_mgmt = rx_mgmt; + rx_mgmt_event->p2p_soc_obj = p2p_soc_obj; + qdf_mem_copy(rx_mgmt->buf, pdata, mgmt_rx_params->buf_len); + msg.type = P2P_EVENT_RX_MGMT; + msg.bodyptr = rx_mgmt_event; + msg.callback = p2p_process_evt; + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + + qdf_nbuf_free(buf); + return QDF_STATUS_SUCCESS; } diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 88b57ce7cc93..cc742fc2d39f 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -27,6 +27,7 @@ #include "wlan_p2p_public_struct.h" #include "../../core/src/wlan_p2p_main.h" #include "../../core/src/wlan_p2p_roc.h" +#include "../../core/src/wlan_p2p_off_chan_tx.h" static inline struct wlan_lmac_if_p2p_tx_ops * ucfg_p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc) @@ -150,12 +151,96 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, struct p2p_mgmt_tx *mgmt_frm, uint64_t *cookie) { + struct scheduler_msg msg; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct tx_action_context *tx_action; + + p2p_debug("soc:%p, vdev_id:%d, chan:%d, wait:%d, buf_len:%d, cck:%d, no ack:%d, off chan:%d", + soc, mgmt_frm->vdev_id, mgmt_frm->chan, + mgmt_frm->wait, mgmt_frm->len, mgmt_frm->no_cck, + mgmt_frm->dont_wait_for_ack, mgmt_frm->off_chan); + + if (soc == NULL) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (p2p_soc_obj == NULL) { + p2p_err("P2P soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + tx_action = qdf_mem_malloc(sizeof(*tx_action)); + if (tx_action == NULL) { + p2p_err("Failed to allocate tx action context"); + return QDF_STATUS_E_NOMEM; + } + + /* return cookie just for ota ack frames */ + if (mgmt_frm->dont_wait_for_ack) + *cookie = 0; + else + *cookie = (uintptr_t)tx_action; + + tx_action->p2p_soc_obj = p2p_soc_obj; + tx_action->vdev_id = mgmt_frm->vdev_id; + tx_action->chan = mgmt_frm->chan; + tx_action->duration = mgmt_frm->wait; + tx_action->buf_len = mgmt_frm->len; + tx_action->no_cck = mgmt_frm->no_cck; + tx_action->no_ack = mgmt_frm->dont_wait_for_ack; + tx_action->off_chan = mgmt_frm->off_chan; + tx_action->buf = qdf_mem_malloc(tx_action->buf_len); + if (tx_action->buf == NULL) { + p2p_err("Failed to allocate buffer for action frame"); + qdf_mem_free(tx_action); + return QDF_STATUS_E_NOMEM; + } + qdf_mem_copy(tx_action->buf, mgmt_frm->buf, tx_action->buf_len); + msg.type = P2P_MGMT_TX; + msg.bodyptr = tx_action; + msg.callback = p2p_process_cmd; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + return QDF_STATUS_SUCCESS; } QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, uint64_t cookie) { + struct scheduler_msg msg; + struct p2p_soc_priv_obj *p2p_soc_obj; + struct cancel_roc_context *cancel_tx; + + p2p_debug("soc:%p, cookie:0x%llx", soc, cookie); + + if (soc == NULL) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (p2p_soc_obj == NULL) { + p2p_err("p2p soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx)); + if (cancel_tx == NULL) { + p2p_err("Failed to allocate cancel p2p roc"); + return QDF_STATUS_E_NOMEM; + } + + cancel_tx->p2p_soc_obj = p2p_soc_obj; + cancel_tx->cookie = cookie; + msg.type = P2P_MGMT_TX_CANCEL; + msg.bodyptr = cancel_tx; + msg.callback = p2p_process_cmd; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + return QDF_STATUS_SUCCESS; } From 2761077ad549c57aa20d26fc86b543dfe57ec707 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 22 Mar 2017 13:18:15 +0800 Subject: [PATCH 027/404] qcacmn: mgmt frame txrx Modify P2P IE and tx mgmt frame. Handles tx confirm and rx frame events. Change-Id: I0c0ada2e12ee5ebdd3e8d7b7a6f2bd2af4357548 CRs-Fixed: 2015297 --- src/wlan_cfg80211_p2p.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 8058a97f1bf5..853513955ab5 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -127,6 +127,7 @@ static void wlan_p2p_action_tx_cnf_callback(void *user_data, struct wlan_objmgr_vdev *vdev; struct vdev_osif_priv *osif_priv; struct wireless_dev *wdev; + bool is_success; cfg80211_info("user data:%p, action cookie:%llx, buf:%p, len:%d, tx status:%d", user_data, tx_cnf->action_cookie, tx_cnf->buf, @@ -159,11 +160,12 @@ static void wlan_p2p_action_tx_cnf_callback(void *user_data, goto fail; } + is_success = tx_cnf->status ? false : true; cfg80211_mgmt_tx_status( wdev, tx_cnf->action_cookie, tx_cnf->buf, tx_cnf->buf_len, - (bool)tx_cnf->status, GFP_KERNEL); + is_success, GFP_KERNEL); fail: wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); } @@ -360,7 +362,7 @@ int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, wlan_vdev_obj_unlock(vdev); if (!psoc) { cfg80211_err("psoc handle is NULL"); - return QDF_STATUS_E_INVAL; + return -EINVAL; } roc_req.chan = (uint32_t)wlan_freq_to_chan(chan->center_freq); @@ -386,7 +388,7 @@ int wlan_cfg80211_cancel_roc(struct wlan_objmgr_vdev *vdev, wlan_vdev_obj_unlock(vdev); if (!psoc) { cfg80211_err("psoc handle is NULL"); - return QDF_STATUS_E_INVAL; + return -EINVAL; } return qdf_status_to_os_return( @@ -419,7 +421,7 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, wlan_vdev_obj_unlock(vdev); if (!psoc) { cfg80211_err("psoc handle is NULL"); - return QDF_STATUS_E_INVAL; + return -EINVAL; } mgmt_tx.vdev_id = (uint32_t)vdev_id; @@ -428,6 +430,7 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, mgmt_tx.len = len; mgmt_tx.no_cck = (uint32_t)no_cck; mgmt_tx.dont_wait_for_ack = (uint32_t)dont_wait_for_ack; + mgmt_tx.off_chan = (uint32_t)offchan; mgmt_tx.buf = buf; return qdf_status_to_os_return( @@ -449,7 +452,7 @@ int wlan_cfg80211_mgmt_tx_cancel(struct wlan_objmgr_vdev *vdev, wlan_vdev_obj_unlock(vdev); if (!psoc) { cfg80211_err("psoc handle is NULL"); - return QDF_STATUS_E_INVAL; + return -EINVAL; } return qdf_status_to_os_return( From 31675f53b882cd99dd526921cf75a08315ff6429 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 13 Mar 2017 20:17:34 +0800 Subject: [PATCH 028/404] qcacmn: WMI changes for P2P component Update WMI layer to adopt to converged P2P component. Change-Id: Ia031476f7ee6071d2e15010fc3f7c998df9995dd CRs-Fixed: 2011217 --- src/target_if_p2p.c | 120 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 96 insertions(+), 24 deletions(-) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index 9df8498ec270..dee2c8c0eca8 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -33,9 +33,9 @@ target_if_psoc_get_p2p_rx_ops(struct wlan_objmgr_psoc *psoc) /** * target_p2p_lo_event_handler() - WMI callback for lo stop event - * @scn: + * @scn: pointer to scn * @event_buf: event buffer - * @len: buffer length + * @len: buffer length * * This function gets called from WMI when triggered wmi event * wmi_p2p_lo_stop_event_id. @@ -52,7 +52,7 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; - target_if_info("scn:%p, data:%p, datalen:%d", scn, data, datalen); + target_if_debug("scn:%p, data:%p, datalen:%d", scn, data, datalen); if (!scn || !data) { target_if_err("scn: 0x%p, data: 0x%p", scn, data); @@ -77,7 +77,12 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, return -ENOMEM; } - /*TODO, extract wmi lo stop event */ + if (wmi_extract_p2p_lo_stop_ev_param(wmi_handle, data, + event_info)) { + target_if_err("Failed to extract wmi p2p lo stop event"); + qdf_mem_free(event_info); + return -EINVAL; + } p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc); if (p2p_rx_ops->lo_ev_handler) { @@ -91,9 +96,9 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, /** * target_p2p_noa_event_handler() - WMI callback for noa event - * @scn: + * @scn: pointer to scn * @event_buf: event buffer - * @len: buffer length + * @len: buffer length * * This function gets called from WMI when triggered WMI event * wmi_p2p_noa_event_id. @@ -110,7 +115,7 @@ static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; - target_if_info("scn:%p, data:%p, datalen:%d", scn, data, datalen); + target_if_debug("scn:%p, data:%p, datalen:%d", scn, data, datalen); if (!scn || !data) { target_if_err("scn: 0x%p, data: 0x%p", scn, data); @@ -131,11 +136,16 @@ static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, event_info = qdf_mem_malloc(sizeof(*event_info)); if (!event_info) { - target_if_err("Failed to allocate p2p noa information"); + target_if_err("failed to allocate p2p noa information"); return -ENOMEM; } - /*TODO, extract wmi noa event */ + if (wmi_extract_p2p_noa_ev_param(wmi_handle, data, + event_info)) { + target_if_err("failed to extract wmi p2p noa event"); + qdf_mem_free(event_info); + return -EINVAL; + } p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc); if (p2p_rx_ops->noa_ev_handler) { @@ -153,7 +163,7 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( int status; wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); - target_if_info("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%p, arg:%p", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -161,10 +171,11 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( } status = wmi_unified_register_event_handler(wmi_handle, - wmi_p2p_lo_stop_event_id, target_p2p_lo_event_handler, + WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID, + target_p2p_lo_event_handler, WMI_RX_UMAC_CTX); - target_if_info("wmi register lo event handle, status:%d", + target_if_debug("wmi register lo event handle, status:%d", status); return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; @@ -176,7 +187,7 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( int status; wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); - target_if_info("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%p, arg:%p", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -184,10 +195,10 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( } status = wmi_unified_register_event_handler(wmi_handle, - wmi_p2p_noa_event_id, target_p2p_noa_event_handler, + WMI_P2P_NOA_EVENTID, target_p2p_noa_event_handler, WMI_RX_UMAC_CTX); - target_if_info("wmi register noa event handle, status:%d", + target_if_debug("wmi register noa event handle, status:%d", status); return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; @@ -199,7 +210,7 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( int status; wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); - target_if_info("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%p, arg:%p", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -207,9 +218,9 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( } status = wmi_unified_unregister_event_handler(wmi_handle, - wmi_p2p_lo_stop_event_id); + WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID); - target_if_info("wmi unregister lo event handle, status:%d", + target_if_debug("wmi unregister lo event handle, status:%d", status); return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; @@ -221,7 +232,7 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( int status; wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); - target_if_info("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%p, arg:%p", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -229,9 +240,9 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( } status = wmi_unified_unregister_event_handler(wmi_handle, - wmi_p2p_noa_event_id); + WMI_P2P_NOA_EVENTID); - target_if_info("wmi unregister noa event handle, status:%d", + target_if_debug("wmi unregister noa event handle, status:%d", status); return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; @@ -240,19 +251,80 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, struct p2p_ps_config *ps_config) { - return QDF_STATUS_SUCCESS; + struct p2p_ps_params cmd; + QDF_STATUS status; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_debug("psoc:%p, vdev_id:%d, opp_ps:%d", psoc, + ps_config->vdev_id, ps_config->opp_ps); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + if (!ps_config) { + target_if_err("ps config parameters is null"); + return QDF_STATUS_E_INVAL; + } + + cmd.opp_ps = ps_config->opp_ps; + cmd.ctwindow = ps_config->ct_window; + cmd.count = ps_config->count; + cmd.duration = ps_config->duration; + cmd.interval = ps_config->interval; + cmd.single_noa_duration = ps_config->single_noa_duration; + cmd.ps_selection = ps_config->ps_selection; + cmd.session_id = ps_config->vdev_id; + + if (ps_config->opp_ps) + status = wmi_unified_set_p2pgo_oppps_req(wmi_handle, + &cmd); + else + status = wmi_unified_set_p2pgo_noa_req_cmd(wmi_handle, + &cmd); + + if (status != QDF_STATUS_SUCCESS) + target_if_err("Failed to send set uapsd param, %d", + status); + + return status; } QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, struct p2p_lo_start *lo_start) { - return QDF_STATUS_SUCCESS; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_debug("psoc:%p, vdev_id:%d", psoc, lo_start->vdev_id); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + if (!lo_start) { + target_if_err("lo start parameters is null"); + return QDF_STATUS_E_INVAL; + } + + return wmi_unified_p2p_lo_start_cmd(wmi_handle, lo_start); } QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { - return QDF_STATUS_SUCCESS; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + target_if_debug("psoc:%p, vdev_id:%d", psoc, vdev_id); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + return wmi_unified_p2p_lo_stop_cmd(wmi_handle, + (uint8_t)vdev_id); } void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) From 3d9b5cf89dd8509f9ca51fc9a8b6baf37ca5e0ab Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Fri, 10 Mar 2017 18:56:44 -0800 Subject: [PATCH 029/404] qcacmn: Save user configurations in policy manager component Update policy manager user configuration with INI parameters. Change-Id: I2e13bec2a1e99c9aee9e66d3e90a1275cf87ccfa CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 14 ++++++++++++ inc/wlan_policy_mgr_public_struct.h | 7 ++++++ src/wlan_policy_mgr_core.c | 15 ------------- src/wlan_policy_mgr_get_set_utils.c | 34 ++++++++++++++++++++++++++++- src/wlan_policy_mgr_i.h | 13 +---------- 5 files changed, 55 insertions(+), 28 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index b2aaa3d0ff97..ffb157a595aa 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1739,4 +1739,18 @@ static inline bool policy_mgr_is_scan_simultaneous_capable( bool policy_mgr_is_mcc_adaptive_scheduler_enabled( struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_set_user_cfg() - Function to set user cfg variables + * required by policy manager component + * @psoc: PSOC object information + * @user_cfg: User config valiables structure pointer + * + * This function sets the user cfg variables required by policy + * manager + * + * Return: SUCCESS or FAILURE + * + */ +QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_user_cfg *user_cfg); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 9bd892f7d186..78a987d4484e 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -972,4 +972,11 @@ struct dual_mac_config { uint32_t req_fw_mode_config; }; +/** + * struct policy_mgr_user_cfg - Policy manager user config variables + * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler + */ +struct policy_mgr_user_cfg { + uint8_t enable_mcc_adaptive_scheduler; +}; #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 1b6c0b9b059e..cc78c181c4c8 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -144,21 +144,6 @@ bool policy_mgr_is_dual_mac_disabled_in_ini( return wlan_objmgr_psoc_get_dual_mac_disable(psoc); } -/** - * policy_mgr_is_mas_enabled_in_user_cfg() - Check if MCC - * adaptive scheduler is enabled in INI - * @psoc: PSOC object information - * - * Checks if MCC adaptive scheduler is enabled in INI - * - * Return: true if MCC adaptive scheduler is enabled in INI - */ -bool policy_mgr_is_mas_enabled_in_user_cfg( - struct wlan_objmgr_psoc *psoc) -{ - return false; -} - uint32_t policy_mgr_mcc_to_scc_switch_mode_in_user_cfg( struct wlan_objmgr_psoc *psoc) { diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 992728ecb412..9bf37e9daa1f 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1224,6 +1224,27 @@ QDF_STATUS policy_mgr_get_channel_from_scan_result( return status; } +QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_user_cfg *user_cfg) +{ + + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + if (NULL == user_cfg) { + policy_mgr_err("Invalid User Config"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->user_cfg = *user_cfg; + + return QDF_STATUS_SUCCESS; +} + uint8_t policy_mgr_search_and_check_for_session_conc( struct wlan_objmgr_psoc *psoc, uint8_t session_id, @@ -1366,9 +1387,20 @@ bool policy_mgr_is_mcc_adaptive_scheduler_enabled( return false; } - return pm_ctx->enable_mcc_adaptive_scheduler ? true : false; + return pm_ctx->user_cfg.enable_mcc_adaptive_scheduler ? + true : false; } +/** + * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval + * @psoc: PSOC object information + * @vdev_id: vdev id + * @dev_mode: device mode + * + * Updates the beacon parameters of the GO in MCC scenario + * + * Return: Success or Failure depending on the overall function behavior + */ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, enum tQDF_ADAPTER_MODE dev_mode) diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 5f65da15d984..44f5b21d07cb 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -257,7 +257,7 @@ struct policy_mgr_psoc_priv_obj { uint8_t conc_system_pref; struct dual_mac_config dual_mac_cfg; uint32_t hw_mode_change_in_progress; - uint8_t enable_mcc_adaptive_scheduler; + struct policy_mgr_user_cfg user_cfg; }; struct policy_mgr_psoc_priv_obj *policy_mgr_get_context( @@ -276,17 +276,6 @@ QDF_STATUS policy_mgr_get_updated_fw_mode_config( bool policy_mgr_is_dual_mac_disabled_in_ini( struct wlan_objmgr_psoc *psoc); -/** - * policy_mgr_is_mas_enabled_in_user_cfg() - Check if MCC - * adaptive scheduler is enabled in INI - * @psoc: PSOC object information - * - * Checks if MCC adaptive scheduler is enabled in INI - * - * Return: true if MCC adaptive scheduler is enabled in INI - */ -bool policy_mgr_is_mas_enabled_in_user_cfg( - struct wlan_objmgr_psoc *psoc); /** * policy_mgr_mcc_to_scc_switch_mode_in_user_cfg() - MCC to SCC * switch mode value in the user config From 631fd9f12b35d986dbd207fee900e4951cbade49 Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Sun, 19 Mar 2017 18:51:30 -0700 Subject: [PATCH 030/404] qcacmn: Policy manager component HDD callback changes Policy manager component HDD callback changes Change-Id: Ib2226a88b27abfff12104c8430245fe384978b9f CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 17 +++++++++-- src/wlan_policy_mgr_action.c | 50 ++++++------------------------- src/wlan_policy_mgr_init_deinit.c | 16 ++++++++++ 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index ffb157a595aa..0181ca240cc3 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -816,9 +816,11 @@ struct policy_mgr_sme_cbacks { * SAP */ struct policy_mgr_hdd_cbacks { - void (*sap_restart_chan_switch_cb)(uint8_t, - uint32_t, uint32_t); + void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint32_t channel, + uint32_t channel_bw); QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)( + struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t *channel, uint8_t *sec_ch, struct ch_params_s *ch_params); @@ -1454,6 +1456,17 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, struct policy_mgr_hdd_cbacks *hdd_cbacks); +/** + * policy_mgr_deregister_hdd_cb() - Deregister HDD callbacks + * @psoc: PSOC object information + * + * API, allows HDD to deregister callbacks + * + * Return: SUCCESS, + * Failure (if de-registration fails) + */ +QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_register_tdls_cb() - register TDLS callbacks * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index b57bef7b163f..f713d36da4c8 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -659,8 +659,13 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) goto work_done; + if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { + policy_mgr_err("SAP restart get channel callback in NULL"); + goto work_done; + } + status = pm_ctx->hdd_cbacks. - wlan_hdd_get_channel_for_sap_restart( + wlan_hdd_get_channel_for_sap_restart(psoc, cc_intf_work->vdev_id, &channel, &sec_ch, &ch_params); if (status != QDF_STATUS_SUCCESS) { @@ -680,7 +685,7 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) if (policy_mgr_is_sap_channel_change_without_restart( mcc_to_scc_switch) && pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { - pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb( + pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc, cc_intf_work->vdev_id, channel, ch_params.ch_width); } @@ -789,8 +794,8 @@ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { policy_mgr_info("SAP change change without restart"); - pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(vdev_id, - channel, ch_width); + pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc, + vdev_id, channel, ch_width); } } #endif @@ -892,43 +897,6 @@ QDF_STATUS policy_mgr_restart_opportunistic_timer( return status; } -#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH -QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( - struct wlan_objmgr_psoc *psoc, - void (*sap_restart_chan_switch_cb)(uint8_t, uint32_t, uint32_t)) -{ - struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; - - policy_mgr_ctx = policy_mgr_get_context(psoc); - if (!policy_mgr_ctx) { - policy_mgr_err("Invalid context"); - return QDF_STATUS_E_FAILURE; - } - - policy_mgr_ctx->hdd_cbacks.sap_restart_chan_switch_cb = - sap_restart_chan_switch_cb; - - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS policy_mgr_deregister_sap_restart_channel_switch_cb( - struct wlan_objmgr_psoc *psoc) -{ - struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; - - policy_mgr_ctx = policy_mgr_get_context(psoc); - if (!policy_mgr_ctx) { - policy_mgr_err("Invalid context"); - return QDF_STATUS_E_FAILURE; - } - - policy_mgr_ctx->hdd_cbacks.sap_restart_chan_switch_cb = NULL; - - return QDF_STATUS_SUCCESS; -} - -#endif - QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( struct wlan_objmgr_psoc *psoc, uint8_t session_id) { diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index ab6dc3a6f408..e81c003f4361 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -436,6 +436,22 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb = NULL; + pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = NULL; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc, struct policy_mgr_wma_cbacks *wma_cbacks) { From 214d7133623da101f9f3e7910dcd61242cbd04b2 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 22 Mar 2017 07:29:53 +0800 Subject: [PATCH 031/404] qcacmn: Add necessary header files Some MCL build environment report that it lack of headers. Add these header files. Change-Id: Ibb4a931840f00119b2abe496d755d1554a715fcd CRs-Fixed: 2022862 --- core/src/wlan_p2p_main.h | 1 + core/src/wlan_p2p_off_chan_tx.h | 1 + core/src/wlan_p2p_roc.h | 1 + dispatcher/inc/wlan_p2p_tgt_api.h | 1 + 4 files changed, 4 insertions(+) diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 7f1ff9539a76..c526bbe92788 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -26,6 +26,7 @@ #include #include #include +#include #define MAX_QUEUE_LENGTH 20 #define P2P_NOA_ATTR_IND 0x1090 diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index ea7cf4966dc1..eb63fc881d46 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -25,6 +25,7 @@ #include #include +#include #define P2P_EID_VENDOR 0xdd #define P2P_ACTION_VENDOR_SPECIFIC_CATEGORY 0x7F diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index 736742748186..cc460a58a1b2 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -25,6 +25,7 @@ #include #include +#include #define P2P_EVENT_PROPOGATE_TIME 10 #define P2P_WAIT_CANCEL_ROC 1000 diff --git a/dispatcher/inc/wlan_p2p_tgt_api.h b/dispatcher/inc/wlan_p2p_tgt_api.h index 5644f263ca1f..9f2b140ab742 100644 --- a/dispatcher/inc/wlan_p2p_tgt_api.h +++ b/dispatcher/inc/wlan_p2p_tgt_api.h @@ -24,6 +24,7 @@ #define _WLAN_P2P_TGT_API_H_ #include +#include struct scan_event; struct wlan_objmgr_psoc; From 6199b64eec2570449f71d694f7dc4e910ccefa3e Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Mon, 20 Mar 2017 13:31:36 -0700 Subject: [PATCH 032/404] qcacmn: Remove legacy dependency from Policy Manager Part 7 Remove legacy dependency from Policy Manager component Part 7 Change-Id: Ied83a92118b8ff2ff1a387a052033aaa97bfbbe0 CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 76 +------------------ src/wlan_policy_mgr_action.c | 110 +++++++++------------------- src/wlan_policy_mgr_get_set_utils.c | 46 ++++++++++++ src/wlan_policy_mgr_i.h | 42 +++++++++++ 4 files changed, 127 insertions(+), 147 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 0181ca240cc3..24b7c46c74a0 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -39,33 +39,6 @@ #include "qdf_status.h" #include "wlan_objmgr_psoc_obj.h" #include "wlan_policy_mgr_public_struct.h" -#include - -enum cds_band_type { - CDS_BAND_ALL = 0, - CDS_BAND_2GHZ = 1, - CDS_BAND_5GHZ = 2 -}; -extern uint32_t cds_chan_to_freq(uint8_t chan); -extern uint8_t cds_freq_to_chan(uint32_t freq); -extern enum cds_band_type cds_chan_to_band(uint32_t chan); - -#define WLAN_REG_IS_24GHZ_CH(ch) CDS_IS_CHANNEL_24GHZ(ch) -#define WLAN_REG_IS_5GHZ_CH(ch) CDS_IS_CHANNEL_5GHZ(ch) -#define WLAN_REG_IS_SAME_BAND_CHANNELS(ch1, ch2) \ - CDS_IS_SAME_BAND_CHANNELS(ch1, ch2) -#define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ - CDS_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) -#define wlan_reg_is_dfs_ch(psoc, ch) CDS_IS_DFS_CH(ch) -#define WLAN_REG_MAX_24GHZ_CH_NUM CDS_MAX_24GHZ_CHANNEL_NUMBER -#define reg_chan_to_freq(chan_num) cds_chan_to_freq(chan_num) -#define reg_freq_to_chan(freq) cds_freq_to_chan(freq) -#define reg_chan_to_band(chan_num) cds_chan_to_band(chan_num) -#define BAND_2G CDS_BAND_2GHZ -#define BAND_5G CDS_BAND_5GHZ -#define BAND_ALL CDS_BAND_ALL -#define wlan_reg_set_channel_params(channel, sec_ch, ch_params) \ - cds_set_channel_params(channel, sec_ch, ch_params) typedef const enum policy_mgr_pcl_type pm_dbs_pcl_second_connection_table_type @@ -186,14 +159,10 @@ QDF_STATUS policy_mgr_handle_conc_multiport( * Return: None */ void policy_mgr_check_concurrent_intf_and_restart_sap( - struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, - uint8_t operation_channel); + struct wlan_objmgr_psoc *psoc); #else static inline void policy_mgr_check_concurrent_intf_and_restart_sap( - struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, - uint8_t operation_channel) + struct wlan_objmgr_psoc *psoc) { } @@ -763,17 +732,6 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, uint8_t next_action, enum policy_mgr_conn_update_reason reason); -/** - * struct check_cc_channel_work - Check concurrent interface - * channel to restart SAP work data - * @wlan_objmgr_psoc: PSOC object data - * @vdev_id: vdev id of sap - */ -struct check_cc_channel_work { - struct wlan_objmgr_psoc *psoc; - uint8_t vdev_id; -}; - /** * struct policy_mgr_sme_cbacks - SME Callbacks to be invoked * from policy manager @@ -822,8 +780,7 @@ struct policy_mgr_hdd_cbacks { QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t *channel, - uint8_t *sec_ch, - struct ch_params_s *ch_params); + uint8_t *sec_ch, bool is_restart_sap); }; @@ -1199,33 +1156,6 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS policy_mgr_set_sap_mandatory_channels(struct wlan_objmgr_psoc *psoc, uint8_t *channels, uint32_t len); -#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH -/** - * policy_mgr_register_sap_restart_channel_switch_cb() - - * Register callback for SAP channel switch without restart - * @psoc: PSOC object information - * @sap_restart_chan_switch_cb: Callback to perform channel switch - * - * Registers callback to perform channel switch without having to actually - * restart the beaconing entity - * - * Return: QDF_STATUS - */ -QDF_STATUS policy_mgr_register_sap_restart_channel_switch_cb( - struct wlan_objmgr_psoc *psoc, - void (*sap_restart_chan_switch_cb)(uint8_t, uint32_t, uint32_t)); - -/** - * policy_mgr_deregister_sap_restart_channel_switch_cb() - - * De-Register callback for SAP channel switch without restart - * @psoc: PSOC object information - * De Registers callback to perform channel switch - * - * Return: QDF_STATUS Enumeration - */ -QDF_STATUS policy_mgr_deregister_sap_restart_channel_switch_cb( - struct wlan_objmgr_psoc *psoc); -#endif /** * policy_mgr_is_any_mode_active_on_band_along_with_session() - diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index f713d36da4c8..76c28363a566 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -630,25 +630,20 @@ static bool policy_mgr_is_sap_channel_change_without_restart( */ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) { - struct check_cc_channel_work *cc_intf_work = - (struct check_cc_channel_work *) data; + struct wlan_objmgr_psoc *psoc = + (struct wlan_objmgr_psoc *) data; struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t mcc_to_scc_switch; - struct wlan_objmgr_psoc *psoc; QDF_STATUS status; uint8_t channel, sec_ch; - struct ch_params_s ch_params; + uint8_t operating_channel, vdev_id; + bool restart_sap; - if (!cc_intf_work) { - policy_mgr_err("Invalid check channel interface work"); - goto work_done; - } - psoc = cc_intf_work->psoc; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid context"); - goto work_done; + return; } mcc_to_scc_switch = policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); @@ -657,67 +652,32 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) policy_mgr_concurrent_open_sessions_running(psoc)); if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) - goto work_done; + return; + + if (!policy_mgr_get_sap_conn_info(psoc, + &operating_channel, + &vdev_id)) { + policy_mgr_err("Could not retrieve SAP channel & vdev id"); + return; + } + + restart_sap = policy_mgr_is_sap_channel_change_without_restart( + mcc_to_scc_switch) ? false : true; if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { policy_mgr_err("SAP restart get channel callback in NULL"); - goto work_done; + return; } - status = pm_ctx->hdd_cbacks. - wlan_hdd_get_channel_for_sap_restart(psoc, - cc_intf_work->vdev_id, &channel, - &sec_ch, &ch_params); + wlan_hdd_get_channel_for_sap_restart(psoc, vdev_id, + &channel, &sec_ch, restart_sap); if (status != QDF_STATUS_SUCCESS) { - policy_mgr_err("Failed to get channel to restart SAP"); - goto work_done; + policy_mgr_err("Failed to switch SAP channel"); + return; } - if (channel == 0) { - policy_mgr_err("Invalid channel to restart SAP"); - goto work_done; - } - policy_mgr_info("SAP restarts due to MCC->SCC switch, new chan: %d", - channel); - - wlan_reg_set_channel_params(channel, sec_ch, &ch_params); - - if (policy_mgr_is_sap_channel_change_without_restart( - mcc_to_scc_switch) && - pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { - pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc, - cc_intf_work->vdev_id, channel, - ch_params.ch_width); - } - -work_done: - qdf_mem_free(cc_intf_work); - -} - -/** - * create_check_cc_channel_work() - Create Check concurrent intf - * channel work - * @psoc: PSOC object information - * - * Create check concurrent interface channel work - * - * Return: check concurrent channel interface work object - */ -static struct check_cc_channel_work *create_check_cc_channel_work( - struct wlan_objmgr_psoc *psoc, uint8_t vdev_id) -{ - struct check_cc_channel_work *cc_intf_work; - - cc_intf_work = qdf_mem_malloc( - sizeof(struct check_cc_channel_work)); - if (NULL == cc_intf_work) { - policy_mgr_err("Falied to allocate check concurrent channel work"); - return NULL; - } - cc_intf_work->psoc = psoc; - cc_intf_work->vdev_id = vdev_id; - return cc_intf_work; + policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d", + operating_channel, channel); } /** @@ -732,13 +692,11 @@ static struct check_cc_channel_work *create_check_cc_channel_work( * Return: None */ void policy_mgr_check_concurrent_intf_and_restart_sap( - struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, - uint8_t operation_channel) + struct wlan_objmgr_psoc *psoc) { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t mcc_to_scc_switch; - struct check_cc_channel_work *cc_intf_work; + uint8_t operating_channel, vdev_id; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -746,22 +704,26 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( return; } + if (!policy_mgr_get_sap_conn_info(psoc, + &operating_channel, + &vdev_id)) { + policy_mgr_err("Could not retrieve SAP channel & vdev id"); + return; + } + mcc_to_scc_switch = policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); policy_mgr_info("MCC to SCC switch: %d chan: %d", - mcc_to_scc_switch, operation_channel); + mcc_to_scc_switch, operating_channel); if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE && !wlan_reg_is_dfs_ch(psoc, - operationChannel) + operating_channel) #endif ) { - cc_intf_work = create_check_cc_channel_work(psoc, vdev_id); - if (!cc_intf_work) - return; qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work, - policy_mgr_check_sta_ap_concurrent_ch_intf, - cc_intf_work); + policy_mgr_check_sta_ap_concurrent_ch_intf, + psoc); qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work); policy_mgr_info("Checking for Concurrent Change interference"); } diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 9bf37e9daa1f..4bb51fad3f02 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -929,6 +929,52 @@ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, return status; } +bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, + uint8_t *channel, uint8_t *vdev_id) +{ + uint32_t count, index = 0; + uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + bool status = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + if (NULL == channel || NULL == vdev_id) { + policy_mgr_err("Null pointer error"); + return false; + } + + count = policy_mgr_mode_specific_connection_count( + psoc, PM_SAP_MODE, list); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + if (count == 0) { + policy_mgr_err("No SAP connection"); + status = false; + } else if (count == 1) { + *channel = pm_conc_connection_list[list[index]].chan; + *vdev_id = + pm_conc_connection_list[list[index]].vdev_id; + status = true; + } else { + /* + * Todo Currently the first SAP connection info is + * returned. Modify this to accommodate SAP+SAP+STA + * and SAP+SAP+P2P + */ + *channel = pm_conc_connection_list[list[index]].chan; + *vdev_id = + pm_conc_connection_list[list[index]].vdev_id; + policy_mgr_notice("Multiple SAP connections, picking first one"); + status = true; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return status; +} + bool policy_mgr_max_concurrent_connections_reached( struct wlan_objmgr_psoc *psoc) { diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 44f5b21d07cb..6e9d400bbac5 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -34,6 +34,34 @@ #include "qdf_lock.h" #include "qdf_defer.h" +#include + +enum cds_band_type { + CDS_BAND_ALL = 0, + CDS_BAND_2GHZ = 1, + CDS_BAND_5GHZ = 2 +}; + +extern uint32_t cds_chan_to_freq(uint8_t chan); +extern uint8_t cds_freq_to_chan(uint32_t freq); +extern enum cds_band_type cds_chan_to_band(uint32_t chan); + +#define WLAN_REG_IS_24GHZ_CH(ch) CDS_IS_CHANNEL_24GHZ(ch) +#define WLAN_REG_IS_5GHZ_CH(ch) CDS_IS_CHANNEL_5GHZ(ch) +#define WLAN_REG_IS_SAME_BAND_CHANNELS(ch1, ch2) \ + CDS_IS_SAME_BAND_CHANNELS(ch1, ch2) +#define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ + CDS_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) +#define wlan_reg_is_dfs_ch(psoc, ch) CDS_IS_DFS_CH(ch) +#define WLAN_REG_MAX_24GHZ_CH_NUM CDS_MAX_24GHZ_CHANNEL_NUMBER +#define reg_chan_to_freq(chan_num) cds_chan_to_freq(chan_num) +#define reg_freq_to_chan(freq) cds_freq_to_chan(freq) +#define reg_chan_to_band(chan_num) cds_chan_to_band(chan_num) +#define BAND_2G CDS_BAND_2GHZ +#define BAND_5G CDS_BAND_5GHZ +#define BAND_ALL CDS_BAND_ALL + + #define MAX_NUMBER_OF_CONC_CONNECTIONS 3 #define DBS_OPPORTUNISTIC_TIME 10 #ifdef QCA_WIFI_3_0_EMU @@ -381,4 +409,18 @@ enum policy_mgr_conc_next_action struct wlan_objmgr_psoc *psoc); QDF_STATUS policy_mgr_reset_sap_mandatory_channels( struct policy_mgr_psoc_priv_obj *pm_ctx); + +/** + * policy_mgr_get_sap_conn_info() - Get active SAP channel and + * vdev id + * @psoc: PSOC object information + * @channel: SAP channel + * @vdev_id: SAP vdev id + * + * Get active SAP channel and vdev id + * + * Return: true for success, else false + */ +bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, + uint8_t *channel, uint8_t *vdev_id); #endif From 7051ad07688ff7a7168c2e654d75eddc92ac4baa Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 23 Mar 2017 11:16:40 -0700 Subject: [PATCH 033/404] qcacmn: Fix DBS & HW mode configurations for policy manager Fix DBS configuration & HW mode initialization for policy manager as part of policy manager restructuring. Change-Id: I0c0ef7797b3251454d86f5980c6e243985075216 CRs-Fixed: 2009818 --- inc/wlan_policy_mgr_api.h | 151 ++++++++- inc/wlan_policy_mgr_public_struct.h | 7 + src/wlan_policy_mgr_action.c | 63 +++- src/wlan_policy_mgr_core.c | 3 + src/wlan_policy_mgr_get_set_utils.c | 469 ++++++++++++++++++++++++++-- src/wlan_policy_mgr_i.h | 15 +- src/wlan_policy_mgr_init_deinit.c | 27 +- src/wlan_policy_mgr_pcl.c | 10 +- 8 files changed, 715 insertions(+), 30 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 24b7c46c74a0..3c92c8402f2b 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -771,7 +771,9 @@ struct policy_mgr_sme_cbacks { * from policy manager * @sap_restart_chan_switch_cb: Restart SAP * @wlan_hdd_get_channel_for_sap_restart: Get channel to restart - * SAP + * SAP + * @get_mode_for_non_connected_vdev: Get the mode for a non + * connected vdev */ struct policy_mgr_hdd_cbacks { void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc, @@ -781,6 +783,9 @@ struct policy_mgr_hdd_cbacks { struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t *channel, uint8_t *sec_ch, bool is_restart_sap); + enum policy_mgr_con_mode (*get_mode_for_non_connected_vdev)( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); }; @@ -1696,4 +1701,148 @@ bool policy_mgr_is_mcc_adaptive_scheduler_enabled( */ QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, struct policy_mgr_user_cfg *user_cfg); + +/** + * policy_mgr_init_dbs_config() - Function to initialize DBS + * config in policy manager component + * @psoc: PSOC object information + * @scan_config: DBS scan config + * @fw_config: DBS FW config + * + * This function sets the DBS configurations required by policy + * manager + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc, + uint32_t scan_config, uint32_t fw_config); + +/** + * policy_mgr_update_dbs_scan_config() - Function to update + * DBS scan config in policy manager component + * @psoc: PSOC object information + * + * This function updates the DBS scan configurations required by + * policy manager + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_update_dbs_scan_config(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_update_dbs_fw_config() - Function to update DBS FW + * config in policy manager component + * @psoc: PSOC object information + * + * This function updates the DBS FW configurations required by + * policy manager + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_update_dbs_fw_config(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_update_dbs_req_config() - Function to update DBS + * request config in policy manager component + * @psoc: PSOC object information + * @scan_config: DBS scan config + * @fw_config: DBS FW config + * + * This function updates DBS request configurations required by + * policy manager + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_update_dbs_req_config(struct wlan_objmgr_psoc *psoc, + uint32_t scan_config, uint32_t fw_mode_config); + +/** + * policy_mgr_dump_dbs_hw_mode() - Function to dump DBS config + * @psoc: PSOC object information + * + * This function dumps the DBS configurations + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_init_dbs_hw_mode() - Function to initialize DBS HW + * modes in policy manager component + * @psoc: PSOC object information + * @num_dbs_hw_modes: Number of HW modes + * @ev_wlan_dbs_hw_mode_list: HW list + * + * This function to initialize the DBS HW modes in policy + * manager + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc, + uint32_t num_dbs_hw_modes, + uint32_t *ev_wlan_dbs_hw_mode_list); + +/** + * policy_mgr_update_hw_mode_list() - Function to initialize DBS + * HW modes in policy manager component + * @psoc: PSOC object information + * @num_dbs_hw_modes: Number of HW modes + * @ev_wlan_dbs_hw_mode_list: HW list + * + * This function to initialize the DBS HW modes in policy + * manager + * + * Return: SUCCESS or FAILURE + * + */ +QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, + struct extended_caps *phy_caps); + +/** + * policy_mgr_update_hw_mode_index() - Function to update + * current HW mode in policy manager component + * @psoc: PSOC object information + * @new_hw_mode_index: index to new HW mode + * + * This function to update the current HW mode in policy manager + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_update_hw_mode_index(struct wlan_objmgr_psoc *psoc, + uint32_t new_hw_mode_index); + +/** + * policy_mgr_update_old_hw_mode_index() - Function to update + * old HW mode in policy manager component + * @psoc: PSOC object information + * @new_hw_mode_index: index to old HW mode + * + * This function to update the old HW mode in policy manager + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc *psoc, + uint32_t old_hw_mode_index); + +/** + * policy_mgr_update_new_hw_mode_index() - Function to update + * new HW mode in policy manager component + * @psoc: PSOC object information + * @new_hw_mode_index: index to new HW mode + * + * This function to update the new HW mode in policy manager + * + * Return: SUCCESS or FAILURE + * + */ +void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, + uint32_t new_hw_mode_index); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 78a987d4484e..361683e20f87 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -869,12 +869,14 @@ struct policy_mgr_dual_mac_config { * @set_hw_mode_cb: HDD set HW mode callback * @reason: Reason for HW mode change * @session_id: Session id + * @context: psoc context */ struct policy_mgr_hw_mode { uint32_t hw_mode_index; void *set_hw_mode_cb; enum policy_mgr_conn_update_reason reason; uint32_t session_id; + struct wlan_objmgr_psoc *context; }; /** @@ -975,8 +977,13 @@ struct dual_mac_config { /** * struct policy_mgr_user_cfg - Policy manager user config variables * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler + * @max_concurrent_active_sessions: User allowed maximum active + * connections + * @conc_system_pref: System preference for PCL table */ struct policy_mgr_user_cfg { uint8_t enable_mcc_adaptive_scheduler; + uint8_t max_concurrent_active_sessions; + uint8_t conc_system_pref; }; #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 76c28363a566..23f893a89040 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -135,6 +135,7 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb; msg.reason = reason; msg.session_id = session_id; + msg.context = psoc; policy_mgr_notice("set hw mode to sme: hw_mode_index: %d session:%d reason:%d", msg.hw_mode_index, msg.session_id, msg.reason); @@ -938,18 +939,76 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( void policy_mgr_set_hw_mode_change_in_progress( struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + pm_ctx->hw_mode_change_in_progress = value; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + policy_mgr_debug("hw_mode_change_in_progress:%d", value); } enum policy_mgr_hw_mode_change policy_mgr_is_hw_mode_change_in_progress( struct wlan_objmgr_psoc *psoc) { - return POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; + enum policy_mgr_hw_mode_change value; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return value; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + value = pm_ctx->hw_mode_change_in_progress; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return value; } enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index) { - return POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t param = 0; + enum policy_mgr_hw_mode_change value + = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return value; + } + + policy_mgr_info("HW param: %x", param); + param = pm_ctx->hw_mode.hw_mode_list[hw_mode_index]; + if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) { + policy_mgr_info("DBS is requested with HW (%d)", + hw_mode_index); + value = POLICY_MGR_DBS_IN_PROGRESS; + goto ret_value; + } + + if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) { + policy_mgr_info("SBS is requested with HW (%d)", + hw_mode_index); + value = POLICY_MGR_SBS_IN_PROGRESS; + goto ret_value; + } + + value = POLICY_MGR_SMM_IN_PROGRESS; + policy_mgr_info("SMM is requested with HW (%d)", hw_mode_index); + +ret_value: + return value; } #ifdef MPC_UT_FRAMEWORK diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index cc78c181c4c8..56929c602a09 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -717,6 +717,9 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, struct policy_mgr_hw_mode_params hw_mode; uint32_t i; + policy_mgr_set_hw_mode_change_in_progress(context, + POLICY_MGR_HW_MODE_NOT_IN_PROGRESS); + if (status != SET_HW_MODE_STATUS_OK) { policy_mgr_err("Set HW mode failed with status %d", status); return; diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 4bb51fad3f02..cd9be988d695 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -43,6 +43,418 @@ /* invalid channel id. */ #define INVALID_CHANNEL_ID 0 +void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, + uint32_t new_hw_mode_index) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + pm_ctx->new_hw_mode_index = new_hw_mode_index; +} + +void policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc *psoc, + uint32_t old_hw_mode_index) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + pm_ctx->old_hw_mode_index = old_hw_mode_index; +} + +void policy_mgr_update_hw_mode_index(struct wlan_objmgr_psoc *psoc, + uint32_t new_hw_mode_index) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + if (POLICY_MGR_DEFAULT_HW_MODE_INDEX == pm_ctx->new_hw_mode_index) { + pm_ctx->new_hw_mode_index = new_hw_mode_index; + } else { + pm_ctx->old_hw_mode_index = pm_ctx->new_hw_mode_index; + pm_ctx->new_hw_mode_index = new_hw_mode_index; + } + policy_mgr_debug("Updated: old_hw_mode_index:%d new_hw_mode_index:%d", + pm_ctx->old_hw_mode_index, pm_ctx->new_hw_mode_index); +} + +/** + * policy_mgr_get_num_of_setbits_from_bitmask() - to get num of + * setbits from bitmask + * @mask: given bitmask + * + * This helper function should return number of setbits from bitmask + * + * Return: number of setbits from bitmask + */ +static uint32_t policy_mgr_get_num_of_setbits_from_bitmask(uint32_t mask) +{ + uint32_t num_of_setbits = 0; + + while (mask) { + mask &= (mask - 1); + num_of_setbits++; + } + return num_of_setbits; +} + +/** + * policy_mgr_map_wmi_channel_width_to_hw_mode_bw() - returns + * bandwidth in terms of hw_mode_bandwidth + * @width: bandwidth in terms of wmi_channel_width + * + * This function returns the bandwidth in terms of hw_mode_bandwidth. + * + * Return: BW in terms of hw_mode_bandwidth. + */ +static enum hw_mode_bandwidth policy_mgr_map_wmi_channel_width_to_hw_mode_bw( + wmi_channel_width width) +{ + switch (width) { + case WMI_CHAN_WIDTH_20: + return HW_MODE_20_MHZ; + case WMI_CHAN_WIDTH_40: + return HW_MODE_40_MHZ; + case WMI_CHAN_WIDTH_80: + return HW_MODE_80_MHZ; + case WMI_CHAN_WIDTH_160: + return HW_MODE_160_MHZ; + case WMI_CHAN_WIDTH_80P80: + return HW_MODE_80_PLUS_80_MHZ; + case WMI_CHAN_WIDTH_5: + return HW_MODE_5_MHZ; + case WMI_CHAN_WIDTH_10: + return HW_MODE_10_MHZ; + default: + return HW_MODE_BW_NONE; + } + + return HW_MODE_BW_NONE; +} + +static void policy_mgr_get_hw_mode_params(WMI_MAC_PHY_CAPABILITIES *caps, + struct policy_mgr_mac_ss_bw_info *info) +{ + if (!caps) { + policy_mgr_err("Invalid capabilities"); + return; + } + + info->mac_tx_stream = policy_mgr_get_num_of_setbits_from_bitmask( + QDF_MAX(caps->tx_chain_mask_2G, + caps->tx_chain_mask_5G)); + info->mac_rx_stream = policy_mgr_get_num_of_setbits_from_bitmask( + QDF_MAX(caps->rx_chain_mask_2G, + caps->rx_chain_mask_5G)); + info->mac_bw = policy_mgr_map_wmi_channel_width_to_hw_mode_bw( + QDF_MAX(caps->max_bw_supported_2G, + caps->max_bw_supported_5G)); +} + +/** + * policy_mgr_set_hw_mode_params() - sets TX-RX stream, + * bandwidth and DBS in hw_mode_list + * @wma_handle: pointer to wma global structure + * @mac0_ss_bw_info: TX-RX streams, BW for MAC0 + * @mac1_ss_bw_info: TX-RX streams, BW for MAC1 + * @pos: refers to hw_mode_index + * @dbs_mode: dbs_mode for the dbs_hw_mode + * @sbs_mode: sbs_mode for the sbs_hw_mode + * + * This function sets TX-RX stream, bandwidth and DBS mode in + * hw_mode_list. + * + * Return: none + */ +static void policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info, + struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info, + uint32_t pos, uint32_t dbs_mode, + uint32_t sbs_mode) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + mac0_ss_bw_info.mac_tx_stream); + POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + mac0_ss_bw_info.mac_rx_stream); + POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + mac0_ss_bw_info.mac_bw); + POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + mac1_ss_bw_info.mac_tx_stream); + POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + mac1_ss_bw_info.mac_rx_stream); + POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + mac1_ss_bw_info.mac_bw); + POLICY_MGR_HW_MODE_DBS_MODE_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + dbs_mode); + POLICY_MGR_HW_MODE_AGILE_DFS_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + HW_MODE_AGILE_DFS_NONE); + POLICY_MGR_HW_MODE_SBS_MODE_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + sbs_mode); +} + +QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, + struct extended_caps *phy_caps) +{ + WMI_MAC_PHY_CAPABILITIES *tmp; + uint32_t i, hw_config_type, j = 0; + uint32_t dbs_mode, sbs_mode; + struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info = {0}; + struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info = {0}; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (!phy_caps) { + policy_mgr_err("Invalid phy capabilities"); + return QDF_STATUS_E_FAILURE; + } + + if (!phy_caps->num_hw_modes.num_hw_modes) { + policy_mgr_err("Number of HW modes: %d", + phy_caps->num_hw_modes.num_hw_modes); + return QDF_STATUS_E_FAILURE; + } + + /* + * This list was updated as part of service ready event. Re-populate + * HW mode list from the device capabilities. + */ + if (pm_ctx->hw_mode.hw_mode_list) { + qdf_mem_free(pm_ctx->hw_mode.hw_mode_list); + pm_ctx->hw_mode.hw_mode_list = NULL; + policy_mgr_err("DBS list is freed"); + } + + pm_ctx->num_dbs_hw_modes = phy_caps->num_hw_modes.num_hw_modes; + pm_ctx->hw_mode.hw_mode_list = + qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) * + pm_ctx->num_dbs_hw_modes); + if (!pm_ctx->hw_mode.hw_mode_list) { + policy_mgr_err("Memory allocation failed for DBS"); + return QDF_STATUS_E_FAILURE; + } + + policy_mgr_err("Updated HW mode list: Num modes:%d", + pm_ctx->num_dbs_hw_modes); + + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + /* Update for MAC0 */ + tmp = &phy_caps->each_phy_cap_per_hwmode[j++]; + policy_mgr_get_hw_mode_params(tmp, &mac0_ss_bw_info); + hw_config_type = + phy_caps->each_hw_mode_cap[i].hw_mode_config_type; + dbs_mode = HW_MODE_DBS_NONE; + sbs_mode = HW_MODE_SBS_NONE; + mac1_ss_bw_info.mac_tx_stream = 0; + mac1_ss_bw_info.mac_rx_stream = 0; + mac1_ss_bw_info.mac_bw = 0; + + /* SBS and DBS have dual MAC. Upto 2 MACs are considered. */ + if ((hw_config_type == WMI_HW_MODE_DBS) || + (hw_config_type == WMI_HW_MODE_SBS_PASSIVE) || + (hw_config_type == WMI_HW_MODE_SBS)) { + /* Update for MAC1 */ + tmp = &phy_caps->each_phy_cap_per_hwmode[j++]; + policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info); + if (hw_config_type == WMI_HW_MODE_DBS) + dbs_mode = HW_MODE_DBS; + if ((hw_config_type == WMI_HW_MODE_SBS_PASSIVE) || + (hw_config_type == WMI_HW_MODE_SBS)) + sbs_mode = HW_MODE_SBS; + } + + /* Updating HW mode list */ + policy_mgr_set_hw_mode_params(psoc, mac0_ss_bw_info, + mac1_ss_bw_info, i, dbs_mode, sbs_mode); + } + return QDF_STATUS_SUCCESS; +} + +void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc, + uint32_t num_dbs_hw_modes, + uint32_t *ev_wlan_dbs_hw_mode_list) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + pm_ctx->num_dbs_hw_modes = num_dbs_hw_modes; + pm_ctx->hw_mode.hw_mode_list = + qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) * + pm_ctx->num_dbs_hw_modes); + if (!pm_ctx->hw_mode.hw_mode_list) { + policy_mgr_err("Memory allocation failed for DBS"); + return; + } + qdf_mem_copy(pm_ctx->hw_mode.hw_mode_list, + ev_wlan_dbs_hw_mode_list, + (sizeof(*pm_ctx->hw_mode.hw_mode_list) * + pm_ctx->num_dbs_hw_modes)); +} + +void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc) +{ + uint32_t i, param; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + param = pm_ctx->hw_mode.hw_mode_list[i]; + policy_mgr_err("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d", + i, + POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param), + POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param), + POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param)); + policy_mgr_err("[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d", + i, + POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param), + POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param), + POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param)); + policy_mgr_err("[%d] DBS:%d SBS:%d", i, + POLICY_MGR_HW_MODE_DBS_MODE_GET(param), + POLICY_MGR_HW_MODE_SBS_MODE_GET(param)); + } +} + +void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc, + uint32_t scan_config, uint32_t fw_config) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + pm_ctx->dual_mac_cfg.cur_scan_config = 0; + pm_ctx->dual_mac_cfg.cur_fw_mode_config = 0; + + /* If dual mac features are disabled in the INI, we + * need not proceed further + */ + if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) { + policy_mgr_err("Disabling dual mac capabilities"); + /* All capabilites are initialized to 0. We can return */ + goto done; + } + + /* Initialize concurrent_scan_config_bits with default FW value */ + WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET( + pm_ctx->dual_mac_cfg.cur_scan_config, + WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config)); + WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_SET( + pm_ctx->dual_mac_cfg.cur_scan_config, + WMI_DBS_CONC_SCAN_CFG_AGILE_SCAN_GET(scan_config)); + WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_SET( + pm_ctx->dual_mac_cfg.cur_scan_config, + WMI_DBS_CONC_SCAN_CFG_AGILE_DFS_SCAN_GET(scan_config)); + + /* Initialize fw_mode_config_bits with default FW value */ + WMI_DBS_FW_MODE_CFG_DBS_SET( + pm_ctx->dual_mac_cfg.cur_fw_mode_config, + WMI_DBS_FW_MODE_CFG_DBS_GET(fw_config)); + WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET( + pm_ctx->dual_mac_cfg.cur_fw_mode_config, + WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_config)); +done: + /* Initialize the previous scan/fw mode config */ + pm_ctx->dual_mac_cfg.prev_scan_config = + pm_ctx->dual_mac_cfg.cur_scan_config; + pm_ctx->dual_mac_cfg.prev_fw_mode_config = + pm_ctx->dual_mac_cfg.cur_fw_mode_config; + + policy_mgr_debug("cur_scan_config:%x cur_fw_mode_config:%x", + pm_ctx->dual_mac_cfg.cur_scan_config, + pm_ctx->dual_mac_cfg.cur_fw_mode_config); +} + +void policy_mgr_update_dbs_scan_config(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + pm_ctx->dual_mac_cfg.prev_scan_config = + pm_ctx->dual_mac_cfg.cur_scan_config; + pm_ctx->dual_mac_cfg.cur_scan_config = + pm_ctx->dual_mac_cfg.req_scan_config; +} + +void policy_mgr_update_dbs_fw_config(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + pm_ctx->dual_mac_cfg.prev_fw_mode_config = + pm_ctx->dual_mac_cfg.cur_fw_mode_config; + pm_ctx->dual_mac_cfg.cur_fw_mode_config = + pm_ctx->dual_mac_cfg.req_fw_mode_config; +} + +void policy_mgr_update_dbs_req_config(struct wlan_objmgr_psoc *psoc, + uint32_t scan_config, uint32_t fw_mode_config) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + pm_ctx->dual_mac_cfg.req_scan_config = scan_config; + pm_ctx->dual_mac_cfg.req_fw_mode_config = fw_mode_config; +} + bool policy_mgr_get_dbs_plus_agile_scan_config(struct wlan_objmgr_psoc *psoc) { uint32_t scan_config; @@ -310,8 +722,10 @@ bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc) { struct policy_mgr_psoc_priv_obj *pm_ctx; - if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) + if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) { + policy_mgr_err("DBS is disabled from ini"); return false; + } pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -697,7 +1111,8 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, } /* set tdls connection tracker state */ - pm_ctx->tdls_cbacks.set_tdls_ct_mode(psoc); + if (pm_ctx->tdls_cbacks.set_tdls_ct_mode) + pm_ctx->tdls_cbacks.set_tdls_ct_mode(psoc); policy_mgr_dump_current_concurrency(psoc); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); @@ -734,7 +1149,8 @@ void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, policy_mgr_decr_connection_count(psoc, session_id); /* set tdls connection tracker state */ - pm_ctx->tdls_cbacks.set_tdls_ct_mode(psoc); + if (pm_ctx->tdls_cbacks.set_tdls_ct_mode) + pm_ctx->tdls_cbacks.set_tdls_ct_mode(psoc); policy_mgr_dump_current_concurrency(psoc); } @@ -759,9 +1175,9 @@ QDF_STATUS policy_mgr_incr_connection_count( } conn_index = policy_mgr_get_connection_count(psoc); - if (pm_ctx->gMaxConcurrentActiveSessions < conn_index) { + if (pm_ctx->user_cfg.max_concurrent_active_sessions < conn_index) { policy_mgr_err("exceeded max connection limit %d", - pm_ctx->gMaxConcurrentActiveSessions); + pm_ctx->user_cfg.max_concurrent_active_sessions); return status; } @@ -986,8 +1402,8 @@ bool policy_mgr_max_concurrent_connections_reached( for (i = 0; i < QDF_MAX_NO_OF_MODE; i++) j += pm_ctx->no_of_active_sessions[i]; return j > - (pm_ctx-> - gMaxConcurrentActiveSessions - 1); + (pm_ctx->user_cfg. + max_concurrent_active_sessions - 1); } return false; @@ -1035,7 +1451,7 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, if (policy_mgr_max_concurrent_connections_reached(psoc)) { policy_mgr_err("Reached max concurrent connections: %d", - pm_ctx->gMaxConcurrentActiveSessions); + pm_ctx->user_cfg.max_concurrent_active_sessions); goto done; } @@ -1258,14 +1674,20 @@ QDF_STATUS policy_mgr_get_channel_from_scan_result( return QDF_STATUS_E_INVAL; } - status = pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan_cache - (roam_profile, &scan_cache, channel); - if (status != QDF_STATUS_SUCCESS) { - policy_mgr_err("Get AP channel failed"); - return status; - } + if (pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan_cache) { + status = pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan_cache + (roam_profile, &scan_cache, channel); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Get AP channel failed"); + return status; + } + } else + policy_mgr_err("sme_get_ap_channel_from_scan_cache NULL"); - status = pm_ctx->sme_cbacks.sme_scan_result_purge(scan_cache); + if (pm_ctx->sme_cbacks.sme_scan_result_purge) + status = pm_ctx->sme_cbacks.sme_scan_result_purge(scan_cache); + else + policy_mgr_err("sme_scan_result_purge NULL"); return status; } @@ -1401,13 +1823,24 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, { enum policy_mgr_con_mode mode; bool ret; + struct policy_mgr_psoc_priv_obj *pm_ctx; - mode = policy_mgr_get_mode_by_vdev_id(psoc, session_id); - if (PM_MAX_NUM_OF_MODE == mode) { - policy_mgr_err("Invalid mode"); + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); return false; } + if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) { + mode = pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev( + psoc, session_id); + if (PM_MAX_NUM_OF_MODE == mode) { + policy_mgr_err("Invalid mode"); + return false; + } + } else + return false; + if (channel == 0) { policy_mgr_err("Invalid channel number 0"); return false; diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 6e9d400bbac5..e9c00f4ca524 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -279,15 +279,24 @@ struct policy_mgr_psoc_priv_obj { struct dbs_hw_mode_info hw_mode; uint32_t old_hw_mode_index; uint32_t new_hw_mode_index; - struct extended_caps phy_caps; bool enable2x2; - uint8_t gMaxConcurrentActiveSessions; - uint8_t conc_system_pref; struct dual_mac_config dual_mac_cfg; uint32_t hw_mode_change_in_progress; struct policy_mgr_user_cfg user_cfg; }; +/** + * struct policy_mgr_mac_ss_bw_info - hw_mode_list PHY/MAC params for each MAC + * @mac_tx_stream: Max TX stream + * @mac_rx_stream: Max RX stream + * @mac_bw: Max bandwidth + */ +struct policy_mgr_mac_ss_bw_info { + uint32_t mac_tx_stream; + uint32_t mac_rx_stream; + uint32_t mac_bw; +}; + struct policy_mgr_psoc_priv_obj *policy_mgr_get_context( struct wlan_objmgr_psoc *psoc); QDF_STATUS policy_mgr_get_updated_scan_config( diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index e81c003f4361..146e997f545c 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -55,6 +55,8 @@ static QDF_STATUS policy_mgr_psoc_obj_create_cb(struct wlan_objmgr_psoc *psoc, } policy_mgr_ctx->psoc = psoc; + policy_mgr_ctx->old_hw_mode_index = POLICY_MGR_DEFAULT_HW_MODE_INDEX; + policy_mgr_ctx->new_hw_mode_index = POLICY_MGR_DEFAULT_HW_MODE_INDEX; wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_UMAC_COMP_POLICY_MGR, @@ -278,8 +280,15 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) return status; } - pm_ctx->do_hw_mode_change = false; + if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create( + &pm_ctx->qdf_conc_list_lock))) { + policy_mgr_err("Failed to init qdf_conc_list_lock"); + QDF_ASSERT(0); + return status; + } + pm_ctx->do_hw_mode_change = false; + pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; /* reset sap mandatory channels */ status = policy_mgr_reset_sap_mandatory_channels(pm_ctx); if (QDF_IS_STATUS_ERROR(status)) { @@ -337,6 +346,19 @@ QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_E_FAILURE; } + if (pm_ctx->hw_mode.hw_mode_list) { + qdf_mem_free(pm_ctx->hw_mode.hw_mode_list); + pm_ctx->hw_mode.hw_mode_list = NULL; + policy_mgr_info("HW list is freed"); + } + + if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy( + &pm_ctx->qdf_conc_list_lock))) { + policy_mgr_err("Failed to destroy qdf_conc_list_lock"); + status = QDF_STATUS_E_FAILURE; + QDF_ASSERT(0); + } + /* destroy connection_update_done_evt */ if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy (&pm_ctx->connection_update_done_evt))) { @@ -432,6 +454,8 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, hdd_cbacks->sap_restart_chan_switch_cb; pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = hdd_cbacks->wlan_hdd_get_channel_for_sap_restart; + pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = + hdd_cbacks->get_mode_for_non_connected_vdev; return QDF_STATUS_SUCCESS; } @@ -448,6 +472,7 @@ QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc) pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb = NULL; pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = NULL; + pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = NULL; return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index f85fc0c618f2..a55fe2d60e63 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -196,9 +196,9 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, /* find the current connection state from pm_conc_connection_list*/ num_connections = policy_mgr_get_connection_count(psoc); policy_mgr_debug("connections:%d pref:%d requested mode:%d", - num_connections, pm_ctx->conc_system_pref, mode); + num_connections, pm_ctx->user_cfg.conc_system_pref, mode); - switch (pm_ctx->conc_system_pref) { + switch (pm_ctx->user_cfg.conc_system_pref) { case 0: conc_system_pref = PM_THROUGHPUT; break; @@ -210,7 +210,7 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, break; default: policy_mgr_err("unknown conc_system_pref value %d", - pm_ctx->conc_system_pref); + pm_ctx->user_cfg.conc_system_pref); break; } @@ -308,10 +308,10 @@ enum policy_mgr_conc_priority_mode return PM_THROUGHPUT; } - if (pm_ctx->conc_system_pref >= PM_MAX_CONC_PRIORITY_MODE) + if (pm_ctx->user_cfg.conc_system_pref >= PM_MAX_CONC_PRIORITY_MODE) return PM_THROUGHPUT; - return pm_ctx->conc_system_pref; + return pm_ctx->user_cfg.conc_system_pref; } enum policy_mgr_one_connection_mode From 68f709d4a0803d4182320ff3d850f8d5f264069c Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 23 Mar 2017 18:00:04 -0700 Subject: [PATCH 034/404] qcacmn: Add 2x2 chain configuration in policy manager Add 2x2 chain configuration in policy manager that is coming from user space. Change-Id: I8c9c54a1e63810327dc4252bc5320f34965ea4ca CRs-Fixed: 2009818 --- inc/wlan_policy_mgr_public_struct.h | 2 ++ src/wlan_policy_mgr_action.c | 4 ++-- src/wlan_policy_mgr_i.h | 8 -------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 361683e20f87..4a3bf4b961df 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -980,10 +980,12 @@ struct dual_mac_config { * @max_concurrent_active_sessions: User allowed maximum active * connections * @conc_system_pref: System preference for PCL table + * @enable2x2: 2x2 chain mask user config */ struct policy_mgr_user_cfg { uint8_t enable_mcc_adaptive_scheduler; uint8_t max_concurrent_active_sessions; uint8_t conc_system_pref; + bool enable2x2; }; #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 23f893a89040..e2d7cff6a8d4 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -115,11 +115,11 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, * if HW is not capable of doing 2x2 or ini config disabled 2x2, don't * allow to request FW for 2x2 */ - if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->enable2x2)) { + if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) { policy_mgr_notice("2x2 is not allowed downgrading to 1x1 for mac0"); mac0_ss = HW_MODE_SS_1x1; } - if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->enable2x2)) { + if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) { policy_mgr_notice("2x2 is not allowed downgrading to 1x1 for mac1"); mac1_ss = HW_MODE_SS_1x1; } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index e9c00f4ca524..7bd3f6dedb0c 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -244,13 +244,6 @@ extern enum policy_mgr_conc_next_action * @hw_mode: List of HW modes supported * @old_hw_mode_index: Old HW mode from hw_mode table * @new_hw_mode_index: New HW mode from hw_mode table - * @phy_caps: PHY capability advertised by FW - * @enable2x2: 2x2 chain mask user config - * @gMaxConcurrentActiveSessions: Max concurrenct active - * connections user config - * @conc_system_pref: System preference of t/p, power or latancy - * for Preferred Channel List table, user - * config * @dual_mac_cfg: DBS configuration currenctly used by FW for * scan & connections * @hw_mode_change_in_progress: This is to track if HW mode @@ -279,7 +272,6 @@ struct policy_mgr_psoc_priv_obj { struct dbs_hw_mode_info hw_mode; uint32_t old_hw_mode_index; uint32_t new_hw_mode_index; - bool enable2x2; struct dual_mac_config dual_mac_cfg; uint32_t hw_mode_change_in_progress; struct policy_mgr_user_cfg user_cfg; From 59cbe5c08ef25738e35759cabf93cd142f2cc20b Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 24 Mar 2017 14:13:52 -0700 Subject: [PATCH 035/404] qcacmn: Add a legacy callback to get the type of non connected vdev Add a legacy callback to get the type of a non connected vdev needed by policy manager. Change-Id: Id3622d5c808c8e0f3b24b257b5899f925dc36b1f CRs-Fixed: 2009818 --- src/wlan_policy_mgr_get_set_utils.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index cd9be988d695..b048579ee4e5 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1722,13 +1722,24 @@ uint8_t policy_mgr_search_and_check_for_session_conc( QDF_STATUS status; enum policy_mgr_con_mode mode; bool ret; + struct policy_mgr_psoc_priv_obj *pm_ctx; - mode = policy_mgr_get_mode_by_vdev_id(psoc, session_id); - if (PM_MAX_NUM_OF_MODE == mode) { - policy_mgr_err("Invalid mode"); + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); return channel; } + if (pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev) { + mode = pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev( + psoc, session_id); + if (PM_MAX_NUM_OF_MODE == mode) { + policy_mgr_err("Invalid mode"); + return channel; + } + } else + return channel; + status = policy_mgr_get_channel_from_scan_result(psoc, roam_profile, &channel); if ((QDF_STATUS_SUCCESS != status) || (channel == 0)) { From 72e062a734561672b708e1a100924daf075389d6 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 24 Mar 2017 18:13:42 +0800 Subject: [PATCH 036/404] qcacmn: Support rx p2p public action frame Support rx p2p public action frame and extend the roc timer for special frames. Also add scan requtest paramters when trigger scan request. Change-Id: I295bdcf9c5ff78320cbe600a483d245d38d05c06 CRs-Fixed: 2024412 --- core/src/wlan_p2p_off_chan_tx.c | 94 ++++++++++++++++++++++++++++--- core/src/wlan_p2p_roc.c | 15 +++-- core/src/wlan_p2p_roc.h | 2 + dispatcher/src/wlan_p2p_tgt_api.c | 18 +++--- 4 files changed, 105 insertions(+), 24 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 45208cc1c158..f243fc60f32d 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -589,23 +589,26 @@ static void p2p_init_frame_info(struct p2p_frame_info *frame_info) /** * p2p_get_frame_info() - get frame information from packet - * @tx_ctx: tx context + * @data_buf: data buffer address + * @length: buffer length + * @frame_info: frame information * * This function gets frame information from packet. * * Return: QDF_STATUS_SUCCESS - in case of success */ -static QDF_STATUS p2p_get_frame_info(struct tx_action_context *tx_ctx) +static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length, + struct p2p_frame_info *frame_info) { uint8_t type; uint8_t sub_type; uint8_t action_type; - uint8_t *buf = tx_ctx->buf; - struct p2p_frame_info *frame_info = &(tx_ctx->frame_info); + uint8_t *buf = data_buf; + + p2p_init_frame_info(frame_info); type = P2P_GET_TYPE_FRM_FC(buf[0]); sub_type = P2P_GET_SUBTYPE_FRM_FC(buf[0]); - p2p_init_frame_info(frame_info); if (type != P2P_FRAME_MGMT) { p2p_err("just support mgmt frame"); return QDF_STATUS_E_FAILURE; @@ -635,17 +638,17 @@ static QDF_STATUS p2p_get_frame_info(struct tx_action_context *tx_ctx) if (buf[0] == P2P_PUBLIC_ACTION_FRAME && buf[1] == P2P_PUBLIC_ACTION_VENDOR_SPECIFIC && !qdf_mem_cmp(&buf[2], P2P_OUI, P2P_OUI_SIZE)) { - buf = tx_ctx->buf + + buf = data_buf + P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET; action_type = buf[0]; - if (action_type >= P2P_PUBLIC_ACTION_NOT_SUPPORT) + if (action_type > P2P_PUBLIC_ACTION_PROV_DIS_RSP) frame_info->public_action_type = P2P_PUBLIC_ACTION_NOT_SUPPORT; else frame_info->public_action_type = action_type; } else if (buf[0] == P2P_ACTION_VENDOR_SPECIFIC_CATEGORY && !qdf_mem_cmp(&buf[1], P2P_OUI, P2P_OUI_SIZE)) { - buf = tx_ctx->buf + + buf = data_buf + P2P_ACTION_FRAME_TYPE_OFFSET; action_type = buf[0]; if (action_type == P2P_ACTION_PRESENCE_RSP) @@ -1003,6 +1006,56 @@ static QDF_STATUS p2p_move_tx_context_to_ack_queue( return status; } +/** + * p2p_extend_roc_timer() - extend roc timer + * @p2p_soc_obj: p2p soc private object + * @frame_info: pointer to frame information + * + * This function extends roc timer for some of p2p public action frame. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_extend_roc_timer( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct p2p_frame_info *frame_info) +{ + struct p2p_roc_context *curr_roc_ctx; + uint32_t extend_time; + + curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); + if (!curr_roc_ctx) { + p2p_debug("no running roc request currently"); + return QDF_STATUS_SUCCESS; + } + + if (!frame_info) { + p2p_err("invalid frame information"); + return QDF_STATUS_E_INVAL; + } + + switch (frame_info->public_action_type) { + case P2P_PUBLIC_ACTION_NEG_REQ: + case P2P_PUBLIC_ACTION_NEG_RSP: + extend_time = 2 * P2P_ACTION_FRAME_DEFAULT_WAIT; + break; + case P2P_PUBLIC_ACTION_INVIT_REQ: + case P2P_PUBLIC_ACTION_DEV_DIS_REQ: + extend_time = P2P_ACTION_FRAME_DEFAULT_WAIT; + break; + default: + extend_time = 0; + break; + } + + if (extend_time) { + p2p_debug("extend roc timer, duration:%d", extend_time); + curr_roc_ctx->duration = extend_time; + return p2p_restart_roc_timer(curr_roc_ctx); + } + + return QDF_STATUS_SUCCESS; +} + /** * p2p_adjust_tx_wait() - adjust tx wait * @tx_ctx: tx context @@ -1397,7 +1450,8 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan, tx_ctx->no_cck, tx_ctx->no_ack, tx_ctx->duration); - status = p2p_get_frame_info(tx_ctx); + status = p2p_get_frame_info(tx_ctx->buf, tx_ctx->buf_len, + &(tx_ctx->frame_info)); if (status != QDF_STATUS_SUCCESS) { p2p_err("unsupport frame"); status = QDF_STATUS_E_INVAL; @@ -1547,6 +1601,7 @@ QDF_STATUS p2p_process_rx_mgmt( struct p2p_rx_mgmt_frame *rx_mgmt; struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_start_param *start_param; + struct p2p_frame_info frame_info; p2p_soc_obj = rx_mgmt_event->p2p_soc_obj; rx_mgmt = rx_mgmt_event->rx_mgmt; @@ -1562,6 +1617,27 @@ QDF_STATUS p2p_process_rx_mgmt( rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, rx_mgmt->rx_rssi, rx_mgmt->buf); + if (rx_mgmt->frm_type == MGMT_ACTION_VENDOR_SPECIFIC) { + p2p_get_frame_info(rx_mgmt->buf, rx_mgmt->frame_len, + &frame_info); + + p2p_debug("action_sub_type %u, action_type %d", + frame_info.public_action_type, + frame_info.action_type); + + if ((frame_info.public_action_type == + P2P_PUBLIC_ACTION_NOT_SUPPORT) && + (frame_info.action_type == + P2P_ACTION_NOT_SUPPORT)) { + p2p_debug("non-p2p frame, drop it"); + qdf_mem_free(rx_mgmt); + return QDF_STATUS_SUCCESS; + } else { + p2p_debug("p2p frame, extend roc accordingly"); + p2p_extend_roc_timer(p2p_soc_obj, &frame_info); + } + } + start_param = p2p_soc_obj->start_param; if (start_param->rx_cb) start_param->rx_cb(start_param->rx_cb_data, rx_mgmt); diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 9c32eb61172e..ca3b7625c837 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -49,21 +49,22 @@ static QDF_STATUS p2p_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, bool isregister) { - struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[2]; QDF_STATUS status; p2p_debug("psoc:%p, is register rx:%d", psoc, isregister); - frm_cb_info.frm_type = MGMT_PROBE_REQ; - frm_cb_info.mgmt_rx_cb = (mgmt_frame_rx_callback) - tgt_p2p_mgmt_frame_rx_cb; + frm_cb_info[0].frm_type = MGMT_PROBE_REQ; + frm_cb_info[0].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; + frm_cb_info[1].frm_type = MGMT_ACTION_VENDOR_SPECIFIC; + frm_cb_info[1].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; if (isregister) status = wlan_mgmt_txrx_register_rx_cb(psoc, - WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); + WLAN_UMAC_COMP_P2P, frm_cb_info, 2); else status = wlan_mgmt_txrx_deregister_rx_cb(psoc, - WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); + WLAN_UMAC_COMP_P2P, frm_cb_info, 2); return status; } @@ -107,6 +108,8 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) req->scan_req.chan_list[0] = wlan_chan_to_freq(roc_ctx->chan); req->scan_req.dwell_time_passive = roc_ctx->duration; req->scan_req.dwell_time_active = 0; + req->scan_req.scan_priority = SCAN_PRIORITY_HIGH; + req->scan_req.num_bssid = 1; qdf_set_macaddr_broadcast(&req->scan_req.bssid_list[0]); status = ucfg_scan_start(req); diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index cc460a58a1b2..354d13382afb 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -33,9 +33,11 @@ #ifdef QCA_WIFI_3_0_EMU #define P2P_ROC_DURATION_MULTI_GO_PRESENT 2 #define P2P_ROC_DURATION_MULTI_GO_ABSENT 3 +#define P2P_ACTION_FRAME_DEFAULT_WAIT 500 #else #define P2P_ROC_DURATION_MULTI_GO_PRESENT 2 #define P2P_ROC_DURATION_MULTI_GO_ABSENT 5 +#define P2P_ACTION_FRAME_DEFAULT_WAIT 200 #endif struct wlan_objmgr_vdev; diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 96fcf15bbf34..b72e52894315 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -140,13 +140,13 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, p2p_soc_obj = tx_ctx->p2p_soc_obj; tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event)); - if (tx_conf_event == NULL) { + if (!tx_conf_event) { p2p_err("Failed to allocate tx cnf event"); return QDF_STATUS_E_NOMEM; } tx_cnf = qdf_mem_malloc(sizeof(*tx_cnf)); - if (tx_cnf == NULL) { + if (!tx_cnf) { p2p_err("Failed to allocate tx cnf"); return QDF_STATUS_E_NOMEM; } @@ -193,14 +193,14 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_P2P); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("p2p ctx is NULL, drop this frame"); return QDF_STATUS_E_FAILURE; } - if (peer == NULL) { + if (!peer) { roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); - if (roc_ctx == NULL) { + if (!roc_ctx) { p2p_err("current roc ctx is null, can't get vdev id"); return QDF_STATUS_E_FAILURE; } else { @@ -210,7 +210,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, wlan_peer_obj_lock(peer); vdev = wlan_peer_get_vdev(peer); wlan_peer_obj_unlock(peer); - if (vdev == NULL) { + if (!vdev) { p2p_err("vdev is NULL in peer, drop this frame"); return QDF_STATUS_E_FAILURE; } @@ -220,14 +220,14 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, } rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event)); - if (rx_mgmt_event == NULL) { + if (!rx_mgmt_event) { p2p_err("Failed to allocate rx mgmt event"); return QDF_STATUS_E_NOMEM; } rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) + mgmt_rx_params->buf_len); - if (rx_mgmt == NULL) { + if (!rx_mgmt) { p2p_err("Failed to allocate rx mgmt frame"); return QDF_STATUS_E_NOMEM; } @@ -237,7 +237,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, rx_mgmt->frame_len = mgmt_rx_params->buf_len; rx_mgmt->rx_chan = mgmt_rx_params->channel; rx_mgmt->vdev_id = vdev_id; - rx_mgmt->frm_type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + rx_mgmt->frm_type = frm_type; rx_mgmt->rx_rssi = mgmt_rx_params->snr + P2P_NOISE_FLOOR_DBM_DEFAULT; rx_mgmt_event->rx_mgmt = rx_mgmt; From 658a48de2dfd90a7a710da827f671256e6d318fd Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Thu, 23 Mar 2017 23:30:23 -0700 Subject: [PATCH 037/404] qcacmn: Fix SME callback for policy manager component Fix SME callback for policy manager component Change-Id: If5c7256fb689e4cdb053aa5012deacac221261f9 CRs-Fixed: 2019994 --- inc/wlan_policy_mgr_api.h | 2 +- src/wlan_policy_mgr_get_set_utils.c | 33 ++++++++++++++++------------- src/wlan_policy_mgr_init_deinit.c | 4 ++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 3c92c8402f2b..cc728643c0e5 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -758,7 +758,7 @@ struct policy_mgr_sme_cbacks { uint8_t next_action, struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason); QDF_STATUS (*sme_change_mcc_beacon_interval) (uint8_t session_id); - QDF_STATUS (*sme_get_ap_channel_from_scan_cache) ( + QDF_STATUS (*sme_get_ap_channel_from_scan) ( void *roam_profile, void **scan_cache, uint8_t *channel); diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index b048579ee4e5..a881839e85b8 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1674,15 +1674,16 @@ QDF_STATUS policy_mgr_get_channel_from_scan_result( return QDF_STATUS_E_INVAL; } - if (pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan_cache) { - status = pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan_cache + if (pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan) { + status = pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan (roam_profile, &scan_cache, channel); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Get AP channel failed"); return status; } - } else + } else { policy_mgr_err("sme_get_ap_channel_from_scan_cache NULL"); + } if (pm_ctx->sme_cbacks.sme_scan_result_purge) status = pm_ctx->sme_cbacks.sme_scan_result_purge(scan_cache); @@ -1907,17 +1908,18 @@ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( policy_mgr_info("UPDATE Beacon Params"); if (QDF_SAP_MODE == dev_mode) { - if (!pm_ctx-> - sme_cbacks.sme_change_mcc_beacon_interval) { + if (pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval + ) { + status = pm_ctx->sme_cbacks. + sme_change_mcc_beacon_interval(vdev_id); + if (status == QDF_STATUS_E_FAILURE) { + policy_mgr_err("Failed to update Beacon Params"); + return QDF_STATUS_E_FAILURE; + } + } else { policy_mgr_err("sme_change_mcc_beacon_interval callback is NULL"); return QDF_STATUS_E_FAILURE; } - status = pm_ctx->sme_cbacks. - sme_change_mcc_beacon_interval(vdev_id); - if (status == QDF_STATUS_E_FAILURE) { - policy_mgr_err("Failed to update Beacon Params"); - return QDF_STATUS_E_FAILURE; - } } return QDF_STATUS_SUCCESS; @@ -2137,14 +2139,15 @@ QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - if (!pm_ctx->sme_cbacks.sme_get_nss_for_vdev) { + if (pm_ctx->sme_cbacks.sme_get_nss_for_vdev) { + pm_ctx->sme_cbacks.sme_get_nss_for_vdev( + dev_mode, nss_2g, nss_5g); + + } else { policy_mgr_err("sme_get_nss_for_vdev callback is NULL"); return QDF_STATUS_E_FAILURE; } - pm_ctx->sme_cbacks.sme_get_nss_for_vdev( - dev_mode, nss_2g, nss_5g); - return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 146e997f545c..63c7b43be190 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -420,8 +420,8 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, sme_cbacks->sme_soc_set_dual_mac_config; pm_ctx->sme_cbacks.sme_change_mcc_beacon_interval = sme_cbacks->sme_change_mcc_beacon_interval; - pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan_cache = - sme_cbacks->sme_get_ap_channel_from_scan_cache; + pm_ctx->sme_cbacks.sme_get_ap_channel_from_scan = + sme_cbacks->sme_get_ap_channel_from_scan; pm_ctx->sme_cbacks.sme_scan_result_purge = sme_cbacks->sme_scan_result_purge; From 878422fc9da72e3a004d1082ac77c0b01d51a8f0 Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Thu, 23 Mar 2017 11:34:02 -0700 Subject: [PATCH 038/404] qcacmn: Update legacy fixes in new policy manager component Update legacy fixes in new policy manager component: 1. Avoid race condition to get pcl while stopping P2P GO 2. Add 160/80+80 MHz support for STA mode 3. Fix SBS is set to true by policy manager in SCC mode Change-Id: I161ebe382915a6d9eefd6b4e3e2158ff14ad02c1 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_core.c | 43 ++++------------------------- src/wlan_policy_mgr_get_set_utils.c | 24 +++------------- src/wlan_policy_mgr_i.h | 1 - 3 files changed, 9 insertions(+), 59 deletions(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 56929c602a09..526b8093a90c 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -570,6 +570,11 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, bool found = false; struct policy_mgr_psoc_priv_obj *pm_ctx; + if (!info) { + policy_mgr_err("Invalid connection info"); + return; + } + qdf_mem_zero(info, sizeof(*info)); pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); @@ -2142,44 +2147,6 @@ bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, return status; } -/** - * policy_mgr_vht160_conn_exist() - to check if we have a connection - * already using vht160 or vht80+80 - * - * This routine will check if vht160 connection already exist or - * no. If it exist then this routine will return true. - * - * Return: true if vht160 connection exist else false - */ -bool policy_mgr_vht160_conn_exist(struct wlan_objmgr_psoc *psoc) -{ - uint32_t conn_index; - bool status = false; - struct policy_mgr_psoc_priv_obj *pm_ctx; - - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid Context"); - return status; - } - - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; - conn_index++) { - if (pm_conc_connection_list[conn_index].in_use && - ((pm_conc_connection_list[conn_index].bw == - HW_MODE_80_PLUS_80_MHZ) || - (pm_conc_connection_list[conn_index].bw == - HW_MODE_160_MHZ))) { - status = true; - break; - } - } - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - - return status; -} - /** * policy_mgr_is_5g_channel_allowed() - check if 5g channel is allowed * @channel: channel number which needs to be validated diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index a881839e85b8..38d55f000669 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -563,17 +563,15 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) return false; } - policy_mgr_notice("SBS service bit map: %d", - pm_ctx->wma_cbacks.wma_is_service_enabled( - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); - /* The agreement with FW is that: To know if the target is SBS * capable, SBS needs to be supported both in the HW mode list * and DBS needs to be supported in the service ready event */ if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) { + policy_mgr_err("SBS cannot be supported since DBS is disabled"); return false; + } for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { param = pm_ctx->hw_mode.hw_mode_list[i]; @@ -588,7 +586,7 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) if (found) return true; - return true; + return false; } QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc, @@ -1600,20 +1598,6 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } - /* don't allow concurrency on vht160 or vht 80+80 */ - if (num_connections && - ((bw == HW_MODE_80_PLUS_80_MHZ) || - (bw == HW_MODE_160_MHZ))) { - policy_mgr_err("No VHT160, we have one connection already"); - goto done; - } - - if (policy_mgr_vht160_conn_exist(psoc)) { - policy_mgr_err("VHT160/80+80 connection exists, no concurrency"); - goto done; - } - - status = true; done: diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 7bd3f6dedb0c..67e69f072bfe 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -389,7 +389,6 @@ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, uint8_t channel); bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, uint8_t channel, uint32_t num_connections); -bool policy_mgr_vht160_conn_exist(struct wlan_objmgr_psoc *psoc); bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, uint8_t channel, uint32_t *list, enum policy_mgr_con_mode mode); From 00ccf115f53624db6c79656565b34c24bbdd3cc1 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 28 Mar 2017 10:45:08 -0700 Subject: [PATCH 039/404] qcacmn: Add null check for legacy callback functions in policy manager Add null check for callback functions registered from legacy modules with policy manager. Change-Id: I8a08870ea904f4e01a17f6a472bdd609df9c3c4c CRs-Fixed: 2009818 --- src/wlan_policy_mgr_action.c | 15 +++++--- src/wlan_policy_mgr_get_set_utils.c | 55 +++++++++++++++++------------ 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index e2d7cff6a8d4..4011622d1ce7 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -260,14 +260,19 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, vdev_id); return status; } - - status = pm_ctx->wma_cbacks.wma_get_connection_info( + if (pm_ctx->wma_cbacks.wma_get_connection_info) { + status = pm_ctx->wma_cbacks.wma_get_connection_info( vdev_id, &conn_table_entry); - if (QDF_STATUS_SUCCESS != status) { - policy_mgr_err("can't find vdev_id %d in connection table", + if (QDF_STATUS_SUCCESS != status) { + policy_mgr_err("can't find vdev_id %d in connection table", vdev_id); - return status; + return status; + } + } else { + policy_mgr_err("wma_get_connection_info is NULL"); + return QDF_STATUS_E_FAILURE; } + mode = policy_mgr_get_mode(conn_table_entry.type, conn_table_entry.sub_type); chan = reg_freq_to_chan(conn_table_entry.mhz); diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 38d55f000669..dad0bf96ba42 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -523,17 +523,19 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) policy_mgr_notice("DBS is disabled"); return false; } + if (pm_ctx->wma_cbacks.wma_is_service_enabled) { + policy_mgr_notice("DBS service bit map: %d", + pm_ctx->wma_cbacks.wma_is_service_enabled( + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); - policy_mgr_notice("DBS service bit map: %d", - pm_ctx->wma_cbacks.wma_is_service_enabled( - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); - - /* The agreement with FW is that: To know if the target is DBS - * capable, DBS needs to be supported both in the HW mode list - * and in the service ready event - */ - if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( + /* The agreement with FW is that: To know if the target is DBS + * capable, DBS needs to be supported both in the HW mode list + * and in the service ready event + */ + if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) + return false; + } else return false; for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { @@ -562,16 +564,20 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) policy_mgr_err("Invalid Context"); return false; } + if (pm_ctx->wma_cbacks.wma_is_service_enabled) { + policy_mgr_notice("DBS service bit map: %d", + pm_ctx->wma_cbacks.wma_is_service_enabled( + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); - /* The agreement with FW is that: To know if the target is SBS - * capable, SBS needs to be supported both in the HW mode list - * and DBS needs to be supported in the service ready event - */ - if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) { - policy_mgr_err("SBS cannot be supported since DBS is disabled"); + /* The agreement with FW is that: To know if the target is SBS + * capable, SBS needs to be supported both in the HW mode list + * and DBS needs to be supported in the service ready event + */ + if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( + WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) + return false; + } else return false; - } for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { param = pm_ctx->hw_mode.hw_mode_list[i]; @@ -1178,14 +1184,19 @@ QDF_STATUS policy_mgr_incr_connection_count( pm_ctx->user_cfg.max_concurrent_active_sessions); return status; } - - status = pm_ctx->wma_cbacks.wma_get_connection_info( + if (pm_ctx->wma_cbacks.wma_get_connection_info) { + status = pm_ctx->wma_cbacks.wma_get_connection_info( vdev_id, &conn_table_entry); - if (QDF_STATUS_SUCCESS != status) { - policy_mgr_err("can't find vdev_id %d in connection table", + if (QDF_STATUS_SUCCESS != status) { + policy_mgr_err("can't find vdev_id %d in connection table", vdev_id); - return status; + return status; + } + } else { + policy_mgr_err("wma_get_connection_info is NULL"); + return QDF_STATUS_E_FAILURE; } + mode = policy_mgr_get_mode(conn_table_entry.type, conn_table_entry.sub_type); chan = reg_freq_to_chan(conn_table_entry.mhz); From 8ae831eadab397cde7e60e1e4703144766fc40ee Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 27 Mar 2017 13:34:18 +0800 Subject: [PATCH 040/404] qcacmn: Move to common wmi event id for P2P Since new wmi API to allow components to move to common event id, P2P add related changes to use common wmi event id. Change-Id: I67b9fb7cba992b06ffdfc09a1243e6f5f2c29fed CRs-Fixed: 2025109 --- src/target_if_p2p.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index dee2c8c0eca8..c19fea4605cb 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -170,10 +170,9 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( return QDF_STATUS_E_INVAL; } - status = wmi_unified_register_event_handler(wmi_handle, - WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID, - target_p2p_lo_event_handler, - WMI_RX_UMAC_CTX); + status = wmi_unified_register_event(wmi_handle, + wmi_p2p_lo_stop_event_id, + target_p2p_lo_event_handler); target_if_debug("wmi register lo event handle, status:%d", status); @@ -194,9 +193,9 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( return QDF_STATUS_E_INVAL; } - status = wmi_unified_register_event_handler(wmi_handle, - WMI_P2P_NOA_EVENTID, target_p2p_noa_event_handler, - WMI_RX_UMAC_CTX); + status = wmi_unified_register_event(wmi_handle, + wmi_p2p_noa_event_id, + target_p2p_noa_event_handler); target_if_debug("wmi register noa event handle, status:%d", status); @@ -217,8 +216,8 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( return QDF_STATUS_E_INVAL; } - status = wmi_unified_unregister_event_handler(wmi_handle, - WMI_P2P_LISTEN_OFFLOAD_STOPPED_EVENTID); + status = wmi_unified_unregister_event(wmi_handle, + wmi_p2p_lo_stop_event_id); target_if_debug("wmi unregister lo event handle, status:%d", status); @@ -239,8 +238,8 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( return QDF_STATUS_E_INVAL; } - status = wmi_unified_unregister_event_handler(wmi_handle, - WMI_P2P_NOA_EVENTID); + status = wmi_unified_unregister_event(wmi_handle, + wmi_p2p_noa_event_id); target_if_debug("wmi unregister noa event handle, status:%d", status); From d187078c6501bb94c33d264f6782d847a2c48704 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 4 Apr 2017 12:03:25 -0700 Subject: [PATCH 041/404] qcacmn: Fix checkpatch warning in policy manager component Fix checkpatch warning in policy manager component. Change-Id: Ibef1681f3dc8e17b0d1d7bcde0d7dbea5526eedf CRs-Fixed: 2009818 --- inc/wlan_policy_mgr_api.h | 6 +++--- src/wlan_policy_mgr_i.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index cc728643c0e5..3eb4a5815880 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -757,12 +757,12 @@ struct policy_mgr_sme_cbacks { uint8_t new_nss, policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason); - QDF_STATUS (*sme_change_mcc_beacon_interval) (uint8_t session_id); - QDF_STATUS (*sme_get_ap_channel_from_scan) ( + QDF_STATUS (*sme_change_mcc_beacon_interval)(uint8_t session_id); + QDF_STATUS (*sme_get_ap_channel_from_scan)( void *roam_profile, void **scan_cache, uint8_t *channel); - QDF_STATUS (*sme_scan_result_purge) ( + QDF_STATUS (*sme_scan_result_purge)( void *scan_result); }; diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 67e69f072bfe..75a2c3d3f164 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -249,7 +249,7 @@ extern enum policy_mgr_conc_next_action * @hw_mode_change_in_progress: This is to track if HW mode * change is in progress * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler - * value from INI + * value from INI */ struct policy_mgr_psoc_priv_obj { struct wlan_objmgr_psoc *psoc; From f3a3e912af94e8a37560fbee898b645378977e4d Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Tue, 4 Apr 2017 15:26:54 +0530 Subject: [PATCH 042/404] qcacmn: Fix peer ref count issue in p2p_mgmt_tx In p2p_mgmt_tx ref count of peer is increased and then frame is passed to wlan_mgmt_txrx_mgmt_frame_tx which again increase the peer ref count. But the ref count is decreased only once when frame tx complete is received. Thus peer is not deleted while vdev destroy and as peer contain the ref count of vdev, vdev is also not deleted. To fix this Release peer ref count in p2p_mgmt_tx after wlan_mgmt_txrx_mgmt_frame_tx. Change-Id: I8e42b22559f3baf43fefd6183a079f9629efae3c CRs-Fixed: 2028550 --- core/src/wlan_p2p_off_chan_tx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index f243fc60f32d..836ace012a72 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -784,11 +784,11 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, wh = (struct wlan_frame_hdr *)frame; mac_addr = wh->i_addr1; - peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_MGMT_NB_ID); + peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_P2P_ID); if (!peer) { mac_addr = wh->i_addr2; peer = wlan_objmgr_get_peer(psoc, mac_addr, - WLAN_MGMT_NB_ID); + WLAN_P2P_ID); } if (!peer) { @@ -813,6 +813,8 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, tx_comp_cb, tx_ota_comp_cb, WLAN_UMAC_COMP_P2P, &mgmt_param); + wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID); + return status; } From 9807d0cd8dda3d2153e6d283ce74bc46b7e580c6 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 4 Apr 2017 17:23:26 -0700 Subject: [PATCH 043/404] qcacmn: Prune PCL to active channels only for P2P GO Prune the PCL to have only active channels for P2P GO mode. Change-Id: Ifade00b3ccfcecff16a49e9e9aa5e077d5f9629b CRs-Fixed: 2029007 --- src/wlan_policy_mgr_i.h | 2 ++ src/wlan_policy_mgr_pcl.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 75a2c3d3f164..a1a91be7ecd2 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -53,6 +53,8 @@ extern enum cds_band_type cds_chan_to_band(uint32_t chan); #define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ CDS_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) #define wlan_reg_is_dfs_ch(psoc, ch) CDS_IS_DFS_CH(ch) +#define wlan_reg_is_passive_or_disable_ch(ch) \ + CDS_IS_PASSIVE_OR_DISABLE_CH(ch) #define WLAN_REG_MAX_24GHZ_CH_NUM CDS_MAX_24GHZ_CHANNEL_NUMBER #define reg_chan_to_freq(chan_num) cds_chan_to_freq(chan_num) #define reg_freq_to_chan(freq) cds_freq_to_chan(freq) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index a55fe2d60e63..edc96138353e 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -139,6 +139,31 @@ void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels, return; } +static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels( + uint8_t *pcl_list_org, + uint8_t *weight_list_org, + uint32_t *pcl_len_org) +{ + uint32_t i, pcl_len = 0; + uint8_t pcl_list[QDF_MAX_NUM_CHAN]; + uint8_t weight_list[QDF_MAX_NUM_CHAN]; + + for (i = 0; i < *pcl_len_org; i++) { + if (!wlan_reg_is_passive_or_disable_ch(pcl_list_org[i])) { + pcl_list[pcl_len] = pcl_list_org[i]; + weight_list[pcl_len++] = weight_list_org[i]; + } + } + + qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org)); + qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org)); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); + qdf_mem_copy(weight_list_org, weight_list, pcl_len); + *pcl_len_org = pcl_len; + + return QDF_STATUS_SUCCESS; +} + uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t *vdev_id) { @@ -293,6 +318,19 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, } + if (mode == PM_P2P_GO_MODE) { + status = policy_mgr_modify_pcl_based_on_enabled_channels( + pcl_channels, pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get modified pcl for GO"); + return status; + } + policy_mgr_debug("modified pcl len:%d", *len); + for (i = 0; i < *len; i++) + policy_mgr_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); + } + return QDF_STATUS_SUCCESS; } From cf450f183be60ef9329307b15ccc6e9ef3985382 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 12 Apr 2017 18:53:07 +0800 Subject: [PATCH 044/404] qcacmn: Handle scan dequeue event and start failed event Handle scan dequeue event and start failed event in P2P component, same as scan complete event. Fix incorrect method to call qdf wait single event. Fix code style issue. Change-Id: Id8fbf5180a942183eff9b02f36f945fe17ceab6e CRs-Fixed: 2032600 --- core/src/wlan_p2p_off_chan_tx.c | 20 +++------ core/src/wlan_p2p_roc.c | 72 ++++++------------------------ dispatcher/src/wlan_p2p_ucfg_api.c | 14 +++--- 3 files changed, 27 insertions(+), 79 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 836ace012a72..81f7021b703e 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -991,7 +991,7 @@ static QDF_STATUS p2p_move_tx_context_to_ack_queue( } if (is_ack_q) { - p2p_err("Already in waiting for ack queue"); + p2p_debug("Already in waiting for ack queue"); return QDF_STATUS_SUCCESS; } } @@ -1374,11 +1374,11 @@ QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj, } } if (is_ack_q) { - p2p_err("Already sent and waiting for ack"); + p2p_debug("Already sent and waiting for ack"); status = QDF_STATUS_SUCCESS; } } else { - p2p_err("Failed to find tx ctx by cookie, cookie %llx", + p2p_debug("Failed to find tx ctx by cookie, cookie %llx", cookie); status = QDF_STATUS_E_INVAL; } @@ -1428,7 +1428,6 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) { struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_roc_context *curr_roc_ctx; - uint64_t rc = 1; QDF_STATUS status; status = p2p_tx_context_check_valid(tx_ctx); @@ -1462,7 +1461,7 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) status = p2p_vdev_check_valid(tx_ctx); if (status != QDF_STATUS_SUCCESS) { - p2p_err("invalid vdev or vdev mode"); + p2p_debug("invalid vdev or vdev mode"); status = QDF_STATUS_E_INVAL; goto fail; } @@ -1486,15 +1485,8 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) /* For off channel tx case */ curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); if (curr_roc_ctx && (curr_roc_ctx->chan == tx_ctx->chan)) { - if (curr_roc_ctx->roc_state == + if (curr_roc_ctx->roc_state != ROC_STATE_CANCEL_IN_PROG) { - /* wait for roc canceling done */ - rc = qdf_wait_single_event( - &p2p_soc_obj->cancel_roc_done, - msecs_to_jiffies(P2P_WAIT_CANCEL_ROC)); - if (!rc) - p2p_err("Timeout occurred while waiting for RoC cancellation"); - } else { p2p_adjust_tx_wait(tx_ctx); status = p2p_restart_roc_timer(curr_roc_ctx); if (status != QDF_STATUS_SUCCESS) { @@ -1552,7 +1544,7 @@ QDF_STATUS p2p_process_mgmt_tx_cancel( cancel_tx->cookie); } } else { - p2p_err("Failed to find tx ctx by cookie, cookie %llx", + p2p_debug("Failed to find tx ctx by cookie, cookie %llx", cancel_tx->cookie); return QDF_STATUS_E_INVAL; } diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index ca3b7625c837..e04082353fa1 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -450,9 +450,13 @@ static QDF_STATUS p2p_process_scan_complete_evt( roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); - status = qdf_mc_timer_stop(&roc_ctx->roc_timer); - if (status != QDF_STATUS_SUCCESS) - p2p_err("Failed to stop roc timer"); + if (QDF_TIMER_STATE_RUNNING == + qdf_mc_timer_get_current_state(&roc_ctx->roc_timer)) { + status = qdf_mc_timer_stop(&roc_ctx->roc_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to stop roc timer"); + } + status = qdf_mc_timer_destroy(&roc_ctx->roc_timer); if (status != QDF_STATUS_SUCCESS) p2p_err("Failed to destroy roc timer"); @@ -489,45 +493,6 @@ static QDF_STATUS p2p_process_scan_complete_evt( return status; } -/** - * p2p_process_scan_dequeue() - Process scan dequeue - * @roc_ctx: remain on channel request - * - * This function process scan dequeued event. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -static QDF_STATUS p2p_process_scan_dequeue( - struct p2p_roc_context *roc_ctx) -{ - QDF_STATUS status; - struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - - if (roc_ctx->roc_state != ROC_STATE_CANCEL_IN_PROG) { - p2p_debug("invalid roc state, %d", roc_ctx->roc_state); - return QDF_STATUS_E_INVAL; - } - - if (QDF_TIMER_STATE_RUNNING != - qdf_mc_timer_get_current_state(&roc_ctx->roc_timer)) { - qdf_mc_timer_stop(&roc_ctx->roc_timer); - } - - status = qdf_mc_timer_destroy(&roc_ctx->roc_timer); - if (status != QDF_STATUS_SUCCESS) - p2p_err("failed to destroy roc timer, roc ctx:%p, status:%d", - roc_ctx, status); - - status = qdf_list_remove_node(&p2p_soc_obj->roc_q, - (qdf_list_node_t *)roc_ctx); - if (status != QDF_STATUS_SUCCESS) - p2p_err("failed to remove roc context, roc ctx:%p, status:%d", - roc_ctx, status); - qdf_mem_free(roc_ctx); - - return status; -} - struct p2p_roc_context *p2p_find_current_roc_ctx( struct p2p_soc_priv_obj *p2p_soc_obj) { @@ -582,7 +547,6 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) QDF_STATUS status = QDF_STATUS_SUCCESS; struct p2p_roc_context *roc_ctx; qdf_list_node_t *tmp, *pos; - unsigned long rc = 0; p2p_debug("clean up idle roc request, roc queue size:%d", qdf_list_size(&p2p_soc_obj->roc_q)); @@ -625,20 +589,13 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) ROC_STATE_CANCEL_IN_PROG) p2p_execute_cancel_roc_req(roc_ctx); - rc = qdf_wait_single_event( + status = qdf_wait_single_event( &p2p_soc_obj->cancel_roc_done, - msecs_to_jiffies(P2P_WAIT_CANCEL_ROC)); - if (!rc) - p2p_err("Timeout occurred while waiting for RoC cancellation"); + P2P_WAIT_CANCEL_ROC); + p2p_err("roc cancellation done, status:%d", status); } } - if (status != QDF_STATUS_SUCCESS || rc) { - p2p_err("failed to cleanup roc queue, status:%d, rc:%ld", - status, rc); - status = QDF_STATUS_E_FAILURE; - } - return status; } @@ -661,7 +618,7 @@ QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx) &roc_ctx->node); if (QDF_STATUS_SUCCESS != status) { qdf_mem_free(roc_ctx); - p2p_err("Failed to insert roc req, status %d", status); + p2p_debug("Failed to insert roc req, status %d", status); return status; } @@ -742,12 +699,11 @@ void p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, p2p_process_ready_on_channel_evt(curr_roc_ctx); break; case SCAN_EVENT_TYPE_COMPLETED: + case SCAN_EVENT_TYPE_DEQUEUED: + case SCAN_EVENT_TYPE_START_FAILED: p2p_process_scan_complete_evt(curr_roc_ctx); break; - case SCAN_EVENT_TYPE_DEQUEUED: - p2p_process_scan_dequeue(curr_roc_ctx); - break; default: - p2p_err("invalid scan event, %d", event->type); + p2p_debug("drop scan event, %d", event->type); } } diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index cc742fc2d39f..977a514b96d3 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -160,20 +160,20 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, mgmt_frm->wait, mgmt_frm->len, mgmt_frm->no_cck, mgmt_frm->dont_wait_for_ack, mgmt_frm->off_chan); - if (soc == NULL) { + if (!soc) { p2p_err("psoc context passed is NULL"); return QDF_STATUS_E_INVAL; } p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, WLAN_UMAC_COMP_P2P); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("P2P soc context is NULL"); return QDF_STATUS_E_FAILURE; } tx_action = qdf_mem_malloc(sizeof(*tx_action)); - if (tx_action == NULL) { + if (!tx_action) { p2p_err("Failed to allocate tx action context"); return QDF_STATUS_E_NOMEM; } @@ -193,7 +193,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, tx_action->no_ack = mgmt_frm->dont_wait_for_ack; tx_action->off_chan = mgmt_frm->off_chan; tx_action->buf = qdf_mem_malloc(tx_action->buf_len); - if (tx_action->buf == NULL) { + if (!(tx_action->buf)) { p2p_err("Failed to allocate buffer for action frame"); qdf_mem_free(tx_action); return QDF_STATUS_E_NOMEM; @@ -216,20 +216,20 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, p2p_debug("soc:%p, cookie:0x%llx", soc, cookie); - if (soc == NULL) { + if (!soc) { p2p_err("psoc context passed is NULL"); return QDF_STATUS_E_INVAL; } p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, WLAN_UMAC_COMP_P2P); - if (p2p_soc_obj == NULL) { + if (!p2p_soc_obj) { p2p_err("p2p soc context is NULL"); return QDF_STATUS_E_FAILURE; } cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx)); - if (cancel_tx == NULL) { + if (!cancel_tx) { p2p_err("Failed to allocate cancel p2p roc"); return QDF_STATUS_E_NOMEM; } From ce237d682b05310abd329f303753f0776373fd18 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 5 Apr 2017 12:52:36 -0700 Subject: [PATCH 045/404] qcacmn: Replace legacy regulatory APIs with new ones from host cmn Get rid of legacy regulatory API references from policy manager as the new ones are available now. Change-Id: I48d41599d7faeb760b51ca5f0d7672e8484e7f91 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_action.c | 4 +- src/wlan_policy_mgr_core.c | 24 ++++-- src/wlan_policy_mgr_get_set_utils.c | 12 +-- src/wlan_policy_mgr_i.h | 33 +------- src/wlan_policy_mgr_init_deinit.c | 115 ++++++++++++++++++++++++---- src/wlan_policy_mgr_pcl.c | 21 +++-- 6 files changed, 140 insertions(+), 69 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 4011622d1ce7..84d4c67d1410 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -275,7 +275,7 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, mode = policy_mgr_get_mode(conn_table_entry.type, conn_table_entry.sub_type); - chan = reg_freq_to_chan(conn_table_entry.mhz); + chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz); status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g); if (QDF_IS_STATUS_SUCCESS(status)) { if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) || @@ -723,7 +723,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( mcc_to_scc_switch, operating_channel); if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) #ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE - && !wlan_reg_is_dfs_ch(psoc, + && !wlan_reg_is_dfs_ch(pm_ctx->pdev, operating_channel) #endif ) { diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 526b8093a90c..546bfdd4a16f 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1529,7 +1529,7 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (POLICY_MGR_PCL_ORDER_NONE == order) { while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (skip_dfs_channel && wlan_reg_is_dfs_ch(psoc, + if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev, pm_conc_connection_list[conn_index].chan)) { conn_index++; } else if (*index < weight_len) { @@ -1555,7 +1555,7 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, } conn_index = 0; while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (skip_dfs_channel && wlan_reg_is_dfs_ch(psoc, + if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev, pm_conc_connection_list[conn_index].chan)) { conn_index++; } else if (WLAN_REG_IS_5GHZ_CH( @@ -1571,7 +1571,7 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, *len = num_channels; } else if (POLICY_MGR_PCL_ORDER_5G_THEN_2G == order) { while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { - if (skip_dfs_channel && wlan_reg_is_dfs_ch(psoc, + if (skip_dfs_channel && wlan_reg_is_dfs_ch(pm_ctx->pdev, pm_conc_connection_list[conn_index].chan)) { conn_index++; } else if (WLAN_REG_IS_5GHZ_CH( @@ -1639,6 +1639,13 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, uint8_t sbs_channel_list[QDF_MAX_NUM_CHAN] = {0}; bool skip_dfs_channel = false; uint32_t i = 0, j = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } if ((NULL == pcl_channels) || (NULL == len)) { policy_mgr_err("pcl_channels or len is NULL"); @@ -1699,7 +1706,8 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, while ((chan_index < num_channels) && (chan_index_5 < QDF_MAX_NUM_CHAN)) { if ((true == skip_dfs_channel) && - wlan_reg_is_dfs_ch(psoc, channel_list[chan_index])) { + wlan_reg_is_dfs_ch(pm_ctx->pdev, + channel_list[chan_index])) { chan_index++; continue; } @@ -2177,11 +2185,11 @@ bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, count = policy_mgr_mode_specific_connection_count(psoc, mode, list); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); while (index < count) { - if (wlan_reg_is_dfs_ch(psoc, + if (wlan_reg_is_dfs_ch( + pm_ctx->pdev, pm_conc_connection_list[list[index]].chan) && - WLAN_REG_IS_5GHZ_CH(channel) && - (channel != - pm_conc_connection_list[list[index]].chan)) { + WLAN_REG_IS_5GHZ_CH(channel) && + (channel != pm_conc_connection_list[list[index]].chan)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_err("don't allow MCC if SAP/GO on DFS channel"); return false; diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index dad0bf96ba42..771f7e37442c 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1199,7 +1199,7 @@ QDF_STATUS policy_mgr_incr_connection_count( mode = policy_mgr_get_mode(conn_table_entry.type, conn_table_entry.sub_type); - chan = reg_freq_to_chan(conn_table_entry.mhz); + chan = wlan_reg_freq_to_chan(pm_ctx->pdev, conn_table_entry.mhz); status = policy_mgr_get_nss_for_vdev(psoc, mode, &nss_2g, &nss_5g); if (QDF_IS_STATUS_SUCCESS(status)) { if ((WLAN_REG_IS_24GHZ_CH(chan) && (nss_2g > 1)) || @@ -1488,7 +1488,7 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, goto done; if ((PM_P2P_GO_MODE == mode) || (PM_SAP_MODE == mode)) { - if (wlan_reg_is_dfs_ch(psoc, channel)) + if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel)) match = policy_mgr_disallow_mcc(psoc, channel); } if (true == match) { @@ -1512,7 +1512,7 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, goto done; } if ((PM_IBSS_MODE == mode) && - (wlan_reg_is_dfs_ch(psoc, channel)) && count) { + (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel)) && count) { policy_mgr_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel"); goto done; } @@ -1565,7 +1565,7 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, } qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (channel && - (wlan_reg_is_dfs_ch(psoc, + (wlan_reg_is_dfs_ch(pm_ctx->pdev, pm_conc_connection_list[0].chan)) && (WLAN_REG_IS_5GHZ_CH(channel))) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); @@ -2059,7 +2059,7 @@ bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { if (pm_conc_connection_list[conn_index].in_use && - !wlan_reg_is_dfs_ch(psoc, + !wlan_reg_is_dfs_ch(pm_ctx->pdev, pm_conc_connection_list[conn_index].chan)) { *channel = pm_conc_connection_list[conn_index].chan; status = true; @@ -2088,7 +2088,7 @@ bool policy_mgr_is_any_dfs_beaconing_session_present( conn_index++) { conn_info = &pm_conc_connection_list[conn_index]; if (conn_info->in_use && - wlan_reg_is_dfs_ch(psoc, conn_info->chan) && + wlan_reg_is_dfs_ch(pm_ctx->pdev, conn_info->chan) && (PM_SAP_MODE == conn_info->mode || PM_P2P_GO_MODE == conn_info->mode)) { *channel = pm_conc_connection_list[conn_index].chan; diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index a1a91be7ecd2..8dd4e4ddb457 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -33,36 +33,7 @@ #include "qdf_mc_timer.h" #include "qdf_lock.h" #include "qdf_defer.h" - -#include - -enum cds_band_type { - CDS_BAND_ALL = 0, - CDS_BAND_2GHZ = 1, - CDS_BAND_5GHZ = 2 -}; - -extern uint32_t cds_chan_to_freq(uint8_t chan); -extern uint8_t cds_freq_to_chan(uint32_t freq); -extern enum cds_band_type cds_chan_to_band(uint32_t chan); - -#define WLAN_REG_IS_24GHZ_CH(ch) CDS_IS_CHANNEL_24GHZ(ch) -#define WLAN_REG_IS_5GHZ_CH(ch) CDS_IS_CHANNEL_5GHZ(ch) -#define WLAN_REG_IS_SAME_BAND_CHANNELS(ch1, ch2) \ - CDS_IS_SAME_BAND_CHANNELS(ch1, ch2) -#define WLAN_REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \ - CDS_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) -#define wlan_reg_is_dfs_ch(psoc, ch) CDS_IS_DFS_CH(ch) -#define wlan_reg_is_passive_or_disable_ch(ch) \ - CDS_IS_PASSIVE_OR_DISABLE_CH(ch) -#define WLAN_REG_MAX_24GHZ_CH_NUM CDS_MAX_24GHZ_CHANNEL_NUMBER -#define reg_chan_to_freq(chan_num) cds_chan_to_freq(chan_num) -#define reg_freq_to_chan(freq) cds_freq_to_chan(freq) -#define reg_chan_to_band(chan_num) cds_chan_to_band(chan_num) -#define BAND_2G CDS_BAND_2GHZ -#define BAND_5G CDS_BAND_5GHZ -#define BAND_ALL CDS_BAND_ALL - +#include "wlan_reg_services_api.h" #define MAX_NUMBER_OF_CONC_CONNECTIONS 3 #define DBS_OPPORTUNISTIC_TIME 10 @@ -213,6 +184,7 @@ extern enum policy_mgr_conc_next_action /** * struct policy_mgr_psoc_priv_obj - Policy manager private data * @psoc: pointer to PSOC object information + * @pdev: pointer to PDEV object information * @connection_update_done_evt: qdf event to synchronize * connection activities * @qdf_conc_list_lock: To protect connection table @@ -255,6 +227,7 @@ extern enum policy_mgr_conc_next_action */ struct policy_mgr_psoc_priv_obj { struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; qdf_event_t connection_update_done_evt; qdf_mutex_t qdf_conc_list_lock; qdf_mc_timer_t dbs_opportunistic_timer; diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 63c7b43be190..9c2fde0ae2d3 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -86,6 +86,42 @@ static void policy_mgr_psoc_obj_status_cb(struct wlan_objmgr_psoc *psoc, return; } +static QDF_STATUS policy_mgr_pdev_obj_create_cb(struct wlan_objmgr_pdev *pdev, + void *data) +{ + struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + policy_mgr_ctx = policy_mgr_get_context(psoc); + if (!policy_mgr_ctx) { + policy_mgr_err("invalid context"); + return QDF_STATUS_E_FAILURE; + } + + policy_mgr_ctx->pdev = pdev; + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS policy_mgr_pdev_obj_destroy_cb(struct wlan_objmgr_pdev *pdev, + void *data) +{ + struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; + struct wlan_objmgr_psoc *psoc; + + psoc = wlan_pdev_get_psoc(pdev); + policy_mgr_ctx = policy_mgr_get_context(psoc); + if (!policy_mgr_ctx) { + policy_mgr_err("invalid context"); + return QDF_STATUS_E_FAILURE; + } + + policy_mgr_ctx->pdev = NULL; + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS policy_mgr_vdev_obj_create_cb(struct wlan_objmgr_vdev *vdev, void *data) { @@ -134,6 +170,24 @@ QDF_STATUS policy_mgr_init(void) goto err_psoc_status; } + status = wlan_objmgr_register_pdev_create_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_pdev_obj_create_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to register pdev obj create cback"); + goto err_pdev_create; + } + + status = wlan_objmgr_register_pdev_destroy_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_pdev_obj_destroy_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to register pdev obj delete cback"); + goto err_pdev_delete; + } + status = wlan_objmgr_register_vdev_create_handler( WLAN_UMAC_COMP_POLICY_MGR, policy_mgr_vdev_obj_create_cb, @@ -167,19 +221,32 @@ QDF_STATUS policy_mgr_init(void) err_vdev_status: wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_vdev_obj_destroy_cb, NULL); + policy_mgr_vdev_obj_destroy_cb, + NULL); err_vdev_delete: wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_vdev_obj_create_cb, NULL); + policy_mgr_vdev_obj_create_cb, + NULL); err_vdev_create: + wlan_objmgr_unregister_pdev_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_pdev_obj_destroy_cb, + NULL); +err_pdev_delete: + wlan_objmgr_unregister_pdev_create_handler(WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_pdev_obj_create_cb, + NULL); +err_pdev_create: wlan_objmgr_unregister_psoc_status_handler(WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_psoc_obj_status_cb, NULL); + policy_mgr_psoc_obj_status_cb, + NULL); err_psoc_status: wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_psoc_obj_destroy_cb, NULL); + policy_mgr_psoc_obj_destroy_cb, + NULL); err_psoc_delete: wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_psoc_obj_create_cb, NULL); + policy_mgr_psoc_obj_create_cb, + NULL); err_psoc_create: return status; } @@ -188,12 +255,12 @@ QDF_STATUS policy_mgr_deinit(void) { QDF_STATUS status; - status = wlan_objmgr_unregister_psoc_create_handler( + status = wlan_objmgr_unregister_psoc_status_handler( WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_psoc_obj_create_cb, + policy_mgr_psoc_obj_status_cb, NULL); if (status != QDF_STATUS_SUCCESS) - policy_mgr_err("Failed to deregister psoc obj create cback"); + policy_mgr_err("Failed to deregister psoc obj status cback"); status = wlan_objmgr_unregister_psoc_destroy_handler( WLAN_UMAC_COMP_POLICY_MGR, @@ -202,19 +269,33 @@ QDF_STATUS policy_mgr_deinit(void) if (status != QDF_STATUS_SUCCESS) policy_mgr_err("Failed to deregister psoc obj delete cback"); - status = wlan_objmgr_unregister_psoc_status_handler( + status = wlan_objmgr_unregister_psoc_create_handler( WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_psoc_obj_status_cb, + policy_mgr_psoc_obj_create_cb, NULL); if (status != QDF_STATUS_SUCCESS) - policy_mgr_err("Failed to deregister psoc obj status cback"); + policy_mgr_err("Failed to deregister psoc obj create cback"); - status = wlan_objmgr_unregister_vdev_create_handler( + status = wlan_objmgr_unregister_pdev_destroy_handler( WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_vdev_obj_create_cb, + policy_mgr_pdev_obj_destroy_cb, NULL); if (status != QDF_STATUS_SUCCESS) - policy_mgr_err("Failed to deregister vdev obj create cback"); + policy_mgr_err("Failed to deregister pdev obj delete cback"); + + status = wlan_objmgr_unregister_pdev_create_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_pdev_obj_create_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to deregister pdev obj create cback"); + + status = wlan_objmgr_unregister_vdev_status_handler( + WLAN_UMAC_COMP_POLICY_MGR, + policy_mgr_vdev_obj_status_cb, + NULL); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to deregister vdev obj status cback"); status = wlan_objmgr_unregister_vdev_destroy_handler( WLAN_UMAC_COMP_POLICY_MGR, @@ -223,12 +304,12 @@ QDF_STATUS policy_mgr_deinit(void) if (status != QDF_STATUS_SUCCESS) policy_mgr_err("Failed to deregister vdev obj delete cback"); - status = wlan_objmgr_unregister_vdev_status_handler( + status = wlan_objmgr_unregister_vdev_create_handler( WLAN_UMAC_COMP_POLICY_MGR, - policy_mgr_vdev_obj_status_cb, + policy_mgr_vdev_obj_create_cb, NULL); if (status != QDF_STATUS_SUCCESS) - policy_mgr_err("Failed to deregister vdev obj status cback"); + policy_mgr_err("Failed to deregister vdev obj create cback"); policy_mgr_info("deregistered callbacks with obj mgr successfully"); diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index edc96138353e..364bced7357d 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -140,16 +140,18 @@ void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels, } static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels( - uint8_t *pcl_list_org, - uint8_t *weight_list_org, - uint32_t *pcl_len_org) + struct policy_mgr_psoc_priv_obj *pm_ctx, + uint8_t *pcl_list_org, + uint8_t *weight_list_org, + uint32_t *pcl_len_org) { uint32_t i, pcl_len = 0; uint8_t pcl_list[QDF_MAX_NUM_CHAN]; uint8_t weight_list[QDF_MAX_NUM_CHAN]; for (i = 0; i < *pcl_len_org; i++) { - if (!wlan_reg_is_passive_or_disable_ch(pcl_list_org[i])) { + if (!wlan_reg_is_passive_or_disable_ch( + pm_ctx->pdev, pcl_list_org[i])) { pcl_list[pcl_len] = pcl_list_org[i]; weight_list[pcl_len++] = weight_list_org[i]; } @@ -320,7 +322,7 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, if (mode == PM_P2P_GO_MODE) { status = policy_mgr_modify_pcl_based_on_enabled_channels( - pcl_channels, pcl_weight, len); + pm_ctx, pcl_channels, pcl_weight, len); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("failed to get modified pcl for GO"); return status; @@ -1104,6 +1106,7 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, { uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; uint8_t pcl_weight[QDF_MAX_NUM_CHAN]; + struct policy_mgr_psoc_priv_obj *pm_ctx; /* * in worst case if we can't find any channel at all @@ -1113,6 +1116,12 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, uint8_t channel = PM_24_GHZ_CHANNEL_6; uint32_t i, pcl_len; + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return channel; + } + if (true == for_existing_conn) { /* * First try to see if there is any non-dfs channel already @@ -1136,7 +1145,7 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, } for (i = 0; i < pcl_len; i++) { - if (wlan_reg_is_dfs_ch(psoc, pcl_channels[i])) { + if (wlan_reg_is_dfs_ch(pm_ctx->pdev, pcl_channels[i])) { continue; } else { channel = pcl_channels[i]; From 9d0085ee8ba1610432920613957688ce1e1eedc5 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Date: Mon, 17 Apr 2017 17:00:41 -0700 Subject: [PATCH 046/404] qcacmn: Initialize scheduler_msg on stack before posting message Initialize scheduler_msg on stack before posting using scheduler API such that un-used fields in message structure are initialized to 0. Change-Id: Ib3183b2c65eb9affd6610f4572c751c39a25fff7 CRs-Fixed: 2034772 --- core/src/wlan_p2p_main.c | 2 +- dispatcher/src/wlan_p2p_tgt_api.c | 8 ++++---- dispatcher/src/wlan_p2p_ucfg_api.c | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 96d472b510b8..e77a16cc6293 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -297,7 +297,7 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( static QDF_STATUS p2p_send_noa_to_pe(struct p2p_noa_info *noa_info) { struct p2p_noa_attr *noa_attr; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; if (!noa_info) { p2p_err("noa info is null"); diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index b72e52894315..3756a8d733d5 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -127,7 +127,7 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, struct p2p_tx_conf_event *tx_conf_event; struct p2p_soc_priv_obj *p2p_soc_obj; struct tx_action_context *tx_ctx; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; p2p_debug("context:%p, buf:%p, status:%d, tx complete params:%p", context, buf, status, tx_compl_params); @@ -176,7 +176,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, struct p2p_rx_mgmt_frame *rx_mgmt; struct p2p_rx_mgmt_event *rx_mgmt_event; struct p2p_soc_priv_obj *p2p_soc_obj; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct wlan_frame_hdr *wh; struct wlan_objmgr_vdev *vdev; struct p2p_roc_context *roc_ctx; @@ -257,7 +257,7 @@ QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, struct p2p_noa_info *event_info) { struct p2p_noa_event *noa_event; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; p2p_debug("soc:%p, event_info:%p", psoc, event_info); @@ -304,7 +304,7 @@ QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, struct p2p_lo_event *event_info) { struct p2p_lo_stop_event *lo_stop_event; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; p2p_debug("soc:%p, event_info:%p", psoc, event_info); diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 977a514b96d3..543ef5417f8d 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -69,7 +69,7 @@ QDF_STATUS ucfg_p2p_psoc_stop(struct wlan_objmgr_psoc *soc) QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, struct p2p_roc_req *roc_req, uint64_t *cookie) { - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_roc_context *roc_ctx; @@ -114,7 +114,7 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, uint64_t cookie) { - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; struct cancel_roc_context *cancel_roc; @@ -151,7 +151,7 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, struct p2p_mgmt_tx *mgmt_frm, uint64_t *cookie) { - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; struct tx_action_context *tx_action; @@ -210,7 +210,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, uint64_t cookie) { - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; struct cancel_roc_context *cancel_tx; From c3aad438f3068a0c49c99687cac570b6eff2c946 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Mon, 13 Mar 2017 21:30:21 +0800 Subject: [PATCH 047/404] qcacmn: TDLS component: core peer operations TDLS peer operations: add, delete and update TDLS peer Change-Id: I7dba1a4b2b3b8597935db811da68ee5ba630bf4d CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 1148 +++++++++++++++++++++ core/src/wlan_tdls_cmds_process.h | 174 ++++ core/src/wlan_tdls_main.c | 110 +- core/src/wlan_tdls_main.h | 93 +- core/src/wlan_tdls_peer.c | 836 +++++++++++++++ core/src/wlan_tdls_peer.h | 245 +++++ dispatcher/inc/wlan_tdls_public_structs.h | 231 ++++- dispatcher/inc/wlan_tdls_ucfg_api.h | 28 +- dispatcher/src/wlan_tdls_ucfg_api.c | 143 ++- 9 files changed, 2924 insertions(+), 84 deletions(-) create mode 100644 core/src/wlan_tdls_peer.c create mode 100644 core/src/wlan_tdls_peer.h diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 7a6aa6cb4953..12dde2563df9 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -21,3 +21,1151 @@ * * TDLS north bound commands implementation */ +#include +#include "wlan_tdls_main.h" +#include "wlan_tdls_peer.h" +#include "wlan_tdls_cmds_process.h" + +static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) +{ + return soc_obj->connected_peer_count; +} + +/** + * tdls_decrement_peer_count() - decrement connected TDLS peer counter + * @soc_obj: TDLS soc object + * + * Return: None. + */ +static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) +{ + if (soc_obj->connected_peer_count) + soc_obj->connected_peer_count--; + + tdls_debug("Connected peer count %d", soc_obj->connected_peer_count); +} + +/** + * tdls_validate_current_mode() - check current TDL mode + * @soc_obj: TDLS soc object + * + * Return: QDF_STATUS_SUCCESS if TDLS enabled, other for disabled + */ +static QDF_STATUS tdls_validate_current_mode(struct tdls_soc_priv_obj *soc_obj) +{ + if (soc_obj->tdls_current_mode == TDLS_SUPPORT_DISABLED || + soc_obj->tdls_current_mode == TDLS_SUPPORT_SUSPENDED) { + tdls_err("TDLS mode disabled OR not enabled, current mode %d", + soc_obj->tdls_current_mode); + return QDF_STATUS_E_NOSUPPORT; + } + return QDF_STATUS_SUCCESS; +} + +static char *tdls_get_ser_cmd_str(enum wlan_serialization_cmd_type type) +{ + switch (type) { + case WLAN_SER_CMD_TDLS_ADD_PEER: + return "TDLS_ADD_PEER_CMD"; + case WLAN_SER_CMD_TDLS_DEL_PEER: + return "TDLS_DEL_PEER_CMD"; + case WLAN_SER_CMD_TDLS_SEND_MGMT: + return "TDLS_SEND_MGMT_CMD"; + default: + return "UNKNOWN"; + } +} + +static void +tdls_release_serialization_command(struct wlan_objmgr_vdev *vdev, + enum wlan_serialization_cmd_type type) +{ + struct wlan_serialization_queued_cmd_info cmd = {0}; + + cmd.cmd_type = type; + cmd.cmd_id = 0; + cmd.vdev = vdev; + + tdls_debug("release %s", tdls_get_ser_cmd_str(type)); + /* Inform serialization for command completion */ + wlan_serialization_remove_cmd(&cmd); +} + +/** + * tdls_pe_add_peer() - send TDLS add peer request to PE + * @req: TDL add peer request + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) +{ + struct tdls_add_sta_req *addstareq; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct scheduler_msg msg = {0,}; + QDF_STATUS status; + + addstareq = qdf_mem_malloc(sizeof(*addstareq)); + if (!addstareq) { + tdls_err("allocate failed"); + return QDF_STATUS_E_NOMEM; + } + vdev = req->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("NULL tdls soc object"); + status = QDF_STATUS_E_INVAL; + goto error; + } + + addstareq->tdls_oper = TDLS_OPER_ADD; + addstareq->transaction_id = 0; + + wlan_vdev_obj_lock(vdev); + addstareq->session_id = wlan_vdev_get_id(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + if (!peer) { + wlan_vdev_obj_unlock(vdev); + tdls_err("bss peer is NULL"); + status = QDF_STATUS_E_INVAL; + goto error; + } + wlan_vdev_obj_unlock(vdev); + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get bss peer"); + goto error; + } + wlan_peer_obj_lock(peer); + qdf_mem_copy(addstareq->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); + qdf_mem_copy(addstareq->peermac.bytes, req->add_peer_req.peer_addr, + QDF_MAC_ADDR_SIZE); + + tdls_debug("for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); + msg.type = soc_obj->tdls_add_sta_req; + msg.bodyptr = addstareq; + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("fail to post pe msg to add peer"); + goto error; + } + return status; +error: + qdf_mem_free(addstareq); + return status; +} + +/** + * tdls_pe_del_peer() - send TDLS delete peer request to PE + * @req: TDLS delete peer request + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) +{ + struct tdls_del_sta_req *delstareq; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct scheduler_msg msg = {0,}; + QDF_STATUS status; + + delstareq = qdf_mem_malloc(sizeof(*delstareq)); + if (!delstareq) { + tdls_err("allocate failed"); + return QDF_STATUS_E_NOMEM; + } + vdev = req->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("NULL tdls soc object"); + status = QDF_STATUS_E_INVAL; + goto error; + } + + delstareq->transaction_id = 0; + + wlan_vdev_obj_lock(vdev); + delstareq->session_id = wlan_vdev_get_id(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + if (!peer) { + wlan_vdev_obj_unlock(vdev); + tdls_err("bss peer is NULL"); + status = QDF_STATUS_E_INVAL; + goto error; + } + wlan_vdev_obj_unlock(vdev); + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get bss peer"); + goto error; + } + wlan_peer_obj_lock(peer); + qdf_mem_copy(delstareq->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); + qdf_mem_copy(delstareq->peermac.bytes, req->del_peer_req.peer_addr, + QDF_MAC_ADDR_SIZE); + + tdls_debug("for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(delstareq->peermac.bytes)); + msg.type = soc_obj->tdls_del_sta_req; + msg.bodyptr = delstareq; + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("fail to post pe msg to del peer"); + goto error; + } + return status; +error: + qdf_mem_free(delstareq); + return status; +} + +/** + * tdls_pe_update_peer() - send TDLS update peer request to PE + * @req: TDLS update peer request + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) +{ + struct tdls_add_sta_req *addstareq; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct scheduler_msg msg = {0,}; + struct tdls_update_peer_params *update_peer; + QDF_STATUS status; + + addstareq = qdf_mem_malloc(sizeof(*addstareq)); + if (!addstareq) { + tdls_err("allocate failed"); + return QDF_STATUS_E_NOMEM; + } + vdev = req->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("NULL tdls soc object"); + status = QDF_STATUS_E_INVAL; + goto error; + } + update_peer = &req->update_peer_req; + + addstareq->tdls_oper = TDLS_OPER_UPDATE; + addstareq->transaction_id = 0; + + wlan_vdev_obj_lock(vdev); + addstareq->session_id = wlan_vdev_get_id(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + if (!peer) { + wlan_vdev_obj_unlock(vdev); + tdls_err("bss peer is NULL"); + status = QDF_STATUS_E_INVAL; + goto error; + } + wlan_vdev_obj_unlock(vdev); + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get bss peer"); + goto error; + } + wlan_peer_obj_lock(peer); + qdf_mem_copy(addstareq->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); + qdf_mem_copy(addstareq->peermac.bytes, update_peer->peer_addr, + QDF_MAC_ADDR_SIZE); + addstareq->capability = update_peer->capability; + addstareq->uapsd_queues = update_peer->uapsd_queues; + addstareq->max_sp = update_peer->max_sp; + + qdf_mem_copy(addstareq->extn_capability, + update_peer->extn_capability, WLAN_MAC_MAX_EXTN_CAP); + addstareq->htcap_present = update_peer->htcap_present; + qdf_mem_copy(&addstareq->ht_cap, + &update_peer->ht_cap, + sizeof(update_peer->ht_cap)); + addstareq->vhtcap_present = update_peer->vhtcap_present; + qdf_mem_copy(&addstareq->vht_cap, + &update_peer->vht_cap, + sizeof(update_peer->vht_cap)); + addstareq->supported_rates_length = update_peer->supported_rates_len; + qdf_mem_copy(&addstareq->supported_rates, + update_peer->supported_rates, + update_peer->supported_rates_len); + tdls_debug("for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); + + msg.type = soc_obj->tdls_add_sta_req; + msg.bodyptr = addstareq; + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("fail to post pe msg to update peer"); + goto error; + } + return status; +error: + qdf_mem_free(addstareq); + return status; +} + +static QDF_STATUS +tdls_internal_add_peer_rsp(struct tdls_add_peer_request *req, + QDF_STATUS status) +{ + struct tdls_soc_priv_obj *soc_obj; + struct wlan_objmgr_vdev *vdev; + struct tdls_osif_indication ind; + QDF_STATUS ret; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + return QDF_STATUS_E_INVAL; + } + vdev = req->vdev; + ret = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_SB_ID); + if (QDF_IS_STATUS_ERROR(ret)) { + tdls_err("can't get vdev object"); + return ret; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = vdev; + ind.status = status; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +tdls_internal_update_peer_rsp(struct tdls_update_peer_request *req, + QDF_STATUS status) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_osif_indication ind; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS ret; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + return QDF_STATUS_E_INVAL; + } + vdev = req->vdev; + ret = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_SB_ID); + if (QDF_IS_STATUS_ERROR(ret)) { + tdls_err("can't get vdev object"); + return ret; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = vdev; + ind.status = status; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tdls_internal_del_peer_rsp(struct tdls_oper_request *req) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_osif_indication ind; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + return QDF_STATUS_E_INVAL; + } + vdev = req->vdev; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev object"); + return status; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = req->vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_DEL_PEER, &ind); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_peer *peer; + uint16_t curr_tdls_peers; + const uint8_t *mac; + struct tdls_osif_indication ind; + + if (!req->vdev) { + tdls_err("vdev null when add tdls peer"); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + mac = req->add_peer_req.peer_addr; + soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); + + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + return QDF_STATUS_E_INVAL; + } + status = tdls_validate_current_mode(soc_obj); + if (QDF_IS_STATUS_ERROR(status)) + goto addrsp; + + peer = tdls_get_peer(vdev_obj, mac); + if (!peer) { + tdls_err("peer: " QDF_MAC_ADDRESS_STR " not exist. invalid", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto addrsp; + } + + /* in add station, we accept existing valid sta_id if there is */ + if ((peer->link_status > TDLS_LINK_CONNECTING) || + (TDLS_STA_INDEX_CHECK((peer->sta_id)))) { + tdls_notice("link_status %d sta_id %d add peer ignored", + peer->link_status, peer->sta_id); + status = QDF_STATUS_SUCCESS; + goto addrsp; + } + + /* when others are on-going, we want to change link_status to idle */ + if (tdls_is_progress(vdev_obj, mac, true)) { + tdls_notice(QDF_MAC_ADDRESS_STR " TDLS setuping. Req declined.", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_PERM; + goto setlink; + } + + /* first to check if we reached to maximum supported TDLS peer. */ + curr_tdls_peers = tdls_get_connected_peer(soc_obj); + if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { + tdls_err(QDF_MAC_ADDRESS_STR + " Request declined. Current %d, Max allowed %d.", + QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, + soc_obj->max_num_tdls_sta); + status = QDF_STATUS_E_PERM; + goto setlink; + } + + tdls_set_peer_link_status(peer, + TDLS_LINK_CONNECTING, TDLS_LINK_SUCCESS); + + status = tdls_pe_add_peer(req); + if (QDF_IS_STATUS_ERROR(status)) + goto setlink; + + return QDF_STATUS_SUCCESS; + +setlink: + tdls_set_link_status(vdev_obj, mac, TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); +addrsp: + if (soc_obj->tdls_event_cb) { + ind.status = status; + ind.vdev = req->vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + + return QDF_STATUS_E_PERM; +} + +static QDF_STATUS +tdls_add_peer_serialize_callback(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + struct tdls_add_peer_request *req; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!cmd || !cmd->umac_cmd) { + tdls_err("cmd: %p, reason: %d", cmd, reason); + return QDF_STATUS_E_NULL_VALUE; + } + + req = cmd->umac_cmd; + tdls_debug("reason: %d, req %p", reason, req); + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* command moved to active list + */ + status = tdls_activate_add_peer(req); + break; + + case WLAN_SER_CB_CANCEL_CMD: + /* command removed from pending list. + * notify os interface the status + */ + status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); + break; + + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + /* active command time out. */ + status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command successfully completed. + * release memory & vdev reference count + */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + break; + + default: + /* Do nothing but logging */ + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) +{ + struct wlan_serialization_command cmd = {0,}; + enum wlan_serialization_status ser_cmd_status; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + status = QDF_STATUS_E_INVAL; + goto error; + } + vdev = req->vdev; + cmd.cmd_type = WLAN_SER_CMD_TDLS_ADD_PEER; + cmd.cmd_id = 0; + cmd.cmd_cb = (wlan_serialization_cmd_callback) + tdls_add_peer_serialize_callback; + cmd.umac_cmd = req; + cmd.source = WLAN_UMAC_COMP_TDLS; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; + cmd.vdev = vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + ser_cmd_status); + + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list. Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + case WLAN_SER_CMD_DENIED_LIST_FULL: + case WLAN_SER_CMD_DENIED_RULES_FAILED: + case WLAN_SER_CMD_DENIED_UNSPECIFIED: + /* notify os interface about internal error*/ + status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + /* cmd can't be serviced. + * release tdls_add_peer_request memory + */ + qdf_mem_free(req); + break; + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + goto error; + } + + return status; +error: + status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); + qdf_mem_free(req); + return status; +} + +static QDF_STATUS +tdls_activate_update_peer(struct tdls_update_peer_request *req) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct wlan_objmgr_vdev *vdev; + struct tdls_peer *curr_peer; + uint16_t curr_tdls_peers; + const uint8_t *mac; + struct tdls_update_peer_params *update_peer; + struct tdls_osif_indication ind; + + if (!req->vdev) { + tdls_err("vdev object NULL when add TDLS peer"); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + mac = req->update_peer_req.peer_addr; + vdev = req->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + return QDF_STATUS_E_INVAL; + } + + status = tdls_validate_current_mode(soc_obj); + if (QDF_IS_STATUS_ERROR(status)) + goto updatersp; + + curr_peer = tdls_get_peer(vdev_obj, mac); + if (!curr_peer) { + tdls_err(QDF_MAC_ADDRESS_STR " not exist. return invalid", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto updatersp; + } + + /* in change station, we accept only when sta_id is valid */ + if (curr_peer->link_status > TDLS_LINK_CONNECTING || + !(TDLS_STA_INDEX_CHECK(curr_peer->sta_id))) { + tdls_err(QDF_MAC_ADDRESS_STR " link %d. sta %d. update peer %s", + QDF_MAC_ADDR_ARRAY(mac), curr_peer->link_status, + curr_peer->sta_id, + (TDLS_STA_INDEX_CHECK(curr_peer->sta_id)) ? "ignored" + : "declined"); + status = (TDLS_STA_INDEX_CHECK(curr_peer->sta_id)) ? + QDF_STATUS_SUCCESS : QDF_STATUS_E_PERM; + goto updatersp; + } + + /* when others are on-going, we want to change link_status to idle */ + if (tdls_is_progress(vdev_obj, mac, true)) { + tdls_notice(QDF_MAC_ADDRESS_STR " TDLS setuping. Req declined.", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_PERM; + goto setlink; + } + + curr_tdls_peers = tdls_get_connected_peer(soc_obj); + if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { + tdls_err(QDF_MAC_ADDRESS_STR + " Request declined. Current: %d, Max allowed: %d.", + QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, + soc_obj->max_num_tdls_sta); + status = QDF_STATUS_E_PERM; + goto setlink; + } + update_peer = &req->update_peer_req; + + if (update_peer->htcap_present) + curr_peer->spatial_streams = update_peer->ht_cap.mcsset[1]; + + tdls_set_peer_caps(vdev_obj, mac, &req->update_peer_req); + status = tdls_pe_update_peer(req); + if (QDF_IS_STATUS_ERROR(status)) + goto setlink; + + return QDF_STATUS_SUCCESS; + +setlink: + tdls_set_link_status(vdev_obj, mac, TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); +updatersp: + if (soc_obj->tdls_event_cb) { + ind.status = status; + ind.vdev = vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + + return QDF_STATUS_E_PERM; +} + +static QDF_STATUS +tdls_update_peer_serialize_callback(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + struct tdls_update_peer_request *req; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!cmd || !cmd->umac_cmd) { + tdls_err("cmd: %p, reason: %d", cmd, reason); + return QDF_STATUS_E_NULL_VALUE; + } + + req = cmd->umac_cmd; + tdls_debug("reason: %d, req %p", reason, req); + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* command moved to active list + */ + status = tdls_activate_update_peer(req); + break; + + case WLAN_SER_CB_CANCEL_CMD: + /* command removed from pending list. + * notify os interface the status + */ + status = tdls_internal_update_peer_rsp(req, + QDF_STATUS_E_FAILURE); + break; + + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + /* active command time out. */ + status = tdls_internal_update_peer_rsp(req, + QDF_STATUS_E_FAILURE); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command successfully completed. + * release memory & release reference count + */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + break; + + default: + /* Do nothing but logging */ + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) +{ + struct wlan_serialization_command cmd = {0,}; + enum wlan_serialization_status ser_cmd_status; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + status = QDF_STATUS_E_FAILURE; + goto error; + } + + vdev = req->vdev; + cmd.cmd_type = WLAN_SER_CMD_TDLS_ADD_PEER; + cmd.cmd_id = 0; + cmd.cmd_cb = (wlan_serialization_cmd_callback) + tdls_update_peer_serialize_callback; + cmd.umac_cmd = req; + cmd.source = WLAN_UMAC_COMP_TDLS; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; + cmd.vdev = req->vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + ser_cmd_status); + + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list. Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + case WLAN_SER_CMD_DENIED_LIST_FULL: + case WLAN_SER_CMD_DENIED_RULES_FAILED: + case WLAN_SER_CMD_DENIED_UNSPECIFIED: + /* notify os interface about internal error*/ + status = tdls_internal_update_peer_rsp(req, + QDF_STATUS_E_FAILURE); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + /* cmd can't be serviced. + * release tdls_add_peer_request memory + */ + qdf_mem_free(req); + break; + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +error: + status = tdls_internal_update_peer_rsp(req, QDF_STATUS_E_FAILURE); + qdf_mem_free(req); + return status; +} + +static QDF_STATUS tdls_activate_del_peer(struct tdls_oper_request *req) +{ + struct tdls_del_peer_request request = {0,}; + + request.vdev = req->vdev; + request.del_peer_req.peer_addr = req->peer_addr; + + return tdls_pe_del_peer(&request); +} + +static QDF_STATUS +tdls_del_peer_serialize_callback(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + struct tdls_oper_request *req; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!cmd || !cmd->umac_cmd) { + tdls_err("cmd: %p, reason: %d", cmd, reason); + return QDF_STATUS_E_NULL_VALUE; + } + + req = cmd->umac_cmd; + tdls_debug("reason: %d, req %p", reason, req); + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* command moved to active list + */ + status = tdls_activate_del_peer(req); + break; + + case WLAN_SER_CB_CANCEL_CMD: + /* command removed from pending list. + * notify os interface the status + */ + status = tdls_internal_del_peer_rsp(req); + break; + + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + /* active command time out. */ + status = tdls_internal_del_peer_rsp(req); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command successfully completed. + * release memory & vdev reference count + */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + break; + + default: + /* Do nothing but logging */ + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) +{ + struct wlan_serialization_command cmd = {0,}; + enum wlan_serialization_status ser_cmd_status; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + status = QDF_STATUS_E_INVAL; + goto error; + } + vdev = req->vdev; + cmd.cmd_type = WLAN_SER_CMD_TDLS_DEL_PEER; + cmd.cmd_id = 0; + cmd.cmd_cb = (wlan_serialization_cmd_callback) + tdls_del_peer_serialize_callback; + cmd.umac_cmd = req; + cmd.source = WLAN_UMAC_COMP_TDLS; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = WAIT_TIME_TDLS_DEL_STA; + cmd.vdev = vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + ser_cmd_status); + + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list. Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + case WLAN_SER_CMD_DENIED_LIST_FULL: + case WLAN_SER_CMD_DENIED_RULES_FAILED: + case WLAN_SER_CMD_DENIED_UNSPECIFIED: + /* notify os interface about internal error*/ + status = tdls_internal_del_peer_rsp(req); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + /* cmd can't be serviced. + * release tdls_add_peer_request memory + */ + qdf_mem_free(req); + break; + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +error: + status = tdls_internal_del_peer_rsp(req); + qdf_mem_free(req); + return status; +} + +/** + * tdls_process_add_peer_rsp() - handle response for update TDLS peer + * @rsp: TDLS add peer response + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +static QDF_STATUS tdls_update_peer_rsp(struct tdls_add_sta_rsp *rsp) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_soc_priv_obj *soc_obj; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_osif_indication ind; + + psoc = rsp->psoc; + if (!psoc) { + tdls_err("psoc is NULL"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("invalid vdev: %d", rsp->session_id); + status = QDF_STATUS_E_INVAL; + goto error; + } + + tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_ADD_PEER); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +error: + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (soc_obj && soc_obj->tdls_event_cb) { + ind.status = rsp->status_code; + ind.vdev = vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + qdf_mem_free(rsp); + + return status; +} + +/** + * tdls_process_add_peer_rsp() - handle response for add TDLS peer + * @rsp: TDLS add peer response + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) +{ + uint8_t sta_idx; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj = NULL; + struct tdls_conn_info *conn_rec; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_osif_indication ind; + + psoc = rsp->psoc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("invalid vdev: %d", rsp->session_id); + status = QDF_STATUS_E_INVAL; + goto error; + } + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!soc_obj || !vdev_obj) { + tdls_err("soc object:%p, vdev object:%p", soc_obj, vdev_obj); + status = QDF_STATUS_E_FAILURE; + goto cmddone; + } + if (rsp->status_code) { + tdls_err("add sta failed. status code(=%d)", rsp->status_code); + status = QDF_STATUS_E_FAILURE; + } else { + conn_rec = soc_obj->tdls_conn_info; + for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; + sta_idx++) { + if (0 == conn_rec[sta_idx].sta_id) { + conn_rec[sta_idx].session_id = rsp->session_id; + conn_rec[sta_idx].sta_id = rsp->sta_id; + qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, + &rsp->peermac); + tdls_warn("TDLS: STA IDX at %d is %d of mac " + QDF_MAC_ADDRESS_STR, sta_idx, + rsp->sta_id, QDF_MAC_ADDR_ARRAY + (rsp->peermac.bytes)); + break; + } + } + + if (sta_idx < soc_obj->max_num_tdls_sta) { + status = tdls_set_sta_id(vdev_obj, rsp->peermac.bytes, + rsp->sta_id); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("set staid failed"); + status = QDF_STATUS_E_FAILURE; + goto cmddone; + } + + tdls_set_signature(vdev_obj, rsp->peermac.bytes, + rsp->ucast_sig); + } else { + status = QDF_STATUS_E_FAILURE; + } + } + +cmddone: + tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_ADD_PEER); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +error: + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = vdev; + ind.status = rsp->status_code; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + qdf_mem_free(rsp); + + return status; +} + +QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp) +{ + tdls_debug("peer oper %d", rsp->tdls_oper); + + if (rsp->tdls_oper == TDLS_OPER_ADD) + return tdls_add_peer_rsp(rsp); + else if (rsp->tdls_oper == TDLS_OPER_UPDATE) + return tdls_update_peer_rsp(rsp); + + return QDF_STATUS_E_INVAL; +} + +QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) +{ + uint8_t sta_idx, id; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj = NULL; + struct tdls_conn_info *conn_rec; + struct tdls_peer *curr_peer = NULL; + const uint8_t *macaddr; + struct tdls_osif_indication ind; + + tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDRESS_STR, + rsp->session_id, QDF_MAC_ADDR_ARRAY(rsp->peermac.bytes)); + psoc = rsp->psoc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("invalid vdev: %d", rsp->session_id); + status = QDF_STATUS_E_INVAL; + goto error; + } + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!soc_obj || !vdev_obj) { + tdls_err("soc object:%p, vdev object:%p", soc_obj, vdev_obj); + status = QDF_STATUS_E_FAILURE; + goto cmddone; + } + + conn_rec = soc_obj->tdls_conn_info; + for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { + if (conn_rec[sta_idx].session_id != rsp->session_id || + conn_rec[sta_idx].sta_id != rsp->sta_id) + continue; + + macaddr = rsp->peermac.bytes; + tdls_warn("TDLS: del STA IDX = %x", rsp->sta_id); + curr_peer = tdls_find_peer(vdev_obj, macaddr); + if (curr_peer) { + tdls_debug(QDF_MAC_ADDRESS_STR " status is %d", + QDF_MAC_ADDR_ARRAY(macaddr), + curr_peer->link_status); + wlan_vdev_obj_lock(vdev); + id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + if (TDLS_IS_CONNECTED(curr_peer)) { + soc_obj->tdls_dereg_tl_peer( + soc_obj->tdls_tl_peer_data, + id, curr_peer->sta_id); + tdls_decrement_peer_count(soc_obj); + } else if (TDLS_LINK_CONNECTING == + curr_peer->link_status) { + soc_obj->tdls_dereg_tl_peer( + soc_obj->tdls_tl_peer_data, + id, curr_peer->sta_id); + } + } + tdls_reset_peer(vdev_obj, macaddr); + conn_rec[sta_idx].sta_id = 0; + conn_rec[sta_idx].session_id = 0xff; + qdf_mem_zero(&conn_rec[sta_idx].peer_mac, + QDF_MAC_ADDR_SIZE); + + status = QDF_STATUS_SUCCESS; + break; + } + macaddr = rsp->peermac.bytes; + if (!curr_peer) { + curr_peer = tdls_find_peer(vdev_obj, macaddr); + + if (curr_peer) + tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE, + (curr_peer->link_status == + TDLS_LINK_TEARING) ? + TDLS_LINK_UNSPECIFIED : + TDLS_LINK_DROPPED_BY_REMOTE); + } + +cmddone: + tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_DEL_PEER); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +error: + + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_DEL_PEER, &ind); + } + qdf_mem_free(rsp); + + return status; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index a90931846aba..253403f55047 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -21,3 +21,177 @@ * * TDLS north bound commands include file */ + +#ifndef _WLAN_TDLS_CMDS_PROCESS_H_ +#define _WLAN_TDLS_CMDS_PROCESS_H_ + +/** + * enum tdls_add_oper - add peer type + * @TDLS_OPER_NONE: none + * @TDLS_OPER_ADD: add new peer + * @TDLS_OPER_UPDATE: used to update peer + */ +enum tdls_add_oper { + TDLS_OPER_NONE, + TDLS_OPER_ADD, + TDLS_OPER_UPDATE +}; + +/** + * struct tdls_add_sta_req - TDLS request struct TDLS module --> PE + * same as struct tSirTdlsAddStaReq; + * @message_type: eWNI_SME_TDLS_ADD_STA_REQ + * @length: message length + * @session_id: session id + * @transaction_id: transaction id for cmd + * @bssid: bssid + * @tdls_oper: add peer type + * @peermac: MAC address for TDLS peer + * @capability: mac capability as sSirMacCapabilityInfo + * @extn_capability: extent capability + * @supported_rates_length: rates length + * @supported_rates: supported rates + * @htcap_present: ht capability present + * @ht_cap: ht capability + * @vhtcap_present: vht capability present + * @vht_cap: vht capability + * @uapsd_queues: uapsd queue as sSirMacQosInfoStation + * @max_sp: maximum service period + */ +struct tdls_add_sta_req { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + uint16_t transaction_id; + struct qdf_mac_addr bssid; + enum tdls_add_oper tdls_oper; + struct qdf_mac_addr peermac; + uint16_t capability; + uint8_t extn_capability[WLAN_MAC_MAX_EXTN_CAP]; + uint8_t supported_rates_length; + uint8_t supported_rates[WLAN_MAC_MAX_SUPP_RATES]; + uint8_t htcap_present; + struct htcap_cmn_ie ht_cap; + uint8_t vhtcap_present; + struct vhtcap vht_cap; + uint8_t uapsd_queues; + uint8_t max_sp; +}; + +/** + * struct tdls_add_sta_rsp - TDLS Response struct PE --> TDLS module + * same as struct sSirTdlsAddStaRsp + * @message_type: message type eWNI_SME_TDLS_ADD_STA_RSP + * @length: message length + * @status_code: status code as tSirResultCodes + * @peermac: MAC address of the TDLS peer + * @session_id: session id + * @sta_id: sta id + * @sta_type: sta type + * @ucast_sig: unicast signature + * @bcast_sig: broadcast signature + * @tdls_oper: add peer type + * @psoc: soc object + */ +struct tdls_add_sta_rsp { + uint16_t message_type; + uint16_t length; + QDF_STATUS status_code; + struct qdf_mac_addr peermac; + uint8_t session_id; + uint16_t sta_id; + uint16_t sta_type; + uint8_t ucast_sig; + uint8_t bcast_sig; + enum tdls_add_oper tdls_oper; + struct wlan_objmgr_psoc *psoc; +}; + +/** + * struct tdls_del_sta_req - TDLS Request struct TDLS module --> PE + * same as sSirTdlsDelStaReq + * @message_type: message type eWNI_SME_TDLS_DEL_STA_REQ + * @length: message length + * @session_id: session id + * @transaction_id: transaction id for cmd + * @bssid: bssid + * @peermac: MAC address of the TDLS peer + */ +struct tdls_del_sta_req { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + uint16_t transaction_id; + struct qdf_mac_addr bssid; + struct qdf_mac_addr peermac; +}; + +/** + * struct tdls_del_sta_rsp - TDLS Response struct PE --> TDLS module + * same as sSirTdlsDelStaRsp + * @message_type: message type eWNI_SME_TDLS_DEL_STA_RSP + * @length: message length + * @session_id: session id + * @status_code: status code as tSirResultCodes + * @peermac: MAC address of the TDLS peer + * @sta_id: sta id + * @psoc: soc object + */ +struct tdls_del_sta_rsp { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + QDF_STATUS status_code; + struct qdf_mac_addr peermac; + uint16_t sta_id; + struct wlan_objmgr_psoc *psoc; +}; + +/** + * tdls_process_add_peer() - add TDLS peer + * @req: TDLS add peer request + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed + */ +QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req); + +/** + * tdls_process_del_peer() - del TDLS peer + * @req: TDLS del peer request + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed + */ +QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req); + +/** + * tdls_process_update_peer() - update TDLS peer + * @req: TDLS update peer request + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed + */ +QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req); + +/** + * tdls_pe_del_peer() - send TDLS delete peer request to PE + * @req: TDLS delete peer request + * + * Return: QDF status + */ +QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req); + +/** + * tdls_process_add_peer_rsp() - handle response for add or update TDLS peer + * @rsp: TDLS add peer response + * + * Return: QDF status + */ +QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp); + +/** + * tdls_process_add_peer_rsp() - handle response for delete TDLS peer + * @rsp: TDLS delete peer response + * + * Return: QDF status + */ +QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp); +#endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index eef8915fb300..ab4a5e5c9aa7 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -23,6 +23,8 @@ */ #include "wlan_tdls_main.h" +#include "wlan_tdls_cmds_process.h" +#include "wlan_tdls_peer.h" QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -31,7 +33,7 @@ QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, struct tdls_soc_priv_obj *tdls_soc_obj; tdls_soc_obj = qdf_mem_malloc(sizeof(*tdls_soc_obj)); - if (tdls_soc_obj == NULL) { + if (!tdls_soc_obj) { tdls_err("Failed to allocate memory for tdls object"); return QDF_STATUS_E_NOMEM; } @@ -61,7 +63,7 @@ QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - if (tdls_soc_obj == NULL) { + if (!tdls_soc_obj) { tdls_err("Failed to get tdls obj in psoc"); return QDF_STATUS_E_FAILURE; } @@ -78,19 +80,53 @@ QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, return status; } -static void tdls_vdev_init(struct tdls_vdev_priv_obj *vdev) +static QDF_STATUS tdls_vdev_init(struct tdls_vdev_priv_obj *vdev_obj) { uint8_t i; + struct tdls_config_params *config; + struct tdls_user_config *user_config; + struct tdls_soc_priv_obj *soc_obj; - for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { - qdf_list_create(&vdev->peer_list[i], - WLAN_TDLS_PEER_SUB_LIST_SIZE); + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("tdls soc obj NULL"); + return QDF_STATUS_E_FAILURE; } - qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW, - NULL, vdev); - qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW, - NULL, vdev); + config = &vdev_obj->threshold_config; + user_config = &soc_obj->tdls_configs; + config->tx_period_t = user_config->tdls_tx_states_period; + config->tx_packet_n = user_config->tdls_tx_pkt_threshold; + config->discovery_tries_n = user_config->tdls_max_discovery_attempt; + config->idle_timeout_t = user_config->tdls_idle_timeout; + config->idle_packet_n = user_config->tdls_idle_pkt_threshold; + config->rssi_trigger_threshold = + user_config->tdls_rssi_trigger_threshold; + config->rssi_teardown_threshold = + user_config->tdls_rssi_teardown_threshold; + config->rssi_delta = user_config->tdls_rssi_delta; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + qdf_list_create(&vdev_obj->peer_list[i], + WLAN_TDLS_PEER_SUB_LIST_SIZE); + } + qdf_mc_timer_init(&vdev_obj->peer_update_timer, QDF_TIMER_TYPE_SW, + NULL, vdev_obj); + qdf_mc_timer_init(&vdev_obj->peer_discovery_timer, QDF_TIMER_TYPE_SW, + NULL, vdev_obj); + return QDF_STATUS_SUCCESS; +} + +static void tdls_vdev_deinit(struct tdls_vdev_priv_obj *vdev_obj) +{ + qdf_mc_timer_stop(&vdev_obj->peer_update_timer); + qdf_mc_timer_stop(&vdev_obj->peer_discovery_timer); + + qdf_mc_timer_destroy(&vdev_obj->peer_update_timer); + qdf_mc_timer_destroy(&vdev_obj->peer_discovery_timer); + + tdls_peer_idle_timers_destroy(vdev_obj); + tdls_free_peer_list(vdev_obj); } QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, @@ -107,14 +143,11 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, /* TODO: Add concurrency check */ tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj)); - if (tdls_vdev_obj == NULL) { + if (!tdls_vdev_obj) { tdls_err("Failed to allocate memory for tdls vdev object"); return QDF_STATUS_E_NOMEM; } - tdls_vdev_obj->vdev = vdev; - tdls_vdev_init(tdls_vdev_obj); - status = wlan_objmgr_vdev_component_obj_attach(vdev, WLAN_UMAC_COMP_TDLS, (void *)tdls_vdev_obj, @@ -122,10 +155,15 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) { tdls_err("Failed to attach vdev tdls component"); qdf_mem_free(tdls_vdev_obj); + goto out; } + tdls_vdev_obj->vdev = vdev; + status = tdls_vdev_init(tdls_vdev_obj); + if (QDF_IS_STATUS_ERROR(status)) + goto out; tdls_notice("tdls object attach to vdev successfully"); - +out: return status; } @@ -142,7 +180,7 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); - if (tdls_vdev_obj == NULL) { + if (!tdls_vdev_obj) { tdls_err("Failed to get tdls vdev object"); return QDF_STATUS_E_FAILURE; } @@ -153,7 +191,47 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) tdls_err("Failed to detach vdev tdls component"); + tdls_vdev_deinit(tdls_vdev_obj); qdf_mem_free(tdls_vdev_obj); return status; } + +QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!msg || !msg->bodyptr) { + tdls_err("msg: 0x%p, bodyptr: 0x%p", msg, msg->bodyptr); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + switch (msg->type) { + case TDLS_CMD_TX_ACTION: + break; + case TDLS_CMD_ADD_STA: + tdls_process_add_peer(msg->bodyptr); + break; + case TDLS_CMD_CHANGE_STA: + tdls_process_update_peer(msg->bodyptr); + break; + case TDLS_CMD_ENABLE_LINK: + break; + case TDLS_CMD_DISABLE_LINK: + tdls_process_del_peer(msg->bodyptr); + break; + case TDLS_CMD_CONFIG_FORCE_PEER: + break; + case TDLS_CMD_REMOVE_FORCE_PEER: + break; + case TDLS_CMD_STATS_UPDATE: + break; + case TDLS_CMD_CONFIG_UPDATE: + break; + default: + break; + } + + return status; +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index b85c74cc5f57..4d4d5f2bbd04 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -39,6 +39,17 @@ #define ENA_TDLS_BUFFER_STA (1 << 1) /* TDLS Buffer STA support */ #define ENA_TDLS_SLEEP_STA (1 << 2) /* TDLS Sleep STA support */ +#define BW_20_OFFSET_BIT 0 +#define BW_40_OFFSET_BIT 1 +#define BW_80_OFFSET_BIT 2 +#define BW_160_OFFSET_BIT 3 + +#define TDLS_SEC_OFFCHAN_OFFSET_0 0 +#define TDLS_SEC_OFFCHAN_OFFSET_40PLUS 40 +#define TDLS_SEC_OFFCHAN_OFFSET_40MINUS (-40) +#define TDLS_SEC_OFFCHAN_OFFSET_80 80 +#define TDLS_SEC_OFFCHAN_OFFSET_160 160 + #define tdls_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) #define tdls_logfl(level, format, args...) \ @@ -163,13 +174,20 @@ struct tdls_set_state_info { * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event user data + * @tdls_reg_tl_peer: callback to register the TDLS peer with TL + * @tdls_dereg_tl_peer: callback to unregister the TDLS peer + * @tdls_tl_peer_data: userdata for register/deregister TDLS peer * @tx_q_ack: queue for tx frames waiting for ack * @tdls_con_cap: tdls concurrency support + * @tdls_send_mgmt_req: store eWNI_SME_TDLS_SEND_MGMT_REQ value + * @tdls_add_sta_req: store eWNI_SME_TDLS_ADD_STA_REQ value + * @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value + * @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value */ struct tdls_soc_priv_obj { struct wlan_objmgr_psoc *soc; - enum tdls_support_mode tdls_current_mode; - enum tdls_support_mode tdls_user_config_mode; + enum tdls_feature_mode tdls_current_mode; + enum tdls_feature_mode tdls_user_config_mode; struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM]; struct tdls_user_config tdls_configs; uint16_t max_num_tdls_sta; @@ -188,8 +206,15 @@ struct tdls_soc_priv_obj { void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; + tdls_register_tl_peer_callback tdls_reg_tl_peer; + tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; + void *tdls_tl_peer_data; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; + uint16_t tdls_send_mgmt_req; + uint16_t tdls_add_sta_req; + uint16_t tdls_del_sta_req; + uint16_t tdls_update_peer_state; }; /** @@ -225,6 +250,12 @@ struct tdls_vdev_priv_obj { qdf_list_t tx_queue; }; +/** + * struct tdls_peer_mlme_info - tdls peer mlme info + **/ +struct tdls_peer_mlme_info { +}; + /** * struct tdls_peer - tdls peer data * @node: node @@ -266,7 +297,7 @@ struct tdls_peer { uint16_t sta_id; int8_t rssi; enum tdls_peer_capab tdls_support; - enum tdls_link_status link_status; + enum tdls_link_state link_status; uint8_t signature; uint8_t is_responder; uint8_t discovery_processed; @@ -288,9 +319,10 @@ struct tdls_peer { qdf_mc_timer_t peer_idle_timer; bool is_peer_idle_timer_initialised; uint8_t spatial_streams; - enum tdls_link_reason reason; + enum tdls_link_state_reason reason; tdls_state_change_callback state_change_notification; uint8_t qos; + struct tdls_peer_mlme_info *tdls_info; }; /** @@ -302,12 +334,29 @@ struct tdls_peer { static inline struct tdls_soc_priv_obj * wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) { - struct wlan_objmgr_psoc *psoc = - wlan_pdev_get_psoc(wlan_vdev_get_pdev(vdev)); + struct wlan_objmgr_psoc *psoc; + struct tdls_soc_priv_obj *soc_obj; - return (struct tdls_soc_priv_obj *) + if (!vdev) { + tdls_err("NULL vdev"); + return NULL; + } + + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + tdls_err("can't get psoc"); + return NULL; + } + + wlan_psoc_obj_lock(psoc); + soc_obj = (struct tdls_soc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); + wlan_psoc_obj_unlock(psoc); + + return soc_obj; } /** @@ -319,9 +368,18 @@ wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) static inline struct tdls_soc_priv_obj * wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc) { - return (struct tdls_soc_priv_obj *) + struct tdls_soc_priv_obj *soc_obj; + if (!psoc) { + tdls_err("NULL psoc"); + return NULL; + } + wlan_psoc_obj_lock(psoc); + soc_obj = (struct tdls_soc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); + wlan_psoc_obj_unlock(psoc); + + return soc_obj; } /** @@ -333,22 +391,33 @@ wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc) static inline struct tdls_vdev_priv_obj * wlan_vdev_get_tdls_vdev_obj(struct wlan_objmgr_vdev *vdev) { - return (struct tdls_vdev_priv_obj *) + struct tdls_vdev_priv_obj *vdev_obj; + + if (!vdev) { + tdls_err("NULL vdev"); + return NULL; + } + + wlan_vdev_obj_lock(vdev); + vdev_obj = (struct tdls_vdev_priv_obj *) wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); + wlan_vdev_obj_unlock(vdev); + + return vdev_obj; } /** * tdls_set_link_status - tdls set link status * @vdev: vdev object * @mac: mac address of tdls peer - * @link_status: tdls link status + * @link_state: tdls link state * @link_reason: reason */ void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev, const uint8_t *mac, - enum tdls_link_status link_status, - enum tdls_link_reason link_reason); + enum tdls_link_state link_state, + enum tdls_link_state_reason link_reason); /** * tdls_psoc_obj_create_notification() - tdls psoc create notification handler * @psoc: psoc object diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c new file mode 100644 index 000000000000..a89736fb95e0 --- /dev/null +++ b/core/src/wlan_tdls_peer.c @@ -0,0 +1,836 @@ +/* + * 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: wlan_tdls_peer.c + * + * TDLS peer basic operations + */ +#include "wlan_tdls_main.h" +#include "wlan_tdls_peer.h" +#include +#include +#include + +static uint8_t calculate_hash_key(const uint8_t *macaddr) +{ + uint8_t i, key; + + for (i = 0, key = 0; i < 6; i++) + key ^= macaddr[i]; + + return key % WLAN_TDLS_PEER_LIST_SIZE; +} + +struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) +{ + uint8_t key; + QDF_STATUS status; + struct tdls_peer *peer; + qdf_list_t *head; + qdf_list_node_t *p_node; + + key = calculate_hash_key(macaddr); + head = &vdev_obj->peer_list[key]; + + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + if (WLAN_ADDR_EQ(&peer->peer_mac, macaddr) + == QDF_STATUS_SUCCESS) { + return peer; + } + status = qdf_list_peek_next(head, p_node, &p_node); + } + + tdls_debug("no tdls peer " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(macaddr)); + return NULL; +} + +/** + * tdls_find_peer_handler() - helper function for tdls_find_all_peer + * @psoc: soc object + * @obj: vdev object + * @arg: used to keep search peer parameters + * + * Return: None. + */ +static void +tdls_find_peer_handler(struct wlan_objmgr_psoc *psoc, void *obj, void *arg) +{ + struct wlan_objmgr_vdev *vdev = obj; + struct tdls_search_peer_param *tdls_param = arg; + struct tdls_vdev_priv_obj *vdev_obj; + + if (tdls_param->peer) + return; + + if (!vdev) { + tdls_err("invalid vdev"); + return; + } + + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && + wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) + return; + + vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); + if (!vdev_obj) + return; + + tdls_param->peer = tdls_find_peer(vdev_obj, tdls_param->macaddr); +} + +struct tdls_peer * +tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr) +{ + struct tdls_search_peer_param tdls_search_param; + struct wlan_objmgr_psoc *psoc; + + if (!soc_obj) { + tdls_err("tdls soc object is NULL"); + return NULL; + } + + psoc = soc_obj->soc; + if (!psoc) { + tdls_err("psoc is NULL"); + return NULL; + } + tdls_search_param.macaddr = macaddr; + tdls_search_param.peer = NULL; + + wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, + tdls_find_peer_handler, + &tdls_search_param, 0, WLAN_TDLS_NB_ID); + + return tdls_search_param.peer; +} + +static uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel, + uint8_t bw_offset) +{ + char country[REG_ALPHA2_LEN + 1]; + QDF_STATUS status; + + if (!psoc) { + tdls_err("psoc is NULL"); + return 0; + } + + status = wlan_reg_read_default_country(psoc, country); + if (QDF_IS_STATUS_ERROR(status)) + return 0; + + return wlan_reg_dmn_get_opclass_from_channel(country, channel, + bw_offset); +} + +/** + * tdls_add_peer() - add TDLS peer in TDLS vdev object + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of peer + * + * Allocate memory for the new peer, and add it to hash table. + * + * Return: new added TDLS peer, NULL if failed. + */ +static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) +{ + struct tdls_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + uint8_t key = 0; + qdf_list_t *head; + + peer = qdf_mem_malloc(sizeof(*peer)); + if (!peer) { + tdls_err("add tdls peer malloc memory failed!"); + return NULL; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL tdls soc object"); + return NULL; + } + + key = calculate_hash_key(macaddr); + head = &vdev_obj->peer_list[key]; + + qdf_mem_copy(&peer->peer_mac, macaddr, sizeof(peer->peer_mac)); + peer->vdev_priv = vdev_obj; + + peer->pref_off_chan_num = + soc_obj->tdls_configs.tdls_pre_off_chan_num; + peer->op_class_for_pref_off_chan = + tdls_find_opclass(soc_obj->soc, + peer->pref_off_chan_num, + soc_obj->tdls_configs.tdls_pre_off_chan_bw); + + qdf_list_insert_back(head, &peer->node); + + tdls_debug("add tdls peer: " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(macaddr)); + return peer; +} + +struct tdls_peer *tdls_get_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) +{ + struct tdls_peer *peer; + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) + peer = tdls_add_peer(vdev_obj, macaddr); + + return peer; +} + +static struct tdls_peer * +tdls_find_progress_peer_in_list(qdf_list_t *head, + const uint8_t *macaddr, uint8_t skip_self) +{ + QDF_STATUS status; + struct tdls_peer *peer; + qdf_list_node_t *p_node; + + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + if (skip_self && macaddr && + WLAN_ADDR_EQ(&peer->peer_mac, macaddr) + == QDF_STATUS_SUCCESS) { + status = qdf_list_peek_next(head, p_node, &p_node); + continue; + } else if (TDLS_LINK_CONNECTING == peer->link_status) { + tdls_debug(QDF_MAC_ADDRESS_STR " TDLS_LINK_CONNECTING", + QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); + return peer; + } + status = qdf_list_peek_next(head, p_node, &p_node); + } + + return NULL; +} + +/** + * tdls_find_progress_peer() - find the peer with ongoing TDLS progress + * on present vdev + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of peer, if NULL check for all the peer list + * @skip_self: If true, skip this macaddr. Otherwise, check all the peer list. + * if macaddr is NULL, this argument is ignored, and check for all + * the peer list. + * + * Return: Pointer to tdls_peer if TDLS is ongoing. Otherwise return NULL. + */ +static struct tdls_peer * +tdls_find_progress_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t skip_self) +{ + uint8_t i; + struct tdls_peer *peer; + qdf_list_t *head; + + if (!vdev_obj) { + tdls_err("invalid tdls vdev object"); + return NULL; + } + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &vdev_obj->peer_list[i]; + + peer = tdls_find_progress_peer_in_list(head, macaddr, + skip_self); + if (peer) + return peer; + } + + return NULL; +} + +/** + * tdls_find_progress_peer_handler() - helper function for tdls_is_progress + * @psoc: soc object + * @obj: vdev object + * @arg: used to keep search peer parameters + * + * Return: None. + */ +static void +tdls_find_progress_peer_handler(struct wlan_objmgr_psoc *psoc, + void *obj, void *arg) +{ + struct wlan_objmgr_vdev *vdev = obj; + struct tdls_search_progress_param *tdls_progress = arg; + struct tdls_vdev_priv_obj *vdev_obj; + + if (tdls_progress->peer) + return; + + if (!vdev) { + tdls_err("invalid vdev"); + return; + } + + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && + wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) + return; + + vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); + + tdls_progress->peer = tdls_find_progress_peer(vdev_obj, + tdls_progress->macaddr, + tdls_progress->skip_self); +} + +struct tdls_peer *tdls_is_progress(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t skip_self) +{ + struct tdls_search_progress_param tdls_progress; + struct wlan_objmgr_psoc *psoc; + + if (!vdev_obj) { + tdls_err("invalid tdls vdev object"); + return NULL; + } + + wlan_vdev_obj_lock(vdev_obj->vdev); + psoc = wlan_vdev_get_psoc(vdev_obj->vdev); + wlan_vdev_obj_unlock(vdev_obj->vdev); + if (!psoc) { + tdls_err("invalid psoc"); + return NULL; + } + tdls_progress.macaddr = macaddr; + tdls_progress.skip_self = skip_self; + tdls_progress.peer = NULL; + + wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, + tdls_find_progress_peer_handler, + &tdls_progress, 0, WLAN_TDLS_NB_ID); + + return tdls_progress.peer; +} + +struct tdls_peer * +tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj) +{ + uint16_t i; + struct tdls_peer *peer; + qdf_list_t *head; + qdf_list_node_t *p_node; + QDF_STATUS status; + + if (!vdev_obj) { + tdls_err("invalid tdls vdev object"); + return NULL; + } + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &vdev_obj->peer_list[i]; + + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + + if (peer && TDLS_LINK_CONNECTED == peer->link_status) { + tdls_debug(QDF_MAC_ADDRESS_STR + " TDLS_LINK_CONNECTED", + QDF_MAC_ADDR_ARRAY( + peer->peer_mac.bytes)); + return peer; + } + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + + return NULL; +} + +/** + * tdls_determine_channel_opclass() - determine channel and opclass + * @soc_obj: TDLS soc object + * @vdev_obj: TDLS vdev object + * @peer: TDLS peer + * @channel: pointer to channel + * @opclass: pinter to opclass + * + * Function determines the channel and operating class + * + * Return: None. + */ +static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, + struct tdls_vdev_priv_obj *vdev_obj, + struct tdls_peer *peer, + uint32_t *channel, uint32_t *opclass) +{ + uint32_t vdev_id; + enum tQDF_ADAPTER_MODE opmode; + /* + * If tdls offchannel is not enabled then we provide base channel + * and in that case pass opclass as 0 since opclass is mainly needed + * for offchannel cases. + */ + if (!(TDLS_IS_OFF_CHANNEL_ENABLED( + soc_obj->tdls_configs.tdls_feature_flags)) || + soc_obj->tdls_fw_off_chan_mode != ENABLE_CHANSWITCH) { + wlan_vdev_obj_lock(vdev_obj->vdev); + vdev_id = wlan_vdev_get_id(vdev_obj->vdev); + opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev); + wlan_vdev_obj_unlock(vdev_obj->vdev); + + *channel = policy_mgr_get_channel(soc_obj->soc, + opmode, &vdev_id); + *opclass = 0; + } else { + *channel = peer->pref_off_chan_num; + *opclass = peer->op_class_for_pref_off_chan; + } + tdls_debug("channel:%d opclass:%d", *channel, *opclass); +} + +/** + * tdls_get_wifi_hal_state() - get TDLS wifi hal state on current peer + * @peer: TDLS peer + * @state: output parameter to store the TDLS wifi hal state + * @reason: output parameter to store the reason of the current peer + * + * Return: None. + */ +static void tdls_get_wifi_hal_state(struct tdls_peer *peer, uint32_t *state, + int32_t *reason) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_soc_priv_obj *soc_obj; + + vdev = peer->vdev_priv->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("can't get tdls object"); + return; + } + + *reason = peer->reason; + + switch (peer->link_status) { + case TDLS_LINK_IDLE: + case TDLS_LINK_DISCOVERED: + case TDLS_LINK_DISCOVERING: + case TDLS_LINK_CONNECTING: + *state = QCA_WIFI_HAL_TDLS_S_ENABLED; + break; + case TDLS_LINK_CONNECTED: + if ((TDLS_IS_OFF_CHANNEL_ENABLED( + soc_obj->tdls_configs.tdls_feature_flags)) && + (soc_obj->tdls_fw_off_chan_mode == ENABLE_CHANSWITCH)) + *state = QCA_WIFI_HAL_TDLS_S_ESTABLISHED_OFF_CHANNEL; + else + *state = QCA_WIFI_HAL_TDLS_S_ENABLED; + break; + case TDLS_LINK_TEARING: + *state = QCA_WIFI_HAL_TDLS_S_DROPPED; + break; + } +} + +/** + * tdls_extract_peer_state_param() - extract peer update params from TDLS peer + * @peer_param: output peer update params + * @peer: TDLS peer + * + * This is used when enable TDLS link + * + * Return: None. + */ +void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, + struct tdls_peer *peer) +{ + uint16_t i, num; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj; + enum channel_state ch_state; + struct wlan_objmgr_pdev *pdev; + uint8_t chan_id; + + vdev_obj = peer->vdev_priv; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + pdev = wlan_vdev_get_pdev(vdev_obj->vdev); + if (!soc_obj || !pdev) { + tdls_err("soc_obj: %p, pdev: %p", soc_obj, pdev); + return; + } + + qdf_mem_zero(peer_param, sizeof(*peer_param)); + wlan_vdev_obj_lock(vdev_obj->vdev); + peer_param->vdev_id = wlan_vdev_get_id(vdev_obj->vdev); + wlan_vdev_obj_unlock(vdev_obj->vdev); + + qdf_mem_copy(peer_param->peer_macaddr, + peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE); + peer_param->peer_state = TDLS_PEER_STATE_CONNCTED; + peer_param->peer_cap.is_peer_responder = peer->is_responder; + peer_param->peer_cap.peer_uapsd_queue = peer->uapsd_queues; + peer_param->peer_cap.peer_max_sp = peer->max_sp; + peer_param->peer_cap.peer_buff_sta_support = peer->buf_sta_capable; + peer_param->peer_cap.peer_off_chan_support = + peer->off_channel_capable; + peer_param->peer_cap.peer_curr_operclass = 0; + peer_param->peer_cap.self_curr_operclass = 0; + peer_param->peer_cap.peer_chanlen = peer->supported_channels_len; + peer_param->peer_cap.pref_off_channum = peer->pref_off_chan_num; + peer_param->peer_cap.pref_off_chan_bandwidth = + soc_obj->tdls_configs.tdls_pre_off_chan_bw; + peer_param->peer_cap.opclass_for_prefoffchan = + peer->op_class_for_pref_off_chan; + + if (wlan_reg_is_dfs_ch(pdev, peer_param->peer_cap.pref_off_channum)) { + tdls_err("Resetting TDLS off-channel from %d to %d", + peer_param->peer_cap.pref_off_channum, + WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF); + peer_param->peer_cap.pref_off_channum = + WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF; + } + + num = 0; + for (i = 0; i < peer->supported_channels_len; i++) { + chan_id = peer->supported_channels[i]; + ch_state = wlan_reg_get_channel_state(pdev, chan_id); + + if (CHANNEL_STATE_INVALID != ch_state && + CHANNEL_STATE_DFS != ch_state && + !wlan_is_dsrc_channel(wlan_is_dsrc_channel(chan_id))) { + peer_param->peer_cap.peer_chan[num].chan_id = chan_id; + peer_param->peer_cap.peer_chan[num].pwr = + wlan_reg_get_channel_reg_power(pdev, chan_id); + peer_param->peer_cap.peer_chan[num].dfs_set = false; + num++; + } + } + + peer_param->peer_cap.peer_oper_classlen = + peer->supported_oper_classes_len; + for (i = 0; i < peer->supported_oper_classes_len; i++) + peer_param->peer_cap.peer_oper_class[i] = + peer->supported_oper_classes[i]; +} + +/** + * tdls_set_link_status() - set link statue for TDLS peer + * @vdev_obj: TDLS vdev object + * @mac: MAC address of current TDLS peer + * @link_status: link status + * @link_reason: reason with link status + * + * Return: None. + */ +void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *mac, + enum tdls_link_state link_status, + enum tdls_link_state_reason link_reason) +{ + uint32_t state = 0; + int32_t res = 0; + uint32_t op_class = 0; + uint32_t channel = 0; + struct tdls_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + + peer = tdls_find_peer(vdev_obj, mac); + if (!peer) { + tdls_err("peer is NULL, can't set link status %d, reason %d", + link_status, link_reason); + return; + } + + peer->link_status = link_status; + + if (link_status >= TDLS_LINK_DISCOVERED) + peer->discovery_attempt = 0; + + if (peer->is_forced_peer && peer->state_change_notification) { + peer->reason = link_reason; + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL psoc object"); + return; + } + + tdls_determine_channel_opclass(soc_obj, vdev_obj, + peer, &channel, &op_class); + tdls_get_wifi_hal_state(peer, &state, &res); + peer->state_change_notification(mac, op_class, channel, + state, res, soc_obj->soc); + } +} + +void tdls_set_peer_link_status(struct tdls_peer *peer, + enum tdls_link_state link_status, + enum tdls_link_state_reason link_reason) +{ + uint32_t state = 0; + int32_t res = 0; + uint32_t op_class = 0; + uint32_t channel = 0; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + + peer->link_status = link_status; + + if (link_status >= TDLS_LINK_DISCOVERED) + peer->discovery_attempt = 0; + + if (peer->is_forced_peer && peer->state_change_notification) { + peer->reason = link_reason; + + vdev_obj = peer->vdev_priv; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL psoc object"); + return; + } + + tdls_determine_channel_opclass(soc_obj, vdev_obj, + peer, &channel, &op_class); + tdls_get_wifi_hal_state(peer, &state, &res); + peer->state_change_notification(peer->peer_mac.bytes, + op_class, channel, state, + res, soc_obj->soc); + } +} + +void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, + struct tdls_update_peer_params *req_info) +{ + uint8_t is_buffer_sta, is_off_channel_supported, is_qos_wmm_sta; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_peer *curr_peer; + uint32_t feature; + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL psoc object"); + return; + } + + curr_peer = tdls_find_peer(vdev_obj, macaddr); + if (!curr_peer) { + tdls_err("NULL tdls peer"); + return; + } + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if ((1 << 4) & req_info->extn_capability[3]) + is_buffer_sta = 1; + + if ((1 << 6) & req_info->extn_capability[3]) + is_off_channel_supported = 1; + + if (TDLS_IS_WMM_ENABLED(feature) && req_info->is_qos_wmm_sta) + is_qos_wmm_sta = true; + + curr_peer->uapsd_queues = req_info->uapsd_queues; + curr_peer->max_sp = req_info->max_sp; + curr_peer->buf_sta_capable = is_buffer_sta; + curr_peer->off_channel_capable = is_off_channel_supported; + + qdf_mem_copy(curr_peer->supported_channels, + req_info->supported_channels, + req_info->supported_channels_len); + + curr_peer->supported_channels_len = req_info->supported_channels_len; + + qdf_mem_copy(curr_peer->supported_oper_classes, + req_info->supported_oper_classes, + req_info->supported_oper_classes_len); + + curr_peer->supported_oper_classes_len = + req_info->supported_oper_classes_len; + + curr_peer->qos = is_qos_wmm_sta; +} + +QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t sta_id) +{ + struct tdls_peer *peer; + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + + peer->sta_id = sta_id; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t signature) +{ + struct tdls_peer *peer; + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + peer->signature = signature; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_set_force_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, bool forcepeer) +{ + struct tdls_peer *peer; + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + peer->is_forced_peer = forcepeer; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_set_callback(struct tdls_peer *peer, + tdls_state_change_callback callback) +{ + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + peer->state_change_notification = callback; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_set_extctrl_param(struct tdls_peer *peer, uint32_t chan, + uint32_t max_latency, uint32_t op_class, + uint32_t min_bandwidth) +{ + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + peer->op_class_for_pref_off_chan = (uint8_t)op_class; + peer->pref_off_chan_num = (uint8_t)chan; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_peer *curr_peer; + struct tdls_user_config *config; + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL psoc object"); + return QDF_STATUS_E_FAILURE; + } + + curr_peer = tdls_find_peer(vdev_obj, macaddr); + if (!curr_peer) { + tdls_err("NULL tdls peer"); + return QDF_STATUS_E_FAILURE; + } + + if (!curr_peer->is_forced_peer) { + config = &soc_obj->tdls_configs; + curr_peer->pref_off_chan_num = config->tdls_pre_off_chan_num; + curr_peer->op_class_for_pref_off_chan = + tdls_find_opclass(soc_obj->soc, + curr_peer->pref_off_chan_num, + config->tdls_pre_off_chan_bw); + } + + tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); + curr_peer->sta_id = 0; + + return QDF_STATUS_SUCCESS; +} + +void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj) +{ + uint16_t i; + struct tdls_peer *peer; + qdf_list_t *head; + qdf_list_node_t *p_node; + QDF_STATUS status; + + if (!vdev_obj) { + tdls_err("NULL tdls vdev object"); + return; + } + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &vdev_obj->peer_list[i]; + + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + if (peer && peer->is_peer_idle_timer_initialised) { + tdls_debug(QDF_MAC_ADDRESS_STR + ": destroy idle timer ", + QDF_MAC_ADDR_ARRAY( + peer->peer_mac.bytes)); + qdf_mc_timer_stop(&peer->peer_idle_timer); + qdf_mc_timer_destroy(&peer->peer_idle_timer); + } + status = qdf_list_peek_next(head, p_node, &p_node); + } + } +} + +void tdls_free_peer_list(struct tdls_vdev_priv_obj *vdev_obj) +{ + uint16_t i; + struct tdls_peer *peer; + qdf_list_t *head; + qdf_list_node_t *p_node; + + if (!vdev_obj) { + tdls_err("NULL tdls vdev object"); + return; + } + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &vdev_obj->peer_list[i]; + + while (QDF_IS_STATUS_SUCCESS( + qdf_list_remove_front(head, &p_node))) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + qdf_mem_free(peer); + } + qdf_list_destroy(head); + } +} diff --git a/core/src/wlan_tdls_peer.h b/core/src/wlan_tdls_peer.h new file mode 100644 index 000000000000..511b4d4ed010 --- /dev/null +++ b/core/src/wlan_tdls_peer.h @@ -0,0 +1,245 @@ +/* + * 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: wlan_tdls_peer.h + * + * TDLS peer function declaration + */ + +#if !defined(_WLAN_TDLS_PEER_H_) +#define _WLAN_TDLS_PEER_H_ + +/** + * struct tdls_search_peer_param - used to search TDLS peer + * @macaddr: MAC address of peer + * @peer: pointer to the found peer + */ +struct tdls_search_peer_param { + const uint8_t *macaddr; + struct tdls_peer *peer; +}; + +/** + * struct tdls_progress_param - used to search progress TDLS peer + * @skip_self: skip self peer + * @macaddr: MAC address of peer + * @peer: pointer to the found peer + */ +struct tdls_search_progress_param { + uint8_t skip_self; + const uint8_t *macaddr; + struct tdls_peer *peer; +}; + +/** + * tdls_get_peer() - find or add an TDLS peer in TDLS vdev object + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of peer + * + * Search the TDLS peer in the hash table and create a new one if not found. + * + * Return: Pointer to tdls_peer, NULL if failed. + */ +struct tdls_peer *tdls_get_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr); + +/** + * tdls_find_peer() - find TDLS peer in TDLS vdev object + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of peer + * + * This is in scheduler thread context, no lock required. + * + * Return: If peer is found, then it returns pointer to tdls_peer; + * otherwise, it returns NULL. + */ +struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr); + +/** + * tdls_find_all_peer() - find peer matching the input MACaddr in soc range + * @soc_obj: TDLS soc object + * @macaddr: MAC address of TDLS peer + * + * This is in scheduler thread context, no lock required. + * + * Return: TDLS peer if a matching is detected; NULL otherwise + */ +struct tdls_peer * +tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr); + +/** + * tdls_find_first_connected_peer() - find the 1st connected tdls peer from vdev + * @vdev_obj: tdls vdev object + * + * This function searches for the 1st connected TDLS peer + * + * Return: The 1st connected TDLS peer if found; NULL otherwise + */ +struct tdls_peer * +tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj); + +/** + * tdls_is_progress() - find the peer with ongoing TDLS progress on present psoc + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of the peer + * @skip_self: if 1, skip checking self. If 0, search include self + * + * This is used in scheduler thread context, no lock required. + * + * Return: TDLS peer if found; NULL otherwise + */ +struct tdls_peer *tdls_is_progress(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t skip_self); + +/** + * tdls_extract_peer_state_param() - extract peer update params from TDL peer + * @peer_param: output peer update params + * @peer: TDLS peer + * + * This is used when enable TDLS link + * + * Return: None. + */ +void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, + struct tdls_peer *peer); + +/** + * tdls_set_link_status() - set link statue for TDLS peer + * @peer: TDLS peer + * @link_state: link state + * @link_reason: reason with link status + * + * This is in scheduler thread context, no lock required. + * + * Return: None. + */ +void tdls_set_peer_link_status(struct tdls_peer *peer, + enum tdls_link_state link_state, + enum tdls_link_state_reason link_reason); + +/** + * tdls_set_peer_caps() - set capability for TDLS peer + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address for the TDLS peer + * @req_info: parameters to update peer capability + * + * This is in scheduler thread context, no lock required. + * + * Return: None. + */ +void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, + struct tdls_update_peer_params *req_info); + +/** + * tdls_set_sta_id() - set station ID on a TDLS peer + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of the TDLS peer + * @sta_id: station ID + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t sta_id); + +/** + * tdls_set_signature() - set TDLS peer's signature + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of the TDLS peer + * @signature: signature value + * + * This is used in scheduler thread context, no lock required. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t signature); + +/** + * tdls_set_force_peer() - set/clear is_forced_peer flag on peer + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of TDLS peer + * @forcepeer: value used to set is_forced_peer flag + * + * This is used in scheduler thread context, no lock required. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_force_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, bool forcepeer); + +/** + * tdls_set_callback() - set state change callback on current TDLS peer + * @peer: TDLS peer + * @callback: state change callback + * + * This is used in scheduler thread context, no lock required. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_callback(struct tdls_peer *peer, + tdls_state_change_callback callback); + +/** + * tdls_set_extctrl_param() - set external control parameter on TDLS peer + * @peer: TDLS peer + * @chan: channel + * @max_latency: maximum latency + * @op_class: operation class + * @min_bandwidth: minimal bandwidth + * + * This is used in scheduler thread context, no lock required. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_extctrl_param(struct tdls_peer *peer, uint32_t chan, + uint32_t max_latency, uint32_t op_class, + uint32_t min_bandwidth); + +/** + * tdls_reset_peer() - reset TDLS peer identified by MAC address + * @vdev_obj: TDLS vdev object + * @mac: MAC address of the peer + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *mac); + +/** + * tdls_peer_idle_timers_destroy() - destroy peer idle timers + * @vdev_obj: TDLS vdev object + * + * Loop through the idle peer list and destroy their timers + * + * Return: None + */ +void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj); + +/** + * tdls_free_peer_list() - free TDLS peer list + * @vdev_obj: TDLS vdev object + * + * Free all the tdls peers + * + * Return: None + */ +void tdls_free_peer_list(struct tdls_vdev_priv_obj *vdev_obj); +#endif diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index d9b5d8da985d..2f76979be4fb 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -30,15 +30,36 @@ #include #include -#define WLAN_TDLS_STA_MAX_NUM 8 -#define WLAN_TDLS_PEER_LIST_SIZE 256 -#define WLAN_TDLS_CT_TABLE_SIZE 8 -#define WLAN_TDLS_PEER_SUB_LIST_SIZE 10 -#define WLAN_MAC_MAX_EXTN_CAP 8 -#define WLAN_MAC_MAX_SUPP_CHANNELS 100 -#define WLAN_MAX_SUPP_OPER_CLASSES 32 -#define WLAN_MAC_MAX_SUPP_RATES 32 -#define ENABLE_CHANSWITCH 1 +#define WLAN_TDLS_STA_MAX_NUM 8 +#define WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM 1 +#define WLAN_TDLS_PEER_LIST_SIZE 16 +#define WLAN_TDLS_CT_TABLE_SIZE 8 +#define WLAN_TDLS_PEER_SUB_LIST_SIZE 10 +#define WLAN_MAC_MAX_EXTN_CAP 8 +#define WLAN_MAC_MAX_SUPP_CHANNELS 100 +#define WLAN_MAX_SUPP_OPER_CLASSES 32 +#define WLAN_MAC_MAX_SUPP_RATES 32 +#define WLAN_CHANNEL_14 14 +#define ENABLE_CHANSWITCH 1 +#define DISABLE_CHANSWITCH 2 +#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1 +#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165 +#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF 36 + +/** Maximum time(ms) to wait for tdls add sta to complete **/ +#define WAIT_TIME_TDLS_ADD_STA 1500 + +/** Maximum time(ms) to wait for tdls del sta to complete **/ +#define WAIT_TIME_TDLS_DEL_STA 1500 + +/** Maximum time(ms) to wait for Link Establish Req to complete **/ +#define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500 + +/** Maximum time(ms) to wait for tdls mgmt to complete **/ +#define WAIT_TIME_TDLS_MGMT 11000 + +#define TDLS_TEARDOWN_PEER_UNREACHABLE 25 +#define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 #define TDLS_STA_INDEX_CHECK(sta_id) \ (((sta_id) >= 1) && ((sta_id) < 0xFF)) @@ -65,7 +86,23 @@ enum tdls_peer_capab { }; /** - * enum tdls_link_status - tdls link status + * enum tdls_peer_state - tdls peer state + * @TDLS_PEER_STATE_PEERING: tdls connection in progress + * @TDLS_PEER_STATE_CONNCTED: tdls peer is connected + * @TDLS_PEER_STATE_TEARDOWN: tdls peer is tear down + * @TDLS_PEER_ADD_MAC_ADDR: add peer mac into connection table + * @TDLS_PEER_REMOVE_MAC_ADDR: remove peer mac from connection table + */ +enum tdls_peer_state { + TDLS_PEER_STATE_PEERING, + TDLS_PEER_STATE_CONNCTED, + TDLS_PEER_STATE_TEARDOWN, + TDLS_PEER_ADD_MAC_ADDR, + TDLS_PEER_REMOVE_MAC_ADDR +}; + +/** + * enum tdls_link_state - tdls link state * @TDLS_LINK_IDLE: tdls link idle * @TDLS_LINK_DISCOVERING: tdls link discovering * @TDLS_LINK_DISCOVERED: tdls link discovered @@ -73,7 +110,7 @@ enum tdls_peer_capab { * @TDLS_LINK_CONNECTED: tdls link connected * @TDLS_LINK_TEARING: tdls link tearing */ -enum tdls_link_status { +enum tdls_link_state { TDLS_LINK_IDLE = 0, TDLS_LINK_DISCOVERING, TDLS_LINK_DISCOVERED, @@ -83,7 +120,7 @@ enum tdls_link_status { }; /** - * enum tdls_link_reason - tdls link reason + * enum tdls_link_state_reason - tdls link reason * @TDLS_LINK_SUCCESS: Success * @TDLS_LINK_UNSPECIFIED: Unspecified reason * @TDLS_LINK_NOT_SUPPORTED: Remote side doesn't support TDLS @@ -91,7 +128,7 @@ enum tdls_link_status { * @TDLS_LINK_NOT_BENEFICIAL: Going to AP is better than direct * @TDLS_LINK_DROPPED_BY_REMOTE: Remote side doesn't want it anymore */ -enum tdls_link_reason { +enum tdls_link_state_reason { TDLS_LINK_SUCCESS, TDLS_LINK_UNSPECIFIED = -1, TDLS_LINK_NOT_SUPPORTED = -2, @@ -101,7 +138,7 @@ enum tdls_link_reason { }; /** - * enum tdls_support_mode - TDLS support mode + * enum tdls_feature_mode - TDLS support mode * @TDLS_SUPPORT_DISABLED: Disabled in ini or FW * @TDLS_SUPPORT_SUSPENDED: TDLS supported by ini and FW, but disabled * temporarily due to off-channel operations or due to other reasons @@ -109,7 +146,7 @@ enum tdls_link_reason { * @TDLS_SUPPORT_IMP_MODE: Implicit mode * @TDLS_SUPPORT_EXT_CONTROL: External control mode */ -enum tdls_support_mode { +enum tdls_feature_mode { TDLS_SUPPORT_DISABLED = 0, TDLS_SUPPORT_SUSPENDED, TDLS_SUPPORT_EXP_TRIG_ONLY, @@ -124,6 +161,9 @@ enum tdls_support_mode { * @TDLS_EVENT_RX_MGMT: rx discovery response frame * @TDLS_EVENT_ADD_PEER: add peer or update peer * @TDLS_EVENT_DEL_PEER: delete peer + * @TDLS_EVENT_DISCOVERY_REQ: dicovery request + * @TDLS_EVENT_TEARDOWN_REQ: teardown request + * @TDLS_EVENT_SETUP_REQ: setup request */ enum tdls_event_type { TDLS_EVENT_VDEV_STATE_CHANGE = 0, @@ -131,11 +171,13 @@ enum tdls_event_type { TDLS_EVENT_RX_MGMT, TDLS_EVENT_ADD_PEER, TDLS_EVENT_DEL_PEER, + TDLS_EVENT_DISCOVERY_REQ, + TDLS_EVENT_TEARDOWN_REQ, + TDLS_EVENT_SETUP_REQ, }; /** * enum tdls_state_t - tdls state - * * @QCA_WIFI_HAL_TDLS_DISABLED: TDLS is not enabled, or is disabled now * @QCA_WIFI_HAL_TDLS_ENABLED: TDLS is enabled, but not yet tried * @QCA_WIFI_HAL_TDLS_ESTABLISHED: Direct link is established @@ -152,12 +194,25 @@ enum tdls_state_t { QCA_WIFI_HAL_TDLS_S_FAILED, }; +/** + * enum tdls_off_chan_mode - mode for WMI_TDLS_SET_OFFCHAN_MODE_CMDID + * @TDLS_ENABLE_OFFCHANNEL: enable off channel + * @TDLS_DISABLE_OFFCHANNEL: disable off channel + */ +enum tdls_off_chan_mode { + TDLS_ENABLE_OFFCHANNEL, + TDLS_DISABLE_OFFCHANNEL +}; + /** * enum tdls_event_msg_type - TDLS event message type - * @TDLS_SHOULD_DISCOVER: should do discover - * @TDLS_SHOULD_TEARDOWN: notify teardown the link + * @TDLS_SHOULD_DISCOVER: should do discover for peer (based on tx bytes per + * second > tx_discover threshold) + * @TDLS_SHOULD_TEARDOWN: recommend teardown the link for peer due to tx bytes + * per second below tx_teardown_threshold * @TDLS_PEER_DISCONNECTED: tdls peer disconnected - * @TDLS_CONNECTION_TRACKER_NOTIFY: connection tracker notify + * @TDLS_CONNECTION_TRACKER_NOTIFY: TDLS/BT role change notification for + * connection tracker */ enum tdls_event_msg_type { TDLS_SHOULD_DISCOVER = 0, @@ -168,19 +223,25 @@ enum tdls_event_msg_type { /** * enum tdls_event_reason - TDLS event reason - * @TDLS_TEARDOWN_TX: - * @TDLS_TEARDOWN_RSSI: - * @TDLS_TEARDOWN_SCAN: - * @TDLS_TEARDOWN_PTR_TIMEOUT: - * @TDLS_TEARDOWN_BAD_PTR: - * @TDLS_TEARDOWN_NO_RSP: - * @TDLS_DISCONNECTED_PEER_DELETE: - * @TDLS_PEER_ENTER_BUF_STA: - * @TDLS_PEER_EXIT_BUF_STA: - * @TDLS_ENTER_BT_BUSY: - * @TDLS_EXIT_BT_BUSY: - * @DLS_SCAN_STARTED: - * @TDLS_SCAN_COMPLETED: + * @TDLS_TEARDOWN_TX: tdls teardown recommended due to low transmits + * @TDLS_TEARDOWN_RSSI: tdls link tear down recommended due to poor RSSI + * @TDLS_TEARDOWN_SCAN: tdls link tear down recommended due to offchannel scan + * @TDLS_TEARDOWN_PTR_TIMEOUT: tdls peer disconnected due to PTR timeout + * @TDLS_TEARDOWN_BAD_PTR: tdls peer disconnected due wrong PTR format + * @TDLS_TEARDOWN_NO_RSP: tdls peer not responding + * @TDLS_DISCONNECTED_PEER_DELETE: tdls peer disconnected due to peer deletion + * @TDLS_PEER_ENTER_BUF_STA: tdls entered buffer STA role, TDLS connection + * tracker needs to handle this + * @TDLS_PEER_EXIT_BUF_STA: tdls exited buffer STA role, TDLS connection tracker + * needs to handle this + * @TDLS_ENTER_BT_BUSY: BT entered busy mode, TDLS connection tracker needs to + * handle this + * @TDLS_EXIT_BT_BUSY: BT exited busy mode, TDLS connection tracker needs to + * handle this + * @DLS_SCAN_STARTED: TDLS module received a scan start event, TDLS connection + * tracker needs to handle this + * @TDLS_SCAN_COMPLETED: TDLS module received a scan complete event, TDLS + * connection tracker needs to handle this */ enum tdls_event_reason { TDLS_TEARDOWN_TX, @@ -198,6 +259,19 @@ enum tdls_event_reason { TDLS_SCAN_COMPLETED, }; +/** + * struct tdls_osif_indication - tdls indication to os if layer + * @vdev: vdev object + * @reason: used with teardown indication + * @peer_mac: MAC address of the TDLS peer + */ +struct tdls_osif_indication { + struct wlan_objmgr_vdev *vdev; + uint16_t reason; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + QDF_STATUS status; +}; + /** * struct tx_frame - tx frame * @buf: frame buffer @@ -268,13 +342,14 @@ enum tdls_feature_bit { * @tdls_pre_off_chan_num: tdls off channel number * @tdls_pre_off_chan_bw: tdls off channel bandwidth * @tdls_peer_kickout_threshold: sta kickout threshold for tdls peer + * @delayed_trig_framint: delayed trigger frame interval */ struct tdls_user_config { uint32_t tdls_tx_states_period; uint32_t tdls_tx_pkt_threshold; uint32_t tdls_rx_pkt_threshold; uint32_t tdls_max_discovery_attempt; - uint32_t tdls_idle_timeoute; + uint32_t tdls_idle_timeout; uint32_t tdls_idle_pkt_threshold; uint32_t tdls_rssi_trigger_threshold; uint32_t tdls_rssi_teardown_threshold; @@ -287,6 +362,7 @@ struct tdls_user_config { uint32_t tdls_pre_off_chan_num; uint32_t tdls_pre_off_chan_bw; uint32_t tdls_peer_kickout_threshold; + uint32_t delayed_trig_framint; }; /** @@ -331,32 +407,60 @@ struct tdls_tx_cnf { /* This callback is used to report state change of peer to wpa_supplicant */ typedef int (*tdls_state_change_callback)(const uint8_t *mac, - uint32_t opclass, - uint32_t channel, - uint32_t state, - int32_t reason, void *ctx); + uint32_t opclass, + uint32_t channel, + uint32_t state, + int32_t reason, void *ctx); /* This callback is used to report events to os_if layer */ -typedef QDF_STATUS (*tdls_evt_callback) (void *data, - enum tdls_event_type ev_type, - void *event); +typedef void (*tdls_evt_callback) (void *data, + enum tdls_event_type ev_type, + struct tdls_osif_indication *event); /* prototype of callback registered by hdd to receive the ack cnf */ typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, - struct tdls_tx_cnf *tx_ack_cnf_cb_data); + struct tdls_tx_cnf *tx_ack_cnf_cb_data); +/* This callback is used to register TDLS peer with TL */ +typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata, + uint32_t vdev_id, + const uint8_t *mac, + uint16_t stat_id, + uint8_t ucastsig, + uint8_t qos); + +/* This callback is used to deregister TDLS peer */ +typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, + uint32_t vdev_id, + uint8_t sta_id); /** * struct tdls_start_params - tdls start params + * @config: tdls user config + * @tdls_send_mgmt_req: pass eWNI_SME_TDLS_SEND_MGMT_REQ value + * @tdls_add_sta_req: pass eWNI_SME_TDLS_ADD_STA_REQ value + * @tdls_del_sta_req: pass eWNI_SME_TDLS_DEL_STA_REQ value + * @tdls_update_peer_state: pass WMA_UPDATE_TDLS_PEER_STATE value * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event data * @ack_cnf_cb: tdls tx ack callback to indicate the tx status * @tx_ack_cnf_cb_data: tdls tx ack user data + * @tdls_reg_tl_peer: tdls register tdls peer + * @tdls_dereg_tl_peer: tdls deregister tdls peer + * @tdls_tl_peer_data: userdata for register/deregister TDLS peer */ struct tdls_start_params { + struct tdls_user_config config; + uint16_t tdls_send_mgmt_req; + uint16_t tdls_add_sta_req; + uint16_t tdls_del_sta_req; + uint16_t tdls_update_peer_state; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; void *tx_ack_cnf_cb_data; + tdls_register_tl_peer_callback tdls_reg_tl_peer; + tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; + void *tdls_tl_peer_data; }; /** @@ -366,7 +470,7 @@ struct tdls_start_params { * @vdev_id: vdev id */ struct tdls_add_peer_params { - const uint8_t *peer_addr; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; uint32_t peer_type; uint32_t vdev_id; }; @@ -437,7 +541,7 @@ struct vhtcap { }; struct tdls_update_peer_params { - const uint8_t *peer_addr; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; uint32_t peer_type; uint32_t vdev_id; uint16_t capability; @@ -454,6 +558,7 @@ struct tdls_update_peer_params { uint8_t supported_channels[WLAN_MAC_MAX_SUPP_CHANNELS]; uint8_t supported_oper_classes_len; uint8_t supported_oper_classes[WLAN_MAX_SUPP_OPER_CLASSES]; + bool is_qos_wmm_sta; }; struct tdls_update_peer_request { @@ -461,6 +566,36 @@ struct tdls_update_peer_request { struct tdls_update_peer_params update_peer_req; }; +/** + * struct tdls_oper_request - tdls operation request + * @vdev: vdev object + * @peer_addr: MAC address of the TDLS peer + */ +struct tdls_oper_request { + struct wlan_objmgr_vdev *vdev; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; +}; + +/** + * struct tdls_oper_config_force_peer_request - tdls enable force peer request + * @vdev: vdev object + * @peer_addr: MAC address of the TDLS peer + * @chan: channel + * @max_latency: maximum latency + * @op_class: operation class + * @min_bandwidth: minimal bandwidth + * @callback: state change callback + */ +struct tdls_oper_config_force_peer_request { + struct wlan_objmgr_vdev *vdev; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; + uint32_t chan; + uint32_t max_latency; + uint32_t op_class; + uint32_t min_bandwidth; + tdls_state_change_callback callback; +}; + /** * struct tdls_info - tdls info * @@ -550,20 +685,22 @@ struct tdls_peer_params { }; /** - * struct tdls_peer_update_params - TDLS peer state parameters + * struct tdls_peer_update_state - TDLS peer state parameters * @vdev_id: vdev id * @peer_macaddr: peer mac address * @peer_cap: peer capabality + * @resp_reqd: response needed */ -struct tdls_peer_update_params { +struct tdls_peer_update_state { uint32_t vdev_id; uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; uint32_t peer_state; struct tdls_peer_params peer_cap; + bool resp_reqd; }; /** - * struct tdls_chan_switch_params - channel switch parameter structure + * struct tdls_channel_switch_params - channel switch parameter structure * @vdev_id: vdev ID * @peer_mac_addr: Peer mac address * @tdls_off_ch_bw_offset: Target off-channel bandwitdh offset @@ -571,7 +708,7 @@ struct tdls_peer_update_params { * @oper_class: Operating class for target channel * @is_responder: Responder or initiator */ -struct tdls_chan_switch_params { +struct tdls_channel_switch_params { uint32_t vdev_id; uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE]; uint16_t tdls_off_ch_bw_offset; diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 02d8c2beff03..052f55b09426 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -28,6 +28,9 @@ #include #include #include +#include +#include +#include /** * ucfg_tdls_init() - TDLS module initialization API @@ -66,8 +69,9 @@ QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc); * * Return: QDF_STATUS */ -QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, - struct tdls_start_params *req); +QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, + struct tdls_start_params *req); + /** * ucfg_tdls_psoc_stop() - TDLS module stop * @psoc: psoc object @@ -75,4 +79,24 @@ QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, * Return: QDF_STATUS */ QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_add_peer() - handle TDLS add peer + * @vdev: vdev object + * @add_peer_req: add peer request parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, + struct tdls_add_peer_params *add_peer_req); + +/** + * ucfg_tdls_update_peer() - handle TDLS update peer + * @vdev: vdev object + * @update_peer: update TDLS request parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, + struct tdls_update_peer_params *update_peer); #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 3d49c5adac75..045d99d1e91d 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -24,6 +24,7 @@ #include #include "../../core/src/wlan_tdls_main.h" +#include "../../core/src/wlan_tdls_cmds_process.h" #include #include @@ -113,6 +114,7 @@ QDF_STATUS ucfg_tdls_deinit(void) static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) { uint8_t sta_idx; + uint32_t feature; soc_obj->connected_peer_count = 0; soc_obj->tdls_nss_switch_in_progress = false; @@ -120,7 +122,16 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) soc_obj->tdls_nss_teardown_complete = false; soc_obj->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_S_UNKNOWN; soc_obj->tdls_user_config_mode = TDLS_SUPPORT_DISABLED; - soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if (TDLS_IS_BUFFER_STA_ENABLED(feature) || + TDLS_IS_SLEEP_STA_ENABLED(feature) || + TDLS_IS_OFF_CHANNEL_ENABLED(feature)) + soc_obj->max_num_tdls_sta = + WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM; + else + soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; + for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { soc_obj->tdls_conn_info[sta_idx].sta_id = 0; @@ -142,7 +153,7 @@ QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc) tdls_notice("tdls psoc open"); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - if (soc_obj == NULL) { + if (!soc_obj) { tdls_err("Failed to get tdls psoc component"); return QDF_STATUS_E_FAILURE; } @@ -152,15 +163,21 @@ QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc) return status; } -QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, - struct tdls_start_params *req) +QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, + struct tdls_start_params *req) { struct tdls_soc_priv_obj *soc_obj; + uint32_t tdls_feature_flags; + + tdls_notice("tdls update config "); + if (!psoc || !req) { + tdls_err("psoc: 0x%p, req: 0x%p", psoc, req); + return QDF_STATUS_E_FAILURE; + } - tdls_notice("tdls psoc start"); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - if (soc_obj == NULL) { + if (!soc_obj) { tdls_err("Failed to get tdls psoc component"); return QDF_STATUS_E_FAILURE; } @@ -171,6 +188,28 @@ QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; + /* Save callbacks to register/deregister TDLS sta with TL */ + soc_obj->tdls_reg_tl_peer = req->tdls_reg_tl_peer; + soc_obj->tdls_dereg_tl_peer = req->tdls_dereg_tl_peer; + soc_obj->tdls_tl_peer_data = req->tdls_tl_peer_data; + + /* Save legacy PE/WMA commands in TDLS soc object */ + soc_obj->tdls_send_mgmt_req = req->tdls_send_mgmt_req; + soc_obj->tdls_add_sta_req = req->tdls_add_sta_req; + soc_obj->tdls_del_sta_req = req->tdls_del_sta_req; + soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; + + /* Update TDLS user config */ + qdf_mem_copy(&soc_obj->tdls_configs, &req->config, sizeof(req->config)); + tdls_feature_flags = soc_obj->tdls_configs.tdls_feature_flags; + + if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) + soc_obj->tdls_current_mode = TDLS_SUPPORT_EXP_TRIG_ONLY; + else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags)) + soc_obj->tdls_current_mode = TDLS_SUPPORT_EXT_CONTROL; + else + soc_obj->tdls_current_mode = TDLS_SUPPORT_IMP_MODE; + return QDF_STATUS_SUCCESS; } @@ -181,7 +220,7 @@ QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc) tdls_notice("tdls psoc stop"); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - if (soc_obj == NULL) { + if (!soc_obj) { tdls_err("Failed to get tdls psoc component"); return QDF_STATUS_E_FAILURE; } @@ -203,3 +242,93 @@ QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc) return status; } + +QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, + struct tdls_add_peer_params *add_peer_req) +{ + struct scheduler_msg msg = {0, }; + struct tdls_add_peer_request *req; + QDF_STATUS status; + + if (!vdev || !add_peer_req) { + tdls_err("vdev: %p, req %p", vdev, add_peer_req); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_debug("vdevid: %d, peertype: %d", + add_peer_req->vdev_id, add_peer_req->peer_type); + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + return status; + } + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + status = QDF_STATUS_E_NOMEM; + goto dec_ref; + } + + qdf_mem_copy(&req->add_peer_req, add_peer_req, sizeof(*add_peer_req)); + req->vdev = vdev; + + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_ADD_STA; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post add peer msg fail"); + qdf_mem_free(req); + goto dec_ref; + } + + return status; +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + return status; +} + +QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, + struct tdls_update_peer_params *update_peer) +{ + struct scheduler_msg msg = {0,}; + struct tdls_update_peer_request *req; + QDF_STATUS status; + + if (!vdev || !update_peer) { + tdls_err("vdev: %p, update_peer: %p", vdev, update_peer); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_debug("vdev_id: %d, peertype: %d", + update_peer->vdev_id, update_peer->peer_type); + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + return status; + } + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + status = QDF_STATUS_E_NOMEM; + goto dec_ref; + } + qdf_mem_copy(&req->update_peer_req, update_peer, sizeof(*update_peer)); + req->vdev = vdev; + + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_CHANGE_STA; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post update peer msg fail"); + qdf_mem_free(req); + goto dec_ref; + } + + return status; +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + return status; +} From 96bbde31a638cb9128ac5773711c6f5d8319f78f Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Tue, 11 Apr 2017 22:37:03 +0800 Subject: [PATCH 048/404] qcacmn: TDLS component: south interface Add lmac_if layer changes for TDLS Change-Id: Ic842857ce7ebc83d2a22a8a8e23c60df1c3dbfc8 CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 2 +- dispatcher/inc/wlan_tdls_public_structs.h | 56 ++++++++ dispatcher/inc/wlan_tdls_tgt_api.h | 91 ++++++++++++ dispatcher/src/wlan_tdls_tgt_api.c | 162 ++++++++++++++++++++++ 4 files changed, 310 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 12dde2563df9..4e1f0f0db1f1 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -981,7 +981,7 @@ error: } /** - * tdls_process_add_peer_rsp() - handle response for add TDLS peer + * tdls_add_peer_rsp() - handle response for add TDLS peer * @rsp: TDLS add peer response * * Return: QDF_STATUS_SUCCESS for success; other values if failed diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 2f76979be4fb..4fc129ebead3 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -718,6 +718,62 @@ struct tdls_channel_switch_params { uint8_t is_responder; }; +/** + * enum uapsd_access_cat - U-APSD Access Categories + * @UAPSD_AC_BE: best effort + * @UAPSD_AC_BK: back ground + * @UAPSD_AC_VI: video + * @UAPSD_AC_VO: voice + */ +enum uapsd_access_cat { + UAPSD_AC_BE, + UAPSD_AC_BK, + UAPSD_AC_VI, + UAPSD_AC_VO +}; + +/** + * enum tspec_dir_type - TSPEC Direction type + * @TX_DIR: uplink + * @RX_DIR: downlink + * @BI_DIR: bidirectional + */ +enum tspec_dir_type { + TX_DIR = 0, + RX_DIR = 1, + BI_DIR = 2, +}; + +/** + * struct sta_uapsd_params - uapsd auto trig params + * @wmm_ac: WMM access category from 0 to 3 + * @user_priority: User priority to use in trigger frames + * @service_interval: service interval + * @suspend_interval: suspend interval + * @delay_interval: delay interval + */ +struct sta_uapsd_params { + uint32_t wmm_ac; + uint32_t user_priority; + uint32_t service_interval; + uint32_t suspend_interval; + uint32_t delay_interval; +}; + +/** + * struct sta_uapsd_trig_params - uapsd trigger parameter + * @vdevid: vdev id + * @peer_addr: peer address + * @auto_triggerparam: trigger parameters + * @num_ac: no of access category + */ +struct sta_uapsd_trig_params { + uint32_t vdevid; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; + struct sta_uapsd_params *auto_triggerparam; + uint32_t num_ac; +}; + /** * struct tdls_event_info - firmware tdls event * @vdev_id: vdev id diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h index 78454e0829f4..dbc8c0683f50 100644 --- a/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -21,3 +21,94 @@ * * TDLS south bound interface declaration */ + +#ifndef _WLAN_TDLS_TGT_API_H_ +#define _WLAN_TDLS_TGT_API_H_ +#include +#include "../../core/src/wlan_tdls_main.h" + +/** + * tgt_tdls_set_fw_state() - invoke lmac tdls update fw + * @psoc: soc object + * @tdls_param: update tdls state parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_set_fw_state(struct wlan_objmgr_psoc *psoc, + struct tdls_info *tdls_param); + +/** + * tgt_tdls_set_peer_state() - invoke lmac tdls update peer state + * @psoc: soc object + * @peer_param: update tdls peer parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_set_peer_state(struct wlan_objmgr_psoc *psoc, + struct tdls_peer_update_state *peer_param); + +/** + * tgt_tdls_set_offchan_mode() - invoke lmac tdls set off-channel mode + * @psoc: soc object + * @param: set tdls off channel parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *param); + +/** + * tgt_tdls_set_uapsd()- invoke lamc tdls set uapsd function + * @psoc: soc object + * @params: uapsd parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, + struct sta_uapsd_trig_params *params); + +/** + * tgt_tdls_del_peer_rsp() - handle TDLS del peer response + * @pmsg: sheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg); + +/** + * tgt_tdls_add_peer_rsp() - handle TDLS add peer response + * @pmsg: sheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg); + +/** + * tgt_tdls_register_ev_handler() - invoke lmac register tdls event handler + * @psoc: soc object + * + * Return: QDF_STATUS_SUCCESS for success or error code. + */ +QDF_STATUS tgt_tdls_register_ev_handler(struct wlan_objmgr_psoc *psoc); + +/** + * tgt_tdls_unregister_ev_handler() - invoke lmac unregister tdls event handler + * @psoc: soc object + * + * Return: QDF_STATUS_SUCCESS for success or error code. + */ +QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc); + +/** + * tgt_tdls_event_handler() - The callback registered to WMI for tdls events + * @psoc: psoc object + * @info: tdls event info + * + * The callback is registered by tgt as tdls rx ops handler. + * + * Return: 0 for success or err code. + */ +QDF_STATUS +tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, + struct tdls_event_info *info); +#endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 864886bb4bb9..78a198b2a71f 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -21,3 +21,165 @@ * * TDLS south bound interface definitions */ + +#include "qdf_status.h" +#include +#include "../../core/src/wlan_tdls_main.h" +#include "../../core/src/wlan_tdls_cmds_process.h" + +static inline struct wlan_lmac_if_tdls_tx_ops * +wlan_psoc_get_tdls_txops(struct wlan_objmgr_psoc *psoc) +{ + return &psoc->soc_cb.tx_ops.tdls_tx_ops; +} + +static inline struct wlan_lmac_if_tdls_rx_ops * +wlan_psoc_get_tdls_rxops(struct wlan_objmgr_psoc *psoc) +{ + return &psoc->soc_cb.rx_ops.tdls_rx_ops; +} + +QDF_STATUS tgt_tdls_set_fw_state(struct wlan_objmgr_psoc *psoc, + struct tdls_info *tdls_param) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->update_fw_state) + return tdls_ops->update_fw_state(psoc, tdls_param); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_set_peer_state(struct wlan_objmgr_psoc *psoc, + struct tdls_peer_update_state *peer_param) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->update_peer_state) + return tdls_ops->update_peer_state(psoc, peer_param); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *param) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->set_offchan_mode) + return tdls_ops->set_offchan_mode(psoc, param); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, + struct sta_uapsd_trig_params *params) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->tdls_set_uapsd) + return tdls_ops->tdls_set_uapsd(psoc, params); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pmsg || !pmsg->bodyptr) { + tdls_err("msg: 0x%p", pmsg); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tdls_process_add_peer_rsp(pmsg->bodyptr); + + return status; +} + +QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pmsg || !pmsg->bodyptr) { + tdls_err("msg: 0x%p", pmsg); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tdls_process_del_peer_rsp(pmsg->bodyptr); + + return status; +} + +QDF_STATUS tgt_tdls_register_ev_handler(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->tdls_reg_ev_handler) + return tdls_ops->tdls_reg_ev_handler(psoc, NULL); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops->tdls_unreg_ev_handler) + return tdls_ops->tdls_unreg_ev_handler(psoc, NULL); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, + struct tdls_event_info *info) +{ + struct scheduler_msg msg = {0,}; + struct tdls_event_notify *notify; + uint8_t vdev_id; + QDF_STATUS status; + + if (!psoc || !info) { + tdls_err("psoc: 0x%p, info: 0x%p", psoc, info); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDRESS_STR, + info->vdev_id, info->message_type, info->peer_reason, + QDF_MAC_ADDR_ARRAY(info->peermac.bytes)); + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + vdev_id = info->vdev_id; + notify->vdev = + wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, WLAN_TDLS_SB_ID); + if (!notify->vdev) { + tdls_err("null vdev, vdev_id: %d, psoc: 0x%p", vdev_id, psoc); + return QDF_STATUS_E_INVAL; + } + qdf_mem_copy(¬ify->event, info, sizeof(*info)); + + msg.bodyptr = notify; + msg.callback = tdls_process_evt; + + status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't post msg to handle tdls event"); + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID); + qdf_mem_free(notify); + } + + return status; +} From 6828d58ce9946db2f43ed6bffeefa2b5858308d9 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Tue, 11 Apr 2017 22:37:03 +0800 Subject: [PATCH 049/404] qcacmn: TDLS component: south interface Add lmac_if layer changes for TDLS Change-Id: Ic842857ce7ebc83d2a22a8a8e23c60df1c3dbfc8 CRs-Fixed: 2011330 --- inc/target_if_tdls.h | 116 ++++++++++++++++++++++++++++ src/target_if_tdls.c | 176 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 292 insertions(+) create mode 100644 inc/target_if_tdls.h create mode 100644 src/target_if_tdls.c diff --git a/inc/target_if_tdls.h b/inc/target_if_tdls.h new file mode 100644 index 000000000000..7fe21cdf0c4e --- /dev/null +++ b/inc/target_if_tdls.h @@ -0,0 +1,116 @@ +/* + * 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: offload lmac interface APIs for tdls + * + */ + +#ifndef __TARGET_IF_TDLS_H__ +#define __TARGET_IF_TDLS_H__ + +struct tdls_info; +struct wlan_objmgr_psoc; +struct tdls_peer_update_state; +struct tdls_channel_switch_params; +struct sta_uapsd_trig_params; + +/** + * target_if_tdls_update_fw_state() - lmac handler to update tdls fw state + * @psoc: psoc object + * @param: tdls state parameter + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_tdls_update_fw_state(struct wlan_objmgr_psoc *psoc, + struct tdls_info *param); + +/** + * target_if_tdls_update_peer_state() - lmac handler to update tdls peer state + * @psoc: psoc object + * @peer_params: tdls peer state params + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_tdls_update_peer_state(struct wlan_objmgr_psoc *psoc, + struct tdls_peer_update_state *peer_params); + +/** + * target_if_tdls_set_offchan_mode() - lmac handler to set tdls off channel mode + * @psoc: psoc object + * @params: tdls channel swithc params + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *params); + +/** + * target_if_tdls_set_uapsd() - lmac handler to set uapsd auto trigger cmd + * @psoc: psoc object + * @params: upasd parameters + * + * This function sets the trigger + * uapsd params such as service interval, delay interval + * and suspend interval which will be used by the firmware + * to send trigger frames periodically when there is no + * traffic on the transmit side. + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, + struct sta_uapsd_trig_params *params); + +/** + * target_if_tdls_register_event_handler() - lmac handler to register tdls event + * handler + * @psoc : psoc object + * @arg: argument passed to lmac + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_tdls_register_event_handler(struct wlan_objmgr_psoc *psoc, + void *arg); + +/** + * target_if_tdls_unregister_event_handler() - lmac handler to unregister tdls + * event handler + * @psoc : psoc object + * @arg: argument passed to lmac + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_tdls_unregister_event_handler(struct wlan_objmgr_psoc *psoc, + void *arg); + +/** + * target_if_tdls_register_tx_ops() - lmac handler to register tdls tx ops + * callback functions + * @tx_ops: wlan_lmac_if_tx_ops object + * + * Return: QDF_STATUS + */ +QDF_STATUS +target_if_tdls_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); +#endif diff --git a/src/target_if_tdls.c b/src/target_if_tdls.c new file mode 100644 index 000000000000..9f304f2bf2b8 --- /dev/null +++ b/src/target_if_tdls.c @@ -0,0 +1,176 @@ +/* + * 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: offload lmac interface APIs for tdls + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline struct wlan_lmac_if_tdls_rx_ops * +target_if_tdls_get_rx_ops(struct wlan_objmgr_psoc *psoc) +{ + return &psoc->soc_cb.rx_ops.tdls_rx_ops; +} + +static int +target_if_tdls_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen) +{ + struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; + struct wlan_lmac_if_tdls_rx_ops *tdls_rx_ops; + struct tdls_event_info info; + QDF_STATUS status; + + if (!scn || !data) { + target_if_err("scn: 0x%p, data: 0x%p", scn, data); + return -EINVAL; + } + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + target_if_err("null psoc"); + return -EINVAL; + } + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + + if (wmi_extract_vdev_tdls_ev_param(wmi_handle, data, &info)) { + target_if_err("Failed to extract wmi tdls event"); + return -EINVAL; + } + + tdls_rx_ops = target_if_tdls_get_rx_ops(psoc); + if (tdls_rx_ops && tdls_rx_ops->tdls_ev_handler) { + status = tdls_rx_ops->tdls_ev_handler(psoc, &info); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("fail to handle tdls event"); + return -EINVAL; + } + } + + return 0; +} + +QDF_STATUS +target_if_tdls_update_fw_state(struct wlan_objmgr_psoc *psoc, + struct tdls_info *param) +{ + QDF_STATUS status; + uint8_t tdls_state; + + if (TDLS_SUPPORT_EXP_TRIG_ONLY == param->tdls_state) + tdls_state = WMI_TDLS_ENABLE_PASSIVE; + else if (TDLS_SUPPORT_IMP_MODE == param->tdls_state || + TDLS_SUPPORT_EXT_CONTROL == param->tdls_state) + tdls_state = WMI_TDLS_ENABLE_CONNECTION_TRACKER_IN_HOST; + else + tdls_state = WMI_TDLS_DISABLE; + + status = wmi_unified_update_fw_tdls_state_cmd(psoc->tgt_if_handle, + param, tdls_state); + + target_if_debug("vdev_id %d", param->vdev_id); + return status; +} + +QDF_STATUS +target_if_tdls_update_peer_state(struct wlan_objmgr_psoc *psoc, + struct tdls_peer_update_state *peer_params) +{ + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +target_if_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *params) +{ + QDF_STATUS status; + + status = wmi_unified_set_tdls_offchan_mode_cmd(psoc->tgt_if_handle, + params); + + return status; +} + +QDF_STATUS +target_if_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, + struct sta_uapsd_trig_params *params) +{ + QDF_STATUS ret; + + if (!WMI_SERVICE_IS_ENABLED(psoc->service_param.service_bitmap, + WMI_STA_UAPSD_BASIC_AUTO_TRIG) || + !WMI_SERVICE_IS_ENABLED(psoc->service_param.service_bitmap, + WMI_STA_UAPSD_VAR_AUTO_TRIG)) { + target_if_debug("Trigger uapsd is not supported vdev id %d", + params->vdevid); + return QDF_STATUS_SUCCESS; + } + ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(psoc->tgt_if_handle, + params); + + if (QDF_IS_STATUS_ERROR(ret)) + target_if_err("Failed to send set uapsd param ret = %d", ret); + + return ret; +} + +QDF_STATUS +target_if_tdls_register_event_handler(struct wlan_objmgr_psoc *psoc, + void *arg) +{ + return wmi_unified_register_event(psoc->tgt_if_handle, + wmi_tdls_peer_event_id, + target_if_tdls_event_handler); +} + +QDF_STATUS +target_if_tdls_unregister_event_handler(struct wlan_objmgr_psoc *psoc, + void *arg) +{ + return wmi_unified_unregister_event(psoc->tgt_if_handle, + wmi_tdls_peer_event_id); +} + +QDF_STATUS +target_if_tdls_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_txops; + + tdls_txops = &tx_ops->tdls_tx_ops; + + tdls_txops->update_fw_state = target_if_tdls_update_fw_state; + tdls_txops->update_peer_state = target_if_tdls_update_peer_state; + tdls_txops->set_offchan_mode = target_if_tdls_set_offchan_mode; + tdls_txops->tdls_reg_ev_handler = target_if_tdls_register_event_handler; + tdls_txops->tdls_unreg_ev_handler = + target_if_tdls_unregister_event_handler; + tdls_txops->tdls_set_uapsd = target_if_tdls_set_uapsd; + + return QDF_STATUS_SUCCESS; +} From 8cbcde2860a9efc3e7b39321c054c7db857d2f4f Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Mon, 20 Mar 2017 14:39:07 +0800 Subject: [PATCH 050/404] qcacmn: TDLS component: core tdls_oper operations Implement TDLS oper fucntions Change-Id: Ibdd1fa30ef5b72fbbe8316f88d8c4b9deab1a5a7 CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 442 ++++++++++++++++++++++ core/src/wlan_tdls_cmds_process.h | 26 ++ core/src/wlan_tdls_main.c | 6 +- core/src/wlan_tdls_main.h | 24 -- dispatcher/inc/wlan_tdls_public_structs.h | 29 +- dispatcher/inc/wlan_tdls_ucfg_api.h | 11 + dispatcher/src/wlan_tdls_ucfg_api.c | 64 ++++ 7 files changed, 576 insertions(+), 26 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 4e1f0f0db1f1..1c5d68454bbd 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -21,10 +21,12 @@ * * TDLS north bound commands implementation */ +#include #include #include "wlan_tdls_main.h" #include "wlan_tdls_peer.h" #include "wlan_tdls_cmds_process.h" +#include "wlan_tdls_tgt_api.h" static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) { @@ -35,6 +37,8 @@ static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) * tdls_decrement_peer_count() - decrement connected TDLS peer counter * @soc_obj: TDLS soc object * + * Used in scheduler thread context, no lock needed. + * * Return: None. */ static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) @@ -45,6 +49,20 @@ static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) tdls_debug("Connected peer count %d", soc_obj->connected_peer_count); } +/** + * tdls_increment_peer_count() - increment connected TDLS peer counter + * @soc_obj: TDLS soc object + * + * Used in scheduler thread context, no lock needed. + * + * Return: None. + */ +static void tdls_increment_peer_count(struct tdls_soc_priv_obj *soc_obj) +{ + soc_obj->connected_peer_count++; + tdls_debug("Connected peer count %d", soc_obj->connected_peer_count); +} + /** * tdls_validate_current_mode() - check current TDL mode * @soc_obj: TDLS soc object @@ -1169,3 +1187,427 @@ error: return status; } + +static QDF_STATUS +tdls_wma_update_peer_state(struct tdls_soc_priv_obj *soc_obj, + struct tdls_peer_update_state *peer_state) +{ + struct scheduler_msg msg = {0,}; + QDF_STATUS status; + + tdls_debug("update TDLS peer " QDF_MAC_ADDRESS_STR " vdev %d, state %d", + QDF_MAC_ADDR_ARRAY(peer_state->peer_macaddr), + peer_state->vdev_id, peer_state->peer_state); + msg.type = soc_obj->tdls_update_peer_state; + msg.reserved = 0; + msg.bodyptr = peer_state; + + status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("scheduler_post_msg failed"); + status = QDF_STATUS_E_FAILURE; + } + + return status; +} + +static QDF_STATUS +tdls_update_uapsd(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, + uint8_t sta_id, uint32_t srvc_int, uint32_t sus_int, + uint8_t dir, uint8_t psb, uint32_t delay_interval) +{ + uint8_t i; + static const uint8_t ac[AC_PRIORITY_NUM] = {UAPSD_AC_VO, UAPSD_AC_VI, + UAPSD_AC_BK, UAPSD_AC_BE}; + static const uint8_t tid[AC_PRIORITY_NUM] = {7, 5, 2, 3}; + uint32_t vdev_id; + + struct sta_uapsd_params tdls_uapsd_params; + struct sta_uapsd_trig_params tdls_trig_params; + struct wlan_objmgr_peer *bsspeer; + uint8_t macaddr[QDF_MAC_ADDR_SIZE]; + QDF_STATUS status; + + if (!psb) { + tdls_debug("No need to configure auto trigger:psb is 0"); + return QDF_STATUS_SUCCESS; + } + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + bsspeer = wlan_vdev_get_bsspeer(vdev); + if (!bsspeer) { + wlan_vdev_obj_unlock(vdev); + tdls_err("bss peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(macaddr, + wlan_peer_get_macaddr(bsspeer), QDF_MAC_ADDR_SIZE); + wlan_vdev_obj_unlock(vdev); + + tdls_debug("TDLS uapsd id %d, srvc %d, sus %d, dir %d psb %d delay %d", + sta_id, srvc_int, sus_int, dir, psb, delay_interval); + for (i = 0; i < AC_PRIORITY_NUM; i++) { + tdls_uapsd_params.wmm_ac = ac[i]; + tdls_uapsd_params.user_priority = tid[i]; + tdls_uapsd_params.service_interval = srvc_int; + tdls_uapsd_params.delay_interval = delay_interval; + tdls_uapsd_params.suspend_interval = sus_int; + + tdls_trig_params.vdevid = vdev_id; + tdls_trig_params.num_ac = 1; + tdls_trig_params.auto_triggerparam = &tdls_uapsd_params; + + qdf_mem_copy(tdls_trig_params.peer_addr, + macaddr, QDF_MAC_ADDR_SIZE); + status = tgt_tdls_set_uapsd(psoc, &tdls_trig_params); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to set uapsd for vdev %d, status %d", + vdev_id, status); + } + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) +{ + struct tdls_peer *peer; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj; + struct wlan_objmgr_vdev *vdev; + uint8_t *mac; + struct tdls_peer_update_state *peer_update_param; + QDF_STATUS status; + uint32_t feature; + uint8_t id; + + vdev = req->vdev; + if (!vdev) { + tdls_err("NULL vdev object"); + qdf_mem_free(req); + return QDF_STATUS_E_NULL_VALUE; + } + + /* vdev reference cnt is acquired in ucfg_tdls_oper */ + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + + if (!vdev_obj || !soc_obj) { + tdls_err("tdls vdev_obj: %p soc_obj: %p", vdev_obj, soc_obj); + status = QDF_STATUS_E_NULL_VALUE; + goto error; + } + + mac = req->peer_addr; + peer = tdls_find_peer(vdev_obj, mac); + if (!peer) { + tdls_err(QDF_MAC_ADDRESS_STR + " not found, ignore NL80211_TDLS_ENABLE_LINK", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto error; + } + + tdls_debug("enable link for peer " QDF_MAC_ADDRESS_STR " link state %d", + QDF_MAC_ADDR_ARRAY(mac), peer->link_status); + if (!TDLS_STA_INDEX_CHECK(peer->sta_id)) { + tdls_err("invalid sta idx %u for " QDF_MAC_ADDRESS_STR, + peer->sta_id, QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto error; + } + + peer->tdls_support = TDLS_CAP_SUPPORTED; + if (TDLS_LINK_CONNECTED != peer->link_status) + tdls_set_peer_link_status(peer, TDLS_LINK_CONNECTED, + TDLS_LINK_SUCCESS); + + wlan_vdev_obj_lock(vdev); + id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + status = soc_obj->tdls_reg_tl_peer(soc_obj->tdls_tl_peer_data, + id, mac, peer->sta_id, + peer->signature, peer->qos); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("TDLS register with TL fail, status %d", status); + goto error; + } + + peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); + if (!peer_update_param) { + tdls_err("memory allocation failed"); + status = QDF_STATUS_E_NOMEM; + goto error; + } + + tdls_extract_peer_state_param(peer_update_param, peer); + + status = tdls_wma_update_peer_state(soc_obj, peer_update_param); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(peer_update_param); + status = QDF_STATUS_E_PERM; + goto error; + } + + tdls_increment_peer_count(soc_obj); + feature = soc_obj->tdls_configs.tdls_feature_flags; + + tdls_debug("TDLS buffer sta: %d, uapsd_mask %d", + TDLS_IS_BUFFER_STA_ENABLED(feature), + soc_obj->tdls_configs.tdls_uapsd_mask); + + if (TDLS_IS_BUFFER_STA_ENABLED(feature) || + soc_obj->tdls_configs.tdls_uapsd_mask) + tdls_update_uapsd(soc_obj->soc, + vdev, peer->sta_id, 0, 0, BI_DIR, 1, + soc_obj->tdls_configs.delayed_trig_framint); +error: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + + return status; +} + +/** + * tdls_config_force_peer() - configure an externally controllable TDLS peer + * @req: TDLS operation request + * + * This is not the tdls_process_cmd function. No need to acquire the reference + * count, release reference count and free the request, the caller handle it + * correctly. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +static QDF_STATUS tdls_config_force_peer( + struct tdls_oper_config_force_peer_request *req) +{ + struct tdls_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_vdev *vdev; + const uint8_t *macaddr; + uint32_t feature; + QDF_STATUS status; + struct tdls_peer_update_state *peer_update_param; + + macaddr = req->peer_addr; + tdls_debug("NL80211_TDLS_SETUP for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(macaddr)); + + vdev = req->vdev; + wlan_vdev_obj_lock(vdev); + pdev = wlan_vdev_get_pdev(vdev); + wlan_vdev_obj_unlock(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!pdev || !vdev_obj || !soc_obj) { + tdls_err("pdev: %p, vdev_obj: %p, soc_obj: %p", + pdev, vdev_obj, soc_obj); + return QDF_STATUS_E_INVAL; + } + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || + !TDLS_IS_IMPLICIT_TRIG_ENABLED(feature)) { + tdls_err("TDLS ext ctrl or Imp Trig not enabled, %x", feature); + return QDF_STATUS_E_NOSUPPORT; + } + + peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); + if (!peer_update_param) { + tdls_err("memory allocation failed"); + return QDF_STATUS_E_NOMEM; + } + + peer = tdls_get_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer " QDF_MAC_ADDRESS_STR " does not exist", + QDF_MAC_ADDR_ARRAY(macaddr)); + status = QDF_STATUS_E_NULL_VALUE; + goto error; + } + status = tdls_set_force_peer(vdev_obj, macaddr, true); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("set force peer failed"); + goto error; + } + + /* Update the peer mac to firmware, so firmware could update the + * connection table + */ + wlan_vdev_obj_lock(vdev); + peer_update_param->vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + qdf_mem_copy(peer_update_param->peer_macaddr, + macaddr, QDF_MAC_ADDR_SIZE); + peer_update_param->peer_state = TDLS_PEER_ADD_MAC_ADDR; + + status = tdls_wma_update_peer_state(soc_obj, peer_update_param); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("update peer state failed"); + goto error; + } + + soc_obj->tdls_external_peer_count++; + + /* Validate if off channel is DFS channel */ + if (wlan_reg_is_dfs_ch(pdev, req->chan)) { + tdls_err("Resetting TDLS off-channel from %d to %d", + req->chan, WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF); + req->chan = WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF; + } + tdls_set_extctrl_param(peer, req->chan, req->max_latency, req->op_class, + req->min_bandwidth); + + tdls_set_callback(peer, req->callback); + + return status; +error: + qdf_mem_free(peer_update_param); + return status; +} + +/** + * tdls_process_setup_peer() - process configure an externally + * controllable TDLS peer + * @req: TDLS operation request + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req) +{ + struct tdls_oper_config_force_peer_request peer_req; + struct tdls_soc_priv_obj *soc_obj; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; + + tdls_debug("Configure external TDLS peer " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(req->peer_addr)); + + /* reference cnt is acquired in ucfg_tdls_oper */ + vdev = req->vdev; + if (!vdev) { + tdls_err("NULL vdev object"); + status = QDF_STATUS_E_NULL_VALUE; + goto freereq; + } + + qdf_mem_zero(&peer_req, sizeof(peer_req)); + peer_req.vdev = vdev; + qdf_mem_copy(peer_req.peer_addr, req->peer_addr, QDF_MAC_ADDR_SIZE); + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("NULL soc object"); + status = QDF_STATUS_E_INVAL; + goto error; + } + + peer_req.chan = soc_obj->tdls_configs.tdls_pre_off_chan_num; + + status = tdls_config_force_peer(&peer_req); +error: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +freereq: + qdf_mem_free(req); + + return status; +} + +QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) +{ + struct tdls_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct wlan_objmgr_vdev *vdev; + const uint8_t *macaddr; + uint32_t feature; + QDF_STATUS status; + struct tdls_peer_update_state *peer_update_param; + struct tdls_osif_indication ind; + + macaddr = req->peer_addr; + tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(macaddr)); + + vdev = req->vdev; + if (!vdev) { + tdls_err("NULL vdev object"); + qdf_mem_free(req); + return QDF_STATUS_E_NULL_VALUE; + } + + /* reference cnt is acquired in ucfg_tdls_oper */ + vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); + soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + status = QDF_STATUS_E_INVAL; + goto error; + } + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || + !TDLS_IS_IMPLICIT_TRIG_ENABLED(feature)) { + tdls_err("TDLS ext ctrl or Imp Trig not enabled, %x", feature); + status = QDF_STATUS_E_NOSUPPORT; + goto error; + } + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer matching " QDF_MAC_ADDRESS_STR " not found", + QDF_MAC_ADDR_ARRAY(macaddr)); + status = QDF_STATUS_E_NULL_VALUE; + goto error; + } + + tdls_set_peer_link_status(peer, TDLS_LINK_TEARING, + TDLS_LINK_UNSPECIFIED); + + if (soc_obj->tdls_event_cb) { + qdf_mem_copy(ind.peer_mac, macaddr, QDF_MAC_ADDR_SIZE); + ind.vdev = vdev; + ind.reason = TDLS_TEARDOWN_PEER_UNSPEC_REASON; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_TEARDOWN_REQ, &ind); + } + + status = tdls_set_force_peer(vdev_obj, macaddr, false); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("set force peer failed"); + status = QDF_STATUS_E_INVAL; + goto error; + } + + if (soc_obj->tdls_external_peer_count) + soc_obj->tdls_external_peer_count--; + + tdls_set_callback(peer, NULL); + peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); + if (!peer_update_param) { + tdls_err("memory allocation failed"); + status = QDF_STATUS_E_NOMEM; + goto error; + } + + wlan_vdev_obj_lock(vdev); + peer_update_param->vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + qdf_mem_copy(peer_update_param->peer_macaddr, + macaddr, QDF_MAC_ADDR_SIZE); + peer_update_param->peer_state = TDLS_PEER_REMOVE_MAC_ADDR; + status = tdls_wma_update_peer_state(soc_obj, peer_update_param); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(peer_update_param); + goto error; + } + + /*TODO set tdls connection tracker state*/ +error: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + + return status; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 253403f55047..ff643199b19f 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -163,6 +163,32 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req); */ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req); +/** + * tdls_process_enable_link() - enable TDLS link + * @req: TDLS enable link request + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed + */ +QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req); + +/** + * tdls_process_setup_peer() - process configure an externally + * controllable TDLS peer + * @req: TDLS configure force peer request + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req); + +/** + * tdls_process_remove_force_peer() - process remove an externally controllable + * TDLS peer + * @req: TDLS operation request + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req); + /** * tdls_process_update_peer() - update TDLS peer * @req: TDLS update peer request diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index ab4a5e5c9aa7..4023edd5e444 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -202,10 +202,11 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!msg || !msg->bodyptr) { - tdls_err("msg: 0x%p, bodyptr: 0x%p", msg, msg->bodyptr); + tdls_err("msg: 0x%p", msg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } + tdls_debug("TDLS process command: %d", msg->type); switch (msg->type) { case TDLS_CMD_TX_ACTION: @@ -217,13 +218,16 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) tdls_process_update_peer(msg->bodyptr); break; case TDLS_CMD_ENABLE_LINK: + tdls_process_enable_link(msg->bodyptr); break; case TDLS_CMD_DISABLE_LINK: tdls_process_del_peer(msg->bodyptr); break; case TDLS_CMD_CONFIG_FORCE_PEER: + tdls_process_setup_peer(msg->bodyptr); break; case TDLS_CMD_REMOVE_FORCE_PEER: + tdls_process_remove_force_peer(msg->bodyptr); break; case TDLS_CMD_STATS_UPDATE: break; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 4d4d5f2bbd04..043250203436 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -97,30 +97,6 @@ enum tdls_nss_transition_state { TDLS_NSS_TRANSITION_S_1x1_to_2x2, }; -/** - * enum tdls_command_type - TDLS command type - * @TDLS_CMD_TX_ACTION: send tdls action frame - * @TDLS_CMD_ADD_STA: add tdls peer - * @TDLS_CMD_CHANGE_STA: change tdls peer - * @TDLS_CMD_ENABLE_LINK: enable tdls link - * @TDLS_CMD_DISABLE_LINK: disable tdls link - * @TDLS_CMD_CONFIG_FORCE_PEER: config external peer - * @TDLS_CMD_REMOVE_FORCE_PEER: remove external peer - * @TDLS_CMD_STATS_UPDATE: update tdls stats - * @TDLS_CMD_CONFIG_UPDATE: config tdls - */ -enum tdls_commmand_type { - TDLS_CMD_TX_ACTION = 1, - TDLS_CMD_ADD_STA, - TDLS_CMD_CHANGE_STA, - TDLS_CMD_ENABLE_LINK, - TDLS_CMD_DISABLE_LINK, - TDLS_CMD_CONFIG_FORCE_PEER, - TDLS_CMD_REMOVE_FORCE_PEER, - TDLS_CMD_STATS_UPDATE, - TDLS_CMD_CONFIG_UPDATE -}; - /** * struct tdls_conn_tracker_mac_table - connection tracker peer table * @mac_address: peer mac address diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 4fc129ebead3..bb5274fb5206 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -37,6 +37,7 @@ #define WLAN_TDLS_PEER_SUB_LIST_SIZE 10 #define WLAN_MAC_MAX_EXTN_CAP 8 #define WLAN_MAC_MAX_SUPP_CHANNELS 100 +#define WLAN_MAC_WMI_MAX_SUPP_CHANNELS 128 #define WLAN_MAX_SUPP_OPER_CLASSES 32 #define WLAN_MAC_MAX_SUPP_RATES 32 #define WLAN_CHANNEL_14 14 @@ -46,6 +47,8 @@ #define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165 #define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF 36 +#define AC_PRIORITY_NUM 4 + /** Maximum time(ms) to wait for tdls add sta to complete **/ #define WAIT_TIME_TDLS_ADD_STA 1500 @@ -154,6 +157,30 @@ enum tdls_feature_mode { TDLS_SUPPORT_EXT_CONTROL, }; +/** + * enum tdls_command_type - TDLS command type + * @TDLS_CMD_TX_ACTION: send tdls action frame + * @TDLS_CMD_ADD_STA: add tdls peer + * @TDLS_CMD_CHANGE_STA: change tdls peer + * @TDLS_CMD_ENABLE_LINK: enable tdls link + * @TDLS_CMD_DISABLE_LINK: disable tdls link + * @TDLS_CMD_CONFIG_FORCE_PEER: config external peer + * @TDLS_CMD_REMOVE_FORCE_PEER: remove external peer + * @TDLS_CMD_STATS_UPDATE: update tdls stats + * @TDLS_CMD_CONFIG_UPDATE: config tdls + */ +enum tdls_command_type { + TDLS_CMD_TX_ACTION = 1, + TDLS_CMD_ADD_STA, + TDLS_CMD_CHANGE_STA, + TDLS_CMD_ENABLE_LINK, + TDLS_CMD_DISABLE_LINK, + TDLS_CMD_CONFIG_FORCE_PEER, + TDLS_CMD_REMOVE_FORCE_PEER, + TDLS_CMD_STATS_UPDATE, + TDLS_CMD_CONFIG_UPDATE +}; + /** * enum tdls_event_type - TDLS event type * @TDLS_EVENT_VDEV_STATE_CHANGE: umac connect/disconnect event @@ -676,7 +703,7 @@ struct tdls_peer_params { uint8_t peer_curr_operclass; uint8_t self_curr_operclass; uint8_t peer_chanlen; - struct tdls_ch_params peer_chan[WLAN_MAC_MAX_SUPP_CHANNELS]; + struct tdls_ch_params peer_chan[WLAN_MAC_WMI_MAX_SUPP_CHANNELS]; uint8_t peer_oper_classlen; uint8_t peer_oper_class[WLAN_MAX_SUPP_OPER_CLASSES]; uint8_t pref_off_channum; diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 052f55b09426..a3aa7b34a4af 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -99,4 +99,15 @@ QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, */ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, struct tdls_update_peer_params *update_peer); + +/** + * ucfg_tdls_oper() - handle TDLS oper functions + * @vdev: vdev object + * @macaddr: MAC address of TDLS peer + * @cmd: oper cmd + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, + const uint8_t *macaddr, enum tdls_command_type cmd); #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 045d99d1e91d..c867af0274e9 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -332,3 +332,67 @@ dec_ref: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); return status; } + +static char *tdls_get_oper_str(enum tdls_command_type cmd_type) +{ + switch (cmd_type) { + case TDLS_CMD_ENABLE_LINK: + return "Enable_TDLS_LINK"; + case TDLS_CMD_DISABLE_LINK: + return "DISABLE_TDLS_LINK"; + case TDLS_CMD_REMOVE_FORCE_PEER: + return "REMOVE_FORCE_PEER"; + case TDLS_CMD_CONFIG_FORCE_PEER: + return "CONFIG_FORCE_PEER"; + default: + return "ERR:UNKNOWN OPER"; + } +} + +QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, + const uint8_t *macaddr, enum tdls_command_type cmd) +{ + struct scheduler_msg msg = {0,}; + struct tdls_oper_request *req; + QDF_STATUS status; + + if (!vdev || !macaddr) { + tdls_err("vdev: %p, mac %p", vdev, macaddr); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_debug("%s for peer " QDF_MAC_ADDRESS_STR, + tdls_get_oper_str(cmd), + QDF_MAC_ADDR_ARRAY(macaddr)); + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("%s: mem allocate fail", tdls_get_oper_str(cmd)); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto error; + } + + qdf_mem_copy(req->peer_addr, macaddr, QDF_MAC_ADDR_SIZE); + req->vdev = vdev; + + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = cmd; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post msg for %s fail", tdls_get_oper_str(cmd)); + goto dec_ref; + } + + return status; +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +error: + qdf_mem_free(req); + return status; +} From 57d308c33cb2a15017870b8c96fa1d5cf2bf1aab Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Thu, 16 Mar 2017 19:28:51 +0800 Subject: [PATCH 051/404] qcacmn: TDLS component: handle TDLS firmware event Handle TDLS related firmware event: tear down, discovery, disconnect, and send correspond indication to upper layer Change-Id: I6cff95904d06408f9458132ab5ce69f1a129e993 CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 238 ++++++++++++++++++++++++++++++ core/src/wlan_tdls_cmds_process.h | 30 ++++ core/src/wlan_tdls_main.c | 41 +++++ core/src/wlan_tdls_main.h | 5 + 4 files changed, 314 insertions(+) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 1c5d68454bbd..57e718d82d79 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1611,3 +1611,241 @@ error: return status; } + +static const char *tdls_evt_to_str(enum tdls_event_msg_type type) +{ + switch (type) { + case TDLS_SHOULD_DISCOVER: + return "SHOULD_DISCOVER"; + case TDLS_SHOULD_TEARDOWN: + return "SHOULD_TEARDOWN"; + case TDLS_PEER_DISCONNECTED: + return "SHOULD_PEER_DISCONNECTED"; + case TDLS_CONNECTION_TRACKER_NOTIFY: + return "CONNECTION_TRACKER_NOTIFICATION"; + default: + return "INVALID_TYPE"; + } +} + +static void +tdls_implicit_send_discovery_request(struct tdls_vdev_priv_obj *vdev_obj) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_peer *curr_peer, *temp_peer; + struct tdls_osif_indication ind; + + if (!vdev_obj) { + tdls_err("vdev_obj is NULL"); + return; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("soc_obj is NULL"); + return; + } + + curr_peer = vdev_obj->curr_candidate; + if (!curr_peer) { + tdls_err("curr_peer is NULL"); + return; + } + + temp_peer = tdls_is_progress(vdev_obj, NULL, 0); + if (temp_peer) { + tdls_notice(QDF_MAC_ADDRESS_STR " ongoing. pre_setup ignored", + QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); + goto done; + } + + if (TDLS_CAP_UNKNOWN != curr_peer->tdls_support) + tdls_set_peer_link_status(curr_peer, TDLS_LINK_DISCOVERING, + TDLS_LINK_SUCCESS); + + tdls_debug("Implicit TDLS, Send Discovery request event"); + + qdf_mem_copy(ind.peer_mac, curr_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + ind.vdev = vdev_obj->vdev; + + if (soc_obj->tdls_event_cb) + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_DISCOVERY_REQ, &ind); + + vdev_obj->discovery_sent_cnt++; + /*TODO restart peer discovery timeout*/ + + tdls_debug("discovery count %u, timeout %u msec", + vdev_obj->discovery_sent_cnt, + vdev_obj->threshold_config.tx_period_t - + TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); +done: + vdev_obj->curr_candidate = NULL; + vdev_obj->magic = 0; +} + +QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_peer *curr_peer; + uint32_t feature; + uint16_t type; + + /*TODO ignore this if any concurrency detected*/ + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + type = evt->message_type; + + tdls_debug("TDLS %s: " QDF_MAC_ADDRESS_STR "reason %d", + tdls_evt_to_str(type), + QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), + evt->peer_reason); + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + soc_obj, vdev_obj, tdls_evt_to_str(type)); + return QDF_STATUS_E_NULL_VALUE; + } + if (soc_obj->tdls_nss_switch_in_progress) { + tdls_err("TDLS antenna switching, ignore %s", + tdls_evt_to_str(type)); + return QDF_STATUS_SUCCESS; + } + + curr_peer = tdls_get_peer(vdev_obj, evt->peermac.bytes); + if (!curr_peer) { + tdls_notice("curr_peer is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (TDLS_LINK_CONNECTED == curr_peer->link_status) { + tdls_err("TDLS link status is connected, ignore"); + return QDF_STATUS_SUCCESS; + } + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) && + !curr_peer->is_forced_peer) { + tdls_debug("curr_peer is not forced, ignore %s", + tdls_evt_to_str(type)); + return QDF_STATUS_SUCCESS; + } + + tdls_debug("initiate TDLS setup on %s, ext: %d, force: %d, reason: %d", + tdls_evt_to_str(type), + TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature), + curr_peer->is_forced_peer, evt->peer_reason); + vdev_obj->curr_candidate = curr_peer; + tdls_implicit_send_discovery_request(vdev_obj); + + return QDF_STATUS_SUCCESS; +} + +static void +tdls_indicate_teardown(struct tdls_vdev_priv_obj *vdev_obj, + struct tdls_peer *curr_peer, uint16_t reason) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_osif_indication ind; + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj || !vdev_obj || !curr_peer) { + tdls_err("soc_obj: %p, vdev_obj: %p, curr_peer: %p", + soc_obj, vdev_obj, curr_peer); + return; + } + + if (TDLS_LINK_CONNECTED != curr_peer->link_status) { + tdls_debug("peer not connected"); + return; + } + + tdls_set_peer_link_status(curr_peer, TDLS_LINK_TEARING, + TDLS_LINK_UNSPECIFIED); + + tdls_debug("Teardown peer " QDF_MAC_ADDRESS_STR "reason %d", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), reason); + + qdf_mem_copy(ind.peer_mac, curr_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + ind.reason = reason; + ind.vdev = vdev_obj->vdev; + + if (soc_obj->tdls_event_cb) + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_TEARDOWN_REQ, &ind); +} + +QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_peer *curr_peer; + uint32_t reason; + uint16_t type; + + type = evt->message_type; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + + tdls_debug("TDLS %s: " QDF_MAC_ADDRESS_STR "reason %d", + tdls_evt_to_str(type), + QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); + + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + soc_obj, vdev_obj, tdls_evt_to_str(type)); + return QDF_STATUS_E_NULL_VALUE; + } + + curr_peer = tdls_find_peer(vdev_obj, evt->peermac.bytes); + if (!curr_peer) { + tdls_notice("curr_peer is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + reason = evt->peer_reason; + if (TDLS_LINK_CONNECTED == curr_peer->link_status) { + tdls_err("%s reason: %d for" QDF_MAC_ADDRESS_STR, + tdls_evt_to_str(type), evt->peer_reason, + QDF_MAC_ADDR_ARRAY(evt->peermac.bytes)); + if (reason == TDLS_TEARDOWN_RSSI || + reason == TDLS_DISCONNECTED_PEER_DELETE || + reason == TDLS_TEARDOWN_PTR_TIMEOUT || + reason == TDLS_TEARDOWN_NO_RSP) + reason = TDLS_TEARDOWN_PEER_UNREACHABLE; + else + reason = TDLS_TEARDOWN_PEER_UNSPEC_REASON; + + tdls_indicate_teardown(vdev_obj, curr_peer, reason); + } else { + tdls_err("TDLS link is not connected, ignore %s", + tdls_evt_to_str(type)); + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + uint16_t type; + + type = evt->message_type; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + soc_obj, vdev_obj, tdls_evt_to_str(type)); + return QDF_STATUS_E_NULL_VALUE; + } + + /*TODO connection tracker update*/ + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index ff643199b19f..17201b792749 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -220,4 +220,34 @@ QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp); * Return: QDF status */ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp); + +/** + * tdls_process_should_discover() - handle tdls should_discover event + * @vdev: vdev object + * @evt: event info + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt); + +/** + * tdls_process_should_teardown() - handle tdls should_teardown event + * @vdev: vdev object + * @evt: event info + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt); + +/** + * tdls_process_connection_tracker_notify() -handle tdls connect tracker notify + * @vdev: vdev object + * @evt: event info + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt); #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 4023edd5e444..a3409b80cf08 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -239,3 +239,44 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) return status; } + +QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_event_notify *notify; + struct tdls_event_info *event; + + if (!msg || !msg->bodyptr) { + tdls_err("msg: %p", msg); + return QDF_STATUS_E_NULL_VALUE; + } + notify = msg->bodyptr; + vdev = notify->vdev; + if (!vdev) { + tdls_err("NULL vdev object"); + qdf_mem_free(notify); + return QDF_STATUS_E_NULL_VALUE; + } + event = ¬ify->event; + + tdls_debug("evt type: %d", event->message_type); + switch (event->message_type) { + case TDLS_SHOULD_DISCOVER: + tdls_process_should_discover(vdev, event); + break; + case TDLS_SHOULD_TEARDOWN: + case TDLS_PEER_DISCONNECTED: + tdls_process_should_teardown(vdev, event); + break; + case TDLS_CONNECTION_TRACKER_NOTIFY: + tdls_process_connection_tracker_notify(vdev, event); + break; + default: + break; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + qdf_mem_free(notify); + + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 043250203436..5087c905d97a 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -49,6 +49,11 @@ #define TDLS_SEC_OFFCHAN_OFFSET_40MINUS (-40) #define TDLS_SEC_OFFCHAN_OFFSET_80 80 #define TDLS_SEC_OFFCHAN_OFFSET_160 160 +/* + * Before UpdateTimer expires, we want to timeout discovery response + * should not be more than 2000. + */ +#define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000 #define tdls_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) From 736e13d6ba310621f0605c1cdf576c76e5bc90b0 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Mon, 20 Mar 2017 14:34:11 +0800 Subject: [PATCH 052/404] 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 502c3bcf6a173084983420f62ab63511ae82ffe7 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 29 Mar 2017 14:43:17 +0800 Subject: [PATCH 053/404] qcacmn: Enable TDLS component Enable TDLS module in dispatcher Change-Id: I4b1fe09278115a90eb6b19ed6ce8fef57143a910 CRs-Fixed: 2011330 --- dispatcher/inc/wlan_tdls_ucfg_api.h | 12 ++++++++++-- dispatcher/src/wlan_tdls_ucfg_api.c | 28 +++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index a3aa7b34a4af..70a6c450a23f 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -73,12 +73,20 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, struct tdls_start_params *req); /** - * ucfg_tdls_psoc_stop() - TDLS module stop + * ucfg_tdls_psoc_enable() - TDLS module enable API * @psoc: psoc object * * Return: QDF_STATUS */ -QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc); +QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_psoc_disable() - TDLS moudle disable API + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc); /** * ucfg_tdls_add_peer() - handle TDLS add peer diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index c867af0274e9..37a94d249592 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -23,6 +23,7 @@ */ #include +#include #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" #include @@ -213,11 +214,32 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc) +QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc) { + QDF_STATUS status; + + tdls_notice("psoc tdls enable: 0x%p", psoc); + if (!psoc) { + tdls_err("NULL psoc"); + return QDF_STATUS_E_FAILURE; + } + + status = tgt_tdls_register_ev_handler(psoc); + + return status; +} + +QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; struct tdls_soc_priv_obj *soc_obj = NULL; - tdls_notice("tdls psoc stop"); + tdls_notice("psoc tdls disable: 0x%p", psoc); + if (!psoc) { + tdls_err("NULL psoc"); + return QDF_STATUS_E_FAILURE; + } + status = tgt_tdls_unregister_ev_handler(psoc); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); if (!soc_obj) { @@ -231,7 +253,7 @@ QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc) soc_obj->tdls_tx_cnf_cb = NULL; soc_obj->tx_ack_cnf_cb_data = NULL; - return QDF_STATUS_SUCCESS; + return status; } QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc) From 712cbfe634c6296e25e4468188f890388aa7ac94 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 27 Mar 2017 17:20:33 -0700 Subject: [PATCH 054/404] qcacmn: Add tdls timers function in tdls component Add tdls timers implemenation for discovery, idle and connection tracker. Change-Id: I7ccd5ec6c1d396a0fd25e6f28a258986a646c800 CRs-Fixed: 2034220 --- core/src/wlan_tdls_main.c | 75 +++++++++++++++++++++++++++++++++++++++ core/src/wlan_tdls_main.h | 21 +++++++++++ 2 files changed, 96 insertions(+) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index a3409b80cf08..d48134e5c58b 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -280,3 +280,78 @@ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) return QDF_STATUS_SUCCESS; } + +void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, + qdf_mc_timer_t *timer, + uint32_t expiration_time) +{ + qdf_mc_timer_stop(timer); + qdf_mc_timer_start(timer, expiration_time); +} + +/** + * wlan_hdd_tdls_monitor_timers_stop() - stop all monitoring timers + * @hdd_tdls_ctx: TDLS context + * + * Return: none + */ +static void tdls_monitor_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) +{ + qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); +} + +/** + * tdls_peer_idle_timers_stop() - stop peer idle timers + * @tdls_vdev: TDLS vdev object + * + * Loop through the idle peer list and stop their timers + * + * Return: None + */ +static void tdls_peer_idle_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *curr_peer; + QDF_STATUS status; + + tdls_vdev->discovery_peer_cnt = 0; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_peer = qdf_container_of(p_node, struct tdls_peer, + node); + if (curr_peer->is_peer_idle_timer_initialised) + qdf_mc_timer_stop(&curr_peer->peer_idle_timer); + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + +} + +/** + * wlan_hdd_tdls_ct_timers_stop() - stop tdls connection tracker timers + * @tdls_vdev: TDLS vdev + * + * Return: None + */ +static void tdls_ct_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) +{ + qdf_mc_timer_stop(&tdls_vdev->peer_update_timer); + tdls_peer_idle_timers_stop(tdls_vdev); +} + +/** + * wlan_hdd_tdls_timers_stop() - stop all the tdls timers running + * @tdls_vdev: TDLS vdev + * + * Return: none + */ +void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) +{ + tdls_monitor_timers_stop(tdls_vdev); + tdls_ct_timers_stop(tdls_vdev); +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 5087c905d97a..391ccbf92aab 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -454,4 +454,25 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg); * Return: QDF_STATUS */ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg); + +/** + * tdls_timer_restart() - restart TDLS timer + * @vdev: VDEV object manager + * @timer: timer to restart + * @expiration_time: new expiration time to set for the timer + * + * Return: Void + */ +void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, + qdf_mc_timer_t *timer, + uint32_t expiration_time); + +/** + * wlan_hdd_tdls_timers_stop() - stop all the tdls timers running + * @tdls_vdev: TDLS vdev + * + * Return: none + */ +void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev); + #endif From 00619ab3b873bed1fc9034a709d77485576975f6 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 20 Mar 2017 01:59:24 -0700 Subject: [PATCH 055/404] qcacmn: Add connection tracker to TDLS UMAC Add connection tracker support in TDLS UMAC component Change-Id: I725b579ab9f393d5247651bfe53df6b4a3f53649 CRs-Fixed: 2034220 --- core/src/wlan_tdls_cmds_process.c | 93 +-- core/src/wlan_tdls_ct.c | 894 ++++++++++++++++++++++++++++ core/src/wlan_tdls_ct.h | 137 ++++- core/src/wlan_tdls_main.c | 36 +- core/src/wlan_tdls_main.h | 26 + dispatcher/src/wlan_tdls_ucfg_api.c | 18 + 6 files changed, 1108 insertions(+), 96 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 57e718d82d79..dacabe74a476 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -25,6 +25,7 @@ #include #include "wlan_tdls_main.h" #include "wlan_tdls_peer.h" +#include "wlan_tdls_ct.h" #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_tgt_api.h" @@ -1628,63 +1629,6 @@ static const char *tdls_evt_to_str(enum tdls_event_msg_type type) } } -static void -tdls_implicit_send_discovery_request(struct tdls_vdev_priv_obj *vdev_obj) -{ - struct tdls_soc_priv_obj *soc_obj; - struct tdls_peer *curr_peer, *temp_peer; - struct tdls_osif_indication ind; - - if (!vdev_obj) { - tdls_err("vdev_obj is NULL"); - return; - } - - soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); - if (!soc_obj) { - tdls_err("soc_obj is NULL"); - return; - } - - curr_peer = vdev_obj->curr_candidate; - if (!curr_peer) { - tdls_err("curr_peer is NULL"); - return; - } - - temp_peer = tdls_is_progress(vdev_obj, NULL, 0); - if (temp_peer) { - tdls_notice(QDF_MAC_ADDRESS_STR " ongoing. pre_setup ignored", - QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); - goto done; - } - - if (TDLS_CAP_UNKNOWN != curr_peer->tdls_support) - tdls_set_peer_link_status(curr_peer, TDLS_LINK_DISCOVERING, - TDLS_LINK_SUCCESS); - - tdls_debug("Implicit TDLS, Send Discovery request event"); - - qdf_mem_copy(ind.peer_mac, curr_peer->peer_mac.bytes, - QDF_MAC_ADDR_SIZE); - ind.vdev = vdev_obj->vdev; - - if (soc_obj->tdls_event_cb) - soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, - TDLS_EVENT_DISCOVERY_REQ, &ind); - - vdev_obj->discovery_sent_cnt++; - /*TODO restart peer discovery timeout*/ - - tdls_debug("discovery count %u, timeout %u msec", - vdev_obj->discovery_sent_cnt, - vdev_obj->threshold_config.tx_period_t - - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); -done: - vdev_obj->curr_candidate = NULL; - vdev_obj->magic = 0; -} - QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, struct tdls_event_info *evt) { @@ -1743,41 +1687,6 @@ QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } -static void -tdls_indicate_teardown(struct tdls_vdev_priv_obj *vdev_obj, - struct tdls_peer *curr_peer, uint16_t reason) -{ - struct tdls_soc_priv_obj *soc_obj; - struct tdls_osif_indication ind; - - soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); - if (!soc_obj || !vdev_obj || !curr_peer) { - tdls_err("soc_obj: %p, vdev_obj: %p, curr_peer: %p", - soc_obj, vdev_obj, curr_peer); - return; - } - - if (TDLS_LINK_CONNECTED != curr_peer->link_status) { - tdls_debug("peer not connected"); - return; - } - - tdls_set_peer_link_status(curr_peer, TDLS_LINK_TEARING, - TDLS_LINK_UNSPECIFIED); - - tdls_debug("Teardown peer " QDF_MAC_ADDRESS_STR "reason %d", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), reason); - - qdf_mem_copy(ind.peer_mac, curr_peer->peer_mac.bytes, - QDF_MAC_ADDR_SIZE); - ind.reason = reason; - ind.vdev = vdev_obj->vdev; - - if (soc_obj->tdls_event_cb) - soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, - TDLS_EVENT_TEARDOWN_REQ, &ind); -} - QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, struct tdls_event_info *evt) { diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 851d0a199968..52ccfcfd2046 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -21,3 +21,897 @@ * * TDLS connection tracker function definitions */ + +#include "wlan_tdls_main.h" +#include "wlan_tdls_peer.h" +#include "wlan_tdls_ct.h" + +bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_peer *peer; + enum wlan_peer_state peer_state; + + wlan_vdev_obj_lock(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + wlan_vdev_obj_unlock(vdev); + + if (!peer) { + tdls_err("peer is null"); + return false; + } + + wlan_peer_obj_lock(peer); + peer_state = wlan_peer_mlme_get_state(peer); + wlan_peer_obj_unlock(peer); + + if (peer_state != WLAN_ASSOC_STATE) { + tdls_err("peer state: %d", peer_state); + return false; + } + + return true; +} + +/** + * tdls_peer_reset_discovery_processed() - reset discovery status + * @tdls_vdev: TDLS vdev object + * + * This function resets discovery processing bit for all TDLS peers + * + * Caller has to take the lock before calling this function + * + * Return: 0 + */ +static int32_t tdls_peer_reset_discovery_processed( + struct tdls_vdev_priv_obj *tdls_vdev) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *peer; + QDF_STATUS status; + + tdls_vdev->discovery_peer_cnt = 0; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + peer->discovery_processed = 0; + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + + return 0; +} + +void tdls_discovery_timeout_peer_cb(void *user_data) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *peer; + QDF_STATUS status; + struct tdls_vdev_priv_obj *tdls_vdev; + + if (!user_data) { + tdls_err("discovery time out data is null"); + return; + } + + tdls_vdev = (struct tdls_vdev_priv_obj *) user_data; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, + node); + if (TDLS_LINK_DISCOVERING != peer->link_status) { + status = qdf_list_peek_next(head, p_node, + &p_node); + continue; + } + tdls_debug(QDF_MAC_ADDRESS_STR " to idle state", + QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); + tdls_set_peer_link_status(peer, + TDLS_LINK_IDLE, + TDLS_LINK_NOT_SUPPORTED); + } + } + tdls_vdev->discovery_sent_cnt = 0; + + /* add tdls power save prohibited */ + + return; +} + +/** + * tdls_reset_tx_rx() - reset tx/rx counters for all tdls peers + * @tdls_vdev: TDLS vdev object + * + * Caller has to take the TDLS lock before calling this function + * + * Return: Void + */ +static void tdls_reset_tx_rx(struct tdls_vdev_priv_obj *tdls_vdev) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *peer; + QDF_STATUS status; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + peer->tx_pkt = 0; + peer->rx_pkt = 0; + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + return; +} + +void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev) +{ + tdls_debug("Disable Implicit TDLS"); + tdls_timers_stop(tdls_vdev); +} + +/** + * tdls_implicit_enable() - enable implicit tdls triggering + * @tdls_vdev: TDLS vdev + * + * Return: Void + */ +void tdls_implicit_enable(struct tdls_vdev_priv_obj *tdls_vdev) +{ + tdls_debug("Enable Implicit TDLS"); + if (!tdls_vdev) + return; + + tdls_peer_reset_discovery_processed(tdls_vdev); + tdls_reset_tx_rx(tdls_vdev); + /* TODO check whether tdls power save prohibited */ + + /* Restart the connection tracker timer */ + tdls_timer_restart(tdls_vdev->vdev, &tdls_vdev->peer_update_timer, + tdls_vdev->threshold_config.tx_period_t); +} + +/** + * tdls_ct_sampling_tx_rx() - collect tx/rx traffic sample + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * Function to update data traffic information in tdls connection + * tracker data structure for connection tracker operation + * + * Return: None + */ +static void tdls_ct_sampling_tx_rx(struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdls_soc) +{ + struct tdls_peer *curr_peer; + uint8_t mac[QDF_MAC_ADDR_SIZE]; + uint8_t mac_cnt; + uint8_t mac_entries; + struct tdls_conn_tracker_mac_table mac_table[WLAN_TDLS_CT_TABLE_SIZE]; + + qdf_spin_lock_bh(&tdls_soc->tdls_ct_spinlock); + + if (0 == tdls_vdev->valid_mac_entries) { + qdf_spin_unlock_bh(&tdls_soc->tdls_ct_spinlock); + return; + } + + mac_entries = tdls_vdev->valid_mac_entries; + + qdf_mem_copy(mac_table, tdls_vdev->ct_peer_table, + (sizeof(struct tdls_conn_tracker_mac_table)) * mac_entries); + + qdf_mem_set(tdls_vdev->ct_peer_table, 0, + (sizeof(struct tdls_conn_tracker_mac_table)) * mac_entries); + + tdls_vdev->valid_mac_entries = 0; + + qdf_spin_unlock_bh(&tdls_soc->tdls_ct_spinlock); + + for (mac_cnt = 0; mac_cnt < mac_entries; mac_cnt++) { + qdf_mem_copy(mac, mac_table[mac_cnt].mac_address.bytes, + QDF_MAC_ADDR_SIZE); + curr_peer = tdls_get_peer(tdls_vdev, mac); + if (NULL != curr_peer) { + curr_peer->tx_pkt = + mac_table[mac_cnt].tx_packet_cnt; + curr_peer->rx_pkt = + mac_table[mac_cnt].rx_packet_cnt; + } + } +} + +void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint8_t mac_cnt; + uint8_t valid_mac_entries; + struct tdls_conn_tracker_mac_table *mac_table; + + tdls_debug("enter "); + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) + return; + + if (!tdls_soc_obj->enable_tdls_connection_tracker) + return; + + if (qdf_is_macaddr_group(mac_addr)) + return; + + if (qdf_mem_cmp(vdev->vdev_mlme.macaddr, mac_addr, + QDF_MAC_ADDR_SIZE) == 0) + return; + + qdf_spin_lock_bh(&tdls_soc_obj->tdls_ct_spinlock); + valid_mac_entries = tdls_vdev_obj->valid_mac_entries; + mac_table = tdls_vdev_obj->ct_peer_table; + + for (mac_cnt = 0; mac_cnt < valid_mac_entries; mac_cnt++) { + if (qdf_mem_cmp(mac_table[mac_cnt].mac_address.bytes, + mac_addr, QDF_MAC_ADDR_SIZE) == 0) { + mac_table[mac_cnt].rx_packet_cnt++; + goto rx_cnt_return; + } + } + + /* If we have more than 8 peers within 30 mins. we will + * stop tracking till the old entries are removed + */ + if (mac_cnt < WLAN_TDLS_CT_TABLE_SIZE) { + qdf_mem_copy(mac_table[mac_cnt].mac_address.bytes, + mac_addr, QDF_MAC_ADDR_SIZE); + tdls_vdev_obj->valid_mac_entries = mac_cnt+1; + mac_table[mac_cnt].rx_packet_cnt = 1; + } + +rx_cnt_return: + qdf_spin_unlock_bh(&tdls_soc_obj->tdls_ct_spinlock); + tdls_debug("exit: rx pkt count %d ", mac_table[mac_cnt].rx_packet_cnt); + return; +} + +void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint8_t mac_cnt; + uint8_t valid_mac_entries; + struct tdls_conn_tracker_mac_table *mac_table; + + tdls_debug("enter "); + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) + return; + + if (!tdls_soc_obj->enable_tdls_connection_tracker) + return; + + if (qdf_is_macaddr_group(mac_addr)) + return; + + if (qdf_mem_cmp(vdev->vdev_mlme.macaddr, mac_addr, + QDF_MAC_ADDR_SIZE) == 0) + return; + + qdf_spin_lock_bh(&tdls_soc_obj->tdls_ct_spinlock); + mac_table = tdls_vdev_obj->ct_peer_table; + + valid_mac_entries = tdls_vdev_obj->valid_mac_entries; + + for (mac_cnt = 0; mac_cnt < valid_mac_entries; mac_cnt++) { + if (qdf_mem_cmp(mac_table[mac_cnt].mac_address.bytes, + mac_addr, QDF_MAC_ADDR_SIZE) == 0) { + mac_table[mac_cnt].tx_packet_cnt++; + goto tx_cnt_return; + } + } + + /* If we have more than 8 peers within 30 mins. we will + * stop tracking till the old entries are removed + */ + if (mac_cnt < WLAN_TDLS_CT_TABLE_SIZE) { + qdf_mem_copy(mac_table[mac_cnt].mac_address.bytes, + mac_addr, QDF_MAC_ADDR_SIZE); + mac_table[mac_cnt].tx_packet_cnt = 1; + tdls_vdev_obj->valid_mac_entries++; + } + +tx_cnt_return: + qdf_spin_unlock_bh(&tdls_soc_obj->tdls_ct_spinlock); + tdls_debug("exit: tx pkt count %d", mac_table[mac_cnt].tx_packet_cnt); + return; +} + +void tdls_implicit_send_discovery_request( + struct tdls_vdev_priv_obj *tdls_vdev_obj) +{ + struct tdls_peer *curr_peer; + struct tdls_peer *temp_peer; + struct tdls_soc_priv_obj *tdls_psoc; + struct tdls_osif_indication tdls_ind; + + if (NULL == tdls_vdev_obj) { + tdls_notice("tdls_vdev_obj is NULL"); + return; + } + + tdls_psoc = wlan_vdev_get_tdls_soc_obj(tdls_vdev_obj->vdev); + + if (NULL == tdls_psoc) { + tdls_notice("tdls_psoc_obj is NULL"); + return; + } + + curr_peer = tdls_vdev_obj->curr_candidate; + + if (NULL == curr_peer) { + tdls_err("curr_peer is NULL"); + return; + } + + /* This function is called in mutex_lock */ + temp_peer = tdls_is_progress(tdls_vdev_obj, NULL, 0); + if (NULL != temp_peer) { + tdls_notice(QDF_MAC_ADDRESS_STR " ongoing. pre_setup ignored", + QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); + goto done; + } + + if (TDLS_CAP_UNKNOWN != curr_peer->tdls_support) + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_DISCOVERING, + TDLS_LINK_SUCCESS); + + qdf_mem_copy(tdls_ind.peer_mac, curr_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + + tdls_ind.vdev = tdls_vdev_obj->vdev; + + tdls_debug("Implicit TDLS, Send Discovery request event"); + + tdls_psoc->tdls_event_cb(tdls_psoc->tdls_evt_cb_data, + TDLS_EVENT_DISCOVERY_REQ, &tdls_ind); + + tdls_vdev_obj->discovery_sent_cnt++; + + tdls_timer_restart(tdls_vdev_obj->vdev, + &tdls_vdev_obj->peer_discovery_timer, + tdls_vdev_obj->threshold_config.tx_period_t - + TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE); + + tdls_debug("discovery count %u timeout %u msec", + tdls_vdev_obj->discovery_sent_cnt, + tdls_vdev_obj->threshold_config.tx_period_t - + TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE); +done: + tdls_vdev_obj->curr_candidate = NULL; + tdls_vdev_obj->magic = 0; + return; +} + +int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, + const uint8_t *mac) +{ + struct tdls_peer *curr_peer; + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_osif_indication indication; + struct tdls_config_params *tdls_cfg; + int status = 0; + + if (!tdls_vdev) + return -EINVAL; + + tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); + if (NULL == tdls_soc) { + tdls_err("tdls soc is NULL"); + return -EINVAL; + } + + curr_peer = tdls_get_peer(tdls_vdev, mac); + if (NULL == curr_peer) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + if (tdls_vdev->discovery_sent_cnt) + tdls_vdev->discovery_sent_cnt--; + + if (0 == tdls_vdev->discovery_sent_cnt) + qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); + + tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDRESS_STR + " link_status %d", tdls_vdev->discovery_sent_cnt, + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->link_status); + + tdls_cfg = &tdls_vdev->threshold_config; + if (TDLS_LINK_DISCOVERING == curr_peer->link_status) { + /* Since we are here, it means Throughput threshold is + * already met. Make sure RSSI threshold is also met + * before setting up TDLS link. + */ + if ((int32_t) curr_peer->rssi > + (int32_t) tdls_cfg->rssi_trigger_threshold) { + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_DISCOVERED, + TDLS_LINK_SUCCESS); + tdls_debug("Rssi Threshold met: " QDF_MAC_ADDRESS_STR + " rssi = %d threshold= %d", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->rssi, + tdls_cfg->rssi_trigger_threshold); + + qdf_mem_copy(indication.peer_mac, mac, + QDF_MAC_ADDR_SIZE); + + indication.vdev = tdls_vdev->vdev; + + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_SETUP_REQ, + &indication); + } else { + tdls_debug("Rssi Threshold not met: " + QDF_MAC_ADDRESS_STR + " rssi = %d threshold = %d ", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->rssi, + tdls_cfg->rssi_trigger_threshold); + + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); + + /* if RSSI threshold is not met then allow + * further discovery attempts by decrementing + * count for the last attempt + */ + if (curr_peer->discovery_attempt) + curr_peer->discovery_attempt--; + } + } + + curr_peer->tdls_support = TDLS_CAP_SUPPORTED; + + return status; +} + +void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_peer *curr_peer, + uint16_t reason) +{ + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_osif_indication indication; + + tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); + if (!tdls_soc || !tdls_vdev || !curr_peer) { + tdls_err("tdls_soc: %p, tdls_vdev: %p, curr_peer: %p", + tdls_soc, tdls_vdev, curr_peer); + return; + } + + if (TDLS_LINK_CONNECTED != curr_peer->link_status) + return; + + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_TEARING, + TDLS_LINK_UNSPECIFIED); + tdls_notice("Teardown reason %d", reason); + + indication.reason = reason; + indication.vdev = tdls_vdev->vdev; + qdf_mem_copy(indication.peer_mac, curr_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + + if (tdls_soc->tdls_event_cb) + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_TEARDOWN_REQ, &indication); +} + +/** + * tdls_get_conn_info() - get the tdls connection information. + * @tdls_soc: tdls soc object + * @idx: sta id + * + * Function to check tdls sta index + * + * Return: tdls connection information + */ +static struct tdls_conn_info * +tdls_get_conn_info(struct tdls_soc_priv_obj *tdls_soc, uint8_t idx) +{ + uint8_t sta_idx; + + /* check if there is available index for this new TDLS STA */ + for (sta_idx = 0; sta_idx < WLAN_TDLS_STA_MAX_NUM; sta_idx++) { + if (idx == tdls_soc->tdls_conn_info[sta_idx].sta_id) { + tdls_debug("tdls peer with sta_idx %u exists", idx); + return &tdls_soc->tdls_conn_info[sta_idx]; + } + } + + tdls_err("tdls peer with staIdx %u not exists", idx); + return NULL; +} + +static void +tdls_ct_process_idle_handler( + struct tdls_ct_idle_peer_data *tdls_idle_peer_data) +{ + struct tdls_conn_info *tdls_info; + struct tdls_peer *curr_peer; + struct wlan_objmgr_vdev *vdev; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + vdev = tdls_idle_peer_data->vdev; + tdls_info = tdls_idle_peer_data->tdls_info; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) + return; + + if (!tdls_info->sta_id) { + tdls_err("peer (staidx %u) doesn't exists", tdls_info->sta_id); + return; + } + + curr_peer = tdls_find_peer(tdls_vdev_obj, + (u8 *) &tdls_info->peer_mac.bytes[0]); + + if (NULL == curr_peer) { + tdls_err("Invalid tdls idle timer expired"); + return; + } + + tdls_debug(QDF_MAC_ADDRESS_STR + " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->tx_pkt, + curr_peer->rx_pkt, + tdls_vdev_obj->threshold_config.idle_packet_n); + + /* Check tx/rx statistics on this tdls link for recent activities and + * then decide whether to tear down the link or keep it. + */ + if ((curr_peer->tx_pkt >= + tdls_vdev_obj->threshold_config.idle_packet_n) || + (curr_peer->rx_pkt >= + tdls_vdev_obj->threshold_config.idle_packet_n)) { + /* this tdls link got back to normal, so keep it */ + tdls_debug("tdls link to " QDF_MAC_ADDRESS_STR + " back to normal, will stay", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + } else { + /* this tdls link needs to get torn down */ + tdls_notice("trigger tdls link to "QDF_MAC_ADDRESS_STR" down", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + tdls_indicate_teardown(tdls_vdev_obj, + curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + } + + return; +} + +void tdls_ct_idle_handler(void *user_data) +{ + struct tdls_ct_idle_peer_data *tdls_idle_peer_data; + struct wlan_objmgr_vdev *vdev; + + tdls_idle_peer_data = (struct tdls_ct_idle_peer_data *) user_data; + + if (NULL == tdls_idle_peer_data || + NULL == tdls_idle_peer_data->vdev || + NULL == tdls_idle_peer_data->tdls_info) + return; + + vdev = tdls_idle_peer_data->vdev; + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, + WLAN_TDLS_NB_ID)) + return; + + tdls_ct_process_idle_handler(tdls_idle_peer_data); + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); +} + +/** + * tdls_ct_process_idle_and_discovery() - process the traffic data + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * Function to check the peer traffic data in idle link and tdls + * discovering link + * + * Return: None + */ +static void +tdls_ct_process_idle_and_discovery(struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj) +{ + uint16_t valid_peers; + + valid_peers = tdls_soc_obj->connected_peer_count; + + if ((curr_peer->tx_pkt + curr_peer->rx_pkt) >= + tdls_vdev_obj->threshold_config.tx_packet_n) { + if (WLAN_TDLS_STA_MAX_NUM > valid_peers) { + tdls_notice("Tput trigger TDLS pre-setup"); + tdls_vdev_obj->curr_candidate = curr_peer; + tdls_implicit_send_discovery_request(tdls_vdev_obj); + } else { + tdls_notice("Maximum peers connected already! %d", + valid_peers); + } + } +} + +/** + * tdls_ct_process_connected_link() - process the traffic + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev + * @tdls_soc_obj: tdls soc context + * + * Function to check the peer traffic data in active STA + * session + * + * Return: None + */ +static void tdls_ct_process_connected_link( + struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdls_soc) +{ + + if ((int32_t)curr_peer->rssi < + (int32_t)tdls_vdev->threshold_config.rssi_teardown_threshold) { + tdls_warn("Tear down - low RSSI: " QDF_MAC_ADDRESS_STR "!", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + tdls_indicate_teardown(tdls_vdev, + curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + return; + } + + /* Only teardown based on non zero idle packet threshold, to address + * a use case where this threshold does not get consider for TEAR DOWN + */ + if ((0 != tdls_vdev->threshold_config.idle_packet_n) && + ((curr_peer->tx_pkt < + tdls_vdev->threshold_config.idle_packet_n) && + (curr_peer->rx_pkt < + tdls_vdev->threshold_config.idle_packet_n))) { + if (!curr_peer->is_peer_idle_timer_initialised) { + uint8_t sta_id = (uint8_t)curr_peer->sta_id; + struct tdls_conn_info *tdls_info; + tdls_info = tdls_get_conn_info(tdls_soc, sta_id); + tdls_soc->tdls_idle_peer_data.tdls_info = tdls_info; + tdls_soc->tdls_idle_peer_data.vdev = tdls_vdev->vdev; + qdf_mc_timer_init(&curr_peer->peer_idle_timer, + QDF_TIMER_TYPE_SW, + tdls_ct_idle_handler, + &tdls_soc->tdls_idle_peer_data); + curr_peer->is_peer_idle_timer_initialised = true; + } + if (QDF_TIMER_STATE_RUNNING != + curr_peer->peer_idle_timer.state) { + tdls_warn("Tx/Rx Idle timer start: " + QDF_MAC_ADDRESS_STR "!", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + tdls_timer_restart(tdls_vdev->vdev, + &curr_peer->peer_idle_timer, + tdls_vdev->threshold_config.idle_timeout_t); + } + } else if (QDF_TIMER_STATE_RUNNING == + curr_peer->peer_idle_timer.state) { + tdls_warn("Tx/Rx Idle timer stop: " QDF_MAC_ADDRESS_STR "!", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + qdf_mc_timer_stop(&curr_peer->peer_idle_timer); + } +} + +/** + * tdls_ct_process_cap_supported() - process TDLS supported peer. + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev context + * @tdls_soc_obj: tdls soc context + * + * Function to check the peer traffic data for tdls supported peer + * + * Return: None + */ +static void tdls_ct_process_cap_supported(struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdls_soc_obj) +{ + tdls_debug("tx %d rx %d thr.pkt %d/idle %d rssi %d thr.trig %d/tear %d", + curr_peer->tx_pkt, curr_peer->rx_pkt, + tdls_vdev->threshold_config.tx_packet_n, + tdls_vdev->threshold_config.idle_packet_n, + curr_peer->rssi, + tdls_vdev->threshold_config.rssi_trigger_threshold, + tdls_vdev->threshold_config.rssi_teardown_threshold); + + switch (curr_peer->link_status) { + case TDLS_LINK_IDLE: + case TDLS_LINK_DISCOVERING: + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdls_soc_obj->tdls_configs.tdls_feature_flags) && + (!curr_peer->is_forced_peer)) + break; + tdls_ct_process_idle_and_discovery(curr_peer, tdls_vdev, + tdls_soc_obj); + break; + case TDLS_LINK_CONNECTED: + tdls_ct_process_connected_link(curr_peer, tdls_vdev, + tdls_soc_obj); + break; + default: + break; + } +} + +/** + * tdls_ct_process_cap_unknown() - process unknown peer + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * Function check the peer traffic data , when tdls capability is unknown + * + * Return: None + */ +static void tdls_ct_process_cap_unknown(struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdlsa_soc) +{ + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdlsa_soc->tdls_configs.tdls_feature_flags) && + (!curr_peer->is_forced_peer)) + return; + + tdls_debug("threshold tx pkt = %d peer tx_pkt = %d & rx_pkt = %d ", + tdls_vdev->threshold_config.tx_packet_n, curr_peer->tx_pkt, + curr_peer->rx_pkt); + + if (!TDLS_IS_LINK_CONNECTED(curr_peer) && + ((curr_peer->tx_pkt + curr_peer->rx_pkt) >= + tdls_vdev->threshold_config.tx_packet_n)) { + /* Ignore discovery attempt if External Control is enabled, that + * is, peer is forced. In that case, continue discovery attempt + * regardless attempt count + */ + tdls_debug("TDLS UNKNOWN pre discover "); + if (curr_peer->is_forced_peer || + curr_peer->discovery_attempt++ < + tdls_vdev->threshold_config.discovery_tries_n) { + tdls_debug("TDLS UNKNOWN discover "); + tdls_vdev->curr_candidate = curr_peer; + tdls_implicit_send_discovery_request(tdls_vdev); + } else { + curr_peer->tdls_support = TDLS_CAP_NOT_SUPPORTED; + tdls_set_peer_link_status( + curr_peer, + TDLS_LINK_IDLE, + TDLS_LINK_NOT_SUPPORTED); + } + } +} + +/** + * tdls_ct_process_peers() - process the peer + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * This function check the peer capability and process the metadata from + * the peer + * + * Return: None + */ +static void tdls_ct_process_peers(struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj) +{ + tdls_debug(QDF_MAC_ADDRESS_STR " link_status %d tdls_support %d", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->link_status, curr_peer->tdls_support); + + switch (curr_peer->tdls_support) { + case TDLS_CAP_SUPPORTED: + tdls_ct_process_cap_supported(curr_peer, tdls_vdev_obj, + tdls_soc_obj); + break; + + case TDLS_CAP_UNKNOWN: + tdls_ct_process_cap_unknown(curr_peer, tdls_vdev_obj, + tdls_soc_obj); + break; + default: + break; + } + +} + +static void tdls_ct_process_handler(struct wlan_objmgr_vdev *vdev) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *list_node; + struct tdls_peer *curr_peer; + QDF_STATUS status; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) + return; + + /* If any concurrency is detected */ + if (!tdls_soc_obj->enable_tdls_connection_tracker) { + tdls_notice("Connection tracker is disabled"); + return; + } + + /* Update tx rx traffic sample in tdls data structures */ + tdls_ct_sampling_tx_rx(tdls_vdev_obj, tdls_soc_obj); + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev_obj->peer_list[i]; + status = qdf_list_peek_front(head, &list_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_peer = qdf_container_of(list_node, + struct tdls_peer, node); + tdls_ct_process_peers(curr_peer, tdls_vdev_obj, + tdls_soc_obj); + curr_peer->tx_pkt = 0; + curr_peer->rx_pkt = 0; + status = qdf_list_peek_next(head, + list_node, &list_node); + } + } + + tdls_timer_restart(tdls_vdev_obj->vdev, + &tdls_vdev_obj->peer_update_timer, + tdls_vdev_obj->threshold_config.tx_period_t); + +} + +void tdls_ct_handler(void *user_data) +{ + struct wlan_objmgr_vdev *vdev; + + if (!user_data) + return; + + vdev = (struct wlan_objmgr_vdev *)user_data; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, + WLAN_TDLS_NB_ID)) + return; + + tdls_ct_process_handler(vdev); + + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); +} + diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index 473f2b556644..d894794eb568 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -19,5 +19,140 @@ /** * DOC: wlan_tdls_ct.h * - * TDLS connection tracker api declaration + * TDLS connection tracker declarations */ + +#ifndef _WLAN_TDLS_CT_H_ +#define _WLAN_TDLS_CT_H_ + + /* + * Before UpdateTimer expires, we want to timeout discovery response + * should not be more than 2000. + */ +#define TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE 1000 + +/** + * tdls_is_vdev_connected() - check the vdev is connected to ap + * @vdev: vdev object manager + * + * This function will check the vdev connection status and return + * true or false + * + * Return: true - Connected, false - Not connected + */ +bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_implicit_enable() - enable implicit tdls triggering + * @tdls_vdev: TDLS vdev + * + * Return: Void + */ +void tdls_implicit_enable(struct tdls_vdev_priv_obj *tdls_vdev); + +/** + * tdls_update_rx_pkt_cnt() - Update rx packet count + * @vdev: vdev object manager + * @mac_addr: mac address of the data + * + * Increase the rx packet count, if the sender is not bssid and the packet is + * not broadcast and muticast packet + * + * This sampling information will be used in TDLS connection tracker + * + * This function expected to be called in an atomic context so blocking APIs + * not allowed + * + * Return: None + */ +void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + +/** + * tdls_update_tx_pkt_cnt() - update tx packet + * @vdev: vdev object + * @mac_addr: mac address of the data + * + * Increase the tx packet count, if the sender is not bssid and the packet is + * not broadcast and muticast packet + * + * This sampling information will be used in TDLS connection tracker + * + * This function expected to be called in an atomic context so blocking APIs + * not allowed + * + * Return: None + */ +void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + +/** + * wlan_hdd_tdls_implicit_send_discovery_request() - send discovery request + * @tdls_vdev_obj: tdls vdev object + * + * Return: None + */ +void tdls_implicit_send_discovery_request( + struct tdls_vdev_priv_obj *tdls_vdev_obj); + +/** + * tdls_recv_discovery_resp() - handling of tdls discovery response + * @soc: object manager + * @mac: mac address of peer from which the response was received + * + * Return: 0 for success or negative errno otherwise + */ +int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, + const uint8_t *mac); + +/** + * tdls_indicate_teardown() - indicate teardown to upper layer + * @tdls_vdev: tdls vdev object + * @curr_peer: teardown peer + * @reason: teardown reason + * + * Return: Void + */ +void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_peer *curr_peer, + uint16_t reason); + +/** + * tdls_ct_handler() - TDLS connection tracker handler + * @user_data: user data from timer + * + * tdls connection tracker timer starts, when the STA connected to AP + * and it's scan the traffic between two STA peers and make TDLS + * connection and teardown, based on the traffic threshold + * + * Return: None + */ +void tdls_ct_handler(void *user_data); + +/** + * tdls_ct_idle_handler() - Check tdls idle traffic + * @user_data: data from tdls idle timer + * + * Function to check the tdls idle traffic and make a decision about + * tdls teardown + * + * Return: None + */ +void tdls_ct_idle_handler(void *user_data); + +/** + * tdls_discovery_timeout_peer_cb() - tdls discovery timeout callback + * @userData: tdls vdev + * + * Return: None + */ +void tdls_discovery_timeout_peer_cb(void *user_data); + +/** + * tdls_implicit_disable() - disable implicit tdls triggering + * @pHddTdlsCtx: TDLS context + * + * Return: Void + */ +void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev); +#endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index d48134e5c58b..e07ffcec7ba2 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -25,6 +25,7 @@ #include "wlan_tdls_main.h" #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_peer.h" +#include "wlan_tdls_ct.h" QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -111,9 +112,10 @@ static QDF_STATUS tdls_vdev_init(struct tdls_vdev_priv_obj *vdev_obj) WLAN_TDLS_PEER_SUB_LIST_SIZE); } qdf_mc_timer_init(&vdev_obj->peer_update_timer, QDF_TIMER_TYPE_SW, - NULL, vdev_obj); + tdls_ct_handler, vdev_obj->vdev); qdf_mc_timer_init(&vdev_obj->peer_discovery_timer, QDF_TIMER_TYPE_SW, - NULL, vdev_obj); + tdls_discovery_timeout_peer_cb, vdev_obj); + return QDF_STATUS_SUCCESS; } @@ -247,7 +249,7 @@ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) struct tdls_event_info *event; if (!msg || !msg->bodyptr) { - tdls_err("msg: %p", msg); + tdls_err("msg is not valid: %p", msg); return QDF_STATUS_E_NULL_VALUE; } notify = msg->bodyptr; @@ -355,3 +357,31 @@ void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) tdls_monitor_timers_stop(tdls_vdev); tdls_ct_timers_stop(tdls_vdev); } + +QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, + struct tdls_vdev_priv_obj **tdls_vdev_obj, + struct tdls_soc_priv_obj **tdls_soc_obj) +{ + enum tQDF_ADAPTER_MODE device_mode; + + if (NULL == vdev) + return QDF_STATUS_E_FAILURE; + + *tdls_vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (NULL == (*tdls_vdev_obj)) + return QDF_STATUS_E_FAILURE; + + *tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (NULL == (*tdls_soc_obj)) + return QDF_STATUS_E_FAILURE; + + wlan_vdev_obj_lock(vdev); + device_mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + + if (device_mode != QDF_STA_MODE && + device_mode != QDF_P2P_CLIENT_MODE) + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 391ccbf92aab..cf758e772e06 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -116,6 +116,16 @@ struct tdls_conn_tracker_mac_table { uint32_t peer_timestamp_ms; }; +/** + * struct tdls_ct_idle_peer_data - connection tracker idle peer info + * @vdev: vdev object + * @tdls_info: tdls connection info + */ +struct tdls_ct_idle_peer_data { + struct wlan_objmgr_vdev *vdev; + struct tdls_conn_info *tdls_info; +}; + /** * struct tdls_set_state_db - to record set tdls state command, we need to * set correct tdls state to firmware: @@ -164,6 +174,8 @@ struct tdls_set_state_info { * @tdls_add_sta_req: store eWNI_SME_TDLS_ADD_STA_REQ value * @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value * @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value + * @tdls_idle_peer_data: provide information about idle peer + * @tdls_ct_spinlock: connection tracker spin lock */ struct tdls_soc_priv_obj { struct wlan_objmgr_psoc *soc; @@ -196,6 +208,8 @@ struct tdls_soc_priv_obj { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + struct tdls_ct_idle_peer_data tdls_idle_peer_data; + qdf_spinlock_t tdls_ct_spinlock; }; /** @@ -475,4 +489,16 @@ void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, */ void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev); +/** + * tdls_get_vdev_objects() - Get TDLS private objects + * @vdev: VDEV object manager + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, + struct tdls_vdev_priv_obj **tdls_vdev_obj, + struct tdls_soc_priv_obj **tdls_soc_obj); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 37a94d249592..7a557a3df2ba 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -142,7 +142,16 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) } soc_obj->enable_tdls_connection_tracker = false; soc_obj->tdls_external_peer_count = 0; + soc_obj->tdls_disable_in_progress = false; + qdf_spinlock_create(&soc_obj->tdls_ct_spinlock); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tdls_global_deinit(struct tdls_soc_priv_obj *soc_obj) +{ + qdf_spinlock_destroy(&soc_obj->tdls_ct_spinlock); return QDF_STATUS_SUCCESS; } @@ -259,8 +268,17 @@ QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc) { QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_soc_priv_obj *tdls_soc; tdls_notice("tdls psoc close"); + tdls_soc = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (!tdls_soc) { + tdls_err("Failed to get tdls psoc component"); + return QDF_STATUS_E_FAILURE; + } + + status = tdls_global_deinit(tdls_soc); return status; } From 61442d253b3f15cbcc01ef1ecc7fd97f0d761ef7 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Sun, 26 Mar 2017 18:19:19 -0700 Subject: [PATCH 056/404] qcacmn: Add TDLS management frames Add TDLS management frames implementaion in TDLS umac component Change-Id: I46943f7df119894e0d54df2c6edb08ed4546a389 CRs-Fixed: 2034220 --- core/src/wlan_tdls_cmds_process.c | 1 + core/src/wlan_tdls_cmds_process.h | 9 + core/src/wlan_tdls_main.c | 2 + core/src/wlan_tdls_mgmt.c | 407 ++++++++++++++++++++++ core/src/wlan_tdls_mgmt.h | 51 +++ dispatcher/inc/wlan_tdls_public_structs.h | 40 +++ dispatcher/inc/wlan_tdls_ucfg_api.h | 12 + dispatcher/src/wlan_tdls_ucfg_api.c | 39 +++ 8 files changed, 561 insertions(+) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index dacabe74a476..49784df9bd19 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -26,6 +26,7 @@ #include "wlan_tdls_main.h" #include "wlan_tdls_peer.h" #include "wlan_tdls_ct.h" +#include "wlan_tdls_mgmt.h" #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_tgt_api.h" diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 17201b792749..32e8cba01ac0 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -250,4 +250,13 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, */ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, struct tdls_event_info *evt); + +/** + * tdls_validate_mgmt_request() -validate mgmt request + * @tdls_validate: action frame request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index e07ffcec7ba2..b4b28c0b83b1 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -26,6 +26,7 @@ #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_peer.h" #include "wlan_tdls_ct.h" +#include "wlan_tdls_mgmt.h" QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -212,6 +213,7 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) switch (msg->type) { case TDLS_CMD_TX_ACTION: + tdls_process_mgmt_req(msg->bodyptr); break; case TDLS_CMD_ADD_STA: tdls_process_add_peer(msg->bodyptr); diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index a8e5f8798076..3f28bf08174f 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -21,3 +21,410 @@ * * TDLS management frames implementation */ + +#include "wlan_tdls_main.h" +#include "wlan_tdls_tgt_api.h" +#include +#include "wlan_mgmt_txrx_utils_api.h" +#include "wlan_tdls_peer.h" +#include "wlan_tdls_ct.h" +#include "wlan_tdls_cmds_process.h" +#include "wlan_tdls_mgmt.h" + +static +const char *const tdls_action_frames_type[] = { "TDLS Setup Request", + "TDLS Setup Response", + "TDLS Setup Confirm", + "TDLS Teardown", + "TDLS Peer Traffic Indication", + "TDLS Channel Switch Request", + "TDLS Channel Switch Response", + "TDLS Peer PSM Request", + "TDLS Peer PSM Response", + "TDLS Peer Traffic Response", + "TDLS Discovery Request"}; + +/** + * tdls_set_rssi() - Set TDLS RSSI on peer given by mac + * @tdls_vdev: tdls vdev object + * @mac: MAC address of Peer + * @rx_rssi: rssi value + * + * Set RSSI on TDSL peer + * + * Return: 0 for success or -EINVAL otherwise + */ +static int tdls_set_rssi(struct tdls_vdev_priv_obj *tdls_vdev, + const uint8_t *mac, + int8_t rx_rssi) +{ + struct tdls_peer *curr_peer; + + curr_peer = tdls_find_peer(tdls_vdev, mac); + if (curr_peer == NULL) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + curr_peer->rssi = rx_rssi; + + return 0; +} + +/** + * tdls_process_rx_mgmt() - process tdls rx mgmt frames + * @rx_mgmt_event: tdls rx mgmt event + * @tdls_vdev: tdls vdev object + * + * Return: QDF_STATUS + */ +static QDF_STATUS tdls_process_rx_mgmt( + struct tdls_rx_mgmt_event *rx_mgmt_event, + struct tdls_vdev_priv_obj *tdls_vdev) +{ + struct tdls_rx_mgmt_frame *rx_mgmt; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint8_t *mac; + enum tdls_actioncode action_frame_type; + + if (!rx_mgmt_event) + return QDF_STATUS_E_INVAL; + + tdls_soc_obj = rx_mgmt_event->tdls_soc_obj; + rx_mgmt = rx_mgmt_event->rx_mgmt; + + if (!tdls_soc_obj || !rx_mgmt) { + tdls_err("invalid psoc object or rx mgmt"); + return QDF_STATUS_E_INVAL; + } + + tdls_debug("soc:%p, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%p", + tdls_soc_obj->soc, rx_mgmt->frame_len, + rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, + rx_mgmt->rx_rssi, rx_mgmt->buf); + + if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1] == + TDLS_PUBLIC_ACTION_DISC_RESP) { + mac = &rx_mgmt->buf[TDLS_80211_PEER_ADDR_OFFSET]; + tdls_notice("[TDLS] TDLS Discovery Response," + QDF_MAC_ADDRESS_STR " RSSI[%d] <--- OTA", + QDF_MAC_ADDR_ARRAY(mac), rx_mgmt->rx_rssi); + tdls_recv_discovery_resp(tdls_vdev, mac); + tdls_set_rssi(tdls_vdev, mac, rx_mgmt->rx_rssi); + } + + + if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET] == + TDLS_ACTION_FRAME) { + action_frame_type = + rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1]; + if (action_frame_type >= TDLS_ACTION_FRAME_TYPE_MAX) { + tdls_debug("[TDLS] unknown[%d] <--- OTA", + action_frame_type); + } else { + tdls_notice("[TDLS] %s <--- OTA", + tdls_action_frames_type[action_frame_type]); + } + } + + /* tdls_soc_obj->tdls_rx_cb ==> wlan_tdls_rx_callback() */ + if (tdls_soc_obj && tdls_soc_obj->tdls_rx_cb) + tdls_soc_obj->tdls_rx_cb(tdls_soc_obj->tdls_rx_cb_data, + rx_mgmt); + else + tdls_debug("rx mgmt, but no valid up layer callback"); + + qdf_mem_free(rx_mgmt); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_rx_mgmt_event *tdls_rx; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (!(msg->bodyptr)) { + tdls_err("invalid message body"); + return QDF_STATUS_E_INVAL; + } + + tdls_rx = (struct tdls_rx_mgmt_event *) msg->bodyptr; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(tdls_rx->tdls_soc_obj->soc, + tdls_rx->rx_mgmt->vdev_id, WLAN_TDLS_NB_ID); + + if (vdev) { + tdls_debug("tdls rx mgmt frame received"); + + tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); + if (tdls_vdev) + status = tdls_process_rx_mgmt(tdls_rx, tdls_vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } + + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + + return status; +} + +QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, + bool isregister) +{ + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[3]; + QDF_STATUS status; + int num_of_entries; + + tdls_debug("psoc:%p, is register rx:%d", psoc, isregister); + + frm_cb_info[0].frm_type = MGMT_PROBE_REQ; + frm_cb_info[0].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; + frm_cb_info[1].frm_type = MGMT_ACTION_TDLS_DISCRESP; + frm_cb_info[1].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; + frm_cb_info[2].frm_type = MGMT_ACTION_VENDOR_SPECIFIC; + frm_cb_info[2].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; + num_of_entries = 3; + + if (isregister) + status = wlan_mgmt_txrx_register_rx_cb(psoc, + WLAN_UMAC_COMP_TDLS, frm_cb_info, + num_of_entries); + else + status = wlan_mgmt_txrx_deregister_rx_cb(psoc, + WLAN_UMAC_COMP_TDLS, frm_cb_info, + num_of_entries); + + return status; +} + +static QDF_STATUS +tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request *req, + QDF_STATUS status) +{ + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_osif_indication indication; + + if (!req || !req->vdev) + return QDF_STATUS_E_NULL_VALUE; + + indication.status = status; + indication.vdev = req->vdev; + + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); + if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) + tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, + TDLS_EVENT_MGMT_TX_ACK_CNF, &indication); + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tdls_activate_send_mgmt_request( + struct tdls_action_frame_request *action_req) +{ + struct wlan_objmgr_peer *peer; + struct tdls_soc_priv_obj *tdls_soc_obj; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + struct scheduler_msg msg; + struct tdls_send_mgmt_request *tdls_mgmt_req; + + if (!action_req || !action_req->vdev) + return QDF_STATUS_E_NULL_VALUE; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(action_req->vdev, + WLAN_TDLS_SB_ID)) + return QDF_STATUS_E_NULL_VALUE; + + + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(action_req->vdev); + if (!tdls_soc_obj) { + status = QDF_STATUS_E_NULL_VALUE; + goto release_mgmt_ref; + } + + tdls_mgmt_req = qdf_mem_malloc(sizeof(struct tdls_send_mgmt_request) + + action_req->tdls_mgmt.len); + if (NULL == tdls_mgmt_req) { + status = QDF_STATUS_E_NOMEM; + tdls_err("mem alloc failed "); + QDF_ASSERT(0); + goto release_mgmt_ref; + } + + tdls_debug("session_id %d " + "tdls_mgmt.dialog %d " + "tdls_mgmt.frame_type %d " + "tdls_mgmt.status_code %d " + "tdls_mgmt.responder %d " + "tdls_mgmt.peer_capability %d", + action_req->session_id, + action_req->tdls_mgmt.dialog, + action_req->tdls_mgmt.frame_type, + action_req->tdls_mgmt.status_code, + action_req->tdls_mgmt.responder, + action_req->tdls_mgmt.peer_capability); + + tdls_mgmt_req->session_id = action_req->session_id; + /* Using dialog as transactionId. This can be used to + * match response with request + */ + tdls_mgmt_req->transaction_id = action_req->tdls_mgmt.dialog; + tdls_mgmt_req->req_type = action_req->tdls_mgmt.frame_type; + tdls_mgmt_req->dialog = action_req->tdls_mgmt.dialog; + tdls_mgmt_req->status_code = action_req->tdls_mgmt.status_code; + tdls_mgmt_req->responder = action_req->tdls_mgmt.responder; + tdls_mgmt_req->peer_capability = action_req->tdls_mgmt.peer_capability; + + peer = wlan_vdev_get_bsspeer(action_req->vdev); + + if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer, + WLAN_TDLS_SB_ID)) { + qdf_mem_free(tdls_mgmt_req); + goto release_mgmt_ref; + } + + qdf_mem_copy(tdls_mgmt_req->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + + qdf_mem_copy(tdls_mgmt_req->peer_mac.bytes, + action_req->tdls_mgmt.peer_mac.bytes, QDF_MAC_ADDR_SIZE); + + if (action_req->tdls_mgmt.len && action_req->tdls_mgmt.buf) { + qdf_mem_copy(tdls_mgmt_req->add_ie, action_req->tdls_mgmt.buf, + action_req->tdls_mgmt.len); + } + + tdls_mgmt_req->length = sizeof(struct tdls_send_mgmt_request) + + action_req->tdls_mgmt.len; + + /* Send the request to PE. */ + qdf_mem_zero(&msg, sizeof(msg)); + + tdls_debug("sending TDLS Mgmt Frame req to PE "); + tdls_mgmt_req->message_type = tdls_soc_obj->tdls_send_mgmt_req; + + msg.type = tdls_soc_obj->tdls_send_mgmt_req; + msg.bodyptr = tdls_mgmt_req; + + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); +release_mgmt_ref: + wlan_objmgr_vdev_release_ref(action_req->vdev, WLAN_TDLS_SB_ID); + + /*update tdls nss infornation based on action code */ + tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code); + + return status; +} + +static QDF_STATUS +tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + struct tdls_action_frame_request *req; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!cmd || !cmd->umac_cmd) { + tdls_err("invalid params cmd: %p, ", cmd); + return QDF_STATUS_E_NULL_VALUE; + } + req = cmd->umac_cmd; + + tdls_debug("reason: %d, vdev_id: %d", + reason, req->vdev_id); + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* command moved to active list */ + status = tdls_activate_send_mgmt_request(req); + break; + + case WLAN_SER_CB_CANCEL_CMD: + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + /* command removed from pending list. + * notify status complete with failure + */ + status = tdls_internal_send_mgmt_tx_done(req, + QDF_STATUS_E_FAILURE); + qdf_mem_free(req); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command successfully completed. + * release tdls_action_frame_request memory + */ + qdf_mem_free(req); + break; + + default: + /* Do nothing but logging */ + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +QDF_STATUS tdls_process_mgmt_req( + struct tdls_action_frame_request *tdls_mgmt_req) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_serialization_command cmd = {0, }; + enum wlan_serialization_status ser_cmd_status; + + /* If connected and in Infra. Only then allow this */ + status = tdls_validate_mgmt_request(tdls_mgmt_req->chk_frame); + if (status != QDF_STATUS_SUCCESS) { + status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req, + status); + qdf_mem_free(tdls_mgmt_req); + return status; + } + + /* update the responder, status code information + * after the cmd validation + */ + tdls_mgmt_req->tdls_mgmt.responder = + tdls_mgmt_req->chk_frame->responder; + tdls_mgmt_req->tdls_mgmt.status_code = + tdls_mgmt_req->chk_frame->status_code; + + cmd.cmd_type = WLAN_SER_CMD_TDLS_SEND_MGMT; + /* Cmd Id not applicable for non scan cmds */ + cmd.cmd_id = 0; + cmd.cmd_cb = (wlan_serialization_cmd_callback) + tdls_send_mgmt_serialize_callback; + cmd.umac_cmd = tdls_mgmt_req; + cmd.source = WLAN_UMAC_COMP_TDLS; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; + + cmd.vdev = tdls_mgmt_req->vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + tdls_debug("wlan_serialization_request status:%d", ser_cmd_status); + + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list.Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + case WLAN_SER_CMD_DENIED_LIST_FULL: + case WLAN_SER_CMD_DENIED_RULES_FAILED: + case WLAN_SER_CMD_DENIED_UNSPECIFIED: + /* free the request */ + qdf_mem_free(tdls_mgmt_req); + + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + return status; +} diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h index 1abd2484120e..94e6d11f9749 100644 --- a/core/src/wlan_tdls_mgmt.h +++ b/core/src/wlan_tdls_mgmt.h @@ -21,3 +21,54 @@ * * TDLS management frames include file */ + +#ifndef _WLAN_TDLS_MGMT_H_ +#define _WLAN_TDLS_MGMT_H_ + +/* default tdls serialize timeout is set to 10 secs */ +#define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000 + +/* + * struct tdls_send_mgmt_request - tdls management request + * @message_type: type of pe message + * @length: length of the frame. + * @session_id: session id + * @transaction_id: transaction ID for cmd + * @req_type: type of action frame + * @dialog: dialog token used in the frame. + * @status_code: status to be incuded in the frame. + * @responder: tdls request type + * @peer_capability: peer capability information + * @bssid: bssid + * @peer_mac: mac address of the peer + * @add_ie: additional ie's to be included + */ +struct tdls_send_mgmt_request { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + uint16_t transaction_id; + uint8_t req_type; + uint8_t dialog; + uint16_t status_code; + uint8_t responder; + uint32_t peer_capability; + struct qdf_mac_addr bssid; + struct qdf_mac_addr peer_mac; + /* Variable length. Dont add any field after this. */ + uint8_t add_ie[1]; +}; + +/** + * tdls_process_mgmt_req() - send a TDLS mgmt request to serialize module + * @tdls_mgmt_req: tdls management request + * + * TDLS request API, called from cfg80211 to send a TDLS frame in + * serialized manner to PE + * + *Return: QDF_STATUS + */ +QDF_STATUS tdls_process_mgmt_req( + struct tdls_action_frame_request *tdls_mgmt_req); +#endif + diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index bb5274fb5206..dc43e792e337 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -824,4 +824,44 @@ struct tdls_event_notify { struct wlan_objmgr_vdev *vdev; struct tdls_event_info event; }; + +/** + * struct tdls_event_notify - tdls event notify + * @peer_mac: peer's mac address + * @frame_type: Type of TDLS mgmt frame to be sent + * @dialog: dialog token used in the frame. + * @status_code: status to be incuded in the frame + * @responder: Tdls request type + * @peer_capability: peer cpabilities + * @len: lenght of additional Ies + * @buf: additional IEs to be included + */ +struct tdls_send_mgmt { + struct qdf_mac_addr peer_mac; + uint8_t frame_type; + uint8_t dialog; + uint16_t status_code; + uint8_t responder; + uint32_t peer_capability; + uint8_t len; + /* Variable length, do not add anything after this */ + uint8_t *buf; +}; + +/** + * struct tdls_send_action_frame_request - tdls send mgmt request + * @vdev: vdev object + * @session_id: session id + * @vdev_id: vdev id + * @tdls_mgmt: tdls managment + */ +struct tdls_action_frame_request { + struct wlan_objmgr_vdev *vdev; + uint8_t session_id; + uint8_t vdev_id; + const uint8_t *cmd_buf; + uint8_t len; + struct tdls_send_mgmt tdls_mgmt; +}; + #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 70a6c450a23f..302043fff731 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -118,4 +118,16 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, */ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, const uint8_t *macaddr, enum tdls_command_type cmd); + +/** + * ucfg_tdls_send_mgmt_frame() - send TDLS mgmt frame + * @mgmt_req: pointer to TDLS action frame request struct + * + * This will TDLS action frames to peer + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_send_mgmt_frame( + struct tdls_action_frame_request *mgmt_req); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 7a557a3df2ba..c57008a19f17 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -436,3 +436,42 @@ error: qdf_mem_free(req); return status; } + +QDF_STATUS ucfg_tdls_send_mgmt_frame( + struct tdls_action_frame_request *req) +{ + struct scheduler_msg msg = {0, }; + struct tdls_action_frame_request *mgmt_req; + + if (!req || !req->vdev) { + tdls_err("Invalid mgmt req params %p", req); + return QDF_STATUS_E_NULL_VALUE; + } + + mgmt_req = qdf_mem_malloc(sizeof(*mgmt_req) + + req->len); + if (!mgmt_req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + qdf_mem_copy(mgmt_req, req, sizeof(*req)); + + /*populate the additional IE's */ + if ((0 != req->len) && (NULL != req->cmd_buf)) { + qdf_mem_copy(mgmt_req->tdls_mgmt.buf, req->cmd_buf, + req->len); + mgmt_req->tdls_mgmt.len = req->len; + } else { + mgmt_req->tdls_mgmt.len = 0; + } + + tdls_notice("vdev id: %d, session id : %d", mgmt_req->vdev_id, + mgmt_req->session_id); + msg.bodyptr = mgmt_req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_TX_ACTION; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + return QDF_STATUS_SUCCESS; +} From 03429f458bae6df8a6553365024986c70a9259dc Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 28 Feb 2017 20:28:54 -0800 Subject: [PATCH 057/404] qcacmn: Add sta connect/disconnect in TDLS UMAC component Add sta connection and disconnection event related methods into TDLS component Change-Id: I1309792cf68df87b1ecf5a7686ac645ac21d1c7c CRs-Fixed: 2034220 --- core/src/wlan_tdls_main.c | 666 ++++++++++++++++++++++ core/src/wlan_tdls_main.h | 125 +++- dispatcher/inc/wlan_tdls_public_structs.h | 16 + dispatcher/src/wlan_tdls_ucfg_api.c | 13 +- 4 files changed, 817 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index b4b28c0b83b1..6faeb5dd925e 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -27,6 +27,10 @@ #include "wlan_tdls_peer.h" #include "wlan_tdls_ct.h" #include "wlan_tdls_mgmt.h" +#include "wlan_tdls_tgt_api.h" +#include "wlan_policy_mgr_public_struct.h" +#include "wlan_policy_mgr_api.h" + QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -387,3 +391,665 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } + +/** + * tdls_state_param_setting_dump() - print tdls state & parameters to send to fw + * @info: tdls setting to be sent to fw + * + * Return: void + */ +static void tdls_state_param_setting_dump(struct tdls_info *info) +{ + if (!info) + return; + + tdls_debug("Setting tdls state and param in fw: vdev_id: %d, tdls_state: %d, notification_interval_ms: %d, tx_discovery_threshold: %d, tx_teardown_threshold: %d, rssi_teardown_threshold: %d, rssi_delta: %d, tdls_options: 0x%x, peer_traffic_ind_window: %d, peer_traffic_response_timeout: %d, puapsd_mask: 0x%x, puapsd_inactivity_time: %d, puapsd_rx_frame_threshold: %d, teardown_notification_ms: %d, tdls_peer_kickout_threshold: %d", + info->vdev_id, + info->tdls_state, + info->notification_interval_ms, + info->tx_discovery_threshold, + info->tx_teardown_threshold, + info->rssi_teardown_threshold, + info->rssi_delta, + info->tdls_options, + info->peer_traffic_ind_window, + info->peer_traffic_response_timeout, + info->puapsd_mask, + info->puapsd_inactivity_time, + info->puapsd_rx_frame_threshold, + info->teardown_notification_ms, + info->tdls_peer_kickout_threshold); + +} + +/** + * tdls_update_fw_tdls_state() - update tdls status info + * @tdls_soc_obj: TDLS soc object + * @tdls_info_to_fw: TDLS state info to update in f/w. + * + * send message to WMA to set TDLS state in f/w + * + * Return: QDF_STATUS. + */ +static +QDF_STATUS tdls_update_fw_tdls_state(struct tdls_soc_priv_obj *tdls_soc_obj, + struct tdls_info *tdls_info_to_fw) +{ + QDF_STATUS status; + + /* wmi_unified_update_fw_tdls_state_cmd() will be called directly */ + status = tgt_tdls_set_fw_state(tdls_soc_obj->soc, tdls_info_to_fw); + + if (!QDF_IS_STATUS_SUCCESS(status)) + status = QDF_STATUS_E_FAILURE; + + return status; +} + +bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + bool state = false; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, + WLAN_TDLS_NB_ID)) + return state; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) { + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); + return state; + } + + if (policy_mgr_get_connection_count(tdls_soc_obj->soc) == 1) + state = true; + else + tdls_warn("Concurrent sessions are running or TDLS disabled"); + /* If any concurrency is detected */ + /* print session information */ + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); + return state; +} + +/** + * cds_set_tdls_ct_mode() - Set the tdls connection tracker mode + * @hdd_ctx: hdd context + * + * This routine is called to set the tdls connection tracker operation status + * + * Return: NONE + */ +void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc) +{ + bool state = false; + struct tdls_soc_priv_obj *tdls_soc_obj; + + tdls_soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (NULL == tdls_soc_obj) + return; + + /* If any concurrency is detected, skip tdls pkt tracker */ + if (policy_mgr_get_connection_count(psoc) > 1) { + state = false; + goto set_state; + } + + if (TDLS_SUPPORT_DISABLED == tdls_soc_obj->tdls_current_mode || + TDLS_SUPPORT_SUSPENDED == tdls_soc_obj->tdls_current_mode || + !TDLS_IS_IMPLICIT_TRIG_ENABLED( + tdls_soc_obj->tdls_configs.tdls_feature_flags)) { + state = false; + goto set_state; + } else if (policy_mgr_mode_specific_connection_count(psoc, + PM_STA_MODE, + NULL) == 1) { + state = true; + } else if (policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_CLIENT_MODE, + NULL) == 1){ + state = true; + } else { + state = false; + goto set_state; + } + + /* In case of TDLS external control, peer should be added + * by the user space to start connection tracker. + */ + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdls_soc_obj->tdls_configs.tdls_feature_flags)) { + if (tdls_soc_obj->tdls_external_peer_count) + state = true; + else + state = false; + } + +set_state: + tdls_soc_obj->enable_tdls_connection_tracker = state; + + tdls_notice("enable_tdls_connection_tracker %d", + tdls_soc_obj->enable_tdls_connection_tracker); +} + +QDF_STATUS +tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) +{ + if (!psoc) { + tdls_err("psoc: %p", psoc); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_debug("enter "); + tdls_set_ct_mode(psoc); + tdls_debug("exit "); + return QDF_STATUS_SUCCESS; +} + +/** + * tdls_get_vdev() - Get tdls specific vdev object manager + * @psoc: wlan psoc object manager + * @dbg_id: debug id + * + * If TDLS possible, return the corresponding vdev + * to enable TDLS in the system. + * + * Return: vdev manager pointer or NULL. + */ +struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, + wlan_objmgr_ref_dbgid dbg_id) +{ + if (policy_mgr_get_connection_count(psoc) > 1) + return NULL; + if (policy_mgr_mode_specific_connection_count(psoc, + PM_STA_MODE, + NULL) == 1) + return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, + QDF_STA_MODE, + dbg_id); + if (policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_CLIENT_MODE, + NULL) == 1) + return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, + QDF_P2P_CLIENT_MODE, + dbg_id); + return NULL; +} + +/** + * tdls_process_session_update() - update session count information + * @psoc: soc object + * @notification: TDLS os if notification + * + * update the session information in connection tracker + * + * Return: None + */ +static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc, + enum tdls_command_type cmd_type) +{ + struct scheduler_msg msg = {0}; + QDF_STATUS status; + + msg.bodyptr = psoc; + msg.callback = tdls_process_cmd; + msg.type = (uint16_t)cmd_type; + + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) + tdls_alert("message post failed "); +} + +void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc) +{ + tdls_process_session_update(psoc, TDLS_CMD_SESSION_INCREMENT); +} + +void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc) +{ + tdls_process_session_update(psoc, TDLS_CMD_SESSION_DECREMENT); +} + +/** + * tdls_send_update_to_fw - update tdls status info + * @tdls_vdev_obj: tdls vdev private object. + * @tdls_prohibited: indicates whether tdls is prohibited. + * @tdls_chan_swit_prohibited: indicates whether tdls channel switch + * is prohibited. + * @sta_connect_event: indicate sta connect or disconnect event + * @session_id: session id + * + * Normally an AP does not influence TDLS connection between STAs + * associated to it. But AP may set bits for TDLS Prohibited or + * TDLS Channel Switch Prohibited in Extended Capability IE in + * Assoc/Re-assoc response to STA. So after STA is connected to + * an AP, call this function to update TDLS status as per those + * bits set in Ext Cap IE in received Assoc/Re-assoc response + * from AP. + * + * Return: None. + */ +static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited, + bool sta_connect_event, + uint8_t session_id) +{ + struct tdls_info *tdls_info_to_fw; + struct tdls_config_params *threshold_params; + uint32_t tdls_feature_flags; + QDF_STATUS status; + + + /* If TDLS support is disabled then no need to update target */ + if (tdls_soc_obj->tdls_current_mode <= TDLS_SUPPORT_SUSPENDED) { + tdls_err("TDLS not enabled or suspended"); + return; + } + + if (tdls_soc_obj->set_state_info.set_state_cnt == 0 && + !sta_connect_event) { + return; + } + + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + + /* If AP or caller indicated TDLS Prohibited then disable tdls mode */ + if (tdls_prohibited) { + tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; + } else { + tdls_debug("TDLS feature flags from ini %d ", + tdls_feature_flags); + if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXP_TRIG_ONLY; + else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXT_CONTROL; + else + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_IMP_MODE; + } + + tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info)); + + if (!tdls_info_to_fw) { + tdls_err("memory allocation failed for tdlsParams"); + QDF_ASSERT(0); + return; + } + + threshold_params = &tdls_vdev_obj->threshold_config; + + tdls_info_to_fw->notification_interval_ms = + threshold_params->tx_period_t; + tdls_info_to_fw->tx_discovery_threshold = + threshold_params->tx_packet_n; + tdls_info_to_fw->tx_teardown_threshold = + threshold_params->idle_packet_n; + tdls_info_to_fw->rssi_teardown_threshold = + threshold_params->rssi_teardown_threshold; + tdls_info_to_fw->rssi_delta = threshold_params->rssi_delta; + + if (tdls_soc_obj->set_state_info.set_state_cnt == 1 && + sta_connect_event) { + tdls_warn("Concurrency not allowed in TDLS! set state cnt %d", + tdls_soc_obj->set_state_info.set_state_cnt); + /* disable off channel and teardown links */ + /* Go through the peer list and delete them */ + tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; + tdls_info_to_fw->vdev_id = tdls_soc_obj->set_state_info.vdev_id; + } else { + tdls_info_to_fw->vdev_id = session_id; + } + + tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode; + tdls_info_to_fw->tdls_options = 0; + + /* Do not enable TDLS offchannel, if AP prohibited TDLS + * channel switch + */ + if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) && + (!tdls_chan_swit_prohibited)) + tdls_info_to_fw->tdls_options = ENA_TDLS_OFFCHAN; + + if (TDLS_IS_BUFFER_STA_ENABLED(tdls_feature_flags)) + tdls_info_to_fw->tdls_options |= ENA_TDLS_BUFFER_STA; + if (TDLS_IS_SLEEP_STA_ENABLED(tdls_feature_flags)) + tdls_info_to_fw->tdls_options |= ENA_TDLS_SLEEP_STA; + + + tdls_info_to_fw->peer_traffic_ind_window = + tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window; + tdls_info_to_fw->peer_traffic_response_timeout = + tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout; + tdls_info_to_fw->puapsd_mask = + tdls_soc_obj->tdls_configs.tdls_uapsd_mask; + tdls_info_to_fw->puapsd_inactivity_time = + tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time; + tdls_info_to_fw->puapsd_rx_frame_threshold = + tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold; + tdls_info_to_fw->teardown_notification_ms = + tdls_soc_obj->tdls_configs.tdls_idle_timeout; + tdls_info_to_fw->tdls_peer_kickout_threshold = + tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold; + + tdls_state_param_setting_dump(tdls_info_to_fw); + + status = tdls_update_fw_tdls_state(tdls_soc_obj, tdls_info_to_fw); + if (QDF_STATUS_SUCCESS != status) { + qdf_mem_free(tdls_info_to_fw); + goto done; + } + + if (sta_connect_event) { + tdls_soc_obj->set_state_info.set_state_cnt++; + tdls_soc_obj->set_state_info.vdev_id = session_id; + } else { + tdls_soc_obj->set_state_info.set_state_cnt--; + } + + tdls_debug("TDLS Set state cnt %d", + tdls_soc_obj->set_state_info.set_state_cnt); + + if (tdls_soc_obj->set_state_info.set_state_cnt == 1) + /* register callbacks with tx/rx mgmt */ + tdls_mgmt_rx_ops(tdls_soc_obj->soc, true); + else + /* deregister callbacks with tx/rx mgmt */ + tdls_mgmt_rx_ops(tdls_soc_obj->soc, false); + +done: + tdls_process_session_update(tdls_soc_obj->soc, + TDLS_CMD_SESSION_INCREMENT); + return; +} + +static QDF_STATUS +tdls_process_sta_connect(struct tdls_sta_notify_params *notify) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(notify->vdev, + &tdls_vdev_obj, + &tdls_soc_obj)) + return QDF_STATUS_E_INVAL; + + + tdls_debug("Check and update TDLS state"); + + /* Association event */ + if (!tdls_soc_obj->tdls_disable_in_progress) { + tdls_send_update_to_fw(tdls_vdev_obj, + tdls_soc_obj, + notify->tdls_prohibited, + notify->tdls_chan_swit_prohibited, + true, + notify->session_id); + } + + /* check and set the connection tracker */ + tdls_set_ct_mode(tdls_soc_obj->soc); + if (tdls_soc_obj->enable_tdls_connection_tracker) + tdls_implicit_enable(tdls_vdev_obj); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) +{ + QDF_STATUS status; + + if (!notify || !notify->vdev) + return QDF_STATUS_E_INVAL; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, + WLAN_TDLS_NB_ID)) + return QDF_STATUS_E_INVAL; + + status = tdls_process_sta_connect(notify); + + wlan_objmgr_vdev_release_ref(notify->vdev, + WLAN_TDLS_NB_ID); + qdf_mem_free(notify); + return status; +} + +static QDF_STATUS +tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_vdev_priv_obj *curr_tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_soc_priv_obj *curr_tdls_soc; + struct wlan_objmgr_vdev *temp_vdev = NULL; + + + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(notify->vdev, + &tdls_vdev_obj, + &tdls_soc_obj)) + return QDF_STATUS_E_INVAL; + + tdls_debug("Check and update TDLS state"); + + curr_tdls_vdev = tdls_vdev_obj; + curr_tdls_soc = tdls_soc_obj; + + /* Disassociation event */ + if (!tdls_soc_obj->tdls_disable_in_progress) + tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, false, + false, false, notify->session_id); + + /* If concurrency is not marked, then we have to + * check, whether TDLS could be enabled in the + * system after this disassoc event. + */ + if (!notify->lfr_roam && !tdls_soc_obj->tdls_disable_in_progress) { + temp_vdev = tdls_get_vdev(tdls_soc_obj->soc, WLAN_TDLS_NB_ID); + if (NULL != temp_vdev) { + status = tdls_get_vdev_objects(temp_vdev, + &tdls_vdev_obj, + &tdls_soc_obj); + if (QDF_STATUS_SUCCESS == status) { + tdls_send_update_to_fw(tdls_vdev_obj, + tdls_soc_obj, + false, + false, + true, + notify->session_id); + curr_tdls_vdev = tdls_vdev_obj; + curr_tdls_soc = tdls_soc_obj; + } + } + } + + /* Check and set the connection tracker and implicit timers */ + tdls_set_ct_mode(curr_tdls_soc->soc); + if (curr_tdls_soc->enable_tdls_connection_tracker) + tdls_implicit_enable(curr_tdls_vdev); + else + tdls_implicit_disable(curr_tdls_vdev); + + /* release the vdev ref , if temp vdev was acquired */ + if (temp_vdev) + wlan_objmgr_vdev_release_ref(temp_vdev, + WLAN_TDLS_NB_ID); + + return status; +} + +QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) +{ + QDF_STATUS status; + + if (!notify || !notify->vdev) + return QDF_STATUS_E_INVAL; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, + WLAN_TDLS_NB_ID)) + return QDF_STATUS_E_INVAL; + + status = tdls_process_sta_disconnect(notify); + + wlan_objmgr_vdev_release_ref(notify->vdev, + WLAN_TDLS_NB_ID); + + qdf_mem_free(notify); + return status; +} + +/** + * tdls_set_mode_in_vdev() - set TDLS mode + * @tdls_vdev: tdls vdev object + * @tdls_soc: tdls soc object + * @tdls_mode: TDLS mode + * @source: TDLS disable source enum values + * + * Return: Void + */ +static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdls_soc, + enum tdls_feature_mode tdls_mode, + enum tdls_disable_sources source) +{ + if (!tdls_vdev) + return; + tdls_debug("enter tdls mode is %d", tdls_mode); + + if (TDLS_SUPPORT_IMP_MODE == tdls_mode || + TDLS_SUPPORT_EXT_CONTROL == tdls_mode) { + clear_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + /* + * Check if any TDLS source bit is set and if + * bitmap is not zero then we should not + * enable TDLS + */ + if (tdls_soc->tdls_source_bitmap) { + tdls_notice("Don't enable TDLS, source bitmap: %lu", + tdls_soc->tdls_source_bitmap); + return; + } + tdls_implicit_enable(tdls_vdev); + /* tdls implicit mode is enabled, so + * enable the connection tracker + */ + tdls_soc->enable_tdls_connection_tracker = + true; + } else if (TDLS_SUPPORT_DISABLED == tdls_mode) { + set_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + tdls_implicit_disable(tdls_vdev); + /* If tdls implicit mode is disabled, then + * stop the connection tracker. + */ + tdls_soc->enable_tdls_connection_tracker = + false; + } else if (TDLS_SUPPORT_EXP_TRIG_ONLY == + tdls_mode) { + clear_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + tdls_implicit_disable(tdls_vdev); + /* If tdls implicit mode is disabled, then + * stop the connection tracker. + */ + tdls_soc->enable_tdls_connection_tracker = + false; + + /* + * Check if any TDLS source bit is set and if + * bitmap is not zero then we should not + * enable TDLS + */ + if (tdls_soc->tdls_source_bitmap) + return; + } + tdls_debug("exit "); + +} + +/** + * tdls_set_current_mode() - set TDLS mode + * @tdls_soc: tdls soc object + * @tdls_mode: TDLS mode + * @update_last: indicate to record the last tdls mode + * @source: TDLS disable source enum values + * + * Return: Void + */ +static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc, + enum tdls_feature_mode tdls_mode, + bool update_last, + enum tdls_disable_sources source) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_vdev_priv_obj *tdls_vdev; + + if (!tdls_soc) + return; + + tdls_debug("mode %d", (int)tdls_mode); + + if (update_last) + tdls_soc->tdls_last_mode = tdls_mode; + + if (tdls_soc->tdls_current_mode == tdls_mode) { + tdls_debug("already in mode %d", tdls_mode); + + switch (tdls_mode) { + /* TDLS is already enabled hence clear source mask, return */ + case TDLS_SUPPORT_IMP_MODE: + case TDLS_SUPPORT_EXP_TRIG_ONLY: + case TDLS_SUPPORT_EXT_CONTROL: + clear_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + tdls_debug("clear source mask:%d", source); + return; + /* TDLS is already disabled hence set source mask, return */ + case TDLS_SUPPORT_DISABLED: + set_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + tdls_debug("set source mask:%d", source); + return; + default: + return; + } + } + + /* get sta vdev */ + vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc, + QDF_STA_MODE, + WLAN_TDLS_NB_ID); + if (NULL != vdev) { + tdls_debug("set mode in tdls vdev "); + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_vdev) + tdls_set_mode_in_vdev(tdls_vdev, tdls_soc, + tdls_mode, source); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } + + /* get p2p client vdev */ + vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc, + QDF_P2P_CLIENT_MODE, + WLAN_TDLS_NB_ID); + if (NULL != vdev) { + tdls_debug("set mode in tdls vdev "); + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_vdev) + tdls_set_mode_in_vdev(tdls_vdev, tdls_soc, + tdls_mode, source); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } + + if (!update_last) + tdls_soc->tdls_last_mode = tdls_soc->tdls_current_mode; + + tdls_soc->tdls_current_mode = tdls_mode; + +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index cf758e772e06..e6929facff01 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -145,7 +145,8 @@ struct tdls_set_state_info { * struct tdls_psoc_priv_ctx - tdls context * @soc: objmgr psoc * @tdls_current_mode: current tdls mode - * @tdls_user_config_mode: user configure tdls mode + * @tdls_last_mode: last tdls mode + * @tdls_source_bitmap: bit map to set/reset TDLS by different sources * @tdls_conn_info: this tdls_conn_info can be removed and we can use peer type * of peer object to get the active tdls peers * @tdls_configs: tdls user configure @@ -180,7 +181,8 @@ struct tdls_set_state_info { struct tdls_soc_priv_obj { struct wlan_objmgr_psoc *soc; enum tdls_feature_mode tdls_current_mode; - enum tdls_feature_mode tdls_user_config_mode; + enum tdls_feature_mode tdls_last_mode; + unsigned long tdls_source_bitmap; struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM]; struct tdls_user_config tdls_configs; uint16_t max_num_tdls_sta; @@ -192,6 +194,7 @@ struct tdls_soc_priv_obj { uint8_t tdls_external_peer_count; bool tdls_nss_switch_in_progress; bool tdls_nss_teardown_complete; + bool tdls_disable_in_progress; enum tdls_nss_transition_state tdls_nss_transition_mode; int32_t tdls_teardown_peers_cnt; struct tdls_set_state_info set_state_info; @@ -320,6 +323,25 @@ struct tdls_peer { struct tdls_peer_mlme_info *tdls_info; }; +/** + * struct tdls_os_if_event - TDLS os event info + * @type: type of event + * @info: pointer to event information + */ +struct tdls_os_if_event { + uint32_t type; + void *info; +}; + +/** + * enum tdls_os_if_notification - TDLS notification from OS IF + * @TDLS_NOTIFY_STA_SESSION_INCREMENT: sta session count incremented + * @TDLS_NOTIFY_STA_SESSION_DECREMENT: sta session count decremented + */ +enum tdls_os_if_notification { + TDLS_NOTIFY_STA_SESSION_INCREMENT, + TDLS_NOTIFY_STA_SESSION_DECREMENT +}; /** * wlan_vdev_get_tdls_soc_obj - private API to get tdls soc object from vdev * @vdev: vdev object @@ -501,4 +523,103 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, struct tdls_vdev_priv_obj **tdls_vdev_obj, struct tdls_soc_priv_obj **tdls_soc_obj); +/** + * cds_set_tdls_ct_mode() - Set the tdls connection tracker mode + * @hdd_ctx: hdd context + * + * This routine is called to set the tdls connection tracker operation status + * + * Return: NONE + */ +void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc); + +/** + * tdls_notify_sta_connect() - Update tdls state for every + * connect event. + * @vdev: vdev object manager + * @tdls_prohibited: flag to tell whether tdls prohibited in this bss + * @tdls_chan_swit_prohibited: flag to tell whether tdls channel switch + * prohibited in this bss + * @session_id: session id + * + * After every connect event in the system, check whether TDLS + * can be enabled in the system. If TDLS can be enabled, update the + * TDLS state as needed. + * + * Return: None + */ +void tdls_notify_sta_connect(struct wlan_objmgr_vdev *vdev, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited, + uint8_t session_id); + +/** + * tdls_notify_sta_disconnect() - Update tdls state for every + * disconnect event. + * @vdev: vdev object manager + * @lfr_roam: roaming case + * @session_id: session id + * + * After every disconnect event in the system, check whether TDLS + * can be disabled/enabled in the system and update the + * TDLS state as needed. + * + * Return: None + */ +void tdls_notify_sta_disconnect(struct wlan_objmgr_vdev *vdev, + bool lfr_roam, + uint8_t session_id); + +/** + * tdls_notify_decrement_session() - Notify the session decrement + * @psoc: psoc object manager + * + * Policy manager notify TDLS about session decrement + * + * Return: None + */ +void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc); + +/** + * tdls_notify_increment_session() - Notify the session increment + * @psoc: psoc object manager + * + * Policy manager notify TDLS about session increment + * + * Return: None + */ +void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc); + +/** + * tdls_check_is_tdls_allowed() - check is tdls allowed or not + * @vdev: vdev object + * + * Function determines the whether TDLS allowed in the system + * + * Return: true or false + */ +bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_get_vdev() - Get tdls specific vdev object manager + * @psoc: wlan psoc object manager + * @dbg_id: debug id + * + * If TDLS possible, return the corresponding vdev + * to enable TDLS in the system. + * + * Return: vdev manager pointer or NULL. + */ +struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, + wlan_objmgr_ref_dbgid dbg_id); + +/** + * tdls_process_policy_mgr_notification() - process policy manager notification + * @psoc: soc object manager + * + * Return: QDF_STATUS + */ +QDF_STATUS +tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc); + #endif diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index dc43e792e337..39e9ddebe7a4 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -286,6 +286,22 @@ enum tdls_event_reason { TDLS_SCAN_COMPLETED, }; +/** + * enum tdls_disable_sources - TDLS disable sources + * @TDLS_SET_MODE_SOURCE_USER: disable from user + * @TDLS_SET_MODE_SOURCE_SCAN: disable during scan + * @TDLS_SET_MODE_SOURCE_OFFCHANNEL: disable during offchannel + * @TDLS_SET_MODE_SOURCE_BTC: disable during bluetooth + * @TDLS_SET_MODE_SOURCE_P2P: disable during p2p + */ +enum tdls_disable_sources { + TDLS_SET_MODE_SOURCE_USER = 0, + TDLS_SET_MODE_SOURCE_SCAN, + TDLS_SET_MODE_SOURCE_OFFCHANNEL, + TDLS_SET_MODE_SOURCE_BTC, + TDLS_SET_MODE_SOURCE_P2P, +}; + /** * struct tdls_osif_indication - tdls indication to os if layer * @vdev: vdev object diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index c57008a19f17..be63fbdbd87c 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -28,6 +28,7 @@ #include "../../core/src/wlan_tdls_cmds_process.h" #include #include +#include "wlan_policy_mgr_api.h" QDF_STATUS ucfg_tdls_init(void) { @@ -122,7 +123,6 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) soc_obj->tdls_teardown_peers_cnt = 0; soc_obj->tdls_nss_teardown_complete = false; soc_obj->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_S_UNKNOWN; - soc_obj->tdls_user_config_mode = TDLS_SUPPORT_DISABLED; feature = soc_obj->tdls_configs.tdls_feature_flags; if (TDLS_IS_BUFFER_STA_ENABLED(feature) || @@ -178,6 +178,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, { struct tdls_soc_priv_obj *soc_obj; uint32_t tdls_feature_flags; + struct policy_mgr_tdls_cbacks tdls_pm_call_backs; tdls_notice("tdls update config "); if (!psoc || !req) { @@ -208,6 +209,16 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_add_sta_req = req->tdls_add_sta_req; soc_obj->tdls_del_sta_req = req->tdls_del_sta_req; soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; + tdls_pm_call_backs.tdls_notify_increment_session = + tdls_notify_increment_session; + + tdls_pm_call_backs.tdls_notify_decrement_session = + tdls_notify_decrement_session; + if (QDF_STATUS_SUCCESS != policy_mgr_register_tdls_cb( + psoc, &tdls_pm_call_backs)) { + tdls_err("policy manager callback registration failed "); + return QDF_STATUS_E_FAILURE; + } /* Update TDLS user config */ qdf_mem_copy(&soc_obj->tdls_configs, &req->config, sizeof(req->config)); From c81d3750b006dfcffc04ade4e6a8ae97d2ddeb24 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 28 Feb 2017 20:28:54 -0800 Subject: [PATCH 058/404] qcacmn: Add sta connect/disconnect in TDLS UMAC component Add sta connection and disconnection event related methods into TDLS component Change-Id: I1309792cf68df87b1ecf5a7686ac645ac21d1c7c CRs-Fixed: 2034220 --- inc/wlan_policy_mgr_api.h | 4 ++-- src/wlan_policy_mgr_get_set_utils.c | 13 +++++++------ src/wlan_policy_mgr_init_deinit.c | 8 ++++---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 3eb4a5815880..fd618266564f 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -796,8 +796,8 @@ struct policy_mgr_hdd_cbacks { * @check_is_tdls_allowed: check if tdls allowed or not */ struct policy_mgr_tdls_cbacks { - void (*set_tdls_ct_mode)(struct wlan_objmgr_psoc *psoc); - bool (*check_is_tdls_allowed)(enum tQDF_ADAPTER_MODE device_mode); + void (*tdls_notify_increment_session)(struct wlan_objmgr_psoc *psoc); + void (*tdls_notify_decrement_session)(struct wlan_objmgr_psoc *psoc); }; /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 771f7e37442c..46cb04661818 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1114,9 +1114,10 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); } - /* set tdls connection tracker state */ - if (pm_ctx->tdls_cbacks.set_tdls_ct_mode) - pm_ctx->tdls_cbacks.set_tdls_ct_mode(psoc); + /* Notify tdls */ + if (pm_ctx->tdls_cbacks.tdls_notify_increment_session) + pm_ctx->tdls_cbacks.tdls_notify_increment_session(psoc); + policy_mgr_dump_current_concurrency(psoc); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); @@ -1152,9 +1153,9 @@ void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, policy_mgr_decr_connection_count(psoc, session_id); - /* set tdls connection tracker state */ - if (pm_ctx->tdls_cbacks.set_tdls_ct_mode) - pm_ctx->tdls_cbacks.set_tdls_ct_mode(psoc); + /* Notify tdls */ + if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session) + pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc); policy_mgr_dump_current_concurrency(psoc); } diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 9c2fde0ae2d3..dcf5d882f3b4 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -605,10 +605,10 @@ QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - pm_ctx->tdls_cbacks.check_is_tdls_allowed = - tdls_cbacks->check_is_tdls_allowed; - pm_ctx->tdls_cbacks.set_tdls_ct_mode = - tdls_cbacks->set_tdls_ct_mode; + pm_ctx->tdls_cbacks.tdls_notify_increment_session = + tdls_cbacks->tdls_notify_increment_session; + pm_ctx->tdls_cbacks.tdls_notify_decrement_session = + tdls_cbacks->tdls_notify_decrement_session; return QDF_STATUS_SUCCESS; } From 53f502c2699a34b5b71c84d13e7551da69414562 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Fri, 14 Apr 2017 23:36:42 -0700 Subject: [PATCH 059/404] qcacmn: Add TDLS ucfg changes for sta connect/disconnect Add TDLS ucfg interface changes for sta connect, sta disconnect and tx/rx data sample Change-Id: Ic57a91b70fe462ee031dc0cf54112601aae0dfc4 CRs-Fixed: 2034220 --- core/src/wlan_tdls_cmds_process.c | 57 ++++++++ core/src/wlan_tdls_cmds_process.h | 8 ++ core/src/wlan_tdls_main.c | 49 +++++++ core/src/wlan_tdls_main.h | 31 ++--- dispatcher/inc/wlan_tdls_public_structs.h | 137 ++++++++++++++++++-- dispatcher/inc/wlan_tdls_ucfg_api.h | 55 ++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 150 ++++++++++++++++++++++ 7 files changed, 461 insertions(+), 26 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 49784df9bd19..51361b65c18f 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1759,3 +1759,60 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, /*TODO connection tracker update*/ return QDF_STATUS_SUCCESS; } + +/** + * tdls_process_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +static +int tdls_process_set_responder(struct tdls_set_responder_req *set_req) +{ + struct tdls_peer *curr_peer; + struct tdls_vdev_priv_obj *tdls_vdev; + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(set_req->vdev); + if (!tdls_vdev) { + tdls_err("tdls vdev obj is NULL"); + return -EINVAL; + } + curr_peer = tdls_get_peer(tdls_vdev, set_req->peer_mac); + if (curr_peer == NULL) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + curr_peer->is_responder = set_req->responder; + return 0; +} + + +/** + * tdls_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_set_responder(struct tdls_set_responder_req *set_req) +{ + QDF_STATUS status; + + if (!set_req || !set_req->vdev) { + tdls_err("Invalid input params %p", set_req); + return -EINVAL; + } + + status = wlan_objmgr_vdev_try_get_ref(set_req->vdev, WLAN_TDLS_NB_ID); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("vdev object is deleted"); + return -EINVAL; + } + + status = tdls_process_set_responder(set_req); + + wlan_objmgr_vdev_release_ref(set_req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(set_req); + return status; +} + diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 32e8cba01ac0..8c17dfebd454 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -259,4 +259,12 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, */ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); +/** + * tdls_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_set_responder(struct tdls_set_responder_req *set_req); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 6faeb5dd925e..879290e56b4d 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -241,6 +241,23 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) break; case TDLS_CMD_CONFIG_UPDATE: break; + case TDLS_CMD_SET_RESPONDER: + tdls_set_responder(msg->bodyptr); + break; + case TDLS_NOTIFY_STA_CONNECTION: + tdls_notify_sta_connect(msg->bodyptr); + break; + case TDLS_NOTIFY_STA_DISCONNECTION: + tdls_notify_sta_disconnect(msg->bodyptr); + break; + case TDLS_CMD_SET_TDLS_MODE: + tdls_set_operation_mode(msg->bodyptr); + break; + case TDLS_CMD_SESSION_INCREMENT: + case TDLS_CMD_SESSION_DECREMENT: + tdls_process_policy_mgr_notification(msg->bodyptr); + break; + default: break; } @@ -1053,3 +1070,35 @@ static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc, tdls_soc->tdls_current_mode = tdls_mode; } + +QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode) +{ + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status; + + if (!tdls_set_mode || !tdls_set_mode->vdev) + return QDF_STATUS_E_INVAL; + + if (QDF_STATUS_SUCCESS != + wlan_objmgr_vdev_try_get_ref(tdls_set_mode->vdev, + WLAN_TDLS_NB_ID)) + return QDF_STATUS_E_INVAL; + + status = tdls_get_vdev_objects(tdls_set_mode->vdev, + &tdls_vdev, &tdls_soc); + + if (status != QDF_STATUS_SUCCESS) + goto release_mode_ref; + + tdls_set_current_mode(tdls_soc, + tdls_set_mode->tdls_mode, + tdls_set_mode->update_last, + tdls_set_mode->source); + +release_mode_ref: + wlan_objmgr_vdev_release_ref(tdls_set_mode->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(tdls_set_mode); + return status; +} + diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index e6929facff01..769f2533c52d 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -533,42 +533,39 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, */ void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc); +/** + * tdls_set_operation_mode() - set tdls operating mode + * @tdls_set_mode: tdls mode set params + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode); + /** * tdls_notify_sta_connect() - Update tdls state for every * connect event. - * @vdev: vdev object manager - * @tdls_prohibited: flag to tell whether tdls prohibited in this bss - * @tdls_chan_swit_prohibited: flag to tell whether tdls channel switch - * prohibited in this bss - * @session_id: session id + * @notify: sta connect params * * After every connect event in the system, check whether TDLS * can be enabled in the system. If TDLS can be enabled, update the * TDLS state as needed. * - * Return: None + * Return: QDF_STATUS */ -void tdls_notify_sta_connect(struct wlan_objmgr_vdev *vdev, - bool tdls_prohibited, - bool tdls_chan_swit_prohibited, - uint8_t session_id); +QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); /** * tdls_notify_sta_disconnect() - Update tdls state for every * disconnect event. - * @vdev: vdev object manager - * @lfr_roam: roaming case - * @session_id: session id + * @notify: sta disconnect params * * After every disconnect event in the system, check whether TDLS * can be disabled/enabled in the system and update the * TDLS state as needed. * - * Return: None + * Return: QDF_STATUS */ -void tdls_notify_sta_disconnect(struct wlan_objmgr_vdev *vdev, - bool lfr_roam, - uint8_t session_id); +QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); /** * tdls_notify_decrement_session() - Notify the session decrement diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 39e9ddebe7a4..4d4b7be4168f 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -178,7 +178,14 @@ enum tdls_command_type { TDLS_CMD_CONFIG_FORCE_PEER, TDLS_CMD_REMOVE_FORCE_PEER, TDLS_CMD_STATS_UPDATE, - TDLS_CMD_CONFIG_UPDATE + TDLS_CMD_CONFIG_UPDATE, + TDLS_CMD_SCAN_DONE, + TDLS_CMD_SET_RESPONDER, + TDLS_NOTIFY_STA_CONNECTION, + TDLS_NOTIFY_STA_DISCONNECTION, + TDLS_CMD_SET_TDLS_MODE, + TDLS_CMD_SESSION_INCREMENT, + TDLS_CMD_SESSION_DECREMENT, }; /** @@ -350,21 +357,21 @@ enum tdls_feature_bit { }; #define TDLS_IS_OFF_CHANNEL_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_OFF_CHANNEL, flags) + CHECK_BIT(flags, TDLS_FEATURE_OFF_CHANNEL) #define TDLS_IS_WMM_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_WMM, flags) + CHECK_BIT(flags, TDLS_FEATURE_WMM) #define TDLS_IS_BUFFER_STA_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_BUFFER_STA, flags) + CHECK_BIT(flags, TDLS_FEATURE_BUFFER_STA) #define TDLS_IS_SLEEP_STA_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_SLEEP_STA, flags) + CHECK_BIT(flags, TDLS_FEATURE_SLEEP_STA) #define TDLS_IS_SCAN_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_SCAN, flags) + CHECK_BIT(flags, TDLS_FEATURE_SCAN) #define TDLS_IS_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_ENABLE, flags) + CHECK_BIT(flags, TDLS_FEATURE_ENABLE) #define TDLS_IS_IMPLICIT_TRIG_ENABLED(flags) \ - CHECK_BIT(TDLS_FEAUTRE_IMPLICIT_TRIGGER, flags) + CHECK_BIT(flags, TDLS_FEAUTRE_IMPLICIT_TRIGGER) #define TDLS_IS_EXTERNAL_CONTROL_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_EXTERNAL_CONTROL, flags) + CHECK_BIT(flags, TDLS_FEATURE_EXTERNAL_CONTROL) /** * struct tdls_user_config - TDLS user configuration @@ -448,6 +455,47 @@ struct tdls_tx_cnf { int status; }; +/** + * struct tdls_rx_mgmt_frame - rx mgmt frame structure + * @frame_len: frame length + * @rx_chan: rx channel + * @vdev_id: vdev id + * @frm_type: frame type + * @rx_rssi: rx rssi + * @buf: buffer address + */ +struct tdls_rx_mgmt_frame { + uint32_t frame_len; + uint32_t rx_chan; + uint32_t vdev_id; + uint32_t frm_type; + uint32_t rx_rssi; + uint8_t buf[1]; +}; + +/** + * tdls_rx_callback() - Callback for rx mgmt frame + * @user_data: user data associated to this rx mgmt frame. + * @rx_frame: RX mgmt frame + * + * This callback will be used to give rx frames to hdd. + * + * Return: None + */ +typedef void (*tdls_rx_callback)(void *user_data, + struct tdls_rx_mgmt_frame *rx_frame); + +/** + * tdls_wmm_check() - Callback for wmm info + * @psoc: psoc object + * + * This callback will be used to check wmm information + * + * Return: true or false + */ +typedef bool (*tdls_wmm_check)(struct wlan_objmgr_vdev **vdev); + + /* This callback is used to report state change of peer to wpa_supplicant */ typedef int (*tdls_state_change_callback)(const uint8_t *mac, uint32_t opclass, @@ -497,6 +545,10 @@ struct tdls_start_params { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + tdls_rx_callback tdls_rx_cb; + void *tdls_rx_cb_data; + tdls_wmm_check tdls_wmm_cb; + void *tdls_wmm_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; @@ -848,6 +900,7 @@ struct tdls_event_notify { * @dialog: dialog token used in the frame. * @status_code: status to be incuded in the frame * @responder: Tdls request type + * @len: lenght of additional Ies * @peer_capability: peer cpabilities * @len: lenght of additional Ies * @buf: additional IEs to be included @@ -864,15 +917,39 @@ struct tdls_send_mgmt { uint8_t *buf; }; +/** + * struct tdls_validate_action_req - tdls validate mgmt request + * @vdev: vdev object + * @action_code: action code + * @peer_mac: peer mac address + * @dialog_token: dialog code + * @status_code: status code to add + * @len: len of the frame + * @responder: whether to respond or not + * @max_sta_failed: mgmt failure reason + */ +struct tdls_validate_action_req { + struct wlan_objmgr_vdev *vdev; + uint8_t action_code; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t dialog_token; + uint8_t status_code; + size_t len; + int responder; + int max_sta_failed; +}; + /** * struct tdls_send_action_frame_request - tdls send mgmt request * @vdev: vdev object + * @chk_frame: frame validation structure * @session_id: session id * @vdev_id: vdev id * @tdls_mgmt: tdls managment */ struct tdls_action_frame_request { struct wlan_objmgr_vdev *vdev; + struct tdls_validate_action_req *chk_frame; uint8_t session_id; uint8_t vdev_id; const uint8_t *cmd_buf; @@ -880,4 +957,46 @@ struct tdls_action_frame_request { struct tdls_send_mgmt tdls_mgmt; }; +/** + * struct tdls_set_responder_req - tdls set responder in peer + * @vdev: vdev object + * @peer_mac: peer mac address + * @responder: whether to respond or not + */ +struct tdls_set_responder_req { + struct wlan_objmgr_vdev *vdev; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t responder; +}; + +/** + * struct tdls_sta_notify_params - STA connection notify info + * @vdev: vdev object + * @tdls_prohibited: peer mac addr + * @tdls_chan_swit_prohibited: peer type + * @lfr_roam: is trigger due to lfr + * @session_id: session id + */ +struct tdls_sta_notify_params { + struct wlan_objmgr_vdev *vdev; + bool tdls_prohibited; + bool tdls_chan_swit_prohibited; + bool lfr_roam; + uint8_t session_id; +}; + +/** + * struct tdls_set_mode_params - TDLS set mode params + * @vdev: vdev object + * @tdls_mode: tdls mode to set + * @update_last: inform to update last tdls mode + * @source: mode change requester + */ +struct tdls_set_mode_params { + struct wlan_objmgr_vdev *vdev; + enum tdls_feature_mode tdls_mode; + bool update_last; + enum tdls_disable_sources source; +}; + #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 302043fff731..6c7d117b44d9 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -130,4 +130,59 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *mgmt_req); +/** + * ucfg_tdls_responder() - set responder in TDLS peer + * @msg_req: responder msg + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req); + +/** + * ucfg_tdls_notify_sta_connect() - notify sta connect + * @notify_info: sta notification info + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_notify_sta_connect( + struct tdls_sta_notify_params *notify_info); + +/** + * ucfg_tdls_notify_sta_disconnect() - notify sta disconnect + * @notify_info: sta notification info + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_notify_sta_disconnect( + struct tdls_sta_notify_params *notify_info); + +/** + * ucfg_tdls_set_operating_mode() - set operating mode + * @set_mode_params: set mode params + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_set_operating_mode( + struct tdls_set_mode_params *set_mode_params); + +/** + * ucfg_tdls_update_rx_pkt_cnt() - update rx pkt count + * @vdev: tdls vdev object + * @mac_addr: peer mac address + * + * Return: None + */ +void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + +/** + * ucfg_tdls_update_tx_pkt_cnt() - update tx pkt count + * @vdev: tdls vdev object + * @mac_addr: peer mac address + * + * Return: None + */ +void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index be63fbdbd87c..ce21c05bf406 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -26,6 +26,7 @@ #include #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" +#include "../../core/src/wlan_tdls_ct.h" #include #include #include "wlan_policy_mgr_api.h" @@ -486,3 +487,152 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( return QDF_STATUS_SUCCESS; } + +QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) +{ + struct scheduler_msg msg = {0, }; + struct tdls_set_responder_req *msg_req; + QDF_STATUS status; + + if (!req || !req->vdev) { + tdls_err("invalid input %p", req); + return QDF_STATUS_E_NULL_VALUE; + } + + msg_req = qdf_mem_malloc(sizeof(*msg_req)); + if (!msg_req) + return QDF_STATUS_E_NULL_VALUE; + + msg_req->responder = req->responder; + msg_req->vdev = req->vdev; + qdf_mem_copy(msg_req->peer_mac, req->peer_mac, QDF_MAC_ADDR_SIZE); + + msg.bodyptr = msg_req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_RESPONDER; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + return status; +} + +QDF_STATUS ucfg_tdls_notify_sta_connect( + struct tdls_sta_notify_params *notify_info) +{ + struct scheduler_msg msg = {0, }; + struct tdls_sta_notify_params *notify; + + if (!notify_info || !notify_info->vdev) { + tdls_err("notify_info->vdev: %p, notify_info %p", + notify_info->vdev, notify_info); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_notice("Enter "); + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) + return QDF_STATUS_E_NULL_VALUE; + + notify->session_id = notify_info->session_id; + notify->tdls_chan_swit_prohibited = + notify_info->tdls_chan_swit_prohibited; + notify->tdls_prohibited = notify_info->tdls_prohibited; + notify->vdev = notify_info->vdev; + + msg.bodyptr = notify; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_STA_CONNECTION; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_notify_sta_disconnect( + struct tdls_sta_notify_params *notify_info) +{ + struct scheduler_msg msg = {0, }; + struct tdls_sta_notify_params *notify; + + if (!notify_info || !notify_info->vdev) { + tdls_err("notify_info->vdev: %p, notify_info %p", + notify_info->vdev, notify_info); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_notice("Enter "); + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) + return QDF_STATUS_E_NULL_VALUE; + + notify->session_id = notify_info->session_id; + notify->tdls_chan_swit_prohibited = false; + notify->tdls_prohibited = false; + notify->vdev = notify_info->vdev; + + msg.bodyptr = notify; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_STA_DISCONNECTION; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_set_operating_mode( + struct tdls_set_mode_params *set_mode_params) +{ + struct scheduler_msg msg = {0, }; + struct tdls_set_mode_params *set_mode; + + if (!set_mode_params || !set_mode_params->vdev) { + tdls_err("vdev: %p, set_mode_params %p", + set_mode_params->vdev, set_mode_params); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_notice("Enter "); + + set_mode = qdf_mem_malloc(sizeof(*set_mode)); + if (!set_mode) + return QDF_STATUS_E_NULL_VALUE; + + set_mode->source = set_mode_params->source; + set_mode->tdls_mode = set_mode_params->tdls_mode; + set_mode->update_last = set_mode_params->update_last; + set_mode->vdev = set_mode_params->vdev; + + msg.bodyptr = set_mode; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_TDLS_MODE; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + + return QDF_STATUS_SUCCESS; +} + +void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + QDF_STATUS status; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (status != QDF_STATUS_SUCCESS) + return; + tdls_update_rx_pkt_cnt(vdev, mac_addr); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + +void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + QDF_STATUS status; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (status != QDF_STATUS_SUCCESS) + return; + tdls_update_tx_pkt_cnt(vdev, mac_addr); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} From b4c693d7f2b9421dd752ca3ac8f508f66a689fca Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 27 Mar 2017 23:42:04 -0700 Subject: [PATCH 060/404] qcacmn: Add scan related events for TDLS component Add Scan start and complete events for TDLS component Change-Id: Ibb452d2823115ec16a7c6e9f88c9ad6cac48930c CRs-Fixed: 2034220 --- core/src/wlan_tdls_main.c | 165 +++++++++++++++++++++++++++- core/src/wlan_tdls_main.h | 43 ++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 14 ++- 3 files changed, 220 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 879290e56b4d..5fef8c76e727 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -31,6 +31,11 @@ #include "wlan_policy_mgr_public_struct.h" #include "wlan_policy_mgr_api.h" +/* Global tdls soc pvt object + * this is useful for some functions which does not receive either vdev or psoc + * objects. + */ +static struct tdls_soc_priv_obj *tdls_soc_global; QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -56,6 +61,7 @@ QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, qdf_mem_free(tdls_soc_obj); } + tdls_soc_global = tdls_soc_obj; tdls_notice("TDLS obj attach to psoc successfully"); return status; @@ -141,6 +147,8 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, { QDF_STATUS status; struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct wlan_objmgr_pdev *pdev; + struct tdls_soc_priv_obj *tdls_soc; tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && @@ -169,6 +177,23 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) goto out; + tdls_soc = wlan_vdev_get_tdls_soc_obj(vdev); + if (!tdls_soc) { + tdls_err("get soc by vdev failed "); + return QDF_STATUS_E_NOMEM; + } + + pdev = wlan_vdev_get_pdev(vdev); + + status = ucfg_scan_register_event_handler(pdev, + tdls_scan_complete_event_handler, + tdls_soc); + + if (QDF_STATUS_SUCCESS != status) { + tdls_err("scan event register failed "); + return QDF_STATUS_E_FAILURE; + } + tdls_notice("tdls object attach to vdev successfully"); out: return status; @@ -244,6 +269,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SET_RESPONDER: tdls_set_responder(msg->bodyptr); break; + case TDLS_CMD_SCAN_DONE: + tdls_scan_done_callback(msg->bodyptr); + break; case TDLS_NOTIFY_STA_CONNECTION: tdls_notify_sta_connect(msg->bodyptr); break; @@ -257,7 +285,6 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SESSION_DECREMENT: tdls_process_policy_mgr_notification(msg->bodyptr); break; - default: break; } @@ -1102,3 +1129,139 @@ release_mode_ref: return status; } +/** + * wlan_hdd_tdls_scan_done_callback() - callback for tdls scan done event + * @pAdapter: HDD adapter + * + * Return: Void + */ +void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc) +{ + if (!tdls_soc) + return; + + if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) { + tdls_notice("TDLS mode is disabled OR not enabled"); + return; + } + + /* if tdls was enabled before scan, re-enable tdls mode */ + if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode || + TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode || + TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode) { + tdls_notice("revert tdls mode %d", + tdls_soc->tdls_last_mode); + + tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode, + false, + TDLS_SET_MODE_SOURCE_SCAN); + } +} + +/** + * tdls_post_scan_done_msg() - post scan done message to tdls cmd queue + * @tdls_soc: tdls soc object + * + * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_NULL_VALUE + */ +static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) +{ + struct scheduler_msg msg = {0, }; + + if (!tdls_soc) { + tdls_err("tdls_soc: %p ", tdls_soc); + return QDF_STATUS_E_NULL_VALUE; + } + + msg.bodyptr = tdls_soc; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SCAN_DONE; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + return QDF_STATUS_SUCCESS; +} + +void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, + struct scan_event *event, + void *arg) +{ + enum tQDF_ADAPTER_MODE device_mode; + struct tdls_soc_priv_obj *tdls_soc; + + if (!vdev || !event || !arg) + return; + + if (SCAN_EVENT_TYPE_COMPLETED != event->type) + return; + + device_mode = wlan_vdev_mlme_get_opmode(vdev); + + if (device_mode != QDF_STA_MODE && + device_mode != QDF_P2P_CLIENT_MODE) + return; + tdls_soc = (struct tdls_soc_priv_obj *) arg; + tdls_post_scan_done_msg(tdls_soc); +} + +QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc) +{ + struct tdls_peer *curr_peer; + struct tdls_vdev_priv_obj *tdls_vdev; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + /* if tdls is not enabled, then continue scan */ + if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) + return status; + + /* Get the vdev based on vdev operating mode*/ + vdev = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_NB_ID); + if (!vdev) + return status; + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_vdev) + goto return_success; + + curr_peer = tdls_is_progress(tdls_vdev, NULL, 0); + if (NULL != curr_peer) { + if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) { + tdls_notice(QDF_MAC_ADDRESS_STR + ". scan rejected %d. force it to idle", + QDF_MAC_ADDR_ARRAY( + curr_peer->peer_mac.bytes), + tdls_soc->scan_reject_count); + tdls_soc->scan_reject_count = 0; + + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); + status = QDF_STATUS_SUCCESS; + } else { + tdls_warn("tdls in progress. scan rejected %d", + tdls_soc->scan_reject_count); + status = QDF_STATUS_E_BUSY; + } + } +return_success: + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); + return status; +} + +void tdls_scan_serialization_comp_info_cb( + union wlan_serialization_rules_info *comp_info) +{ + struct tdls_soc_priv_obj *tdls_soc; + QDF_STATUS status; + if (!comp_info) + return; + + tdls_soc = tdls_soc_global; + comp_info->scan_info.is_tdls_in_progress = false; + status = tdls_scan_callback(tdls_soc); + if (QDF_STATUS_E_BUSY == status) + comp_info->scan_info.is_tdls_in_progress = true; +} + + diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 769f2533c52d..30ace4511980 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -33,6 +33,7 @@ #include #include #include +#include "wlan_serialization_api.h" /* Bit mask flag for tdls_option to FW */ #define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ @@ -54,6 +55,8 @@ * should not be more than 2000. */ #define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000 +#define TDLS_SCAN_REJECT_MAX 5 + #define tdls_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) @@ -146,6 +149,7 @@ struct tdls_set_state_info { * @soc: objmgr psoc * @tdls_current_mode: current tdls mode * @tdls_last_mode: last tdls mode + * @scan_reject_count: number of times scan rejected due to TDLS * @tdls_source_bitmap: bit map to set/reset TDLS by different sources * @tdls_conn_info: this tdls_conn_info can be removed and we can use peer type * of peer object to get the active tdls peers @@ -182,6 +186,7 @@ struct tdls_soc_priv_obj { struct wlan_objmgr_psoc *soc; enum tdls_feature_mode tdls_current_mode; enum tdls_feature_mode tdls_last_mode; + int scan_reject_count; unsigned long tdls_source_bitmap; struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM]; struct tdls_user_config tdls_configs; @@ -619,4 +624,42 @@ struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, QDF_STATUS tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc); +/** + * tdls_scan_complete_event_handler() - scan complete event handler for tdls + * @vdev: vdev object + * @event: scan event + * @arg: tdls soc object + * + * Return: None + */ +void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, + struct scan_event *event, + void *arg); + +/** + * tdls_scan_callback() - callback for TDLS scan operation + * @soc: tdls soc pvt object + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc); + +/** + * wlan_hdd_tdls_scan_done_callback() - callback for tdls scan done event + * @tdls_soc: tdls soc object + * + * Return: Void + */ +void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc); + +/** + * tdls_scan_serialization_comp_info_cb() - callback for scan start + * @comp_info: serialize rules info + * + * Return: negative = caller should stop and return error code immediately + * 1 = caller can continue to scan + */ +void tdls_scan_serialization_comp_info_cb( + union wlan_serialization_rules_info *comp_info); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index ce21c05bf406..1e4afdbfaa06 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -30,6 +30,7 @@ #include #include #include "wlan_policy_mgr_api.h" +#include "wlan_scan_ucfg_api.h" QDF_STATUS ucfg_tdls_init(void) { @@ -134,7 +135,6 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) else soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; - for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { soc_obj->tdls_conn_info[sta_idx].sta_id = 0; soc_obj->tdls_conn_info[sta_idx].session_id = 255; @@ -247,6 +247,18 @@ QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc) status = tgt_tdls_register_ev_handler(psoc); + if (status != QDF_STATUS_SUCCESS) + return status; + + status = wlan_serialization_register_comp_info_cb(psoc, + WLAN_UMAC_COMP_TDLS, + WLAN_SER_CMD_SCAN, + tdls_scan_serialization_comp_info_cb); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("Serialize scan cmd register failed "); + status = QDF_STATUS_E_FAILURE; + } + return status; } From f3f11a78c3cbbc1736cab00c8e2bb5f2e9adc392 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Sun, 26 Mar 2017 18:52:47 -0700 Subject: [PATCH 061/404] 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 --- core/src/wlan_tdls_cmds_process.c | 349 +++++++++++++++++++++- core/src/wlan_tdls_cmds_process.h | 98 ++++++ core/src/wlan_tdls_ct.c | 21 ++ core/src/wlan_tdls_ct.h | 17 ++ core/src/wlan_tdls_main.c | 2 + core/src/wlan_tdls_main.h | 7 +- core/src/wlan_tdls_mgmt.c | 5 +- core/src/wlan_tdls_mgmt.h | 39 +++ dispatcher/inc/wlan_tdls_public_structs.h | 6 +- dispatcher/inc/wlan_tdls_tgt_api.h | 35 +++ dispatcher/src/wlan_tdls_tgt_api.c | 151 ++++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 15 +- 12 files changed, 736 insertions(+), 9 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 51361b65c18f..26594e3f37f4 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -569,6 +569,244 @@ tdls_add_peer_serialize_callback(struct wlan_serialization_command *cmd, return status; } +void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, + uint8_t action_code) +{ + if (!tdls_soc) + return; + + if (TDLS_TEARDOWN != action_code || + tdls_soc->tdls_nss_switch_in_progress) + return; + + if (tdls_soc->tdls_teardown_peers_cnt != 0) + tdls_soc->tdls_teardown_peers_cnt--; + if (tdls_soc->tdls_teardown_peers_cnt == 0) { + if (tdls_soc->tdls_nss_transition_mode == + TDLS_NSS_TRANSITION_S_1x1_to_2x2) { + /* TDLS NSS switch is fully completed, so + * reset the flags. + */ + tdls_notice("TDLS NSS switch is fully completed"); + tdls_soc->tdls_nss_switch_in_progress = false; + tdls_soc->tdls_nss_teardown_complete = false; + } else { + /* TDLS NSS switch is not yet completed, but + * tdls teardown is completed for all the + * peers. + */ + tdls_notice("teardown done & NSS switch in progress"); + tdls_soc->tdls_nss_teardown_complete = true; + } + } + +} + +/** + * tdls_set_cap() - set TDLS capability type + * @tdls_vdev: tdls vdev object + * @mac: peer mac address + * @cap: TDLS capability type + * + * Return: 0 if successful or negative errno otherwise + */ +int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac, + enum tdls_peer_capab cap) +{ + struct tdls_peer *curr_peer; + + curr_peer = tdls_get_peer(tdls_vdev, mac); + if (curr_peer == NULL) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + curr_peer->tdls_support = cap; + return 0; +} + +static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, + struct tdls_validate_action_req *tdls_validate) +{ + /* supplicant still sends tdls_mgmt(SETUP_REQ) + * even after we return error code at + * 'add_station()'. Hence we have this check + * again in addition to add_station(). Anyway, + * there is no harm to double-check. + */ + if (TDLS_SETUP_REQUEST == tdls_validate->action_code) { + tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_validate->action_code, + tdls_soc->connected_peer_count, + tdls_soc->max_num_tdls_sta); + return -EINVAL; + } + /* maximum reached. tweak to send + * error code to peer and return error + * code to supplicant + */ + tdls_validate->status_code = QDF_STATUS_E_RESOURCES; + tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_validate->action_code, + tdls_soc->connected_peer_count, + tdls_soc->max_num_tdls_sta); + + tdls_validate->max_sta_failed = -EPERM; + return 0; +} + +int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate) +{ + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_peer *curr_peer; + struct tdls_peer *temp_peer; + QDF_STATUS status; + + + if (!tdls_validate || !tdls_validate->vdev) + return -EINVAL; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(tdls_validate->vdev, + &tdls_vdev, + &tdls_soc)) + return -ENOTSUPP; + + /* + * STA or P2P client should be connected and authenticated before + * sending any TDLS frames + */ + if (!tdls_is_vdev_connected(tdls_validate->vdev) || + !tdls_is_vdev_authenticated(tdls_validate->vdev)) { + tdls_err("STA is not connected or not authenticated."); + return -EAGAIN; + } + + /* other than teardown frame, mgmt frames are not sent if disabled */ + if (TDLS_TEARDOWN != tdls_validate->action_code) { + if (!tdls_check_is_tdls_allowed(tdls_validate->vdev)) { + tdls_err("TDLS not allowed, reject MGMT, action = %d", + tdls_validate->action_code); + return -EPERM; + } + /* if tdls_mode is disabled, then decline the peer's request */ + if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode || + TDLS_SUPPORT_SUSPENDED == tdls_soc->tdls_current_mode) { + tdls_notice(QDF_MAC_ADDRESS_STR + " TDLS mode is disabled. action %d declined.", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_validate->action_code); + return -ENOTSUPP; + } + if (tdls_soc->tdls_nss_switch_in_progress) { + tdls_err("nss switch in progress, action %d declined " + QDF_MAC_ADDRESS_STR, + tdls_validate->action_code, + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); + return -EAGAIN; + } + } + + if (TDLS_IS_SETUP_ACTION(tdls_validate->action_code)) { + if (NULL != tdls_is_progress(tdls_vdev, + tdls_validate->peer_mac, true)) { + tdls_err("setup is ongoing. action %d declined for " + QDF_MAC_ADDRESS_STR, + tdls_validate->action_code, + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); + return -EPERM; + } + } + + /* + * Discard TDLS Discovery request and setup confirm if violates + * ACM rules + */ + if ((TDLS_DISCOVERY_REQUEST == tdls_validate->action_code || + TDLS_SETUP_CONFIRM == tdls_validate->action_code)) { + /* call hdd_wmm_is_acm_allowed() */ + if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) { + tdls_err("admission ctrl set to VI, action %d declined", + tdls_validate->action_code); + return -EPERM; + } + } + + + if (TDLS_SETUP_REQUEST == tdls_validate->action_code || + TDLS_SETUP_RESPONSE == tdls_validate->action_code) { + if (tdls_soc->max_num_tdls_sta <= + tdls_soc->connected_peer_count) { + status = tdls_validate_setup_frames(tdls_soc, + tdls_validate); + if (QDF_STATUS_SUCCESS != status) + return status; + /* fall through to send setup resp + * with failure status code + */ + } else { + curr_peer = + tdls_find_peer(tdls_vdev, + tdls_validate->peer_mac); + if (curr_peer) { + if (TDLS_IS_LINK_CONNECTED(curr_peer)) { + tdls_err(QDF_MAC_ADDRESS_STR " already connected action %d declined.", + QDF_MAC_ADDR_ARRAY( + tdls_validate->peer_mac), + tdls_validate->action_code); + + return -EPERM; + } + } + } + } + + tdls_notice("tdls_mgmt" QDF_MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_validate->action_code, tdls_validate->dialog_token, + tdls_validate->status_code, tdls_validate->len); + + /*Except teardown responder will not be used so just make 0 */ + tdls_validate->responder = 0; + if (TDLS_TEARDOWN == tdls_validate->action_code) { + temp_peer = tdls_find_peer(tdls_vdev, tdls_validate->peer_mac); + if (!temp_peer) { + tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist", + QDF_MAC_ADDR_ARRAY( + tdls_validate->peer_mac)); + return -EPERM; + } + + if (TDLS_IS_LINK_CONNECTED(temp_peer)) + tdls_validate->responder = temp_peer->is_responder; + else { + tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + temp_peer->link_status, + tdls_validate->dialog_token, + tdls_validate->status_code, + tdls_validate->len); + return -EPERM; + } + } + + /* For explicit trigger of DIS_REQ come out of BMPS for + * successfully receiving DIS_RSP from peer. + */ + if ((TDLS_SETUP_RESPONSE == tdls_validate->action_code) || + (TDLS_SETUP_CONFIRM == tdls_validate->action_code) || + (TDLS_DISCOVERY_RESPONSE == tdls_validate->action_code) || + (TDLS_DISCOVERY_REQUEST == tdls_validate->action_code)) { + /* Fw will take care if PS offload is enabled. */ + if (TDLS_DISCOVERY_REQUEST != tdls_validate->action_code) + tdls_set_cap(tdls_vdev, tdls_validate->peer_mac, + TDLS_CAP_SUPPORTED); + } + return 0; +} + QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) { struct wlan_serialization_command cmd = {0,}; @@ -1000,6 +1238,105 @@ error: return status; } +/** + * tdls_process_send_mgmt_rsp() - handle response for send mgmt + * @rsp: TDLS send mgmt response + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_osif_indication ind; + + psoc = rsp->psoc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("invalid vdev"); + status = QDF_STATUS_E_INVAL; + qdf_mem_free(rsp); + return status; + } + tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_soc || !tdls_vdev) { + tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev); + status = QDF_STATUS_E_FAILURE; + } + + tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_SEND_MGMT); + + if (legacy_result_success == rsp->status_code) + goto free_rsp; + tdls_err("send mgmt failed. status code(=%d)", rsp->status_code); + status = QDF_STATUS_E_FAILURE; + + if (tdls_soc && tdls_soc->tdls_event_cb) { + ind.vdev = vdev; + ind.status = rsp->status_code; + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_MGMT_TX_ACK_CNF, &ind); + } + +free_rsp: + qdf_mem_free(rsp); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + return status; +} + +/** + * tdls_send_mgmt_tx_completion() - process tx completion + * @tx_complete: TDLS mgmt completion info + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_send_mgmt_tx_completion( + struct tdls_mgmt_tx_completion_ind *tx_complete) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_osif_indication ind; + + psoc = tx_complete->psoc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + tx_complete->session_id, + WLAN_TDLS_SB_ID); + + if (!vdev) { + tdls_err("invalid vdev"); + status = QDF_STATUS_E_INVAL; + goto free_tx_complete; + } + + tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + + if (!tdls_soc || !tdls_vdev) { + tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev); + status = QDF_STATUS_E_FAILURE; + } + + if (tdls_soc && tdls_soc->tdls_event_cb) { + ind.vdev = vdev; + ind.status = tx_complete->tx_complete_status; + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_MGMT_TX_ACK_CNF, &ind); + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +free_tx_complete: + qdf_mem_free(tx_complete); + return status; +} + /** * tdls_add_peer_rsp() - handle response for add TDLS peer * @rsp: TDLS add peer response @@ -1139,10 +1476,12 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) tdls_debug(QDF_MAC_ADDRESS_STR " status is %d", QDF_MAC_ADDR_ARRAY(macaddr), curr_peer->link_status); + wlan_vdev_obj_lock(vdev); id = wlan_vdev_get_id(vdev); wlan_vdev_obj_unlock(vdev); - if (TDLS_IS_CONNECTED(curr_peer)) { + + if (TDLS_IS_LINK_CONNECTED(curr_peer)) { soc_obj->tdls_dereg_tl_peer( soc_obj->tdls_tl_peer_data, id, curr_peer->sta_id); @@ -1464,6 +1803,10 @@ static QDF_STATUS tdls_config_force_peer( tdls_set_callback(peer, req->callback); + tdls_set_ct_mode(soc_obj->soc); + if (soc_obj->enable_tdls_connection_tracker) + tdls_implicit_enable(vdev_obj); + return status; error: qdf_mem_free(peer_update_param); @@ -1605,8 +1948,10 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) qdf_mem_free(peer_update_param); goto error; } + tdls_set_ct_mode(soc_obj->soc); + if (!soc_obj->enable_tdls_connection_tracker) + tdls_implicit_disable(vdev_obj); - /*TODO set tdls connection tracker state*/ error: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); qdf_mem_free(req); diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 8c17dfebd454..ec2f40e1070d 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -25,6 +25,11 @@ #ifndef _WLAN_TDLS_CMDS_PROCESS_H_ #define _WLAN_TDLS_CMDS_PROCESS_H_ +#define TDLS_IS_SETUP_ACTION(action) \ + ((TDLS_SETUP_REQUEST <= action) && \ + (TDLS_SETUP_CONFIRM >= action)) + + /** * enum tdls_add_oper - add peer type * @TDLS_OPER_NONE: none @@ -37,6 +42,53 @@ enum tdls_add_oper { TDLS_OPER_UPDATE }; +/** + * enum legacy_result_code - defined to comply with tSirResultCodes, need refine + * when mlme converged. + * @legacy_result_success: success + * @legacy_result_max: max result value + */ +enum legacy_result_code { + legacy_result_success, + legacy_result_max = 0x7FFFFFFF +}; + +/** + * struct tdls_send_mgmt_rsp - TDLS Response struct PE --> TDLS module + * same as struct tSirSmeRsp + * @message_type: message type eWNI_SME_TDLS_SEND_MGMT_RSP + * @length: message length + * @session_id: session id + * @transaction_id: transaction id + * @status_code: status code as tSirResultCodes + * @psoc: soc object + */ +struct tdls_send_mgmt_rsp { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + uint16_t transaction_id; + enum legacy_result_code status_code; + struct wlan_objmgr_psoc *psoc; +}; + +/** + * struct tdls_mgmt_tx_completion_ind - TDLS TX completion PE --> TDLS module + * same as struct sSirMgmtTxCompletionInd + * @message_type: message type eWNI_SME_MGMT_FRM_TX_COMPLETION_IND + * @length: message length + * @session_id: session id + * @tx_complete_status: tx complete status + * @psoc: soc object + */ +struct tdls_mgmt_tx_completion_ind { + uint16_t message_type; + uint16_t length; + uint8_t session_id; /* Session ID */ + uint32_t tx_complete_status; + struct wlan_objmgr_psoc *psoc; +}; + /** * struct tdls_add_sta_req - TDLS request struct TDLS module --> PE * same as struct tSirTdlsAddStaReq; @@ -213,6 +265,52 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req); */ QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp); +/** + * tdls_reset_nss() - reset tdls nss parameters + * @tdls_soc: TDLS soc object + * @action_code: action code + * + * Return: None + */ +void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, + uint8_t action_code); + +/** + * tdls_set_cap() - set TDLS capability type + * @tdls_vdev: tdls vdev object + * @mac: peer mac address + * @cap: TDLS capability type + * + * Return: 0 if successful or negative errno otherwise + */ +int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac, + enum tdls_peer_capab cap); + +/** + * tdls_validate_mgmt_request() -validate mgmt request + * @tdls_validate: action frame request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); + +/** + * tdls_process_send_mgmt_rsp() - handle response for send mgmt + * @rsp: TDLS send mgmt response + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp); + +/** + * tdls_send_mgmt_tx_completion() - process tx completion + * @tx_complete: TDLS mgmt completion info + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_send_mgmt_tx_completion( + struct tdls_mgmt_tx_completion_ind *tx_complete); + /** * tdls_process_add_peer_rsp() - handle response for delete TDLS peer * @rsp: TDLS delete peer response diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 52ccfcfd2046..cb48dd205771 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -52,6 +52,27 @@ bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev) return true; } +bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_peer *peer; + bool is_authenticated = false; + + wlan_vdev_obj_lock(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + wlan_vdev_obj_unlock(vdev); + + if (!peer) { + tdls_err("peer is null"); + return false; + } + + wlan_peer_obj_lock(peer); + is_authenticated = wlan_peer_mlme_get_auth_state(peer); + wlan_peer_obj_unlock(peer); + + return is_authenticated; +} + /** * tdls_peer_reset_discovery_processed() - reset discovery status * @tdls_vdev: TDLS vdev object diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index d894794eb568..e497daed2bac 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -155,4 +155,21 @@ void tdls_discovery_timeout_peer_cb(void *user_data); * Return: Void */ void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev); + +/** + * tdls_is_vdev_connected() -check the vdev connection + * @vdev: vdev oobject + * + * Return: true or false + */ +bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_is_vdev_authenticated() -check the vdev authentication state + * @vdev: vdev oobject + * + * Return: true or false + */ +bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 5fef8c76e727..c58d8682b38b 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -30,6 +30,8 @@ #include "wlan_tdls_tgt_api.h" #include "wlan_policy_mgr_public_struct.h" #include "wlan_policy_mgr_api.h" +#include "wlan_scan_ucfg_api.h" + /* Global tdls soc pvt object * this is useful for some functions which does not receive either vdev or psoc diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 30ace4511980..bfbddf0dede2 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -34,6 +34,7 @@ #include #include #include "wlan_serialization_api.h" +#include "wlan_tdls_mgmt.h" /* Bit mask flag for tdls_option to FW */ #define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ @@ -74,7 +75,7 @@ #define tdls_alert(format, args...) \ tdls_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) -#define TDLS_IS_CONNECTED(peer) \ +#define TDLS_IS_LINK_CONNECTED(peer) \ ((TDLS_LINK_CONNECTED == (peer)->link_status) || \ (TDLS_LINK_TEARING == (peer)->link_status)) @@ -203,6 +204,10 @@ struct tdls_soc_priv_obj { enum tdls_nss_transition_state tdls_nss_transition_mode; int32_t tdls_teardown_peers_cnt; struct tdls_set_state_info set_state_info; + tdls_rx_callback tdls_rx_cb; + void *tdls_rx_cb_data; + tdls_wmm_check tdls_wmm_cb; + void *tdls_wmm_cb_data; tdls_tx_ack_cnf_callback tdls_tx_cnf_cb; void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 3f28bf08174f..f6e27dfd757e 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -113,7 +113,6 @@ static QDF_STATUS tdls_process_rx_mgmt( tdls_set_rssi(tdls_vdev, mac, rx_mgmt->rx_rssi); } - if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET] == TDLS_ACTION_FRAME) { action_frame_type = @@ -127,7 +126,7 @@ static QDF_STATUS tdls_process_rx_mgmt( } } - /* tdls_soc_obj->tdls_rx_cb ==> wlan_tdls_rx_callback() */ + /* tdls_soc_obj->tdls_rx_cb ==> wlan_cfg80211_tdls_rx_callback() */ if (tdls_soc_obj && tdls_soc_obj->tdls_rx_cb) tdls_soc_obj->tdls_rx_cb(tdls_soc_obj->tdls_rx_cb_data, rx_mgmt); @@ -157,7 +156,6 @@ QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg) if (vdev) { tdls_debug("tdls rx mgmt frame received"); - tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); if (tdls_vdev) @@ -175,6 +173,7 @@ QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, bool isregister) { struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[3]; + QDF_STATUS status; int num_of_entries; diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h index 94e6d11f9749..3d3e6dd54a50 100644 --- a/core/src/wlan_tdls_mgmt.h +++ b/core/src/wlan_tdls_mgmt.h @@ -28,6 +28,24 @@ /* default tdls serialize timeout is set to 10 secs */ #define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000 +#define TDLS_PUBLIC_ACTION_FRAME_OFFSET 24 +#define TDLS_PUBLIC_ACTION_FRAME 4 +#define TDLS_PUBLIC_ACTION_DISC_RESP 14 +#define TDLS_ACTION_FRAME 12 +#define TDLS_80211_PEER_ADDR_OFFSET (TDLS_PUBLIC_ACTION_FRAME + \ + QDF_MAC_ADDR_SIZE) +#define TDLS_ACTION_FRAME_TYPE_MAX 11 + +/** + * struct tdls_rx_mgmt_event - tdls rx mgmt frame event + * @tdls_soc_obj: tdls soc private object + * @rx_mgmt: tdls rx mgmt frame structure + */ +struct tdls_rx_mgmt_event { + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_rx_mgmt_frame *rx_mgmt; +}; + /* * struct tdls_send_mgmt_request - tdls management request * @message_type: type of pe message @@ -70,5 +88,26 @@ struct tdls_send_mgmt_request { */ QDF_STATUS tdls_process_mgmt_req( struct tdls_action_frame_request *tdls_mgmt_req); + +/** + * tdls_mgmt_rx_ops() - register or unregister rx callback + * @psoc: psoc object + * @isregister: register if true, unregister if false + * + * This function registers or unregisters rx callback to mgmt txrx + * component. + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, + bool isregister); + +/** + * tdls_process_rx_frame() - process tdls rx frames + * @msg: scheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg); #endif diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 4d4b7be4168f..36e3a4676c90 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -29,6 +29,8 @@ #include #include #include +#include + #define WLAN_TDLS_STA_MAX_NUM 8 #define WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM 1 @@ -59,7 +61,7 @@ #define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500 /** Maximum time(ms) to wait for tdls mgmt to complete **/ -#define WAIT_TIME_TDLS_MGMT 11000 +#define WAIT_TIME_FOR_TDLS_MGMT 11000 #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 @@ -252,7 +254,7 @@ enum tdls_event_msg_type { TDLS_SHOULD_DISCOVER = 0, TDLS_SHOULD_TEARDOWN, TDLS_PEER_DISCONNECTED, - TDLS_CONNECTION_TRACKER_NOTIFY, + TDLS_CONNECTION_TRACKER_NOTIFY }; /** diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h index dbc8c0683f50..4357241a4eee 100644 --- a/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -67,6 +67,22 @@ QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, struct sta_uapsd_trig_params *params); +/** + * tgt_tdls_send_mgmt_rsp() - process tdls mgmt response + * @pmsg: sheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg); + +/** + * tgt_tdls_send_mgmt_tx_completion() -process tx completion message + * @pmsg: sheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg); + /** * tgt_tdls_del_peer_rsp() - handle TDLS del peer response * @pmsg: sheduler msg @@ -111,4 +127,23 @@ QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc); QDF_STATUS tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, struct tdls_event_info *info); + +/** + * tgt_tdls_mgmt_frame_rx_cb() - callback for rx mgmt frame + * @psoc: soc context + * @peer: peer context + * @buf: rx buffer + * @mgmt_rx_params: mgmt rx parameters + * @frm_type: frame type + * + * This function gets called from mgmt tx/rx component when rx mgmt + * received. + * + * Return: QDF_STATUS_SUCCESS + */ +QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, qdf_nbuf_t buf, + struct mgmt_rx_event_params *mgmt_rx_params, + enum mgmt_frame_type frm_type); + #endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 78a198b2a71f..a55f6d134151 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -87,6 +87,36 @@ QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pmsg || !pmsg->bodyptr) { + tdls_err("msg: 0x%p", pmsg); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tdls_send_mgmt_tx_completion(pmsg->bodyptr); + + return status; +} + +QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pmsg || !pmsg->bodyptr) { + tdls_err("msg: 0x%p", pmsg); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tdls_process_send_mgmt_rsp(pmsg->bodyptr); + + return status; +} + QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -183,3 +213,124 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, return status; } + +static +QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, + qdf_nbuf_t buf, + struct mgmt_rx_event_params *mgmt_rx_params, + enum mgmt_frame_type frm_type) +{ + struct tdls_rx_mgmt_frame *rx_mgmt; + struct tdls_rx_mgmt_event *rx_mgmt_event; + struct tdls_soc_priv_obj *tdls_soc_obj; + struct scheduler_msg msg; + struct wlan_objmgr_vdev *vdev; + uint32_t vdev_id; + uint8_t *pdata; + QDF_STATUS status; + + tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (!tdls_soc_obj) { + tdls_err("tdls ctx is NULL, drop this frame"); + return QDF_STATUS_E_FAILURE; + } + + if (!peer) { + vdev = tdls_get_vdev(psoc, WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("current tdls vdev is null, can't get vdev id"); + return QDF_STATUS_E_FAILURE; + } + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + } else { + wlan_peer_obj_lock(peer); + vdev = wlan_peer_get_vdev(peer); + wlan_peer_obj_unlock(peer); + if (!vdev) { + tdls_err("vdev is NULL in peer, drop this frame"); + return QDF_STATUS_E_FAILURE; + } + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + } + + rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event)); + if (!rx_mgmt_event) { + tdls_err("Failed to allocate rx mgmt event"); + return QDF_STATUS_E_NOMEM; + } + + rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) + + mgmt_rx_params->buf_len); + if (!rx_mgmt) { + tdls_err("Failed to allocate rx mgmt frame"); + qdf_mem_free(rx_mgmt_event); + return QDF_STATUS_E_NOMEM; + } + + pdata = (uint8_t *)qdf_nbuf_data(buf); + rx_mgmt->frame_len = mgmt_rx_params->buf_len; + rx_mgmt->rx_chan = mgmt_rx_params->channel; + rx_mgmt->vdev_id = vdev_id; + rx_mgmt->frm_type = frm_type; + rx_mgmt->rx_rssi = mgmt_rx_params->rssi; + + rx_mgmt_event->rx_mgmt = rx_mgmt; + rx_mgmt_event->tdls_soc_obj = tdls_soc_obj; + qdf_mem_copy(rx_mgmt->buf, pdata, mgmt_rx_params->buf_len); + msg.type = TDLS_EVENT_RX_MGMT; + msg.bodyptr = rx_mgmt_event; + msg.callback = tdls_process_rx_frame; + status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + + qdf_nbuf_free(buf); + + return status; +} + +QDF_STATUS tgt_tdls_mgmt_frame_rx_cb( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, + qdf_nbuf_t buf, + struct mgmt_rx_event_params *mgmt_rx_params, + enum mgmt_frame_type frm_type) +{ + QDF_STATUS status; + + tdls_debug("psoc:%p, peer:%p, type:%d", psoc, peer, frm_type); + + + if (!buf) { + tdls_err("rx frame buff is null buf:%p", buf); + return QDF_STATUS_E_INVAL; + } + + if (!mgmt_rx_params || !psoc) { + tdls_err("input is NULL mgmt_rx_params:%p psoc:%p, peer:%p", + mgmt_rx_params, psoc, peer); + status = QDF_STATUS_E_INVAL; + goto release_nbuf; + } + + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID); + if (QDF_STATUS_SUCCESS != status) + goto release_nbuf; + + status = tgt_tdls_mgmt_frame_process_rx_cb(psoc, peer, buf, + mgmt_rx_params, frm_type); + + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); + + if (QDF_STATUS_SUCCESS != status) +release_nbuf: + qdf_nbuf_free(buf); + return status; +} + diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 1e4afdbfaa06..ecef61fdaeed 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -194,6 +194,12 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + soc_obj->tdls_rx_cb = req->tdls_rx_cb; + soc_obj->tdls_rx_cb_data = req->tdls_rx_cb_data; + + soc_obj->tdls_wmm_cb = req->tdls_wmm_cb; + soc_obj->tdls_wmm_cb_data = req->tdls_wmm_cb_data; + soc_obj->tdls_event_cb = req->tdls_event_cb; soc_obj->tdls_evt_cb_data = req->tdls_evt_cb_data; @@ -256,9 +262,14 @@ QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc) tdls_scan_serialization_comp_info_cb); if (QDF_STATUS_SUCCESS != status) { tdls_err("Serialize scan cmd register failed "); - status = QDF_STATUS_E_FAILURE; + return status; } + /* register callbacks with tx/rx mgmt */ + status = tdls_mgmt_rx_ops(psoc, true); + if (status != QDF_STATUS_SUCCESS) + tdls_err("Failed to register mgmt rx callback, status:%d", + status); return status; } @@ -647,4 +658,6 @@ void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, tdls_update_tx_pkt_cnt(vdev, mac_addr); wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } + From 84ddd1f69917f81394757ea69cc7cbef918e7dc6 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Sun, 26 Mar 2017 18:52:47 -0700 Subject: [PATCH 062/404] 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 ce5880e182f4cae6b2c3e4c49d56d14c680a7fe6 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 17 Apr 2017 21:53:42 -0700 Subject: [PATCH 063/404] 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 --- core/src/wlan_tdls_cmds_process.c | 2 +- core/src/wlan_tdls_cmds_process.h | 10 + core/src/wlan_tdls_ct.c | 384 ++++++++++++++++++++++ core/src/wlan_tdls_ct.h | 22 ++ core/src/wlan_tdls_main.c | 20 ++ core/src/wlan_tdls_main.h | 15 + core/src/wlan_tdls_peer.c | 2 +- core/src/wlan_tdls_peer.h | 14 + dispatcher/inc/wlan_tdls_public_structs.h | 19 +- dispatcher/inc/wlan_tdls_ucfg_api.h | 8 + dispatcher/src/wlan_tdls_ucfg_api.c | 22 ++ 11 files changed, 515 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 26594e3f37f4..35cd7f3e7df8 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -43,7 +43,7 @@ static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) * * Return: None. */ -static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) +void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) { if (soc_obj->connected_peer_count) soc_obj->connected_peer_count--; diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index ec2f40e1070d..5e2c03508475 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -365,4 +365,14 @@ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); */ int tdls_set_responder(struct tdls_set_responder_req *set_req); +/** + * tdls_decrement_peer_count() - decrement connected TDLS peer counter + * @soc_obj: TDLS soc object + * + * Used in scheduler thread context, no lock needed. + * + * Return: None. + */ +void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj); + #endif diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index cb48dd205771..3b5b554fb83b 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -25,6 +25,7 @@ #include "wlan_tdls_main.h" #include "wlan_tdls_peer.h" #include "wlan_tdls_ct.h" +#include "wlan_tdls_cmds_process.h" bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev) { @@ -936,3 +937,386 @@ void tdls_ct_handler(void *user_data) WLAN_TDLS_NB_ID); } +/** + * tdls_set_tdls_offchannel() - set tdls off-channel number + * @tdls_soc: tdls soc object + * @offchanmode: tdls off-channel number + * + * This function sets tdls off-channel number + * + * Return: 0 on success; negative errno otherwise + */ +static +int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, + int offchannel) +{ + uint32_t tdls_feature_flags; + + tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags; + + if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) && + (TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_current_mode || + TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_current_mode || + TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_current_mode)) { + if (offchannel < TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN || + offchannel > TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX) { + tdls_err("Invalid tdls off channel %u", offchannel); + return -EINVAL; + } + } else { + tdls_err("Either TDLS or TDLS Off-channel is not enabled"); + return -ENOTSUPP; + } + tdls_notice("change tdls off channel from %d to %d", + tdls_soc->tdls_off_channel, offchannel); + tdls_soc->tdls_off_channel = offchannel; + return 0; +} + +/** + * tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset + * @tdls_soc: tdls soc object + * @offchanmode: tdls off-channel offset + * + * This function sets 2nd tdls off-channel offset + * + * Return: 0 on success; negative errno otherwise + */ +static +int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, + int offchanoffset) +{ + uint32_t tdls_feature_flags; + + tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags; + + if (!TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) || + TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) { + tdls_err("Either TDLS or TDLS Off-channel is not enabled"); + return -ENOTSUPP; + } + + tdls_soc->tdls_channel_offset = 0; + + switch (offchanoffset) { + case TDLS_SEC_OFFCHAN_OFFSET_0: + tdls_soc->tdls_channel_offset = (1 << BW_20_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_40PLUS: + case TDLS_SEC_OFFCHAN_OFFSET_40MINUS: + tdls_soc->tdls_channel_offset = (1 << BW_40_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_80: + tdls_soc->tdls_channel_offset = (1 << BW_80_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_160: + tdls_soc->tdls_channel_offset = (1 << BW_160_OFFSET_BIT); + break; + default: + tdls_err("Invalid tdls secondary off channel offset %d", + offchanoffset); + return -EINVAL; + } /* end switch */ + + tdls_notice("change tdls secondary off channel offset to 0x%x", + tdls_soc->tdls_channel_offset); + return 0; +} + +/** + * tdls_set_tdls_offchannelmode() - set tdls off-channel mode + * @adapter: Pointer to the HDD adapter + * @offchanmode: tdls off-channel mode + * + * This function sets tdls off-channel mode + * + * Return: 0 on success; negative errno otherwise + */ +static +int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, + int offchanmode) +{ + struct tdls_peer *conn_peer = NULL; + struct tdls_channel_switch_params chan_switch_params; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + int ret_value = 0; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc; + uint32_t tdls_feature_flags; + + + status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); + + if (status != QDF_STATUS_SUCCESS) + return -EINVAL; + + + if (offchanmode < ENABLE_CHANSWITCH || + offchanmode > DISABLE_CHANSWITCH) { + tdls_err("Invalid tdls off channel mode %d", offchanmode); + return -EINVAL; + } + + if (tdls_is_vdev_connected(vdev)) { + tdls_err("tdls off channel req in not associated state %d", + offchanmode); + return -EPERM; + } + + tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) || + TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) { + tdls_err("Either TDLS or TDLS Off-channel is not enabled"); + return -ENOTSUPP; + } + + conn_peer = tdls_find_first_connected_peer(tdls_vdev); + if (NULL == conn_peer) { + tdls_err("No TDLS Connected Peer"); + return -EPERM; + } + + tdls_notice("TDLS Channel Switch in swmode=%d tdls_off_channel %d offchanoffset %d", + offchanmode, tdls_soc->tdls_off_channel, + tdls_soc->tdls_channel_offset); + + switch (offchanmode) { + case ENABLE_CHANSWITCH: + if (tdls_soc->tdls_off_channel && + tdls_soc->tdls_channel_offset) { + chan_switch_params.tdls_off_ch = + tdls_soc->tdls_off_channel; + chan_switch_params.tdls_off_ch_bw_offset = + tdls_soc->tdls_channel_offset; + chan_switch_params.oper_class = + tdls_find_opclass(tdls_soc->soc, + chan_switch_params.tdls_off_ch, + chan_switch_params.tdls_off_ch_bw_offset); + } else { + tdls_err("TDLS off-channel parameters are not set yet!!!"); + return -EINVAL; + + } + break; + case DISABLE_CHANSWITCH: + chan_switch_params.tdls_off_ch = 0; + chan_switch_params.tdls_off_ch_bw_offset = 0; + chan_switch_params.oper_class = 0; + break; + default: + tdls_err("Incorrect Parameters mode: %d tdls_off_channel: %d offchanoffset: %d", + offchanmode, tdls_soc->tdls_off_channel, + tdls_soc->tdls_channel_offset); + return -EINVAL; + } /* end switch */ + + chan_switch_params.vdev_id = tdls_vdev->session_id; + chan_switch_params.tdls_sw_mode = offchanmode; + chan_switch_params.is_responder = + conn_peer->is_responder; + qdf_mem_copy(&chan_switch_params.peer_mac_addr, + &conn_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + tdls_notice("Peer " QDF_MAC_ADDRESS_STR " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d", + QDF_MAC_ADDR_ARRAY(chan_switch_params.peer_mac_addr), + chan_switch_params.vdev_id, + chan_switch_params.tdls_off_ch, + chan_switch_params.tdls_off_ch_bw_offset, + chan_switch_params.tdls_sw_mode, + chan_switch_params.is_responder); + + status = tdls_set_offchan_mode(tdls_soc->soc, + &chan_switch_params); + + if (status != QDF_STATUS_SUCCESS) { + tdls_err("Failed to send channel switch request to wmi"); + return -EINVAL; + } + + tdls_soc->tdls_fw_off_chan_mode = offchanmode; + + if (ENABLE_CHANSWITCH == offchanmode) { + conn_peer = tdls_find_first_connected_peer(tdls_vdev); + if (NULL == conn_peer) { + tdls_err("No TDLS Connected Peer"); + return -EPERM; + } + conn_peer->pref_off_chan_num = + chan_switch_params.tdls_off_ch; + conn_peer->op_class_for_pref_off_chan = + chan_switch_params.oper_class; + } + + return ret_value; +} + +/** + * tdls_delete_all_tdls_peers(): send request to delete tdls peers + * @vdev: vdev object + * @tdls_soc: tdls soc object + * + * This function sends request to lim to delete tdls peers + * + * Return: QDF_STATUS + */ +static +QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, + struct tdls_soc_priv_obj *tdls_soc) +{ + struct wlan_objmgr_peer *peer; + struct tdls_del_all_tdls_peers *del_msg; + struct scheduler_msg msg; + QDF_STATUS status; + + + del_msg = qdf_mem_malloc(sizeof(*del_msg)); + if (NULL == del_msg) { + tdls_err("memory alloc failed"); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_zero(del_msg, sizeof(*del_msg)); + + peer = wlan_vdev_get_bsspeer(vdev); + if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer, + WLAN_TDLS_SB_ID)) { + return QDF_STATUS_E_FAILURE; + } + + qdf_mem_copy(del_msg->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + + del_msg->msg_type = tdls_soc->tdls_del_all_peers; + del_msg->msg_len = (uint16_t) sizeof(*del_msg); + + /* Send the request to PE. */ + qdf_mem_zero(&msg, sizeof(msg)); + + tdls_debug("sending delete all peers req to PE "); + + msg.type = del_msg->msg_type; + msg.bodyptr = del_msg; + + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); + return status; +} + +void tdls_disable_offchan_and_teardown_links( + struct wlan_objmgr_vdev *vdev) +{ + uint16_t connected_tdls_peers = 0; + uint8_t staidx; + struct tdls_peer *curr_peer = NULL; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc; + QDF_STATUS status; + + status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("tdls objects are NULL "); + return; + } + + if (TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) { + tdls_notice("TDLS mode %d is disabled OR not suspended now", + tdls_soc->tdls_current_mode); + return; + } + + connected_tdls_peers = tdls_soc->connected_peer_count; + + if (!connected_tdls_peers) { + tdls_notice("No TDLS connected peers to delete"); + return; + } + + /* TDLS is not supported in case of concurrency. + * Disable TDLS Offchannel in FW to avoid more + * than two concurrent channels and generate TDLS + * teardown indication to supplicant. + * Below function Finds the first connected peer and + * disables TDLS offchannel for that peer. + * FW enables TDLS offchannel only when there is + * one TDLS peer. When there are more than one TDLS peer, + * there will not be TDLS offchannel in FW. + * So to avoid sending multiple request to FW, for now, + * just invoke offchannel mode functions only once + */ + tdls_set_tdls_offchannel(tdls_soc, + tdls_soc->tdls_configs.tdls_pre_off_chan_num); + tdls_set_tdls_secoffchanneloffset(tdls_soc, + TDLS_SEC_OFFCHAN_OFFSET_40PLUS); + tdls_set_tdls_offchannelmode(vdev, DISABLE_CHANSWITCH); + + /* Send Msg to PE for deleting all the TDLS peers */ + tdls_delete_all_tdls_peers(vdev, tdls_soc); + + for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; + staidx++) { + if (!tdls_soc->tdls_conn_info[staidx].sta_id) + continue; + + curr_peer = tdls_find_all_peer(tdls_soc, + tdls_soc->tdls_conn_info[staidx].peer_mac.bytes); + if (!curr_peer) + continue; + + tdls_notice("indicate TDLS teardown (staId %d)", + curr_peer->sta_id); + + /* Indicate teardown to supplicant */ + tdls_indicate_teardown(tdls_vdev, + curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + + /* + * Del Sta happened already as part of tdls_delete_all_tdls_peers + * Hence clear tdls vdev data structure. + */ + tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); + + if (tdls_soc->tdls_dereg_tl_peer) + tdls_soc->tdls_dereg_tl_peer( + tdls_soc->tdls_tl_peer_data, + wlan_vdev_get_id(vdev), + curr_peer->sta_id); + + tdls_decrement_peer_count(tdls_soc); + tdls_soc->tdls_conn_info[staidx].sta_id = 0; + tdls_soc->tdls_conn_info[staidx].session_id = 255; + + qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, + sizeof(struct qdf_mac_addr)); + } +} + +void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev) +{ + struct tdls_osif_indication indication; + struct tdls_soc_priv_obj *tdls_soc; + struct wlan_objmgr_vdev *tdls_vdev_obj; + + if (!vdev) { + QDF_ASSERT(0); + return; + } + + tdls_soc = wlan_vdev_get_tdls_soc_obj(vdev); + if (!tdls_soc) + return; + + /* Get the tdls specific vdev and clear the links */ + tdls_vdev_obj = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_SB_ID); + if (tdls_vdev_obj) { + tdls_disable_offchan_and_teardown_links(tdls_vdev_obj); + wlan_objmgr_vdev_release_ref(tdls_vdev_obj, WLAN_TDLS_SB_ID); + } + + indication.vdev = vdev; + + if (tdls_soc->tdls_event_cb) + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_TEARDOWN_LINKS_DONE, + &indication); +} diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index e497daed2bac..63e306378000 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -31,6 +31,10 @@ */ #define TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE 1000 +#define TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1 +#define TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165 +#define TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT 36 + /** * tdls_is_vdev_connected() - check the vdev is connected to ap * @vdev: vdev object manager @@ -172,4 +176,22 @@ bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev); */ bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev); +/** + * tdls_teardown_connections() -teardown and delete all the tdls peers + * @vdev: vdev oobject + * + * Return: true or false + */ +void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_disable_offchan_and_teardown_links - Disable offchannel + * and teardown TDLS links + * @tdls_soc : tdls soc object + * + * Return: None + */ +void tdls_disable_offchan_and_teardown_links( + struct wlan_objmgr_vdev *vdev); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index c58d8682b38b..f98d993579c1 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -287,6 +287,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SESSION_DECREMENT: tdls_process_policy_mgr_notification(msg->bodyptr); break; + case TDLS_CMD_TEARDOWN_LINKS: + tdls_teardown_connections(msg->bodyptr); + break; default: break; } @@ -468,6 +471,20 @@ static void tdls_state_param_setting_dump(struct tdls_info *info) } +QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *param) +{ + QDF_STATUS status; + + /* wmi_unified_set_tdls_offchan_mode_cmd() will be called directly */ + status = tgt_tdls_set_offchan_mode(psoc, param); + + if (!QDF_IS_STATUS_SUCCESS(status)) + status = QDF_STATUS_E_FAILURE; + + return status; +} + /** * tdls_update_fw_tdls_state() - update tdls status info * @tdls_soc_obj: TDLS soc object @@ -745,12 +762,15 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_soc_obj->set_state_info.set_state_cnt); /* disable off channel and teardown links */ /* Go through the peer list and delete them */ + tdls_disable_offchan_and_teardown_links(tdls_vdev_obj->vdev); tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; tdls_info_to_fw->vdev_id = tdls_soc_obj->set_state_info.vdev_id; } else { tdls_info_to_fw->vdev_id = session_id; } + /* record the session id in vdev context */ + tdls_vdev_obj->session_id = session_id; tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode; tdls_info_to_fw->tdls_options = 0; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index bfbddf0dede2..f6096f2ef3e3 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -180,6 +180,7 @@ struct tdls_set_state_info { * @tdls_add_sta_req: store eWNI_SME_TDLS_ADD_STA_REQ value * @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value * @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value + * @tdls_del_all_peers:store eWNI_SME_DEL_ALL_TDLS_PEERS * @tdls_idle_peer_data: provide information about idle peer * @tdls_ct_spinlock: connection tracker spin lock */ @@ -221,6 +222,7 @@ struct tdls_soc_priv_obj { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + uint16_t tdls_del_all_peers; struct tdls_ct_idle_peer_data tdls_idle_peer_data; qdf_spinlock_t tdls_ct_spinlock; }; @@ -255,6 +257,7 @@ struct tdls_vdev_priv_obj { ct_peer_table[WLAN_TDLS_CT_TABLE_SIZE]; uint8_t valid_mac_entries; uint32_t magic; + uint8_t session_id; qdf_list_t tx_queue; }; @@ -667,4 +670,16 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc); void tdls_scan_serialization_comp_info_cb( union wlan_serialization_rules_info *comp_info); +/** + * tdls_set_offchan_mode() - update tdls status info + * @psoc: soc object + * @param: channel switch params + * + * send message to WMI to set TDLS off channel in f/w + * + * Return: QDF_STATUS. + */ +QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *param); + #endif diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index a89736fb95e0..56e5ec715ea4 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -125,7 +125,7 @@ tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr) return tdls_search_param.peer; } -static uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel, +uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel, uint8_t bw_offset) { char country[REG_ALPHA2_LEN + 1]; diff --git a/core/src/wlan_tdls_peer.h b/core/src/wlan_tdls_peer.h index 511b4d4ed010..7a510c1dac64 100644 --- a/core/src/wlan_tdls_peer.h +++ b/core/src/wlan_tdls_peer.h @@ -84,6 +84,20 @@ struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, struct tdls_peer * tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr); +/** + * tdls_find_all_peer() - find peer matching the input MACaddr in soc range + * @soc_obj: TDLS soc object + * @channel:channel number + * @bw_offset: offset to bandwidth + * + * This is in scheduler thread context, no lock required. + * + * Return: Operating class + */ +uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, + uint8_t channel, + uint8_t bw_offset); + /** * tdls_find_first_connected_peer() - find the 1st connected tdls peer from vdev * @vdev_obj: tdls vdev object diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 36e3a4676c90..3632af50a163 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -29,7 +29,6 @@ #include #include #include -#include #define WLAN_TDLS_STA_MAX_NUM 8 @@ -63,6 +62,9 @@ /** Maximum time(ms) to wait for tdls mgmt to complete **/ #define WAIT_TIME_FOR_TDLS_MGMT 11000 +/** Maximum waittime for TDLS teardown links **/ +#define WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS 10000 + #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 @@ -188,6 +190,7 @@ enum tdls_command_type { TDLS_CMD_SET_TDLS_MODE, TDLS_CMD_SESSION_INCREMENT, TDLS_CMD_SESSION_DECREMENT, + TDLS_CMD_TEARDOWN_LINKS, }; /** @@ -210,6 +213,7 @@ enum tdls_event_type { TDLS_EVENT_DISCOVERY_REQ, TDLS_EVENT_TEARDOWN_REQ, TDLS_EVENT_SETUP_REQ, + TDLS_EVENT_TEARDOWN_LINKS_DONE, }; /** @@ -547,6 +551,7 @@ struct tdls_start_params { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + uint16_t tdls_del_all_peers; tdls_rx_callback tdls_rx_cb; void *tdls_rx_cb_data; tdls_wmm_check tdls_wmm_cb; @@ -1001,4 +1006,16 @@ struct tdls_set_mode_params { enum tdls_disable_sources source; }; +/** + * struct tdls_del_all_tdls_peers - delete all tdls peers + * @msg_type: type of message + * @msg_len: length of message + * @bssid: bssid of peer device + */ +struct tdls_del_all_tdls_peers { + uint16_t msg_type; + uint16_t msg_len; + struct qdf_mac_addr bssid; +}; + #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 6c7d117b44d9..5d99669740ab 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -138,6 +138,14 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( */ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req); +/** + * ucfg_tdls_teardown_links() - teardown all TDLS links + * @vdev: vdev object manager + * + * Return: None + */ +QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev); + /** * ucfg_tdls_notify_sta_connect() - notify sta connect * @notify_info: sta notification info diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index ecef61fdaeed..4412c5878232 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -216,6 +216,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_add_sta_req = req->tdls_add_sta_req; soc_obj->tdls_del_sta_req = req->tdls_del_sta_req; soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; + soc_obj->tdls_del_all_peers = req->tdls_del_all_peers; tdls_pm_call_backs.tdls_notify_increment_session = tdls_notify_increment_session; @@ -238,6 +239,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, else soc_obj->tdls_current_mode = TDLS_SUPPORT_IMP_MODE; + soc_obj->tdls_last_mode = soc_obj->tdls_current_mode; return QDF_STATUS_SUCCESS; } @@ -538,6 +540,26 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) return status; } +QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status; + struct scheduler_msg msg = {0, }; + + if (!vdev) { + tdls_err("vdev is NULL "); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_notice("Enter "); + + msg.bodyptr = vdev; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_TEARDOWN_LINKS; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + return status; +} + QDF_STATUS ucfg_tdls_notify_sta_connect( struct tdls_sta_notify_params *notify_info) { From 0d7f2bb901fad3bdc6638c074b95ec226abdc463 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 17 Apr 2017 21:53:42 -0700 Subject: [PATCH 064/404] 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 1ac9c552b2a2c76b626c6a0511c2210c76e0743b Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 20 Apr 2017 10:33:39 -0700 Subject: [PATCH 065/404] qcacmn: Fix TDLS UMAC memory init issues scheduler message structure needs to be initialised to zero before populating it contents. Init scheduler msg structure to zero during the structure declaration. Change-Id: Ib6281b7d3b0a103be5adf65d12c20a28f48065f5 CRs-Fixed: 2034220 --- core/src/wlan_tdls_ct.c | 2 +- core/src/wlan_tdls_main.c | 5 ++--- core/src/wlan_tdls_mgmt.c | 3 +-- dispatcher/src/wlan_tdls_tgt_api.c | 2 +- dispatcher/src/wlan_tdls_ucfg_api.c | 8 ++++++++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 3b5b554fb83b..2e8b60e8b656 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1165,7 +1165,7 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, { struct wlan_objmgr_peer *peer; struct tdls_del_all_tdls_peers *del_msg; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; QDF_STATUS status; diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index f98d993579c1..5e2bdbf79a20 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -805,10 +805,8 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_state_param_setting_dump(tdls_info_to_fw); status = tdls_update_fw_tdls_state(tdls_soc_obj, tdls_info_to_fw); - if (QDF_STATUS_SUCCESS != status) { - qdf_mem_free(tdls_info_to_fw); + if (QDF_STATUS_SUCCESS != status) goto done; - } if (sta_connect_event) { tdls_soc_obj->set_state_info.set_state_cnt++; @@ -828,6 +826,7 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_mgmt_rx_ops(tdls_soc_obj->soc, false); done: + qdf_mem_free(tdls_info_to_fw); tdls_process_session_update(tdls_soc_obj->soc, TDLS_CMD_SESSION_INCREMENT); return; diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index f6e27dfd757e..ed8848e09913 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -225,8 +225,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request( struct wlan_objmgr_peer *peer; struct tdls_soc_priv_obj *tdls_soc_obj; QDF_STATUS status = QDF_STATUS_SUCCESS; - - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct tdls_send_mgmt_request *tdls_mgmt_req; if (!action_req || !action_req->vdev) diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index a55f6d134151..cd097dbf86f6 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -225,7 +225,7 @@ QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( struct tdls_rx_mgmt_frame *rx_mgmt; struct tdls_rx_mgmt_event *rx_mgmt_event; struct tdls_soc_priv_obj *tdls_soc_obj; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct wlan_objmgr_vdev *vdev; uint32_t vdev_id; uint8_t *pdata; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 4412c5878232..2dca630659d0 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -285,7 +285,15 @@ QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) tdls_err("NULL psoc"); return QDF_STATUS_E_FAILURE; } + status = tgt_tdls_unregister_ev_handler(psoc); + if (QDF_IS_STATUS_ERROR(status)) + tdls_err("Failed to unregister tdls event handler"); + + status = tdls_mgmt_rx_ops(psoc, false); + if (QDF_IS_STATUS_ERROR(status)) + tdls_err("Failed to unregister mgmt rx callback"); + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); if (!soc_obj) { From 0b3198cbc0156a36ac0bb48712dfd537686109bb Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 19 Apr 2017 18:50:51 +0800 Subject: [PATCH 066/404] qcacmn: Add runtime pm lock for P2P Add runtime pm lock for remain on channel request in P2P component. Change-Id: Ic29c5edf9e9325d1f9b65d766385327b91b0d14a CRs-Fixed: 2036085 --- core/src/wlan_p2p_main.c | 18 ++- core/src/wlan_p2p_main.h | 3 + core/src/wlan_p2p_off_chan_tx.c | 1 - core/src/wlan_p2p_roc.c | 220 ++++++++++++++++++++------------ 4 files changed, 156 insertions(+), 86 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index e77a16cc6293..3c91293707ef 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -456,6 +456,7 @@ QDF_STATUS p2p_component_deinit(void) QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) { + QDF_STATUS status; struct p2p_soc_priv_obj *p2p_soc_obj; if (!soc) { @@ -473,11 +474,25 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) qdf_list_create(&p2p_soc_obj->roc_q, MAX_QUEUE_LENGTH); qdf_list_create(&p2p_soc_obj->tx_q_roc, MAX_QUEUE_LENGTH); qdf_list_create(&p2p_soc_obj->tx_q_ack, MAX_QUEUE_LENGTH); - qdf_event_create(&p2p_soc_obj->cancel_roc_done); + + status = qdf_event_create(&p2p_soc_obj->cancel_roc_done); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("failed to create cancel roc done event"); + goto fail_event; + } + p2p_soc_obj->roc_runtime_lock = qdf_runtime_lock_init( + P2P_MODULE_NAME); p2p_debug("p2p psoc object open successful"); return QDF_STATUS_SUCCESS; + +fail_event: + qdf_list_destroy(&p2p_soc_obj->tx_q_ack); + qdf_list_destroy(&p2p_soc_obj->tx_q_roc); + qdf_list_destroy(&p2p_soc_obj->roc_q); + + return status; } QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) @@ -496,6 +511,7 @@ QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) return QDF_STATUS_E_FAILURE; } + qdf_runtime_lock_deinit(p2p_soc_obj->roc_runtime_lock); qdf_event_destroy(&p2p_soc_obj->cancel_roc_done); qdf_list_destroy(&p2p_soc_obj->tx_q_ack); qdf_list_destroy(&p2p_soc_obj->tx_q_roc); diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index c526bbe92788..c13068c805d2 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -27,6 +27,7 @@ #include #include #include +#include #define MAX_QUEUE_LENGTH 20 #define P2P_NOA_ATTR_IND 0x1090 @@ -138,6 +139,7 @@ struct p2p_noa_event { * @start_param: Start parameters, include callbacks and user * data to HDD * @cancel_roc_done: Cancel roc done event + * @roc_runtime_lock: Runtime lock for roc request */ struct p2p_soc_priv_obj { struct wlan_objmgr_psoc *soc; @@ -147,6 +149,7 @@ struct p2p_soc_priv_obj { uint16_t scan_req_id; struct p2p_start_param *start_param; qdf_event_t cancel_roc_done; + qdf_runtime_lock_t roc_runtime_lock; }; /** diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 81f7021b703e..2fe4b6ba6ae8 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -855,7 +855,6 @@ static QDF_STATUS p2p_roc_req_for_tx_action( status = p2p_process_roc_req(roc_ctx); if (status != QDF_STATUS_SUCCESS) { p2p_err("request roc for tx action frrame fail"); - qdf_mem_free(roc_ctx); return status; } diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index e04082353fa1..facf285a7e09 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -246,83 +246,6 @@ static void p2p_roc_timeout(void *pdata) p2p_execute_cancel_roc_req(roc_ctx); } -/** - * p2p_execute_roc_req() - Execute roc request - * @roc_ctx: remain on channel request - * - * This function init roc timer, start scan and register mgmt rx - * callbak. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -static QDF_STATUS p2p_execute_roc_req(struct p2p_roc_context *roc_ctx) -{ - QDF_STATUS status; - uint32_t go_num; - struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", - p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, - roc_ctx->phy_mode, roc_ctx->duration, - roc_ctx->roc_type, roc_ctx->roc_state); - - status = qdf_mc_timer_init(&roc_ctx->roc_timer, - QDF_TIMER_TYPE_SW, p2p_roc_timeout, - p2p_soc_obj); - if (status != QDF_STATUS_SUCCESS) - return status; - - roc_ctx->roc_state = ROC_STATE_REQUESTED; - go_num = policy_mgr_mode_specific_connection_count( - p2p_soc_obj->soc, PM_P2P_GO_MODE, NULL); - p2p_debug("present go number:%d", go_num); - if (go_num) - roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_PRESENT; - else - roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_ABSENT; - - status = p2p_scan_start(roc_ctx); - if (status != QDF_STATUS_SUCCESS) { - p2p_err("Failed to start scan, status:%d", status); - } - status = p2p_mgmt_rx_ops(roc_ctx->p2p_soc_obj->soc, true); - if (status != QDF_STATUS_SUCCESS) - p2p_err("Failed to register mgmt rx callback, status:%d", - status); - - return status; -} - -/** - * p2p_find_roc_ctx() - Find out roc context by cookie - * @p2p_soc_obj: p2p psoc private object - * @cookie: cookie is the key to find out roc context - * - * This function find out roc context by cookie from p2p psoc private - * object - * - * Return: Pointer to roc context - success - * NULL - failure - */ -static struct p2p_roc_context *p2p_find_roc_ctx( - struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie) -{ - struct p2p_roc_context *curr_roc_ctx; - qdf_list_node_t *tmp, *pos; - - p2p_debug("p2p soc obj:%p, cookie:%llx", p2p_soc_obj, cookie); - - list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { - curr_roc_ctx = list_entry(pos, struct p2p_roc_context, - node); - if ((uintptr_t) curr_roc_ctx == cookie) - return curr_roc_ctx; - } - - return NULL; -} - /** * p2p_send_roc_event() - Send roc event * @roc_ctx: remain on channel request @@ -366,6 +289,135 @@ static QDF_STATUS p2p_send_roc_event( return QDF_STATUS_SUCCESS; } +/** + * p2p_destroy_roc_ctx() - destroy roc ctx + * @roc_ctx: remain on channel request + * @up_layer_event: if send uplayer event + * @in_roc_queue: if roc context in roc queue + * + * This function destroy roc context. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_destroy_roc_ctx(struct p2p_roc_context *roc_ctx, + bool up_layer_event, bool in_roc_queue) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + p2p_debug("p2p_soc_obj:%p, roc_ctx:%p, up_layer_event:%d, in_roc_queue:%d", + p2p_soc_obj, roc_ctx, up_layer_event, in_roc_queue); + + if (up_layer_event) { + p2p_send_roc_event(roc_ctx, ROC_EVENT_READY_ON_CHAN); + p2p_send_roc_event(roc_ctx, ROC_EVENT_COMPLETED); + } + + if (in_roc_queue) { + status = qdf_list_remove_node(&p2p_soc_obj->roc_q, + (qdf_list_node_t *)roc_ctx); + if (QDF_STATUS_SUCCESS != status) + p2p_err("Failed to remove roc req, status %d", status); + } + + qdf_mem_free(roc_ctx); + + return status; +} + +/** + * p2p_execute_roc_req() - Execute roc request + * @roc_ctx: remain on channel request + * + * This function init roc timer, start scan and register mgmt rx + * callbak. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_execute_roc_req(struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status; + uint32_t go_num; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + /* prevent runtime suspend */ + qdf_runtime_pm_prevent_suspend(p2p_soc_obj->roc_runtime_lock); + + status = qdf_mc_timer_init(&roc_ctx->roc_timer, + QDF_TIMER_TYPE_SW, p2p_roc_timeout, + p2p_soc_obj); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("failed to init roc timer, status:%d", status); + goto fail; + } + + roc_ctx->roc_state = ROC_STATE_REQUESTED; + go_num = policy_mgr_mode_specific_connection_count( + p2p_soc_obj->soc, PM_P2P_GO_MODE, NULL); + p2p_debug("present go number:%d", go_num); + if (go_num) + roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_PRESENT; + else + roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_ABSENT; + + status = p2p_scan_start(roc_ctx); + if (status != QDF_STATUS_SUCCESS) { + qdf_mc_timer_destroy(&roc_ctx->roc_timer); + p2p_err("Failed to start scan, status:%d", status); + goto fail; + } + +fail: + if (status != QDF_STATUS_SUCCESS) { + p2p_destroy_roc_ctx(roc_ctx, true, true); + qdf_runtime_pm_allow_suspend( + p2p_soc_obj->roc_runtime_lock); + return status; + } + + status = p2p_mgmt_rx_ops(roc_ctx->p2p_soc_obj->soc, true); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to register mgmt rx callback, status:%d", + status); + + return status; +} + +/** + * p2p_find_roc_ctx() - Find out roc context by cookie + * @p2p_soc_obj: p2p psoc private object + * @cookie: cookie is the key to find out roc context + * + * This function find out roc context by cookie from p2p psoc private + * object + * + * Return: Pointer to roc context - success + * NULL - failure + */ +static struct p2p_roc_context *p2p_find_roc_ctx( + struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie) +{ + struct p2p_roc_context *curr_roc_ctx; + qdf_list_node_t *tmp, *pos; + + p2p_debug("p2p soc obj:%p, cookie:%llx", p2p_soc_obj, cookie); + + list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { + curr_roc_ctx = list_entry(pos, struct p2p_roc_context, + node); + if ((uintptr_t) curr_roc_ctx == cookie) + return curr_roc_ctx; + } + + return NULL; +} + /** * p2p_process_scan_start_evt() - Process scan start event * @roc_ctx: remain on channel request @@ -450,6 +502,9 @@ static QDF_STATUS p2p_process_scan_complete_evt( roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); + /* allow runtime suspend */ + qdf_runtime_pm_allow_suspend(p2p_soc_obj->roc_runtime_lock); + if (QDF_TIMER_STATE_RUNNING == qdf_mc_timer_get_current_state(&roc_ctx->roc_timer)) { status = qdf_mc_timer_stop(&roc_ctx->roc_timer); @@ -469,11 +524,7 @@ static QDF_STATUS p2p_process_scan_complete_evt( status = p2p_send_roc_event(roc_ctx, ROC_EVENT_COMPLETED); - status = qdf_list_remove_node(&p2p_soc_obj->roc_q, - (qdf_list_node_t *)roc_ctx); - if (QDF_STATUS_SUCCESS != status) - p2p_err("Failed to remove roc req, status %d", status); - qdf_mem_free(roc_ctx); + p2p_destroy_roc_ctx(roc_ctx, false, true); qdf_event_set(&p2p_soc_obj->cancel_roc_done); size = qdf_list_size(&p2p_soc_obj->roc_q); @@ -566,7 +617,8 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) &p2p_soc_obj->roc_q, (qdf_list_node_t *)roc_ctx); if (status == QDF_STATUS_SUCCESS) - qdf_mem_free(roc_ctx); + p2p_destroy_roc_ctx(roc_ctx, + true, false); else p2p_err("Failed to remove roc ctx from queue"); } @@ -617,7 +669,7 @@ QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx) status = qdf_list_insert_back(&p2p_soc_obj->roc_q, &roc_ctx->node); if (QDF_STATUS_SUCCESS != status) { - qdf_mem_free(roc_ctx); + p2p_destroy_roc_ctx(roc_ctx, true, false); p2p_debug("Failed to insert roc req, status %d", status); return status; } From 8becb02681403100cf888cf69b324d57187f3607 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 24 Apr 2017 16:26:50 -0700 Subject: [PATCH 067/404] qcacmn: Fix excessive logging problem in TDLS TDLS registered for optional action frames to print the information about unknown peer commands. This causes problem in the system with too many logs. Remove the optional action frames registration from the TDLS component. Change-Id: Iec2ee86ae1b3139858f6a1ff5b96477bc6dae169 CRs-Fixed: 2037911 --- core/src/wlan_tdls_mgmt.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index ed8848e09913..2bef1af535cf 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -172,28 +172,23 @@ QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg) QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, bool isregister) { - struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[3]; - + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; QDF_STATUS status; int num_of_entries; tdls_debug("psoc:%p, is register rx:%d", psoc, isregister); - frm_cb_info[0].frm_type = MGMT_PROBE_REQ; - frm_cb_info[0].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; - frm_cb_info[1].frm_type = MGMT_ACTION_TDLS_DISCRESP; - frm_cb_info[1].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; - frm_cb_info[2].frm_type = MGMT_ACTION_VENDOR_SPECIFIC; - frm_cb_info[2].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; - num_of_entries = 3; + frm_cb_info.frm_type = MGMT_ACTION_TDLS_DISCRESP; + frm_cb_info.mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; + num_of_entries = 1; if (isregister) status = wlan_mgmt_txrx_register_rx_cb(psoc, - WLAN_UMAC_COMP_TDLS, frm_cb_info, + WLAN_UMAC_COMP_TDLS, &frm_cb_info, num_of_entries); else status = wlan_mgmt_txrx_deregister_rx_cb(psoc, - WLAN_UMAC_COMP_TDLS, frm_cb_info, + WLAN_UMAC_COMP_TDLS, &frm_cb_info, num_of_entries); return status; From 152c87421e5608dbc5131f6f717062efba008511 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 24 Apr 2017 19:17:12 +0800 Subject: [PATCH 068/404] qcacmn: register vendor specific action frame after P2P started It only register vendor specific action frame when requested remain on channel. When DUT as GO and invite third P2P peer, there isn't remain on channel request and doesn't register this action frame from mgmt txrx component, then P2P component can't receive provision discover request frame and invitation failed. Change-Id: Ia04e1af97aedf91fd75047b12994011b054177fc CRs-Fixed: 2037600 --- core/src/wlan_p2p_main.c | 6 ++++++ core/src/wlan_p2p_roc.c | 33 ++++++++++++++++++++++++++------- core/src/wlan_p2p_roc.h | 13 +++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 3c91293707ef..bc613c69b657 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -564,6 +564,9 @@ QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, soc, P2P_MODULE_NAME, tgt_p2p_scan_event_cb, p2p_soc_obj); + /* register rx action frame */ + p2p_mgmt_rx_action_ops(soc, true); + p2p_debug("p2p psoc start successful, scan request id:%d", p2p_soc_obj->scan_req_id); @@ -594,6 +597,9 @@ QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc) return QDF_STATUS_E_FAILURE; } + /* unregister rx action frame */ + p2p_mgmt_rx_action_ops(soc, false); + /* clean up queue of p2p psoc private object */ p2p_cleanup_tx_queue(p2p_soc_obj); p2p_cleanup_roc_queue(p2p_soc_obj); diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index facf285a7e09..0f7dc7871100 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -49,22 +49,20 @@ static QDF_STATUS p2p_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, bool isregister) { - struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[2]; + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; QDF_STATUS status; p2p_debug("psoc:%p, is register rx:%d", psoc, isregister); - frm_cb_info[0].frm_type = MGMT_PROBE_REQ; - frm_cb_info[0].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; - frm_cb_info[1].frm_type = MGMT_ACTION_VENDOR_SPECIFIC; - frm_cb_info[1].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; + frm_cb_info.frm_type = MGMT_PROBE_REQ; + frm_cb_info.mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; if (isregister) status = wlan_mgmt_txrx_register_rx_cb(psoc, - WLAN_UMAC_COMP_P2P, frm_cb_info, 2); + WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); else status = wlan_mgmt_txrx_deregister_rx_cb(psoc, - WLAN_UMAC_COMP_P2P, frm_cb_info, 2); + WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); return status; } @@ -544,6 +542,27 @@ static QDF_STATUS p2p_process_scan_complete_evt( return status; } +QDF_STATUS p2p_mgmt_rx_action_ops(struct wlan_objmgr_psoc *psoc, + bool isregister) +{ + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; + QDF_STATUS status; + + p2p_debug("psoc:%p, is register rx:%d", psoc, isregister); + + frm_cb_info.frm_type = MGMT_ACTION_VENDOR_SPECIFIC; + frm_cb_info.mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; + + if (isregister) + status = wlan_mgmt_txrx_register_rx_cb(psoc, + WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); + else + status = wlan_mgmt_txrx_deregister_rx_cb(psoc, + WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); + + return status; +} + struct p2p_roc_context *p2p_find_current_roc_ctx( struct p2p_soc_priv_obj *p2p_soc_obj) { diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index 354d13382afb..3eb8b5114fc3 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -109,6 +109,19 @@ struct cancel_roc_context { uint64_t cookie; }; +/** + * p2p_mgmt_rx_action_ops() - register or unregister rx action callback + * @psoc: psoc object + * @isregister: register if true, unregister if false + * + * This function registers or unregisters rx action frame callback to + * mgmt txrx component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_mgmt_rx_action_ops(struct wlan_objmgr_psoc *psoc, + bool isregister); + /** * p2p_find_current_roc_ctx() - Find out roc context in progressing * @p2p_soc_obj: p2p psoc private object From fe5117036d3b07e16918169b73f2991f6603fedf Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Mon, 24 Apr 2017 15:21:59 -0700 Subject: [PATCH 069/404] qcacmn: Fix next action status in policy manager for SBS The next action function to reflect the SBS capability in its status correctly. If SBS is not supported the second connection should proceed, without waiting for a HW mode change to SBS. Change-Id: I99eee6c854c6a1605f1c5b7655773818811f19ea CRs-Fixed: 2021512 --- src/wlan_policy_mgr_action.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 84d4c67d1410..0e5f64b55b00 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -450,7 +450,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, if (!policy_mgr_is_hw_sbs_capable(psoc)) { /* No action */ policy_mgr_notice("firmware is not sbs capable"); - return QDF_STATUS_SUCCESS; + return QDF_STATUS_E_NOSUPPORT; } /* check if current mode is already SBS nothing to be * done From 590c40f63be0270a9ed5ad159cf6d33ba7cc829d Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 27 Apr 2017 11:49:06 -0700 Subject: [PATCH 070/404] qcacmn: Fix memory leak at policy manager initialization Fix memory leak in policy manager init/deinit sequence. Change-Id: I3c1728f2becb16b415f532acf657c7c29dc76122 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_init_deinit.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index dcf5d882f3b4..55957cf61333 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -324,7 +324,20 @@ QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc) QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) { - /* placeholder for now */ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (pm_ctx->hw_mode.hw_mode_list) { + qdf_mem_free(pm_ctx->hw_mode.hw_mode_list); + pm_ctx->hw_mode.hw_mode_list = NULL; + policy_mgr_info("HW list is freed"); + } + return QDF_STATUS_SUCCESS; } @@ -427,12 +440,6 @@ QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_E_FAILURE; } - if (pm_ctx->hw_mode.hw_mode_list) { - qdf_mem_free(pm_ctx->hw_mode.hw_mode_list); - pm_ctx->hw_mode.hw_mode_list = NULL; - policy_mgr_info("HW list is freed"); - } - if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy( &pm_ctx->qdf_conc_list_lock))) { policy_mgr_err("Failed to destroy qdf_conc_list_lock"); From d7655cae83ac3cf9d91fb85d9bc9342fc12adadb Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 26 Apr 2017 12:58:42 -0700 Subject: [PATCH 071/404] qcacmn: Add missing ini configurations to policy manager Add missing ini configurations to be used in policy manager. Change-Id: Id94c017f3c96ef0376028d124b11fd48ee24fe7e CRs-Fixed: 2009818 --- inc/wlan_policy_mgr_public_struct.h | 4 ++++ src/wlan_policy_mgr_core.c | 10 +++++++++- src/wlan_policy_mgr_get_set_utils.c | 14 +++++++++++--- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 4a3bf4b961df..dde1b65ddd0b 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -981,11 +981,15 @@ struct dual_mac_config { * connections * @conc_system_pref: System preference for PCL table * @enable2x2: 2x2 chain mask user config + * @mcc_to_scc_switch_mode: Control SAP channel in concurrency + * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled */ struct policy_mgr_user_cfg { uint8_t enable_mcc_adaptive_scheduler; uint8_t max_concurrent_active_sessions; uint8_t conc_system_pref; bool enable2x2; + uint32_t mcc_to_scc_switch_mode; + bool sub_20_mhz_enabled; }; #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 546bfdd4a16f..03fc3396196d 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -147,7 +147,15 @@ bool policy_mgr_is_dual_mac_disabled_in_ini( uint32_t policy_mgr_mcc_to_scc_switch_mode_in_user_cfg( struct wlan_objmgr_psoc *psoc) { - return 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return 0; + } + + return pm_ctx->user_cfg.mcc_to_scc_switch_mode; } /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 46cb04661818..380dae5a07d7 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1419,9 +1419,17 @@ bool policy_mgr_max_concurrent_connections_reached( return false; } -static bool policy_mgr_is_sub_20_mhz_enabled(void) +static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc) { - return false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + return pm_ctx->user_cfg.sub_20_mhz_enabled; } bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, @@ -1453,7 +1461,7 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, /* find the current connection state from pm_conc_connection_list*/ num_connections = policy_mgr_get_connection_count(psoc); - if (num_connections && policy_mgr_is_sub_20_mhz_enabled()) { + if (num_connections && policy_mgr_is_sub_20_mhz_enabled(psoc)) { policy_mgr_err("dont allow concurrency if Sub 20 MHz is enabled"); status = false; goto done; From c65575e5437b002564ee2acc0ec9a4fb061aa222 Mon Sep 17 00:00:00 2001 From: Ajit Pal Singh Date: Mon, 17 Apr 2017 16:49:01 +0530 Subject: [PATCH 072/404] qcacmn: Add API to check Do Not Break Stream eligibility 1) Adds new policy mgr API 'policy_mgr_is_chan_ok_for_dnbs' to check if a channel is OK for "Do Not Break Stream". It means that if Do_Not_Switch_Channel is set for AP/GO vdev, the channel passed should be either the AP/GO channel or a channel from the other band. 2) Adds a new function policy_mgr_get_mode_specific_conn_info() to get the mode specific connection count. Change-Id: I4da6f7d56d01b01761a5f3557b8acbb84226a6fd CRs-Fixed: 2037302 --- inc/wlan_policy_mgr_api.h | 14 +++++ src/wlan_policy_mgr_get_set_utils.c | 87 +++++++++++++++++++++++++++-- src/wlan_policy_mgr_i.h | 28 ++++++++++ src/wlan_policy_mgr_pcl.c | 42 ++++++++++++++ 4 files changed, 166 insertions(+), 5 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index fd618266564f..783bf78d165d 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1845,4 +1845,18 @@ void policy_mgr_update_old_hw_mode_index(struct wlan_objmgr_psoc *psoc, */ void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, uint32_t new_hw_mode_index); + +/** + * policy_mgr_is_chan_ok_for_dnbs() - Function to check if a channel + * is OK for "Do Not Break Stream" + * @psoc: PSOC object information + * @channel: Channel to check. + * @ok: Pointer to flag in which status will be stored + * This function checks if a channel is OK for + * "Do Not Break Stream" + * Return: SUCCESS or FAILURE + */ +QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, + uint8_t channel, bool *ok); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 380dae5a07d7..9c2f9054e491 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -39,6 +39,8 @@ #include "qdf_types.h" #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" +#include "wlan_objmgr_pdev_obj.h" +#include "wlan_objmgr_vdev_obj.h" /* invalid channel id. */ #define INVALID_CHANNEL_ID 0 @@ -1355,9 +1357,11 @@ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, return status; } -bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, - uint8_t *channel, uint8_t *vdev_id) +bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, + uint8_t *channel, uint8_t *vdev_id, + enum policy_mgr_con_mode mode) { + uint32_t count, index = 0; uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; bool status = false; @@ -1374,10 +1378,10 @@ bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, } count = policy_mgr_mode_specific_connection_count( - psoc, PM_SAP_MODE, list); + psoc, mode, list); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (count == 0) { - policy_mgr_err("No SAP connection"); + policy_mgr_err("No mode:[%d] connection", mode); status = false; } else if (count == 1) { *channel = pm_conc_connection_list[list[index]].chan; @@ -1393,7 +1397,8 @@ bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, *channel = pm_conc_connection_list[list[index]].chan; *vdev_id = pm_conc_connection_list[list[index]].vdev_id; - policy_mgr_notice("Multiple SAP connections, picking first one"); + policy_mgr_notice("Multiple mode:[%d] connections, picking first one", + mode); status = true; } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); @@ -1401,6 +1406,15 @@ bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, return status; } +bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, + uint8_t *channel, uint8_t *vdev_id) +{ + return policy_mgr_get_mode_specific_conn_info(psoc, + channel, + vdev_id, + PM_SAP_MODE); +} + bool policy_mgr_max_concurrent_connections_reached( struct wlan_objmgr_psoc *psoc) { @@ -2358,3 +2372,66 @@ bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc) return flag; } + +bool policy_mgr_vdev_mlme_is_dnsc_set(struct wlan_objmgr_vdev *vdev) +{ + /* TODO : Check Dont_Switch_Channel status from vdev mlme caps*/ + return false; +} + +QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, + uint8_t channel, bool *ok) +{ + uint8_t operating_channel = 0, vdev_id = 0; + struct wlan_objmgr_vdev *vdev; + + if (!channel || !ok) { + policy_mgr_err("Invalid parameter"); + return QDF_STATUS_E_INVAL; + } + + if (policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel, + &vdev_id, + PM_SAP_MODE)) + policy_mgr_debug("SAP mode active"); + else if (policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel, + &vdev_id, + PM_P2P_GO_MODE)) + policy_mgr_debug("P2P_GO_MODE mode active"); + else { + *ok = true; + return QDF_STATUS_SUCCESS; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_POLICY_MGR_ID); + if (!vdev) { + policy_mgr_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + /** + * If channel passed is same as AP/GO operating channel, then + * return true. + * If channel is different from operating channel but in same band. + * return false. + * If operating channel in different band. + * return true. + */ + /* TODO: To be enhanced for SBS */ + if (policy_mgr_vdev_mlme_is_dnsc_set(vdev)) { + if (operating_channel == channel) + *ok = true; + else if (WLAN_REG_IS_SAME_BAND_CHANNELS(operating_channel, + channel)) + *ok = false; + else + *ok = true; + } else { + *ok = true; + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); + return QDF_STATUS_SUCCESS; +} diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 8dd4e4ddb457..9a48a16fc32e 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -398,4 +398,32 @@ QDF_STATUS policy_mgr_reset_sap_mandatory_channels( */ bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, uint8_t *channel, uint8_t *vdev_id); + +/** + * policy_mgr_get_mode_specific_conn_info() - Get active mode specific + * channel and vdev id + * @psoc: PSOC object information + * @channel: Mode specific channel + * @vdev_id: Mode specific vdev id + * @mode: Connection Mode + * + * Get active mode specific channel and vdev id + * + * Return: true for success, else false + */ +bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, + uint8_t *channel, uint8_t *vdev_id, + enum policy_mgr_con_mode mode); + +/** + * policy_mgr_vdev_mlme_is_dnsc_set - Check if user has set + * "Do_Not_Switch_Channel" for this vdev + * @vdev: vdev pointer + * + * Get "Do_Not_Switch_Channel" setting for this vdev + * + * Return: true for success, else false + */ +bool policy_mgr_vdev_mlme_is_dnsc_set(struct wlan_objmgr_vdev *vdev); + #endif diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 364bced7357d..88f35b2ad34e 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -166,6 +166,41 @@ static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels( return QDF_STATUS_SUCCESS; } +static QDF_STATUS policy_mgr_modify_pcl_based_on_dnbs( + struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_list_org, + uint8_t *weight_list_org, + uint32_t *pcl_len_org) +{ + uint32_t i, pcl_len = 0; + uint8_t pcl_list[QDF_MAX_NUM_CHAN]; + uint8_t weight_list[QDF_MAX_NUM_CHAN]; + bool ok; + int ret; + + for (i = 0; i < *pcl_len_org; i++) { + ret = policy_mgr_is_chan_ok_for_dnbs(psoc, pcl_list_org[i], + &ok); + + if (QDF_IS_STATUS_ERROR(ret)) { + policy_mgr_err("Not able to check DNBS eligibility"); + return ret; + } + if (ok) { + pcl_list[pcl_len] = pcl_list_org[i]; + weight_list[pcl_len++] = weight_list_org[i]; + } + } + + qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org)); + qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org)); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); + qdf_mem_copy(weight_list_org, weight_list, pcl_len); + *pcl_len_org = pcl_len; + + return QDF_STATUS_SUCCESS; +} + uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t *vdev_id) { @@ -333,6 +368,13 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, pcl_channels[i], pcl_weight[i]); } + status = policy_mgr_modify_pcl_based_on_dnbs(psoc, pcl_channels, + pcl_weight, len); + + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get modified pcl based on DNBS"); + return status; + } return QDF_STATUS_SUCCESS; } From a598cbe5c7cfc43eeefe243f1905b019a8878e55 Mon Sep 17 00:00:00 2001 From: Ajit Pal Singh Date: Sat, 22 Apr 2017 15:40:27 +0530 Subject: [PATCH 073/404] qcacmn: Reject remain on channel if Do_Not_Switch_Channel set Remain on Channel request is rejected: 1) If an AP/GO interface is already active AND 2) Do_Not_Switch_Channel is set for the AP/GO interface AND 3) The requested channel is on the same band but different from the AP/GO channel. We allow one time procedures like GO Negotiation/Provision Discovery/Invitation if the offchannel time is <= 150msecs Change-Id: If19e9a06916891c5d3dbe6823fca72d70ead460d CRs-Fixed: 2037302 --- src/wlan_cfg80211_p2p.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 853513955ab5..3963b64fd621 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -28,12 +28,14 @@ #include #include #include +#include #include #include #include "wlan_cfg80211.h" #include "wlan_cfg80211_p2p.h" #define MAX_NO_OF_2_4_CHANNELS 14 +#define MAX_OFFCHAN_TIME_FOR_DNBS 150 /** * wlan_p2p_rx_callback() - Callback for rx mgmt frame @@ -345,6 +347,8 @@ int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, struct p2p_roc_req roc_req; struct wlan_objmgr_psoc *psoc; uint8_t vdev_id; + bool ok; + int ret; if (!vdev) { cfg80211_err("invalid vdev object"); @@ -369,6 +373,18 @@ int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, roc_req.duration = duration; roc_req.vdev_id = (uint32_t)vdev_id; + ret = policy_mgr_is_chan_ok_for_dnbs(psoc, roc_req.chan, &ok); + if (QDF_IS_STATUS_ERROR(ret)) { + cfg80211_err("policy_mgr_is_chan_ok_for_dnbs():ret:%d", + ret); + return -EINVAL; + } + + if (!ok) { + cfg80211_err("channel%d not OK for DNBS", roc_req.chan); + return -EINVAL; + } + return qdf_status_to_os_return( ucfg_p2p_roc_req(psoc, &roc_req, cookie)); } @@ -424,6 +440,28 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, return -EINVAL; } + /** + * When offchannel time is more than MAX_OFFCHAN_TIME_FOR_DNBS, + * allow offchannel only if Do_Not_Switch_Channel is not set. + */ + if (wait > MAX_OFFCHAN_TIME_FOR_DNBS) { + int ret; + bool ok; + uint32_t channel = wlan_freq_to_chan(chan->center_freq); + + ret = policy_mgr_is_chan_ok_for_dnbs(psoc, channel, &ok); + if (QDF_IS_STATUS_ERROR(ret)) { + cfg80211_err("policy_mgr_is_chan_ok_for_dnbs():ret:%d", + ret); + return -EINVAL; + } + if (!ok) { + cfg80211_err("Rejecting mgmt_tx for channel:%d as DNSC is set", + channel); + return -EINVAL; + } + } + mgmt_tx.vdev_id = (uint32_t)vdev_id; mgmt_tx.chan = (uint32_t)wlan_freq_to_chan(chan->center_freq); mgmt_tx.wait = wait; From 3abaf942a0d8248fc3ab91d45ef65eab108389c9 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Wed, 19 Apr 2017 11:49:18 +0530 Subject: [PATCH 074/404] qcacmn: P2P protocol changes to Disable/Enable NOA P2P-GO whenever goes offchannel, issues NOA. With this behavior, we have issue whenever legacy STA connects to P2P-GO since legacy STA does not understand NOA. To handle this case, changes are done in p2p protocol component and the revised behavior will be: 1. By default no change in NOA. 2. Whenever first legacy STA connects to GO, p2p protocol component disables NOA (i.e. P2P-GO will issue Self-CTS whenever it goes off-channel). 3. Whenever last legacy STA disconnects from GO, p2p protocol component enables NOA (i.e. P2P-GO will issue NOA whenever it goes off-channel). Change-Id: I113950ac3fa99ca68fcafcfe4c6095cf4b2def43 CRs-Fixed: 2035609 --- core/src/wlan_p2p_main.c | 241 +++++++++++++++++++++++++++++ core/src/wlan_p2p_main.h | 12 +- dispatcher/inc/wlan_p2p_ucfg_api.h | 25 +++ dispatcher/src/wlan_p2p_ucfg_api.c | 73 +++++++++ 4 files changed, 347 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index bc613c69b657..9084c75bf2a5 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -211,6 +211,8 @@ static QDF_STATUS p2p_vdev_obj_create_notification( } p2p_vdev_obj->vdev = vdev; + p2p_vdev_obj->noa_status = true; + p2p_vdev_obj->non_p2p_peer_count = 0; status = wlan_objmgr_vdev_component_obj_attach(vdev, WLAN_UMAC_COMP_P2P, p2p_vdev_obj, @@ -285,6 +287,127 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( return QDF_STATUS_SUCCESS; } +/** + * p2p_peer_obj_create_notification() - manages peer details per vdev + * @peer: peer object + * @arg: Pointer to private argument - NULL + * + * This function gets called from object manager when peer is being + * created. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_peer_obj_create_notification( + struct wlan_objmgr_peer *peer, void *arg) +{ + struct wlan_objmgr_vdev *vdev; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + enum tQDF_ADAPTER_MODE mode; + enum wlan_peer_type peer_type; + + if (!peer) { + p2p_err("peer context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + wlan_peer_obj_lock(peer); + vdev = wlan_peer_get_vdev(peer); + wlan_peer_obj_unlock(peer); + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_P2P); + wlan_peer_obj_lock(peer); + peer_type = wlan_peer_get_peer_type(peer); + wlan_peer_obj_unlock(peer); + if ((peer_type == WLAN_PEER_STA) && p2p_vdev_obj) { + + wlan_vdev_obj_lock(vdev); + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + if (mode == QDF_P2P_GO_MODE) { + p2p_vdev_obj->non_p2p_peer_count++; + p2p_debug("Non P2P peer count: %d", + p2p_vdev_obj->non_p2p_peer_count); + } + } + p2p_debug("p2p peer object create successful"); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_peer_obj_destroy_notification() - clears peer details per vdev + * @peer: peer object + * @arg: Pointer to private argument - NULL + * + * This function gets called from object manager when peer is being + * destroyed. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_peer_obj_destroy_notification( + struct wlan_objmgr_peer *peer, void *arg) +{ + struct wlan_objmgr_vdev *vdev; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct wlan_objmgr_psoc *psoc; + enum tQDF_ADAPTER_MODE mode; + enum wlan_peer_type peer_type; + uint8_t vdev_id; + + if (!peer) { + p2p_err("peer context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + wlan_peer_obj_lock(peer); + vdev = wlan_peer_get_vdev(peer); + wlan_peer_obj_unlock(peer); + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_P2P); + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + if (!p2p_vdev_obj || !psoc) { + p2p_err("p2p_vdev_obj:%p psoc:%p", p2p_vdev_obj, psoc); + return QDF_STATUS_E_INVAL; + } + + wlan_vdev_obj_lock(vdev); + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + + wlan_peer_obj_lock(peer); + peer_type = wlan_peer_get_peer_type(peer); + wlan_peer_obj_unlock(peer); + + if ((peer_type == WLAN_PEER_STA) && (mode == QDF_P2P_GO_MODE)) { + + p2p_vdev_obj->non_p2p_peer_count--; + + if (!p2p_vdev_obj->non_p2p_peer_count && + (p2p_vdev_obj->noa_status == false)) { + + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + + if (ucfg_p2p_set_noa(psoc, vdev_id, + false) == QDF_STATUS_SUCCESS) + p2p_vdev_obj->noa_status = true; + else + p2p_vdev_obj->noa_status = false; + + p2p_debug("Non p2p peer disconnected from GO,NOA status: %d.", + p2p_vdev_obj->noa_status); + } + p2p_debug("Non P2P peer count: %d", + p2p_vdev_obj->non_p2p_peer_count); + } + p2p_debug("p2p peer object destroy successful"); + + return QDF_STATUS_SUCCESS; +} + /** * p2p_send_noa_to_pe() - send noa information to pe * @noa_info: vdev context @@ -348,6 +471,68 @@ static QDF_STATUS p2p_send_noa_to_pe(struct p2p_noa_info *noa_info) return QDF_STATUS_SUCCESS; } +/** + * process_peer_for_noa() - disable NoA + * @vdev: vdev object + * @psoc: soc object + * @peer: peer object + * + * This function disables NoA + * + * + * Return: QDF_STATUS + */ +static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer) +{ + struct p2p_vdev_priv_obj *p2p_vdev_obj = NULL; + enum tQDF_ADAPTER_MODE mode; + enum wlan_peer_type peer_type; + bool disable_noa; + uint8_t vdev_id; + + if (!vdev || !psoc || !peer) { + p2p_err("vdev:%p psoc:%p peer:%p", vdev, psoc, peer); + return QDF_STATUS_E_INVAL; + } + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) { + p2p_err("p2p_vdev_obj:%p", p2p_vdev_obj); + return QDF_STATUS_E_INVAL; + } + wlan_vdev_obj_lock(vdev); + mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + + wlan_peer_obj_lock(peer); + peer_type = wlan_peer_get_peer_type(peer); + wlan_peer_obj_unlock(peer); + + disable_noa = ((mode == QDF_P2P_GO_MODE) + && p2p_vdev_obj->non_p2p_peer_count + && p2p_vdev_obj->noa_status); + + if (disable_noa && (peer_type == WLAN_PEER_STA)) { + + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + + if (ucfg_p2p_set_noa(psoc, vdev_id, + true) == QDF_STATUS_SUCCESS) { + p2p_vdev_obj->noa_status = false; + } else { + p2p_vdev_obj->noa_status = true; + } + p2p_debug("NoA status: %d", p2p_vdev_obj->noa_status); + } + p2p_debug("process_peer_for_noa"); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS p2p_component_init(void) { QDF_STATUS status; @@ -388,9 +573,33 @@ QDF_STATUS p2p_component_init(void) goto err_reg_vdev_delete; } + status = wlan_objmgr_register_peer_create_handler( + WLAN_UMAC_COMP_P2P, + p2p_peer_obj_create_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to register p2p peer create handler"); + goto err_reg_peer_create; + } + + status = wlan_objmgr_register_peer_destroy_handler( + WLAN_UMAC_COMP_P2P, + p2p_peer_obj_destroy_notification, + NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to register p2p peer destroy handler"); + goto err_reg_peer_destroy; + } + p2p_debug("Register p2p obj handler successful"); return QDF_STATUS_SUCCESS; +err_reg_peer_destroy: + wlan_objmgr_unregister_peer_create_handler(WLAN_UMAC_COMP_P2P, + p2p_peer_obj_create_notification, NULL); +err_reg_peer_create: + wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_P2P, + p2p_vdev_obj_destroy_notification, NULL); err_reg_vdev_delete: wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_P2P, p2p_vdev_obj_create_notification, NULL); @@ -810,3 +1019,35 @@ fail: return status; } + +void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr) +{ + QDF_STATUS status; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_peer *peer; + + if (!vdev) { + p2p_err("vdev:%p", vdev); + return; + } + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + p2p_err("psoc:%p", psoc); + return; + } + peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_P2P_ID); + if (!peer) { + p2p_debug("peer info not found"); + return; + } + status = process_peer_for_noa(vdev, psoc, peer); + wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID); + + if (status != QDF_STATUS_SUCCESS) { + p2p_err("status:%u", status); + return; + } + p2p_debug("peer is authorized"); +} diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index c13068c805d2..9aabc6a5448d 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -154,12 +154,16 @@ struct p2p_soc_priv_obj { /** * struct p2p_vdev_priv_obj - Per vdev p2p private object - * @vdev: Pointer to vdev context - * @noa_info: NoA information + * @vdev: Pointer to vdev context + * @noa_info: NoA information + * @noa_status: NoA status i.e. Enabled / Disabled (TRUE/FALSE) + * @non_p2p_peer_count: Number of legacy stations connected to this GO */ struct p2p_vdev_priv_obj { - struct wlan_objmgr_vdev *vdev; - struct p2p_noa_info *noa_info; + struct wlan_objmgr_vdev *vdev; + struct p2p_noa_info *noa_info; + bool noa_status; + uint16_t non_p2p_peer_count; }; /** diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/dispatcher/inc/wlan_p2p_ucfg_api.h index 185d9491c077..6e861307f89c 100644 --- a/dispatcher/inc/wlan_p2p_ucfg_api.h +++ b/dispatcher/inc/wlan_p2p_ucfg_api.h @@ -262,4 +262,29 @@ QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc, uint32_t vdev_id); +/** + * p2p_peer_authorized() - Process peer authorized event + * @vdev: vdev structure to which peer is associated + * @mac_addr: peer mac address + * + * This function handles disables noa whenever a legacy station + * complete 4-way handshake after association. + * + * Return: void + */ +void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr); + +/** + * ucfg_p2p_set_noa() - Disable/Enable NOA + * @soc: soc context + * @vdev_id: vdev id + * @disable_noa: TRUE - Disable NoA, FALSE - Enable NoA + * + * This function send wmi command to enable / disable NoA. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc, + uint32_t vdev_id, bool disable_noa); + #endif /* _WLAN_P2P_UCFG_API_H_ */ diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 543ef5417f8d..4278d8cb783e 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -35,6 +35,48 @@ ucfg_p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc) return &(psoc->soc_cb.tx_ops.p2p); } +/** + * is_p2p_ps_allowed() - If P2P power save is allowed or not + * @vdev: vdev object + * @id: umac component id + * + * This function returns TRUE if P2P power-save is allowed + * else returns FALSE. + * + * Return: bool + */ +static bool is_p2p_ps_allowed(struct wlan_objmgr_vdev *vdev, + enum wlan_umac_comp_id id) +{ + struct p2p_vdev_priv_obj *p2p_vdev_obj; + uint8_t is_p2pgo = 0; + + if (!vdev) { + p2p_err("vdev:%p", vdev); + return true; + } + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_P2P); + + if (wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) + is_p2pgo = 1; + + if (!p2p_vdev_obj || !is_p2pgo) { + p2p_err("p2p_vdev_obj:%p is_p2pgo:%u", + p2p_vdev_obj, is_p2pgo); + return false; + } + if (p2p_vdev_obj->non_p2p_peer_count && + p2p_vdev_obj->noa_status == false) { + p2p_debug("non_p2p_peer_count: %u, noa_status: %d", + p2p_vdev_obj->non_p2p_peer_count, + p2p_vdev_obj->noa_status); + return false; + } + + return true; +} + QDF_STATUS ucfg_p2p_init(void) { return p2p_component_init(); @@ -249,6 +291,8 @@ QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, { struct wlan_lmac_if_p2p_tx_ops *p2p_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint16_t obj_id; + struct wlan_objmgr_vdev *vdev; p2p_debug("soc:%p, vdev_id:%d, opp_ps:%d, ct_window:%d, count:%d, duration:%d, duration:%d, ps_selection:%d", soc, ps_config->vdev_id, ps_config->opp_ps, @@ -261,6 +305,20 @@ QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, return QDF_STATUS_E_INVAL; } + for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) { + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, obj_id, + WLAN_P2P_ID); + if (vdev) { + if (is_p2p_ps_allowed(vdev, + WLAN_UMAC_COMP_P2P) == false) { + p2p_debug("p2p set ps, NoA is disabled as legacy STA is connected to GO."); + return QDF_STATUS_E_BUSY; + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + } + } + p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc); if (p2p_ops->set_ps) { status = p2p_ops->set_ps(soc, ps_config); @@ -318,3 +376,18 @@ QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc, return status; } + +QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc, + uint32_t vdev_id, bool disable_noa) +{ + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_INVAL; + + p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc); + if (p2p_ops->set_noa) { + status = p2p_ops->set_noa(soc, vdev_id, disable_noa); + p2p_debug("p2p set noa, status:%d", status); + } + + return status; +} From 289076ba96d538f04809312589b10c52bb397109 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Wed, 19 Apr 2017 11:49:18 +0530 Subject: [PATCH 075/404] qcacmn: P2P protocol changes to Disable/Enable NOA P2P-GO whenever goes offchannel, issues NOA. With this behavior, we have issue whenever legacy STA connects to P2P-GO since legacy STA does not understand NOA. To handle this case, changes are done in p2p protocol component and the revised behavior will be: 1. By default no change in NOA. 2. Whenever first legacy STA connects to GO, p2p protocol component disables NOA (i.e. P2P-GO will issue Self-CTS whenever it goes off-channel). 3. Whenever last legacy STA disconnects from GO, p2p protocol component enables NOA (i.e. P2P-GO will issue NOA whenever it goes off-channel). Change-Id: I113950ac3fa99ca68fcafcfe4c6095cf4b2def43 CRs-Fixed: 2035609 --- inc/target_if_p2p.h | 13 +++++++++++++ src/target_if_p2p.c | 21 +++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/inc/target_if_p2p.h b/inc/target_if_p2p.h index 9d3c33583a53..dcb46b9519e9 100644 --- a/inc/target_if_p2p.h +++ b/inc/target_if_p2p.h @@ -121,4 +121,17 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id); +/** + * target_if_p2p_set_noa() - Disable / Enable NOA + * @psoc: soc object + * @vdev_id: vdev id + * @disable_noa: TRUE - Disable NoA, FALSE - Enable NoA + * + * Target interface API to Disable / Enable P2P NOA. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, bool disable_noa); + #endif /* _TARGET_IF_P2P_H_ */ diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index c19fea4605cb..70680ecab1be 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -326,6 +326,26 @@ QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, (uint8_t)vdev_id); } +QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, bool disable_noa) +{ + struct vdev_set_params param; + wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + target_if_debug("psoc:%p, vdev_id:%d disable_noa:%d", + psoc, vdev_id, disable_noa); + param.if_id = vdev_id; + param.param_id = WMI_VDEV_PARAM_DISABLE_NOA_P2P_GO; + param.param_value = (uint32_t)disable_noa; + + return wmi_unified_vdev_set_param_send(wmi_handle, ¶m); +} + void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops; @@ -339,6 +359,7 @@ void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) p2p_tx_ops->set_ps = target_if_p2p_set_ps; p2p_tx_ops->lo_start = target_if_p2p_lo_start; p2p_tx_ops->lo_stop = target_if_p2p_lo_stop; + p2p_tx_ops->set_noa = target_if_p2p_set_noa; p2p_tx_ops->reg_lo_ev_handler = target_if_p2p_register_lo_event_handler; p2p_tx_ops->reg_noa_ev_handler = From 31eb12c1b285b010952939801ae46bd711890b3f Mon Sep 17 00:00:00 2001 From: Vikrampal Date: Fri, 28 Apr 2017 17:44:30 +0530 Subject: [PATCH 076/404] qcacmn: Modify H/w DBS cap check and fetch NSS Modify API policy_mgr_is_hw_dbs_2x2_capable() to check H/w DBS capability and check if downgrading needed while entering DBS. Define a new API policy_mgr_get_hw_dbs_nss() to get NSS information of both MAC0 and MAC1. Change-Id: If24817017f675e45197d060cd75317aa381256de CRs-Fixed: 2037487 --- inc/wlan_policy_mgr_api.h | 14 ++++- inc/wlan_policy_mgr_public_struct.h | 10 ++++ src/wlan_policy_mgr_action.c | 30 ++++------ src/wlan_policy_mgr_get_set_utils.c | 91 ++++++++++++++++++----------- 4 files changed, 92 insertions(+), 53 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 783bf78d165d..803f0df633e9 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1485,7 +1485,7 @@ bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc); * policy_mgr_is_hw_dbs_2x2_capable() - if hardware is capable of dbs 2x2 * @psoc: PSOC object information * This function checks if hw_modes supported are always capable of - * DBS 2x2. + * DBS and there is no need for downgrading while entering DBS. * true: DBS 2x2 can always be supported * false: hw_modes support DBS 1x1 as well * @@ -1859,4 +1859,16 @@ void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, uint8_t channel, bool *ok); +/** + * policy_mgr_get_hw_dbs_nss() - Computes DBS NSS + * @psoc: PSOC object information + * @nss_dbs: NSS info of both MAC0 and MAC1 + * This function computes NSS info of both MAC0 and MAC1 + * True: DBS capable + * False: not DBS capable + * + * Return: True or False + */ +bool policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, + struct dbs_nss *nss_dbs); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index dde1b65ddd0b..156e4c6ef677 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -992,4 +992,14 @@ struct policy_mgr_user_cfg { uint32_t mcc_to_scc_switch_mode; bool sub_20_mhz_enabled; }; + +/** + * struct dbs_nss - Number of spatial streams in DBS mode + * @mac0_ss: Number of spatial streams on MAC0 + * @mac1_ss: Number of spatial streams on MAC1 + */ +struct dbs_nss { + enum hw_mode_ss_config mac0_ss; + enum hw_mode_ss_config mac1_ss; +}; #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 0e5f64b55b00..a8d34b62bbd4 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -422,6 +422,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_hw_mode_params hw_mode; + struct dbs_nss nss_dbs; if (policy_mgr_is_hw_dbs_capable(psoc) == false) { policy_mgr_err("driver isn't dbs capable, no further action needed"); @@ -469,24 +470,17 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, PM_DBS, reason, session_id); break; case PM_DBS: - if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) - status = policy_mgr_pdev_set_hw_mode(psoc, session_id, - HW_MODE_SS_2x2, - HW_MODE_80_MHZ, - HW_MODE_SS_2x2, HW_MODE_40_MHZ, - HW_MODE_DBS, - HW_MODE_AGILE_DFS_NONE, - HW_MODE_SBS_NONE, - reason); - else - status = policy_mgr_pdev_set_hw_mode(psoc, session_id, - HW_MODE_SS_1x1, - HW_MODE_80_MHZ, - HW_MODE_SS_1x1, HW_MODE_40_MHZ, - HW_MODE_DBS, - HW_MODE_AGILE_DFS_NONE, - HW_MODE_SBS_NONE, - reason); + (void)policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs); + + status = policy_mgr_pdev_set_hw_mode(psoc, session_id, + nss_dbs.mac0_ss, + HW_MODE_80_MHZ, + nss_dbs.mac1_ss, + HW_MODE_40_MHZ, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE, + reason); break; case PM_SINGLE_MAC_UPGRADE: /* diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 9c2f9054e491..9af7f9cda062 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -752,43 +752,18 @@ bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc) bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc) { - int i, param; - uint32_t dbs, tx_chain0, rx_chain0, tx_chain1, rx_chain1; - uint32_t final_min_rf_chains = 2; - uint32_t min_rf_chains, min_mac0_rf_chains, min_mac1_rf_chains; - bool is_dbs_found = false; - struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t max_rf_chains, final_min_rf_chains = HW_MODE_SS_2x2; + struct dbs_nss nss_dbs; - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid Context"); - return false; + if (policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs)) { + max_rf_chains = QDF_MAX(nss_dbs.mac0_ss, nss_dbs.mac1_ss); + final_min_rf_chains + = QDF_MIN(final_min_rf_chains, max_rf_chains); + } else { + final_min_rf_chains = HW_MODE_SS_0x0; } - for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { - param = pm_ctx->hw_mode.hw_mode_list[i]; - tx_chain0 = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param); - rx_chain0 = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param); - dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param); - tx_chain1 = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param); - rx_chain1 = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param); - - if (dbs) { - min_mac0_rf_chains = QDF_MIN(tx_chain0, rx_chain0); - min_mac1_rf_chains = QDF_MIN(tx_chain1, rx_chain1); - min_rf_chains = QDF_MIN(min_mac0_rf_chains, - min_mac1_rf_chains); - is_dbs_found = true; - } else { - continue; - } - final_min_rf_chains = QDF_MIN(final_min_rf_chains, - min_rf_chains); - } - if (false == is_dbs_found) - final_min_rf_chains = 0; - - return (final_min_rf_chains == 2) ? true : false; + return (final_min_rf_chains == HW_MODE_SS_2x2) ? true : false; } uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc) @@ -2435,3 +2410,51 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); return QDF_STATUS_SUCCESS; } + +bool policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, + struct dbs_nss *nss_dbs) +{ + int i, param; + uint32_t dbs, tx_chain0, rx_chain0, tx_chain1, rx_chain1; + uint32_t min_mac0_rf_chains, min_mac1_rf_chains; + bool is_dbs_found = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) + policy_mgr_err("Invalid Context"); + + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + param = pm_ctx->hw_mode.hw_mode_list[i]; + dbs = POLICY_MGR_HW_MODE_DBS_MODE_GET(param); + + if (dbs) { + tx_chain0 + = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param); + rx_chain0 + = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param); + + tx_chain1 + = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param); + rx_chain1 + = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param); + + min_mac0_rf_chains = QDF_MIN(tx_chain0, rx_chain0); + min_mac1_rf_chains = QDF_MIN(tx_chain1, rx_chain1); + + nss_dbs->mac0_ss + = (min_mac0_rf_chains == 2) + ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; + + nss_dbs->mac1_ss + = (min_mac1_rf_chains == 2) + ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; + + is_dbs_found = true; + } else { + continue; + } + } + + return is_dbs_found; +} From 9647e35f73c0fdf251937161fc3f503a02a8332e Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 25 Apr 2017 13:37:25 -0700 Subject: [PATCH 077/404] qcacmn: Filter PCL with NOL Filter the PCL with NOL before providing to the requester to avoid including radar channels in PCL. Change-Id: I915572f6653a6c9c98cb525c03570543cfc86e12 CRs-Fixed: 2009818 --- src/wlan_policy_mgr_pcl.c | 150 +++++++++++++++++++++++++++++++------- 1 file changed, 125 insertions(+), 25 deletions(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 88f35b2ad34e..ad0b2c9d0684 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -235,6 +235,127 @@ uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, return 0; } +static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_nol( + struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_list_org, + uint8_t *weight_list_org, + uint32_t *pcl_len_org) +{ + uint32_t i, pcl_len = 0; + uint8_t pcl_list[QDF_MAX_NUM_CHAN]; + uint8_t weight_list[QDF_MAX_NUM_CHAN]; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + for (i = 0; i < *pcl_len_org; i++) { + if (!wlan_reg_is_disable_ch(pm_ctx->pdev, pcl_list_org[i])) { + pcl_list[pcl_len] = pcl_list_org[i]; + weight_list[pcl_len++] = weight_list_org[i]; + } + } + + qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org)); + qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org)); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); + qdf_mem_copy(weight_list_org, weight_list, pcl_len); + *pcl_len_org = pcl_len; + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS policy_mgr_pcl_modification_for_sap( + struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_channels, uint8_t *pcl_weight, + uint32_t *len) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + uint32_t i; + + if (policy_mgr_is_sap_mandatory_channel_set(psoc)) { + status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel( + psoc, pcl_channels, pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get modified pcl for SAP"); + return status; + } + policy_mgr_debug("modified pcl len:%d", *len); + for (i = 0; i < *len; i++) + policy_mgr_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); + } + + status = policy_mgr_modify_sap_pcl_based_on_nol( + psoc, pcl_channels, pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get modified pcl for SAP"); + return status; + } + policy_mgr_debug("modified pcl len:%d", *len); + for (i = 0; i < *len; i++) + policy_mgr_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS policy_mgr_pcl_modification_for_p2p_go( + struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_channels, uint8_t *pcl_weight, + uint32_t *len) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t i; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("context is NULL"); + return status; + } + + status = policy_mgr_modify_pcl_based_on_enabled_channels( + pm_ctx, pcl_channels, pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get modified pcl for GO"); + return status; + } + policy_mgr_debug("modified pcl len:%d", *len); + for (i = 0; i < *len; i++) + policy_mgr_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl( + struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_channels, uint8_t *pcl_weight, + uint32_t *len, enum policy_mgr_con_mode mode) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + switch (mode) { + case PM_SAP_MODE: + status = policy_mgr_pcl_modification_for_sap( + psoc, pcl_channels, pcl_weight, len); + break; + case PM_P2P_GO_MODE: + status = policy_mgr_pcl_modification_for_p2p_go( + psoc, pcl_channels, pcl_weight, len); + break; + default: + policy_mgr_err("unexpected mode %d", mode); + break; + } + + return status; +} + QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t *pcl_channels, uint32_t *len, @@ -340,33 +461,12 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, pcl_channels[i], pcl_weight[i]); } - if ((mode == PM_SAP_MODE) && - policy_mgr_is_sap_mandatory_channel_set(psoc)) { - status = policy_mgr_modify_sap_pcl_based_on_mandatory_channel( - psoc, pcl_channels, pcl_weight, len); - if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("failed to get modified pcl for SAP"); - return status; - } - policy_mgr_debug("modified pcl len:%d", *len); - for (i = 0; i < *len; i++) - policy_mgr_debug("chan:%d weight:%d", - pcl_channels[i], pcl_weight[i]); + policy_mgr_mode_specific_modification_on_pcl( + psoc, pcl_channels, pcl_weight, len, PM_SAP_MODE); - } + policy_mgr_mode_specific_modification_on_pcl( + psoc, pcl_channels, pcl_weight, len, PM_P2P_GO_MODE); - if (mode == PM_P2P_GO_MODE) { - status = policy_mgr_modify_pcl_based_on_enabled_channels( - pm_ctx, pcl_channels, pcl_weight, len); - if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("failed to get modified pcl for GO"); - return status; - } - policy_mgr_debug("modified pcl len:%d", *len); - for (i = 0; i < *len; i++) - policy_mgr_debug("chan:%d weight:%d", - pcl_channels[i], pcl_weight[i]); - } status = policy_mgr_modify_pcl_based_on_dnbs(psoc, pcl_channels, pcl_weight, len); From 6b436516feccfb40a2e965b874ceb42abaaef749 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 6 Apr 2017 19:57:47 +0800 Subject: [PATCH 078/404] qcacmn: Add API to cleanup roc request by vdev It required to cleaup remain on channel request before changing adpter type, add this API in P2P component. Handling scan dequeue event and start failed event same as scan complete event. Change-Id: Ie5926c954f4deff75fec53ae2c8f9762b576374e CRs-Fixed: 2030079 --- core/src/wlan_p2p_roc.c | 64 +++++++++++++++++++++++++++++- core/src/wlan_p2p_roc.h | 13 ++++++ dispatcher/inc/wlan_p2p_ucfg_api.h | 10 +++++ dispatcher/src/wlan_p2p_ucfg_api.c | 32 +++++++++++++++ 4 files changed, 117 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 0f7dc7871100..cff85f4e2a38 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -663,7 +663,67 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) status = qdf_wait_single_event( &p2p_soc_obj->cancel_roc_done, P2P_WAIT_CANCEL_ROC); - p2p_err("roc cancellation done, status:%d", status); + p2p_debug("roc cancellation done, status:%d", status); + } + } + + return status; +} + +QDF_STATUS p2p_cleanup_roc_by_vdev( + struct p2p_soc_priv_obj *p2p_soc_obj, uint32_t vdev_id) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct p2p_roc_context *roc_ctx; + qdf_list_node_t *tmp, *pos; + + p2p_debug("clean up idle roc request, roc queue size:%d, vdev id:%d", + qdf_list_size(&p2p_soc_obj->roc_q), vdev_id); + list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { + roc_ctx = list_entry(pos, struct p2p_roc_context, + node); + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, + roc_ctx->vdev_id, roc_ctx->scan_id, + roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + if (roc_ctx->roc_state == ROC_STATE_IDLE && + roc_ctx->vdev_id == vdev_id) { + status = qdf_list_remove_node( + &p2p_soc_obj->roc_q, + (qdf_list_node_t *)roc_ctx); + if (status == QDF_STATUS_SUCCESS) + qdf_mem_free(roc_ctx); + else + p2p_err("Failed to remove roc ctx from queue"); + } + } + + p2p_debug("clean up started roc request, roc queue size:%d", + qdf_list_size(&p2p_soc_obj->roc_q)); + list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { + roc_ctx = list_entry(pos, struct p2p_roc_context, + node); + + p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + if (roc_ctx->roc_state != ROC_STATE_IDLE && + roc_ctx->vdev_id == vdev_id) { + if (roc_ctx->roc_state != + ROC_STATE_CANCEL_IN_PROG) + p2p_execute_cancel_roc_req(roc_ctx); + + status = qdf_wait_single_event( + &p2p_soc_obj->cancel_roc_done, + P2P_WAIT_CANCEL_ROC); + p2p_debug("RoC cancellation done, status:%d", status); } } @@ -719,7 +779,7 @@ QDF_STATUS p2p_process_cancel_roc_req( p2p_soc_obj, cancel_roc_ctx->cookie, curr_roc_ctx); if (!curr_roc_ctx) { - p2p_err("Failed to find roc req by cookie, cookie %llx", + p2p_debug("Failed to find roc req by cookie, cookie %llx", cancel_roc_ctx->cookie); return QDF_STATUS_E_INVAL; } diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index 3eb8b5114fc3..2e8d14a18be7 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -157,6 +157,19 @@ QDF_STATUS p2p_restart_roc_timer(struct p2p_roc_context *roc_ctx); QDF_STATUS p2p_cleanup_roc_queue( struct p2p_soc_priv_obj *p2p_soc_obj); +/** + * p2p_cleanup_roc_by_vdev() - Cleanup roc context by vdev id + * @p2p_soc_obj: p2p psoc private object + * @vdev_id: vdev id + * + * This function cleanup roc context by vdev id, include the roc + * context in progressing. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_cleanup_roc_by_vdev( + struct p2p_soc_priv_obj *p2p_soc_obj, uint32_t vdev_id); + /** * p2p_process_roc_req() - Process roc request * @roc_ctx: roc request context diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/dispatcher/inc/wlan_p2p_ucfg_api.h index 6e861307f89c..228da46ccb50 100644 --- a/dispatcher/inc/wlan_p2p_ucfg_api.h +++ b/dispatcher/inc/wlan_p2p_ucfg_api.h @@ -199,6 +199,16 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, uint64_t cookie); +/** + * ucfg_p2p_cleanup_roc() - Cleanup roc request by vdev + * @vdev: pointer to vdev object + * + * This function call P2P API to cleanup roc request by vdev. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev); + /** * ucfg_p2p_mgmt_tx() - Mgmt frame tx request * @soc: soc context diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 4278d8cb783e..2ab8046b0c94 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -190,6 +190,38 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, return QDF_STATUS_SUCCESS; } +QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_psoc *psoc; + struct p2p_soc_priv_obj *p2p_soc_obj; + uint32_t vdev_id; + + p2p_debug("vdev:%p", vdev); + + if (!vdev) { + p2p_err("null vdev"); + return QDF_STATUS_E_INVAL; + } + + wlan_vdev_obj_lock(vdev); + vdev_id = (uint32_t)wlan_vdev_get_id(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + p2p_err("null psoc"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("p2p soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + return p2p_cleanup_roc_by_vdev(p2p_soc_obj, vdev_id); +} + QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, struct p2p_mgmt_tx *mgmt_frm, uint64_t *cookie) { From 7c0093d955a695850ae0867c0daf3200ccf0d1a8 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Wed, 26 Apr 2017 13:26:47 -0700 Subject: [PATCH 079/404] qcacmn: Update address search flags for TDLS Add support to set address search flags in WLAN Tx Descriptor for TDLS operation Change-Id: Iafb15fb1efd84a4bef436062368401a5496e4468 CRs-Fixed: 2041759 --- core/src/wlan_tdls_cmds_process.c | 14 ++++++++++++++ core/src/wlan_tdls_ct.c | 7 +++++++ core/src/wlan_tdls_main.h | 3 +++ dispatcher/inc/wlan_tdls_public_structs.h | 13 +++++++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 5 files changed, 38 insertions(+) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 35cd7f3e7df8..80a7ef387397 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1693,6 +1693,13 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) tdls_increment_peer_count(soc_obj); feature = soc_obj->tdls_configs.tdls_feature_flags; + if (soc_obj->tdls_dp_vdev_update) + soc_obj->tdls_dp_vdev_update(&soc_obj->soc, + peer->sta_id, + soc_obj->tdls_update_dp_vdev_flags, + ((peer->link_status == + TDLS_LINK_CONNECTED) ? true : false)); + tdls_debug("TDLS buffer sta: %d, uapsd_mask %d", TDLS_IS_BUFFER_STA_ENABLED(feature), soc_obj->tdls_configs.tdls_uapsd_mask); @@ -1911,6 +1918,13 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) tdls_set_peer_link_status(peer, TDLS_LINK_TEARING, TDLS_LINK_UNSPECIFIED); + if (soc_obj->tdls_dp_vdev_update) + soc_obj->tdls_dp_vdev_update(&soc_obj->soc, + peer->sta_id, + soc_obj->tdls_update_dp_vdev_flags, + ((peer->link_status == + TDLS_LINK_CONNECTED) ? true : false)); + if (soc_obj->tdls_event_cb) { qdf_mem_copy(ind.peer_mac, macaddr, QDF_MAC_ADDR_SIZE); ind.vdev = vdev; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 2e8b60e8b656..d6e73f69746b 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -536,6 +536,13 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, TDLS_LINK_UNSPECIFIED); tdls_notice("Teardown reason %d", reason); + if (tdls_soc->tdls_dp_vdev_update) + tdls_soc->tdls_dp_vdev_update(&tdls_soc->soc, + curr_peer->sta_id, + tdls_soc->tdls_update_dp_vdev_flags, + ((curr_peer->link_status == + TDLS_LINK_CONNECTED) ? true : false)); + indication.reason = reason; indication.vdev = tdls_vdev->vdev; qdf_mem_copy(indication.peer_mac, curr_peer->peer_mac.bytes, diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index f6096f2ef3e3..b250c4d3d8b3 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -181,6 +181,7 @@ struct tdls_set_state_info { * @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value * @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value * @tdls_del_all_peers:store eWNI_SME_DEL_ALL_TDLS_PEERS + * @tdls_update_dp_vdev_flags store CDP_UPDATE_TDLS_FLAGS * @tdls_idle_peer_data: provide information about idle peer * @tdls_ct_spinlock: connection tracker spin lock */ @@ -215,6 +216,7 @@ struct tdls_soc_priv_obj { void *tdls_evt_cb_data; tdls_register_tl_peer_callback tdls_reg_tl_peer; tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; + tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; void *tdls_tl_peer_data; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; @@ -223,6 +225,7 @@ struct tdls_soc_priv_obj { uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; uint16_t tdls_del_all_peers; + uint32_t tdls_update_dp_vdev_flags; struct tdls_ct_idle_peer_data tdls_idle_peer_data; qdf_spinlock_t tdls_ct_spinlock; }; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 3632af50a163..974fca313b81 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -530,6 +530,14 @@ typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata, typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, uint32_t vdev_id, uint8_t sta_id); + +/* This callback is used to update datapath vdev flags */ +typedef QDF_STATUS +(*tdls_dp_vdev_update_flags_callback)(void *cbk_data, + uint8_t sta_id, + uint32_t vdev_param, + bool is_link_up); + /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -537,12 +545,15 @@ typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, * @tdls_add_sta_req: pass eWNI_SME_TDLS_ADD_STA_REQ value * @tdls_del_sta_req: pass eWNI_SME_TDLS_DEL_STA_REQ value * @tdls_update_peer_state: pass WMA_UPDATE_TDLS_PEER_STATE value + * @tdls_del_all_peers: pass eWNI_SME_DEL_ALL_TDLS_PEERS + * @tdls_update_dp_vdev_flags: pass CDP_UPDATE_TDLS_FLAGS * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event data * @ack_cnf_cb: tdls tx ack callback to indicate the tx status * @tx_ack_cnf_cb_data: tdls tx ack user data * @tdls_reg_tl_peer: tdls register tdls peer * @tdls_dereg_tl_peer: tdls deregister tdls peer + * @tdls_dp_vdev_update: update vdev flags in datapath * @tdls_tl_peer_data: userdata for register/deregister TDLS peer */ struct tdls_start_params { @@ -552,6 +563,7 @@ struct tdls_start_params { uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; uint16_t tdls_del_all_peers; + uint32_t tdls_update_dp_vdev_flags; tdls_rx_callback tdls_rx_cb; void *tdls_rx_cb_data; tdls_wmm_check tdls_wmm_cb; @@ -562,6 +574,7 @@ struct tdls_start_params { void *tx_ack_cnf_cb_data; tdls_register_tl_peer_callback tdls_reg_tl_peer; tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; + tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; void *tdls_tl_peer_data; }; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 2dca630659d0..427c183ae420 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -217,6 +217,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_del_sta_req = req->tdls_del_sta_req; soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; soc_obj->tdls_del_all_peers = req->tdls_del_all_peers; + soc_obj->tdls_update_dp_vdev_flags = req->tdls_update_dp_vdev_flags; tdls_pm_call_backs.tdls_notify_increment_session = tdls_notify_increment_session; From 3ab43844f0afae0b8400eecced7cb15ccd4051fb Mon Sep 17 00:00:00 2001 From: Nitesh Shah Date: Wed, 26 Apr 2017 20:02:34 +0530 Subject: [PATCH 080/404] qcacmn: Get channel properly from conc_connection_list table The channel information is obtained from the conc_connetion_list table using the index equal to the session_id. But the session in conc_connection_list table is not kept in the increasing order of session_id. Thus, the wrong channel information can be obtained. Thus, the fix is to obtain the channel information from the conc_connection_list table corresponding to the index whose vdev_id matches the session_id. Change-Id: If289ea7c0567b892dba495b878540f9cb5df5668 CRs-Fixed: 2039474 --- inc/wlan_policy_mgr_api.h | 13 ++++++++ src/wlan_policy_mgr_get_set_utils.c | 46 ++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 4 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 803f0df633e9..53cf435021fb 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1180,6 +1180,19 @@ bool policy_mgr_is_any_mode_active_on_band_along_with_session( struct wlan_objmgr_psoc *psoc, uint8_t session_id, enum policy_mgr_band band); +/** + * policy_mgr_get_chan_by_session_id() - Get channel for a given session ID + * @psoc: PSOC object information + * @session_id: Session ID + * @chan: Pointer to the channel + * + * Gets the channel for a given session ID + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint8_t *chan); + /** * policy_mgr_get_mac_id_by_session_id() - Get MAC ID for a given session ID * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 9af7f9cda062..a9885f68a7cc 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2219,6 +2219,32 @@ send_status: return status; } +QDF_STATUS policy_mgr_get_chan_by_session_id(struct wlan_objmgr_psoc *psoc, + uint8_t session_id, uint8_t *chan) +{ + uint32_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + if ((pm_conc_connection_list[i].vdev_id == session_id) && + (pm_conc_connection_list[i].in_use)) { + *chan = pm_conc_connection_list[i].chan; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return QDF_STATUS_SUCCESS; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return QDF_STATUS_E_FAILURE; +} + QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t *mac_id) { @@ -2250,7 +2276,8 @@ QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, uint8_t *mcc_session_id) { uint32_t i; - uint8_t chan = pm_conc_connection_list[session_id].chan; + QDF_STATUS status; + uint8_t chan; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); @@ -2259,6 +2286,13 @@ QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + status = policy_mgr_get_chan_by_session_id(psoc, session_id, &chan); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Failed to get channel for session id:%d", + session_id); + return QDF_STATUS_E_FAILURE; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { if (pm_conc_connection_list[i].mac != mac_id) @@ -2305,9 +2339,13 @@ uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, return INVALID_CHANNEL_ID; } - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - chan = pm_conc_connection_list[mcc_session_id].chan; - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + status = policy_mgr_get_chan_by_session_id(psoc, mcc_session_id, + &chan); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Failed to get channel for MCC session ID:%d", + mcc_session_id); + return INVALID_CHANNEL_ID; + } return chan; } From 6fb01f70f4e91b3efeb9cfc57d1e9f5bb4ed75da Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 5 May 2017 13:01:51 -0700 Subject: [PATCH 081/404] qcacmn: Move the lock initialization to module open for policy manager Move the lock initialization to module open from module enable for policy manager. Change-Id: I44716537dcb3f559c1c27401bb579239c98a9f02 CRs-Fixed: 2009818 --- inc/wlan_policy_mgr_public_struct.h | 2 +- src/wlan_policy_mgr_init_deinit.c | 37 +++++++++++++++++------------ 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 156e4c6ef677..f0c73e983817 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -35,7 +35,7 @@ */ /* Include files */ -#include "wmi_unified.h" +#include #define POLICY_MGR_MAX_CHANNEL_LIST 128 diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 55957cf61333..43f325412fdd 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -318,7 +318,21 @@ QDF_STATUS policy_mgr_deinit(void) QDF_STATUS policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc) { - /* placeholder for now */ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create( + &pm_ctx->qdf_conc_list_lock))) { + policy_mgr_err("Failed to init qdf_conc_list_lock"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + return QDF_STATUS_SUCCESS; } @@ -332,6 +346,13 @@ QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_E_FAILURE; } + if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy( + &pm_ctx->qdf_conc_list_lock))) { + policy_mgr_err("Failed to destroy qdf_conc_list_lock"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + if (pm_ctx->hw_mode.hw_mode_list) { qdf_mem_free(pm_ctx->hw_mode.hw_mode_list); pm_ctx->hw_mode.hw_mode_list = NULL; @@ -374,13 +395,6 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) return status; } - if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create( - &pm_ctx->qdf_conc_list_lock))) { - policy_mgr_err("Failed to init qdf_conc_list_lock"); - QDF_ASSERT(0); - return status; - } - pm_ctx->do_hw_mode_change = false; pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; /* reset sap mandatory channels */ @@ -440,13 +454,6 @@ QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_E_FAILURE; } - if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy( - &pm_ctx->qdf_conc_list_lock))) { - policy_mgr_err("Failed to destroy qdf_conc_list_lock"); - status = QDF_STATUS_E_FAILURE; - QDF_ASSERT(0); - } - /* destroy connection_update_done_evt */ if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy (&pm_ctx->connection_update_done_evt))) { From 5125d0f5184878402422e4e03dddd72992e9946b Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 15 May 2017 20:28:05 -0700 Subject: [PATCH 082/404] qcacmn: Fix TDLS set state cmd sequence for roaming Firmware expects TDLS set state cmd before vdev stop, but the cmd is going out of sequence during roaming and induce crash in the system. Send the TDLS set state cmd with correct sequence. Change-Id: Ie106b8a8cebaa7f107c9eff67dda924b231162da CRs-Fixed: 2048036 --- inc/wlan_policy_mgr_api.h | 13 +++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 30 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 53cf435021fb..9853383b3f54 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1331,6 +1331,19 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( */ void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_mode_specific_vdev_id() - provides the + * vdev id of the pecific mode + * @psoc: PSOC object information + * @mode: type of connection + * + * This function provides vdev id for the given mode + * + * Return: vdev id + */ +uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode); + /** * policy_mgr_mode_specific_connection_count() - provides the * count of connections of specific mode diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index a9885f68a7cc..873e1d2eb8b1 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -788,6 +788,36 @@ uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc) return count; } +uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode) +{ + uint32_t conn_index = 0; + uint32_t vdev_id = WLAN_INVALID_VDEV_ID; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return vdev_id; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + /* + * Note: This gives you the first vdev id of the mode type in a + * sta+sta or sap+sap or p2p + p2p case + */ + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].mode == mode) && + pm_conc_connection_list[conn_index].in_use) { + vdev_id = pm_conc_connection_list[conn_index].vdev_id; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return vdev_id; +} + uint32_t policy_mgr_mode_specific_connection_count( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, From 952df1941822642b6a5b31722b154cc9c416750e Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 15 May 2017 20:28:05 -0700 Subject: [PATCH 083/404] qcacmn: Fix TDLS set state cmd sequence for roaming Firmware expects TDLS set state cmd before vdev stop, but the cmd is going out of sequence during roaming and induce crash in the system. Send the TDLS set state cmd with correct sequence. Change-Id: Ie106b8a8cebaa7f107c9eff67dda924b231162da CRs-Fixed: 2048036 --- core/src/wlan_tdls_main.c | 106 +++++++++++++++++++--------- core/src/wlan_tdls_main.h | 14 ++++ dispatcher/inc/wlan_tdls_tgt_api.h | 12 ++++ dispatcher/src/wlan_tdls_tgt_api.c | 21 ++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 5 files changed, 119 insertions(+), 35 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 5e2bdbf79a20..437b51f5fc8d 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -623,20 +623,25 @@ tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, wlan_objmgr_ref_dbgid dbg_id) { + uint32_t vdev_id; + if (policy_mgr_get_connection_count(psoc) > 1) return NULL; - if (policy_mgr_mode_specific_connection_count(psoc, - PM_STA_MODE, - NULL) == 1) - return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_STA_MODE, - dbg_id); - if (policy_mgr_mode_specific_connection_count(psoc, - PM_P2P_CLIENT_MODE, - NULL) == 1) - return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_P2P_CLIENT_MODE, - dbg_id); + + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE); + + if (WLAN_INVALID_VDEV_ID != vdev_id) + return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + dbg_id); + + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_P2P_CLIENT_MODE); + + if (WLAN_INVALID_VDEV_ID != vdev_id) + return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + dbg_id); + return NULL; } @@ -705,10 +710,9 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, uint32_t tdls_feature_flags; QDF_STATUS status; - - /* If TDLS support is disabled then no need to update target */ - if (tdls_soc_obj->tdls_current_mode <= TDLS_SUPPORT_SUSPENDED) { - tdls_err("TDLS not enabled or suspended"); + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_ENABLED(tdls_feature_flags)) { + tdls_debug("TDLS mode is not enabled"); return; } @@ -717,23 +721,28 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, return; } - tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; - /* If AP or caller indicated TDLS Prohibited then disable tdls mode */ - if (tdls_prohibited) { - tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; - } else { - tdls_debug("TDLS feature flags from ini %d ", + if (sta_connect_event) { + if (tdls_prohibited) { + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_DISABLED; + } else { + tdls_debug("TDLS feature flags from ini %d ", tdls_feature_flags); - if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_EXP_TRIG_ONLY; - else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags)) - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_EXT_CONTROL; - else - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_IMP_MODE; + if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXP_TRIG_ONLY; + else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXT_CONTROL; + else + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_IMP_MODE; + } + } else { + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_DISABLED; } tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info)); @@ -827,8 +836,6 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, done: qdf_mem_free(tdls_info_to_fw); - tdls_process_session_update(tdls_soc_obj->soc, - TDLS_CMD_SESSION_INCREMENT); return; } @@ -846,6 +853,11 @@ tdls_process_sta_connect(struct tdls_sta_notify_params *notify) tdls_debug("Check and update TDLS state"); + if (policy_mgr_get_connection_count(tdls_soc_obj->soc) > 1) { + tdls_debug("Concurrent sessions exist, TDLS can't be enabled"); + return QDF_STATUS_SUCCESS; + } + /* Association event */ if (!tdls_soc_obj->tdls_disable_in_progress) { tdls_send_update_to_fw(tdls_vdev_obj, @@ -872,8 +884,10 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) return QDF_STATUS_E_INVAL; if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) + WLAN_TDLS_NB_ID)) { + qdf_mem_free(notify); return QDF_STATUS_E_INVAL; + } status = tdls_process_sta_connect(notify); @@ -956,8 +970,10 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) return QDF_STATUS_E_INVAL; if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) + WLAN_TDLS_NB_ID)) { + qdf_mem_free(notify); return QDF_STATUS_E_INVAL; + } status = tdls_process_sta_disconnect(notify); @@ -968,6 +984,26 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) return status; } +void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, + uint32_t session_id) +{ + struct tdls_sta_notify_params *notify; + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) { + tdls_err("memory allocation failed !!!"); + return; + } + + notify->lfr_roam = true; + notify->tdls_chan_swit_prohibited = false; + notify->tdls_prohibited = false; + notify->session_id = session_id; + notify->vdev = vdev; + + tdls_notify_sta_disconnect(notify); +} + /** * tdls_set_mode_in_vdev() - set TDLS mode * @tdls_vdev: tdls vdev object diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index b250c4d3d8b3..a518ceaa7aad 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -583,6 +583,20 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); +/** + * tdls_peers_deleted_notification() - peer delete notification + * @vdev: vdev object + * @session_id: session id + * + * Legacy lim layer will delete tdls peers for roaming and heart beat failures + * and notify the component about the delete event to update the tdls. + * state. + * + * Return: None + */ +void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, + uint32_t session_id); + /** * tdls_notify_decrement_session() - Notify the session decrement * @psoc: psoc object manager diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h index 4357241a4eee..4b1e99c4a302 100644 --- a/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -146,4 +146,16 @@ QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, struct mgmt_rx_event_params *mgmt_rx_params, enum mgmt_frame_type frm_type); +/** + * tgt_tdls_peers_deleted_notification()- notification from legacy lim + * @psoc: soc object + * @session_id: session id + * + * This function called from legacy lim to notify tdls peer deletion + * + * Return: None + */ +void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint32_t session_id); + #endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index cd097dbf86f6..c292ac1fea0c 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -334,3 +334,24 @@ release_nbuf: return status; } +void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint32_t session_id) +{ + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + session_id, + WLAN_TDLS_SB_ID); + + if (!vdev) { + tdls_err("vdev not exist for the session id %d", + session_id); + return; + } + + tdls_peers_deleted_notification(vdev, session_id); + + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_SB_ID); +} + diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 427c183ae420..9bb85352bcea 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -623,6 +623,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( notify->tdls_chan_swit_prohibited = false; notify->tdls_prohibited = false; notify->vdev = notify_info->vdev; + notify->lfr_roam = notify_info->lfr_roam; msg.bodyptr = notify; msg.callback = tdls_process_cmd; From 7e4d4c2699aec786c1bb1b301405adab5da3922c Mon Sep 17 00:00:00 2001 From: Vikrampal Date: Wed, 17 May 2017 09:36:46 +0530 Subject: [PATCH 084/404] qcacmn: Handle multiple H/w DBS modes Host handling enhanced in case of F/w advertising multiple DBS H/w modes Change-Id: I90dfd9360df60be126dbfa8add30d38aeb6f7bf1 CRs-Fixed: 2048301 --- inc/wlan_policy_mgr_api.h | 8 +++--- src/wlan_policy_mgr_get_set_utils.c | 41 ++++++++++++++--------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 9853383b3f54..c96d0e9abfcd 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1890,11 +1890,9 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, * @psoc: PSOC object information * @nss_dbs: NSS info of both MAC0 and MAC1 * This function computes NSS info of both MAC0 and MAC1 - * True: DBS capable - * False: not DBS capable * - * Return: True or False + * Return: uint32_t value signifies supported RF chains */ -bool policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, - struct dbs_nss *nss_dbs); +uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, + struct dbs_nss *nss_dbs); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 873e1d2eb8b1..4420e63a5350 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -752,18 +752,10 @@ bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc) bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc) { - uint32_t max_rf_chains, final_min_rf_chains = HW_MODE_SS_2x2; struct dbs_nss nss_dbs; - if (policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs)) { - max_rf_chains = QDF_MAX(nss_dbs.mac0_ss, nss_dbs.mac1_ss); - final_min_rf_chains - = QDF_MIN(final_min_rf_chains, max_rf_chains); - } else { - final_min_rf_chains = HW_MODE_SS_0x0; - } - - return (final_min_rf_chains == HW_MODE_SS_2x2) ? true : false; + return ((policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs)) >= HW_MODE_SS_2x2) + ? true : false; } uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc) @@ -2479,13 +2471,13 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -bool policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, - struct dbs_nss *nss_dbs) +uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, + struct dbs_nss *nss_dbs) { int i, param; uint32_t dbs, tx_chain0, rx_chain0, tx_chain1, rx_chain1; uint32_t min_mac0_rf_chains, min_mac1_rf_chains; - bool is_dbs_found = false; + uint32_t max_rf_chains, final_max_rf_chains = HW_MODE_SS_0x0; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); @@ -2510,19 +2502,26 @@ bool policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, min_mac0_rf_chains = QDF_MIN(tx_chain0, rx_chain0); min_mac1_rf_chains = QDF_MIN(tx_chain1, rx_chain1); - nss_dbs->mac0_ss - = (min_mac0_rf_chains == 2) - ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; + max_rf_chains + = QDF_MAX(min_mac0_rf_chains, min_mac1_rf_chains); - nss_dbs->mac1_ss - = (min_mac1_rf_chains == 2) - ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; + if (final_max_rf_chains < max_rf_chains) { + final_max_rf_chains + = (max_rf_chains == 2) + ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; - is_dbs_found = true; + nss_dbs->mac0_ss + = (min_mac0_rf_chains == 2) + ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; + + nss_dbs->mac1_ss + = (min_mac1_rf_chains == 2) + ? HW_MODE_SS_2x2 : HW_MODE_SS_1x1; + } } else { continue; } } - return is_dbs_found; + return final_max_rf_chains; } From 6bc3f9898359ca7a2337fda7499d02e1a911e0f6 Mon Sep 17 00:00:00 2001 From: Nitesh Shah Date: Tue, 16 May 2017 12:55:48 +0530 Subject: [PATCH 085/404] qcacmn: Avoid race condition while modifying connection list In case of STA-AP case, new thread is created to call the func policy_mgr_check_sta_ap_concurrent_ch_intf() that calls policy_mgr_get_pcl_for_existing_conn() that modifies pm_conc_connection_list table. The mc_thread calls policy_mgr_get_valid_chan_weights() that also modifies pm_conc_connection_list table. But the race condition is created that mess up the pm_conc_connection_list table. This race condition also leads to the scenario where the STA connection to the AP is not updated properly . This shall lead to the improper PCL update for a STA+SAP concurrency and thus the channel switch fails. The fix is to protect the whole sequence of the function policy_mgr_check_sta_ap_concurrent_ch_intf() with mutex to avoid race condition. Change-Id: Ibb6d804afa70ef45d99e7ec9fc7fecc4993c7621 CRs-Fixed: 2047765 --- src/wlan_policy_mgr_action.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index a8d34b62bbd4..1695fc4bff80 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -668,9 +668,11 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) policy_mgr_err("SAP restart get channel callback in NULL"); return; } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); status = pm_ctx->hdd_cbacks. wlan_hdd_get_channel_for_sap_restart(psoc, vdev_id, &channel, &sec_ch, restart_sap); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed to switch SAP channel"); return; From af44d14a13cb4d33e80eab98c1b87e79e66d0a60 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 27 Apr 2017 19:50:56 +0800 Subject: [PATCH 086/404] qcacmn: support presence request Support presence request frame in P2P component. Change-Id: I21c1e63742396f328da1b2c7b2446abc4c35ef52 CRs-Fixed: 2039628 --- core/src/wlan_p2p_off_chan_tx.c | 9 +++++++++ core/src/wlan_p2p_off_chan_tx.h | 2 ++ core/src/wlan_p2p_roc.c | 12 +++++++----- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 2fe4b6ba6ae8..3831efb029ab 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -535,6 +535,8 @@ static char *p2p_get_frame_type_str(struct p2p_frame_info *frame_info) return "Invalid P2P command"; } + if (frame_info->action_type == P2P_ACTION_PRESENCE_REQ) + return "P2P action presence request"; if (frame_info->action_type == P2P_ACTION_PRESENCE_RSP) return "P2P action presence response"; @@ -651,6 +653,9 @@ static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length, buf = data_buf + P2P_ACTION_FRAME_TYPE_OFFSET; action_type = buf[0]; + if (action_type == P2P_ACTION_PRESENCE_REQ) + frame_info->action_type = + P2P_ACTION_PRESENCE_REQ; if (action_type == P2P_ACTION_PRESENCE_RSP) frame_info->action_type = P2P_ACTION_PRESENCE_RSP; @@ -1631,6 +1636,10 @@ QDF_STATUS p2p_process_rx_mgmt( } } + if (rx_mgmt->frm_type == MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC) + p2p_get_frame_info(rx_mgmt->buf, rx_mgmt->frame_len, + &frame_info); + start_param = p2p_soc_obj->start_param; if (start_param->rx_cb) start_param->rx_cb(start_param->rx_cb_data, rx_mgmt); diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index eb63fc881d46..8b255e71f699 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -121,10 +121,12 @@ enum p2p_public_action_type { /** * enum p2p_action_type - p2p action frame type + * @P2P_ACTION_PRESENCE_REQ: presence request frame * @P2P_ACTION_PRESENCE_RSP: presence response frame * @P2P_ACTION_NOT_SUPPORT: not support action frame type */ enum p2p_action_type { + P2P_ACTION_PRESENCE_REQ = 1, P2P_ACTION_PRESENCE_RSP = 2, P2P_ACTION_NOT_SUPPORT, }; diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index cff85f4e2a38..e83914d1c300 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -545,20 +545,22 @@ static QDF_STATUS p2p_process_scan_complete_evt( QDF_STATUS p2p_mgmt_rx_action_ops(struct wlan_objmgr_psoc *psoc, bool isregister) { - struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[2]; QDF_STATUS status; p2p_debug("psoc:%p, is register rx:%d", psoc, isregister); - frm_cb_info.frm_type = MGMT_ACTION_VENDOR_SPECIFIC; - frm_cb_info.mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; + frm_cb_info[0].frm_type = MGMT_ACTION_VENDOR_SPECIFIC; + frm_cb_info[0].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; + frm_cb_info[1].frm_type = MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC; + frm_cb_info[1].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; if (isregister) status = wlan_mgmt_txrx_register_rx_cb(psoc, - WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); + WLAN_UMAC_COMP_P2P, frm_cb_info, 2); else status = wlan_mgmt_txrx_deregister_rx_cb(psoc, - WLAN_UMAC_COMP_P2P, &frm_cb_info, 1); + WLAN_UMAC_COMP_P2P, frm_cb_info, 2); return status; } From c0af3e87c68ad46df62a6d0c66f6d2ea3dbd2379 Mon Sep 17 00:00:00 2001 From: Ajit Pal Singh Date: Wed, 24 May 2017 11:58:09 +0530 Subject: [PATCH 087/404] qcacmn: Add vdev-mlme caps MASK for restrict_offchannel Adds new vdev-mlme caps mask WLAN_VDEV_C_RESTRICT_OFFCHAN for tracking restrict offchannel setting. When this bit is set any operations which can cause the AP/GO to leave the operating channel are avoided. Also reads vdev-mlme caps:WLAN_VDEV_C_RESTRICT_OFFCHAN in function policy_mgr_is_dnsc_set() to determine if Do_Not_Switch_Channel is enabled. Moves declaration of policy_mgr_is_dnsc_set() to wlan_policy_mgr_api.h so that it can be used outside of policy manager. Change-Id: I53013af5f4c72917f862630e63333951ec75ce8c CRs-Fixed: 2050999 --- inc/wlan_policy_mgr_api.h | 11 +++++++++++ src/wlan_policy_mgr_get_set_utils.c | 21 +++++++++++++++++---- src/wlan_policy_mgr_i.h | 12 ------------ 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index c96d0e9abfcd..40cce054c0e1 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1895,4 +1895,15 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, */ uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, struct dbs_nss *nss_dbs); + +/** + * policy_mgr_is_dnsc_set - Check if user has set + * "Do_Not_Switch_Channel" for the vdev passed + * @vdev: vdev pointer + * + * Get "Do_Not_Switch_Channel" setting for the vdev passed. + * + * Return: true for success, else false + */ +bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 4420e63a5350..9d16bdd63c25 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2408,10 +2408,23 @@ bool policy_mgr_is_hw_mode_change_after_vdev_up(struct wlan_objmgr_psoc *psoc) return flag; } -bool policy_mgr_vdev_mlme_is_dnsc_set(struct wlan_objmgr_vdev *vdev) +bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev) { - /* TODO : Check Dont_Switch_Channel status from vdev mlme caps*/ - return false; + bool roffchan; + + if (!vdev) { + policy_mgr_err("Invalid parameter"); + return false; + } + + wlan_vdev_obj_lock(vdev); + roffchan = wlan_vdev_mlme_cap_get(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN); + wlan_vdev_obj_unlock(vdev); + + policy_mgr_debug("Restrict offchannel:%s", + roffchan ? "set" : "clear"); + + return roffchan; } QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, @@ -2456,7 +2469,7 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, * return true. */ /* TODO: To be enhanced for SBS */ - if (policy_mgr_vdev_mlme_is_dnsc_set(vdev)) { + if (policy_mgr_is_dnsc_set(vdev)) { if (operating_channel == channel) *ok = true; else if (WLAN_REG_IS_SAME_BAND_CHANNELS(operating_channel, diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 9a48a16fc32e..5100017bda57 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -414,16 +414,4 @@ bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, uint8_t *channel, uint8_t *vdev_id, enum policy_mgr_con_mode mode); - -/** - * policy_mgr_vdev_mlme_is_dnsc_set - Check if user has set - * "Do_Not_Switch_Channel" for this vdev - * @vdev: vdev pointer - * - * Get "Do_Not_Switch_Channel" setting for this vdev - * - * Return: true for success, else false - */ -bool policy_mgr_vdev_mlme_is_dnsc_set(struct wlan_objmgr_vdev *vdev); - #endif From 084b544a68a9acede48b8e8b9dd4ac3ae415d544 Mon Sep 17 00:00:00 2001 From: Vivek Date: Sun, 4 Jun 2017 23:12:00 +0530 Subject: [PATCH 088/404] qcacmn: Add target information details to target_iflayer Add a new target_psoc_info structure in the target if layer with the following members wmi_handle target_type target_version target_revision Also update the psoc data member tgt_if_handle to point to target_psoc_info instead of pointing to WMI handle directly. Updated all calls to psoc_get_tgt_if_handle to target_if_get_wmi_handle which inturn calls psoc_get_tgt_if_handle and getting the tgt_if_handle returns the WMI handle CRs-Fixed: 2048277 Change-Id: Icb02d5f3c09f7f9bb7eff4d814ef3ce90ddb84bd --- src/target_if_p2p.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index 70680ecab1be..a101d127835e 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -161,7 +161,7 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); target_if_debug("psoc:%p, arg:%p", psoc, arg); @@ -184,7 +184,7 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); target_if_debug("psoc:%p, arg:%p", psoc, arg); @@ -207,7 +207,7 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); target_if_debug("psoc:%p, arg:%p", psoc, arg); @@ -229,7 +229,7 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); target_if_debug("psoc:%p, arg:%p", psoc, arg); @@ -252,7 +252,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, { struct p2p_ps_params cmd; QDF_STATUS status; - wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); target_if_debug("psoc:%p, vdev_id:%d, opp_ps:%d", psoc, ps_config->vdev_id, ps_config->opp_ps); @@ -293,7 +293,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, struct p2p_lo_start *lo_start) { - wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); target_if_debug("psoc:%p, vdev_id:%d", psoc, lo_start->vdev_id); @@ -313,7 +313,7 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { - wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); target_if_debug("psoc:%p, vdev_id:%d", psoc, vdev_id); @@ -330,7 +330,7 @@ QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, bool disable_noa) { struct vdev_set_params param; - wmi_unified_t wmi_handle = wlan_psoc_get_tgt_if_handle(psoc); + wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); From 97d14e4122677fa0f69fb029d0f7e53ea3d5ba5b Mon Sep 17 00:00:00 2001 From: Vivek Date: Sun, 4 Jun 2017 23:12:00 +0530 Subject: [PATCH 089/404] qcacmn: Add target information details to target_iflayer Add a new target_psoc_info structure in the target if layer with the following members wmi_handle target_type target_version target_revision Also update the psoc data member tgt_if_handle to point to target_psoc_info instead of pointing to WMI handle directly. Updated all calls to psoc_get_tgt_if_handle to target_if_get_wmi_handle which inturn calls psoc_get_tgt_if_handle and getting the tgt_if_handle returns the WMI handle CRs-Fixed: 2048277 Change-Id: Icb02d5f3c09f7f9bb7eff4d814ef3ce90ddb84bd --- src/target_if_tdls.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/target_if_tdls.c b/src/target_if_tdls.c index 9f304f2bf2b8..af4255be5d71 100644 --- a/src/target_if_tdls.c +++ b/src/target_if_tdls.c @@ -91,7 +91,7 @@ target_if_tdls_update_fw_state(struct wlan_objmgr_psoc *psoc, else tdls_state = WMI_TDLS_DISABLE; - status = wmi_unified_update_fw_tdls_state_cmd(psoc->tgt_if_handle, + status = wmi_unified_update_fw_tdls_state_cmd(GET_WMI_HDL_FROM_PSOC(psoc), param, tdls_state); target_if_debug("vdev_id %d", param->vdev_id); @@ -111,7 +111,7 @@ target_if_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, { QDF_STATUS status; - status = wmi_unified_set_tdls_offchan_mode_cmd(psoc->tgt_if_handle, + status = wmi_unified_set_tdls_offchan_mode_cmd(GET_WMI_HDL_FROM_PSOC(psoc), params); return status; @@ -131,7 +131,7 @@ target_if_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, params->vdevid); return QDF_STATUS_SUCCESS; } - ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(psoc->tgt_if_handle, + ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(GET_WMI_HDL_FROM_PSOC(psoc), params); if (QDF_IS_STATUS_ERROR(ret)) @@ -144,7 +144,7 @@ QDF_STATUS target_if_tdls_register_event_handler(struct wlan_objmgr_psoc *psoc, void *arg) { - return wmi_unified_register_event(psoc->tgt_if_handle, + return wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc), wmi_tdls_peer_event_id, target_if_tdls_event_handler); } @@ -153,7 +153,7 @@ QDF_STATUS target_if_tdls_unregister_event_handler(struct wlan_objmgr_psoc *psoc, void *arg) { - return wmi_unified_unregister_event(psoc->tgt_if_handle, + return wmi_unified_unregister_event(GET_WMI_HDL_FROM_PSOC(psoc), wmi_tdls_peer_event_id); } From df19983a642d9e25dccf1ebf1a9ad2885c3080c6 Mon Sep 17 00:00:00 2001 From: Nitesh Shah Date: Fri, 12 May 2017 16:54:33 +0530 Subject: [PATCH 090/404] qcacmn: Provide Rx LDPC support for 2G STA Currently Rx LDPC is disabled for STA(2G) connection due to PHY-B hardware limitation. PHY-A can still support RxLDPC, so make changes such a way that when ever STA is on 2G band and current hardware mode is non-dbs then enable the Rx LDPC and if STA is on 2G band and current hardware mode is dbs then disable the RX LDPC. Change-Id: Ib0183fea06619056c61e297d3fcfd82d91775dcd CRs-Fixed: 2046542 --- inc/wlan_policy_mgr_api.h | 22 ++++++++++++++++ src/wlan_policy_mgr_action.c | 32 ++++++++++++++++++++++ src/wlan_policy_mgr_core.c | 44 +++++++++++++++++++++++++++++++ src/wlan_policy_mgr_init_deinit.c | 6 +++++ 4 files changed, 104 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 40cce054c0e1..1b0d80f75900 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -735,6 +735,9 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, /** * struct policy_mgr_sme_cbacks - SME Callbacks to be invoked * from policy manager + * @sme_check_enable_rx_ldpc_sta_ini_item: Get rx ldpc sta ini value + * @sme_set_vdev_ies_per_band: Set vdev IEs per band + * @sme_issue_same_ap_reassoc_cmd: Issue AP reassoc * @sme_get_valid_channels: Get valid channel list * @sme_get_nss_for_vdev: Get the allowed nss value for the vdev * @sme_soc_set_dual_mac_config: Set the dual MAC scan & FW @@ -745,6 +748,10 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, * @sme_change_mcc_beacon_interval: Set MCC beacon interval to FW */ struct policy_mgr_sme_cbacks { + bool (*sme_check_enable_rx_ldpc_sta_ini_item)(void); + void (*sme_set_vdev_ies_per_band)(uint8_t vdev_id, + uint8_t is_hw_mode_dbs); + QDF_STATUS (*sme_issue_same_ap_reassoc_cmd)(uint8_t session_id); QDF_STATUS (*sme_get_valid_channels)(uint8_t *chan_list, uint32_t *list_len); void (*sme_get_nss_for_vdev)(enum tQDF_ADAPTER_MODE, @@ -1906,4 +1913,19 @@ uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, * Return: true for success, else false */ bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev); + +/** + * policy_mgr_find_sta_and_update_caps_with_reassociation() - find sta and + * update HT/VHT caps and do reassociation with same ap + * @psoc: PSOC object information + * @is_hw_mode_dbs: DBS or NON-DBS hardware mode to use + * + * This API will find the 2G STA currently active from policy manager table + * and update their HT/VHT caps to firmware and trigger self reassociation + * with same AP through LFR3 roaming module. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_find_sta_and_update_caps_with_reassociation( + struct wlan_objmgr_psoc *psoc, uint8_t is_hw_mode_dbs); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 1695fc4bff80..231ea42ec002 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -423,6 +423,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_hw_mode_params hw_mode; struct dbs_nss nss_dbs; + struct policy_mgr_psoc_priv_obj *pm_ctx; if (policy_mgr_is_hw_dbs_capable(psoc) == false) { policy_mgr_err("driver isn't dbs capable, no further action needed"); @@ -447,6 +448,12 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_ALREADY; } + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + if ((PM_SBS == action) || (action == PM_SBS_DOWNGRADE)) { if (!policy_mgr_is_hw_sbs_capable(psoc)) { /* No action */ @@ -459,6 +466,31 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, } + /* + * just check PM_DBS action only, no need to check for + * PM_DBS_DOWNGRADE as it will eventually call PM_DBS. if you check + * for PM_DBS_DOWNGRADE then IE update and self reassoc will happen + * two times back to back as this functon is nested which + * will not make sense. Same things apply for PM_SINGLE_MAC_UPGRADE + * and PM_SINGLE_MAC operations. + */ + if ((PM_DBS == action) && !hw_mode.dbs_cap && + pm_ctx->sme_cbacks.sme_check_enable_rx_ldpc_sta_ini_item()) { + policy_mgr_notice("Going for DBS, disable rx-ldpc for all 2G STAs"); + policy_mgr_find_sta_and_update_caps_with_reassociation(psoc, + true); + } else if ((PM_SINGLE_MAC == action) && hw_mode.dbs_cap + && + pm_ctx->sme_cbacks.sme_check_enable_rx_ldpc_sta_ini_item()) { + /* + * don't use default RX LDPC which isenabled for 5g and + * disable for 2g + */ + policy_mgr_notice("Going for SMM, enable rx-ldpc for all 2G STAs"); + policy_mgr_find_sta_and_update_caps_with_reassociation(psoc, + false); + } + switch (action) { case PM_DBS_DOWNGRADE: /* diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 03fc3396196d..86fad4330025 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2252,6 +2252,50 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, return; } +QDF_STATUS policy_mgr_find_sta_and_update_caps_with_reassociation( + struct wlan_objmgr_psoc *psoc, uint8_t is_hw_mode_dbs) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint32_t index, count; + uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t conn_index = 0; + uint32_t vdev_id, channel; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, + list); + for (index = 0; index < count; index++) { + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + vdev_id = pm_conc_connection_list[list[index]].vdev_id; + channel = pm_conc_connection_list[list[index]].chan; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + conn_index = policy_mgr_get_connection_for_vdev_id(psoc, + vdev_id); + if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) { + policy_mgr_err("connection not found for vdev %d", + vdev_id); + continue; + } + /* do it only for 2.4GHz channels */ + if (!WLAN_REG_IS_24GHZ_CH(channel)) + continue; + pm_ctx->sme_cbacks.sme_set_vdev_ies_per_band(vdev_id, + is_hw_mode_dbs); + status = pm_ctx->sme_cbacks.sme_issue_same_ap_reassoc_cmd( + vdev_id); + if (QDF_STATUS_E_FAILURE == status) + policy_mgr_err("Self reassoc failed %d", status); + } + + return status; +} + /** * policy_mgr_complete_action() - initiates actions needed on * current connections once channel has been decided for the new diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 43f325412fdd..5fed2e24f1c7 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -501,6 +501,12 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + pm_ctx->sme_cbacks.sme_check_enable_rx_ldpc_sta_ini_item = + sme_cbacks->sme_check_enable_rx_ldpc_sta_ini_item; + pm_ctx->sme_cbacks.sme_set_vdev_ies_per_band = + sme_cbacks->sme_set_vdev_ies_per_band; + pm_ctx->sme_cbacks.sme_issue_same_ap_reassoc_cmd = + sme_cbacks->sme_issue_same_ap_reassoc_cmd; pm_ctx->sme_cbacks.sme_get_nss_for_vdev = sme_cbacks->sme_get_nss_for_vdev; pm_ctx->sme_cbacks.sme_get_valid_channels = From e2142700d7fb5beca8ea161fdc4d4aefb358f567 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Tue, 9 May 2017 19:47:37 +0800 Subject: [PATCH 091/404] qcacmn: fix implict memory leak Fix implict memory leak in P2P target if layer. Change-Id: Ic7dbf6673b67ec34e060b785c59dd3a99b855f6d CRs-Fixed: 2055496 --- src/target_if_p2p.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index a101d127835e..430a306a4eb4 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -89,6 +89,9 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, status = p2p_rx_ops->lo_ev_handler(psoc, event_info); target_if_debug("call lo event handler, status:%d", status); + } else { + qdf_mem_free(event_info); + target_if_debug("no valid lo event handler"); } return qdf_status_to_os_return(status); @@ -152,6 +155,9 @@ static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, status = p2p_rx_ops->noa_ev_handler(psoc, event_info); target_if_debug("call noa event handler, status:%d", status); + } else { + qdf_mem_free(event_info); + target_if_debug("no valid noa event handler"); } return qdf_status_to_os_return(status); From 2ff84bd4de5d7e0cf3203bf8340e3176a7b44624 Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Fri, 9 Jun 2017 16:39:12 -0700 Subject: [PATCH 092/404] Revert "qcacmn: Provide Rx LDPC support for 2G STA" This reverts change-id: Ib0183fea06619056c61e297d3fcfd82d91775dcd. CRs-Fixed: 2046542 Change-Id: I558d2d78683133fbd8ab97260aa484a997bd3e7e --- inc/wlan_policy_mgr_api.h | 22 ---------------- src/wlan_policy_mgr_action.c | 32 ---------------------- src/wlan_policy_mgr_core.c | 44 ------------------------------- src/wlan_policy_mgr_init_deinit.c | 6 ----- 4 files changed, 104 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 1b0d80f75900..40cce054c0e1 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -735,9 +735,6 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, /** * struct policy_mgr_sme_cbacks - SME Callbacks to be invoked * from policy manager - * @sme_check_enable_rx_ldpc_sta_ini_item: Get rx ldpc sta ini value - * @sme_set_vdev_ies_per_band: Set vdev IEs per band - * @sme_issue_same_ap_reassoc_cmd: Issue AP reassoc * @sme_get_valid_channels: Get valid channel list * @sme_get_nss_for_vdev: Get the allowed nss value for the vdev * @sme_soc_set_dual_mac_config: Set the dual MAC scan & FW @@ -748,10 +745,6 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, * @sme_change_mcc_beacon_interval: Set MCC beacon interval to FW */ struct policy_mgr_sme_cbacks { - bool (*sme_check_enable_rx_ldpc_sta_ini_item)(void); - void (*sme_set_vdev_ies_per_band)(uint8_t vdev_id, - uint8_t is_hw_mode_dbs); - QDF_STATUS (*sme_issue_same_ap_reassoc_cmd)(uint8_t session_id); QDF_STATUS (*sme_get_valid_channels)(uint8_t *chan_list, uint32_t *list_len); void (*sme_get_nss_for_vdev)(enum tQDF_ADAPTER_MODE, @@ -1913,19 +1906,4 @@ uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, * Return: true for success, else false */ bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev); - -/** - * policy_mgr_find_sta_and_update_caps_with_reassociation() - find sta and - * update HT/VHT caps and do reassociation with same ap - * @psoc: PSOC object information - * @is_hw_mode_dbs: DBS or NON-DBS hardware mode to use - * - * This API will find the 2G STA currently active from policy manager table - * and update their HT/VHT caps to firmware and trigger self reassociation - * with same AP through LFR3 roaming module. - * - * Return: QDF_STATUS - */ -QDF_STATUS policy_mgr_find_sta_and_update_caps_with_reassociation( - struct wlan_objmgr_psoc *psoc, uint8_t is_hw_mode_dbs); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 231ea42ec002..1695fc4bff80 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -423,7 +423,6 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_hw_mode_params hw_mode; struct dbs_nss nss_dbs; - struct policy_mgr_psoc_priv_obj *pm_ctx; if (policy_mgr_is_hw_dbs_capable(psoc) == false) { policy_mgr_err("driver isn't dbs capable, no further action needed"); @@ -448,12 +447,6 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_ALREADY; } - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid context"); - return QDF_STATUS_E_FAILURE; - } - if ((PM_SBS == action) || (action == PM_SBS_DOWNGRADE)) { if (!policy_mgr_is_hw_sbs_capable(psoc)) { /* No action */ @@ -466,31 +459,6 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, } - /* - * just check PM_DBS action only, no need to check for - * PM_DBS_DOWNGRADE as it will eventually call PM_DBS. if you check - * for PM_DBS_DOWNGRADE then IE update and self reassoc will happen - * two times back to back as this functon is nested which - * will not make sense. Same things apply for PM_SINGLE_MAC_UPGRADE - * and PM_SINGLE_MAC operations. - */ - if ((PM_DBS == action) && !hw_mode.dbs_cap && - pm_ctx->sme_cbacks.sme_check_enable_rx_ldpc_sta_ini_item()) { - policy_mgr_notice("Going for DBS, disable rx-ldpc for all 2G STAs"); - policy_mgr_find_sta_and_update_caps_with_reassociation(psoc, - true); - } else if ((PM_SINGLE_MAC == action) && hw_mode.dbs_cap - && - pm_ctx->sme_cbacks.sme_check_enable_rx_ldpc_sta_ini_item()) { - /* - * don't use default RX LDPC which isenabled for 5g and - * disable for 2g - */ - policy_mgr_notice("Going for SMM, enable rx-ldpc for all 2G STAs"); - policy_mgr_find_sta_and_update_caps_with_reassociation(psoc, - false); - } - switch (action) { case PM_DBS_DOWNGRADE: /* diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 86fad4330025..03fc3396196d 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2252,50 +2252,6 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, return; } -QDF_STATUS policy_mgr_find_sta_and_update_caps_with_reassociation( - struct wlan_objmgr_psoc *psoc, uint8_t is_hw_mode_dbs) -{ - struct policy_mgr_psoc_priv_obj *pm_ctx; - QDF_STATUS status = QDF_STATUS_SUCCESS; - uint32_t index, count; - uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; - uint32_t conn_index = 0; - uint32_t vdev_id, channel; - - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid Context"); - return QDF_STATUS_E_FAILURE; - } - - count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, - list); - for (index = 0; index < count; index++) { - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - vdev_id = pm_conc_connection_list[list[index]].vdev_id; - channel = pm_conc_connection_list[list[index]].chan; - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - conn_index = policy_mgr_get_connection_for_vdev_id(psoc, - vdev_id); - if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) { - policy_mgr_err("connection not found for vdev %d", - vdev_id); - continue; - } - /* do it only for 2.4GHz channels */ - if (!WLAN_REG_IS_24GHZ_CH(channel)) - continue; - pm_ctx->sme_cbacks.sme_set_vdev_ies_per_band(vdev_id, - is_hw_mode_dbs); - status = pm_ctx->sme_cbacks.sme_issue_same_ap_reassoc_cmd( - vdev_id); - if (QDF_STATUS_E_FAILURE == status) - policy_mgr_err("Self reassoc failed %d", status); - } - - return status; -} - /** * policy_mgr_complete_action() - initiates actions needed on * current connections once channel has been decided for the new diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 5fed2e24f1c7..43f325412fdd 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -501,12 +501,6 @@ QDF_STATUS policy_mgr_register_sme_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - pm_ctx->sme_cbacks.sme_check_enable_rx_ldpc_sta_ini_item = - sme_cbacks->sme_check_enable_rx_ldpc_sta_ini_item; - pm_ctx->sme_cbacks.sme_set_vdev_ies_per_band = - sme_cbacks->sme_set_vdev_ies_per_band; - pm_ctx->sme_cbacks.sme_issue_same_ap_reassoc_cmd = - sme_cbacks->sme_issue_same_ap_reassoc_cmd; pm_ctx->sme_cbacks.sme_get_nss_for_vdev = sme_cbacks->sme_get_nss_for_vdev; pm_ctx->sme_cbacks.sme_get_valid_channels = From ee5e70ec8519e75729e63b5f6d0ef9c185ff2502 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 8 Jun 2017 13:59:02 -0700 Subject: [PATCH 093/404] qcacmn: Restart SAP with CSA/ECSA when gWlanMccToSccSwitchMod=3 Restart SAP with CSA/ECSA when ini variable gWlanMccToSccSwitchMod=3. Currently ini variable setting gWlanMccToSccSwitchMod=2 was causing SAP to restart with CSA. Change-Id: I9a4b68cd154fa63325d146510832c2410f2dc244 CRs-Fixed: 2058567 --- inc/wlan_policy_mgr_api.h | 2 +- src/wlan_policy_mgr_action.c | 28 +--------------------------- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 40cce054c0e1..728d32eb7f7b 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -782,7 +782,7 @@ struct policy_mgr_hdd_cbacks { QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t *channel, - uint8_t *sec_ch, bool is_restart_sap); + uint8_t *sec_ch); enum policy_mgr_con_mode (*get_mode_for_non_connected_vdev)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 1695fc4bff80..8990550e66b2 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -599,27 +599,6 @@ static bool policy_mgr_is_restart_sap_allowed( return true; } -/** - * policy_mgr_is_sap_channel_change_without_restart() - Check if - * SAP channel change allowed without restart - * @mcc_to_scc_switch: MCC to SCC switch enabled user config - * - * Check if SAP channel change allowed without restart - * - * Restart: true or false - */ -static bool policy_mgr_is_sap_channel_change_without_restart( - uint32_t mcc_to_scc_switch) { - if (mcc_to_scc_switch == - QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION || - mcc_to_scc_switch == - QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) { - policy_mgr_info("SAP chan change without restart allowed"); - return true; - } - return false; -} - /** * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case * @data: Pointer check concurrent channel work data @@ -637,8 +616,6 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) QDF_STATUS status; uint8_t channel, sec_ch; uint8_t operating_channel, vdev_id; - bool restart_sap; - pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -661,9 +638,6 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) return; } - restart_sap = policy_mgr_is_sap_channel_change_without_restart( - mcc_to_scc_switch) ? false : true; - if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { policy_mgr_err("SAP restart get channel callback in NULL"); return; @@ -671,7 +645,7 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); status = pm_ctx->hdd_cbacks. wlan_hdd_get_channel_for_sap_restart(psoc, vdev_id, - &channel, &sec_ch, restart_sap); + &channel, &sec_ch); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed to switch SAP channel"); From c26d3bdbb3677eb2b4461efdf689da8005a2a0c3 Mon Sep 17 00:00:00 2001 From: Nitesh Shah Date: Wed, 7 Jun 2017 15:25:07 +0530 Subject: [PATCH 094/404] qcacmn: Validate mode and vdev while decrementing session The function policy_mgr_decr_active_session() decrements mode and then remove the session from the pm_conn_connection_info table after validating vdev. This change adds a check to validate if the session is present with specific mode and vdev_id, and then decrement the session. If not present, then return without doing any change. Change-Id: If53d7fc9356b2c3bb72b22b228103389396910ce CRs-Fixed: 2057599 --- inc/wlan_policy_mgr_api.h | 20 +++++++++++-- src/wlan_policy_mgr_get_set_utils.c | 44 +++++++++++++++++++++++++++-- src/wlan_policy_mgr_pcl.c | 7 ++++- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 728d32eb7f7b..6c18c484edf9 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -245,9 +245,9 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, * mode. In the case of STA/P2P CLI/IBSS upon disconnection it is decremented * In the case of SAP/P2P GO upon bss stop it is decremented * - * Return: None + * Return: QDF_STATUS */ -void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, +QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, enum tQDF_ADAPTER_MODE mode, uint8_t sessionId); /** @@ -1360,6 +1360,22 @@ uint32_t policy_mgr_mode_specific_connection_count( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint32_t *list); +/** + * policy_mgr_check_conn_with_mode_and_vdev_id() - checks if any active + * session with specific mode and vdev_id + * @psoc: PSOC object information + * @mode: type of connection + * @vdev_id: vdev_id of the connection + * + * This function checks if any active session with specific mode and vdev_id + * is present + * + * Return: QDF STATUS with success if active session is found, else failure + */ +QDF_STATUS policy_mgr_check_conn_with_mode_and_vdev_id( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t vdev_id); + /** * policy_mgr_hw_mode_transition_cb() - Callback for HW mode * transition from FW diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 9d16bdd63c25..2bdebb638c54 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -838,6 +838,33 @@ uint32_t policy_mgr_mode_specific_connection_count( return count; } +QDF_STATUS policy_mgr_check_conn_with_mode_and_vdev_id( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, + uint32_t vdev_id) +{ + QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE; + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return qdf_status; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + if ((pm_conc_connection_list[conn_index].mode == mode) && + (pm_conc_connection_list[conn_index].vdev_id == vdev_id)) { + qdf_status = QDF_STATUS_SUCCESS; + break; + } + conn_index++; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return qdf_status; +} + void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, uint32_t scan_config, uint32_t fw_mode_config) @@ -1122,16 +1149,27 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } -void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, +QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, enum tQDF_ADAPTER_MODE mode, uint8_t session_id) { struct policy_mgr_psoc_priv_obj *pm_ctx; + QDF_STATUS qdf_status; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("context is NULL"); - return; + return QDF_STATUS_E_EMPTY; + } + + qdf_status = policy_mgr_check_conn_with_mode_and_vdev_id(psoc, + policy_mgr_convert_device_mode_to_qdf_type(mode), + session_id); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + policy_mgr_err("No connection with mode:%d vdev_id:%d", + policy_mgr_convert_device_mode_to_qdf_type(mode), + session_id); + return qdf_status; } switch (mode) { @@ -1157,6 +1195,8 @@ void policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc); policy_mgr_dump_current_concurrency(psoc); + + return qdf_status; } QDF_STATUS policy_mgr_incr_connection_count( diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index ad0b2c9d0684..6c2a6971125c 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -103,7 +103,12 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, return; } - policy_mgr_decr_active_session(psoc, mode, session_id); + qdf_status = policy_mgr_decr_active_session(psoc, mode, session_id); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { + policy_mgr_err("Invalid active session"); + return; + } + /* * After the removal of this connection, we need to check if * a STA connection still exists. The reason for this is that From c1246b19b98103fe430d12d565b85dc71f7d3644 Mon Sep 17 00:00:00 2001 From: Ajit Pal Singh Date: Fri, 16 Jun 2017 11:36:12 +0530 Subject: [PATCH 095/404] qcacmn: Move GO to STA channel to achieve SCC Enable movement of GO to STA channel to achieve SCC. This movement is controlled by the ini variable "gWlanMccToSccSwitchMode" just as its done for SAP. Change-Id: I50f9487aa26dfc359211699f3d46e7869cedca4b CRs-Fixed: 2062450 --- src/wlan_policy_mgr_action.c | 42 ++++++++++++++++++++++------- src/wlan_policy_mgr_get_set_utils.c | 9 ------- src/wlan_policy_mgr_i.h | 14 ---------- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 8990550e66b2..1d093b43823a 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -591,9 +591,11 @@ static bool policy_mgr_is_restart_sap_allowed( { if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) || !(policy_mgr_concurrent_open_sessions_running(psoc) && + ((policy_mgr_get_concurrency_mode(psoc) == + (QDF_STA_MASK | QDF_SAP_MASK)) || (policy_mgr_get_concurrency_mode(psoc) == - (QDF_STA_MASK | QDF_SAP_MASK)))) { - policy_mgr_err("MCC switch disabled or not concurrent STA/SAP"); + (QDF_STA_MASK | QDF_P2P_GO_MASK))))) { + policy_mgr_err("MCC switch disabled or not concurrent STA/SAP, STA/GO"); return false; } return true; @@ -631,10 +633,20 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) return; - if (!policy_mgr_get_sap_conn_info(psoc, - &operating_channel, - &vdev_id)) { - policy_mgr_err("Could not retrieve SAP channel & vdev id"); + if (policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel, + &vdev_id, + PM_SAP_MODE)) { + policy_mgr_debug("SAP operating at channel:%d", + operating_channel); + } else if (policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel, + &vdev_id, + PM_P2P_GO_MODE)) { + policy_mgr_debug("GO operating at channel:%d", + operating_channel); + } else { + policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid"); return; } @@ -680,10 +692,20 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( return; } - if (!policy_mgr_get_sap_conn_info(psoc, - &operating_channel, - &vdev_id)) { - policy_mgr_err("Could not retrieve SAP channel & vdev id"); + if (policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel, + &vdev_id, + PM_SAP_MODE)) { + policy_mgr_debug("SAP operating at channel:%d", + operating_channel); + } else if (policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel, + &vdev_id, + PM_P2P_GO_MODE)) { + policy_mgr_debug("GO operating at channel:%d", + operating_channel); + } else { + policy_mgr_err("Could not get SAP/GO operating channel&vdevid"); return; } diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 2bdebb638c54..f614a1c4e0b4 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1443,15 +1443,6 @@ bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, return status; } -bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, - uint8_t *channel, uint8_t *vdev_id) -{ - return policy_mgr_get_mode_specific_conn_info(psoc, - channel, - vdev_id, - PM_SAP_MODE); -} - bool policy_mgr_max_concurrent_connections_reached( struct wlan_objmgr_psoc *psoc) { diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 5100017bda57..7d3f4e4a03e6 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -385,20 +385,6 @@ enum policy_mgr_conc_next_action QDF_STATUS policy_mgr_reset_sap_mandatory_channels( struct policy_mgr_psoc_priv_obj *pm_ctx); -/** - * policy_mgr_get_sap_conn_info() - Get active SAP channel and - * vdev id - * @psoc: PSOC object information - * @channel: SAP channel - * @vdev_id: SAP vdev id - * - * Get active SAP channel and vdev id - * - * Return: true for success, else false - */ -bool policy_mgr_get_sap_conn_info(struct wlan_objmgr_psoc *psoc, - uint8_t *channel, uint8_t *vdev_id); - /** * policy_mgr_get_mode_specific_conn_info() - Get active mode specific * channel and vdev id From 77776fed8b146276a74904ca3752b00cf38dc58e Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 23 Jun 2017 21:05:31 +0530 Subject: [PATCH 096/404] qcacmn: Remove psoc/pdev locks for trivial APIs Remove psoc/pdev locks from trivial API's. This follows the changes from which the lock requirement from few simple APIs are removed. Change-Id: Ib5769c2234c8d57f485c0eef5a4e3c61fa170508 CRs-Fixed: 2060880 --- core/src/wlan_tdls_main.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index a518ceaa7aad..0f699f319c75 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -383,11 +383,9 @@ wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) return NULL; } - wlan_psoc_obj_lock(psoc); soc_obj = (struct tdls_soc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - wlan_psoc_obj_unlock(psoc); return soc_obj; } @@ -406,11 +404,9 @@ wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc) tdls_err("NULL psoc"); return NULL; } - wlan_psoc_obj_lock(psoc); soc_obj = (struct tdls_soc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - wlan_psoc_obj_unlock(psoc); return soc_obj; } From 92e301c41466b0589853b6ded85304529205a23e Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 21 Jun 2017 08:21:58 +0530 Subject: [PATCH 097/404] 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_policy_mgr_get_set_utils.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index f614a1c4e0b4..1b64f22c45e5 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2448,9 +2448,7 @@ bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev) return false; } - wlan_vdev_obj_lock(vdev); roffchan = wlan_vdev_mlme_cap_get(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN); - wlan_vdev_obj_unlock(vdev); policy_mgr_debug("Restrict offchannel:%s", roffchan ? "set" : "clear"); From de1e5bcaa9741d3f5aa8d8b2bbc5461907f80712 Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 21 Jun 2017 08:21:58 +0530 Subject: [PATCH 098/404] 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 --- core/src/wlan_tdls_cmds_process.c | 22 +--------------------- core/src/wlan_tdls_ct.c | 8 -------- core/src/wlan_tdls_main.c | 2 -- core/src/wlan_tdls_main.h | 4 ---- core/src/wlan_tdls_peer.c | 6 ------ dispatcher/src/wlan_tdls_tgt_api.c | 6 ------ 6 files changed, 1 insertion(+), 47 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 80a7ef387397..671eaf03c06f 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -142,16 +142,13 @@ static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) addstareq->tdls_oper = TDLS_OPER_ADD; addstareq->transaction_id = 0; - wlan_vdev_obj_lock(vdev); addstareq->session_id = wlan_vdev_get_id(vdev); peer = wlan_vdev_get_bsspeer(vdev); if (!peer) { - wlan_vdev_obj_unlock(vdev); tdls_err("bss peer is NULL"); status = QDF_STATUS_E_INVAL; goto error; } - wlan_vdev_obj_unlock(vdev); status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get bss peer"); @@ -210,16 +207,13 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) delstareq->transaction_id = 0; - wlan_vdev_obj_lock(vdev); delstareq->session_id = wlan_vdev_get_id(vdev); peer = wlan_vdev_get_bsspeer(vdev); if (!peer) { - wlan_vdev_obj_unlock(vdev); tdls_err("bss peer is NULL"); status = QDF_STATUS_E_INVAL; goto error; } - wlan_vdev_obj_unlock(vdev); status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get bss peer"); @@ -281,16 +275,13 @@ static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) addstareq->tdls_oper = TDLS_OPER_UPDATE; addstareq->transaction_id = 0; - wlan_vdev_obj_lock(vdev); addstareq->session_id = wlan_vdev_get_id(vdev); peer = wlan_vdev_get_bsspeer(vdev); if (!peer) { - wlan_vdev_obj_unlock(vdev); tdls_err("bss peer is NULL"); status = QDF_STATUS_E_INVAL; goto error; } - wlan_vdev_obj_unlock(vdev); status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get bss peer"); @@ -1477,9 +1468,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) QDF_MAC_ADDR_ARRAY(macaddr), curr_peer->link_status); - wlan_vdev_obj_lock(vdev); id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); if (TDLS_IS_LINK_CONNECTED(curr_peer)) { soc_obj->tdls_dereg_tl_peer( @@ -1573,14 +1562,13 @@ tdls_update_uapsd(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, tdls_debug("No need to configure auto trigger:psb is 0"); return QDF_STATUS_SUCCESS; } - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); bsspeer = wlan_vdev_get_bsspeer(vdev); if (!bsspeer) { - wlan_vdev_obj_unlock(vdev); tdls_err("bss peer is NULL"); return QDF_STATUS_E_FAILURE; } + wlan_vdev_obj_lock(vdev); qdf_mem_copy(macaddr, wlan_peer_get_macaddr(bsspeer), QDF_MAC_ADDR_SIZE); wlan_vdev_obj_unlock(vdev); @@ -1663,9 +1651,7 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) tdls_set_peer_link_status(peer, TDLS_LINK_CONNECTED, TDLS_LINK_SUCCESS); - wlan_vdev_obj_lock(vdev); id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); status = soc_obj->tdls_reg_tl_peer(soc_obj->tdls_tl_peer_data, id, mac, peer->sta_id, peer->signature, peer->qos); @@ -1744,9 +1730,7 @@ static QDF_STATUS tdls_config_force_peer( QDF_MAC_ADDR_ARRAY(macaddr)); vdev = req->vdev; - wlan_vdev_obj_lock(vdev); pdev = wlan_vdev_get_pdev(vdev); - wlan_vdev_obj_unlock(vdev); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); if (!pdev || !vdev_obj || !soc_obj) { @@ -1784,9 +1768,7 @@ static QDF_STATUS tdls_config_force_peer( /* Update the peer mac to firmware, so firmware could update the * connection table */ - wlan_vdev_obj_lock(vdev); peer_update_param->vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); qdf_mem_copy(peer_update_param->peer_macaddr, macaddr, QDF_MAC_ADDR_SIZE); peer_update_param->peer_state = TDLS_PEER_ADD_MAC_ADDR; @@ -1951,9 +1933,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) goto error; } - wlan_vdev_obj_lock(vdev); peer_update_param->vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); qdf_mem_copy(peer_update_param->peer_macaddr, macaddr, QDF_MAC_ADDR_SIZE); peer_update_param->peer_state = TDLS_PEER_REMOVE_MAC_ADDR; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index d6e73f69746b..1ed20b976f0b 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -32,18 +32,14 @@ bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev) struct wlan_objmgr_peer *peer; enum wlan_peer_state peer_state; - wlan_vdev_obj_lock(vdev); peer = wlan_vdev_get_bsspeer(vdev); - wlan_vdev_obj_unlock(vdev); if (!peer) { tdls_err("peer is null"); return false; } - wlan_peer_obj_lock(peer); peer_state = wlan_peer_mlme_get_state(peer); - wlan_peer_obj_unlock(peer); if (peer_state != WLAN_ASSOC_STATE) { tdls_err("peer state: %d", peer_state); @@ -58,18 +54,14 @@ bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev) struct wlan_objmgr_peer *peer; bool is_authenticated = false; - wlan_vdev_obj_lock(vdev); peer = wlan_vdev_get_bsspeer(vdev); - wlan_vdev_obj_unlock(vdev); if (!peer) { tdls_err("peer is null"); return false; } - wlan_peer_obj_lock(peer); is_authenticated = wlan_peer_mlme_get_auth_state(peer); - wlan_peer_obj_unlock(peer); return is_authenticated; } diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 437b51f5fc8d..5ce0596f0e3c 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -430,9 +430,7 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, if (NULL == (*tdls_soc_obj)) return QDF_STATUS_E_FAILURE; - wlan_vdev_obj_lock(vdev); device_mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); if (device_mode != QDF_STA_MODE && device_mode != QDF_P2P_CLIENT_MODE) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 0f699f319c75..f9f657a6055d 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -375,9 +375,7 @@ wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) return NULL; } - wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); - wlan_vdev_obj_unlock(vdev); if (!psoc) { tdls_err("can't get psoc"); return NULL; @@ -427,11 +425,9 @@ wlan_vdev_get_tdls_vdev_obj(struct wlan_objmgr_vdev *vdev) return NULL; } - wlan_vdev_obj_lock(vdev); vdev_obj = (struct tdls_vdev_priv_obj *) wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); - wlan_vdev_obj_unlock(vdev); return vdev_obj; } diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 56e5ec715ea4..c78f0f0f3569 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -315,9 +315,7 @@ struct tdls_peer *tdls_is_progress(struct tdls_vdev_priv_obj *vdev_obj, return NULL; } - wlan_vdev_obj_lock(vdev_obj->vdev); psoc = wlan_vdev_get_psoc(vdev_obj->vdev); - wlan_vdev_obj_unlock(vdev_obj->vdev); if (!psoc) { tdls_err("invalid psoc"); return NULL; @@ -395,10 +393,8 @@ static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, if (!(TDLS_IS_OFF_CHANNEL_ENABLED( soc_obj->tdls_configs.tdls_feature_flags)) || soc_obj->tdls_fw_off_chan_mode != ENABLE_CHANSWITCH) { - wlan_vdev_obj_lock(vdev_obj->vdev); vdev_id = wlan_vdev_get_id(vdev_obj->vdev); opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev); - wlan_vdev_obj_unlock(vdev_obj->vdev); *channel = policy_mgr_get_channel(soc_obj->soc, opmode, &vdev_id); @@ -482,9 +478,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, } qdf_mem_zero(peer_param, sizeof(*peer_param)); - wlan_vdev_obj_lock(vdev_obj->vdev); peer_param->vdev_id = wlan_vdev_get_id(vdev_obj->vdev); - wlan_vdev_obj_unlock(vdev_obj->vdev); qdf_mem_copy(peer_param->peer_macaddr, peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE); diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index c292ac1fea0c..e1ab734fcc0e 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -244,21 +244,15 @@ QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( tdls_err("current tdls vdev is null, can't get vdev id"); return QDF_STATUS_E_FAILURE; } - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); } else { - wlan_peer_obj_lock(peer); vdev = wlan_peer_get_vdev(peer); - wlan_peer_obj_unlock(peer); if (!vdev) { tdls_err("vdev is NULL in peer, drop this frame"); return QDF_STATUS_E_FAILURE; } - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); } rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event)); From 74ffd94a250f869818a1599a390145afe578afeb Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 21 Jun 2017 08:21:58 +0530 Subject: [PATCH 099/404] 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 245f447a244de8e5f91c30c1d3380292406cb4e1 Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 21 Jun 2017 08:21:58 +0530 Subject: [PATCH 100/404] 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 --- core/src/wlan_p2p_main.c | 30 ------------------------------ core/src/wlan_p2p_off_chan_tx.c | 4 ---- dispatcher/src/wlan_p2p_tgt_api.c | 4 ---- dispatcher/src/wlan_p2p_ucfg_api.c | 2 -- 4 files changed, 40 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 9084c75bf2a5..bce6afc5fe1a 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -194,9 +194,7 @@ static QDF_STATUS p2p_vdev_obj_create_notification( return QDF_STATUS_E_INVAL; } - wlan_vdev_obj_lock(vdev); mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); p2p_debug("vdev mode:%d", mode); if (mode != QDF_P2P_GO_MODE) { p2p_debug("won't create p2p vdev private object if it is not GO"); @@ -251,9 +249,7 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( return QDF_STATUS_E_INVAL; } - wlan_vdev_obj_lock(vdev); mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); p2p_debug("vdev mode:%d", mode); if (mode != QDF_P2P_GO_MODE) { p2p_debug("no p2p vdev private object if it is not GO"); @@ -310,19 +306,13 @@ static QDF_STATUS p2p_peer_obj_create_notification( return QDF_STATUS_E_INVAL; } - wlan_peer_obj_lock(peer); vdev = wlan_peer_get_vdev(peer); - wlan_peer_obj_unlock(peer); p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_P2P); - wlan_peer_obj_lock(peer); peer_type = wlan_peer_get_peer_type(peer); - wlan_peer_obj_unlock(peer); if ((peer_type == WLAN_PEER_STA) && p2p_vdev_obj) { - wlan_vdev_obj_lock(vdev); mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); if (mode == QDF_P2P_GO_MODE) { p2p_vdev_obj->non_p2p_peer_count++; p2p_debug("Non P2P peer count: %d", @@ -359,26 +349,18 @@ static QDF_STATUS p2p_peer_obj_destroy_notification( return QDF_STATUS_E_INVAL; } - wlan_peer_obj_lock(peer); vdev = wlan_peer_get_vdev(peer); - wlan_peer_obj_unlock(peer); p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_P2P); - wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); - wlan_vdev_obj_unlock(vdev); if (!p2p_vdev_obj || !psoc) { p2p_err("p2p_vdev_obj:%p psoc:%p", p2p_vdev_obj, psoc); return QDF_STATUS_E_INVAL; } - wlan_vdev_obj_lock(vdev); mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); - wlan_peer_obj_lock(peer); peer_type = wlan_peer_get_peer_type(peer); - wlan_peer_obj_unlock(peer); if ((peer_type == WLAN_PEER_STA) && (mode == QDF_P2P_GO_MODE)) { @@ -387,9 +369,7 @@ static QDF_STATUS p2p_peer_obj_destroy_notification( if (!p2p_vdev_obj->non_p2p_peer_count && (p2p_vdev_obj->noa_status == false)) { - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); if (ucfg_p2p_set_noa(psoc, vdev_id, false) == QDF_STATUS_SUCCESS) @@ -502,13 +482,9 @@ static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev, p2p_err("p2p_vdev_obj:%p", p2p_vdev_obj); return QDF_STATUS_E_INVAL; } - wlan_vdev_obj_lock(vdev); mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); - wlan_peer_obj_lock(peer); peer_type = wlan_peer_get_peer_type(peer); - wlan_peer_obj_unlock(peer); disable_noa = ((mode == QDF_P2P_GO_MODE) && p2p_vdev_obj->non_p2p_peer_count @@ -516,9 +492,7 @@ static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev, if (disable_noa && (peer_type == WLAN_PEER_STA)) { - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); if (ucfg_p2p_set_noa(psoc, vdev_id, true) == QDF_STATUS_SUCCESS) { @@ -987,9 +961,7 @@ QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event) return QDF_STATUS_E_INVAL; } - wlan_vdev_obj_lock(vdev); mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); p2p_debug("vdev mode:%d", mode); if (mode != QDF_P2P_GO_MODE) { p2p_err("invalid p2p vdev mode:%d", mode); @@ -1030,9 +1002,7 @@ void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr) p2p_err("vdev:%p", vdev); return; } - wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); - wlan_vdev_obj_unlock(vdev); if (!psoc) { p2p_err("psoc:%p", psoc); return; diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 3831efb029ab..924c384b47d2 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -95,9 +95,7 @@ static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx) return QDF_STATUS_E_INVAL; } - wlan_vdev_obj_lock(vdev); mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); p2p_debug("vdev mode:%d", mode); /* drop probe response for sta, go, sap */ @@ -272,9 +270,7 @@ static struct p2p_noa_info *p2p_get_vdev_noa_info( return NULL; } - wlan_vdev_obj_lock(vdev); mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); p2p_debug("vdev mode:%d", mode); if (mode != QDF_P2P_GO_MODE) { p2p_debug("invalid p2p vdev mode:%d", mode); diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 3756a8d733d5..92764d72bc7c 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -207,16 +207,12 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, vdev_id = roc_ctx->vdev_id; } } else { - wlan_peer_obj_lock(peer); vdev = wlan_peer_get_vdev(peer); - wlan_peer_obj_unlock(peer); if (!vdev) { p2p_err("vdev is NULL in peer, drop this frame"); return QDF_STATUS_E_FAILURE; } - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); } rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event)); diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 2ab8046b0c94..c8d791b23540 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -203,10 +203,8 @@ QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_E_INVAL; } - wlan_vdev_obj_lock(vdev); vdev_id = (uint32_t)wlan_vdev_get_id(vdev); psoc = wlan_vdev_get_psoc(vdev); - wlan_vdev_obj_unlock(vdev); if (!psoc) { p2p_err("null psoc"); return QDF_STATUS_E_INVAL; From c7bf604323512b53f5f5800b017aea3b95f4ea0c Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 21 Jun 2017 08:21:58 +0530 Subject: [PATCH 101/404] 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_p2p.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 3963b64fd621..57429a1db88a 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -72,9 +72,7 @@ static void wlan_p2p_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; @@ -148,9 +146,7 @@ static void wlan_p2p_action_tx_cnf_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; @@ -207,9 +203,7 @@ static void wlan_p2p_lo_event_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; @@ -278,9 +272,7 @@ static void wlan_p2p_event_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; @@ -360,10 +352,8 @@ int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, return -EINVAL; } - wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); if (!psoc) { cfg80211_err("psoc handle is NULL"); return -EINVAL; @@ -399,9 +389,7 @@ int wlan_cfg80211_cancel_roc(struct wlan_objmgr_vdev *vdev, return -EINVAL; } - wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); - wlan_vdev_obj_unlock(vdev); if (!psoc) { cfg80211_err("psoc handle is NULL"); return -EINVAL; @@ -431,10 +419,8 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, return -EINVAL; } - wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); if (!psoc) { cfg80211_err("psoc handle is NULL"); return -EINVAL; @@ -485,9 +471,7 @@ int wlan_cfg80211_mgmt_tx_cancel(struct wlan_objmgr_vdev *vdev, return -EINVAL; } - wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); - wlan_vdev_obj_unlock(vdev); if (!psoc) { cfg80211_err("psoc handle is NULL"); return -EINVAL; From 944f1fda18553979926be6bb673779279a5fd3c0 Mon Sep 17 00:00:00 2001 From: Archana Ramachandran Date: Fri, 2 Jun 2017 16:48:17 -0700 Subject: [PATCH 102/404] qcacmn: Disallow moving to single MAC mode when a 2.4GHz connection exist After the P2P GO is up on 2.4 GHZ, the opportunistic upgrade timer handler is sending request to move to single MAC mode. Since 2.4 GHZ connection is always on MAC1 in DBS 2X2 capable HW, this is causing P2P connection failure. Add fix to not downgrade to single MAC mode when there exist a 2.4 GHZ connection. Change-Id: I90e2b5b43a6bc8a5b5b44ea96905410092f2866e CRs-Fixed: 2055867 --- src/wlan_policy_mgr_action.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 1d093b43823a..8c6b08c563f0 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -200,6 +200,14 @@ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( } else if ((pm_conc_connection_list[conn_index].mac == 1) && pm_conc_connection_list[conn_index].in_use) { mac |= POLICY_MGR_MAC1; + if (policy_mgr_is_hw_dbs_2x2_capable(psoc) && + WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[conn_index].chan) + ) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug("2X2 DBS capable with 2.4 GHZ connection"); + goto done; + } if (POLICY_MGR_MAC0_AND_MAC1 == mac) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); goto done; From da68b5a736f8ad4616699dfc4badbbf4efe9aedf Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 20 Jul 2017 12:40:12 -0700 Subject: [PATCH 103/404] qcacmn: policy_mgr_mode_specific_modification_on_pcl to be called per mode policy_mgr_mode_specific_modification_on_pcl to be called for the connection type for which get_pcl is called. Change-Id: I78010ebf877130eca9eaa0074a833fb5b7faa4a1 CRs-Fixed: 2079986 --- src/wlan_policy_mgr_pcl.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 6c2a6971125c..b12d66b2164c 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -353,6 +353,11 @@ static QDF_STATUS policy_mgr_mode_specific_modification_on_pcl( status = policy_mgr_pcl_modification_for_p2p_go( psoc, pcl_channels, pcl_weight, len); break; + case PM_STA_MODE: + case PM_P2P_CLIENT_MODE: + case PM_IBSS_MODE: + status = QDF_STATUS_SUCCESS; + break; default: policy_mgr_err("unexpected mode %d", mode); break; @@ -467,11 +472,7 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, } policy_mgr_mode_specific_modification_on_pcl( - psoc, pcl_channels, pcl_weight, len, PM_SAP_MODE); - - policy_mgr_mode_specific_modification_on_pcl( - psoc, pcl_channels, pcl_weight, len, PM_P2P_GO_MODE); - + psoc, pcl_channels, pcl_weight, len, mode); status = policy_mgr_modify_pcl_based_on_dnbs(psoc, pcl_channels, pcl_weight, len); From 52eb3c761df978e4499102f116945c1b70db7be8 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 6 Jun 2017 19:40:03 -0700 Subject: [PATCH 104/404] 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 --- core/src/wlan_tdls_main.c | 28 +++++++++++++++++++++++ core/src/wlan_tdls_main.h | 10 ++++++++ dispatcher/inc/wlan_tdls_public_structs.h | 10 ++++++++ dispatcher/inc/wlan_tdls_ucfg_api.h | 8 +++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 17 ++++++++++++++ 5 files changed, 73 insertions(+) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 5ce0596f0e3c..b894ba7d0d97 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -290,6 +290,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_TEARDOWN_LINKS: tdls_teardown_connections(msg->bodyptr); break; + case TDLS_NOTIFY_RESET_ADAPTERS: + tdls_notify_reset_adapter(msg->bodyptr); + break; default: break; } @@ -982,6 +985,31 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) return status; } +static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev) +{ + struct tdls_vdev_priv_obj *tdls_vdev; + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_vdev) + return; + tdls_timers_stop(tdls_vdev); +} + +void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + QDF_ASSERT(0); + return; + } + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, + WLAN_TDLS_NB_ID)) + return; + + tdls_process_reset_adapter(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, uint32_t session_id) { diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index f9f657a6055d..58aa9cd2eb1c 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -575,6 +575,16 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); +/** + * tdls_notify_reset_adapter() - notify reset adapter + * @vdev: vdev object manager + * + * Notify TDLS about the adapter reset + * + * Return: None + */ +void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); + /** * tdls_peers_deleted_notification() - peer delete notification * @vdev: vdev object diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 974fca313b81..4691869ffacd 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -172,6 +172,15 @@ enum tdls_feature_mode { * @TDLS_CMD_REMOVE_FORCE_PEER: remove external peer * @TDLS_CMD_STATS_UPDATE: update tdls stats * @TDLS_CMD_CONFIG_UPDATE: config tdls + * @TDLS_CMD_SCAN_DONE: scon done event + * @TDLS_CMD_SET_RESPONDER: responder event + * @TDLS_NOTIFY_STA_CONNECTION: notify sta connection + * @TDLS_NOTIFY_STA_DISCONNECTION: notify sta disconnection + * @TDLS_CMD_SET_TDLS_MODE: set the tdls mode + * @TDLS_CMD_SESSION_INCREMENT: notify session increment + * @TDLS_CMD_SESSION_DECREMENT: notify session decrement + * @TDLS_CMD_TEARDOWN_LINKS: notify teardown + * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -191,6 +200,7 @@ enum tdls_command_type { TDLS_CMD_SESSION_INCREMENT, TDLS_CMD_SESSION_DECREMENT, TDLS_CMD_TEARDOWN_LINKS, + TDLS_NOTIFY_RESET_ADAPTERS, }; /** diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 5d99669740ab..0a06658fe8b7 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -146,6 +146,14 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req); */ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev); +/** + * ucfg_tdls_notify_reset_adapter() - notify reset adapter + * @vdev: vdev object manager + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); + /** * ucfg_tdls_notify_sta_connect() - notify sta connect * @notify_info: sta notification info diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 9bb85352bcea..67517aabc3aa 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -569,6 +569,23 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) return status; } +QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status; + struct scheduler_msg msg = {0, }; + + if (!vdev) { + tdls_err("vdev is NULL "); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_debug("Enter "); + msg.bodyptr = vdev; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_RESET_ADAPTERS; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + return status; +} + QDF_STATUS ucfg_tdls_notify_sta_connect( struct tdls_sta_notify_params *notify_info) { From ba8219da59f1a9e53ab57493fb12087f9a542508 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 6 Jun 2017 19:40:03 -0700 Subject: [PATCH 105/404] 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 cccf099982a646fefa72f9c85e1ea26a17e12c7e Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Thu, 10 Aug 2017 13:37:08 -0700 Subject: [PATCH 106/404] qcacmn: Add vdev as argument to wlan_serialization_comp_info_cb Add an additional argument to wlan_serialization_comp_info_cb to pass the vdev information while filling the information required to apply the rules. Change-Id: I44dadc01108e746fd2ce6353a90cdf9401dd6d06 CRs-Fixed: 2090987 --- core/src/wlan_tdls_main.c | 2 +- core/src/wlan_tdls_main.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index b894ba7d0d97..fc16026556b0 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1332,7 +1332,7 @@ return_success: return status; } -void tdls_scan_serialization_comp_info_cb( +void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, union wlan_serialization_rules_info *comp_info) { struct tdls_soc_priv_obj *tdls_soc; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 58aa9cd2eb1c..bfdcb2cb123b 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -681,12 +681,13 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc); /** * tdls_scan_serialization_comp_info_cb() - callback for scan start + * @vdev: VDEV on which the scan command is being processed * @comp_info: serialize rules info * * Return: negative = caller should stop and return error code immediately * 1 = caller can continue to scan */ -void tdls_scan_serialization_comp_info_cb( +void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, union wlan_serialization_rules_info *comp_info); /** From bcd3481965d2032f68b18185796db7acffe35332 Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Thu, 19 Jan 2017 15:33:43 -0800 Subject: [PATCH 107/404] qcacmn: Change semantics of Runtime Lock APIs Runtime PM lock init API right now returns pointer to a context but this would cause confusion to the caller if feature is not defined and dummy function return NULL as caller can't find real failure versus dummy function returning because feature not being enabled. Fix declaring a data structure in QDF layer that caller can use but it hides the internal details of HIF implementation for Runtime PM locks. CRs-fixed: 1116509 Change-Id: I4dcba604e803faa0e14fac6403610391895e382e --- core/src/wlan_p2p_main.c | 6 +++--- core/src/wlan_p2p_roc.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index bce6afc5fe1a..3d68b43cec97 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -663,8 +663,8 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) p2p_err("failed to create cancel roc done event"); goto fail_event; } - p2p_soc_obj->roc_runtime_lock = qdf_runtime_lock_init( - P2P_MODULE_NAME); + + qdf_runtime_lock_init(&p2p_soc_obj->roc_runtime_lock); p2p_debug("p2p psoc object open successful"); @@ -694,7 +694,7 @@ QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) return QDF_STATUS_E_FAILURE; } - qdf_runtime_lock_deinit(p2p_soc_obj->roc_runtime_lock); + qdf_runtime_lock_deinit(&p2p_soc_obj->roc_runtime_lock); qdf_event_destroy(&p2p_soc_obj->cancel_roc_done); qdf_list_destroy(&p2p_soc_obj->tx_q_ack); qdf_list_destroy(&p2p_soc_obj->tx_q_roc); diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index e83914d1c300..6456b723ad17 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -345,7 +345,7 @@ static QDF_STATUS p2p_execute_roc_req(struct p2p_roc_context *roc_ctx) roc_ctx->roc_type, roc_ctx->roc_state); /* prevent runtime suspend */ - qdf_runtime_pm_prevent_suspend(p2p_soc_obj->roc_runtime_lock); + qdf_runtime_pm_prevent_suspend(&p2p_soc_obj->roc_runtime_lock); status = qdf_mc_timer_init(&roc_ctx->roc_timer, QDF_TIMER_TYPE_SW, p2p_roc_timeout, @@ -375,7 +375,7 @@ fail: if (status != QDF_STATUS_SUCCESS) { p2p_destroy_roc_ctx(roc_ctx, true, true); qdf_runtime_pm_allow_suspend( - p2p_soc_obj->roc_runtime_lock); + &p2p_soc_obj->roc_runtime_lock); return status; } @@ -501,7 +501,7 @@ static QDF_STATUS p2p_process_scan_complete_evt( roc_ctx->roc_type, roc_ctx->roc_state); /* allow runtime suspend */ - qdf_runtime_pm_allow_suspend(p2p_soc_obj->roc_runtime_lock); + qdf_runtime_pm_allow_suspend(&p2p_soc_obj->roc_runtime_lock); if (QDF_TIMER_STATE_RUNNING == qdf_mc_timer_get_current_state(&roc_ctx->roc_timer)) { From ffe5ca51ed8b91f69ee71fed2bd348669e65e585 Mon Sep 17 00:00:00 2001 From: bings Date: Tue, 18 Jul 2017 17:40:51 +0800 Subject: [PATCH 108/404] qcacmn: Fix connection information deleting and restoring Currently only one connection information corresponding to the provided mode is deleted and restored, which causes channel selecting failure in DFS testing with AP+AP concurrency mode. When radar is found in AP+AP concurrency mode, a new valid channel should be selected. Before selecting the channel, all existing connection information of SAP mode should be deleted, otherwise no valid channel can be selected. All the connection information corresponding to the provided mode should be deleted and restored. Change-Id: Id363dbb2c31485fefcd6915696060923063079bb CRs-Fixed: 2079597 --- inc/wlan_policy_mgr_api.h | 4 +- src/wlan_policy_mgr_core.c | 87 +++++++++++++++++++++++++------------- src/wlan_policy_mgr_i.h | 7 ++- src/wlan_policy_mgr_pcl.c | 27 ++++++++---- 4 files changed, 84 insertions(+), 41 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 6c18c484edf9..06f377f5a853 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1241,6 +1241,7 @@ uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, * @len: Pointer to the length of the PCL * @pcl_weight: Pointer to the weights of the PCL * @weight_len: Max length of the weights list + * @all_matching_cxn_to_del: Need remove all entries before getting pcl * * Get the PCL for an existing connection * @@ -1249,7 +1250,8 @@ uint8_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t *pcl_ch, uint32_t *len, - uint8_t *weight_list, uint32_t weight_len); + uint8_t *weight_list, uint32_t weight_len, + bool all_matching_cxn_to_del); /** * policy_mgr_get_valid_chan_weights() - Get the weightage for diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 03fc3396196d..68d6c235ad3c 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -562,7 +562,9 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, /** * policy_mgr_store_and_del_conn_info() - Store and del a connection info * @mode: Mode whose entry has to be deleted - * @info: Struture pointer where the connection info will be saved + * @all_matching_cxn_to_del: All the specified mode entries should be deleted + * @info: Struture array pointer where the connection info will be saved + * @num_cxn_del: Number of connection which are going to be deleted * * Saves the connection info corresponding to the provided mode * and deleted that corresponding entry based on vdev from the @@ -571,18 +573,22 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, * Return: None */ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - struct policy_mgr_conc_connection_info *info) + enum policy_mgr_con_mode mode, bool all_matching_cxn_to_del, + struct policy_mgr_conc_connection_info *info, uint8_t *num_cxn_del) { - uint32_t conn_index = 0; - bool found = false; + int32_t conn_index = 0; + uint32_t found_index = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + if (!num_cxn_del) { + policy_mgr_err("num_cxn_del is NULL"); + return; + } + *num_cxn_del = 0; if (!info) { policy_mgr_err("Invalid connection info"); return; } - qdf_mem_zero(info, sizeof(*info)); pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); @@ -592,34 +598,47 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); while (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (mode == pm_conc_connection_list[conn_index].mode) { - found = true; - break; + /* + * Storing the connection entry which will be + * temporarily deleted. + */ + info[found_index] = pm_conc_connection_list[conn_index]; + /* Deleting the connection entry */ + policy_mgr_decr_connection_count(psoc, + info[found_index].vdev_id); + policy_mgr_notice("Stored %d (%d), deleted STA entry with vdev id %d, index %d", + info[found_index].vdev_id, + info[found_index].mode, + info[found_index].vdev_id, conn_index); + found_index++; + if (all_matching_cxn_to_del) + continue; + else + break; } conn_index++; } - - if (!found) { - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - policy_mgr_err("Mode:%d not available in the conn info", mode); - return; - } - - /* Storing the STA entry which will be temporarily deleted */ - *info = pm_conc_connection_list[conn_index]; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - /* Deleting the STA entry */ - policy_mgr_decr_connection_count(psoc, info->vdev_id); + if (!found_index) { + *num_cxn_del = 0; + policy_mgr_err("Mode:%d not available in the conn info", mode); + } else { + *num_cxn_del = found_index; + policy_mgr_err("Mode:%d number of conn %d temp del", + mode, *num_cxn_del); + } - policy_mgr_notice("Stored %d (%d), deleted STA entry with vdev id %d, index %d", - info->vdev_id, info->mode, info->vdev_id, conn_index); - - /* Caller should set the PCL and restore the STA entry in conn info */ + /* + * Caller should set the PCL and restore the connection entry + * in conn info. + */ } /** * policy_mgr_restore_deleted_conn_info() - Restore connection info - * @info: Saved connection info that is to be restored + * @info: An array saving connection info that is to be restored + * @num_cxn_del: Number of connection temporary deleted * * Restores the connection info of STA that was saved before * updating the PCL to the FW @@ -627,11 +646,17 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, * Return: None */ void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, - struct policy_mgr_conc_connection_info *info) + struct policy_mgr_conc_connection_info *info, + uint8_t num_cxn_del) { uint32_t conn_index; struct policy_mgr_psoc_priv_obj *pm_ctx; + if (MAX_NUMBER_OF_CONC_CONNECTIONS <= num_cxn_del || 0 == num_cxn_del) { + policy_mgr_err("Failed to restore %d/%d deleted information", + num_cxn_del, MAX_NUMBER_OF_CONC_CONNECTIONS); + return; + } pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); @@ -646,7 +671,8 @@ void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, } qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - pm_conc_connection_list[conn_index] = *info; + qdf_mem_copy(&pm_conc_connection_list[conn_index], info, + num_cxn_del * sizeof(*info)); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_notice("Restored the deleleted conn info, vdev:%d, index:%d", @@ -1157,8 +1183,10 @@ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, void policy_mgr_set_pcl_for_existing_combo( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) { - struct policy_mgr_conc_connection_info info; + struct policy_mgr_conc_connection_info + info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; enum tQDF_ADAPTER_MODE pcl_mode; + uint8_t num_cxn_del = 0; switch (mode) { case PM_STA_MODE: @@ -1183,12 +1211,13 @@ void policy_mgr_set_pcl_for_existing_combo( if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { /* Check, store and temp delete the mode's parameter */ - policy_mgr_store_and_del_conn_info(psoc, mode, &info); + policy_mgr_store_and_del_conn_info(psoc, mode, false, + info, &num_cxn_del); /* Set the PCL to the FW since connection got updated */ policy_mgr_pdev_set_pcl(psoc, pcl_mode); policy_mgr_notice("Set PCL to FW for mode:%d", mode); /* Restore the connection info */ - policy_mgr_restore_deleted_conn_info(psoc, &info); + policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 7d3f4e4a03e6..662dfed033b5 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -334,9 +334,12 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, bool in_use); void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - struct policy_mgr_conc_connection_info *info); + bool all_matching_cxn_to_del, + struct policy_mgr_conc_connection_info *info, + uint8_t *num_cxn_del); void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, - struct policy_mgr_conc_connection_info *info); + struct policy_mgr_conc_connection_info *info, + uint8_t num_cxn_del); void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc, uint32_t num_vdev_mac_entries, struct policy_mgr_vdev_mac_map *vdev_mac_map, diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index b12d66b2164c..f328dd1a7617 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -68,9 +68,12 @@ policy_mgr_next_action_three_connection_table_type QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t *pcl_ch, uint32_t *len, - uint8_t *pcl_weight, uint32_t weight_len) + uint8_t *pcl_weight, uint32_t weight_len, + bool all_matching_cxn_to_del) { - struct policy_mgr_conc_connection_info info; + struct policy_mgr_conc_connection_info + info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; + uint8_t num_cxn_del = 0; QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -78,13 +81,14 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { /* Check, store and temp delete the mode's parameter */ - policy_mgr_store_and_del_conn_info(psoc, mode, &info); + policy_mgr_store_and_del_conn_info(psoc, mode, + all_matching_cxn_to_del, info, &num_cxn_del); /* Get the PCL */ status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, pcl_weight, weight_len); policy_mgr_notice("Get PCL to FW for mode:%d", mode); /* Restore the connection info */ - policy_mgr_restore_deleted_conn_info(psoc, &info); + policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } return status; @@ -1283,7 +1287,8 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl_for_existing_conn( psoc, mode, &pcl_channels[0], &pcl_len, - pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) + pcl_weight, QDF_ARRAY_SIZE(pcl_weight), + false)) return channel; } else { if (QDF_STATUS_SUCCESS != policy_mgr_get_pcl(psoc, mode, @@ -1464,7 +1469,8 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, status = policy_mgr_get_pcl_for_existing_conn(psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len, - pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); + pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list), + false); if (QDF_IS_STATUS_ERROR(status)) { policy_mgr_err("Unable to get PCL for SAP"); return status; @@ -1504,7 +1510,9 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, struct policy_mgr_pcl_chan_weights *weight) { uint32_t i, j; - struct policy_mgr_conc_connection_info info; + struct policy_mgr_conc_connection_info + info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; + uint8_t num_cxn_del = 0; if (!weight->pcl_list) { policy_mgr_err("Invalid pcl"); @@ -1532,7 +1540,8 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, * check can be used as though a new connection is coming up, * allowing to detect the disallowed channels. */ - policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, &info); + policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, false, + info, &num_cxn_del); /* * There is a small window between releasing the above lock * and acquiring the same in policy_mgr_allow_concurrency, @@ -1548,7 +1557,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, } /* Restore the connection info */ - policy_mgr_restore_deleted_conn_info(psoc, &info); + policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } for (i = 0; i < weight->saved_num_chan; i++) { From 3583d566d26252a2415560de4e0123e3bd4a64aa Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 24 Jul 2017 18:20:11 -0700 Subject: [PATCH 109/404] 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 c989ebe26ede8df389b7e7f848d10d10acdca5e2 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 9 Aug 2017 15:51:21 -0700 Subject: [PATCH 110/404] qcacmn: Relax the check on nss field during HW mode table lookup Relax the check on nss field during FW advertised HW mode table lookup. Instead of looking for exact match look for less than or equal to the FW advertised nss value. Change-Id: I360d14282f03aad25f4338546cbcbfb3cbd3a76b CRs-Fixed: 2090863 --- src/wlan_policy_mgr_core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 68d6c235ad3c..924997fcf726 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -324,12 +324,12 @@ int8_t policy_mgr_get_matching_hw_mode_index( for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { t_mac0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET( pm_ctx->hw_mode.hw_mode_list[i]); - if (t_mac0_tx_ss != mac0_tx_ss) + if (t_mac0_tx_ss < mac0_tx_ss) continue; t_mac0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET( pm_ctx->hw_mode.hw_mode_list[i]); - if (t_mac0_rx_ss != mac0_rx_ss) + if (t_mac0_rx_ss < mac0_rx_ss) continue; t_mac0_bw = POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET( @@ -344,12 +344,12 @@ int8_t policy_mgr_get_matching_hw_mode_index( t_mac1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET( pm_ctx->hw_mode.hw_mode_list[i]); - if (t_mac1_tx_ss != mac1_tx_ss) + if (t_mac1_tx_ss < mac1_tx_ss) continue; t_mac1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET( pm_ctx->hw_mode.hw_mode_list[i]); - if (t_mac1_rx_ss != mac1_rx_ss) + if (t_mac1_rx_ss < mac1_rx_ss) continue; t_mac1_bw = POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET( From 42b8067e18861c19107903dfd3b2349a0be6f9c3 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Mon, 21 Aug 2017 13:01:21 -0700 Subject: [PATCH 111/404] qcacmn: Fix the use of uninitialized variable in policy manager Initialize the uninitialized variable in policy_mgr_get_channel_from_scan_result(). Change-Id: I435e6021b989562b69b3bccaa9a90d9cfd3ae560 CRs-Fixed: 2091884 --- src/wlan_policy_mgr_get_set_utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 1b64f22c45e5..a93c6c31db21 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1705,7 +1705,7 @@ QDF_STATUS policy_mgr_get_channel_from_scan_result( struct wlan_objmgr_psoc *psoc, void *roam_profile, uint8_t *channel) { - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_E_FAILURE; void *scan_cache = NULL; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1729,6 +1729,7 @@ QDF_STATUS policy_mgr_get_channel_from_scan_result( } } else { policy_mgr_err("sme_get_ap_channel_from_scan_cache NULL"); + return QDF_STATUS_E_FAILURE; } if (pm_ctx->sme_cbacks.sme_scan_result_purge) From ecc6e108b13f530230f32aa65b1e68d605f7c347 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 26 May 2017 18:25:56 -0700 Subject: [PATCH 112/404] qcacmn: Expand the use of gDualMacFeatureDisable INI Few OEMs want DBS to be disabled for connections while keeping DBS scan enabled. Few OEMs want advance DBS scan features to be disabled. Provide different value to gDualMacFeatureDisable INI item to achive the goal. Change-Id: Iddf5df23575a2f907bb8dbd0c37e03ff4ebbdea8 CRs-Fixed: 2068779 --- inc/wlan_policy_mgr_api.h | 24 ++++++++---- inc/wlan_policy_mgr_public_struct.h | 20 ++++++++++ src/wlan_policy_mgr_core.c | 24 +++++++++++- src/wlan_policy_mgr_get_set_utils.c | 61 ++++++++++++++++++++++++++++- 4 files changed, 118 insertions(+), 11 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 06f377f5a853..bbcb7e4c295f 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1709,14 +1709,7 @@ enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( * * Return: True if master DBS control is enabled */ -static inline bool policy_mgr_is_scan_simultaneous_capable( - struct wlan_objmgr_psoc *psoc) -{ - if (policy_mgr_is_hw_dbs_capable(psoc)) - return true; - - return false; -} +bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc); /** * policy_mgr_is_mcc_adaptive_scheduler_enabled() - Function to @@ -1924,4 +1917,19 @@ uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, * Return: true for success, else false */ bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev); + +/** + * policy_mgr_get_updated_scan_and_fw_mode_config() - Function + * to get latest scan & fw config for DBS + * @psoc: PSOC object information + * @scan_config: DBS related scan config + * @fw_mode_config: DBS related FW config + * @dual_mac_disable_ini: DBS related ini config + * This function returns the latest DBS configuration for + * connection & scan, sent to FW + * Return: SUCCESS or FAILURE + */ +QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( + struct wlan_objmgr_psoc *psoc, uint32_t *scan_config, + uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index f0c73e983817..b10adbaff31a 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -794,6 +794,26 @@ enum policy_mgr_hw_mode_change { POLICY_MGR_SBS_IN_PROGRESS }; +/** + * enum dbs_support - structure to define INI values and their meaning + * + * @ENABLE_DBS_CXN_AND_SCAN: Enable DBS support for connection and scan + * @DISABLE_DBS_CXN_AND_SCAN: Disable DBS support for connection and scan + * @DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN: disable dbs support for + * connection but keep dbs support for scan + * @DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF: disable dbs support + * for connection but keep dbs for scan but switch off the async scan + * @ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF: enable dbs support for + * connection and scan but switch off the async scan + */ +enum dbs_support { + ENABLE_DBS_CXN_AND_SCAN, + DISABLE_DBS_CXN_AND_SCAN, + DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN, + DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF, + ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF, +}; + /** * struct policy_mgr_conc_connection_info - information of all existing * connections in the wlan system diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 924997fcf726..c284a9647f85 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -136,12 +136,32 @@ QDF_STATUS policy_mgr_get_updated_fw_mode_config( * * Checks if the dual mac feature is disabled in INI * - * Return: true if the dual mac feature is disabled from INI + * Return: true if the dual mac connection is disabled from INI */ bool policy_mgr_is_dual_mac_disabled_in_ini( struct wlan_objmgr_psoc *psoc) { - return wlan_objmgr_psoc_get_dual_mac_disable(psoc); + bool is_disabled = false; + enum dbs_support dbs_type = wlan_objmgr_psoc_get_dual_mac_disable(psoc); + + /* + * If DBS support for connection is disabled through INI then assume + * that DBS is not supported, so that policy manager takes + * the decision considering non-dbs cases only. + * + * For DBS scan check the INI value explicitly + */ + switch (dbs_type) { + case DISABLE_DBS_CXN_AND_SCAN: + case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN: + case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF: + is_disabled = true; + break; + default: + break; + } + + return is_disabled; } uint32_t policy_mgr_mcc_to_scc_switch_mode_in_user_cfg( diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 1b64f22c45e5..a2561f5b038e 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -375,13 +375,20 @@ void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc, /* If dual mac features are disabled in the INI, we * need not proceed further */ - if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) { + if (DISABLE_DBS_CXN_AND_SCAN == + wlan_objmgr_psoc_get_dual_mac_disable(psoc)) { policy_mgr_err("Disabling dual mac capabilities"); /* All capabilites are initialized to 0. We can return */ goto done; } /* Initialize concurrent_scan_config_bits with default FW value */ + WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET( + pm_ctx->dual_mac_cfg.cur_scan_config, + WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_GET(scan_config)); + WMI_DBS_CONC_SCAN_CFG_SYNC_DBS_SCAN_SET( + pm_ctx->dual_mac_cfg.cur_scan_config, + WMI_DBS_CONC_SCAN_CFG_SYNC_DBS_SCAN_GET(scan_config)); WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET( pm_ctx->dual_mac_cfg.cur_scan_config, WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_GET(scan_config)); @@ -399,6 +406,9 @@ void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc, WMI_DBS_FW_MODE_CFG_AGILE_DFS_SET( pm_ctx->dual_mac_cfg.cur_fw_mode_config, WMI_DBS_FW_MODE_CFG_AGILE_DFS_GET(fw_config)); + WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET( + pm_ctx->dual_mac_cfg.cur_fw_mode_config, + WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_GET(fw_config)); done: /* Initialize the previous scan/fw mode config */ pm_ctx->dual_mac_cfg.prev_scan_config = @@ -2567,3 +2577,52 @@ uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, return final_max_rf_chains; } + +bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc) +{ + if (DISABLE_DBS_CXN_AND_SCAN != + wlan_objmgr_psoc_get_dual_mac_disable(psoc)) + return true; + + return false; +} + +QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( + struct wlan_objmgr_psoc *psoc, uint32_t *scan_config, + uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + *scan_config = pm_ctx->dual_mac_cfg.cur_scan_config; + *fw_mode_config = pm_ctx->dual_mac_cfg.cur_fw_mode_config; + switch (dual_mac_disable_ini) { + case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF: + policy_mgr_debug("dual_mac_disable_ini:%d async/dbs off", + dual_mac_disable_ini); + WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0); + WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(*fw_mode_config, 0); + break; + case DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN: + policy_mgr_debug("dual_mac_disable_ini:%d dbs_cxn off", + dual_mac_disable_ini); + WMI_DBS_FW_MODE_CFG_DBS_FOR_CXN_SET(*fw_mode_config, 0); + break; + case ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF: + policy_mgr_debug("dual_mac_disable_ini:%d async off", + dual_mac_disable_ini); + WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0); + break; + default: + break; + } + policy_mgr_debug("*scan_config:%x ", *scan_config); + policy_mgr_debug("*fw_mode_config:%x ", *fw_mode_config); + + return QDF_STATUS_SUCCESS; +} From 8b60ebb5c6182322fa4a842fd3e667e7bcc0c2f6 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 17 Aug 2017 14:53:07 -0700 Subject: [PATCH 113/404] qcacmn: Reduce log spam from policy manager Reduce log spam from policy manager by converting non essential & periodic logs to debug level. Change-Id: I3cb01b47dd56edcf141479b14ea1e51e89b0473a CRs-Fixed: 2094743 --- src/wlan_policy_mgr_action.c | 26 +++++++-------- src/wlan_policy_mgr_core.c | 34 ++++++++++---------- src/wlan_policy_mgr_get_set_utils.c | 50 ++++++++++++++--------------- src/wlan_policy_mgr_pcl.c | 8 ++--- 4 files changed, 59 insertions(+), 59 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 8c6b08c563f0..358c25428ee0 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -59,11 +59,11 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, return; } - policy_mgr_notice("old_hw_mode_index=%d, new_hw_mode_index=%d", + policy_mgr_debug("old_hw_mode_index=%d, new_hw_mode_index=%d", old_hw_mode_index, new_hw_mode_index); for (i = 0; i < num_vdev_mac_entries; i++) - policy_mgr_notice("vdev_id:%d mac_id:%d", + policy_mgr_debug("vdev_id:%d mac_id:%d", vdev_mac_map[i].vdev_id, vdev_mac_map[i].mac_id); @@ -74,11 +74,11 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, return; } - policy_mgr_notice("MAC0: TxSS:%d, RxSS:%d, Bw:%d", + policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d", hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, hw_mode.mac0_bw); - policy_mgr_notice("MAC1: TxSS:%d, RxSS:%d, Bw:%d", + policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d", hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, hw_mode.mac1_bw); - policy_mgr_notice("DBS:%d, Agile DFS:%d, SBS:%d", + policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d", hw_mode.dbs_cap, hw_mode.agile_dfs_cap, hw_mode.sbs_cap); /* update pm_conc_connection_list */ @@ -116,11 +116,11 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, * allow to request FW for 2x2 */ if ((HW_MODE_SS_2x2 == mac0_ss) && (!pm_ctx->user_cfg.enable2x2)) { - policy_mgr_notice("2x2 is not allowed downgrading to 1x1 for mac0"); + policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac0"); mac0_ss = HW_MODE_SS_1x1; } if ((HW_MODE_SS_2x2 == mac1_ss) && (!pm_ctx->user_cfg.enable2x2)) { - policy_mgr_notice("2x2 is not allowed downgrading to 1x1 for mac1"); + policy_mgr_debug("2x2 is not allowed downgrading to 1x1 for mac1"); mac1_ss = HW_MODE_SS_1x1; } @@ -137,7 +137,7 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, msg.session_id = session_id; msg.context = psoc; - policy_mgr_notice("set hw mode to sme: hw_mode_index: %d session:%d reason:%d", + policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d", msg.hw_mode_index, msg.session_id, msg.reason); status = pm_ctx->sme_cbacks.sme_pdev_set_hw_mode(msg); @@ -884,7 +884,7 @@ QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( goto done; } - policy_mgr_notice("action:%d session id:%d", action, session_id); + policy_mgr_debug("action:%d session id:%d", action, session_id); /* Opportunistic timer is started, PM will check if MCC upgrade can be * done on timer expiry. This avoids any possible ping pong effect @@ -894,7 +894,7 @@ QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( qdf_status = policy_mgr_restart_opportunistic_timer( psoc, false); if (QDF_IS_STATUS_SUCCESS(qdf_status)) - policy_mgr_notice("opportunistic timer for MCC upgrade"); + policy_mgr_debug("opportunistic timer for MCC upgrade"); goto done; } @@ -928,7 +928,7 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_conc_connection_list[i].chan)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - policy_mgr_notice("DBS required"); + policy_mgr_debug("DBS required"); return; } } @@ -1049,7 +1049,7 @@ QDF_STATUS policy_mgr_update_connection_info_utfw( vdev_id); return status; } - policy_mgr_notice("--> updating entry at index[%d]", conn_index); + policy_mgr_debug("--> updating entry at index[%d]", conn_index); policy_mgr_update_conc_list(psoc, conn_index, policy_mgr_get_mode(type, sub_type), @@ -1074,7 +1074,7 @@ QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, MAX_NUMBER_OF_CONC_CONNECTIONS); return status; } - policy_mgr_notice("--> filling entry at index[%d]", conn_index); + policy_mgr_debug("--> filling entry at index[%d]", conn_index); policy_mgr_update_conc_list(psoc, conn_index, policy_mgr_get_mode(type, sub_type), diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 924997fcf726..0cc4d412292e 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -373,7 +373,7 @@ int8_t policy_mgr_get_matching_hw_mode_index( continue; found = i; - policy_mgr_notice("hw_mode index %d found", i); + policy_mgr_debug("hw_mode index %d found", i); break; } return found; @@ -410,11 +410,11 @@ int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list( policy_mgr_get_tx_rx_ss_from_config(mac0_ss, &mac0_tx_ss, &mac0_rx_ss); policy_mgr_get_tx_rx_ss_from_config(mac1_ss, &mac1_tx_ss, &mac1_rx_ss); - policy_mgr_notice("MAC0: TxSS=%d, RxSS=%d, BW=%d", + policy_mgr_debug("MAC0: TxSS=%d, RxSS=%d, BW=%d", mac0_tx_ss, mac0_rx_ss, mac0_bw); - policy_mgr_notice("MAC1: TxSS=%d, RxSS=%d, BW=%d", + policy_mgr_debug("MAC1: TxSS=%d, RxSS=%d, BW=%d", mac1_tx_ss, mac1_rx_ss, mac1_bw); - policy_mgr_notice("DBS=%d, Agile DFS=%d, SBS=%d", + policy_mgr_debug("DBS=%d, Agile DFS=%d, SBS=%d", dbs, dfs, sbs); return policy_mgr_get_matching_hw_mode_index(psoc, mac0_tx_ss, @@ -675,7 +675,7 @@ void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, num_cxn_del * sizeof(*info)); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - policy_mgr_notice("Restored the deleleted conn info, vdev:%d, index:%d", + policy_mgr_debug("Restored the deleleted conn info, vdev:%d, index:%d", info->vdev_id, conn_index); } @@ -719,7 +719,7 @@ void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc, if (found) { pm_conc_connection_list[conn_index].mac = vdev_mac_map[i].mac_id; - policy_mgr_notice("vdev:%d, mac:%d", + policy_mgr_debug("vdev:%d, mac:%d", pm_conc_connection_list[conn_index].vdev_id, pm_conc_connection_list[conn_index].mac); if (pm_ctx->cdp_cbacks.cdp_update_mac_id) @@ -769,10 +769,10 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, return; } - policy_mgr_notice("cfgd_hw_mode_index=%d", cfgd_hw_mode_index); + policy_mgr_debug("cfgd_hw_mode_index=%d", cfgd_hw_mode_index); for (i = 0; i < num_vdev_mac_entries; i++) - policy_mgr_notice("vdev_id:%d mac_id:%d", + policy_mgr_debug("vdev_id:%d mac_id:%d", vdev_mac_map[i].vdev_id, vdev_mac_map[i].mac_id); @@ -783,11 +783,11 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, return; } - policy_mgr_notice("MAC0: TxSS:%d, RxSS:%d, Bw:%d", + policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d", hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, hw_mode.mac0_bw); - policy_mgr_notice("MAC1: TxSS:%d, RxSS:%d, Bw:%d", + policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d", hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, hw_mode.mac1_bw); - policy_mgr_notice("DBS:%d, Agile DFS:%d, SBS:%d", + policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d", hw_mode.dbs_cap, hw_mode.agile_dfs_cap, hw_mode.sbs_cap); /* update pm_conc_connection_list */ @@ -1168,7 +1168,7 @@ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, if (status != QDF_STATUS_SUCCESS) policy_mgr_err("Send soc set PCL to SME failed"); else - policy_mgr_notice("Set PCL to FW for mode:%d", mode); + policy_mgr_debug("Set PCL to FW for mode:%d", mode); } @@ -1215,7 +1215,7 @@ void policy_mgr_set_pcl_for_existing_combo( info, &num_cxn_del); /* Set the PCL to the FW since connection got updated */ policy_mgr_pdev_set_pcl(psoc, pcl_mode); - policy_mgr_notice("Set PCL to FW for mode:%d", mode); + policy_mgr_debug("Set PCL to FW for mode:%d", mode); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } @@ -1242,7 +1242,7 @@ void pm_dbs_opportunistic_timer_handler(void *data) /* if we still need it */ action = policy_mgr_need_opportunistic_upgrade(psoc); - policy_mgr_notice("action:%d", action); + policy_mgr_debug("action:%d", action); if (action) { /* lets call for action */ /* session id is being used only @@ -1697,7 +1697,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, if (PM_NONE == pcl) { /* msg */ - policy_mgr_notice("pcl is 0"); + policy_mgr_debug("pcl is 0"); return QDF_STATUS_SUCCESS; } /* get the channel list for current domain */ @@ -1714,7 +1714,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, if (((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) && (policy_mgr_mode_specific_connection_count( psoc, PM_STA_MODE, NULL) > 0)) { - policy_mgr_notice("STA present, skip DFS channels from pcl for SAP/Go"); + policy_mgr_debug("STA present, skip DFS channels from pcl for SAP/Go"); skip_dfs_channel = true; } @@ -2082,7 +2082,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, } if ((*len != 0) && (*len != i)) - policy_mgr_notice("pcl len (%d) and weight list len mismatch (%d)", + policy_mgr_debug("pcl len (%d) and weight list len mismatch (%d)", *len, i); /* check the channel avoidance list */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 1b64f22c45e5..e558971f1694 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -256,7 +256,7 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, if (pm_ctx->hw_mode.hw_mode_list) { qdf_mem_free(pm_ctx->hw_mode.hw_mode_list); pm_ctx->hw_mode.hw_mode_list = NULL; - policy_mgr_err("DBS list is freed"); + policy_mgr_debug("DBS list is freed"); } pm_ctx->num_dbs_hw_modes = phy_caps->num_hw_modes.num_hw_modes; @@ -268,7 +268,7 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - policy_mgr_err("Updated HW mode list: Num modes:%d", + policy_mgr_debug("Updated HW mode list: Num modes:%d", pm_ctx->num_dbs_hw_modes); for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { @@ -343,17 +343,17 @@ void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc) for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { param = pm_ctx->hw_mode.hw_mode_list[i]; - policy_mgr_err("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d", + policy_mgr_debug("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d", i, POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param), POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param), POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param)); - policy_mgr_err("[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d", + policy_mgr_debug("[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d", i, POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param), POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param), POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param)); - policy_mgr_err("[%d] DBS:%d SBS:%d", i, + policy_mgr_debug("[%d] DBS:%d SBS:%d", i, POLICY_MGR_HW_MODE_DBS_MODE_GET(param), POLICY_MGR_HW_MODE_SBS_MODE_GET(param)); } @@ -522,11 +522,11 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) } if (!policy_mgr_is_dbs_enable(psoc)) { - policy_mgr_notice("DBS is disabled"); + policy_mgr_debug("DBS is disabled"); return false; } if (pm_ctx->wma_cbacks.wma_is_service_enabled) { - policy_mgr_notice("DBS service bit map: %d", + policy_mgr_debug("DBS service bit map: %d", pm_ctx->wma_cbacks.wma_is_service_enabled( WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); @@ -542,9 +542,9 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { param = pm_ctx->hw_mode.hw_mode_list[i]; - policy_mgr_notice("HW param: %x", param); + policy_mgr_debug("HW param: %x", param); if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) { - policy_mgr_notice("HW (%d) is DBS capable", i); + policy_mgr_debug("HW (%d) is DBS capable", i); found = 1; break; } @@ -567,7 +567,7 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) return false; } if (pm_ctx->wma_cbacks.wma_is_service_enabled) { - policy_mgr_notice("DBS service bit map: %d", + policy_mgr_debug("DBS service bit map: %d", pm_ctx->wma_cbacks.wma_is_service_enabled( WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); @@ -583,9 +583,9 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { param = pm_ctx->hw_mode.hw_mode_list[i]; - policy_mgr_notice("HW param: %x", param); + policy_mgr_debug("HW param: %x", param); if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) { - policy_mgr_notice("HW (%d) is SBS capable", i); + policy_mgr_debug("HW (%d) is SBS capable", i); found = 1; break; } @@ -652,7 +652,7 @@ QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc, (dbs_mode == HW_MODE_DBS)) && (found_one_by_one < 0)) { found_one_by_one = i; - policy_mgr_notice("1x1 hw_mode index %d found", i); + policy_mgr_debug("1x1 hw_mode index %d found", i); /* Once an entry is found, need not check for 1x1 * again */ @@ -666,7 +666,7 @@ QDF_STATUS policy_mgr_get_dbs_hw_modes(struct wlan_objmgr_psoc *psoc, (dbs_mode == HW_MODE_DBS)) && (found_two_by_two < 0)) { found_two_by_two = i; - policy_mgr_notice("2x2 hw_mode index %d found", i); + policy_mgr_debug("2x2 hw_mode index %d found", i); /* Once an entry is found, need not check for 2x2 * again */ @@ -688,7 +688,7 @@ QDF_STATUS policy_mgr_get_current_hw_mode(struct wlan_objmgr_psoc *psoc, QDF_STATUS status; uint32_t old_hw_index = 0, new_hw_index = 0; - policy_mgr_notice("Get the current hw mode"); + policy_mgr_debug("Get the current hw mode"); status = policy_mgr_get_old_and_new_hw_index(psoc, &old_hw_index, &new_hw_index); @@ -869,7 +869,7 @@ void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, uint32_t scan_config, uint32_t fw_mode_config) { - policy_mgr_notice("Status:%d for scan_config:%x fw_mode_config:%x", + policy_mgr_debug("Status:%d for scan_config:%x fw_mode_config:%x", status, scan_config, fw_mode_config); } @@ -918,7 +918,7 @@ void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc, cfg.set_dual_mac_cb = (void *)policy_mgr_soc_set_dual_mac_cfg_cb; - policy_mgr_notice("scan_config:%x fw_mode_config:%x", + policy_mgr_debug("scan_config:%x fw_mode_config:%x", cfg.scan_config, cfg.fw_mode_config); status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg); @@ -965,7 +965,7 @@ void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc, cfg.set_dual_mac_cb = (void *)policy_mgr_soc_set_dual_mac_cfg_cb; - policy_mgr_notice("scan_config:%x fw_mode_config:%x", + policy_mgr_debug("scan_config:%x fw_mode_config:%x", cfg.scan_config, cfg.fw_mode_config); status = pm_ctx->sme_cbacks.sme_soc_set_dual_mac_config(cfg); @@ -1118,7 +1118,7 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, } - policy_mgr_notice("No.# of active sessions for mode %d = %d", + policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); /* * Get PCL logic makes use of the connection info structure. @@ -1130,7 +1130,7 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, /* Set PCL of STA to the FW */ policy_mgr_pdev_set_pcl(psoc, mode); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - policy_mgr_notice("Set PCL of STA to FW"); + policy_mgr_debug("Set PCL of STA to FW"); } policy_mgr_incr_connection_count(psoc, session_id); if ((policy_mgr_mode_specific_connection_count( @@ -1185,7 +1185,7 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, break; } - policy_mgr_notice("No.# of active sessions for mode %d = %d", + policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); policy_mgr_decr_connection_count(psoc, session_id); @@ -1261,7 +1261,7 @@ QDF_STATUS policy_mgr_incr_connection_count( conn_table_entry.mac_id, chain_mask, nss, vdev_id, true); - policy_mgr_notice("Add at idx:%d vdev %d mac=%d", + policy_mgr_debug("Add at idx:%d vdev %d mac=%d", conn_index, vdev_id, conn_table_entry.mac_id); @@ -1386,7 +1386,7 @@ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, status = true; } else { *ibss_channel = pm_conc_connection_list[list[index]].chan; - policy_mgr_notice("Multiple IBSS connections, picking first one"); + policy_mgr_debug("Multiple IBSS connections, picking first one"); status = true; } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); @@ -1418,7 +1418,7 @@ bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, psoc, mode, list); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (count == 0) { - policy_mgr_err("No mode:[%d] connection", mode); + policy_mgr_debug("No mode:[%d] connection", mode); status = false; } else if (count == 1) { *channel = pm_conc_connection_list[list[index]].chan; @@ -1434,7 +1434,7 @@ bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, *channel = pm_conc_connection_list[list[index]].chan; *vdev_id = pm_conc_connection_list[list[index]].vdev_id; - policy_mgr_notice("Multiple mode:[%d] connections, picking first one", + policy_mgr_debug("Multiple mode:[%d] connections, picking first one", mode); status = true; } diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index f328dd1a7617..9ac167e088d6 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -77,7 +77,7 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, QDF_STATUS status = QDF_STATUS_SUCCESS; - policy_mgr_notice("get pcl for existing conn:%d", mode); + policy_mgr_debug("get pcl for existing conn:%d", mode); if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { /* Check, store and temp delete the mode's parameter */ @@ -86,7 +86,7 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, /* Get the PCL */ status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, pcl_weight, weight_len); - policy_mgr_notice("Get PCL to FW for mode:%d", mode); + policy_mgr_debug("Get PCL to FW for mode:%d", mode); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } @@ -1480,7 +1480,7 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, * coming up. */ if (!pcl.pcl_len) { - policy_mgr_notice("policy_mgr_get_pcl_for_existing_conn returned no pcl"); + policy_mgr_debug("policy_mgr_get_pcl_for_existing_conn returned no pcl"); status = policy_mgr_get_pcl(psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len, pcl.weight_list, @@ -1501,7 +1501,7 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, } *chan = pcl.pcl_list[0]; - policy_mgr_notice("mandatory channel:%d", *chan); + policy_mgr_debug("mandatory channel:%d", *chan); return QDF_STATUS_SUCCESS; } From 05328bb022b1a797092386854ec991f781d228bc Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 27 Apr 2017 12:31:41 -0700 Subject: [PATCH 114/404] qcacmn: Save the unsafe channels in policy manager Save the list of unsafe channels in policy manager to be used on PCL. Change-Id: Ibb705830e878d1cc03dfbc76e49c169d2febd75d CRs-Fixed: 2095290 --- inc/wlan_policy_mgr_api.h | 6 ++- src/wlan_policy_mgr_core.c | 2 +- src/wlan_policy_mgr_i.h | 23 ++++++++ src/wlan_policy_mgr_init_deinit.c | 5 ++ src/wlan_policy_mgr_pcl.c | 90 ++++++++++++++++++++++++++++++- 5 files changed, 121 insertions(+), 5 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index bbcb7e4c295f..6bd3f0bf1910 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -304,6 +304,7 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, /** * policy_mgr_update_with_safe_channel_list() - provides the safe * channel list + * @psoc: PSOC object information * @pcl_channels: channel list * @len: length of the list * @weight_list: Weights of the PCL @@ -314,8 +315,9 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, * * Return: None */ -void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels, - uint32_t *len, uint8_t *weight_list, uint32_t weight_len); +void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_channels, uint32_t *len, + uint8_t *weight_list, uint32_t weight_len); /** * policy_mgr_get_nondfs_preferred_channel() - to get non-dfs preferred channel diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 4cc43d08d608..be108750f5c4 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2106,7 +2106,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, *len, i); /* check the channel avoidance list */ - policy_mgr_update_with_safe_channel_list(pcl_channels, len, + policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, len, pcl_weights, weight_len); return status; diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 662dfed033b5..d27b3e71add1 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -224,6 +224,8 @@ extern enum policy_mgr_conc_next_action * change is in progress * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler * value from INI + * @unsafe_channel_list: LTE coex channel avoidance list + * @unsafe_channel_count: LTE coex channel avoidance list count */ struct policy_mgr_psoc_priv_obj { struct wlan_objmgr_psoc *psoc; @@ -250,6 +252,8 @@ struct policy_mgr_psoc_priv_obj { struct dual_mac_config dual_mac_cfg; uint32_t hw_mode_change_in_progress; struct policy_mgr_user_cfg user_cfg; + uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN]; + uint16_t unsafe_channel_count; }; /** @@ -403,4 +407,23 @@ QDF_STATUS policy_mgr_reset_sap_mandatory_channels( bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, uint8_t *channel, uint8_t *vdev_id, enum policy_mgr_con_mode mode); + +/** + * policy_mgr_reg_chan_change_callback() - Callback to be + * invoked by regulatory module when valid channel list changes + * @psoc: PSOC object information + * @pdev: PDEV object information + * @chan_list: New channel list + * @avoid_freq_ind: LTE coex avoid channel list + * @arg: Information passed at registration + * + * Get updated channel list from regulatory module + * + * Return: None + */ +void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, + struct regulatory_channel *chan_list, + struct avoid_freq_ind_data *avoid_freq_ind, + void *arg); #endif diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 43f325412fdd..fd91357a3ecc 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -101,6 +101,9 @@ static QDF_STATUS policy_mgr_pdev_obj_create_cb(struct wlan_objmgr_pdev *pdev, policy_mgr_ctx->pdev = pdev; + wlan_reg_register_chan_change_callback(psoc, + policy_mgr_reg_chan_change_callback, NULL); + return QDF_STATUS_SUCCESS; } @@ -118,6 +121,8 @@ static QDF_STATUS policy_mgr_pdev_obj_destroy_cb(struct wlan_objmgr_pdev *pdev, } policy_mgr_ctx->pdev = NULL; + wlan_reg_unregister_chan_change_callback(psoc, + policy_mgr_reg_chan_change_callback); return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 9ac167e088d6..9b88c76d384b 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -142,9 +142,95 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, return; } -void policy_mgr_update_with_safe_channel_list(uint8_t *pcl_channels, - uint32_t *len, uint8_t *weight_list, uint32_t weight_len) +void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, + struct regulatory_channel *chan_list, + struct avoid_freq_ind_data *avoid_freq_ind, + void *arg) { + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + if (!avoid_freq_ind) { + policy_mgr_debug("avoid_freq_ind NULL"); + return; + } + + pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.ch_cnt >= + QDF_MAX_NUM_CHAN ? + QDF_MAX_NUM_CHAN : avoid_freq_ind->chan_list.ch_cnt; + if (pm_ctx->unsafe_channel_count) + qdf_mem_copy(pm_ctx->unsafe_channel_list, + avoid_freq_ind->chan_list.ch_list, + pm_ctx->unsafe_channel_count); + policy_mgr_debug("Channel list update, recieved %d avoided channels", + pm_ctx->unsafe_channel_count); +} + +void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_channels, uint32_t *len, + uint8_t *weight_list, uint32_t weight_len) +{ + uint8_t current_channel_list[QDF_MAX_NUM_CHAN]; + uint8_t org_weight_list[QDF_MAX_NUM_CHAN]; + uint8_t is_unsafe = 1; + uint8_t i, j; + uint32_t safe_channel_count = 0, current_channel_count = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + if (len) { + current_channel_count = QDF_MIN(*len, QDF_MAX_NUM_CHAN); + } else { + policy_mgr_err("invalid number of channel length"); + return; + } + + if (pm_ctx->unsafe_channel_count == 0) { + policy_mgr_debug("There are no unsafe channels"); + return; + } + + qdf_mem_copy(current_channel_list, pcl_channels, + current_channel_count); + qdf_mem_zero(pcl_channels, current_channel_count); + + qdf_mem_copy(org_weight_list, weight_list, QDF_MAX_NUM_CHAN); + qdf_mem_zero(weight_list, weight_len); + + for (i = 0; i < current_channel_count; i++) { + is_unsafe = 0; + for (j = 0; j < pm_ctx->unsafe_channel_count; j++) { + if (current_channel_list[i] == + pm_ctx->unsafe_channel_list[j]) { + /* Found unsafe channel, update it */ + is_unsafe = 1; + policy_mgr_warn("CH %d is not safe", + current_channel_list[i]); + break; + } + } + if (!is_unsafe) { + pcl_channels[safe_channel_count] = + current_channel_list[i]; + if (safe_channel_count < weight_len) + weight_list[safe_channel_count] = + org_weight_list[i]; + safe_channel_count++; + } + } + *len = safe_channel_count; + return; } From 0027e3f02b6f71896ee40316a0d895c1529d825d Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 5 May 2017 05:29:07 -0400 Subject: [PATCH 115/404] qcacmn: Fix hotspot starting failure When softap is stopping, there are two threads accessing the "conc_connection_list". hostapd thread (__wlan_hdd_cfg80211_stop_ap) read and modify it by cds_decr_session_set_pcl. cds_mc_thread thread (cds_get_valid_chan_weights) read and modify it by cds_store_and_del_conn_info and cds_restore_deleted_conn_info. They are not protected,which causes two same station connection info saved to the "conc_connection_list". This fix is to acquire lock before read/modify the list. Change-Id: I5f1becef711363f659044c46e69fab1cd6d07d81 CRs-Fixed: 2038000 --- src/wlan_policy_mgr_core.c | 12 +++++++++++- src/wlan_policy_mgr_pcl.c | 23 +++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index be108750f5c4..a8a92b446df3 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1207,6 +1207,13 @@ void policy_mgr_set_pcl_for_existing_combo( info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; enum tQDF_ADAPTER_MODE pcl_mode; uint8_t num_cxn_del = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } switch (mode) { case PM_STA_MODE: @@ -1228,17 +1235,20 @@ void policy_mgr_set_pcl_for_existing_combo( policy_mgr_err("Invalid mode to set PCL"); return; }; - + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { /* Check, store and temp delete the mode's parameter */ policy_mgr_store_and_del_conn_info(psoc, mode, false, info, &num_cxn_del); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* Set the PCL to the FW since connection got updated */ policy_mgr_pdev_set_pcl(psoc, pcl_mode); policy_mgr_debug("Set PCL to FW for mode:%d", mode); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } /** diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 9b88c76d384b..09b4009d70f4 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -76,20 +76,30 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, uint8_t num_cxn_del = 0; QDF_STATUS status = QDF_STATUS_SUCCESS; + struct policy_mgr_psoc_priv_obj *pm_ctx; policy_mgr_debug("get pcl for existing conn:%d", mode); + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { /* Check, store and temp delete the mode's parameter */ policy_mgr_store_and_del_conn_info(psoc, mode, all_matching_cxn_to_del, info, &num_cxn_del); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* Get the PCL */ status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len, pcl_weight, weight_len); policy_mgr_debug("Get PCL to FW for mode:%d", mode); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); return status; } @@ -1599,6 +1609,13 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, struct policy_mgr_conc_connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; uint8_t num_cxn_del = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } if (!weight->pcl_list) { policy_mgr_err("Invalid pcl"); @@ -1617,7 +1634,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, qdf_mem_set(weight->weighed_valid_list, QDF_MAX_NUM_CHAN, WEIGHT_OF_DISALLOWED_CHANNELS); - + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (policy_mgr_mode_specific_connection_count( psoc, PM_STA_MODE, NULL) > 0) { /* @@ -1628,6 +1645,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, */ policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, false, info, &num_cxn_del); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); /* * There is a small window between releasing the above lock * and acquiring the same in policy_mgr_allow_concurrency, @@ -1641,10 +1659,11 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, WEIGHT_OF_NON_PCL_CHANNELS; } } - + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); /* Restore the connection info */ policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del); } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); for (i = 0; i < weight->saved_num_chan; i++) { for (j = 0; j < weight->pcl_len; j++) { From 08a833946d522c17b96413063d272ac5065ef1e9 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 28 Jun 2017 13:28:49 -0700 Subject: [PATCH 116/404] qcacmn: Add logic to force SCC in SAP+STA concurrency If SAP is up & STA comes up or moves to a DFS or passive or LTE unsafe channel that causes MCC, move SAP to the other band if DBS is supported. This logic is enabled only if gWlanMccToSccSwitchMode is non zero. Change-Id: I56f78dfaedec31c4c41aea6ac8c66261c9ad4c91 CRs-Fixed: 2063060 --- inc/wlan_policy_mgr_api.h | 13 ++++++++ src/wlan_policy_mgr_action.c | 58 +++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 6bd3f0bf1910..b5fbfb5ecd64 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1934,4 +1934,17 @@ bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev); QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( struct wlan_objmgr_psoc *psoc, uint32_t *scan_config, uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini); + +/** + * policy_mgr_is_safe_channel - Check if the channel is in LTE + * coex channel avoidance list + * @psoc: PSOC object information + * @channel: channel to be checked + * + * Check if the channel is in LTE coex channel avoidance list. + * + * Return: true for success, else false + */ +bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, + uint8_t channel); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 358c25428ee0..b0d3a368609a 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -609,6 +609,36 @@ static bool policy_mgr_is_restart_sap_allowed( return true; } +bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, + uint8_t channel) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + bool is_safe = true; + uint8_t j; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return is_safe; + } + + + if (pm_ctx->unsafe_channel_count == 0) { + policy_mgr_debug("There are no unsafe channels"); + return is_safe; + } + + for (j = 0; j < pm_ctx->unsafe_channel_count; j++) { + if (channel == pm_ctx->unsafe_channel_list[j]) { + is_safe = false; + policy_mgr_warn("CH %d is not safe", channel); + break; + } + } + + return is_safe; +} + /** * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case * @data: Pointer check concurrent channel work data @@ -676,6 +706,28 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) operating_channel, channel); } +static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, + uint8_t sta_channel) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return false; + } + + if (wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) || + wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) || + !policy_mgr_is_safe_channel(psoc, sta_channel)) + if (policy_mgr_is_hw_dbs_capable(psoc)) + return true; + else + return false; + else + return true; +} + /** * policy_mgr_check_concurrent_intf_and_restart_sap() - Check * concurrent change intf @@ -721,11 +773,9 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); policy_mgr_info("MCC to SCC switch: %d chan: %d", mcc_to_scc_switch, operating_channel); - if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) -#ifdef FEATURE_WLAN_STA_AP_MODE_DFS_DISABLE - && !wlan_reg_is_dfs_ch(pm_ctx->pdev, + if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && + policy_mgr_valid_sta_channel_check(psoc, operating_channel) -#endif ) { qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work, policy_mgr_check_sta_ap_concurrent_ch_intf, From a2c3b62a866b43b8acadf6e95a7967ce0621e0a9 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 3 Aug 2017 16:58:38 -0700 Subject: [PATCH 117/404] qcacmn: Add logic to force SCC in SAP+STA concurrency - Part 2 If STA is up on a a DFS or passive or LTE unsafe channel & SAP is comings up that causes MCC, move SAP to the other band if DBS is supported. This logic is enabled only if gWlanMccToSccSwitchMode is set to QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION. Change-Id: I5d393a21301f3fa838f7cf38620fb1d57ae1d57a CRs-Fixed: 2063060 --- inc/wlan_policy_mgr_api.h | 36 ++++++++++++++ src/wlan_policy_mgr_action.c | 73 +++++++++++++++++++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 16 +++++++ src/wlan_policy_mgr_i.h | 16 +++++++ src/wlan_policy_mgr_pcl.c | 50 ++++++++++++++++++-- 5 files changed, 188 insertions(+), 3 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index b5fbfb5ecd64..a5a0ef670efd 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1947,4 +1947,40 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( */ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, uint8_t channel); + +/** + * policy_mgr_is_force_scc() - checks if SCC needs to be + * mandated + * @psoc: PSOC object information + * + * This function checks if SCC needs to be mandated or not + * + * Return: True if SCC to be mandated, false otherwise + */ +bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_valid_sap_conc_channel_check() - checks & updates + * the channel SAP to come up on in case of STA+SAP concurrency + * @psoc: PSOC object information + * @con_ch: pointer to the channel on which sap will come up + * @sap_ch: initial channel for SAP + * + * This function checks & updates the channel SAP to come up on in + * case of STA+SAP concurrency + * Return: Success if SAP can come up on a channel + */ +QDF_STATUS policy_mgr_valid_sap_conc_channel_check( + struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch); + +/** + * policy_mgr_get_alternate_channel_for_sap() - Get an alternate + * channel to move the SAP to + * @psoc: PSOC object information + * + * This function returns an alternate channel for SAP to move to + * Return: The new channel for SAP + */ +uint8_t policy_mgr_get_alternate_channel_for_sap( + struct wlan_objmgr_psoc *psoc); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index b0d3a368609a..6ed459865219 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -728,6 +728,79 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, return true; } +QDF_STATUS policy_mgr_valid_sap_conc_channel_check( + struct wlan_objmgr_psoc *psoc, uint8_t *con_ch, uint8_t sap_ch) +{ + uint8_t channel = *con_ch; + uint8_t temp_channel = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + /* + * if force SCC is set, Check if conc channel is DFS + * or passive or part of LTE avoided channel list. + * In that case move SAP to other band if DBS is supported, + * return otherwise + */ + if (!policy_mgr_is_force_scc(psoc)) + return QDF_STATUS_SUCCESS; + + /* + * if interference is 0, check if it is DBS case. If DBS case + * return from here. If SCC, check further if SAP can move to + * STA's channel. + */ + if (!channel && + (sap_ch != policy_mgr_mode_specific_get_channel( + psoc, PM_STA_MODE))) + return QDF_STATUS_SUCCESS; + else if (!channel) + channel = sap_ch; + + if (policy_mgr_valid_sta_channel_check(psoc, channel)) { + if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) || + wlan_reg_is_passive_or_disable_ch( + pm_ctx->pdev, channel) || + !policy_mgr_is_safe_channel(psoc, channel)) { + if (policy_mgr_is_hw_dbs_capable(psoc)) { + temp_channel = + policy_mgr_get_alternate_channel_for_sap(psoc); + policy_mgr_debug("temp_channel is %d", + temp_channel); + if (temp_channel) { + channel = temp_channel; + } else { + if (WLAN_REG_IS_5GHZ_CH(channel)) + channel = PM_24_GHZ_CHANNEL_6; + else + channel = PM_5_GHZ_CHANNEL_36; + } + if (!policy_mgr_is_safe_channel( + psoc, channel)) { + policy_mgr_warn( + "Can't have concurrency on %d as it is not safe", + channel); + return QDF_STATUS_E_FAILURE; + } + } else { + policy_mgr_warn("Can't have concurrency on %d", + channel); + return QDF_STATUS_E_FAILURE; + } + } + } + + if (channel != sap_ch) + *con_ch = channel; + + return QDF_STATUS_SUCCESS; +} + /** * policy_mgr_check_concurrent_intf_and_restart_sap() - Check * concurrent change intf diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 0909847e1afc..ba337ab71ae1 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2627,3 +2627,19 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( return QDF_STATUS_SUCCESS; } + +bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return 0; + } + + return ((pm_ctx->user_cfg.mcc_to_scc_switch_mode == + QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) || + (pm_ctx->user_cfg.mcc_to_scc_switch_mode == + QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)); +} diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index d27b3e71add1..f285bfce9ed0 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -43,6 +43,9 @@ #define CONNECTION_UPDATE_TIMEOUT 1000 #endif +#define PM_24_GHZ_CHANNEL_6 (6) +#define PM_5_GHZ_CHANNEL_36 (36) + /** * Policy Mgr hardware mode list bit-mask definitions. * Bits 4:0, 31:29 are unused. @@ -426,4 +429,17 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, struct regulatory_channel *chan_list, struct avoid_freq_ind_data *avoid_freq_ind, void *arg); + +/** + * policy_mgr_mode_specific_get_channel() - Get channel for a + * connection type + * @psoc: PSOC object information + * @chan_list: Connection type + * + * Get channel for a connection type + * + * Return: channel number + */ +uint8_t policy_mgr_mode_specific_get_channel( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); #endif diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 09b4009d70f4..84b0197084e0 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -41,7 +41,6 @@ #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" -#define PM_24_GHZ_CHANNEL_6 (6) /** * first_connection_pcl_table - table which provides PCL for the * very first connection in the system @@ -1653,8 +1652,9 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, */ for (i = 0; i < weight->saved_num_chan; i++) { if (policy_mgr_allow_concurrency(psoc, PM_STA_MODE, - weight->saved_chan_list[i], - HW_MODE_20_MHZ)) { + weight->saved_chan_list[i], + HW_MODE_20_MHZ) && + !policy_mgr_is_force_scc(psoc)) { weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS; } @@ -1677,3 +1677,47 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } + +uint8_t policy_mgr_mode_specific_get_channel( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode) +{ + uint32_t conn_index; + uint8_t channel = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return channel; + } + /* provides the channel for the first matching mode type */ + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].mode == mode) && + pm_conc_connection_list[conn_index].in_use) { + channel = pm_conc_connection_list[conn_index].chan; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return channel; +} + +uint8_t policy_mgr_get_alternate_channel_for_sap( + struct wlan_objmgr_psoc *psoc) +{ + uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; + uint8_t pcl_weight[QDF_MAX_NUM_CHAN]; + uint8_t channel = 0; + uint32_t pcl_len; + + if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(psoc, PM_SAP_MODE, + &pcl_channels[0], &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) { + channel = pcl_channels[0]; + } + + return channel; +} From 5e026735cb2996b63b59a914519b6ac689b1294f Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 4 Aug 2017 12:39:20 -0700 Subject: [PATCH 118/404] qcacmn: Add logic to force SCC in SAP+STA concurrency with ACS If STA is up & SAP is comings up on a ACS derived channel causing MCC, move SAP to the other band if DBS is supported. This logic is enabled only if gWlanMccToSccSwitchMode is set to QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION. Change-Id: I48d809f83921292f51ca1735bff4c4d6dd339975 CRs-Fixed: 2063060 --- inc/wlan_policy_mgr_api.h | 15 +++++++++++++++ src/wlan_policy_mgr_i.h | 2 -- src/wlan_policy_mgr_pcl.c | 3 +-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index a5a0ef670efd..a96747f6fae8 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1983,4 +1983,19 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( */ uint8_t policy_mgr_get_alternate_channel_for_sap( struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_disallow_mcc() - Check for mcc + * + * @psoc: PSOC object information + * @channel: channel on which new connection is coming up + * + * When a new connection is about to come up check if current + * concurrency combination including the new connection is + * causing MCC + * + * Return: True if it is causing MCC + */ +bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, + uint8_t channel); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index f285bfce9ed0..2dcc30497b98 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -370,8 +370,6 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels, uint32_t *len, enum policy_mgr_con_mode mode, uint8_t *pcl_weights, uint32_t weight_len); -bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, - uint8_t channel); bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, uint8_t channel, uint32_t num_connections); bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 84b0197084e0..22e8a0b955d7 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1653,8 +1653,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, for (i = 0; i < weight->saved_num_chan; i++) { if (policy_mgr_allow_concurrency(psoc, PM_STA_MODE, weight->saved_chan_list[i], - HW_MODE_20_MHZ) && - !policy_mgr_is_force_scc(psoc)) { + HW_MODE_20_MHZ)) { weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS; } From 8d185ebf41632c9da9b209865da14206a6998575 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 30 Jun 2017 17:40:49 -0700 Subject: [PATCH 119/404] qcacmn: Dynamically allocate memory for work sta_ap_intf_check_work To handle back to back scheduling of sta_ap_intf_check_work, allocate the memory used by the work dynamically. Change-Id: Ibbcfafb2fadd2de1cca44086f9335dca86641f50 CRs-Fixed: 2070220 --- src/wlan_policy_mgr_action.c | 70 +++++++++++++++++++++++-------- src/wlan_policy_mgr_i.h | 63 ++++++++++++++++------------ src/wlan_policy_mgr_init_deinit.c | 6 +++ 3 files changed, 95 insertions(+), 44 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 6ed459865219..c828a3ae1491 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -598,14 +598,15 @@ static bool policy_mgr_is_restart_sap_allowed( uint32_t mcc_to_scc_switch) { if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) || - !(policy_mgr_concurrent_open_sessions_running(psoc) && - ((policy_mgr_get_concurrency_mode(psoc) == - (QDF_STA_MASK | QDF_SAP_MASK)) || - (policy_mgr_get_concurrency_mode(psoc) == - (QDF_STA_MASK | QDF_P2P_GO_MASK))))) { + !policy_mgr_concurrent_open_sessions_running(psoc) || + !((policy_mgr_get_concurrency_mode(psoc) == + (QDF_STA_MASK | QDF_SAP_MASK)) || + (policy_mgr_get_concurrency_mode(psoc) == + (QDF_STA_MASK | QDF_P2P_GO_MASK)))) { policy_mgr_err("MCC switch disabled or not concurrent STA/SAP, STA/GO"); return false; } + return true; } @@ -649,18 +650,30 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, */ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) { - struct wlan_objmgr_psoc *psoc = - (struct wlan_objmgr_psoc *) data; - struct policy_mgr_psoc_priv_obj *pm_ctx; + struct wlan_objmgr_psoc *psoc; + struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; + struct sta_ap_intf_check_work_ctx *work_info = NULL; uint32_t mcc_to_scc_switch; QDF_STATUS status; uint8_t channel, sec_ch; uint8_t operating_channel, vdev_id; + work_info = (struct sta_ap_intf_check_work_ctx *) data; + if (!work_info) { + policy_mgr_err("Invalid work_info"); + goto end; + } + + psoc = work_info->psoc; + if (!psoc) { + policy_mgr_err("Invalid psoc"); + goto end; + } + pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid context"); - return; + goto end; } mcc_to_scc_switch = policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); @@ -669,7 +682,7 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) policy_mgr_concurrent_open_sessions_running(psoc)); if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) - return; + goto end; if (policy_mgr_get_mode_specific_conn_info(psoc, &operating_channel, @@ -685,12 +698,12 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) operating_channel); } else { policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid"); - return; + goto end; } if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { policy_mgr_err("SAP restart get channel callback in NULL"); - return; + goto end; } qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); status = pm_ctx->hdd_cbacks. @@ -699,11 +712,17 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed to switch SAP channel"); - return; + goto end; } policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d", operating_channel, channel); +end: + if (work_info) { + qdf_mem_free(work_info); + if (pm_ctx) + pm_ctx->sta_ap_intf_check_work_info = NULL; + } } static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, @@ -846,15 +865,30 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); policy_mgr_info("MCC to SCC switch: %d chan: %d", mcc_to_scc_switch, operating_channel); + + if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) { + policy_mgr_debug( + "No action taken at check_concurrent_intf_and_restart_sap"); + return; + } + if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && policy_mgr_valid_sta_channel_check(psoc, operating_channel) - ) { - qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work, + && !pm_ctx->sta_ap_intf_check_work_info) { + struct sta_ap_intf_check_work_ctx *work_info; + work_info = qdf_mem_malloc( + sizeof(struct sta_ap_intf_check_work_ctx)); + pm_ctx->sta_ap_intf_check_work_info = work_info; + if (work_info) { + work_info->psoc = psoc; + qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work, policy_mgr_check_sta_ap_concurrent_ch_intf, - psoc); - qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work); - policy_mgr_info("Checking for Concurrent Change interference"); + work_info); + qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work); + policy_mgr_info( + "Checking for Concurrent Change interference"); + } } } #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */ diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 2dcc30497b98..df104a7f7af9 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -184,6 +184,15 @@ extern enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) (struct wlan_objmgr_psoc *psoc); +/** + * struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work + * related info + * @psoc: pointer to PSOC object information + */ +struct sta_ap_intf_check_work_ctx { + struct wlan_objmgr_psoc *psoc; +}; + /** * struct policy_mgr_psoc_priv_obj - Policy manager private data * @psoc: pointer to PSOC object information @@ -229,34 +238,36 @@ extern enum policy_mgr_conc_next_action * value from INI * @unsafe_channel_list: LTE coex channel avoidance list * @unsafe_channel_count: LTE coex channel avoidance list count + * @sta_ap_intf_check_work_info: Info related to sta_ap_intf_check_work */ struct policy_mgr_psoc_priv_obj { - struct wlan_objmgr_psoc *psoc; - struct wlan_objmgr_pdev *pdev; - qdf_event_t connection_update_done_evt; - qdf_mutex_t qdf_conc_list_lock; - qdf_mc_timer_t dbs_opportunistic_timer; - struct policy_mgr_hdd_cbacks hdd_cbacks; - struct policy_mgr_sme_cbacks sme_cbacks; - struct policy_mgr_wma_cbacks wma_cbacks; - struct policy_mgr_tdls_cbacks tdls_cbacks; - struct policy_mgr_cdp_cbacks cdp_cbacks; - uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; - uint32_t sap_mandatory_channels_len; - bool do_hw_mode_change; - uint32_t concurrency_mode; - uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE]; - uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE]; - qdf_work_t sta_ap_intf_check_work; - uint32_t num_dbs_hw_modes; - struct dbs_hw_mode_info hw_mode; - uint32_t old_hw_mode_index; - uint32_t new_hw_mode_index; - struct dual_mac_config dual_mac_cfg; - uint32_t hw_mode_change_in_progress; - struct policy_mgr_user_cfg user_cfg; - uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN]; - uint16_t unsafe_channel_count; + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + qdf_event_t connection_update_done_evt; + qdf_mutex_t qdf_conc_list_lock; + qdf_mc_timer_t dbs_opportunistic_timer; + struct policy_mgr_hdd_cbacks hdd_cbacks; + struct policy_mgr_sme_cbacks sme_cbacks; + struct policy_mgr_wma_cbacks wma_cbacks; + struct policy_mgr_tdls_cbacks tdls_cbacks; + struct policy_mgr_cdp_cbacks cdp_cbacks; + uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; + uint32_t sap_mandatory_channels_len; + bool do_hw_mode_change; + uint32_t concurrency_mode; + uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE]; + uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE]; + qdf_work_t sta_ap_intf_check_work; + uint32_t num_dbs_hw_modes; + struct dbs_hw_mode_info hw_mode; + uint32_t old_hw_mode_index; + uint32_t new_hw_mode_index; + struct dual_mac_config dual_mac_cfg; + uint32_t hw_mode_change_in_progress; + struct policy_mgr_user_cfg user_cfg; + uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN]; + uint16_t unsafe_channel_count; + struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info; }; /** diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index fd91357a3ecc..c20c548a7290 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -364,6 +364,12 @@ QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) policy_mgr_info("HW list is freed"); } + if (pm_ctx->sta_ap_intf_check_work_info) { + qdf_cancel_work(0, &pm_ctx->sta_ap_intf_check_work); + qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info); + pm_ctx->sta_ap_intf_check_work_info = NULL; + } + return QDF_STATUS_SUCCESS; } From c5348955ecb733448a6fc2a8ebbd34434ba74fab Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 4 Aug 2017 15:10:03 -0700 Subject: [PATCH 120/404] qcacmn: Fix logic to force SCC in SAP+STA concurrency If SAP is up & STA is coming up next(or vice versa) on a different channel causing MCC, move SAP to cause SCC or DBS. This logic is enabled only if gWlanMccToSccSwitchMode is set to QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION or QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL. Change-Id: I16615d828a285762133ee3533339320ef119b3d3 CRs-Fixed: 2063060 --- inc/wlan_policy_mgr_api.h | 13 +++++++++++++ src/wlan_policy_mgr_i.h | 13 ------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index a96747f6fae8..ffe2fe12c80c 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1998,4 +1998,17 @@ uint8_t policy_mgr_get_alternate_channel_for_sap( */ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, uint8_t channel); + +/** + * policy_mgr_mode_specific_get_channel() - Get channel for a + * connection type + * @psoc: PSOC object information + * @chan_list: Connection type + * + * Get channel for a connection type + * + * Return: channel number + */ +uint8_t policy_mgr_mode_specific_get_channel( + struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index df104a7f7af9..2b2fcd88292a 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -438,17 +438,4 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, struct regulatory_channel *chan_list, struct avoid_freq_ind_data *avoid_freq_ind, void *arg); - -/** - * policy_mgr_mode_specific_get_channel() - Get channel for a - * connection type - * @psoc: PSOC object information - * @chan_list: Connection type - * - * Get channel for a connection type - * - * Return: channel number - */ -uint8_t policy_mgr_mode_specific_get_channel( - struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); #endif From 126d7e12813f1e4236607975ef77af18d2211a21 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 13 Jul 2017 10:51:53 -0700 Subject: [PATCH 121/404] qcacmn: Handle no common channel between PCL and the favorite channel list Handle the scenario where no common channel between PCL & the favorite channel list is found. Change-Id: I560d7ef861d89f3f4a0c63afacd0ffbf6aaa976e CRs-Fixed: 2063060 --- src/wlan_policy_mgr_pcl.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 22e8a0b955d7..429873676b74 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1571,10 +1571,13 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, return status; } - /* No existing SAP connection and hence a new SAP connection might be - * coming up. + /* + * Get inside below loop if no existing SAP connection and hence a new + * SAP connection might be coming up. pcl.pcl_len can be 0 if no common + * channel between PCL & mandatory channel list as well */ - if (!pcl.pcl_len) { + if (!pcl.pcl_len && !policy_mgr_mode_specific_connection_count(psoc, + PM_SAP_MODE, NULL)) { policy_mgr_debug("policy_mgr_get_pcl_for_existing_conn returned no pcl"); status = policy_mgr_get_pcl(psoc, PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len, @@ -1595,6 +1598,11 @@ QDF_STATUS policy_mgr_get_sap_mandatory_channel(struct wlan_objmgr_psoc *psoc, return status; } + if (!pcl.pcl_len) { + policy_mgr_err("No common channel between mandatory list & PCL"); + return QDF_STATUS_E_FAILURE; + } + *chan = pcl.pcl_list[0]; policy_mgr_debug("mandatory channel:%d", *chan); From b641b5e094fe08f8e7d43dd1b3eaec997983401b Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 26 Jul 2017 12:10:43 -0700 Subject: [PATCH 122/404] qcacmn: Avoid deadlock while protecting connection list Avoid deadlock while protecting connection list during SAP channel switch. Change-Id: Ib4f8bd3e185b3dd6bd746e49645b6456dca50e96 CRs-Fixed: 2088106 --- src/wlan_policy_mgr_action.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index c828a3ae1491..bc208a838c2a 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -705,11 +705,9 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) policy_mgr_err("SAP restart get channel callback in NULL"); goto end; } - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); status = pm_ctx->hdd_cbacks. wlan_hdd_get_channel_for_sap_restart(psoc, vdev_id, &channel, &sec_ch); - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed to switch SAP channel"); goto end; From 15c3144230cd14705438621f8b84dbc5c6ed2470 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Sat, 5 Aug 2017 08:47:21 -0700 Subject: [PATCH 123/404] qcacmn: Strip out the DSRC channels while getting valid channel list Strip out the DSRC channels while getting valid channel list from sme. Change-Id: I540869a01dbc045033ba1e3623c3d237b1e5a54c CRs-Fixed: 2063060 --- src/wlan_policy_mgr_pcl.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 429873676b74..79a437ac0342 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -40,6 +40,7 @@ #include "qdf_types.h" #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" +#include "wlan_utility.h" /** * first_connection_pcl_table - table which provides PCL for the @@ -1404,6 +1405,22 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, return channel; } +static void policy_mgr_remove_dsrc_channels(uint8_t *chan_list, + uint32_t *num_channels) +{ + uint32_t num_chan_temp = 0; + int i; + + for (i = 0; i < *num_channels; i++) { + if (!wlan_is_dsrc_channel(wlan_chan_to_freq(chan_list[i]))) { + chan_list[num_chan_temp] = chan_list[i]; + num_chan_temp++; + } + } + + *num_channels = num_chan_temp; +} + QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, uint8_t *chan_list, uint32_t *list_len) { @@ -1432,6 +1449,8 @@ QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, return status; } + policy_mgr_remove_dsrc_channels(chan_list, list_len); + return QDF_STATUS_SUCCESS; } From 5d284f7b1ae21fd4c173dd3cfac133943551d4ca Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Mon, 10 Jul 2017 16:27:19 -0700 Subject: [PATCH 124/404] qcacmn: Update PCL table for non DBS to give SCC preference Update the non DBS PCL table to give preference to SCC. Change-Id: I9d2d982f367bf6fb8d18e4d448fa0c45e95cbbf4 CRs-Fixed: 2063060 --- src/wlan_policy_mgr_tables_no_dbs_i.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/wlan_policy_mgr_tables_no_dbs_i.h b/src/wlan_policy_mgr_tables_no_dbs_i.h index cddd184cf939..1e831f3bc478 100644 --- a/src/wlan_policy_mgr_tables_no_dbs_i.h +++ b/src/wlan_policy_mgr_tables_no_dbs_i.h @@ -40,7 +40,7 @@ second_connection_pcl_nodbs_table[PM_MAX_ONE_CONNECTION_MODE] [PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE] = { [PM_STA_24_1x1] = { [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_SAP_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_IBSS_MODE] = { @@ -48,7 +48,7 @@ second_connection_pcl_nodbs_table[PM_MAX_ONE_CONNECTION_MODE] [PM_STA_24_2x2] = { [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_SAP_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_IBSS_MODE] = { @@ -72,7 +72,7 @@ second_connection_pcl_nodbs_table[PM_MAX_ONE_CONNECTION_MODE] [PM_P2P_CLI_24_1x1] = { [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_SAP_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_IBSS_MODE] = { @@ -80,7 +80,7 @@ second_connection_pcl_nodbs_table[PM_MAX_ONE_CONNECTION_MODE] [PM_P2P_CLI_24_2x2] = { [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_SAP_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_IBSS_MODE] = { @@ -224,7 +224,7 @@ static const enum policy_mgr_pcl_type third_connection_pcl_nodbs_table[PM_MAX_TWO_CONNECTION_MODE] [PM_MAX_NUM_OF_MODE][PM_MAX_CONC_PRIORITY_MODE] = { [PM_STA_SAP_SCC_24_1x1] = { - [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -234,7 +234,7 @@ third_connection_pcl_nodbs_table[PM_MAX_TWO_CONNECTION_MODE] PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_SCC_24_2x2] = { - [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, @@ -345,10 +345,10 @@ third_connection_pcl_nodbs_table[PM_MAX_TWO_CONNECTION_MODE] PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_GO_SCC_24_2x2] = { - [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -554,17 +554,17 @@ third_connection_pcl_nodbs_table[PM_MAX_TWO_CONNECTION_MODE] PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = { - [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = { - [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_SCC_CH, PM_SCC_CH}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, From 6c0554aac7f04f0640a8547b262033c985011404 Mon Sep 17 00:00:00 2001 From: Ganesh Kondabattini Date: Tue, 8 Aug 2017 12:19:00 +0530 Subject: [PATCH 125/404] qcacmn: Initialize SAP mandatory chan list Initialize SAP mandatory chan list. Change-Id: I126d67da1bfe8426cd3a7b031e97aba907e6155a CRs-Fixed: 2089122 --- inc/wlan_policy_mgr_api.h | 74 ++++++++++++++++++++++ src/wlan_policy_mgr_core.c | 126 +++++++++++++++++++++++++++++++++++++ src/wlan_policy_mgr_i.h | 1 + 3 files changed, 201 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index ffe2fe12c80c..94668d76e366 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2011,4 +2011,78 @@ bool policy_mgr_disallow_mcc(struct wlan_objmgr_psoc *psoc, */ uint8_t policy_mgr_mode_specific_get_channel( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); + +/** + * policy_mgr_enable_disable_sap_mandatory_chan_list() - Update the value of + * enable_sap_mandatory_chan_list + * @psoc: Pointer to soc + * @val: value of enable_sap_mandatory_chan_list + * + * Update the value of enable_sap_mandatory_chan_list + * + * Return: void + */ +void policy_mgr_enable_disable_sap_mandatory_chan_list( + struct wlan_objmgr_psoc *psoc, bool val); + +/** + * policy_mgr_add_sap_mandatory_chan() - Add chan to SAP mandatory channel + * list + * @psoc: Pointer to soc + * @chan: Channel to be added + * + * Add chan to SAP mandatory channel list + * + * Return: None + */ +void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, + uint8_t chan); + +/** + * policy_mgr_is_sap_mandatory_chan_list_enabled() - Return the SAP mandatory + * channel list enabled status + * @psoc: Pointer to soc + * + * Get the SAP mandatory channel list enabled status + * + * Return: Enable or Disable + */ +bool policy_mgr_is_sap_mandatory_chan_list_enabled( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_sap_mandatory_chan_list_len() - Return the SAP mandatory + * channel list len + * @psoc: Pointer to soc + * + * Get the SAP mandatory channel list len + * + * Return: Channel list length + */ +uint32_t policy_mgr_get_sap_mandatory_chan_list_len( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_init_sap_mandatory_2g_chan() - Init 2.4G SAP mandatory channel + * list + * @psoc: Pointer to soc + * + * Initialize the 2.4G SAP mandatory channels + * + * Return: None + */ +void policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_remove_sap_mandatory_chan() - Remove channel from SAP mandatory + * channel list + * @psoc: Pointer to soc + * @chan: channel to be removed from mandatory channel list + * + * Remove channel from SAP mandatory channel list + * + * Return: None + */ +void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, + uint8_t chan); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index a8a92b446df3..04535e2775db 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2681,3 +2681,129 @@ QDF_STATUS policy_mgr_reset_sap_mandatory_channels( return QDF_STATUS_SUCCESS; } + +void policy_mgr_enable_disable_sap_mandatory_chan_list( + struct wlan_objmgr_psoc *psoc, bool val) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + pm_ctx->enable_sap_mandatory_chan_list = val; +} + +void policy_mgr_add_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, + uint8_t chan) +{ + int i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) { + if (chan == pm_ctx->sap_mandatory_channels[i]) + return; + } + + policy_mgr_debug("chan %hu", chan); + pm_ctx->sap_mandatory_channels[pm_ctx->sap_mandatory_channels_len++] + = chan; +} + +bool policy_mgr_is_sap_mandatory_chan_list_enabled( + struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + return pm_ctx->enable_sap_mandatory_chan_list; +} + +uint32_t policy_mgr_get_sap_mandatory_chan_list_len( + struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return 0; + } + + return pm_ctx->sap_mandatory_channels_len; +} + +void policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc) +{ + uint8_t chan_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t len = 0; + int i; + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + status = policy_mgr_get_valid_chans(psoc, chan_list, &len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Error in getting valid channels"); + return; + } + for (i = 0; i < len; i++) { + if (WLAN_REG_IS_24GHZ_CH(chan_list[i])) { + policy_mgr_debug("Add chan %hu to mandatory list", + chan_list[i]); + pm_ctx->sap_mandatory_channels[ + pm_ctx->sap_mandatory_channels_len++] = + chan_list[i]; + } + } +} + +void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, + uint8_t chan) +{ + uint8_t chan_list[QDF_MAX_NUM_CHAN] = {0}; + uint32_t num_chan = 0; + int i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + if (pm_ctx->sap_mandatory_channels_len >= QDF_MAX_NUM_CHAN) { + policy_mgr_err("Invalid channel len %d ", + pm_ctx->sap_mandatory_channels_len); + return; + } + + for (i = 0; i < pm_ctx->sap_mandatory_channels_len; i++) { + if (chan == pm_ctx->sap_mandatory_channels[i]) + continue; + chan_list[num_chan++] = pm_ctx->sap_mandatory_channels[i]; + } + + qdf_mem_zero(pm_ctx->sap_mandatory_channels, + pm_ctx->sap_mandatory_channels_len); + qdf_mem_copy(pm_ctx->sap_mandatory_channels, chan_list, num_chan); + pm_ctx->sap_mandatory_channels_len = num_chan; +} diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 2b2fcd88292a..fd5ab69f5846 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -251,6 +251,7 @@ struct policy_mgr_psoc_priv_obj { struct policy_mgr_wma_cbacks wma_cbacks; struct policy_mgr_tdls_cbacks tdls_cbacks; struct policy_mgr_cdp_cbacks cdp_cbacks; + bool enable_sap_mandatory_chan_list; uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; uint32_t sap_mandatory_channels_len; bool do_hw_mode_change; From 63b4af0cef5f8d1bbd98f192ceb300573a6a0091 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 15 Aug 2017 12:31:27 -0700 Subject: [PATCH 126/404] qcacmn: Remove name indirection for ieee80211_get_channel() Versions 4.11+ of the Linux kernel removed '__' from the beginning of ieee80211_get_channel(). Migrate all calls from __ieee80211_get_channel to ieee80211_get_channel instead. Change-Id: I0548259beb59f0a3cb27fe6fee1dd9626cc624cc CRs-Fixed: 2098795 --- src/wlan_cfg80211_p2p.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 57429a1db88a..17d5178c3486 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -284,8 +284,8 @@ static void wlan_p2p_event_callback(void *user_data, goto fail; } - chan = __ieee80211_get_channel(wdev->wiphy, - wlan_chan_to_freq(p2p_event->chan)); + chan = ieee80211_get_channel(wdev->wiphy, + wlan_chan_to_freq(p2p_event->chan)); if (p2p_event->roc_event == ROC_EVENT_READY_ON_CHAN) { cfg80211_ready_on_channel(wdev, p2p_event->cookie, chan, From 36a2ad6e13ee4c9fe0ac315763e5115004e0f938 Mon Sep 17 00:00:00 2001 From: Naveen Rawat Date: Fri, 1 Sep 2017 17:01:01 -0700 Subject: [PATCH 127/404] qcacmn: Add APIs to get IE by EID and Ext ID Add wlan utility APIs to get IE pointer from within IE buffer by EID or Ext ID. Change-Id: I26492078cec73b5877f3fc346a91223a045f31aa CRs-Fixed: 2103529 --- core/src/wlan_p2p_off_chan_tx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 924c384b47d2..f353f624d72b 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -121,7 +121,7 @@ static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx) * * Return: pointer to p2p ie */ -static uint8_t *p2p_get_p2pie_ptr(uint8_t *ie, uint16_t ie_len) +static const uint8_t *p2p_get_p2pie_ptr(const uint8_t *ie, uint16_t ie_len) { return wlan_get_vendor_ie_ptr_from_oui(P2P_OUI, P2P_OUI_SIZE, ie, ie_len); @@ -137,12 +137,12 @@ static uint8_t *p2p_get_p2pie_ptr(uint8_t *ie, uint16_t ie_len) * * Return: pointer to p2p ie */ -static uint8_t *p2p_get_p2pie_from_probe_rsp( +static const uint8_t *p2p_get_p2pie_from_probe_rsp( struct tx_action_context *tx_ctx) { - uint8_t *ie; - uint8_t *p2p_ie; - uint8_t *tmp_p2p_ie; + const uint8_t *ie; + const uint8_t *p2p_ie; + const uint8_t *tmp_p2p_ie; uint16_t ie_len; ie = tx_ctx->buf + PROBE_RSP_IE_OFFSET; @@ -176,10 +176,10 @@ static uint8_t *p2p_get_p2pie_from_probe_rsp( * * Return: pointer to noa attr */ -static uint8_t *p2p_get_presence_noa_attr(uint8_t *pies, int length) +static const uint8_t *p2p_get_presence_noa_attr(const uint8_t *pies, int length) { int left = length; - uint8_t *ptr = pies; + const uint8_t *ptr = pies; uint8_t elem_id; uint16_t elem_len; @@ -387,7 +387,7 @@ static uint8_t p2p_get_noa_attr_stream( * Return: noa stream length */ static uint16_t p2p_update_noa_stream(struct tx_action_context *tx_ctx, - uint8_t *p2p_ie, uint8_t *noa_attr, uint32_t *total_len, + uint8_t *p2p_ie, const uint8_t *noa_attr, uint32_t *total_len, uint8_t *noa_stream) { uint16_t noa_len; @@ -1231,24 +1231,24 @@ static QDF_STATUS p2p_execute_tx_action_frame( uint8_t noa_len = 0; uint8_t noa_stream[P2P_NOA_STREAM_ARR_SIZE]; uint8_t orig_len = 0; - uint8_t *ie; + const uint8_t *ie; uint8_t ie_len; uint8_t *p2p_ie = NULL; - uint8_t *presence_noa_attr = NULL; + const uint8_t *presence_noa_attr = NULL; uint32_t nbytes_copy; uint32_t buf_len = tx_ctx->buf_len; struct p2p_frame_info *frame_info; frame_info = &(tx_ctx->frame_info); if (frame_info->sub_type == P2P_MGMT_PROBE_RSP) { - p2p_ie = p2p_get_p2pie_from_probe_rsp(tx_ctx); + p2p_ie = (uint8_t *)p2p_get_p2pie_from_probe_rsp(tx_ctx); } else if (frame_info->action_type == P2P_ACTION_PRESENCE_RSP) { ie = tx_ctx->buf + P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET; ie_len = tx_ctx->buf_len - P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET; - p2p_ie = p2p_get_p2pie_ptr(ie, ie_len); + p2p_ie = (uint8_t *)p2p_get_p2pie_ptr(ie, ie_len); if (p2p_ie) { /* extract the presence of NoA attribute inside * P2P IE */ From a75fa9d06ad6f910d8989e413966031e5fb25650 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Wed, 23 Aug 2017 18:06:30 -0700 Subject: [PATCH 128/404] qcacmn: Fix TDLS peer capability initialization In tdls_set_peer_caps(), is_buffer_sta and is_off_channel_supported are declared, but are not initialized. This will create unpredictable problem in TDLS operations. Initialize all the variables with default values in peer capability. Change-Id: I469d7a56e1222944f3cd76efb76544aba7d8dff6 CRs-Fixed: 2092034 --- core/src/wlan_tdls_peer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index c78f0f0f3569..1513295db464 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -618,7 +618,9 @@ void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, const uint8_t *macaddr, struct tdls_update_peer_params *req_info) { - uint8_t is_buffer_sta, is_off_channel_supported, is_qos_wmm_sta; + uint8_t is_buffer_sta = 0; + uint8_t is_off_channel_supported = 0; + uint8_t is_qos_wmm_sta = 0; struct tdls_soc_priv_obj *soc_obj; struct tdls_peer *curr_peer; uint32_t feature; @@ -643,7 +645,7 @@ void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, is_off_channel_supported = 1; if (TDLS_IS_WMM_ENABLED(feature) && req_info->is_qos_wmm_sta) - is_qos_wmm_sta = true; + is_qos_wmm_sta = 1; curr_peer->uapsd_queues = req_info->uapsd_queues; curr_peer->max_sp = req_info->max_sp; From 2a8c7b0c6d4f6afb32c63da271a37abde47a5c27 Mon Sep 17 00:00:00 2001 From: Ganesh Kondabattini Date: Mon, 10 Jul 2017 17:34:36 +0530 Subject: [PATCH 129/404] qcacmn: Refactor the code to update the conc_system_pref Refactor the code to dynamically change the conc_system_pref. Whenever user changes conc_system_pref from application, driver is overwriting the conc_system_pref which is getting populated from ini file. Once it is overwritten there is no way to get the configured value for this setting. So add a new variable to hold the value of conc_system_pref without disturbing default value read from ini file. CRs-Fixed: 2082073 Change-Id: Icfb245c7a8872885332ec222780c911d08521d46 --- inc/wlan_policy_mgr_api.h | 20 ++++++++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 32 +++++++++++++++++++++++++++++ src/wlan_policy_mgr_i.h | 1 + src/wlan_policy_mgr_pcl.c | 12 +++++------ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 94668d76e366..3865a8674f4c 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2085,4 +2085,24 @@ void policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc); */ void policy_mgr_remove_sap_mandatory_chan(struct wlan_objmgr_psoc *psoc, uint8_t chan); +/* + * policy_set_cur_conc_system_pref - set current conc_system_pref + * @psoc: soc pointer + * + * Set the current concurrency system preference. + * + * Return: None + */ +void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc, + uint8_t conc_system_pref); +/** + * policy_mgr_get_cur_conc_system_pref - Get current conc_system_pref + * @psoc: soc pointer + * + * Get the current concurrent system preference. + * + * Return: conc_system_pref + */ +uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index ba337ab71ae1..c156881c7028 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1768,6 +1768,8 @@ QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, pm_ctx->user_cfg = *user_cfg; + pm_ctx->cur_conc_system_pref = pm_ctx->user_cfg.conc_system_pref; + return QDF_STATUS_SUCCESS; } @@ -2588,6 +2590,36 @@ bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc) return false; } +void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc, + uint8_t conc_system_pref) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + policy_mgr_debug("conc_system_pref %hu", conc_system_pref); + pm_ctx->cur_conc_system_pref = conc_system_pref; +} + +uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return PM_THROUGHPUT; + } + + policy_mgr_debug("conc_system_pref %hu", pm_ctx->cur_conc_system_pref); + return pm_ctx->cur_conc_system_pref; +} + QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( struct wlan_objmgr_psoc *psoc, uint32_t *scan_config, uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini) diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index fd5ab69f5846..5610f49f8c09 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -269,6 +269,7 @@ struct policy_mgr_psoc_priv_obj { uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN]; uint16_t unsafe_channel_count; struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info; + uint8_t cur_conc_system_pref; }; /** diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 79a437ac0342..01f2cc91c000 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -489,9 +489,9 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, /* find the current connection state from pm_conc_connection_list*/ num_connections = policy_mgr_get_connection_count(psoc); policy_mgr_debug("connections:%d pref:%d requested mode:%d", - num_connections, pm_ctx->user_cfg.conc_system_pref, mode); + num_connections, pm_ctx->cur_conc_system_pref, mode); - switch (pm_ctx->user_cfg.conc_system_pref) { + switch (pm_ctx->cur_conc_system_pref) { case 0: conc_system_pref = PM_THROUGHPUT; break; @@ -502,8 +502,8 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, conc_system_pref = PM_LATENCY; break; default: - policy_mgr_err("unknown conc_system_pref value %d", - pm_ctx->user_cfg.conc_system_pref); + policy_mgr_err("unknown cur_conc_system_pref value %d", + pm_ctx->cur_conc_system_pref); break; } @@ -596,10 +596,10 @@ enum policy_mgr_conc_priority_mode return PM_THROUGHPUT; } - if (pm_ctx->user_cfg.conc_system_pref >= PM_MAX_CONC_PRIORITY_MODE) + if (pm_ctx->cur_conc_system_pref >= PM_MAX_CONC_PRIORITY_MODE) return PM_THROUGHPUT; - return pm_ctx->user_cfg.conc_system_pref; + return pm_ctx->cur_conc_system_pref; } enum policy_mgr_one_connection_mode From e677364a0f5fbb2075ec4c72d0262bc98a179bd3 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 28 Sep 2017 15:02:22 -0700 Subject: [PATCH 130/404] qcacmn: Update PCL table for non DBS to give preference to SCC Update PCL table for non DBS to give preference to SCC in STA+P2P cases. Change-Id: I0dfa1f2f37960b90a32e325e1397e301f6ce313d CRs-Fixed: 2118720 --- src/wlan_policy_mgr_tables_no_dbs_i.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wlan_policy_mgr_tables_no_dbs_i.h b/src/wlan_policy_mgr_tables_no_dbs_i.h index 1e831f3bc478..b0119950f73c 100644 --- a/src/wlan_policy_mgr_tables_no_dbs_i.h +++ b/src/wlan_policy_mgr_tables_no_dbs_i.h @@ -41,32 +41,32 @@ second_connection_pcl_nodbs_table[PM_MAX_ONE_CONNECTION_MODE] [PM_STA_24_1x1] = { [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, - [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_24_2x2] = { [PM_STA_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH}, [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, - [PM_P2P_GO_MODE] = {PM_5G, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH_5G}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_5_1x1] = { [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_5_2x2] = { [PM_STA_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH_5G}, [PM_SAP_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_SCC_CH_5G, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_CLIENT_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, + [PM_P2P_GO_MODE] = {PM_SCC_CH, PM_SCC_CH, PM_SCC_CH}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, From 6ada3cdac934c7c9280b60b78d936ba69a968140 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 18 Sep 2017 10:07:54 -0700 Subject: [PATCH 131/404] qcacmn: umac: Replace instances of unadorned %p Replace instances of unadorned %p in umac. Change-Id: I7ae33c51405b31df24670dee3c98b6b4f1da9ab4 CRs-Fixed: 2111274 --- core/src/wlan_tdls_cmds_process.c | 56 ++++++++++++++--------------- core/src/wlan_tdls_ct.c | 2 +- core/src/wlan_tdls_main.c | 8 ++--- core/src/wlan_tdls_mgmt.c | 6 ++-- core/src/wlan_tdls_peer.c | 2 +- dispatcher/src/wlan_tdls_tgt_api.c | 18 +++++----- dispatcher/src/wlan_tdls_ucfg_api.c | 22 ++++++------ 7 files changed, 57 insertions(+), 57 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 671eaf03c06f..5b66567618e5 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -338,7 +338,7 @@ tdls_internal_add_peer_rsp(struct tdls_add_peer_request *req, QDF_STATUS ret; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); return QDF_STATUS_E_INVAL; } vdev = req->vdev; @@ -370,7 +370,7 @@ tdls_internal_update_peer_rsp(struct tdls_update_peer_request *req, QDF_STATUS ret; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); return QDF_STATUS_E_INVAL; } vdev = req->vdev; @@ -400,7 +400,7 @@ static QDF_STATUS tdls_internal_del_peer_rsp(struct tdls_oper_request *req) QDF_STATUS status; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); return QDF_STATUS_E_INVAL; } vdev = req->vdev; @@ -442,7 +442,7 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); return QDF_STATUS_E_INVAL; } status = tdls_validate_current_mode(soc_obj); @@ -516,12 +516,12 @@ tdls_add_peer_serialize_callback(struct wlan_serialization_command *cmd, QDF_STATUS status = QDF_STATUS_SUCCESS; if (!cmd || !cmd->umac_cmd) { - tdls_err("cmd: %p, reason: %d", cmd, reason); + tdls_err("cmd: %pK, reason: %d", cmd, reason); return QDF_STATUS_E_NULL_VALUE; } req = cmd->umac_cmd; - tdls_debug("reason: %d, req %p", reason, req); + tdls_debug("reason: %d, req %pK", reason, req); switch (reason) { case WLAN_SER_CB_ACTIVATE_CMD: @@ -806,7 +806,7 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); status = QDF_STATUS_E_INVAL; goto error; } @@ -822,7 +822,7 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) cmd.vdev = vdev; ser_cmd_status = wlan_serialization_request(&cmd); - tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, ser_cmd_status); switch (ser_cmd_status) { @@ -880,7 +880,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); return QDF_STATUS_E_INVAL; } @@ -960,12 +960,12 @@ tdls_update_peer_serialize_callback(struct wlan_serialization_command *cmd, QDF_STATUS status = QDF_STATUS_SUCCESS; if (!cmd || !cmd->umac_cmd) { - tdls_err("cmd: %p, reason: %d", cmd, reason); + tdls_err("cmd: %pK, reason: %d", cmd, reason); return QDF_STATUS_E_NULL_VALUE; } req = cmd->umac_cmd; - tdls_debug("reason: %d, req %p", reason, req); + tdls_debug("reason: %d, req %pK", reason, req); switch (reason) { case WLAN_SER_CB_ACTIVATE_CMD: @@ -1014,7 +1014,7 @@ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); status = QDF_STATUS_E_FAILURE; goto error; } @@ -1031,7 +1031,7 @@ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) cmd.vdev = req->vdev; ser_cmd_status = wlan_serialization_request(&cmd); - tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, ser_cmd_status); switch (ser_cmd_status) { @@ -1084,12 +1084,12 @@ tdls_del_peer_serialize_callback(struct wlan_serialization_command *cmd, QDF_STATUS status = QDF_STATUS_SUCCESS; if (!cmd || !cmd->umac_cmd) { - tdls_err("cmd: %p, reason: %d", cmd, reason); + tdls_err("cmd: %pK, reason: %d", cmd, reason); return QDF_STATUS_E_NULL_VALUE; } req = cmd->umac_cmd; - tdls_debug("reason: %d, req %p", reason, req); + tdls_debug("reason: %d, req %pK", reason, req); switch (reason) { case WLAN_SER_CB_ACTIVATE_CMD: @@ -1136,7 +1136,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); status = QDF_STATUS_E_INVAL; goto error; } @@ -1152,7 +1152,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) cmd.vdev = vdev; ser_cmd_status = wlan_serialization_request(&cmd); - tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, ser_cmd_status); switch (ser_cmd_status) { @@ -1256,7 +1256,7 @@ QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp) tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); if (!tdls_soc || !tdls_vdev) { - tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev); + tdls_err("soc object:%pK, vdev object:%pK", tdls_soc, tdls_vdev); status = QDF_STATUS_E_FAILURE; } @@ -1311,7 +1311,7 @@ QDF_STATUS tdls_send_mgmt_tx_completion( tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); if (!tdls_soc || !tdls_vdev) { - tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev); + tdls_err("soc object:%pK, vdev object:%pK", tdls_soc, tdls_vdev); status = QDF_STATUS_E_FAILURE; } @@ -1356,7 +1356,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc object:%p, vdev object:%p", soc_obj, vdev_obj); + tdls_err("soc object:%pK, vdev object:%pK", soc_obj, vdev_obj); status = QDF_STATUS_E_FAILURE; goto cmddone; } @@ -1449,7 +1449,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc object:%p, vdev object:%p", soc_obj, vdev_obj); + tdls_err("soc object:%pK, vdev object:%pK", soc_obj, vdev_obj); status = QDF_STATUS_E_FAILURE; goto cmddone; } @@ -1622,7 +1622,7 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); if (!vdev_obj || !soc_obj) { - tdls_err("tdls vdev_obj: %p soc_obj: %p", vdev_obj, soc_obj); + tdls_err("tdls vdev_obj: %pK soc_obj: %pK", vdev_obj, soc_obj); status = QDF_STATUS_E_NULL_VALUE; goto error; } @@ -1734,7 +1734,7 @@ static QDF_STATUS tdls_config_force_peer( vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); if (!pdev || !vdev_obj || !soc_obj) { - tdls_err("pdev: %p, vdev_obj: %p, soc_obj: %p", + tdls_err("pdev: %pK, vdev_obj: %pK, soc_obj: %pK", pdev, vdev_obj, soc_obj); return QDF_STATUS_E_INVAL; } @@ -1876,7 +1876,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); status = QDF_STATUS_E_INVAL; goto error; } @@ -1988,7 +1988,7 @@ QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", soc_obj, vdev_obj, tdls_evt_to_str(type)); return QDF_STATUS_E_NULL_VALUE; } @@ -2045,7 +2045,7 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", soc_obj, vdev_obj, tdls_evt_to_str(type)); return QDF_STATUS_E_NULL_VALUE; } @@ -2090,7 +2090,7 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", soc_obj, vdev_obj, tdls_evt_to_str(type)); return QDF_STATUS_E_NULL_VALUE; } @@ -2138,7 +2138,7 @@ int tdls_set_responder(struct tdls_set_responder_req *set_req) QDF_STATUS status; if (!set_req || !set_req->vdev) { - tdls_err("Invalid input params %p", set_req); + tdls_err("Invalid input params %pK", set_req); return -EINVAL; } diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 1ed20b976f0b..a07f6dc418bf 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -515,7 +515,7 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); if (!tdls_soc || !tdls_vdev || !curr_peer) { - tdls_err("tdls_soc: %p, tdls_vdev: %p, curr_peer: %p", + tdls_err("tdls_soc: %pK, tdls_vdev: %pK, curr_peer: %pK", tdls_soc, tdls_vdev, curr_peer); return; } diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index fc16026556b0..b66edc02cdbd 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -236,7 +236,7 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!msg || !msg->bodyptr) { - tdls_err("msg: 0x%p", msg); + tdls_err("msg: 0x%pK", msg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -307,7 +307,7 @@ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) struct tdls_event_info *event; if (!msg || !msg->bodyptr) { - tdls_err("msg is not valid: %p", msg); + tdls_err("msg is not valid: %pK", msg); return QDF_STATUS_E_NULL_VALUE; } notify = msg->bodyptr; @@ -602,7 +602,7 @@ QDF_STATUS tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) { if (!psoc) { - tdls_err("psoc: %p", psoc); + tdls_err("psoc: %pK", psoc); return QDF_STATUS_E_NULL_VALUE; } tdls_debug("enter "); @@ -1252,7 +1252,7 @@ static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) struct scheduler_msg msg = {0, }; if (!tdls_soc) { - tdls_err("tdls_soc: %p ", tdls_soc); + tdls_err("tdls_soc: %pK ", tdls_soc); return QDF_STATUS_E_NULL_VALUE; } diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 2bef1af535cf..d0bbf3326984 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -98,7 +98,7 @@ static QDF_STATUS tdls_process_rx_mgmt( return QDF_STATUS_E_INVAL; } - tdls_debug("soc:%p, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%p", + tdls_debug("soc:%pK, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK", tdls_soc_obj->soc, rx_mgmt->frame_len, rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, rx_mgmt->rx_rssi, rx_mgmt->buf); @@ -176,7 +176,7 @@ QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, QDF_STATUS status; int num_of_entries; - tdls_debug("psoc:%p, is register rx:%d", psoc, isregister); + tdls_debug("psoc:%pK, is register rx:%d", psoc, isregister); frm_cb_info.frm_type = MGMT_ACTION_TDLS_DISCRESP; frm_cb_info.mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; @@ -321,7 +321,7 @@ tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd, QDF_STATUS status = QDF_STATUS_SUCCESS; if (!cmd || !cmd->umac_cmd) { - tdls_err("invalid params cmd: %p, ", cmd); + tdls_err("invalid params cmd: %pK, ", cmd); return QDF_STATUS_E_NULL_VALUE; } req = cmd->umac_cmd; diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 1513295db464..26837ffdd818 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -473,7 +473,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); pdev = wlan_vdev_get_pdev(vdev_obj->vdev); if (!soc_obj || !pdev) { - tdls_err("soc_obj: %p, pdev: %p", soc_obj, pdev); + tdls_err("soc_obj: %pK, pdev: %pK", soc_obj, pdev); return; } diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index e1ab734fcc0e..4100c29ad67d 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -92,7 +92,7 @@ QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pmsg || !pmsg->bodyptr) { - tdls_err("msg: 0x%p", pmsg); + tdls_err("msg: 0x%pK", pmsg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -107,7 +107,7 @@ QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pmsg || !pmsg->bodyptr) { - tdls_err("msg: 0x%p", pmsg); + tdls_err("msg: 0x%pK", pmsg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -122,7 +122,7 @@ QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pmsg || !pmsg->bodyptr) { - tdls_err("msg: 0x%p", pmsg); + tdls_err("msg: 0x%pK", pmsg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -137,7 +137,7 @@ QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pmsg || !pmsg->bodyptr) { - tdls_err("msg: 0x%p", pmsg); + tdls_err("msg: 0x%pK", pmsg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -179,7 +179,7 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, QDF_STATUS status; if (!psoc || !info) { - tdls_err("psoc: 0x%p, info: 0x%p", psoc, info); + tdls_err("psoc: 0x%pK, info: 0x%pK", psoc, info); return QDF_STATUS_E_NULL_VALUE; } tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDRESS_STR, @@ -196,7 +196,7 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_TDLS_SB_ID); if (!notify->vdev) { - tdls_err("null vdev, vdev_id: %d, psoc: 0x%p", vdev_id, psoc); + tdls_err("null vdev, vdev_id: %d, psoc: 0x%pK", vdev_id, psoc); return QDF_STATUS_E_INVAL; } qdf_mem_copy(¬ify->event, info, sizeof(*info)); @@ -298,16 +298,16 @@ QDF_STATUS tgt_tdls_mgmt_frame_rx_cb( { QDF_STATUS status; - tdls_debug("psoc:%p, peer:%p, type:%d", psoc, peer, frm_type); + tdls_debug("psoc:%pK, peer:%pK, type:%d", psoc, peer, frm_type); if (!buf) { - tdls_err("rx frame buff is null buf:%p", buf); + tdls_err("rx frame buff is null buf:%pK", buf); return QDF_STATUS_E_INVAL; } if (!mgmt_rx_params || !psoc) { - tdls_err("input is NULL mgmt_rx_params:%p psoc:%p, peer:%p", + tdls_err("input is NULL mgmt_rx_params:%pK psoc:%pK, peer:%pK", mgmt_rx_params, psoc, peer); status = QDF_STATUS_E_INVAL; goto release_nbuf; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 67517aabc3aa..5b41921a02fc 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -183,7 +183,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, tdls_notice("tdls update config "); if (!psoc || !req) { - tdls_err("psoc: 0x%p, req: 0x%p", psoc, req); + tdls_err("psoc: 0x%pK, req: 0x%pK", psoc, req); return QDF_STATUS_E_FAILURE; } @@ -248,7 +248,7 @@ QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc) { QDF_STATUS status; - tdls_notice("psoc tdls enable: 0x%p", psoc); + tdls_notice("psoc tdls enable: 0x%pK", psoc); if (!psoc) { tdls_err("NULL psoc"); return QDF_STATUS_E_FAILURE; @@ -281,7 +281,7 @@ QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) QDF_STATUS status; struct tdls_soc_priv_obj *soc_obj = NULL; - tdls_notice("psoc tdls disable: 0x%p", psoc); + tdls_notice("psoc tdls disable: 0x%pK", psoc); if (!psoc) { tdls_err("NULL psoc"); return QDF_STATUS_E_FAILURE; @@ -337,7 +337,7 @@ QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; if (!vdev || !add_peer_req) { - tdls_err("vdev: %p, req %p", vdev, add_peer_req); + tdls_err("vdev: %pK, req %pK", vdev, add_peer_req); return QDF_STATUS_E_NULL_VALUE; } tdls_debug("vdevid: %d, peertype: %d", @@ -383,7 +383,7 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; if (!vdev || !update_peer) { - tdls_err("vdev: %p, update_peer: %p", vdev, update_peer); + tdls_err("vdev: %pK, update_peer: %pK", vdev, update_peer); return QDF_STATUS_E_NULL_VALUE; } @@ -443,7 +443,7 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; if (!vdev || !macaddr) { - tdls_err("vdev: %p, mac %p", vdev, macaddr); + tdls_err("vdev: %pK, mac %pK", vdev, macaddr); return QDF_STATUS_E_NULL_VALUE; } @@ -490,7 +490,7 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *mgmt_req; if (!req || !req->vdev) { - tdls_err("Invalid mgmt req params %p", req); + tdls_err("Invalid mgmt req params %pK", req); return QDF_STATUS_E_NULL_VALUE; } @@ -529,7 +529,7 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) QDF_STATUS status; if (!req || !req->vdev) { - tdls_err("invalid input %p", req); + tdls_err("invalid input %pK", req); return QDF_STATUS_E_NULL_VALUE; } @@ -593,7 +593,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( struct tdls_sta_notify_params *notify; if (!notify_info || !notify_info->vdev) { - tdls_err("notify_info->vdev: %p, notify_info %p", + tdls_err("notify_info->vdev: %pK, notify_info %pK", notify_info->vdev, notify_info); return QDF_STATUS_E_NULL_VALUE; } @@ -625,7 +625,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( struct tdls_sta_notify_params *notify; if (!notify_info || !notify_info->vdev) { - tdls_err("notify_info->vdev: %p, notify_info %p", + tdls_err("notify_info->vdev: %pK, notify_info %pK", notify_info->vdev, notify_info); return QDF_STATUS_E_NULL_VALUE; } @@ -659,7 +659,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( struct tdls_set_mode_params *set_mode; if (!set_mode_params || !set_mode_params->vdev) { - tdls_err("vdev: %p, set_mode_params %p", + tdls_err("vdev: %pK, set_mode_params %pK", set_mode_params->vdev, set_mode_params); return QDF_STATUS_E_NULL_VALUE; } From dc3f822c6e7fa0af4ea71cf57aa639e80ce4644a Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 18 Sep 2017 10:07:54 -0700 Subject: [PATCH 132/404] qcacmn: umac: Replace instances of unadorned %p Replace instances of unadorned %p in umac. Change-Id: I7ae33c51405b31df24670dee3c98b6b4f1da9ab4 CRs-Fixed: 2111274 --- core/src/wlan_p2p_main.c | 20 +++++++------- core/src/wlan_p2p_off_chan_tx.c | 38 +++++++++++++-------------- core/src/wlan_p2p_roc.c | 42 +++++++++++++++--------------- dispatcher/src/wlan_p2p_tgt_api.c | 10 +++---- dispatcher/src/wlan_p2p_ucfg_api.c | 20 +++++++------- 5 files changed, 65 insertions(+), 65 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 3d68b43cec97..77c22dc5ffaa 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -123,7 +123,7 @@ static QDF_STATUS p2p_psoc_obj_create_notification( return status; } - p2p_debug("p2p soc object create successful, %p", p2p_soc_obj); + p2p_debug("p2p soc object create successful, %pK", p2p_soc_obj); return QDF_STATUS_SUCCESS; } @@ -165,7 +165,7 @@ static QDF_STATUS p2p_psoc_obj_destroy_notification( return status; } - p2p_debug("destroy p2p soc object, %p", p2p_soc_obj); + p2p_debug("destroy p2p soc object, %pK", p2p_soc_obj); qdf_mem_free(p2p_soc_obj); @@ -222,7 +222,7 @@ static QDF_STATUS p2p_vdev_obj_create_notification( return status; } - p2p_debug("p2p vdev object create successful, %p", p2p_vdev_obj); + p2p_debug("p2p vdev object create successful, %pK", p2p_vdev_obj); return QDF_STATUS_SUCCESS; } @@ -272,7 +272,7 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( return status; } - p2p_debug("destroy p2p vdev object, p2p vdev obj:%p, noa info:%p", + p2p_debug("destroy p2p vdev object, p2p vdev obj:%pK, noa info:%pK", p2p_vdev_obj, p2p_vdev_obj->noa_info); if (p2p_vdev_obj->noa_info) @@ -354,7 +354,7 @@ static QDF_STATUS p2p_peer_obj_destroy_notification( WLAN_UMAC_COMP_P2P); psoc = wlan_vdev_get_psoc(vdev); if (!p2p_vdev_obj || !psoc) { - p2p_err("p2p_vdev_obj:%p psoc:%p", p2p_vdev_obj, psoc); + p2p_err("p2p_vdev_obj:%pK psoc:%pK", p2p_vdev_obj, psoc); return QDF_STATUS_E_INVAL; } @@ -473,13 +473,13 @@ static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev, uint8_t vdev_id; if (!vdev || !psoc || !peer) { - p2p_err("vdev:%p psoc:%p peer:%p", vdev, psoc, peer); + p2p_err("vdev:%pK psoc:%pK peer:%pK", vdev, psoc, peer); return QDF_STATUS_E_INVAL; } p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_P2P); if (!p2p_vdev_obj) { - p2p_err("p2p_vdev_obj:%p", p2p_vdev_obj); + p2p_err("p2p_vdev_obj:%pK", p2p_vdev_obj); return QDF_STATUS_E_INVAL; } mode = wlan_vdev_mlme_get_opmode(vdev); @@ -948,7 +948,7 @@ QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event) p2p_soc_obj = noa_event->p2p_soc_obj; psoc = p2p_soc_obj->soc; - p2p_debug("psoc:%p, index:%d, opps_ps:%d, ct_window:%d, num_desc:%d, vdev_id:%d", + p2p_debug("psoc:%pK, index:%d, opps_ps:%d, ct_window:%d, num_desc:%d, vdev_id:%d", psoc, noa_info->index, noa_info->opps_ps, noa_info->ct_window, noa_info->num_desc, noa_info->vdev_id); @@ -999,12 +999,12 @@ void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr) struct wlan_objmgr_peer *peer; if (!vdev) { - p2p_err("vdev:%p", vdev); + p2p_err("vdev:%pK", vdev); return; } psoc = wlan_vdev_get_psoc(vdev); if (!psoc) { - p2p_err("psoc:%p", psoc); + p2p_err("psoc:%pK", psoc); return; } peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_P2P_ID); diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index f353f624d72b..ce0692c2111e 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -183,7 +183,7 @@ static const uint8_t *p2p_get_presence_noa_attr(const uint8_t *pies, int length) uint8_t elem_id; uint16_t elem_len; - p2p_debug("pies:%p, length:%d", pies, length); + p2p_debug("pies:%pK, length:%d", pies, length); while (left >= 3) { elem_id = ptr[0]; @@ -221,7 +221,7 @@ static uint8_t p2p_get_noa_attr_stream_in_mult_p2p_ies(uint8_t *noa_stream, { uint8_t overflow_p2p_stream[P2P_MAX_NOA_ATTR_LEN]; - p2p_debug("noa_stream:%p, noa_len:%d, overflow_len:%d", + p2p_debug("noa_stream:%pK, noa_len:%d, overflow_len:%d", noa_stream, noa_len, overflow_len); if ((noa_len <= (P2P_MAX_NOA_ATTR_LEN + P2P_IE_HEADER_LEN)) && (noa_len >= overflow_len) && @@ -424,7 +424,7 @@ static uint16_t p2p_update_noa_stream(struct tx_action_context *tx_ctx, *total_len = buf_len; nbytes_copy = (p2p_ie + orig_len + 2) - tx_ctx->buf; - p2p_debug("noa_len=%d orig_len=%d p2p_ie=%p buf_len=%d nbytes copy=%d ", + p2p_debug("noa_len=%d orig_len=%d p2p_ie=%pK buf_len=%d nbytes copy=%d ", noa_len, orig_len, p2p_ie, buf_len, nbytes_copy); return noa_len; @@ -737,7 +737,7 @@ static QDF_STATUS p2p_send_tx_conf(struct tx_action_context *tx_ctx, tx_cnf.buf_len = tx_ctx->buf_len; tx_cnf.status = status ? 0 : 1; - p2p_debug("soc:%p, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%p", + p2p_debug("soc:%pK, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%pK", p2p_soc_obj->soc, tx_cnf.vdev_id, tx_cnf.action_cookie, tx_cnf.buf_len, tx_cnf.status, tx_cnf.buf); @@ -850,7 +850,7 @@ static QDF_STATUS p2p_roc_req_for_tx_action( roc_ctx->roc_type = OFF_CHANNEL_TX; tx_ctx->roc_cookie = (uintptr_t)roc_ctx; - p2p_debug("create roc request for off channel tx, tx ctx:%p, roc ctx:%p", + p2p_debug("create roc request for off channel tx, tx ctx:%pK, roc ctx:%pK", tx_ctx, roc_ctx); status = p2p_process_roc_req(roc_ctx); @@ -887,7 +887,7 @@ static struct tx_action_context *p2p_find_tx_ctx( *is_roc_q = false; *is_ack_q = false; - p2p_debug("Start to find tx ctx, p2p soc_obj:%p, cookie:%llx", + p2p_debug("Start to find tx ctx, p2p soc_obj:%pK, cookie:%llx", p2p_soc_obj, cookie); list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { @@ -933,7 +933,7 @@ static struct tx_action_context *p2p_find_tx_ctx_by_roc( *is_roc_q = false; *is_ack_q = false; - p2p_debug("Start to find tx ctx, p2p soc_obj:%p, cookie:%llx", + p2p_debug("Start to find tx ctx, p2p soc_obj:%pK, cookie:%llx", p2p_soc_obj, cookie); list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { @@ -976,7 +976,7 @@ static QDF_STATUS p2p_move_tx_context_to_ack_queue( struct tx_action_context *cur_tx_ctx; QDF_STATUS status; - p2p_debug("move tx context to wait for roc queue, %p", tx_ctx); + p2p_debug("move tx context to wait for roc queue, %pK", tx_ctx); cur_tx_ctx = p2p_find_tx_ctx(p2p_soc_obj, (uintptr_t)tx_ctx, &is_roc_q, &is_ack_q); @@ -1104,7 +1104,7 @@ static QDF_STATUS p2p_remove_tx_context( struct p2p_soc_priv_obj *p2p_soc_obj = tx_ctx->p2p_soc_obj; QDF_STATUS status = QDF_STATUS_E_FAILURE; - p2p_debug("tx context:%p", tx_ctx); + p2p_debug("tx context:%pK", tx_ctx); cur_tx_ctx = p2p_find_tx_ctx(p2p_soc_obj, cookie, &is_roc_q, &is_ack_q); @@ -1147,7 +1147,7 @@ static void p2p_tx_timeout(void *pdata) { struct tx_action_context *tx_ctx = pdata; - p2p_debug("pdata:%p", pdata); + p2p_debug("pdata:%pK", pdata); if (!tx_ctx) { p2p_err("invalid tx context"); @@ -1171,7 +1171,7 @@ static QDF_STATUS p2p_enable_tx_timer(struct tx_action_context *tx_ctx) { QDF_STATUS status; - p2p_debug("tx context:%p", tx_ctx); + p2p_debug("tx context:%pK", tx_ctx); status = qdf_mc_timer_init(&tx_ctx->tx_timer, QDF_TIMER_TYPE_SW, p2p_tx_timeout, @@ -1201,7 +1201,7 @@ static QDF_STATUS p2p_disable_tx_timer(struct tx_action_context *tx_ctx) { QDF_STATUS status; - p2p_debug("tx context:%p", tx_ctx); + p2p_debug("tx context:%pK", tx_ctx); status = qdf_mc_timer_stop(&tx_ctx->tx_timer); if (status != QDF_STATUS_SUCCESS) @@ -1324,12 +1324,12 @@ void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) struct tx_action_context *tx_ctx; qdf_list_node_t *tmp, *pos; - p2p_debug("dump tx queue wait for roc, p2p soc obj:%p, size:%d", + p2p_debug("dump tx queue wait for roc, p2p soc obj:%pK, size:%d", p2p_soc_obj, qdf_list_size(&p2p_soc_obj->tx_q_roc)); list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { tx_ctx = list_entry(pos, struct tx_action_context, node); - p2p_debug("p2p soc object:%p, tx ctx:%p, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%p, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", + p2p_debug("p2p soc object:%pK, tx ctx:%pK, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%pK, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", p2p_soc_obj, tx_ctx, tx_ctx->vdev_id, tx_ctx->scan_id, tx_ctx->roc_cookie, tx_ctx->chan, @@ -1343,7 +1343,7 @@ void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { tx_ctx = list_entry(pos, struct tx_action_context, node); - p2p_debug("p2p soc object:%p, tx_ctx:%p, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%p, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", + p2p_debug("p2p soc object:%pK, tx_ctx:%pK, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%pK, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", p2p_soc_obj, tx_ctx, tx_ctx->vdev_id, tx_ctx->scan_id, tx_ctx->roc_cookie, tx_ctx->chan, @@ -1363,7 +1363,7 @@ QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj, cur_tx_ctx = p2p_find_tx_ctx_by_roc(p2p_soc_obj, cookie, &is_roc_q, &is_ack_q); - p2p_debug("tx_ctx:%p, is_roc_q:%d, is_ack_q:%d", cur_tx_ctx, + p2p_debug("tx_ctx:%pK, is_roc_q:%d, is_ack_q:%d", cur_tx_ctx, is_roc_q, is_ack_q); if (cur_tx_ctx) { if (is_roc_q) { @@ -1445,7 +1445,7 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) p2p_soc_obj = tx_ctx->p2p_soc_obj; - p2p_debug("soc:%p, tx_ctx:%p, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%p, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", + p2p_debug("soc:%pK, tx_ctx:%pK, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%pK, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", p2p_soc_obj->soc, tx_ctx, tx_ctx->vdev_id, tx_ctx->scan_id, tx_ctx->roc_cookie, tx_ctx->chan, tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan, @@ -1568,7 +1568,7 @@ QDF_STATUS p2p_process_mgmt_tx_ack_cnf( return QDF_STATUS_E_INVAL; } - p2p_debug("soc:%p, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%p", + p2p_debug("soc:%pK, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%pK", p2p_soc_obj->soc, tx_cnf->vdev_id, tx_cnf->action_cookie, tx_cnf->buf_len, tx_cnf->status, tx_cnf->buf); @@ -1606,7 +1606,7 @@ QDF_STATUS p2p_process_rx_mgmt( return QDF_STATUS_E_INVAL; } - p2p_debug("soc:%p, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%p", + p2p_debug("soc:%pK, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK", p2p_soc_obj->soc, rx_mgmt->frame_len, rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, rx_mgmt->rx_rssi, rx_mgmt->buf); diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 6456b723ad17..1fa37ee66885 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -52,7 +52,7 @@ static QDF_STATUS p2p_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; QDF_STATUS status; - p2p_debug("psoc:%p, is register rx:%d", psoc, isregister); + p2p_debug("psoc:%pK, is register rx:%d", psoc, isregister); frm_cb_info.frm_type = MGMT_PROBE_REQ; frm_cb_info.mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; @@ -184,7 +184,7 @@ static QDF_STATUS p2p_execute_cancel_roc_req( QDF_STATUS status; struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -194,7 +194,7 @@ static QDF_STATUS p2p_execute_cancel_roc_req( qdf_event_reset(&p2p_soc_obj->cancel_roc_done); status = qdf_mc_timer_stop(&roc_ctx->roc_timer); if (status != QDF_STATUS_SUCCESS) - p2p_err("Failed to stop roc timer, roc %p", roc_ctx); + p2p_err("Failed to stop roc timer, roc %pK", roc_ctx); status = p2p_scan_abort(roc_ctx); if (status != QDF_STATUS_SUCCESS) { @@ -217,7 +217,7 @@ static void p2p_roc_timeout(void *pdata) struct p2p_roc_context *roc_ctx; struct p2p_soc_priv_obj *p2p_soc_obj; - p2p_debug("p2p soc obj:%p", pdata); + p2p_debug("p2p soc obj:%pK", pdata); p2p_soc_obj = pdata; if (!p2p_soc_obj) { @@ -231,7 +231,7 @@ static void p2p_roc_timeout(void *pdata) return; } - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -277,7 +277,7 @@ static QDF_STATUS p2p_send_roc_event( p2p_evt.chan = roc_ctx->chan; p2p_evt.duration = roc_ctx->duration; - p2p_debug("p2p soc_obj:%p, roc_ctx:%p, vdev_id:%d, roc_event:" + p2p_debug("p2p soc_obj:%pK, roc_ctx:%pK, vdev_id:%d, roc_event:" "%d, cookie:%llx, chan:%d, duration:%d", p2p_soc_obj, roc_ctx, p2p_evt.vdev_id, p2p_evt.roc_event, p2p_evt.cookie, p2p_evt.chan, p2p_evt.duration); @@ -303,7 +303,7 @@ static QDF_STATUS p2p_destroy_roc_ctx(struct p2p_roc_context *roc_ctx, QDF_STATUS status = QDF_STATUS_SUCCESS; struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p_soc_obj:%p, roc_ctx:%p, up_layer_event:%d, in_roc_queue:%d", + p2p_debug("p2p_soc_obj:%pK, roc_ctx:%pK, up_layer_event:%d, in_roc_queue:%d", p2p_soc_obj, roc_ctx, up_layer_event, in_roc_queue); if (up_layer_event) { @@ -338,7 +338,7 @@ static QDF_STATUS p2p_execute_roc_req(struct p2p_roc_context *roc_ctx) uint32_t go_num; struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -404,7 +404,7 @@ static struct p2p_roc_context *p2p_find_roc_ctx( struct p2p_roc_context *curr_roc_ctx; qdf_list_node_t *tmp, *pos; - p2p_debug("p2p soc obj:%p, cookie:%llx", p2p_soc_obj, cookie); + p2p_debug("p2p soc obj:%pK, cookie:%llx", p2p_soc_obj, cookie); list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { curr_roc_ctx = list_entry(pos, struct p2p_roc_context, @@ -428,7 +428,7 @@ static QDF_STATUS p2p_process_scan_start_evt( struct p2p_roc_context *roc_ctx) { roc_ctx->roc_state = ROC_STATE_STARTED; - p2p_debug("scan started, roc ctx:%p, scan id:%d", + p2p_debug("scan started, roc ctx:%pK, scan id:%d", roc_ctx, roc_ctx->scan_id); return QDF_STATUS_SUCCESS; @@ -454,7 +454,7 @@ static QDF_STATUS p2p_process_ready_on_channel_evt( p2p_soc_obj = roc_ctx->p2p_soc_obj; roc_ctx->roc_state = ROC_STATE_ON_CHAN; - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -494,7 +494,7 @@ static QDF_STATUS p2p_process_scan_complete_evt( uint32_t size; struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -548,7 +548,7 @@ QDF_STATUS p2p_mgmt_rx_action_ops(struct wlan_objmgr_psoc *psoc, struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[2]; QDF_STATUS status; - p2p_debug("psoc:%p, is register rx:%d", psoc, isregister); + p2p_debug("psoc:%pK, is register rx:%d", psoc, isregister); frm_cb_info[0].frm_type = MGMT_ACTION_VENDOR_SPECIFIC; frm_cb_info[0].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb; @@ -575,7 +575,7 @@ struct p2p_roc_context *p2p_find_current_roc_ctx( roc_ctx = list_entry(pos, struct p2p_roc_context, node); if (roc_ctx->roc_state != ROC_STATE_IDLE) { - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id" + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id" ":%d, scan_id:%d, cookie:%llx, chan:" "%d, phy_mode:%d, duration:%d, " "roc_type:%d, roc_state:%d", @@ -626,7 +626,7 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx = list_entry(pos, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, @@ -651,7 +651,7 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx = list_entry(pos, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -685,7 +685,7 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( roc_ctx = list_entry(pos, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, @@ -710,7 +710,7 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( roc_ctx = list_entry(pos, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -741,7 +741,7 @@ QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx) p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p soc obj:%p, roc ctx:%p, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -777,7 +777,7 @@ QDF_STATUS p2p_process_cancel_roc_req( curr_roc_ctx = p2p_find_roc_ctx(p2p_soc_obj, cancel_roc_ctx->cookie); - p2p_debug("p2p soc obj:%p, cookie:%llx, roc ctx:%p", + p2p_debug("p2p soc obj:%pK, cookie:%llx, roc ctx:%pK", p2p_soc_obj, cancel_roc_ctx->cookie, curr_roc_ctx); if (!curr_roc_ctx) { @@ -811,7 +811,7 @@ void p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_roc_context *curr_roc_ctx; - p2p_debug("soc:%p, scan event:%d", arg, event->type); + p2p_debug("soc:%pK, scan event:%d", arg, event->type); p2p_soc_obj = (struct p2p_soc_priv_obj *)arg; if (!p2p_soc_obj) { diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 92764d72bc7c..39a5364fbb55 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -112,7 +112,7 @@ void tgt_p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, QDF_STATUS tgt_p2p_mgmt_download_comp_cb(void *context, qdf_nbuf_t buf, bool free) { - p2p_debug("conext:%p, buf:%p, free:%d", context, + p2p_debug("conext:%pK, buf:%pK, free:%d", context, qdf_nbuf_data(buf), free); qdf_nbuf_free(buf); @@ -129,7 +129,7 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, struct tx_action_context *tx_ctx; struct scheduler_msg msg = {0}; - p2p_debug("context:%p, buf:%p, status:%d, tx complete params:%p", + p2p_debug("context:%pK, buf:%pK, status:%d, tx complete params:%pK", context, buf, status, tx_compl_params); if (!context) { @@ -183,7 +183,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id; uint8_t *pdata; - p2p_debug("psoc:%p, peer:%p, type:%d", psoc, peer, frm_type); + p2p_debug("psoc:%pK, peer:%pK, type:%d", psoc, peer, frm_type); if (!mgmt_rx_params) { p2p_err("mgmt rx params is NULL"); @@ -256,7 +256,7 @@ QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; - p2p_debug("soc:%p, event_info:%p", psoc, event_info); + p2p_debug("soc:%pK, event_info:%pK", psoc, event_info); if (!psoc) { p2p_err("psoc context passed is NULL"); @@ -303,7 +303,7 @@ QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; - p2p_debug("soc:%p, event_info:%p", psoc, event_info); + p2p_debug("soc:%pK, event_info:%pK", psoc, event_info); if (!psoc) { p2p_err("psoc context passed is NULL"); diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index c8d791b23540..8398dd2dccf1 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -52,7 +52,7 @@ static bool is_p2p_ps_allowed(struct wlan_objmgr_vdev *vdev, uint8_t is_p2pgo = 0; if (!vdev) { - p2p_err("vdev:%p", vdev); + p2p_err("vdev:%pK", vdev); return true; } p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, @@ -62,7 +62,7 @@ static bool is_p2p_ps_allowed(struct wlan_objmgr_vdev *vdev, is_p2pgo = 1; if (!p2p_vdev_obj || !is_p2pgo) { - p2p_err("p2p_vdev_obj:%p is_p2pgo:%u", + p2p_err("p2p_vdev_obj:%pK is_p2pgo:%u", p2p_vdev_obj, is_p2pgo); return false; } @@ -115,7 +115,7 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_roc_context *roc_ctx; - p2p_debug("soc:%p, vdev_id:%d, chan:%d, phy_mode:%d, duration:%d", + p2p_debug("soc:%pK, vdev_id:%d, chan:%d, phy_mode:%d, duration:%d", soc, roc_req->vdev_id, roc_req->chan, roc_req->phy_mode, roc_req->duration); @@ -160,7 +160,7 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, struct p2p_soc_priv_obj *p2p_soc_obj; struct cancel_roc_context *cancel_roc; - p2p_debug("soc:%p, cookie:0x%llx", soc, cookie); + p2p_debug("soc:%pK, cookie:0x%llx", soc, cookie); if (!soc) { p2p_err("psoc context passed is NULL"); @@ -196,7 +196,7 @@ QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev) struct p2p_soc_priv_obj *p2p_soc_obj; uint32_t vdev_id; - p2p_debug("vdev:%p", vdev); + p2p_debug("vdev:%pK", vdev); if (!vdev) { p2p_err("null vdev"); @@ -227,7 +227,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, struct p2p_soc_priv_obj *p2p_soc_obj; struct tx_action_context *tx_action; - p2p_debug("soc:%p, vdev_id:%d, chan:%d, wait:%d, buf_len:%d, cck:%d, no ack:%d, off chan:%d", + p2p_debug("soc:%pK, vdev_id:%d, chan:%d, wait:%d, buf_len:%d, cck:%d, no ack:%d, off chan:%d", soc, mgmt_frm->vdev_id, mgmt_frm->chan, mgmt_frm->wait, mgmt_frm->len, mgmt_frm->no_cck, mgmt_frm->dont_wait_for_ack, mgmt_frm->off_chan); @@ -286,7 +286,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, struct p2p_soc_priv_obj *p2p_soc_obj; struct cancel_roc_context *cancel_tx; - p2p_debug("soc:%p, cookie:0x%llx", soc, cookie); + p2p_debug("soc:%pK, cookie:0x%llx", soc, cookie); if (!soc) { p2p_err("psoc context passed is NULL"); @@ -324,7 +324,7 @@ QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, uint16_t obj_id; struct wlan_objmgr_vdev *vdev; - p2p_debug("soc:%p, vdev_id:%d, opp_ps:%d, ct_window:%d, count:%d, duration:%d, duration:%d, ps_selection:%d", + p2p_debug("soc:%pK, vdev_id:%d, opp_ps:%d, ct_window:%d, count:%d, duration:%d, duration:%d, ps_selection:%d", soc, ps_config->vdev_id, ps_config->opp_ps, ps_config->ct_window, ps_config->count, ps_config->duration, ps_config->single_noa_duration, @@ -364,7 +364,7 @@ QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc, struct wlan_lmac_if_p2p_tx_ops *p2p_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; - p2p_debug("soc:%p, vdev_id:%d, ctl_flags:%d, freq:%d, period:%d, interval:%d, count:%d, dev_types_len:%d, probe_resp_len:%d, device_types:%p, probe_resp_tmplt:%p", + p2p_debug("soc:%pK, vdev_id:%d, ctl_flags:%d, freq:%d, period:%d, interval:%d, count:%d, dev_types_len:%d, probe_resp_len:%d, device_types:%pK, probe_resp_tmplt:%pK", soc, p2p_lo_start->vdev_id, p2p_lo_start->ctl_flags, p2p_lo_start->freq, p2p_lo_start->period, p2p_lo_start->interval, p2p_lo_start->count, @@ -391,7 +391,7 @@ QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc, struct wlan_lmac_if_p2p_tx_ops *p2p_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; - p2p_debug("soc:%p, vdev_id:%d", soc, vdev_id); + p2p_debug("soc:%pK, vdev_id:%d", soc, vdev_id); if (!soc) { p2p_err("psoc context passed is NULL"); From d1f5b2d71fe13dfed798971d8522c49479dfe9b3 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 18 Sep 2017 10:09:05 -0700 Subject: [PATCH 133/404] qcacmn: target_if: Replace instances of unadorned %p Replace instances of unadorned %p in target_if. Change-Id: I1c8a1b98be2d12fcf8e1fadf4a889268dfe37058 CRs-Fixed: 2111274 --- src/target_if_p2p.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index 430a306a4eb4..5f03401c389c 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -52,10 +52,10 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; - target_if_debug("scn:%p, data:%p, datalen:%d", scn, data, datalen); + target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, data, datalen); if (!scn || !data) { - target_if_err("scn: 0x%p, data: 0x%p", scn, data); + target_if_err("scn: 0x%pK, data: 0x%pK", scn, data); return -EINVAL; } @@ -118,10 +118,10 @@ static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; QDF_STATUS status = QDF_STATUS_E_FAILURE; - target_if_debug("scn:%p, data:%p, datalen:%d", scn, data, datalen); + target_if_debug("scn:%pK, data:%pK, datalen:%d", scn, data, datalen); if (!scn || !data) { - target_if_err("scn: 0x%p, data: 0x%p", scn, data); + target_if_err("scn: 0x%pK, data: 0x%pK", scn, data); return -EINVAL; } @@ -169,7 +169,7 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( int status; wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%pK, arg:%pK", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -192,7 +192,7 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( int status; wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%pK, arg:%pK", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -215,7 +215,7 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( int status; wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%pK, arg:%pK", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -237,7 +237,7 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( int status; wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%p, arg:%p", psoc, arg); + target_if_debug("psoc:%pK, arg:%pK", psoc, arg); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -260,7 +260,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, QDF_STATUS status; wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%p, vdev_id:%d, opp_ps:%d", psoc, + target_if_debug("psoc:%pK, vdev_id:%d, opp_ps:%d", psoc, ps_config->vdev_id, ps_config->opp_ps); if (!wmi_handle) { @@ -301,7 +301,7 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, { wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%p, vdev_id:%d", psoc, lo_start->vdev_id); + target_if_debug("psoc:%pK, vdev_id:%d", psoc, lo_start->vdev_id); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -321,7 +321,7 @@ QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, { wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%p, vdev_id:%d", psoc, vdev_id); + target_if_debug("psoc:%pK, vdev_id:%d", psoc, vdev_id); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -343,7 +343,7 @@ QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_INVAL; } - target_if_debug("psoc:%p, vdev_id:%d disable_noa:%d", + target_if_debug("psoc:%pK, vdev_id:%d disable_noa:%d", psoc, vdev_id, disable_noa); param.if_id = vdev_id; param.param_id = WMI_VDEV_PARAM_DISABLE_NOA_P2P_GO; From 33e2307f4221061a643ee8ce7589beafcbc9ca16 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 18 Sep 2017 10:09:05 -0700 Subject: [PATCH 134/404] qcacmn: target_if: Replace instances of unadorned %p Replace instances of unadorned %p in target_if. Change-Id: I1c8a1b98be2d12fcf8e1fadf4a889268dfe37058 CRs-Fixed: 2111274 --- src/target_if_tdls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/target_if_tdls.c b/src/target_if_tdls.c index af4255be5d71..cff486f375ad 100644 --- a/src/target_if_tdls.c +++ b/src/target_if_tdls.c @@ -49,7 +49,7 @@ target_if_tdls_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen) QDF_STATUS status; if (!scn || !data) { - target_if_err("scn: 0x%p, data: 0x%p", scn, data); + target_if_err("scn: 0x%pK, data: 0x%pK", scn, data); return -EINVAL; } psoc = target_if_get_psoc_from_scn_hdl(scn); From 95a3ebacc1efbb13faa534e4d52f73b8d001769c Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 18 Sep 2017 10:11:16 -0700 Subject: [PATCH 135/404] 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_p2p.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 17d5178c3486..96be4c5b8755 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -55,7 +55,7 @@ static void wlan_p2p_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); @@ -129,7 +129,7 @@ static void wlan_p2p_action_tx_cnf_callback(void *user_data, struct wireless_dev *wdev; bool is_success; - cfg80211_info("user data:%p, action cookie:%llx, buf:%p, len:%d, tx status:%d", + cfg80211_info("user data:%pK, action cookie:%llx, buf:%pK, len:%d, tx status:%d", user_data, tx_cnf->action_cookie, tx_cnf->buf, tx_cnf->buf_len, tx_cnf->status); @@ -186,7 +186,7 @@ static void wlan_p2p_lo_event_callback(void *user_data, struct wireless_dev *wdev; struct sk_buff *vendor_event; - cfg80211_debug("user data:%p, vdev id:%d, reason code:%d", + cfg80211_debug("user data:%pK, vdev id:%d, reason code:%d", user_data, p2p_lo_event->vdev_id, p2p_lo_event->reason_code); @@ -256,7 +256,7 @@ static void wlan_p2p_event_callback(void *user_data, struct vdev_osif_priv *osif_priv; struct wireless_dev *wdev; - cfg80211_debug("user data:%p, vdev id:%d, event type:%d", + cfg80211_debug("user data:%pK, vdev id:%d, event type:%d", user_data, p2p_event->vdev_id, p2p_event->roc_event); psoc = user_data; From b4b4eb8df3168e4719ae8579c3fa35782db923db Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 18 Sep 2017 10:11:16 -0700 Subject: [PATCH 136/404] 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 c441d7b5a8beb3bb718b447c1b38ff5ea6144752 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 7 Sep 2017 20:06:17 -0700 Subject: [PATCH 137/404] qcacmn: Add host data path functions for TDLS Add and enable host data path functions for Napier TDLS. Change-Id: I228c2dcf4e8d797d173007a3306d112aca5ba52f CRs-Fixed: 2114813 --- core/src/wlan_tdls_cmds_process.c | 35 +++++++++++++++++++++++++++-- core/src/wlan_tdls_ct.c | 3 +-- dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 5b66567618e5..3b9f1ad339a0 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1133,6 +1133,10 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) struct wlan_serialization_command cmd = {0,}; enum wlan_serialization_status ser_cmd_status; struct wlan_objmgr_vdev *vdev; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj; + uint8_t *mac; + struct tdls_peer *peer; QDF_STATUS status = QDF_STATUS_SUCCESS; if (!req || !req->vdev) { @@ -1140,7 +1144,35 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) status = QDF_STATUS_E_INVAL; goto error; } + vdev = req->vdev; + + /* vdev reference cnt is acquired in ucfg_tdls_oper */ + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + + if (!vdev_obj || !soc_obj) { + tdls_err("tdls vdev_obj: %p soc_obj: %p", vdev_obj, soc_obj); + status = QDF_STATUS_E_NULL_VALUE; + goto error; + } + + mac = req->peer_addr; + peer = tdls_find_peer(vdev_obj, mac); + if (!peer) { + tdls_err(QDF_MAC_ADDRESS_STR + " not found, ignore NL80211_TDLS_ENABLE_LINK", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto error; + } + + if (soc_obj->tdls_dp_vdev_update) + soc_obj->tdls_dp_vdev_update(&soc_obj->soc, + peer->sta_id, + soc_obj->tdls_update_dp_vdev_flags, + false); + cmd.cmd_type = WLAN_SER_CMD_TDLS_DEL_PEER; cmd.cmd_id = 0; cmd.cmd_cb = (wlan_serialization_cmd_callback) @@ -1904,8 +1936,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) soc_obj->tdls_dp_vdev_update(&soc_obj->soc, peer->sta_id, soc_obj->tdls_update_dp_vdev_flags, - ((peer->link_status == - TDLS_LINK_CONNECTED) ? true : false)); + false); if (soc_obj->tdls_event_cb) { qdf_mem_copy(ind.peer_mac, macaddr, QDF_MAC_ADDR_SIZE); diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index a07f6dc418bf..2b676114c892 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -532,8 +532,7 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, tdls_soc->tdls_dp_vdev_update(&tdls_soc->soc, curr_peer->sta_id, tdls_soc->tdls_update_dp_vdev_flags, - ((curr_peer->link_status == - TDLS_LINK_CONNECTED) ? true : false)); + false); indication.reason = reason; indication.vdev = tdls_vdev->vdev; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 5b41921a02fc..c5bf80475e8e 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -218,6 +218,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; soc_obj->tdls_del_all_peers = req->tdls_del_all_peers; soc_obj->tdls_update_dp_vdev_flags = req->tdls_update_dp_vdev_flags; + soc_obj->tdls_dp_vdev_update = req->tdls_dp_vdev_update; tdls_pm_call_backs.tdls_notify_increment_session = tdls_notify_increment_session; From 3c49b2e6f95f6aac026669efcd4acb16ef7dc06d Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Tue, 19 Sep 2017 11:29:41 -0700 Subject: [PATCH 138/404] qcacmn: Remove qdf_handle_t from unused qdf_defer APIs There are many QDF APIs require a qdf_handle_t parameter. None of these APIs actually use the qdf_handle_t parameter, meaning it can be completely removed. As a step toward globally removing this unused type, remove qdf_handle_t parameters from unsed qdf_defer APIs. Change-Id: I0568aa7cbd430abc0d046143482a067d96bf6313 CRs-Fixed: 2112646 --- src/wlan_policy_mgr_init_deinit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index c20c548a7290..c946988f8789 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -365,7 +365,7 @@ QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) } if (pm_ctx->sta_ap_intf_check_work_info) { - qdf_cancel_work(0, &pm_ctx->sta_ap_intf_check_work); + qdf_cancel_work(&pm_ctx->sta_ap_intf_check_work); qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info); pm_ctx->sta_ap_intf_check_work_info = NULL; } From 8f099b8930de2d6634d5b20548c2b0e280509798 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 7 Sep 2017 17:42:15 +0800 Subject: [PATCH 139/404] qcacmn: Add debug functions to P2P component In order to facilitate debugging P2P issues, add debug information to P2P component. Change-Id: I0192b1ee25bb74dc512b01ad451b03d1a45a5446 CRs-Fixed: 2105782 --- core/src/wlan_p2p_main.c | 235 +++++++++++++++++++++++++++++ core/src/wlan_p2p_main.h | 106 +++++++++++++ core/src/wlan_p2p_off_chan_tx.c | 123 +++++++++++++++ core/src/wlan_p2p_off_chan_tx.h | 3 + dispatcher/inc/wlan_p2p_ucfg_api.h | 50 ++++++ dispatcher/src/wlan_p2p_ucfg_api.c | 50 ++++++ 6 files changed, 567 insertions(+) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 77c22dc5ffaa..bb6a237b887b 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -507,6 +507,32 @@ static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } +#ifdef WLAN_FEATURE_P2P_DEBUG +/** + * wlan_p2p_init_connection_status() - init connection status + * @p2p_soc_obj: pointer to p2p psoc object + * + * This function initial p2p connection status. + * + * Return: None + */ +static void wlan_p2p_init_connection_status( + struct p2p_soc_priv_obj *p2p_soc_obj) +{ + if (!p2p_soc_obj) { + p2p_err("invalid p2p soc obj"); + return; + } + + p2p_soc_obj->connection_status = P2P_NOT_ACTIVE; +} +#else +static void wlan_p2p_init_connection_status( + struct p2p_soc_priv_obj *p2p_soc_obj) +{ +} +#endif /* WLAN_FEATURE_P2P_DEBUG */ + QDF_STATUS p2p_component_init(void) { QDF_STATUS status; @@ -738,6 +764,8 @@ QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, start_param->lo_event_cb_data = req->lo_event_cb_data; p2p_soc_obj->start_param = start_param; + wlan_p2p_init_connection_status(p2p_soc_obj); + /* register p2p lo stop and noa event */ tgt_p2p_register_lo_ev_handler(soc); tgt_p2p_register_noa_ev_handler(soc); @@ -1021,3 +1049,210 @@ void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr) } p2p_debug("peer is authorized"); } + +#ifdef WLAN_FEATURE_P2P_DEBUG +static struct p2p_soc_priv_obj * +get_p2p_soc_obj_by_vdev(struct wlan_objmgr_vdev *vdev) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + struct wlan_objmgr_psoc *soc; + + if (!vdev) { + p2p_err("vdev context passed is NULL"); + return NULL; + } + + soc = wlan_vdev_get_psoc(vdev); + if (!soc) { + p2p_err("soc context is NULL"); + return NULL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) + p2p_err("P2P soc context is NULL"); + + return p2p_soc_obj; +} + +QDF_STATUS p2p_status_scan(struct wlan_objmgr_vdev *vdev) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + enum tQDF_ADAPTER_MODE mode; + + p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); + if (!p2p_soc_obj) { + p2p_err("P2P soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mode = wlan_vdev_mlme_get_opmode(vdev); + if (mode != QDF_P2P_CLIENT_MODE && + mode != QDF_P2P_DEVICE_MODE) { + p2p_debug("this is not P2P CLIENT or DEVICE, mode:%d", + mode); + return QDF_STATUS_SUCCESS; + } + + p2p_debug("connection status:%d", p2p_soc_obj->connection_status); + switch (p2p_soc_obj->connection_status) { + case P2P_GO_NEG_COMPLETED: + case P2P_GO_NEG_PROCESS: + p2p_soc_obj->connection_status = + P2P_CLIENT_CONNECTING_STATE_1; + p2p_debug("[P2P State] Changing state from Go nego completed to Connection is started"); + p2p_debug("P2P Scanning is started for 8way Handshake"); + break; + case P2P_CLIENT_DISCONNECTED_STATE: + p2p_soc_obj->connection_status = + P2P_CLIENT_CONNECTING_STATE_2; + p2p_debug("[P2P State] Changing state from Disconnected state to Connection is started"); + p2p_debug("P2P Scanning is started for 4way Handshake"); + break; + default: + break; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_status_connect(struct wlan_objmgr_vdev *vdev) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + enum tQDF_ADAPTER_MODE mode; + + p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); + if (!p2p_soc_obj) { + p2p_err("P2P soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mode = wlan_vdev_mlme_get_opmode(vdev); + if (mode != QDF_P2P_CLIENT_MODE) { + p2p_debug("this is not P2P CLIENT, mode:%d", mode); + return QDF_STATUS_SUCCESS; + } + + p2p_debug("connection status:%d", p2p_soc_obj->connection_status); + switch (p2p_soc_obj->connection_status) { + case P2P_CLIENT_CONNECTING_STATE_1: + p2p_soc_obj->connection_status = + P2P_CLIENT_CONNECTED_STATE_1; + p2p_debug("[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake"); + break; + case P2P_CLIENT_DISCONNECTED_STATE: + p2p_debug("No scan before 4-way handshake"); + /* + * Fall thru since no scan before 4-way handshake and + * won't enter state P2P_CLIENT_CONNECTING_STATE_2: + */ + case P2P_CLIENT_CONNECTING_STATE_2: + p2p_soc_obj->connection_status = + P2P_CLIENT_COMPLETED_STATE; + p2p_debug("[P2P State] Changing state from Connecting state to P2P Client Connection Completed"); + break; + default: + break; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_status_disconnect(struct wlan_objmgr_vdev *vdev) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + enum tQDF_ADAPTER_MODE mode; + + p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); + if (!p2p_soc_obj) { + p2p_err("P2P soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mode = wlan_vdev_mlme_get_opmode(vdev); + if (mode != QDF_P2P_CLIENT_MODE) { + p2p_debug("this is not P2P CLIENT, mode:%d", mode); + return QDF_STATUS_SUCCESS; + } + + p2p_debug("connection status:%d", p2p_soc_obj->connection_status); + switch (p2p_soc_obj->connection_status) { + case P2P_CLIENT_CONNECTED_STATE_1: + p2p_soc_obj->connection_status = + P2P_CLIENT_DISCONNECTED_STATE; + p2p_debug("[P2P State] 8 way Handshake completed and moved to disconnected state"); + break; + case P2P_CLIENT_COMPLETED_STATE: + p2p_soc_obj->connection_status = P2P_NOT_ACTIVE; + p2p_debug("[P2P State] P2P Client is removed and moved to inactive state"); + break; + default: + break; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_status_start_bss(struct wlan_objmgr_vdev *vdev) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + enum tQDF_ADAPTER_MODE mode; + + p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); + if (!p2p_soc_obj) { + p2p_err("P2P soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mode = wlan_vdev_mlme_get_opmode(vdev); + if (mode != QDF_P2P_GO_MODE) { + p2p_debug("this is not P2P GO, mode:%d", mode); + return QDF_STATUS_SUCCESS; + } + + p2p_debug("connection status:%d", p2p_soc_obj->connection_status); + switch (p2p_soc_obj->connection_status) { + case P2P_GO_NEG_COMPLETED: + p2p_soc_obj->connection_status = + P2P_GO_COMPLETED_STATE; + p2p_debug("[P2P State] From Go nego completed to Non-autonomous Group started"); + break; + case P2P_NOT_ACTIVE: + p2p_soc_obj->connection_status = + P2P_GO_COMPLETED_STATE; + p2p_debug("[P2P State] From Inactive to Autonomous Group started"); + break; + default: + break; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + enum tQDF_ADAPTER_MODE mode; + + p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); + if (!p2p_soc_obj) { + p2p_err("P2P soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mode = wlan_vdev_mlme_get_opmode(vdev); + if (mode != QDF_P2P_GO_MODE) { + p2p_debug("this is not P2P GO, mode:%d", mode); + return QDF_STATUS_SUCCESS; + } + + p2p_debug("connection status:%d", p2p_soc_obj->connection_status); + if (p2p_soc_obj->connection_status == P2P_GO_COMPLETED_STATE) { + p2p_soc_obj->connection_status = P2P_NOT_ACTIVE; + p2p_debug("[P2P State] From GO completed to Inactive state GO got removed"); + } + + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_P2P_DEBUG */ diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 9aabc6a5448d..95aa3f0094b8 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -129,6 +129,32 @@ struct p2p_noa_event { struct p2p_noa_info *noa_info; }; +#ifdef WLAN_FEATURE_P2P_DEBUG +/** + * enum p2p_connection_status - p2p connection status + * @P2P_NOT_ACTIVE: P2P not active status + * @P2P_GO_NEG_PROCESS: P2P GO negotiation in process + * @P2P_GO_NEG_COMPLETED: P2P GO negotiation complete + * @P2P_CLIENT_CONNECTING_STATE_1: P2P client connecting state 1 + * @P2P_GO_COMPLETED_STATE: P2P GO complete state + * @P2P_CLIENT_CONNECTED_STATE_1: P2P client connected state 1 + * @P2P_CLIENT_DISCONNECTED_STATE: P2P client disconnected state + * @P2P_CLIENT_CONNECTING_STATE_2: P2P client connecting state 2 + * @P2P_CLIENT_COMPLETED_STATE: P2P client complete state + */ +enum p2p_connection_status { + P2P_NOT_ACTIVE, + P2P_GO_NEG_PROCESS, + P2P_GO_NEG_COMPLETED, + P2P_CLIENT_CONNECTING_STATE_1, + P2P_GO_COMPLETED_STATE, + P2P_CLIENT_CONNECTED_STATE_1, + P2P_CLIENT_DISCONNECTED_STATE, + P2P_CLIENT_CONNECTING_STATE_2, + P2P_CLIENT_COMPLETED_STATE +}; +#endif + /** * struct p2p_soc_priv_obj - Per SoC p2p private object * @soc: Pointer to SoC context @@ -140,6 +166,7 @@ struct p2p_noa_event { * data to HDD * @cancel_roc_done: Cancel roc done event * @roc_runtime_lock: Runtime lock for roc request + * @connection_status:Global P2P connection status */ struct p2p_soc_priv_obj { struct wlan_objmgr_psoc *soc; @@ -150,6 +177,9 @@ struct p2p_soc_priv_obj { struct p2p_start_param *start_param; qdf_event_t cancel_roc_done; qdf_runtime_lock_t roc_runtime_lock; +#ifdef WLAN_FEATURE_P2P_DEBUG + enum p2p_connection_status connection_status; +#endif }; /** @@ -305,4 +335,80 @@ QDF_STATUS p2p_process_lo_stop( */ QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event); +#ifdef WLAN_FEATURE_P2P_DEBUG +/** + * p2p_status_scan() - Update P2P connection status + * @vdev: vdev context + * + * This function updates P2P connection status when scanning + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_status_scan(struct wlan_objmgr_vdev *vdev); + +/** + * p2p_status_connect() - Update P2P connection status + * @vdev: vdev context + * + * This function updates P2P connection status when connecting. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_status_connect(struct wlan_objmgr_vdev *vdev); + +/** + * p2p_status_disconnect() - Update P2P connection status + * @vdev: vdev context + * + * This function updates P2P connection status when disconnecting. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_status_disconnect(struct wlan_objmgr_vdev *vdev); + +/** + * p2p_status_start_bss() - Update P2P connection status + * @vdev: vdev context + * + * This function updates P2P connection status when starting BSS. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_status_start_bss(struct wlan_objmgr_vdev *vdev); + +/** + * p2p_status_stop_bss() - Update P2P connection status + * @vdev: vdev context + * + * This function updates P2P connection status when stopping BSS. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev); +#else +static inline QDF_STATUS p2p_status_scan(struct wlan_objmgr_vdev *vdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS p2p_status_connect(struct wlan_objmgr_vdev *vdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS p2p_status_disconnect(struct wlan_objmgr_vdev *vdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS p2p_status_start_bss(struct wlan_objmgr_vdev *vdev) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* WLAN_FEATURE_P2P_DEBUG */ #endif /* _WLAN_P2P_MAIN_H_ */ diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index ce0692c2111e..7b7c3c50ef18 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -665,6 +665,117 @@ static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length, return QDF_STATUS_SUCCESS; } +#ifdef WLAN_FEATURE_P2P_DEBUG +/** + * p2p_tx_update_connection_status() - Update P2P connection status + * with tx frame + * @p2p_soc_obj: P2P soc private object + * @tx_frame_info: frame information + * @mac_to: Pointer to dest MAC address + * + * This function updates P2P connection status with tx frame. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_tx_update_connection_status( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct p2p_frame_info *tx_frame_info, + uint8_t *mac_to) +{ + if (!p2p_soc_obj || !tx_frame_info || !mac_to) { + p2p_err("invalid p2p_soc_obj:%pK or tx_frame_info:%pK or mac_to:%pK", + p2p_soc_obj, tx_frame_info, mac_to); + return QDF_STATUS_E_INVAL; + } + + if (tx_frame_info->public_action_type != + P2P_PUBLIC_ACTION_NOT_SUPPORT) + p2p_debug("%s ---> OTA to "QDF_MAC_ADDRESS_STR, + p2p_get_frame_type_str(tx_frame_info), + QDF_MAC_ADDR_ARRAY(mac_to)); + + if ((tx_frame_info->public_action_type == + P2P_PUBLIC_ACTION_PROV_DIS_REQ) && + (p2p_soc_obj->connection_status == P2P_NOT_ACTIVE)) { + p2p_soc_obj->connection_status = P2P_GO_NEG_PROCESS; + p2p_debug("[P2P State]Inactive state to GO negotiation progress state"); + } else if ((tx_frame_info->public_action_type == + P2P_PUBLIC_ACTION_NEG_CNF) && + (p2p_soc_obj->connection_status == + P2P_GO_NEG_PROCESS)) { + p2p_soc_obj->connection_status = P2P_GO_NEG_COMPLETED; + p2p_debug("[P2P State]GO nego progress to GO nego completed state"); + } + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_rx_update_connection_status() - Update P2P connection status + * with rx frame + * @p2p_soc_obj: P2P soc private object + * @rx_frame_info: frame information + * @mac_from: Pointer to source MAC address + * + * This function updates P2P connection status with rx frame. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_rx_update_connection_status( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct p2p_frame_info *rx_frame_info, + uint8_t *mac_from) +{ + if (!p2p_soc_obj || !rx_frame_info || !mac_from) { + p2p_err("invalid p2p_soc_obj:%pK or rx_frame_info:%pK, mac_from:%pK", + p2p_soc_obj, rx_frame_info, mac_from); + return QDF_STATUS_E_INVAL; + } + + if (rx_frame_info->public_action_type != + P2P_PUBLIC_ACTION_NOT_SUPPORT) + p2p_debug("%s <--- OTA from "QDF_MAC_ADDRESS_STR, + p2p_get_frame_type_str(rx_frame_info), + QDF_MAC_ADDR_ARRAY(mac_from)); + + if ((rx_frame_info->public_action_type == + P2P_PUBLIC_ACTION_PROV_DIS_REQ) && + (p2p_soc_obj->connection_status == P2P_NOT_ACTIVE)) { + p2p_soc_obj->connection_status = P2P_GO_NEG_PROCESS; + p2p_debug("[P2P State]Inactive state to GO negotiation progress state"); + } else if ((rx_frame_info->public_action_type == + P2P_PUBLIC_ACTION_NEG_CNF) && + (p2p_soc_obj->connection_status == + P2P_GO_NEG_PROCESS)) { + p2p_soc_obj->connection_status = P2P_GO_NEG_COMPLETED; + p2p_debug("[P2P State]GO negotiation progress to GO negotiation completed state"); + } else if ((rx_frame_info->public_action_type == + P2P_PUBLIC_ACTION_INVIT_REQ) && + (p2p_soc_obj->connection_status == P2P_NOT_ACTIVE)) { + p2p_soc_obj->connection_status = P2P_GO_NEG_COMPLETED; + p2p_debug("[P2P State]Inactive state to GO negotiation completed state Autonomous GO formation"); + } + + return QDF_STATUS_SUCCESS; +} +#else +static QDF_STATUS p2p_tx_update_connection_status( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct p2p_frame_info *tx_frame_info, + uint8_t *mac_to) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS p2p_rx_update_connection_status( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct p2p_frame_info *rx_frame_info, + uint8_t *mac_from) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * p2p_packet_alloc() - allocate qdf nbuf * @size: buffe size @@ -1428,6 +1539,7 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) { struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_roc_context *curr_roc_ctx; + uint8_t *mac_to; QDF_STATUS status; status = p2p_tx_context_check_valid(tx_ctx); @@ -1459,6 +1571,11 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) goto fail; } + /* update P2P connection status with tx frame info */ + mac_to = &(tx_ctx->buf[DST_MAC_ADDR_OFFSET]); + p2p_tx_update_connection_status(p2p_soc_obj, + &(tx_ctx->frame_info), mac_to); + status = p2p_vdev_check_valid(tx_ctx); if (status != QDF_STATUS_SUCCESS) { p2p_debug("invalid vdev or vdev mode"); @@ -1596,6 +1713,7 @@ QDF_STATUS p2p_process_rx_mgmt( struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_start_param *start_param; struct p2p_frame_info frame_info; + uint8_t *mac_from; p2p_soc_obj = rx_mgmt_event->p2p_soc_obj; rx_mgmt = rx_mgmt_event->rx_mgmt; @@ -1615,6 +1733,11 @@ QDF_STATUS p2p_process_rx_mgmt( p2p_get_frame_info(rx_mgmt->buf, rx_mgmt->frame_len, &frame_info); + /* update P2P connection status with rx frame info */ + mac_from = &(rx_mgmt->buf[SRC_MAC_ADDR_OFFSET]); + p2p_rx_update_connection_status(p2p_soc_obj, + &frame_info, mac_from); + p2p_debug("action_sub_type %u, action_type %d", frame_info.public_action_type, frame_info.action_type); diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index 8b255e71f699..39f006b7e0f7 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -51,6 +51,9 @@ #define P2P_ACTION_FRAME_ACK_WAIT 300 #define P2P_ACTION_FRAME_TX_TIMEOUT 2000 +#define DST_MAC_ADDR_OFFSET 4 +#define SRC_MAC_ADDR_OFFSET (DST_MAC_ADDR_OFFSET + QDF_MAC_ADDR_SIZE) + #define P2P_NOA_STREAM_ARR_SIZE (P2P_MAX_NOA_ATTR_LEN + (2 * P2P_IE_HEADER_LEN)) #define P2P_GET_TYPE_FRM_FC(__fc__) (((__fc__) & 0x0F) >> 2) diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/dispatcher/inc/wlan_p2p_ucfg_api.h index 228da46ccb50..708a4bf7e338 100644 --- a/dispatcher/inc/wlan_p2p_ucfg_api.h +++ b/dispatcher/inc/wlan_p2p_ucfg_api.h @@ -297,4 +297,54 @@ void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr); QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, bool disable_noa); +/** + * ucfg_p2p_status_scan() - Show P2P connection status when scanning + * @vdev: vdev context + * + * This function shows P2P connection status when scanning. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_status_scan(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_p2p_status_connect() - Update P2P connection status + * @vdev: vdev context + * + * Updates P2P connection status by up layer when connecting. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_status_connect(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_p2p_status_disconnect() - Update P2P connection status + * @vdev: vdev context + * + * Updates P2P connection status by up layer when disconnecting. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_status_disconnect(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_p2p_status_start_bss() - Update P2P connection status + * @vdev: vdev context + * + * Updates P2P connection status by up layer when starting bss. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_status_start_bss(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_p2p_status_stop_bss() - Update P2P connection status + * @vdev: vdev context + * + * Updates P2P connection status by up layer when stopping bss. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev); + #endif /* _WLAN_P2P_UCFG_API_H_ */ diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 8398dd2dccf1..a59469282ee4 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -421,3 +421,53 @@ QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc, return status; } + +QDF_STATUS ucfg_p2p_status_scan(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + p2p_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + return p2p_status_scan(vdev); +} + +QDF_STATUS ucfg_p2p_status_connect(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + p2p_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + return p2p_status_connect(vdev); +} + +QDF_STATUS ucfg_p2p_status_disconnect(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + p2p_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + return p2p_status_disconnect(vdev); +} + +QDF_STATUS ucfg_p2p_status_start_bss(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + p2p_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + return p2p_status_start_bss(vdev); +} + +QDF_STATUS ucfg_p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + p2p_err("vdev is NULL"); + return QDF_STATUS_E_INVAL; + } + + return p2p_status_stop_bss(vdev); +} From f2dce0cf16439d4b396ea34df624b5789f46bef1 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 25 Aug 2017 15:28:50 +0800 Subject: [PATCH 140/404] qcacmn: Initialize variable in cfg80211 roc and mgmt tx To avoid unexpect issue, initialize variable in cfg80211 roc and mgmt tx. Change-Id: I5cc11cf011a136f29f6815142a45918ed71583fa CRs-Fixed: 2091906 --- src/wlan_cfg80211_p2p.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 96be4c5b8755..372a115e3986 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -336,7 +336,7 @@ int wlan_cfg80211_roc(struct wlan_objmgr_vdev *vdev, struct ieee80211_channel *chan, uint32_t duration, uint64_t *cookie) { - struct p2p_roc_req roc_req; + struct p2p_roc_req roc_req = {0}; struct wlan_objmgr_psoc *psoc; uint8_t vdev_id; bool ok; @@ -405,7 +405,7 @@ int wlan_cfg80211_mgmt_tx(struct wlan_objmgr_vdev *vdev, const uint8_t *buf, uint32_t len, bool no_cck, bool dont_wait_for_ack, uint64_t *cookie) { - struct p2p_mgmt_tx mgmt_tx; + struct p2p_mgmt_tx mgmt_tx = {0}; struct wlan_objmgr_psoc *psoc; uint8_t vdev_id; From 96f75a60380bb6d7e98acf2635d885ee24f9dea9 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 9 Jun 2017 15:42:11 +0800 Subject: [PATCH 141/404] qcacmn: Add suspend and resume handler in P2P Add suspend and resume handler in P2P component. Cleanup mgmt tx queue and roc queue in P2P suspend handler. Change-Id: I36bbe98e51eb817b60f08404636f0617b6aa537f CRs-Fixed: 2058858 --- core/src/wlan_p2p_main.c | 131 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index bb6a237b887b..063af68ce1d9 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -34,6 +34,10 @@ #include "wlan_p2p_roc.h" #include "wlan_p2p_off_chan_tx.h" +#ifdef WLAN_PMO_ENABLE +#include +#endif + /** * p2p_get_cmd_type_str() - parse cmd to string * @cmd_type: P2P cmd type @@ -533,6 +537,131 @@ static void wlan_p2p_init_connection_status( } #endif /* WLAN_FEATURE_P2P_DEBUG */ +#ifdef WLAN_PMO_ENABLE + +/** + * p2p_suspend_handler() - suspend handler of P2P + * @psoc: pointer to psoc object + * @arg: pointer to input argument + * + * This function is suspend handler of P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + if (!psoc) { + p2p_err("psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("P2P soc object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + /* clean up queue of p2p psoc private object */ + p2p_cleanup_tx_queue(p2p_soc_obj); + p2p_cleanup_roc_queue(p2p_soc_obj); + + p2p_debug("handle suspend complete"); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_resume_handler() - resume handler of P2P + * @psoc: pointer to psoc object + * @arg: pointer to input argument + * + * This function is resume handler of P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) +{ + p2p_debug("handle resume complete"); + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_register_pmo_handler() - register pmo handler + * + * This function registers pmo handler of P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static inline QDF_STATUS p2p_register_pmo_handler(void) +{ + QDF_STATUS status; + + status = pmo_register_suspend_handler(WLAN_UMAC_COMP_P2P, + p2p_suspend_handler, NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to register suspend handler"); + return status; + } + + status = pmo_register_resume_handler(WLAN_UMAC_COMP_P2P, + p2p_resume_handler, NULL); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to register resume handler"); + pmo_unregister_suspend_handler(WLAN_UMAC_COMP_P2P, + p2p_suspend_handler); + return status; + } + + p2p_debug("Register pmo handler success"); + + return status; +} + +/** + * p2p_unregister_pmo_handler() - unregister pmo handler + * + * This function unregisters pmo handler of P2P component. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static inline QDF_STATUS p2p_unregister_pmo_handler(void) +{ + QDF_STATUS status; + QDF_STATUS ret_status = QDF_STATUS_SUCCESS; + + status = pmo_unregister_suspend_handler(WLAN_UMAC_COMP_P2P, + p2p_suspend_handler); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to unregister suspend handler"); + ret_status = status; + } + + status = pmo_unregister_resume_handler(WLAN_UMAC_COMP_P2P, + p2p_resume_handler); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to unregister resume handler"); + ret_status = status; + } + + p2p_debug("Unregister pmo handler complete"); + + return status; +} + +#else +static inline QDF_STATUS p2p_register_pmo_handler(void) +{ +} + +static inline QDF_STATUS p2p_unregister_pmo_handler(void) +{ +} +#endif /* End of WLAN_PMO_ENABLE */ + QDF_STATUS p2p_component_init(void) { QDF_STATUS status; @@ -691,6 +820,7 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) } qdf_runtime_lock_init(&p2p_soc_obj->roc_runtime_lock); + p2p_register_pmo_handler(); p2p_debug("p2p psoc object open successful"); @@ -720,6 +850,7 @@ QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) return QDF_STATUS_E_FAILURE; } + p2p_unregister_pmo_handler(); qdf_runtime_lock_deinit(&p2p_soc_obj->roc_runtime_lock); qdf_event_destroy(&p2p_soc_obj->cancel_roc_done); qdf_list_destroy(&p2p_soc_obj->tx_q_ack); From fc4449c809867a442d10f1a175dcba63a3b8cd24 Mon Sep 17 00:00:00 2001 From: Sandeep Puligilla Date: Wed, 18 Oct 2017 16:31:12 -0700 Subject: [PATCH 142/404] qcacmn: Initialize the mgmt tx params Triggering crash at firmware due to uninitialized value sent to firmware as part of wmi_mgmt_params. Initialize the management tx params at p2p_mgmt_tx before populate. Change-Id: Iea77266ee11f5742ea6a0074e4a6612452a764b1 CRs-Fixed: 2128419 --- core/src/wlan_p2p_off_chan_tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 7b7c3c50ef18..fb6b71ed35e6 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -877,7 +877,7 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, mgmt_ota_comp_cb tx_ota_comp_cb; struct wlan_frame_hdr *wh; struct wlan_objmgr_peer *peer; - struct wmi_mgmt_params mgmt_param; + struct wmi_mgmt_params mgmt_param = { 0 }; struct wlan_objmgr_psoc *psoc; void *mac_addr; From 76b846451293eac10f640401a92e235c8dd1cce1 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Fri, 15 Sep 2017 13:39:04 +0530 Subject: [PATCH 143/404] qcacmn: PCL update for 3-port combinations Updated PCL table to support 3-port concurrent scenarios AP+AP+STA, AP+GO+STA and AP+AP+AP. The PCL entries are updated to have below behavior: 1. AP+GO or AP+AP will be supported either in DBS or in SCC mode 2. The Precedence order will be DBS, SCC. Also disabling 3-port combinations with P2P-CLI. Change-Id: I678e2b5a49577e173c0e34f83a7ccc528313aadd CRs-Fixed: 2127091 --- src/wlan_policy_mgr_tables_1x1_dbs_i.h | 480 +++++++++++++++++-------- src/wlan_policy_mgr_tables_2x2_dbs_i.h | 308 ++++++++-------- 2 files changed, 479 insertions(+), 309 deletions(-) diff --git a/src/wlan_policy_mgr_tables_1x1_dbs_i.h b/src/wlan_policy_mgr_tables_1x1_dbs_i.h index caaedaf05431..c12ab33993f4 100644 --- a/src/wlan_policy_mgr_tables_1x1_dbs_i.h +++ b/src/wlan_policy_mgr_tables_1x1_dbs_i.h @@ -222,61 +222,55 @@ static pm_dbs_pcl_third_connection_table_type pm_third_connection_pcl_dbs_1x1_table = { [PM_STA_SAP_SCC_24_1x1] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_SCC_24_2x2] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_MCC_24_1x1] = { [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_MCC_24_2x2] = { [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_SCC_5_1x1] = { [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_SCC_5_2x2] = { [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -285,8 +279,7 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -295,8 +288,7 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -323,8 +315,36 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_STA_SAP_DBS_1x1] = { [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, - [PM_SAP_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_24_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -332,10 +352,91 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + [PM_SAP_SAP_MCC_24_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_SCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, + PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_5_1x1] = { + [PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_5_2x2] = { + [PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_24_5_1x1] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_MCC_24_5_2x2] = { + [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + + [PM_SAP_SAP_DBS_1x1] = { + [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, + [PM_STA_P2P_GO_SCC_24_1x1] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_IBSS_MODE] = { @@ -343,65 +444,63 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_STA_P2P_GO_SCC_24_2x2] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = { + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_GO_MCC_24_1x1] = { [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_SAP_MODE] = { + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_GO_MCC_24_2x2] = { [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_SAP_MODE] = { + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_GO_SCC_5_1x1] = { [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_GO_SCC_5_2x2] = { [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_GO_MCC_5_1x1] = { [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, - [PM_SAP_MODE] = { + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_GO_MCC_5_2x2] = { [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, - [PM_SAP_MODE] = { + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -410,7 +509,8 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -419,7 +519,8 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -427,10 +528,10 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_STA_P2P_GO_DBS_1x1] = { [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { @@ -438,216 +539,272 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_STA_P2P_CLI_SCC_24_1x1] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_SCC_24_2x2] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_MCC_24_1x1] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_MCC_24_2x2] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_SCC_5_1x1] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_SCC_5_2x2] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_MCC_5_1x1] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_MCC_5_2x2] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, - [PM_IBSS_MODE] = {PM_NONE, PM_NONE, PM_NONE} }, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_IBSS_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_MCC_24_5_1x1] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_MCC_24_5_2x2] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_MCC_CH_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_P2P_CLI_DBS_1x1] = { [PM_STA_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = { - [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = { - [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = { - [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = { - [PM_STA_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_SAP_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_MCC_CH, PM_5G, PM_5G_MCC_CH}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = { - [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = { - [PM_STA_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_SAP_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, - [PM_P2P_GO_MODE] = {PM_SCC_CH_24G, PM_24G_SCC_CH, PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = { - [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, - [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = { - [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, - [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = { - [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, - [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = { - [PM_STA_MODE] = {PM_MCC_CH_5G, PM_5G, PM_5G}, - [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G, PM_24G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_DBS_1x1] = { [PM_STA_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_NONE, PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_SAP_SCC_24_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -658,8 +815,7 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_GO_SAP_SCC_24_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -694,8 +850,7 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_GO_SAP_SCC_5_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -706,8 +861,7 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_GO_SAP_SCC_5_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -766,8 +920,8 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_GO_SAP_DBS_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -778,31 +932,34 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_CLI_SAP_SCC_24_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_CLI_SAP_SCC_24_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_CLI_SAP_MCC_24_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { @@ -811,9 +968,10 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_CLI_SAP_MCC_24_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { @@ -822,9 +980,10 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_CLI_SAP_SCC_5_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { @@ -833,9 +992,10 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_CLI_SAP_SCC_5_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { @@ -844,9 +1004,10 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_CLI_SAP_MCC_5_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { @@ -855,20 +1016,22 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_CLI_SAP_MCC_5_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_CLI_SAP_MCC_24_5_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { @@ -877,9 +1040,10 @@ pm_third_connection_pcl_dbs_1x1_table = { [PM_P2P_CLI_SAP_MCC_24_5_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { diff --git a/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/src/wlan_policy_mgr_tables_2x2_dbs_i.h index 3f8b8c4a7329..c13944dfd06d 100644 --- a/src/wlan_policy_mgr_tables_2x2_dbs_i.h +++ b/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -252,24 +252,27 @@ static pm_dbs_pcl_third_connection_table_type pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_SAP_SCC_24_1x1] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_SCC_24_2x2] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_MCC_24_1x1] = { [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -277,7 +280,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_SAP_MCC_24_2x2] = { [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -285,42 +289,38 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_SAP_SCC_5_1x1] = { [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, - [PM_P2P_CLIENT_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, - [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_SCC_5_2x2] = { [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, - [PM_P2P_CLIENT_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, - [PM_P2P_GO_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_MCC_5_1x1] = { [PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, - [PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { - PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, - [PM_P2P_GO_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_STA_SAP_MCC_5_2x2] = { [PM_STA_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, - [PM_SAP_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, - PM_24G_MCC_CH}, - [PM_P2P_GO_MODE] = {PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -347,11 +347,11 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_SAP_DBS_1x1] = { [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_P2P_CLIENT_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -359,11 +359,11 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_SAP_DBS_2x2] = { [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_P2P_CLIENT_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -374,7 +374,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_SAP_MODE] = { PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, [PM_P2P_CLIENT_MODE] = { - PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, [PM_IBSS_MODE] = { @@ -382,21 +382,19 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_SAP_SAP_SCC_24_1x1] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_SAP_SAP_SCC_24_2x2] = { [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -423,24 +421,20 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_SAP_SAP_SCC_5_1x1] = { [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_SAP_SAP_SCC_5_2x2] = { [PM_STA_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_24G, PM_24G, PM_24G}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -487,24 +481,24 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_SAP_SAP_DBS_1x1] = { [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_SAP_SAP_DBS_2x2] = { [PM_STA_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, - [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, + [PM_SAP_MODE] = { PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_P2P_GO_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = {PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, @@ -674,8 +668,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_P2P_GO_SAP_SCC_24_1x1] = { [PM_STA_MODE] = { PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -686,8 +679,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_P2P_GO_SAP_SCC_24_2x2] = { [PM_STA_MODE] = { PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -721,8 +713,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -734,8 +725,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, PM_24G_SCC_CH_SBS_CH}, - [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -796,7 +786,8 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -809,7 +800,8 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24}, [PM_SAP_MODE] = { - PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + PM_SCC_ON_5_SCC_ON_24, PM_SCC_ON_5_SCC_ON_24, + PM_SCC_ON_5_SCC_ON_24}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -833,7 +825,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -845,7 +837,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -856,7 +848,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_P2P_CLI_MCC_24_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -867,7 +860,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_P2P_CLI_MCC_24_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -878,8 +872,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_P2P_CLI_SCC_5_1x1] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -890,8 +884,8 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_P2P_CLI_SCC_5_2x2] = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, - [PM_SAP_MODE] = {PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH, - PM_24G_SCC_CH_SBS_CH}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -903,7 +897,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -915,7 +909,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_24G_SBS_CH_MCC_CH, PM_24G, PM_24G_MCC_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -951,8 +945,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -964,8 +957,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -977,7 +969,7 @@ pm_third_connection_pcl_dbs_2x2_table = { [PM_STA_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { @@ -986,144 +978,158 @@ pm_third_connection_pcl_dbs_2x2_table = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = { - [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = { - [PM_STA_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_SAP_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, - [PM_P2P_GO_MODE] = {PM_5G_SCC_CH, PM_5G_SCC_CH, PM_5G_SCC_CH}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = { - [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = { - [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = { [PM_STA_MODE] = { - PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH_5G, - PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH_5G, - PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH_SBS_CH_5G, - PM_24G_SCC_CH_SBS_CH_5G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH_SBS_CH_5G, - PM_24G_SCC_CH_SBS_CH_5G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = { [PM_STA_MODE] = { - PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH_5G, - PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_24G_SCC_CH_SBS_CH, PM_24G_SCC_CH_SBS_CH_5G, - PM_SCC_CH_24G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH_SBS_CH_5G, - PM_24G_SCC_CH_SBS_CH_5G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_24G_SCC_CH_SBS_CH_5G, PM_24G_SCC_CH_SBS_CH_5G, - PM_24G_SCC_CH_SBS_CH_5G}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = { - [PM_STA_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, PM_24G_MCC_CH}, - [PM_SAP_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, PM_24G_MCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, - PM_24G_MCC_CH}, - [PM_P2P_GO_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, PM_24G_MCC_CH}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = { - [PM_STA_MODE] = {PM_MCC_CH_24G, PM_24G_MCC_CH, PM_24G_MCC_CH}, - [PM_SAP_MODE] = {PM_24G_MCC_CH, PM_24G_MCC_CH, PM_24G_MCC_CH}, - [PM_P2P_CLIENT_MODE] = {PM_MCC_CH_24G, PM_24G_MCC_CH, - PM_24G_MCC_CH}, - [PM_P2P_GO_MODE] = {PM_MCC_CH_24G, PM_24G_MCC_CH, PM_24G_MCC_CH}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = { - [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = { - [PM_STA_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_SAP_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_CLIENT_MODE] = {PM_5G, PM_5G, PM_5G}, - [PM_P2P_GO_MODE] = {PM_5G, PM_5G, PM_5G}, + [PM_STA_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_SAP_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_CLIENT_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, + [PM_P2P_GO_MODE] = { + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_DBS_1x1] = { [PM_STA_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_DBS_2x2] = { [PM_STA_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_SCC_ON_5_SCC_ON_24_5G, PM_SCC_ON_5_SCC_ON_24_5G, - PM_SCC_ON_5_SCC_ON_24}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, [PM_P2P_GO_P2P_CLI_SBS_5_1x1] = { [PM_STA_MODE] = { - PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_SAP_MODE] = { - PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_CLIENT_MODE] = { - PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_P2P_GO_MODE] = { - PM_SBS_CH_5G, PM_SBS_CH, PM_SBS_CH}, + PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE}, [PM_IBSS_MODE] = { PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE, PM_MAX_PCL_TYPE} }, From c4e7ce7142c0d3c3a2f7ed5f6f2c072aa6b5477e Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Fri, 15 Sep 2017 16:17:13 +0530 Subject: [PATCH 144/404] qcacmn: Correction in PCL index fetching routine In case of SBS or DBS, both the MACs are used for operations. We have issue in PCL index fatching routines for 3-port concurrent combinations when first two ports are configured in DBS mode. Change-Id: I36ca9979ef4222428e383d89b52ff1388c79ac22 CRs-Fixed: 2127091 --- src/wlan_policy_mgr_pcl.c | 208 ++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 112 deletions(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 01f2cc91c000..9a2092a0b8a6 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -747,26 +747,24 @@ static enum policy_mgr_two_connection_mode else index = PM_P2P_CLI_SAP_MCC_24_5_2x2; } - /* SBS */ + /* SBS or DBS */ } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_CLI_SAP_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_CLI_SAP_DBS_1x1; + else + index = PM_P2P_CLI_SAP_DBS_2x2; } - /* DBS */ - } else { - if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_P2P_CLI_SAP_DBS_1x1; - else - index = PM_P2P_CLI_SAP_DBS_2x2; } - return index; } @@ -819,26 +817,24 @@ static enum policy_mgr_two_connection_mode else index = PM_STA_SAP_MCC_24_5_2x2; } - /* SBS */ + /* SBS or DBS */ } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_SAP_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_SAP_DBS_1x1; + else + index = PM_STA_SAP_DBS_2x2; } - /* DBS */ - } else { - if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_STA_SAP_DBS_1x1; - else - index = PM_STA_SAP_DBS_2x2; } - return index; } @@ -891,26 +887,24 @@ static enum policy_mgr_two_connection_mode else index = PM_SAP_SAP_MCC_24_5_2x2; } - /* SBS */ + /* SBS or DBS */ } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_SAP_SAP_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_SAP_SAP_DBS_1x1; + else + index = PM_SAP_SAP_DBS_2x2; } - /* DBS */ - } else { - if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_SAP_SAP_DBS_1x1; - else - index = PM_SAP_SAP_DBS_2x2; } - return index; } @@ -963,26 +957,24 @@ static enum policy_mgr_two_connection_mode else index = PM_STA_P2P_GO_MCC_24_5_2x2; } - /* SBS */ + /* SBS or DBS */ } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_GO_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_GO_DBS_1x1; + else + index = PM_STA_P2P_GO_DBS_2x2; } - /* DBS */ - } else { - if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_STA_P2P_GO_DBS_1x1; - else - index = PM_STA_P2P_GO_DBS_2x2; } - return index; } @@ -1035,26 +1027,24 @@ static enum policy_mgr_two_connection_mode else index = PM_STA_P2P_CLI_MCC_24_5_2x2; } - /* SBS */ + /* SBS or DBS */ } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_P2P_CLI_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_P2P_CLI_DBS_1x1; + else + index = PM_STA_P2P_CLI_DBS_2x2; } - /* DBS */ - } else { - if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_STA_P2P_CLI_DBS_1x1; - else - index = PM_STA_P2P_CLI_DBS_2x2; } - return index; } @@ -1107,26 +1097,24 @@ static enum policy_mgr_two_connection_mode else index = PM_P2P_GO_P2P_CLI_MCC_24_5_2x2; } - /* SBS */ + /* SBS or DBS */ } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_P2P_CLI_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_P2P_CLI_DBS_1x1; + else + index = PM_P2P_GO_P2P_CLI_DBS_2x2; } - /* DBS */ - } else { - if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_P2P_CLI_DBS_1x1; - else - index = PM_P2P_GO_P2P_CLI_DBS_2x2; } - return index; } @@ -1179,26 +1167,24 @@ static enum policy_mgr_two_connection_mode else index = PM_P2P_GO_SAP_MCC_24_5_2x2; } - /* SBS */ + /* SBS or DBS */ } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_P2P_GO_SAP_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_P2P_GO_SAP_DBS_1x1; + else + index = PM_P2P_GO_SAP_DBS_2x2; } - /* DBS */ - } else { - if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_P2P_GO_SAP_DBS_1x1; - else - index = PM_P2P_GO_SAP_DBS_2x2; } - return index; } @@ -1251,26 +1237,24 @@ static enum policy_mgr_two_connection_mode else index = PM_STA_STA_MCC_24_5_2x2; } - /* SBS */ + /* SBS or DBS */ } else if (pm_conc_connection_list[0].mac != - pm_conc_connection_list[1].mac) { - if ((WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[0].chan)) && - (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[1].chan))) { + pm_conc_connection_list[1].mac) { + /* SBS */ + if ((WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[0].chan)) && + (WLAN_REG_IS_5GHZ_CH(pm_conc_connection_list[1].chan))) { if (POLICY_MGR_ONE_ONE == pm_conc_connection_list[0].chain_mask) index = PM_STA_STA_SBS_5_1x1; + } else { + /* DBS */ + if (POLICY_MGR_ONE_ONE == + pm_conc_connection_list[0].chain_mask) + index = PM_STA_STA_DBS_1x1; + else + index = PM_STA_STA_DBS_2x2; } - /* DBS */ - } else { - if (POLICY_MGR_ONE_ONE == - pm_conc_connection_list[0].chain_mask) - index = PM_STA_STA_DBS_1x1; - else - index = PM_STA_STA_DBS_2x2; } - return index; } From 758528a6e5b117ba498cad84bb6b4277a962d1d3 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Fri, 15 Sep 2017 16:36:33 +0530 Subject: [PATCH 145/404] qcacmn: New value for ini gWlanMccToSccSwitchMode Currently ini variable gWlanMccToSccSwitchMode has 4 values. Value 3 enforces SCC in anycase, if SCC is not possible then switchoff the AP. Added new value 5 for auto specific scenarios where, if SCC is not possible the allow MCC. Change-Id: I584958c6c61f7d1f5e077871e3891bba79f726a3 CRs-Fixed: 2127091 --- src/wlan_policy_mgr_get_set_utils.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index c156881c7028..5f75ab4e6dc0 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2672,6 +2672,8 @@ bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc) return ((pm_ctx->user_cfg.mcc_to_scc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) || - (pm_ctx->user_cfg.mcc_to_scc_switch_mode == - QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL)); + (pm_ctx->user_cfg.mcc_to_scc_switch_mode == + QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) || + (pm_ctx->user_cfg.mcc_to_scc_switch_mode == + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)); } From 1303fcd9b1550b74e4e4d53493b948fb30778709 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Fri, 15 Sep 2017 17:42:35 +0530 Subject: [PATCH 146/404] qcacmn: policy_mgr update for new connection Policy Manager updated when new connection request is under process. The update is resctricting below behavior: 1. Maximum 2 vdevs are only supported per mac. 2. Intraband MCC among beaconing entities shall not be supported. 3. Intraband MCC shall be allowed when STA is operating on DFS/Passive/LTE avoidance channel. 4. No DFC SCC shall be allowed both in 2-port and 3-port for Auto. Change-Id: If4e78791832207838c38ab7525f8081093cc73ed CRs-Fixed: 2127091 --- src/wlan_policy_mgr_core.c | 57 ++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 04535e2775db..353fa57130ae 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2184,26 +2184,45 @@ bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, { bool status = true; struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t mcc_to_scc_switch; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); return false; } + mcc_to_scc_switch = + policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - if ((num_connections == 2) && - (pm_conc_connection_list[0].chan != - pm_conc_connection_list[1].chan) && - (pm_conc_connection_list[0].mac == - pm_conc_connection_list[1].mac)) { - if (policy_mgr_is_hw_dbs_capable(psoc) == false) { - if ((channel != pm_conc_connection_list[0].chan) && - (channel != pm_conc_connection_list[1].chan)) { - policy_mgr_err("don't allow 3rd home channel on same MAC"); - status = false; - } - } else if (((WLAN_REG_IS_24GHZ_CH(channel)) && + if (num_connections == 2) { + /* No SCC or MCC combination is allowed with / on DFS channel */ + if ((mcc_to_scc_switch == + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) + && wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) && + (wlan_reg_is_dfs_ch(pm_ctx->pdev, + pm_conc_connection_list[0].chan) || + wlan_reg_is_dfs_ch(pm_ctx->pdev, + pm_conc_connection_list[1].chan))) { + + policy_mgr_err("Existing DFS connection, new 3-port DFS connection is not allowed"); + status = false; + + } else if (((pm_conc_connection_list[0].chan != + pm_conc_connection_list[1].chan) + || (mcc_to_scc_switch == + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) + ) && (pm_conc_connection_list[0].mac == + pm_conc_connection_list[1].mac)) { + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + if ((channel != + pm_conc_connection_list[0].chan) && + (channel != + pm_conc_connection_list[1].chan)) { + policy_mgr_err("don't allow 3rd home channel on same MAC"); + status = false; + } + } else if (((WLAN_REG_IS_24GHZ_CH(channel)) && (WLAN_REG_IS_24GHZ_CH (pm_conc_connection_list[0].chan)) && (WLAN_REG_IS_24GHZ_CH @@ -2213,9 +2232,19 @@ bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, (pm_conc_connection_list[0].chan)) && (WLAN_REG_IS_5GHZ_CH (pm_conc_connection_list[1].chan)))) { - policy_mgr_err("don't allow 3rd home channel on same MAC"); - status = false; + policy_mgr_err("don't allow 3rd home channel on same MAC"); + status = false; + } } + } else if ((num_connections == 1) + && (mcc_to_scc_switch == + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) + && wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) + && wlan_reg_is_dfs_ch(pm_ctx->pdev, + pm_conc_connection_list[0].chan)) { + + policy_mgr_err("Existing DFS connection, new 2-port DFS connection is not allowed"); + status = false; } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); From a07e4b97d47aa034543dbd2afde6e367f7f71a46 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Fri, 15 Sep 2017 19:38:49 +0530 Subject: [PATCH 147/404] qcacmn: Enforce MCC to SCC for 3-port combinations This update is for moving of AP/GO to enforce SCC for 3-port combinations AP+AP+STA and AP+GO+STA. Change-Id: I878b56cd8215f0d0f846af62fa2033b268e96317 CRs-Fixed: 2127091 --- src/wlan_policy_mgr_action.c | 82 ++++++++++++------------ src/wlan_policy_mgr_get_set_utils.c | 96 +++++++++++++++-------------- src/wlan_policy_mgr_i.h | 8 +-- 3 files changed, 94 insertions(+), 92 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index bc208a838c2a..2b53cc4697a2 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -597,12 +597,15 @@ static bool policy_mgr_is_restart_sap_allowed( struct wlan_objmgr_psoc *psoc, uint32_t mcc_to_scc_switch) { + uint32_t sta_ap_bit_mask = QDF_STA_MASK | QDF_SAP_MASK; + uint32_t sta_go_bit_mask = QDF_STA_MASK | QDF_P2P_GO_MASK; + if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) || !policy_mgr_concurrent_open_sessions_running(psoc) || - !((policy_mgr_get_concurrency_mode(psoc) == - (QDF_STA_MASK | QDF_SAP_MASK)) || - (policy_mgr_get_concurrency_mode(psoc) == - (QDF_STA_MASK | QDF_P2P_GO_MASK)))) { + !(((policy_mgr_get_concurrency_mode(psoc) & sta_ap_bit_mask) + == sta_ap_bit_mask) || + ((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask) + == sta_go_bit_mask))) { policy_mgr_err("MCC switch disabled or not concurrent STA/SAP, STA/GO"); return false; } @@ -653,10 +656,11 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) struct wlan_objmgr_psoc *psoc; struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; struct sta_ap_intf_check_work_ctx *work_info = NULL; - uint32_t mcc_to_scc_switch; + uint32_t mcc_to_scc_switch, cc_count = 0, i; QDF_STATUS status; uint8_t channel, sec_ch; - uint8_t operating_channel, vdev_id; + uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; work_info = (struct sta_ap_intf_check_work_ctx *) data; if (!work_info) { @@ -684,19 +688,18 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) goto end; - if (policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel, - &vdev_id, - PM_SAP_MODE)) { - policy_mgr_debug("SAP operating at channel:%d", - operating_channel); - } else if (policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel, - &vdev_id, - PM_P2P_GO_MODE)) { - policy_mgr_debug("GO operating at channel:%d", - operating_channel); - } else { + cc_count = policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel[cc_count], + &vdev_id[cc_count], + PM_SAP_MODE); + policy_mgr_debug("Number of concurrent SAP: %d", cc_count); + cc_count = cc_count + policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel[cc_count], + &vdev_id[cc_count], + PM_P2P_GO_MODE); + policy_mgr_debug("Number of beaconing entities (SAP + GO):%d", + cc_count); + if (!cc_count) { policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid"); goto end; } @@ -705,16 +708,18 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) policy_mgr_err("SAP restart get channel callback in NULL"); goto end; } - status = pm_ctx->hdd_cbacks. - wlan_hdd_get_channel_for_sap_restart(psoc, vdev_id, - &channel, &sec_ch); - if (status != QDF_STATUS_SUCCESS) { - policy_mgr_err("Failed to switch SAP channel"); - goto end; + for (i = 0; i < cc_count; i++) { + status = pm_ctx->hdd_cbacks. + wlan_hdd_get_channel_for_sap_restart(psoc, + vdev_id[i], &channel, &sec_ch); + if (status == QDF_STATUS_SUCCESS) { + policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d" + , operating_channel[i], channel); + break; + } } - - policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d", - operating_channel, channel); + if (status != QDF_STATUS_SUCCESS) + policy_mgr_err("Failed to switch SAP channel"); end: if (work_info) { qdf_mem_free(work_info); @@ -842,20 +847,12 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( return; } - if (policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel, - &vdev_id, - PM_SAP_MODE)) { - policy_mgr_debug("SAP operating at channel:%d", - operating_channel); - } else if (policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel, - &vdev_id, - PM_P2P_GO_MODE)) { - policy_mgr_debug("GO operating at channel:%d", - operating_channel); + if (policy_mgr_get_mode_specific_conn_info(psoc, &operating_channel, + &vdev_id, PM_STA_MODE)) { + policy_mgr_debug("STA operating Channel: %u", + operating_channel); } else { - policy_mgr_err("Could not get SAP/GO operating channel&vdevid"); + policy_mgr_err("Could not get STA operating channel&vdevid"); return; } @@ -871,8 +868,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( } if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && - policy_mgr_valid_sta_channel_check(psoc, - operating_channel) + policy_mgr_valid_sta_channel_check(psoc, operating_channel) && !pm_ctx->sta_ap_intf_check_work_info) { struct sta_ap_intf_check_work_ctx *work_info; work_info = qdf_mem_malloc( diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 5f75ab4e6dc0..5a6a48d238fa 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1404,24 +1404,23 @@ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, return status; } -bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, +uint32_t policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, uint8_t *channel, uint8_t *vdev_id, enum policy_mgr_con_mode mode) { - uint32_t count, index = 0; + uint32_t count = 0, index = 0; uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; - bool status = false; struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); - return false; + return count; } if (NULL == channel || NULL == vdev_id) { policy_mgr_err("Null pointer error"); - return false; + return count; } count = policy_mgr_mode_specific_connection_count( @@ -1429,28 +1428,23 @@ bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (count == 0) { policy_mgr_debug("No mode:[%d] connection", mode); - status = false; } else if (count == 1) { *channel = pm_conc_connection_list[list[index]].chan; *vdev_id = pm_conc_connection_list[list[index]].vdev_id; - status = true; } else { - /* - * Todo Currently the first SAP connection info is - * returned. Modify this to accommodate SAP+SAP+STA - * and SAP+SAP+P2P - */ - *channel = pm_conc_connection_list[list[index]].chan; - *vdev_id = + for (index = 0; index < count; index++) { + channel[index] = + pm_conc_connection_list[list[index]].chan; + + vdev_id[index] = pm_conc_connection_list[list[index]].vdev_id; - policy_mgr_debug("Multiple mode:[%d] connections, picking first one", - mode); - status = true; + } + policy_mgr_debug("Multiple mode:[%d] connections", mode); } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - return status; + return count; } bool policy_mgr_max_concurrent_connections_reached( @@ -2472,7 +2466,9 @@ bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev) QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, uint8_t channel, bool *ok) { - uint8_t operating_channel = 0, vdev_id = 0; + uint32_t cc_count = 0, i; + uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; struct wlan_objmgr_vdev *vdev; if (!channel || !ok) { @@ -2480,27 +2476,31 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_INVAL; } - if (policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel, - &vdev_id, - PM_SAP_MODE)) - policy_mgr_debug("SAP mode active"); - else if (policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel, - &vdev_id, - PM_P2P_GO_MODE)) - policy_mgr_debug("P2P_GO_MODE mode active"); - else { + cc_count = policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel[cc_count], + &vdev_id[cc_count], + PM_SAP_MODE); + policy_mgr_debug("Number of SAP modes: %d", cc_count); + cc_count = cc_count + policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel[cc_count], + &vdev_id[cc_count], + PM_P2P_GO_MODE); + policy_mgr_debug("Number of beaconing entities (SAP + GO):%d", + cc_count); + if (!cc_count) { *ok = true; return QDF_STATUS_SUCCESS; } - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + for (i = 0; i < cc_count; i++) { + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id[i], WLAN_POLICY_MGR_ID); - if (!vdev) { - policy_mgr_err("vdev is NULL"); - return QDF_STATUS_E_INVAL; - } + if (!vdev) { + policy_mgr_err("vdev for vdev_id:%d is NULL", + vdev_id[i]); + return QDF_STATUS_E_INVAL; + } /** * If channel passed is same as AP/GO operating channel, then @@ -2511,18 +2511,24 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, * return true. */ /* TODO: To be enhanced for SBS */ - if (policy_mgr_is_dnsc_set(vdev)) { - if (operating_channel == channel) + if (policy_mgr_is_dnsc_set(vdev)) { + if (operating_channel[i] == channel) { + *ok = true; + wlan_objmgr_vdev_release_ref(vdev, + WLAN_POLICY_MGR_ID); + break; + } else if (WLAN_REG_IS_SAME_BAND_CHANNELS( + operating_channel[i], channel)) { + *ok = false; + wlan_objmgr_vdev_release_ref(vdev, + WLAN_POLICY_MGR_ID); + break; + } + } else { *ok = true; - else if (WLAN_REG_IS_SAME_BAND_CHANNELS(operating_channel, - channel)) - *ok = false; - else - *ok = true; - } else { - *ok = true; + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); } - wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 5610f49f8c09..85cacb8c254e 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -410,15 +410,15 @@ QDF_STATUS policy_mgr_reset_sap_mandatory_channels( * policy_mgr_get_mode_specific_conn_info() - Get active mode specific * channel and vdev id * @psoc: PSOC object information - * @channel: Mode specific channel - * @vdev_id: Mode specific vdev id + * @channel: Mode specific channel (list) + * @vdev_id: Mode specific vdev id (list) * @mode: Connection Mode * * Get active mode specific channel and vdev id * - * Return: true for success, else false + * Return: number of connection found as per given mode */ -bool policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, +uint32_t policy_mgr_get_mode_specific_conn_info(struct wlan_objmgr_psoc *psoc, uint8_t *channel, uint8_t *vdev_id, enum policy_mgr_con_mode mode); From 51c7fdeb9ebc61f4a6b9d70f7adf418380009298 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 10 Oct 2017 01:36:39 -0700 Subject: [PATCH 148/404] 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 --- core/src/wlan_tdls_ct.c | 1 - core/src/wlan_tdls_ct.h | 12 ++++++++++++ core/src/wlan_tdls_main.c | 7 +++++++ dispatcher/inc/wlan_tdls_public_structs.h | 1 + dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 2b676114c892..801044283928 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1157,7 +1157,6 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, * * Return: QDF_STATUS */ -static QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc) { diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index 63e306378000..b713c971b4af 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -194,4 +194,16 @@ void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev); void tdls_disable_offchan_and_teardown_links( struct wlan_objmgr_vdev *vdev); +/** + * tdls_delete_all_tdls_peers(): send request to delete tdls peers + * @vdev: vdev object + * @tdls_soc: tdls soc object + * + * This function sends request to lim to delete tdls peers + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, + struct tdls_soc_priv_obj *tdls_soc); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index b66edc02cdbd..53de84207855 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -915,6 +915,12 @@ tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify) &tdls_soc_obj)) return QDF_STATUS_E_INVAL; + /* if the disconnect comes from user space, we have to delete all the + * tdls peers before sending the set state cmd. + */ + if (notify->user_disconnect) + return tdls_delete_all_tdls_peers(notify->vdev, tdls_soc_obj); + tdls_debug("Check and update TDLS state"); curr_tdls_vdev = tdls_vdev_obj; @@ -1026,6 +1032,7 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, notify->tdls_prohibited = false; notify->session_id = session_id; notify->vdev = vdev; + notify->user_disconnect = false; tdls_notify_sta_disconnect(notify); } diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 4691869ffacd..eaed5612c74a 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1012,6 +1012,7 @@ struct tdls_sta_notify_params { bool tdls_prohibited; bool tdls_chan_swit_prohibited; bool lfr_roam; + bool user_disconnect; uint8_t session_id; }; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index c5bf80475e8e..0d8f34c56aec 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -642,6 +642,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( notify->tdls_prohibited = false; notify->vdev = notify_info->vdev; notify->lfr_roam = notify_info->lfr_roam; + notify->user_disconnect = notify_info->user_disconnect; msg.bodyptr = notify; msg.callback = tdls_process_cmd; From 58d8a1fa36e9478e90488b7cdbb5ee7bcbb51403 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 10 Oct 2017 01:36:39 -0700 Subject: [PATCH 149/404] 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 fb82833f38e8cb74b4c498d6918b300d60380892 Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Wed, 5 Apr 2017 15:59:49 -0700 Subject: [PATCH 150/404] qcacmn: Disable LRO capability during concurrency LRO rx jumbo packets cannot be forwarded to other vdev and kernel drops them with warning message: "skbuff: wlan0: received packets cannot be forwarded while LRO is enabled" So disable LRO capability during concurrency. Change-Id: Ib35e1ee5f9c18a846e21ce1eb293e12e17761fa8 CRs-Fixed: 1092193 --- inc/wlan_policy_mgr_api.h | 23 +++++++++++++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 24 ++++++++++++++++++++++++ src/wlan_policy_mgr_i.h | 1 + src/wlan_policy_mgr_init_deinit.c | 17 +++++++++++++++++ 4 files changed, 65 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 3865a8674f4c..7f8fcfd34b80 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -812,6 +812,15 @@ struct policy_mgr_cdp_cbacks { uint8_t vdev_id, uint8_t mac_id); }; +/** + * struct policy_mgr_dp_cbacks - CDP Callbacks to be invoked + * from policy manager + * @hdd_disable_lro_in_concurrency: Callback to disable LRO + */ +struct policy_mgr_dp_cbacks { + void (*hdd_disable_lro_in_concurrency)(bool); +}; + /** * struct policy_mgr_wma_cbacks - WMA Callbacks to be invoked * from policy manager @@ -1476,6 +1485,20 @@ QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_register_cdp_cb(struct wlan_objmgr_psoc *psoc, struct policy_mgr_cdp_cbacks *cdp_cbacks); +/** + * policy_mgr_register_dp_cb() - register CDP callbacks + * @psoc: PSOC object information + * @cdp_cbacks: function pointers from CDP + * + * API, allows CDP to register callbacks to be invoked by + * policy mgr + * + * Return: SUCCESS, + * Failure (if registration fails) + */ +QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_dp_cbacks *dp_cbacks); + /** * policy_mgr_register_wma_cb() - register WMA callbacks * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 5a6a48d238fa..4d970b5b7703 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1154,6 +1154,20 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, if (pm_ctx->tdls_cbacks.tdls_notify_increment_session) pm_ctx->tdls_cbacks.tdls_notify_increment_session(psoc); + /* + * Disable LRO if P2P or IBSS or SAP connection has come up or + * there are more than one STA connections + */ + if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL) > 1) || + (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL) > 0) || + (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_CLIENT_MODE, NULL) > + 0) || + (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_GO_MODE, NULL) > 0) || + (policy_mgr_mode_specific_connection_count(psoc, PM_IBSS_MODE, NULL) > 0)) { + if (pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency != NULL) + pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency(true); + }; + policy_mgr_dump_current_concurrency(psoc); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); @@ -1203,6 +1217,16 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, /* Notify tdls */ if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session) pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc); + /* Enable LRO if there no concurrency */ + if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL) == 1) && + (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL) == 0) && + (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_CLIENT_MODE, NULL) == + 0) && + (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_GO_MODE, NULL) == 0) && + (policy_mgr_mode_specific_connection_count(psoc, PM_IBSS_MODE, NULL) == 0)) { + if (pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency != NULL) + pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency(false); + }; policy_mgr_dump_current_concurrency(psoc); diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 85cacb8c254e..0b058781d92b 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -251,6 +251,7 @@ struct policy_mgr_psoc_priv_obj { struct policy_mgr_wma_cbacks wma_cbacks; struct policy_mgr_tdls_cbacks tdls_cbacks; struct policy_mgr_cdp_cbacks cdp_cbacks; + struct policy_mgr_dp_cbacks dp_cbacks; bool enable_sap_mandatory_chan_list; uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN]; uint32_t sap_mandatory_channels_len; diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index c946988f8789..d556c3ed9aeb 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -619,6 +619,23 @@ QDF_STATUS policy_mgr_register_cdp_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc, + struct policy_mgr_dp_cbacks *dp_cbacks) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency = + dp_cbacks->hdd_disable_lro_in_concurrency; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc, struct policy_mgr_tdls_cbacks *tdls_cbacks) { From ab131773f7d44b7dcaa1d52f8a1bb265ffa61a26 Mon Sep 17 00:00:00 2001 From: Yun Park Date: Tue, 26 Sep 2017 16:39:17 -0700 Subject: [PATCH 151/404] qcacmn: Enable RPS dynamically for SAP mode SAP Rx TPUT is bounded by host network stack, which is running in the context of IPA work-queue, when IPA offload data path enabled. However RPS shouldn't enabled for legacy Rx data path, where NAPI is enabled. So, we dynamically enable RPS for SAP interface when the vdev comes up and IPA was enabled only. Send RPS enable indication to CNSS daemon to enable RPS only when SAP interface comes up and disable RPS when SAP interface is closed. Change-Id: Ia669b2c3ae814d0577f5226d8acbf026740ad760 CRs-Fixed: 2129520 --- inc/wlan_policy_mgr_api.h | 2 ++ src/wlan_policy_mgr_get_set_utils.c | 14 ++++++++++++++ src/wlan_policy_mgr_init_deinit.c | 2 ++ 3 files changed, 18 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 7f8fcfd34b80..580c94fff49c 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -816,9 +816,11 @@ struct policy_mgr_cdp_cbacks { * struct policy_mgr_dp_cbacks - CDP Callbacks to be invoked * from policy manager * @hdd_disable_lro_in_concurrency: Callback to disable LRO + * @hdd_set_rx_mode_rps_cb: Callback to set RPS */ struct policy_mgr_dp_cbacks { void (*hdd_disable_lro_in_concurrency)(bool); + void (*hdd_set_rx_mode_rps_cb)(bool); }; /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 4d970b5b7703..42195ab01b87 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1168,6 +1168,13 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency(true); }; + /* Enable RPS if SAP interface has come up */ + if (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL) + == 1) { + if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb != NULL) + pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(true); + } + policy_mgr_dump_current_concurrency(psoc); qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); @@ -1228,6 +1235,13 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency(false); }; + /* Disable RPS if SAP interface has come up */ + if (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL) + == 0) { + if (pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb != NULL) + pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb(false); + } + policy_mgr_dump_current_concurrency(psoc); return qdf_status; diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index d556c3ed9aeb..08513de35abd 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -632,6 +632,8 @@ QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc, pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency = dp_cbacks->hdd_disable_lro_in_concurrency; + pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb = + dp_cbacks->hdd_set_rx_mode_rps_cb; return QDF_STATUS_SUCCESS; } From 93225df9d163e4f88623ea88f8e3fe9dc632d6af Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 17 May 2017 14:03:37 +0800 Subject: [PATCH 152/404] qcacmn: Send TDLS frames with lower AC If ACM enabled and access is not granted for AC_VI, then send TDLS frames with lower access category instead of dropping them. Change-Id: I2201536dc4475764f33eebce1faa0a7df0b2c454 CRs-Fixed: 2119433 --- core/src/wlan_tdls_cmds_process.c | 24 ++++++++++------------- core/src/wlan_tdls_cmds_process.h | 10 +--------- core/src/wlan_tdls_main.h | 1 - core/src/wlan_tdls_mgmt.c | 6 +++++- core/src/wlan_tdls_mgmt.h | 1 + dispatcher/inc/wlan_tdls_public_structs.h | 1 + dispatcher/src/wlan_tdls_tgt_api.c | 1 + dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 8 files changed, 20 insertions(+), 25 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 3b9f1ad339a0..6f54b081b4bb 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -648,7 +648,7 @@ static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, return 0; } -int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate) +int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) { struct tdls_vdev_priv_obj *tdls_vdev; struct tdls_soc_priv_obj *tdls_soc; @@ -656,6 +656,8 @@ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate) struct tdls_peer *temp_peer; QDF_STATUS status; + struct tdls_validate_action_req *tdls_validate = + tdls_mgmt_req->chk_frame; if (!tdls_validate || !tdls_validate->vdev) return -EINVAL; @@ -711,21 +713,15 @@ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate) } } - /* - * Discard TDLS Discovery request and setup confirm if violates - * ACM rules - */ - if ((TDLS_DISCOVERY_REQUEST == tdls_validate->action_code || - TDLS_SETUP_CONFIRM == tdls_validate->action_code)) { - /* call hdd_wmm_is_acm_allowed() */ - if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) { - tdls_err("admission ctrl set to VI, action %d declined", - tdls_validate->action_code); - return -EPERM; - } + /* call hdd_wmm_is_acm_allowed() */ + if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) { + tdls_debug("admission ctrl set to VI, send the frame with least AC (BK) for action %d", + tdls_validate->action_code); + tdls_mgmt_req->use_default_ac = false; + } else { + tdls_mgmt_req->use_default_ac = true; } - if (TDLS_SETUP_REQUEST == tdls_validate->action_code || TDLS_SETUP_RESPONSE == tdls_validate->action_code) { if (tdls_soc->max_num_tdls_sta <= diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 5e2c03508475..561a40d78b34 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -286,14 +286,6 @@ void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac, enum tdls_peer_capab cap); -/** - * tdls_validate_mgmt_request() -validate mgmt request - * @tdls_validate: action frame request - * - * Return: 0 for success or -EINVAL otherwise - */ -int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); - /** * tdls_process_send_mgmt_rsp() - handle response for send mgmt * @rsp: TDLS send mgmt response @@ -355,7 +347,7 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, * * Return: 0 for success or -EINVAL otherwise */ -int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); +int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req); /** * tdls_set_responder() - Set/clear TDLS peer's responder role diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index bfdcb2cb123b..95178af8cc65 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -34,7 +34,6 @@ #include #include #include "wlan_serialization_api.h" -#include "wlan_tdls_mgmt.h" /* Bit mask flag for tdls_option to FW */ #define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index d0bbf3326984..c7582196e884 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -291,6 +291,10 @@ static QDF_STATUS tdls_activate_send_mgmt_request( tdls_mgmt_req->length = sizeof(struct tdls_send_mgmt_request) + action_req->tdls_mgmt.len; + if (action_req->use_default_ac) + tdls_mgmt_req->ac = WIFI_AC_VI; + else + tdls_mgmt_req->ac = WIFI_AC_BK; /* Send the request to PE. */ qdf_mem_zero(&msg, sizeof(msg)); @@ -370,7 +374,7 @@ QDF_STATUS tdls_process_mgmt_req( enum wlan_serialization_status ser_cmd_status; /* If connected and in Infra. Only then allow this */ - status = tdls_validate_mgmt_request(tdls_mgmt_req->chk_frame); + status = tdls_validate_mgmt_request(tdls_mgmt_req); if (status != QDF_STATUS_SUCCESS) { status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req, status); diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h index 3d3e6dd54a50..a6973f17d715 100644 --- a/core/src/wlan_tdls_mgmt.h +++ b/core/src/wlan_tdls_mgmt.h @@ -73,6 +73,7 @@ struct tdls_send_mgmt_request { uint32_t peer_capability; struct qdf_mac_addr bssid; struct qdf_mac_addr peer_mac; + enum wifi_traffic_ac ac; /* Variable length. Dont add any field after this. */ uint8_t add_ie[1]; }; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index eaed5612c74a..712a81dac8aa 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -985,6 +985,7 @@ struct tdls_action_frame_request { const uint8_t *cmd_buf; uint8_t len; struct tdls_send_mgmt tdls_mgmt; + bool use_default_ac; }; /** diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 4100c29ad67d..8b35247d8b94 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -26,6 +26,7 @@ #include #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" +#include "../../core/src/wlan_tdls_mgmt.h" static inline struct wlan_lmac_if_tdls_tx_ops * wlan_psoc_get_tdls_txops(struct wlan_objmgr_psoc *psoc) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 0d8f34c56aec..930ea1bf9365 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -27,6 +27,7 @@ #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" #include "../../core/src/wlan_tdls_ct.h" +#include "../../core/src/wlan_tdls_mgmt.h" #include #include #include "wlan_policy_mgr_api.h" From c5e4a344ba7cc708357d5150fc4a188b6a56f765 Mon Sep 17 00:00:00 2001 From: Rajeev Kumar Sirasanagandla Date: Fri, 1 Sep 2017 18:48:36 +0530 Subject: [PATCH 153/404] qcacmn: Fix invalid buffer access in p2p mgmt tx processing While transmitting p2p mgmt action tx frame, there is no check for minimum payload length which can result in buffer over-read. To avoid this, add check for header and payload length. Change-Id: I9e3b4ef0878d934f3425d91bb6ea4a37b1892a3d CRs-Fixed: 2103849 --- core/src/wlan_p2p_off_chan_tx.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index fb6b71ed35e6..f75742627d36 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -145,6 +145,11 @@ static const uint8_t *p2p_get_p2pie_from_probe_rsp( const uint8_t *tmp_p2p_ie; uint16_t ie_len; + if (tx_ctx->buf_len <= PROBE_RSP_IE_OFFSET) { + p2p_err("Invalid header len for probe response"); + return NULL; + } + ie = tx_ctx->buf + PROBE_RSP_IE_OFFSET; ie_len = tx_ctx->buf_len - PROBE_RSP_IE_OFFSET; p2p_ie = p2p_get_p2pie_ptr(ie, ie_len); @@ -605,6 +610,11 @@ static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length, p2p_init_frame_info(frame_info); + if (length < P2P_ACTION_OFFSET + 1) { + p2p_err("invalid p2p mgmt hdr len"); + return QDF_STATUS_E_INVAL; + } + type = P2P_GET_TYPE_FRM_FC(buf[0]); sub_type = P2P_GET_SUBTYPE_FRM_FC(buf[0]); if (type != P2P_FRAME_MGMT) { @@ -633,7 +643,8 @@ static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length, frame_info->sub_type = P2P_MGMT_ACTION; buf += P2P_ACTION_OFFSET; - if (buf[0] == P2P_PUBLIC_ACTION_FRAME && + if (length > P2P_PUBLIC_ACTION_FRAME_TYPE_OFFSET && + buf[0] == P2P_PUBLIC_ACTION_FRAME && buf[1] == P2P_PUBLIC_ACTION_VENDOR_SPECIFIC && !qdf_mem_cmp(&buf[2], P2P_OUI, P2P_OUI_SIZE)) { buf = data_buf + @@ -644,8 +655,9 @@ static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length, P2P_PUBLIC_ACTION_NOT_SUPPORT; else frame_info->public_action_type = action_type; - } else if (buf[0] == P2P_ACTION_VENDOR_SPECIFIC_CATEGORY && - !qdf_mem_cmp(&buf[1], P2P_OUI, P2P_OUI_SIZE)) { + } else if (length > P2P_ACTION_FRAME_TYPE_OFFSET && + buf[0] == P2P_ACTION_VENDOR_SPECIFIC_CATEGORY && + !qdf_mem_cmp(&buf[1], P2P_OUI, P2P_OUI_SIZE)) { buf = data_buf + P2P_ACTION_FRAME_TYPE_OFFSET; action_type = buf[0]; @@ -1397,7 +1409,7 @@ static QDF_STATUS p2p_execute_tx_action_frame( */ p2p_populate_mac_header(tx_ctx); - if ((noa_len > 0) + if ((noa_len > 0) && p2p_ie && (noa_len < (P2P_MAX_NOA_ATTR_LEN + P2P_IE_HEADER_LEN))) { /* Add 2 bytes for length and Arribute field */ From a598b91ee0f7824fdbf6325e208806408e199bcb Mon Sep 17 00:00:00 2001 From: Ganesh Kondabattini Date: Tue, 31 Oct 2017 22:40:18 +0530 Subject: [PATCH 154/404] qcacmn: Set weight of DFS/passive channels in pcl to 0 If force SCC is set and SAP is active then all DFS/disabled channels in PCL should have 0 weight to avoid the STA roaming to these channels. Change-Id: I4519c29477c5108f5131b7caa806505b69efea8b CRs-Fixed: 2135750 --- inc/wlan_policy_mgr_api.h | 15 +++++++++ src/wlan_policy_mgr_core.c | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 580c94fff49c..040f930ef5fd 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2130,4 +2130,19 @@ void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc, */ uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_set_weight_of_dfs_passive_channels_to_zero() - set weight of dfs + * and passive channels to 0 + * @psoc: pointer to soc + * @pcl_channels: preferred channel list + * @len: length of preferred channel list + * @weight_list: preferred channel weight list + * @weight_len: length of weight list + * This function set the weight of dfs and passive channels to 0 + * + * Return: None + */ +void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( + struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels, + uint32_t *len, uint8_t *weight_list, uint32_t weight_len); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 353fa57130ae..29f6069fad80 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1674,6 +1674,68 @@ QDF_STATUS policy_mgr_get_connection_channels(struct wlan_objmgr_psoc *psoc, return status; } +/** + * policy_mgr_set_weight_of_dfs_passive_channels_to_zero() - set weight of dfs + * and passive channels to 0 + * @psoc: pointer to soc + * @pcl_channels: preferred channel list + * @len: length of preferred channel list + * @weight_list: preferred channel weight list + * @weight_len: length of weight list + * This function set the weight of dfs and passive channels to 0 + * + * Return: None + */ +void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( + struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels, + uint32_t *len, uint8_t *weight_list, uint32_t weight_len) +{ + uint8_t i; + uint32_t orig_channel_count = 0; + bool mcc_to_scc_mode; + uint32_t sap_count; + enum channel_state channel_state; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + mcc_to_scc_mode = policy_mgr_is_force_scc(psoc); + sap_count = policy_mgr_mode_specific_connection_count(psoc, + PM_SAP_MODE, NULL); + policy_mgr_debug("mcc_to_scc_mode %u, sap_count %u", mcc_to_scc_mode, + sap_count); + + if (!mcc_to_scc_mode || !sap_count) + return; + + if (len) + orig_channel_count = QDF_MIN(*len, QDF_MAX_NUM_CHAN); + else { + policy_mgr_err("invalid number of channel length"); + return; + } + + policy_mgr_debug("Set weight of DFS/passive channels to 0"); + + for (i = 0; i < orig_channel_count; i++) { + channel_state = reg_get_channel_state(pm_ctx->pdev, + pcl_channels[i]); + if ((channel_state == CHANNEL_STATE_DISABLE) || + (channel_state == CHANNEL_STATE_INVALID)) + /* Set weight of inactive channels to 0 */ + weight_list[i] = 0; + + policy_mgr_debug("chan[%d] - %d, weight[%d] - %d", + i, pcl_channels[i], i, weight_list[i]); + } + + return; +} + /** * policy_mgr_get_channel_list() - provides the channel list * suggestion for new connection @@ -2119,6 +2181,8 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, len, pcl_weights, weight_len); + policy_mgr_set_weight_of_dfs_passive_channels_to_zero(psoc, + pcl_channels, len, pcl_weights, weight_len); return status; } From bdda5823be71cb654788b536666a09d4a1e79906 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 25 Oct 2017 16:33:06 -0700 Subject: [PATCH 155/404] qcacmn: Stop the opportunistic timer when hdd stop happens Stop the opportunistic timer & take action if needed when hdd stop happens. Also, take action when set_hw_mode request to FW times out. Change-Id: I32f1e38e93a5805e0d85b800cc4e070cd6f79669 CRs-Fixed: 2133388 --- inc/wlan_policy_mgr_api.h | 13 +++++++++++++ inc/wlan_policy_mgr_public_struct.h | 1 + src/wlan_policy_mgr_action.c | 17 +++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 040f930ef5fd..4dd3629ad843 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2129,6 +2129,19 @@ void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc, * Return: conc_system_pref */ uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_check_and_stop_opportunistic_timer - Get current + * state of opportunistic timer, if running, stop it and take + * action + * @psoc: soc pointer + * + * Get the current state of opportunistic timer, if it is + * running, stop it and take action. + * + * Return: None + */ +void policy_mgr_check_and_stop_opportunistic_timer( + struct wlan_objmgr_psoc *psoc); /** * policy_mgr_set_weight_of_dfs_passive_channels_to_zero() - set weight of dfs diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index b10adbaff31a..4d4f9ad53f86 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -896,6 +896,7 @@ struct policy_mgr_hw_mode { void *set_hw_mode_cb; enum policy_mgr_conn_update_reason reason; uint32_t session_id; + struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_psoc *context; }; diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 2b53cc4697a2..48ab89322b0f 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1092,6 +1092,23 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( pm_dbs_opportunistic_timer_handler((void *)psoc); } +void policy_mgr_check_and_stop_opportunistic_timer( + struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + if (QDF_TIMER_STATE_RUNNING == + pm_ctx->dbs_opportunistic_timer.state) { + qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); + pm_dbs_opportunistic_timer_handler((void *)psoc); + } +} + void policy_mgr_set_hw_mode_change_in_progress( struct wlan_objmgr_psoc *psoc, enum policy_mgr_hw_mode_change value) { From 295b10073945e296989dc405b153830c81fd3801 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 2 Nov 2017 11:53:50 +0800 Subject: [PATCH 156/404] qcacmn: Fix memory leak in P2P component Due to race condition, there is memory leak in P2P component. Free buffer in error scenarios. Change-Id: I5baf77ec0d0d2f3aea9da5fcca9105dc2c60c3d0 CRs-Fixed: 2136089 --- core/src/wlan_p2p_main.c | 7 +++++++ dispatcher/src/wlan_p2p_tgt_api.c | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 063af68ce1d9..3669a4fb2dd9 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -1067,7 +1067,13 @@ QDF_STATUS p2p_process_lo_stop( p2p_err("invalid lo stop event"); return QDF_STATUS_E_INVAL; } + lo_evt = lo_stop_event->lo_event; + if (!lo_evt) { + p2p_err("invalid lo event"); + return QDF_STATUS_E_INVAL; + } + p2p_soc_obj = lo_stop_event->p2p_soc_obj; p2p_debug("vdev_id %d, reason %d", @@ -1075,6 +1081,7 @@ QDF_STATUS p2p_process_lo_stop( if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) { p2p_err("Invalid p2p soc object or start parameters"); + qdf_mem_free(lo_evt); return QDF_STATUS_E_INVAL; } start_param = p2p_soc_obj->start_param; diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 39a5364fbb55..699bd4707160 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -134,6 +134,7 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, if (!context) { p2p_err("invalid context"); + qdf_nbuf_free(buf); return QDF_STATUS_E_INVAL; } tx_ctx = (struct tx_action_context *)context; @@ -142,12 +143,14 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event)); if (!tx_conf_event) { p2p_err("Failed to allocate tx cnf event"); + qdf_nbuf_free(buf); return QDF_STATUS_E_NOMEM; } tx_cnf = qdf_mem_malloc(sizeof(*tx_cnf)); if (!tx_cnf) { p2p_err("Failed to allocate tx cnf"); + qdf_nbuf_free(buf); return QDF_STATUS_E_NOMEM; } @@ -195,6 +198,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, WLAN_UMAC_COMP_P2P); if (!p2p_soc_obj) { p2p_err("p2p ctx is NULL, drop this frame"); + qdf_nbuf_free(buf); return QDF_STATUS_E_FAILURE; } @@ -202,6 +206,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); if (!roc_ctx) { p2p_err("current roc ctx is null, can't get vdev id"); + qdf_nbuf_free(buf); return QDF_STATUS_E_FAILURE; } else { vdev_id = roc_ctx->vdev_id; @@ -210,6 +215,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, vdev = wlan_peer_get_vdev(peer); if (!vdev) { p2p_err("vdev is NULL in peer, drop this frame"); + qdf_nbuf_free(buf); return QDF_STATUS_E_FAILURE; } vdev_id = wlan_vdev_get_id(vdev); @@ -218,6 +224,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event)); if (!rx_mgmt_event) { p2p_err("Failed to allocate rx mgmt event"); + qdf_nbuf_free(buf); return QDF_STATUS_E_NOMEM; } @@ -225,6 +232,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, mgmt_rx_params->buf_len); if (!rx_mgmt) { p2p_err("Failed to allocate rx mgmt frame"); + qdf_nbuf_free(buf); return QDF_STATUS_E_NOMEM; } From 17e4c635ca1a54702269019865dee5393dc4d026 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Wed, 1 Nov 2017 20:58:23 -0700 Subject: [PATCH 157/404] qcacmn: Fix the invalid memory access issue in TDLS Additional IE's in the TDLS management request is not populated correctly and it causes invalid memory access and system crash. Populate the additional TDLS IE's in correct order. Change-Id: I1c65f04c3b0e134dc4854e3f16022c887e8ce7c0 CRs-Fixed: 2136739 --- dispatcher/inc/wlan_tdls_public_structs.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 712a81dac8aa..936623c0eb29 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -930,9 +930,8 @@ struct tdls_event_notify { * @dialog: dialog token used in the frame. * @status_code: status to be incuded in the frame * @responder: Tdls request type - * @len: lenght of additional Ies * @peer_capability: peer cpabilities - * @len: lenght of additional Ies + * @len: length of additional Ies * @buf: additional IEs to be included */ struct tdls_send_mgmt { @@ -944,7 +943,7 @@ struct tdls_send_mgmt { uint32_t peer_capability; uint8_t len; /* Variable length, do not add anything after this */ - uint8_t *buf; + uint8_t buf[]; }; /** @@ -975,6 +974,9 @@ struct tdls_validate_action_req { * @chk_frame: frame validation structure * @session_id: session id * @vdev_id: vdev id + * @cmd_buf: cmd buffer + * @len: length of the frame + * @use_default_ac: access category * @tdls_mgmt: tdls managment */ struct tdls_action_frame_request { @@ -984,8 +986,9 @@ struct tdls_action_frame_request { uint8_t vdev_id; const uint8_t *cmd_buf; uint8_t len; - struct tdls_send_mgmt tdls_mgmt; bool use_default_ac; + /* Variable length, do not add anything after this */ + struct tdls_send_mgmt tdls_mgmt; }; /** From 198678568916f21b1aeee9ce93adcf9e2d9d7b9b Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Thu, 9 Nov 2017 09:54:12 -0800 Subject: [PATCH 158/404] qcacmn: Use enum QDF_OPMODE Change "qcacmn: Rename enum tQDF_ADAPTER_MODE" (qca-wifi-host-cmn Change-Id I20f1b6d1a0ab4b8fe6a85cefdff96a49e2f4652c) renamed enum tQDF_ADAPTER_MODE to QDF_OPMODE. Update all references to use the new name. Change-Id: Ic6f663dac11a100f168b2626c7c0fbcaccbfca4f CRs-Fixed: 2141061 --- core/src/wlan_tdls_main.c | 4 ++-- core/src/wlan_tdls_peer.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 53de84207855..000bc78ee102 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -420,7 +420,7 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, struct tdls_vdev_priv_obj **tdls_vdev_obj, struct tdls_soc_priv_obj **tdls_soc_obj) { - enum tQDF_ADAPTER_MODE device_mode; + enum QDF_OPMODE device_mode; if (NULL == vdev) return QDF_STATUS_E_FAILURE; @@ -1275,7 +1275,7 @@ void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, struct scan_event *event, void *arg) { - enum tQDF_ADAPTER_MODE device_mode; + enum QDF_OPMODE device_mode; struct tdls_soc_priv_obj *tdls_soc; if (!vdev || !event || !arg) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 26837ffdd818..769ba533423e 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -384,7 +384,7 @@ static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, uint32_t *channel, uint32_t *opclass) { uint32_t vdev_id; - enum tQDF_ADAPTER_MODE opmode; + enum QDF_OPMODE opmode; /* * If tdls offchannel is not enabled then we provide base channel * and in that case pass opclass as 0 since opclass is mainly needed From 8713e345e679d447a7c52f81638c726b438bd7d2 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Thu, 9 Nov 2017 09:54:12 -0800 Subject: [PATCH 159/404] qcacmn: Use enum QDF_OPMODE Change "qcacmn: Rename enum tQDF_ADAPTER_MODE" (qca-wifi-host-cmn Change-Id I20f1b6d1a0ab4b8fe6a85cefdff96a49e2f4652c) renamed enum tQDF_ADAPTER_MODE to QDF_OPMODE. Update all references to use the new name. Change-Id: Ic6f663dac11a100f168b2626c7c0fbcaccbfca4f CRs-Fixed: 2141061 --- core/src/wlan_p2p_main.c | 22 +++++++++++----------- core/src/wlan_p2p_off_chan_tx.c | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 3669a4fb2dd9..32c9fb0b5b76 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -191,7 +191,7 @@ static QDF_STATUS p2p_vdev_obj_create_notification( { struct p2p_vdev_priv_obj *p2p_vdev_obj; QDF_STATUS status; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; if (!vdev) { p2p_err("vdev context passed is NULL"); @@ -246,7 +246,7 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( { struct p2p_vdev_priv_obj *p2p_vdev_obj; QDF_STATUS status; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; if (!vdev) { p2p_err("vdev context passed is NULL"); @@ -302,7 +302,7 @@ static QDF_STATUS p2p_peer_obj_create_notification( { struct wlan_objmgr_vdev *vdev; struct p2p_vdev_priv_obj *p2p_vdev_obj; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; enum wlan_peer_type peer_type; if (!peer) { @@ -344,7 +344,7 @@ static QDF_STATUS p2p_peer_obj_destroy_notification( struct wlan_objmgr_vdev *vdev; struct p2p_vdev_priv_obj *p2p_vdev_obj; struct wlan_objmgr_psoc *psoc; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; enum wlan_peer_type peer_type; uint8_t vdev_id; @@ -471,7 +471,7 @@ static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_peer *peer) { struct p2p_vdev_priv_obj *p2p_vdev_obj = NULL; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; enum wlan_peer_type peer_type; bool disable_noa; uint8_t vdev_id; @@ -1104,7 +1104,7 @@ QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event) struct p2p_soc_priv_obj *p2p_soc_obj; struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_psoc *psoc; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; if (!noa_event) { p2p_err("invalid noa event"); @@ -1217,7 +1217,7 @@ get_p2p_soc_obj_by_vdev(struct wlan_objmgr_vdev *vdev) QDF_STATUS p2p_status_scan(struct wlan_objmgr_vdev *vdev) { struct p2p_soc_priv_obj *p2p_soc_obj; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); if (!p2p_soc_obj) { @@ -1258,7 +1258,7 @@ QDF_STATUS p2p_status_scan(struct wlan_objmgr_vdev *vdev) QDF_STATUS p2p_status_connect(struct wlan_objmgr_vdev *vdev) { struct p2p_soc_priv_obj *p2p_soc_obj; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); if (!p2p_soc_obj) { @@ -1300,7 +1300,7 @@ QDF_STATUS p2p_status_connect(struct wlan_objmgr_vdev *vdev) QDF_STATUS p2p_status_disconnect(struct wlan_objmgr_vdev *vdev) { struct p2p_soc_priv_obj *p2p_soc_obj; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); if (!p2p_soc_obj) { @@ -1335,7 +1335,7 @@ QDF_STATUS p2p_status_disconnect(struct wlan_objmgr_vdev *vdev) QDF_STATUS p2p_status_start_bss(struct wlan_objmgr_vdev *vdev) { struct p2p_soc_priv_obj *p2p_soc_obj; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); if (!p2p_soc_obj) { @@ -1371,7 +1371,7 @@ QDF_STATUS p2p_status_start_bss(struct wlan_objmgr_vdev *vdev) QDF_STATUS p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev) { struct p2p_soc_priv_obj *p2p_soc_obj; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; p2p_soc_obj = get_p2p_soc_obj_by_vdev(vdev); if (!p2p_soc_obj) { diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index f75742627d36..f97937275aa8 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -80,7 +80,7 @@ static QDF_STATUS p2p_tx_context_check_valid(struct tx_action_context *tx_ctx) */ static QDF_STATUS p2p_vdev_check_valid(struct tx_action_context *tx_ctx) { - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_psoc *psoc; struct p2p_soc_priv_obj *p2p_soc_obj; @@ -263,7 +263,7 @@ static struct p2p_noa_info *p2p_get_vdev_noa_info( struct p2p_soc_priv_obj *p2p_soc_obj; struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_psoc *psoc; - enum tQDF_ADAPTER_MODE mode; + enum QDF_OPMODE mode; struct p2p_noa_info *noa_info = NULL; p2p_soc_obj = tx_ctx->p2p_soc_obj; From 275208bd392b2d2ee90c4d7ae78c334969b2c214 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Thu, 9 Nov 2017 09:54:12 -0800 Subject: [PATCH 160/404] qcacmn: Use enum QDF_OPMODE Change "qcacmn: Rename enum tQDF_ADAPTER_MODE" (qca-wifi-host-cmn Change-Id I20f1b6d1a0ab4b8fe6a85cefdff96a49e2f4652c) renamed enum tQDF_ADAPTER_MODE to QDF_OPMODE. Update all references to use the new name. Change-Id: Ic6f663dac11a100f168b2626c7c0fbcaccbfca4f CRs-Fixed: 2141061 --- inc/wlan_policy_mgr_api.h | 24 ++++++++++++------------ src/wlan_policy_mgr_core.c | 4 ++-- src/wlan_policy_mgr_get_set_utils.c | 18 +++++++++--------- src/wlan_policy_mgr_i.h | 2 +- src/wlan_policy_mgr_pcl.c | 2 +- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 4dd3629ad843..301cd0c7c1c4 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -68,7 +68,7 @@ typedef const enum policy_mgr_conc_next_action * Return: NONE */ void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode); + enum QDF_OPMODE mode); /** * policy_mgr_clear_concurrency_mode() - To clear concurrency mode @@ -80,7 +80,7 @@ void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc, * Return: NONE */ void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode); + enum QDF_OPMODE mode); /** * policy_mgr_get_connection_count() - provides the count of @@ -192,7 +192,7 @@ bool policy_mgr_is_mcc_in_24G(struct wlan_objmgr_psoc *psoc); */ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, enum tQDF_ADAPTER_MODE dev_mode); + uint8_t vdev_id, enum QDF_OPMODE dev_mode); #if defined(FEATURE_WLAN_MCC_TO_SCC_SWITCH) /** @@ -233,7 +233,7 @@ static inline void policy_mgr_change_sap_channel_with_csa( * Return: None */ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode, uint8_t sessionId); + enum QDF_OPMODE mode, uint8_t session_id); /** * policy_mgr_decr_active_session() - decrements the number of active sessions @@ -248,7 +248,7 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, * Return: QDF_STATUS */ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode, uint8_t sessionId); + enum QDF_OPMODE mode, uint8_t session_id); /** * policy_mgr_decr_session_set_pcl() - Decrement session count and set PCL @@ -262,7 +262,7 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, * Return: None */ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode, uint8_t session_id); + enum QDF_OPMODE mode, uint8_t session_id); /** * policy_mgr_get_channel() - provide channel number of given mode and vdevid @@ -666,7 +666,7 @@ static inline QDF_STATUS policy_mgr_decr_connection_count_utfw( * Return: policy_mgr_con_mode enum */ enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( - enum tQDF_ADAPTER_MODE device_mode); + enum QDF_OPMODE device_mode); /** * policy_mgr_pdev_set_hw_mode() - Set HW mode command to FW @@ -748,9 +748,9 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, */ struct policy_mgr_sme_cbacks { QDF_STATUS (*sme_get_valid_channels)(uint8_t *chan_list, - uint32_t *list_len); - void (*sme_get_nss_for_vdev)(enum tQDF_ADAPTER_MODE, - uint8_t *nss_2g, uint8_t *nss_5g); + uint32_t *list_len); + void (*sme_get_nss_for_vdev)(enum QDF_OPMODE, + uint8_t *nss_2g, uint8_t *nss_5g); QDF_STATUS (*sme_soc_set_dual_mac_config)( struct policy_mgr_dual_mac_config msg); QDF_STATUS (*sme_pdev_set_hw_mode)(struct policy_mgr_hw_mode msg); @@ -923,8 +923,8 @@ void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, * * Return: true or false */ -bool policy_mgr_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, - enum policy_mgr_con_mode *new_mode); +bool policy_mgr_map_concurrency_mode(enum QDF_OPMODE *old_mode, + enum policy_mgr_con_mode *new_mode); /** * policy_mgr_get_channel_from_scan_result() - to get channel from scan result diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 29f6069fad80..037ad11aa81b 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1138,7 +1138,7 @@ void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc) * Return: None */ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode) + enum QDF_OPMODE mode) { QDF_STATUS status; enum policy_mgr_con_mode con_mode; @@ -1205,7 +1205,7 @@ void policy_mgr_set_pcl_for_existing_combo( { struct policy_mgr_conc_connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} }; - enum tQDF_ADAPTER_MODE pcl_mode; + enum QDF_OPMODE pcl_mode; uint8_t num_cxn_del = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 42195ab01b87..3d11ab25cf00 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1030,7 +1030,7 @@ bool policy_mgr_current_concurrency_is_mcc(struct wlan_objmgr_psoc *psoc) * Return: NONE */ void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode) + enum QDF_OPMODE mode) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1069,7 +1069,7 @@ void policy_mgr_set_concurrency_mode(struct wlan_objmgr_psoc *psoc, * Return: NONE */ void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode) + enum QDF_OPMODE mode) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1099,7 +1099,7 @@ void policy_mgr_clear_concurrency_mode(struct wlan_objmgr_psoc *psoc, } void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode, + enum QDF_OPMODE mode, uint8_t session_id) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1181,7 +1181,7 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, } QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode, + enum QDF_OPMODE mode, uint8_t session_id) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1375,8 +1375,8 @@ QDF_STATUS policy_mgr_decr_connection_count(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -bool policy_mgr_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, - enum policy_mgr_con_mode *new_mode) +bool policy_mgr_map_concurrency_mode(enum QDF_OPMODE *old_mode, + enum policy_mgr_con_mode *new_mode) { bool status = true; @@ -1985,7 +1985,7 @@ bool policy_mgr_is_mcc_adaptive_scheduler_enabled( */ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( struct wlan_objmgr_psoc *psoc, - uint8_t vdev_id, enum tQDF_ADAPTER_MODE dev_mode) + uint8_t vdev_id, enum QDF_OPMODE dev_mode) { QDF_STATUS status; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -2026,7 +2026,7 @@ struct policy_mgr_conc_connection_info *policy_mgr_get_conn_info(uint32_t *len) } enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( - enum tQDF_ADAPTER_MODE device_mode) + enum QDF_OPMODE device_mode) { enum policy_mgr_con_mode mode = PM_MAX_NUM_OF_MODE; switch (device_mode) { @@ -2200,7 +2200,7 @@ QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t *nss_2g, uint8_t *nss_5g) { - enum tQDF_ADAPTER_MODE dev_mode; + enum QDF_OPMODE dev_mode; struct policy_mgr_psoc_priv_obj *pm_ctx; switch (mode) { diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 0b058781d92b..17c83b42101d 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -372,7 +372,7 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, void *context); void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc); void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode); + enum QDF_OPMODE mode); void policy_mgr_set_pcl_for_existing_combo( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); void pm_dbs_opportunistic_timer_handler(void *data); diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 9a2092a0b8a6..3728d2a3adcb 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -105,7 +105,7 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, } void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, - enum tQDF_ADAPTER_MODE mode, + enum QDF_OPMODE mode, uint8_t session_id) { QDF_STATUS qdf_status; From ce66489b627ccad46fe74eb3d2c197d105a3f91a Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Thu, 2 Nov 2017 17:24:10 -0700 Subject: [PATCH 161/404] qcacmn: tdls: Replace instances of unadorned %p Replace instances of unadorned %p in tdls. Change-Id: Ife7db6d669d04c7e2d8e1a6fec5b442e180a34bb CRs-Fixed: 2133327 --- core/src/wlan_tdls_cmds_process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 6f54b081b4bb..6780f0a2c237 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1148,7 +1148,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); if (!vdev_obj || !soc_obj) { - tdls_err("tdls vdev_obj: %p soc_obj: %p", vdev_obj, soc_obj); + tdls_err("tdls vdev_obj: %pK soc_obj: %pK", vdev_obj, soc_obj); status = QDF_STATUS_E_NULL_VALUE; goto error; } From 6097caa167f1f0e2db7a9f05902cacc8e4eadb5f Mon Sep 17 00:00:00 2001 From: Om Prakash Tripathi Date: Fri, 3 Nov 2017 16:11:11 +0530 Subject: [PATCH 162/404] qcacmn: Add support for wide band scan Add support for 40 MHz or wider channel bandwidth scan Change-Id: I72f3cf42e6dc957ef56842d0c333c62169cb6d68 CRs-Fixed: 2139415 --- core/src/wlan_p2p_roc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 1fa37ee66885..ae71a7765124 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -102,8 +102,8 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) req->vdev = vdev; req->scan_req.scan_id = roc_ctx->scan_id; req->scan_req.scan_req_id = p2p_soc_obj->scan_req_id; - req->scan_req.num_chan = 1; - req->scan_req.chan_list[0] = wlan_chan_to_freq(roc_ctx->chan); + req->scan_req.chan_list.num_chan = 1; + req->scan_req.chan_list.chan[0].freq = wlan_chan_to_freq(roc_ctx->chan); req->scan_req.dwell_time_passive = roc_ctx->duration; req->scan_req.dwell_time_active = 0; req->scan_req.scan_priority = SCAN_PRIORITY_HIGH; From c993cb8078fc1431690bb72f22c62355c8665a89 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Wed, 8 Nov 2017 16:42:12 -0800 Subject: [PATCH 163/404] qcacmn: Fix memory leak issue in tdls peer delete operation In TDLS peer delete function memory is not freed in error handling path and it causes leak for every error operation. Free the memory in error handling path. Change-Id: Idb4725ec7a4c1b9614ecad1f685ffdeb8f795e72 CRs-Fixed: 2139570 --- core/src/wlan_tdls_ct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 801044283928..a7636e34b502 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1176,6 +1176,7 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, peer = wlan_vdev_get_bsspeer(vdev); if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID)) { + qdf_mem_free(del_msg); return QDF_STATUS_E_FAILURE; } From 28c82c3f428a1c653755faa35d904a89637d9532 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 14 Nov 2017 17:19:29 -0800 Subject: [PATCH 164/404] 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 4058ac5456e2d23cd5de38def88a18cd37a68afd Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 14 Nov 2017 17:19:29 -0800 Subject: [PATCH 165/404] qcacmn: Add TDLS user command getTDLSPeers Add TDLS user command getTDLSPeers for TDLS functional verification Change-Id: Ia02461a364ca604672d728f7dad7c3537e78f067 CRs-Fixed: 2146626 --- core/src/wlan_tdls_main.c | 94 +++++++++++++++++++++++ core/src/wlan_tdls_main.h | 10 +++ dispatcher/inc/wlan_tdls_public_structs.h | 20 +++++ dispatcher/inc/wlan_tdls_ucfg_api.h | 11 +++ dispatcher/src/wlan_tdls_ucfg_api.c | 29 +++++++ 5 files changed, 164 insertions(+) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 000bc78ee102..a423dcd08a05 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -293,6 +293,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_NOTIFY_RESET_ADAPTERS: tdls_notify_reset_adapter(msg->bodyptr); break; + case TDLS_CMD_GET_ALL_PEERS: + tdls_get_all_peers_from_list(msg->bodyptr); + break; default: break; } @@ -1001,6 +1004,97 @@ static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev) tdls_timers_stop(tdls_vdev); } +static int __tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers) +{ + int i; + int len, init_len; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *curr_peer; + char *buf; + int buf_len; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status; + + tdls_notice("Enter "); + + buf = get_tdls_peers->buf; + buf_len = get_tdls_peers->buf_len; + + if (!tdls_is_vdev_connected(get_tdls_peers->vdev)) { + len = qdf_scnprintf(buf, buf_len, + "\nSTA is not associated\n"); + return len; + } + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev); + + if (!tdls_vdev) { + len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n"); + return len; + } + + init_len = buf_len; + len = qdf_scnprintf(buf, buf_len, + "\n%-18s%-3s%-4s%-3s%-5s\n", + "MAC", "Id", "cap", "up", "RSSI"); + buf += len; + buf_len -= len; + len = qdf_scnprintf(buf, buf_len, + "---------------------------------\n"); + buf += len; + buf_len -= len; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_peer = qdf_container_of(p_node, + struct tdls_peer, node); + if (buf_len < 32 + 1) + break; + len = qdf_scnprintf(buf, buf_len, + QDF_MAC_ADDRESS_STR "%3d%4s%3s%5d\n", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->sta_id, + (curr_peer->tdls_support == + TDLS_CAP_SUPPORTED) ? "Y" : "N", + TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" : + "N", curr_peer->rssi); + buf += len; + buf_len -= len; + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + + tdls_notice("Exit "); + return init_len - buf_len; +} + +void tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers) +{ + int32_t len; + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_osif_indication indication; + + if (!get_tdls_peers->vdev) + qdf_mem_free(get_tdls_peers); + + len = __tdls_get_all_peers_from_list(get_tdls_peers); + + indication.status = len; + indication.vdev = get_tdls_peers->vdev; + + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev); + if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) + tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, + TDLS_EVENT_USER_CMD, &indication); + + qdf_mem_free(get_tdls_peers); +} + void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) { if (!vdev) { diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 95178af8cc65..0dee99c63fa8 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -574,6 +574,16 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); + +/** + * tdls_get_all_peers_from_list() - get all the tdls peers from the list + * @get_tdls_peers: get_tdls_peers object + * + * Return: None + */ +void tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers); + /** * tdls_notify_reset_adapter() - notify reset adapter * @vdev: vdev object manager diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 936623c0eb29..ae0a4077b247 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -62,6 +62,9 @@ /** Maximum time(ms) to wait for tdls mgmt to complete **/ #define WAIT_TIME_FOR_TDLS_MGMT 11000 +/** Maximum time(ms) to wait for tdls mgmt to complete **/ +#define WAIT_TIME_FOR_TDLS_USER_CMD 11000 + /** Maximum waittime for TDLS teardown links **/ #define WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS 10000 @@ -181,6 +184,7 @@ enum tdls_feature_mode { * @TDLS_CMD_SESSION_DECREMENT: notify session decrement * @TDLS_CMD_TEARDOWN_LINKS: notify teardown * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset + * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -201,6 +205,7 @@ enum tdls_command_type { TDLS_CMD_SESSION_DECREMENT, TDLS_CMD_TEARDOWN_LINKS, TDLS_NOTIFY_RESET_ADAPTERS, + TDLS_CMD_GET_ALL_PEERS, }; /** @@ -213,6 +218,8 @@ enum tdls_command_type { * @TDLS_EVENT_DISCOVERY_REQ: dicovery request * @TDLS_EVENT_TEARDOWN_REQ: teardown request * @TDLS_EVENT_SETUP_REQ: setup request + * @TDLS_EVENT_TEARDOWN_LINKS_DONE: teardown completion event + * @TDLS_EVENT_USER_CMD: tdls user command */ enum tdls_event_type { TDLS_EVENT_VDEV_STATE_CHANGE = 0, @@ -224,6 +231,7 @@ enum tdls_event_type { TDLS_EVENT_TEARDOWN_REQ, TDLS_EVENT_SETUP_REQ, TDLS_EVENT_TEARDOWN_LINKS_DONE, + TDLS_EVENT_USER_CMD, }; /** @@ -968,6 +976,18 @@ struct tdls_validate_action_req { int max_sta_failed; }; +/** + * struct tdls_get_all_peers - get all peers from the list + * @vdev: vdev object + * @buf: output string buffer to hold the peer info + * @buf_len: the size of output string buffer + */ +struct tdls_get_all_peers { + struct wlan_objmgr_vdev *vdev; + char *buf; + int buf_len; +}; + /** * struct tdls_send_action_frame_request - tdls send mgmt request * @vdev: vdev object diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 0a06658fe8b7..f23bf52aebee 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -119,6 +119,17 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, const uint8_t *macaddr, enum tdls_command_type cmd); +/** + * ucfg_tdls_get_all_peers() - get all tdls peers from the list + * @vdev: vdev object + * @buf: output buffer + * @buflen: length of written data + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, + char *buf, int buflen); + /** * ucfg_tdls_send_mgmt_frame() - send TDLS mgmt frame * @mgmt_req: pointer to TDLS action frame request struct diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 930ea1bf9365..36c6318156f5 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -485,6 +485,35 @@ error: return status; } +QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, + char *buf, int buflen) +{ + struct scheduler_msg msg = {0, }; + struct tdls_get_all_peers *tdls_peers; + QDF_STATUS status; + + tdls_peers = qdf_mem_malloc(sizeof(*tdls_peers)); + + if (!tdls_peers) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + tdls_peers->vdev = vdev; + tdls_peers->buf_len = buflen; + tdls_peers->buf = buf; + + msg.bodyptr = tdls_peers; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_GET_ALL_PEERS; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + if (status != QDF_STATUS_SUCCESS) + qdf_mem_free(tdls_peers); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *req) { From 9420656c9be77c89b16200b828ecfd30d64f5444 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 15 Nov 2017 15:30:07 -0800 Subject: [PATCH 166/404] qcacmn: Make the set HW mode & NSS update actions independent of each other Typically set hw mode & Nss update happens at the same time. Since the order of these 2 actions may not be same always, make them independent of each other. Change-Id: I652ad08e16680991535e0f064c7b5996f4f58792 CRs-Fixed: 2144977 --- inc/wlan_policy_mgr_api.h | 31 +++++++++- inc/wlan_policy_mgr_public_struct.h | 7 ++- src/wlan_policy_mgr_action.c | 40 +++++++----- src/wlan_policy_mgr_core.c | 94 +++++++++++++++-------------- src/wlan_policy_mgr_i.h | 8 ++- 5 files changed, 117 insertions(+), 63 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 301cd0c7c1c4..7e514d265f3b 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -680,6 +680,8 @@ enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( * @dfs: HW Agile DFS capability * @sbs: HW SBS capability * @reason: Reason for connection update + * @next_action: next action to happen at policy mgr after + * HW mode change * * Sends the set hw mode request to FW * @@ -710,7 +712,34 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, enum hw_mode_dbs_capab dbs, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs, - enum policy_mgr_conn_update_reason reason); + enum policy_mgr_conn_update_reason reason, + uint8_t next_action); + +/** + * policy_mgr_pdev_set_hw_mode_cback() - callback invoked by + * other component to provide set HW mode request status + * @status: status of the request + * @cfgd_hw_mode_index: new HW mode index + * @num_vdev_mac_entries: Number of mac entries + * @vdev_mac_map: The table of vdev to mac mapping + * @next_action: next action to happen at policy mgr after + * beacon update + * @reason: Reason for set HW mode + * @session_id: vdev id on which the request was made + * @context: PSOC object information + * + * This function is the callback registered with SME at set HW + * mode request time + * + * Return: None + */ +typedef void (*policy_mgr_pdev_set_hw_mode_cback)(uint32_t status, + uint32_t cfgd_hw_mode_index, + uint32_t num_vdev_mac_entries, + struct policy_mgr_vdev_mac_map *vdev_mac_map, + uint8_t next_action, + enum policy_mgr_conn_update_reason reason, + uint32_t session_id, void *context); /** * policy_mgr_nss_update_cback() - callback invoked by other diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 4d4f9ad53f86..18d16254efa4 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -668,6 +668,8 @@ enum policy_mgr_two_connection_mode { * @PM_SINGLE_MAC_UPGRADE: switch to MCC/SCC mode & upgrade to 2x2 * @PM_SBS: switch to SBS mode * @PM_SBS_DOWNGRADE: switch to SBS mode & downgrade to 1x1 + * @PM_DOWNGRADE: downgrade to 1x1 + * @PM_UPGRADE: upgrade to 2x2 * @PM_MAX_CONC_PRIORITY_MODE: Max place holder * * These are generic IDs that identify the various roles @@ -682,6 +684,8 @@ enum policy_mgr_conc_next_action { PM_SINGLE_MAC_UPGRADE, PM_SBS, PM_SBS_DOWNGRADE, + PM_DOWNGRADE, + PM_UPGRADE, PM_MAX_CONC_NEXT_ACTION }; @@ -889,6 +893,7 @@ struct policy_mgr_dual_mac_config { * @set_hw_mode_cb: HDD set HW mode callback * @reason: Reason for HW mode change * @session_id: Session id + * @next_action: next action to happen at policy mgr * @context: psoc context */ struct policy_mgr_hw_mode { @@ -896,7 +901,7 @@ struct policy_mgr_hw_mode { void *set_hw_mode_cb; enum policy_mgr_conn_update_reason reason; uint32_t session_id; - struct wlan_objmgr_vdev *vdev; + uint8_t next_action; struct wlan_objmgr_psoc *context; }; diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 48ab89322b0f..a4e0886a1ba1 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -98,7 +98,8 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, enum hw_mode_dbs_capab dbs, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs, - enum policy_mgr_conn_update_reason reason) + enum policy_mgr_conn_update_reason reason, + uint8_t next_action) { int8_t hw_mode_index; struct policy_mgr_hw_mode msg; @@ -135,6 +136,7 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, msg.set_hw_mode_cb = (void *)policy_mgr_pdev_set_hw_mode_cb; msg.reason = reason; msg.session_id = session_id; + msg.next_action = next_action; msg.context = psoc; policy_mgr_debug("set hw mode to sme: hw_mode_index: %d session:%d reason:%d", @@ -488,7 +490,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason); + reason, PM_NOP); break; case PM_SINGLE_MAC_UPGRADE: /* @@ -501,14 +503,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_DBS_NONE, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason); - /* - * check if we have a beaconing entity that advertised 2x2 - * intially. If yes, update the beacon template & notify FW. - * Once FW confirms beacon updated, send the HW mode change req - */ - status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_2, - PM_SINGLE_MAC, reason, session_id); + reason, PM_UPGRADE); break; case PM_SINGLE_MAC: status = policy_mgr_pdev_set_hw_mode(psoc, session_id, @@ -518,7 +513,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_DBS_NONE, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason); + reason, PM_NOP); break; case PM_DBS_UPGRADE: status = policy_mgr_pdev_set_hw_mode(psoc, session_id, @@ -528,10 +523,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, - reason); - - status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_2, - PM_DBS, reason, session_id); + reason, PM_UPGRADE); break; case PM_SBS_DOWNGRADE: status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, @@ -545,7 +537,23 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS, - reason); + reason, PM_NOP); + break; + case PM_DOWNGRADE: + /* + * check if we have a beaconing entity that advertised 2x2 + * intially. If yes, update the beacon template & notify FW. + */ + status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1, + PM_NOP, reason); + break; + case PM_UPGRADE: + /* + * check if we have a beaconing entity that advertised 2x2 + * intially. If yes, update the beacon template & notify FW. + */ + status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2, + PM_NOP, reason); break; default: policy_mgr_err("unexpected action value %d", action); diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 037ad11aa81b..c707cdac8a04 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -753,24 +753,13 @@ void policy_mgr_update_hw_mode_conn_info(struct wlan_objmgr_psoc *psoc, policy_mgr_dump_connection_status_info(psoc); } -/** - * policy_mgr_pdev_set_hw_mode_cb() - Callback for set hw mode - * @status: Status - * @cfgd_hw_mode_index: Configured HW mode index - * @num_vdev_mac_entries: Number of vdev-mac id mapping that follows - * @vdev_mac_map: vdev-mac id map. This memory will be freed by the caller. - * So, make local copy if needed. - * - * Provides the status and configured hw mode index set - * by the FW - * - * Return: None - */ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, uint32_t cfgd_hw_mode_index, uint32_t num_vdev_mac_entries, struct policy_mgr_vdev_mac_map *vdev_mac_map, - void *context) + uint8_t next_action, + enum policy_mgr_conn_update_reason reason, + uint32_t session_id, void *context) { QDF_STATUS ret; struct policy_mgr_hw_mode_params hw_mode; @@ -819,6 +808,12 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, if (!QDF_IS_STATUS_SUCCESS(ret)) policy_mgr_err("ERROR: set connection_update_done event failed"); + if (PM_NOP != next_action) + policy_mgr_next_actions(context, session_id, + next_action, reason); + else + policy_mgr_debug("No action needed right now"); + return; } @@ -2404,26 +2399,9 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, return; } -/** - * policy_mgr_complete_action() - initiates actions needed on - * current connections once channel has been decided for the new - * connection - * @new_nss: the new nss value - * @next_action: next action to happen at policy mgr after - * beacon update - * @reason: Reason for connection update - * @session_id: Session id - * - * This function initiates initiates actions - * needed on current connections once channel has been decided - * for the new connection. Notifies UMAC & FW as well - * - * Return: QDF_STATUS enum - */ -QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, - uint8_t new_nss, uint8_t next_action, - enum policy_mgr_conn_update_reason reason, - uint32_t session_id) +QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, + uint8_t new_nss, uint8_t next_action, + enum policy_mgr_conn_update_reason reason) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t index, count; @@ -2439,16 +2417,6 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, return status; } - if (policy_mgr_is_hw_dbs_capable(psoc) == false) { - policy_mgr_err("driver isn't dbs capable, no further action needed"); - return QDF_STATUS_E_NOSUPPORT; - } - - /* policy_mgr_complete_action() is called by policy_mgr_next_actions(). - * All other callers of policy_mgr_next_actions() have taken mutex - * protection. So, not taking any lock inside - * policy_mgr_complete_action() during pm_conc_connection_list access. - */ count = policy_mgr_mode_specific_connection_count(psoc, PM_P2P_GO_MODE, list); for (index = 0; index < count; index++) { @@ -2503,6 +2471,44 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, } } } + + return status; +} + +/** + * policy_mgr_complete_action() - initiates actions needed on + * current connections once channel has been decided for the new + * connection + * @new_nss: the new nss value + * @next_action: next action to happen at policy mgr after + * beacon update + * @reason: Reason for connection update + * @session_id: Session id + * + * This function initiates initiates actions + * needed on current connections once channel has been decided + * for the new connection. Notifies UMAC & FW as well + * + * Return: QDF_STATUS enum + */ +QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, + uint8_t new_nss, uint8_t next_action, + enum policy_mgr_conn_update_reason reason, + uint32_t session_id) +{ + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (policy_mgr_is_hw_dbs_capable(psoc) == false) { + policy_mgr_err("driver isn't dbs capable, no further action needed"); + return QDF_STATUS_E_NOSUPPORT; + } + + /* policy_mgr_complete_action() is called by policy_mgr_next_actions(). + * All other callers of policy_mgr_next_actions() have taken mutex + * protection. So, not taking any lock inside + * policy_mgr_complete_action() during pm_conc_connection_list access. + */ + status = policy_mgr_nss_update(psoc, new_nss, next_action, reason); if (!QDF_IS_STATUS_SUCCESS(status)) status = policy_mgr_next_actions(psoc, session_id, next_action, reason); diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 17c83b42101d..c05716131bc5 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -369,7 +369,9 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, uint32_t cfgd_hw_mode_index, uint32_t num_vdev_mac_entries, struct policy_mgr_vdev_mac_map *vdev_mac_map, - void *context); + uint8_t next_action, + enum policy_mgr_conn_update_reason reason, + uint32_t session_id, void *context); void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc); void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode); @@ -441,4 +443,8 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, struct regulatory_channel *chan_list, struct avoid_freq_ind_data *avoid_freq_ind, void *arg); + +QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, + uint8_t new_nss, uint8_t next_action, + enum policy_mgr_conn_update_reason reason); #endif From 8a611c641c52a7a6cbe9b2b2c6f16580031ca945 Mon Sep 17 00:00:00 2001 From: Ganesh Kondabattini Date: Tue, 21 Nov 2017 15:01:31 +0530 Subject: [PATCH 167/404] qcacmn: Allow SAP to come up on DFS channel in SCC mode Allow SAP to come up on DFS channel in STA+SAP concurrency mode only when g_sta_sap_scc_on_dfs_chan enabled in ini file and also disable chan_switch_hostapd_rate_enabled when force SCC is enabled. CRs-Fixed: 2147032 Change-Id: Id1333a49d0538eb4ccfaf3c8498e9ca06671de02 --- inc/wlan_policy_mgr_api.h | 11 +++++++++++ inc/wlan_policy_mgr_public_struct.h | 1 + src/wlan_policy_mgr_action.c | 6 ++++-- src/wlan_policy_mgr_get_set_utils.c | 19 +++++++++++++++++++ src/wlan_policy_mgr_i.h | 1 + 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 7e514d265f3b..7347880dce2a 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2187,4 +2187,15 @@ void policy_mgr_check_and_stop_opportunistic_timer( void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels, uint32_t *len, uint8_t *weight_list, uint32_t weight_len); + +/** + * policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan() - check if sta+sap scc + * allowed on dfs chan + * @psoc: pointer to soc + * This function is used to check if sta+sap scc allowed on dfs channel + * + * Return: true if sta+sap scc is allowed on dfs channel, otherwise false + */ +bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( + struct wlan_objmgr_psoc *psoc); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 18d16254efa4..3ace5acb8d2a 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1017,6 +1017,7 @@ struct policy_mgr_user_cfg { bool enable2x2; uint32_t mcc_to_scc_switch_mode; bool sub_20_mhz_enabled; + bool is_sta_sap_scc_allowed_on_dfs_chan; }; /** diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index a4e0886a1ba1..607d1b0ef977 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -747,13 +747,15 @@ static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, return false; } - if (wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) || + if ((wlan_reg_is_dfs_ch(pm_ctx->pdev, sta_channel) && + (!policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc))) || wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, sta_channel) || - !policy_mgr_is_safe_channel(psoc, sta_channel)) + !policy_mgr_is_safe_channel(psoc, sta_channel)) { if (policy_mgr_is_hw_dbs_capable(psoc)) return true; else return false; + } else return true; } diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 3d11ab25cf00..50d8a3f6a4b9 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2721,3 +2721,22 @@ bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc) (pm_ctx->user_cfg.mcc_to_scc_switch_mode == QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)); } + +bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( + struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + bool status = false; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return status; + } + + if (policy_mgr_is_force_scc(psoc) && + pm_ctx->user_cfg.is_sta_sap_scc_allowed_on_dfs_chan) + status = true; + + return status; +} diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index c05716131bc5..16d38fabddfe 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -271,6 +271,7 @@ struct policy_mgr_psoc_priv_obj { uint16_t unsafe_channel_count; struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info; uint8_t cur_conc_system_pref; + uint8_t sta_sap_scc_on_dfs_chan_allowed; }; /** From 5ef3b6fc5f0130519e3f41a630ed2c1d5d120fb1 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Fri, 21 Jul 2017 18:02:02 +0800 Subject: [PATCH 168/404] 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 7fc7beb46328f3aabec9c5f3ef65883a1f692a75 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Fri, 21 Jul 2017 18:02:02 +0800 Subject: [PATCH 169/404] 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 --- core/src/wlan_tdls_cmds_process.c | 149 +++++++++++++++++++++- core/src/wlan_tdls_cmds_process.h | 20 +++ core/src/wlan_tdls_main.c | 2 + dispatcher/inc/wlan_tdls_public_structs.h | 20 +++ dispatcher/inc/wlan_tdls_ucfg_api.h | 10 ++ dispatcher/src/wlan_tdls_ucfg_api.c | 40 ++++++ 6 files changed, 240 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 6780f0a2c237..e934f4f49a0e 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -29,6 +29,7 @@ #include "wlan_tdls_mgmt.h" #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_tgt_api.h" +#include "wlan_policy_mgr_api.h" static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) { @@ -567,7 +568,7 @@ void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, return; if (TDLS_TEARDOWN != action_code || - tdls_soc->tdls_nss_switch_in_progress) + !tdls_soc->tdls_nss_switch_in_progress) return; if (tdls_soc->tdls_teardown_peers_cnt != 0) @@ -589,6 +590,8 @@ void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, tdls_notice("teardown done & NSS switch in progress"); tdls_soc->tdls_nss_teardown_complete = true; } + tdls_soc->tdls_nss_transition_mode = + TDLS_NSS_TRANSITION_S_UNKNOWN; } } @@ -2182,3 +2185,147 @@ int tdls_set_responder(struct tdls_set_responder_req *set_req) return status; } +static int tdls_teardown_links(struct tdls_soc_priv_obj *soc_obj, uint32_t mode) +{ + uint8_t staidx; + struct tdls_peer *curr_peer; + struct tdls_conn_info *conn_rec; + int ret = 0; + + conn_rec = soc_obj->tdls_conn_info; + for (staidx = 0; staidx < soc_obj->max_num_tdls_sta; staidx++) { + if (conn_rec[staidx].sta_id == 0) + continue; + + curr_peer = tdls_find_all_peer(soc_obj, + conn_rec[staidx].peer_mac.bytes); + if (!curr_peer) + continue; + + /* if supported only 1x1, skip it */ + if (curr_peer->spatial_streams == HW_MODE_SS_1x1) + continue; + + tdls_debug("Indicate TDLS teardown (staId %d)", + curr_peer->sta_id); + tdls_indicate_teardown(curr_peer->vdev_priv, curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + + soc_obj->tdls_teardown_peers_cnt++; + } + + if (soc_obj->tdls_teardown_peers_cnt >= 1) { + soc_obj->tdls_nss_switch_in_progress = true; + tdls_debug("TDLS peers to be torn down = %d", + soc_obj->tdls_teardown_peers_cnt); + + /* set the antenna switch transition mode */ + if (mode == HW_MODE_SS_1x1) { + soc_obj->tdls_nss_transition_mode = + TDLS_NSS_TRANSITION_S_2x2_to_1x1; + ret = -EAGAIN; + } else { + soc_obj->tdls_nss_transition_mode = + TDLS_NSS_TRANSITION_S_1x1_to_2x2; + ret = 0; + } + tdls_debug("TDLS teardown for antenna switch operation starts"); + } + + return ret; +} + +QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct wlan_objmgr_vdev *vdev = NULL; + uint32_t vdev_nss; + int ant_switch_state = 0; + uint32_t vdev_id; + enum QDF_OPMODE opmode; + uint8_t channel; + struct tdls_osif_indication ind; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + status = QDF_STATUS_E_INVAL; + goto error; + } + + vdev = req->vdev; + status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev_obj & soc_obj"); + goto error; + } + + if (soc_obj->connected_peer_count == 0) + goto ant_sw_done; + + if (soc_obj->tdls_nss_switch_in_progress) { + if (!soc_obj->tdls_nss_teardown_complete) { + tdls_err("TDLS antenna switch is in progress"); + goto error; + } else { + goto ant_sw_done; + } + } + + vdev_id = wlan_vdev_get_id(vdev); + opmode = wlan_vdev_mlme_get_opmode(vdev); + channel = policy_mgr_get_channel(soc_obj->soc, opmode, &vdev_id); + + /* Check supported nss for TDLS, if is 1x1, no need to teardown links */ + if (WLAN_REG_IS_24GHZ_CH(channel)) + vdev_nss = soc_obj->tdls_configs.tdls_vdev_nss_2g; + else + vdev_nss = soc_obj->tdls_configs.tdls_vdev_nss_5g; + + if (vdev_nss == HW_MODE_SS_1x1) { + tdls_debug("Supported NSS is 1x1, no need to teardown TDLS links"); + goto ant_sw_done; + } + + if (tdls_teardown_links(soc_obj, req->mode) == 0) + goto ant_sw_done; + +error: + ant_switch_state = -EAGAIN; +ant_sw_done: + if (soc_obj->tdls_event_cb) { + ind.vdev = vdev; + ind.status = ant_switch_state; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ANTENNA_SWITCH, &ind); + } + + if (soc_obj->tdls_nss_switch_in_progress && + soc_obj->tdls_nss_teardown_complete) { + soc_obj->tdls_nss_switch_in_progress = false; + soc_obj->tdls_nss_teardown_complete = false; + } + tdls_debug("tdls_nss_switch_in_progress: %d tdls_nss_teardown_complete: %d", + soc_obj->tdls_nss_switch_in_progress, + soc_obj->tdls_nss_teardown_complete); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + return status; +} + +QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg) +{ + struct tdls_antenna_switch_request *req; + + if (!msg || !msg->bodyptr) { + tdls_err("msg: 0x%pK, bodyptr: 0x%pK", msg, msg->bodyptr); + return QDF_STATUS_E_NULL_VALUE; + } + req = msg->bodyptr; + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 561a40d78b34..10e20cfa1b5e 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -249,6 +249,26 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req); */ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req); +/** + * tdls_process_antenna_switch() - handle TDLS antenna switch + * @req: TDLS antenna switch request + * + * Rely on callback to indicate the antenna switch state to caller. + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed. + */ +QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req); + +/** + * tdls_antenna_switch_flush_callback() - flush TDLS antenna switch request + * @msg: scheduler message contains tdls antenna switch event + * + * This function call is invoked when scheduler thread is going down + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg); + /** * tdls_pe_del_peer() - send TDLS delete peer request to PE * @req: TDLS delete peer request diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index a423dcd08a05..a269a95cc6ba 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -292,6 +292,8 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) break; case TDLS_NOTIFY_RESET_ADAPTERS: tdls_notify_reset_adapter(msg->bodyptr); + case TDLS_CMD_ANTENNA_SWITCH: + tdls_process_antenna_switch(msg->bodyptr); break; case TDLS_CMD_GET_ALL_PEERS: tdls_get_all_peers_from_list(msg->bodyptr); diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index ae0a4077b247..457a3ded556b 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -68,6 +68,9 @@ /** Maximum waittime for TDLS teardown links **/ #define WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS 10000 +/** Maximum waittime for TDLS antenna switch **/ +#define WAIT_TIME_FOR_TDLS_ANTENNA_SWITCH 1000 + #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 @@ -185,6 +188,7 @@ enum tdls_feature_mode { * @TDLS_CMD_TEARDOWN_LINKS: notify teardown * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list + * @TDLS_CMD_ANTENNA_SWITCH: dynamic tdls antenna switch */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -206,6 +210,7 @@ enum tdls_command_type { TDLS_CMD_TEARDOWN_LINKS, TDLS_NOTIFY_RESET_ADAPTERS, TDLS_CMD_GET_ALL_PEERS, + TDLS_CMD_ANTENNA_SWITCH }; /** @@ -220,6 +225,7 @@ enum tdls_command_type { * @TDLS_EVENT_SETUP_REQ: setup request * @TDLS_EVENT_TEARDOWN_LINKS_DONE: teardown completion event * @TDLS_EVENT_USER_CMD: tdls user command + * @TDLS_EVENT_ANTENNA_SWITCH: antenna switch event */ enum tdls_event_type { TDLS_EVENT_VDEV_STATE_CHANGE = 0, @@ -232,6 +238,7 @@ enum tdls_event_type { TDLS_EVENT_SETUP_REQ, TDLS_EVENT_TEARDOWN_LINKS_DONE, TDLS_EVENT_USER_CMD, + TDLS_EVENT_ANTENNA_SWITCH, }; /** @@ -417,6 +424,8 @@ enum tdls_feature_bit { * @tdls_pre_off_chan_bw: tdls off channel bandwidth * @tdls_peer_kickout_threshold: sta kickout threshold for tdls peer * @delayed_trig_framint: delayed trigger frame interval + * @tdls_vdev_nss_2g: tdls NSS setting for 2G band + * @tdls_vdev_nss_5g: tdls NSS setting for 5G band */ struct tdls_user_config { uint32_t tdls_tx_states_period; @@ -437,6 +446,8 @@ struct tdls_user_config { uint32_t tdls_pre_off_chan_bw; uint32_t tdls_peer_kickout_threshold; uint32_t delayed_trig_framint; + uint8_t tdls_vdev_nss_2g; + uint8_t tdls_vdev_nss_5g; }; /** @@ -1066,4 +1077,13 @@ struct tdls_del_all_tdls_peers { struct qdf_mac_addr bssid; }; +/** + * struct tdls_antenna_switch_request - TDLS antenna switch request + * @vdev: vdev object + * @mode: antenna mode, 1x1 or 2x2 + */ +struct tdls_antenna_switch_request { + struct wlan_objmgr_vdev *vdev; + uint32_t mode; +}; #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index f23bf52aebee..ffe3404dc6b6 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -212,4 +212,14 @@ void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *mac_addr); +/** + * ucfg_tdls_antenna_switch() - tdls antenna switch + * @vdev: tdls vdev object + * @mode: antenna mode + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, + uint32_t mode); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 36c6318156f5..7ed904bd3ae0 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -742,3 +742,43 @@ void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, } +QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, + uint32_t mode) +{ + QDF_STATUS status; + struct tdls_antenna_switch_request *req; + struct scheduler_msg msg = {0, }; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto error; + } + + req->vdev = vdev; + req->mode = mode; + + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_antenna_switch_flush_callback; + msg.type = TDLS_CMD_ANTENNA_SWITCH; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post antenna switch msg fail"); + goto dec_ref; + } + + return status; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +error: + qdf_mem_free(req); + return status; +} From e823bbf9d530b327c5fb1cd8ffd05a8c772faece Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 23 Nov 2017 14:08:29 +0800 Subject: [PATCH 170/404] qcacmn: Use qdf API instead of linux function Replacing linux function with qdf API in P2P conponemt. Change-Id: Ibf4e8acef0b2f4be113dbecb9ac2a685f456fd53 CRs-Fixed: 2148472 --- core/src/wlan_p2p_off_chan_tx.c | 94 ++++++++++++++++++++------------- core/src/wlan_p2p_roc.c | 93 +++++++++++++++++++------------- 2 files changed, 112 insertions(+), 75 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index f97937275aa8..51e8492ac57b 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1006,31 +1006,38 @@ static struct tx_action_context *p2p_find_tx_ctx( bool *is_roc_q, bool *is_ack_q) { struct tx_action_context *cur_tx_ctx; - qdf_list_node_t *tmp, *pos; + qdf_list_node_t *p_node; + QDF_STATUS status; *is_roc_q = false; *is_ack_q = false; p2p_debug("Start to find tx ctx, p2p soc_obj:%pK, cookie:%llx", p2p_soc_obj, cookie); - list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { - cur_tx_ctx = - list_entry(pos, struct tx_action_context, node); + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_roc, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + cur_tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); if ((uintptr_t) cur_tx_ctx == cookie) { *is_roc_q = true; p2p_debug("find tx ctx, cookie:%llx", cookie); return cur_tx_ctx; } + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc, + p_node, &p_node); } - list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { - cur_tx_ctx = - list_entry(pos, struct tx_action_context, node); + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + cur_tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); if ((uintptr_t) cur_tx_ctx == cookie) { *is_ack_q = true; p2p_debug("find tx ctx, cookie:%llx", cookie); return cur_tx_ctx; } + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, + p_node, &p_node); } return NULL; @@ -1052,31 +1059,38 @@ static struct tx_action_context *p2p_find_tx_ctx_by_roc( bool *is_roc_q, bool *is_ack_q) { struct tx_action_context *cur_tx_ctx; - qdf_list_node_t *tmp, *pos; + qdf_list_node_t *p_node; + QDF_STATUS status; *is_roc_q = false; *is_ack_q = false; p2p_debug("Start to find tx ctx, p2p soc_obj:%pK, cookie:%llx", p2p_soc_obj, cookie); - list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { - cur_tx_ctx = - list_entry(pos, struct tx_action_context, node); + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_roc, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + cur_tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); if (cur_tx_ctx->roc_cookie == cookie) { *is_roc_q = true; p2p_debug("find tx ctx, cookie:%llx", cookie); return cur_tx_ctx; } + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc, + p_node, &p_node); } - list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { - cur_tx_ctx = - list_entry(pos, struct tx_action_context, node); + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + cur_tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); if (cur_tx_ctx->roc_cookie == cookie) { *is_ack_q = true; p2p_debug("find tx ctx, cookie:%llx", cookie); return cur_tx_ctx; } + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, + p_node, &p_node); } return NULL; @@ -1445,13 +1459,16 @@ static QDF_STATUS p2p_execute_tx_action_frame( void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) { struct tx_action_context *tx_ctx; - qdf_list_node_t *tmp, *pos; + qdf_list_node_t *p_node; + QDF_STATUS status; p2p_debug("dump tx queue wait for roc, p2p soc obj:%pK, size:%d", p2p_soc_obj, qdf_list_size(&p2p_soc_obj->tx_q_roc)); - list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { - tx_ctx = list_entry(pos, struct tx_action_context, - node); + + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_roc, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); p2p_debug("p2p soc object:%pK, tx ctx:%pK, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%pK, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", p2p_soc_obj, tx_ctx, tx_ctx->vdev_id, tx_ctx->scan_id, @@ -1459,13 +1476,17 @@ void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan, tx_ctx->no_cck, tx_ctx->no_ack, tx_ctx->duration); + + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc, + p_node, &p_node); } p2p_debug("dump tx queue wait for ack, size:%d", qdf_list_size(&p2p_soc_obj->tx_q_ack)); - list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { - tx_ctx = list_entry(pos, struct tx_action_context, - node); + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); p2p_debug("p2p soc object:%pK, tx_ctx:%pK, vdev_id:%d, scan_id:%d, roc_cookie:%llx, chan:%d, buf:%pK, len:%d, off_chan:%d, cck:%d, ack:%d, duration:%d", p2p_soc_obj, tx_ctx, tx_ctx->vdev_id, tx_ctx->scan_id, @@ -1473,6 +1494,9 @@ void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) tx_ctx->buf, tx_ctx->buf_len, tx_ctx->off_chan, tx_ctx->no_cck, tx_ctx->no_ack, tx_ctx->duration); + + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, + p_node, &p_node); } } @@ -1511,19 +1535,16 @@ QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj, QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) { - QDF_STATUS status = QDF_STATUS_E_FAILURE; struct tx_action_context *curr_tx_ctx; - qdf_list_node_t *tmp, *pos; + qdf_list_node_t *p_node; p2p_debug("clean up tx queue wait for roc, size:%d", qdf_list_size(&p2p_soc_obj->tx_q_roc)); - list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_roc.anchor) { - curr_tx_ctx = list_entry(pos, - struct tx_action_context, node); - status = qdf_list_remove_node(&p2p_soc_obj->tx_q_roc, - (qdf_list_node_t *)curr_tx_ctx); - if (status != QDF_STATUS_SUCCESS) - p2p_err("Failed to remove tx ctx from tx wait for roc queue"); + + while (qdf_list_remove_front(&p2p_soc_obj->tx_q_roc, &p_node) == + QDF_STATUS_SUCCESS) { + curr_tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); p2p_send_tx_conf(curr_tx_ctx, false); qdf_mem_free(curr_tx_ctx->buf); qdf_mem_free(curr_tx_ctx); @@ -1531,20 +1552,17 @@ QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) p2p_debug("clean up tx queue wait for ack, size:%d", qdf_list_size(&p2p_soc_obj->tx_q_ack)); - list_for_each_safe(pos, tmp, &p2p_soc_obj->tx_q_ack.anchor) { - curr_tx_ctx = list_entry(pos, - struct tx_action_context, node); - status = qdf_list_remove_node(&p2p_soc_obj->tx_q_ack, - (qdf_list_node_t *)curr_tx_ctx); - if (status != QDF_STATUS_SUCCESS) - p2p_err("Failed to remove tx ctx from tx wait for ack queue"); + while (qdf_list_remove_front(&p2p_soc_obj->tx_q_ack, &p_node) == + QDF_STATUS_SUCCESS) { + curr_tx_ctx = qdf_container_of(p_node, + struct tx_action_context, node); p2p_disable_tx_timer(curr_tx_ctx); p2p_send_tx_conf(curr_tx_ctx, false); qdf_mem_free(curr_tx_ctx->buf); qdf_mem_free(curr_tx_ctx); } - return status; + return QDF_STATUS_SUCCESS; } QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index ae71a7765124..a6eff6ed87cf 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -402,15 +402,19 @@ static struct p2p_roc_context *p2p_find_roc_ctx( struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie) { struct p2p_roc_context *curr_roc_ctx; - qdf_list_node_t *tmp, *pos; + qdf_list_node_t *p_node; + QDF_STATUS status; p2p_debug("p2p soc obj:%pK, cookie:%llx", p2p_soc_obj, cookie); - list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { - curr_roc_ctx = list_entry(pos, struct p2p_roc_context, - node); + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_roc_ctx = qdf_container_of(p_node, + struct p2p_roc_context, node); if ((uintptr_t) curr_roc_ctx == cookie) return curr_roc_ctx; + status = qdf_list_peek_next(&p2p_soc_obj->roc_q, + p_node, &p_node); } return NULL; @@ -569,11 +573,13 @@ struct p2p_roc_context *p2p_find_current_roc_ctx( struct p2p_soc_priv_obj *p2p_soc_obj) { struct p2p_roc_context *roc_ctx; - qdf_list_node_t *tmp, *pos; + qdf_list_node_t *p_node; + QDF_STATUS status; - list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { - roc_ctx = list_entry(pos, struct p2p_roc_context, - node); + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + roc_ctx = qdf_container_of(p_node, + struct p2p_roc_context, node); if (roc_ctx->roc_state != ROC_STATE_IDLE) { p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id" ":%d, scan_id:%d, cookie:%llx, chan:" @@ -587,6 +593,8 @@ struct p2p_roc_context *p2p_find_current_roc_ctx( return roc_ctx; } + status = qdf_list_peek_next(&p2p_soc_obj->roc_q, + p_node, &p_node); } return NULL; @@ -616,15 +624,17 @@ QDF_STATUS p2p_restart_roc_timer(struct p2p_roc_context *roc_ctx) QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) { - QDF_STATUS status = QDF_STATUS_SUCCESS; struct p2p_roc_context *roc_ctx; - qdf_list_node_t *tmp, *pos; + qdf_list_node_t *p_node; + QDF_STATUS status, ret; p2p_debug("clean up idle roc request, roc queue size:%d", qdf_list_size(&p2p_soc_obj->roc_q)); - list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { - roc_ctx = list_entry(pos, struct p2p_roc_context, - node); + + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + roc_ctx = qdf_container_of(p_node, + struct p2p_roc_context, node); p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, @@ -632,12 +642,13 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); - + status = qdf_list_peek_next(&p2p_soc_obj->roc_q, + p_node, &p_node); if (roc_ctx->roc_state == ROC_STATE_IDLE) { - status = qdf_list_remove_node( + ret = qdf_list_remove_node( &p2p_soc_obj->roc_q, (qdf_list_node_t *)roc_ctx); - if (status == QDF_STATUS_SUCCESS) + if (ret == QDF_STATUS_SUCCESS) p2p_destroy_roc_ctx(roc_ctx, true, false); else @@ -647,9 +658,10 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) p2p_debug("clean up started roc request, roc queue size:%d", qdf_list_size(&p2p_soc_obj->roc_q)); - list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { - roc_ctx = list_entry(pos, struct p2p_roc_context, - node); + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + roc_ctx = qdf_container_of(p_node, + struct p2p_roc_context, node); p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, @@ -657,33 +669,36 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); + status = qdf_list_peek_next(&p2p_soc_obj->roc_q, + p_node, &p_node); if (roc_ctx->roc_state != ROC_STATE_IDLE) { if (roc_ctx->roc_state != ROC_STATE_CANCEL_IN_PROG) p2p_execute_cancel_roc_req(roc_ctx); - status = qdf_wait_single_event( + ret = qdf_wait_single_event( &p2p_soc_obj->cancel_roc_done, P2P_WAIT_CANCEL_ROC); - p2p_debug("roc cancellation done, status:%d", status); + p2p_debug("roc cancellation done, return:%d", ret); } } - return status; + return QDF_STATUS_SUCCESS; } QDF_STATUS p2p_cleanup_roc_by_vdev( struct p2p_soc_priv_obj *p2p_soc_obj, uint32_t vdev_id) { - QDF_STATUS status = QDF_STATUS_SUCCESS; + QDF_STATUS status, ret; struct p2p_roc_context *roc_ctx; - qdf_list_node_t *tmp, *pos; + qdf_list_node_t *p_node; p2p_debug("clean up idle roc request, roc queue size:%d, vdev id:%d", qdf_list_size(&p2p_soc_obj->roc_q), vdev_id); - list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { - roc_ctx = list_entry(pos, struct p2p_roc_context, - node); + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + roc_ctx = qdf_container_of(p_node, + struct p2p_roc_context, node); p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, @@ -691,13 +706,14 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); - + status = qdf_list_peek_next(&p2p_soc_obj->roc_q, + p_node, &p_node); if (roc_ctx->roc_state == ROC_STATE_IDLE && roc_ctx->vdev_id == vdev_id) { - status = qdf_list_remove_node( + ret = qdf_list_remove_node( &p2p_soc_obj->roc_q, (qdf_list_node_t *)roc_ctx); - if (status == QDF_STATUS_SUCCESS) + if (ret == QDF_STATUS_SUCCESS) qdf_mem_free(roc_ctx); else p2p_err("Failed to remove roc ctx from queue"); @@ -706,30 +722,33 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( p2p_debug("clean up started roc request, roc queue size:%d", qdf_list_size(&p2p_soc_obj->roc_q)); - list_for_each_safe(pos, tmp, &p2p_soc_obj->roc_q.anchor) { - roc_ctx = list_entry(pos, struct p2p_roc_context, - node); + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + roc_ctx = qdf_container_of(p_node, + struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); + status = qdf_list_peek_next(&p2p_soc_obj->roc_q, + p_node, &p_node); if (roc_ctx->roc_state != ROC_STATE_IDLE && roc_ctx->vdev_id == vdev_id) { if (roc_ctx->roc_state != ROC_STATE_CANCEL_IN_PROG) p2p_execute_cancel_roc_req(roc_ctx); - status = qdf_wait_single_event( + ret = qdf_wait_single_event( &p2p_soc_obj->cancel_roc_done, P2P_WAIT_CANCEL_ROC); - p2p_debug("RoC cancellation done, status:%d", status); + p2p_debug("RoC cancellation done, return:%d", ret); } } - return status; + return QDF_STATUS_SUCCESS; } QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx) From ef459873afd182f9668324225efa96379886623c Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 16 Nov 2017 10:15:41 +0800 Subject: [PATCH 171/404] qcacmn: Handle late tx ack in P2P component In some special case, ota tx ack of P2P action frame comes more than 2 second and tx context is free due to tx time out, than crash happens since of invalid pointer access. Solution is search tx context by nbuf, do not process the ota tx ack if not find tx context from waiting for ack queue. Change-Id: I0778d0f22d963b00af5212b9d6080a95a4888e73 CRs-Fixed: 2142870 --- core/src/wlan_p2p_off_chan_tx.c | 43 +++++++++++++++++++++++++----- core/src/wlan_p2p_off_chan_tx.h | 13 +++++++++ dispatcher/src/wlan_p2p_tgt_api.c | 9 +++++-- dispatcher/src/wlan_p2p_ucfg_api.c | 1 + 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 51e8492ac57b..0b6b6d249f9a 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -932,9 +932,10 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, mgmt_param.frm_len, mgmt_param.vdev_id, mgmt_param.chanfreq, tx_ctx->no_ack); - status = wlan_mgmt_txrx_mgmt_frame_tx(peer, tx_ctx, - (qdf_nbuf_t)packet, - tx_comp_cb, tx_ota_comp_cb, + tx_ctx->nbuf = packet; + + status = wlan_mgmt_txrx_mgmt_frame_tx(peer, tx_ctx->p2p_soc_obj, + (qdf_nbuf_t)packet, tx_comp_cb, tx_ota_comp_cb, WLAN_UMAC_COMP_P2P, &mgmt_param); wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID); @@ -1138,7 +1139,6 @@ static QDF_STATUS p2p_move_tx_context_to_ack_queue( &tx_ctx->node); if (status != QDF_STATUS_SUCCESS) p2p_err("Failed to insert off chan tx context to wait ack req queue"); - p2p_debug("insert tx context to wait for roc queue, status:%d", status); @@ -1286,8 +1286,8 @@ static void p2p_tx_timeout(void *pdata) p2p_debug("pdata:%pK", pdata); - if (!tx_ctx) { - p2p_err("invalid tx context"); + if (!tx_ctx || !(tx_ctx->p2p_soc_obj)) { + p2p_err("invalid tx context or p2p soc object"); return; } @@ -1456,6 +1456,37 @@ static QDF_STATUS p2p_execute_tx_action_frame( return status; } +struct tx_action_context *p2p_find_tx_ctx_by_nbuf( + struct p2p_soc_priv_obj *p2p_soc_obj, void *nbuf) +{ + struct tx_action_context *cur_tx_ctx; + qdf_list_node_t *p_node; + QDF_STATUS status; + + if (!p2p_soc_obj) { + p2p_err("invalid p2p soc object"); + return NULL; + } + + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + cur_tx_ctx = + qdf_container_of(p_node, struct tx_action_context, node); + if (cur_tx_ctx->nbuf == nbuf) { + p2p_debug("find tx ctx, nbuf:%pK", nbuf); + status = qdf_mc_timer_stop(&cur_tx_ctx->tx_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to stop tx timer, status:%d", + status); + return cur_tx_ctx; + } + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, + p_node, &p_node); + } + + return NULL; +} + void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) { struct tx_action_context *tx_ctx; diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index 39f006b7e0f7..87465875f0fc 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -173,6 +173,7 @@ struct tx_action_context { uint32_t duration; qdf_mc_timer_t tx_timer; struct p2p_frame_info frame_info; + void *nbuf; }; /** @@ -255,4 +256,16 @@ QDF_STATUS p2p_process_mgmt_tx_ack_cnf( QDF_STATUS p2p_process_rx_mgmt( struct p2p_rx_mgmt_event *rx_mgmt_event); +/** + * p2p_find_tx_ctx_by_nbuf() - find tx context by nbuf + * @p2p_soc_obj: p2p soc object + * @nbuf: pointer to nbuf + * + * This function finds out tx context by nbuf. + * + * Return: pointer to tx context + */ +struct tx_action_context *p2p_find_tx_ctx_by_nbuf( + struct p2p_soc_priv_obj *p2p_soc_obj, void *nbuf); + #endif /* _WLAN_P2P_OFF_CHAN_TX_H_ */ diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 699bd4707160..84cd4673a50d 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -137,8 +137,13 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, qdf_nbuf_free(buf); return QDF_STATUS_E_INVAL; } - tx_ctx = (struct tx_action_context *)context; - p2p_soc_obj = tx_ctx->p2p_soc_obj; + p2p_soc_obj = (struct p2p_soc_priv_obj *)context; + tx_ctx = p2p_find_tx_ctx_by_nbuf(p2p_soc_obj, buf); + if (!tx_ctx) { + p2p_err("can't find tx_ctx, tx ack comes late"); + qdf_nbuf_free(buf); + return QDF_STATUS_E_FAULT; + } tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event)); if (!tx_conf_event) { diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index a59469282ee4..4415b3cbefc2 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -271,6 +271,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, return QDF_STATUS_E_NOMEM; } qdf_mem_copy(tx_action->buf, mgmt_frm->buf, tx_action->buf_len); + tx_action->nbuf = NULL; msg.type = P2P_MGMT_TX; msg.bodyptr = tx_action; msg.callback = p2p_process_cmd; From 77f47d78efcdd7d9190dc355c64c5908b01f8317 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Fri, 1 Dec 2017 10:32:28 -0800 Subject: [PATCH 172/404] 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 efbeeab4fc24a4c3ab5a552b5f9e99925bdf49ed Mon Sep 17 00:00:00 2001 From: Srinivas Girigowda Date: Tue, 28 Nov 2017 18:12:22 -0800 Subject: [PATCH 173/404] qcacmn: clang: Remove unnecessary NULL check for address of array Clang generated the following warning in various places: warning: address of array 'weight->pcl_list' will always evaluate to 'true' [-Wpointer-bool-conversion] if (weight->pcl_list) { ~~ ~~~^~~ Remove the unnecessary NULL check for address of array. Change-Id: Ibc82b4d7135a0425748c0fb7f065435ccd28ad6f CRs-Fixed: 2150493 --- src/wlan_policy_mgr_pcl.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 3728d2a3adcb..11a4b32598e5 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1627,21 +1627,6 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - if (!weight->pcl_list) { - policy_mgr_err("Invalid pcl"); - return QDF_STATUS_E_FAILURE; - } - - if (!weight->saved_chan_list) { - policy_mgr_err("Invalid valid channel list"); - return QDF_STATUS_E_FAILURE; - } - - if (!weight->weighed_valid_list) { - policy_mgr_err("Invalid weighed valid channel list"); - return QDF_STATUS_E_FAILURE; - } - qdf_mem_set(weight->weighed_valid_list, QDF_MAX_NUM_CHAN, WEIGHT_OF_DISALLOWED_CHANNELS); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); From c183c790f9920667e2c7c09863e7a7d48f651a54 Mon Sep 17 00:00:00 2001 From: Yun Park Date: Mon, 27 Nov 2017 10:51:53 -0800 Subject: [PATCH 174/404] qcacmn: Optimize data path logging Remove or lower log level to reduce log from data path which affects to TPUT. Change-Id: I7d4344c80cefb4a9539644ef50ff2074d80d6548 CRs-Fixed: 2143250 --- core/src/wlan_tdls_ct.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index a7636e34b502..3e9e70eb77dd 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -257,7 +257,6 @@ void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, uint8_t valid_mac_entries; struct tdls_conn_tracker_mac_table *mac_table; - tdls_debug("enter "); if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj)) return; @@ -296,7 +295,6 @@ void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, rx_cnt_return: qdf_spin_unlock_bh(&tdls_soc_obj->tdls_ct_spinlock); - tdls_debug("exit: rx pkt count %d ", mac_table[mac_cnt].rx_packet_cnt); return; } @@ -309,7 +307,6 @@ void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, uint8_t valid_mac_entries; struct tdls_conn_tracker_mac_table *mac_table; - tdls_debug("enter "); if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj)) return; @@ -349,7 +346,6 @@ void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, tx_cnt_return: qdf_spin_unlock_bh(&tdls_soc_obj->tdls_ct_spinlock); - tdls_debug("exit: tx pkt count %d", mac_table[mac_cnt].tx_packet_cnt); return; } From 07992021c7207e39b2785c0f7e054fd3d666477b Mon Sep 17 00:00:00 2001 From: Paul Zhang Date: Thu, 30 Nov 2017 12:15:46 +0800 Subject: [PATCH 175/404] qcacmn: Do sanity check of requester ID If the requester id is 0 or other invalid values, the function scm_scan_get_requester_event_handler will get unexpected handler. Change-Id: I505e2e1a1bdc9cec57aaa0c28abadf28d228ba5b CRs-Fixed: 2147555 --- core/src/wlan_p2p_main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 95aa3f0094b8..c1b60d05b13f 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -173,7 +173,7 @@ struct p2p_soc_priv_obj { qdf_list_t roc_q; qdf_list_t tx_q_roc; qdf_list_t tx_q_ack; - uint16_t scan_req_id; + wlan_scan_requester scan_req_id; struct p2p_start_param *start_param; qdf_event_t cancel_roc_done; qdf_runtime_lock_t roc_runtime_lock; From 9b84b21a1cebc669520e4e13054cf4b87b1e5437 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 14 Dec 2017 17:02:55 -0800 Subject: [PATCH 176/404] qcacmn: Fix the TDLS command process map TDLS command processing incorrectly fall through to the wrong command, and it causes the crash in the system. Fix the mapping in TDLS process command function Change-Id: I296e10f92e283a813259e1f33143d09bcf3ab39b CRs-Fixed: 2159351 --- core/src/wlan_tdls_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index a269a95cc6ba..800666feb225 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -292,6 +292,7 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) break; case TDLS_NOTIFY_RESET_ADAPTERS: tdls_notify_reset_adapter(msg->bodyptr); + break; case TDLS_CMD_ANTENNA_SWITCH: tdls_process_antenna_switch(msg->bodyptr); break; From 8fc14c2eca8b4aa7ac153ebfa3a245f75c4ce00c Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Wed, 29 Nov 2017 15:32:58 -0800 Subject: [PATCH 177/404] qcacmn: Correct the log level for debug messages Correct the log level for debug messages Change-Id: I847d606ea28b382c1dd449221f72822cf37f2be8 CRs-Fixed: 2160779 --- core/src/wlan_tdls_main.c | 2 +- dispatcher/src/wlan_tdls_ucfg_api.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 800666feb225..fc1817bcde97 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -600,7 +600,7 @@ void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc) set_state: tdls_soc_obj->enable_tdls_connection_tracker = state; - tdls_notice("enable_tdls_connection_tracker %d", + tdls_debug("enable_tdls_connection_tracker %d", tdls_soc_obj->enable_tdls_connection_tracker); } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 7ed904bd3ae0..7c5d9ad619ed 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -543,7 +543,7 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( mgmt_req->tdls_mgmt.len = 0; } - tdls_notice("vdev id: %d, session id : %d", mgmt_req->vdev_id, + tdls_debug("vdev id: %d, session id : %d", mgmt_req->vdev_id, mgmt_req->session_id); msg.bodyptr = mgmt_req; msg.callback = tdls_process_cmd; @@ -589,14 +589,14 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) tdls_err("vdev is NULL "); return QDF_STATUS_E_NULL_VALUE; } - tdls_notice("Enter "); + tdls_debug("Enter "); msg.bodyptr = vdev; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_TEARDOWN_LINKS; status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - tdls_notice("Exit "); + tdls_debug("Exit "); return status; } @@ -628,7 +628,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( notify_info->vdev, notify_info); return QDF_STATUS_E_NULL_VALUE; } - tdls_notice("Enter "); + tdls_debug("Enter "); notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) @@ -645,7 +645,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( msg.type = TDLS_NOTIFY_STA_CONNECTION; scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - tdls_notice("Exit "); + tdls_debug("Exit "); return QDF_STATUS_SUCCESS; } @@ -661,7 +661,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( return QDF_STATUS_E_NULL_VALUE; } - tdls_notice("Enter "); + tdls_debug("Enter "); notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) @@ -679,7 +679,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( msg.type = TDLS_NOTIFY_STA_DISCONNECTION; scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - tdls_notice("Exit "); + tdls_debug("Exit "); return QDF_STATUS_SUCCESS; } @@ -696,7 +696,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( return QDF_STATUS_E_NULL_VALUE; } - tdls_notice("Enter "); + tdls_debug("Enter "); set_mode = qdf_mem_malloc(sizeof(*set_mode)); if (!set_mode) @@ -712,7 +712,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( msg.type = TDLS_CMD_SET_TDLS_MODE; scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - tdls_notice("Exit "); + tdls_debug("Exit "); return QDF_STATUS_SUCCESS; } From 067cd3e3ebb554f4e5957f38bcf5af060f6b00d0 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 14 Dec 2017 17:56:04 +0530 Subject: [PATCH 178/404] qcacmn: Set passive dwell time Set passive dwell time to 28msecs for active scan when bt a2dp is enabled and hw is not dbs capable and when sta is connected on 2G band. Change-Id: I44f2e3d98f2d7ddc52e4902ba989131c256da4ef CRs-Fixed: 2160963 --- inc/wlan_policy_mgr_api.h | 7 +++++++ src/wlan_policy_mgr_get_set_utils.c | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 7347880dce2a..f9160f93003a 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2198,4 +2198,11 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( */ bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_is_sta_connected_2g() - check if sta connected in 2g + * @psoc: pointer to soc + * + * Return: true if sta is connected in 2g else false + */ +bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 50d8a3f6a4b9..e5ac3c384e39 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2740,3 +2740,27 @@ bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( return status; } + +bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t conn_index; + bool ret = false; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return ret; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (pm_conc_connection_list[conn_index].mode == PM_STA_MODE && + pm_conc_connection_list[conn_index].chan <= 14 && + pm_conc_connection_list[conn_index].in_use) + ret = true; + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return ret; +} From 3488bf405fd795541a715df3628b99284d6309b3 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 8 Dec 2017 14:02:51 +0800 Subject: [PATCH 179/404] qcacmn: Cancel ROC if cancel tx MGMT It do not cancel the roc for tx MGMT frame, then wait this ROC timeout even if the next off channel tx is coming. This affact WLAN DPP test. Change-Id: Iffdef35d137485d7b17b3671e6bbe35a228b0893 CRs-Fixed: 2155852 --- core/src/wlan_p2p_off_chan_tx.c | 16 ++++++++ core/src/wlan_p2p_roc.c | 66 ++++++++++++++++++++++----------- core/src/wlan_p2p_roc.h | 18 ++++++++- 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 0b6b6d249f9a..51c57f796ed7 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -972,6 +972,7 @@ static QDF_STATUS p2p_roc_req_for_tx_action( roc_ctx->duration = tx_ctx->duration; roc_ctx->roc_state = ROC_STATE_IDLE; roc_ctx->roc_type = OFF_CHANNEL_TX; + roc_ctx->tx_ctx = tx_ctx; tx_ctx->roc_cookie = (uintptr_t)roc_ctx; p2p_debug("create roc request for off channel tx, tx ctx:%pK, roc ctx:%pK", @@ -1667,6 +1668,7 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) ROC_STATE_CANCEL_IN_PROG) { p2p_adjust_tx_wait(tx_ctx); status = p2p_restart_roc_timer(curr_roc_ctx); + curr_roc_ctx->tx_ctx = tx_ctx; if (status != QDF_STATUS_SUCCESS) { p2p_err("restart roc timer fail"); goto fail; @@ -1702,6 +1704,7 @@ QDF_STATUS p2p_process_mgmt_tx_cancel( bool is_roc_q = false; bool is_ack_q = false; struct tx_action_context *cur_tx_ctx; + struct p2p_roc_context *cur_roc_ctx; struct cancel_roc_context cancel_roc; p2p_debug("cookie:0x%llx", cancel_tx->cookie); @@ -1724,6 +1727,19 @@ QDF_STATUS p2p_process_mgmt_tx_cancel( } else { p2p_debug("Failed to find tx ctx by cookie, cookie %llx", cancel_tx->cookie); + + cur_roc_ctx = p2p_find_roc_by_tx_ctx(cancel_tx->p2p_soc_obj, + cancel_tx->cookie); + if (cur_roc_ctx) { + p2p_debug("tx ctx:%llx, roc:%pK", + cancel_tx->cookie, cur_roc_ctx); + cancel_roc.p2p_soc_obj = + cancel_tx->p2p_soc_obj; + cancel_roc.cookie = (uintptr_t) cur_roc_ctx; + return p2p_process_cancel_roc_req(&cancel_roc); + } + + p2p_debug("Failed to find roc by tx ctx"); return QDF_STATUS_E_INVAL; } diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index a6eff6ed87cf..44ea9dac8953 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -184,9 +184,9 @@ static QDF_STATUS p2p_execute_cancel_roc_req( QDF_STATUS status; struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); @@ -231,9 +231,9 @@ static void p2p_roc_timeout(void *pdata) return; } - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); @@ -338,9 +338,9 @@ static QDF_STATUS p2p_execute_roc_req(struct p2p_roc_context *roc_ctx) uint32_t go_num; struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); @@ -458,9 +458,9 @@ static QDF_STATUS p2p_process_ready_on_channel_evt( p2p_soc_obj = roc_ctx->p2p_soc_obj; roc_ctx->roc_state = ROC_STATE_ON_CHAN; - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); @@ -498,9 +498,9 @@ static QDF_STATUS p2p_process_scan_complete_evt( uint32_t size; struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); @@ -582,12 +582,12 @@ struct p2p_roc_context *p2p_find_current_roc_ctx( struct p2p_roc_context, node); if (roc_ctx->roc_state != ROC_STATE_IDLE) { p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id" - ":%d, scan_id:%d, cookie:%llx, chan:" + ":%d, scan_id:%d, tx ctx:%pK, chan:" "%d, phy_mode:%d, duration:%d, " "roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, - roc_ctx->cookie, roc_ctx->chan, + roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); @@ -600,6 +600,28 @@ struct p2p_roc_context *p2p_find_current_roc_ctx( return NULL; } +struct p2p_roc_context *p2p_find_roc_by_tx_ctx( + struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie) +{ + struct p2p_roc_context *curr_roc_ctx; + qdf_list_node_t *p_node; + QDF_STATUS status; + + p2p_debug("p2p soc obj:%pK, cookie:%llx", p2p_soc_obj, cookie); + + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_roc_ctx = qdf_container_of(p_node, + struct p2p_roc_context, node); + if ((uintptr_t) curr_roc_ctx->tx_ctx == cookie) + return curr_roc_ctx; + status = qdf_list_peek_next(&p2p_soc_obj->roc_q, + p_node, &p_node); + } + + return NULL; +} + QDF_STATUS p2p_restart_roc_timer(struct p2p_roc_context *roc_ctx) { QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -636,10 +658,10 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, - roc_ctx->cookie, roc_ctx->chan, + roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); status = qdf_list_peek_next(&p2p_soc_obj->roc_q, @@ -663,9 +685,9 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx_ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); @@ -700,10 +722,10 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, - roc_ctx->cookie, roc_ctx->chan, + roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); status = qdf_list_peek_next(&p2p_soc_obj->roc_q, @@ -727,9 +749,9 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); @@ -760,9 +782,9 @@ QDF_STATUS p2p_process_roc_req(struct p2p_roc_context *roc_ctx) p2p_soc_obj = roc_ctx->p2p_soc_obj; - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, cookie:%llx, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx_ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->cookie, roc_ctx->chan, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, roc_ctx->roc_type, roc_ctx->roc_state); diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index 2e8d14a18be7..21863e996ae9 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -77,7 +77,7 @@ enum roc_state { * @p2p_soc_obj: Pointer to SoC global p2p private object * @vdev_id: Vdev id on which this request has come * @scan_id: Scan id given by scan component for this roc req - * @cookie: Cookie which is given to supplicant for this roc req + * @tx_ctx: TX context if this ROC is for tx MGMT * @chan: Chan for which this RoC has been requested * @phy_mode: PHY mode * @duration: Duration for the RoC @@ -90,7 +90,7 @@ struct p2p_roc_context { struct p2p_soc_priv_obj *p2p_soc_obj; uint32_t vdev_id; uint32_t scan_id; - uint64_t cookie; + void *tx_ctx; uint8_t chan; uint8_t phy_mode; uint32_t duration; @@ -135,6 +135,20 @@ QDF_STATUS p2p_mgmt_rx_action_ops(struct wlan_objmgr_psoc *psoc, struct p2p_roc_context *p2p_find_current_roc_ctx( struct p2p_soc_priv_obj *p2p_soc_obj); +/** + * p2p_find_roc_by_tx_ctx() - Find out roc context by tx context + * @p2p_soc_obj: p2p psoc private object + * @cookie: cookie is the key to find out roc context + * + * This function find out roc context by tx context from p2p psoc + * private object + * + * Return: Pointer to roc context - success + * NULL - failure + */ +struct p2p_roc_context *p2p_find_roc_by_tx_ctx( + struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie); + /** * p2p_restart_roc_timer() - Restarts roc timer * @roc_ctx: remain on channel context From 17623642ea50ef76c55af78424c4a20f85ed561f Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 28 Dec 2017 11:31:57 +0530 Subject: [PATCH 180/404] qcacmn: Initialize pcl length to 0 in cds_get_alternate_channel_for_sap When number of connections is more than 2 then the pcl length will be garbage value. Initialize the pcl length with 0 to avoid wrong channel list initialization. Change-Id: If08dc2670ff5ff296220d6ad68766becb252fab7 CRs-Fixed: 2164773 --- src/wlan_policy_mgr_pcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 11a4b32598e5..a8118a10a151 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1706,7 +1706,7 @@ uint8_t policy_mgr_get_alternate_channel_for_sap( uint8_t pcl_channels[QDF_MAX_NUM_CHAN]; uint8_t pcl_weight[QDF_MAX_NUM_CHAN]; uint8_t channel = 0; - uint32_t pcl_len; + uint32_t pcl_len = 0; if (QDF_STATUS_SUCCESS == policy_mgr_get_pcl(psoc, PM_SAP_MODE, &pcl_channels[0], &pcl_len, From 3b9ff3715afd9d2bed0c0eaa6f019a5760eb168d Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 27 Dec 2017 13:57:24 -0800 Subject: [PATCH 181/404] qcacmn: Keep HW mode in sync with FW when hdd stop happens Stop the opportunistic timer & take action to keep HW mode in sync when hdd stop happens. Change-Id: Id34adb579987605831d2c7c4e22c2d76fe7d25dd CRs-Fixed: 2165109 --- inc/wlan_policy_mgr_api.h | 13 ++++++++- src/wlan_policy_mgr_action.c | 44 +++++++++++++++++++++++++++++-- src/wlan_policy_mgr_core.c | 16 +++++++++-- src/wlan_policy_mgr_i.h | 3 +++ src/wlan_policy_mgr_init_deinit.c | 14 ++++++++++ 5 files changed, 85 insertions(+), 5 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index f9160f93003a..4b77fca93dcd 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1079,6 +1079,16 @@ QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc); */ QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_set_opportunistic_update() - Set opportunistic + * update event + * @psoc: PSOC object information + * Sets the opportunistic update event + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_restart_opportunistic_timer() - Restarts opportunistic timer * @psoc: PSOC object information @@ -2163,6 +2173,7 @@ uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc); * state of opportunistic timer, if running, stop it and take * action * @psoc: soc pointer + * @id: Session/vdev id * * Get the current state of opportunistic timer, if it is * running, stop it and take action. @@ -2170,7 +2181,7 @@ uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc); * Return: None */ void policy_mgr_check_and_stop_opportunistic_timer( - struct wlan_objmgr_psoc *psoc); + struct wlan_objmgr_psoc *psoc, uint8_t id); /** * policy_mgr_set_weight_of_dfs_passive_channels_to_zero() - set weight of dfs diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 607d1b0ef977..7e57b359ef08 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -995,6 +995,28 @@ QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *policy_mgr_context; + + policy_mgr_context = policy_mgr_get_context(psoc); + if (!policy_mgr_context) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + status = qdf_event_set( + &policy_mgr_context->opportunistic_update_done_evt); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("set event failed"); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_restart_opportunistic_timer( struct wlan_objmgr_psoc *psoc, bool check_state) { @@ -1103,9 +1125,11 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( } void policy_mgr_check_and_stop_opportunistic_timer( - struct wlan_objmgr_psoc *psoc) + struct wlan_objmgr_psoc *psoc, uint8_t id) { struct policy_mgr_psoc_priv_obj *pm_ctx; + enum policy_mgr_conc_next_action action = PM_NOP; + QDF_STATUS status = QDF_STATUS_E_FAILURE; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1115,7 +1139,23 @@ void policy_mgr_check_and_stop_opportunistic_timer( if (QDF_TIMER_STATE_RUNNING == pm_ctx->dbs_opportunistic_timer.state) { qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); - pm_dbs_opportunistic_timer_handler((void *)psoc); + action = policy_mgr_need_opportunistic_upgrade(psoc); + if (action) { + status = policy_mgr_next_actions(psoc, id, action, + POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed in policy_mgr_next_actions"); + return; + } + status = qdf_wait_single_event( + &pm_ctx->opportunistic_update_done_evt, + CONNECTION_UPDATE_TIMEOUT); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("wait for event failed"); + return; + } + } } } diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index c707cdac8a04..9ff2bb4db803 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -811,8 +811,12 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, if (PM_NOP != next_action) policy_mgr_next_actions(context, session_id, next_action, reason); - else + else { policy_mgr_debug("No action needed right now"); + ret = policy_mgr_set_opportunistic_update(context); + if (!QDF_IS_STATUS_SUCCESS(ret)) + policy_mgr_err("ERROR: set opportunistic_update event failed"); + } return; } @@ -2379,6 +2383,7 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, enum policy_mgr_conn_update_reason reason) { uint32_t conn_index = 0; + QDF_STATUS ret; if (QDF_STATUS_SUCCESS != tx_status) policy_mgr_err("nss update failed(%d) for vdev %d", @@ -2394,7 +2399,14 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, } policy_mgr_debug("nss update successful for vdev:%d", vdev_id); - policy_mgr_next_actions(psoc, vdev_id, next_action, reason); + if (PM_NOP != next_action) + policy_mgr_next_actions(psoc, vdev_id, next_action, reason); + else { + policy_mgr_debug("No action needed right now"); + ret = policy_mgr_set_opportunistic_update(psoc); + if (!QDF_IS_STATUS_SUCCESS(ret)) + policy_mgr_err("ERROR: set opportunistic_update event failed"); + } return; } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 16d38fabddfe..e8b21092a4c2 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -239,6 +239,8 @@ struct sta_ap_intf_check_work_ctx { * @unsafe_channel_list: LTE coex channel avoidance list * @unsafe_channel_count: LTE coex channel avoidance list count * @sta_ap_intf_check_work_info: Info related to sta_ap_intf_check_work + * @opportunistic_update_done_evt: qdf event to synchronize host + * & FW HW mode */ struct policy_mgr_psoc_priv_obj { struct wlan_objmgr_psoc *psoc; @@ -272,6 +274,7 @@ struct policy_mgr_psoc_priv_obj { struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info; uint8_t cur_conc_system_pref; uint8_t sta_sap_scc_on_dfs_chan_allowed; + qdf_event_t opportunistic_update_done_evt; }; /** diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 08513de35abd..74f9e54892a5 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -406,6 +406,12 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) return status; } + status = qdf_event_create(&pm_ctx->opportunistic_update_done_evt); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("opportunistic_update_done_evt init failed"); + return status; + } + pm_ctx->do_hw_mode_change = false; pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; /* reset sap mandatory channels */ @@ -473,6 +479,14 @@ QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc) QDF_ASSERT(0); } + /* destroy opportunistic_update_done_evt */ + if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy + (&pm_ctx->opportunistic_update_done_evt))) { + policy_mgr_err("Failed to destroy opportunistic_update_done_evt"); + status = QDF_STATUS_E_FAILURE; + QDF_ASSERT(0); + } + /* deallocate dbs_opportunistic_timer */ if (QDF_TIMER_STATE_RUNNING == qdf_mc_timer_get_current_state( From 27f023ad5942794cf700d596d68b21e80c36457a Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Thu, 4 Jan 2018 16:25:06 -0800 Subject: [PATCH 182/404] qcacmn: Fix potential NULL dereference in P2P 1) Check for validity of ps_config before dereferencing. 2) Check for validity of lo_start before dereferencing. 3) Initialize tmp_p2p_ie before using it. Change-Id: I4cd5bcb025e63d727e5535921a4e4121d618ee36 CRs-Fixed: 2160760 --- core/src/wlan_p2p_off_chan_tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 51c57f796ed7..2a7bf48a9d9d 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.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 @@ -142,7 +142,7 @@ static const uint8_t *p2p_get_p2pie_from_probe_rsp( { const uint8_t *ie; const uint8_t *p2p_ie; - const uint8_t *tmp_p2p_ie; + const uint8_t *tmp_p2p_ie = NULL; uint16_t ie_len; if (tx_ctx->buf_len <= PROBE_RSP_IE_OFFSET) { From 21399d2a8e99627156352401c9f747af1791cf4a Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Thu, 4 Jan 2018 16:25:06 -0800 Subject: [PATCH 183/404] qcacmn: Fix potential NULL dereference in P2P 1) Check for validity of ps_config before dereferencing. 2) Check for validity of lo_start before dereferencing. 3) Initialize tmp_p2p_ie before using it. Change-Id: I4cd5bcb025e63d727e5535921a4e4121d618ee36 CRs-Fixed: 2160760 --- src/target_if_p2p.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index 5f03401c389c..000a91758692 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.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 @@ -260,9 +260,6 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, QDF_STATUS status; wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%pK, vdev_id:%d, opp_ps:%d", psoc, - ps_config->vdev_id, ps_config->opp_ps); - if (!wmi_handle) { target_if_err("Invalid wmi handle"); return QDF_STATUS_E_INVAL; @@ -273,6 +270,9 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_INVAL; } + target_if_debug("psoc:%pK, vdev_id:%d, opp_ps:%d", psoc, + ps_config->vdev_id, ps_config->opp_ps); + cmd.opp_ps = ps_config->opp_ps; cmd.ctwindow = ps_config->ct_window; cmd.count = ps_config->count; @@ -301,8 +301,6 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, { wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); - target_if_debug("psoc:%pK, vdev_id:%d", psoc, lo_start->vdev_id); - if (!wmi_handle) { target_if_err("Invalid wmi handle"); return QDF_STATUS_E_INVAL; @@ -312,6 +310,7 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, target_if_err("lo start parameters is null"); return QDF_STATUS_E_INVAL; } + target_if_debug("psoc:%pK, vdev_id:%d", psoc, lo_start->vdev_id); return wmi_unified_p2p_lo_start_cmd(wmi_handle, lo_start); } From e23b6bc5fcf51d176d1dd868630ac244dcc19491 Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Mon, 8 Jan 2018 13:18:41 -0800 Subject: [PATCH 184/404] qcacmn: Fix static analysis issues in policy manager 1) Check for policy manager context to be non NULL before dereferncing and return if it is NULL. 2) Use QDF_MAX_NUM_CHAN consistently to represent the maximum number of channels supported. Change-Id: I3393bc801dd780d881423c8be346e74ac6d3ac6c CRs-Fixed: 2160770 --- src/wlan_policy_mgr_action.c | 4 ++-- src/wlan_policy_mgr_get_set_utils.c | 6 ++++-- src/wlan_policy_mgr_pcl.c | 11 ++++++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 7e57b359ef08..5e8031115551 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -432,7 +432,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, { QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_hw_mode_params hw_mode; - struct dbs_nss nss_dbs; + struct dbs_nss nss_dbs = {0}; if (policy_mgr_is_hw_dbs_capable(psoc) == false) { policy_mgr_err("driver isn't dbs capable, no further action needed"); diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index e5ac3c384e39..d477600da5df 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2580,8 +2580,10 @@ uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, struct policy_mgr_psoc_priv_obj *pm_ctx; pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) + if (!pm_ctx) { policy_mgr_err("Invalid Context"); + return final_max_rf_chains; + } for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { param = pm_ctx->hw_mode.hw_mode_list[i]; diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index a8118a10a151..ce627c690a70 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -171,9 +171,14 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, return; } + /* + * The ch_list buffer can accomadate a maximum of + * NUM_CHANNELS and hence the ch_cnt should also not + * exceed NUM_CHANNELS. + */ pm_ctx->unsafe_channel_count = avoid_freq_ind->chan_list.ch_cnt >= - QDF_MAX_NUM_CHAN ? - QDF_MAX_NUM_CHAN : avoid_freq_ind->chan_list.ch_cnt; + NUM_CHANNELS ? + NUM_CHANNELS : avoid_freq_ind->chan_list.ch_cnt; if (pm_ctx->unsafe_channel_count) qdf_mem_copy(pm_ctx->unsafe_channel_list, avoid_freq_ind->chan_list.ch_list, From 0c738b7b020f435cdf5d16aa03d37bafdb926465 Mon Sep 17 00:00:00 2001 From: Himanshu Agarwal Date: Wed, 10 Jan 2018 14:21:53 +0530 Subject: [PATCH 185/404] qcacmn: Green AP UMAC componentization Add APIs, structures for Green AP component. Change-Id: I4a39470104c89c20eec5440b7ae251a764151fd5 CRs-Fixed: 2166428 --- inc/wlan_policy_mgr_api.h | 15 ++++++++++++++- src/wlan_policy_mgr_get_set_utils.c | 16 ++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 4b77fca93dcd..493b6fef2bea 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -970,6 +970,19 @@ QDF_STATUS policy_mgr_get_channel_from_scan_result( struct wlan_objmgr_psoc *psoc, void *roam_profile, uint8_t *channel); +/** + * policy_mgr_mode_specific_num_open_sessions() - to get number of open sessions + * for a specific mode + * @psoc: PSOC object information + * @mode: device mode + * @num_sessions: to store num open sessions + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_mode_specific_num_open_sessions( + struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, + uint8_t *num_sessions); + /** * policy_mgr_concurrent_open_sessions_running() - Checks for * concurrent open session diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index d477600da5df..33483e045839 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2053,6 +2053,22 @@ enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( return mode; } +QDF_STATUS policy_mgr_mode_specific_num_open_sessions( + struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, + uint8_t *num_sessions) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + *num_sessions = pm_ctx->no_of_open_sessions[mode]; + return QDF_STATUS_SUCCESS; +} + /** * policy_mgr_concurrent_open_sessions_running() - Checks for * concurrent open session From 4943b90122827fd9034fe982c104d618360f310d Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Fri, 5 Jan 2018 17:36:40 -0800 Subject: [PATCH 186/404] qcacmn: Choose opportunistic timer's session id dynamically Current opportunistic timer chooses session id as 0 up on expiry which creates the issue when session id 0 doesn't exist. Fix the situation by dynamically choosing existing session id to complete the action. CRs-Fixed: 2166667 Change-Id: I2e1da2ba0078381a5e91decd32d32b8ad77cec19 --- src/wlan_policy_mgr_action.c | 1 + src/wlan_policy_mgr_core.c | 44 ++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 5e8031115551..13c4d6c817e3 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1141,6 +1141,7 @@ void policy_mgr_check_and_stop_opportunistic_timer( qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); action = policy_mgr_need_opportunistic_upgrade(psoc); if (action) { + qdf_event_reset(&pm_ctx->opportunistic_update_done_evt); status = policy_mgr_next_actions(psoc, id, action, POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC); if (status != QDF_STATUS_SUCCESS) { diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 9ff2bb4db803..085d379863ff 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1250,6 +1250,35 @@ void policy_mgr_set_pcl_for_existing_combo( qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } +static uint32_t pm_get_vdev_id_of_first_conn_idx(struct wlan_objmgr_psoc *psoc) +{ + uint32_t conn_index = 0, vdev_id = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return conn_index; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (pm_conc_connection_list[conn_index].in_use) { + vdev_id = pm_conc_connection_list[conn_index].vdev_id; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + if (conn_index == MAX_NUMBER_OF_CONC_CONNECTIONS) + policy_mgr_debug("Use default vdev_id:%d for opportunistic upgrade", + vdev_id); + else + policy_mgr_debug("Use vdev_id:%d for opportunistic upgrade", + vdev_id); + + return vdev_id; +} + /** * pm_dbs_opportunistic_timer_handler() - handler of * dbs_opportunistic_timer @@ -1262,6 +1291,7 @@ void policy_mgr_set_pcl_for_existing_combo( void pm_dbs_opportunistic_timer_handler(void *data) { enum policy_mgr_conc_next_action action = PM_NOP; + uint32_t session_id; struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)data; if (!psoc) { @@ -1272,15 +1302,11 @@ void pm_dbs_opportunistic_timer_handler(void *data) /* if we still need it */ action = policy_mgr_need_opportunistic_upgrade(psoc); policy_mgr_debug("action:%d", action); - if (action) { - /* lets call for action */ - /* session id is being used only - * in hidden ssid case for now. - * So, session id 0 is ok here. - */ - policy_mgr_next_actions(psoc, 0, action, + if (!action) + return; + session_id = pm_get_vdev_id_of_first_conn_idx(psoc); + policy_mgr_next_actions(psoc, session_id, action, POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC); - } } /** From 7728e21cf93579c57e9bc9b9b225844b2ed6327e Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Tue, 9 Jan 2018 11:00:28 -0800 Subject: [PATCH 187/404] qcacmn: Check pcl array size against QDF_MAX_NUM_CHAN While populating preferred channel list array, length has not been checked against QDF_MAX_NUM_CHAN which is size of PCL. Fix it by checking indices and length against QDF_MAX_NUM_CHAN CRs-Fixed: 2169424 Change-Id: I8c4d050bfc7040fba052eb42b32a91302a0a0ecb --- src/wlan_policy_mgr_pcl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index ce627c690a70..74f86baa2dd0 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1540,6 +1540,10 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( for (i = 0; i < *pcl_len_org; i++) { found = false; + if (i >= QDF_MAX_NUM_CHAN) { + policy_mgr_debug("index is exceeding QDF_MAX_NUM_CHAN"); + break; + } for (j = 0; j < pm_ctx->sap_mandatory_channels_len; j++) { if (pcl_list_org[i] == pm_ctx->sap_mandatory_channels[j]) { @@ -1547,7 +1551,7 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( break; } } - if (found) { + if (found && (pcl_len < QDF_MAX_NUM_CHAN)) { pcl_list[pcl_len] = pcl_list_org[i]; weight_list[pcl_len++] = weight_list_org[i]; } From 90b989b050db6c079652ae238d1189442b884063 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 10 Jan 2018 13:46:50 +0800 Subject: [PATCH 188/404] qcacmn: Fix tdls KW issues Fix static code analysis issues in tdls component: NULL pointer dereference - tdls_process_antenna_switch - tdls_antenna_switch_flush_callback - tdls_indicate_teardown - ucfg_tdls_notify_sta_connect - ucfg_tdls_notify_sta_disconnect - ucfg_tdls_set_operating_mode Change-Id: I3bb72658dcd3116f6f64da15a7039f49157a0f3f CRs-Fixed: 2169736 --- core/src/wlan_tdls_cmds_process.c | 20 ++++++++++++-------- core/src/wlan_tdls_ct.c | 13 +++++++++---- dispatcher/src/wlan_tdls_ucfg_api.c | 11 ++++------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index e934f4f49a0e..96195335374f 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.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 @@ -2249,16 +2249,18 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) struct tdls_osif_indication ind; if (!req || !req->vdev) { - tdls_err("req: %p", req); - status = QDF_STATUS_E_INVAL; - goto error; + tdls_err("Invalid input params req: %p", req); + if (req) + qdf_mem_free(req); + + return QDF_STATUS_E_INVAL; } vdev = req->vdev; status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get vdev_obj & soc_obj"); - goto error; + goto get_obj_err; } if (soc_obj->connected_peer_count == 0) @@ -2267,7 +2269,7 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) if (soc_obj->tdls_nss_switch_in_progress) { if (!soc_obj->tdls_nss_teardown_complete) { tdls_err("TDLS antenna switch is in progress"); - goto error; + goto ant_sw_in_progress; } else { goto ant_sw_done; } @@ -2291,7 +2293,7 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) if (tdls_teardown_links(soc_obj, req->mode) == 0) goto ant_sw_done; -error: +ant_sw_in_progress: ant_switch_state = -EAGAIN; ant_sw_done: if (soc_obj->tdls_event_cb) { @@ -2310,8 +2312,10 @@ ant_sw_done: soc_obj->tdls_nss_switch_in_progress, soc_obj->tdls_nss_teardown_complete); +get_obj_err: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); qdf_mem_free(req); + return status; } @@ -2320,7 +2324,7 @@ QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg) struct tdls_antenna_switch_request *req; if (!msg || !msg->bodyptr) { - tdls_err("msg: 0x%pK, bodyptr: 0x%pK", msg, msg->bodyptr); + tdls_err("msg: 0x%pK", msg); return QDF_STATUS_E_NULL_VALUE; } req = msg->bodyptr; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 3e9e70eb77dd..e55bea3727ad 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.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 @@ -509,10 +509,15 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, struct tdls_soc_priv_obj *tdls_soc; struct tdls_osif_indication indication; + if (!tdls_vdev || !curr_peer) { + tdls_err("tdls_vdev: %pK, curr_peer: %pK", + tdls_vdev, curr_peer); + return; + } + tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); - if (!tdls_soc || !tdls_vdev || !curr_peer) { - tdls_err("tdls_soc: %pK, tdls_vdev: %pK, curr_peer: %pK", - tdls_soc, tdls_vdev, curr_peer); + if (!tdls_soc) { + tdls_err("tdls_soc: %pK", tdls_soc); return; } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 7c5d9ad619ed..583b8c53ee21 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.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 @@ -624,8 +624,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( struct tdls_sta_notify_params *notify; if (!notify_info || !notify_info->vdev) { - tdls_err("notify_info->vdev: %pK, notify_info %pK", - notify_info->vdev, notify_info); + tdls_err("notify_info %pK", notify_info); return QDF_STATUS_E_NULL_VALUE; } tdls_debug("Enter "); @@ -656,8 +655,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( struct tdls_sta_notify_params *notify; if (!notify_info || !notify_info->vdev) { - tdls_err("notify_info->vdev: %pK, notify_info %pK", - notify_info->vdev, notify_info); + tdls_err("notify_info %pK", notify_info); return QDF_STATUS_E_NULL_VALUE; } @@ -691,8 +689,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( struct tdls_set_mode_params *set_mode; if (!set_mode_params || !set_mode_params->vdev) { - tdls_err("vdev: %pK, set_mode_params %pK", - set_mode_params->vdev, set_mode_params); + tdls_err("set_mode_params %pK", set_mode_params); return QDF_STATUS_E_NULL_VALUE; } From 93667779c82255469d932e01b0681c3a1cc36b95 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 16 Jan 2018 01:52:25 -0800 Subject: [PATCH 189/404] qcacmn: Fix TDLS wpa2 teardown failures TDLS teardown request from the DUT is dropped in the peer, due to invalid MIC in the teardown frame. TDLS responder value is not set correctly in TDLS teardown frame, and it causes MIC failures in the peer device. Set the correct responder value in TDLS teardown frame. Change-Id: Ibe056c89f644c094a10f7a5eb51b6d90a13a4a01 CRs-Fixed: 2155555 --- core/src/wlan_tdls_mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index c7582196e884..8dfae9f15fee 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.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 @@ -386,7 +386,7 @@ QDF_STATUS tdls_process_mgmt_req( * after the cmd validation */ tdls_mgmt_req->tdls_mgmt.responder = - tdls_mgmt_req->chk_frame->responder; + !tdls_mgmt_req->chk_frame->responder; tdls_mgmt_req->tdls_mgmt.status_code = tdls_mgmt_req->chk_frame->status_code; From e93f5d1b348c6994acd2c87a7ea6be0db122183f Mon Sep 17 00:00:00 2001 From: Will Huang Date: Mon, 8 Jan 2018 18:23:56 +0800 Subject: [PATCH 190/404] qcacmn: Fix copy length error of unsafe_channel_list unsafe_channel_list is defined as uint16, but copy with length of byte. Change-Id: I35cd1d006f561c6bb1e64fd56e9822fefd991848 CRs-Fixed: 2170439 --- src/wlan_policy_mgr_pcl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 74f86baa2dd0..481107a1e91b 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -182,7 +182,8 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, if (pm_ctx->unsafe_channel_count) qdf_mem_copy(pm_ctx->unsafe_channel_list, avoid_freq_ind->chan_list.ch_list, - pm_ctx->unsafe_channel_count); + pm_ctx->unsafe_channel_count * + sizeof(pm_ctx->unsafe_channel_list[0])); policy_mgr_debug("Channel list update, recieved %d avoided channels", pm_ctx->unsafe_channel_count); } From ab13769063f8998102b7bdefa741a4723b413fb6 Mon Sep 17 00:00:00 2001 From: Zhu Jianmin Date: Tue, 9 Jan 2018 12:49:35 +0800 Subject: [PATCH 191/404] qcacmn: Avoid using tdls_soc_obj after it has been freed Object tdls_soc_obj is being used ever after it has been freed which creates stability issue. Fix it by returning up on releasing the memory. Change-Id: I0b3faf2435396f2e3cd92bc18afc263f3280eae3 CRs-Fixed: 2164332 --- core/src/wlan_tdls_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index fc1817bcde97..7e447d3eba53 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.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 @@ -61,6 +61,7 @@ QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, if (QDF_IS_STATUS_ERROR(status)) { tdls_err("Failed to attach psoc tdls component"); qdf_mem_free(tdls_soc_obj); + return status; } tdls_soc_global = tdls_soc_obj; @@ -88,7 +89,6 @@ QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, if (QDF_IS_STATUS_ERROR(status)) tdls_err("Failed to detach psoc tdls component"); - qdf_mem_free(tdls_soc_obj); return status; From 76659b0055a48ea1ef3ff4212ac4a8fd10115056 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Thu, 28 Dec 2017 00:34:42 -0500 Subject: [PATCH 192/404] qcacmn: Disallow Dualband MCC For non DBS capable chip, to disallow dualband MCC in case dnbs vdev exist. Change-Id: Iee96e12dbb09e2d4633ca2fb73b5fb8bf155bd66 CRs-Fixed: 2164835 --- src/wlan_policy_mgr_get_set_utils.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 33483e045839..41a9a8025028 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2561,8 +2561,10 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, * return true. * If channel is different from operating channel but in same band. * return false. - * If operating channel in different band. + * If operating channel in different band (DBS capable). * return true. + * If operating channel in different band (not DBS capable). + * return false. */ /* TODO: To be enhanced for SBS */ if (policy_mgr_is_dnsc_set(vdev)) { @@ -2577,12 +2579,24 @@ QDF_STATUS policy_mgr_is_chan_ok_for_dnbs(struct wlan_objmgr_psoc *psoc, wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); break; + } else if (policy_mgr_is_hw_dbs_capable(psoc)) { + *ok = true; + wlan_objmgr_vdev_release_ref(vdev, + WLAN_POLICY_MGR_ID); + break; + } else { + *ok = false; + wlan_objmgr_vdev_release_ref(vdev, + WLAN_POLICY_MGR_ID); + break; } } else { *ok = true; } wlan_objmgr_vdev_release_ref(vdev, WLAN_POLICY_MGR_ID); } + policy_mgr_debug("chan: %d ok %d", channel, *ok); + return QDF_STATUS_SUCCESS; } From 0c1a7f6c69dee3b189327b702ce3f087fbb59ed7 Mon Sep 17 00:00:00 2001 From: Sourav Mohapatra Date: Sun, 3 Dec 2017 11:44:44 +0530 Subject: [PATCH 193/404] qcacmn: Converge on wmi service/ext service is enable Converge on wmi service/ext service is enable Change-Id: Ib246befa72cce927bee157394cd22c7d1562d341 CRs-Fixed: 2152751 --- inc/wlan_policy_mgr_api.h | 3 -- src/wlan_policy_mgr_get_set_utils.c | 57 ++++++++++++++++------------- src/wlan_policy_mgr_init_deinit.c | 4 +- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 493b6fef2bea..7e3c9dc532f9 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -857,13 +857,10 @@ struct policy_mgr_dp_cbacks { * from policy manager * @wma_get_connection_info: Get the connection related info * from wma table - * @wma_is_service_enabled: check if certain service is enabled - * by FW */ struct policy_mgr_wma_cbacks { QDF_STATUS (*wma_get_connection_info)(uint8_t vdev_id, struct policy_mgr_vdev_entry_info *conn_table_entry); - bool (*wma_is_service_enabled)(WMI_SERVICE service_type); }; /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 41a9a8025028..dc2588ed8ca9 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -33,7 +33,7 @@ */ /* Include files */ - +#include "target_if.h" #include "wlan_policy_mgr_api.h" #include "wlan_policy_mgr_i.h" #include "qdf_types.h" @@ -524,8 +524,10 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) { uint32_t param, i, found = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + void *wmi_handle; pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { policy_mgr_err("Invalid Context"); return false; @@ -535,19 +537,23 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) policy_mgr_debug("DBS is disabled"); return false; } - if (pm_ctx->wma_cbacks.wma_is_service_enabled) { - policy_mgr_debug("DBS service bit map: %d", - pm_ctx->wma_cbacks.wma_is_service_enabled( - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); - /* The agreement with FW is that: To know if the target is DBS - * capable, DBS needs to be supported both in the HW mode list - * and in the service ready event - */ - if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) - return false; - } else + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + if (!wmi_handle) { + policy_mgr_debug("Invalid WMA context"); + return false; + } + + policy_mgr_debug("DBS service bit map: %d", + wmi_service_enabled(wmi_handle, + wmi_service_dual_band_simultaneous_support)); + + /* The agreement with FW is that: To know if the target is DBS + * capable, DBS needs to be supported both in the HW mode list + * and in the service ready event + */ + if (!(wmi_service_enabled(wmi_handle, + wmi_service_dual_band_simultaneous_support))) return false; for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { @@ -570,25 +576,26 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) { uint32_t param, i, found = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + void *wmi_handle; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); return false; } - if (pm_ctx->wma_cbacks.wma_is_service_enabled) { - policy_mgr_debug("DBS service bit map: %d", - pm_ctx->wma_cbacks.wma_is_service_enabled( - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT)); - /* The agreement with FW is that: To know if the target is SBS - * capable, SBS needs to be supported both in the HW mode list - * and DBS needs to be supported in the service ready event - */ - if (!(pm_ctx->wma_cbacks.wma_is_service_enabled( - WMI_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT))) - return false; - } else + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + + policy_mgr_debug("DBS service bit map: %d", + wmi_service_enabled(wmi_handle, + wmi_service_dual_band_simultaneous_support)); + + /* The agreement with FW is that: To know if the target is SBS + * capable, SBS needs to be supported both in the HW mode list + * and DBS needs to be supported in the service ready event + */ + if (!(wmi_service_enabled(wmi_handle, + wmi_service_dual_band_simultaneous_support))) return false; for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 74f9e54892a5..44bde60ec7f5 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -610,8 +610,6 @@ QDF_STATUS policy_mgr_register_wma_cb(struct wlan_objmgr_psoc *psoc, pm_ctx->wma_cbacks.wma_get_connection_info = wma_cbacks->wma_get_connection_info; - pm_ctx->wma_cbacks.wma_is_service_enabled = - wma_cbacks->wma_is_service_enabled; return QDF_STATUS_SUCCESS; } From e52f36ef361bb87d2c15861209f915d6ef419c1f Mon Sep 17 00:00:00 2001 From: Sourav Mohapatra Date: Sun, 3 Dec 2017 11:44:44 +0530 Subject: [PATCH 194/404] qcacmn: Converge on wmi service/ext service is enable Converge on wmi service/ext service is enable Change-Id: Ib246befa72cce927bee157394cd22c7d1562d341 CRs-Fixed: 2152751 --- src/target_if_tdls.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/target_if_tdls.c b/src/target_if_tdls.c index cff486f375ad..e0a0ef23f916 100644 --- a/src/target_if_tdls.c +++ b/src/target_if_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 @@ -122,11 +122,12 @@ target_if_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, struct sta_uapsd_trig_params *params) { QDF_STATUS ret; + wmi_unified_t wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); - if (!WMI_SERVICE_IS_ENABLED(psoc->service_param.service_bitmap, - WMI_STA_UAPSD_BASIC_AUTO_TRIG) || - !WMI_SERVICE_IS_ENABLED(psoc->service_param.service_bitmap, - WMI_STA_UAPSD_VAR_AUTO_TRIG)) { + if (!wmi_service_enabled(wmi_handle, + wmi_sta_uapsd_basic_auto_trig) || + !wmi_service_enabled(wmi_handle, + wmi_sta_uapsd_var_auto_trig)) { target_if_debug("Trigger uapsd is not supported vdev id %d", params->vdevid); return QDF_STATUS_SUCCESS; From 67427ce6e57ae905fcc30807f226f9a4d4381b21 Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Sun, 14 Jan 2018 22:13:16 -0800 Subject: [PATCH 195/404] qcacmn: tdls: Fix instances of unadorned %p Fix instances of unadorned %p in tdls. Change-Id: I5faad47ad7bdcc6f079466c277a88b5a21719e2c CRs-Fixed: 2170907 --- core/src/wlan_tdls_cmds_process.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 96195335374f..ecae73b711fc 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -2248,15 +2248,18 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) uint8_t channel; struct tdls_osif_indication ind; - if (!req || !req->vdev) { - tdls_err("Invalid input params req: %p", req); - if (req) - qdf_mem_free(req); - + if (!req) { + tdls_err("null req"); return QDF_STATUS_E_INVAL; } vdev = req->vdev; + if (!vdev) { + tdls_err("null vdev"); + qdf_mem_free(req); + return QDF_STATUS_E_INVAL; + } + status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get vdev_obj & soc_obj"); From c5b104351d46abec33595752726199744efdbee9 Mon Sep 17 00:00:00 2001 From: Min Liu Date: Fri, 19 Jan 2018 18:01:44 +0800 Subject: [PATCH 196/404] qcacmn: Fix safe channel switch failure For the AP+AP SCC LTE-Coex case, when channel avoidance event is reported, the channel switch request for SAP will be blocked by policy manager if the target channel is different with the operating channel of the existing SAP due to the SCC policy. Need to update the logic to give higher priority to the channel avoidance request. Change-Id: Ie42bab50c1fa92e4e8df9f1b0ce8b8f4f09551b5 CRs-Fixed: 2176250 --- inc/wlan_policy_mgr_api.h | 10 +++++++--- src/wlan_policy_mgr_action.c | 6 ++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 7e3c9dc532f9..1a9c8744e6e5 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -201,6 +201,7 @@ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( * @vdev_id: Vdev id * @channel: Channel to change * @ch_width: channel width to change + * @forced: Force to switch channel, ignore SCC/MCC check * * Invoke the callback function to change SAP channel using (E)CSA * @@ -209,12 +210,14 @@ QDF_STATUS policy_mgr_change_mcc_go_beacon_interval( void policy_mgr_change_sap_channel_with_csa( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t channel, - uint32_t ch_width); + uint32_t ch_width, + bool forced); #else static inline void policy_mgr_change_sap_channel_with_csa( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t channel, - uint32_t ch_width) + uint32_t ch_width, + bool forced) { } @@ -809,7 +812,8 @@ struct policy_mgr_sme_cbacks { struct policy_mgr_hdd_cbacks { void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t channel, - uint32_t channel_bw); + uint32_t channel_bw, + bool forced); QDF_STATUS (*wlan_hdd_get_channel_for_sap_restart)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t *channel, diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 13c4d6c817e3..897571ecd5d7 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -904,6 +904,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( * @vdev_id: Vdev id * @channel: Channel to change * @ch_width: channel width to change + * @forced: Force to switch channel, ignore SCC/MCC check * * Invoke the callback function to change SAP channel using (E)CSA * @@ -911,7 +912,8 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( */ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint32_t channel, - uint32_t ch_width) + uint32_t ch_width, + bool forced) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -924,7 +926,7 @@ void policy_mgr_change_sap_channel_with_csa(struct wlan_objmgr_psoc *psoc, if (pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb) { policy_mgr_info("SAP change change without restart"); pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb(psoc, - vdev_id, channel, ch_width); + vdev_id, channel, ch_width, forced); } } #endif From 48467505c0a87dda7bd8ccd6152c173a8ae792b6 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 25 Jan 2018 11:46:31 -0800 Subject: [PATCH 197/404] 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 --- core/src/wlan_p2p_off_chan_tx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 2a7bf48a9d9d..7510af8977e3 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -702,9 +702,9 @@ static QDF_STATUS p2p_tx_update_connection_status( if (tx_frame_info->public_action_type != P2P_PUBLIC_ACTION_NOT_SUPPORT) - p2p_debug("%s ---> OTA to "QDF_MAC_ADDRESS_STR, - p2p_get_frame_type_str(tx_frame_info), - QDF_MAC_ADDR_ARRAY(mac_to)); + p2p_debug("%s ---> OTA to " QDF_MAC_ADDR_STR, + p2p_get_frame_type_str(tx_frame_info), + QDF_MAC_ADDR_ARRAY(mac_to)); if ((tx_frame_info->public_action_type == P2P_PUBLIC_ACTION_PROV_DIS_REQ) && @@ -746,9 +746,9 @@ static QDF_STATUS p2p_rx_update_connection_status( if (rx_frame_info->public_action_type != P2P_PUBLIC_ACTION_NOT_SUPPORT) - p2p_debug("%s <--- OTA from "QDF_MAC_ADDRESS_STR, - p2p_get_frame_type_str(rx_frame_info), - QDF_MAC_ADDR_ARRAY(mac_from)); + p2p_debug("%s <--- OTA from " QDF_MAC_ADDR_STR, + p2p_get_frame_type_str(rx_frame_info), + QDF_MAC_ADDR_ARRAY(mac_from)); if ((rx_frame_info->public_action_type == P2P_PUBLIC_ACTION_PROV_DIS_REQ) && From 759661d38d32758c622a6beec23f00e461d355e4 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 25 Jan 2018 11:46:31 -0800 Subject: [PATCH 198/404] 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 --- core/src/wlan_tdls_cmds_process.c | 70 ++++++++++++++--------------- core/src/wlan_tdls_ct.c | 31 +++++++------ core/src/wlan_tdls_main.c | 4 +- core/src/wlan_tdls_mgmt.c | 2 +- core/src/wlan_tdls_peer.c | 12 ++--- dispatcher/src/wlan_tdls_tgt_api.c | 4 +- dispatcher/src/wlan_tdls_ucfg_api.c | 2 +- 7 files changed, 62 insertions(+), 63 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index ecae73b711fc..f8622a82cf87 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -163,7 +163,7 @@ static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) qdf_mem_copy(addstareq->peermac.bytes, req->add_peer_req.peer_addr, QDF_MAC_ADDR_SIZE); - tdls_debug("for " QDF_MAC_ADDRESS_STR, + tdls_debug("for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); msg.type = soc_obj->tdls_add_sta_req; msg.bodyptr = addstareq; @@ -228,7 +228,7 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) qdf_mem_copy(delstareq->peermac.bytes, req->del_peer_req.peer_addr, QDF_MAC_ADDR_SIZE); - tdls_debug("for " QDF_MAC_ADDRESS_STR, + tdls_debug("for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(delstareq->peermac.bytes)); msg.type = soc_obj->tdls_del_sta_req; msg.bodyptr = delstareq; @@ -313,7 +313,7 @@ static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) qdf_mem_copy(&addstareq->supported_rates, update_peer->supported_rates, update_peer->supported_rates_len); - tdls_debug("for " QDF_MAC_ADDRESS_STR, + tdls_debug("for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); msg.type = soc_obj->tdls_add_sta_req; @@ -452,7 +452,7 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) peer = tdls_get_peer(vdev_obj, mac); if (!peer) { - tdls_err("peer: " QDF_MAC_ADDRESS_STR " not exist. invalid", + tdls_err("peer: " QDF_MAC_ADDR_STR " not exist. invalid", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; goto addrsp; @@ -469,7 +469,7 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) /* when others are on-going, we want to change link_status to idle */ if (tdls_is_progress(vdev_obj, mac, true)) { - tdls_notice(QDF_MAC_ADDRESS_STR " TDLS setuping. Req declined.", + tdls_notice(QDF_MAC_ADDR_STR " TDLS setuping. Req declined.", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_PERM; goto setlink; @@ -478,7 +478,7 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) /* first to check if we reached to maximum supported TDLS peer. */ curr_tdls_peers = tdls_get_connected_peer(soc_obj); if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { - tdls_err(QDF_MAC_ADDRESS_STR + tdls_err(QDF_MAC_ADDR_STR " Request declined. Current %d, Max allowed %d.", QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, soc_obj->max_num_tdls_sta); @@ -629,7 +629,7 @@ static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, * there is no harm to double-check. */ if (TDLS_SETUP_REQUEST == tdls_validate->action_code) { - tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", + tdls_err(QDF_MAC_ADDR_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), tdls_validate->action_code, tdls_soc->connected_peer_count, @@ -641,7 +641,7 @@ static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, * code to supplicant */ tdls_validate->status_code = QDF_STATUS_E_RESOURCES; - tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", + tdls_err(QDF_MAC_ADDR_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), tdls_validate->action_code, tdls_soc->connected_peer_count, @@ -690,7 +690,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) /* if tdls_mode is disabled, then decline the peer's request */ if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode || TDLS_SUPPORT_SUSPENDED == tdls_soc->tdls_current_mode) { - tdls_notice(QDF_MAC_ADDRESS_STR + tdls_notice(QDF_MAC_ADDR_STR " TDLS mode is disabled. action %d declined.", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), tdls_validate->action_code); @@ -698,7 +698,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) } if (tdls_soc->tdls_nss_switch_in_progress) { tdls_err("nss switch in progress, action %d declined " - QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_STR, tdls_validate->action_code, QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); return -EAGAIN; @@ -709,7 +709,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (NULL != tdls_is_progress(tdls_vdev, tdls_validate->peer_mac, true)) { tdls_err("setup is ongoing. action %d declined for " - QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_STR, tdls_validate->action_code, QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); return -EPERM; @@ -742,7 +742,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) tdls_validate->peer_mac); if (curr_peer) { if (TDLS_IS_LINK_CONNECTED(curr_peer)) { - tdls_err(QDF_MAC_ADDRESS_STR " already connected action %d declined.", + tdls_err(QDF_MAC_ADDR_STR " already connected action %d declined.", QDF_MAC_ADDR_ARRAY( tdls_validate->peer_mac), tdls_validate->action_code); @@ -753,7 +753,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) } } - tdls_notice("tdls_mgmt" QDF_MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu", + tdls_notice("tdls_mgmt" QDF_MAC_ADDR_STR " action %d, dialog_token %d status %d, len = %zu", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), tdls_validate->action_code, tdls_validate->dialog_token, tdls_validate->status_code, tdls_validate->len); @@ -763,7 +763,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (TDLS_TEARDOWN == tdls_validate->action_code) { temp_peer = tdls_find_peer(tdls_vdev, tdls_validate->peer_mac); if (!temp_peer) { - tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist", + tdls_err(QDF_MAC_ADDR_STR " peer doesn't exist", QDF_MAC_ADDR_ARRAY( tdls_validate->peer_mac)); return -EPERM; @@ -772,7 +772,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (TDLS_IS_LINK_CONNECTED(temp_peer)) tdls_validate->responder = temp_peer->is_responder; else { - tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", + tdls_err(QDF_MAC_ADDR_STR " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), temp_peer->link_status, tdls_validate->dialog_token, @@ -889,7 +889,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) curr_peer = tdls_get_peer(vdev_obj, mac); if (!curr_peer) { - tdls_err(QDF_MAC_ADDRESS_STR " not exist. return invalid", + tdls_err(QDF_MAC_ADDR_STR " not exist. return invalid", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; goto updatersp; @@ -898,7 +898,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) /* in change station, we accept only when sta_id is valid */ if (curr_peer->link_status > TDLS_LINK_CONNECTING || !(TDLS_STA_INDEX_CHECK(curr_peer->sta_id))) { - tdls_err(QDF_MAC_ADDRESS_STR " link %d. sta %d. update peer %s", + tdls_err(QDF_MAC_ADDR_STR " link %d. sta %d. update peer %s", QDF_MAC_ADDR_ARRAY(mac), curr_peer->link_status, curr_peer->sta_id, (TDLS_STA_INDEX_CHECK(curr_peer->sta_id)) ? "ignored" @@ -910,7 +910,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) /* when others are on-going, we want to change link_status to idle */ if (tdls_is_progress(vdev_obj, mac, true)) { - tdls_notice(QDF_MAC_ADDRESS_STR " TDLS setuping. Req declined.", + tdls_notice(QDF_MAC_ADDR_STR " TDLS setuping. Req declined.", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_PERM; goto setlink; @@ -918,7 +918,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) curr_tdls_peers = tdls_get_connected_peer(soc_obj); if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { - tdls_err(QDF_MAC_ADDRESS_STR + tdls_err(QDF_MAC_ADDR_STR " Request declined. Current: %d, Max allowed: %d.", QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, soc_obj->max_num_tdls_sta); @@ -1159,7 +1159,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) mac = req->peer_addr; peer = tdls_find_peer(vdev_obj, mac); if (!peer) { - tdls_err(QDF_MAC_ADDRESS_STR + tdls_err(QDF_MAC_ADDR_STR " not found, ignore NL80211_TDLS_ENABLE_LINK", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; @@ -1404,7 +1404,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, &rsp->peermac); tdls_warn("TDLS: STA IDX at %d is %d of mac " - QDF_MAC_ADDRESS_STR, sta_idx, + QDF_MAC_ADDR_STR, sta_idx, rsp->sta_id, QDF_MAC_ADDR_ARRAY (rsp->peermac.bytes)); break; @@ -1467,7 +1467,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) const uint8_t *macaddr; struct tdls_osif_indication ind; - tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDRESS_STR, + tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDR_STR, rsp->session_id, QDF_MAC_ADDR_ARRAY(rsp->peermac.bytes)); psoc = rsp->psoc; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, @@ -1495,7 +1495,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) tdls_warn("TDLS: del STA IDX = %x", rsp->sta_id); curr_peer = tdls_find_peer(vdev_obj, macaddr); if (curr_peer) { - tdls_debug(QDF_MAC_ADDRESS_STR " status is %d", + tdls_debug(QDF_MAC_ADDR_STR " status is %d", QDF_MAC_ADDR_ARRAY(macaddr), curr_peer->link_status); @@ -1556,7 +1556,7 @@ tdls_wma_update_peer_state(struct tdls_soc_priv_obj *soc_obj, struct scheduler_msg msg = {0,}; QDF_STATUS status; - tdls_debug("update TDLS peer " QDF_MAC_ADDRESS_STR " vdev %d, state %d", + tdls_debug("update TDLS peer " QDF_MAC_ADDR_STR " vdev %d, state %d", QDF_MAC_ADDR_ARRAY(peer_state->peer_macaddr), peer_state->vdev_id, peer_state->peer_state); msg.type = soc_obj->tdls_update_peer_state; @@ -1661,17 +1661,17 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) mac = req->peer_addr; peer = tdls_find_peer(vdev_obj, mac); if (!peer) { - tdls_err(QDF_MAC_ADDRESS_STR + tdls_err(QDF_MAC_ADDR_STR " not found, ignore NL80211_TDLS_ENABLE_LINK", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; goto error; } - tdls_debug("enable link for peer " QDF_MAC_ADDRESS_STR " link state %d", + tdls_debug("enable link for peer " QDF_MAC_ADDR_STR " link state %d", QDF_MAC_ADDR_ARRAY(mac), peer->link_status); if (!TDLS_STA_INDEX_CHECK(peer->sta_id)) { - tdls_err("invalid sta idx %u for " QDF_MAC_ADDRESS_STR, + tdls_err("invalid sta idx %u for " QDF_MAC_ADDR_STR, peer->sta_id, QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; goto error; @@ -1757,7 +1757,7 @@ static QDF_STATUS tdls_config_force_peer( struct tdls_peer_update_state *peer_update_param; macaddr = req->peer_addr; - tdls_debug("NL80211_TDLS_SETUP for " QDF_MAC_ADDRESS_STR, + tdls_debug("NL80211_TDLS_SETUP for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); vdev = req->vdev; @@ -1785,7 +1785,7 @@ static QDF_STATUS tdls_config_force_peer( peer = tdls_get_peer(vdev_obj, macaddr); if (!peer) { - tdls_err("peer " QDF_MAC_ADDRESS_STR " does not exist", + tdls_err("peer " QDF_MAC_ADDR_STR " does not exist", QDF_MAC_ADDR_ARRAY(macaddr)); status = QDF_STATUS_E_NULL_VALUE; goto error; @@ -1847,7 +1847,7 @@ QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req) struct wlan_objmgr_vdev *vdev; QDF_STATUS status; - tdls_debug("Configure external TDLS peer " QDF_MAC_ADDRESS_STR, + tdls_debug("Configure external TDLS peer " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(req->peer_addr)); /* reference cnt is acquired in ucfg_tdls_oper */ @@ -1893,7 +1893,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) struct tdls_osif_indication ind; macaddr = req->peer_addr; - tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDRESS_STR, + tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); vdev = req->vdev; @@ -1922,7 +1922,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) peer = tdls_find_peer(vdev_obj, macaddr); if (!peer) { - tdls_err("peer matching " QDF_MAC_ADDRESS_STR " not found", + tdls_err("peer matching " QDF_MAC_ADDR_STR " not found", QDF_MAC_ADDR_ARRAY(macaddr)); status = QDF_STATUS_E_NULL_VALUE; goto error; @@ -2013,7 +2013,7 @@ QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); type = evt->message_type; - tdls_debug("TDLS %s: " QDF_MAC_ADDRESS_STR "reason %d", + tdls_debug("TDLS %s: " QDF_MAC_ADDR_STR "reason %d", tdls_evt_to_str(type), QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); @@ -2070,7 +2070,7 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); - tdls_debug("TDLS %s: " QDF_MAC_ADDRESS_STR "reason %d", + tdls_debug("TDLS %s: " QDF_MAC_ADDR_STR "reason %d", tdls_evt_to_str(type), QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); @@ -2088,7 +2088,7 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, reason = evt->peer_reason; if (TDLS_LINK_CONNECTED == curr_peer->link_status) { - tdls_err("%s reason: %d for" QDF_MAC_ADDRESS_STR, + tdls_err("%s reason: %d for" QDF_MAC_ADDR_STR, tdls_evt_to_str(type), evt->peer_reason, QDF_MAC_ADDR_ARRAY(evt->peermac.bytes)); if (reason == TDLS_TEARDOWN_RSSI || diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index e55bea3727ad..2327fc4744c6 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -127,8 +127,8 @@ void tdls_discovery_timeout_peer_cb(void *user_data) &p_node); continue; } - tdls_debug(QDF_MAC_ADDRESS_STR " to idle state", - QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); + tdls_debug(QDF_MAC_ADDR_STR " to idle state", + QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); tdls_set_peer_link_status(peer, TDLS_LINK_IDLE, TDLS_LINK_NOT_SUPPORTED); @@ -379,8 +379,8 @@ void tdls_implicit_send_discovery_request( /* This function is called in mutex_lock */ temp_peer = tdls_is_progress(tdls_vdev_obj, NULL, 0); if (NULL != temp_peer) { - tdls_notice(QDF_MAC_ADDRESS_STR " ongoing. pre_setup ignored", - QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); + tdls_notice(QDF_MAC_ADDR_STR " ongoing. pre_setup ignored", + QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); goto done; } @@ -446,7 +446,7 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, if (0 == tdls_vdev->discovery_sent_cnt) qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); - tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDRESS_STR + tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDR_STR " link_status %d", tdls_vdev->discovery_sent_cnt, QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->link_status); @@ -462,7 +462,7 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, tdls_set_peer_link_status(curr_peer, TDLS_LINK_DISCOVERED, TDLS_LINK_SUCCESS); - tdls_debug("Rssi Threshold met: " QDF_MAC_ADDRESS_STR + tdls_debug("Rssi Threshold met: " QDF_MAC_ADDR_STR " rssi = %d threshold= %d", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->rssi, @@ -477,8 +477,7 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, TDLS_EVENT_SETUP_REQ, &indication); } else { - tdls_debug("Rssi Threshold not met: " - QDF_MAC_ADDRESS_STR + tdls_debug("Rssi Threshold not met: " QDF_MAC_ADDR_STR " rssi = %d threshold = %d ", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->rssi, @@ -601,7 +600,7 @@ tdls_ct_process_idle_handler( return; } - tdls_debug(QDF_MAC_ADDRESS_STR + tdls_debug(QDF_MAC_ADDR_STR " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->tx_pkt, @@ -616,12 +615,12 @@ tdls_ct_process_idle_handler( (curr_peer->rx_pkt >= tdls_vdev_obj->threshold_config.idle_packet_n)) { /* this tdls link got back to normal, so keep it */ - tdls_debug("tdls link to " QDF_MAC_ADDRESS_STR + tdls_debug("tdls link to " QDF_MAC_ADDR_STR " back to normal, will stay", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); } else { /* this tdls link needs to get torn down */ - tdls_notice("trigger tdls link to "QDF_MAC_ADDRESS_STR" down", + tdls_notice("trigger tdls link to "QDF_MAC_ADDR_STR" down", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); tdls_indicate_teardown(tdls_vdev_obj, curr_peer, @@ -705,7 +704,7 @@ static void tdls_ct_process_connected_link( if ((int32_t)curr_peer->rssi < (int32_t)tdls_vdev->threshold_config.rssi_teardown_threshold) { - tdls_warn("Tear down - low RSSI: " QDF_MAC_ADDRESS_STR "!", + tdls_warn("Tear down - low RSSI: " QDF_MAC_ADDR_STR "!", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); tdls_indicate_teardown(tdls_vdev, curr_peer, @@ -736,7 +735,7 @@ static void tdls_ct_process_connected_link( if (QDF_TIMER_STATE_RUNNING != curr_peer->peer_idle_timer.state) { tdls_warn("Tx/Rx Idle timer start: " - QDF_MAC_ADDRESS_STR "!", + QDF_MAC_ADDR_STR "!", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); tdls_timer_restart(tdls_vdev->vdev, &curr_peer->peer_idle_timer, @@ -744,7 +743,7 @@ static void tdls_ct_process_connected_link( } } else if (QDF_TIMER_STATE_RUNNING == curr_peer->peer_idle_timer.state) { - tdls_warn("Tx/Rx Idle timer stop: " QDF_MAC_ADDRESS_STR "!", + tdls_warn("Tx/Rx Idle timer stop: " QDF_MAC_ADDR_STR "!", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); qdf_mc_timer_stop(&curr_peer->peer_idle_timer); } @@ -853,7 +852,7 @@ static void tdls_ct_process_peers(struct tdls_peer *curr_peer, struct tdls_vdev_priv_obj *tdls_vdev_obj, struct tdls_soc_priv_obj *tdls_soc_obj) { - tdls_debug(QDF_MAC_ADDRESS_STR " link_status %d tdls_support %d", + tdls_debug(QDF_MAC_ADDR_STR " link_status %d tdls_support %d", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->link_status, curr_peer->tdls_support); @@ -1116,7 +1115,7 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, qdf_mem_copy(&chan_switch_params.peer_mac_addr, &conn_peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE); - tdls_notice("Peer " QDF_MAC_ADDRESS_STR " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d", + tdls_notice("Peer " QDF_MAC_ADDR_STR " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d", QDF_MAC_ADDR_ARRAY(chan_switch_params.peer_mac_addr), chan_switch_params.vdev_id, chan_switch_params.tdls_off_ch, diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 7e447d3eba53..bfe79473eff8 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1058,7 +1058,7 @@ static int __tdls_get_all_peers_from_list( if (buf_len < 32 + 1) break; len = qdf_scnprintf(buf, buf_len, - QDF_MAC_ADDRESS_STR "%3d%4s%3s%5d\n", + QDF_MAC_ADDR_STR "%3d%4s%3s%5d\n", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->sta_id, (curr_peer->tdls_support == @@ -1413,7 +1413,7 @@ QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc) curr_peer = tdls_is_progress(tdls_vdev, NULL, 0); if (NULL != curr_peer) { if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) { - tdls_notice(QDF_MAC_ADDRESS_STR + tdls_notice(QDF_MAC_ADDR_STR ". scan rejected %d. force it to idle", QDF_MAC_ADDR_ARRAY( curr_peer->peer_mac.bytes), diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 8dfae9f15fee..b271b3209a57 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -107,7 +107,7 @@ static QDF_STATUS tdls_process_rx_mgmt( TDLS_PUBLIC_ACTION_DISC_RESP) { mac = &rx_mgmt->buf[TDLS_80211_PEER_ADDR_OFFSET]; tdls_notice("[TDLS] TDLS Discovery Response," - QDF_MAC_ADDRESS_STR " RSSI[%d] <--- OTA", + QDF_MAC_ADDR_STR " RSSI[%d] <--- OTA", QDF_MAC_ADDR_ARRAY(mac), rx_mgmt->rx_rssi); tdls_recv_discovery_resp(tdls_vdev, mac); tdls_set_rssi(tdls_vdev, mac, rx_mgmt->rx_rssi); diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 769ba533423e..a254ff5fd3f2 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.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 @@ -59,7 +59,7 @@ struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, status = qdf_list_peek_next(head, p_node, &p_node); } - tdls_debug("no tdls peer " QDF_MAC_ADDRESS_STR, + tdls_debug("no tdls peer " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); return NULL; } @@ -188,7 +188,7 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj, qdf_list_insert_back(head, &peer->node); - tdls_debug("add tdls peer: " QDF_MAC_ADDRESS_STR, + tdls_debug("add tdls peer: " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); return peer; } @@ -222,7 +222,7 @@ tdls_find_progress_peer_in_list(qdf_list_t *head, status = qdf_list_peek_next(head, p_node, &p_node); continue; } else if (TDLS_LINK_CONNECTING == peer->link_status) { - tdls_debug(QDF_MAC_ADDRESS_STR " TDLS_LINK_CONNECTING", + tdls_debug(QDF_MAC_ADDR_STR " TDLS_LINK_CONNECTING", QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); return peer; } @@ -353,7 +353,7 @@ tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj) peer = qdf_container_of(p_node, struct tdls_peer, node); if (peer && TDLS_LINK_CONNECTED == peer->link_status) { - tdls_debug(QDF_MAC_ADDRESS_STR + tdls_debug(QDF_MAC_ADDR_STR " TDLS_LINK_CONNECTED", QDF_MAC_ADDR_ARRAY( peer->peer_mac.bytes)); @@ -795,7 +795,7 @@ void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj) while (QDF_IS_STATUS_SUCCESS(status)) { peer = qdf_container_of(p_node, struct tdls_peer, node); if (peer && peer->is_peer_idle_timer_initialised) { - tdls_debug(QDF_MAC_ADDRESS_STR + tdls_debug(QDF_MAC_ADDR_STR ": destroy idle timer ", QDF_MAC_ADDR_ARRAY( peer->peer_mac.bytes)); diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 8b35247d8b94..c89e202e205f 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.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 @@ -183,7 +183,7 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, tdls_err("psoc: 0x%pK, info: 0x%pK", psoc, info); return QDF_STATUS_E_NULL_VALUE; } - tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDRESS_STR, + tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDR_STR, info->vdev_id, info->message_type, info->peer_reason, QDF_MAC_ADDR_ARRAY(info->peermac.bytes)); notify = qdf_mem_malloc(sizeof(*notify)); diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 583b8c53ee21..1bae8eb0a616 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -449,7 +449,7 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_NULL_VALUE; } - tdls_debug("%s for peer " QDF_MAC_ADDRESS_STR, + tdls_debug("%s for peer " QDF_MAC_ADDR_STR, tdls_get_oper_str(cmd), QDF_MAC_ADDR_ARRAY(macaddr)); From a6540eed2c1a6f7bfe625e26d01a55084c58c46e Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 25 Jan 2018 11:46:31 -0800 Subject: [PATCH 199/404] 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 eb32063dcc3b3dc6121dc93f98ae14b271e0b3b4 Mon Sep 17 00:00:00 2001 From: hqu Date: Wed, 17 Jan 2018 17:25:25 +0800 Subject: [PATCH 200/404] qcacmn: Use no_of_open_sessions to check multiple beaconing sessions When start sap+sap with acs concurrently, the first sap usually choose dfs channel, the second sap will be failed to start. when check multiple beaconing sessions it only checks in_use sap for pm_conc_connection_lis which means bss started sap while it has no started sap at that time, so the second sap can't follow the first sap's dfs channel and start failed according to current code flow. Fix is to use no_of_open_sessions to check multiple beaconing sessions. CRs-Fixed: 2170567 Change-Id: Iada737dffcd826aaff3873b81355018d53485948 --- src/wlan_policy_mgr_get_set_utils.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index dc2588ed8ca9..916d6291e4d6 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2118,13 +2118,17 @@ bool policy_mgr_concurrent_open_sessions_running( bool policy_mgr_concurrent_beaconing_sessions_running( struct wlan_objmgr_psoc *psoc) { - return (policy_mgr_mode_specific_connection_count( - psoc, QDF_SAP_MODE, NULL) + - policy_mgr_mode_specific_connection_count( - psoc, QDF_P2P_GO_MODE, NULL) + - policy_mgr_mode_specific_connection_count( - psoc, QDF_IBSS_MODE, NULL) > 1) ? - true : false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return false; + } + + return (pm_ctx->no_of_open_sessions[QDF_SAP_MODE] + + pm_ctx->no_of_open_sessions[QDF_P2P_GO_MODE] + + pm_ctx->no_of_open_sessions[QDF_IBSS_MODE] > 1) ? true : false; } From a8f08ee4637c5790e3b6f5eaa54658608555e795 Mon Sep 17 00:00:00 2001 From: Srinivas Pitla Date: Mon, 22 Jan 2018 16:10:33 +0530 Subject: [PATCH 201/404] qcacmn: Define API to get component handles Introduce APIs set and get component handles Change-Id: I8bfcd802f10b8ecf9908a02d492f1ad757d8f7ec CRs-Fixed: 2177109 --- src/target_if_p2p.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index 000a91758692..6f6b306e5e6b 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -24,6 +24,7 @@ #include #include "target_if.h" #include "target_if_p2p.h" +#include "init_deinit_ucfg.h" static inline struct wlan_lmac_if_p2p_rx_ops * target_if_psoc_get_p2p_rx_ops(struct wlan_objmgr_psoc *psoc) @@ -167,7 +168,7 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -190,7 +191,7 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -213,7 +214,7 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -235,7 +236,7 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -258,7 +259,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, { struct p2p_ps_params cmd; QDF_STATUS status; - wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -299,7 +300,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, struct p2p_lo_start *lo_start) { - wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -318,7 +319,7 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { - wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); target_if_debug("psoc:%pK, vdev_id:%d", psoc, vdev_id); @@ -335,7 +336,7 @@ QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, bool disable_noa) { struct vdev_set_params param; - wmi_unified_t wmi_handle = target_if_get_wmi_handle(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); From 533baa3076b589e5c15e155c8cebdfd72bdb135d Mon Sep 17 00:00:00 2001 From: Himanshu Agarwal Date: Thu, 25 Jan 2018 16:20:33 +0530 Subject: [PATCH 202/404] qcacmn: Add policy mgr API to get no. of active sessions Add policy mgr API to get no. of active sessions for a specific mode. Change-Id: If91685ae7b72c6be52426648e9d01cba92eee85e CRs-Fixed: 2178921 --- inc/wlan_policy_mgr_api.h | 13 +++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 16 ++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 1a9c8744e6e5..fe0dbe89591b 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -984,6 +984,19 @@ QDF_STATUS policy_mgr_mode_specific_num_open_sessions( struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, uint8_t *num_sessions); +/** + * policy_mgr_mode_specific_num_active_sessions() - to get number of active + * sessions for a specific mode + * @psoc: PSOC object information + * @mode: device mode + * @num_sessions: to store num active sessions + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_mode_specific_num_active_sessions( + struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, + uint8_t *num_sessions); + /** * policy_mgr_concurrent_open_sessions_running() - Checks for * concurrent open session diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 916d6291e4d6..0d1a40453298 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2076,6 +2076,22 @@ QDF_STATUS policy_mgr_mode_specific_num_open_sessions( return QDF_STATUS_SUCCESS; } +QDF_STATUS policy_mgr_mode_specific_num_active_sessions( + struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, + uint8_t *num_sessions) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + *num_sessions = pm_ctx->no_of_active_sessions[mode]; + return QDF_STATUS_SUCCESS; +} + /** * policy_mgr_concurrent_open_sessions_running() - Checks for * concurrent open session From 24167fc8f35820f62dbea96bea735ac197b209ba Mon Sep 17 00:00:00 2001 From: Arunk Khandavalli Date: Mon, 5 Feb 2018 15:42:31 +0530 Subject: [PATCH 203/404] qcacmn: update the pcl info from the converged structures Update the pcl information from the converged strutures. CRs-Fixed: 2179012 Change-Id: Id9269e85728409645266e1edc17d03237144a9cc --- inc/wlan_policy_mgr_api.h | 7 ++++--- src/wlan_policy_mgr_get_set_utils.c | 27 ++++++++++++--------------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index fe0dbe89591b..06d3925616c7 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -40,6 +40,8 @@ #include "wlan_objmgr_psoc_obj.h" #include "wlan_policy_mgr_public_struct.h" +struct target_psoc_info; + typedef const enum policy_mgr_pcl_type pm_dbs_pcl_second_connection_table_type [PM_MAX_ONE_CONNECTION_MODE][PM_MAX_NUM_OF_MODE] @@ -1922,8 +1924,7 @@ void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc, * policy_mgr_update_hw_mode_list() - Function to initialize DBS * HW modes in policy manager component * @psoc: PSOC object information - * @num_dbs_hw_modes: Number of HW modes - * @ev_wlan_dbs_hw_mode_list: HW list + * @tgt_hdl: Target psoc information * * This function to initialize the DBS HW modes in policy * manager @@ -1932,7 +1933,7 @@ void policy_mgr_init_dbs_hw_mode(struct wlan_objmgr_psoc *psoc, * */ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, - struct extended_caps *phy_caps); + struct target_psoc_info *tgt_hdl); /** * policy_mgr_update_hw_mode_index() - Function to update diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 0d1a40453298..3565eb110a7e 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -145,7 +145,8 @@ static enum hw_mode_bandwidth policy_mgr_map_wmi_channel_width_to_hw_mode_bw( return HW_MODE_BW_NONE; } -static void policy_mgr_get_hw_mode_params(WMI_MAC_PHY_CAPABILITIES *caps, +static void policy_mgr_get_hw_mode_params( + struct wlan_psoc_host_mac_phy_caps *caps, struct policy_mgr_mac_ss_bw_info *info) { if (!caps) { @@ -223,14 +224,15 @@ static void policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc *psoc, } QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, - struct extended_caps *phy_caps) + struct target_psoc_info *tgt_hdl) { - WMI_MAC_PHY_CAPABILITIES *tmp; + struct wlan_psoc_host_mac_phy_caps *tmp; uint32_t i, hw_config_type, j = 0; uint32_t dbs_mode, sbs_mode; struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info = {0}; struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info = {0}; struct policy_mgr_psoc_priv_obj *pm_ctx; + struct tgt_info *info; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -238,14 +240,10 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - if (!phy_caps) { - policy_mgr_err("Invalid phy capabilities"); - return QDF_STATUS_E_FAILURE; - } - - if (!phy_caps->num_hw_modes.num_hw_modes) { + info = &tgt_hdl->info; + if (!info->service_ext_param.num_hw_modes) { policy_mgr_err("Number of HW modes: %d", - phy_caps->num_hw_modes.num_hw_modes); + info->service_ext_param.num_hw_modes); return QDF_STATUS_E_FAILURE; } @@ -259,7 +257,7 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("DBS list is freed"); } - pm_ctx->num_dbs_hw_modes = phy_caps->num_hw_modes.num_hw_modes; + pm_ctx->num_dbs_hw_modes = info->service_ext_param.num_hw_modes; pm_ctx->hw_mode.hw_mode_list = qdf_mem_malloc(sizeof(*pm_ctx->hw_mode.hw_mode_list) * pm_ctx->num_dbs_hw_modes); @@ -273,10 +271,9 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { /* Update for MAC0 */ - tmp = &phy_caps->each_phy_cap_per_hwmode[j++]; + tmp = &info->mac_phy_cap[j++]; policy_mgr_get_hw_mode_params(tmp, &mac0_ss_bw_info); - hw_config_type = - phy_caps->each_hw_mode_cap[i].hw_mode_config_type; + hw_config_type = tmp->hw_mode_config_type; dbs_mode = HW_MODE_DBS_NONE; sbs_mode = HW_MODE_SBS_NONE; mac1_ss_bw_info.mac_tx_stream = 0; @@ -288,7 +285,7 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, (hw_config_type == WMI_HW_MODE_SBS_PASSIVE) || (hw_config_type == WMI_HW_MODE_SBS)) { /* Update for MAC1 */ - tmp = &phy_caps->each_phy_cap_per_hwmode[j++]; + tmp = &info->mac_phy_cap[j++]; policy_mgr_get_hw_mode_params(tmp, &mac1_ss_bw_info); if (hw_config_type == WMI_HW_MODE_DBS) dbs_mode = HW_MODE_DBS; From 7766dffe94cd27bd96ee23d5338e5f35d47ad836 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 18 Jan 2018 16:08:25 +0530 Subject: [PATCH 204/404] qcacmn: Move wma_get_buf_start_scan_cmd to ucfg_scan_update_params Move wma_get_buf_start_scan_cmd logic to common code in ucfg_scan_update_params. Change-Id: I4c9dcb48b4862ad10f64e260d87938251e270185 CRs-Fixed: 2180960 --- core/src/wlan_p2p_roc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 44ea9dac8953..d2d94d453d6c 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.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 @@ -101,6 +101,7 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) roc_ctx->scan_id = ucfg_scan_get_scan_id(p2p_soc_obj->soc); req->vdev = vdev; req->scan_req.scan_id = roc_ctx->scan_id; + req->scan_req.p2p_scan_type = SCAN_P2P_LISTEN; req->scan_req.scan_req_id = p2p_soc_obj->scan_req_id; req->scan_req.chan_list.num_chan = 1; req->scan_req.chan_list.chan[0].freq = wlan_chan_to_freq(roc_ctx->chan); From 9409bca6b7414a343fb89c6c66a1e4e97611e3b3 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 19 Jan 2018 00:47:14 -0500 Subject: [PATCH 205/404] qcacmn: Add 80211W support to P2P component Newly designed P2P component doesn't contain 80211W PMF related information which is one of the mandatory requirement to make PMF work for P2P. Provide PMF support to P2P component by adding necessary callbacks to protocol stack to get 11W related information. Change-Id: I399f0d296f9461239ac9d720905b196e87983f29 CRs-Fixed: 2175898 --- core/src/wlan_p2p_main.h | 4 +- core/src/wlan_p2p_off_chan_tx.c | 146 ++++++++++++++++++++---- core/src/wlan_p2p_off_chan_tx.h | 4 +- dispatcher/inc/wlan_p2p_public_struct.h | 10 +- dispatcher/inc/wlan_p2p_ucfg_api.h | 15 ++- dispatcher/src/wlan_p2p_ucfg_api.c | 26 ++++- 6 files changed, 177 insertions(+), 28 deletions(-) diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index c1b60d05b13f..17e6bedc0786 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.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 @@ -166,6 +166,7 @@ enum p2p_connection_status { * data to HDD * @cancel_roc_done: Cancel roc done event * @roc_runtime_lock: Runtime lock for roc request + * @p2p_cb: Callbacks to protocol stack * @connection_status:Global P2P connection status */ struct p2p_soc_priv_obj { @@ -177,6 +178,7 @@ struct p2p_soc_priv_obj { struct p2p_start_param *start_param; qdf_event_t cancel_roc_done; qdf_runtime_lock_t roc_runtime_lock; + struct p2p_protocol_callbacks p2p_cb; #ifdef WLAN_FEATURE_P2P_DEBUG enum p2p_connection_status connection_status; #endif diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 7510af8977e3..62ef353e7b76 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -494,21 +494,6 @@ static QDF_STATUS p2p_populate_mac_header( return QDF_STATUS_SUCCESS; } -/** - * p2p_set_protected_bit() - set protected bit - * @tx_ctx: tx context - * @frame: pointer to frame - * - * This function sets protected bit of this mgmt frame - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -static QDF_STATUS p2p_set_protected_bit( - struct tx_action_context *tx_ctx, void *frame) -{ - return QDF_STATUS_E_INVAL; -} - /** * p2p_get_frame_type_str() - parse frame type to string * @frame_info: frame information @@ -799,7 +784,7 @@ static QDF_STATUS p2p_rx_update_connection_status( * Return: QDF_STATUS_SUCCESS - in case of success */ static QDF_STATUS p2p_packet_alloc(uint16_t size, void **data, - void **ppPacket) + qdf_nbuf_t *ppPacket) { QDF_STATUS status = QDF_STATUS_E_FAILURE; qdf_nbuf_t nbuf; @@ -882,7 +867,7 @@ static QDF_STATUS p2p_send_tx_conf(struct tx_action_context *tx_ctx, * Return: QDF_STATUS_SUCCESS - in case of success */ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, - uint32_t buf_len, void *packet, uint8_t *frame) + uint32_t buf_len, qdf_nbuf_t packet, uint8_t *frame) { QDF_STATUS status; mgmt_tx_download_comp_cb tx_comp_cb; @@ -935,7 +920,7 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, tx_ctx->nbuf = packet; status = wlan_mgmt_txrx_mgmt_frame_tx(peer, tx_ctx->p2p_soc_obj, - (qdf_nbuf_t)packet, tx_comp_cb, tx_ota_comp_cb, + packet, tx_comp_cb, tx_ota_comp_cb, WLAN_UMAC_COMP_P2P, &mgmt_param); wlan_objmgr_peer_release_ref(peer, WLAN_P2P_ID); @@ -1352,6 +1337,120 @@ static QDF_STATUS p2p_disable_tx_timer(struct tx_action_context *tx_ctx) return status; } +/** + * is_rmf_mgmt_action_frame() - check RMF action frame by category + * @action_category: action frame actegory + * + * This function check the frame is robust mgmt action frame or not + * + * Return: true - if category is robust mgmt type + */ +static bool is_rmf_mgmt_action_frame(uint8_t action_category) +{ + switch (action_category) { + case ACTION_CATEGORY_SPECTRUM_MGMT: + case ACTION_CATEGORY_QOS: + case ACTION_CATEGORY_DLS: + case ACTION_CATEGORY_BACK: + case ACTION_CATEGORY_RRM: + case ACTION_FAST_BSS_TRNST: + case ACTION_CATEGORY_SA_QUERY: + case ACTION_CATEGORY_PROTECTED_DUAL_OF_PUBLIC_ACTION: + case ACTION_CATEGORY_WNM: + case ACTION_CATEGORY_MESH_ACTION: + case ACTION_CATEGORY_MULTIHOP_ACTION: + case ACTION_CATEGORY_DMG: + case ACTION_CATEGORY_FST: + case ACTION_CATEGORY_VENDOR_SPECIFIC_PROTECTED: + return true; + default: + break; + } + return false; +} + +/** + * p2p_populate_rmf_field() - populate unicast rmf frame + * @tx_ctx: tx_action_context + * @size: input size of frame, and output new size + * @ppbuf: input frame ptr, and output new frame + * @ppkt: input pkt, output new pkt. + * + * This function allocates new pkt for rmf frame. The + * new frame has extra space for ccmp field. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_populate_rmf_field(struct tx_action_context *tx_ctx, + uint32_t *size, uint8_t **ppbuf, qdf_nbuf_t *ppkt) +{ + struct wlan_frame_hdr *wh, *rmf_wh; + struct action_frm_hdr *action_hdr; + QDF_STATUS status = QDF_STATUS_SUCCESS; + qdf_nbuf_t pkt = NULL; + uint8_t *frame; + uint32_t frame_len; + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_soc_obj = tx_ctx->p2p_soc_obj; + + if (tx_ctx->frame_info.sub_type != P2P_MGMT_ACTION || + !p2p_soc_obj->p2p_cb.is_mgmt_protected) + return QDF_STATUS_SUCCESS; + if (*size < (sizeof(struct wlan_frame_hdr) + + sizeof(struct action_frm_hdr))) { + return QDF_STATUS_E_INVAL; + } + + wh = (struct wlan_frame_hdr *)(*ppbuf); + action_hdr = (struct action_frm_hdr *)(*ppbuf + sizeof(*wh)); + + if (!is_rmf_mgmt_action_frame(action_hdr->action_category)) { + p2p_debug("non rmf act frame 0x%x cat %x", + tx_ctx->frame_info.sub_type, + action_hdr->action_category); + return QDF_STATUS_SUCCESS; + } + + if (!p2p_soc_obj->p2p_cb.is_mgmt_protected( + tx_ctx->vdev_id, wh->i_addr1)) { + p2p_debug("non rmf connection vdev %d "QDF_MAC_ADDR_STR, + tx_ctx->vdev_id, QDF_MAC_ADDR_ARRAY(wh->i_addr1)); + return QDF_STATUS_SUCCESS; + } + if (!qdf_is_macaddr_group((struct qdf_mac_addr *)wh->i_addr1) && + !qdf_is_macaddr_broadcast((struct qdf_mac_addr *)wh->i_addr1)) { + + frame_len = *size + IEEE80211_CCMP_HEADERLEN + + IEEE80211_CCMP_MICLEN; + status = p2p_packet_alloc((uint16_t)frame_len, (void **)&frame, + &pkt); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to allocate %d bytes for rmf frame.", + frame_len); + return QDF_STATUS_E_NOMEM; + } + + qdf_mem_copy(frame, wh, sizeof(*wh)); + qdf_mem_copy(frame + sizeof(*wh) + IEEE80211_CCMP_HEADERLEN, + *ppbuf + sizeof(*wh), + *size - sizeof(*wh)); + rmf_wh = (struct wlan_frame_hdr *)frame; + (rmf_wh)->i_fc[1] |= IEEE80211_FC1_WEP; + p2p_debug("set protection 0x%x cat %d "QDF_MAC_ADDR_STR, + tx_ctx->frame_info.sub_type, + action_hdr->action_category, + QDF_MAC_ADDR_ARRAY(wh->i_addr1)); + + qdf_nbuf_free(*ppkt); + *ppbuf = frame; + *ppkt = pkt; + *size = frame_len; + } + + return status; +} + /** * p2p_execute_tx_action_frame() - execute tx action frame * @tx_ctx: tx context @@ -1364,7 +1463,7 @@ static QDF_STATUS p2p_execute_tx_action_frame( struct tx_action_context *tx_ctx) { uint8_t *frame; - void *packet; + qdf_nbuf_t packet; QDF_STATUS status; uint8_t noa_len = 0; uint8_t noa_stream[P2P_NOA_STREAM_ARR_SIZE]; @@ -1411,7 +1510,7 @@ static QDF_STATUS p2p_execute_tx_action_frame( /* Ok-- try to allocate some memory: */ status = p2p_packet_alloc((uint16_t) buf_len, (void **)&frame, - (void **)&packet); + &packet); if (status != QDF_STATUS_SUCCESS) { p2p_err("Failed to allocate %d bytes for a Probe Request.", buf_len); @@ -1439,7 +1538,12 @@ static QDF_STATUS p2p_execute_tx_action_frame( qdf_mem_copy(frame, tx_ctx->buf, buf_len); } - p2p_set_protected_bit(tx_ctx, frame); + status = p2p_populate_rmf_field(tx_ctx, &buf_len, &frame, &packet); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("failed to populate rmf frame"); + qdf_nbuf_free(packet); + return status; + } status = p2p_mgmt_tx(tx_ctx, buf_len, packet, frame); if (status == QDF_STATUS_SUCCESS) { if (tx_ctx->no_ack) { diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index 87465875f0fc..41bdc806d527 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.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 @@ -173,7 +173,7 @@ struct tx_action_context { uint32_t duration; qdf_mc_timer_t tx_timer; struct p2p_frame_info frame_info; - void *nbuf; + qdf_nbuf_t nbuf; }; /** diff --git a/dispatcher/inc/wlan_p2p_public_struct.h b/dispatcher/inc/wlan_p2p_public_struct.h index febd25f75f24..4f156c633d7c 100644 --- a/dispatcher/inc/wlan_p2p_public_struct.h +++ b/dispatcher/inc/wlan_p2p_public_struct.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 @@ -215,4 +215,12 @@ struct p2p_noa_info { struct noa_descriptor noa_desc[P2P_MAX_NOA_DESC]; }; +/** + * struct p2p_protocol_callbacks - callback to non-converged driver + * @is_mgmt_protected: func to get 11w mgmt protection status + */ +struct p2p_protocol_callbacks { + bool (*is_mgmt_protected)(uint32_t vdev_id, const uint8_t *peer_addr); +}; + #endif /* _WLAN_P2P_PUBLIC_STRUCT_H_ */ diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/dispatcher/inc/wlan_p2p_ucfg_api.h index 708a4bf7e338..7ef8974a7993 100644 --- a/dispatcher/inc/wlan_p2p_ucfg_api.h +++ b/dispatcher/inc/wlan_p2p_ucfg_api.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 @@ -297,6 +297,19 @@ void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr); QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, bool disable_noa); +/** + * ucfg_p2p_register_callbacks() - register p2p callbacks + * @soc: soc context + * @cb_obj: p2p_protocol_callbacks struct + * + * This function registers lim callbacks to p2p components to provide + * protocol information. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_register_callbacks(struct wlan_objmgr_psoc *soc, + struct p2p_protocol_callbacks *cb_obj); + /** * ucfg_p2p_status_scan() - Show P2P connection status when scanning * @vdev: vdev context diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 4415b3cbefc2..8e2ea051aa72 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.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 @@ -23,8 +23,8 @@ #include #include #include -#include "wlan_p2p_ucfg_api.h" #include "wlan_p2p_public_struct.h" +#include "wlan_p2p_ucfg_api.h" #include "../../core/src/wlan_p2p_main.h" #include "../../core/src/wlan_p2p_roc.h" #include "../../core/src/wlan_p2p_off_chan_tx.h" @@ -423,6 +423,28 @@ QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc, return status; } +QDF_STATUS ucfg_p2p_register_callbacks(struct wlan_objmgr_psoc *soc, + struct p2p_protocol_callbacks *cb_obj) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + if (!soc || !cb_obj) { + p2p_err("psoc %pM cb_obj %pM context passed is NULL", soc, + cb_obj); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(soc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("p2p soc private object is NULL"); + return QDF_STATUS_E_FAILURE; + } + p2p_soc_obj->p2p_cb = *cb_obj; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_p2p_status_scan(struct wlan_objmgr_vdev *vdev) { if (!vdev) { From c7b9769831e17bf2d1f9a544d253e1950e054557 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 21 Feb 2018 13:37:00 -0800 Subject: [PATCH 206/404] qcacmn: Trim ACS channel list based on the concurrent connections If force SCC is enabled and there is a STA connection, trim the ACS channel list on the band on which STA connection is present. Change-Id: Ibd580a7afdcdfc5fb4398ada547565e229d59c70 CRs-Fixed: 2193720 --- inc/wlan_policy_mgr_api.h | 11 ++++ src/wlan_policy_mgr_get_set_utils.c | 83 +++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 06d3925616c7..a9886edbc3ed 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2244,4 +2244,15 @@ bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( * Return: true if sta is connected in 2g else false */ bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_trim_acs_channel_list() - Trim the ACS channel list based + * on the number of active station connections + * @org_ch_list: ACS channel list from user space + * @org_ch_list_count: ACS channel count from user space + * + * Return: None + */ +void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc, + uint8_t *org_ch_list, uint8_t *org_ch_list_count); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 3565eb110a7e..653bed941113 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2820,3 +2820,86 @@ bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc) return ret; } + +void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc, + uint8_t *org_ch_list, uint8_t *org_ch_list_count) +{ + uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; + uint32_t index, count, i, ch_list_count; + uint8_t band_mask = 0, ch_5g = 0, ch_24g = 0; + uint8_t ch_list[QDF_MAX_NUM_CHAN]; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + + if (*org_ch_list_count >= QDF_MAX_NUM_CHAN) { + policy_mgr_err("org_ch_list_count too big %d", + *org_ch_list_count); + return; + } + /* + * if force SCC is enabled and there is a STA connection, trim the + * ACS channel list on the band on which STA connection is present + */ + count = policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, list); + if (policy_mgr_is_force_scc(psoc) && count) { + index = 0; + while (index < count) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list[index]].chan) && + policy_mgr_is_safe_channel(psoc, + pm_conc_connection_list[list[index]].chan)) { + band_mask |= 1; + ch_24g = pm_conc_connection_list[list[index]].chan; + } + if (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list[index]].chan) && + policy_mgr_is_safe_channel(psoc, + pm_conc_connection_list[list[index]].chan) && + !wlan_reg_is_dfs_ch(pm_ctx->pdev, + pm_conc_connection_list[list[index]].chan) && + !wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, + pm_conc_connection_list[list[index]].chan)) { + band_mask |= 2; + ch_5g = pm_conc_connection_list[list[index]].chan; + } + index++; + } + ch_list_count = 0; + if (band_mask == 1) { + ch_list[ch_list_count++] = ch_24g; + for (i = 0; i < *org_ch_list_count; i++) { + if (WLAN_REG_IS_24GHZ_CH( + org_ch_list[i])) + continue; + ch_list[ch_list_count++] = + org_ch_list[i]; + } + } else if (band_mask == 2) { + ch_list[ch_list_count++] = ch_5g; + for (i = 0; i < *org_ch_list_count; i++) { + if (WLAN_REG_IS_5GHZ_CH( + org_ch_list[i])) + continue; + ch_list[ch_list_count++] = + org_ch_list[i]; + } + } else if (band_mask == 3) { + ch_list[ch_list_count++] = ch_24g; + ch_list[ch_list_count++] = ch_5g; + } else { + policy_mgr_debug("unexpected band_mask value %d", + band_mask); + return; + } + + *org_ch_list_count = ch_list_count; + for (i = 0; i < *org_ch_list_count; i++) + org_ch_list[i] = ch_list[i]; + } +} From 97e0192b6581bd03b8459b0fd09aeb5b66dfc9c4 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 8 Feb 2018 21:20:38 -0800 Subject: [PATCH 207/404] qcacmn: Fix memory leak in TDLS rx mgmt callback TDLS RX management callback needs to be registered only during driver load time. Remove the redundant callback registration. Change-Id: Iee0e781ade2a4dafaaf372e8a9078347493418df CRs-Fixed: 2185908 --- core/src/wlan_tdls_main.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index bfe79473eff8..782408f6d073 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -833,14 +833,6 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_debug("TDLS Set state cnt %d", tdls_soc_obj->set_state_info.set_state_cnt); - - if (tdls_soc_obj->set_state_info.set_state_cnt == 1) - /* register callbacks with tx/rx mgmt */ - tdls_mgmt_rx_ops(tdls_soc_obj->soc, true); - else - /* deregister callbacks with tx/rx mgmt */ - tdls_mgmt_rx_ops(tdls_soc_obj->soc, false); - done: qdf_mem_free(tdls_info_to_fw); return; From 257a5d7edec245a4e99985b4ad6007f976077996 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Mon, 12 Feb 2018 12:24:06 +0530 Subject: [PATCH 208/404] qcacmn: Add ini support for channel selection logic Add ini to select DBS or inter-band MCC channel selection logic for STA+STA and STA+P2P connections. Change-Id: I7cfde9592ec210b0a8c812171d2bc6f005e17fb2 CRs-Fixed: 2189845 --- inc/wlan_policy_mgr_api.h | 16 +++++++++++++++- src/wlan_policy_mgr_get_set_utils.c | 9 ++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index a9886edbc3ed..9399e1416990 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -60,6 +60,19 @@ typedef const enum policy_mgr_conc_next_action policy_mgr_next_action_three_connection_table_type [PM_MAX_TWO_CONNECTION_MODE][POLICY_MGR_MAX_BAND]; +#define PM_FW_MODE_STA_STA_BIT_POS 0 +#define PM_FW_MODE_STA_P2P_BIT_POS 1 + +#define PM_FW_MODE_STA_STA_BIT_MASK (0x1 << PM_FW_MODE_STA_STA_BIT_POS) +#define PM_FW_MODE_STA_P2P_BIT_MASK (0x1 << PM_FW_MODE_STA_P2P_BIT_POS) + +#define PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(channel_select_logic_conc) \ + ((channel_select_logic_conc & PM_FW_MODE_STA_STA_BIT_MASK) >> \ + PM_FW_MODE_STA_STA_BIT_POS) +#define PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(channel_select_logic_conc) \ + ((channel_select_logic_conc & PM_FW_MODE_STA_P2P_BIT_MASK) >> \ + PM_FW_MODE_STA_P2P_BIT_POS) + /** * policy_mgr_set_concurrency_mode() - To set concurrency mode * @psoc: PSOC object data @@ -2025,7 +2038,8 @@ bool policy_mgr_is_dnsc_set(struct wlan_objmgr_vdev *vdev); */ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( struct wlan_objmgr_psoc *psoc, uint32_t *scan_config, - uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini); + uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini, + uint32_t channel_select_logic_conc); /** * policy_mgr_is_safe_channel - Check if the channel is in LTE diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 653bed941113..f164df3724a9 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2722,7 +2722,8 @@ uint8_t policy_mgr_get_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc) QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( struct wlan_objmgr_psoc *psoc, uint32_t *scan_config, - uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini) + uint32_t *fw_mode_config, uint32_t dual_mac_disable_ini, + uint32_t channel_select_logic_conc) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -2754,6 +2755,12 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( default: break; } + + WMI_DBS_FW_MODE_CFG_DBS_FOR_STA_PLUS_STA_SET(*fw_mode_config, + PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(channel_select_logic_conc)); + WMI_DBS_FW_MODE_CFG_DBS_FOR_STA_PLUS_P2P_SET(*fw_mode_config, + PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(channel_select_logic_conc)); + policy_mgr_debug("*scan_config:%x ", *scan_config); policy_mgr_debug("*fw_mode_config:%x ", *fw_mode_config); From 71e5ae6889af2f3b97bc95d010b3190d6991413b Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Mon, 12 Feb 2018 13:30:23 +0530 Subject: [PATCH 209/404] qcacmn: Set hw mode based on channel_select_logic_conc ini Set hw mode to DBS or single MAC for STA+STA and STA+P2P concurrencies based on channel_select_logic_conc ini. Change-Id: I46ba4d5cd8f5cda71d0c00be2b612bc851eb5ba4 CRs-Fixed: 2189848 --- inc/wlan_policy_mgr_api.h | 1 + inc/wlan_policy_mgr_public_struct.h | 3 +- src/wlan_policy_mgr_action.c | 88 +++++++++++++++++++++++++++++ src/wlan_policy_mgr_init_deinit.c | 3 + 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 9399e1416990..ad47414676be 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -836,6 +836,7 @@ struct policy_mgr_hdd_cbacks { enum policy_mgr_con_mode (*get_mode_for_non_connected_vdev)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); + enum tQDF_ADAPTER_MODE (*hdd_get_device_mode)(uint32_t session_id); }; diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 3ace5acb8d2a..651c3ad41886 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1018,6 +1018,7 @@ struct policy_mgr_user_cfg { uint32_t mcc_to_scc_switch_mode; bool sub_20_mhz_enabled; bool is_sta_sap_scc_allowed_on_dfs_chan; + uint32_t channel_select_logic_conc; }; /** diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 897571ecd5d7..f77f2fe9c873 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -346,6 +346,78 @@ QDF_STATUS policy_mgr_update_and_wait_for_connection_update( return QDF_STATUS_SUCCESS; } +/** + * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current + * concurreny + * @new_conn_mode: new connection mode + * + * When a new connection is about to come up, check if dbs is allowed for + * STA+STA or STA+P2P + * + * Return: true if dbs is allowed for STA+STA or STA+P2P else false + */ +static bool policy_mgr_is_dbs_allowed_for_concurrency( + struct wlan_objmgr_psoc *psoc, uint32_t session_id) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p; + enum tQDF_ADAPTER_MODE new_conn_mode = QDF_MAX_NO_OF_MODE; + bool ret = true; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return ret; + } + + count = policy_mgr_get_connection_count(psoc); + if (pm_ctx->hdd_cbacks.hdd_get_device_mode) + new_conn_mode = pm_ctx->hdd_cbacks. + hdd_get_device_mode(session_id); + + if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE) + return ret; + + dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(pm_ctx->user_cfg. + channel_select_logic_conc); + dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(pm_ctx->user_cfg. + channel_select_logic_conc); + + switch (pm_conc_connection_list[0].mode) { + case PM_STA_MODE: + switch (new_conn_mode) { + case QDF_STA_MODE: + if (!dbs_for_sta_sta) + return false; + break; + case QDF_P2P_DEVICE_MODE: + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_GO_MODE: + if (!dbs_for_sta_p2p) + return false; + break; + default: + break; + } + break; + case PM_P2P_CLIENT_MODE: + case PM_P2P_GO_MODE: + switch (new_conn_mode) { + case QDF_STA_MODE: + if (!dbs_for_sta_p2p) + return false; + break; + default: + break; + } + break; + default: + break; + } + + return ret; +} + QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, uint32_t session_id, uint8_t channel, @@ -410,6 +482,22 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, break; } + /* + * Based on channel_select_logic_conc ini, hw mode is set + * when second connection is about to come up that results + * in STA+STA and STA+P2P concurrency. + * 1) If MCC is set and if current hw mode is dbs, hw mode + * should be set to single mac for above concurrency. + * 2) If MCC is set and if current hw mode is not dbs, hw + * mode change is not required. + */ + if (policy_mgr_is_current_hwmode_dbs(psoc) && + !policy_mgr_is_dbs_allowed_for_concurrency(psoc, session_id)) + next_action = PM_SINGLE_MAC; + else if (!policy_mgr_is_current_hwmode_dbs(psoc) && + !policy_mgr_is_dbs_allowed_for_concurrency(psoc, session_id)) + next_action = PM_NOP; + if (PM_NOP != next_action) status = policy_mgr_next_actions(psoc, session_id, next_action, reason); diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 44bde60ec7f5..ef55b1e4102b 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -576,6 +576,8 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, hdd_cbacks->wlan_hdd_get_channel_for_sap_restart; pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = hdd_cbacks->get_mode_for_non_connected_vdev; + pm_ctx->hdd_cbacks.hdd_get_device_mode = + hdd_cbacks->hdd_get_device_mode; return QDF_STATUS_SUCCESS; } @@ -593,6 +595,7 @@ QDF_STATUS policy_mgr_deregister_hdd_cb(struct wlan_objmgr_psoc *psoc) pm_ctx->hdd_cbacks.sap_restart_chan_switch_cb = NULL; pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart = NULL; pm_ctx->hdd_cbacks.get_mode_for_non_connected_vdev = NULL; + pm_ctx->hdd_cbacks.hdd_get_device_mode = NULL; return QDF_STATUS_SUCCESS; } From 6a3be16847d7c162f4e7e2d466858469eead0b26 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Fri, 23 Feb 2018 12:14:46 +0530 Subject: [PATCH 210/404] qcacmn: Add support for HW mode info vendor command Add support for HW mode info vendor command which sends mac id, band, interface id and frequency information for each MAC provided by driver to userspace. Change-Id: If1112d29b8781cf5ba0480c84feeb772142f2c0e CRs-Fixed: 2185559 --- inc/wlan_policy_mgr_api.h | 26 ++++++++++++++++++++++++ inc/wlan_policy_mgr_public_struct.h | 18 +++++++++++++++++ src/wlan_policy_mgr_action.c | 10 ++++++++++ src/wlan_policy_mgr_core.c | 12 +++++++++++ src/wlan_policy_mgr_get_set_utils.c | 28 ++++++++++++++++++++++++++ src/wlan_policy_mgr_i.h | 4 ++-- src/wlan_policy_mgr_init_deinit.c | 31 +++++++++++++++++++++++++++++ 7 files changed, 127 insertions(+), 2 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index ad47414676be..a54e46cf2799 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2270,4 +2270,30 @@ bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc); */ void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc, uint8_t *org_ch_list, uint8_t *org_ch_list_count); +/* + * policy_mgr_get_connection_info() - Get info of all active connections + * @info: Pointer to connection info + * + * Return: Connection count + */ +uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, + struct connection_info *info); +/** + * policy_mgr_register_mode_change_cb() - Register mode change callback with + * policy manager + * @callback: HDD callback to be registered + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc, + send_mode_change_event_cb mode_change_cb); +/** + * policy_mgr_deregister_mode_change_cb() - Deregister mode change callback with + * policy manager + * @callback: HDD callback to be registered + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 651c3ad41886..d0793d372b5b 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -66,6 +66,12 @@ #define WEIGHT_OF_NON_PCL_CHANNELS 1 #define WEIGHT_OF_DISALLOWED_CHANNELS 0 +#define MAX_MAC 2 + +#define MAX_NUMBER_OF_CONC_CONNECTIONS 3 + +typedef int (*send_mode_change_event_cb)(void); + /** * enum hw_mode_ss_config - Possible spatial stream configuration * @HW_MODE_SS_0x0: Unused Tx and Rx of MAC @@ -1030,4 +1036,16 @@ struct dbs_nss { enum hw_mode_ss_config mac0_ss; enum hw_mode_ss_config mac1_ss; }; + +/** + * struct connection_info - connection information + * @mac_id: The HW mac it is running + * @vdev_id: vdev id + * @channel: channel of the connection + */ +struct connection_info { + uint8_t mac_id; + uint8_t vdev_id; + uint8_t channel; +}; #endif /* __WLAN_POLICY_MGR_PUBLIC_STRUCT_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index f77f2fe9c873..db6e957ad659 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -53,6 +53,13 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, QDF_STATUS status; struct policy_mgr_hw_mode_params hw_mode; uint32_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(context); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return; + } if (!vdev_mac_map) { policy_mgr_err("vdev_mac_map is NULL"); @@ -86,6 +93,9 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, vdev_mac_map, hw_mode); + if (pm_ctx->mode_change_cb) + pm_ctx->mode_change_cb(); + return; } diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 085d379863ff..161fa92ae91f 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -573,6 +573,9 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, pm_conc_connection_list[conn_index].vdev_id = vdev_id; pm_conc_connection_list[conn_index].in_use = in_use; + if (pm_ctx->mode_change_cb) + pm_ctx->mode_change_cb(); + policy_mgr_dump_connection_status_info(psoc); if (pm_ctx->cdp_cbacks.cdp_update_mac_id) pm_ctx->cdp_cbacks.cdp_update_mac_id(psoc, vdev_id, mac); @@ -764,6 +767,13 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, QDF_STATUS ret; struct policy_mgr_hw_mode_params hw_mode; uint32_t i; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(context); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } policy_mgr_set_hw_mode_change_in_progress(context, POLICY_MGR_HW_MODE_NOT_IN_PROGRESS); @@ -803,6 +813,8 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries, vdev_mac_map, hw_mode); + if (pm_ctx->mode_change_cb) + pm_ctx->mode_change_cb(); ret = policy_mgr_set_connection_update(context); if (!QDF_IS_STATUS_SUCCESS(ret)) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index f164df3724a9..31c67cf2a150 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2910,3 +2910,31 @@ void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc, org_ch_list[i] = ch_list[i]; } } + +uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, + struct connection_info *info) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t conn_index, count = 0; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return count; + } + + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (PM_CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { + info[count].vdev_id = + pm_conc_connection_list[conn_index].vdev_id; + info[count].mac_id = + pm_conc_connection_list[conn_index].mac; + info[count].channel = + pm_conc_connection_list[conn_index].chan; + count++; + } + } + + return count; +} diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index e8b21092a4c2..6f8b1fe36992 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -35,7 +35,6 @@ #include "qdf_defer.h" #include "wlan_reg_services_api.h" -#define MAX_NUMBER_OF_CONC_CONNECTIONS 3 #define DBS_OPPORTUNISTIC_TIME 10 #ifdef QCA_WIFI_3_0_EMU #define CONNECTION_UPDATE_TIMEOUT 3000 @@ -275,6 +274,7 @@ struct policy_mgr_psoc_priv_obj { uint8_t cur_conc_system_pref; uint8_t sta_sap_scc_on_dfs_chan_allowed; qdf_event_t opportunistic_update_done_evt; + send_mode_change_event_cb mode_change_cb; }; /** diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index ef55b1e4102b..eb9eab9e2219 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -671,3 +671,34 @@ QDF_STATUS policy_mgr_register_tdls_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } + +QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc, + send_mode_change_event_cb mode_change_cb) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->mode_change_cb = mode_change_cb; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + + pm_ctx->mode_change_cb = NULL; + + return QDF_STATUS_SUCCESS; +} From 410dd64dd0f9000618eddd00342962e6b0647a66 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 19 Jan 2018 22:58:32 +0530 Subject: [PATCH 211/404] qcacmn: Save vdev id of current roc ctx RX mgmt frame is from interrupt thread, it may be access freed roc ctx for low rate case. Save vdev id of current roc ctx in p2p psoc object. Low log level of P2P RX and TX conf since too many output. Change-Id: I4c944244f32b844d78bb69d66e341a1f3bf13abf CRs-Fixed: 2180116 --- core/src/wlan_p2p_main.c | 3 ++- core/src/wlan_p2p_main.h | 3 +++ core/src/wlan_p2p_roc.c | 4 +++- dispatcher/src/wlan_p2p_tgt_api.c | 12 ++++-------- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 32c9fb0b5b76..a09edbbc57e6 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.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 @@ -820,6 +820,7 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) } qdf_runtime_lock_init(&p2p_soc_obj->roc_runtime_lock); + p2p_soc_obj->cur_roc_vdev_id = P2P_INVALID_VDEV_ID; p2p_register_pmo_handler(); p2p_debug("p2p psoc object open successful"); diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 17e6bedc0786..7f0950abb24b 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -32,6 +32,7 @@ #define MAX_QUEUE_LENGTH 20 #define P2P_NOA_ATTR_IND 0x1090 #define P2P_MODULE_NAME "P2P" +#define P2P_INVALID_VDEV_ID 0xFFFFFFFF #define p2p_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_P2P, level, ## args) @@ -167,6 +168,7 @@ enum p2p_connection_status { * @cancel_roc_done: Cancel roc done event * @roc_runtime_lock: Runtime lock for roc request * @p2p_cb: Callbacks to protocol stack + * @cur_roc_vdev_id: Vdev id of current roc * @connection_status:Global P2P connection status */ struct p2p_soc_priv_obj { @@ -179,6 +181,7 @@ struct p2p_soc_priv_obj { qdf_event_t cancel_roc_done; qdf_runtime_lock_t roc_runtime_lock; struct p2p_protocol_callbacks p2p_cb; + uint32_t cur_roc_vdev_id; #ifdef WLAN_FEATURE_P2P_DEBUG enum p2p_connection_status connection_status; #endif diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index d2d94d453d6c..bfc7bd184cf6 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -380,7 +380,8 @@ fail: return status; } - status = p2p_mgmt_rx_ops(roc_ctx->p2p_soc_obj->soc, true); + p2p_soc_obj->cur_roc_vdev_id = roc_ctx->vdev_id; + status = p2p_mgmt_rx_ops(p2p_soc_obj->soc, true); if (status != QDF_STATUS_SUCCESS) p2p_err("Failed to register mgmt rx callback, status:%d", status); @@ -520,6 +521,7 @@ static QDF_STATUS p2p_process_scan_complete_evt( p2p_err("Failed to destroy roc timer"); status = p2p_mgmt_rx_ops(p2p_soc_obj->soc, false); + p2p_soc_obj->cur_roc_vdev_id = P2P_INVALID_VDEV_ID; if (status != QDF_STATUS_SUCCESS) p2p_err("Failed to deregister mgmt rx callback"); diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 84cd4673a50d..1762cf2b7618 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.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 @@ -185,9 +185,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, struct p2p_rx_mgmt_event *rx_mgmt_event; struct p2p_soc_priv_obj *p2p_soc_obj; struct scheduler_msg msg = {0}; - struct wlan_frame_hdr *wh; struct wlan_objmgr_vdev *vdev; - struct p2p_roc_context *roc_ctx; uint32_t vdev_id; uint8_t *pdata; @@ -208,13 +206,12 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, } if (!peer) { - roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); - if (!roc_ctx) { - p2p_err("current roc ctx is null, can't get vdev id"); + if (p2p_soc_obj->cur_roc_vdev_id == P2P_INVALID_VDEV_ID) { + p2p_err("vdev id of current roc invalid"); qdf_nbuf_free(buf); return QDF_STATUS_E_FAILURE; } else { - vdev_id = roc_ctx->vdev_id; + vdev_id = p2p_soc_obj->cur_roc_vdev_id; } } else { vdev = wlan_peer_get_vdev(peer); @@ -241,7 +238,6 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_NOMEM; } - wh = (struct wlan_frame_hdr *)qdf_nbuf_data(buf); pdata = (uint8_t *)qdf_nbuf_data(buf); rx_mgmt->frame_len = mgmt_rx_params->buf_len; rx_mgmt->rx_chan = mgmt_rx_params->channel; From d82af43cd3ba46325b1cf5ff659323e19b6104a5 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 19 Jan 2018 22:58:32 +0530 Subject: [PATCH 212/404] qcacmn: Save vdev id of current roc ctx RX mgmt frame is from interrupt thread, it may be access freed roc ctx for low rate case. Save vdev id of current roc ctx in p2p psoc object. Low log level of P2P RX and TX conf since too many output. Change-Id: I4c944244f32b844d78bb69d66e341a1f3bf13abf CRs-Fixed: 2180116 --- src/wlan_cfg80211_p2p.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 372a115e3986..e6ab17ab4d00 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.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 @@ -91,7 +91,7 @@ static void wlan_p2p_rx_callback(void *user_data, freq = ieee80211_channel_to_frequency( rx_frame->rx_chan, NL80211_BAND_5GHZ); - cfg80211_notice("Indicate frame over nl80211, vdev id:%d, idx:%d", + cfg80211_debug("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)) @@ -129,7 +129,7 @@ static void wlan_p2p_action_tx_cnf_callback(void *user_data, struct wireless_dev *wdev; bool is_success; - cfg80211_info("user data:%pK, action cookie:%llx, buf:%pK, len:%d, tx status:%d", + cfg80211_debug("user data:%pK, action cookie:%llx, buf:%pK, len:%d, tx status:%d", user_data, tx_cnf->action_cookie, tx_cnf->buf, tx_cnf->buf_len, tx_cnf->status); From 23a5404b7673b9cd10ecd6f2190bf7be688f431b Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 2 Mar 2018 14:09:16 -0800 Subject: [PATCH 213/404] qcacmn: Remove redundant DBS HW mode request Remove redundant DBS HW mode request from pm_next_action_two_connection_dbs_2x2_table. For 2x2 DBS HW even for first connection if it is on 2.4G, DBS will get requested. Hence no need to request again for second connection on the other band. Change-Id: I17db8de5ed7a60f556cc8eeed59bbbfe0d63e795 CRs-Fixed: 2199420 --- src/wlan_policy_mgr_tables_2x2_dbs_i.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/src/wlan_policy_mgr_tables_2x2_dbs_i.h index c13944dfd06d..cbef81312141 100644 --- a/src/wlan_policy_mgr_tables_2x2_dbs_i.h +++ b/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1306,8 +1306,8 @@ static policy_mgr_next_action_two_connection_table_type [PM_P2P_GO_24_2x2] = {PM_NOP, PM_NOP}, [PM_P2P_GO_5_1x1] = {PM_DBS, PM_SBS}, [PM_P2P_GO_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, - [PM_SAP_24_1x1] = {PM_NOP, PM_DBS}, - [PM_SAP_24_2x2] = {PM_NOP, PM_DBS}, + [PM_SAP_24_1x1] = {PM_NOP, PM_NOP}, + [PM_SAP_24_2x2] = {PM_NOP, PM_NOP}, [PM_SAP_5_1x1] = {PM_DBS, PM_SBS}, [PM_SAP_5_2x2] = {PM_DBS, PM_SBS_DOWNGRADE}, [PM_IBSS_24_1x1] = {PM_NOP, PM_NOP}, From 05a208a4fd592eacccbdb1e63ed533b1935bfb0b Mon Sep 17 00:00:00 2001 From: Will Huang Date: Tue, 6 Mar 2018 11:22:34 +0800 Subject: [PATCH 214/404] qcacmn: Free ROC context if p2p_scan_abort failed It is possible that call p2p_scan_abort fail while cleanup roc queue, because vdev already been destroyed when unloading driver. In this case, even the scan complete event will be discarded, so ROC context include ROC timer has no chance to free. Free ROC context include ROC timer in p2p_scan_abort failure path and set cancel_roc_done event to avoid unneeded waiting while unloading. CRs-Fixed: 2187778 Change-Id: I43751dca0c480e811c15de35ee28bc9426ac3764 --- core/src/wlan_p2p_roc.c | 155 +++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 75 deletions(-) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index bfc7bd184cf6..47ad67d2ba93 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -170,81 +170,6 @@ fail: return status; } -/** - * p2p_execute_cancel_roc_req() - Execute cancel roc request - * @roc_ctx: remain on channel request - * - * This function stop roc timer, abort scan and unregister mgmt rx - * callbak. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -static QDF_STATUS p2p_execute_cancel_roc_req( - struct p2p_roc_context *roc_ctx) -{ - QDF_STATUS status; - struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; - - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", - p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, - roc_ctx->phy_mode, roc_ctx->duration, - roc_ctx->roc_type, roc_ctx->roc_state); - - roc_ctx->roc_state = ROC_STATE_CANCEL_IN_PROG; - qdf_event_reset(&p2p_soc_obj->cancel_roc_done); - status = qdf_mc_timer_stop(&roc_ctx->roc_timer); - if (status != QDF_STATUS_SUCCESS) - p2p_err("Failed to stop roc timer, roc %pK", roc_ctx); - - status = p2p_scan_abort(roc_ctx); - if (status != QDF_STATUS_SUCCESS) { - p2p_err("Failed to abort scan, status:%d", status); - } - - return QDF_STATUS_SUCCESS; -} - -/** - * p2p_roc_timeout() - Callback for roc timeout - * @pdata: pointer to p2p soc private object - * - * This function is callback for roc time out. - * - * Return: None - */ -static void p2p_roc_timeout(void *pdata) -{ - struct p2p_roc_context *roc_ctx; - struct p2p_soc_priv_obj *p2p_soc_obj; - - p2p_debug("p2p soc obj:%pK", pdata); - - p2p_soc_obj = pdata; - if (!p2p_soc_obj) { - p2p_err("Invalid p2p soc object"); - return; - } - - roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); - if (!roc_ctx) { - p2p_debug("No P2P roc is pending"); - return; - } - - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", - roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, - roc_ctx->phy_mode, roc_ctx->duration, - roc_ctx->roc_type, roc_ctx->roc_state); - - if (roc_ctx->roc_state == ROC_STATE_CANCEL_IN_PROG) { - p2p_err("Cancellation already in progress"); - return; - } - p2p_execute_cancel_roc_req(roc_ctx); -} - /** * p2p_send_roc_event() - Send roc event * @roc_ctx: remain on channel request @@ -324,6 +249,86 @@ static QDF_STATUS p2p_destroy_roc_ctx(struct p2p_roc_context *roc_ctx, return status; } +/** + * p2p_execute_cancel_roc_req() - Execute cancel roc request + * @roc_ctx: remain on channel request + * + * This function stop roc timer, abort scan and unregister mgmt rx + * callbak. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +static QDF_STATUS p2p_execute_cancel_roc_req( + struct p2p_roc_context *roc_ctx) +{ + QDF_STATUS status; + struct p2p_soc_priv_obj *p2p_soc_obj = roc_ctx->p2p_soc_obj; + + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + roc_ctx->roc_state = ROC_STATE_CANCEL_IN_PROG; + qdf_event_reset(&p2p_soc_obj->cancel_roc_done); + status = qdf_mc_timer_stop(&roc_ctx->roc_timer); + if (status != QDF_STATUS_SUCCESS) + p2p_err("Failed to stop roc timer, roc %pK", roc_ctx); + + status = p2p_scan_abort(roc_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to abort scan, status:%d, destroy roc %pK", + status, roc_ctx); + qdf_mc_timer_destroy(&roc_ctx->roc_timer); + p2p_destroy_roc_ctx(roc_ctx, true, true); + qdf_event_set(&p2p_soc_obj->cancel_roc_done); + return status; + } + + return QDF_STATUS_SUCCESS; +} + +/** + * p2p_roc_timeout() - Callback for roc timeout + * @pdata: pointer to p2p soc private object + * + * This function is callback for roc time out. + * + * Return: None + */ +static void p2p_roc_timeout(void *pdata) +{ + struct p2p_roc_context *roc_ctx; + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_debug("p2p soc obj:%pK", pdata); + + p2p_soc_obj = pdata; + if (!p2p_soc_obj) { + p2p_err("Invalid p2p soc object"); + return; + } + + roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); + if (!roc_ctx) { + p2p_debug("No P2P roc is pending"); + return; + } + + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + if (roc_ctx->roc_state == ROC_STATE_CANCEL_IN_PROG) { + p2p_err("Cancellation already in progress"); + return; + } + p2p_execute_cancel_roc_req(roc_ctx); +} + /** * p2p_execute_roc_req() - Execute roc request * @roc_ctx: remain on channel request From 31dade3142955b1e63a274215205cb5ad4a41b51 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Thu, 1 Mar 2018 15:31:35 -0800 Subject: [PATCH 215/404] qcacmn: Introduce new versions of TDLS peer callbacks The parameters to function typedef tdls_register_tl_peer_callback() currently includes ucastsig. This "unicast signature" parameter dates back to a previous version of the driver that used signatures to synchronize the data plane with the control plane. However the current version of the driver does not use this mechanism, so there is a desire to remove this parameter from the callback. In addition both typedef tdls_register_tl_peer_callback() and typedef tdls_deregister_tl_peer_callback() suffer from poor naming since the "_tl_" in the names refers to a datapath component that was present in an older version of the driver but which is no longer present. Therefore introduce a new version of these typedefs with better naming and which removes the ucastsig parameter. Use temporary conditional compilation to allow support for both the old and new interfaces until such time as all registrants have converted to the new interfaces. This is part of the plan to completely remove the obsolete unicast and broadcast signatures from throughout the driver. Change-Id: Id4ea23266b0f3e1480b645c5afce6c17585ccb46 CRs-Fixed: 2200931 --- core/src/wlan_tdls_cmds_process.c | 22 +++++++++++++- core/src/wlan_tdls_ct.c | 9 +++++- core/src/wlan_tdls_main.h | 18 ++++++++++-- dispatcher/inc/wlan_tdls_public_structs.h | 36 +++++++++++++++++++++-- dispatcher/src/wlan_tdls_ucfg_api.c | 7 +++++ 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index f8622a82cf87..06f6813a6c51 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1501,6 +1501,19 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) id = wlan_vdev_get_id(vdev); +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + if (TDLS_IS_LINK_CONNECTED(curr_peer)) { + soc_obj->tdls_dereg_peer( + soc_obj->tdls_peer_context, + id, curr_peer->sta_id); + tdls_decrement_peer_count(soc_obj); + } else if (TDLS_LINK_CONNECTING == + curr_peer->link_status) { + soc_obj->tdls_dereg_peer( + soc_obj->tdls_peer_context, + id, curr_peer->sta_id); + } +#else if (TDLS_IS_LINK_CONNECTED(curr_peer)) { soc_obj->tdls_dereg_tl_peer( soc_obj->tdls_tl_peer_data, @@ -1512,6 +1525,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) soc_obj->tdls_tl_peer_data, id, curr_peer->sta_id); } +#endif } tdls_reset_peer(vdev_obj, macaddr); conn_rec[sta_idx].sta_id = 0; @@ -1683,11 +1697,17 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) TDLS_LINK_SUCCESS); id = wlan_vdev_get_id(vdev); +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + status = soc_obj->tdls_reg_peer(soc_obj->tdls_peer_context, + id, mac, peer->sta_id, + peer->qos); +#else status = soc_obj->tdls_reg_tl_peer(soc_obj->tdls_tl_peer_data, id, mac, peer->sta_id, peer->signature, peer->qos); +#endif if (QDF_IS_STATUS_ERROR(status)) { - tdls_err("TDLS register with TL fail, status %d", status); + tdls_err("TDLS register peer fail, status %d", status); goto error; } diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 2327fc4744c6..d6839a3e2746 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1274,12 +1274,19 @@ void tdls_disable_offchan_and_teardown_links( */ tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + if (tdls_soc->tdls_dereg_peer) + tdls_soc->tdls_dereg_peer( + tdls_soc->tdls_peer_context, + wlan_vdev_get_id(vdev), + curr_peer->sta_id); +#else if (tdls_soc->tdls_dereg_tl_peer) tdls_soc->tdls_dereg_tl_peer( tdls_soc->tdls_tl_peer_data, wlan_vdev_get_id(vdev), curr_peer->sta_id); - +#endif tdls_decrement_peer_count(tdls_soc); tdls_soc->tdls_conn_info[staidx].sta_id = 0; tdls_soc->tdls_conn_info[staidx].session_id = 255; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 0dee99c63fa8..14b2b65ca1bf 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.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 @@ -170,9 +170,15 @@ struct tdls_set_state_info { * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event user data +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + * @tdls_peer_context: userdata for register/deregister TDLS peer + * @tdls_reg_peer: register tdls peer with datapath + * @tdls_dereg_peer: deregister tdls peer from datapath +#else + * @tdls_tl_peer_data: userdata for register/deregister TDLS peer * @tdls_reg_tl_peer: callback to register the TDLS peer with TL * @tdls_dereg_tl_peer: callback to unregister the TDLS peer - * @tdls_tl_peer_data: userdata for register/deregister TDLS peer +#endif * @tx_q_ack: queue for tx frames waiting for ack * @tdls_con_cap: tdls concurrency support * @tdls_send_mgmt_req: store eWNI_SME_TDLS_SEND_MGMT_REQ value @@ -213,10 +219,16 @@ struct tdls_soc_priv_obj { void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + void *tdls_peer_context; + tdls_register_peer_callback tdls_reg_peer; + tdls_deregister_peer_callback tdls_dereg_peer; +#else + void *tdls_tl_peer_data; tdls_register_tl_peer_callback tdls_reg_tl_peer; tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; +#endif tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; - void *tdls_tl_peer_data; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; uint16_t tdls_send_mgmt_req; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 457a3ded556b..0ada980ae637 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.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 @@ -547,6 +547,22 @@ typedef void (*tdls_evt_callback) (void *data, typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, struct tdls_tx_cnf *tx_ack_cnf_cb_data); +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + +/* This callback is used to register TDLS peer with the datapath */ +typedef QDF_STATUS (*tdls_register_peer_callback)(void *userdata, + uint32_t vdev_id, + const uint8_t *mac, + uint16_t stat_id, + uint8_t qos); + +/* This callback is used to deregister TDLS peer from the datapath */ +typedef QDF_STATUS (*tdls_deregister_peer_callback)(void *userdata, + uint32_t vdev_id, + uint8_t sta_id); + +#else + /* This callback is used to register TDLS peer with TL */ typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata, uint32_t vdev_id, @@ -560,6 +576,8 @@ typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, uint32_t vdev_id, uint8_t sta_id); +#endif + /* This callback is used to update datapath vdev flags */ typedef QDF_STATUS (*tdls_dp_vdev_update_flags_callback)(void *cbk_data, @@ -580,10 +598,16 @@ typedef QDF_STATUS * @tdls_evt_cb_data: tdls event data * @ack_cnf_cb: tdls tx ack callback to indicate the tx status * @tx_ack_cnf_cb_data: tdls tx ack user data +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + * @tdls_peer_context: userdata for register/deregister TDLS peer + * @tdls_reg_peer: register tdls peer with datapath + * @tdls_dereg_peer: deregister tdls peer from datapath +#else + * @tdls_tl_peer_data: userdata for register/deregister TDLS peer * @tdls_reg_tl_peer: tdls register tdls peer * @tdls_dereg_tl_peer: tdls deregister tdls peer +#endif * @tdls_dp_vdev_update: update vdev flags in datapath - * @tdls_tl_peer_data: userdata for register/deregister TDLS peer */ struct tdls_start_params { struct tdls_user_config config; @@ -601,10 +625,16 @@ struct tdls_start_params { void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; void *tx_ack_cnf_cb_data; +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + void *tdls_peer_context; + tdls_register_peer_callback tdls_reg_peer; + tdls_deregister_peer_callback tdls_dereg_peer; +#else + void *tdls_tl_peer_data; tdls_register_tl_peer_callback tdls_reg_tl_peer; tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; +#endif tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; - void *tdls_tl_peer_data; }; /** diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 1bae8eb0a616..f4aecc150273 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -207,10 +207,17 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + /* Save callbacks to register/deregister TDLS sta with TL */ + soc_obj->tdls_reg_peer = req->tdls_reg_peer; + soc_obj->tdls_dereg_peer = req->tdls_dereg_peer; + soc_obj->tdls_peer_context = req->tdls_peer_context; +#else /* Save callbacks to register/deregister TDLS sta with TL */ soc_obj->tdls_reg_tl_peer = req->tdls_reg_tl_peer; soc_obj->tdls_dereg_tl_peer = req->tdls_dereg_tl_peer; soc_obj->tdls_tl_peer_data = req->tdls_tl_peer_data; +#endif /* Save legacy PE/WMA commands in TDLS soc object */ soc_obj->tdls_send_mgmt_req = req->tdls_send_mgmt_req; From 1f5b24e8b550bfec84a892bd8bb93fd7b92066a9 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Fri, 2 Mar 2018 08:48:24 -0800 Subject: [PATCH 216/404] qcacmn: Remove obsolete TDLS peer callback interface Change "qcacmn: Introduce new versions of TDLS peer callbacks" (Change-Id Id4ea23266b0f3e1480b645c5afce6c17585ccb46) introduced a new interface which removed an unused parameter and changed obsolete naming. Subsequently change "qcacld-3.0: Use new TDLS peer callback interface" (Change-Id: I5c4684ac0a62f314da26f92ece2c9a9874d63634 in project qcacld-3.0) updated the only registrant to use the new interface. Now that the old interface is no longer being used, remove it. Change-Id: I32bb1f633b1dd1514aa6e4c3fdea044b3bca0009 CRs-Fixed: 2200971 --- core/src/wlan_tdls_cmds_process.c | 20 --------------- core/src/wlan_tdls_ct.c | 8 ------ core/src/wlan_tdls_main.h | 12 --------- dispatcher/inc/wlan_tdls_public_structs.h | 31 ----------------------- dispatcher/src/wlan_tdls_ucfg_api.c | 9 +------ 5 files changed, 1 insertion(+), 79 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 06f6813a6c51..ffbc701f2d48 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1501,7 +1501,6 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) id = wlan_vdev_get_id(vdev); -#ifdef USE_NEW_TDLS_PEER_CALLBACKS if (TDLS_IS_LINK_CONNECTED(curr_peer)) { soc_obj->tdls_dereg_peer( soc_obj->tdls_peer_context, @@ -1513,19 +1512,6 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) soc_obj->tdls_peer_context, id, curr_peer->sta_id); } -#else - if (TDLS_IS_LINK_CONNECTED(curr_peer)) { - soc_obj->tdls_dereg_tl_peer( - soc_obj->tdls_tl_peer_data, - id, curr_peer->sta_id); - tdls_decrement_peer_count(soc_obj); - } else if (TDLS_LINK_CONNECTING == - curr_peer->link_status) { - soc_obj->tdls_dereg_tl_peer( - soc_obj->tdls_tl_peer_data, - id, curr_peer->sta_id); - } -#endif } tdls_reset_peer(vdev_obj, macaddr); conn_rec[sta_idx].sta_id = 0; @@ -1697,15 +1683,9 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) TDLS_LINK_SUCCESS); id = wlan_vdev_get_id(vdev); -#ifdef USE_NEW_TDLS_PEER_CALLBACKS status = soc_obj->tdls_reg_peer(soc_obj->tdls_peer_context, id, mac, peer->sta_id, peer->qos); -#else - status = soc_obj->tdls_reg_tl_peer(soc_obj->tdls_tl_peer_data, - id, mac, peer->sta_id, - peer->signature, peer->qos); -#endif if (QDF_IS_STATUS_ERROR(status)) { tdls_err("TDLS register peer fail, status %d", status); goto error; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index d6839a3e2746..e2c73a49bdd4 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1274,19 +1274,11 @@ void tdls_disable_offchan_and_teardown_links( */ tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); -#ifdef USE_NEW_TDLS_PEER_CALLBACKS if (tdls_soc->tdls_dereg_peer) tdls_soc->tdls_dereg_peer( tdls_soc->tdls_peer_context, wlan_vdev_get_id(vdev), curr_peer->sta_id); -#else - if (tdls_soc->tdls_dereg_tl_peer) - tdls_soc->tdls_dereg_tl_peer( - tdls_soc->tdls_tl_peer_data, - wlan_vdev_get_id(vdev), - curr_peer->sta_id); -#endif tdls_decrement_peer_count(tdls_soc); tdls_soc->tdls_conn_info[staidx].sta_id = 0; tdls_soc->tdls_conn_info[staidx].session_id = 255; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 14b2b65ca1bf..fbddfedc1cf0 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -170,15 +170,9 @@ struct tdls_set_state_info { * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event user data -#ifdef USE_NEW_TDLS_PEER_CALLBACKS * @tdls_peer_context: userdata for register/deregister TDLS peer * @tdls_reg_peer: register tdls peer with datapath * @tdls_dereg_peer: deregister tdls peer from datapath -#else - * @tdls_tl_peer_data: userdata for register/deregister TDLS peer - * @tdls_reg_tl_peer: callback to register the TDLS peer with TL - * @tdls_dereg_tl_peer: callback to unregister the TDLS peer -#endif * @tx_q_ack: queue for tx frames waiting for ack * @tdls_con_cap: tdls concurrency support * @tdls_send_mgmt_req: store eWNI_SME_TDLS_SEND_MGMT_REQ value @@ -219,15 +213,9 @@ struct tdls_soc_priv_obj { void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; -#ifdef USE_NEW_TDLS_PEER_CALLBACKS void *tdls_peer_context; tdls_register_peer_callback tdls_reg_peer; tdls_deregister_peer_callback tdls_dereg_peer; -#else - void *tdls_tl_peer_data; - tdls_register_tl_peer_callback tdls_reg_tl_peer; - tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; -#endif tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 0ada980ae637..4458872aaf4b 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -547,8 +547,6 @@ typedef void (*tdls_evt_callback) (void *data, typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, struct tdls_tx_cnf *tx_ack_cnf_cb_data); -#ifdef USE_NEW_TDLS_PEER_CALLBACKS - /* This callback is used to register TDLS peer with the datapath */ typedef QDF_STATUS (*tdls_register_peer_callback)(void *userdata, uint32_t vdev_id, @@ -561,23 +559,6 @@ typedef QDF_STATUS (*tdls_deregister_peer_callback)(void *userdata, uint32_t vdev_id, uint8_t sta_id); -#else - -/* This callback is used to register TDLS peer with TL */ -typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata, - uint32_t vdev_id, - const uint8_t *mac, - uint16_t stat_id, - uint8_t ucastsig, - uint8_t qos); - -/* This callback is used to deregister TDLS peer */ -typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, - uint32_t vdev_id, - uint8_t sta_id); - -#endif - /* This callback is used to update datapath vdev flags */ typedef QDF_STATUS (*tdls_dp_vdev_update_flags_callback)(void *cbk_data, @@ -598,15 +579,9 @@ typedef QDF_STATUS * @tdls_evt_cb_data: tdls event data * @ack_cnf_cb: tdls tx ack callback to indicate the tx status * @tx_ack_cnf_cb_data: tdls tx ack user data -#ifdef USE_NEW_TDLS_PEER_CALLBACKS * @tdls_peer_context: userdata for register/deregister TDLS peer * @tdls_reg_peer: register tdls peer with datapath * @tdls_dereg_peer: deregister tdls peer from datapath -#else - * @tdls_tl_peer_data: userdata for register/deregister TDLS peer - * @tdls_reg_tl_peer: tdls register tdls peer - * @tdls_dereg_tl_peer: tdls deregister tdls peer -#endif * @tdls_dp_vdev_update: update vdev flags in datapath */ struct tdls_start_params { @@ -625,15 +600,9 @@ struct tdls_start_params { void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; void *tx_ack_cnf_cb_data; -#ifdef USE_NEW_TDLS_PEER_CALLBACKS void *tdls_peer_context; tdls_register_peer_callback tdls_reg_peer; tdls_deregister_peer_callback tdls_dereg_peer; -#else - void *tdls_tl_peer_data; - tdls_register_tl_peer_callback tdls_reg_tl_peer; - tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; -#endif tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; }; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index f4aecc150273..9134509eacc0 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -207,17 +207,10 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; -#ifdef USE_NEW_TDLS_PEER_CALLBACKS - /* Save callbacks to register/deregister TDLS sta with TL */ + /* Save callbacks to register/deregister TDLS sta with datapath */ soc_obj->tdls_reg_peer = req->tdls_reg_peer; soc_obj->tdls_dereg_peer = req->tdls_dereg_peer; soc_obj->tdls_peer_context = req->tdls_peer_context; -#else - /* Save callbacks to register/deregister TDLS sta with TL */ - soc_obj->tdls_reg_tl_peer = req->tdls_reg_tl_peer; - soc_obj->tdls_dereg_tl_peer = req->tdls_dereg_tl_peer; - soc_obj->tdls_tl_peer_data = req->tdls_tl_peer_data; -#endif /* Save legacy PE/WMA commands in TDLS soc object */ soc_obj->tdls_send_mgmt_req = req->tdls_send_mgmt_req; From 38dc9fe98dd5739a56ae3ddfb2d00b70d86212f9 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Fri, 2 Mar 2018 13:32:57 -0800 Subject: [PATCH 217/404] qcacmn: Remove obsolete TDLS signature Change "qcacmn: Remove obsolete TDLS peer callback interface" (Change-Id I32bb1f633b1dd1514aa6e4c3fdea044b3bca0009) removed the obsolete logic that utilized the TDLS signature field, so remove all remaining traces of it. Change-Id: I731c81a0b1f7e5d885cfa18a551ad0d3af3cecbe CRs-Fixed: 2200972 --- core/src/wlan_tdls_cmds_process.c | 4 ---- core/src/wlan_tdls_main.h | 2 -- core/src/wlan_tdls_peer.c | 15 --------------- core/src/wlan_tdls_peer.h | 15 +-------------- 4 files changed, 1 insertion(+), 35 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index ffbc701f2d48..9f9239c42801 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1417,11 +1417,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) if (QDF_IS_STATUS_ERROR(status)) { tdls_err("set staid failed"); status = QDF_STATUS_E_FAILURE; - goto cmddone; } - - tdls_set_signature(vdev_obj, rsp->peermac.bytes, - rsp->ucast_sig); } else { status = QDF_STATUS_E_FAILURE; } diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index fbddfedc1cf0..6867ffd4f1e9 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -278,7 +278,6 @@ struct tdls_peer_mlme_info { * @rssi: rssi * @tdls_support: tdls support * @link_status: tdls link status - * @signature: signature * @is_responder: is responder * @discovery_processed: dicovery processed * @discovery_attempt: discovery attempt @@ -311,7 +310,6 @@ struct tdls_peer { int8_t rssi; enum tdls_peer_capab tdls_support; enum tdls_link_state link_status; - uint8_t signature; uint8_t is_responder; uint8_t discovery_processed; uint16_t discovery_attempt; diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index a254ff5fd3f2..998b4796a100 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -684,21 +684,6 @@ QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, return QDF_STATUS_SUCCESS; } -QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj, - const uint8_t *macaddr, uint8_t signature) -{ - struct tdls_peer *peer; - - peer = tdls_find_peer(vdev_obj, macaddr); - if (!peer) { - tdls_err("peer is NULL"); - return QDF_STATUS_E_FAILURE; - } - peer->signature = signature; - - return QDF_STATUS_SUCCESS; -} - QDF_STATUS tdls_set_force_peer(struct tdls_vdev_priv_obj *vdev_obj, const uint8_t *macaddr, bool forcepeer) { diff --git a/core/src/wlan_tdls_peer.h b/core/src/wlan_tdls_peer.h index 7a510c1dac64..41ffa8096f54 100644 --- a/core/src/wlan_tdls_peer.h +++ b/core/src/wlan_tdls_peer.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 @@ -173,19 +173,6 @@ void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, const uint8_t *macaddr, uint8_t sta_id); -/** - * tdls_set_signature() - set TDLS peer's signature - * @vdev_obj: TDLS vdev object - * @macaddr: MAC address of the TDLS peer - * @signature: signature value - * - * This is used in scheduler thread context, no lock required. - * - * Return: QDF_STATUS_SUCCESS if success; other values if failed - */ -QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj, - const uint8_t *macaddr, uint8_t signature); - /** * tdls_set_force_peer() - set/clear is_forced_peer flag on peer * @vdev_obj: TDLS vdev object From 8c2468e41e493ca81acf289d0e4282acedb52949 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 5 Mar 2018 12:06:17 -0800 Subject: [PATCH 218/404] qcacmn: Remove DPU signatures from TDLS Add STA Response The ucast_sig and bcast_sig fields in struct tdls_add_sta_rsp date back to a previous version of the driver that used these signatures to synchronize the data plane with the control plane. However the current version of the driver does not use these parameters, so remove them as the final stage of the plan to completely remove these signatures from throughout the driver. Since the converged struct tdls_add_sta_rsp must exactly match the legacy tSirTdlsAddStaRsp data structure, this change is co-dependent with the qcacld-3.0 change: qcacld-3.0: Remove DPU signatures from TDLS Add STA Response Change-Id: I765b090fc5dbe9bdaf83b05a72223c0a12f71a18 Change-Id: I7750fac9e4870d75358606bea427a5dbab97c665 CRs-Fixed: 2200973 --- core/src/wlan_tdls_cmds_process.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 10e20cfa1b5e..938e96671608 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.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 @@ -140,8 +140,6 @@ struct tdls_add_sta_req { * @session_id: session id * @sta_id: sta id * @sta_type: sta type - * @ucast_sig: unicast signature - * @bcast_sig: broadcast signature * @tdls_oper: add peer type * @psoc: soc object */ @@ -153,8 +151,6 @@ struct tdls_add_sta_rsp { uint8_t session_id; uint16_t sta_id; uint16_t sta_type; - uint8_t ucast_sig; - uint8_t bcast_sig; enum tdls_add_oper tdls_oper; struct wlan_objmgr_psoc *psoc; }; From b8a1068a4822be724beb6af84b9a3aa647323adb Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Tue, 13 Mar 2018 18:23:03 +0800 Subject: [PATCH 219/404] qcacmn: Set flag for deleting tx context Duplicate for MGMT frame tx ack comes before scheduler process first one, then it will use freed memory. Add flag to avoid this case. Change-Id: Id50f692ced0ddd5b267d096818f3e7ff12bf07aa CRs-Fixed: 2188110 --- core/src/wlan_p2p_off_chan_tx.h | 2 ++ dispatcher/src/wlan_p2p_tgt_api.c | 6 ++++++ dispatcher/src/wlan_p2p_ucfg_api.c | 1 + 3 files changed, 9 insertions(+) diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index 41bdc806d527..713c3c35a811 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -154,6 +154,7 @@ struct p2p_frame_info { * @off_chan: Is this off channel tx * @no_cck: Required cck or not * @no_ack: Required ack or not + * @is_deleting: Received tx ack and waiting for deleting * @duration: Duration for the RoC * @tx_timer: RoC timer * @frame_info: Frame type information @@ -170,6 +171,7 @@ struct tx_action_context { bool off_chan; bool no_cck; bool no_ack; + bool is_deleting; uint32_t duration; qdf_mc_timer_t tx_timer; struct p2p_frame_info frame_info; diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 1762cf2b7618..6c41bb27a2dd 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -145,6 +145,12 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, return QDF_STATUS_E_FAULT; } + if (tx_ctx->is_deleting) { + p2p_info("Received duplicate tx ack"); + return QDF_STATUS_SUCCESS; + } + tx_ctx->is_deleting = true; + tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event)); if (!tx_conf_event) { p2p_err("Failed to allocate tx cnf event"); diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 8e2ea051aa72..af51792cf72b 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -264,6 +264,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, tx_action->no_cck = mgmt_frm->no_cck; tx_action->no_ack = mgmt_frm->dont_wait_for_ack; tx_action->off_chan = mgmt_frm->off_chan; + tx_action->is_deleting = false; tx_action->buf = qdf_mem_malloc(tx_action->buf_len); if (!(tx_action->buf)) { p2p_err("Failed to allocate buffer for action frame"); From 8bd8fe504f43e9ce50367beaf8bb27abf0c09c7c Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 2 Mar 2018 15:32:15 +0800 Subject: [PATCH 220/404] qcacmn: Enable more debug information for P2P Change log level and enable more debug information for P2P connection. Change-Id: I459869d48c7f688246bc6e566ad2fae395ff8a2b CRs-Fixed: 2204758 --- core/src/wlan_p2p_main.c | 4 ++-- core/src/wlan_p2p_off_chan_tx.c | 22 +++++++++++----------- core/src/wlan_p2p_roc.c | 16 ++++++++-------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index a09edbbc57e6..ba86929c088c 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -199,7 +199,7 @@ static QDF_STATUS p2p_vdev_obj_create_notification( } mode = wlan_vdev_mlme_get_opmode(vdev); - p2p_debug("vdev mode:%d", mode); + p2p_info("vdev mode:%d", mode); if (mode != QDF_P2P_GO_MODE) { p2p_debug("won't create p2p vdev private object if it is not GO"); return QDF_STATUS_SUCCESS; @@ -254,7 +254,7 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( } mode = wlan_vdev_mlme_get_opmode(vdev); - p2p_debug("vdev mode:%d", mode); + p2p_info("vdev mode:%d", mode); if (mode != QDF_P2P_GO_MODE) { p2p_debug("no p2p vdev private object if it is not GO"); return QDF_STATUS_SUCCESS; diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 62ef353e7b76..4aa1f44c93e6 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -687,7 +687,7 @@ static QDF_STATUS p2p_tx_update_connection_status( if (tx_frame_info->public_action_type != P2P_PUBLIC_ACTION_NOT_SUPPORT) - p2p_debug("%s ---> OTA to " QDF_MAC_ADDR_STR, + p2p_info("%s ---> OTA to " QDF_MAC_ADDR_STR, p2p_get_frame_type_str(tx_frame_info), QDF_MAC_ADDR_ARRAY(mac_to)); @@ -695,13 +695,13 @@ static QDF_STATUS p2p_tx_update_connection_status( P2P_PUBLIC_ACTION_PROV_DIS_REQ) && (p2p_soc_obj->connection_status == P2P_NOT_ACTIVE)) { p2p_soc_obj->connection_status = P2P_GO_NEG_PROCESS; - p2p_debug("[P2P State]Inactive state to GO negotiation progress state"); + p2p_info("[P2P State]Inactive state to GO negotiation progress state"); } else if ((tx_frame_info->public_action_type == P2P_PUBLIC_ACTION_NEG_CNF) && (p2p_soc_obj->connection_status == P2P_GO_NEG_PROCESS)) { p2p_soc_obj->connection_status = P2P_GO_NEG_COMPLETED; - p2p_debug("[P2P State]GO nego progress to GO nego completed state"); + p2p_info("[P2P State]GO nego progress to GO nego completed state"); } return QDF_STATUS_SUCCESS; @@ -731,7 +731,7 @@ static QDF_STATUS p2p_rx_update_connection_status( if (rx_frame_info->public_action_type != P2P_PUBLIC_ACTION_NOT_SUPPORT) - p2p_debug("%s <--- OTA from " QDF_MAC_ADDR_STR, + p2p_info("%s <--- OTA from " QDF_MAC_ADDR_STR, p2p_get_frame_type_str(rx_frame_info), QDF_MAC_ADDR_ARRAY(mac_from)); @@ -739,18 +739,18 @@ static QDF_STATUS p2p_rx_update_connection_status( P2P_PUBLIC_ACTION_PROV_DIS_REQ) && (p2p_soc_obj->connection_status == P2P_NOT_ACTIVE)) { p2p_soc_obj->connection_status = P2P_GO_NEG_PROCESS; - p2p_debug("[P2P State]Inactive state to GO negotiation progress state"); + p2p_info("[P2P State]Inactive state to GO negotiation progress state"); } else if ((rx_frame_info->public_action_type == P2P_PUBLIC_ACTION_NEG_CNF) && (p2p_soc_obj->connection_status == P2P_GO_NEG_PROCESS)) { p2p_soc_obj->connection_status = P2P_GO_NEG_COMPLETED; - p2p_debug("[P2P State]GO negotiation progress to GO negotiation completed state"); + p2p_info("[P2P State]GO negotiation progress to GO negotiation completed state"); } else if ((rx_frame_info->public_action_type == P2P_PUBLIC_ACTION_INVIT_REQ) && (p2p_soc_obj->connection_status == P2P_NOT_ACTIVE)) { p2p_soc_obj->connection_status = P2P_GO_NEG_COMPLETED; - p2p_debug("[P2P State]Inactive state to GO negotiation completed state Autonomous GO formation"); + p2p_info("[P2P State]Inactive state to GO negotiation completed state Autonomous GO formation"); } return QDF_STATUS_SUCCESS; @@ -1125,7 +1125,7 @@ static QDF_STATUS p2p_move_tx_context_to_ack_queue( &tx_ctx->node); if (status != QDF_STATUS_SUCCESS) p2p_err("Failed to insert off chan tx context to wait ack req queue"); - p2p_debug("insert tx context to wait for roc queue, status:%d", + p2p_debug("insert tx context to wait for ack queue, status:%d", status); return status; @@ -1270,7 +1270,7 @@ static void p2p_tx_timeout(void *pdata) { struct tx_action_context *tx_ctx = pdata; - p2p_debug("pdata:%pK", pdata); + p2p_info("pdata:%pK", pdata); if (!tx_ctx || !(tx_ctx->p2p_soc_obj)) { p2p_err("invalid tx context or p2p soc object"); @@ -1674,7 +1674,7 @@ QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) struct tx_action_context *curr_tx_ctx; qdf_list_node_t *p_node; - p2p_debug("clean up tx queue wait for roc, size:%d", + p2p_info("clean up tx queue wait for roc, size:%d", qdf_list_size(&p2p_soc_obj->tx_q_roc)); while (qdf_list_remove_front(&p2p_soc_obj->tx_q_roc, &p_node) == @@ -1686,7 +1686,7 @@ QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) qdf_mem_free(curr_tx_ctx); } - p2p_debug("clean up tx queue wait for ack, size:%d", + p2p_info("clean up tx queue wait for ack, size:%d", qdf_list_size(&p2p_soc_obj->tx_q_ack)); while (qdf_list_remove_front(&p2p_soc_obj->tx_q_ack, &p_node) == QDF_STATUS_SUCCESS) { diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 47ad67d2ba93..979f92ec3260 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -658,7 +658,7 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) qdf_list_node_t *p_node; QDF_STATUS status, ret; - p2p_debug("clean up idle roc request, roc queue size:%d", + p2p_info("clean up idle roc request, roc queue size:%d", qdf_list_size(&p2p_soc_obj->roc_q)); status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); @@ -666,7 +666,7 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_info("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, @@ -686,14 +686,14 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) } } - p2p_debug("clean up started roc request, roc queue size:%d", + p2p_info("clean up started roc request, roc queue size:%d", qdf_list_size(&p2p_soc_obj->roc_q)); status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); while (QDF_IS_STATUS_SUCCESS(status)) { roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx_ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_info("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx_ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, @@ -723,14 +723,14 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( struct p2p_roc_context *roc_ctx; qdf_list_node_t *p_node; - p2p_debug("clean up idle roc request, roc queue size:%d, vdev id:%d", + p2p_info("clean up idle roc request, roc queue size:%d, vdev id:%d", qdf_list_size(&p2p_soc_obj->roc_q), vdev_id); status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); while (QDF_IS_STATUS_SUCCESS(status)) { roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_info("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, @@ -750,14 +750,14 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( } } - p2p_debug("clean up started roc request, roc queue size:%d", + p2p_info("clean up started roc request, roc queue size:%d", qdf_list_size(&p2p_soc_obj->roc_q)); status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); while (QDF_IS_STATUS_SUCCESS(status)) { roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + p2p_info("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, roc_ctx->phy_mode, roc_ctx->duration, From f54054683ba1a67629f25ecef17af04c6690d072 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 9 Mar 2018 15:26:50 +0800 Subject: [PATCH 221/404] qcacmn: Handle multi P2P MGMT frame TX When P2P mgmt frame comes and there is same channel ROC requested but not start, it will be failed to restart ROC timer and then drop this frame. Change-Id: I40cc2b66a266ebf2aa1017669e6d97b1c7de3da1 CRs-Fixed: 2202954 --- core/src/wlan_p2p_off_chan_tx.c | 67 +++++++++++---------------------- core/src/wlan_p2p_roc.c | 9 ++--- 2 files changed, 27 insertions(+), 49 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 4aa1f44c93e6..75fbcd3c54e8 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1034,22 +1034,17 @@ static struct tx_action_context *p2p_find_tx_ctx( * p2p_find_tx_ctx_by_roc() - find tx context by roc * @p2p_soc_obj: p2p soc object * @cookie: cookie to roc context - * @is_roc_q: it is in waiting for roc queue - * @is_ack_q: it is in waiting for ack queue * * This function finds out tx context by roc context. * * Return: pointer to tx context */ static struct tx_action_context *p2p_find_tx_ctx_by_roc( - struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie, - bool *is_roc_q, bool *is_ack_q) + struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie) { struct tx_action_context *cur_tx_ctx; qdf_list_node_t *p_node; QDF_STATUS status; - *is_roc_q = false; - *is_ack_q = false; p2p_debug("Start to find tx ctx, p2p soc_obj:%pK, cookie:%llx", p2p_soc_obj, cookie); @@ -1059,7 +1054,6 @@ static struct tx_action_context *p2p_find_tx_ctx_by_roc( cur_tx_ctx = qdf_container_of(p_node, struct tx_action_context, node); if (cur_tx_ctx->roc_cookie == cookie) { - *is_roc_q = true; p2p_debug("find tx ctx, cookie:%llx", cookie); return cur_tx_ctx; } @@ -1067,19 +1061,6 @@ static struct tx_action_context *p2p_find_tx_ctx_by_roc( p_node, &p_node); } - status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node); - while (QDF_IS_STATUS_SUCCESS(status)) { - cur_tx_ctx = qdf_container_of(p_node, - struct tx_action_context, node); - if (cur_tx_ctx->roc_cookie == cookie) { - *is_ack_q = true; - p2p_debug("find tx ctx, cookie:%llx", cookie); - return cur_tx_ctx; - } - status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, - p_node, &p_node); - } - return NULL; } @@ -1639,31 +1620,19 @@ void p2p_dump_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie) { - bool is_roc_q = false; - bool is_ack_q = false; struct tx_action_context *cur_tx_ctx; - QDF_STATUS status = QDF_STATUS_E_FAILURE; + QDF_STATUS status = QDF_STATUS_SUCCESS; - cur_tx_ctx = p2p_find_tx_ctx_by_roc(p2p_soc_obj, cookie, - &is_roc_q, &is_ack_q); - p2p_debug("tx_ctx:%pK, is_roc_q:%d, is_ack_q:%d", cur_tx_ctx, - is_roc_q, is_ack_q); - if (cur_tx_ctx) { - if (is_roc_q) { - status = p2p_execute_tx_action_frame(cur_tx_ctx); - if (status != QDF_STATUS_SUCCESS) { - p2p_send_tx_conf(cur_tx_ctx, false); - p2p_remove_tx_context(cur_tx_ctx); - } + cur_tx_ctx = p2p_find_tx_ctx_by_roc(p2p_soc_obj, cookie); + + while (cur_tx_ctx) { + p2p_debug("tx_ctx:%pK", cur_tx_ctx); + status = p2p_execute_tx_action_frame(cur_tx_ctx); + if (status != QDF_STATUS_SUCCESS) { + p2p_send_tx_conf(cur_tx_ctx, false); + p2p_remove_tx_context(cur_tx_ctx); } - if (is_ack_q) { - p2p_debug("Already sent and waiting for ack"); - status = QDF_STATUS_SUCCESS; - } - } else { - p2p_debug("Failed to find tx ctx by cookie, cookie %llx", - cookie); - status = QDF_STATUS_E_INVAL; + cur_tx_ctx = p2p_find_tx_ctx_by_roc(p2p_soc_obj, cookie); } return status; @@ -1768,8 +1737,18 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) /* For off channel tx case */ curr_roc_ctx = p2p_find_current_roc_ctx(p2p_soc_obj); if (curr_roc_ctx && (curr_roc_ctx->chan == tx_ctx->chan)) { - if (curr_roc_ctx->roc_state != - ROC_STATE_CANCEL_IN_PROG) { + if ((curr_roc_ctx->roc_state == ROC_STATE_REQUESTED) || + (curr_roc_ctx->roc_state == ROC_STATE_STARTED)) { + tx_ctx->roc_cookie = (uintptr_t)curr_roc_ctx; + status = qdf_list_insert_back( + &p2p_soc_obj->tx_q_roc, + &tx_ctx->node); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to insert off chan tx context to wait roc req queue"); + goto fail; + } else + return QDF_STATUS_SUCCESS; + } else if (curr_roc_ctx->roc_state == ROC_STATE_ON_CHAN) { p2p_adjust_tx_wait(tx_ctx); status = p2p_restart_roc_timer(curr_roc_ctx); curr_roc_ctx->tx_ctx = tx_ctx; diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 979f92ec3260..12893878bb68 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -479,13 +479,12 @@ static QDF_STATUS p2p_process_ready_on_channel_evt( p2p_debug("user required roc, send roc event"); status = p2p_send_roc_event(roc_ctx, ROC_EVENT_READY_ON_CHAN); - } else { - p2p_debug("roc for off chan tx, ready to send frame"); - cookie = (uintptr_t)roc_ctx; - /* ready to tx frame */ - p2p_ready_to_tx_frame(p2p_soc_obj, cookie); } + cookie = (uintptr_t)roc_ctx; + /* ready to tx frame */ + p2p_ready_to_tx_frame(p2p_soc_obj, cookie); + return status; } From 119ed6b1e1417aecccdb327ad058d170ac2fe22c Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Sat, 17 Mar 2018 18:48:31 +0530 Subject: [PATCH 222/404] qcacmn: Add ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN Add ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN option for the ini gDualMacFeatureDisable. To enable DBS support for the connection and disable DBS support for the scan. Change-Id: I05c613467195fffac98e79b7e4a2991471ac1d80 CRs-Fixed: 2207820 --- inc/wlan_policy_mgr_public_struct.h | 3 +++ src/wlan_policy_mgr_get_set_utils.c | 15 +++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index d0793d372b5b..67c4af2c730a 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -815,6 +815,8 @@ enum policy_mgr_hw_mode_change { * for connection but keep dbs for scan but switch off the async scan * @ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF: enable dbs support for * connection and scan but switch off the async scan + * @ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN: Enable DBS support for connection and + * disable DBS support for scan */ enum dbs_support { ENABLE_DBS_CXN_AND_SCAN, @@ -822,6 +824,7 @@ enum dbs_support { DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN, DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF, ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF, + ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN }; /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 31c67cf2a150..6cc6e2f1077b 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2683,11 +2683,13 @@ uint32_t policy_mgr_get_hw_dbs_nss(struct wlan_objmgr_psoc *psoc, bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc) { - if (DISABLE_DBS_CXN_AND_SCAN != - wlan_objmgr_psoc_get_dual_mac_disable(psoc)) - return true; + if ((DISABLE_DBS_CXN_AND_SCAN == + wlan_objmgr_psoc_get_dual_mac_disable(psoc)) || + (ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN == + wlan_objmgr_psoc_get_dual_mac_disable(psoc))) + return false; - return false; + return true; } void policy_mgr_set_cur_conc_system_pref(struct wlan_objmgr_psoc *psoc, @@ -2752,6 +2754,11 @@ QDF_STATUS policy_mgr_get_updated_scan_and_fw_mode_config( dual_mac_disable_ini); WMI_DBS_CONC_SCAN_CFG_ASYNC_DBS_SCAN_SET(*scan_config, 0); break; + case ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN: + policy_mgr_debug("%s: dual_mac_disable_ini:%d ", __func__, + dual_mac_disable_ini); + WMI_DBS_CONC_SCAN_CFG_DBS_SCAN_SET(*scan_config, 0); + break; default: break; } From a7bff60cf063857ea080803240efe6018bb230c2 Mon Sep 17 00:00:00 2001 From: wadesong Date: Wed, 28 Mar 2018 14:48:51 +0800 Subject: [PATCH 223/404] qcacmn: Suppress the verbose log from policy mgr When DBS is disabled in WLAN INI file(e.g. on some platforms where RM chipset is attached), the policy manager will keep posting a verbose message saying 'DBS is disabled from ini'. This isn't exhibiting much useful information, and may cause watchdog bark when SnS stress is running. Suppress the verbose log by lowering it's debug level. Change-Id: Ie8d5a1784940f483cc671da43f734851c0b5adb6 CRs-Fixed: 2214201 --- src/wlan_policy_mgr_get_set_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 6cc6e2f1077b..8b5fa354576b 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -743,7 +743,7 @@ bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc) struct policy_mgr_psoc_priv_obj *pm_ctx; if (policy_mgr_is_dual_mac_disabled_in_ini(psoc)) { - policy_mgr_err("DBS is disabled from ini"); + policy_mgr_debug("DBS is disabled from ini"); return false; } From d7b52a1cc72f31297156feb8de38cc6492bd11b0 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 28 Mar 2018 11:41:04 -0700 Subject: [PATCH 224/404] qcacmn: Use correct enum type in function call Use correct enum type in tdls_determine_channel_opclass, tdls_process_antenna_switch & tdls_process_send_mgmt_rsp. Change-Id: Idd4e7ac47196e3e11971fe3013805b6a8551c8de CRs-Fixed: 2214003 --- core/src/wlan_tdls_cmds_process.c | 6 ++++-- core/src/wlan_tdls_peer.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 9f9239c42801..30bbe01e0885 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1300,7 +1300,7 @@ QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp) if (tdls_soc && tdls_soc->tdls_event_cb) { ind.vdev = vdev; - ind.status = rsp->status_code; + ind.status = status; tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, TDLS_EVENT_MGMT_TX_ACK_CNF, &ind); } @@ -2276,7 +2276,9 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) vdev_id = wlan_vdev_get_id(vdev); opmode = wlan_vdev_mlme_get_opmode(vdev); - channel = policy_mgr_get_channel(soc_obj->soc, opmode, &vdev_id); + channel = policy_mgr_get_channel(soc_obj->soc, + policy_mgr_convert_device_mode_to_qdf_type(opmode), + &vdev_id); /* Check supported nss for TDLS, if is 1x1, no need to teardown links */ if (WLAN_REG_IS_24GHZ_CH(channel)) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 998b4796a100..7e2f7e597b91 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -397,7 +397,8 @@ static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev); *channel = policy_mgr_get_channel(soc_obj->soc, - opmode, &vdev_id); + policy_mgr_convert_device_mode_to_qdf_type(opmode), + &vdev_id); *opclass = 0; } else { *channel = peer->pref_off_chan_num; From b4f30633136af6d4330978363a16c49331baf060 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 28 Mar 2018 17:23:55 -0700 Subject: [PATCH 225/404] qcacmn: Use enum type policy_mgr_con_mode instead of enum QDF_OPMODE Use enum type policy_mgr_con_mode instead of enum QDF_OPMODE. Change-Id: Ia7a6bb5e05c6dac650dc6386734462547365a4eb CRs-Fixed: 2214003 --- inc/wlan_policy_mgr_public_struct.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 67c4af2c730a..c45f3e63f08d 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -219,6 +219,7 @@ enum policy_mgr_conc_priority_mode { * @PM_P2P_CLIENT_MODE: P2P client mode * @PM_P2P_GO_MODE: P2P Go mode * @PM_IBSS_MODE: IBSS mode + * @PM_NDI_MODE: NDI mode * @PM_MAX_NUM_OF_MODE: max value place holder */ enum policy_mgr_con_mode { @@ -227,6 +228,7 @@ enum policy_mgr_con_mode { PM_P2P_CLIENT_MODE, PM_P2P_GO_MODE, PM_IBSS_MODE, + PM_NDI_MODE, PM_MAX_NUM_OF_MODE }; From 0d506a4d64bb4a8a2d274a76bc4e02a040c541c0 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Wed, 28 Mar 2018 18:05:30 -0700 Subject: [PATCH 226/404] qcacmn: Fix LLVM compiling issues Remove typedef redefinition, use correct enum type, remove extra parentheses and correct header guard. CRs-Fixed: 2214003 Change-Id: I0a75c70cd530590a16f6bfa884955ebc26906de0 --- src/wlan_policy_mgr_get_set_utils.c | 2 +- src/wlan_policy_mgr_tables_2x2_dbs_i.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 8b5fa354576b..2e027d67b2ae 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2176,7 +2176,7 @@ bool policy_mgr_is_sta_active_connection_exists( struct wlan_objmgr_psoc *psoc) { return (!policy_mgr_mode_specific_connection_count( - psoc, QDF_STA_MODE, NULL)) ? false : true; + psoc, PM_STA_MODE, NULL)) ? false : true; } bool policy_mgr_is_any_nondfs_chnl_present(struct wlan_objmgr_psoc *psoc, diff --git a/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/src/wlan_policy_mgr_tables_2x2_dbs_i.h index cbef81312141..815bdd5d10a6 100644 --- a/src/wlan_policy_mgr_tables_2x2_dbs_i.h +++ b/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -26,7 +26,7 @@ */ #ifndef __WLAN_POLICY_MGR_TABLES_2X2_DBS_H -#define __WLAN_POLICY_MGR_TABLESY_2X2_DBS_H +#define __WLAN_POLICY_MGR_TABLES_2X2_DBS_H #include "wlan_policy_mgr_api.h" From e727d0d95d72a143ee443a8460ea24aedec9638a Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 29 Mar 2018 12:27:35 -0700 Subject: [PATCH 227/404] qcacmn: Fix compilation warnings in TDLS Fix the warning issue in TDLS, which popped up with newer compiler options. Change-Id: I1516a47ec01faa9315d2045ebcfe49097680e80d CRs-Fixed: 2215517 --- core/src/wlan_tdls_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index b271b3209a57..00d31dad7d63 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -284,7 +284,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request( qdf_mem_copy(tdls_mgmt_req->peer_mac.bytes, action_req->tdls_mgmt.peer_mac.bytes, QDF_MAC_ADDR_SIZE); - if (action_req->tdls_mgmt.len && action_req->tdls_mgmt.buf) { + if (action_req->tdls_mgmt.len) { qdf_mem_copy(tdls_mgmt_req->add_ie, action_req->tdls_mgmt.buf, action_req->tdls_mgmt.len); } From c8754ac4bdc0dfd884c7676894fc652c610debb2 Mon Sep 17 00:00:00 2001 From: jiad Date: Fri, 30 Mar 2018 16:33:59 +0800 Subject: [PATCH 228/404] qcacmn: fix ipa mcc scc event notification Issue is under AP-AP MCC config, mcc event is not sent from wlan to IPA driver. mcc mode is decided with the help of connection table. But for AP mode, mcc mode is checked and updated before connection table is updated by adding the SAP vdev entry. Fix is to make ipa mcc mode check and notification when connection table is updated. Change-Id: I1ba3fcb874b014f05cebd8af90530b9aa54980a2 CRs-Fixed: 2214351 --- inc/wlan_policy_mgr_api.h | 2 ++ src/wlan_policy_mgr_core.c | 13 +++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 14 ++++++++++++++ src/wlan_policy_mgr_init_deinit.c | 2 ++ 4 files changed, 31 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index a54e46cf2799..461064e440f8 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -866,10 +866,12 @@ struct policy_mgr_cdp_cbacks { * from policy manager * @hdd_disable_lro_in_concurrency: Callback to disable LRO * @hdd_set_rx_mode_rps_cb: Callback to set RPS + * @hdd_ipa_set_mcc_mode_cb: Callback to set mcc mode for ipa module */ struct policy_mgr_dp_cbacks { void (*hdd_disable_lro_in_concurrency)(bool); void (*hdd_set_rx_mode_rps_cb)(bool); + void (*hdd_ipa_set_mcc_mode_cb)(bool); }; /** diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 161fa92ae91f..b6569e589173 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -552,6 +552,7 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, bool in_use) { struct policy_mgr_psoc_priv_obj *pm_ctx; + bool mcc_mode; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -564,6 +565,8 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, conn_index); return; } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); pm_conc_connection_list[conn_index].mode = mode; pm_conc_connection_list[conn_index].chan = chan; pm_conc_connection_list[conn_index].bw = bw; @@ -572,6 +575,7 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, pm_conc_connection_list[conn_index].original_nss = original_nss; pm_conc_connection_list[conn_index].vdev_id = vdev_id; pm_conc_connection_list[conn_index].in_use = in_use; + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); if (pm_ctx->mode_change_cb) pm_ctx->mode_change_cb(); @@ -580,6 +584,15 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, if (pm_ctx->cdp_cbacks.cdp_update_mac_id) pm_ctx->cdp_cbacks.cdp_update_mac_id(psoc, vdev_id, mac); + /* IPA only cares about STA or SAP mode */ + if (mode == PM_STA_MODE || mode == PM_SAP_MODE) { + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb) + pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode); + } } /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 2e027d67b2ae..fe2551209555 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1190,6 +1190,7 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, { struct policy_mgr_psoc_priv_obj *pm_ctx; QDF_STATUS qdf_status; + bool mcc_mode; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1248,6 +1249,19 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, policy_mgr_dump_current_concurrency(psoc); + /* + * Check mode of entry being removed. Update mcc_mode only when STA + * or SAP since IPA only cares about these two + */ + if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) { + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + mcc_mode = policy_mgr_current_concurrency_is_mcc(psoc); + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + if (pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb) + pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb(mcc_mode); + } + return qdf_status; } diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index eb9eab9e2219..992e0ff2aeac 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -649,6 +649,8 @@ QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc, dp_cbacks->hdd_disable_lro_in_concurrency; pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb = dp_cbacks->hdd_set_rx_mode_rps_cb; + pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb = + dp_cbacks->hdd_ipa_set_mcc_mode_cb; return QDF_STATUS_SUCCESS; } From 949b6394fe1a45790b3bea2b5c2585748a2e40e8 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 23 Mar 2018 05:25:12 -0400 Subject: [PATCH 229/404] qcacmn: Fix OPPS set failed on p2p GO Find the correct P2P GO vdev and update the vdev_id to ps_config before set opps parameter to Firmware. Change-Id: Ie5435de8330f6e9c13f645e19d80cbd97f1f027d CRs-Fixed: 2203066 --- dispatcher/src/wlan_p2p_ucfg_api.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index af51792cf72b..4246f4bded0e 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -325,6 +325,7 @@ QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, QDF_STATUS status = QDF_STATUS_E_FAILURE; uint16_t obj_id; struct wlan_objmgr_vdev *vdev; + struct p2p_ps_config go_ps_config; p2p_debug("soc:%pK, vdev_id:%d, opp_ps:%d, ct_window:%d, count:%d, duration:%d, duration:%d, ps_selection:%d", soc, ps_config->vdev_id, ps_config->opp_ps, @@ -342,19 +343,26 @@ QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, obj_id, WLAN_P2P_ID); if (vdev) { - if (is_p2p_ps_allowed(vdev, - WLAN_UMAC_COMP_P2P) == false) { - p2p_debug("p2p set ps, NoA is disabled as legacy STA is connected to GO."); - return QDF_STATUS_E_BUSY; + if (is_p2p_ps_allowed(vdev, WLAN_UMAC_COMP_P2P)) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + break; } wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("skip p2p set ps vdev %d, NoA is disabled as legacy STA is connected to GO.", + obj_id); } } + if (obj_id >= WLAN_UMAC_PSOC_MAX_VDEVS) { + p2p_debug("No GO found!"); + return QDF_STATUS_E_INVAL; + } + go_ps_config = *ps_config; + go_ps_config.vdev_id = obj_id; p2p_ops = ucfg_p2p_psoc_get_tx_ops(soc); if (p2p_ops->set_ps) { - status = p2p_ops->set_ps(soc, ps_config); - p2p_debug("p2p set ps, status:%d", status); + status = p2p_ops->set_ps(soc, &go_ps_config); + p2p_debug("p2p set ps vdev %d, status:%d", obj_id, status); } return status; From 9098eacdc8c6a813049599824eba8a6231620ff8 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 9 Apr 2018 16:08:22 -0700 Subject: [PATCH 230/404] qcacmn: Serialize TDLS set state cmd to firmware Serialize TDLS set command to firmware to avoid out of sequence WMI commands. Change-Id: Ia5d493b329dfa687e532797a5b47f3b82a0b3f76 CRs-Fixed: 2214605 --- core/src/wlan_tdls_main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 782408f6d073..391713849159 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1108,7 +1108,9 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, uint32_t session_id) { + struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; + QDF_STATUS status; notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { @@ -1123,7 +1125,15 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, notify->vdev = vdev; notify->user_disconnect = false; - tdls_notify_sta_disconnect(notify); + msg.bodyptr = notify; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_STA_DISCONNECTION; + + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(notify); + tdls_alert("message post failed "); + } } /** From e51aba73e79e36e689088322459ae7450bba9f4f Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Sun, 15 Apr 2018 00:42:41 -0700 Subject: [PATCH 231/404] qcacmn: add API to get NAPI instance corresponding to NAPI ID Add API to get NAPI instance from NAPI ID. Handle to NAPI is required for Rx processing via GRO. Change-Id: I15535827a03953231670d4138235c4876b16e045 CRs-Fixed: 2062180 --- inc/wlan_policy_mgr_api.h | 4 ++-- src/wlan_policy_mgr_get_set_utils.c | 12 ++++++------ src/wlan_policy_mgr_init_deinit.c | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 461064e440f8..3db7f62741be 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -864,12 +864,12 @@ struct policy_mgr_cdp_cbacks { /** * struct policy_mgr_dp_cbacks - CDP Callbacks to be invoked * from policy manager - * @hdd_disable_lro_in_concurrency: Callback to disable LRO + * @hdd_disable_rx_ol_in_concurrency: Callback to disable LRO/GRO offloads * @hdd_set_rx_mode_rps_cb: Callback to set RPS * @hdd_ipa_set_mcc_mode_cb: Callback to set mcc mode for ipa module */ struct policy_mgr_dp_cbacks { - void (*hdd_disable_lro_in_concurrency)(bool); + void (*hdd_disable_rx_ol_in_concurrency)(bool); void (*hdd_set_rx_mode_rps_cb)(bool); void (*hdd_ipa_set_mcc_mode_cb)(bool); }; diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index fe2551209555..9b86fdc7c343 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1159,7 +1159,7 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, pm_ctx->tdls_cbacks.tdls_notify_increment_session(psoc); /* - * Disable LRO if P2P or IBSS or SAP connection has come up or + * Disable LRO/GRO if P2P or IBSS or SAP connection has come up or * there are more than one STA connections */ if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL) > 1) || @@ -1168,8 +1168,8 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, 0) || (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_GO_MODE, NULL) > 0) || (policy_mgr_mode_specific_connection_count(psoc, PM_IBSS_MODE, NULL) > 0)) { - if (pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency != NULL) - pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency(true); + if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency != NULL) + pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(true); }; /* Enable RPS if SAP interface has come up */ @@ -1229,15 +1229,15 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, /* Notify tdls */ if (pm_ctx->tdls_cbacks.tdls_notify_decrement_session) pm_ctx->tdls_cbacks.tdls_notify_decrement_session(psoc); - /* Enable LRO if there no concurrency */ + /* Enable LRO/GRO if there no concurrency */ if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, NULL) == 1) && (policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL) == 0) && (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_CLIENT_MODE, NULL) == 0) && (policy_mgr_mode_specific_connection_count(psoc, PM_P2P_GO_MODE, NULL) == 0) && (policy_mgr_mode_specific_connection_count(psoc, PM_IBSS_MODE, NULL) == 0)) { - if (pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency != NULL) - pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency(false); + if (pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency != NULL) + pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency(false); }; /* Disable RPS if SAP interface has come up */ diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 992e0ff2aeac..4e97913bf306 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -645,8 +645,8 @@ QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - pm_ctx->dp_cbacks.hdd_disable_lro_in_concurrency = - dp_cbacks->hdd_disable_lro_in_concurrency; + pm_ctx->dp_cbacks.hdd_disable_rx_ol_in_concurrency = + dp_cbacks->hdd_disable_rx_ol_in_concurrency; pm_ctx->dp_cbacks.hdd_set_rx_mode_rps_cb = dp_cbacks->hdd_set_rx_mode_rps_cb; pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb = From 2923e70b09c45541a694fb1d67ebc7297fd05f5d Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 1 May 2018 15:18:09 -0700 Subject: [PATCH 232/404] qcacmn: Add range check for mode param in cds_get_pcl Add range check for mode parameter in cds_get_pcl. Change-Id: I049bebc5ec62f925e164517d59f94d122dbc5dc2 CRs-Fixed: 2234351 --- src/wlan_policy_mgr_pcl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 481107a1e91b..7851c6070ba3 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -492,6 +492,11 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, return status; } + if (mode >= PM_MAX_NUM_OF_MODE) { + policy_mgr_err("requested mode:%d is not supported", mode); + return status; + } + /* find the current connection state from pm_conc_connection_list*/ num_connections = policy_mgr_get_connection_count(psoc); policy_mgr_debug("connections:%d pref:%d requested mode:%d", From 23c12b21dd5c1cb29d88bca10082ed3e9c73131e Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Fri, 27 Apr 2018 16:44:53 -0700 Subject: [PATCH 233/404] qcacmn: Add NULL pointer check in p2p_remove_tx_context() API Add NULL pointer check in p2p_remove_tx_context() API. CRs-Fixed: 2232786 Change-Id: I67e541573d704f313a48c16c195a626a4040402c --- core/src/wlan_p2p_off_chan_tx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 75fbcd3c54e8..6af91f761b67 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1214,8 +1214,10 @@ static QDF_STATUS p2p_remove_tx_context( &is_ack_q); /* for not off channel tx case, won't find from queue */ - if (!cur_tx_ctx) + if (!cur_tx_ctx) { p2p_debug("Do not find tx context from queue"); + goto end; + } if (is_roc_q) { status = qdf_list_remove_node( @@ -1233,6 +1235,7 @@ static QDF_STATUS p2p_remove_tx_context( p2p_err("Failed to tx context from wait ack req queue"); } +end: qdf_mem_free(tx_ctx->buf); qdf_mem_free(tx_ctx); From af29fe97359c6f98aafe07db8bc0747aecb2881d Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Fri, 27 Apr 2018 16:46:08 -0700 Subject: [PATCH 234/404] qcacmn: Fix uninitialize variables in few policy manager APIs Few variables are left uninitialized and they are being used with some random value. Fix by initializing to default value. CRs-Fixed: 2232791 Change-Id: I3351cae52c58e963601d53376f42ca8ebf0d3b9a --- src/wlan_policy_mgr_pcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 7851c6070ba3..2179993f73c2 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1357,7 +1357,7 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, * under 5G MCC scenario */ uint8_t channel = PM_24_GHZ_CHANNEL_6; - uint32_t i, pcl_len; + uint32_t i, pcl_len = 0; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { From 0b19b4b59f942495a21133fb50de4d172901201f Mon Sep 17 00:00:00 2001 From: Amir Patel Date: Thu, 3 May 2018 23:01:08 +0530 Subject: [PATCH 235/404] qcacmn: Update API signature for vdev and peer search to include pdev_id Add a pdev_id parameter to following API For peer: a. wlan_objmgr_get_peer() b. wlan_objmgr_get_peer_by_mac_n_vdev() c. wlan_objmgr_get_peer_by_mac_n_vdev_no_state() d. wlan_objmgr_get_peer_no_state() e. wlan_objmgr_get_peer_nolock() f. wlan_objmgr_populate_logically_ deleted_peerlist_by_mac_n_vdev() For vdev: wlan_objmgr_get_vdev_by_macaddr_from_psoc() Change-Id: I7480c5e17e24b5dfb1a7846cfa773821a86a27ca CRs-Fixed: 2210118 --- core/src/wlan_p2p_main.c | 4 +++- core/src/wlan_p2p_off_chan_tx.c | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index ba86929c088c..e76f06ffb40d 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -1164,6 +1164,7 @@ void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr) QDF_STATUS status; struct wlan_objmgr_psoc *psoc; struct wlan_objmgr_peer *peer; + uint8_t pdev_id; if (!vdev) { p2p_err("vdev:%pK", vdev); @@ -1174,7 +1175,8 @@ void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr) p2p_err("psoc:%pK", psoc); return; } - peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_P2P_ID); + pdev_id = wlan_objmgr_pdev_get_pdev_id(wlan_vdev_get_pdev(vdev)); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_P2P_ID); if (!peer) { p2p_debug("peer info not found"); return; diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 6af91f761b67..65b514c4f2b8 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -466,16 +466,19 @@ static QDF_STATUS p2p_populate_mac_header( struct wlan_objmgr_psoc *psoc; void *mac_addr; uint16_t seq_num; + uint8_t pdev_id; psoc = tx_ctx->p2p_soc_obj->soc; wh = (struct wlan_frame_hdr *)tx_ctx->buf; mac_addr = wh->i_addr1; - peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_P2P_ID); + pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, tx_ctx->vdev_id, + WLAN_P2P_ID); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_P2P_ID); if (!peer) { mac_addr = wh->i_addr2; - peer = wlan_objmgr_get_peer(psoc, mac_addr, - WLAN_P2P_ID); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, + WLAN_P2P_ID); } if (!peer) { @@ -877,6 +880,7 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, struct wmi_mgmt_params mgmt_param = { 0 }; struct wlan_objmgr_psoc *psoc; void *mac_addr; + uint8_t pdev_id; psoc = tx_ctx->p2p_soc_obj->soc; mgmt_param.tx_frame = packet; @@ -893,11 +897,13 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, wh = (struct wlan_frame_hdr *)frame; mac_addr = wh->i_addr1; - peer = wlan_objmgr_get_peer(psoc, mac_addr, WLAN_P2P_ID); + pdev_id = wlan_get_pdev_id_from_vdev_id(psoc, tx_ctx->vdev_id, + WLAN_P2P_ID); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_P2P_ID); if (!peer) { mac_addr = wh->i_addr2; - peer = wlan_objmgr_get_peer(psoc, mac_addr, - WLAN_P2P_ID); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, + WLAN_P2P_ID); } if (!peer) { From 59cc7659b10866e5910ec6dd17e6954f6588f894 Mon Sep 17 00:00:00 2001 From: Akshay Kosigi Date: Tue, 6 Feb 2018 16:02:25 +0530 Subject: [PATCH 236/404] qcacmn: Replace void pointers with appropriate/common structure types Void pointer usage may lead to memory corruption due to wrong pointer is typecasted. Hence define structure for all, and modules internally typecasting based on their type Change-Id: I6271ed8aa3f94254fd85f41962f23ea36895154e CRs-Fixed: 2182452 --- src/target_if_p2p.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index 6f6b306e5e6b..03741472dd45 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -66,7 +66,7 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, return -EINVAL; } - wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); if (!wmi_handle) { target_if_err("null wmi handle"); return -EINVAL; @@ -132,7 +132,7 @@ static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, return -EINVAL; } - wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); if (!wmi_handle) { target_if_err("null wmi handle"); return -EINVAL; @@ -168,7 +168,7 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -191,7 +191,7 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -214,7 +214,7 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -236,7 +236,7 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -259,7 +259,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, { struct p2p_ps_params cmd; QDF_STATUS status; - wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -300,7 +300,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, struct p2p_lo_start *lo_start) { - wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -319,7 +319,7 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { - wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, vdev_id:%d", psoc, vdev_id); @@ -336,7 +336,7 @@ QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, bool disable_noa) { struct vdev_set_params param; - wmi_unified_t wmi_handle = ucfg_get_wmi_hdl(psoc); + wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); From b6322f435410553bd1e4644032465b8114fe0e29 Mon Sep 17 00:00:00 2001 From: Akshay Kosigi Date: Tue, 6 Feb 2018 16:02:25 +0530 Subject: [PATCH 237/404] qcacmn: Replace void pointers with appropriate/common structure types Void pointer usage may lead to memory corruption due to wrong pointer is typecasted. Hence define structure for all, and modules internally typecasting based on their type Change-Id: I6271ed8aa3f94254fd85f41962f23ea36895154e CRs-Fixed: 2182452 --- src/target_if_tdls.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/target_if_tdls.c b/src/target_if_tdls.c index e0a0ef23f916..bbb3c32cf096 100644 --- a/src/target_if_tdls.c +++ b/src/target_if_tdls.c @@ -57,7 +57,7 @@ target_if_tdls_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen) target_if_err("null psoc"); return -EINVAL; } - wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); if (wmi_extract_vdev_tdls_ev_param(wmi_handle, data, &info)) { target_if_err("Failed to extract wmi tdls event"); @@ -122,7 +122,7 @@ target_if_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, struct sta_uapsd_trig_params *params) { QDF_STATUS ret; - wmi_unified_t wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); if (!wmi_service_enabled(wmi_handle, wmi_sta_uapsd_basic_auto_trig) || @@ -145,17 +145,19 @@ QDF_STATUS target_if_tdls_register_event_handler(struct wlan_objmgr_psoc *psoc, void *arg) { - return wmi_unified_register_event(GET_WMI_HDL_FROM_PSOC(psoc), - wmi_tdls_peer_event_id, - target_if_tdls_event_handler); + return wmi_unified_register_event( + get_wmi_unified_hdl_from_psoc(psoc), + wmi_tdls_peer_event_id, + target_if_tdls_event_handler); } QDF_STATUS target_if_tdls_unregister_event_handler(struct wlan_objmgr_psoc *psoc, void *arg) { - return wmi_unified_unregister_event(GET_WMI_HDL_FROM_PSOC(psoc), - wmi_tdls_peer_event_id); + return wmi_unified_unregister_event( + get_wmi_unified_hdl_from_psoc(psoc), + wmi_tdls_peer_event_id); } QDF_STATUS From 6e91ab86948fa0d9c8c17d6cca4833a863413a0f Mon Sep 17 00:00:00 2001 From: Akshay Kosigi Date: Wed, 28 Feb 2018 22:37:24 +0530 Subject: [PATCH 238/404] qcacmn: Replace ucfg prefix with lmac Replace functions with ucfg as prefix in init_deinit_ucfg file with lmac as prefix Change-Id: I90d77dd5ddae4854ea68eeb67dc1b4fc356c2fe3 CRs-Fixed: 2182449 --- src/target_if_p2p.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index 03741472dd45..746b4f6cb81a 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -24,7 +24,7 @@ #include #include "target_if.h" #include "target_if_p2p.h" -#include "init_deinit_ucfg.h" +#include "init_deinit_lmac.h" static inline struct wlan_lmac_if_p2p_rx_ops * target_if_psoc_get_p2p_rx_ops(struct wlan_objmgr_psoc *psoc) @@ -168,7 +168,7 @@ QDF_STATUS target_if_p2p_register_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -191,7 +191,7 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -214,7 +214,7 @@ QDF_STATUS target_if_p2p_unregister_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -236,7 +236,7 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { int status; - wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, arg:%pK", psoc, arg); @@ -259,7 +259,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, { struct p2p_ps_params cmd; QDF_STATUS status; - wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -300,7 +300,7 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, struct p2p_lo_start *lo_start) { - wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); @@ -319,7 +319,7 @@ QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id) { - wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); target_if_debug("psoc:%pK, vdev_id:%d", psoc, vdev_id); @@ -336,7 +336,7 @@ QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, bool disable_noa) { struct vdev_set_params param; - wmi_unified_t wmi_handle = ucfg_get_wmi_unified_hdl(psoc); + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); if (!wmi_handle) { target_if_err("Invalid wmi handle"); From 70a52d9a29f20777fa3559a512ab81191975090f Mon Sep 17 00:00:00 2001 From: Himanshu Agarwal Date: Fri, 4 May 2018 14:37:48 +0530 Subject: [PATCH 239/404] qcacmn: Add API to stop DBS opportunistic timer Add API to stop DBS opportunistic timer in policy mgr. Change-Id: I11a2b2976c59d7cd09695f90c2d2bdd7338dde54 CRs-Fixed: 2236333 --- inc/wlan_policy_mgr_api.h | 8 ++++++++ src/wlan_policy_mgr_action.c | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 3db7f62741be..9eeb9e08e845 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1134,6 +1134,14 @@ QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc); */ QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_stop_opportunistic_timer() - Stops opportunistic timer + * @psoc: PSOC object information + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_restart_opportunistic_timer() - Restarts opportunistic timer * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index db6e957ad659..9cfa97d85816 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1117,6 +1117,24 @@ QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +QDF_STATUS policy_mgr_stop_opportunistic_timer(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *policy_mgr_ctx; + + policy_mgr_ctx = policy_mgr_get_context(psoc); + if (!policy_mgr_ctx) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + + if (policy_mgr_ctx->dbs_opportunistic_timer.state != + QDF_TIMER_STATE_RUNNING) + return QDF_STATUS_SUCCESS; + + qdf_mc_timer_stop(&policy_mgr_ctx->dbs_opportunistic_timer); + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_restart_opportunistic_timer( struct wlan_objmgr_psoc *psoc, bool check_state) { From b031fa6e0e6f42f7594bfa85fbae16a7287110aa Mon Sep 17 00:00:00 2001 From: Srinivas Girigowda Date: Thu, 15 Feb 2018 14:30:05 -0800 Subject: [PATCH 240/404] qcacmn: Consistently use policy_mgr_dual_mac_config Remove duplicate structs wmi_dual_mac_config and sir_dual_mac_config and use policy_mgr_dual_mac_config. Change-Id: I6da6539f519ec46ee274ba3f3ae042e5fd9c25d2 CRs-Fixed: 2191031 --- inc/wlan_policy_mgr_public_struct.h | 5 ++++- src/wlan_policy_mgr_get_set_utils.c | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index c45f3e63f08d..19ac08d1ebd4 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -788,6 +788,9 @@ enum set_hw_mode_status { SET_HW_MODE_STATUS_ECOEX, }; +typedef void (*dual_mac_cb)(enum set_hw_mode_status status, + uint32_t scan_config, + uint32_t fw_mode_config); /** * enum policy_mgr_hw_mode_change - identify the HW mode switching to. * @@ -895,7 +898,7 @@ struct policy_mgr_vdev_mac_map { struct policy_mgr_dual_mac_config { uint32_t scan_config; uint32_t fw_mode_config; - void *set_dual_mac_cb; + dual_mac_cb set_dual_mac_cb; }; /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 9b86fdc7c343..2a7430127d1b 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -884,7 +884,7 @@ void policy_mgr_soc_set_dual_mac_cfg_cb(enum set_hw_mode_status status, uint32_t fw_mode_config) { policy_mgr_debug("Status:%d for scan_config:%x fw_mode_config:%x", - status, scan_config, fw_mode_config); + status, scan_config, fw_mode_config); } void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc, @@ -930,7 +930,7 @@ void policy_mgr_set_dual_mac_scan_config(struct wlan_objmgr_psoc *psoc, return; } - cfg.set_dual_mac_cb = (void *)policy_mgr_soc_set_dual_mac_cfg_cb; + cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; policy_mgr_debug("scan_config:%x fw_mode_config:%x", cfg.scan_config, cfg.fw_mode_config); @@ -977,7 +977,7 @@ void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc, return; } - cfg.set_dual_mac_cb = (void *)policy_mgr_soc_set_dual_mac_cfg_cb; + cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb; policy_mgr_debug("scan_config:%x fw_mode_config:%x", cfg.scan_config, cfg.fw_mode_config); From 79d1442c3543780c36966378f81a9b3d9575fbfc Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 2 May 2018 15:42:54 +0530 Subject: [PATCH 241/404] qcacmn: Add break for few cases in tdls_process_mgmt_req Currently break statement is missing for some cases in tdls_process_mgmt_req. Add break statement as fallthrough is not required for these cases. Change-Id: I9ef290cdea8980f1b550cfebfb80ee81c5a694c0 CRs-Fixed: 2233184 --- core/src/wlan_tdls_mgmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 00d31dad7d63..38b93d1cab7c 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -417,6 +417,7 @@ QDF_STATUS tdls_process_mgmt_req( case WLAN_SER_CMD_DENIED_UNSPECIFIED: /* free the request */ qdf_mem_free(tdls_mgmt_req); + break; default: QDF_ASSERT(0); From f8417d1117822bc05ad9f74a621799c6ba78a504 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 8 May 2018 15:31:21 -0700 Subject: [PATCH 242/404] qcacmn: Use channel and vdev_id array for get_mode_specific_conn_info Use channel and vdev_id array while calling policy_mgr_get_mode_specific_conn_info. Change-Id: I64579e2b1af0eca47af5292d456367d059a461f5 CRs-Fixed: 2238386 --- src/wlan_policy_mgr_action.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 9cfa97d85816..884c09f53084 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -947,7 +947,9 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t mcc_to_scc_switch; - uint8_t operating_channel, vdev_id; + uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; + uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; + uint32_t cc_count = 0; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -955,11 +957,13 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( return; } - if (policy_mgr_get_mode_specific_conn_info(psoc, &operating_channel, - &vdev_id, PM_STA_MODE)) { - policy_mgr_debug("STA operating Channel: %u", - operating_channel); - } else { + /* + * force SCC with STA+STA+SAP will need some additional logic + */ + cc_count = policy_mgr_get_mode_specific_conn_info(psoc, + &operating_channel[cc_count], + &vdev_id[cc_count], PM_STA_MODE); + if (!cc_count) { policy_mgr_err("Could not get STA operating channel&vdevid"); return; } @@ -967,7 +971,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( mcc_to_scc_switch = policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); policy_mgr_info("MCC to SCC switch: %d chan: %d", - mcc_to_scc_switch, operating_channel); + mcc_to_scc_switch, operating_channel[0]); if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) { policy_mgr_debug( @@ -976,7 +980,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( } if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && - policy_mgr_valid_sta_channel_check(psoc, operating_channel) + policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) && !pm_ctx->sta_ap_intf_check_work_info) { struct sta_ap_intf_check_work_ctx *work_info; work_info = qdf_mem_malloc( From 656fa9a38f626a4e6a5f6addd91ca5cd17693a48 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 6 May 2018 00:15:04 -0700 Subject: [PATCH 243/404] qcacmn: Fix typo "capabilites" Replace typo "capabilites" with correct spelling "capabilities" Change-Id: I8efa1d974ecabb1466bdf27ec305fd9960da0616 CRs-Fixed: 2238309 --- src/wlan_policy_mgr_get_set_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 2a7430127d1b..6f71a5ffa1a0 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -375,7 +375,7 @@ void policy_mgr_init_dbs_config(struct wlan_objmgr_psoc *psoc, if (DISABLE_DBS_CXN_AND_SCAN == wlan_objmgr_psoc_get_dual_mac_disable(psoc)) { policy_mgr_err("Disabling dual mac capabilities"); - /* All capabilites are initialized to 0. We can return */ + /* All capabilities are initialized to 0. We can return */ goto done; } From d8f7e46f252819b894fe2e93c07580f0dc6eb7ca Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 6 May 2018 07:59:55 -0700 Subject: [PATCH 244/404] qcacmn: Fix typo in "P2P_EVENT_PROPOGATE_TIME" Macro P2P_EVENT_PROPOGATE_TIME contains a misspelling of PROPAGATE so fix the misspelling in both places it occurs. CRs-Fixed: 2238309 Change-Id: Ic5c4a31820f8b51a5117241c6c6fa01025f4ae84 --- core/src/wlan_p2p_roc.c | 2 +- core/src/wlan_p2p_roc.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 12893878bb68..4b968214dcfc 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -472,7 +472,7 @@ static QDF_STATUS p2p_process_ready_on_channel_evt( roc_ctx->roc_type, roc_ctx->roc_state); status = qdf_mc_timer_start(&roc_ctx->roc_timer, - (roc_ctx->duration + P2P_EVENT_PROPOGATE_TIME)); + (roc_ctx->duration + P2P_EVENT_PROPAGATE_TIME)); if (status != QDF_STATUS_SUCCESS) p2p_err("Remain on Channel timer start failed"); if (roc_ctx->roc_type == USER_REQUESTED) { diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index 21863e996ae9..84cadf99aeed 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.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 @@ -27,7 +27,7 @@ #include #include -#define P2P_EVENT_PROPOGATE_TIME 10 +#define P2P_EVENT_PROPAGATE_TIME 10 #define P2P_WAIT_CANCEL_ROC 1000 #ifdef QCA_WIFI_3_0_EMU From de4df85fdbaa88fa300456a504f0bc5034bf2684 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 6 May 2018 11:21:59 -0700 Subject: [PATCH 245/404] qcacmn: Fix typo "adapater" Replace typo "adapater" with correct spelling "adapter". Change-Id: I53a98385a38df6e26fc3a4a5448566e89c6710ea CRs-Fixed: 2238309 --- dispatcher/inc/wlan_tdls_public_structs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 4458872aaf4b..00fecd76da5f 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -186,7 +186,7 @@ enum tdls_feature_mode { * @TDLS_CMD_SESSION_INCREMENT: notify session increment * @TDLS_CMD_SESSION_DECREMENT: notify session decrement * @TDLS_CMD_TEARDOWN_LINKS: notify teardown - * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset + * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapter reset * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list * @TDLS_CMD_ANTENNA_SWITCH: dynamic tdls antenna switch */ From 114fe088c9e43b346d093a63c0f5dd0f8556d209 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 6 May 2018 15:40:42 -0700 Subject: [PATCH 246/404] qcacmn: Fix typo "lenght" Replace typo "lenght" with correct spelling "length". Change-Id: Ieea0c547c61248e510835d16a9fa55ace486df23 CRs-Fixed: 2238309 --- inc/wlan_policy_mgr_api.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 9eeb9e08e845..1efd27777acf 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -303,7 +303,7 @@ uint8_t policy_mgr_get_channel(struct wlan_objmgr_psoc *psoc, * @psoc: PSOC object information * @mode: Device mode * @pcl_channels: PCL channels - * @len: lenght of the PCL + * @len: length of the PCL * @pcl_weight: Weights of the PCL * @weight_len: Max length of the weights list * @@ -532,7 +532,7 @@ bool policy_mgr_is_ibss_conn_exist(struct wlan_objmgr_psoc *psoc, /** * policy_mgr_get_conn_info() - get the current connections list - * @len: lenght of the list + * @len: length of the list * * This function returns a pointer to the current connections * list From 98db4cb1fd56f9eb5e7b508d27425560c99c9e7b Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 6 May 2018 15:40:42 -0700 Subject: [PATCH 247/404] 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 a4d1ee9066984f85be25437759f21f6a2ca8acf6 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 6 May 2018 16:25:49 -0700 Subject: [PATCH 248/404] qcacmn: Fix typo "recieve" Replace typo "recieve" with correct spelling "receive". Change-Id: I7d88e57b97fa6d217630d4a5d5c365b56e714428 CRs-Fixed: 2238309 --- src/wlan_policy_mgr_pcl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 2179993f73c2..465f9f57ac00 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -184,7 +184,7 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, avoid_freq_ind->chan_list.ch_list, pm_ctx->unsafe_channel_count * sizeof(pm_ctx->unsafe_channel_list[0])); - policy_mgr_debug("Channel list update, recieved %d avoided channels", + policy_mgr_debug("Channel list update, received %d avoided channels", pm_ctx->unsafe_channel_count); } From c65c98fb3ee3438c3fd1740bf2f209dc64ec6f5e Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Tue, 24 Apr 2018 20:29:43 -0700 Subject: [PATCH 249/404] qcacmn: umac: Remove legacy markings Per current guidance remove legacy markings. Change-Id: I34c7acfad802a3878ffa373489b7f6a4194abb62 CRs-Fixed: 2230684 --- inc/wlan_policy_mgr_api.h | 9 --------- inc/wlan_policy_mgr_public_struct.h | 9 --------- src/wlan_policy_mgr_action.c | 9 --------- src/wlan_policy_mgr_core.c | 9 --------- src/wlan_policy_mgr_get_set_utils.c | 9 --------- src/wlan_policy_mgr_i.h | 9 --------- src/wlan_policy_mgr_init_deinit.c | 9 --------- src/wlan_policy_mgr_pcl.c | 9 --------- src/wlan_policy_mgr_tables_1x1_dbs_i.h | 9 --------- src/wlan_policy_mgr_tables_2x2_dbs_i.h | 9 --------- src/wlan_policy_mgr_tables_no_dbs_i.h | 9 --------- 11 files changed, 99 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 1efd27777acf..32b30d2f9e7f 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - #ifndef __WLAN_POLICY_MGR_API_H #define __WLAN_POLICY_MGR_API_H diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 19ac08d1ebd4..7bf2f876ec83 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - #ifndef __WLAN_POLICY_MGR_PUBLIC_STRUCT_H #define __WLAN_POLICY_MGR_PUBLIC_STRUCT_H diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 884c09f53084..e8fefe16ae1c 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /** * DOC: wlan_policy_mgr_action.c * diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index b6569e589173..46415feef511 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /** * DOC: wlan_policy_mgr_core.c * diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 6f71a5ffa1a0..a8df535e0761 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /** * DOC: wlan_policy_mgr_get_set_utils.c * diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 6f8b1fe36992..6e305fac1088 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - #ifndef WLAN_POLICY_MGR_I_H #define WLAN_POLICY_MGR_I_H diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 4e97913bf306..14f82aae1418 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /** * DOC: wlan_policy_mgr_init_deinit.c * diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 465f9f57ac00..8c413e4fd0df 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - /** * DOC: wlan_policy_mgr_pcl.c * diff --git a/src/wlan_policy_mgr_tables_1x1_dbs_i.h b/src/wlan_policy_mgr_tables_1x1_dbs_i.h index c12ab33993f4..92501e8872ce 100644 --- a/src/wlan_policy_mgr_tables_1x1_dbs_i.h +++ b/src/wlan_policy_mgr_tables_1x1_dbs_i.h @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - #ifndef __WLAN_POLICY_MGR_TABLES_1X1_DBS_H #define __WLAN_POLICY_MGR_TABLES_1X1_DBS_H diff --git a/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/src/wlan_policy_mgr_tables_2x2_dbs_i.h index 815bdd5d10a6..dd11a9faea0a 100644 --- a/src/wlan_policy_mgr_tables_2x2_dbs_i.h +++ b/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - #ifndef __WLAN_POLICY_MGR_TABLES_2X2_DBS_H #define __WLAN_POLICY_MGR_TABLES_2X2_DBS_H diff --git a/src/wlan_policy_mgr_tables_no_dbs_i.h b/src/wlan_policy_mgr_tables_no_dbs_i.h index b0119950f73c..204185247d07 100644 --- a/src/wlan_policy_mgr_tables_no_dbs_i.h +++ b/src/wlan_policy_mgr_tables_no_dbs_i.h @@ -1,9 +1,6 @@ /* * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. * - * Previously licensed under the ISC license by Qualcomm Atheros, Inc. - * - * * 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 @@ -19,12 +16,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* - * This file was originally distributed by Qualcomm Atheros, Inc. - * under proprietary terms before Copyright ownership was assigned - * to the Linux Foundation. - */ - #ifndef __WLAN_POLICY_MGR_TABLES_NO_DBS_H #define __WLAN_POLICY_MGR_TABLES_NO_DBS_H From 65059eb8372a9c22ebc576630073e64e88303abd Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sat, 12 May 2018 13:22:27 -0700 Subject: [PATCH 250/404] qcacmn: umac: Fix misspellings Address the following issues in the umac folder: CHECK: 'defintions' may be misspelled - perhaps 'definitions'? CHECK: 'destory' may be misspelled - perhaps 'destroy'? CHECK: 'faild' may be misspelled - perhaps 'failed'? CHECK: 'initilization' may be misspelled - perhaps 'initialization'? CHECK: 'managment' may be misspelled - perhaps 'management'? CHECK: 'muticast' may be misspelled - perhaps 'multicast'? CHECK: 'ouput' may be misspelled - perhaps 'output'? CHECK: 'segement' may be misspelled - perhaps 'segment'? CHECK: 'successfull' may be misspelled - perhaps 'successful'? CHECK: 'untill' may be misspelled - perhaps 'until'? Change-Id: If60c276c134ef10ce6be26cd5a4036d53d5724b6 CRs-Fixed: 2241586 --- core/src/wlan_tdls_ct.h | 6 +++--- dispatcher/inc/wlan_tdls_public_structs.h | 2 +- dispatcher/inc/wlan_tdls_ucfg_api.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index b713c971b4af..04926b9bba33 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.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 @@ -60,7 +60,7 @@ void tdls_implicit_enable(struct tdls_vdev_priv_obj *tdls_vdev); * @mac_addr: mac address of the data * * Increase the rx packet count, if the sender is not bssid and the packet is - * not broadcast and muticast packet + * not broadcast and multicast packet * * This sampling information will be used in TDLS connection tracker * @@ -78,7 +78,7 @@ void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, * @mac_addr: mac address of the data * * Increase the tx packet count, if the sender is not bssid and the packet is - * not broadcast and muticast packet + * not broadcast and multicast packet * * This sampling information will be used in TDLS connection tracker * diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 00fecd76da5f..089a75f9e151 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1007,7 +1007,7 @@ struct tdls_get_all_peers { * @cmd_buf: cmd buffer * @len: length of the frame * @use_default_ac: access category - * @tdls_mgmt: tdls managment + * @tdls_mgmt: tdls management */ struct tdls_action_frame_request { struct wlan_objmgr_vdev *vdev; diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index ffe3404dc6b6..1135c48e2dec 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.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 @@ -40,7 +40,7 @@ QDF_STATUS ucfg_tdls_init(void); /** - * ucfg_tdls_deinit() - TDLS module deinitilization API + * ucfg_tdls_deinit() - TDLS module deinitialization API * * Return: QDF_STATUS */ From c3b7af01ed2fd691cca6be965d7edc8c734f7b1e Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 4 May 2018 19:03:50 +0800 Subject: [PATCH 251/404] qcacmn: Use IDR API in p2p component Use qdf idr API to create id for roc and mgmt tx cookie, and not provide kernel address to userspace. Change-Id: I0b80dbe265d0e5f9981ae89df709720e7d9901f9 CRs-Fixed: 2232947 --- core/src/wlan_p2p_main.c | 2 ++ core/src/wlan_p2p_main.h | 3 ++ core/src/wlan_p2p_off_chan_tx.c | 3 +- core/src/wlan_p2p_off_chan_tx.h | 2 ++ core/src/wlan_p2p_roc.c | 3 +- core/src/wlan_p2p_roc.h | 2 ++ dispatcher/src/wlan_p2p_tgt_api.c | 2 +- dispatcher/src/wlan_p2p_ucfg_api.c | 46 ++++++++++++++++++++++++++---- 8 files changed, 55 insertions(+), 8 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index e76f06ffb40d..d7944cf084ad 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -821,6 +821,7 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) qdf_runtime_lock_init(&p2p_soc_obj->roc_runtime_lock); p2p_soc_obj->cur_roc_vdev_id = P2P_INVALID_VDEV_ID; + qdf_idr_create(&p2p_soc_obj->p2p_idr); p2p_register_pmo_handler(); p2p_debug("p2p psoc object open successful"); @@ -852,6 +853,7 @@ QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) } p2p_unregister_pmo_handler(); + qdf_idr_destroy(&p2p_soc_obj->p2p_idr); qdf_runtime_lock_deinit(&p2p_soc_obj->roc_runtime_lock); qdf_event_destroy(&p2p_soc_obj->cancel_roc_done); qdf_list_destroy(&p2p_soc_obj->tx_q_ack); diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 7f0950abb24b..013505f652eb 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -28,6 +28,7 @@ #include #include #include +#include #define MAX_QUEUE_LENGTH 20 #define P2P_NOA_ATTR_IND 0x1090 @@ -169,6 +170,7 @@ enum p2p_connection_status { * @roc_runtime_lock: Runtime lock for roc request * @p2p_cb: Callbacks to protocol stack * @cur_roc_vdev_id: Vdev id of current roc + * @p2p_idr: p2p idr * @connection_status:Global P2P connection status */ struct p2p_soc_priv_obj { @@ -182,6 +184,7 @@ struct p2p_soc_priv_obj { qdf_runtime_lock_t roc_runtime_lock; struct p2p_protocol_callbacks p2p_cb; uint32_t cur_roc_vdev_id; + qdf_idr p2p_idr; #ifdef WLAN_FEATURE_P2P_DEBUG enum p2p_connection_status connection_status; #endif diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 65b514c4f2b8..d8fc89eec7b6 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -841,7 +841,7 @@ static QDF_STATUS p2p_send_tx_conf(struct tx_action_context *tx_ctx, if (tx_ctx->no_ack) tx_cnf.action_cookie = 0; else - tx_cnf.action_cookie = (uintptr_t)tx_ctx; + tx_cnf.action_cookie = (uint64_t)tx_ctx->id; tx_cnf.vdev_id = tx_ctx->vdev_id; tx_cnf.buf = tx_ctx->buf; @@ -1242,6 +1242,7 @@ static QDF_STATUS p2p_remove_tx_context( } end: + qdf_idr_remove(&p2p_soc_obj->p2p_idr, tx_ctx->id); qdf_mem_free(tx_ctx->buf); qdf_mem_free(tx_ctx); diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index 713c3c35a811..19287c3fedef 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -148,6 +148,7 @@ struct p2p_frame_info { * @vdev_id: Vdev id on which this request has come * @scan_id: Scan id given by scan component for this roc req * @roc_cookie: Cookie for remain on channel request + * @id: Identifier of this tx context * @chan: Chan for which this tx has been requested * @buf: tx buffer * @buf_len: Length of tx buffer @@ -165,6 +166,7 @@ struct tx_action_context { int vdev_id; int scan_id; uint64_t roc_cookie; + int32_t id; uint8_t chan; uint8_t *buf; int buf_len; diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 4b968214dcfc..ff8a55c2ec3e 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -199,7 +199,7 @@ static QDF_STATUS p2p_send_roc_event( p2p_evt.vdev_id = roc_ctx->vdev_id; p2p_evt.roc_event = evt; - p2p_evt.cookie = (uintptr_t)roc_ctx; + p2p_evt.cookie = (uint64_t)roc_ctx->id; p2p_evt.chan = roc_ctx->chan; p2p_evt.duration = roc_ctx->duration; @@ -244,6 +244,7 @@ static QDF_STATUS p2p_destroy_roc_ctx(struct p2p_roc_context *roc_ctx, p2p_err("Failed to remove roc req, status %d", status); } + qdf_idr_remove(&p2p_soc_obj->p2p_idr, roc_ctx->id); qdf_mem_free(roc_ctx); return status; diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index 84cadf99aeed..fa40e7aa885d 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -84,6 +84,7 @@ enum roc_state { * @roc_type: RoC type User requested or internal * @roc_timer: RoC timer * @roc_state: Roc state + * @id: identifier of roc */ struct p2p_roc_context { qdf_list_node_t node; @@ -97,6 +98,7 @@ struct p2p_roc_context { enum roc_type roc_type; qdf_mc_timer_t roc_timer; enum roc_state roc_state; + int32_t id; }; /** diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 6c41bb27a2dd..50017d7f5688 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -167,7 +167,7 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, qdf_nbuf_free(buf); tx_cnf->vdev_id = tx_ctx->vdev_id; - tx_cnf->action_cookie = (uintptr_t)tx_ctx; + tx_cnf->action_cookie = (uint64_t)tx_ctx->id; tx_cnf->buf = tx_ctx->buf; tx_cnf->buf_len = tx_ctx->buf_len; tx_cnf->status = status; diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 4246f4bded0e..1956b13e9bb1 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -114,6 +114,8 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_roc_context *roc_ctx; + QDF_STATUS status; + int32_t id; p2p_debug("soc:%pK, vdev_id:%d, chan:%d, phy_mode:%d, duration:%d", soc, roc_req->vdev_id, roc_req->chan, @@ -137,7 +139,14 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, return QDF_STATUS_E_NOMEM; } - *cookie = (uintptr_t)roc_ctx; + status = qdf_idr_alloc(&p2p_soc_obj->p2p_idr, roc_ctx, &id); + if (status != QDF_STATUS_SUCCESS) { + qdf_mem_free(roc_ctx); + p2p_err("failed to alloc idr, status %d", status); + return status; + } + + *cookie = (uint64_t)id; roc_ctx->p2p_soc_obj = p2p_soc_obj; roc_ctx->vdev_id = roc_req->vdev_id; roc_ctx->chan = roc_req->chan; @@ -145,10 +154,12 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, roc_ctx->duration = roc_req->duration; roc_ctx->roc_state = ROC_STATE_IDLE; roc_ctx->roc_type = USER_REQUESTED; + roc_ctx->id = id; msg.type = P2P_ROC_REQ; msg.bodyptr = roc_ctx; msg.callback = p2p_process_cmd; scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + p2p_debug("cookie = 0x%llx", *cookie); return QDF_STATUS_SUCCESS; } @@ -159,6 +170,7 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; struct cancel_roc_context *cancel_roc; + void *roc_ctx = NULL; p2p_debug("soc:%pK, cookie:0x%llx", soc, cookie); @@ -174,6 +186,12 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, return QDF_STATUS_E_FAILURE; } + if (QDF_STATUS_SUCCESS != qdf_idr_find(&p2p_soc_obj->p2p_idr, + cookie, &roc_ctx)) { + p2p_err("invalid id"); + return QDF_STATUS_E_INVAL; + } + cancel_roc = qdf_mem_malloc(sizeof(*cancel_roc)); if (!cancel_roc) { p2p_err("failed to allocate cancel p2p roc"); @@ -181,7 +199,7 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, } cancel_roc->p2p_soc_obj = p2p_soc_obj; - cancel_roc->cookie = cookie; + cancel_roc->cookie = (uintptr_t)roc_ctx; msg.type = P2P_CANCEL_ROC_REQ; msg.bodyptr = cancel_roc; msg.callback = p2p_process_cmd; @@ -226,6 +244,8 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; struct tx_action_context *tx_action; + QDF_STATUS status; + int32_t id; p2p_debug("soc:%pK, vdev_id:%d, chan:%d, wait:%d, buf_len:%d, cck:%d, no ack:%d, off chan:%d", soc, mgmt_frm->vdev_id, mgmt_frm->chan, @@ -253,9 +273,17 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, /* return cookie just for ota ack frames */ if (mgmt_frm->dont_wait_for_ack) *cookie = 0; - else - *cookie = (uintptr_t)tx_action; + else { + status = qdf_idr_alloc(&p2p_soc_obj->p2p_idr, + tx_action, &id); + if (status != QDF_STATUS_SUCCESS) { + qdf_mem_free(tx_action); + p2p_err("failed to alloc idr, status :%d", status); + return status; + } + } + *cookie = (uint64_t)id; tx_action->p2p_soc_obj = p2p_soc_obj; tx_action->vdev_id = mgmt_frm->vdev_id; tx_action->chan = mgmt_frm->chan; @@ -273,6 +301,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, } qdf_mem_copy(tx_action->buf, mgmt_frm->buf, tx_action->buf_len); tx_action->nbuf = NULL; + tx_action->id = id; msg.type = P2P_MGMT_TX; msg.bodyptr = tx_action; msg.callback = p2p_process_cmd; @@ -287,6 +316,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; struct cancel_roc_context *cancel_tx; + void *tx_ctx; p2p_debug("soc:%pK, cookie:0x%llx", soc, cookie); @@ -302,6 +332,12 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, return QDF_STATUS_E_FAILURE; } + if (QDF_STATUS_SUCCESS != qdf_idr_find(&p2p_soc_obj->p2p_idr, + cookie, &tx_ctx)) { + p2p_err("invalid id"); + return QDF_STATUS_E_INVAL; + } + cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx)); if (!cancel_tx) { p2p_err("Failed to allocate cancel p2p roc"); @@ -309,7 +345,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, } cancel_tx->p2p_soc_obj = p2p_soc_obj; - cancel_tx->cookie = cookie; + cancel_tx->cookie = (uintptr_t)tx_ctx; msg.type = P2P_MGMT_TX_CANCEL; msg.bodyptr = cancel_tx; msg.callback = p2p_process_cmd; From 7044285902f51574dde43d26b7d942f2d3730eb0 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 21 May 2018 15:28:28 +0800 Subject: [PATCH 252/404] qcacmn: Check return value for channel conversion It may return NULL, which pass to another function and dereference it. Check return value, don't pass to another function if return value is NULL. Change-Id: Ib2e87231bb724c5631c12e9bee98c22d4dcc9bf2 CRs-Fixed: 2233639 --- src/wlan_cfg80211_p2p.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index e6ab17ab4d00..5f383e732e35 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -286,6 +286,11 @@ static void wlan_p2p_event_callback(void *user_data, chan = ieee80211_get_channel(wdev->wiphy, wlan_chan_to_freq(p2p_event->chan)); + if (!chan) { + cfg80211_err("channel conversion failed"); + goto fail; + } + if (p2p_event->roc_event == ROC_EVENT_READY_ON_CHAN) { cfg80211_ready_on_channel(wdev, p2p_event->cookie, chan, From ee56b4491c3f449d40fbb6ce4f51e39edeec8c1d Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 20 May 2018 11:29:42 -0700 Subject: [PATCH 253/404] qcacmn: Replace new instances of tQDF_ADAPTER_MODE Previously change "qcacmn: Use enum QDF_OPMODE", Change-Id Ic6f663dac11a100f168b2626c7c0fbcaccbfca4f, replaced all instances of tQDF_ADAPTER_MODE to QDF_OPMODE in the qca-wifi-host-cmn project. However since tQDF_ADAPTER_MODE was originally defined in a common project, and not all references to it could be immediately removed, a legacy definition was left with the expectation that it would be removed when all references to it had been updated. Unfortunately new instances of using tQDF_ADAPTER_MODE have been subsequently added to the project, so replace them with QDF_OPMODE. Change-Id: I71cead84151cc0411f7cc5cc13a87a281e7502c0 CRs-Fixed: 2245249 --- inc/wlan_policy_mgr_api.h | 2 +- src/wlan_policy_mgr_action.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 32b30d2f9e7f..044708767b71 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -827,7 +827,7 @@ struct policy_mgr_hdd_cbacks { enum policy_mgr_con_mode (*get_mode_for_non_connected_vdev)( struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); - enum tQDF_ADAPTER_MODE (*hdd_get_device_mode)(uint32_t session_id); + enum QDF_OPMODE (*hdd_get_device_mode)(uint32_t session_id); }; diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index e8fefe16ae1c..b50712b35d4d 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -362,7 +362,7 @@ static bool policy_mgr_is_dbs_allowed_for_concurrency( { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p; - enum tQDF_ADAPTER_MODE new_conn_mode = QDF_MAX_NO_OF_MODE; + enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE; bool ret = true; pm_ctx = policy_mgr_get_context(psoc); From 3688381753552302230d5b49a795832b3351ab9b Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Thu, 3 May 2018 15:06:44 -0700 Subject: [PATCH 254/404] qcacmn: Pass the arg by reference while calling sme_pdev_set_pcl() While calling sme_pdev_set_pcl() API, driver is passing the argument by value. The size of the argument is 280 bytes which is not good design. Pass the argument by reference instead of passing it by value to make design simple. CRs-Fixed: 2238293 Change-Id: I92849fb125fe864c1c7c7977bce392a7bcfe4121 --- inc/wlan_policy_mgr_api.h | 2 +- src/wlan_policy_mgr_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 044708767b71..38c84cb7cff2 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -792,7 +792,7 @@ struct policy_mgr_sme_cbacks { QDF_STATUS (*sme_soc_set_dual_mac_config)( struct policy_mgr_dual_mac_config msg); QDF_STATUS (*sme_pdev_set_hw_mode)(struct policy_mgr_hw_mode msg); - QDF_STATUS (*sme_pdev_set_pcl)(struct policy_mgr_pcl_list msg); + QDF_STATUS (*sme_pdev_set_pcl)(struct policy_mgr_pcl_list *msg); QDF_STATUS (*sme_nss_update_request)(uint32_t vdev_id, uint8_t new_nss, policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 46415feef511..30c604cb5285 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1199,7 +1199,7 @@ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, return; } - status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(pcl); + status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(&pcl); if (status != QDF_STATUS_SUCCESS) policy_mgr_err("Send soc set PCL to SME failed"); else From 7f8d1df7e9fdca66bb5a5e61d038d991f67735d5 Mon Sep 17 00:00:00 2001 From: Zhu Jianmin Date: Thu, 19 Apr 2018 17:55:30 +0800 Subject: [PATCH 255/404] qcacmn: Check chip capability when enable AP+AP Check capability of dbs, mcc and scc on single band when enable AP+AP, then same driver code can support different chip and firmware. Add wmi_service_dual_beacon_on_single_mac_(mcc/scc)_support Change-Id: I505747122504b2a89813e7bdfcd27dc07539f39e CRs-Fixed: 2214237 --- inc/wlan_policy_mgr_api.h | 35 ++++++++ src/wlan_policy_mgr_get_set_utils.c | 119 ++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 38c84cb7cff2..22e1f7b38ee8 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2297,4 +2297,39 @@ QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_allow_sap_go_concurrency() - check whether multiple SAP/GO + * interfaces are allowed + * @psoc: pointer to soc + * @policy_mgr_con_mode: operating mode of the new interface + * @channel: operating channel of the new interface + * This function checks whether second SAP/GO interface is allowed on the same + * MAC. + * + * Return: true or false + */ +bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel); + +/** + * policy_mgr_dual_beacon_on_single_mac_scc_capable() - get capability that + * whether support dual beacon on same channel on single MAC + * @psoc: pointer to soc + * + * Return: bool: capable + */ +bool policy_mgr_dual_beacon_on_single_mac_scc_capable( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_dual_beacon_on_single_mac_mcc_capable() - get capability that + * whether support dual beacon on different channel on single MAC + * @psoc: pointer to soc + * + * Return: bool: capable + */ +bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( + struct wlan_objmgr_psoc *psoc); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index a8df535e0761..68f87c0a6dce 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1693,6 +1693,11 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, } } + if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, channel)) { + policy_mgr_err("This concurrency combination is not allowed"); + goto done; + } + /* don't allow two P2P GO on same band */ if (channel && (mode == PM_P2P_GO_MODE) && num_connections) { index = 0; @@ -2950,3 +2955,117 @@ uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, return count; } + +bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel) +{ + uint32_t sap_cnt; + uint32_t go_cnt; + enum policy_mgr_con_mode con_mode; + uint8_t con_chan; + int id; + + sap_cnt = policy_mgr_mode_specific_connection_count(psoc, + PM_SAP_MODE, + NULL); + go_cnt = policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_GO_MODE, + NULL); + + if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) && + (sap_cnt || go_cnt)) { + if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc)) + return true; + if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc)) { + for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; + id++) { + if (pm_conc_connection_list[id].in_use) { + con_mode = + pm_conc_connection_list[id].mode; + con_chan = + pm_conc_connection_list[id].chan; + if (((con_mode == PM_SAP_MODE) || + (con_mode == PM_P2P_GO_MODE)) && + (channel != con_chan)) { + policy_mgr_debug("Scc is supported, but first SAP and second SAP are not in same channel, So don't allow second SAP interface"); + return false; + } + } + } + return true; + } + if (!policy_mgr_is_hw_dbs_capable(psoc)) { + policy_mgr_debug("DBS is not supported, mcc and scc are not supported too, don't allow second SAP interface"); + return false; + } + /* If DBS is supported then allow second SAP/GO session only if + * the freq band of the second SAP/GO interface is different + * than the first SAP/GO interface. + */ + for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) { + if (pm_conc_connection_list[id].in_use) { + con_mode = pm_conc_connection_list[id].mode; + con_chan = pm_conc_connection_list[id].chan; + if (((con_mode == PM_SAP_MODE) || + (con_mode == PM_P2P_GO_MODE)) && + (WLAN_REG_IS_SAME_BAND_CHANNELS(channel, + con_chan))) { + policy_mgr_debug("DBS is supported, but first SAP and second SAP are on same band, So don't allow second SAP interface"); + return false; + } + } + } + } + + /* Don't block the second interface */ + return true; +} + +bool policy_mgr_dual_beacon_on_single_mac_scc_capable( + struct wlan_objmgr_psoc *psoc) +{ + void *wmi_handle = NULL; + + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + if (!wmi_handle) { + policy_mgr_debug("Invalid WMI handle"); + return false; + } + + if (wmi_service_enabled( + wmi_handle, + wmi_service_dual_beacon_on_single_mac_scc_support)) { + policy_mgr_debug("Support dual beacon on same channel on single MAC"); + return true; + } + if (wmi_service_enabled( + wmi_handle, + wmi_service_dual_beacon_on_single_mac_mcc_support)) { + policy_mgr_debug("Support dual beacon on both different and same channel on single MAC"); + return true; + } + policy_mgr_debug("Not support dual beacon on same channel on single MAC"); + return false; +} + +bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( + struct wlan_objmgr_psoc *psoc) +{ + void *wmi_handle = NULL; + + wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + if (!wmi_handle) { + policy_mgr_debug("Invalid WMI handle"); + return false; + } + + if (wmi_service_enabled( + wmi_handle, + wmi_service_dual_beacon_on_single_mac_mcc_support)) { + policy_mgr_debug("Support dual beacon on different channel on single MAC"); + return true; + } + policy_mgr_debug("Not support dual beacon on different channel on single MAC"); + return false; +} From 618adb809f112b626b973c51ca4dc4f85e8eabdd Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 1 Jun 2018 15:16:53 -0700 Subject: [PATCH 256/404] qcacmn: Reduce log level to debug for tdls Reduce the log level for tdls related logs from info to debug. Change-Id: I0de4d0b4ae78a5b1c72c975d4d928cee7c21970f CRs-Fixed: 2252980 --- core/src/wlan_tdls_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 391713849159..e4406818a32a 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1338,7 +1338,7 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc) if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode || TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode || TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode) { - tdls_notice("revert tdls mode %d", + tdls_debug("revert tdls mode %d", tdls_soc->tdls_last_mode); tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode, From cdf1813b35a57f6fd2a4bc86c61d322f1e49fe02 Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Tue, 8 May 2018 19:55:25 -0700 Subject: [PATCH 257/404] qcacmn: Add DP callbacks for flow_pool create and delete Current lithim_dp flow pool created in wma_vdev_start, wma_vdev_start is called for same vdev multiple times for vdev. This leads to creation of multiple flow pools for each vdev. Instead create from policy_manager when session become active. Register flow pool create/delete callbacks with policy manager. So that lithium_dp vdev flow pools are created/deleted when vdev become active/not-active. Change-Id: Iaf6aaece47c79c7e6f7745feaee35a6bc5cd1297 CRs-Fixed: 2231601 --- inc/wlan_policy_mgr_api.h | 4 ++++ src/wlan_policy_mgr_get_set_utils.c | 5 +++++ src/wlan_policy_mgr_init_deinit.c | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 22e1f7b38ee8..3ba1cce50467 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -858,11 +858,15 @@ struct policy_mgr_cdp_cbacks { * @hdd_disable_rx_ol_in_concurrency: Callback to disable LRO/GRO offloads * @hdd_set_rx_mode_rps_cb: Callback to set RPS * @hdd_ipa_set_mcc_mode_cb: Callback to set mcc mode for ipa module + * @hdd_v2_flow_pool_map: Callback to create vdev flow pool + * @hdd_v2_flow_pool_unmap: Callback to delete vdev flow pool */ struct policy_mgr_dp_cbacks { void (*hdd_disable_rx_ol_in_concurrency)(bool); void (*hdd_set_rx_mode_rps_cb)(bool); void (*hdd_ipa_set_mcc_mode_cb)(bool); + void (*hdd_v2_flow_pool_map)(int); + void (*hdd_v2_flow_pool_unmap)(int); }; /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 68f87c0a6dce..e76057c32e63 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1122,6 +1122,8 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, break; } + if (pm_ctx->dp_cbacks.hdd_v2_flow_pool_map) + pm_ctx->dp_cbacks.hdd_v2_flow_pool_map(session_id); policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); @@ -1212,6 +1214,9 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, break; } + if (pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap) + pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap(session_id); + policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 14f82aae1418..d6a198932aa2 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -642,6 +642,10 @@ QDF_STATUS policy_mgr_register_dp_cb(struct wlan_objmgr_psoc *psoc, dp_cbacks->hdd_set_rx_mode_rps_cb; pm_ctx->dp_cbacks.hdd_ipa_set_mcc_mode_cb = dp_cbacks->hdd_ipa_set_mcc_mode_cb; + pm_ctx->dp_cbacks.hdd_v2_flow_pool_map = + dp_cbacks->hdd_v2_flow_pool_map; + pm_ctx->dp_cbacks.hdd_v2_flow_pool_unmap = + dp_cbacks->hdd_v2_flow_pool_unmap; return QDF_STATUS_SUCCESS; } From 7503f363336be18ae47a2d553d7d8850810e0634 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 17 May 2018 16:14:00 +0800 Subject: [PATCH 258/404] qcacmn: pmo feature flag disable In case PMO feature flag disable, add this change. Change WLAN_PMO_ENABLE to WLAN_POWER_MANAGEMENT_OFFLOAD. Change-Id: I875e568dcb239da1b86d1a76cb8cbc925bb13cde CRs-Fixed: 2243948 --- core/src/wlan_p2p_main.c | 8 +++++--- core/src/wlan_p2p_off_chan_tx.c | 1 + dispatcher/src/wlan_p2p_ucfg_api.c | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index d7944cf084ad..db7c91351502 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -34,7 +34,7 @@ #include "wlan_p2p_roc.h" #include "wlan_p2p_off_chan_tx.h" -#ifdef WLAN_PMO_ENABLE +#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD #include #endif @@ -537,7 +537,7 @@ static void wlan_p2p_init_connection_status( } #endif /* WLAN_FEATURE_P2P_DEBUG */ -#ifdef WLAN_PMO_ENABLE +#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD /** * p2p_suspend_handler() - suspend handler of P2P @@ -655,12 +655,14 @@ static inline QDF_STATUS p2p_unregister_pmo_handler(void) #else static inline QDF_STATUS p2p_register_pmo_handler(void) { + return QDF_STATUS_SUCCESS; } static inline QDF_STATUS p2p_unregister_pmo_handler(void) { + return QDF_STATUS_SUCCESS; } -#endif /* End of WLAN_PMO_ENABLE */ +#endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ QDF_STATUS p2p_component_init(void) { diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index d8fc89eec7b6..c74c3a0f93f0 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "wlan_p2p_public_struct.h" #include "wlan_p2p_tgt_api.h" diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 1956b13e9bb1..162daf91b3f6 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -22,6 +22,7 @@ #include #include +#include #include #include "wlan_p2p_public_struct.h" #include "wlan_p2p_ucfg_api.h" From 2688ed785defce0bed78a9e165ff7520102535e7 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Tue, 24 Apr 2018 16:50:40 +0800 Subject: [PATCH 259/404] qcacmn: Reject tdls_vdev create/destroy when disabled in INI Reject tdls_vdev creation and destroy, when TDLS is disabled in INI. Change-Id: Ie85e8ed231e14dc413e4bfdcff205c47115c84dd CRs-Fixed: 2229872 --- core/src/wlan_tdls_main.c | 49 ++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index e4406818a32a..e1a564ce92e7 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -150,13 +150,26 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; struct tdls_vdev_priv_obj *tdls_vdev_obj; struct wlan_objmgr_pdev *pdev; - struct tdls_soc_priv_obj *tdls_soc; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint32_t tdls_feature_flags; tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!tdls_soc_obj) { + tdls_err("get soc by vdev failed"); + return QDF_STATUS_E_NOMEM; + } + + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_ENABLED(tdls_feature_flags)) { + tdls_debug("disabled in ini"); + return QDF_STATUS_E_NOSUPPORT; + } + /* TODO: Add concurrency check */ tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj)); @@ -171,33 +184,29 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, QDF_STATUS_SUCCESS); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("Failed to attach vdev tdls component"); - qdf_mem_free(tdls_vdev_obj); - goto out; + goto err; } tdls_vdev_obj->vdev = vdev; status = tdls_vdev_init(tdls_vdev_obj); if (QDF_IS_STATUS_ERROR(status)) - goto out; - - tdls_soc = wlan_vdev_get_tdls_soc_obj(vdev); - if (!tdls_soc) { - tdls_err("get soc by vdev failed "); - return QDF_STATUS_E_NOMEM; - } + goto err; pdev = wlan_vdev_get_pdev(vdev); status = ucfg_scan_register_event_handler(pdev, tdls_scan_complete_event_handler, - tdls_soc); + tdls_soc_obj); if (QDF_STATUS_SUCCESS != status) { tdls_err("scan event register failed "); - return QDF_STATUS_E_FAILURE; + tdls_vdev_deinit(tdls_vdev_obj); + goto err; } tdls_notice("tdls object attach to vdev successfully"); -out: + return status; +err: + qdf_mem_free(tdls_vdev_obj); return status; } @@ -206,12 +215,26 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, { QDF_STATUS status; void *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint32_t tdls_feature_flags; tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!tdls_soc_obj) { + tdls_err("get soc by vdev failed"); + return QDF_STATUS_E_NOMEM; + } + + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_ENABLED(tdls_feature_flags)) { + tdls_debug("disabled in ini"); + return QDF_STATUS_E_NOSUPPORT; + } + tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); if (!tdls_vdev_obj) { From 5ff88a8b637f5dcf2e2280b4ed0ed303130806e8 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Sun, 13 May 2018 20:12:37 -0700 Subject: [PATCH 260/404] qcacmn: Remove unused data structures in TDLS component Remove the unused data structures in TDLS component to avoid incorrect usage Change-Id: Id3997d5895dba8e3cb3f60fe102ca846cb009607 CRs-Fixed: 2232726 --- core/src/wlan_tdls_main.h | 4 ---- dispatcher/inc/wlan_tdls_public_structs.h | 8 -------- dispatcher/src/wlan_tdls_ucfg_api.c | 6 ------ 3 files changed, 18 deletions(-) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 6867ffd4f1e9..b2a0a8613786 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -165,9 +165,7 @@ struct tdls_set_state_info { * @tdls_nss_teardown_complete: tdls tear down complete * @tdls_nss_transition_mode: tdls nss transition mode * @tdls_teardown_peers_cnt: tdls tear down peer count - * @tdls_tx_cnf_cb: callback registered by hdd to receive the ack cnf * @set_state_info: set tdls state info - * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event user data * @tdls_peer_context: userdata for register/deregister TDLS peer @@ -209,8 +207,6 @@ struct tdls_soc_priv_obj { void *tdls_rx_cb_data; tdls_wmm_check tdls_wmm_cb; void *tdls_wmm_cb_data; - tdls_tx_ack_cnf_callback tdls_tx_cnf_cb; - void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; void *tdls_peer_context; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 089a75f9e151..8f1e045fb9af 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -543,10 +543,6 @@ typedef void (*tdls_evt_callback) (void *data, enum tdls_event_type ev_type, struct tdls_osif_indication *event); -/* prototype of callback registered by hdd to receive the ack cnf */ -typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, - struct tdls_tx_cnf *tx_ack_cnf_cb_data); - /* This callback is used to register TDLS peer with the datapath */ typedef QDF_STATUS (*tdls_register_peer_callback)(void *userdata, uint32_t vdev_id, @@ -577,8 +573,6 @@ typedef QDF_STATUS * @tdls_update_dp_vdev_flags: pass CDP_UPDATE_TDLS_FLAGS * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event data - * @ack_cnf_cb: tdls tx ack callback to indicate the tx status - * @tx_ack_cnf_cb_data: tdls tx ack user data * @tdls_peer_context: userdata for register/deregister TDLS peer * @tdls_reg_peer: register tdls peer with datapath * @tdls_dereg_peer: deregister tdls peer from datapath @@ -598,8 +592,6 @@ struct tdls_start_params { void *tdls_wmm_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; - tdls_tx_ack_cnf_callback ack_cnf_cb; - void *tx_ack_cnf_cb_data; void *tdls_peer_context; tdls_register_peer_callback tdls_reg_peer; tdls_deregister_peer_callback tdls_dereg_peer; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 9134509eacc0..d071dc0cd622 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -204,9 +204,6 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_event_cb = req->tdls_event_cb; soc_obj->tdls_evt_cb_data = req->tdls_evt_cb_data; - soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; - soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; - /* Save callbacks to register/deregister TDLS sta with datapath */ soc_obj->tdls_reg_peer = req->tdls_reg_peer; soc_obj->tdls_dereg_peer = req->tdls_dereg_peer; @@ -307,9 +304,6 @@ QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) soc_obj->tdls_event_cb = NULL; soc_obj->tdls_evt_cb_data = NULL; - soc_obj->tdls_tx_cnf_cb = NULL; - soc_obj->tx_ack_cnf_cb_data = NULL; - return status; } From 845c5e27b7af3a6bff889ffce103d95b231e50d2 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Mon, 11 Jun 2018 15:39:13 -0700 Subject: [PATCH 261/404] qcacmn: Reduce excessive p2p logging during suspend Several bits of debug information are being logged to console from the p2p module, which is seen consistently during suspend/resume. Reduce the logging level of these debug logs to avoid spamming the console. Change-Id: I4cf63e88a9d0391fb366b11fa3eb14e9f2f69698 CRs-Fixed: 2258427 --- core/src/wlan_p2p_off_chan_tx.c | 8 ++++---- core/src/wlan_p2p_roc.c | 30 +++++++++++++++--------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index c74c3a0f93f0..f50b0db93fb7 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1654,8 +1654,8 @@ QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) struct tx_action_context *curr_tx_ctx; qdf_list_node_t *p_node; - p2p_info("clean up tx queue wait for roc, size:%d", - qdf_list_size(&p2p_soc_obj->tx_q_roc)); + p2p_debug("clean up tx queue wait for roc, size:%d", + qdf_list_size(&p2p_soc_obj->tx_q_roc)); while (qdf_list_remove_front(&p2p_soc_obj->tx_q_roc, &p_node) == QDF_STATUS_SUCCESS) { @@ -1666,8 +1666,8 @@ QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) qdf_mem_free(curr_tx_ctx); } - p2p_info("clean up tx queue wait for ack, size:%d", - qdf_list_size(&p2p_soc_obj->tx_q_ack)); + p2p_debug("clean up tx queue wait for ack, size:%d", + qdf_list_size(&p2p_soc_obj->tx_q_ack)); while (qdf_list_remove_front(&p2p_soc_obj->tx_q_ack, &p_node) == QDF_STATUS_SUCCESS) { curr_tx_ctx = qdf_container_of(p_node, diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index ff8a55c2ec3e..3650af9d73e5 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -658,20 +658,20 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) qdf_list_node_t *p_node; QDF_STATUS status, ret; - p2p_info("clean up idle roc request, roc queue size:%d", - qdf_list_size(&p2p_soc_obj->roc_q)); + p2p_debug("clean up idle roc request, roc queue size:%d", + qdf_list_size(&p2p_soc_obj->roc_q)); status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); while (QDF_IS_STATUS_SUCCESS(status)) { roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_info("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", - roc_ctx->p2p_soc_obj, roc_ctx, - roc_ctx->vdev_id, roc_ctx->scan_id, - roc_ctx->tx_ctx, roc_ctx->chan, - roc_ctx->phy_mode, roc_ctx->duration, - roc_ctx->roc_type, roc_ctx->roc_state); + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, + roc_ctx->vdev_id, roc_ctx->scan_id, + roc_ctx->tx_ctx, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); status = qdf_list_peek_next(&p2p_soc_obj->roc_q, p_node, &p_node); if (roc_ctx->roc_state == ROC_STATE_IDLE) { @@ -686,18 +686,18 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) } } - p2p_info("clean up started roc request, roc queue size:%d", - qdf_list_size(&p2p_soc_obj->roc_q)); + p2p_debug("clean up started roc request, roc queue size:%d", + qdf_list_size(&p2p_soc_obj->roc_q)); status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); while (QDF_IS_STATUS_SUCCESS(status)) { roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_info("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx_ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", - roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, - roc_ctx->phy_mode, roc_ctx->duration, - roc_ctx->roc_type, roc_ctx->roc_state); + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx_ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); status = qdf_list_peek_next(&p2p_soc_obj->roc_q, p_node, &p_node); From 179a9be485e966b5398a56e54e67d8245a36b0a5 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 11 Jun 2018 16:09:42 +0800 Subject: [PATCH 262/404] qcacmn: Initialize id before tx MGMT frame It use an uninitialized variable to TX (not wait ack) MGMT frame. Change-Id: I46c96a2879a945e8284c436e5ff6b761e1c246ba CRs-Fixed: 2254688 --- dispatcher/src/wlan_p2p_ucfg_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 162daf91b3f6..84366e846e16 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -273,7 +273,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, /* return cookie just for ota ack frames */ if (mgmt_frm->dont_wait_for_ack) - *cookie = 0; + id = 0; else { status = qdf_idr_alloc(&p2p_soc_obj->p2p_idr, tx_action, &id); From b02882e70b24a4162d668e906675c0a39432e9eb Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 5 Jun 2018 16:24:14 +0530 Subject: [PATCH 263/404] qcacmn: Fix TDLS tear down issue on initiator The tdls peer sta id is allocated as part of wma_create_peer. In HDD, as part of change interface, wlan_hdd_tdls_disable_offchan_and_teardown_links API is called. Here driver checks for valid TDLS peers based on staid. Here HDD assumes staid zero as invalid and non zero values as valid ID. This is not correct as staid zero also is a valid staid. Due to this teardown status is not informed to upper layers. Use 0xFF as invalid sta id for tdls peer to fix this issue. Change-Id: I3827df9a63081952b2d443c175ef5a59eab85e43 CRs-Fixed: 2258171 --- core/src/wlan_tdls_cmds_process.c | 6 +++--- core/src/wlan_tdls_ct.c | 7 ++++--- core/src/wlan_tdls_peer.c | 2 +- dispatcher/inc/wlan_tdls_public_structs.h | 3 ++- dispatcher/src/wlan_tdls_ucfg_api.c | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 30bbe01e0885..8570484c2de4 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1398,7 +1398,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) conn_rec = soc_obj->tdls_conn_info; for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { - if (0 == conn_rec[sta_idx].sta_id) { + if (INVALID_TDLS_PEER_ID == conn_rec[sta_idx].sta_id) { conn_rec[sta_idx].session_id = rsp->session_id; conn_rec[sta_idx].sta_id = rsp->sta_id; qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, @@ -1510,7 +1510,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) } } tdls_reset_peer(vdev_obj, macaddr); - conn_rec[sta_idx].sta_id = 0; + conn_rec[sta_idx].sta_id = INVALID_TDLS_PEER_ID; conn_rec[sta_idx].session_id = 0xff; qdf_mem_zero(&conn_rec[sta_idx].peer_mac, QDF_MAC_ADDR_SIZE); @@ -2190,7 +2190,7 @@ static int tdls_teardown_links(struct tdls_soc_priv_obj *soc_obj, uint32_t mode) conn_rec = soc_obj->tdls_conn_info; for (staidx = 0; staidx < soc_obj->max_num_tdls_sta; staidx++) { - if (conn_rec[staidx].sta_id == 0) + if (conn_rec[staidx].sta_id == INVALID_TDLS_PEER_ID) continue; curr_peer = tdls_find_all_peer(soc_obj, diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index e2c73a49bdd4..7c44278af44f 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -587,7 +587,7 @@ tdls_ct_process_idle_handler( &tdls_soc_obj)) return; - if (!tdls_info->sta_id) { + if (INVALID_TDLS_PEER_ID == tdls_info->sta_id) { tdls_err("peer (staidx %u) doesn't exists", tdls_info->sta_id); return; } @@ -1252,7 +1252,8 @@ void tdls_disable_offchan_and_teardown_links( for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; staidx++) { - if (!tdls_soc->tdls_conn_info[staidx].sta_id) + if (tdls_soc->tdls_conn_info[staidx].sta_id + == INVALID_TDLS_PEER_ID) continue; curr_peer = tdls_find_all_peer(tdls_soc, @@ -1280,7 +1281,7 @@ void tdls_disable_offchan_and_teardown_links( wlan_vdev_get_id(vdev), curr_peer->sta_id); tdls_decrement_peer_count(tdls_soc); - tdls_soc->tdls_conn_info[staidx].sta_id = 0; + tdls_soc->tdls_conn_info[staidx].sta_id = INVALID_TDLS_PEER_ID; tdls_soc->tdls_conn_info[staidx].session_id = 255; qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 7e2f7e597b91..b761646d0c04 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -756,7 +756,7 @@ QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj, tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE, TDLS_LINK_UNSPECIFIED); - curr_peer->sta_id = 0; + curr_peer->sta_id = INVALID_TDLS_PEER_ID; return QDF_STATUS_SUCCESS; } diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 8f1e045fb9af..cb5a8f816e44 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -74,8 +74,9 @@ #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 +#define INVALID_TDLS_PEER_ID 0xFF #define TDLS_STA_INDEX_CHECK(sta_id) \ - (((sta_id) >= 1) && ((sta_id) < 0xFF)) + (((sta_id) >= 0) && ((sta_id) < 0xFF)) /** * enum tdls_conc_cap - tdls concurrency support * @TDLS_SUPPORTED_ONLY_ON_STA: only support sta tdls diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index d071dc0cd622..442fb5c9f989 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -137,7 +137,7 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { - soc_obj->tdls_conn_info[sta_idx].sta_id = 0; + soc_obj->tdls_conn_info[sta_idx].sta_id = INVALID_TDLS_PEER_ID; soc_obj->tdls_conn_info[sta_idx].session_id = 255; qdf_mem_zero(&soc_obj->tdls_conn_info[sta_idx].peer_mac, QDF_MAC_ADDR_SIZE); From b7f839694abe65c11553f3f2f489166d3891ab7e Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 14 Jun 2018 17:56:38 -0700 Subject: [PATCH 264/404] qcacmn: Restrict the force SCC logic for STA+SAP only Restrict the force SCC logic for STA+SAP only unless ini is set for QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION. Change-Id: If2c4c285b92ea5eba69679561c32875cff5f7b08 CRs-Fixed: 2261717 --- src/wlan_policy_mgr_action.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index b50712b35d4d..553356679170 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -701,8 +701,10 @@ static bool policy_mgr_is_restart_sap_allowed( !policy_mgr_concurrent_open_sessions_running(psoc) || !(((policy_mgr_get_concurrency_mode(psoc) & sta_ap_bit_mask) == sta_ap_bit_mask) || + ((mcc_to_scc_switch == + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && ((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask) - == sta_go_bit_mask))) { + == sta_go_bit_mask)))) { policy_mgr_err("MCC switch disabled or not concurrent STA/SAP, STA/GO"); return false; } From 5ac66ef3f786b75105620d80e7dc8d89a6f5861a Mon Sep 17 00:00:00 2001 From: Zhu Jianmin Date: Mon, 11 Jun 2018 19:03:39 +0800 Subject: [PATCH 265/404] qcacmn: ini parameter to allow STA+SAP SCC on LTE coex channel When Force SCC and STA+SAP SCC on LTE coex channel are enabled: 1. When STA on LTE coex channel, start SAP, select STA channel. 2. When SAP on, connect STA on LTE coex channel, then switch SAP channel to STA channel. Change-Id: I7864e0ab2655c3bee95154ea4dedfb60fe8689e4 CRs-Fixed: 2261226 --- inc/wlan_policy_mgr_api.h | 10 ++++++++++ inc/wlan_policy_mgr_public_struct.h | 1 + src/wlan_policy_mgr_action.c | 5 +++-- src/wlan_policy_mgr_get_set_utils.c | 13 +++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 3ba1cce50467..7ddc73f0f8f6 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2336,4 +2336,14 @@ bool policy_mgr_dual_beacon_on_single_mac_scc_capable( bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_sta_sap_scc_on_lte_coex_chan() - get capability that + * whether support sta sap scc on lte coex chan + * @psoc: pointer to soc + * + * Return: bool: capable + */ +bool policy_mgr_sta_sap_scc_on_lte_coex_chan( + struct wlan_objmgr_psoc *psoc); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 7bf2f876ec83..2d7f61042574 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1024,6 +1024,7 @@ struct policy_mgr_user_cfg { bool sub_20_mhz_enabled; bool is_sta_sap_scc_allowed_on_dfs_chan; uint32_t channel_select_logic_conc; + uint32_t sta_sap_scc_on_lte_coex_chan; }; /** diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 553356679170..c000c8a93657 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -887,9 +887,10 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( if (policy_mgr_valid_sta_channel_check(psoc, channel)) { if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) || - wlan_reg_is_passive_or_disable_ch( + wlan_reg_is_passive_or_disable_ch( pm_ctx->pdev, channel) || - !policy_mgr_is_safe_channel(psoc, channel)) { + !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) || + policy_mgr_is_safe_channel(psoc, channel))) { if (policy_mgr_is_hw_dbs_capable(psoc)) { temp_channel = policy_mgr_get_alternate_channel_for_sap(psoc); diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index e76057c32e63..b733b71abfa5 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -3074,3 +3074,16 @@ bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( policy_mgr_debug("Not support dual beacon on different channel on single MAC"); return false; } + +bool policy_mgr_sta_sap_scc_on_lte_coex_chan( + struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + return pm_ctx->user_cfg.sta_sap_scc_on_lte_coex_chan; +} From 06a4e7c57e54b6bbdb137a6f552d69d665513c31 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Sat, 9 Jun 2018 20:19:18 +0530 Subject: [PATCH 266/404] qcacmn: Skip CAC and ignore radar indication for SAP If STA is already connected on DFS channel and SAP is going to start on the same channel then skip the CAC for SAP. If STA and SAP sessions are already operating on same DFS channel, then ignore radar indication received on SAP interface. CRs-Fixed: 2262494 Change-Id: Ife0ab6979a07c8773001a43f5a30c9a555dab37a --- src/wlan_policy_mgr_core.c | 20 +++++++++++++------- src/wlan_policy_mgr_get_set_utils.c | 9 ++++++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 30c604cb5285..1c0739a21e6e 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1733,7 +1733,7 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( { uint8_t i; uint32_t orig_channel_count = 0; - bool mcc_to_scc_mode; + bool sta_sap_scc_on_dfs_chan; uint32_t sap_count; enum channel_state channel_state; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1744,13 +1744,14 @@ void policy_mgr_set_weight_of_dfs_passive_channels_to_zero( return; } - mcc_to_scc_mode = policy_mgr_is_force_scc(psoc); + sta_sap_scc_on_dfs_chan = + policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); sap_count = policy_mgr_mode_specific_connection_count(psoc, PM_SAP_MODE, NULL); - policy_mgr_debug("mcc_to_scc_mode %u, sap_count %u", mcc_to_scc_mode, - sap_count); + policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u", + sta_sap_scc_on_dfs_chan, sap_count); - if (!mcc_to_scc_mode || !sap_count) + if (!sta_sap_scc_on_dfs_chan || !sap_count) return; if (len) @@ -1810,6 +1811,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, bool skip_dfs_channel = false; uint32_t i = 0, j = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + bool sta_sap_scc_on_dfs_chan; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1844,9 +1846,13 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, * if you have atleast one STA connection then don't fill DFS channels * in the preferred channel list */ - if (((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) && + sta_sap_scc_on_dfs_chan = + policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); + policy_mgr_debug("sta_sap_scc_on_dfs_chan %u", sta_sap_scc_on_dfs_chan); + if ((((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) && (policy_mgr_mode_specific_connection_count( - psoc, PM_STA_MODE, NULL) > 0)) { + psoc, PM_STA_MODE, NULL) > 0)) || + !sta_sap_scc_on_dfs_chan) { policy_mgr_debug("STA present, skip DFS channels from pcl for SAP/Go"); skip_dfs_channel = true; } diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index b733b71abfa5..fc5a0564e1b4 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1540,6 +1540,7 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, struct policy_mgr_psoc_priv_obj *pm_ctx; QDF_STATUS ret; struct policy_mgr_pcl_list pcl; + bool sta_sap_scc_on_dfs_chan; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1594,7 +1595,13 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, channel, list, PM_SAP_MODE)) goto done; - if ((PM_P2P_GO_MODE == mode) || (PM_SAP_MODE == mode)) { + sta_sap_scc_on_dfs_chan = + policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); + policy_mgr_debug("sta_sap_scc_on_dfs_chan %u", + sta_sap_scc_on_dfs_chan); + + if (!sta_sap_scc_on_dfs_chan && ((mode == PM_P2P_GO_MODE) || + (mode == PM_SAP_MODE))) { if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel)) match = policy_mgr_disallow_mcc(psoc, channel); } From 28477d3975991b18b9e509c263f0cca13f6c0096 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 7 May 2018 21:35:55 +0530 Subject: [PATCH 267/404] qcacmn: Populate PCL list correctly using channel select logic ini Currently, PCL list is populated without checking channel select logic ini. Check for channel select logic ini before selecting the second connection pcl table. Change-Id: I5a64d4ff43a7dcc2c70eac75b51d5f87de2903bb CRs-FIxed: 2237403 --- inc/wlan_policy_mgr_api.h | 27 +++++++++++++++ src/wlan_policy_mgr_action.c | 24 ++++++++----- src/wlan_policy_mgr_core.c | 22 ++---------- src/wlan_policy_mgr_get_set_utils.c | 52 +++++++++++++++++------------ src/wlan_policy_mgr_pcl.c | 10 ++++-- 5 files changed, 84 insertions(+), 51 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 7ddc73f0f8f6..0244b1498aa9 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -508,6 +508,19 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, uint32_t session_id, uint8_t channel, enum policy_mgr_conn_update_reason); +/** + * policy_mgr_is_dbs_allowed_for_concurrency() - If dbs is allowed for current + * concurreny + * @new_conn_mode: new connection mode + * + * When a new connection is about to come up, check if dbs is allowed for + * STA+STA or STA+P2P + * + * Return: true if dbs is allowed for STA+STA or STA+P2P else false + */ +bool policy_mgr_is_dbs_allowed_for_concurrency( + struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode); + /** * policy_mgr_is_ibss_conn_exist() - to check if IBSS connection already present * @psoc: PSOC object information @@ -677,6 +690,20 @@ static inline QDF_STATUS policy_mgr_decr_connection_count_utfw( enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( enum QDF_OPMODE device_mode); +/** + * policy_mgr_get_qdf_mode_from_pm - provides the + * type translation from policy manager type + * to generic connection mode type + * @device_mode: policy manager mode type + * + * + * This function provides the type translation + * + * Return: QDF_OPMODE enum + */ +enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm( + enum policy_mgr_con_mode device_mode); + /** * policy_mgr_pdev_set_hw_mode() - Set HW mode command to FW * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index c000c8a93657..4cbffd08431c 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -357,12 +357,11 @@ QDF_STATUS policy_mgr_update_and_wait_for_connection_update( * * Return: true if dbs is allowed for STA+STA or STA+P2P else false */ -static bool policy_mgr_is_dbs_allowed_for_concurrency( - struct wlan_objmgr_psoc *psoc, uint32_t session_id) +bool policy_mgr_is_dbs_allowed_for_concurrency( + struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode) { struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p; - enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE; bool ret = true; pm_ctx = policy_mgr_get_context(psoc); @@ -372,9 +371,6 @@ static bool policy_mgr_is_dbs_allowed_for_concurrency( } count = policy_mgr_get_connection_count(psoc); - if (pm_ctx->hdd_cbacks.hdd_get_device_mode) - new_conn_mode = pm_ctx->hdd_cbacks. - hdd_get_device_mode(session_id); if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE) return ret; @@ -430,6 +426,8 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, enum policy_mgr_two_connection_mode third_index = 0; enum policy_mgr_band band; QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum QDF_OPMODE new_conn_mode = QDF_MAX_NO_OF_MODE; if (policy_mgr_is_hw_dbs_capable(psoc) == false) { policy_mgr_err("driver isn't dbs capable, no further action needed"); @@ -483,6 +481,16 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, break; } + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + goto done; + } + + if (pm_ctx->hdd_cbacks.hdd_get_device_mode) + new_conn_mode = pm_ctx->hdd_cbacks. + hdd_get_device_mode(session_id); + /* * Based on channel_select_logic_conc ini, hw mode is set * when second connection is about to come up that results @@ -493,10 +501,10 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, * mode change is not required. */ if (policy_mgr_is_current_hwmode_dbs(psoc) && - !policy_mgr_is_dbs_allowed_for_concurrency(psoc, session_id)) + !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode)) next_action = PM_SINGLE_MAC; else if (!policy_mgr_is_current_hwmode_dbs(psoc) && - !policy_mgr_is_dbs_allowed_for_concurrency(psoc, session_id)) + !policy_mgr_is_dbs_allowed_for_concurrency(psoc, new_conn_mode)) next_action = PM_NOP; if (PM_NOP != next_action) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 1c0739a21e6e..a0b1643d6c81 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1206,7 +1206,6 @@ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("Set PCL to FW for mode:%d", mode); } - /** * policy_mgr_set_pcl_for_existing_combo() - Set PCL for existing connection * @mode: Connection mode of type 'policy_mgr_con_mode' @@ -1230,26 +1229,9 @@ void policy_mgr_set_pcl_for_existing_combo( return; } - switch (mode) { - case PM_STA_MODE: - pcl_mode = QDF_STA_MODE; - break; - case PM_SAP_MODE: - pcl_mode = QDF_SAP_MODE; - break; - case PM_P2P_CLIENT_MODE: - pcl_mode = QDF_P2P_CLIENT_MODE; - break; - case PM_P2P_GO_MODE: - pcl_mode = QDF_P2P_GO_MODE; - break; - case PM_IBSS_MODE: - pcl_mode = QDF_IBSS_MODE; - break; - default: - policy_mgr_err("Invalid mode to set PCL"); + pcl_mode = policy_mgr_get_qdf_mode_from_pm(mode); + if (pcl_mode == QDF_MAX_NO_OF_MODE) return; - }; qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) { /* Check, store and temp delete the mode's parameter */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index fc5a0564e1b4..c43a06f0d489 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2079,6 +2079,34 @@ enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( return mode; } +enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm( + enum policy_mgr_con_mode device_mode) +{ + enum QDF_OPMODE mode = QDF_MAX_NO_OF_MODE; + + switch (device_mode) { + case PM_STA_MODE: + mode = QDF_STA_MODE; + break; + case PM_SAP_MODE: + mode = QDF_SAP_MODE; + break; + case PM_P2P_CLIENT_MODE: + mode = QDF_P2P_CLIENT_MODE; + break; + case PM_P2P_GO_MODE: + mode = QDF_P2P_GO_MODE; + break; + case PM_IBSS_MODE: + mode = QDF_IBSS_MODE; + break; + default: + policy_mgr_err("Unsupported policy mgr mode (%d)", + device_mode); + } + return mode; +} + QDF_STATUS policy_mgr_mode_specific_num_open_sessions( struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE mode, uint8_t *num_sessions) @@ -2265,27 +2293,9 @@ QDF_STATUS policy_mgr_get_nss_for_vdev(struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE dev_mode; struct policy_mgr_psoc_priv_obj *pm_ctx; - switch (mode) { - case PM_STA_MODE: - dev_mode = QDF_STA_MODE; - break; - case PM_SAP_MODE: - dev_mode = QDF_SAP_MODE; - break; - case PM_P2P_CLIENT_MODE: - dev_mode = QDF_P2P_CLIENT_MODE; - break; - case PM_P2P_GO_MODE: - dev_mode = QDF_P2P_GO_MODE; - break; - case PM_IBSS_MODE: - dev_mode = QDF_IBSS_MODE; - break; - default: - policy_mgr_err("Invalid mode to get allowed NSS value"); - return QDF_STATUS_E_FAILURE; - }; - + dev_mode = policy_mgr_get_qdf_mode_from_pm(mode); + if (dev_mode == QDF_MAX_NO_OF_MODE) + return QDF_STATUS_E_FAILURE; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 8c413e4fd0df..0dab0d739a6d 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -476,7 +476,7 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, enum policy_mgr_pcl_type pcl = PM_NONE; enum policy_mgr_conc_priority_mode conc_system_pref = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; - + enum QDF_OPMODE qdf_mode; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("context is NULL"); @@ -522,7 +522,13 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, policy_mgr_err("couldn't find index for 2nd connection pcl table"); return status; } - if (policy_mgr_is_hw_dbs_capable(psoc) == true) { + qdf_mode = policy_mgr_get_qdf_mode_from_pm(mode); + if (qdf_mode == QDF_MAX_NO_OF_MODE) + return status; + + if (policy_mgr_is_hw_dbs_capable(psoc) == true && + policy_mgr_is_dbs_allowed_for_concurrency( + psoc, qdf_mode)) { pcl = (*second_connection_pcl_dbs_table) [second_index][mode][conc_system_pref]; } else { From a02444a20634c89c972a92bb56bbeea1e3a5c442 Mon Sep 17 00:00:00 2001 From: Dundi Raviteja Date: Mon, 18 Jun 2018 11:57:37 +0530 Subject: [PATCH 268/404] qcacmn: Incorrect usage of QDF_ARRAY_SIZE macro In some use cases of QDF_ARRAY_SIZE macro, the argument passing to it is a pointer instead of array which leads to getting incorrect array size. Current implementation of updating main arrays pcl_list_org and weight_list_org is inefficient. So, update the main arrays directly, instead of copying the data to local arrays and again updating the main arrays. Change-Id: I9a4a7fa813412fd000ce55d2a958e49ab1b02ed5 CRs-Fixed: 2262231 --- src/wlan_policy_mgr_pcl.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 0dab0d739a6d..b122d2130cbb 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -248,21 +248,14 @@ static QDF_STATUS policy_mgr_modify_pcl_based_on_enabled_channels( uint32_t *pcl_len_org) { uint32_t i, pcl_len = 0; - uint8_t pcl_list[QDF_MAX_NUM_CHAN]; - uint8_t weight_list[QDF_MAX_NUM_CHAN]; for (i = 0; i < *pcl_len_org; i++) { if (!wlan_reg_is_passive_or_disable_ch( pm_ctx->pdev, pcl_list_org[i])) { - pcl_list[pcl_len] = pcl_list_org[i]; - weight_list[pcl_len++] = weight_list_org[i]; + pcl_list_org[pcl_len] = pcl_list_org[i]; + weight_list_org[pcl_len++] = weight_list_org[i]; } } - - qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org)); - qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org)); - qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); - qdf_mem_copy(weight_list_org, weight_list, pcl_len); *pcl_len_org = pcl_len; return QDF_STATUS_SUCCESS; @@ -1517,8 +1510,6 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( uint32_t *pcl_len_org) { uint32_t i, j, pcl_len = 0; - uint8_t pcl_list[QDF_MAX_NUM_CHAN]; - uint8_t weight_list[QDF_MAX_NUM_CHAN]; bool found; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -1555,15 +1546,10 @@ QDF_STATUS policy_mgr_modify_sap_pcl_based_on_mandatory_channel( } } if (found && (pcl_len < QDF_MAX_NUM_CHAN)) { - pcl_list[pcl_len] = pcl_list_org[i]; - weight_list[pcl_len++] = weight_list_org[i]; + pcl_list_org[pcl_len] = pcl_list_org[i]; + weight_list_org[pcl_len++] = weight_list_org[i]; } } - - qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org)); - qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org)); - qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); - qdf_mem_copy(weight_list_org, weight_list, pcl_len); *pcl_len_org = pcl_len; return QDF_STATUS_SUCCESS; From 62b1503f677e5613c56bcc84b4e02d9423a3b052 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 26 Mar 2018 10:26:00 +0800 Subject: [PATCH 269/404] qcacmn: Cleanup roc and handle tx ack in schedule thread To avoid different thread delete the roc context or tx context at same time, move cleanup roc and handle tx ack in scheduler thread. Change-Id: Idc2a5394886a2e10c3acfabe139365dd263d6c0a CRs-Fixed: 2211827 --- core/src/wlan_p2p_main.c | 48 +++++++-- core/src/wlan_p2p_main.h | 16 ++- core/src/wlan_p2p_off_chan_tx.c | 115 +++++++++++++++++---- core/src/wlan_p2p_off_chan_tx.h | 23 ++++- core/src/wlan_p2p_roc.c | 154 ++++++++++++++--------------- core/src/wlan_p2p_roc.h | 35 ++++--- dispatcher/src/wlan_p2p_tgt_api.c | 44 +++------ dispatcher/src/wlan_p2p_ucfg_api.c | 7 +- 8 files changed, 282 insertions(+), 160 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index db7c91351502..105449f580de 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -57,6 +57,10 @@ static char *p2p_get_cmd_type_str(enum p2p_cmd_type cmd_type) return "P2P mgmt tx request"; case P2P_MGMT_TX_CANCEL: return "P2P cancel mgmt tx request"; + case P2P_CLEANUP_ROC: + return "P2P cleanup roc"; + case P2P_CLEANUP_TX: + return "P2P cleanup tx"; default: return "Invalid P2P command"; } @@ -565,8 +569,8 @@ static QDF_STATUS p2p_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) } /* clean up queue of p2p psoc private object */ - p2p_cleanup_tx_queue(p2p_soc_obj); - p2p_cleanup_roc_queue(p2p_soc_obj); + p2p_cleanup_tx_sync(p2p_soc_obj, NULL); + p2p_cleanup_roc_sync(p2p_soc_obj, NULL); p2p_debug("handle suspend complete"); @@ -818,7 +822,19 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) status = qdf_event_create(&p2p_soc_obj->cancel_roc_done); if (status != QDF_STATUS_SUCCESS) { p2p_err("failed to create cancel roc done event"); - goto fail_event; + goto fail_cancel_roc; + } + + status = qdf_event_create(&p2p_soc_obj->cleanup_roc_done); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("failed to create cleanup roc done event"); + goto fail_cleanup_roc; + } + + status = qdf_event_create(&p2p_soc_obj->cleanup_tx_done); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("failed to create cleanup roc done event"); + goto fail_cleanup_tx; } qdf_runtime_lock_init(&p2p_soc_obj->roc_runtime_lock); @@ -830,7 +846,13 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) return QDF_STATUS_SUCCESS; -fail_event: +fail_cleanup_tx: + qdf_event_destroy(&p2p_soc_obj->cleanup_roc_done); + +fail_cleanup_roc: + qdf_event_destroy(&p2p_soc_obj->cancel_roc_done); + +fail_cancel_roc: qdf_list_destroy(&p2p_soc_obj->tx_q_ack); qdf_list_destroy(&p2p_soc_obj->tx_q_roc); qdf_list_destroy(&p2p_soc_obj->roc_q); @@ -857,6 +879,8 @@ QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) p2p_unregister_pmo_handler(); qdf_idr_destroy(&p2p_soc_obj->p2p_idr); qdf_runtime_lock_deinit(&p2p_soc_obj->roc_runtime_lock); + qdf_event_destroy(&p2p_soc_obj->cleanup_tx_done); + qdf_event_destroy(&p2p_soc_obj->cleanup_roc_done); qdf_event_destroy(&p2p_soc_obj->cancel_roc_done); qdf_list_destroy(&p2p_soc_obj->tx_q_ack); qdf_list_destroy(&p2p_soc_obj->tx_q_roc); @@ -948,8 +972,8 @@ QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc) p2p_mgmt_rx_action_ops(soc, false); /* clean up queue of p2p psoc private object */ - p2p_cleanup_tx_queue(p2p_soc_obj); - p2p_cleanup_roc_queue(p2p_soc_obj); + p2p_cleanup_tx_sync(p2p_soc_obj, NULL); + p2p_cleanup_roc_sync(p2p_soc_obj, NULL); /* unrgister scan request id*/ ucfg_scan_unregister_requester(soc, p2p_soc_obj->scan_req_id); @@ -1005,6 +1029,18 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg) msg->bodyptr); qdf_mem_free(msg->bodyptr); break; + case P2P_CLEANUP_ROC: + status = p2p_process_cleanup_roc_queue( + (struct p2p_cleanup_param *) + msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; + case P2P_CLEANUP_TX: + status = p2p_process_cleanup_tx_queue( + (struct p2p_cleanup_param *) + msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; default: p2p_err("drop unexpected message received %d", msg->type); diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 013505f652eb..2e2beecd67f8 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -65,12 +65,16 @@ struct tx_action_context; * @P2P_CANCEL_ROC_REQ: Cancel P2P roc request * @P2P_MGMT_TX: P2P tx action frame request * @P2P_MGMT_TX_CANCEL: Cancel tx action frame request + * @P2P_CLEANUP_ROC: Cleanup roc queue + * @P2P_CLEANUP_TX: Cleanup tx mgmt queue */ enum p2p_cmd_type { P2P_ROC_REQ = 0, P2P_CANCEL_ROC_REQ, P2P_MGMT_TX, P2P_MGMT_TX_CANCEL, + P2P_CLEANUP_ROC, + P2P_CLEANUP_TX, }; /** @@ -92,13 +96,13 @@ enum p2p_event_type { /** * struct p2p_tx_conf_event - p2p tx confirm event * @p2p_soc_obj: p2p soc private object - * @tx_cnf: p2p tx confirm structure - * @tx_ctx: tx context + * @buf: buffer address + * @status: tx status */ struct p2p_tx_conf_event { struct p2p_soc_priv_obj *p2p_soc_obj; - struct p2p_tx_cnf *tx_cnf; - struct tx_action_context *tx_ctx; + qdf_nbuf_t nbuf; + uint32_t status; }; /** @@ -167,6 +171,8 @@ enum p2p_connection_status { * @start_param: Start parameters, include callbacks and user * data to HDD * @cancel_roc_done: Cancel roc done event + * @cleanup_roc_done: Cleanup roc done event + * @cleanup_tx_done: Cleanup tx done event * @roc_runtime_lock: Runtime lock for roc request * @p2p_cb: Callbacks to protocol stack * @cur_roc_vdev_id: Vdev id of current roc @@ -181,6 +187,8 @@ struct p2p_soc_priv_obj { wlan_scan_requester scan_req_id; struct p2p_start_param *start_param; qdf_event_t cancel_roc_done; + qdf_event_t cleanup_roc_done; + qdf_event_t cleanup_tx_done; qdf_runtime_lock_t roc_runtime_lock; struct p2p_protocol_callbacks p2p_cb; uint32_t cur_roc_vdev_id; diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index f50b0db93fb7..c50a32b07124 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "wlan_p2p_public_struct.h" #include "wlan_p2p_tgt_api.h" #include "wlan_p2p_ucfg_api.h" @@ -1649,10 +1650,68 @@ QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj, return status; } -QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) +QDF_STATUS p2p_cleanup_tx_sync( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct wlan_objmgr_vdev *vdev) +{ + struct scheduler_msg msg = {0}; + struct p2p_cleanup_param *param; + QDF_STATUS status; + uint32_t vdev_id; + + if (!p2p_soc_obj) { + p2p_err("p2p soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + p2p_debug("p2p_soc_obj:%pK, vdev:%pK", p2p_soc_obj, vdev); + param = qdf_mem_malloc(sizeof(*param)); + if (!param) { + p2p_err("failed to allocate cleanup param"); + return QDF_STATUS_E_NOMEM; + } + + param->p2p_soc_obj = p2p_soc_obj; + if (vdev) + vdev_id = (uint32_t)wlan_vdev_get_id(vdev); + else + vdev_id = P2P_INVALID_VDEV_ID; + param->vdev_id = vdev_id; + qdf_event_reset(&p2p_soc_obj->cleanup_tx_done); + msg.type = P2P_CLEANUP_TX; + msg.bodyptr = param; + msg.callback = p2p_process_cmd; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("failed to post message"); + qdf_mem_free(param); + return status; + } + + status = qdf_wait_single_event( + &p2p_soc_obj->cleanup_tx_done, + P2P_WAIT_CLEANUP_ROC); + + if (status != QDF_STATUS_SUCCESS) + p2p_err("wait for cleanup tx timeout, %d", status); + + return status; +} + +QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param) { struct tx_action_context *curr_tx_ctx; qdf_list_node_t *p_node; + struct p2p_soc_priv_obj *p2p_soc_obj; + uint32_t vdev_id; + + if (!param || !(param->p2p_soc_obj)) { + p2p_err("Invalid cleanup param"); + return QDF_STATUS_E_FAILURE; + } + + p2p_soc_obj = param->p2p_soc_obj; + vdev_id = param->vdev_id; p2p_debug("clean up tx queue wait for roc, size:%d", qdf_list_size(&p2p_soc_obj->tx_q_roc)); @@ -1661,9 +1720,12 @@ QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) QDF_STATUS_SUCCESS) { curr_tx_ctx = qdf_container_of(p_node, struct tx_action_context, node); - p2p_send_tx_conf(curr_tx_ctx, false); - qdf_mem_free(curr_tx_ctx->buf); - qdf_mem_free(curr_tx_ctx); + if ((vdev_id == P2P_INVALID_VDEV_ID) || + (vdev_id == curr_tx_ctx->vdev_id)) { + p2p_send_tx_conf(curr_tx_ctx, false); + qdf_mem_free(curr_tx_ctx->buf); + qdf_mem_free(curr_tx_ctx); + } } p2p_debug("clean up tx queue wait for ack, size:%d", @@ -1672,12 +1734,17 @@ QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj) QDF_STATUS_SUCCESS) { curr_tx_ctx = qdf_container_of(p_node, struct tx_action_context, node); - p2p_disable_tx_timer(curr_tx_ctx); - p2p_send_tx_conf(curr_tx_ctx, false); - qdf_mem_free(curr_tx_ctx->buf); - qdf_mem_free(curr_tx_ctx); + if ((vdev_id == P2P_INVALID_VDEV_ID) || + (vdev_id == curr_tx_ctx->vdev_id)) { + p2p_disable_tx_timer(curr_tx_ctx); + p2p_send_tx_conf(curr_tx_ctx, false); + qdf_mem_free(curr_tx_ctx->buf); + qdf_mem_free(curr_tx_ctx); + } } + qdf_event_set(&p2p_soc_obj->cleanup_tx_done); + return QDF_STATUS_SUCCESS; } @@ -1843,36 +1910,48 @@ QDF_STATUS p2p_process_mgmt_tx_cancel( QDF_STATUS p2p_process_mgmt_tx_ack_cnf( struct p2p_tx_conf_event *tx_cnf_event) { - struct p2p_tx_cnf *tx_cnf; + struct p2p_tx_cnf tx_cnf; + struct tx_action_context *tx_ctx; struct p2p_soc_priv_obj *p2p_soc_obj; struct p2p_start_param *start_param; p2p_soc_obj = tx_cnf_event->p2p_soc_obj; - tx_cnf = tx_cnf_event->tx_cnf; if (!p2p_soc_obj || !(p2p_soc_obj->start_param)) { + qdf_nbuf_free(tx_cnf_event->nbuf); p2p_err("Invalid p2p soc object or start parameters"); - qdf_mem_free(tx_cnf); return QDF_STATUS_E_INVAL; } + tx_ctx = p2p_find_tx_ctx_by_nbuf(p2p_soc_obj, tx_cnf_event->nbuf); + qdf_nbuf_free(tx_cnf_event->nbuf); + if (!tx_ctx) { + p2p_err("can't find tx_ctx, tx ack comes late"); + return QDF_STATUS_SUCCESS; + } + + tx_cnf.vdev_id = tx_ctx->vdev_id; + tx_cnf.action_cookie = (uint64_t)tx_ctx->id; + tx_cnf.buf = tx_ctx->buf; + tx_cnf.buf_len = tx_ctx->buf_len; + tx_cnf.status = tx_cnf_event->status; + p2p_debug("soc:%pK, vdev_id:%d, action_cookie:%llx, len:%d, status:%d, buf:%pK", - p2p_soc_obj->soc, tx_cnf->vdev_id, - tx_cnf->action_cookie, tx_cnf->buf_len, - tx_cnf->status, tx_cnf->buf); + p2p_soc_obj->soc, tx_cnf.vdev_id, + tx_cnf.action_cookie, tx_cnf.buf_len, + tx_cnf.status, tx_cnf.buf); /* disable tx timer */ - p2p_disable_tx_timer(tx_cnf_event->tx_ctx); + p2p_disable_tx_timer(tx_ctx); start_param = p2p_soc_obj->start_param; if (start_param->tx_cnf_cb) start_param->tx_cnf_cb(start_param->tx_cnf_cb_data, - tx_cnf); + &tx_cnf); else p2p_debug("Got tx conf, but no valid up layer callback"); - p2p_remove_tx_context(tx_cnf_event->tx_ctx); - qdf_mem_free(tx_cnf); + p2p_remove_tx_context(tx_ctx); return QDF_STATUS_SUCCESS; } diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index 19287c3fedef..b7bb89876546 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -155,7 +155,6 @@ struct p2p_frame_info { * @off_chan: Is this off channel tx * @no_cck: Required cck or not * @no_ack: Required ack or not - * @is_deleting: Received tx ack and waiting for deleting * @duration: Duration for the RoC * @tx_timer: RoC timer * @frame_info: Frame type information @@ -173,7 +172,6 @@ struct tx_action_context { bool off_chan; bool no_cck; bool no_ack; - bool is_deleting; uint32_t duration; qdf_mc_timer_t tx_timer; struct p2p_frame_info frame_info; @@ -205,14 +203,29 @@ QDF_STATUS p2p_ready_to_tx_frame(struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie); /** - * p2p_cleanup_tx_queue() - cleanup tx queue - * @p2p_soc_obj: p2p soc private object + * p2p_cleanup_tx_sync() - Cleanup tx queue + * @p2p_soc_obj: p2p psoc private object + * @vdev: vdev object + * + * This function cleanup tx context in queue until cancellation done. + * To avoid deadlock, don't call from scheduler thread. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_cleanup_tx_sync( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct wlan_objmgr_vdev *vdev); + +/** + * p2p_process_cleanup_tx_queue() - process the message to cleanup tx + * @param: pointer to cleanup parameters * * This function cleanup wait for roc queue and wait for ack queue. * * Return: QDF_STATUS_SUCCESS - in case of success */ -QDF_STATUS p2p_cleanup_tx_queue(struct p2p_soc_priv_obj *p2p_soc_obj); +QDF_STATUS p2p_process_cleanup_tx_queue( + struct p2p_cleanup_param *param); /** * p2p_process_mgmt_tx() - Process mgmt frame tx request diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 3650af9d73e5..1ff391e4b4ea 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -652,15 +652,73 @@ QDF_STATUS p2p_restart_roc_timer(struct p2p_roc_context *roc_ctx) return status; } -QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) +QDF_STATUS p2p_cleanup_roc_sync( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct wlan_objmgr_vdev *vdev) { + struct scheduler_msg msg = {0}; + struct p2p_cleanup_param *param; + QDF_STATUS status; + uint32_t vdev_id; + + if (!p2p_soc_obj) { + p2p_err("p2p soc context is NULL"); + return QDF_STATUS_E_FAILURE; + } + + p2p_debug("p2p_soc_obj:%pK, vdev:%pK", p2p_soc_obj, vdev); + param = qdf_mem_malloc(sizeof(*param)); + if (!param) { + p2p_err("failed to allocate cleanup param"); + return QDF_STATUS_E_NOMEM; + } + + param->p2p_soc_obj = p2p_soc_obj; + if (vdev) + vdev_id = (uint32_t)wlan_vdev_get_id(vdev); + else + vdev_id = P2P_INVALID_VDEV_ID; + param->vdev_id = vdev_id; + qdf_event_reset(&p2p_soc_obj->cleanup_roc_done); + msg.type = P2P_CLEANUP_ROC; + msg.bodyptr = param; + msg.callback = p2p_process_cmd; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("failed to post message"); + qdf_mem_free(param); + return status; + } + + status = qdf_wait_single_event( + &p2p_soc_obj->cleanup_roc_done, + P2P_WAIT_CLEANUP_ROC); + + if (status != QDF_STATUS_SUCCESS) + p2p_err("wait for cleanup roc timeout, %d", status); + + return status; +} + +QDF_STATUS p2p_process_cleanup_roc_queue( + struct p2p_cleanup_param *param) +{ + uint32_t vdev_id; + QDF_STATUS status, ret; struct p2p_roc_context *roc_ctx; qdf_list_node_t *p_node; - QDF_STATUS status, ret; + struct p2p_soc_priv_obj *p2p_soc_obj; - p2p_debug("clean up idle roc request, roc queue size:%d", - qdf_list_size(&p2p_soc_obj->roc_q)); + if (!param || !(param->p2p_soc_obj)) { + p2p_err("Invalid cleanup param"); + return QDF_STATUS_E_FAILURE; + } + p2p_soc_obj = param->p2p_soc_obj; + vdev_id = param->vdev_id; + + p2p_debug("clean up idle roc request, roc queue size:%d, vdev id:%d", + qdf_list_size(&p2p_soc_obj->roc_q), vdev_id); status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); while (QDF_IS_STATUS_SUCCESS(status)) { roc_ctx = qdf_container_of(p_node, @@ -674,13 +732,14 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx->roc_type, roc_ctx->roc_state); status = qdf_list_peek_next(&p2p_soc_obj->roc_q, p_node, &p_node); - if (roc_ctx->roc_state == ROC_STATE_IDLE) { + if ((roc_ctx->roc_state == ROC_STATE_IDLE) && + ((vdev_id == P2P_INVALID_VDEV_ID) || + (vdev_id == roc_ctx->vdev_id))) { ret = qdf_list_remove_node( &p2p_soc_obj->roc_q, (qdf_list_node_t *)roc_ctx); if (ret == QDF_STATUS_SUCCESS) - p2p_destroy_roc_ctx(roc_ctx, - true, false); + qdf_mem_free(roc_ctx); else p2p_err("Failed to remove roc ctx from queue"); } @@ -693,80 +752,17 @@ QDF_STATUS p2p_cleanup_roc_queue(struct p2p_soc_priv_obj *p2p_soc_obj) roc_ctx = qdf_container_of(p_node, struct p2p_roc_context, node); - p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx_ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", - roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, - roc_ctx->phy_mode, roc_ctx->duration, - roc_ctx->roc_type, roc_ctx->roc_state); + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, + roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); status = qdf_list_peek_next(&p2p_soc_obj->roc_q, p_node, &p_node); - if (roc_ctx->roc_state != ROC_STATE_IDLE) { - if (roc_ctx->roc_state != - ROC_STATE_CANCEL_IN_PROG) - p2p_execute_cancel_roc_req(roc_ctx); - - ret = qdf_wait_single_event( - &p2p_soc_obj->cancel_roc_done, - P2P_WAIT_CANCEL_ROC); - p2p_debug("roc cancellation done, return:%d", ret); - } - } - - return QDF_STATUS_SUCCESS; -} - -QDF_STATUS p2p_cleanup_roc_by_vdev( - struct p2p_soc_priv_obj *p2p_soc_obj, uint32_t vdev_id) -{ - QDF_STATUS status, ret; - struct p2p_roc_context *roc_ctx; - qdf_list_node_t *p_node; - - p2p_info("clean up idle roc request, roc queue size:%d, vdev id:%d", - qdf_list_size(&p2p_soc_obj->roc_q), vdev_id); - status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); - while (QDF_IS_STATUS_SUCCESS(status)) { - roc_ctx = qdf_container_of(p_node, - struct p2p_roc_context, node); - - p2p_info("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", - roc_ctx->p2p_soc_obj, roc_ctx, - roc_ctx->vdev_id, roc_ctx->scan_id, - roc_ctx->tx_ctx, roc_ctx->chan, - roc_ctx->phy_mode, roc_ctx->duration, - roc_ctx->roc_type, roc_ctx->roc_state); - status = qdf_list_peek_next(&p2p_soc_obj->roc_q, - p_node, &p_node); - if (roc_ctx->roc_state == ROC_STATE_IDLE && - roc_ctx->vdev_id == vdev_id) { - ret = qdf_list_remove_node( - &p2p_soc_obj->roc_q, - (qdf_list_node_t *)roc_ctx); - if (ret == QDF_STATUS_SUCCESS) - qdf_mem_free(roc_ctx); - else - p2p_err("Failed to remove roc ctx from queue"); - } - } - - p2p_info("clean up started roc request, roc queue size:%d", - qdf_list_size(&p2p_soc_obj->roc_q)); - status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); - while (QDF_IS_STATUS_SUCCESS(status)) { - roc_ctx = qdf_container_of(p_node, - struct p2p_roc_context, node); - - p2p_info("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", - roc_ctx->p2p_soc_obj, roc_ctx, roc_ctx->vdev_id, - roc_ctx->scan_id, roc_ctx->tx_ctx, roc_ctx->chan, - roc_ctx->phy_mode, roc_ctx->duration, - roc_ctx->roc_type, roc_ctx->roc_state); - - status = qdf_list_peek_next(&p2p_soc_obj->roc_q, - p_node, &p_node); - if (roc_ctx->roc_state != ROC_STATE_IDLE && - roc_ctx->vdev_id == vdev_id) { + if ((roc_ctx->roc_state != ROC_STATE_IDLE) && + ((vdev_id == P2P_INVALID_VDEV_ID) || + (vdev_id == roc_ctx->vdev_id))) { if (roc_ctx->roc_state != ROC_STATE_CANCEL_IN_PROG) p2p_execute_cancel_roc_req(roc_ctx); @@ -778,6 +774,8 @@ QDF_STATUS p2p_cleanup_roc_by_vdev( } } + qdf_event_set(&p2p_soc_obj->cleanup_roc_done); + return QDF_STATUS_SUCCESS; } diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index fa40e7aa885d..3ccff8c17297 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -29,6 +29,7 @@ #define P2P_EVENT_PROPAGATE_TIME 10 #define P2P_WAIT_CANCEL_ROC 1000 +#define P2P_WAIT_CLEANUP_ROC 2000 #ifdef QCA_WIFI_3_0_EMU #define P2P_ROC_DURATION_MULTI_GO_PRESENT 2 @@ -111,6 +112,16 @@ struct cancel_roc_context { uint64_t cookie; }; +/** + * struct p2p_cleanup_param - p2p cleanup parameters + * @p2p_soc_obj: Pointer to SoC global p2p private object + * @vdev_id: vdev id + */ +struct p2p_cleanup_param { + struct p2p_soc_priv_obj *p2p_soc_obj; + uint32_t vdev_id; +}; + /** * p2p_mgmt_rx_action_ops() - register or unregister rx action callback * @psoc: psoc object @@ -162,29 +173,31 @@ struct p2p_roc_context *p2p_find_roc_by_tx_ctx( QDF_STATUS p2p_restart_roc_timer(struct p2p_roc_context *roc_ctx); /** - * p2p_cleanup_roc_queue() - Cleanup roc context in queue + * p2p_cleanup_roc_sync() - Cleanup roc context in queue * @p2p_soc_obj: p2p psoc private object + * @vdev: vdev object * * This function cleanup roc context in queue, include the roc - * context in progressing. + * context in progressing until cancellation done. To avoid deadlock, + * don't call from scheduler thread. * * Return: QDF_STATUS_SUCCESS - in case of success */ -QDF_STATUS p2p_cleanup_roc_queue( - struct p2p_soc_priv_obj *p2p_soc_obj); +QDF_STATUS p2p_cleanup_roc_sync( + struct p2p_soc_priv_obj *p2p_soc_obj, + struct wlan_objmgr_vdev *vdev); /** - * p2p_cleanup_roc_by_vdev() - Cleanup roc context by vdev id - * @p2p_soc_obj: p2p psoc private object - * @vdev_id: vdev id + * p2p_process_cleanup_roc_queue() - process the message to cleanup roc + * @param: pointer to cleanup parameters * - * This function cleanup roc context by vdev id, include the roc - * context in progressing. + * This function process the message to cleanup roc context in queue, + * include the roc context in progressing. * * Return: QDF_STATUS_SUCCESS - in case of success */ -QDF_STATUS p2p_cleanup_roc_by_vdev( - struct p2p_soc_priv_obj *p2p_soc_obj, uint32_t vdev_id); +QDF_STATUS p2p_process_cleanup_roc_queue( + struct p2p_cleanup_param *param); /** * p2p_process_roc_req() - Process roc request diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 50017d7f5688..17e289de96f9 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -123,11 +123,9 @@ QDF_STATUS tgt_p2p_mgmt_download_comp_cb(void *context, QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, uint32_t status, void *tx_compl_params) { - struct p2p_tx_cnf *tx_cnf; struct p2p_tx_conf_event *tx_conf_event; - struct p2p_soc_priv_obj *p2p_soc_obj; - struct tx_action_context *tx_ctx; struct scheduler_msg msg = {0}; + QDF_STATUS ret; p2p_debug("context:%pK, buf:%pK, status:%d, tx complete params:%pK", context, buf, status, tx_compl_params); @@ -137,19 +135,6 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, qdf_nbuf_free(buf); return QDF_STATUS_E_INVAL; } - p2p_soc_obj = (struct p2p_soc_priv_obj *)context; - tx_ctx = p2p_find_tx_ctx_by_nbuf(p2p_soc_obj, buf); - if (!tx_ctx) { - p2p_err("can't find tx_ctx, tx ack comes late"); - qdf_nbuf_free(buf); - return QDF_STATUS_E_FAULT; - } - - if (tx_ctx->is_deleting) { - p2p_info("Received duplicate tx ack"); - return QDF_STATUS_SUCCESS; - } - tx_ctx->is_deleting = true; tx_conf_event = qdf_mem_malloc(sizeof(*tx_conf_event)); if (!tx_conf_event) { @@ -158,26 +143,19 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, return QDF_STATUS_E_NOMEM; } - tx_cnf = qdf_mem_malloc(sizeof(*tx_cnf)); - if (!tx_cnf) { - p2p_err("Failed to allocate tx cnf"); - qdf_nbuf_free(buf); - return QDF_STATUS_E_NOMEM; - } - - qdf_nbuf_free(buf); - tx_cnf->vdev_id = tx_ctx->vdev_id; - tx_cnf->action_cookie = (uint64_t)tx_ctx->id; - tx_cnf->buf = tx_ctx->buf; - tx_cnf->buf_len = tx_ctx->buf_len; - tx_cnf->status = status; - tx_conf_event->p2p_soc_obj = p2p_soc_obj; - tx_conf_event->tx_cnf = tx_cnf; - tx_conf_event->tx_ctx = tx_ctx; + tx_conf_event->status = status; + tx_conf_event->nbuf = buf; + tx_conf_event->p2p_soc_obj = (struct p2p_soc_priv_obj *)context; msg.type = P2P_EVENT_MGMT_TX_ACK_CNF; msg.bodyptr = tx_conf_event; msg.callback = p2p_process_evt; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + ret = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + if (ret != QDF_STATUS_SUCCESS) { + qdf_mem_free(tx_conf_event); + qdf_mem_free(buf); + p2p_err("failed to post message"); + return status; + } return QDF_STATUS_SUCCESS; } diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 84366e846e16..efa74baba9de 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -211,9 +211,8 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev) { - struct wlan_objmgr_psoc *psoc; struct p2p_soc_priv_obj *p2p_soc_obj; - uint32_t vdev_id; + struct wlan_objmgr_psoc *psoc; p2p_debug("vdev:%pK", vdev); @@ -222,7 +221,6 @@ QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_E_INVAL; } - vdev_id = (uint32_t)wlan_vdev_get_id(vdev); psoc = wlan_vdev_get_psoc(vdev); if (!psoc) { p2p_err("null psoc"); @@ -236,7 +234,7 @@ QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev) return QDF_STATUS_E_FAILURE; } - return p2p_cleanup_roc_by_vdev(p2p_soc_obj, vdev_id); + return p2p_cleanup_roc_sync(p2p_soc_obj, vdev); } QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, @@ -293,7 +291,6 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, tx_action->no_cck = mgmt_frm->no_cck; tx_action->no_ack = mgmt_frm->dont_wait_for_ack; tx_action->off_chan = mgmt_frm->off_chan; - tx_action->is_deleting = false; tx_action->buf = qdf_mem_malloc(tx_action->buf_len); if (!(tx_action->buf)) { p2p_err("Failed to allocate buffer for action frame"); From 1554dcd7e143e2caa9530bf67e66891ea93857c2 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 12 Apr 2018 17:38:28 -0700 Subject: [PATCH 270/404] qcacmn: Do not stop TDLS timers before restart MC timer implementation has changed recently, and it requires TDLS timers shouldn't be stopped before restart. Change-Id: I718972bd0f7c66b04145ee38c58440f6240a8de2 CRs-Fixed: 2223777 --- core/src/wlan_tdls_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index e1a564ce92e7..852352255ef5 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -374,7 +374,6 @@ void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, qdf_mc_timer_t *timer, uint32_t expiration_time) { - qdf_mc_timer_stop(timer); qdf_mc_timer_start(timer, expiration_time); } From 7c96e54a19e7711c0aeec1cf3abd8879c02d5c13 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 7 Jun 2018 19:32:27 +0530 Subject: [PATCH 271/404] qcacmn: Allow SAP to move from one DFS chan to another DFS chan Allow the SAP to move from DFS channel to another DFS channel in STA+SAP SCC concurrency scenario. CRs-Fixed: 2263031 Change-Id: I3d1f5e57415ed39a30125d4565bb768926dff4c9 --- src/wlan_policy_mgr_action.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 4cbffd08431c..765778787d48 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -865,6 +865,7 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( uint8_t channel = *con_ch; uint8_t temp_channel = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + bool sta_sap_scc_on_dfs_chan; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -893,6 +894,9 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( else if (!channel) channel = sap_ch; + sta_sap_scc_on_dfs_chan = + policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); + if (policy_mgr_valid_sta_channel_check(psoc, channel)) { if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) || wlan_reg_is_passive_or_disable_ch( @@ -920,6 +924,11 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( return QDF_STATUS_E_FAILURE; } } else { + if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) && + sta_sap_scc_on_dfs_chan) { + policy_mgr_debug("STA SAP SCC is allowed on DFS channel"); + goto update_chan; + } policy_mgr_warn("Can't have concurrency on %d", channel); return QDF_STATUS_E_FAILURE; @@ -927,6 +936,7 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( } } +update_chan: if (channel != sap_ch) *con_ch = channel; From 637eba547a6f83d4ae601b3d47d1640f8a66bc3e Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Thu, 14 Jun 2018 17:55:15 -0700 Subject: [PATCH 272/404] qcacmn: Check HW mode before sending join request to lower layers When STA's join req times out on current BSS, SME issues next BSS internally without checking HW mode for new channel For example, STA tries to connect SSID="abc", BSSID="a1:a2:a3:a4:a5:a6", channel=36 and lets say it fails. It should try few more times to same BSSID and after that it will try next bss. Lets say next BSS it found has, SSID="abc", BSSID="b1:b2:b3:b4:b5:b6", channel=1 then it needs to check whether hardware mode change is required for channel=1. If driver fails in checking hardware mode then following check will prevent the bad situation. CRs-Fixed: 2261129 Change-Id: Ie31ac5b8b90c6e63122148647ad333fccfbf9dbf --- inc/wlan_policy_mgr_api.h | 18 ++++++++++ src/wlan_policy_mgr_action.c | 70 ++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 0244b1498aa9..c58f81812595 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2302,6 +2302,24 @@ bool policy_mgr_is_sta_connected_2g(struct wlan_objmgr_psoc *psoc); */ void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc, uint8_t *org_ch_list, uint8_t *org_ch_list_count); + +/** + * policy_mgr_is_hwmode_set_for_given_chnl() - to check for given channel + * if the hw mode is properly set. + * @psoc: pointer to psoc + * @channel: given channel + * + * If HW mode is properly set for given channel then it returns true else + * it returns false. + * For example, when 2x2 DBS is supported and if the first connection is + * coming up on 2G band then driver expects DBS HW mode to be set first + * before the connection can be established. Driver can call this API to + * find-out if HW mode is set properly. + * + * Return: true if HW mode is set properly else false + */ +bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc, + uint8_t channel); /* * policy_mgr_get_connection_info() - Get info of all active connections * @info: Pointer to connection info diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 765778787d48..3f22044699d8 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -415,6 +415,76 @@ bool policy_mgr_is_dbs_allowed_for_concurrency( return ret; } +static bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, + uint8_t channel) +{ + uint8_t i, pm_chnl; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + /* + * check given channel against already existing connections' + * channels. if they differ then channels are in different bands + */ + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + pm_chnl = pm_conc_connection_list[i].chan; + if (pm_conc_connection_list[i].in_use) + if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_chnl)) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug("channel is in diff band"); + return true; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return false; +} + +bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc, + uint8_t channel) +{ + enum policy_mgr_band band; + bool is_hwmode_dbs, is_2x2_dbs; + + if (policy_mgr_is_hw_dbs_capable(psoc) == false) + return true; + + if (WLAN_REG_IS_24GHZ_CH(channel)) + band = POLICY_MGR_BAND_24; + else + band = POLICY_MGR_BAND_5; + + is_hwmode_dbs = policy_mgr_is_current_hwmode_dbs(psoc); + is_2x2_dbs = policy_mgr_is_hw_dbs_2x2_capable(psoc); + /* + * If HW supports 2x2 chains in DBS HW mode and if DBS HW mode is not + * yet set then this is the right time to block the connection. + */ + if ((band == POLICY_MGR_BAND_24) && is_2x2_dbs && !is_hwmode_dbs) { + policy_mgr_err("HW mode is not yet in DBS!!!!!"); + return false; + } + + /* + * If HW supports 1x1 chains DBS HW mode and if first connection is + * 2G or 5G band and if second connection is coming up in diffrent + * band than the first connection and if current HW mode is not yet + * set in DBS then this is the right time to block the connection. + */ + if (policy_mgr_is_chnl_in_diff_band(psoc, channel) && !is_hwmode_dbs) { + policy_mgr_err("Given channel & existing conn is diff band & HW mode is not yet in DBS !!!!"); + return false; + } + + return true; +} + QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, uint32_t session_id, uint8_t channel, From 85b42f4930d95189ca1cc70d25dae93efe220b0b Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Fri, 8 Jun 2018 12:38:35 +0530 Subject: [PATCH 273/404] qcacmn: Ignore CSA if the channel is DFS or disabled If MCC to SCC switch is enabled, SAP is active and CSA received for STA interface, then ignore the CSA if channel is DFS/disabled. CRs-Fixed: 2263037 Change-Id: I98b8d957766358ea86cc9f50339725cf4bf0038b --- inc/wlan_policy_mgr_api.h | 13 +++++++++++ src/wlan_policy_mgr_get_set_utils.c | 34 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index c58f81812595..9b866395dabf 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2391,4 +2391,17 @@ bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( bool policy_mgr_sta_sap_scc_on_lte_coex_chan( struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_valid_channel_for_channel_switch() - check for valid channel for + * channel switch. + * @psoc: poniter to psoc + * @channel: channel to be validated. + * This function validates whether the given channel is valid for channel + * switch. + * + * Return: true or false + */ +bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, + uint8_t channel); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index c43a06f0d489..fcc811dbf5c1 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -3104,3 +3104,37 @@ bool policy_mgr_sta_sap_scc_on_lte_coex_chan( } return pm_ctx->user_cfg.sta_sap_scc_on_lte_coex_chan; } + +bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, + uint8_t channel) +{ + uint32_t sta_sap_scc_on_dfs_chan; + uint32_t sap_count; + enum channel_state state; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + sta_sap_scc_on_dfs_chan = + policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); + sap_count = policy_mgr_mode_specific_connection_count(psoc, + PM_SAP_MODE, + NULL); + state = reg_get_channel_state(pm_ctx->pdev, channel); + + policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_count %u, channel %u, state %u", + sta_sap_scc_on_dfs_chan, sap_count, channel, state); + + if ((state == CHANNEL_STATE_ENABLE) || (sap_count == 0) || + ((state == CHANNEL_STATE_DFS) && sta_sap_scc_on_dfs_chan)) { + policy_mgr_debug("Valid channel for channel switch"); + return true; + } + + policy_mgr_debug("Invalid channel for channel switch"); + return false; +} From 378064b5e091768758e0b5102941a785f45dba35 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 11 Jun 2018 15:06:53 +0530 Subject: [PATCH 274/404] qcacmn: Defer the channel switch if it is already in progress When sta+sap scc enabled on dfs channel then SAP cannot operate on DFS channel in standalone mode. If STA+SAP are operating in SCC mode on a DFS channel and STA gets disconnected from reference AP then driver schedules a workqueue to move the SAP from DFS channel to user configured channel. At this time if STA again connects to reference AP within few ms then driver again schedules one more workqueue to move the SAP to STA's channel. Sometimes the second workqueue may fail to switch the channel if first one is not yet completed. So added event variable to schedule second workqueue only when first one is complete. CRs-Fixed: 2267005 Change-Id: Ia6ce4b6264c35f6d2c809e2a3f65f535e930874e --- inc/wlan_policy_mgr_api.h | 22 +++++++++++++ src/wlan_policy_mgr_action.c | 54 +++++++++++++++++++++++++++++++ src/wlan_policy_mgr_i.h | 2 ++ src/wlan_policy_mgr_init_deinit.c | 12 +++++++ 4 files changed, 90 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 9b866395dabf..af7e88831592 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1146,6 +1146,28 @@ QDF_STATUS policy_mgr_reset_connection_update(struct wlan_objmgr_psoc *psoc); */ QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_set_chan_switch_complete_evt() - set channel + * switch completion event + * @psoc: PSOC object information + * Sets the channel switch completion event. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_set_chan_switch_complete_evt( + struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_reset_chan_switch_complete_evt() - reset channel + * switch completion event + * @psoc: PSOC object information + * Resets the channel switch completion event. + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_reset_chan_switch_complete_evt( + struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_set_opportunistic_update() - Set opportunistic * update event diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 3f22044699d8..7cb62158e3ee 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -881,6 +881,14 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) goto end; } + policy_mgr_debug("wait if channel switch is already in progress"); + status = qdf_wait_single_event( + &pm_ctx->channel_switch_complete_evt, + CHANNEL_SWITCH_COMPLETE_TIMEOUT); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("wait for event failed, still continue with channel switch"); + } if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) { policy_mgr_err("SAP restart get channel callback in NULL"); goto end; @@ -1181,6 +1189,52 @@ QDF_STATUS policy_mgr_set_connection_update(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +QDF_STATUS policy_mgr_set_chan_switch_complete_evt( + struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *policy_mgr_context; + + policy_mgr_context = policy_mgr_get_context(psoc); + + if (!policy_mgr_context) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + status = qdf_event_set( + &policy_mgr_context->channel_switch_complete_evt); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("set event failed"); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_reset_chan_switch_complete_evt( + struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct policy_mgr_psoc_priv_obj *policy_mgr_context; + + policy_mgr_context = policy_mgr_get_context(psoc); + + if (!policy_mgr_context) { + policy_mgr_err("Invalid context"); + return QDF_STATUS_E_FAILURE; + } + status = qdf_event_reset( + &policy_mgr_context->channel_switch_complete_evt); + + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("reset event failed"); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_set_opportunistic_update(struct wlan_objmgr_psoc *psoc) { QDF_STATUS status; diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 6e305fac1088..208f9ceb5f2c 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -35,6 +35,7 @@ #define PM_24_GHZ_CHANNEL_6 (6) #define PM_5_GHZ_CHANNEL_36 (36) +#define CHANNEL_SWITCH_COMPLETE_TIMEOUT (2000) /** * Policy Mgr hardware mode list bit-mask definitions. @@ -265,6 +266,7 @@ struct policy_mgr_psoc_priv_obj { uint8_t cur_conc_system_pref; uint8_t sta_sap_scc_on_dfs_chan_allowed; qdf_event_t opportunistic_update_done_evt; + qdf_event_t channel_switch_complete_evt; send_mode_change_event_cb mode_change_cb; }; diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index d6a198932aa2..83528a963e27 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -403,6 +403,11 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) return status; } + status = qdf_event_create(&pm_ctx->channel_switch_complete_evt); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("channel_switch_complete_evt init failed"); + return status; + } pm_ctx->do_hw_mode_change = false; pm_ctx->hw_mode_change_in_progress = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; /* reset sap mandatory channels */ @@ -477,6 +482,13 @@ QDF_STATUS policy_mgr_psoc_disable(struct wlan_objmgr_psoc *psoc) status = QDF_STATUS_E_FAILURE; QDF_ASSERT(0); } + /* destroy channel_switch_complete_evt */ + if (!QDF_IS_STATUS_SUCCESS(qdf_event_destroy + (&pm_ctx->channel_switch_complete_evt))) { + policy_mgr_err("Failed to destroy channel_switch_complete evt"); + status = QDF_STATUS_E_FAILURE; + QDF_ASSERT(0); + } /* deallocate dbs_opportunistic_timer */ if (QDF_TIMER_STATE_RUNNING == From 2854295433be6cb8a044703f21234e3aab44b9c0 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Wed, 13 Jun 2018 11:43:46 +0530 Subject: [PATCH 275/404] qcacmn: Send mode change event after addkey On STA connection, mode change event is sent to userspace after association is completed. This causes delay in processing of M1 frame at supplicant due to latency associated with nl80211_get_wiphy_index function as part of processing mode change vendor event. Fix is to send mode change event for STA after key is added. Change-Id: Id403bfdd26ed3a47449ba3f2967f4b4322ad5da6 CRs-Fixed: 2260483 --- src/wlan_policy_mgr_action.c | 15 +++++++++++---- src/wlan_policy_mgr_core.c | 13 +++++++++++-- src/wlan_policy_mgr_get_set_utils.c | 5 ++++- src/wlan_policy_mgr_i.h | 3 ++- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 7cb62158e3ee..730f3bdeb7b1 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -308,7 +308,7 @@ QDF_STATUS policy_mgr_update_connection_info(struct wlan_objmgr_psoc *psoc, policy_mgr_get_bw(conn_table_entry.chan_width), conn_table_entry.mac_id, chain_mask, - nss, vdev_id, true); + nss, vdev_id, true, true); return QDF_STATUS_SUCCESS; } @@ -1531,7 +1531,7 @@ QDF_STATUS policy_mgr_update_connection_info_utfw( policy_mgr_update_conc_list(psoc, conn_index, policy_mgr_get_mode(type, sub_type), channelid, HW_MODE_20_MHZ, - mac_id, chain_mask, 0, vdev_id, true); + mac_id, chain_mask, 0, vdev_id, true, true); return QDF_STATUS_SUCCESS; } @@ -1543,6 +1543,8 @@ QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t conn_index = 0; + bool update_conn = true; + enum policy_mgr_con_mode mode; conn_index = policy_mgr_get_connection_count(psoc); if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) { @@ -1553,10 +1555,15 @@ QDF_STATUS policy_mgr_incr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, } policy_mgr_debug("--> filling entry at index[%d]", conn_index); + mode = policy_mgr_get_mode(type, sub_type); + if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE) + update_conn = false; + policy_mgr_update_conc_list(psoc, conn_index, - policy_mgr_get_mode(type, sub_type), + mode, channelid, HW_MODE_20_MHZ, - mac_id, chain_mask, 0, vdev_id, true); + mac_id, chain_mask, 0, vdev_id, true, + update_conn); return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index a0b1643d6c81..54583ed52b19 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -526,6 +526,8 @@ QDF_STATUS policy_mgr_get_old_and_new_hw_index( * @chain_mask: Chain mask * @vdev_id: vdev id * @in_use: Flag to indicate if the index is in use or not + * @update_conn: Flag to indicate if mode change event should + * be sent or not * * Updates the index value of the concurrent connection list * @@ -540,7 +542,8 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, enum policy_mgr_chain_mode chain_mask, uint32_t original_nss, uint32_t vdev_id, - bool in_use) + bool in_use, + bool update_conn) { struct policy_mgr_psoc_priv_obj *pm_ctx; bool mcc_mode; @@ -568,7 +571,13 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, pm_conc_connection_list[conn_index].in_use = in_use; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - if (pm_ctx->mode_change_cb) + /* + * For STA and P2P client mode, the mode change event sent as part + * of the callback causes delay in processing M1 frame at supplicant + * resulting in cert test case failure. The mode change event is sent + * as part of add key for STA and P2P client mode. + */ + if (pm_ctx->mode_change_cb && update_conn) pm_ctx->mode_change_cb(); policy_mgr_dump_connection_status_info(psoc); diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index fcc811dbf5c1..7f24349f7298 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1273,6 +1273,7 @@ QDF_STATUS policy_mgr_incr_connection_count( uint8_t chan; uint32_t nss = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; + bool update_conn = true; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1314,6 +1315,8 @@ QDF_STATUS policy_mgr_incr_connection_count( policy_mgr_err("Error in getting nss"); } + if (mode == PM_STA_MODE || mode == PM_P2P_CLIENT_MODE) + update_conn = false; /* add the entry */ policy_mgr_update_conc_list(psoc, conn_index, @@ -1322,7 +1325,7 @@ QDF_STATUS policy_mgr_incr_connection_count( policy_mgr_get_bw(conn_table_entry.chan_width), conn_table_entry.mac_id, chain_mask, - nss, vdev_id, true); + nss, vdev_id, true, update_conn); policy_mgr_debug("Add at idx:%d vdev %d mac=%d", conn_index, vdev_id, conn_table_entry.mac_id); diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 208f9ceb5f2c..66ceaa043733 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -349,7 +349,8 @@ void policy_mgr_update_conc_list(struct wlan_objmgr_psoc *psoc, enum policy_mgr_chain_mode chain_mask, uint32_t original_nss, uint32_t vdev_id, - bool in_use); + bool in_use, + bool update_conn); void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, bool all_matching_cxn_to_del, From 9b1636dcd4dc8592b129ed121bd62989b1575e5a Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 27 Jun 2018 13:27:11 -0700 Subject: [PATCH 276/404] qcacmn: Don't move SAP if SCC on lte coex channel is allowed If STA+SAP is doing SCC & g_sta_sap_scc_on_lte_coex_chan is set, don't move SAP to a different channel when LTE channel avoidance event comes. Change-Id: I3dfdbb6d59769a8ff9b3b2e6d828feee94630569 CRs-Fixed: 2268993 --- inc/wlan_policy_mgr_api.h | 10 +++++++++ src/wlan_policy_mgr_get_set_utils.c | 34 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index af7e88831592..efdeb088c974 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2426,4 +2426,14 @@ bool policy_mgr_sta_sap_scc_on_lte_coex_chan( bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, uint8_t channel); +/** + * policy_mgr_is_sta_sap_scc() - check whether SAP is doing SCC with + * STA + * @psoc: poniter to psoc + * @sap_ch: operating channel of SAP interface + * This function checks whether SAP is doing SCC with STA + * + * Return: true or false + */ +bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 7f24349f7298..ab66d8bd5674 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -3141,3 +3141,37 @@ bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("Invalid channel for channel switch"); return false; } + +bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch) +{ + uint32_t conn_index; + bool is_scc = false; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return is_scc; + } + + if (!policy_mgr_mode_specific_connection_count( + psoc, PM_STA_MODE, NULL)) { + policy_mgr_debug("There is no STA+SAP conc"); + return is_scc; + } + + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if (pm_conc_connection_list[conn_index].in_use && + (pm_conc_connection_list[conn_index].mode == + PM_STA_MODE) && + (sap_ch == pm_conc_connection_list[conn_index].chan)) { + is_scc = true; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return is_scc; +} From 68bdbfa062eb39e65bc8e2398aa891a6fdd3bb35 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 14 Jun 2018 12:28:10 +0530 Subject: [PATCH 277/404] qcacmn: Add support to allow user select preferred band for SAP Add enum QDF_MCC_TO_SCC_WITH_PREFERRED_BAND(6) for this. If ini gWlanMccToSccSwitchMode is selected to QDF_MCC_TO_SCC_WITH_PREFERRED_BAND(6) then following will be the behaviour of STA+SAP concurrency. 1. If second interface(SAP/STA) comes in same band as first interface(STA/SAP) respectively then force SCC irrespective of channel. 2. If second interface(SAP/STA) comes in other band as first interface(STA/SAP) then dont force SCC allow interband MCC or DBS based on DBS capability. Allow interband MCC but not intraband MCC. Change-Id: I91d41b4b0306ed4e362b5bcab9538f5fd5feea7d CRs-Fixed: 2260677 --- src/wlan_policy_mgr_get_set_utils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index ab66d8bd5674..3a6e71a6c835 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2824,7 +2824,9 @@ bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc) (pm_ctx->user_cfg.mcc_to_scc_switch_mode == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) || (pm_ctx->user_cfg.mcc_to_scc_switch_mode == - QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION)); + QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) || + (pm_ctx->user_cfg.mcc_to_scc_switch_mode == + QDF_MCC_TO_SCC_WITH_PREFERRED_BAND)); } bool policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan( From 3b3f16f39f8df23cc491e77b17a7a3b5861e1bba Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Wed, 27 Jun 2018 12:50:10 +0530 Subject: [PATCH 278/404] qcacmn: Move the SAP to non DFS channel after STA disconnection Standalone SAP is not allowed on DFS channel if STA+SAP SCC enabled on DFS channel. So move the SAP to a non DFS channel as soon as STA gets disconnect. CRs-Fixed: 2269249 Change-Id: I27d018739f53997641a7113cfc7c844e02bd7e29 --- inc/wlan_policy_mgr_api.h | 27 ++++++++++++ src/wlan_policy_mgr_action.c | 80 ++++++++++++++++++++++++++++++++++-- src/wlan_policy_mgr_i.h | 1 + 3 files changed, 105 insertions(+), 3 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index efdeb088c974..6256fe7fc6cf 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2426,6 +2426,32 @@ bool policy_mgr_sta_sap_scc_on_lte_coex_chan( bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, uint8_t channel); +/** + * policy_mgr_update_user_config_sap_chan() - Update user configured channel + * @psoc: poniter to psoc + * @channel: channel to be upated + * + * Return: void + **/ +void policy_mgr_update_user_config_sap_chan( + struct wlan_objmgr_psoc *psoc, uint32_t channel); + +/** + * policy_mgr_is_sap_restart_required_after_sta_disconnect() - is sap restart + * required + * after sta disconnection + * @psoc: psoc object data + * @intf_ch: sap channel + * + * Check if SAP should be moved to a non dfs channel after STA disconnection. + * This API applicable only for STA+SAP SCC and ini 'sta_sap_scc_on_dfs_chan' + * is enabled. + * + * Return: true if sap restart is required, otherwise false + */ +bool policy_mgr_is_sap_restart_required_after_sta_disconnect( + struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch); + /** * policy_mgr_is_sta_sap_scc() - check whether SAP is doing SCC with * STA @@ -2436,4 +2462,5 @@ bool policy_mgr_is_valid_for_channel_switch(struct wlan_objmgr_psoc *psoc, * Return: true or false */ bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch); + #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 730f3bdeb7b1..3fa6002fd568 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -758,6 +758,19 @@ QDF_STATUS policy_mgr_handle_conc_multiport(struct wlan_objmgr_psoc *psoc, } #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +void policy_mgr_update_user_config_sap_chan( + struct wlan_objmgr_psoc *psoc, uint32_t channel) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid pm context and failed to update the user config sap channel"); + return; + } + pm_ctx->user_config_sap_channel = channel; +} + /** * policy_mgr_is_restart_sap_allowed() - Check if restart SAP * allowed during SCC -> MCC switch @@ -820,6 +833,40 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc, return is_safe; } +bool policy_mgr_is_sap_restart_required_after_sta_disconnect( + struct wlan_objmgr_psoc *psoc, uint8_t *intf_ch) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint8_t sap_chan = policy_mgr_mode_specific_get_channel(psoc, + PM_SAP_MODE); + bool sta_sap_scc_on_dfs_chan = + policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); + + *intf_ch = 0; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid pm context"); + return false; + } + + policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u", + sta_sap_scc_on_dfs_chan, sap_chan); + + if (!sta_sap_scc_on_dfs_chan || + !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) && + (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) == + CHANNEL_STATE_DFS))) { + return false; + } + + *intf_ch = pm_ctx->user_config_sap_channel; + policy_mgr_debug("Standalone SAP is not allowed on DFS channel, Move it to channel %u", + *intf_ch); + + return true; +} + /** * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case * @data: Pointer check concurrent channel work data @@ -1040,12 +1087,28 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; uint32_t cc_count = 0; + bool restart_sap = false; + uint8_t sap_ch; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid context"); return; } + if (policy_mgr_get_connection_count(psoc) == 1) { + /* + * If STA+SAP sessions are on DFS channel and STA+SAP SCC is + * enabled on DFS channel then move the SAP out of DFS channel + * as soon as STA gets disconnect. + */ + if (policy_mgr_is_sap_restart_required_after_sta_disconnect( + psoc, &sap_ch)) { + policy_mgr_debug("move the SAP to configured channel %u", + sap_ch); + restart_sap = true; + goto sap_restart; + } + } /* * force SCC with STA+STA+SAP will need some additional logic @@ -1069,9 +1132,20 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( return; } - if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && - policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) - && !pm_ctx->sta_ap_intf_check_work_info) { +sap_restart: + /* + * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not + * allowed on DFS channel. SAP is allowed on DFS channel only when STA + * is already connected on that channel. + * In following condition restart_sap will be true if + * sta_sap_scc_on_dfs_chan is true and SAP is on DFS channel. + * This scenario can come if STA+SAP are operating on DFS channel and + * STA gets disconnected. + */ + if (restart_sap || + ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && + policy_mgr_valid_sta_channel_check(psoc, operating_channel[0]) && + !pm_ctx->sta_ap_intf_check_work_info)) { struct sta_ap_intf_check_work_ctx *work_info; work_info = qdf_mem_malloc( sizeof(struct sta_ap_intf_check_work_ctx)); diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 66ceaa043733..41c9cc40d200 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -268,6 +268,7 @@ struct policy_mgr_psoc_priv_obj { qdf_event_t opportunistic_update_done_evt; qdf_event_t channel_switch_complete_evt; send_mode_change_event_cb mode_change_cb; + uint32_t user_config_sap_channel; }; /** From ce724ff735f56ae1960382bc76be2d19db6c6e85 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Tue, 26 Jun 2018 15:21:30 +0800 Subject: [PATCH 279/404] qcacmn: Initialize tdls peer sta_id TDLS sta_id check logic has changed, the value zero is valid, so initialize the tdls peer sta_id as 0xff, otherwise add tdls peer won't happen. Change-Id: I805e4abdec8806f649d15da4f02980de9ffdc0ea CRs-Fixed: 2263523 --- core/src/wlan_tdls_peer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index b761646d0c04..82ecb43d326c 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -185,6 +185,7 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj, tdls_find_opclass(soc_obj->soc, peer->pref_off_chan_num, soc_obj->tdls_configs.tdls_pre_off_chan_bw); + peer->sta_id = INVALID_TDLS_PEER_ID; qdf_list_insert_back(head, &peer->node); From 7f6bdd3b9db40310d08fd0c7935659fdbfc6287e Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Fri, 29 Jun 2018 10:39:30 +0800 Subject: [PATCH 280/404] qcacmn: Move SAP to safe channel after STA disconnection Standalone SAP is not allowed on lte-coex channel if STA+SAP SCC enabled on lte-coex channel. So move the SAP to a safe channel once STA disconnected. Change-Id: I00682f5bbb3da772e3e26ccd8d08183be28cc9ec CRs-Fixed: 2265263 --- inc/wlan_policy_mgr_api.h | 2 +- src/wlan_policy_mgr_action.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 6256fe7fc6cf..e48ff10ded08 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2445,7 +2445,7 @@ void policy_mgr_update_user_config_sap_chan( * * Check if SAP should be moved to a non dfs channel after STA disconnection. * This API applicable only for STA+SAP SCC and ini 'sta_sap_scc_on_dfs_chan' - * is enabled. + * or 'sta_sap_scc_on_lte_coex_chan' is enabled. * * Return: true if sap restart is required, otherwise false */ diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 3fa6002fd568..4a711e74bf37 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -853,10 +853,12 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect( policy_mgr_debug("sta_sap_scc_on_dfs_chan %u, sap_chan %u", sta_sap_scc_on_dfs_chan, sap_chan); - if (!sta_sap_scc_on_dfs_chan || - !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) && - (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) == - CHANNEL_STATE_DFS))) { + if ((!sta_sap_scc_on_dfs_chan || + !(sap_chan && WLAN_REG_IS_5GHZ_CH(sap_chan) && + (wlan_reg_get_channel_state(pm_ctx->pdev, sap_chan) == + CHANNEL_STATE_DFS))) && + (!policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) || + policy_mgr_is_safe_channel(psoc, sap_chan))) { return false; } @@ -1100,6 +1102,9 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( * If STA+SAP sessions are on DFS channel and STA+SAP SCC is * enabled on DFS channel then move the SAP out of DFS channel * as soon as STA gets disconnect. + * If STA+SAP sessions are on unsafe channel and STA+SAP SCC is + * enabled on unsafe channel then move the SAP to safe channel + * as soon as STA disconnected. */ if (policy_mgr_is_sap_restart_required_after_sta_disconnect( psoc, &sap_ch)) { From dcff88fc76c1d53289788f9a5a9a607ac3ce78ab Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Fri, 29 Jun 2018 11:58:08 +0800 Subject: [PATCH 281/404] qcacmn: Post tdls connet/disconnect event to target_if queue TDLS will update tdls firmware state according to STA connection status, the change is to post tdls connect/disconnect event to target_if queue, otherwise these events will be scheduled too late which would be out of sync, cause unexpected results. Change-Id: I76d70339f236b580bfb98fb1b8f5121784cb3465 CRs-Fixed: 2269978 --- dispatcher/src/wlan_tdls_ucfg_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 442fb5c9f989..c93333d99ead 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -636,7 +636,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_CONNECTION; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); tdls_debug("Exit "); return QDF_STATUS_SUCCESS; @@ -669,7 +669,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); tdls_debug("Exit "); From e173405103640123e9f5fffad687fcdf3e71cd05 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 28 Jun 2018 11:13:25 +0530 Subject: [PATCH 282/404] qcacmn: Avoid possible buffer overflow In function tdls_ct_sampling_tx_rx, memcpy of unknown length buffer is done into fixed size struct array. Mem copying without checking length can lead to buffer overflow. Change-Id: I0608bd69d71ff1901f82b44d045963e9d383e6ce CRs-Fixed: 2269276 --- core/src/wlan_tdls_ct.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 7c44278af44f..b3f28a458648 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -223,7 +223,8 @@ static void tdls_ct_sampling_tx_rx(struct tdls_vdev_priv_obj *tdls_vdev, return; } - mac_entries = tdls_vdev->valid_mac_entries; + mac_entries = QDF_MIN(tdls_vdev->valid_mac_entries, + WLAN_TDLS_CT_TABLE_SIZE); qdf_mem_copy(mac_table, tdls_vdev->ct_peer_table, (sizeof(struct tdls_conn_tracker_mac_table)) * mac_entries); From 8f12beb1dfe8130c0dcfdc662b24944faa9be09d Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Wed, 4 Jul 2018 21:14:59 +0800 Subject: [PATCH 283/404] qcacmn: Deregister rx callback if failed to abort P2P scan For failed to abort P2P scan case, it won't deregister rx callback and then memory leak. To fix the memory leak, call deregister rx callback if abort P2P scan fails. Change-Id: Iad4087175d437bf73363c782181b070492251f5b CRs-Fixed: 2268674 --- core/src/wlan_p2p_roc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 1ff391e4b4ea..2e171a9244b2 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -282,6 +282,7 @@ static QDF_STATUS p2p_execute_cancel_roc_req( p2p_err("Failed to abort scan, status:%d, destroy roc %pK", status, roc_ctx); qdf_mc_timer_destroy(&roc_ctx->roc_timer); + p2p_mgmt_rx_ops(p2p_soc_obj->soc, false); p2p_destroy_roc_ctx(roc_ctx, true, true); qdf_event_set(&p2p_soc_obj->cancel_roc_done); return status; From aa40f60b9c6ee2a64f8e8acfb7cd39a550ce3abe Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Tue, 15 May 2018 15:48:57 -0700 Subject: [PATCH 284/404] qcacmn: Add support for SRD channels in ETSI domain Add support for Short Range Devices 25 mW max power channels in ETSI regulatory domain. Add Short Range Devices 25 mW max power channels only if DSRC feature is disabled. Provide service apis to check SRD and DSRC channels. Change-Id: Ib2a1d7cf191d07319cb29038ad60130f5cbe7f16 CRs-Fixed: 2264790 --- src/wlan_policy_mgr_core.c | 24 ++++++++++++++++++------ src/wlan_policy_mgr_pcl.c | 7 ++++--- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 54583ed52b19..ee1ac42303b2 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1800,6 +1800,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, uint8_t channel_list_5[QDF_MAX_NUM_CHAN] = {0}; uint8_t sbs_channel_list[QDF_MAX_NUM_CHAN] = {0}; bool skip_dfs_channel = false; + bool is_etsi13_srd_chan_allowed_in_mas_mode = true; uint32_t i = 0, j = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; bool sta_sap_scc_on_dfs_chan; @@ -1840,12 +1841,17 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, sta_sap_scc_on_dfs_chan = policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc); policy_mgr_debug("sta_sap_scc_on_dfs_chan %u", sta_sap_scc_on_dfs_chan); - if ((((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) && - (policy_mgr_mode_specific_connection_count( - psoc, PM_STA_MODE, NULL) > 0)) || - !sta_sap_scc_on_dfs_chan) { - policy_mgr_debug("STA present, skip DFS channels from pcl for SAP/Go"); - skip_dfs_channel = true; + if ((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) { + if ((policy_mgr_mode_specific_connection_count(psoc, + PM_STA_MODE, + NULL) > 0) || + !sta_sap_scc_on_dfs_chan) { + policy_mgr_debug("skip DFS ch from pcl for SAP/Go"); + skip_dfs_channel = true; + } + is_etsi13_srd_chan_allowed_in_mas_mode = + wlan_reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx-> + pdev); } /* Let's divide the list in 2.4 & 5 Ghz lists */ @@ -1878,6 +1884,12 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, chan_index++; continue; } + if (!is_etsi13_srd_chan_allowed_in_mas_mode && + wlan_reg_is_etsi13_srd_chan(pm_ctx->pdev, + channel_list[chan_index])) { + chan_index++; + continue; + } channel_list_5[chan_index_5++] = channel_list[chan_index++]; } diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index b122d2130cbb..88a58f085785 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -1391,13 +1391,14 @@ policy_mgr_get_nondfs_preferred_channel(struct wlan_objmgr_psoc *psoc, } static void policy_mgr_remove_dsrc_channels(uint8_t *chan_list, - uint32_t *num_channels) + uint32_t *num_channels, + struct wlan_objmgr_pdev *pdev) { uint32_t num_chan_temp = 0; int i; for (i = 0; i < *num_channels; i++) { - if (!wlan_is_dsrc_channel(wlan_chan_to_freq(chan_list[i]))) { + if (!wlan_reg_is_dsrc_chan(pdev, chan_list[i])) { chan_list[num_chan_temp] = chan_list[i]; num_chan_temp++; } @@ -1434,7 +1435,7 @@ QDF_STATUS policy_mgr_get_valid_chans(struct wlan_objmgr_psoc *psoc, return status; } - policy_mgr_remove_dsrc_channels(chan_list, list_len); + policy_mgr_remove_dsrc_channels(chan_list, list_len, pm_ctx->pdev); return QDF_STATUS_SUCCESS; } From 693754cc10d23c9b121bb15dded2d36869fdd28f Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Tue, 15 May 2018 15:48:57 -0700 Subject: [PATCH 285/404] qcacmn: Add support for SRD channels in ETSI domain Add support for Short Range Devices 25 mW max power channels in ETSI regulatory domain. Add Short Range Devices 25 mW max power channels only if DSRC feature is disabled. Provide service apis to check SRD and DSRC channels. Change-Id: Ib2a1d7cf191d07319cb29038ad60130f5cbe7f16 CRs-Fixed: 2264790 --- core/src/wlan_tdls_peer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 82ecb43d326c..3f8a132e0e87 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -515,7 +515,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, if (CHANNEL_STATE_INVALID != ch_state && CHANNEL_STATE_DFS != ch_state && - !wlan_is_dsrc_channel(wlan_is_dsrc_channel(chan_id))) { + !wlan_reg_is_dsrc_chan(pdev, chan_id)) { peer_param->peer_cap.peer_chan[num].chan_id = chan_id; peer_param->peer_cap.peer_chan[num].pwr = wlan_reg_get_channel_reg_power(pdev, chan_id); From afa4e1b2248f6c621c15e5aace010575354b84ef Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Thu, 5 Jul 2018 15:04:46 +0530 Subject: [PATCH 286/404] qcacmn: Fix hw mode change issue in case of DBS The driver stops the oppurtunitistic timer for DBS, when the start AP requests come, which results in HW mode stuck in DBS if the next vdev start request comes on the same MAC This further results in NSS = 1 for the MAC, hence throughput decreases. Fix is to set hw mode to single MAC in case the STA/SAP comes up in the band/channel Change-Id: I8ec4282c78594ee7e133a1e7768fa230bb2e8180 CRs-Fixed: 2273443 --- src/wlan_policy_mgr_action.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 4a711e74bf37..bb0beae7bd30 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1442,6 +1442,10 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( return; } + if (QDF_TIMER_STATE_RUNNING == + pm_ctx->dbs_opportunistic_timer.state) + qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { if (pm_conc_connection_list[i].in_use) @@ -1453,11 +1457,6 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( } } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - - if (QDF_TIMER_STATE_RUNNING == - pm_ctx->dbs_opportunistic_timer.state) - qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); - pm_dbs_opportunistic_timer_handler((void *)psoc); } From e57b6b7417a133ea718b978fe0fcfccd8b69c112 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Mon, 21 May 2018 04:51:47 -0400 Subject: [PATCH 287/404] qcacmn: Extract Hw mode Id and band info Extract/Save the Hw mode ID and Mac0 band info to hw mode list. This helps to identify the 2x2 5G + 1x1 2G and 2x2 2G + 1x1 5G. Change-Id: I0682337b1a80c1b502c3307e0847aaa99479d2d3 CRs-Fixed: 2256152 --- inc/wlan_policy_mgr_public_struct.h | 6 ++-- src/wlan_policy_mgr_action.c | 11 ++++--- src/wlan_policy_mgr_core.c | 12 +++++--- src/wlan_policy_mgr_get_set_utils.c | 41 ++++++++++++++++---------- src/wlan_policy_mgr_i.h | 45 +++++++++++++++++++++-------- 5 files changed, 78 insertions(+), 37 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 2d7f61042574..8706c61a8c72 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -855,8 +855,9 @@ struct policy_mgr_conc_connection_info { * @mac1_rx_ss: MAC1 Rx spatial stream * @mac0_bw: MAC0 bandwidth * @mac1_bw: MAC1 bandwidth - * @dbs_cap: DBS capabality - * @agile_dfs_cap: Agile DFS capabality + * @mac0_band_cap: mac0 band (5g/2g) capability + * @dbs_cap: DBS capability + * @agile_dfs_cap: Agile DFS capability */ struct policy_mgr_hw_mode_params { uint8_t mac0_tx_ss; @@ -865,6 +866,7 @@ struct policy_mgr_hw_mode_params { uint8_t mac1_rx_ss; uint8_t mac0_bw; uint8_t mac1_bw; + uint8_t mac0_band_cap; uint8_t dbs_cap; uint8_t agile_dfs_cap; uint8_t sbs_cap; diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index bb0beae7bd30..95e126bada3c 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -72,12 +72,15 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, return; } - policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d", - hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, hw_mode.mac0_bw); + policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d band_cap:%d", + hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, + hw_mode.mac0_bw, hw_mode.mac0_band_cap); policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d", - hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, hw_mode.mac1_bw); + hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, + hw_mode.mac1_bw); policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d", - hw_mode.dbs_cap, hw_mode.agile_dfs_cap, hw_mode.sbs_cap); + hw_mode.dbs_cap, hw_mode.agile_dfs_cap, + hw_mode.sbs_cap); /* update pm_conc_connection_list */ policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries, diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index ee1ac42303b2..930cfe033d08 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -477,6 +477,7 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx( hw_mode->mac1_tx_ss = POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param); hw_mode->mac1_rx_ss = POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param); hw_mode->mac1_bw = POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param); + hw_mode->mac0_band_cap = POLICY_MGR_HW_MODE_MAC0_BAND_GET(param); hw_mode->dbs_cap = POLICY_MGR_HW_MODE_DBS_MODE_GET(param); hw_mode->agile_dfs_cap = POLICY_MGR_HW_MODE_AGILE_DFS_GET(param); hw_mode->sbs_cap = POLICY_MGR_HW_MODE_SBS_MODE_GET(param); @@ -815,12 +816,15 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, return; } - policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d", - hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, hw_mode.mac0_bw); + policy_mgr_debug("MAC0: TxSS:%d, RxSS:%d, Bw:%d, band_cap %d", + hw_mode.mac0_tx_ss, hw_mode.mac0_rx_ss, + hw_mode.mac0_bw, hw_mode.mac0_band_cap); policy_mgr_debug("MAC1: TxSS:%d, RxSS:%d, Bw:%d", - hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, hw_mode.mac1_bw); + hw_mode.mac1_tx_ss, hw_mode.mac1_rx_ss, + hw_mode.mac1_bw); policy_mgr_debug("DBS:%d, Agile DFS:%d, SBS:%d", - hw_mode.dbs_cap, hw_mode.agile_dfs_cap, hw_mode.sbs_cap); + hw_mode.dbs_cap, hw_mode.agile_dfs_cap, + hw_mode.sbs_cap); /* update pm_conc_connection_list */ policy_mgr_update_hw_mode_conn_info(context, num_vdev_mac_entries, diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 3a6e71a6c835..281a6845590e 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -154,6 +154,7 @@ static void policy_mgr_get_hw_mode_params( info->mac_bw = policy_mgr_map_wmi_channel_width_to_hw_mode_bw( QDF_MAX(caps->max_bw_supported_2G, caps->max_bw_supported_5G)); + info->mac_band_cap = caps->supported_bands; } /** @@ -162,7 +163,8 @@ static void policy_mgr_get_hw_mode_params( * @wma_handle: pointer to wma global structure * @mac0_ss_bw_info: TX-RX streams, BW for MAC0 * @mac1_ss_bw_info: TX-RX streams, BW for MAC1 - * @pos: refers to hw_mode_index + * @pos: refers to hw_mode_list array index + * @hw_mode_id: hw mode id value used by firmware * @dbs_mode: dbs_mode for the dbs_hw_mode * @sbs_mode: sbs_mode for the sbs_hw_mode * @@ -174,7 +176,7 @@ static void policy_mgr_get_hw_mode_params( static void policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc *psoc, struct policy_mgr_mac_ss_bw_info mac0_ss_bw_info, struct policy_mgr_mac_ss_bw_info mac1_ss_bw_info, - uint32_t pos, uint32_t dbs_mode, + uint32_t pos, uint32_t hw_mode_id, uint32_t dbs_mode, uint32_t sbs_mode) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -212,6 +214,12 @@ static void policy_mgr_set_hw_mode_params(struct wlan_objmgr_psoc *psoc, POLICY_MGR_HW_MODE_SBS_MODE_SET( pm_ctx->hw_mode.hw_mode_list[pos], sbs_mode); + POLICY_MGR_HW_MODE_MAC0_BAND_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + mac0_ss_bw_info.mac_band_cap); + POLICY_MGR_HW_MODE_ID_SET( + pm_ctx->hw_mode.hw_mode_list[pos], + hw_mode_id); } QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, @@ -287,7 +295,8 @@ QDF_STATUS policy_mgr_update_hw_mode_list(struct wlan_objmgr_psoc *psoc, /* Updating HW mode list */ policy_mgr_set_hw_mode_params(psoc, mac0_ss_bw_info, - mac1_ss_bw_info, i, dbs_mode, sbs_mode); + mac1_ss_bw_info, i, tmp->hw_mode_id, dbs_mode, + sbs_mode); } return QDF_STATUS_SUCCESS; } @@ -331,19 +340,21 @@ void policy_mgr_dump_dbs_hw_mode(struct wlan_objmgr_psoc *psoc) for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { param = pm_ctx->hw_mode.hw_mode_list[i]; - policy_mgr_debug("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d", - i, - POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param), - POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param), - POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param)); + policy_mgr_debug("[%d]-MAC0: tx_ss:%d rx_ss:%d bw_idx:%d band_cap:%d", + i, + POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param), + POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param), + POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(param), + POLICY_MGR_HW_MODE_MAC0_BAND_GET(param)); policy_mgr_debug("[%d]-MAC1: tx_ss:%d rx_ss:%d bw_idx:%d", - i, - POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param), - POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param), - POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param)); - policy_mgr_debug("[%d] DBS:%d SBS:%d", i, - POLICY_MGR_HW_MODE_DBS_MODE_GET(param), - POLICY_MGR_HW_MODE_SBS_MODE_GET(param)); + i, + POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(param), + POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(param), + POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(param)); + policy_mgr_debug("[%d] DBS:%d SBS:%d hw_mode_id:%d", i, + POLICY_MGR_HW_MODE_DBS_MODE_GET(param), + POLICY_MGR_HW_MODE_SBS_MODE_GET(param), + POLICY_MGR_HW_MODE_ID_GET(param)); } } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 41c9cc40d200..32d2cbfeb620 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -57,6 +57,8 @@ #define POLICY_MGR_HW_MODE_DBS_MODE_BITPOS (7) #define POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS (6) #define POLICY_MGR_HW_MODE_SBS_MODE_BITPOS (5) +#define POLICY_MGR_HW_MODE_MAC0_BAND_BITPOS (3) +#define POLICY_MGR_HW_MODE_ID_BITPOS (0) #define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_MASK \ (0xf << POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS) @@ -76,6 +78,10 @@ (0x1 << POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS) #define POLICY_MGR_HW_MODE_SBS_MODE_MASK \ (0x1 << POLICY_MGR_HW_MODE_SBS_MODE_BITPOS) +#define POLICY_MGR_HW_MODE_MAC0_BAND_MASK \ + (0x3 << POLICY_MGR_HW_MODE_MAC0_BAND_BITPOS) +#define POLICY_MGR_HW_MODE_ID_MASK \ + (0x7 << POLICY_MGR_HW_MODE_ID_BITPOS) #define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_SET(hw_mode, value) \ WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS,\ @@ -104,34 +110,46 @@ #define POLICY_MGR_HW_MODE_SBS_MODE_SET(hw_mode, value) \ WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_SBS_MODE_BITPOS,\ 1, value) +#define POLICY_MGR_HW_MODE_MAC0_BAND_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_MAC0_BAND_BITPOS,\ + 2, value) +#define POLICY_MGR_HW_MODE_ID_SET(hw_mode, value) \ + WMI_SET_BITS(hw_mode, POLICY_MGR_HW_MODE_ID_BITPOS,\ + 3, value) #define POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_MASK) >> \ POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_BITPOS) #define POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_MASK) >> \ POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_BITPOS) #define POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_MASK) >> \ POLICY_MGR_HW_MODE_MAC1_TX_STREAMS_BITPOS) #define POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_MASK) >> \ POLICY_MGR_HW_MODE_MAC1_RX_STREAMS_BITPOS) #define POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_MASK) >> \ POLICY_MGR_HW_MODE_MAC0_BANDWIDTH_BITPOS) #define POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_MASK) >> \ POLICY_MGR_HW_MODE_MAC1_BANDWIDTH_BITPOS) #define POLICY_MGR_HW_MODE_DBS_MODE_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_DBS_MODE_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_DBS_MODE_MASK) >> \ POLICY_MGR_HW_MODE_DBS_MODE_BITPOS) #define POLICY_MGR_HW_MODE_AGILE_DFS_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_AGILE_DFS_MODE_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_AGILE_DFS_MODE_MASK) >> \ POLICY_MGR_HW_MODE_AGILE_DFS_MODE_BITPOS) #define POLICY_MGR_HW_MODE_SBS_MODE_GET(hw_mode) \ - ((hw_mode & POLICY_MGR_HW_MODE_SBS_MODE_MASK) >> \ + (((hw_mode) & POLICY_MGR_HW_MODE_SBS_MODE_MASK) >> \ POLICY_MGR_HW_MODE_SBS_MODE_BITPOS) +#define POLICY_MGR_HW_MODE_MAC0_BAND_GET(hw_mode) \ + (((hw_mode) & POLICY_MGR_HW_MODE_MAC0_BAND_MASK) >> \ + POLICY_MGR_HW_MODE_MAC0_BAND_BITPOS) +#define POLICY_MGR_HW_MODE_ID_GET(hw_mode) \ + (((hw_mode) & POLICY_MGR_HW_MODE_ID_MASK) >> \ + POLICY_MGR_HW_MODE_ID_BITPOS) #define POLICY_MGR_DEFAULT_HW_MODE_INDEX 0xFFFF @@ -273,14 +291,17 @@ struct policy_mgr_psoc_priv_obj { /** * struct policy_mgr_mac_ss_bw_info - hw_mode_list PHY/MAC params for each MAC - * @mac_tx_stream: Max TX stream - * @mac_rx_stream: Max RX stream - * @mac_bw: Max bandwidth + * @mac_tx_stream: Max TX stream number supported on MAC + * @mac_rx_stream: Max RX stream number supported on MAC + * @mac_bw: Max bandwidth(wmi_channel_width enum type) + * @mac_band_cap: supported Band bit map(WLAN_2G_CAPABILITY = 0x1, + * WLAN_5G_CAPABILITY = 0x2) */ struct policy_mgr_mac_ss_bw_info { uint32_t mac_tx_stream; uint32_t mac_rx_stream; uint32_t mac_bw; + uint32_t mac_band_cap; }; struct policy_mgr_psoc_priv_obj *policy_mgr_get_context( From eabb08f0668ff53a28d4bf475faffadbaca08ee2 Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Tue, 1 May 2018 12:32:47 +0530 Subject: [PATCH 288/404] qcacmn: Fix OOB read in iw_hdd_set_var_ints_getnone From the IOCTL command WE_POLICY_MANAGER_PCL_CMD, we get the cds concurrency mode as argument and pass it to cds_get_pcl to get the pcl channel list. This concurrency mode parameter is used as the array index to retrieve the enum cds_pcl_type. If this value is greater than CDS_MAX_NUM_OF_MODE an OOB read will occur in iw_hdd_set_var_ints_getnone. Add check to validate the input cds mode argument against the macro CDS_MAX_NUM_OF_MODE. Return error if it is violated. Change-Id: I51073061be363d9680abf0566b77be7c7573d0fe CRs-Fixed: 2233991 --- src/wlan_policy_mgr_pcl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 88a58f085785..5303ee8092d1 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -476,8 +476,8 @@ QDF_STATUS policy_mgr_get_pcl(struct wlan_objmgr_psoc *psoc, return status; } - if (mode >= PM_MAX_NUM_OF_MODE) { - policy_mgr_err("requested mode:%d is not supported", mode); + if ((mode < 0) || (mode >= PM_MAX_NUM_OF_MODE)) { + policy_mgr_err("Invalid connection mode %d received", mode); return status; } From 77cb42a95239aa0e2e78ebde1a05e84e800b036f Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Fri, 15 Jun 2018 16:46:30 +0530 Subject: [PATCH 289/404] qcacmn: Fix high latency during BTM roaming While processing the WMA_ROAM_OFFLOAD_SYNCH_IND event, The driver takes nearly 150 to 200 msec time to just write fatal, error and info messages to the kmsg log buffer. Also to get tx power supplicant runs another thread while roaming. These cause more latency(300ms) to send WMA_ROAM_OFFLOAD_SYNCH_CNF message to fw. To decrease roam latency, the driver should write the only necessary error message to kmsg buffer. Fix is to change irrelevant fatal, error and info message type to debug. Change-Id: I521104c692eb42112ce2528c15d09785ff3470b6 CRs-Fixed: 2261592 --- src/wlan_policy_mgr_action.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 95e126bada3c..1bd5c4d1cecb 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -799,7 +799,7 @@ static bool policy_mgr_is_restart_sap_allowed( QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) && ((policy_mgr_get_concurrency_mode(psoc) & sta_go_bit_mask) == sta_go_bit_mask)))) { - policy_mgr_err("MCC switch disabled or not concurrent STA/SAP, STA/GO"); + policy_mgr_debug("MCC switch disabled or not concurrent STA/SAP, STA/GO"); return false; } From 2bd04035fdfec8a1341a611a930db06e071a0d07 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 9 Jul 2018 12:39:16 +0800 Subject: [PATCH 290/404] qcacmn: Do not request new ROC if there is idle ROC in queue When transmitting management frames, do not request new ROC if there is idle ROC on same channel in queue. Change-Id: Id7b33aa2b9fa376675c520161e4c907ea0593c88 CRs-Fixed: 2275191 --- core/src/wlan_p2p_off_chan_tx.c | 14 ++++++++++++++ core/src/wlan_p2p_roc.c | 29 +++++++++++++++++++++++++++++ core/src/wlan_p2p_roc.h | 18 ++++++++++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index c50a32b07124..6f02665f1a29 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1843,6 +1843,20 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) } } + curr_roc_ctx = p2p_find_roc_by_chan(p2p_soc_obj, tx_ctx->chan); + if (curr_roc_ctx && (curr_roc_ctx->roc_state == ROC_STATE_IDLE)) { + tx_ctx->roc_cookie = (uintptr_t)curr_roc_ctx; + status = qdf_list_insert_back( + &p2p_soc_obj->tx_q_roc, + &tx_ctx->node); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("Failed to insert off chan tx context to wait roc req queue"); + goto fail; + } else { + return QDF_STATUS_SUCCESS; + } + } + status = p2p_roc_req_for_tx_action(tx_ctx); if (status != QDF_STATUS_SUCCESS) { p2p_err("Failed to request roc before off chan tx"); diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 2e171a9244b2..c75bfdd28eab 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -631,6 +631,35 @@ struct p2p_roc_context *p2p_find_roc_by_tx_ctx( return NULL; } +struct p2p_roc_context *p2p_find_roc_by_chan( + struct p2p_soc_priv_obj *p2p_soc_obj, uint8_t chan) +{ + struct p2p_roc_context *roc_ctx; + qdf_list_node_t *p_node; + QDF_STATUS status; + + status = qdf_list_peek_front(&p2p_soc_obj->roc_q, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + roc_ctx = qdf_container_of(p_node, + struct p2p_roc_context, + node); + if (roc_ctx->chan == chan) { + p2p_debug("p2p soc obj:%pK, roc ctx:%pK, vdev_id:%d, scan_id:%d, tx ctx:%pK, chan:%d, phy_mode:%d, duration:%d, roc_type:%d, roc_state:%d", + roc_ctx->p2p_soc_obj, roc_ctx, + roc_ctx->vdev_id, roc_ctx->scan_id, + roc_ctx->tx_ctx, roc_ctx->chan, + roc_ctx->phy_mode, roc_ctx->duration, + roc_ctx->roc_type, roc_ctx->roc_state); + + return roc_ctx; + } + status = qdf_list_peek_next(&p2p_soc_obj->roc_q, + p_node, &p_node); + } + + return NULL; +} + QDF_STATUS p2p_restart_roc_timer(struct p2p_roc_context *roc_ctx) { QDF_STATUS status = QDF_STATUS_E_FAILURE; diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index 3ccff8c17297..2bce9a4b68b5 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -139,7 +139,7 @@ QDF_STATUS p2p_mgmt_rx_action_ops(struct wlan_objmgr_psoc *psoc, * p2p_find_current_roc_ctx() - Find out roc context in progressing * @p2p_soc_obj: p2p psoc private object * - * This function find out roc context in progressing from p2p psoc + * This function finds out roc context in progressing from p2p psoc * private object * * Return: Pointer to roc context - success @@ -153,7 +153,7 @@ struct p2p_roc_context *p2p_find_current_roc_ctx( * @p2p_soc_obj: p2p psoc private object * @cookie: cookie is the key to find out roc context * - * This function find out roc context by tx context from p2p psoc + * This function finds out roc context by tx context from p2p psoc * private object * * Return: Pointer to roc context - success @@ -162,6 +162,20 @@ struct p2p_roc_context *p2p_find_current_roc_ctx( struct p2p_roc_context *p2p_find_roc_by_tx_ctx( struct p2p_soc_priv_obj *p2p_soc_obj, uint64_t cookie); +/** + * p2p_find_roc_by_chan() - Find out roc context by channel + * @p2p_soc_obj: p2p psoc private object + * @chan: channel of the ROC + * + * This function finds out roc context by channel from p2p psoc + * private object + * + * Return: Pointer to roc context - success + * NULL - failure + */ +struct p2p_roc_context *p2p_find_roc_by_chan( + struct p2p_soc_priv_obj *p2p_soc_obj, uint8_t chan); + /** * p2p_restart_roc_timer() - Restarts roc timer * @roc_ctx: remain on channel context From 1d78ede2cdf57bd0ac6ff91257e241c3bd4cdc66 Mon Sep 17 00:00:00 2001 From: bings Date: Tue, 10 Jul 2018 17:41:42 +0800 Subject: [PATCH 291/404] qcacmn: Skip DFS channels for SAP/GO when station exists Currently DFS channels are skipped for SAP/GO in cds_get_channel_list when ini g_sta_sap_scc_on_dfs_chan is configured as 0. Refine the logic of DFS channels skipping when station exists. Do not select DFS channels for SAP/GO when below cases are both satisfied. 1. Station exists. 2. Ini g_sta_sap_scc_on_dfs_chan is set as 0. Change-Id: I2f082388a662d54968b3c2e95e5713eeffa1b131 CRs-Fixed: 2275724 --- src/wlan_policy_mgr_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 930cfe033d08..a2b754ee4efb 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1848,8 +1848,8 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, if ((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) { if ((policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE, - NULL) > 0) || - !sta_sap_scc_on_dfs_chan) { + NULL) > 0) && + (!sta_sap_scc_on_dfs_chan)) { policy_mgr_debug("skip DFS ch from pcl for SAP/Go"); skip_dfs_channel = true; } From 9ace8a9dd9374ba5d3d2ff055cd89628c73bd59e Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Mon, 21 May 2018 05:39:04 -0400 Subject: [PATCH 292/404] qcacmn: Set hw mode Id to FW Firmware needs HW MODE ID not list index. Use HW mode ID to set HW MODE WMI command. Change-Id: I12f9d83daee1c99706c345d85f03781257b492bf CRs-Fixed: 2256175 --- inc/wlan_policy_mgr_api.h | 32 +++++++++++++++ inc/wlan_policy_mgr_public_struct.h | 20 +++++++++ src/wlan_policy_mgr_action.c | 24 ++++++++--- src/wlan_policy_mgr_core.c | 63 ++++++++++++++++++++++------- src/wlan_policy_mgr_i.h | 6 +-- 5 files changed, 120 insertions(+), 25 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index e48ff10ded08..2fa1cd616205 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -712,6 +712,8 @@ enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm( * @mac0_bw: MAC0 bandwidth configuration * @mac1_ss: MAC1 spatial stream configuration * @mac1_bw: MAC1 bandwidth configuration + * @mac0_band_cap: mac0 band capability requirement + * (0: Don't care, 1: 2.4G, 2: 5G) * @dbs: HW DBS capability * @dfs: HW Agile DFS capability * @sbs: HW SBS capability @@ -724,18 +726,33 @@ enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm( * e.g.: To configure 2x2_80 * mac0_ss = HW_MODE_SS_2x2, mac0_bw = HW_MODE_80_MHZ * mac1_ss = HW_MODE_SS_0x0, mac1_bw = HW_MODE_BW_NONE + * mac0_band_cap = HW_MODE_MAC_BAND_NONE, * dbs = HW_MODE_DBS_NONE, dfs = HW_MODE_AGILE_DFS_NONE, * sbs = HW_MODE_SBS_NONE * e.g.: To configure 1x1_80_1x1_40 (DBS) * mac0_ss = HW_MODE_SS_1x1, mac0_bw = HW_MODE_80_MHZ * mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ + * mac0_band_cap = HW_MODE_MAC_BAND_NONE, * dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS_NONE, * sbs = HW_MODE_SBS_NONE * e.g.: To configure 1x1_80_1x1_40 (Agile DFS) * mac0_ss = HW_MODE_SS_1x1, mac0_bw = HW_MODE_80_MHZ * mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ + * mac0_band_cap = HW_MODE_MAC_BAND_NONE, * dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS, * sbs = HW_MODE_SBS_NONE + * e.g.: To configure 2x2_5g_80+1x1_2g_40 + * mac0_ss = HW_MODE_SS_2x2, mac0_bw = HW_MODE_80_MHZ + * mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ + * mac0_band_cap = HW_MODE_MAC_BAND_5G + * dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS_NONE, + * sbs = HW_MODE_SBS_NONE + * e.g.: To configure 2x2_2g_40+1x1_5g_40 + * mac0_ss = HW_MODE_SS_2x2, mac0_bw = HW_MODE_40_MHZ + * mac1_ss = HW_MODE_SS_1x1, mac1_bw = HW_MODE_40_MHZ + * mac0_band_cap = HW_MODE_MAC_BAND_2G + * dbs = HW_MODE_DBS, dfs = HW_MODE_AGILE_DFS_NONE, + * sbs = HW_MODE_SBS_NONE * * Return: Success if the message made it down to the next layer */ @@ -745,6 +762,7 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, enum hw_mode_bandwidth mac0_bw, enum hw_mode_ss_config mac1_ss, enum hw_mode_bandwidth mac1_bw, + enum hw_mode_mac_band_cap mac0_band_cap, enum hw_mode_dbs_capab dbs, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs, @@ -2463,4 +2481,18 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect( */ bool policy_mgr_is_sta_sap_scc(struct wlan_objmgr_psoc *psoc, uint8_t sap_ch); +/** + * policy_mgr_get_hw_mode_from_idx() - Get HW mode based on index + * @psoc: psoc object + * @idx: HW mode id + * @hw_mode: HW mode params + * + * Fetches the HW mode parameters + * + * Return: Success if hw mode is obtained and the hw mode params + */ +QDF_STATUS policy_mgr_get_hw_mode_from_idx( + struct wlan_objmgr_psoc *psoc, + uint32_t idx, + struct policy_mgr_hw_mode_params *hw_mode); #endif /* __WLAN_POLICY_MGR_API_H */ diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 8706c61a8c72..6b46aab6daaf 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -114,6 +114,26 @@ enum hw_mode_sbs_capab { HW_MODE_SBS, }; +/** + * enum hw_mode_mac_band_cap - mac band capability + * @HW_MODE_MAC_BAND_NONE: No band requirement. + * @HW_MODE_MAC_BAND_2G: 2G band supported. + * @HW_MODE_MAC_BAND_5G: 5G band supported. + * + * To add HW_MODE_MAC_BAND_NONE value to help to + * match the HW DBS mode in hw mode list. + * Other enum values should match with WMI header: + * typedef enum { + * WLAN_2G_CAPABILITY = 0x1, + * WLAN_5G_CAPABILITY = 0x2, + * } WLAN_BAND_CAPABILITY; + */ +enum hw_mode_mac_band_cap { + HW_MODE_MAC_BAND_NONE = 0, + HW_MODE_MAC_BAND_2G = WLAN_2G_CAPABILITY, + HW_MODE_MAC_BAND_5G = WLAN_5G_CAPABILITY, +}; + /** * enum policy_mgr_pcl_group_id - Identifies the pcl groups to be used * @POLICY_MGR_PCL_GROUP_ID1_ID2: Use weights of group1 and group2 diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 1bd5c4d1cecb..603382bfd95c 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -99,6 +99,7 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, enum hw_mode_bandwidth mac0_bw, enum hw_mode_ss_config mac1_ss, enum hw_mode_bandwidth mac1_bw, + enum hw_mode_mac_band_cap mac0_band_cap, enum hw_mode_dbs_capab dbs, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs, @@ -130,7 +131,8 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, } hw_mode_index = policy_mgr_get_hw_mode_idx_from_dbs_hw_list(psoc, - mac0_ss, mac0_bw, mac1_ss, mac1_bw, dbs, dfs, sbs); + mac0_ss, mac0_bw, mac1_ss, mac1_bw, mac0_band_cap, + dbs, dfs, sbs); if (hw_mode_index < 0) { policy_mgr_err("Invalid HW mode index obtained"); return QDF_STATUS_E_FAILURE; @@ -657,6 +659,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_80_MHZ, nss_dbs.mac1_ss, HW_MODE_40_MHZ, + HW_MODE_MAC_BAND_NONE, HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, @@ -670,6 +673,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_SS_2x2, HW_MODE_80_MHZ, HW_MODE_SS_0x0, HW_MODE_BW_NONE, + HW_MODE_MAC_BAND_NONE, HW_MODE_DBS_NONE, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, @@ -680,6 +684,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_SS_2x2, HW_MODE_80_MHZ, HW_MODE_SS_0x0, HW_MODE_BW_NONE, + HW_MODE_MAC_BAND_NONE, HW_MODE_DBS_NONE, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, @@ -690,6 +695,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_SS_2x2, HW_MODE_80_MHZ, HW_MODE_SS_2x2, HW_MODE_80_MHZ, + HW_MODE_MAC_BAND_NONE, HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS_NONE, @@ -704,6 +710,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, HW_MODE_SS_1x1, HW_MODE_80_MHZ, HW_MODE_SS_1x1, HW_MODE_80_MHZ, + HW_MODE_MAC_BAND_NONE, HW_MODE_DBS, HW_MODE_AGILE_DFS_NONE, HW_MODE_SBS, @@ -1541,9 +1548,10 @@ enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( struct wlan_objmgr_psoc *psoc, uint32_t hw_mode_index) { struct policy_mgr_psoc_priv_obj *pm_ctx; - uint32_t param = 0; + struct policy_mgr_hw_mode_params hw_mode; enum policy_mgr_hw_mode_change value = POLICY_MGR_HW_MODE_NOT_IN_PROGRESS; + QDF_STATUS status; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1551,16 +1559,20 @@ enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( return value; } - policy_mgr_info("HW param: %x", param); - param = pm_ctx->hw_mode.hw_mode_list[hw_mode_index]; - if (POLICY_MGR_HW_MODE_DBS_MODE_GET(param)) { + status = policy_mgr_get_hw_mode_from_idx(psoc, hw_mode_index, &hw_mode); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("Failed to get HW mode index"); + return value; + } + + if (hw_mode.dbs_cap) { policy_mgr_info("DBS is requested with HW (%d)", hw_mode_index); value = POLICY_MGR_DBS_IN_PROGRESS; goto ret_value; } - if (POLICY_MGR_HW_MODE_SBS_MODE_GET(param)) { + if (hw_mode.sbs_cap) { policy_mgr_info("SBS is requested with HW (%d)", hw_mode_index); value = POLICY_MGR_SBS_IN_PROGRESS; diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index a2b754ee4efb..b76644192f91 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -300,11 +300,18 @@ void policy_mgr_get_tx_rx_ss_from_config(enum hw_mode_ss_config mac_ss, * @mac1_tx_ss: Number of tx spatial streams of MAC1 * @mac1_rx_ss: Number of rx spatial streams of MAC1 * @mac1_bw: Bandwidth of MAC1 of type 'hw_mode_bandwidth' + * @mac0_band_cap: mac0 band capability requirement + * (0: Don't care, 1: 2.4G, 2: 5G) * @dbs: DBS capability of type 'hw_mode_dbs_capab' * @dfs: Agile DFS capability of type 'hw_mode_agile_dfs_capab' * @sbs: SBS capability of type 'hw_mode_sbs_capab' * - * Fetches the HW mode index corresponding to the HW mode provided + * Fetches the HW mode index corresponding to the HW mode provided. + * In Genoa two DBS HW modes (2x2 5G + 1x1 2G, 2x2 2G + 1x1 5G), + * the "ss" number and "bw" value are not enough to specify the expected + * HW mode. But in both HW mode, the mac0 can support either 5G or 2G. + * So, the Parameter "mac0_band_cap" will specify the expected band support + * requirement on mac 0 to find the expected HW mode. * * Return: Positive hw mode index in case a match is found or a negative * value, otherwise @@ -315,6 +322,7 @@ int8_t policy_mgr_get_matching_hw_mode_index( enum hw_mode_bandwidth mac0_bw, uint32_t mac1_tx_ss, uint32_t mac1_rx_ss, enum hw_mode_bandwidth mac1_bw, + enum hw_mode_mac_band_cap mac0_band_cap, enum hw_mode_dbs_capab dbs, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs) @@ -323,6 +331,7 @@ int8_t policy_mgr_get_matching_hw_mode_index( uint32_t t_mac0_tx_ss, t_mac0_rx_ss, t_mac0_bw; uint32_t t_mac1_tx_ss, t_mac1_rx_ss, t_mac1_bw; uint32_t dbs_mode, agile_dfs_mode, sbs_mode; + uint32_t t_mac0_band_cap; int8_t found = -EINVAL; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -383,8 +392,16 @@ int8_t policy_mgr_get_matching_hw_mode_index( if (sbs_mode != sbs) continue; - found = i; - policy_mgr_debug("hw_mode index %d found", i); + t_mac0_band_cap = POLICY_MGR_HW_MODE_MAC0_BAND_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + if (mac0_band_cap && t_mac0_band_cap != mac0_band_cap) + continue; + + found = POLICY_MGR_HW_MODE_ID_GET( + pm_ctx->hw_mode.hw_mode_list[i]); + + policy_mgr_debug("hw_mode id %d found at %d", found, i); + break; } return found; @@ -396,6 +413,8 @@ int8_t policy_mgr_get_matching_hw_mode_index( * @mac0_bw: MAC0 bandwidth configuration * @mac1_ss: MAC1 spatial stream configuration * @mac1_bw: MAC1 bandwidth configuration + * @mac0_band_cap: mac0 band capability requirement + * (0: Don't care, 1: 2.4G, 2: 5G) * @dbs: HW DBS capability * @dfs: HW Agile DFS capability * @sbs: HW SBS capability @@ -403,6 +422,12 @@ int8_t policy_mgr_get_matching_hw_mode_index( * Get the HW mode index corresponding to the HW modes spatial stream, * bandwidth, DBS, Agile DFS and SBS capability * + * In Genoa two DBS HW modes (2x2 5G + 1x1 2G, 2x2 2G + 1x1 5G), + * the "ss" number and "bw" value are not enough to specify the expected + * HW mode. But in both HW mode, the mac0 can support either 5G or 2G. + * So, the Parameter "mac0_band_cap" will specify the expected band support + * requirement on mac 0 to find the expected HW mode. + * * Return: Index number if a match is found or -negative value if not found */ int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list( @@ -411,6 +436,7 @@ int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list( enum hw_mode_bandwidth mac0_bw, enum hw_mode_ss_config mac1_ss, enum hw_mode_bandwidth mac1_bw, + enum hw_mode_mac_band_cap mac0_band_cap, enum hw_mode_dbs_capab dbs, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs) @@ -421,24 +447,26 @@ int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list( policy_mgr_get_tx_rx_ss_from_config(mac0_ss, &mac0_tx_ss, &mac0_rx_ss); policy_mgr_get_tx_rx_ss_from_config(mac1_ss, &mac1_tx_ss, &mac1_rx_ss); - policy_mgr_debug("MAC0: TxSS=%d, RxSS=%d, BW=%d", - mac0_tx_ss, mac0_rx_ss, mac0_bw); + policy_mgr_debug("MAC0: TxSS=%d, RxSS=%d, BW=%d band=%d", + mac0_tx_ss, mac0_rx_ss, mac0_bw, mac0_band_cap); policy_mgr_debug("MAC1: TxSS=%d, RxSS=%d, BW=%d", - mac1_tx_ss, mac1_rx_ss, mac1_bw); + mac1_tx_ss, mac1_rx_ss, mac1_bw); policy_mgr_debug("DBS=%d, Agile DFS=%d, SBS=%d", - dbs, dfs, sbs); + dbs, dfs, sbs); return policy_mgr_get_matching_hw_mode_index(psoc, mac0_tx_ss, mac0_rx_ss, mac0_bw, mac1_tx_ss, mac1_rx_ss, mac1_bw, + mac0_band_cap, dbs, dfs, sbs); } /** * policy_mgr_get_hw_mode_from_idx() - Get HW mode based on index - * @idx: HW mode index + * @psoc: psoc object + * @idx: HW mode id * @hw_mode: HW mode params * * Fetches the HW mode parameters @@ -452,24 +480,29 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx( { uint32_t param; struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t i, hw_mode_id; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); return QDF_STATUS_E_FAILURE; } - - if (idx > pm_ctx->num_dbs_hw_modes) { - policy_mgr_err("Invalid index"); - return QDF_STATUS_E_FAILURE; - } - if (!pm_ctx->num_dbs_hw_modes) { policy_mgr_err("No dbs hw modes available"); return QDF_STATUS_E_FAILURE; } + for (i = 0; i < pm_ctx->num_dbs_hw_modes; i++) { + param = pm_ctx->hw_mode.hw_mode_list[i]; + hw_mode_id = POLICY_MGR_HW_MODE_ID_GET(param); + if (hw_mode_id == idx) + break; + } + if (i >= pm_ctx->num_dbs_hw_modes) { + policy_mgr_err("hw mode id %d not found", idx); + return QDF_STATUS_E_FAILURE; + } - param = pm_ctx->hw_mode.hw_mode_list[idx]; + param = pm_ctx->hw_mode.hw_mode_list[i]; hw_mode->mac0_tx_ss = POLICY_MGR_HW_MODE_MAC0_TX_STREAMS_GET(param); hw_mode->mac0_rx_ss = POLICY_MGR_HW_MODE_MAC0_RX_STREAMS_GET(param); diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 32d2cbfeb620..0d7655ec3269 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -342,6 +342,7 @@ int8_t policy_mgr_get_matching_hw_mode_index( enum hw_mode_bandwidth mac0_bw, uint32_t mac1_tx_ss, uint32_t mac1_rx_ss, enum hw_mode_bandwidth mac1_bw, + enum hw_mode_mac_band_cap mac0_band_cap, enum hw_mode_dbs_capab dbs, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs); @@ -351,13 +352,10 @@ int8_t policy_mgr_get_hw_mode_idx_from_dbs_hw_list( enum hw_mode_bandwidth mac0_bw, enum hw_mode_ss_config mac1_ss, enum hw_mode_bandwidth mac1_bw, + enum hw_mode_mac_band_cap mac0_band_cap, enum hw_mode_dbs_capab dbs, enum hw_mode_agile_dfs_capab dfs, enum hw_mode_sbs_capab sbs); -QDF_STATUS policy_mgr_get_hw_mode_from_idx( - struct wlan_objmgr_psoc *psoc, - uint32_t idx, - struct policy_mgr_hw_mode_params *hw_mode); QDF_STATUS policy_mgr_get_old_and_new_hw_index( struct wlan_objmgr_psoc *psoc, uint32_t *old_hw_mode_index, From 226214bc25208d3eb02fe4d56af5781a0e617978 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Sat, 23 Jun 2018 14:43:23 +0530 Subject: [PATCH 293/404] qcacmn: Map all module logs to per-level log APIs Map all module level log APIs to per-level log APIs to compile out specific log level if required. Change-Id: I4072b6740cb43200fd95c40943b66e1d5f8f1847 CRs-Fixed: 2266719 --- src/wlan_policy_mgr_i.h | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 0d7655ec3269..787c9fe1669e 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -153,23 +153,18 @@ #define POLICY_MGR_DEFAULT_HW_MODE_INDEX 0xFFFF -#define policy_mgr_log(level, args...) \ - QDF_TRACE(QDF_MODULE_ID_POLICY_MGR, level, ## args) -#define policy_mgr_logfl(level, format, args...) \ - policy_mgr_log(level, FL(format), ## args) - -#define policy_mgr_alert(format, args...) \ - policy_mgr_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) -#define policy_mgr_err(format, args...) \ - policy_mgr_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) -#define policy_mgr_warn(format, args...) \ - policy_mgr_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) -#define policy_mgr_notice(format, args...) \ - policy_mgr_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) -#define policy_mgr_info(format, args...) \ - policy_mgr_logfl(QDF_TRACE_LEVEL_INFO_HIGH, format, ## args) -#define policy_mgr_debug(format, args...) \ - policy_mgr_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) +#define policy_mgr_alert(params...) \ + QDF_TRACE_FATAL(QDF_MODULE_ID_POLICY_MGR, params) +#define policy_mgr_err(params...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_POLICY_MGR, params) +#define policy_mgr_warn(params...) \ + QDF_TRACE_WARN(QDF_MODULE_ID_POLICY_MGR, params) +#define policy_mgr_notice(params...) \ + QDF_TRACE_INFO(QDF_MODULE_ID_POLICY_MGR, params) +#define policy_mgr_info(params...) \ + QDF_TRACE_INFO(QDF_MODULE_ID_POLICY_MGR, params) +#define policy_mgr_debug(params...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_POLICY_MGR, params) #define PM_CONC_CONNECTION_LIST_VALID_INDEX(index) \ ((MAX_NUMBER_OF_CONC_CONNECTIONS > index) && \ From 0bbf3364757a83ced2574ea7c15abb9343fdf094 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Sat, 23 Jun 2018 14:43:23 +0530 Subject: [PATCH 294/404] qcacmn: Map all module logs to per-level log APIs Map all module level log APIs to per-level log APIs to compile out specific log level if required. Change-Id: I4072b6740cb43200fd95c40943b66e1d5f8f1847 CRs-Fixed: 2266719 --- core/src/wlan_tdls_main.h | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index b2a0a8613786..d9cd88864d0c 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -57,22 +57,16 @@ #define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000 #define TDLS_SCAN_REJECT_MAX 5 - -#define tdls_log(level, args...) \ - QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) -#define tdls_logfl(level, format, args...) \ - tdls_log(level, FL(format), ## args) - -#define tdls_debug(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) -#define tdls_notice(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) -#define tdls_warn(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) -#define tdls_err(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) -#define tdls_alert(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) +#define tdls_debug(params...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_TDLS, params) +#define tdls_notice(params...) \ + QDF_TRACE_INFO(QDF_MODULE_ID_TDLS, params) +#define tdls_warn(params...) \ + QDF_TRACE_WARN(QDF_MODULE_ID_TDLS, params) +#define tdls_err(params...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_TDLS, params) +#define tdls_alert(params...) \ + QDF_TRACE_FATAL(QDF_MODULE_ID_TDLS, params) #define TDLS_IS_LINK_CONNECTED(peer) \ ((TDLS_LINK_CONNECTED == (peer)->link_status) || \ From 5e9f7f7836c3c4ccb2b616a508271df84ed25842 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Sat, 23 Jun 2018 14:43:23 +0530 Subject: [PATCH 295/404] qcacmn: Map all module logs to per-level log APIs Map all module level log APIs to per-level log APIs to compile out specific log level if required. Change-Id: I4072b6740cb43200fd95c40943b66e1d5f8f1847 CRs-Fixed: 2266719 --- core/src/wlan_p2p_main.h | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 2e2beecd67f8..8cae74085863 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -35,21 +35,16 @@ #define P2P_MODULE_NAME "P2P" #define P2P_INVALID_VDEV_ID 0xFFFFFFFF -#define p2p_log(level, args...) \ - QDF_TRACE(QDF_MODULE_ID_P2P, level, ## args) -#define p2p_logl(level, format, args...) \ - p2p_log(level, FL(format), ## args) - -#define p2p_debug(format, args ...) \ - p2p_logl(QDF_TRACE_LEVEL_DEBUG, format, ## args) -#define p2p_info(format, args ...) \ - p2p_logl(QDF_TRACE_LEVEL_INFO, format, ## args) -#define p2p_warn(format, args ...) \ - p2p_logl(QDF_TRACE_LEVEL_WARN, format, ## args) -#define p2p_err(format, args ...) \ - p2p_logl(QDF_TRACE_LEVEL_ERROR, format, ## args) -#define p2p_alert(format, args ...) \ - p2p_logl(QDF_TRACE_LEVEL_FATAL, format, ## args) +#define p2p_debug(params ...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_P2P, params) +#define p2p_info(params ...) \ + QDF_TRACE_INFO(QDF_MODULE_ID_P2P, params) +#define p2p_warn(params ...) \ + QDF_TRACE_WARN(QDF_MODULE_ID_P2P, params) +#define p2p_err(params ...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_P2P, params) +#define p2p_alert(params ...) \ + QDF_TRACE_FATAL(QDF_MODULE_ID_P2P, params) struct scheduler_msg; struct p2p_tx_cnf; From bdffeb8d955fdedc66d894ddd8e9c50a69b5eadf Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Fri, 13 Jul 2018 09:19:09 +0530 Subject: [PATCH 296/404] qcacmn: Fix channel selection in case of DFS in ACS algo The driver includes the DFS channel in case of force SCC, on 5GHz band, and rejects all 2.4Ghz band channels in the ACS scan list in case of band_width > 40. The DFS SCC not allowed till date prevents the SAP vdev up on that DFS channel, hence the SAP turns on with default channel of 2.4 Ghz i.e channel 1, because the ACS scan channel list didn't contain any 2.4Ghz channel. Fix is to include the 2.4Ghz channel list, and remove that DFS channel in case the force SCC is enabled, and STA is already up on that channel. Change-Id: I1dc14d3890d8128e83910c2bed1cb95d7f70ea1c CRs-Fixed: 2261802 --- src/wlan_policy_mgr_get_set_utils.c | 112 +++++++++++++++------------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 281a6845590e..d81e6d17a775 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2887,7 +2887,7 @@ void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc, uint8_t *org_ch_list, uint8_t *org_ch_list_count) { uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; - uint32_t index, count, i, ch_list_count; + uint32_t index = 0, count, i, ch_list_count; uint8_t band_mask = 0, ch_5g = 0, ch_24g = 0; uint8_t ch_list[QDF_MAX_NUM_CHAN]; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -2909,61 +2909,67 @@ void policy_mgr_trim_acs_channel_list(struct wlan_objmgr_psoc *psoc, */ count = policy_mgr_mode_specific_connection_count( psoc, PM_STA_MODE, list); - if (policy_mgr_is_force_scc(psoc) && count) { - index = 0; - while (index < count) { - if (WLAN_REG_IS_24GHZ_CH( - pm_conc_connection_list[list[index]].chan) && - policy_mgr_is_safe_channel(psoc, - pm_conc_connection_list[list[index]].chan)) { - band_mask |= 1; - ch_24g = pm_conc_connection_list[list[index]].chan; - } - if (WLAN_REG_IS_5GHZ_CH( - pm_conc_connection_list[list[index]].chan) && - policy_mgr_is_safe_channel(psoc, - pm_conc_connection_list[list[index]].chan) && - !wlan_reg_is_dfs_ch(pm_ctx->pdev, - pm_conc_connection_list[list[index]].chan) && - !wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, - pm_conc_connection_list[list[index]].chan)) { - band_mask |= 2; - ch_5g = pm_conc_connection_list[list[index]].chan; - } - index++; + if (!(policy_mgr_is_force_scc(psoc) && count)) + return; + while (index < count) { + if (WLAN_REG_IS_24GHZ_CH( + pm_conc_connection_list[list[index]].chan) && + policy_mgr_is_safe_channel(psoc, + pm_conc_connection_list[list[index]].chan)) { + band_mask |= 1; + ch_24g = pm_conc_connection_list[list[index]].chan; } - ch_list_count = 0; - if (band_mask == 1) { - ch_list[ch_list_count++] = ch_24g; - for (i = 0; i < *org_ch_list_count; i++) { - if (WLAN_REG_IS_24GHZ_CH( - org_ch_list[i])) - continue; - ch_list[ch_list_count++] = - org_ch_list[i]; - } - } else if (band_mask == 2) { - ch_list[ch_list_count++] = ch_5g; - for (i = 0; i < *org_ch_list_count; i++) { - if (WLAN_REG_IS_5GHZ_CH( - org_ch_list[i])) - continue; - ch_list[ch_list_count++] = - org_ch_list[i]; - } - } else if (band_mask == 3) { - ch_list[ch_list_count++] = ch_24g; - ch_list[ch_list_count++] = ch_5g; - } else { - policy_mgr_debug("unexpected band_mask value %d", - band_mask); - return; + if (WLAN_REG_IS_5GHZ_CH( + pm_conc_connection_list[list[index]].chan) && + policy_mgr_is_safe_channel(psoc, + pm_conc_connection_list[list[index]].chan) && + !wlan_reg_is_dfs_ch(pm_ctx->pdev, + pm_conc_connection_list[list[index]].chan) && + !wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, + pm_conc_connection_list[list[index]].chan)) { + band_mask |= 2; + ch_5g = pm_conc_connection_list[list[index]].chan; } - - *org_ch_list_count = ch_list_count; - for (i = 0; i < *org_ch_list_count; i++) - org_ch_list[i] = ch_list[i]; + index++; } + ch_list_count = 0; + if (band_mask == 1) { + ch_list[ch_list_count++] = ch_24g; + for (i = 0; i < *org_ch_list_count; i++) { + if (WLAN_REG_IS_24GHZ_CH( + org_ch_list[i])) + continue; + ch_list[ch_list_count++] = + org_ch_list[i]; + } + } else if (band_mask == 2) { + if ((reg_get_channel_state(pm_ctx->pdev, ch_5g) == + CHANNEL_STATE_DFS) && + policy_mgr_is_sta_sap_scc_allowed_on_dfs_chan(psoc)) + ch_list[ch_list_count++] = ch_5g; + else if (!(reg_get_channel_state(pm_ctx->pdev, ch_5g) == + CHANNEL_STATE_DFS)) + ch_list[ch_list_count++] = ch_5g; + for (i = 0; i < *org_ch_list_count; i++) { + if (WLAN_REG_IS_5GHZ_CH( + org_ch_list[i])) + continue; + ch_list[ch_list_count++] = + org_ch_list[i]; + } + } else if (band_mask == 3) { + ch_list[ch_list_count++] = ch_24g; + ch_list[ch_list_count++] = ch_5g; + } else { + policy_mgr_debug("unexpected band_mask value %d", + band_mask); + return; + } + + *org_ch_list_count = ch_list_count; + for (i = 0; i < *org_ch_list_count; i++) + org_ch_list[i] = ch_list[i]; + } uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, From c0817c6e73e9b20530785b425f64bd9982a35090 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 19 Jul 2018 14:09:30 -0700 Subject: [PATCH 297/404] qcacmn: Reduce DBS opportunistic timer value to 5 sec Drop the timeout to 5 sec on hastings as it is a 2x2 DBS solution, as IOT issues due to frequent 2x2 to 1x1 or 1x1 to 2x2 transition can be avoided. Change-Id: I67f9c97a7190baeadba79d709a8773b154932e76 CRs-Fixed: 2281954 --- src/wlan_policy_mgr_i.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 787c9fe1669e..393d4d431b38 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -26,7 +26,7 @@ #include "qdf_defer.h" #include "wlan_reg_services_api.h" -#define DBS_OPPORTUNISTIC_TIME 10 +#define DBS_OPPORTUNISTIC_TIME 5 #ifdef QCA_WIFI_3_0_EMU #define CONNECTION_UPDATE_TIMEOUT 3000 #else From db91f687713bd73c5a3a60bb298555b46e9b3dce Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Tue, 17 Jul 2018 13:23:46 +0530 Subject: [PATCH 298/404] 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 a551f698df5a6786846dcde329d35c45d5a78133 Mon Sep 17 00:00:00 2001 From: Jingxiang Ge Date: Fri, 13 Jul 2018 15:16:03 +0800 Subject: [PATCH 299/404] 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 --- core/src/wlan_tdls_main.c | 41 +++++++++-------------- core/src/wlan_tdls_main.h | 9 +++-- dispatcher/inc/wlan_tdls_public_structs.h | 4 +++ dispatcher/src/wlan_tdls_tgt_api.c | 29 +++++++++++++--- dispatcher/src/wlan_tdls_ucfg_api.c | 13 ++----- 5 files changed, 51 insertions(+), 45 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 852352255ef5..bd1a2783f0cc 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -901,19 +901,16 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) { QDF_STATUS status; - if (!notify || !notify->vdev) - return QDF_STATUS_E_INVAL; - - if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) { - qdf_mem_free(notify); + if (!notify || !notify->vdev) { + tdls_err("invalid param"); return QDF_STATUS_E_INVAL; } status = tdls_process_sta_connect(notify); - wlan_objmgr_vdev_release_ref(notify->vdev, - WLAN_TDLS_NB_ID); + if (notify->callback) + notify->callback(notify->vdev); + qdf_mem_free(notify); return status; } @@ -993,19 +990,15 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) { QDF_STATUS status; - if (!notify || !notify->vdev) - return QDF_STATUS_E_INVAL; - - if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) { - qdf_mem_free(notify); + if (!notify || !notify->vdev) { + tdls_err("invalid param"); return QDF_STATUS_E_INVAL; } status = tdls_process_sta_disconnect(notify); - wlan_objmgr_vdev_release_ref(notify->vdev, - WLAN_TDLS_NB_ID); + if (notify->callback) + notify->callback(notify->vdev); qdf_mem_free(notify); return status; @@ -1127,8 +1120,8 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); } -void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, - uint32_t session_id) +QDF_STATUS tdls_peers_deleted_notification( + struct tdls_sta_notify_params *notify_info) { struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; @@ -1137,15 +1130,10 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { tdls_err("memory allocation failed !!!"); - return; + return QDF_STATUS_E_NULL_VALUE; } - notify->lfr_roam = true; - notify->tdls_chan_swit_prohibited = false; - notify->tdls_prohibited = false; - notify->session_id = session_id; - notify->vdev = vdev; - notify->user_disconnect = false; + *notify = *notify_info; msg.bodyptr = notify; msg.callback = tdls_process_cmd; @@ -1155,7 +1143,10 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(notify); tdls_alert("message post failed "); + return QDF_STATUS_E_FAILURE; } + + return QDF_STATUS_SUCCESS; } /** diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index d9cd88864d0c..5c6591424b4a 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -584,17 +584,16 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); /** * tdls_peers_deleted_notification() - peer delete notification - * @vdev: vdev object - * @session_id: session id + * @notify_info: peer info * * Legacy lim layer will delete tdls peers for roaming and heart beat failures * and notify the component about the delete event to update the tdls. * state. * - * Return: None + * Return: QDF_STATUS */ -void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, - uint32_t session_id); +QDF_STATUS tdls_peers_deleted_notification( + struct tdls_sta_notify_params *notify_info); /** * tdls_notify_decrement_session() - Notify the session decrement diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index cb5a8f816e44..eec7260b5d81 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -563,6 +563,9 @@ typedef QDF_STATUS uint32_t vdev_param, bool is_link_up); +/* This callback is to release vdev ref for tdls sta notify msg */ +typedef void (*tdls_sta_notify_callback)(struct wlan_objmgr_vdev *vdev); + /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -1041,6 +1044,7 @@ struct tdls_sta_notify_params { bool lfr_roam; bool user_disconnect; uint8_t session_id; + tdls_sta_notify_callback callback; }; /** diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index c89e202e205f..5c58a73361dd 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -329,10 +329,23 @@ release_nbuf: return status; } +static void tgt_tdls_peers_deleted_notification_callback( + struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + tdls_err("vdev is NULL"); + return; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +} + void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, uint32_t session_id) { struct wlan_objmgr_vdev *vdev; + struct tdls_sta_notify_params notify_info; + QDF_STATUS status; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id, @@ -344,9 +357,17 @@ void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, return; } - tdls_peers_deleted_notification(vdev, session_id); - - wlan_objmgr_vdev_release_ref(vdev, - WLAN_TDLS_SB_ID); + notify_info.lfr_roam = true; + notify_info.tdls_chan_swit_prohibited = false; + notify_info.tdls_prohibited = false; + notify_info.session_id = session_id; + notify_info.vdev = vdev; + notify_info.user_disconnect = false; + notify_info.callback = tgt_tdls_peers_deleted_notification_callback; + status = tdls_peers_deleted_notification(¬ify_info); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("tdls_peers_deleted_notification failed"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + } } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index c93333d99ead..a477ac60ef67 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -627,11 +627,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( if (!notify) return QDF_STATUS_E_NULL_VALUE; - notify->session_id = notify_info->session_id; - notify->tdls_chan_swit_prohibited = - notify_info->tdls_chan_swit_prohibited; - notify->tdls_prohibited = notify_info->tdls_prohibited; - notify->vdev = notify_info->vdev; + *notify = *notify_info; msg.bodyptr = notify; msg.callback = tdls_process_cmd; @@ -659,12 +655,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( if (!notify) return QDF_STATUS_E_NULL_VALUE; - notify->session_id = notify_info->session_id; - notify->tdls_chan_swit_prohibited = false; - notify->tdls_prohibited = false; - notify->vdev = notify_info->vdev; - notify->lfr_roam = notify_info->lfr_roam; - notify->user_disconnect = notify_info->user_disconnect; + *notify = *notify_info; msg.bodyptr = notify; msg.callback = tdls_process_cmd; From 30f5fabfd547df93a804f8fabe2a649e3ed1239f Mon Sep 17 00:00:00 2001 From: Jingxiang Ge Date: Fri, 13 Jul 2018 15:16:03 +0800 Subject: [PATCH 300/404] 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 9a67728191f5d3ae53fb9af34f6332a805c6203d Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 14 Jun 2018 18:58:40 +0800 Subject: [PATCH 301/404] qcacmn: Define configures about P2P Based on converged cfg component, define P2P configures and APIs to get or set these configures. Change-Id: I9b0126d9cc71f7de0d255981ba5fe88f3da05ce2 CRs-Fixed: 2277551 --- core/src/wlan_p2p_main.c | 31 ++++++++ core/src/wlan_p2p_main.h | 20 +++++ dispatcher/inc/wlan_p2p_cfg.h | 128 ++++++++++++++++++++++++++++++ dispatcher/inc/wlan_p2p_cfg_api.h | 76 ++++++++++++++++++ dispatcher/src/wlan_p2p_cfg.c | 105 ++++++++++++++++++++++++ 5 files changed, 360 insertions(+) create mode 100644 dispatcher/inc/wlan_p2p_cfg.h create mode 100644 dispatcher/inc/wlan_p2p_cfg_api.h create mode 100644 dispatcher/src/wlan_p2p_cfg.c diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 105449f580de..2cf7a040914e 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -33,6 +33,8 @@ #include "wlan_p2p_main.h" #include "wlan_p2p_roc.h" #include "wlan_p2p_off_chan_tx.h" +#include "wlan_p2p_cfg.h" +#include "cfg_ucfg_api.h" #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD #include @@ -515,6 +517,34 @@ static QDF_STATUS process_peer_for_noa(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } +/** + * p2p_object_init_params() - init parameters for p2p object + * @psoc: pointer to psoc object + * @p2p_soc_obj: pointer to p2p psoc object + * + * This function init parameters for p2p object + */ +static QDF_STATUS p2p_object_init_params( + struct wlan_objmgr_psoc *psoc, + struct p2p_soc_priv_obj *p2p_soc_obj) +{ + if (!psoc || !p2p_soc_obj) { + p2p_err("invalid param"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj->param.go_keepalive_period = + cfg_get(psoc, CFG_GO_KEEP_ALIVE_PERIOD); + p2p_soc_obj->param.go_link_monitor_period = + cfg_get(psoc, CFG_GO_LINK_MONITOR_PERIOD); + p2p_soc_obj->param.p2p_device_addr_admin = + cfg_get(psoc, CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED); + p2p_soc_obj->param.skip_dfs_channel_p2p_search = + cfg_get(psoc, CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH); + + return QDF_STATUS_SUCCESS; +} + #ifdef WLAN_FEATURE_P2P_DEBUG /** * wlan_p2p_init_connection_status() - init connection status @@ -815,6 +845,7 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) return QDF_STATUS_E_FAILURE; } + p2p_object_init_params(soc, p2p_soc_obj); qdf_list_create(&p2p_soc_obj->roc_q, MAX_QUEUE_LENGTH); qdf_list_create(&p2p_soc_obj->tx_q_roc, MAX_QUEUE_LENGTH); qdf_list_create(&p2p_soc_obj->tx_q_ack, MAX_QUEUE_LENGTH); diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 8cae74085863..1e57b2e17213 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -156,6 +156,24 @@ enum p2p_connection_status { }; #endif +/** + * struct p2p_param - p2p parameters to be used + * @go_keepalive_period: P2P GO keep alive period + * @go_link_monitor_period: period where link is idle and + * where we send NULL frame + * @p2p_device_addr_admin: enable/disable to derive the P2P + * MAC address from the primary MAC address + * @skip_dfs_channel_p2p_search: kip DFS Channel in case of P2P Search + * @ignore_dynamic_dtim_in_p2p_mode:Ignore Dynamic Dtim in case of P2P options + */ +struct p2p_param { + uint32_t go_keepalive_period; + uint32_t go_link_monitor_period; + bool p2p_device_addr_admin; + bool skip_dfs_channel_p2p_search; + bool ignore_dynamic_dtim_in_p2p_mode; +}; + /** * struct p2p_soc_priv_obj - Per SoC p2p private object * @soc: Pointer to SoC context @@ -172,6 +190,7 @@ enum p2p_connection_status { * @p2p_cb: Callbacks to protocol stack * @cur_roc_vdev_id: Vdev id of current roc * @p2p_idr: p2p idr + * @param: p2p parameters to be used * @connection_status:Global P2P connection status */ struct p2p_soc_priv_obj { @@ -188,6 +207,7 @@ struct p2p_soc_priv_obj { struct p2p_protocol_callbacks p2p_cb; uint32_t cur_roc_vdev_id; qdf_idr p2p_idr; + struct p2p_param param; #ifdef WLAN_FEATURE_P2P_DEBUG enum p2p_connection_status connection_status; #endif diff --git a/dispatcher/inc/wlan_p2p_cfg.h b/dispatcher/inc/wlan_p2p_cfg.h new file mode 100644 index 000000000000..3ee037f5a0a0 --- /dev/null +++ b/dispatcher/inc/wlan_p2p_cfg.h @@ -0,0 +1,128 @@ +/* + * Copyright (c) 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 + * 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. + */ + +#if !defined(CONFIG_P2P_H__) +#define CONFIG_P2P_H__ + +#include "cfg_define.h" +#include "cfg_converged.h" +#include "qdf_types.h" + +/* + * + * gGoKeepAlivePeriod - P2P GO keep alive period. + * @Min: 1 + * @Max: 65535 + * @Default: 20 + * + * This is P2P GO keep alive period. + * + * Related: None. + * + * Supported Feature: P2P + * + * Usage: Internal/External + * + * + */ +#define CFG_GO_KEEP_ALIVE_PERIOD CFG_INI_UINT( \ + "gGoKeepAlivePeriod", \ + 1, \ + 65535, \ + 20, \ + CFG_VALUE_OR_DEFAULT, \ + "P2P GO keep alive period") + +/* + * + * gGoLinkMonitorPeriod - period where link is idle and where + * we send NULL frame + * @Min: 3 + * @Max: 50 + * @Default: 10 + * + * This is period where link is idle and where we send NULL frame for P2P GO. + * + * Related: None. + * + * Supported Feature: P2P + * + * Usage: Internal/External + * + * + */ +#define CFG_GO_LINK_MONITOR_PERIOD CFG_INI_UINT( \ + "gGoLinkMonitorPeriod", \ + 3, \ + 50, \ + 10, \ + CFG_VALUE_OR_DEFAULT, \ + "period where link is idle and where we send NULL frame") + +/* + * + * isP2pDeviceAddrAdministrated - Enables to derive the P2P MAC address from + * the primary MAC address + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to enable/disable to derive the P2P MAC address from the + * primary MAC address. + * + * Related: None. + * + * Supported Feature: P2P + * + * Usage: Internal/External + * + * + */ +#define CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED CFG_INI_BOOL( \ + "isP2pDeviceAddrAdministrated", \ + 1, \ + "derive the P2P MAC address from the primary MAC address") + +/* + * + * gSkipDfsChannelInP2pSearch - Skip DFS Channel in case of P2P Search + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to disable(skip) dfs channel in p2p search. + * Related: None. + * + * Supported Feature: DFS P2P + * + * Usage: Internal/External + * + * + */ +#define CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH CFG_INI_BOOL( \ + "gSkipDfsChannelInP2pSearch", \ + 1, \ + "skip dfs channel in p2p search") + +#define CFG_P2P_ALL \ + CFG(CFG_GO_KEEP_ALIVE_PERIOD) \ + CFG(CFG_GO_LINK_MONITOR_PERIOD) \ + CFG(CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED) \ + CFG(CFG_ENABLE_SKIP_DFS_IN_P2P_SEARCH) + +#endif diff --git a/dispatcher/inc/wlan_p2p_cfg_api.h b/dispatcher/inc/wlan_p2p_cfg_api.h new file mode 100644 index 000000000000..18e86055bcd2 --- /dev/null +++ b/dispatcher/inc/wlan_p2p_cfg_api.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 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 + * 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: Contains p2p configures interface definitions + */ + +#ifndef _WLAN_P2P_CFG_API_H_ +#define _WLAN_P2P_CFG_API_H_ + +#include + +struct wlan_objmgr_psoc; + +/** + * cfg_p2p_get_go_keepalive_period() - get go keepalive period + * @psoc: pointer to psoc object + * @period: go keepalive period + * + * This function gets go keepalive period to p2p component + */ +QDF_STATUS +cfg_p2p_get_go_keepalive_period(struct wlan_objmgr_psoc *psoc, + uint32_t *period); + +/** + * cfg_p2p_get_go_link_monitor_period() - get go link monitor period + * @psoc: pointer to psoc object + * @period: go link monitor period + * + * This function gets go link monitor period to p2p component + */ +QDF_STATUS +cfg_p2p_get_go_link_monitor_period(struct wlan_objmgr_psoc *psoc, + uint32_t *period); + +/** + * cfg_p2p_get_device_addr_admin() - get enable/disable p2p device + * addr administrated + * @psoc: pointer to psoc object + * @enable: enable/disable p2p device addr administrated + * + * This function gets enable/disable p2p device addr administrated + */ +QDF_STATUS +cfg_p2p_get_device_addr_admin(struct wlan_objmgr_psoc *psoc, + bool *enable); + +/** + * cfg_p2p_get_skip_dfs_channel_p2p_search() - get skip dfs channel + * in p2p search + * @psoc: pointer to psoc object + * @enable: enable/disable skip dfs channel in p2p search + * + * This function gets enable/disable skip dfs channel in p2p search + */ +QDF_STATUS +cfg_p2p_get_skip_dfs_channel_p2p_search(struct wlan_objmgr_psoc *psoc, + bool *enable); + +#endif /* _WLAN_P2P_CFG_API_H_ */ diff --git a/dispatcher/src/wlan_p2p_cfg.c b/dispatcher/src/wlan_p2p_cfg.c new file mode 100644 index 000000000000..490b95821eaf --- /dev/null +++ b/dispatcher/src/wlan_p2p_cfg.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 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 + * 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: This file contains p2p configures interface definitions + */ + +#include +#include "wlan_p2p_public_struct.h" +#include "wlan_p2p_cfg_api.h" +#include "../../core/src/wlan_p2p_main.h" + +static inline struct p2p_soc_priv_obj * +wlan_psoc_get_p2p_object(struct wlan_objmgr_psoc *psoc) +{ + return wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_P2P); +} + +QDF_STATUS +cfg_p2p_get_go_keepalive_period(struct wlan_objmgr_psoc *psoc, + uint32_t *period) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_soc_obj = wlan_psoc_get_p2p_object(psoc); + if (!p2p_soc_obj) { + *period = 0; + p2p_err("p2p psoc null"); + return QDF_STATUS_E_INVAL; + } + + *period = p2p_soc_obj->param.go_keepalive_period; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_p2p_get_go_link_monitor_period(struct wlan_objmgr_psoc *psoc, + uint32_t *period) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_soc_obj = wlan_psoc_get_p2p_object(psoc); + if (!p2p_soc_obj) { + *period = 0; + p2p_err("p2p psoc null"); + return QDF_STATUS_E_INVAL; + } + + *period = p2p_soc_obj->param.go_link_monitor_period; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_p2p_get_device_addr_admin(struct wlan_objmgr_psoc *psoc, + bool *enable) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_soc_obj = wlan_psoc_get_p2p_object(psoc); + if (!p2p_soc_obj) { + *enable = false; + p2p_err("p2p psoc null"); + return QDF_STATUS_E_INVAL; + } + + *enable = p2p_soc_obj->param.p2p_device_addr_admin; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_p2p_get_skip_dfs_channel_p2p_search(struct wlan_objmgr_psoc *psoc, + bool *enable) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_soc_obj = wlan_psoc_get_p2p_object(psoc); + if (!p2p_soc_obj) { + *enable = false; + p2p_err("p2p psoc null"); + return QDF_STATUS_E_INVAL; + } + + *enable = p2p_soc_obj->param.skip_dfs_channel_p2p_search; + + return QDF_STATUS_SUCCESS; +} From a590ecd80e4cd41532ace95fbf9a6eba2c0ec1eb Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 25 May 2018 00:56:38 -0400 Subject: [PATCH 302/404] qcacmn: Add Band selection for NSS Update API Add parameter to NSS Update API to specify which Band to downgrade/upgrade. Change-Id: I57ae4304fbf8de366531154f03d04792c18e176d CRs-Fixed: 2256803 --- inc/wlan_policy_mgr_public_struct.h | 4 +++- src/wlan_policy_mgr_action.c | 4 ++-- src/wlan_policy_mgr_core.c | 21 ++++++++++++++++++--- src/wlan_policy_mgr_i.h | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 6b46aab6daaf..448f7b0532da 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -714,6 +714,7 @@ enum policy_mgr_conc_next_action { * * @POLICY_MGR_BAND_24: 2.4 Ghz band * @POLICY_MGR_BAND_5: 5 Ghz band + * @POLICY_MGR_ANY: to specify all band * @POLICY_MGR_MAX_BAND: Max place holder * * These are generic IDs that identify the various roles @@ -722,7 +723,8 @@ enum policy_mgr_conc_next_action { enum policy_mgr_band { POLICY_MGR_BAND_24 = 0, POLICY_MGR_BAND_5, - POLICY_MGR_MAX_BAND + POLICY_MGR_ANY, + POLICY_MGR_MAX_BAND = POLICY_MGR_ANY, }; /** diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 603382bfd95c..2d9cab406595 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -722,7 +722,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, * intially. If yes, update the beacon template & notify FW. */ status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1, - PM_NOP, reason); + PM_NOP, POLICY_MGR_ANY, reason); break; case PM_UPGRADE: /* @@ -730,7 +730,7 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, * intially. If yes, update the beacon template & notify FW. */ status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2, - PM_NOP, reason); + PM_NOP, POLICY_MGR_ANY, reason); break; default: policy_mgr_err("unexpected action value %d", action); diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index b76644192f91..7882bf29ecb9 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2501,6 +2501,7 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, uint8_t new_nss, uint8_t next_action, + enum policy_mgr_band band, enum policy_mgr_conn_update_reason reason) { QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -2510,6 +2511,7 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id; uint32_t original_nss; struct policy_mgr_psoc_priv_obj *pm_ctx; + uint8_t chan; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -2524,6 +2526,7 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, vdev_id = pm_conc_connection_list[list[index]].vdev_id; original_nss = pm_conc_connection_list[list[index]].original_nss; + chan = pm_conc_connection_list[list[index]].chan; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); conn_index = policy_mgr_get_connection_for_vdev_id( psoc, vdev_id); @@ -2533,7 +2536,12 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, continue; } - if (2 == original_nss) { + if (original_nss == 2 && + (band == POLICY_MGR_ANY || + (band == POLICY_MGR_BAND_24 && + WLAN_REG_IS_24GHZ_CH(chan)) || + (band == POLICY_MGR_BAND_5 && + WLAN_REG_IS_5GHZ_CH(chan)))) { status = pm_ctx->sme_cbacks.sme_nss_update_request( vdev_id, new_nss, policy_mgr_nss_update_cb, @@ -2552,6 +2560,7 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, vdev_id = pm_conc_connection_list[list[index]].vdev_id; original_nss = pm_conc_connection_list[list[index]].original_nss; + chan = pm_conc_connection_list[list[index]].chan; qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); conn_index = policy_mgr_get_connection_for_vdev_id( psoc, vdev_id); @@ -2560,7 +2569,12 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, vdev_id); continue; } - if (2 == original_nss) { + if (original_nss == 2 && + (band == POLICY_MGR_ANY || + (band == POLICY_MGR_BAND_24 && + WLAN_REG_IS_24GHZ_CH(chan)) || + (band == POLICY_MGR_BAND_5 && + WLAN_REG_IS_5GHZ_CH(chan)))) { status = pm_ctx->sme_cbacks.sme_nss_update_request( vdev_id, new_nss, policy_mgr_nss_update_cb, @@ -2608,7 +2622,8 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, * protection. So, not taking any lock inside * policy_mgr_complete_action() during pm_conc_connection_list access. */ - status = policy_mgr_nss_update(psoc, new_nss, next_action, reason); + status = policy_mgr_nss_update(psoc, new_nss, next_action, + POLICY_MGR_ANY, reason); if (!QDF_IS_STATUS_SUCCESS(status)) status = policy_mgr_next_actions(psoc, session_id, next_action, reason); diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 393d4d431b38..15c9d9b92b61 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -457,7 +457,21 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, struct avoid_freq_ind_data *avoid_freq_ind, void *arg); +/** + * policy_mgr_nss_update() - update nss for AP vdev + * @psoc: PSOC object information + * @new_nss: new NSS value + * @next_action: Next action after nss update + * @band: update AP vdev on the Band. + * @reason: action reason + * + * The function will update AP vdevs on specific band. + * eg. band = POLICY_MGR_ANY will request to update all band (2g and 5g) + * + * Return: QDF_STATUS_SUCCESS, update requested successfully. + */ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, uint8_t new_nss, uint8_t next_action, + enum policy_mgr_band band, enum policy_mgr_conn_update_reason reason); #endif From 3baf0037227c4b99046fa5d0ea33f5814048223d Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Tue, 19 Jun 2018 19:21:06 +0800 Subject: [PATCH 303/404] qcacmn: Define configures about TDLS Based on converged cfg component, define TDLS configures and APIs to get or set these configures. Change-Id: I86f61246b810c7f25a74c814df20d0e2c810b292 CRs-Fixed: 2277559 --- dispatcher/inc/wlan_tdls_cfg.h | 759 ++++++++++++++++++++++ dispatcher/inc/wlan_tdls_cfg_api.h | 217 +++++++ dispatcher/inc/wlan_tdls_public_structs.h | 20 +- dispatcher/src/wlan_tdls_cfg.c | 324 +++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 97 ++- 5 files changed, 1413 insertions(+), 4 deletions(-) create mode 100644 dispatcher/inc/wlan_tdls_cfg.h create mode 100644 dispatcher/inc/wlan_tdls_cfg_api.h create mode 100644 dispatcher/src/wlan_tdls_cfg.c diff --git a/dispatcher/inc/wlan_tdls_cfg.h b/dispatcher/inc/wlan_tdls_cfg.h new file mode 100644 index 000000000000..03827e593a58 --- /dev/null +++ b/dispatcher/inc/wlan_tdls_cfg.h @@ -0,0 +1,759 @@ +/* + * Copyright (c) 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 + * 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. + */ + +#if !defined(CONFIG_TDLS_H__) +#define CONFIG_TDLS_H__ + +#include "cfg_define.h" +#include "cfg_converged.h" +#include "qdf_types.h" + +/* + * + * gTDLSUapsdMask - ACs to setup U-APSD for TDLS Sta. + * @Min: 0 + * @Max: 0x0F + * @Default: 0x0F + * + * This ini is used to configure the ACs for which mask needs to be enabled. + * 0x1: Background 0x2: Best effort + * 0x4: Video 0x8: Voice + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_QOS_WMM_UAPSD_MASK CFG_INI_UINT( \ + "gTDLSUapsdMask", \ + 0, \ + 0x0F, \ + 0x0F, \ + CFG_VALUE_OR_DEFAULT, \ + "ACs to setup U-APSD for TDLS Sta") + +/* + * + * gEnableTDLSBufferSta - Controls the TDLS buffer. + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to control the TDLS buffer. + * Buffer STA is not enabled in CLD 2.0 yet. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_BUF_STA_ENABLED CFG_INI_BOOL( \ + "gEnableTDLSBufferSta", \ + 1, \ + "Controls the TDLS buffer") + +/* + * + * gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time. + * @Min: 0 + * @Max: 10 + * @Default: 0 + * + * This ini is used to configure peer uapsd inactivity time. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_INACT_TIME CFG_INI_UINT( \ + "gTDLSPuapsdInactivityTime", \ + 0, \ + 10, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer UAPSD Inactivity time") + +/* + * + * gTDLSPuapsdRxFrameThreshold - Peer UAPSD Rx frame threshold. + * @Min: 10 + * @Max: 20 + * @Default: 10 + * + * This ini is used to configure maximum Rx frame during SP. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_RX_FRAME_THRESHOLD CFG_INI_UINT( \ + "gTDLSPuapsdRxFrameThreshold", \ + 10, \ + 20, \ + 10, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer UAPSD Rx frame threshold") + +/* + * + * gEnableTDLSOffChannel - Enables off-channel support for TDLS link. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable off-channel support for TDLS link. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_OFF_CHANNEL_ENABLED CFG_INI_BOOL( \ + "gEnableTDLSOffChannel", \ + 0, \ + "Enables off-channel support for TDLS") + +/* + * + * gEnableTDLSSupport - Enable support for TDLS. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable TDLS support. + * + * Related: None. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_SUPPORT_ENABLE CFG_INI_BOOL( \ + "gEnableTDLSSupport", \ + 0, \ + "enable/disable TDLS support") + +/* + * + * gEnableTDLSImplicitTrigger - Enable Implicit TDLS. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable implicit TDLS. + * CLD driver initiates TDLS Discovery towards a peer whenever TDLS Setup + * criteria (throughput and RSSI thresholds) is met and then it tears down + * TDLS when teardown criteria (idle packet count and RSSI) is met. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_IMPLICIT_TRIGGER CFG_INI_BOOL( \ + "gEnableTDLSImplicitTrigger", \ + 0, \ + "enable/disable implicit TDLS") + +/* + * + * gTDLSTxStatsPeriod - TDLS TX statistics time period. + * @Min: 1000 + * @Max: 4294967295 + * @Default: 2000 + * + * This ini is used to configure the time period (in ms) to evaluate whether + * the number of Tx/Rx packets exceeds TDLSTxPacketThreshold and triggers a + * TDLS Discovery request. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_TX_STATS_PERIOD CFG_INI_UINT( \ + "gTDLSTxStatsPeriod", \ + 1000, \ + 4294967295UL, \ + 2000, \ + CFG_VALUE_OR_DEFAULT, \ + "TDLS TX statistics time period") + +/* + * + * gTDLSTxPacketThreshold - Tx/Rx Packet threshold for initiating TDLS. + * @Min: 0 + * @Max: 4294967295 + * @Default: 40 + * + * This ini is used to configure the number of Tx/Rx packets during the + * period of gTDLSTxStatsPeriod when exceeded, a TDLS Discovery request + * is triggered. + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_TX_PACKET_THRESHOLD CFG_INI_UINT( \ + "gTDLSTxPacketThreshold", \ + 0, \ + 4294967295UL, \ + 40, \ + CFG_VALUE_OR_DEFAULT, \ + "Tx/Rx Packet threshold for initiating TDLS") + +/* + * + * gTDLSMaxDiscoveryAttempt - Attempts for sending TDLS discovery requests. + * @Min: 1 + * @Max: 100 + * @Default: 5 + * + * This ini is used to configure the number of failures of discover request, + * when exceeded, the peer is assumed to be not TDLS capable and no further + * TDLS Discovery request is made. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT CFG_INI_UINT( \ + "gTDLSMaxDiscoveryAttempt", \ + 1, \ + 100, \ + 5, \ + CFG_VALUE_OR_DEFAULT, \ + "Attempts for sending TDLS discovery requests") + +/* + * + * gTDLSIdleTimeout - Duration within which number of TX / RX frames meet the + * criteria for TDLS teardown. + * @Min: 500 + * @Max: 40000 + * @Default: 5000 + * + * This ini is used to configure the time period (in ms) to evaluate whether + * the number of Tx/Rx packets exceeds gTDLSIdlePacketThreshold and thus meets + * criteria for TDLS teardown. + * Teardown notification interval (gTDLSIdleTimeout) should be multiple of + * setup notification (gTDLSTxStatsPeriod) interval. + * e.g. + * if setup notification (gTDLSTxStatsPeriod) interval = 500, then + * teardown notification (gTDLSIdleTimeout) interval should be 1000, + * 1500, 2000, 2500... + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + */ +#define CFG_TDLS_IDLE_TIMEOUT CFG_INI_UINT( \ + "gTDLSIdleTimeout", \ + 500, \ + 40000, \ + 5000, \ + CFG_VALUE_OR_DEFAULT, \ + "this is idle time period") + +/* + * + * gTDLSIdlePacketThreshold - Number of idle packet. + * @Min: 0 + * @Max: 40000 + * @Default: 3 + * + * This ini is used to configure the number of Tx/Rx packet, below which + * within last gTDLSTxStatsPeriod period is considered as idle condition. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_IDLE_PACKET_THRESHOLD CFG_INI_UINT( \ + "gTDLSIdlePacketThreshold", \ + 0, \ + 40000, \ + 3, \ + CFG_VALUE_OR_DEFAULT, \ + "Number of idle packet") + +/* + * + * gTDLSRSSITriggerThreshold - RSSI threshold for TDLS connection. + * @Min: -120 + * @Max: 0 + * @Default: -75 + * + * This ini is used to configure the absolute value (in dB) of the peer RSSI, + * below which a TDLS setup request is triggered. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD CFG_INI_INT( \ + "gTDLSRSSITriggerThreshold", \ + -120, \ + 0, \ + -75, \ + CFG_VALUE_OR_DEFAULT, \ + "RSSI threshold for TDLS connection") + +/* + * + * gTDLSRSSITeardownThreshold - RSSI threshold for TDLS teardown. + * @Min: -120 + * @Max: 0 + * @Default: -75 + * + * This ini is used to configure the absolute value (in dB) of the peer RSSI, + * when exceed, a TDLS teardown is triggered. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD CFG_INI_INT( \ + "gTDLSRSSITeardownThreshold", \ + -120, \ + 0, \ + -75, \ + CFG_VALUE_OR_DEFAULT, \ + "RSSI threshold for TDLS teardown") + +/* + * + * gTDLSRSSITeardownThreshold - RSSI threshold for TDLS teardown. + * @Min: -120 + * @Max: 0 + * @Default: -75 + * + * This ini is used to configure the absolute value (in dB) of the peer RSSI, + * when exceed, a TDLS teardown is triggered. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_RSSI_DELTA CFG_INI_INT( \ + "gTDLSRSSIDelta", \ + -30, \ + 0, \ + -20, \ + CFG_VALUE_OR_DEFAULT, \ + "Delta value for the peer RSSI that can trigger teardown") + +/* + * + * gTDLSPrefOffChanNum - Preferred TDLS channel number when off-channel support + * is enabled. + * @Min: 1 + * @Max: 165 + * @Default: 36 + * + * This ini is used to configure preferred TDLS channel number when off-channel + * support is enabled. + * + * Related: gEnableTDLSSupport, gEnableTDLSOffChannel. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM CFG_INI_UINT( \ + "gTDLSPrefOffChanNum", \ + 1, \ + 165, \ + 36, \ + CFG_VALUE_OR_DEFAULT, \ + "Preferred TDLS channel number") + +/* + * + * gTDLSPrefOffChanBandwidth - Preferred TDLS channel bandwidth when + * off-channel support is enabled. + * @Min: 0x01 + * @Max: 0x0F + * @Default: 0x07 + * + * This ini is used to configure preferred TDLS channel bandwidth when + * off-channel support is enabled. + * 0x1: 20 MHz 0x2: 40 MHz 0x4: 80 MHz 0x8: 160 MHz + * When more than one bits are set then firmware starts from the highest and + * selects one based on capability of peer. + * + * Related: gEnableTDLSSupport, gEnableTDLSOffChannel. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW CFG_INI_UINT( \ + "gTDLSPrefOffChanBandwidth", \ + 1, \ + 15, \ + 7, \ + CFG_VALUE_OR_DEFAULT, \ + "Preferred TDLS channel bandwidth") + +/* + * + * gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time. + * @Min: 0 + * @Max: 10 + * @Default: 0 + * + * This ini is used to configure peer uapsd inactivity time. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME CFG_INI_UINT( \ + "gTDLSPuapsdInactivityTime", \ + 0, \ + 10, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer UAPSD Inactivity time") + +/* + * + * gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time. + * @Min: 0 + * @Max: 10 + * @Default: 0 + * + * This ini is used to configure peer uapsd inactivity time. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD CFG_INI_UINT( \ + "gTDLSPuapsdRxFrameThreshold", \ + 10, \ + 20, \ + 10, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer UAPSD Rx frame threshold") + +/* + * + * gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication + * window. + * @Min: 1 + * @Max: 5 + * @Default: 2 + * + * This ini is used to configure buffering time in number of beacon intervals. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW CFG_INI_UINT( \ + "gTDLSPuapsdPTIWindow", \ + 1, \ + 5, \ + 2, \ + CFG_VALUE_OR_DEFAULT, \ + "This ini is used to configure peer traffic indication") + +/* + * + * gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication + * window. + * @Min: 1 + * @Max: 5 + * @Default: 2 + * + * This ini is used to configure buffering time in number of beacon intervals. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT CFG_INI_UINT( \ + "gTDLSPuapsdPTRTimeout", \ + 0, \ + 10000, \ + 5000, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer Traffic Response timer duration in ms") + +/* + * + * gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication + * window. + * @Min: 1 + * @Max: 5 + * @Default: 2 + * + * This ini is used to configure buffering time in number of beacon intervals. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_EXTERNAL_CONTROL CFG_INI_BOOL( \ + "gTDLSExternalControl", \ + 1, \ + "Enable external TDLS control") + +/* + * + * gEnableTDLSWmmMode - Enables WMM support over TDLS link. + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to enable/disable WMM support over TDLS link. + * This is required to be set to 1 for any TDLS and uAPSD functionality. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_WMM_MODE_ENABLE CFG_INI_BOOL( \ + "gEnableTDLSWmmMode", \ + 1, \ + "Enables WMM support over TDLS link") + +/* + * + * gEnableTDLSScan - Allow scan and maintain TDLS link. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable TDLS scan. + * 0: If peer is not buffer STA capable and device is not sleep STA + * capable, then teardown TDLS link when scan is initiated. If peer + * is buffer STA and we can be sleep STA then TDLS link is maintained + * during scan. + * 1: Maintain TDLS link and allow scan even if peer is not buffer STA + * capable and device is not sleep STA capable. There will be loss of + * Rx pkts since peer would not know when device moves away from tdls + * channel. Tx on TDLS link would stop when device moves away from tdls + * channel. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_SCAN_ENABLE CFG_INI_BOOL( \ + "gEnableTDLSScan", \ + 0, \ + "Allow scan and maintain TDLS link") + +/* + * + * gTDLSPeerKickoutThreshold - TDLS peer kick out threshold to firmware. + * @Min: 10 + * @Max: 5000 + * @Default: 96 + * + * This ini is used to configure TDLS peer kick out threshold to firmware. + * Firmware will use this value to determine, when to send TDLS + * peer kick out event to host. + * E.g. + * if peer kick out threshold is 10, then firmware will wait for 10 + * consecutive packet failures and then send TDLS kick out + * notification to host driver + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PEER_KICKOUT_THRESHOLD CFG_INI_UINT( \ + "gTDLSPeerKickoutThreshold", \ + 10, \ + 5000, \ + 96, \ + CFG_VALUE_OR_DEFAULT, \ + "TDLS peer kick out threshold to firmware") + +/* + * + * gTDLSEnableDeferTime - Timer to defer for enabling TDLS on P2P listen. + * @Min: 500 + * @Max: 6000 + * @Default: 2000 + * + * This ini is used to set the timer to defer for enabling TDLS on P2P + * listen (value in milliseconds). + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_ENABLE_DEFER_TIMER CFG_INI_UINT( \ + "gTDLSEnableDeferTime", \ + 500, \ + 6000, \ + 2000, \ + CFG_VALUE_OR_DEFAULT, \ + "Timer to defer for enabling TDLS on P2P listen") + +/* + * + * DelayedTriggerFrmInt - delayed trigger frame interval. + * @Min: 500 + * @Max: 6000 + * @Default: 2000 + * + * This ini is used to set the delayed trigger frame interval. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_DELAYED_TRGR_FRM_INT CFG_INI_UINT( \ + "DelayedTriggerFrmInt", \ + 1, \ + 4294967295UL, \ + 3000, \ + CFG_VALUE_OR_DEFAULT, \ + "delayed trigger frame interval") + +#define CFG_TDLS_ALL \ + CFG(CFG_TDLS_QOS_WMM_UAPSD_MASK) \ + CFG(CFG_TDLS_BUF_STA_ENABLED) \ + CFG(CFG_TDLS_PUAPSD_INACT_TIME) \ + CFG(CFG_TDLS_RX_FRAME_THRESHOLD) \ + CFG(CFG_TDLS_OFF_CHANNEL_ENABLED) \ + CFG(CFG_TDLS_SUPPORT_ENABLE) \ + CFG(CFG_TDLS_IMPLICIT_TRIGGER) \ + CFG(CFG_TDLS_TX_STATS_PERIOD) \ + CFG(CFG_TDLS_TX_PACKET_THRESHOLD) \ + CFG(CFG_TDLS_MAX_DISCOVERY_ATTEMPT) \ + CFG(CFG_TDLS_IDLE_TIMEOUT) \ + CFG(CFG_TDLS_IDLE_PACKET_THRESHOLD) \ + CFG(CFG_TDLS_RSSI_TRIGGER_THRESHOLD) \ + CFG(CFG_TDLS_RSSI_TEARDOWN_THRESHOLD) \ + CFG(CFG_TDLS_RSSI_DELTA) \ + CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM) \ + CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_BW) \ + CFG(CFG_TDLS_PUAPSD_INACTIVITY_TIME) \ + CFG(CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD) \ + CFG(CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW) \ + CFG(CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT) \ + CFG(CFG_TDLS_EXTERNAL_CONTROL) \ + CFG(CFG_TDLS_WMM_MODE_ENABLE) \ + CFG(CFG_TDLS_SCAN_ENABLE) \ + CFG(CFG_TDLS_PEER_KICKOUT_THRESHOLD) \ + CFG(CFG_TDLS_ENABLE_DEFER_TIMER) \ + CFG(CFG_TDLS_DELAYED_TRGR_FRM_INT) + +#endif diff --git a/dispatcher/inc/wlan_tdls_cfg_api.h b/dispatcher/inc/wlan_tdls_cfg_api.h new file mode 100644 index 000000000000..6229c0ca1bd3 --- /dev/null +++ b/dispatcher/inc/wlan_tdls_cfg_api.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 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 + * 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: Contains p2p configures interface definitions + */ + +#ifndef _WLAN_TDLS_CFG_API_H_ +#define _WLAN_TDLS_CFG_API_H_ + +#include + +struct wlan_objmgr_psoc; + +/** + * cfg_tdls_get_support_enable() - get tdls support enable + * @psoc: pointer to psoc object + * @val: pointer to tdls support enable/disable + * + * This function gets tdls support enable + */ +QDF_STATUS +cfg_tdls_get_support_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_support_enable() - set tdls support enable + * @psoc: pointer to psoc object + * @val: set tdls support enable/disable + * + * This function sets tdls support enable + */ +QDF_STATUS +cfg_tdls_set_support_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * cfg_tdls_get_external_control() - get tdls external control + * @psoc: pointer to psoc object + * @val: pointer to tdls external control enable/disable + * + * This function gets tdls external control + */ +QDF_STATUS +cfg_tdls_get_external_control(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_get_uapsd_mask() - get tdls uapsd mask + * @psoc: pointer to psoc object + * @val: pointer to tdls uapsd mask + * + * This function gets tdls uapsd mask + */ +QDF_STATUS +cfg_tdls_get_uapsd_mask(struct wlan_objmgr_psoc *psoc, + uint32_t *val); + +/** + * cfg_tdls_get_buffer_sta_enable() - get tdls buffer sta enable + * @psoc: pointer to psoc object + * @val: pointer to tdls buffer sta enable + * + * This function gets tdls buffer sta enable + */ +QDF_STATUS +cfg_tdls_get_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_buffer_sta_enable() - set tdls buffer sta enable + * @psoc: pointer to psoc object + * @val: tdls buffer sta enable + * + * This function sets tdls buffer sta enable + */ +QDF_STATUS +cfg_tdls_set_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * cfg_tdls_get_uapsd_inactivity_time() - get tdls uapsd inactivity time + * @psoc: pointer to psoc object + * @val: pointer to tdls uapsd inactivity time + * + * This function gets tdls uapsd inactivity time + */ +QDF_STATUS +cfg_tdls_get_uapsd_inactivity_time(struct wlan_objmgr_psoc *psoc, + uint32_t *val); + +/** + * cfg_tdls_get_rx_pkt_threshold() - get tdls rx pkt threshold + * @psoc: pointer to psoc object + * @val: pointer to tdls tdls rx pkt threshold + * + * This function gets tdls rx pkt threshold + */ +QDF_STATUS +cfg_tdls_get_rx_pkt_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t *val); + +/** + * cfg_tdls_get_off_channel_enable() - get tdls off channel enable + * @psoc: pointer to psoc object + * @val: pointer to tdls off channel enable + * + * This function gets tdls off channel enable + */ +QDF_STATUS +cfg_tdls_get_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_off_channel_enable() - set tdls off channel enable + * @psoc: pointer to psoc object + * @val: tdls off channel enable + * + * This function sets tdls off channel enable + */ +QDF_STATUS +cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * cfg_tdls_get_wmm_mode_enable() - get tdls wmm mode enable + * @psoc: pointer to psoc object + * @val: pointer to tdls wmm mode enable + * + * This function gets tdls wmm mode enable + */ +QDF_STATUS +cfg_tdls_get_wmm_mode_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_vdev_nss_2g() - set tdls vdev nss 2g + * @psoc: pointer to psoc object + * @val: tdls vdev nss 2g + * + * This function sets tdls vdev nss 2g + */ +QDF_STATUS +cfg_tdls_set_vdev_nss_2g(struct wlan_objmgr_psoc *psoc, + uint8_t val); + +/** + * cfg_tdls_set_vdev_nss_5g() - set tdls vdev nss 5g + * @psoc: pointer to psoc object + * @val: tdls vdev nss 5g + * + * This function sets tdls vdev nss 5g + */ +QDF_STATUS +cfg_tdls_set_vdev_nss_5g(struct wlan_objmgr_psoc *psoc, + uint8_t val); + +/** + * cfg_tdls_get_sleep_sta_enable() - get tdls sleep sta enable + * @psoc: pointer to psoc object + * @val: pointer to tdls sleep sta enable + * + * This function gets tdls sleep sta enable + */ +QDF_STATUS +cfg_tdls_get_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_sleep_sta_enable() - set tdls sleep sta enable + * @psoc: pointer to psoc object + * @val: tdls sleep sta enable + * + * This function sets tdls sleep sta enable + */ +QDF_STATUS +cfg_tdls_set_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * cfg_tdls_get_scan_enable() - get tdls scan enable + * @psoc: pointer to psoc object + * @val: pointer to tdls scan enable + * + * This function gets tdls scan enable + */ +QDF_STATUS +cfg_tdls_get_scan_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_scan_enable() - set tdls scan enable + * @psoc: pointer to psoc object + * @val: tdls scan enable + * + * This function sets tdls scan enable + */ +QDF_STATUS +cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +#endif /* _WLAN_TDLS_CFG_API_H_ */ diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index eec7260b5d81..c8dd05f53ecc 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -427,6 +427,14 @@ enum tdls_feature_bit { * @delayed_trig_framint: delayed trigger frame interval * @tdls_vdev_nss_2g: tdls NSS setting for 2G band * @tdls_vdev_nss_5g: tdls NSS setting for 5G band + * @tdls_buffer_sta_enable: tdls buffer station enable + * @tdls_off_chan_enable: tdls off channel enable + * @tdls_wmm_mode_enable: tdls wmm mode enable + * @tdls_external_control: tdls external control enable + * @tdls_implicit_trigger_enable: tdls implicit trigger enable + * @tdls_scan_enable: tdls scan enable + * @tdls_sleep_sta_enable: tdls sleep sta enable + * @tdls_support_enable: tdls support enable */ struct tdls_user_config { uint32_t tdls_tx_states_period; @@ -435,8 +443,8 @@ struct tdls_user_config { uint32_t tdls_max_discovery_attempt; uint32_t tdls_idle_timeout; uint32_t tdls_idle_pkt_threshold; - uint32_t tdls_rssi_trigger_threshold; - uint32_t tdls_rssi_teardown_threshold; + int32_t tdls_rssi_trigger_threshold; + int32_t tdls_rssi_teardown_threshold; uint32_t tdls_rssi_delta; uint32_t tdls_uapsd_mask; uint32_t tdls_uapsd_inactivity_time; @@ -449,6 +457,14 @@ struct tdls_user_config { uint32_t delayed_trig_framint; uint8_t tdls_vdev_nss_2g; uint8_t tdls_vdev_nss_5g; + bool tdls_buffer_sta_enable; + bool tdls_off_chan_enable; + bool tdls_wmm_mode_enable; + bool tdls_external_control; + bool tdls_implicit_trigger_enable; + bool tdls_scan_enable; + bool tdls_sleep_sta_enable; + bool tdls_support_enable; }; /** diff --git a/dispatcher/src/wlan_tdls_cfg.c b/dispatcher/src/wlan_tdls_cfg.c new file mode 100644 index 000000000000..b9ff89221213 --- /dev/null +++ b/dispatcher/src/wlan_tdls_cfg.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 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 + * 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: This file contains TDLS configures interface definitions + */ + +#include +#include "wlan_tdls_cfg_api.h" +#include "../../core/src/wlan_tdls_main.h" + +QDF_STATUS +cfg_tdls_get_support_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_support_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_support_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_support_enable = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_external_control(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_external_control; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_uapsd_mask(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = 0; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_uapsd_mask; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_buffer_sta_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_buffer_sta_enable = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_uapsd_inactivity_time(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = 0; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_uapsd_inactivity_time; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_rx_pkt_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = 0; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_rx_pkt_threshold; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_off_chan_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_off_chan_enable = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_wmm_mode_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_wmm_mode_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_vdev_nss_2g(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_vdev_nss_2g = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_vdev_nss_5g(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_vdev_nss_5g = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_sleep_sta_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_sleep_sta_enable = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_scan_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_scan_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_scan_enable = val; + + return QDF_STATUS_SUCCESS; +} diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index a477ac60ef67..009d8e6ab192 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -32,6 +32,8 @@ #include #include "wlan_policy_mgr_api.h" #include "wlan_scan_ucfg_api.h" +#include "wlan_tdls_cfg.h" +#include "cfg_ucfg_api.h" QDF_STATUS ucfg_tdls_init(void) { @@ -116,11 +118,104 @@ QDF_STATUS ucfg_tdls_deinit(void) return ret; } +/** + * tdls_object_init_params() - init parameters for tdls object + * @tdls_soc_obj: pointer to tdls psoc object + * + * This function init parameters for tdls object + */ +static QDF_STATUS tdls_object_init_params( + struct tdls_soc_priv_obj *tdls_soc_obj) +{ + struct wlan_objmgr_psoc *psoc; + + if (!tdls_soc_obj) { + tdls_err("invalid param"); + return QDF_STATUS_E_INVAL; + } + + psoc = tdls_soc_obj->soc; + if (!psoc) { + tdls_err("invalid psoc object"); + return QDF_STATUS_E_INVAL; + } + + tdls_soc_obj->tdls_configs.tdls_tx_states_period = + cfg_get(psoc, CFG_TDLS_TX_STATS_PERIOD); + tdls_soc_obj->tdls_configs.tdls_tx_pkt_threshold = + cfg_get(psoc, CFG_TDLS_TX_PACKET_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold = + cfg_get(psoc, CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_max_discovery_attempt = + cfg_get(psoc, CFG_TDLS_MAX_DISCOVERY_ATTEMPT); + tdls_soc_obj->tdls_configs.tdls_idle_timeout = + cfg_get(psoc, CFG_TDLS_IDLE_TIMEOUT); + tdls_soc_obj->tdls_configs.tdls_idle_pkt_threshold = + cfg_get(psoc, CFG_TDLS_IDLE_PACKET_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_rssi_trigger_threshold = + cfg_get(psoc, CFG_TDLS_RSSI_TRIGGER_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_rssi_teardown_threshold = + cfg_get(psoc, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_rssi_delta = + cfg_get(psoc, CFG_TDLS_RSSI_DELTA); + tdls_soc_obj->tdls_configs.tdls_uapsd_mask = + cfg_get(psoc, CFG_TDLS_QOS_WMM_UAPSD_MASK); + tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time = + cfg_get(psoc, CFG_TDLS_PUAPSD_INACT_TIME); + tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window = + cfg_get(psoc, CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW); + tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout = + cfg_get(psoc, CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT); + tdls_soc_obj->tdls_configs.tdls_pre_off_chan_num = + cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM); + tdls_soc_obj->tdls_configs.tdls_pre_off_chan_bw = + cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_BW); + tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold = + cfg_get(psoc, CFG_TDLS_PEER_KICKOUT_THRESHOLD); + tdls_soc_obj->tdls_configs.delayed_trig_framint = + cfg_get(psoc, CFG_TDLS_DELAYED_TRGR_FRM_INT); + tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable = + cfg_get(psoc, CFG_TDLS_WMM_MODE_ENABLE); + tdls_soc_obj->tdls_configs.tdls_off_chan_enable = + cfg_get(psoc, CFG_TDLS_OFF_CHANNEL_ENABLED); + tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable = + cfg_get(psoc, CFG_TDLS_BUF_STA_ENABLED); + tdls_soc_obj->tdls_configs.tdls_scan_enable = + cfg_get(psoc, CFG_TDLS_SCAN_ENABLE); + tdls_soc_obj->tdls_configs.tdls_support_enable = + cfg_get(psoc, CFG_TDLS_SUPPORT_ENABLE); + tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable = + cfg_get(psoc, CFG_TDLS_IMPLICIT_TRIGGER); + tdls_soc_obj->tdls_configs.tdls_external_control = + cfg_get(psoc, CFG_TDLS_EXTERNAL_CONTROL); + + tdls_soc_obj->tdls_configs.tdls_feature_flags = + ((tdls_soc_obj->tdls_configs.tdls_off_chan_enable ? + 1 << TDLS_FEATURE_OFF_CHANNEL : 0) | + (tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable ? + 1 << TDLS_FEATURE_WMM : 0) | + (tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable ? + 1 << TDLS_FEATURE_BUFFER_STA : 0) | + (tdls_soc_obj->tdls_configs.tdls_sleep_sta_enable ? + 1 << TDLS_FEATURE_SLEEP_STA : 0) | + (tdls_soc_obj->tdls_configs.tdls_scan_enable ? + 1 << TDLS_FEATURE_SCAN : 0) | + (tdls_soc_obj->tdls_configs.tdls_support_enable ? + 1 << TDLS_FEATURE_ENABLE : 0) | + (tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable ? + 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) | + (tdls_soc_obj->tdls_configs.tdls_external_control ? + 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0)); + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) { uint8_t sta_idx; uint32_t feature; + tdls_object_init_params(soc_obj); soc_obj->connected_peer_count = 0; soc_obj->tdls_nss_switch_in_progress = false; soc_obj->tdls_teardown_peers_cnt = 0; @@ -228,8 +323,6 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - /* Update TDLS user config */ - qdf_mem_copy(&soc_obj->tdls_configs, &req->config, sizeof(req->config)); tdls_feature_flags = soc_obj->tdls_configs.tdls_feature_flags; if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) From 369792eea1f61fae883baf3ce573497c988eec2f Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 23 Jul 2018 19:26:32 +0800 Subject: [PATCH 304/404] qcacmn: Define the APIs to cleanup roc and tx action by vdev or psoc Define the APIs to cleanup roc and tx action by vdev or psoc in p2p component, and remove cleanup task in p2p suspend handler since scheduler thread in suspend state already. Change-Id: I4e67e99569f62ee62715dcf7e4c45f136c6f1719 CRs-Fixed: 2283301 --- core/src/wlan_p2p_main.c | 133 ----------------------------- dispatcher/inc/wlan_p2p_ucfg_api.h | 36 +++++++- dispatcher/src/wlan_p2p_ucfg_api.c | 63 +++++++++++++- 3 files changed, 95 insertions(+), 137 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 2cf7a040914e..7263fd3a2349 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -36,10 +36,6 @@ #include "wlan_p2p_cfg.h" #include "cfg_ucfg_api.h" -#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD -#include -#endif - /** * p2p_get_cmd_type_str() - parse cmd to string * @cmd_type: P2P cmd type @@ -571,133 +567,6 @@ static void wlan_p2p_init_connection_status( } #endif /* WLAN_FEATURE_P2P_DEBUG */ -#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD - -/** - * p2p_suspend_handler() - suspend handler of P2P - * @psoc: pointer to psoc object - * @arg: pointer to input argument - * - * This function is suspend handler of P2P component. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -static QDF_STATUS p2p_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg) -{ - struct p2p_soc_priv_obj *p2p_soc_obj; - - if (!psoc) { - p2p_err("psoc context passed is NULL"); - return QDF_STATUS_E_INVAL; - } - - p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, - WLAN_UMAC_COMP_P2P); - if (!p2p_soc_obj) { - p2p_err("P2P soc object is NULL"); - return QDF_STATUS_E_FAILURE; - } - - /* clean up queue of p2p psoc private object */ - p2p_cleanup_tx_sync(p2p_soc_obj, NULL); - p2p_cleanup_roc_sync(p2p_soc_obj, NULL); - - p2p_debug("handle suspend complete"); - - return QDF_STATUS_SUCCESS; -} - -/** - * p2p_resume_handler() - resume handler of P2P - * @psoc: pointer to psoc object - * @arg: pointer to input argument - * - * This function is resume handler of P2P component. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -static QDF_STATUS p2p_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg) -{ - p2p_debug("handle resume complete"); - - return QDF_STATUS_SUCCESS; -} - -/** - * p2p_register_pmo_handler() - register pmo handler - * - * This function registers pmo handler of P2P component. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -static inline QDF_STATUS p2p_register_pmo_handler(void) -{ - QDF_STATUS status; - - status = pmo_register_suspend_handler(WLAN_UMAC_COMP_P2P, - p2p_suspend_handler, NULL); - if (status != QDF_STATUS_SUCCESS) { - p2p_err("Failed to register suspend handler"); - return status; - } - - status = pmo_register_resume_handler(WLAN_UMAC_COMP_P2P, - p2p_resume_handler, NULL); - if (status != QDF_STATUS_SUCCESS) { - p2p_err("Failed to register resume handler"); - pmo_unregister_suspend_handler(WLAN_UMAC_COMP_P2P, - p2p_suspend_handler); - return status; - } - - p2p_debug("Register pmo handler success"); - - return status; -} - -/** - * p2p_unregister_pmo_handler() - unregister pmo handler - * - * This function unregisters pmo handler of P2P component. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -static inline QDF_STATUS p2p_unregister_pmo_handler(void) -{ - QDF_STATUS status; - QDF_STATUS ret_status = QDF_STATUS_SUCCESS; - - status = pmo_unregister_suspend_handler(WLAN_UMAC_COMP_P2P, - p2p_suspend_handler); - if (status != QDF_STATUS_SUCCESS) { - p2p_err("Failed to unregister suspend handler"); - ret_status = status; - } - - status = pmo_unregister_resume_handler(WLAN_UMAC_COMP_P2P, - p2p_resume_handler); - if (status != QDF_STATUS_SUCCESS) { - p2p_err("Failed to unregister resume handler"); - ret_status = status; - } - - p2p_debug("Unregister pmo handler complete"); - - return status; -} - -#else -static inline QDF_STATUS p2p_register_pmo_handler(void) -{ - return QDF_STATUS_SUCCESS; -} - -static inline QDF_STATUS p2p_unregister_pmo_handler(void) -{ - return QDF_STATUS_SUCCESS; -} -#endif /* End of WLAN_POWER_MANAGEMENT_OFFLOAD */ - QDF_STATUS p2p_component_init(void) { QDF_STATUS status; @@ -871,7 +740,6 @@ QDF_STATUS p2p_psoc_object_open(struct wlan_objmgr_psoc *soc) qdf_runtime_lock_init(&p2p_soc_obj->roc_runtime_lock); p2p_soc_obj->cur_roc_vdev_id = P2P_INVALID_VDEV_ID; qdf_idr_create(&p2p_soc_obj->p2p_idr); - p2p_register_pmo_handler(); p2p_debug("p2p psoc object open successful"); @@ -907,7 +775,6 @@ QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) return QDF_STATUS_E_FAILURE; } - p2p_unregister_pmo_handler(); qdf_idr_destroy(&p2p_soc_obj->p2p_idr); qdf_runtime_lock_deinit(&p2p_soc_obj->roc_runtime_lock); qdf_event_destroy(&p2p_soc_obj->cleanup_tx_done); diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/dispatcher/inc/wlan_p2p_ucfg_api.h index 7ef8974a7993..25f0d532c876 100644 --- a/dispatcher/inc/wlan_p2p_ucfg_api.h +++ b/dispatcher/inc/wlan_p2p_ucfg_api.h @@ -200,14 +200,44 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, uint64_t cookie); /** - * ucfg_p2p_cleanup_roc() - Cleanup roc request by vdev + * ucfg_p2p_cleanup_roc_by_vdev() - Cleanup roc request by vdev * @vdev: pointer to vdev object * - * This function call P2P API to cleanup roc request by vdev. + * This function call P2P API to cleanup roc request by vdev * * Return: QDF_STATUS_SUCCESS - in case of success */ -QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev); +QDF_STATUS ucfg_p2p_cleanup_roc_by_vdev(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_p2p_cleanup_roc_by_poc() - Cleanup roc request by psoc + * @psoc: pointer to psoc object + * + * This function call P2P API to cleanup roc request by psoc + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_cleanup_roc_by_psoc(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_p2p_cleanup_tx_by_vdev() - Cleanup tx request by vdev + * @vdev: pointer to vdev object + * + * This function call P2P API to cleanup tx action frame request by vdev + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_cleanup_tx_by_vdev(struct wlan_objmgr_vdev *vdev); + +/** + * ucfg_p2p_cleanup_tx_by_poc() - Cleanup tx request by psoc + * @psoc: pointer to psoc object + * + * This function call P2P API to cleanup tx action frame request by psoc + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS ucfg_p2p_cleanup_tx_by_psoc(struct wlan_objmgr_psoc *psoc); /** * ucfg_p2p_mgmt_tx() - Mgmt frame tx request diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index efa74baba9de..9581cfa89f95 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -209,7 +209,7 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, return QDF_STATUS_SUCCESS; } -QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev) +QDF_STATUS ucfg_p2p_cleanup_roc_by_vdev(struct wlan_objmgr_vdev *vdev) { struct p2p_soc_priv_obj *p2p_soc_obj; struct wlan_objmgr_psoc *psoc; @@ -237,6 +237,67 @@ QDF_STATUS ucfg_p2p_cleanup_roc(struct wlan_objmgr_vdev *vdev) return p2p_cleanup_roc_sync(p2p_soc_obj, vdev); } +QDF_STATUS ucfg_p2p_cleanup_roc_by_psoc(struct wlan_objmgr_psoc *psoc) +{ + struct p2p_soc_priv_obj *obj; + + if (!psoc) { + p2p_err("null psoc"); + return QDF_STATUS_E_INVAL; + } + + obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_P2P); + if (!obj) { + p2p_err("null p2p soc obj"); + return QDF_STATUS_E_FAILURE; + } + + return p2p_cleanup_roc_sync(obj, NULL); +} + +QDF_STATUS ucfg_p2p_cleanup_tx_by_vdev(struct wlan_objmgr_vdev *vdev) +{ + struct p2p_soc_priv_obj *obj; + struct wlan_objmgr_psoc *psoc; + + if (!vdev) { + p2p_err("null vdev"); + return QDF_STATUS_E_INVAL; + } + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) { + p2p_err("null psoc"); + return QDF_STATUS_E_INVAL; + } + + obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_P2P); + if (!obj) { + p2p_err("null p2p soc obj"); + return QDF_STATUS_E_FAILURE; + } + + return p2p_cleanup_tx_sync(obj, vdev); +} + +QDF_STATUS ucfg_p2p_cleanup_tx_by_psoc(struct wlan_objmgr_psoc *psoc) +{ + struct p2p_soc_priv_obj *obj; + + if (!psoc) { + p2p_err("null psoc"); + return QDF_STATUS_E_INVAL; + } + + obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_P2P); + if (!obj) { + p2p_err("null p2p soc obj"); + return QDF_STATUS_E_FAILURE; + } + + return p2p_cleanup_tx_sync(obj, NULL); +} + QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, struct p2p_mgmt_tx *mgmt_frm, uint64_t *cookie) { From 0351f170cd96ace2062c16109ac312386ad734ac Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 31 Jul 2018 12:24:57 -0700 Subject: [PATCH 305/404] qcacmn: Do not invoke get_pcl multiple times during set_pcl to FW Do not invoke get_pcl when calculating weightage of channels sent to FW as part of set_pcl WMI command. Change-Id: I62b39aaf0943cf10deab380d8030d1ef08fbbcb3 CRs-Fixed: 2287649 --- inc/wlan_policy_mgr_api.h | 2 +- src/wlan_policy_mgr_core.c | 8 +++--- src/wlan_policy_mgr_get_set_utils.c | 38 +++++++++++++++++------------ src/wlan_policy_mgr_i.h | 20 +++++++++++++++ src/wlan_policy_mgr_pcl.c | 8 +++--- 5 files changed, 53 insertions(+), 23 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 2fa1cd616205..d0e6ee9e7e62 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -379,7 +379,7 @@ bool policy_mgr_is_any_dfs_beaconing_session_present( /** * policy_mgr_allow_concurrency() - Check for allowed concurrency - * combination + * combination consulting the PCL * @psoc: PSOC object information * @mode: new connection mode * @channel: channel on which new connection is coming up diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 7882bf29ecb9..7bd923ed00c9 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2264,9 +2264,11 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("pcl len (%d) and weight list len mismatch (%d)", *len, i); - /* check the channel avoidance list */ - policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, len, - pcl_weights, weight_len); + /* check the channel avoidance list for beaconing entities */ + if ((mode == PM_SAP_MODE) || (mode == PM_P2P_GO_MODE)) + policy_mgr_update_with_safe_channel_list(psoc, pcl_channels, + len, pcl_weights, + weight_len); policy_mgr_set_weight_of_dfs_passive_channels_to_zero(psoc, pcl_channels, len, pcl_weights, weight_len); diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index d81e6d17a775..816f3c6a38b9 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1544,16 +1544,15 @@ static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc) return pm_ctx->user_cfg.sub_20_mhz_enabled; } -bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, - enum policy_mgr_con_mode mode, - uint8_t channel, enum hw_mode_bandwidth bw) +bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, + enum hw_mode_bandwidth bw) { uint32_t num_connections = 0, count = 0, index = 0; bool status = false, match = false; uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS]; struct policy_mgr_psoc_priv_obj *pm_ctx; - QDF_STATUS ret; - struct policy_mgr_pcl_list pcl; bool sta_sap_scc_on_dfs_chan; pm_ctx = policy_mgr_get_context(psoc); @@ -1561,16 +1560,6 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, policy_mgr_err("Invalid Context"); return status; } - - - qdf_mem_zero(&pcl, sizeof(pcl)); - ret = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len, - pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); - if (QDF_IS_STATUS_ERROR(ret)) { - policy_mgr_err("disallow connection:%d", ret); - goto done; - } - /* find the current connection state from pm_conc_connection_list*/ num_connections = policy_mgr_get_connection_count(psoc); @@ -1748,6 +1737,25 @@ done: return status; } +bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, enum hw_mode_bandwidth bw) +{ + QDF_STATUS status; + struct policy_mgr_pcl_list pcl; + + qdf_mem_zero(&pcl, sizeof(pcl)); + status = policy_mgr_get_pcl(psoc, mode, pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, + QDF_ARRAY_SIZE(pcl.weight_list)); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("disallow connection:%d", status); + return false; + } + + return policy_mgr_is_concurrency_allowed(psoc, mode, channel, bw); +} + /** * policy_mgr_get_concurrency_mode() - return concurrency mode * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 15c9d9b92b61..73d54904b6e9 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -474,4 +474,24 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, uint8_t new_nss, uint8_t next_action, enum policy_mgr_band band, enum policy_mgr_conn_update_reason reason); + +/** + * policy_mgr_is_concurrency_allowed() - Check for allowed + * concurrency combination + * @psoc: PSOC object information + * @mode: new connection mode + * @channel: channel on which new connection is coming up + * @bw: Bandwidth requested by the connection (optional) + * + * When a new connection is about to come up check if current + * concurrency combination including the new connection is + * allowed or not based on the HW capability, but no need to + * invoke get_pcl + * + * Return: True/False + */ +bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, + enum hw_mode_bandwidth bw); #endif diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 5303ee8092d1..1a4c8f4c5200 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -222,7 +222,7 @@ void policy_mgr_update_with_safe_channel_list(struct wlan_objmgr_psoc *psoc, pm_ctx->unsafe_channel_list[j]) { /* Found unsafe channel, update it */ is_unsafe = 1; - policy_mgr_warn("CH %d is not safe", + policy_mgr_debug("CH %d is not safe", current_channel_list[i]); break; } @@ -1646,9 +1646,9 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc, * below! */ for (i = 0; i < weight->saved_num_chan; i++) { - if (policy_mgr_allow_concurrency(psoc, PM_STA_MODE, - weight->saved_chan_list[i], - HW_MODE_20_MHZ)) { + if (policy_mgr_is_concurrency_allowed + (psoc, PM_STA_MODE, weight->saved_chan_list[i], + HW_MODE_20_MHZ)) { weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS; } From 95bec5aa1989e65e1e7a89a5773db6d791008ebc Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 22 Jul 2018 14:53:30 -0700 Subject: [PATCH 306/404] qcacmn: Remove struct extended_caps struct extended_caps is unused, so remove it. Change-Id: I96fd072b7d6b58a9c237165fcba7ed8c8da0eae3 CRs-Fixed: 2289156 --- inc/wlan_policy_mgr_public_struct.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 448f7b0532da..5cce4910d47f 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -994,23 +994,6 @@ struct dbs_hw_mode_info { uint32_t *hw_mode_list; }; -/** - * struct extended_caps - new extended caps given by firmware - * @num_hw_modes: number of hardware modes for current SOC - * @each_hw_mode_cap: hw mode id to phy id mapping - * @each_phy_cap_per_hwmode: PHY's caps for each hw mode - * @num_phy_for_hal_reg_cap: number of phy for hal reg cap - * @hw_mode_to_mac_cap_map: map between hw_mode to capabilities - */ -struct extended_caps { - WMI_SOC_MAC_PHY_HW_MODE_CAPS num_hw_modes; - WMI_HW_MODE_CAPABILITIES *each_hw_mode_cap; - WMI_MAC_PHY_CAPABILITIES *each_phy_cap_per_hwmode; - WMI_SOC_HAL_REG_CAPABILITIES num_phy_for_hal_reg_cap; - WMI_HAL_REG_CAPABILITIES_EXT *each_phy_hal_reg_cap; - struct hw_mode_idx_to_mac_cap_idx *hw_mode_to_mac_cap_map; -}; - /** * struct dual_mac_config - Dual MAC configurations * @prev_scan_config: Previous scan configuration From 2b083b6daa9c9a6c12ff2befa35e3401cd68bf9c Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Mon, 6 Aug 2018 13:39:23 -0700 Subject: [PATCH 307/404] qcacmn: Add ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN Add ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN option for the ini gDualMacFeatureDisable. This is to enable DBS support for the connection and disable simultaneous scan from upper layer. But DBS scan remains enabled in FW. Change-Id: Ic280de2cc63a3775c0d9dd61985ff89df58a4a89 CRs-Fixed: 2291935 --- inc/wlan_policy_mgr_public_struct.h | 6 +++++- src/wlan_policy_mgr_get_set_utils.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 5cce4910d47f..ea748b230b35 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -835,6 +835,9 @@ enum policy_mgr_hw_mode_change { * connection and scan but switch off the async scan * @ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN: Enable DBS support for connection and * disable DBS support for scan + * @ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN: Enable DBS + * support for connection and disable simultaneous scan from + * upper layer (DBS scan remains enabled in FW) */ enum dbs_support { ENABLE_DBS_CXN_AND_SCAN, @@ -842,7 +845,8 @@ enum dbs_support { DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN, DISABLE_DBS_CXN_AND_ENABLE_DBS_SCAN_WITH_ASYNC_SCAN_OFF, ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF, - ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN + ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN, + ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN, }; /** diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 816f3c6a38b9..41d961f120ab 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2740,6 +2740,8 @@ bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc) if ((DISABLE_DBS_CXN_AND_SCAN == wlan_objmgr_psoc_get_dual_mac_disable(psoc)) || (ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN == + wlan_objmgr_psoc_get_dual_mac_disable(psoc)) || + (ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN == wlan_objmgr_psoc_get_dual_mac_disable(psoc))) return false; From d6dbd79a8ad6e52acc8e59d44e5c3eeaace70266 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 6 Aug 2018 10:29:10 +0800 Subject: [PATCH 308/404] qcacmn: Update TDLS feature flag when hanling FW ready event It doesn't update TDLS feature flag when handling FW ready event, and cause feature mismatch between FW and host. So update TDLS feature feature flag when updating tdls configures. Change-Id: Ib5978063581cac0f4c0ebc90f8981a5b68aed1da CRs-Fixed: 2291311 --- dispatcher/src/wlan_tdls_ucfg_api.c | 47 ++++++++++++++++++----------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 009d8e6ab192..8930e0295272 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -118,6 +118,34 @@ QDF_STATUS ucfg_tdls_deinit(void) return ret; } +/** + * tdls_update_feature_flag() - update tdls feature flag + * @tdls_soc_obj: pointer to tdls psoc object + * + * This function updates tdls feature flag + */ +static void +tdls_update_feature_flag(struct tdls_soc_priv_obj *tdls_soc_obj) +{ + tdls_soc_obj->tdls_configs.tdls_feature_flags = + ((tdls_soc_obj->tdls_configs.tdls_off_chan_enable ? + 1 << TDLS_FEATURE_OFF_CHANNEL : 0) | + (tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable ? + 1 << TDLS_FEATURE_WMM : 0) | + (tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable ? + 1 << TDLS_FEATURE_BUFFER_STA : 0) | + (tdls_soc_obj->tdls_configs.tdls_sleep_sta_enable ? + 1 << TDLS_FEATURE_SLEEP_STA : 0) | + (tdls_soc_obj->tdls_configs.tdls_scan_enable ? + 1 << TDLS_FEATURE_SCAN : 0) | + (tdls_soc_obj->tdls_configs.tdls_support_enable ? + 1 << TDLS_FEATURE_ENABLE : 0) | + (tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable ? + 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) | + (tdls_soc_obj->tdls_configs.tdls_external_control ? + 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0)); +} + /** * tdls_object_init_params() - init parameters for tdls object * @tdls_soc_obj: pointer to tdls psoc object @@ -189,23 +217,7 @@ static QDF_STATUS tdls_object_init_params( tdls_soc_obj->tdls_configs.tdls_external_control = cfg_get(psoc, CFG_TDLS_EXTERNAL_CONTROL); - tdls_soc_obj->tdls_configs.tdls_feature_flags = - ((tdls_soc_obj->tdls_configs.tdls_off_chan_enable ? - 1 << TDLS_FEATURE_OFF_CHANNEL : 0) | - (tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable ? - 1 << TDLS_FEATURE_WMM : 0) | - (tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable ? - 1 << TDLS_FEATURE_BUFFER_STA : 0) | - (tdls_soc_obj->tdls_configs.tdls_sleep_sta_enable ? - 1 << TDLS_FEATURE_SLEEP_STA : 0) | - (tdls_soc_obj->tdls_configs.tdls_scan_enable ? - 1 << TDLS_FEATURE_SCAN : 0) | - (tdls_soc_obj->tdls_configs.tdls_support_enable ? - 1 << TDLS_FEATURE_ENABLE : 0) | - (tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable ? - 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) | - (tdls_soc_obj->tdls_configs.tdls_external_control ? - 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0)); + tdls_update_feature_flag(tdls_soc_obj); return QDF_STATUS_SUCCESS; } @@ -323,6 +335,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + tdls_update_feature_flag(soc_obj); tdls_feature_flags = soc_obj->tdls_configs.tdls_feature_flags; if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) From c304f8924df156919e076401d892ce0c0a0c1bfb Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 1 Aug 2018 19:15:55 -0700 Subject: [PATCH 309/404] qcacmn: Do HW mode change based on all the candidate APs for STA The driver currently changes the hw_mode based upon the first candidate found in the scan list, and tries to connect to it. It may happen that the connection fails, and the STA then tries to connect to the AP on same channel as the concurrent adapter. It would result in hw_mode = DBS, as it is not updated after connection success/failure. Also if the first AP channel is in same band as that of concurrent adapter, and the connection fails, and the STA tries to connect to an AP in a different band, this too is not allowed as hw_mode is not DBS Fix is to change the hw_mode based upon the scan list. If the driver finds any scan result which may lead to DBS connection, the hw_mode should be set to DBS. Once the connection is done or failed, the driver can check and update the hw_mode again. Change-Id: I3c186f47dd5528f0af2598bb02c1b7e297d01548 CRs-Fixed: 2290760 --- inc/wlan_policy_mgr_api.h | 12 ++++++++++++ src/wlan_policy_mgr_action.c | 34 +++++++++++++++++++++++++++++++++- src/wlan_policy_mgr_pcl.c | 11 +---------- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index d0e6ee9e7e62..f9d38dc4c9b6 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -704,6 +704,18 @@ enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm( enum policy_mgr_con_mode device_mode); +/** + * policy_mgr_check_n_start_opportunistic_timer - check single mac upgrade + * needed or not, if needed start the oppurtunistic timer. + * @psoc: pointer to SOC + * + * This function starts the oppurtunistic timer if hw_mode change is needed + * + * Return: QDF_STATUS + */ +QDF_STATUS policy_mgr_check_n_start_opportunistic_timer( + struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_pdev_set_hw_mode() - Set HW mode command to FW * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 2d9cab406595..061a068e6eb0 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -93,6 +93,29 @@ void policy_mgr_hw_mode_transition_cb(uint32_t old_hw_mode_index, return; } +QDF_STATUS policy_mgr_check_n_start_opportunistic_timer( + struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start"); + return QDF_STATUS_E_FAILURE; + } + if (policy_mgr_need_opportunistic_upgrade(psoc)) { + /* let's start the timer */ + qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); + status = qdf_mc_timer_start( + &pm_ctx->dbs_opportunistic_timer, + DBS_OPPORTUNISTIC_TIME * 1000); + if (!QDF_IS_STATUS_SUCCESS(status)) + policy_mgr_err("Failed to start dbs opportunistic timer"); + } + return status; +} + QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, uint32_t session_id, enum hw_mode_ss_config mac0_ss, @@ -1458,13 +1481,22 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { - if (pm_conc_connection_list[i].in_use) + if (pm_conc_connection_list[i].in_use) { if (!WLAN_REG_IS_SAME_BAND_CHANNELS(channel, pm_conc_connection_list[i].chan)) { qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); policy_mgr_debug("DBS required"); return; } + if (policy_mgr_is_hw_dbs_2x2_capable(psoc) && + (WLAN_REG_IS_24GHZ_CH(channel) || + WLAN_REG_IS_24GHZ_CH + (pm_conc_connection_list[i].chan))) { + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + policy_mgr_debug("DBS required"); + return; + } + } } qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); pm_dbs_opportunistic_timer_handler((void *)psoc); diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 1a4c8f4c5200..e41025045d5d 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -130,16 +130,7 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, */ policy_mgr_set_pcl_for_existing_combo(psoc, PM_STA_MODE); /* do we need to change the HW mode */ - if (policy_mgr_need_opportunistic_upgrade(psoc)) { - /* let's start the timer */ - qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); - qdf_status = qdf_mc_timer_start( - &pm_ctx->dbs_opportunistic_timer, - DBS_OPPORTUNISTIC_TIME * 1000); - if (!QDF_IS_STATUS_SUCCESS(qdf_status)) - policy_mgr_err("Failed to start dbs opportunistic timer"); - } - + policy_mgr_check_n_start_opportunistic_timer(psoc); return; } From 1a18faf9e8faa5ee290877c96fed276892ec3540 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Mon, 16 Jul 2018 06:39:29 -0400 Subject: [PATCH 310/404] qcacmn: Limit concurrency of STA(WAPI) When STA role is coexisting with other sessions(P2P, SAP or IBSS), WAPI encryption mode is not allowed. Add a new API to check if the connection/start request should be rejected when: 1) A STA with WAPI encryption is to be connected while there is at least one concurrent session already running. 2) A new session is to be started while there is already a STA connection with WAPI encryption enabled. Change-Id: Idf0d346138eeda339254535f1f7131fda4a5086a CRs-Fixed: 2290549 --- inc/wlan_policy_mgr_api.h | 5 +++++ src/wlan_policy_mgr_get_set_utils.c | 28 ++++++++++++++++++++++++++++ src/wlan_policy_mgr_init_deinit.c | 2 ++ 3 files changed, 35 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index f9d38dc4c9b6..7dc6d12ba209 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -871,6 +871,10 @@ struct policy_mgr_sme_cbacks { * SAP * @get_mode_for_non_connected_vdev: Get the mode for a non * connected vdev + * @hdd_get_device_mode: Get QDF_OPMODE type for session id (vdev id) + * @hdd_wapi_security_sta_exist: Get whether wapi encription station existing + * or not. Some hw doesn't support WAPI encryption concurrency with other + * encryption type. */ struct policy_mgr_hdd_cbacks { void (*sap_restart_chan_switch_cb)(struct wlan_objmgr_psoc *psoc, @@ -885,6 +889,7 @@ struct policy_mgr_hdd_cbacks { struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); enum QDF_OPMODE (*hdd_get_device_mode)(uint32_t session_id); + bool (*hdd_wapi_security_sta_exist)(void); }; diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 41d961f120ab..9079e721b02a 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1544,6 +1544,29 @@ static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc) return pm_ctx->user_cfg.sub_20_mhz_enabled; } +/** + * policy_mgr_check_privacy_for_new_conn() - Check privacy mode concurrency + * @pm_ctx: policy_mgr_psoc_priv_obj policy mgr context + * + * This routine is called to check vdev security mode allowed in concurrency. + * At present, WAPI security mode is not allowed to run concurrency with any + * other vdev. + * + * Return: true - allow + */ +static bool policy_mgr_check_privacy_for_new_conn( + struct policy_mgr_psoc_priv_obj *pm_ctx) +{ + if (!pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist) + return true; + + if (pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist() && + (policy_mgr_get_connection_count(pm_ctx->psoc) > 0)) + return false; + + return true; +} + bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t channel, @@ -1731,6 +1754,11 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); } + if (!policy_mgr_check_privacy_for_new_conn(pm_ctx)) { + policy_mgr_err("Don't allow new conn when wapi security conn existing"); + goto done; + } + status = true; done: diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 83528a963e27..322de079032d 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -581,6 +581,8 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc, hdd_cbacks->get_mode_for_non_connected_vdev; pm_ctx->hdd_cbacks.hdd_get_device_mode = hdd_cbacks->hdd_get_device_mode; + pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist = + hdd_cbacks->hdd_wapi_security_sta_exist; return QDF_STATUS_SUCCESS; } From 24fd8a10e9fe7ad34f95ed939a61feb5cf71b866 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Tue, 24 Jul 2018 16:33:11 +0530 Subject: [PATCH 311/404] qcacmn: umac: Add logging macros without function/line info Add per module logging macros without function/line info to avoid adding function/line info where it is not required. Change-Id: I34ba6f6485f9b506264daf4e116052d2858bed40 CRs-Fixed: 2278876 --- core/src/wlan_p2p_main.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 1e57b2e17213..5a313abfd51b 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -46,6 +46,17 @@ #define p2p_alert(params ...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_P2P, params) +#define p2p_nofl_debug(params ...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_P2P, params) +#define p2p_nofl_info(params ...) \ + QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_P2P, params) +#define p2p_nofl_warn(params ...) \ + QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_P2P, params) +#define p2p_nofl_err(params ...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_P2P, params) +#define p2p_nofl_alert(params ...) \ + QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_P2P, params) + struct scheduler_msg; struct p2p_tx_cnf; struct p2p_rx_mgmt_frame; From e173492a225045930f710b5668248b366baad75b Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Tue, 24 Jul 2018 16:33:11 +0530 Subject: [PATCH 312/404] qcacmn: umac: Add logging macros without function/line info Add per module logging macros without function/line info to avoid adding function/line info where it is not required. Change-Id: I34ba6f6485f9b506264daf4e116052d2858bed40 CRs-Fixed: 2278876 --- core/src/wlan_tdls_main.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 5c6591424b4a..753866ed07cb 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -68,6 +68,17 @@ #define tdls_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_debug(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_notice(params...) \ + QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_warn(params...) \ + QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_err(params...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_alert(params...) \ + QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_TDLS, params) + #define TDLS_IS_LINK_CONNECTED(peer) \ ((TDLS_LINK_CONNECTED == (peer)->link_status) || \ (TDLS_LINK_TEARING == (peer)->link_status)) From 18de9c1b54b359702d9775e24fa9fff21313f843 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Tue, 24 Jul 2018 16:33:11 +0530 Subject: [PATCH 313/404] qcacmn: umac: Add logging macros without function/line info Add per module logging macros without function/line info to avoid adding function/line info where it is not required. Change-Id: I34ba6f6485f9b506264daf4e116052d2858bed40 CRs-Fixed: 2278876 --- src/wlan_policy_mgr_i.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 73d54904b6e9..cf6ac6d943af 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -166,6 +166,17 @@ #define policy_mgr_debug(params...) \ QDF_TRACE_DEBUG(QDF_MODULE_ID_POLICY_MGR, params) +#define policymgr_nofl_alert(params...) \ + QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_POLICY_MGR, params) +#define policymgr_nofl_err(params...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_POLICY_MGR, params) +#define policymgr_nofl_warn(params...) \ + QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_POLICY_MGR, params) +#define policymgr_nofl_info(params...) \ + QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_POLICY_MGR, params) +#define policymgr_nofl_debug(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_POLICY_MGR, params) + #define PM_CONC_CONNECTION_LIST_VALID_INDEX(index) \ ((MAX_NUMBER_OF_CONC_CONNECTIONS > index) && \ (pm_conc_connection_list[index].in_use)) From 2b1d323609637757035eb4e2973678272752d003 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 13 Aug 2018 10:54:28 +0800 Subject: [PATCH 314/404] qcacmn: Check and then remove tx context from queue It will remove the tx context firstly and then check whether need to be deleted, which cause tx context memory leak. So, check the tx context firstly, and then remove the tx context if need. Change-Id: Icfe72318ccdd580002d269ffa8082b7f5fa4a341 CRs-Fixed: 2291867 --- core/src/wlan_p2p_off_chan_tx.c | 44 +++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 6f02665f1a29..a03fe0127983 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1704,6 +1704,7 @@ QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param) qdf_list_node_t *p_node; struct p2p_soc_priv_obj *p2p_soc_obj; uint32_t vdev_id; + QDF_STATUS status, ret; if (!param || !(param->p2p_soc_obj)) { p2p_err("Invalid cleanup param"); @@ -1713,34 +1714,51 @@ QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param) p2p_soc_obj = param->p2p_soc_obj; vdev_id = param->vdev_id; - p2p_debug("clean up tx queue wait for roc, size:%d", - qdf_list_size(&p2p_soc_obj->tx_q_roc)); + p2p_debug("clean up tx queue wait for roc, size:%d, vdev_id:%d", + qdf_list_size(&p2p_soc_obj->tx_q_roc), vdev_id); - while (qdf_list_remove_front(&p2p_soc_obj->tx_q_roc, &p_node) == - QDF_STATUS_SUCCESS) { + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_roc, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { curr_tx_ctx = qdf_container_of(p_node, struct tx_action_context, node); if ((vdev_id == P2P_INVALID_VDEV_ID) || (vdev_id == curr_tx_ctx->vdev_id)) { - p2p_send_tx_conf(curr_tx_ctx, false); - qdf_mem_free(curr_tx_ctx->buf); - qdf_mem_free(curr_tx_ctx); + ret = qdf_list_remove_node(&p2p_soc_obj->tx_q_roc, + &curr_tx_ctx->node); + if (ret == QDF_STATUS_SUCCESS) { + p2p_send_tx_conf(curr_tx_ctx, false); + qdf_mem_free(curr_tx_ctx->buf); + qdf_mem_free(curr_tx_ctx); + } else + p2p_err("remove %pK from roc_q fail", + curr_tx_ctx); } + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc, + p_node, &p_node); } p2p_debug("clean up tx queue wait for ack, size:%d", qdf_list_size(&p2p_soc_obj->tx_q_ack)); - while (qdf_list_remove_front(&p2p_soc_obj->tx_q_ack, &p_node) == - QDF_STATUS_SUCCESS) { + + status = qdf_list_peek_front(&p2p_soc_obj->tx_q_ack, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { curr_tx_ctx = qdf_container_of(p_node, struct tx_action_context, node); if ((vdev_id == P2P_INVALID_VDEV_ID) || (vdev_id == curr_tx_ctx->vdev_id)) { - p2p_disable_tx_timer(curr_tx_ctx); - p2p_send_tx_conf(curr_tx_ctx, false); - qdf_mem_free(curr_tx_ctx->buf); - qdf_mem_free(curr_tx_ctx); + ret = qdf_list_remove_node(&p2p_soc_obj->tx_q_ack, + &curr_tx_ctx->node); + if (ret == QDF_STATUS_SUCCESS) { + p2p_disable_tx_timer(curr_tx_ctx); + p2p_send_tx_conf(curr_tx_ctx, false); + qdf_mem_free(curr_tx_ctx->buf); + qdf_mem_free(curr_tx_ctx); + } else + p2p_err("remove %pK from roc_q fail", + curr_tx_ctx); } + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, + p_node, &p_node); } qdf_event_set(&p2p_soc_obj->cleanup_tx_done); From 5fb3096c626ed362efe8c9663ffee15db98e1111 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 16 Aug 2018 13:25:29 +0800 Subject: [PATCH 315/404] qcacmn: Get next node and then delete current queue It will delete current node and then get next node by current node, which cause NULL pointer access. Change-Id: Ieb1f1fe924d4c86368e340b2482f2ffdb09f301f CRs-Fixed: 2297087 --- core/src/wlan_p2p_off_chan_tx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index a03fe0127983..849dafced0c8 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1721,6 +1721,8 @@ QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param) while (QDF_IS_STATUS_SUCCESS(status)) { curr_tx_ctx = qdf_container_of(p_node, struct tx_action_context, node); + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc, + p_node, &p_node); if ((vdev_id == P2P_INVALID_VDEV_ID) || (vdev_id == curr_tx_ctx->vdev_id)) { ret = qdf_list_remove_node(&p2p_soc_obj->tx_q_roc, @@ -1733,8 +1735,6 @@ QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param) p2p_err("remove %pK from roc_q fail", curr_tx_ctx); } - status = qdf_list_peek_next(&p2p_soc_obj->tx_q_roc, - p_node, &p_node); } p2p_debug("clean up tx queue wait for ack, size:%d", @@ -1744,6 +1744,8 @@ QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param) while (QDF_IS_STATUS_SUCCESS(status)) { curr_tx_ctx = qdf_container_of(p_node, struct tx_action_context, node); + status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, + p_node, &p_node); if ((vdev_id == P2P_INVALID_VDEV_ID) || (vdev_id == curr_tx_ctx->vdev_id)) { ret = qdf_list_remove_node(&p2p_soc_obj->tx_q_ack, @@ -1757,8 +1759,6 @@ QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param) p2p_err("remove %pK from roc_q fail", curr_tx_ctx); } - status = qdf_list_peek_next(&p2p_soc_obj->tx_q_ack, - p_node, &p_node); } qdf_event_set(&p2p_soc_obj->cleanup_tx_done); From 4568beb47c7dcab35d24214721b24cd47e0307a0 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 16 Aug 2018 15:55:25 +0530 Subject: [PATCH 316/404] qcacmn: Reduce log level for few prints to debug Reduce log level for few prints to debug to avoid flooding of prints to console. Change-Id: I514585cc87d51ead15fb1f40d45f62023628d9bb CRs-Fixed: 2296839 --- dispatcher/src/wlan_tdls_ucfg_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 8930e0295272..4d0c64bcc459 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -269,7 +269,7 @@ QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc) QDF_STATUS status; struct tdls_soc_priv_obj *soc_obj; - tdls_notice("tdls psoc open"); + tdls_debug("tdls psoc open"); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); if (!soc_obj) { @@ -289,7 +289,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, uint32_t tdls_feature_flags; struct policy_mgr_tdls_cbacks tdls_pm_call_backs; - tdls_notice("tdls update config "); + tdls_debug("tdls update config "); if (!psoc || !req) { tdls_err("psoc: 0x%pK, req: 0x%pK", psoc, req); return QDF_STATUS_E_FAILURE; From 59d68afe2e99f62d4f51145635c1559448f0bf66 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Thu, 2 Aug 2018 21:23:58 +0530 Subject: [PATCH 317/404] qcacmn: Remove dual beacon MCC check from SCC check case In the API policy_mgr_dual_beacon_on_single_mac_scc_capable the check of wmi_service_dual_beacon_on_single_mac_mcc_support is there too, which in any case is void, as if the driver supports SCC, then it will return true from the first check itself, and if it doesn't support SCC, it will surely not support MCC too, so the check of MCC after SCC is void anyways Fix is to remove the check of MCC dual beaconing capability from policy_mgr_dual_beacon_on_single_mac_scc_capable Change-Id: Ia427be4fcee0e0267171d81cf7e8e669560d20a9 CRs-Fixed: 2299182 --- src/wlan_policy_mgr_get_set_utils.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 9079e721b02a..c2a1b704bf6f 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -3118,16 +3118,10 @@ bool policy_mgr_dual_beacon_on_single_mac_scc_capable( if (wmi_service_enabled( wmi_handle, wmi_service_dual_beacon_on_single_mac_scc_support)) { - policy_mgr_debug("Support dual beacon on same channel on single MAC"); + policy_mgr_debug("Dual beaconing on same channel on single MAC supported"); return true; } - if (wmi_service_enabled( - wmi_handle, - wmi_service_dual_beacon_on_single_mac_mcc_support)) { - policy_mgr_debug("Support dual beacon on both different and same channel on single MAC"); - return true; - } - policy_mgr_debug("Not support dual beacon on same channel on single MAC"); + policy_mgr_debug("Dual beaconing on same channel on single MAC is not supported"); return false; } @@ -3145,10 +3139,10 @@ bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( if (wmi_service_enabled( wmi_handle, wmi_service_dual_beacon_on_single_mac_mcc_support)) { - policy_mgr_debug("Support dual beacon on different channel on single MAC"); + policy_mgr_debug("Dual beaconing on different channel on single MAC supported"); return true; } - policy_mgr_debug("Not support dual beacon on different channel on single MAC"); + policy_mgr_debug("Dual beaconing on different channel on single MAC is not supported"); return false; } From 0eaef9f0388ccfdc3f9ddf700dd85c109f90b99d Mon Sep 17 00:00:00 2001 From: jiad Date: Fri, 10 Aug 2018 18:21:04 +0800 Subject: [PATCH 318/404] qcacmn: Add SAP-SAP-SAP policy manager next actions SAP-SAP-SAP next actions in policy manager are missing. Fix is to add SAP-SAP-SAP next actions so that correct actions can be taken, such as DBS mode can be enabled. Change-Id: I347540d9aabf44ed59e7be8b695e87dd8d129aea CRs-Fixed: 2297763 --- src/wlan_policy_mgr_tables_1x1_dbs_i.h | 5 ++++- src/wlan_policy_mgr_tables_2x2_dbs_i.h | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_tables_1x1_dbs_i.h b/src/wlan_policy_mgr_tables_1x1_dbs_i.h index 92501e8872ce..b1f193fe53d9 100644 --- a/src/wlan_policy_mgr_tables_1x1_dbs_i.h +++ b/src/wlan_policy_mgr_tables_1x1_dbs_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-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 @@ -1165,6 +1165,9 @@ static policy_mgr_next_action_three_connection_table_type [PM_P2P_CLI_SAP_MCC_24_5_2x2] = {PM_DBS_DOWNGRADE, PM_DBS_DOWNGRADE}, [PM_P2P_CLI_SAP_DBS_1x1] = {PM_NOP, PM_NOP}, + [PM_SAP_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_SAP_SAP_SCC_5_1x1] = {PM_DBS, PM_NOP}, + }; #endif diff --git a/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/src/wlan_policy_mgr_tables_2x2_dbs_i.h index dd11a9faea0a..370c38cff509 100644 --- a/src/wlan_policy_mgr_tables_2x2_dbs_i.h +++ b/src/wlan_policy_mgr_tables_2x2_dbs_i.h @@ -1384,6 +1384,11 @@ static policy_mgr_next_action_three_connection_table_type [PM_STA_STA_DBS_2x2] = {PM_NOP, PM_NOP}, [PM_STA_STA_SBS_5_1x1] = {PM_DBS_UPGRADE, PM_NOP}, + [PM_SAP_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS}, + [PM_SAP_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS}, + [PM_SAP_SAP_SCC_5_1x1] = {PM_DBS, PM_NOP}, + [PM_SAP_SAP_SCC_5_2x2] = {PM_DBS, PM_NOP}, + }; #endif From 0f192096cdc3f74fab47bb2eb96475e5e34e1ced Mon Sep 17 00:00:00 2001 From: jiad Date: Fri, 10 Aug 2018 15:23:12 +0800 Subject: [PATCH 319/404] qcacmn: Fix SAP-SAP concurrency when they are on single band Currently SAP-SAP concurrency on same band support is indicated through WMI service bit wmi_service_dual_beacon_on_single_mac_scc_support and wmi_service_dual_beacon_on_single_mac_mcc_support. If SCC is supported, channel of desirable SAP is checked against current available SAP interfaces. If channel is different, the desirable SAP is disallowed. Issue is that on DBS capable platforms, this will prevent second SAP from doing DBS. Fix is to check if desirable channel is equal to current SAP interfaces. If equal, SAP-SAP SCC will be allowed. Otherwise fall back to DBS checks and SCC/MCC on single band will be rejected if above two service bits check failed or not supported. Change-Id: I4bfbe5804003797e087bd0234b999cfe1eb4290a CRs-Fixed: 2297756 --- src/wlan_policy_mgr_get_set_utils.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index c2a1b704bf6f..d27f61c5709e 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -3069,13 +3069,12 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, pm_conc_connection_list[id].chan; if (((con_mode == PM_SAP_MODE) || (con_mode == PM_P2P_GO_MODE)) && - (channel != con_chan)) { - policy_mgr_debug("Scc is supported, but first SAP and second SAP are not in same channel, So don't allow second SAP interface"); - return false; + (channel == con_chan)) { + policy_mgr_debug("Scc is supported, allow second SAP interface"); + return true; } } } - return true; } if (!policy_mgr_is_hw_dbs_capable(psoc)) { policy_mgr_debug("DBS is not supported, mcc and scc are not supported too, don't allow second SAP interface"); From 15ca8ea97a238cadbc7ae915c27103fe5a99a118 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 21 Aug 2018 19:00:36 +0530 Subject: [PATCH 320/404] qcacmn: Re initialize default SAP mandatory channel list Re initialize default SAP mandatory channel list as part of the start bss. Without this change the 5GHz channels which were added as part of previous start bss are valid for the current start bss operation. Change-Id: Id234b413bbddb05efd3af8c3349271bf93a0a3bd CRs-Fixed: 2300501 --- src/wlan_policy_mgr_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 7bd923ed00c9..8417228ae08a 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2981,6 +2981,8 @@ void policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc) policy_mgr_err("Error in getting valid channels"); return; } + pm_ctx->sap_mandatory_channels_len = 0; + for (i = 0; i < len; i++) { if (WLAN_REG_IS_24GHZ_CH(chan_list[i])) { policy_mgr_debug("Add chan %hu to mandatory list", From 1830013b3fd62f610e095dd086122d16948c7f5b Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 25 May 2018 01:25:24 -0400 Subject: [PATCH 321/404] qcacmn: Add 2x2+1x1 DBS Action type Add new DBS Action types and handle the Actions in policy_mgr_next_actions API. Change-Id: Iccc62303383c0701955446a172ed956d1aea0e0f CRs-Fixed: 2257692 --- inc/wlan_policy_mgr_api.h | 40 ++++++ inc/wlan_policy_mgr_public_struct.h | 19 ++- src/wlan_policy_mgr_action.c | 190 ++++++++++++++++++++++++---- src/wlan_policy_mgr_core.c | 27 +++- src/wlan_policy_mgr_get_set_utils.c | 81 +++++++++++- 5 files changed, 328 insertions(+), 29 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 7dc6d12ba209..7a70a04bfe6f 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1730,11 +1730,51 @@ bool policy_mgr_is_current_hwmode_dbs(struct wlan_objmgr_psoc *psoc); * DBS and there is no need for downgrading while entering DBS. * true: DBS 2x2 can always be supported * false: hw_modes support DBS 1x1 as well + * Genoa DBS 2x2 + 1x1 will not be included. * * Return: true - DBS2x2, false - DBS1x1 */ bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc); +/* + * policy_mgr_is_2x2_1x1_dbs_capable() - check 2x2+1x1 DBS supported or not + * @psoc: PSOC object data + * + * This routine is called to check 2x2 5G + 1x1 2G (DBS1) or + * 2x2 2G + 1x1 5G (DBS2) support or not. + * Either DBS1 or DBS2 supported + * + * Return: true/false + */ +bool policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc *psoc); + +/* + * policy_mgr_is_2x2_5G_1x1_2G_dbs_capable() - check Genoa DBS1 enabled or not + * @psoc: PSOC object data + * + * This routine is called to check support DBS1 or not. + * Notes: DBS1: 2x2 5G + 1x1 2G. + * This function will call policy_mgr_get_hw_mode_idx_from_dbs_hw_list to match + * the HW mode from hw mode list. The parameters will also be matched to + * 2x2 5G +2x2 2G HW mode. But firmware will not report 2x2 5G + 2x2 2G alone + * with 2x2 5G + 1x1 2G at same time. So, it is safe to find DBS1 with + * policy_mgr_get_hw_mode_idx_from_dbs_hw_list. + * + * Return: true/false + */ +bool policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc *psoc); + +/* + * policy_mgr_is_2x2_2G_1x1_5G_dbs_capable() - check Genoa DBS2 enabled or not + * @psoc: PSOC object data + * + * This routine is called to check support DBS2 or not. + * Notes: DBS2: 2x2 2G + 1x1 5G + * + * Return: true/false + */ +bool policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_init() - Policy Manager component initialization * routine diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index ea748b230b35..021ad962227b 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -689,6 +689,12 @@ enum policy_mgr_two_connection_mode { * @PM_SBS_DOWNGRADE: switch to SBS mode & downgrade to 1x1 * @PM_DOWNGRADE: downgrade to 1x1 * @PM_UPGRADE: upgrade to 2x2 + * @PM_DBS1: switch to DBS 1 + * @PM_DBS1_DOWNGRADE: downgrade 2G beaconing entity to 1x1 and switch to DBS1. + * @PM_DBS2: switch to DBS 2 + * @PM_DBS2_DOWNGRADE: downgrade 5G beaconing entity to 1x1 and switch to DBS2. + * @PM_UPGRADE_5G: upgrade 5g beaconing entity to 2x2. + * @PM_UPGRADE_2G: upgrade 2g beaconing entity to 2x2. * @PM_MAX_CONC_PRIORITY_MODE: Max place holder * * These are generic IDs that identify the various roles @@ -705,6 +711,12 @@ enum policy_mgr_conc_next_action { PM_SBS_DOWNGRADE, PM_DOWNGRADE, PM_UPGRADE, + PM_DBS1, + PM_DBS1_DOWNGRADE, + PM_DBS2, + PM_DBS2_DOWNGRADE, + PM_UPGRADE_5G, + PM_UPGRADE_2G, PM_MAX_CONC_NEXT_ACTION }; @@ -882,8 +894,10 @@ struct policy_mgr_conc_connection_info { * @mac0_bw: MAC0 bandwidth * @mac1_bw: MAC1 bandwidth * @mac0_band_cap: mac0 band (5g/2g) capability - * @dbs_cap: DBS capability - * @agile_dfs_cap: Agile DFS capability + * @dbs_cap: DBS capabality + * @agile_dfs_cap: Agile DFS capabality + * @action_type: for dbs mode, the field indicates the "Action type" to be + * used to switch to the mode. To help the hw mode validation. */ struct policy_mgr_hw_mode_params { uint8_t mac0_tx_ss; @@ -896,6 +910,7 @@ struct policy_mgr_hw_mode_params { uint8_t dbs_cap; uint8_t agile_dfs_cap; uint8_t sbs_cap; + enum policy_mgr_conc_next_action action_type; }; /** diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 061a068e6eb0..5f90175345b7 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -620,14 +620,108 @@ done: return status; } -QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, +/** + * policy_mgr_validate_dbs_switch() - Check DBS action valid or not + * @psoc: Pointer to psoc + * @session_id: vdev id + * @action: action requested + * @reason: reason of hw mode change + * + * This routine will check the current hw mode with requested action. + * If we are already in the mode, the caller will do nothing. + * This will be called by policy_mgr_next_actions to check the action needed + * or not. + * + * return : QDF_STATUS_SUCCESS, action is allowed. + * QDF_STATUS_E_ALREADY, action is not needed. + * QDF_STATUS_E_FAILURE, error happens. + * QDF_STATUS_E_NOSUPPORT, the requested mode not supported. + */ +static +QDF_STATUS policy_mgr_validate_dbs_switch( + struct wlan_objmgr_psoc *psoc, + uint32_t session_id, + enum policy_mgr_conc_next_action action, + enum policy_mgr_conn_update_reason reason) +{ + QDF_STATUS status; + struct policy_mgr_hw_mode_params hw_mode; + + /* check for the current HW index to see if really need any action */ + status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("policy_mgr_get_current_hw_mode failed"); + return status; + } + + if (hw_mode.sbs_cap) { + if ((action == PM_SBS) || (action == PM_SBS_DOWNGRADE)) { + if (!policy_mgr_is_hw_sbs_capable(psoc)) { + /* No action */ + policy_mgr_notice("firmware is not sbs capable"); + return QDF_STATUS_E_NOSUPPORT; + } + /* current mode is already SBS nothing to be + * done + */ + policy_mgr_notice("current mode is already SBS"); + return QDF_STATUS_E_ALREADY; + } else { + return QDF_STATUS_SUCCESS; + } + } + + if (!hw_mode.dbs_cap) { + if (action == PM_SINGLE_MAC || + action == PM_SINGLE_MAC_UPGRADE) { + policy_mgr_notice("current mode is already single MAC"); + return QDF_STATUS_E_ALREADY; + } else { + return QDF_STATUS_SUCCESS; + } + } + /** + * If already in DBS, no need to request DBS again (HL, Napier). + * For dual DBS HW, in case DBS1 -> DBS2 or DBS2 -> DBS1 + * switching, we need to check the current DBS mode is same as + * requested or not. + */ + if (policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc) || + policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)) { + policy_mgr_info("curr dbs action %d new action %d", + hw_mode.action_type, action); + if (hw_mode.action_type == PM_DBS1 && + ((action == PM_DBS1 || + action == PM_DBS1_DOWNGRADE))) { + policy_mgr_err("driver is already in DBS_5G_2x2_24G_1x1 (%d), no further action %d needed", + hw_mode.action_type, action); + return QDF_STATUS_E_ALREADY; + } else if (hw_mode.action_type == PM_DBS2 && + ((action == PM_DBS2 || + action == PM_DBS2_DOWNGRADE))) { + policy_mgr_err("driver is already in DBS_24G_2x2_5G_1x1 (%d), no further action %d needed", + hw_mode.action_type, action); + return QDF_STATUS_E_ALREADY; + } + } else if ((action == PM_DBS_DOWNGRADE) || (action == PM_DBS) || + (action == PM_DBS_UPGRADE)) { + policy_mgr_err("driver is already in %s mode, no further action needed", + (hw_mode.dbs_cap) ? "dbs" : "non dbs"); + return QDF_STATUS_E_ALREADY; + } + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_next_actions( + struct wlan_objmgr_psoc *psoc, uint32_t session_id, enum policy_mgr_conc_next_action action, enum policy_mgr_conn_update_reason reason) { QDF_STATUS status = QDF_STATUS_E_FAILURE; - struct policy_mgr_hw_mode_params hw_mode; struct dbs_nss nss_dbs = {0}; + struct policy_mgr_hw_mode_params hw_mode; + enum policy_mgr_conc_next_action next_action; if (policy_mgr_is_hw_dbs_capable(psoc) == false) { policy_mgr_err("driver isn't dbs capable, no further action needed"); @@ -640,28 +734,14 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, policy_mgr_err("policy_mgr_get_current_hw_mode failed"); return status; } - /** - * if already in DBS no need to request DBS. Might be needed - * to extend the logic when multiple dbs HW mode is available - */ - if ((((PM_DBS_DOWNGRADE == action) || (PM_DBS == action) || - (PM_DBS_UPGRADE == action)) - && hw_mode.dbs_cap)) { - policy_mgr_err("driver is already in %s mode, no further action needed", - (hw_mode.dbs_cap) ? "dbs" : "non dbs"); - return QDF_STATUS_E_ALREADY; - } - - if ((PM_SBS == action) || (action == PM_SBS_DOWNGRADE)) { - if (!policy_mgr_is_hw_sbs_capable(psoc)) { - /* No action */ - policy_mgr_notice("firmware is not sbs capable"); - return QDF_STATUS_E_NOSUPPORT; - } - /* check if current mode is already SBS nothing to be - * done - */ + /* check for the current HW index to see if really need any action */ + status = policy_mgr_validate_dbs_switch(psoc, session_id, action, + reason); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err(" not take action %d reason %d session %d status %d", + action, reason, session_id, status); + return status; } switch (action) { @@ -755,6 +835,70 @@ QDF_STATUS policy_mgr_next_actions(struct wlan_objmgr_psoc *psoc, status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2, PM_NOP, POLICY_MGR_ANY, reason); break; + case PM_DBS1_DOWNGRADE: + status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, + PM_DBS1, reason, + session_id); + break; + case PM_DBS2_DOWNGRADE: + status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, + PM_DBS2, reason, + session_id); + break; + case PM_DBS1: + /* + * PM_DBS1 (2x2 5G + 1x1 2G) will support 5G 2x2. If previous + * mode is DBS, that should be 2x2 2G + 1x1 5G mode and + * the 5G band was downgraded to 1x1. So, we need to + * upgrade 5G vdevs after hw mode change. + */ + if (hw_mode.dbs_cap) + next_action = PM_UPGRADE_5G; + else + next_action = PM_NOP; + status = policy_mgr_pdev_set_hw_mode( + psoc, session_id, + HW_MODE_SS_2x2, + HW_MODE_80_MHZ, + HW_MODE_SS_1x1, HW_MODE_40_MHZ, + HW_MODE_MAC_BAND_5G, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE, + reason, next_action); + break; + case PM_DBS2: + /* + * PM_DBS2 (2x2 2G + 1x1 5G) will support 2G 2x2. If previous + * mode is DBS, that should be 2x2 5G + 1x1 2G mode and + * the 2G band was downgraded to 1x1. So, we need to + * upgrade 5G vdevs after hw mode change. + */ + if (hw_mode.dbs_cap) + next_action = PM_UPGRADE_2G; + else + next_action = PM_NOP; + status = policy_mgr_pdev_set_hw_mode( + psoc, session_id, + HW_MODE_SS_2x2, + HW_MODE_40_MHZ, + HW_MODE_SS_1x1, HW_MODE_40_MHZ, + HW_MODE_MAC_BAND_2G, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE, + reason, next_action); + break; + case PM_UPGRADE_5G: + status = policy_mgr_nss_update( + psoc, POLICY_MGR_RX_NSS_2, + PM_NOP, POLICY_MGR_BAND_5, reason); + break; + case PM_UPGRADE_2G: + status = policy_mgr_nss_update( + psoc, POLICY_MGR_RX_NSS_2, + PM_NOP, POLICY_MGR_BAND_24, reason); + break; default: policy_mgr_err("unexpected action value %d", action); status = QDF_STATUS_E_FAILURE; diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 8417228ae08a..e7f2303e8fa1 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -480,6 +480,8 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx( { uint32_t param; struct policy_mgr_psoc_priv_obj *pm_ctx; + uint8_t mac0_min_ss; + uint8_t mac1_min_ss; uint32_t i, hw_mode_id; pm_ctx = policy_mgr_get_context(psoc); @@ -514,7 +516,20 @@ QDF_STATUS policy_mgr_get_hw_mode_from_idx( hw_mode->dbs_cap = POLICY_MGR_HW_MODE_DBS_MODE_GET(param); hw_mode->agile_dfs_cap = POLICY_MGR_HW_MODE_AGILE_DFS_GET(param); hw_mode->sbs_cap = POLICY_MGR_HW_MODE_SBS_MODE_GET(param); - + if (hw_mode->dbs_cap) { + mac0_min_ss = QDF_MIN(hw_mode->mac0_tx_ss, hw_mode->mac0_rx_ss); + mac1_min_ss = QDF_MIN(hw_mode->mac1_tx_ss, hw_mode->mac1_rx_ss); + if (hw_mode->mac0_band_cap == WLAN_5G_CAPABILITY && + mac0_min_ss && mac1_min_ss && + mac0_min_ss > mac1_min_ss) + hw_mode->action_type = PM_DBS1; + else if (hw_mode->mac0_band_cap == WLAN_2G_CAPABILITY && + mac0_min_ss && mac1_min_ss && + mac0_min_ss > mac1_min_ss) + hw_mode->action_type = PM_DBS2; + else + hw_mode->action_type = PM_DBS; + } return QDF_STATUS_SUCCESS; } @@ -2613,6 +2628,7 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, uint32_t session_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; + enum policy_mgr_band downgrade_band; if (policy_mgr_is_hw_dbs_capable(psoc) == false) { policy_mgr_err("driver isn't dbs capable, no further action needed"); @@ -2624,8 +2640,15 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, * protection. So, not taking any lock inside * policy_mgr_complete_action() during pm_conc_connection_list access. */ + if (next_action == PM_DBS1) + downgrade_band = POLICY_MGR_BAND_24; + else if (next_action == PM_DBS2) + downgrade_band = POLICY_MGR_BAND_5; + else + downgrade_band = POLICY_MGR_ANY; + status = policy_mgr_nss_update(psoc, new_nss, next_action, - POLICY_MGR_ANY, reason); + downgrade_band, reason); if (!QDF_IS_STATUS_SUCCESS(status)) status = policy_mgr_next_actions(psoc, session_id, next_action, reason); diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index d27f61c5709e..3e239b3b6d0c 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -769,9 +769,86 @@ bool policy_mgr_is_dbs_enable(struct wlan_objmgr_psoc *psoc) bool policy_mgr_is_hw_dbs_2x2_capable(struct wlan_objmgr_psoc *psoc) { struct dbs_nss nss_dbs; + uint32_t nss; - return ((policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs)) >= HW_MODE_SS_2x2) - ? true : false; + nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs); + if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss == nss_dbs.mac1_ss)) + return true; + else + return false; +} + +/* + * policy_mgr_is_2x2_1x1_dbs_capable() - check 2x2+1x1 DBS supported or not + * @psoc: PSOC object data + * + * This routine is called to check 2x2 5G + 1x1 2G (DBS1) or + * 2x2 2G + 1x1 5G (DBS2) support or not. + * Either DBS1 or DBS2 supported + * + * Return: true/false + */ +bool policy_mgr_is_2x2_1x1_dbs_capable(struct wlan_objmgr_psoc *psoc) +{ + struct dbs_nss nss_dbs; + uint32_t nss; + + nss = policy_mgr_get_hw_dbs_nss(psoc, &nss_dbs); + if (nss >= HW_MODE_SS_2x2 && (nss_dbs.mac0_ss > nss_dbs.mac1_ss)) + return true; + else + return false; +} + +/* + * policy_mgr_is_2x2_5G_1x1_2G_dbs_capable() - check Genoa DBS1 enabled or not + * @psoc: PSOC object data + * + * This routine is called to check support DBS1 or not. + * Notes: DBS1: 2x2 5G + 1x1 2G. + * This function will call policy_mgr_get_hw_mode_idx_from_dbs_hw_list to match + * the HW mode from hw mode list. The parameters will also be matched to + * 2x2 5G +2x2 2G HW mode. But firmware will not report 2x2 5G + 2x2 2G alone + * with 2x2 5G + 1x1 2G at same time. So, it is safe to find DBS1 with + * policy_mgr_get_hw_mode_idx_from_dbs_hw_list. + * + * Return: true/false + */ +bool policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(struct wlan_objmgr_psoc *psoc) +{ + return policy_mgr_is_2x2_1x1_dbs_capable(psoc) && + (policy_mgr_get_hw_mode_idx_from_dbs_hw_list( + psoc, + HW_MODE_SS_2x2, + HW_MODE_80_MHZ, + HW_MODE_SS_1x1, HW_MODE_40_MHZ, + HW_MODE_MAC_BAND_5G, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE) >= 0); +} + +/* + * policy_mgr_is_2x2_2G_1x1_5G_dbs_capable() - check Genoa DBS2 enabled or not + * @psoc: PSOC object data + * + * This routine is called to check support DBS2 or not. + * Notes: DBS2: 2x2 2G + 1x1 5G + * + * Return: true/false + */ +bool policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(struct wlan_objmgr_psoc *psoc) +{ + return policy_mgr_is_2x2_1x1_dbs_capable(psoc) && + (policy_mgr_get_hw_mode_idx_from_dbs_hw_list( + psoc, + HW_MODE_SS_2x2, + HW_MODE_40_MHZ, + HW_MODE_SS_1x1, HW_MODE_40_MHZ, + HW_MODE_MAC_BAND_2G, + HW_MODE_DBS, + HW_MODE_AGILE_DFS_NONE, + HW_MODE_SBS_NONE) >= 0); } uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc) From 065556ab011d6ebd119b251e487c612dc551a2cf Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 25 May 2018 03:45:32 -0400 Subject: [PATCH 322/404] qcacmn: Add 2x2_1x1 DBS action tables Add action table for DBS 2x2 5G + 1x1 2G and 2x2 2G + 1x1 5G action tables. Change-Id: Idadb223cde86729c0f2bbf0cdcc97d96d28c72ba CRs-Fixed: 2258683 --- src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h | 154 +++++++++++++++++++++ src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h | 154 +++++++++++++++++++++ 2 files changed, 308 insertions(+) create mode 100644 src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h create mode 100644 src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h diff --git a/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h b/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h new file mode 100644 index 000000000000..54d4c8ab80c6 --- /dev/null +++ b/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2012-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 + * 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. + */ + +#ifndef __WLAN_POLICY_MGR_TABLES_2X2_2G_1X1_5G_DBS_H +#define __WLAN_POLICY_MGR_TABLES_2X2_2G_1X1_5G_DBS_H + +#include "wlan_policy_mgr_api.h" + +/** + * next_action_two_connection_table - table which provides next + * action while a new connection is coming up, with one + * connection already in the system + */ +static policy_mgr_next_action_two_connection_table_type + pm_next_action_two_connection_dbs_2x2_2g_1x1_5g_table = { + [PM_STA_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_STA_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_STA_5_2x2] = {PM_DBS2, PM_NOP}, + [PM_P2P_CLI_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_P2P_CLI_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_P2P_CLI_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_P2P_CLI_5_2x2] = {PM_DBS2, PM_NOP}, + [PM_P2P_GO_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_P2P_GO_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_SAP_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_SAP_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_SAP_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_SAP_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_IBSS_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_IBSS_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_IBSS_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_IBSS_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, +}; + +/** + * next_action_three_connection_table - table which provides next + * action while a new connection is coming up, with two + * connections already in the system + */ +static policy_mgr_next_action_three_connection_table_type + pm_next_action_three_connection_dbs_2x2_2g_1x1_5g_table = { + [PM_STA_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_STA_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_STA_SAP_SCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_STA_SAP_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_STA_SAP_MCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_STA_SAP_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_STA_SAP_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_STA_SAP_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_STA_SAP_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_STA_SAP_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + + [PM_STA_P2P_GO_SCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_GO_SCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_GO_MCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_GO_MCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_GO_SCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_STA_P2P_GO_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_STA_P2P_GO_MCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_STA_P2P_GO_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_STA_P2P_GO_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_STA_P2P_GO_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_STA_P2P_GO_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_STA_P2P_GO_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + + [PM_STA_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_CLI_SCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_STA_P2P_CLI_SCC_5_2x2] = {PM_DBS2, PM_NOP}, + [PM_STA_P2P_CLI_MCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_STA_P2P_CLI_MCC_5_2x2] = {PM_DBS2, PM_NOP}, + [PM_STA_P2P_CLI_MCC_24_5_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_CLI_MCC_24_5_2x2] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_CLI_DBS_1x1] = {PM_NOP, PM_DBS2}, + [PM_STA_P2P_CLI_DBS_2x2] = {PM_NOP, PM_DBS2}, + + [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, + PM_DBS2_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, + PM_DBS2_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + + [PM_P2P_GO_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_P2P_GO_SAP_SCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_P2P_GO_SAP_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_SAP_MCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_P2P_GO_SAP_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_P2P_GO_SAP_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_P2P_GO_SAP_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_P2P_GO_SAP_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_P2P_GO_SAP_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + + [PM_P2P_CLI_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_P2P_CLI_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_P2P_CLI_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_P2P_CLI_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_P2P_CLI_SAP_SCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_P2P_CLI_SAP_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_P2P_CLI_SAP_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_P2P_CLI_SAP_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_P2P_CLI_SAP_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + + [PM_SAP_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_SAP_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_SAP_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS2}, + [PM_SAP_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS2}, + [PM_SAP_SAP_SCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_SAP_SAP_SCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_SAP_SAP_MCC_5_1x1] = {PM_DBS2, PM_NOP}, + [PM_SAP_SAP_MCC_5_2x2] = {PM_DBS2_DOWNGRADE, PM_NOP}, + [PM_SAP_SAP_MCC_24_5_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_SAP_SAP_MCC_24_5_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_SAP_SAP_DBS_1x1] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, + [PM_SAP_SAP_DBS_2x2] = {PM_DBS2_DOWNGRADE, PM_DBS2_DOWNGRADE}, +}; + +#endif diff --git a/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h b/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h new file mode 100644 index 000000000000..bdf8223d8fbb --- /dev/null +++ b/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2012-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 + * 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. + */ + +#ifndef __WLAN_POLICY_MGR_TABLES_2X2_5G_1X1_2G_DBS_H +#define __WLAN_POLICY_MGR_TABLES_2X2_5G_1X1_2G_DBS_H + +#include "wlan_policy_mgr_api.h" + +/** + * next_action_two_connection_table - table which provides next + * action while a new connection is coming up, with one + * connection already in the system + */ +static policy_mgr_next_action_two_connection_table_type + pm_next_action_two_connection_dbs_2x2_5g_1x1_2g_table = { + [PM_STA_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_STA_24_2x2] = {PM_NOP, PM_DBS1}, + [PM_STA_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_STA_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_P2P_CLI_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_P2P_CLI_24_2x2] = {PM_NOP, PM_DBS1}, + [PM_P2P_CLI_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_P2P_CLI_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_P2P_GO_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_SAP_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_SAP_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_SAP_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_SAP_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_IBSS_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_IBSS_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_IBSS_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_IBSS_5_2x2] = {PM_DBS1, PM_NOP}, +}; + +/** + * next_action_three_connection_table - table which provides next + * action while a new connection is coming up, with two + * connections already in the system + */ +static policy_mgr_next_action_three_connection_table_type + pm_next_action_three_connection_dbs_2x2_5g_1x1_2g_table = { + [PM_STA_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_STA_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_STA_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_STA_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_STA_SAP_SCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_STA_SAP_SCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_STA_SAP_MCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_STA_SAP_MCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_STA_SAP_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_STA_SAP_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_STA_SAP_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_STA_SAP_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + + [PM_STA_P2P_GO_SCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_STA_P2P_GO_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_STA_P2P_GO_MCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_STA_P2P_GO_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_STA_P2P_GO_SCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_STA_P2P_GO_SCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_STA_P2P_GO_MCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_STA_P2P_GO_MCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_STA_P2P_GO_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_STA_P2P_GO_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_STA_P2P_GO_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_STA_P2P_GO_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + + [PM_STA_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_STA_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_DBS1}, + [PM_STA_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_STA_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_DBS1}, + [PM_STA_P2P_CLI_SCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_STA_P2P_CLI_SCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_STA_P2P_CLI_MCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_STA_P2P_CLI_MCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_STA_P2P_CLI_MCC_24_5_1x1] = {PM_DBS1, PM_DBS1}, + [PM_STA_P2P_CLI_MCC_24_5_2x2] = {PM_DBS1, PM_DBS1}, + [PM_STA_P2P_CLI_DBS_1x1] = {PM_DBS1, PM_DBS1}, + [PM_STA_P2P_CLI_DBS_2x2] = {PM_DBS1, PM_DBS1}, + + [PM_P2P_GO_P2P_CLI_SCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_P2P_GO_P2P_CLI_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_MCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_P2P_GO_P2P_CLI_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_SCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_P2P_CLI_SCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_P2P_CLI_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, + PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, + PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_P2P_CLI_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + + [PM_P2P_GO_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_P2P_GO_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_P2P_GO_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_SAP_SCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_SAP_SCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_SAP_MCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_SAP_MCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_P2P_GO_SAP_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_SAP_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_SAP_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_P2P_GO_SAP_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + + [PM_P2P_CLI_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_P2P_CLI_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_P2P_CLI_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_P2P_CLI_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_P2P_CLI_SAP_SCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_P2P_CLI_SAP_SCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_P2P_CLI_SAP_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_P2P_CLI_SAP_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_P2P_CLI_SAP_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_P2P_CLI_SAP_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + + [PM_SAP_SAP_SCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_SAP_SAP_SCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_SAP_SAP_MCC_24_1x1] = {PM_NOP, PM_DBS1}, + [PM_SAP_SAP_MCC_24_2x2] = {PM_NOP, PM_DBS1_DOWNGRADE}, + [PM_SAP_SAP_SCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_SAP_SAP_SCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_SAP_SAP_MCC_5_1x1] = {PM_DBS1, PM_NOP}, + [PM_SAP_SAP_MCC_5_2x2] = {PM_DBS1, PM_NOP}, + [PM_SAP_SAP_MCC_24_5_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_SAP_SAP_MCC_24_5_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_SAP_SAP_DBS_1x1] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, + [PM_SAP_SAP_DBS_2x2] = {PM_DBS1_DOWNGRADE, PM_DBS1_DOWNGRADE}, +}; + +#endif From e1ebfd058d87df0adbe828525534e0b471f256b9 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Tue, 21 Aug 2018 19:20:28 +0800 Subject: [PATCH 323/404] qcacmn: Enhance SAP concurrency check to cover AP channel switch case SAP(Go) concurrency check is mainly used for two purposes: 1) When new GO/SAP session is coming up and needs to check if this session's channel can co-exist with existing GO/SAP sessions. For example, in case of single radio platform, MCC for SAP/GO+SAP/GO is not supported, in such case this API should prevent bringing the second connection. 2) There is already existing SAP+GO combination but due to upper layer notifying LTE-COEX event or sending command to move one of the connections to different channel. In such cases before moving existing connection to new channel, check if new channel can co-exist with the other existing connection. For example, one SAP1 is on channel-6 and second SAP2 is on channel-36 and lets say they are doing DBS, and lets say upper layer sends LTE-COEX to move SAP1 from channel-6 to channel-149. In this case, SAP1 and SAP2 will end up doing MCC which may not be desirable result. such cases will be prevented with this API. Add vdev_id check while checking for 2nd case. If connection with given vdev_id exist then it is confirmed that it's a case of channel switch rather than a new connection case. Optimize the performance and readability of policy_mgr_allow_sap_go_concurrency() API by re-organizing the code blocks. Change-Id: Idce5d2df7d21e36d2311946115a19482e4b81a8e CRs-Fixed: 2299105 --- inc/wlan_policy_mgr_api.h | 32 +++++++++--- src/wlan_policy_mgr_get_set_utils.c | 77 +++++++++++------------------ 2 files changed, 54 insertions(+), 55 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 7a70a04bfe6f..192f32db31c0 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -2444,19 +2444,37 @@ QDF_STATUS policy_mgr_register_mode_change_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_deregister_mode_change_cb(struct wlan_objmgr_psoc *psoc); /** - * policy_mgr_allow_sap_go_concurrency() - check whether multiple SAP/GO - * interfaces are allowed + * policy_mgr_allow_sap_go_concurrency() - check whether SAP/GO concurrency is + * allowed. * @psoc: pointer to soc - * @policy_mgr_con_mode: operating mode of the new interface - * @channel: operating channel of the new interface - * This function checks whether second SAP/GO interface is allowed on the same - * MAC. + * @policy_mgr_con_mode: operating mode of interface to be checked + * @channel: new operating channel of the interface to be checked + * @vdev_id: vdev id of the connection to be checked, 0xff for new connection + * + * Checks whether new channel SAP/GO can co-exist with the channel of existing + * SAP/GO connection. This API mainly used for two purposes: + * + * 1) When new GO/SAP session is coming up and needs to check if this session's + * channel can co-exist with existing existing GO/SAP sessions. For example, + * when single radio platform comes, MCC for SAP/GO+SAP/GO is not supported, in + * such case this API should prevent bringing the second connection. + * + * 2) There is already existing SAP+GO combination but due to upper layer + * notifying LTE-COEX event or sending command to move one of the connections + * to different channel. In such cases before moving existing connection to new + * channel, check if new channel can co-exist with the other existing + * connection. For example, one SAP1 is on channel-6 and second SAP2 is on + * channel-36 and lets say they are doing DBS, and lets say upper layer sends + * LTE-COEX to move SAP1 from channel-6 to channel-149. In this case, SAP1 and + * SAP2 will end up doing MCC which may not be desirable result. such cases + * will be prevented with this API. * * Return: true or false */ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t channel); + uint8_t channel, + uint32_t vdev_id); /** * policy_mgr_dual_beacon_on_single_mac_scc_capable() - get capability that diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 3e239b3b6d0c..58fb43f4b187 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1808,7 +1808,8 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, } } - if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, channel)) { + if (!policy_mgr_allow_sap_go_concurrency(psoc, mode, channel, + WLAN_INVALID_VDEV_ID)) { policy_mgr_err("This concurrency combination is not allowed"); goto done; } @@ -3117,62 +3118,42 @@ uint32_t policy_mgr_get_connection_info(struct wlan_objmgr_psoc *psoc, bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, - uint8_t channel) + uint8_t channel, + uint32_t vdev_id) { - uint32_t sap_cnt; - uint32_t go_cnt; enum policy_mgr_con_mode con_mode; uint8_t con_chan; int id; + uint32_t vdev; + bool dbs; - sap_cnt = policy_mgr_mode_specific_connection_count(psoc, - PM_SAP_MODE, - NULL); - go_cnt = policy_mgr_mode_specific_connection_count(psoc, - PM_P2P_GO_MODE, - NULL); - - if ((mode == PM_SAP_MODE || mode == PM_P2P_GO_MODE) && - (sap_cnt || go_cnt)) { - if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc)) + if (mode != PM_SAP_MODE && mode != PM_P2P_GO_MODE) + return true; + if (policy_mgr_dual_beacon_on_single_mac_mcc_capable(psoc)) + return true; + dbs = policy_mgr_is_hw_dbs_capable(psoc); + for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) { + if (!pm_conc_connection_list[id].in_use) + continue; + vdev = pm_conc_connection_list[id].vdev_id; + if (vdev_id == vdev) + continue; + con_mode = pm_conc_connection_list[id].mode; + if (con_mode != PM_SAP_MODE && con_mode != PM_P2P_GO_MODE) + continue; + con_chan = pm_conc_connection_list[id].chan; + if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc) && + (channel == con_chan)) { + policy_mgr_debug("SCC enabled, 2 AP on same channel, allow 2nd AP"); return true; - if (policy_mgr_dual_beacon_on_single_mac_scc_capable(psoc)) { - for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; - id++) { - if (pm_conc_connection_list[id].in_use) { - con_mode = - pm_conc_connection_list[id].mode; - con_chan = - pm_conc_connection_list[id].chan; - if (((con_mode == PM_SAP_MODE) || - (con_mode == PM_P2P_GO_MODE)) && - (channel == con_chan)) { - policy_mgr_debug("Scc is supported, allow second SAP interface"); - return true; - } - } - } } - if (!policy_mgr_is_hw_dbs_capable(psoc)) { - policy_mgr_debug("DBS is not supported, mcc and scc are not supported too, don't allow second SAP interface"); + if (!dbs) { + policy_mgr_debug("DBS unsupported, mcc and scc unsupported too, don't allow 2nd AP"); return false; } - /* If DBS is supported then allow second SAP/GO session only if - * the freq band of the second SAP/GO interface is different - * than the first SAP/GO interface. - */ - for (id = 0; id < MAX_NUMBER_OF_CONC_CONNECTIONS; id++) { - if (pm_conc_connection_list[id].in_use) { - con_mode = pm_conc_connection_list[id].mode; - con_chan = pm_conc_connection_list[id].chan; - if (((con_mode == PM_SAP_MODE) || - (con_mode == PM_P2P_GO_MODE)) && - (WLAN_REG_IS_SAME_BAND_CHANNELS(channel, - con_chan))) { - policy_mgr_debug("DBS is supported, but first SAP and second SAP are on same band, So don't allow second SAP interface"); - return false; - } - } + if (WLAN_REG_IS_SAME_BAND_CHANNELS(channel, con_chan)) { + policy_mgr_debug("DBS supported, 2 SAP on same band, reject 2nd AP"); + return false; } } From 687602cfb9723ff6a83a83650b641bfcde018550 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Fri, 24 Aug 2018 17:01:14 +0800 Subject: [PATCH 324/404] qcacmn: Add API for concurrency check to cover AP channel switch case There is already existing SAP+GO combination but due to upper layer notifying LTE-COEX event or sending command to move one of the connections to different channel. In such cases before moving existing connection to new channel, check if new channel can co-exist with the other existing connection. For example, one SAP1 is on channel-6 and second SAP2 is on channel-36 and lets say they are doing DBS, and lets say upper layer sends LTE-COEX to move SAP1 from channel-6 to channel-149. In this case, SAP1 and SAP2 will end up doing MCC which may not be desirable result. When channel switch, need recheck whether concurrency is allowed, Store the connection's parameter and temporarily delete it from the concurrency table. This way the allow concurrency check can be used as though a new connection is coming up, after check, restore the connection to concurrency table. Change-Id: I66e262774de8dfeba56f9b6f3d1d6721f1748881 CRs-Fixed: 2299105 --- inc/wlan_policy_mgr_api.h | 25 +++++++++++++++++ src/wlan_policy_mgr_core.c | 42 +++++++++++++++++++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 31 +++++++++++++++++++++ src/wlan_policy_mgr_i.h | 21 +++++++++++++++ 4 files changed, 119 insertions(+) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 192f32db31c0..d676607acd69 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -395,6 +395,31 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, uint8_t channel, enum hw_mode_bandwidth bw); +/** + * policy_mgr_allow_concurrency_csa() - Check for allowed concurrency + * combination when channel switch + * @psoc: PSOC object information + * @mode: connection mode + * @channel: target channel to switch + * @vdev_id: vdev id of channel switch interface + * + * There is already existing SAP+GO combination but due to upper layer + * notifying LTE-COEX event or sending command to move one of the connections + * to different channel. In such cases before moving existing connection to new + * channel, check if new channel can co-exist with the other existing + * connection. For example, one SAP1 is on channel-6 and second SAP2 is on + * channel-36 and lets say they are doing DBS, and lets say upper layer sends + * LTE-COEX to move SAP1 from channel-6 to channel-149. In this case, SAP1 and + * SAP2 will end up doing MCC which may not be desirable result. such cases + * will be prevented with this API. + * + * Return: True/False + */ +bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, + uint32_t vdev_id); + /** * policy_mgr_get_first_connection_pcl_table_index() - provides the * row index to firstConnectionPclTable to get to the correct diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index e7f2303e8fa1..2ddbbd3f3986 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -720,6 +720,48 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, */ } +void policy_mgr_store_and_del_conn_info_by_vdev_id( + struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, + struct policy_mgr_conc_connection_info *info, + uint8_t *num_cxn_del) +{ + uint32_t conn_index = 0; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + if (!info || !num_cxn_del) { + policy_mgr_err("Invalid parameters"); + return; + } + *num_cxn_del = 0; + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].vdev_id == vdev_id) && + pm_conc_connection_list[conn_index].in_use) { + *num_cxn_del = 1; + break; + } + } + /* + * Storing the connection entry which will be + * temporarily deleted. + */ + if (*num_cxn_del == 1) { + *info = pm_conc_connection_list[conn_index]; + /* Deleting the connection entry */ + policy_mgr_decr_connection_count( + psoc, + pm_conc_connection_list[conn_index].vdev_id); + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); +} + /** * policy_mgr_restore_deleted_conn_info() - Restore connection info * @info: An array saving connection info that is to be restored diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 58fb43f4b187..e4490593758d 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1862,6 +1862,37 @@ bool policy_mgr_allow_concurrency(struct wlan_objmgr_psoc *psoc, return policy_mgr_is_concurrency_allowed(psoc, mode, channel, bw); } +bool policy_mgr_allow_concurrency_csa(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode, + uint8_t channel, + uint32_t vdev_id) +{ + bool allow = false; + struct policy_mgr_conc_connection_info info; + uint8_t num_cxn_del = 0; + + /* + * Store the connection's parameter and temporarily delete it + * from the concurrency table. This way the allow concurrency + * check can be used as though a new connection is coming up, + * after check, restore the connection to concurrency table. + */ + policy_mgr_store_and_del_conn_info_by_vdev_id(psoc, vdev_id, + &info, &num_cxn_del); + allow = policy_mgr_allow_concurrency( + psoc, + mode, + channel, + HW_MODE_20_MHZ); + if (!allow) + policy_mgr_err("CSA concurrency check failed"); + /* Restore the connection entry */ + if (num_cxn_del > 0) + policy_mgr_restore_deleted_conn_info(psoc, &info, num_cxn_del); + + return allow; +} + /** * policy_mgr_get_concurrency_mode() - return concurrency mode * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index cf6ac6d943af..ba2f708ae1d2 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -382,6 +382,27 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, bool all_matching_cxn_to_del, struct policy_mgr_conc_connection_info *info, uint8_t *num_cxn_del); + +/** + * policy_mgr_store_and_del_conn_info_by_vdev_id() - Store and del a + * connection info by vdev id + * @psoc: PSOC object information + * @vdev_id: vdev id whose entry has to be deleted + * @info: struture array pointer where the connection info will be saved + * @num_cxn_del: number of connection which are going to be deleted + * + * Saves the connection info corresponding to the provided mode + * and deleted that corresponding entry based on vdev from the + * connection info structure + * + * Return: None + */ +void policy_mgr_store_and_del_conn_info_by_vdev_id( + struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, + struct policy_mgr_conc_connection_info *info, + uint8_t *num_cxn_del); + void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc, struct policy_mgr_conc_connection_info *info, uint8_t num_cxn_del); From 3c5f2dea0719131187145fc5e08d467dd8ae411c Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Tue, 14 Aug 2018 17:06:12 +0800 Subject: [PATCH 325/404] qcacmn: Indicate roc event to up layer for idle roc request It won't indicate roc event to up layer for idle roc request, which casue p2p listen command pending. Change-Id: I7a1c3c83411c63b790db1500a283d062dd87d63b CRs-Fixed: 2298546 --- core/src/wlan_p2p_off_chan_tx.c | 5 +++++ core/src/wlan_p2p_roc.c | 10 +++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 849dafced0c8..275442a70850 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1900,6 +1900,11 @@ QDF_STATUS p2p_process_mgmt_tx_cancel( struct p2p_roc_context *cur_roc_ctx; struct cancel_roc_context cancel_roc; + if (!cancel_tx || !(cancel_tx->cookie)) { + p2p_info("invalid cancel info"); + return QDF_STATUS_SUCCESS; + } + p2p_debug("cookie:0x%llx", cancel_tx->cookie); cur_tx_ctx = p2p_find_tx_ctx(cancel_tx->p2p_soc_obj, diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index c75bfdd28eab..13b85f291e6e 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -233,7 +233,8 @@ static QDF_STATUS p2p_destroy_roc_ctx(struct p2p_roc_context *roc_ctx, p2p_soc_obj, roc_ctx, up_layer_event, in_roc_queue); if (up_layer_event) { - p2p_send_roc_event(roc_ctx, ROC_EVENT_READY_ON_CHAN); + if (roc_ctx->roc_state < ROC_STATE_ON_CHAN) + p2p_send_roc_event(roc_ctx, ROC_EVENT_READY_ON_CHAN); p2p_send_roc_event(roc_ctx, ROC_EVENT_COMPLETED); } @@ -864,12 +865,7 @@ QDF_STATUS p2p_process_cancel_roc_req( } if (curr_roc_ctx->roc_state == ROC_STATE_IDLE) { - status = qdf_list_remove_node(&p2p_soc_obj->roc_q, - (qdf_list_node_t *)curr_roc_ctx); - if (status == QDF_STATUS_SUCCESS) - qdf_mem_free(curr_roc_ctx); - else - p2p_err("Failed to remove roc req, status %d", status); + status = p2p_destroy_roc_ctx(curr_roc_ctx, true, true); } else if (curr_roc_ctx->roc_state == ROC_STATE_CANCEL_IN_PROG) { p2p_debug("Receive cancel roc req when roc req is canceling, cookie %llx", From d540cd08dcd4c2d368284cd5f0cfba3c47369dd4 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 23 Aug 2018 18:25:28 +0530 Subject: [PATCH 326/404] qcacmn: Reduce log level for few prints to debug Change log level for few messages from info/warn/err to debug. Change-Id: I2fd3df21d70326301b39b91efdf827d6b391f4e3 CRs-Fixed: 2301926 --- src/wlan_policy_mgr_action.c | 4 ++-- src/wlan_policy_mgr_core.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 5f90175345b7..98c3c827a41a 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -207,7 +207,7 @@ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( goto done; } if (!hw_mode.dbs_cap) { - policy_mgr_notice("current HW mode is non-DBS capable"); + policy_mgr_debug("current HW mode is non-DBS capable"); goto done; } @@ -1299,7 +1299,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( &operating_channel[cc_count], &vdev_id[cc_count], PM_STA_MODE); if (!cc_count) { - policy_mgr_err("Could not get STA operating channel&vdevid"); + policy_mgr_debug("Could not get STA operating channel&vdevid"); return; } diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 2ddbbd3f3986..6fb55a412f0c 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -691,10 +691,10 @@ void policy_mgr_store_and_del_conn_info(struct wlan_objmgr_psoc *psoc, /* Deleting the connection entry */ policy_mgr_decr_connection_count(psoc, info[found_index].vdev_id); - policy_mgr_notice("Stored %d (%d), deleted STA entry with vdev id %d, index %d", - info[found_index].vdev_id, - info[found_index].mode, - info[found_index].vdev_id, conn_index); + policy_mgr_debug("Stored %d (%d), deleted STA entry with vdev id %d, index %d", + info[found_index].vdev_id, + info[found_index].mode, + info[found_index].vdev_id, conn_index); found_index++; if (all_matching_cxn_to_del) continue; From d50ff21e825d27a00023c9ea92d1fcf52a3ad719 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 23 Aug 2018 18:25:28 +0530 Subject: [PATCH 327/404] qcacmn: Reduce log level for few prints to debug Change log level for few messages from info/warn/err to debug. Change-Id: I2fd3df21d70326301b39b91efdf827d6b391f4e3 CRs-Fixed: 2301926 --- core/src/wlan_tdls_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index bd1a2783f0cc..62344ed6d921 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -218,7 +218,7 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc_obj; uint32_t tdls_feature_flags; - tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); + tdls_debug("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; From a49ef635164421eee73edc573dd6aa4e37795180 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 23 Aug 2018 18:25:28 +0530 Subject: [PATCH 328/404] qcacmn: Reduce log level for few prints to debug Change log level for few messages from info/warn/err to debug. Change-Id: I2fd3df21d70326301b39b91efdf827d6b391f4e3 CRs-Fixed: 2301926 --- core/src/wlan_p2p_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 7263fd3a2349..a722d17d4f0a 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -201,7 +201,7 @@ static QDF_STATUS p2p_vdev_obj_create_notification( } mode = wlan_vdev_mlme_get_opmode(vdev); - p2p_info("vdev mode:%d", mode); + p2p_debug("vdev mode:%d", mode); if (mode != QDF_P2P_GO_MODE) { p2p_debug("won't create p2p vdev private object if it is not GO"); return QDF_STATUS_SUCCESS; @@ -360,7 +360,7 @@ static QDF_STATUS p2p_peer_obj_destroy_notification( WLAN_UMAC_COMP_P2P); psoc = wlan_vdev_get_psoc(vdev); if (!p2p_vdev_obj || !psoc) { - p2p_err("p2p_vdev_obj:%pK psoc:%pK", p2p_vdev_obj, psoc); + p2p_debug("p2p_vdev_obj:%pK psoc:%pK", p2p_vdev_obj, psoc); return QDF_STATUS_E_INVAL; } From ecbf113b55443c36c619e19005690088d8cb786b Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 25 May 2018 05:24:12 -0400 Subject: [PATCH 329/404] qcacmn: Attach 2x2+1x1 action tables Attach action tables with 2x2+1x1 DBS hw modes, and select the table based on user dbs preference INI setting. Change-Id: If1fc79ce9a774fbf1ca08d09546679746ba1c4a3 CRs-Fixed: 2258919 --- inc/wlan_policy_mgr_api.h | 27 +++ inc/wlan_policy_mgr_public_struct.h | 32 ++++ src/wlan_policy_mgr_action.c | 248 +++++++++++++++++++++++++++- src/wlan_policy_mgr_get_set_utils.c | 5 +- src/wlan_policy_mgr_i.h | 5 + src/wlan_policy_mgr_init_deinit.c | 36 +++- src/wlan_policy_mgr_pcl.c | 4 + 7 files changed, 346 insertions(+), 11 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index d676607acd69..0fdf5110b199 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -546,6 +546,33 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, bool policy_mgr_is_dbs_allowed_for_concurrency( struct wlan_objmgr_psoc *psoc, enum QDF_OPMODE new_conn_mode); +/** + * policy_mgr_get_preferred_dbs_action_table() - get dbs action table type + * @psoc: Pointer to psoc + * @vdev_id: vdev Id + * @channel: channel of vdev. + * @reason: reason of request + * + * 1. Based on band preferred and vdev priority setting to choose the preferred + * dbs action. + * 2. This routine will be used to get DBS switching action tables. + * In Genoa, two action tables for DBS1 (2x2 5G + 1x1 2G), DBS2 + * (2x2 2G + 1x1 5G). + * 3. It can be used in mode change case in CSA channel switching or Roaming, + * opportunistic upgrade. If needs switch to DBS, we needs to query this + * function to get preferred DBS mode. + * 4. This is mainly used for dual dbs mode HW. For Legacy HW, there is + * only single DBS mode. This function will return PM_NOP. + * + * return : PM_NOP, PM_DBS1, PM_DBS2 + */ +enum policy_mgr_conc_next_action +policy_mgr_get_preferred_dbs_action_table( + struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, + uint8_t channel, + enum policy_mgr_conn_update_reason reason); + /** * policy_mgr_is_ibss_conn_exist() - to check if IBSS connection already present * @psoc: PSOC object information diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 021ad962227b..53ec91238654 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1031,6 +1031,25 @@ struct dual_mac_config { uint32_t req_fw_mode_config; }; +/** + * enum policy_mgr_pri_id - vdev type priority id + * @PM_STA_PRI_ID: station vdev type priority id + * @PM_SAP_PRI_ID: sap vdev type priority id + * @PM_P2P_GO_PRI_ID: p2p go vdev type priority id + * @PM_P2P_CLI_PRI_ID: p2p cli vdev type priority id + * @PM_MAX_PRI_ID: vdev type priority id max value + */ +enum policy_mgr_pri_id { + PM_STA_PRI_ID = 1, + PM_SAP_PRI_ID, + PM_P2P_GO_PRI_ID, + PM_P2P_CLI_PRI_ID, + PM_MAX_PRI_ID = 0xF, +}; + +#define PM_GET_BAND_PREFERRED(_policy_) ((_policy_) & 0x1) +#define PM_GET_VDEV_PRIORITY_ENABLED(_policy_) (((_policy_) & 0x2) >> 1) + /** * struct policy_mgr_user_cfg - Policy manager user config variables * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler @@ -1040,6 +1059,17 @@ struct dual_mac_config { * @enable2x2: 2x2 chain mask user config * @mcc_to_scc_switch_mode: Control SAP channel in concurrency * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled + * @dbs_selection_policy: band preference or Vdev preference + * bit[0] = 0: 5G 2x2 preferred to select 2x2 5G + 1x1 2G DBS mode. + * bit[0] = 1: 2G 2x2 preferred to select 2x2 2G + 1x1 5G DBS mode. + * bit[1] = 1: vdev priority enabled. + * bit[1] = 0: vdev priority disabled. + * @vdev_priority_list: vdev priority list + * bit[0-3]: pri_id (policy_mgr_pri_id) of highest priority + * bit[4-7]: pri_id (policy_mgr_pri_id) of second priority + * bit[8-11]: pri_id (policy_mgr_pri_id) of third priority + * bit[12-15]: pri_id (policy_mgr_pri_id) of fourth priority + * example: 0x4321 - CLI < GO < SAP < STA */ struct policy_mgr_user_cfg { uint8_t enable_mcc_adaptive_scheduler; @@ -1051,6 +1081,8 @@ struct policy_mgr_user_cfg { bool is_sta_sap_scc_allowed_on_dfs_chan; uint32_t channel_select_logic_conc; uint32_t sta_sap_scc_on_lte_coex_chan; + uint32_t dbs_selection_policy; + uint32_t vdev_priority_list; }; /** diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 98c3c827a41a..d9be9c19b876 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -513,6 +513,242 @@ bool policy_mgr_is_hwmode_set_for_given_chnl(struct wlan_objmgr_psoc *psoc, return true; } +/** + * policy_mgr_pri_id_to_con_mode() - convert policy_mgr_pri_id to + * policy_mgr_con_mode + * @pri_id: policy_mgr_pri_id + * + * The help function converts policy_mgr_pri_id type to policy_mgr_con_mode + * type. + * + * Return: policy_mgr_con_mode type. + */ +static +enum policy_mgr_con_mode policy_mgr_pri_id_to_con_mode( + enum policy_mgr_pri_id pri_id) +{ + switch (pri_id) { + case PM_STA_PRI_ID: + return PM_STA_MODE; + case PM_SAP_PRI_ID: + return PM_SAP_MODE; + case PM_P2P_GO_PRI_ID: + return PM_P2P_GO_MODE; + case PM_P2P_CLI_PRI_ID: + return PM_P2P_CLIENT_MODE; + default: + return PM_MAX_NUM_OF_MODE; + } +} + +enum policy_mgr_conc_next_action +policy_mgr_get_preferred_dbs_action_table( + struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, + uint8_t channel, + enum policy_mgr_conn_update_reason reason) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum policy_mgr_con_mode pri_conn_mode = PM_MAX_NUM_OF_MODE; + enum policy_mgr_con_mode new_conn_mode = PM_MAX_NUM_OF_MODE; + enum QDF_OPMODE new_conn_op_mode = QDF_MAX_NO_OF_MODE; + bool band_pref_5g = true; + bool vdev_priority_enabled = false; + bool dbs_2x2_5g_1x1_2g_supported; + bool dbs_2x2_2g_1x1_5g_supported; + uint32_t vdev_pri_list, vdev_pri_id; + uint8_t chan_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; + uint8_t vdev_list[MAX_NUMBER_OF_CONC_CONNECTIONS + 1]; + uint32_t vdev_count = 0; + uint32_t i; + bool found; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid context"); + return PM_NOP; + } + dbs_2x2_5g_1x1_2g_supported = + policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc); + dbs_2x2_2g_1x1_5g_supported = + policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc); + policy_mgr_debug("target support DBS1 %d DBS2 %d", + dbs_2x2_5g_1x1_2g_supported, + dbs_2x2_2g_1x1_5g_supported); + /* + * If both DBS1 and DBS2 not supported, this should be Legacy Single + * DBS mode HW. The policy_mgr_psoc_enable has setup the correct + * action tables. + */ + if (!dbs_2x2_5g_1x1_2g_supported && !dbs_2x2_2g_1x1_5g_supported) + return PM_NOP; + if (!dbs_2x2_5g_1x1_2g_supported) { + band_pref_5g = false; + policy_mgr_debug("target only supports DBS2!"); + goto DONE; + } + if (!dbs_2x2_2g_1x1_5g_supported) { + policy_mgr_debug("target only supports DBS1!"); + goto DONE; + } + if (PM_GET_BAND_PREFERRED(pm_ctx->user_cfg.dbs_selection_policy) == 1) + band_pref_5g = false; + + if (PM_GET_VDEV_PRIORITY_ENABLED( + pm_ctx->user_cfg.dbs_selection_policy) == 1 && + pm_ctx->user_cfg.vdev_priority_list) + vdev_priority_enabled = true; + + if (!vdev_priority_enabled) + goto DONE; + + if (vdev_id != INVALID_VDEV_ID && channel) { + if (pm_ctx->hdd_cbacks.hdd_get_device_mode) + new_conn_op_mode = pm_ctx->hdd_cbacks. + hdd_get_device_mode(vdev_id); + + new_conn_mode = policy_mgr_convert_device_mode_to_qdf_type( + new_conn_op_mode); + if (new_conn_mode == PM_MAX_NUM_OF_MODE) + policy_mgr_debug("new vdev %d op_mode %d chan %d reason %d: not prioritized", + vdev_id, new_conn_op_mode, + channel, reason); + else + policy_mgr_debug("new vdev %d op_mode %d chan %d : reason %d", + vdev_id, new_conn_op_mode, channel, + reason); + } + vdev_pri_list = pm_ctx->user_cfg.vdev_priority_list; + while (vdev_pri_list) { + vdev_pri_id = vdev_pri_list & 0xF; + pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id); + if (pri_conn_mode == PM_MAX_NUM_OF_MODE) { + policy_mgr_debug("vdev_pri_id %d prioritization not supported", + vdev_pri_id); + goto NEXT; + } + vdev_count = policy_mgr_get_mode_specific_conn_info( + psoc, chan_list, vdev_list, pri_conn_mode); + /** + * Take care of duplication case, the vdev id may + * exist in the conn list already with old chan. + * Replace with new chan before make decision. + */ + found = false; + for (i = 0; i < vdev_count; i++) { + policy_mgr_debug("[%d] vdev %d chan %d conn_mode %d", + i, vdev_list[i], chan_list[i], + pri_conn_mode); + + if (new_conn_mode == pri_conn_mode && + vdev_list[i] == vdev_id) { + chan_list[i] = channel; + found = true; + } + } + /** + * The new coming vdev should be added to the list to + * make decision if it is prioritized. + */ + if (!found && new_conn_mode == pri_conn_mode) { + chan_list[vdev_count] = channel; + vdev_list[vdev_count++] = vdev_id; + } + /** + * if more than one vdev has same priority, keep "band_pref_5g" + * value as default band preference setting. + */ + if (vdev_count > 1) + break; + /** + * select the only active vdev (or new coming vdev) chan as + * preferred band. + */ + if (vdev_count > 0) { + band_pref_5g = WLAN_REG_IS_5GHZ_CH(chan_list[0]); + break; + } +NEXT: + vdev_pri_list >>= 4; + } +DONE: + policy_mgr_debug("band_pref_5g %d", band_pref_5g); + if (band_pref_5g) + return PM_DBS1; + else + return PM_DBS2; +} + +/** + * policy_mgr_get_second_conn_action_table() - get second conn action table + * @psoc: Pointer to psoc + * @vdev_id: vdev Id + * @channel: channel of vdev. + * @reason: reason of request + * + * Get the action table based on current HW Caps and INI user preference. + * This function will be called by policy_mgr_current_connections_update during + * DBS action decision. + * + * return : action table address + */ +static policy_mgr_next_action_two_connection_table_type * +policy_mgr_get_second_conn_action_table( + struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, + uint8_t channel, + enum policy_mgr_conn_update_reason reason) +{ + enum policy_mgr_conc_next_action preferred_action; + + if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc)) + return next_action_two_connection_table; + + preferred_action = policy_mgr_get_preferred_dbs_action_table( + psoc, vdev_id, channel, reason); + switch (preferred_action) { + case PM_DBS2: + return next_action_two_connection_2x2_2g_1x1_5g_table; + default: + return next_action_two_connection_table; + } +} + +/** + * policy_mgr_get_third_conn_action_table() - get third connection action table + * @psoc: Pointer to psoc + * @vdev_id: vdev Id + * @channel: channel of vdev. + * @reason: reason of request + * + * Get the action table based on current HW Caps and INI user preference. + * This function will be called by policy_mgr_current_connections_update during + * DBS action decision. + * + * return : action table address + */ +static policy_mgr_next_action_three_connection_table_type * +policy_mgr_get_third_conn_action_table( + struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id, + uint8_t channel, + enum policy_mgr_conn_update_reason reason) +{ + enum policy_mgr_conc_next_action preferred_action; + + if (!policy_mgr_is_2x2_1x1_dbs_capable(psoc)) + return next_action_three_connection_table; + + preferred_action = policy_mgr_get_preferred_dbs_action_table( + psoc, vdev_id, channel, reason); + switch (preferred_action) { + case PM_DBS2: + return next_action_three_connection_2x2_2g_1x1_5g_table; + default: + return next_action_three_connection_table; + } +} + QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, uint32_t session_id, uint8_t channel, @@ -522,6 +758,8 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, uint32_t num_connections = 0; enum policy_mgr_one_connection_mode second_index = 0; enum policy_mgr_two_connection_mode third_index = 0; + policy_mgr_next_action_two_connection_table_type *second_conn_table; + policy_mgr_next_action_three_connection_table_type *third_conn_table; enum policy_mgr_band band; QDF_STATUS status = QDF_STATUS_E_FAILURE; struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -559,8 +797,9 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, "couldn't find index for 2nd connection next action table"); goto done; } - next_action = - (*next_action_two_connection_table)[second_index][band]; + second_conn_table = policy_mgr_get_second_conn_action_table( + psoc, session_id, channel, reason); + next_action = (*second_conn_table)[second_index][band]; break; case 2: third_index = @@ -570,8 +809,9 @@ QDF_STATUS policy_mgr_current_connections_update(struct wlan_objmgr_psoc *psoc, "couldn't find index for 3rd connection next action table"); goto done; } - next_action = (*next_action_three_connection_table) - [third_index][band]; + third_conn_table = policy_mgr_get_third_conn_action_table( + psoc, session_id, channel, reason); + next_action = (*third_conn_table)[third_index][band]; break; default: policy_mgr_err("unexpected num_connections value %d", diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index e4490593758d..73dec446db76 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1984,7 +1984,10 @@ QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, } pm_ctx->user_cfg = *user_cfg; - + policy_mgr_debug("dbs_selection_policy 0x%x", + user_cfg->dbs_selection_policy); + policy_mgr_debug("vdev_priority_list 0x%x", + user_cfg->vdev_priority_list); pm_ctx->cur_conc_system_pref = pm_ctx->user_cfg.conc_system_pref; return QDF_STATUS_SUCCESS; diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index ba2f708ae1d2..f079276d81fc 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -195,6 +195,11 @@ extern policy_mgr_next_action_two_connection_table_type *next_action_two_connection_table; extern policy_mgr_next_action_three_connection_table_type *next_action_three_connection_table; +extern policy_mgr_next_action_two_connection_table_type + *next_action_two_connection_2x2_2g_1x1_5g_table; +extern policy_mgr_next_action_three_connection_table_type + *next_action_three_connection_2x2_2g_1x1_5g_table; + extern enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) (struct wlan_objmgr_psoc *psoc); diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 322de079032d..2dc015d3f404 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -28,6 +28,8 @@ #include "wlan_policy_mgr_api.h" #include "wlan_policy_mgr_tables_1x1_dbs_i.h" #include "wlan_policy_mgr_tables_2x2_dbs_i.h" +#include "wlan_policy_mgr_tables_2x2_5g_1x1_2g.h" +#include "wlan_policy_mgr_tables_2x2_2g_1x1_5g.h" #include "wlan_policy_mgr_i.h" #include "qdf_types.h" #include "qdf_trace.h" @@ -425,33 +427,55 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) policy_mgr_get_current_pref_hw_mode_ptr = policy_mgr_get_current_pref_hw_mode_dbs_1x1; - if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + if (policy_mgr_is_hw_dbs_2x2_capable(psoc) || + policy_mgr_is_2x2_1x1_dbs_capable(psoc)) second_connection_pcl_dbs_table = &pm_second_connection_pcl_dbs_2x2_table; else second_connection_pcl_dbs_table = &pm_second_connection_pcl_dbs_1x1_table; - if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + if (policy_mgr_is_hw_dbs_2x2_capable(psoc) || + policy_mgr_is_2x2_1x1_dbs_capable(psoc)) third_connection_pcl_dbs_table = &pm_third_connection_pcl_dbs_2x2_table; else third_connection_pcl_dbs_table = &pm_third_connection_pcl_dbs_1x1_table; - if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) { next_action_two_connection_table = &pm_next_action_two_connection_dbs_2x2_table; - else + } else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) { + next_action_two_connection_table = + &pm_next_action_two_connection_dbs_2x2_5g_1x1_2g_table; + next_action_two_connection_2x2_2g_1x1_5g_table = + &pm_next_action_two_connection_dbs_2x2_2g_1x1_5g_table; + } else { next_action_two_connection_table = &pm_next_action_two_connection_dbs_1x1_table; + } - if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) + if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) { next_action_three_connection_table = &pm_next_action_three_connection_dbs_2x2_table; - else + } else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) { + next_action_three_connection_table = + &pm_next_action_three_connection_dbs_2x2_5g_1x1_2g_table; + next_action_three_connection_2x2_2g_1x1_5g_table = + &pm_next_action_three_connection_dbs_2x2_2g_1x1_5g_table; + } else { next_action_three_connection_table = &pm_next_action_three_connection_dbs_1x1_table; + } + policy_mgr_debug("is DBS Capable %d, is SBS Capable %d", + policy_mgr_is_hw_dbs_capable(psoc), + policy_mgr_is_hw_sbs_capable(psoc)); + policy_mgr_debug("is2x2 %d, is2x2+1x1 %d, is2x2_5g+1x1_2g %d, is2x2_2g+1x1_5g %d", + policy_mgr_is_hw_dbs_2x2_capable(psoc), + policy_mgr_is_2x2_1x1_dbs_capable(psoc), + policy_mgr_is_2x2_5G_1x1_2G_dbs_capable(psoc), + policy_mgr_is_2x2_2G_1x1_5G_dbs_capable(psoc)); return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index e41025045d5d..9db76d523103 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -55,6 +55,10 @@ policy_mgr_next_action_two_connection_table_type *next_action_two_connection_table; policy_mgr_next_action_three_connection_table_type *next_action_three_connection_table; +policy_mgr_next_action_two_connection_table_type + *next_action_two_connection_2x2_2g_1x1_5g_table; +policy_mgr_next_action_three_connection_table_type + *next_action_three_connection_2x2_2g_1x1_5g_table; QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, From e345d8539b7652423dd3e592411e3cfe0baba782 Mon Sep 17 00:00:00 2001 From: Sandeep Puligilla Date: Sat, 18 Aug 2018 12:42:41 -0700 Subject: [PATCH 330/404] qcacmn: Modify debug log levels in P2P/TDLS/SCAN Change debug message log level info/error/warn to debug. Change-Id: Ib8c5606b67ee653532489db876482b377c93e73c CRs-Fixed: 2303185 --- core/src/wlan_tdls_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 62344ed6d921..d9bb025e1d04 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -153,7 +153,7 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc_obj; uint32_t tdls_feature_flags; - tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); + tdls_debug("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; @@ -203,7 +203,7 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, goto err; } - tdls_notice("tdls object attach to vdev successfully"); + tdls_debug("tdls object attach to vdev successfully"); return status; err: qdf_mem_free(tdls_vdev_obj); @@ -1343,7 +1343,7 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc) return; if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) { - tdls_notice("TDLS mode is disabled OR not enabled"); + tdls_debug("TDLS mode is disabled OR not enabled"); return; } From a78776f3fbf259d887e5e977c5a8dd721f2e2060 Mon Sep 17 00:00:00 2001 From: Sandeep Puligilla Date: Sat, 18 Aug 2018 12:42:41 -0700 Subject: [PATCH 331/404] qcacmn: Modify debug log levels in P2P/TDLS/SCAN Change debug message log level info/error/warn to debug. Change-Id: Ib8c5606b67ee653532489db876482b377c93e73c CRs-Fixed: 2303185 --- core/src/wlan_p2p_main.c | 2 +- dispatcher/src/wlan_p2p_ucfg_api.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index a722d17d4f0a..b6d3cdc1878e 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -256,7 +256,7 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( } mode = wlan_vdev_mlme_get_opmode(vdev); - p2p_info("vdev mode:%d", mode); + p2p_debug("vdev mode:%d", mode); if (mode != QDF_P2P_GO_MODE) { p2p_debug("no p2p vdev private object if it is not GO"); return QDF_STATUS_SUCCESS; diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 9581cfa89f95..1f64b96b8e14 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -393,7 +393,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, if (QDF_STATUS_SUCCESS != qdf_idr_find(&p2p_soc_obj->p2p_idr, cookie, &tx_ctx)) { - p2p_err("invalid id"); + p2p_debug("invalid id"); return QDF_STATUS_E_INVAL; } From 5304ace8438d1c47d867acf797aa9152f32ce99d Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 30 Aug 2018 15:28:14 +0530 Subject: [PATCH 332/404] qcacmn: Configure the tdls offchannel params through IOCTL Add support to configure tdls offchannel params through IOCTL commands. Change-Id: I90ba90b5ef980f837ce4759755efe190672ad911 CRs-Fixed: 2309185 --- core/src/wlan_tdls_cmds_process.c | 80 ++++++++++++++ core/src/wlan_tdls_cmds_process.h | 34 ++++++ core/src/wlan_tdls_ct.c | 34 +----- core/src/wlan_tdls_ct.h | 38 +++++++ core/src/wlan_tdls_main.c | 9 ++ dispatcher/inc/wlan_tdls_public_structs.h | 42 +++++++- dispatcher/inc/wlan_tdls_ucfg_api.h | 29 +++++ dispatcher/src/wlan_tdls_ucfg_api.c | 122 ++++++++++++++++++++++ 8 files changed, 355 insertions(+), 33 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 8570484c2de4..90805709fc6a 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -2334,3 +2334,83 @@ QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg) return QDF_STATUS_SUCCESS; } + +void wlan_tdls_offchan_parms_callback(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + tdls_err("vdev is NULL"); + return; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + +int tdls_process_set_offchannel(struct tdls_set_offchannel *req) +{ + int status; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + if (tdls_get_vdev_objects(req->vdev, &tdls_vdev_obj, &tdls_soc_obj) != + QDF_STATUS_SUCCESS) { + status = -ENOTSUPP; + goto free; + } + + tdls_debug("TDLS offchannel to be configured %d", req->offchannel); + + if (req->offchannel) + status = tdls_set_tdls_offchannel(tdls_soc_obj, + req->offchannel); + else + status = -ENOTSUPP; + +free: + + if (req->callback) + req->callback(req->vdev); + qdf_mem_free(req); + + return status; +} + +int tdls_process_set_offchan_mode(struct tdls_set_offchanmode *req) +{ + int status; + + tdls_debug("TDLS offchan mode to be configured %d", req->offchan_mode); + status = tdls_set_tdls_offchannelmode(req->vdev, req->offchan_mode); + + if (req->callback) + req->callback(req->vdev); + qdf_mem_free(req); + + return status; +} + +int tdls_process_set_secoffchanneloffset( + struct tdls_set_secoffchanneloffset *req) +{ + int status; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + if (tdls_get_vdev_objects(req->vdev, &tdls_vdev_obj, &tdls_soc_obj) != + QDF_STATUS_SUCCESS) { + status = -ENOTSUPP; + goto free; + } + + tdls_debug("TDLS offchannel offset to be configured %d", + req->offchan_offset); + status = tdls_set_tdls_secoffchanneloffset(tdls_soc_obj, + req->offchan_offset); + +free: + + if (req->callback) + req->callback(req->vdev); + qdf_mem_free(req); + + return status; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 938e96671608..da14cfa6ab9f 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -383,4 +383,38 @@ int tdls_set_responder(struct tdls_set_responder_req *set_req); */ void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj); +/** + * wlan_tdls_offchan_parms_callback() - Callback to release ref count + * @vdev: vdev object + * + * Return: none + */ +void wlan_tdls_offchan_parms_callback(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_process_set_offchannel() - Handle set offchannel request for TDLS + * @req: TDLS set offchannel request + * + * Return: int status + */ +int tdls_process_set_offchannel(struct tdls_set_offchannel *req); + +/** + * tdls_process_set_offchan_mode() - Handle set offchan mode request for TDLS + * @req: TDLS set offchannel mode request + * + * Return: int status + */ +int tdls_process_set_offchan_mode(struct tdls_set_offchanmode *req); + +/** + * tdls_process_set_secoffchanneloffset() - Handle set sec offchannel + * offset request for TDLS + * @req: TDLS set secoffchannel offchannel request + * + * Return: int status + */ +int tdls_process_set_secoffchanneloffset( + struct tdls_set_secoffchanneloffset *req); + #endif diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index b3f28a458648..4e0b4cdbb531 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -936,16 +936,6 @@ void tdls_ct_handler(void *user_data) WLAN_TDLS_NB_ID); } -/** - * tdls_set_tdls_offchannel() - set tdls off-channel number - * @tdls_soc: tdls soc object - * @offchanmode: tdls off-channel number - * - * This function sets tdls off-channel number - * - * Return: 0 on success; negative errno otherwise - */ -static int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, int offchannel) { @@ -964,7 +954,7 @@ int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, } } else { tdls_err("Either TDLS or TDLS Off-channel is not enabled"); - return -ENOTSUPP; + return -ENOTSUPP; } tdls_notice("change tdls off channel from %d to %d", tdls_soc->tdls_off_channel, offchannel); @@ -972,16 +962,6 @@ int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, return 0; } -/** - * tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset - * @tdls_soc: tdls soc object - * @offchanmode: tdls off-channel offset - * - * This function sets 2nd tdls off-channel offset - * - * Return: 0 on success; negative errno otherwise - */ -static int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, int offchanoffset) { @@ -1022,16 +1002,6 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, return 0; } -/** - * tdls_set_tdls_offchannelmode() - set tdls off-channel mode - * @adapter: Pointer to the HDD adapter - * @offchanmode: tdls off-channel mode - * - * This function sets tdls off-channel mode - * - * Return: 0 on success; negative errno otherwise - */ -static int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, int offchanmode) { @@ -1056,7 +1026,7 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, return -EINVAL; } - if (tdls_is_vdev_connected(vdev)) { + if (!tdls_is_vdev_connected(vdev)) { tdls_err("tdls off channel req in not associated state %d", offchanmode); return -EPERM; diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index 04926b9bba33..6c8dbf680f04 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -206,4 +206,42 @@ void tdls_disable_offchan_and_teardown_links( QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc); +/** + * tdls_set_tdls_offchannel() - set tdls off-channel number + * @tdls_soc: tdls soc object + * @offchanmode: tdls off-channel number + * + * This function sets tdls off-channel number + * + * Return: 0 on success; negative errno otherwise + */ +int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, + int offchannel); + +/** + * tdls_set_tdls_offchannelmode() - set tdls off-channel mode + * @adapter: Pointer to the HDD adapter + * @offchannel: tdls off-channel mode + * + * This function sets tdls off-channel mode + * + * Return: 0 on success; negative errno otherwise + */ + +int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, + int offchanmode); + +/** + * tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset + * @tdls_soc: tdls soc object + * @offchanoffset: tdls off-channel offset + * + * This function sets secondary tdls off-channel offset + * + * Return: 0 on success; negative errno otherwise + */ + +int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, + int offchanoffset); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index d9bb025e1d04..66ebc7edb56e 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -322,6 +322,15 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_GET_ALL_PEERS: tdls_get_all_peers_from_list(msg->bodyptr); break; + case TDLS_CMD_SET_OFFCHANNEL: + tdls_process_set_offchannel(msg->bodyptr); + break; + case TDLS_CMD_SET_OFFCHANMODE: + tdls_process_set_offchan_mode(msg->bodyptr); + break; + case TDLS_CMD_SET_SECOFFCHANOFFSET: + tdls_process_set_secoffchanneloffset(msg->bodyptr); + break; default: break; } diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index c8dd05f53ecc..3ecf2dfd26d9 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -190,6 +190,9 @@ enum tdls_feature_mode { * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapter reset * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list * @TDLS_CMD_ANTENNA_SWITCH: dynamic tdls antenna switch + * @TDLS_CMD_SET_OFFCHANNEL: tdls offchannel + * @TDLS_CMD_SET_OFFCHANMODE: tdls offchannel mode + * @TDLS_CMD_SET_SECOFFCHANOFFSET: tdls secondary offchannel offset */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -211,7 +214,10 @@ enum tdls_command_type { TDLS_CMD_TEARDOWN_LINKS, TDLS_NOTIFY_RESET_ADAPTERS, TDLS_CMD_GET_ALL_PEERS, - TDLS_CMD_ANTENNA_SWITCH + TDLS_CMD_ANTENNA_SWITCH, + TDLS_CMD_SET_OFFCHANNEL, + TDLS_CMD_SET_OFFCHANMODE, + TDLS_CMD_SET_SECOFFCHANOFFSET }; /** @@ -582,6 +588,9 @@ typedef QDF_STATUS /* This callback is to release vdev ref for tdls sta notify msg */ typedef void (*tdls_sta_notify_callback)(struct wlan_objmgr_vdev *vdev); +/* This callback is to release vdev ref for tdls offchan param related msg */ +typedef void (*tdls_offchan_parms_callback)(struct wlan_objmgr_vdev *vdev); + /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -1098,4 +1107,35 @@ struct tdls_antenna_switch_request { struct wlan_objmgr_vdev *vdev; uint32_t mode; }; + +/** + * struct tdls_set_offchannel - TDLS set offchannel + * @offchannel: Updated tdls offchannel value. + */ +struct tdls_set_offchannel { + struct wlan_objmgr_vdev *vdev; + uint16_t offchannel; + tdls_offchan_parms_callback callback; +}; + +/** + * struct tdls_set_offchan_mode - TDLS set offchannel mode + * @offchan_mode: Updated tdls offchannel mode value. + */ +struct tdls_set_offchanmode { + struct wlan_objmgr_vdev *vdev; + uint8_t offchan_mode; + tdls_offchan_parms_callback callback; +}; + +/** + * struct tdls_set_offchan_offset - TDLS set offchannel mode + * @offchan_offset: Offchan offset value. + */ +struct tdls_set_secoffchanneloffset { + struct wlan_objmgr_vdev *vdev; + uint8_t offchan_offset; + tdls_offchan_parms_callback callback; +}; + #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 1135c48e2dec..3d6570772c64 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -222,4 +222,33 @@ void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode); +/** + * ucfg_set_tdls_offchannel() - Handle TDLS set offchannel + * @vdev: vdev object + * @offchannel: updated offchannel + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_set_tdls_offchannel(struct wlan_objmgr_vdev *vdev, + int offchannel); + +/** + * ucfg_set_tdls_offchan_mode() - Handle TDLS set offchannel mode + * @vdev: vdev object + * @offchanmode: updated off-channel mode + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_set_tdls_offchan_mode(struct wlan_objmgr_vdev *vdev, + int offchanmode); + +/** + * ucfg_set_tdls_secoffchanneloffset() - Handle TDLS set offchannel offset + * @vdev: vdev object + * @offchanoffset: tdls off-channel offset + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_set_tdls_secoffchanneloffset(struct wlan_objmgr_vdev *vdev, + int offchanoffset); #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 4d0c64bcc459..5b76f0e80afb 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -870,3 +870,125 @@ error: qdf_mem_free(req); return status; } + +QDF_STATUS ucfg_set_tdls_offchannel(struct wlan_objmgr_vdev *vdev, + int offchannel) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct scheduler_msg msg = {0, }; + struct tdls_set_offchannel *req; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto free; + } + + req->offchannel = offchannel; + req->vdev = vdev; + req->callback = wlan_tdls_offchan_parms_callback; + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_OFFCHANNEL; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post set tdls offchannel msg fail"); + goto dec_ref; + } + + return status; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + +free: + qdf_mem_free(req); + return status; +} + +QDF_STATUS ucfg_set_tdls_offchan_mode(struct wlan_objmgr_vdev *vdev, + int offchanmode) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct scheduler_msg msg = {0, }; + struct tdls_set_offchanmode *req; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto free; + } + + req->offchan_mode = offchanmode; + req->vdev = vdev; + req->callback = wlan_tdls_offchan_parms_callback; + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_OFFCHANMODE; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post set offchanmode msg fail"); + goto dec_ref; + } + + return status; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + +free: + qdf_mem_free(req); + return status; +} + +QDF_STATUS ucfg_set_tdls_secoffchanneloffset(struct wlan_objmgr_vdev *vdev, + int offchanoffset) +{ + int status = QDF_STATUS_SUCCESS; + struct scheduler_msg msg = {0, }; + struct tdls_set_secoffchanneloffset *req; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto free; + } + + req->offchan_offset = offchanoffset; + req->vdev = vdev; + req->callback = wlan_tdls_offchan_parms_callback; + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_SECOFFCHANOFFSET; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post set secoffchan offset msg fail"); + goto dec_ref; + } + return status; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + +free: + qdf_mem_free(req); + return status; +} From 4d01f9bf6a6c2071a37f0a2c900466b3f336d06b Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 30 Aug 2018 13:26:21 -0700 Subject: [PATCH 333/404] qcacmn: Fix NULL pointer dereference in tdls In target_if_tdls_update_fw_state, target_if_tdls_set_offchan_mode, & target_if_tdls_set_uapsd wmi_handle is derived & dereferenced with out a NULL check. Add a NULL check for wmi_handle before it is dereferenced. Change-Id: If741f69773a712cebcd1be889ca09d01eee97fae CRs-Fixed: 2305520 --- src/target_if_tdls.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/target_if_tdls.c b/src/target_if_tdls.c index bbb3c32cf096..f6b248e93d53 100644 --- a/src/target_if_tdls.c +++ b/src/target_if_tdls.c @@ -82,6 +82,13 @@ target_if_tdls_update_fw_state(struct wlan_objmgr_psoc *psoc, { QDF_STATUS status; uint8_t tdls_state; + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid WMI handle"); + return QDF_STATUS_E_FAILURE; + } if (TDLS_SUPPORT_EXP_TRIG_ONLY == param->tdls_state) tdls_state = WMI_TDLS_ENABLE_PASSIVE; @@ -91,7 +98,7 @@ target_if_tdls_update_fw_state(struct wlan_objmgr_psoc *psoc, else tdls_state = WMI_TDLS_DISABLE; - status = wmi_unified_update_fw_tdls_state_cmd(GET_WMI_HDL_FROM_PSOC(psoc), + status = wmi_unified_update_fw_tdls_state_cmd(wmi_handle, param, tdls_state); target_if_debug("vdev_id %d", param->vdev_id); @@ -110,8 +117,14 @@ target_if_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, struct tdls_channel_switch_params *params) { QDF_STATUS status; + struct wmi_unified *wmi_handle; - status = wmi_unified_set_tdls_offchan_mode_cmd(GET_WMI_HDL_FROM_PSOC(psoc), + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid WMI handle"); + return QDF_STATUS_E_FAILURE; + } + status = wmi_unified_set_tdls_offchan_mode_cmd(wmi_handle, params); return status; @@ -122,8 +135,13 @@ target_if_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, struct sta_uapsd_trig_params *params) { QDF_STATUS ret; - wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + struct wmi_unified *wmi_handle; + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("Invalid WMI handle"); + return QDF_STATUS_E_FAILURE; + } if (!wmi_service_enabled(wmi_handle, wmi_sta_uapsd_basic_auto_trig) || !wmi_service_enabled(wmi_handle, @@ -132,7 +150,7 @@ target_if_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, params->vdevid); return QDF_STATUS_SUCCESS; } - ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(GET_WMI_HDL_FROM_PSOC(psoc), + ret = wmi_unified_set_sta_uapsd_auto_trig_cmd(wmi_handle, params); if (QDF_IS_STATUS_ERROR(ret)) From 5dd541e8f6b630b59e2ea515fad77062ec7f87c2 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Thu, 30 Aug 2018 10:20:31 -0700 Subject: [PATCH 334/404] qcacmn: Fix NULL pointer dereference in policy manager In policy_mgr_is_hw_sbs_capable wmi_handle is derived & dereferenced with out a NULL check. Add a NULL check for wmi_handle before it is dereferenced. Change-Id: I6081bb6f24ce52a3016712d4f1b481f5fb6a9c8f CRs-Fixed: 2305529 --- src/wlan_policy_mgr_get_set_utils.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 73dec446db76..671412cae1c6 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -523,7 +523,7 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) { uint32_t param, i, found = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; - void *wmi_handle; + struct wmi_unified *wmi_handle; pm_ctx = policy_mgr_get_context(psoc); @@ -537,9 +537,9 @@ bool policy_mgr_is_hw_dbs_capable(struct wlan_objmgr_psoc *psoc) return false; } - wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); if (!wmi_handle) { - policy_mgr_debug("Invalid WMA context"); + policy_mgr_debug("Invalid WMI handle"); return false; } @@ -575,7 +575,7 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) { uint32_t param, i, found = 0; struct policy_mgr_psoc_priv_obj *pm_ctx; - void *wmi_handle; + struct wmi_unified *wmi_handle; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -583,7 +583,11 @@ bool policy_mgr_is_hw_sbs_capable(struct wlan_objmgr_psoc *psoc) return false; } - wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + policy_mgr_debug("Invalid WMI handle"); + return false; + } policy_mgr_debug("DBS service bit map: %d", wmi_service_enabled(wmi_handle, @@ -3198,9 +3202,9 @@ bool policy_mgr_allow_sap_go_concurrency(struct wlan_objmgr_psoc *psoc, bool policy_mgr_dual_beacon_on_single_mac_scc_capable( struct wlan_objmgr_psoc *psoc) { - void *wmi_handle = NULL; + struct wmi_unified *wmi_handle; - wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); if (!wmi_handle) { policy_mgr_debug("Invalid WMI handle"); return false; @@ -3219,9 +3223,9 @@ bool policy_mgr_dual_beacon_on_single_mac_scc_capable( bool policy_mgr_dual_beacon_on_single_mac_mcc_capable( struct wlan_objmgr_psoc *psoc) { - void *wmi_handle = NULL; + struct wmi_unified *wmi_handle; - wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); if (!wmi_handle) { policy_mgr_debug("Invalid WMI handle"); return false; From a06b0287833e82feec991c77109a166ca2c93d2d Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Tue, 31 Jul 2018 16:26:38 +0530 Subject: [PATCH 335/404] qcacmn: Featurize P2P Listen Offload P2P Listen offload is not a requirement for Genoa, hence featurize P2P listen offload code to save memory foot-print for Genoa. Change-Id: I3c32b4ee2b37421e49acee4bd20d36e7a8a3bf77 CRs-Fixed: 2304555 --- core/src/wlan_p2p_main.c | 19 ++++- core/src/wlan_p2p_main.h | 9 ++- dispatcher/inc/wlan_p2p_tgt_api.h | 63 +++++++++------ dispatcher/inc/wlan_p2p_ucfg_api.h | 4 + dispatcher/src/wlan_p2p_tgt_api.c | 126 +++++++++++++++-------------- dispatcher/src/wlan_p2p_ucfg_api.c | 2 + 6 files changed, 134 insertions(+), 89 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index b6d3cdc1878e..f66f05718d37 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -789,6 +789,20 @@ QDF_STATUS p2p_psoc_object_close(struct wlan_objmgr_psoc *soc) return QDF_STATUS_SUCCESS; } +#ifdef FEATURE_P2P_LISTEN_OFFLOAD +static inline void p2p_init_lo_event(struct p2p_start_param *start_param, + struct p2p_start_param *req) +{ + start_param->lo_event_cb = req->lo_event_cb; + start_param->lo_event_cb_data = req->lo_event_cb_data; +} +#else +static inline void p2p_init_lo_event(struct p2p_start_param *start_param, + struct p2p_start_param *req) +{ +} +#endif + QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, struct p2p_start_param *req) { @@ -818,8 +832,7 @@ QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, start_param->event_cb_data = req->event_cb_data; start_param->tx_cnf_cb = req->tx_cnf_cb; start_param->tx_cnf_cb_data = req->tx_cnf_cb_data; - start_param->lo_event_cb = req->lo_event_cb; - start_param->lo_event_cb_data = req->lo_event_cb_data; + p2p_init_lo_event(start_param, req); p2p_soc_obj->start_param = start_param; wlan_p2p_init_connection_status(p2p_soc_obj); @@ -995,6 +1008,7 @@ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg) return status; } +#ifdef FEATURE_P2P_LISTEN_OFFLOAD QDF_STATUS p2p_process_lo_stop( struct p2p_lo_stop_event *lo_stop_event) { @@ -1034,6 +1048,7 @@ QDF_STATUS p2p_process_lo_stop( return QDF_STATUS_SUCCESS; } +#endif QDF_STATUS p2p_process_noa(struct p2p_noa_event *noa_event) { diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 5a313abfd51b..ef0fc484794e 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -354,6 +354,7 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg); */ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg); +#ifdef FEATURE_P2P_LISTEN_OFFLOAD /** * p2p_process_lo_stop() - Process lo stop event * @lo_stop_event: listen offload stop event information @@ -365,7 +366,13 @@ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg); */ QDF_STATUS p2p_process_lo_stop( struct p2p_lo_stop_event *lo_stop_event); - +#else +static inline QDF_STATUS p2p_process_lo_stop( + struct p2p_lo_stop_event *lo_stop_event) +{ + return QDF_STATUS_SUCCESS; +} +#endif /** * p2p_process_noa() - Process noa event * @noa_event: noa event information diff --git a/dispatcher/inc/wlan_p2p_tgt_api.h b/dispatcher/inc/wlan_p2p_tgt_api.h index 9f2b140ab742..5412063263bd 100644 --- a/dispatcher/inc/wlan_p2p_tgt_api.h +++ b/dispatcher/inc/wlan_p2p_tgt_api.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 @@ -34,6 +34,20 @@ struct p2p_lo_event; struct mgmt_rx_event_params; enum mgmt_frame_type; +#ifdef FEATURE_P2P_LISTEN_OFFLOAD + +/** + * tgt_p2p_lo_event_cb() - Listen offload stop request + * @psoc: soc object + * @event_info: lo stop event buffer + * + * This function gets called from target interface. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, + struct p2p_lo_event *event_info); + /** * tgt_p2p_register_lo_ev_handler() - register lo event * @psoc: soc object @@ -45,17 +59,6 @@ enum mgmt_frame_type; QDF_STATUS tgt_p2p_register_lo_ev_handler( struct wlan_objmgr_psoc *psoc); -/** - * tgt_p2p_register_noa_ev_handler() - register noa event - * @psoc: soc object - * - * p2p tgt api to register noa event handler. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -QDF_STATUS tgt_p2p_register_noa_ev_handler( - struct wlan_objmgr_psoc *psoc); - /** * tgt_p2p_unregister_lo_ev_handler() - unregister lo event * @psoc: soc object @@ -66,6 +69,30 @@ QDF_STATUS tgt_p2p_register_noa_ev_handler( */ QDF_STATUS tgt_p2p_unregister_lo_ev_handler( struct wlan_objmgr_psoc *psoc); +#else +static inline QDF_STATUS tgt_p2p_register_lo_ev_handler( + struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS tgt_p2p_unregister_lo_ev_handler( + struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * tgt_p2p_register_noa_ev_handler() - register noa event + * @psoc: soc object + * + * p2p tgt api to register noa event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_register_noa_ev_handler( + struct wlan_objmgr_psoc *psoc); /** * tgt_p2p_unregister_noa_ev_handler() - unregister noa event @@ -151,16 +178,4 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, struct p2p_noa_info *event_info); -/** - * tgt_p2p_lo_event_cb() - Listen offload stop request - * @psoc: soc object - * @event_info: lo stop event buffer - * - * This function gets called from target interface. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, - struct p2p_lo_event *event_info); - #endif /* _WLAN_P2P_TGT_API_H_ */ diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/dispatcher/inc/wlan_p2p_ucfg_api.h index 25f0d532c876..0cdc9bd32281 100644 --- a/dispatcher/inc/wlan_p2p_ucfg_api.h +++ b/dispatcher/inc/wlan_p2p_ucfg_api.h @@ -110,8 +110,10 @@ struct p2p_start_param { void *event_cb_data; p2p_action_tx_cnf_callback tx_cnf_cb; void *tx_cnf_cb_data; +#ifdef FEATURE_P2P_LISTEN_OFFLOAD p2p_lo_event_callback lo_event_cb; void *lo_event_cb_data; +#endif }; /** @@ -277,6 +279,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, struct p2p_ps_config *ps_config); +#ifdef FEATURE_P2P_LISTEN_OFFLOAD /** * ucfg_p2p_lo_start() - Listen offload start request * @soc: soc context @@ -301,6 +304,7 @@ QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc, */ QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc, uint32_t vdev_id); +#endif /** * p2p_peer_authorized() - Process peer authorized event diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 17e289de96f9..8fd2236f053d 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -43,6 +43,7 @@ wlan_psoc_get_p2p_tx_ops(struct wlan_objmgr_psoc *psoc) return &(psoc->soc_cb.tx_ops.p2p); } +#ifdef FEATURE_P2P_LISTEN_OFFLOAD QDF_STATUS tgt_p2p_register_lo_ev_handler( struct wlan_objmgr_psoc *psoc) { @@ -58,21 +59,6 @@ QDF_STATUS tgt_p2p_register_lo_ev_handler( return status; } -QDF_STATUS tgt_p2p_register_noa_ev_handler( - struct wlan_objmgr_psoc *psoc) -{ - struct wlan_lmac_if_p2p_tx_ops *p2p_ops; - QDF_STATUS status = QDF_STATUS_E_FAILURE; - - p2p_ops = wlan_psoc_get_p2p_tx_ops(psoc); - if (p2p_ops && p2p_ops->reg_noa_ev_handler) { - status = p2p_ops->reg_noa_ev_handler(psoc, NULL); - p2p_debug("register noa event, status:%d", status); - } - - return status; -} - QDF_STATUS tgt_p2p_unregister_lo_ev_handler( struct wlan_objmgr_psoc *psoc) { @@ -88,6 +74,69 @@ QDF_STATUS tgt_p2p_unregister_lo_ev_handler( return status; } +QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, + struct p2p_lo_event *event_info) +{ + struct p2p_lo_stop_event *lo_stop_event; + struct scheduler_msg msg = {0}; + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_debug("soc:%pK, event_info:%pK", psoc, event_info); + + if (!psoc) { + p2p_err("psoc context passed is NULL"); + if (event_info) + qdf_mem_free(event_info); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("p2p soc object is NULL"); + if (event_info) + qdf_mem_free(event_info); + return QDF_STATUS_E_INVAL; + } + + if (!event_info) { + p2p_err("invalid lo stop event information"); + return QDF_STATUS_E_INVAL; + } + + lo_stop_event = qdf_mem_malloc(sizeof(*lo_stop_event)); + if (!lo_stop_event) { + p2p_err("Failed to allocate p2p lo stop event"); + qdf_mem_free(event_info); + return QDF_STATUS_E_NOMEM; + } + + lo_stop_event->p2p_soc_obj = p2p_soc_obj; + lo_stop_event->lo_event = event_info; + msg.type = P2P_EVENT_LO_STOPPED; + msg.bodyptr = lo_stop_event; + msg.callback = p2p_process_evt; + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + + return QDF_STATUS_SUCCESS; +} +#endif /* FEATURE_P2P_LISTEN_OFFLOAD */ + +QDF_STATUS tgt_p2p_register_noa_ev_handler( + struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_ops = wlan_psoc_get_p2p_tx_ops(psoc); + if (p2p_ops && p2p_ops->reg_noa_ev_handler) { + status = p2p_ops->reg_noa_ev_handler(psoc, NULL); + p2p_debug("register noa event, status:%d", status); + } + + return status; +} + QDF_STATUS tgt_p2p_unregister_noa_ev_handler( struct wlan_objmgr_psoc *psoc) { @@ -288,50 +337,3 @@ QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } - -QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, - struct p2p_lo_event *event_info) -{ - struct p2p_lo_stop_event *lo_stop_event; - struct scheduler_msg msg = {0}; - struct p2p_soc_priv_obj *p2p_soc_obj; - - p2p_debug("soc:%pK, event_info:%pK", psoc, event_info); - - if (!psoc) { - p2p_err("psoc context passed is NULL"); - if (event_info) - qdf_mem_free(event_info); - return QDF_STATUS_E_INVAL; - } - - p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, - WLAN_UMAC_COMP_P2P); - if (!p2p_soc_obj) { - p2p_err("p2p soc object is NULL"); - if (event_info) - qdf_mem_free(event_info); - return QDF_STATUS_E_INVAL; - } - - if (!event_info) { - p2p_err("invalid lo stop event information"); - return QDF_STATUS_E_INVAL; - } - - lo_stop_event = qdf_mem_malloc(sizeof(*lo_stop_event)); - if (!lo_stop_event) { - p2p_err("Failed to allocate p2p lo stop event"); - qdf_mem_free(event_info); - return QDF_STATUS_E_NOMEM; - } - - lo_stop_event->p2p_soc_obj = p2p_soc_obj; - lo_stop_event->lo_event = event_info; - msg.type = P2P_EVENT_LO_STOPPED; - msg.bodyptr = lo_stop_event; - msg.callback = p2p_process_evt; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); - - return QDF_STATUS_SUCCESS; -} diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 1f64b96b8e14..cfeddc9967c4 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -463,6 +463,7 @@ QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, return status; } +#ifdef FEATURE_P2P_LISTEN_OFFLOAD QDF_STATUS ucfg_p2p_lo_start(struct wlan_objmgr_psoc *soc, struct p2p_lo_start *p2p_lo_start) { @@ -511,6 +512,7 @@ QDF_STATUS ucfg_p2p_lo_stop(struct wlan_objmgr_psoc *soc, return status; } +#endif QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, bool disable_noa) From 8c188ac0931b88fbfda1d2e0c8b57b553f78ac44 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Tue, 31 Jul 2018 16:26:38 +0530 Subject: [PATCH 336/404] qcacmn: Featurize P2P Listen Offload P2P Listen offload is not a requirement for Genoa, hence featurize P2P listen offload code to save memory foot-print for Genoa. Change-Id: I3c32b4ee2b37421e49acee4bd20d36e7a8a3bf77 CRs-Fixed: 2304555 --- inc/target_if_p2p.h | 93 +++++++++++----------- src/target_if_p2p.c | 184 +++++++++++++++++++++++--------------------- 2 files changed, 146 insertions(+), 131 deletions(-) diff --git a/inc/target_if_p2p.h b/inc/target_if_p2p.h index dcb46b9519e9..1306e781554b 100644 --- a/inc/target_if_p2p.h +++ b/inc/target_if_p2p.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 @@ -29,13 +29,7 @@ struct wlan_objmgr_psoc; struct p2p_ps_config; struct p2p_lo_start; -/** - * target_if_p2p_register_tx_ops() - Register P2P component TX OPS - * @tx_ops: lmac if transmit ops - * - * Return: None - */ -void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); +#ifdef FEATURE_P2P_LISTEN_OFFLOAD /** * target_if_p2p_register_lo_event_handler() - Register lo event handler @@ -49,18 +43,6 @@ void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); QDF_STATUS target_if_p2p_register_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg); -/** - * target_if_p2p_register_noa_event_handler() - Register noa event handler - * @psoc: soc object - * @arg: additional argument - * - * Target interface API to register P2P noa event handler. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -QDF_STATUS target_if_p2p_register_noa_event_handler( - struct wlan_objmgr_psoc *psoc, void *arg); - /** * target_if_p2p_unregister_lo_event_handler() - Unregister lo event handler * @psoc: soc object @@ -73,6 +55,51 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( QDF_STATUS target_if_p2p_unregister_lo_event_handler( struct wlan_objmgr_psoc *psoc, void *arg); +/** + * target_if_p2p_lo_start() - Start listen offload + * @psoc: soc object + * @lo_start: lo start information + * + * Target interface API to start listen offload. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, + struct p2p_lo_start *lo_start); + +/** + * target_if_p2p_lo_stop() - Stop listen offload + * @psoc: soc object + * @vdev_id: vdev id + * + * Target interface API to stop listen offload. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id); +#endif + +/** + * target_if_p2p_register_tx_ops() - Register P2P component TX OPS + * @tx_ops: lmac if transmit ops + * + * Return: None + */ +void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops); + +/** + * target_if_p2p_register_noa_event_handler() - Register noa event handler + * @psoc: soc object + * @arg: additional argument + * + * Target interface API to register P2P noa event handler. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS target_if_p2p_register_noa_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg); + /** * target_if_p2p_unregister_noa_event_handler() - Unregister noa event handler * @psoc: soc object @@ -95,31 +122,7 @@ QDF_STATUS target_if_p2p_unregister_noa_event_handler( * Return: QDF_STATUS_SUCCESS - in case of success */ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, - struct p2p_ps_config *ps_config); - -/** - * target_if_p2p_lo_start() - Start listen offload - * @psoc: soc object - * @lo_start: lo start information - * - * Target interface API to start listen offload. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, - struct p2p_lo_start *lo_start); - -/** - * target_if_p2p_lo_stop() - Stop listen offload - * @psoc: soc object - * @vdev_id: vdev id - * - * Target interface API to stop listen offload. - * - * Return: QDF_STATUS_SUCCESS - in case of success - */ -QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id); + struct p2p_ps_config *ps_config); /** * target_if_p2p_set_noa() - Disable / Enable NOA diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index 746b4f6cb81a..af30938c89f7 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -32,6 +32,18 @@ target_if_psoc_get_p2p_rx_ops(struct wlan_objmgr_psoc *psoc) return &(psoc->soc_cb.rx_ops.p2p); } +#ifdef FEATURE_P2P_LISTEN_OFFLOAD +static inline void +target_if_p2p_lo_register_tx_ops(struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops) +{ + p2p_tx_ops->lo_start = target_if_p2p_lo_start; + p2p_tx_ops->lo_stop = target_if_p2p_lo_stop; + p2p_tx_ops->reg_lo_ev_handler = + target_if_p2p_register_lo_event_handler; + p2p_tx_ops->unreg_lo_ev_handler = + target_if_p2p_unregister_lo_event_handler; +} + /** * target_p2p_lo_event_handler() - WMI callback for lo stop event * @scn: pointer to scn @@ -98,6 +110,90 @@ static int target_p2p_lo_event_handler(ol_scn_t scn, uint8_t *data, return qdf_status_to_os_return(status); } +QDF_STATUS target_if_p2p_register_lo_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg) +{ + int status; + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); + + target_if_debug("psoc:%pK, arg:%pK", psoc, arg); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_register_event(wmi_handle, + wmi_p2p_lo_stop_event_id, + target_p2p_lo_event_handler); + + target_if_debug("wmi register lo event handle, status:%d", status); + + return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; +} + +QDF_STATUS target_if_p2p_unregister_lo_event_handler( + struct wlan_objmgr_psoc *psoc, void *arg) +{ + int status; + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); + + target_if_debug("psoc:%pK, arg:%pK", psoc, arg); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + status = wmi_unified_unregister_event(wmi_handle, + wmi_p2p_lo_stop_event_id); + + target_if_debug("wmi unregister lo event handle, status:%d", status); + + return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; +} + +QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, + struct p2p_lo_start *lo_start) +{ + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + if (!lo_start) { + target_if_err("lo start parameters is null"); + return QDF_STATUS_E_INVAL; + } + target_if_debug("psoc:%pK, vdev_id:%d", psoc, lo_start->vdev_id); + + return wmi_unified_p2p_lo_start_cmd(wmi_handle, lo_start); +} + +QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, + uint32_t vdev_id) +{ + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); + + target_if_debug("psoc:%pK, vdev_id:%d", psoc, vdev_id); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + return wmi_unified_p2p_lo_stop_cmd(wmi_handle, + (uint8_t)vdev_id); +} +#else +static inline void +target_if_p2p_lo_register_tx_ops(struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops) +{ +} +#endif /* FEATURE_P2P_LISTEN_OFFLOAD */ + /** * target_p2p_noa_event_handler() - WMI callback for noa event * @scn: pointer to scn @@ -164,29 +260,6 @@ static int target_p2p_noa_event_handler(ol_scn_t scn, uint8_t *data, return qdf_status_to_os_return(status); } -QDF_STATUS target_if_p2p_register_lo_event_handler( - struct wlan_objmgr_psoc *psoc, void *arg) -{ - int status; - wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); - - target_if_debug("psoc:%pK, arg:%pK", psoc, arg); - - if (!wmi_handle) { - target_if_err("Invalid wmi handle"); - return QDF_STATUS_E_INVAL; - } - - status = wmi_unified_register_event(wmi_handle, - wmi_p2p_lo_stop_event_id, - target_p2p_lo_event_handler); - - target_if_debug("wmi register lo event handle, status:%d", - status); - - return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; -} - QDF_STATUS target_if_p2p_register_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { @@ -210,28 +283,6 @@ QDF_STATUS target_if_p2p_register_noa_event_handler( return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; } -QDF_STATUS target_if_p2p_unregister_lo_event_handler( - struct wlan_objmgr_psoc *psoc, void *arg) -{ - int status; - wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); - - target_if_debug("psoc:%pK, arg:%pK", psoc, arg); - - if (!wmi_handle) { - target_if_err("Invalid wmi handle"); - return QDF_STATUS_E_INVAL; - } - - status = wmi_unified_unregister_event(wmi_handle, - wmi_p2p_lo_stop_event_id); - - target_if_debug("wmi unregister lo event handle, status:%d", - status); - - return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; -} - QDF_STATUS target_if_p2p_unregister_noa_event_handler( struct wlan_objmgr_psoc *psoc, void *arg) { @@ -297,41 +348,6 @@ QDF_STATUS target_if_p2p_set_ps(struct wlan_objmgr_psoc *psoc, return status; } -QDF_STATUS target_if_p2p_lo_start(struct wlan_objmgr_psoc *psoc, - struct p2p_lo_start *lo_start) -{ - wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); - - if (!wmi_handle) { - target_if_err("Invalid wmi handle"); - return QDF_STATUS_E_INVAL; - } - - if (!lo_start) { - target_if_err("lo start parameters is null"); - return QDF_STATUS_E_INVAL; - } - target_if_debug("psoc:%pK, vdev_id:%d", psoc, lo_start->vdev_id); - - return wmi_unified_p2p_lo_start_cmd(wmi_handle, lo_start); -} - -QDF_STATUS target_if_p2p_lo_stop(struct wlan_objmgr_psoc *psoc, - uint32_t vdev_id) -{ - wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); - - target_if_debug("psoc:%pK, vdev_id:%d", psoc, vdev_id); - - if (!wmi_handle) { - target_if_err("Invalid wmi handle"); - return QDF_STATUS_E_INVAL; - } - - return wmi_unified_p2p_lo_stop_cmd(wmi_handle, - (uint8_t)vdev_id); -} - QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id, bool disable_noa) { @@ -363,15 +379,11 @@ void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) p2p_tx_ops = &tx_ops->p2p; p2p_tx_ops->set_ps = target_if_p2p_set_ps; - p2p_tx_ops->lo_start = target_if_p2p_lo_start; - p2p_tx_ops->lo_stop = target_if_p2p_lo_stop; p2p_tx_ops->set_noa = target_if_p2p_set_noa; - p2p_tx_ops->reg_lo_ev_handler = - target_if_p2p_register_lo_event_handler; p2p_tx_ops->reg_noa_ev_handler = target_if_p2p_register_noa_event_handler; - p2p_tx_ops->unreg_lo_ev_handler = - target_if_p2p_unregister_lo_event_handler; p2p_tx_ops->unreg_noa_ev_handler = target_if_p2p_unregister_noa_event_handler; + /* register P2P listen offload callbacks */ + target_if_p2p_lo_register_tx_ops(p2p_tx_ops); } From 6066a963685c0c467c69a10b70f5c8f8cfd1b46a Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Tue, 31 Jul 2018 16:26:38 +0530 Subject: [PATCH 337/404] qcacmn: Featurize P2P Listen Offload P2P Listen offload is not a requirement for Genoa, hence featurize P2P listen offload code to save memory foot-print for Genoa. Change-Id: I3c32b4ee2b37421e49acee4bd20d36e7a8a3bf77 CRs-Fixed: 2304555 --- src/wlan_cfg80211_p2p.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 5f383e732e35..2cfe0f3bf346 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -168,6 +168,7 @@ fail: wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); } +#ifdef FEATURE_P2P_LISTEN_OFFLOAD /** * wlan_p2p_lo_event_callback() - Callback for listen offload event * @user_data: pointer to soc object @@ -238,6 +239,18 @@ fail: wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); } +static inline void wlan_p2p_init_lo_event(struct p2p_start_param *start_param, + struct wlan_objmgr_psoc *psoc) +{ + start_param->lo_event_cb = wlan_p2p_lo_event_callback; + start_param->lo_event_cb_data = psoc; +} +#else +static inline void wlan_p2p_init_lo_event(struct p2p_start_param *start_param, + struct wlan_objmgr_psoc *psoc) +{ +} +#endif /* FEATURE_P2P_LISTEN_OFFLOAD */ /** * wlan_p2p_event_callback() - Callback for P2P event * @user_data: pointer to soc object @@ -321,8 +334,7 @@ QDF_STATUS wlan_p2p_start(struct wlan_objmgr_psoc *psoc) start_param.event_cb_data = psoc; start_param.tx_cnf_cb = wlan_p2p_action_tx_cnf_callback; start_param.tx_cnf_cb_data = psoc; - start_param.lo_event_cb = wlan_p2p_lo_event_callback; - start_param.lo_event_cb_data = psoc; + wlan_p2p_init_lo_event(&start_param, psoc); return ucfg_p2p_psoc_start(psoc, &start_param); } From ae7b3b1a012ada588b2ab6f56476b2006c341606 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Thu, 6 Sep 2018 19:01:13 +0800 Subject: [PATCH 338/404] qcacmn: Do not remove id when tx action frame Don't remove id tx action frame, since it will be removed when cleanup related ROC. Limit the ROC duration if the original ROC duration is very long. Change-Id: I78e34710530a32f88e955471c974f7078df2e0a9 CRs-Fixed: 2302008 --- core/src/wlan_p2p_off_chan_tx.c | 5 ++++- core/src/wlan_p2p_roc.c | 22 ++++++++++++++-------- core/src/wlan_p2p_roc.h | 11 +++-------- dispatcher/src/wlan_p2p_ucfg_api.c | 3 ++- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 275442a70850..73e53e78b3ad 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -966,6 +966,7 @@ static QDF_STATUS p2p_roc_req_for_tx_action( roc_ctx->roc_state = ROC_STATE_IDLE; roc_ctx->roc_type = OFF_CHANNEL_TX; roc_ctx->tx_ctx = tx_ctx; + roc_ctx->id = tx_ctx->id; tx_ctx->roc_cookie = (uintptr_t)roc_ctx; p2p_debug("create roc request for off channel tx, tx ctx:%pK, roc ctx:%pK", @@ -1244,7 +1245,8 @@ static QDF_STATUS p2p_remove_tx_context( } end: - qdf_idr_remove(&p2p_soc_obj->p2p_idr, tx_ctx->id); + if (!tx_ctx->roc_cookie) + qdf_idr_remove(&p2p_soc_obj->p2p_idr, tx_ctx->id); qdf_mem_free(tx_ctx->buf); qdf_mem_free(tx_ctx); @@ -1885,6 +1887,7 @@ QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) fail: p2p_send_tx_conf(tx_ctx, false); + qdf_idr_remove(&p2p_soc_obj->p2p_idr, tx_ctx->id); qdf_mem_free(tx_ctx->buf); qdf_mem_free(tx_ctx); diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 13b85f291e6e..7a1e35842894 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -365,14 +365,20 @@ static QDF_STATUS p2p_execute_roc_req(struct p2p_roc_context *roc_ctx) } roc_ctx->roc_state = ROC_STATE_REQUESTED; - go_num = policy_mgr_mode_specific_connection_count( - p2p_soc_obj->soc, PM_P2P_GO_MODE, NULL); - p2p_debug("present go number:%d", go_num); - if (go_num) - roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_PRESENT; - else - roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_ABSENT; - + if (roc_ctx->duration < P2P_MAX_ROC_DURATION) { + go_num = policy_mgr_mode_specific_connection_count( + p2p_soc_obj->soc, PM_P2P_GO_MODE, NULL); + p2p_debug("present go number:%d", go_num); + if (go_num) + roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_PRESENT; + else + roc_ctx->duration *= P2P_ROC_DURATION_MULTI_GO_ABSENT; + /* this is to protect too huge value if some customers + * give a higher value from supplicant + */ + if (roc_ctx->duration > P2P_MAX_ROC_DURATION) + roc_ctx->duration = P2P_MAX_ROC_DURATION; + } status = p2p_scan_start(roc_ctx); if (status != QDF_STATUS_SUCCESS) { qdf_mc_timer_destroy(&roc_ctx->roc_timer); diff --git a/core/src/wlan_p2p_roc.h b/core/src/wlan_p2p_roc.h index 2bce9a4b68b5..5e49b1497647 100644 --- a/core/src/wlan_p2p_roc.h +++ b/core/src/wlan_p2p_roc.h @@ -30,16 +30,11 @@ #define P2P_EVENT_PROPAGATE_TIME 10 #define P2P_WAIT_CANCEL_ROC 1000 #define P2P_WAIT_CLEANUP_ROC 2000 +#define P2P_MAX_ROC_DURATION 1500 -#ifdef QCA_WIFI_3_0_EMU -#define P2P_ROC_DURATION_MULTI_GO_PRESENT 2 -#define P2P_ROC_DURATION_MULTI_GO_ABSENT 3 -#define P2P_ACTION_FRAME_DEFAULT_WAIT 500 -#else -#define P2P_ROC_DURATION_MULTI_GO_PRESENT 2 -#define P2P_ROC_DURATION_MULTI_GO_ABSENT 5 +#define P2P_ROC_DURATION_MULTI_GO_PRESENT 6 +#define P2P_ROC_DURATION_MULTI_GO_ABSENT 10 #define P2P_ACTION_FRAME_DEFAULT_WAIT 200 -#endif struct wlan_objmgr_vdev; struct scan_event; diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index cfeddc9967c4..70ff4c660698 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -392,10 +392,11 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, } if (QDF_STATUS_SUCCESS != qdf_idr_find(&p2p_soc_obj->p2p_idr, - cookie, &tx_ctx)) { + (int32_t)cookie, &tx_ctx)) { p2p_debug("invalid id"); return QDF_STATUS_E_INVAL; } + qdf_idr_remove(&p2p_soc_obj->p2p_idr, (int32_t)cookie); cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx)); if (!cancel_tx) { From ea5d70a34ac03e51d9385d15475019c4a1c2a309 Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Mon, 23 Jul 2018 19:26:57 +0530 Subject: [PATCH 339/404] qcacmn: Add mtrace logging for P2P module We are transitioning to new logging infrastructure by using existing mtrace functionality. Add new logging for complete P2P module. Change-Id: I34b1f3b0db9e9b5cfd4ae779cca14584e9b68841 CRs-Fixed: 2308565 --- core/src/wlan_p2p_roc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index 7a1e35842894..db2d5714e3c2 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -160,6 +160,9 @@ static QDF_STATUS p2p_scan_abort(struct p2p_roc_context *roc_ctx) req->cancel_req.vdev_id = roc_ctx->vdev_id; req->cancel_req.req_type = WLAN_SCAN_CANCEL_SINGLE; + qdf_mtrace(QDF_MODULE_ID_P2P, QDF_MODULE_ID_SCAN, + req->cancel_req.req_type, + req->vdev->vdev_objmgr.vdev_id, req->cancel_req.scan_id); status = ucfg_scan_cancel(req); p2p_debug("abort scan, scan req id:%d, scan id:%d, status:%d", From 10a46e915bcc3973bdb9cec2e1fe1259ebd701a1 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 6 Sep 2018 14:38:13 +0530 Subject: [PATCH 340/404] qcacmn: Send TDLS set state disable command in concurrency TDLS is not supported in concurrency and FW expects set state disable command in concurrency. Currently, disable command is sent only if the active connection is present when second interface comes up. Send disable command to FW irrespecive of active TDLS connections. Change-Id: I0716a6caf76a8a69da2225f22e385ce259c231b6 CRs-Fixed: 2305714 --- core/src/wlan_tdls_ct.c | 7 +++++++ core/src/wlan_tdls_main.c | 31 ++++++------------------------- core/src/wlan_tdls_main.h | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 4e0b4cdbb531..6d4c1fb21037 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1180,6 +1180,7 @@ void tdls_disable_offchan_and_teardown_links( struct tdls_vdev_priv_obj *tdls_vdev; struct tdls_soc_priv_obj *tdls_soc; QDF_STATUS status; + uint8_t vdev_id; status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); if (QDF_STATUS_SUCCESS != status) { @@ -1197,6 +1198,12 @@ void tdls_disable_offchan_and_teardown_links( if (!connected_tdls_peers) { tdls_notice("No TDLS connected peers to delete"); + vdev_id = vdev->vdev_objmgr.vdev_id; + if (tdls_soc->set_state_info.set_state_cnt > 0) { + tdls_debug("Disable the tdls in FW as second interface is coming up"); + tdls_send_update_to_fw(tdls_vdev, tdls_soc, true, + true, false, vdev_id); + } return; } diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 66ebc7edb56e..55a810ba1f0c 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -717,31 +717,12 @@ void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc) tdls_process_session_update(psoc, TDLS_CMD_SESSION_DECREMENT); } -/** - * tdls_send_update_to_fw - update tdls status info - * @tdls_vdev_obj: tdls vdev private object. - * @tdls_prohibited: indicates whether tdls is prohibited. - * @tdls_chan_swit_prohibited: indicates whether tdls channel switch - * is prohibited. - * @sta_connect_event: indicate sta connect or disconnect event - * @session_id: session id - * - * Normally an AP does not influence TDLS connection between STAs - * associated to it. But AP may set bits for TDLS Prohibited or - * TDLS Channel Switch Prohibited in Extended Capability IE in - * Assoc/Re-assoc response to STA. So after STA is connected to - * an AP, call this function to update TDLS status as per those - * bits set in Ext Cap IE in received Assoc/Re-assoc response - * from AP. - * - * Return: None. - */ -static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, - struct tdls_soc_priv_obj *tdls_soc_obj, - bool tdls_prohibited, - bool tdls_chan_swit_prohibited, - bool sta_connect_event, - uint8_t session_id) +void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited, + bool sta_connect_event, + uint8_t session_id) { struct tdls_info *tdls_info_to_fw; struct tdls_config_params *threshold_params; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 753866ed07cb..da149aec5992 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -616,6 +616,32 @@ QDF_STATUS tdls_peers_deleted_notification( */ void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc); +/** + * tdls_send_update_to_fw - update tdls status info + * @tdls_vdev_obj: tdls vdev private object. + * @tdls_prohibited: indicates whether tdls is prohibited. + * @tdls_chan_swit_prohibited: indicates whether tdls channel switch + * is prohibited. + * @sta_connect_event: indicate sta connect or disconnect event + * @session_id: session id + * + * Normally an AP does not influence TDLS connection between STAs + * associated to it. But AP may set bits for TDLS Prohibited or + * TDLS Channel Switch Prohibited in Extended Capability IE in + * Assoc/Re-assoc response to STA. So after STA is connected to + * an AP, call this function to update TDLS status as per those + * bits set in Ext Cap IE in received Assoc/Re-assoc response + * from AP. + * + * Return: None. + */ +void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited, + bool sta_connect_event, + uint8_t session_id); + /** * tdls_notify_increment_session() - Notify the session increment * @psoc: psoc object manager From 3c1a394b25c6f0189420876215aaf293ed0134ff Mon Sep 17 00:00:00 2001 From: Min Liu Date: Fri, 7 Sep 2018 16:31:20 +0800 Subject: [PATCH 341/404] qcacmn: Fix vdev ref issue in tdls_process_del_peer vdev ref is not released in some error path of tdls_process_del_peer, which will lead to vdev obj failed to be deleted. Change-Id: I439af4abbb4670d9252296b39d75eb435bb436fc CRs-Fixed: 2311161 --- core/src/wlan_tdls_cmds_process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 90805709fc6a..f5240e66b2fe 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1141,7 +1141,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) if (!req || !req->vdev) { tdls_err("req: %pK", req); status = QDF_STATUS_E_INVAL; - goto error; + goto free_req; } vdev = req->vdev; @@ -1213,6 +1213,8 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) return status; error: status = tdls_internal_del_peer_rsp(req); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +free_req: qdf_mem_free(req); return status; } From a6c1ffdcafc5efdf82931813c83d0245c200ee0c Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Wed, 11 Jul 2018 20:46:06 +0530 Subject: [PATCH 342/404] qcacmn: Add mtrace logging for scan request We are transitioning to new logging infrastructure by using existing mtrace functionality. Add new logging for complete scan request and response path. Change-Id: Iac644a78ef521721d33ce7568be56b47c55fed6b CRs-Fixed: 2308272 --- core/src/wlan_p2p_roc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index db2d5714e3c2..c4ca27ef8d7a 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -906,6 +906,9 @@ void p2p_scan_event_cb(struct wlan_objmgr_vdev *vdev, p2p_err("Failed to find valid P2P roc context"); return; } + + qdf_mtrace(QDF_MODULE_ID_SCAN, QDF_MODULE_ID_P2P, event->type, + event->vdev_id, event->scan_id); switch (event->type) { case SCAN_EVENT_TYPE_STARTED: p2p_process_scan_start_evt(curr_roc_ctx); From bd8b24bbcd148638ddc4be31b0f27ca362ebfdcf Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 5 Sep 2018 23:13:52 -0400 Subject: [PATCH 343/404] qcacmn: allow STA SAP SCC on DFS If sta_sap_scc_on_dfs_chan = 1, we allow the SAP on STA's DFS chan. Allow this for DBS chip as well. Change-Id: I115984c0e659ca00f244d7b477daf4ccb3f2ccd2 CRs-Fixed: 2306801 --- src/wlan_policy_mgr_action.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index d9be9c19b876..e2295cf93156 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1447,6 +1447,12 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( pm_ctx->pdev, channel) || !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) || policy_mgr_is_safe_channel(psoc, channel))) { + if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) && + sta_sap_scc_on_dfs_chan) { + policy_mgr_debug("STA SAP SCC is allowed on DFS channel"); + goto update_chan; + } + if (policy_mgr_is_hw_dbs_capable(psoc)) { temp_channel = policy_mgr_get_alternate_channel_for_sap(psoc); @@ -1468,11 +1474,6 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( return QDF_STATUS_E_FAILURE; } } else { - if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) && - sta_sap_scc_on_dfs_chan) { - policy_mgr_debug("STA SAP SCC is allowed on DFS channel"); - goto update_chan; - } policy_mgr_warn("Can't have concurrency on %d", channel); return QDF_STATUS_E_FAILURE; From c54f1a6f2d0eccba8526cde3e2ae1eb820ed116d Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Wed, 5 Sep 2018 10:58:05 -0700 Subject: [PATCH 344/404] qcacmn: Fix policy manager utfw API to delete all connection policy_mgr_decr_connection_count_utfw() API is using policy_mgr_psoc_enable() API to reset policy manager table as well as timer deinit but it does more than resetting the table which causes a stablity issue. For example, policy_mgr_psoc_enable() API calls to reinitialization connection_update_done_evt event which triggers stability issue as it has been already initialized once. Purpose of delete all connection option is, to reset the policy manager table, to reset any timers which can be achieved by calling policy_mgr_psoc_disable() followed by policy_mgr_psoc_enable() Change-Id: Ie3328e150ead99418ddd5025b42a2669e95e1553 CRs-Fixed: 2305419 --- src/wlan_policy_mgr_action.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index e2295cf93156..22c07a0bd777 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -2084,6 +2084,11 @@ QDF_STATUS policy_mgr_decr_connection_count_utfw(struct wlan_objmgr_psoc *psoc, QDF_STATUS status; if (del_all) { + status = policy_mgr_psoc_disable(psoc); + if (!QDF_IS_STATUS_SUCCESS(status)) { + policy_mgr_err("Policy manager initialization failed"); + return QDF_STATUS_E_FAILURE; + } status = policy_mgr_psoc_enable(psoc); if (!QDF_IS_STATUS_SUCCESS(status)) { policy_mgr_err("Policy manager initialization failed"); From dfa388a856a62efcabc70abf0fc34431956cc47b Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Sun, 9 Sep 2018 13:24:17 +0530 Subject: [PATCH 345/404] qcacmn: Avoid possible NULL dereference Avoid possible NULL dereference in function tdls_get_all_peers_from_list. Change-Id: I0d7dce6b8cabf5b8cee4429dbc2d5e64f1f32ce8 CRs-Fixed: 2311960 --- core/src/wlan_tdls_ct.h | 4 +- core/src/wlan_tdls_main.c | 195 ++++++++++++---------- core/src/wlan_tdls_main.h | 10 -- dispatcher/inc/wlan_tdls_public_structs.h | 6 + 4 files changed, 112 insertions(+), 103 deletions(-) diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index 6c8dbf680f04..00e03f20d14f 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -209,7 +209,7 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, /** * tdls_set_tdls_offchannel() - set tdls off-channel number * @tdls_soc: tdls soc object - * @offchanmode: tdls off-channel number + * @offchannel: tdls off-channel number * * This function sets tdls off-channel number * @@ -221,7 +221,7 @@ int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, /** * tdls_set_tdls_offchannelmode() - set tdls off-channel mode * @adapter: Pointer to the HDD adapter - * @offchannel: tdls off-channel mode + * @offchanmode: tdls off-channel mode * * This function sets tdls off-channel mode * diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 55a810ba1f0c..60153249af7c 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -254,6 +254,110 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, return status; } +/** + * __tdls_get_all_peers_from_list() - get all the tdls peers from the list + * @get_tdls_peers: get_tdls_peers object + * + * Return: int + */ +static int __tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers) +{ + int i; + int len, init_len; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *curr_peer; + char *buf; + int buf_len; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status; + + tdls_notice("Enter "); + + buf = get_tdls_peers->buf; + buf_len = get_tdls_peers->buf_len; + + if (!tdls_is_vdev_connected(get_tdls_peers->vdev)) { + len = qdf_scnprintf(buf, buf_len, + "\nSTA is not associated\n"); + return len; + } + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev); + + if (!tdls_vdev) { + len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n"); + return len; + } + + init_len = buf_len; + len = qdf_scnprintf(buf, buf_len, + "\n%-18s%-3s%-4s%-3s%-5s\n", + "MAC", "Id", "cap", "up", "RSSI"); + buf += len; + buf_len -= len; + len = qdf_scnprintf(buf, buf_len, + "---------------------------------\n"); + buf += len; + buf_len -= len; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_peer = qdf_container_of(p_node, + struct tdls_peer, node); + if (buf_len < 32 + 1) + break; + len = qdf_scnprintf(buf, buf_len, + QDF_MAC_ADDR_STR "%3d%4s%3s%5d\n", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->sta_id, + (curr_peer->tdls_support == + TDLS_CAP_SUPPORTED) ? "Y" : "N", + TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" : + "N", curr_peer->rssi); + buf += len; + buf_len -= len; + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + + tdls_notice("Exit "); + return init_len - buf_len; +} + +/** + * tdls_get_all_peers_from_list() - get all the tdls peers from the list + * @get_tdls_peers: get_tdls_peers object + * + * Return: None + */ +static void tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers) +{ + int32_t len; + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_osif_indication indication; + + if (!get_tdls_peers->vdev) { + qdf_mem_free(get_tdls_peers); + return; + } + len = __tdls_get_all_peers_from_list(get_tdls_peers); + + indication.status = len; + indication.vdev = get_tdls_peers->vdev; + + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev); + if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) + tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, + TDLS_EVENT_USER_CMD, &indication); + + qdf_mem_free(get_tdls_peers); +} + QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -1004,97 +1108,6 @@ static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev) tdls_timers_stop(tdls_vdev); } -static int __tdls_get_all_peers_from_list( - struct tdls_get_all_peers *get_tdls_peers) -{ - int i; - int len, init_len; - qdf_list_t *head; - qdf_list_node_t *p_node; - struct tdls_peer *curr_peer; - char *buf; - int buf_len; - struct tdls_vdev_priv_obj *tdls_vdev; - QDF_STATUS status; - - tdls_notice("Enter "); - - buf = get_tdls_peers->buf; - buf_len = get_tdls_peers->buf_len; - - if (!tdls_is_vdev_connected(get_tdls_peers->vdev)) { - len = qdf_scnprintf(buf, buf_len, - "\nSTA is not associated\n"); - return len; - } - - tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev); - - if (!tdls_vdev) { - len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n"); - return len; - } - - init_len = buf_len; - len = qdf_scnprintf(buf, buf_len, - "\n%-18s%-3s%-4s%-3s%-5s\n", - "MAC", "Id", "cap", "up", "RSSI"); - buf += len; - buf_len -= len; - len = qdf_scnprintf(buf, buf_len, - "---------------------------------\n"); - buf += len; - buf_len -= len; - - for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { - head = &tdls_vdev->peer_list[i]; - status = qdf_list_peek_front(head, &p_node); - while (QDF_IS_STATUS_SUCCESS(status)) { - curr_peer = qdf_container_of(p_node, - struct tdls_peer, node); - if (buf_len < 32 + 1) - break; - len = qdf_scnprintf(buf, buf_len, - QDF_MAC_ADDR_STR "%3d%4s%3s%5d\n", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), - curr_peer->sta_id, - (curr_peer->tdls_support == - TDLS_CAP_SUPPORTED) ? "Y" : "N", - TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" : - "N", curr_peer->rssi); - buf += len; - buf_len -= len; - status = qdf_list_peek_next(head, p_node, &p_node); - } - } - - tdls_notice("Exit "); - return init_len - buf_len; -} - -void tdls_get_all_peers_from_list( - struct tdls_get_all_peers *get_tdls_peers) -{ - int32_t len; - struct tdls_soc_priv_obj *tdls_soc_obj; - struct tdls_osif_indication indication; - - if (!get_tdls_peers->vdev) - qdf_mem_free(get_tdls_peers); - - len = __tdls_get_all_peers_from_list(get_tdls_peers); - - indication.status = len; - indication.vdev = get_tdls_peers->vdev; - - tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev); - if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) - tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, - TDLS_EVENT_USER_CMD, &indication); - - qdf_mem_free(get_tdls_peers); -} - void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) { if (!vdev) { diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index da149aec5992..421d6f2bd0d0 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -573,16 +573,6 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); - -/** - * tdls_get_all_peers_from_list() - get all the tdls peers from the list - * @get_tdls_peers: get_tdls_peers object - * - * Return: None - */ -void tdls_get_all_peers_from_list( - struct tdls_get_all_peers *get_tdls_peers); - /** * tdls_notify_reset_adapter() - notify reset adapter * @vdev: vdev object manager diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 3ecf2dfd26d9..6ab5f663fb08 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1110,7 +1110,9 @@ struct tdls_antenna_switch_request { /** * struct tdls_set_offchannel - TDLS set offchannel + * @vdev: vdev object * @offchannel: Updated tdls offchannel value. + * @callback: callback to release vdev ref. */ struct tdls_set_offchannel { struct wlan_objmgr_vdev *vdev; @@ -1120,7 +1122,9 @@ struct tdls_set_offchannel { /** * struct tdls_set_offchan_mode - TDLS set offchannel mode + * @vdev: vdev object * @offchan_mode: Updated tdls offchannel mode value. + * @callback: callback to release vdev ref. */ struct tdls_set_offchanmode { struct wlan_objmgr_vdev *vdev; @@ -1130,7 +1134,9 @@ struct tdls_set_offchanmode { /** * struct tdls_set_offchan_offset - TDLS set offchannel mode + * @vdev: vdev object * @offchan_offset: Offchan offset value. + * @callback: callback to release vdev ref. */ struct tdls_set_secoffchanneloffset { struct wlan_objmgr_vdev *vdev; From d5d2ce4d04bab459a6ba1651a426ef6c8a7da04a Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 28 Aug 2018 19:54:03 +0530 Subject: [PATCH 346/404] qcacmn: Add src, and dst id support in P2P In the scheduler_post_message, src_id is now added to know the source module of the msg. the present scheduler doesn't know about the same which is scheduler_post_msg Replace the scheduler_post_msg with scheduler_post_message Change-Id: I558adf0cf0335972a1318a5a33d22dc01d545645 CRs-Fixed: 2306015 --- core/src/wlan_p2p_main.c | 4 +++- core/src/wlan_p2p_off_chan_tx.c | 4 +++- core/src/wlan_p2p_roc.c | 4 +++- dispatcher/src/wlan_p2p_tgt_api.c | 16 ++++++++++++---- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index f66f05718d37..a8989ad26af6 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -452,7 +452,9 @@ static QDF_STATUS p2p_send_noa_to_pe(struct p2p_noa_info *noa_info) msg.type = P2P_NOA_ATTR_IND; msg.bodyval = 0; msg.bodyptr = noa_attr; - scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_PE, &msg); return QDF_STATUS_SUCCESS; } diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 73e53e78b3ad..71ac3ee5a87f 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -1683,7 +1683,9 @@ QDF_STATUS p2p_cleanup_tx_sync( msg.type = P2P_CLEANUP_TX; msg.bodyptr = param; msg.callback = p2p_process_cmd; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, &msg); if (status != QDF_STATUS_SUCCESS) { p2p_err("failed to post message"); qdf_mem_free(param); diff --git a/core/src/wlan_p2p_roc.c b/core/src/wlan_p2p_roc.c index c4ca27ef8d7a..10db8e74d4c3 100644 --- a/core/src/wlan_p2p_roc.c +++ b/core/src/wlan_p2p_roc.c @@ -723,7 +723,9 @@ QDF_STATUS p2p_cleanup_roc_sync( msg.type = P2P_CLEANUP_ROC; msg.bodyptr = param; msg.callback = p2p_process_cmd; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, &msg); if (status != QDF_STATUS_SUCCESS) { p2p_err("failed to post message"); qdf_mem_free(param); diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 8fd2236f053d..3dbc7ff0cd9c 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -116,8 +116,10 @@ QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, msg.type = P2P_EVENT_LO_STOPPED; msg.bodyptr = lo_stop_event; msg.callback = p2p_process_evt; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_TARGET_IF, &msg); return QDF_STATUS_SUCCESS; } #endif /* FEATURE_P2P_LISTEN_OFFLOAD */ @@ -198,7 +200,9 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, msg.type = P2P_EVENT_MGMT_TX_ACK_CNF; msg.bodyptr = tx_conf_event; msg.callback = p2p_process_evt; - ret = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + ret = scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_TARGET_IF, &msg); if (ret != QDF_STATUS_SUCCESS) { qdf_mem_free(tx_conf_event); qdf_mem_free(buf); @@ -284,7 +288,9 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, msg.type = P2P_EVENT_RX_MGMT; msg.bodyptr = rx_mgmt_event; msg.callback = p2p_process_evt; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_TARGET_IF, &msg); qdf_nbuf_free(buf); @@ -333,7 +339,9 @@ QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, msg.type = P2P_EVENT_NOA; msg.bodyptr = noa_event; msg.callback = p2p_process_evt; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_TARGET_IF, &msg); return QDF_STATUS_SUCCESS; } From f744acaff76174829014d506dc2502cdb8f75bcf Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 28 Aug 2018 19:34:37 +0530 Subject: [PATCH 347/404] qcacmn: Add src, and dst id support in UCFG/HDD In the scheduler_post_message, src_id is now added to know the source module of the msg. the present scheduler doesn't know about the same which is scheduler_post_msg Replace the scheduler_post_msg with scheduler_post_message Change-Id: I37532d323a0945b522087a23a65396ba2899fb5b CRs-Fixed: 2306011 --- dispatcher/src/wlan_tdls_ucfg_api.c | 48 +++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 5b76f0e80afb..a87b42be126c 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -464,7 +464,9 @@ QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, msg.bodyptr = req; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_ADD_STA; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("post add peer msg fail"); qdf_mem_free(req); @@ -508,7 +510,9 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, msg.bodyptr = req; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_CHANGE_STA; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("post update peer msg fail"); qdf_mem_free(req); @@ -571,7 +575,9 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, msg.bodyptr = req; msg.callback = tdls_process_cmd; msg.type = cmd; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("post msg for %s fail", tdls_get_oper_str(cmd)); goto dec_ref; @@ -606,7 +612,9 @@ QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, msg.bodyptr = tdls_peers; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_GET_ALL_PEERS; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (status != QDF_STATUS_SUCCESS) qdf_mem_free(tdls_peers); @@ -648,7 +656,9 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( msg.bodyptr = mgmt_req; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_TX_ACTION; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); return QDF_STATUS_SUCCESS; } @@ -675,7 +685,9 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) msg.bodyptr = msg_req; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_SET_RESPONDER; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); return status; } @@ -694,7 +706,9 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) msg.bodyptr = vdev; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_TEARDOWN_LINKS; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); tdls_debug("Exit "); return status; @@ -713,7 +727,9 @@ QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) msg.bodyptr = vdev; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_RESET_ADAPTERS; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); return status; } @@ -738,7 +754,9 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_CONNECTION; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); tdls_debug("Exit "); return QDF_STATUS_SUCCESS; @@ -766,7 +784,9 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); tdls_debug("Exit "); @@ -798,7 +818,9 @@ QDF_STATUS ucfg_tdls_set_operating_mode( msg.bodyptr = set_mode; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_SET_TDLS_MODE; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); tdls_debug("Exit "); @@ -856,7 +878,9 @@ QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, msg.callback = tdls_process_cmd; msg.flush_callback = tdls_antenna_switch_flush_callback; msg.type = TDLS_CMD_ANTENNA_SWITCH; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("post antenna switch msg fail"); goto dec_ref; From 6255d23e9e1a3c6012c4ee04fa2549bd66fb8428 Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 28 Aug 2018 19:34:37 +0530 Subject: [PATCH 348/404] qcacmn: Add src, and dst id support in UCFG/HDD In the scheduler_post_message, src_id is now added to know the source module of the msg. the present scheduler doesn't know about the same which is scheduler_post_msg Replace the scheduler_post_msg with scheduler_post_message Change-Id: I37532d323a0945b522087a23a65396ba2899fb5b CRs-Fixed: 2306011 --- dispatcher/src/wlan_p2p_ucfg_api.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 70ff4c660698..563b1dc392f1 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -159,7 +159,9 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, msg.type = P2P_ROC_REQ; msg.bodyptr = roc_ctx; msg.callback = p2p_process_cmd; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, &msg); p2p_debug("cookie = 0x%llx", *cookie); return QDF_STATUS_SUCCESS; @@ -204,7 +206,9 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, msg.type = P2P_CANCEL_ROC_REQ; msg.bodyptr = cancel_roc; msg.callback = p2p_process_cmd; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, &msg); return QDF_STATUS_SUCCESS; } @@ -364,7 +368,9 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, msg.type = P2P_MGMT_TX; msg.bodyptr = tx_action; msg.callback = p2p_process_cmd; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, &msg); return QDF_STATUS_SUCCESS; } @@ -409,7 +415,9 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, msg.type = P2P_MGMT_TX_CANCEL; msg.bodyptr = cancel_tx; msg.callback = p2p_process_cmd; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, &msg); return QDF_STATUS_SUCCESS; } From c5d0228b58d56ee30ee26b9d2dc2fb78e05f5b5b Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 28 Aug 2018 19:50:21 +0530 Subject: [PATCH 349/404] qcacmn: Add src, and dst id support in TDLS In the scheduler_post_message, src_id is now added to know the source module of the msg. the present scheduler doesn't know about the same which is scheduler_post_msg Replace the scheduler_post_msg with scheduler_post_message Change-Id: I184827ec58625dc60be67b8f16aa7e698ecc893e CRs-Fixed: 2306014 --- core/src/wlan_tdls_cmds_process.c | 16 ++++++++++++---- core/src/wlan_tdls_ct.c | 4 +++- core/src/wlan_tdls_main.c | 12 +++++++++--- core/src/wlan_tdls_mgmt.c | 4 +++- dispatcher/src/wlan_tdls_tgt_api.c | 8 ++++++-- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index f5240e66b2fe..2933bae26c48 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -167,7 +167,9 @@ static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); msg.type = soc_obj->tdls_add_sta_req; msg.bodyptr = addstareq; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("fail to post pe msg to add peer"); goto error; @@ -232,7 +234,9 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) QDF_MAC_ADDR_ARRAY(delstareq->peermac.bytes)); msg.type = soc_obj->tdls_del_sta_req; msg.bodyptr = delstareq; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("fail to post pe msg to del peer"); goto error; @@ -318,7 +322,9 @@ static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) msg.type = soc_obj->tdls_add_sta_req; msg.bodyptr = addstareq; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("fail to post pe msg to update peer"); goto error; @@ -1561,7 +1567,9 @@ tdls_wma_update_peer_state(struct tdls_soc_priv_obj *soc_obj, msg.reserved = 0; msg.bodyptr = peer_state; - status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("scheduler_post_msg failed"); status = QDF_STATUS_E_FAILURE; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 6d4c1fb21037..95ddd82ac94c 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1165,7 +1165,9 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, msg.type = del_msg->msg_type; msg.bodyptr = del_msg; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); return status; diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 60153249af7c..d969d250693d 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -806,7 +806,9 @@ static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc, msg.callback = tdls_process_cmd; msg.type = (uint16_t)cmd_type; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) tdls_alert("message post failed "); } @@ -1142,7 +1144,9 @@ QDF_STATUS tdls_peers_deleted_notification( msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(notify); tdls_alert("message post failed "); @@ -1381,7 +1385,9 @@ static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) msg.bodyptr = tdls_soc; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_SCAN_DONE; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); return QDF_STATUS_SUCCESS; } diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 38b93d1cab7c..af73df1e8660 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -305,7 +305,9 @@ static QDF_STATUS tdls_activate_send_mgmt_request( msg.type = tdls_soc_obj->tdls_send_mgmt_req; msg.bodyptr = tdls_mgmt_req; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_PE, &msg); wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); release_mgmt_ref: diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 5c58a73361dd..a6eb77716fc3 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -205,7 +205,9 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, msg.bodyptr = notify; msg.callback = tdls_process_evt; - status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't post msg to handle tdls event"); wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID); @@ -283,7 +285,9 @@ QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( msg.type = TDLS_EVENT_RX_MGMT; msg.bodyptr = rx_mgmt_event; msg.callback = tdls_process_rx_frame; - status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); qdf_nbuf_free(buf); From c05a19115e0da14b60274739aa3fa2dbd44f30c6 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Tue, 18 Sep 2018 15:53:50 -0700 Subject: [PATCH 350/404] qcacmn: Reduce log level in policy manager Reduce log level from error to debug in policy_mgr_convert_device_mode_to_qdf_type, policy_mgr_get_qdf_mode_from_pm, policy_mgr_decr_active_session, policy_mgr_decr_session_set_pcl. Change-Id: I236c6770b87c5a4d4888cb6249aaf128b1cdcb8f CRs-Fixed: 2317899 --- src/wlan_policy_mgr_get_set_utils.c | 10 +++++----- src/wlan_policy_mgr_pcl.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 671412cae1c6..64ad5c2cdd12 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1287,7 +1287,7 @@ QDF_STATUS policy_mgr_decr_active_session(struct wlan_objmgr_psoc *psoc, policy_mgr_convert_device_mode_to_qdf_type(mode), session_id); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - policy_mgr_err("No connection with mode:%d vdev_id:%d", + policy_mgr_debug("No connection with mode:%d vdev_id:%d", policy_mgr_convert_device_mode_to_qdf_type(mode), session_id); return qdf_status; @@ -2238,8 +2238,8 @@ enum policy_mgr_con_mode policy_mgr_convert_device_mode_to_qdf_type( mode = PM_IBSS_MODE; break; default: - policy_mgr_err("Unsupported mode (%d)", - device_mode); + policy_mgr_debug("Unsupported mode (%d)", + device_mode); } return mode; @@ -2267,8 +2267,8 @@ enum QDF_OPMODE policy_mgr_get_qdf_mode_from_pm( mode = QDF_IBSS_MODE; break; default: - policy_mgr_err("Unsupported policy mgr mode (%d)", - device_mode); + policy_mgr_debug("Unsupported policy mgr mode (%d)", + device_mode); } return mode; } diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 9db76d523103..8f91e024aea6 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -114,7 +114,7 @@ void policy_mgr_decr_session_set_pcl(struct wlan_objmgr_psoc *psoc, qdf_status = policy_mgr_decr_active_session(psoc, mode, session_id); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { - policy_mgr_err("Invalid active session"); + policy_mgr_debug("Invalid active session"); return; } From 6fdaf77b6d7c247f317522c7ea1975a44082ba67 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Thu, 30 Aug 2018 13:23:30 +0800 Subject: [PATCH 351/404] qcacmn: MCL part change after serialization enhancement 1. Keep serialization legacy api not broken. Serialization enhancement have much changes on internal struct and API, need re-implement serialization legacy APIs. 2. Set all cmds on MCL platform as blocking type. MCL dones't support cmd concurrency on multi vdevs, while WIN need it. Change-Id: I5d5d6e0e16becb0b0f285fd8ed20982f2819659c CRs-Fixed: 2315407 --- core/src/wlan_tdls_cmds_process.c | 3 +++ core/src/wlan_tdls_mgmt.c | 1 + 2 files changed, 4 insertions(+) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 2933bae26c48..ded673c0b5fd 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -825,6 +825,7 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) cmd.is_high_priority = false; cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; cmd.vdev = vdev; + cmd.is_blocking = true; ser_cmd_status = wlan_serialization_request(&cmd); tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, @@ -1034,6 +1035,7 @@ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) cmd.is_high_priority = false; cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; cmd.vdev = req->vdev; + cmd.is_blocking = true; ser_cmd_status = wlan_serialization_request(&cmd); tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, @@ -1187,6 +1189,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) cmd.is_high_priority = false; cmd.cmd_timeout_duration = WAIT_TIME_TDLS_DEL_STA; cmd.vdev = vdev; + cmd.is_blocking = true; ser_cmd_status = wlan_serialization_request(&cmd); tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index af73df1e8660..e60d2824c655 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -403,6 +403,7 @@ QDF_STATUS tdls_process_mgmt_req( cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; cmd.vdev = tdls_mgmt_req->vdev; + cmd.is_blocking = true; ser_cmd_status = wlan_serialization_request(&cmd); tdls_debug("wlan_serialization_request status:%d", ser_cmd_status); From d525947221764566890451afd3402ec8f817eba1 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 19 Sep 2018 16:23:57 +0800 Subject: [PATCH 352/404] qcacmn: Fix KW issue in tdls Potential NULL pointer dereferences of wmi_handle are found in these functions: target_if_tdls_event_handler() target_if_tdls_register_event_handler() target_if_tdls_unregister_event_handler() Do wmi_handle NULL check in the above functions. Change-Id: I7cb4b574750d6bc6538862aa24a0cf49831b7c25 CRs-Fixed: 2317029 --- src/target_if_tdls.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/target_if_tdls.c b/src/target_if_tdls.c index f6b248e93d53..6adb2622319e 100644 --- a/src/target_if_tdls.c +++ b/src/target_if_tdls.c @@ -59,6 +59,11 @@ target_if_tdls_event_handler(ol_scn_t scn, uint8_t *data, uint32_t datalen) } wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("null wmi_handle"); + return -EINVAL; + } + if (wmi_extract_vdev_tdls_ev_param(wmi_handle, data, &info)) { target_if_err("Failed to extract wmi tdls event"); return -EINVAL; @@ -163,19 +168,31 @@ QDF_STATUS target_if_tdls_register_event_handler(struct wlan_objmgr_psoc *psoc, void *arg) { - return wmi_unified_register_event( - get_wmi_unified_hdl_from_psoc(psoc), - wmi_tdls_peer_event_id, - target_if_tdls_event_handler); + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("null wmi_handle"); + return QDF_STATUS_E_INVAL; + } + return wmi_unified_register_event(wmi_handle, + wmi_tdls_peer_event_id, + target_if_tdls_event_handler); } QDF_STATUS target_if_tdls_unregister_event_handler(struct wlan_objmgr_psoc *psoc, void *arg) { - return wmi_unified_unregister_event( - get_wmi_unified_hdl_from_psoc(psoc), - wmi_tdls_peer_event_id); + struct wmi_unified *wmi_handle; + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("null wmi_handle"); + return QDF_STATUS_E_INVAL; + } + return wmi_unified_unregister_event(wmi_handle, + wmi_tdls_peer_event_id); } QDF_STATUS From 11eab431ebd0f543abb2168b6bcab123f3b9c5aa Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 25 Sep 2018 13:51:01 +0530 Subject: [PATCH 353/404] qcacmn: Fix double free of qdf idr Currently, As part of mgmt tx request qdf id is alloted and it is removed as part of mgmt tx cancel and the same idr value is stored in roc context and that idr is removed once again during roc context destroy that lead to double free of the same qdf idr. This will result in subsequent mgmt tx cancel failures. Dont remove qdf idr as part of mgmt tx cancel. Change-Id: I7c6f19f6d50e7f5eef216eedfa750f058dbc1ba6 CRs-Fixed: 2320990 --- dispatcher/src/wlan_p2p_ucfg_api.c | 1 - 1 file changed, 1 deletion(-) diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 563b1dc392f1..da0f423b90b3 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -402,7 +402,6 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, p2p_debug("invalid id"); return QDF_STATUS_E_INVAL; } - qdf_idr_remove(&p2p_soc_obj->p2p_idr, (int32_t)cookie); cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx)); if (!cancel_tx) { From 31e789e40f8aa6fba86a44fa1dd0460c1f354981 Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Fri, 14 Sep 2018 15:11:46 -0700 Subject: [PATCH 354/404] qcacmn: Make policy_mgr_pdev_set_pcl as public API Make policy_mgr_pdev_set_pcl as public API Remove SET PCL for STA vdev from policy manager as it is being done now from the roaming start cmd core function which is csr_roam_offload_scan() Change-Id: I3fc0eb4d37278a67a1f18579cec7d65e491bd967 CRs-Fixed: 2320734 --- inc/wlan_policy_mgr_api.h | 10 ++++++++++ src/wlan_policy_mgr_get_set_utils.c | 12 ------------ src/wlan_policy_mgr_i.h | 2 -- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 0fdf5110b199..6cc9fad844a9 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -229,6 +229,16 @@ static inline void policy_mgr_change_sap_channel_with_csa( } #endif +/** + * policy_mgr_pdev_set_pcl() - SET PCL channel list and send to firmware + * @psoc: PSOC object information + * @mode: Adapter mode + * + * Return: None + */ +void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE mode); + /** * policy_mgr_incr_active_session() - increments the number of active sessions * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 64ad5c2cdd12..3fdc26773b7b 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1219,18 +1219,6 @@ void policy_mgr_incr_active_session(struct wlan_objmgr_psoc *psoc, policy_mgr_debug("No.# of active sessions for mode %d = %d", mode, pm_ctx->no_of_active_sessions[mode]); - /* - * Get PCL logic makes use of the connection info structure. - * Let us set the PCL to the FW before updating the connection - * info structure about the new connection. - */ - if (mode == QDF_STA_MODE) { - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - /* Set PCL of STA to the FW */ - policy_mgr_pdev_set_pcl(psoc, mode); - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - policy_mgr_debug("Set PCL of STA to FW"); - } policy_mgr_incr_connection_count(psoc, session_id); if ((policy_mgr_mode_specific_connection_count( psoc, PM_STA_MODE, NULL) > 0) && (mode != QDF_STA_MODE)) { diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index f079276d81fc..31e90e3a6490 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -423,8 +423,6 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, enum policy_mgr_conn_update_reason reason, uint32_t session_id, void *context); void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc); -void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, - enum QDF_OPMODE mode); void policy_mgr_set_pcl_for_existing_combo( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); void pm_dbs_opportunistic_timer_handler(void *data); From 89036a7c26769f881eb2d38f276f60c58bf4bf63 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Mon, 1 Oct 2018 14:50:15 -0700 Subject: [PATCH 355/404] qcacmn: Protect sap restart work for driver unload Protect sap restart work handler from SSR to avoid accessing data structures which are freed already. Change-Id: I75d2032b022aa68817ec102cbe65f635a627eb82 CRs-Fixed: 2325966 --- src/wlan_policy_mgr_action.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 22c07a0bd777..191384b81f07 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -31,6 +31,7 @@ #include "qdf_types.h" #include "qdf_trace.h" #include "wlan_objmgr_global_obj.h" +#include "qdf_platform.h" enum policy_mgr_conc_next_action (*policy_mgr_get_current_pref_hw_mode_ptr) (struct wlan_objmgr_psoc *psoc); @@ -1286,15 +1287,7 @@ bool policy_mgr_is_sap_restart_required_after_sta_disconnect( return true; } -/** - * policy_mgr_check_sta_ap_concurrent_ch_intf() - Restart SAP in STA-AP case - * @data: Pointer check concurrent channel work data - * - * Restarts the SAP interface in STA-AP concurrency scenario - * - * Restart: None - */ -void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) +static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) { struct wlan_objmgr_psoc *psoc; struct policy_mgr_psoc_priv_obj *pm_ctx = NULL; @@ -1305,6 +1298,11 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) uint8_t operating_channel[MAX_NUMBER_OF_CONC_CONNECTIONS]; uint8_t vdev_id[MAX_NUMBER_OF_CONC_CONNECTIONS]; + if (qdf_is_module_state_transitioning()) { + policy_mgr_err("Module transition in progress"); + goto end; + } + work_info = (struct sta_ap_intf_check_work_ctx *) data; if (!work_info) { policy_mgr_err("Invalid work_info"); @@ -1379,6 +1377,13 @@ end: } } +void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) +{ + qdf_ssr_protect(__func__); + __policy_mgr_check_sta_ap_concurrent_ch_intf(data); + qdf_ssr_unprotect(__func__); +} + static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc, uint8_t sta_channel) { From a105eeecdb8ec4df96710c28a59ec78089c22e9c Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Wed, 3 Oct 2018 10:51:38 +0530 Subject: [PATCH 356/404] qcacmn: Update TDLS opclass correctly to FW Due to change in Opclass calculation in the new regulatory component invalid opclass is returned for the TDLS component. Update arguments to calculate opclass correctly to regulatory component. Change-Id: I062bbb55d283f9525da241d32177e26d07aa8590 CRs-Fixed: 2325834 --- core/src/wlan_tdls_ct.c | 10 ++++++---- dispatcher/inc/wlan_tdls_public_structs.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 95ddd82ac94c..d7c50ab7c68f 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -979,17 +979,19 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, switch (offchanoffset) { case TDLS_SEC_OFFCHAN_OFFSET_0: - tdls_soc->tdls_channel_offset = (1 << BW_20_OFFSET_BIT); + tdls_soc->tdls_channel_offset = BW20; break; case TDLS_SEC_OFFCHAN_OFFSET_40PLUS: + tdls_soc->tdls_channel_offset = BW40_LOW_PRIMARY; + break; case TDLS_SEC_OFFCHAN_OFFSET_40MINUS: - tdls_soc->tdls_channel_offset = (1 << BW_40_OFFSET_BIT); + tdls_soc->tdls_channel_offset = BW40_LOW_PRIMARY; break; case TDLS_SEC_OFFCHAN_OFFSET_80: - tdls_soc->tdls_channel_offset = (1 << BW_80_OFFSET_BIT); + tdls_soc->tdls_channel_offset = BW80; break; case TDLS_SEC_OFFCHAN_OFFSET_160: - tdls_soc->tdls_channel_offset = (1 << BW_160_OFFSET_BIT); + tdls_soc->tdls_channel_offset = BWALL; break; default: tdls_err("Invalid tdls secondary off channel offset %d", diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 6ab5f663fb08..3aa85b71aeb5 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1140,7 +1140,7 @@ struct tdls_set_offchanmode { */ struct tdls_set_secoffchanneloffset { struct wlan_objmgr_vdev *vdev; - uint8_t offchan_offset; + int offchan_offset; tdls_offchan_parms_callback callback; }; From 93b3c7fdba0d11bff4afcbe59bbc692ed9a61d0f Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Thu, 23 Aug 2018 21:46:44 +0530 Subject: [PATCH 357/404] qcacmn: Add SRD channel check in restart SAP Currently the driver doesn't have a check to bring up a SAP on STA SCC channel if its a SRD channel and does force SCC on it, even if SRD master mode is not supported. Fix is to check the SRD ini before SAP bringup on the STA channel. Change-Id: I850d8b252afb20d9e4374e1fb4932d7ef17f3e51 CRs-Fixed: 2302742 --- src/wlan_policy_mgr_action.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 191384b81f07..ab5dff442c96 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1448,10 +1448,11 @@ QDF_STATUS policy_mgr_valid_sap_conc_channel_check( if (policy_mgr_valid_sta_channel_check(psoc, channel)) { if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) || - wlan_reg_is_passive_or_disable_ch( - pm_ctx->pdev, channel) || + wlan_reg_is_passive_or_disable_ch(pm_ctx->pdev, channel) || !(policy_mgr_sta_sap_scc_on_lte_coex_chan(psoc) || - policy_mgr_is_safe_channel(psoc, channel))) { + policy_mgr_is_safe_channel(psoc, channel)) || + (!reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx->pdev) + && reg_is_etsi13_srd_chan(pm_ctx->pdev, channel))) { if (wlan_reg_is_dfs_ch(pm_ctx->pdev, channel) && sta_sap_scc_on_dfs_chan) { policy_mgr_debug("STA SAP SCC is allowed on DFS channel"); From 9ba5f5e9f94c9713a23ec726cd443c432f645a2d Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Thu, 4 Oct 2018 01:36:09 +0530 Subject: [PATCH 358/404] qcacmn: Fix BSS scoring params Currently the driver calculates the nss score based upon the max capability of the AP, and not the hw_mde config which would be there after connection for example, the driver calculates the score for a 2x2 11n AP, and 1x1 VHT (11ac) AP, it connects to the 11n AP in 1x1 mode, if a concurrent connection is present, which affects throughput Fix is to check whether the current AP channel results in DBS or not, if yes then change the NSS to 1 instead of 2 Change-Id: I80e2af00044b760325eb1a51b09a45189d58a417 CRs-Fixed: 2271976 --- inc/wlan_policy_mgr_api.h | 14 ++++++++++++++ src/wlan_policy_mgr_action.c | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 6cc9fad844a9..c09031a0a29b 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -125,6 +125,20 @@ uint8_t policy_mgr_search_and_check_for_session_conc( struct wlan_objmgr_psoc *psoc, uint8_t session_id, void *roam_profile); +/** + * policy_mgr_is_chnl_in_diff_band() - to check that given channel + * is in diff band from existing channel or not + * @psoc: pointer to psoc + * @channel: given channel + * + * This API will check that if the passed channel is in diff band than the + * already existing connections or not. + * + * Return: true if channel is in diff band + */ +bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, + uint8_t channel); + /** * policy_mgr_check_for_session_conc() - Check if concurrency is * allowed for a session diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index ab5dff442c96..1cad53c5f7bf 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -444,7 +444,7 @@ bool policy_mgr_is_dbs_allowed_for_concurrency( return ret; } -static bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, +bool policy_mgr_is_chnl_in_diff_band(struct wlan_objmgr_psoc *psoc, uint8_t channel) { uint8_t i, pm_chnl; From 1acaac7e9441649372d78494b2a3637d7a66d03a Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Mon, 8 Oct 2018 12:47:26 -0700 Subject: [PATCH 359/404] qcacmn: Fix OOB in __policy_mgr_check_sta_ap_concurrent_ch_intf Fix out of bound array access for operating_channel[] in __policy_mgr_check_sta_ap_concurrent_ch_intf. Change-Id: I3945d2fd5b1e3d02a9e827ba4a907b48b4170fd2 CRs-Fixed: 2329332 --- src/wlan_policy_mgr_action.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 1cad53c5f7bf..5c1d4a344f6d 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1334,10 +1334,13 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) &vdev_id[cc_count], PM_SAP_MODE); policy_mgr_debug("Number of concurrent SAP: %d", cc_count); - cc_count = cc_count + policy_mgr_get_mode_specific_conn_info(psoc, - &operating_channel[cc_count], - &vdev_id[cc_count], - PM_P2P_GO_MODE); + if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) + cc_count = cc_count + + policy_mgr_get_mode_specific_conn_info + (psoc, + &operating_channel[cc_count], + &vdev_id[cc_count], + PM_P2P_GO_MODE); policy_mgr_debug("Number of beaconing entities (SAP + GO):%d", cc_count); if (!cc_count) { @@ -1357,16 +1360,18 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) policy_mgr_err("SAP restart get channel callback in NULL"); goto end; } - for (i = 0; i < cc_count; i++) { - status = pm_ctx->hdd_cbacks. - wlan_hdd_get_channel_for_sap_restart(psoc, + if (cc_count < MAX_NUMBER_OF_CONC_CONNECTIONS) + for (i = 0; i < cc_count; i++) { + status = pm_ctx->hdd_cbacks. + wlan_hdd_get_channel_for_sap_restart + (psoc, vdev_id[i], &channel, &sec_ch); - if (status == QDF_STATUS_SUCCESS) { - policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d" + if (status == QDF_STATUS_SUCCESS) { + policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d" , operating_channel[i], channel); - break; + break; + } } - } if (status != QDF_STATUS_SUCCESS) policy_mgr_err("Failed to switch SAP channel"); end: From af9e1da39ed2ce6ec95b57ce96aa28697f52e3eb Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Wed, 10 Oct 2018 17:21:01 -0700 Subject: [PATCH 360/404] qcacmn: Make policy_mgr_set_pcl_for_existing_combo as public API Make policy_mgr_set_pcl_for_existing_combo as public API Move policy_mgr_pdev_set_pcl to policy manager internal header file Change-Id: I6ef45fb34c4bc4bc0c07cad6f546a777922fde9d CRs-Fixed: 2331254 --- inc/wlan_policy_mgr_api.h | 9 ++++----- src/wlan_policy_mgr_i.h | 12 ++++++++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index c09031a0a29b..da66a3e47e8b 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -244,15 +244,14 @@ static inline void policy_mgr_change_sap_channel_with_csa( #endif /** - * policy_mgr_pdev_set_pcl() - SET PCL channel list and send to firmware + * policy_mgr_set_pcl_for_existing_combo() - SET PCL for existing combo * @psoc: PSOC object information - * @mode: Adapter mode + * @mode: Adapter mode * * Return: None */ -void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, - enum QDF_OPMODE mode); - +void policy_mgr_set_pcl_for_existing_combo(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode); /** * policy_mgr_incr_active_session() - increments the number of active sessions * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 31e90e3a6490..c5a54dbd8d51 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -423,8 +423,16 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status, enum policy_mgr_conn_update_reason reason, uint32_t session_id, void *context); void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc); -void policy_mgr_set_pcl_for_existing_combo( - struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode); + +/** + * policy_mgr_pdev_set_pcl() - SET PCL channel list and send to firmware + * @psoc: PSOC object information + * @mode: Adapter mode + * + * Return: None + */ +void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc, + enum QDF_OPMODE mode); void pm_dbs_opportunistic_timer_handler(void *data); enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type, uint8_t subtype); From fd4e3d3ee3ada8287d8fafd9a169b60db00b732e Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 15 Oct 2018 14:31:36 +0530 Subject: [PATCH 361/404] qcacmn: Remove TDLS mgmt tx command from active list If bss peer is freed after posting TDLS mgmt request command to serialization component. Free the tdls mgmt req command from active list. Change-Id: I6bf2c3518dfc64052470375e4018e56abdcfcabb CRs-Fixed: 2333288 --- core/src/wlan_tdls_cmds_process.c | 2 +- core/src/wlan_tdls_cmds_process.h | 13 +++++++++++++ core/src/wlan_tdls_mgmt.c | 10 +++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index ded673c0b5fd..8c9f985a5e72 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -97,7 +97,7 @@ static char *tdls_get_ser_cmd_str(enum wlan_serialization_cmd_type type) } } -static void +void tdls_release_serialization_command(struct wlan_objmgr_vdev *vdev, enum wlan_serialization_cmd_type type) { diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index da14cfa6ab9f..bebf1b099f54 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -291,6 +291,19 @@ QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp); void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, uint8_t action_code); +/** + * tdls_release_serialization_command() - TDLS wrapper to + * relases serialization command. + * @vdev: Object manager vdev + * @type: command to release. + * + * Return: None + */ + +void +tdls_release_serialization_command(struct wlan_objmgr_vdev *vdev, + enum wlan_serialization_cmd_type type); + /** * tdls_set_cap() - set TDLS capability type * @tdls_vdev: tdls vdev object diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index e60d2824c655..8b051ac36871 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -206,7 +206,6 @@ tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request *req, indication.status = status; indication.vdev = req->vdev; - tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, @@ -272,8 +271,8 @@ static QDF_STATUS tdls_activate_send_mgmt_request( peer = wlan_vdev_get_bsspeer(action_req->vdev); - if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer, - WLAN_TDLS_SB_ID)) { + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID); + if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(tdls_mgmt_req); goto release_mgmt_ref; } @@ -315,6 +314,11 @@ release_mgmt_ref: /*update tdls nss infornation based on action code */ tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_internal_send_mgmt_tx_done(action_req, status); + tdls_release_serialization_command(action_req->vdev, + WLAN_SER_CMD_TDLS_SEND_MGMT); + } return status; } From 909a73c15b9aa33f63911768b7ee0e16650bf7d9 Mon Sep 17 00:00:00 2001 From: Qiwei Cai Date: Mon, 17 Sep 2018 19:17:13 +0800 Subject: [PATCH 362/404] qcacmn: Featurize WMI APIs and TLVs that are specific to MCL In the existing converged component, WMI TLV APIs are implemented in a generic manner without proper featurization. All the APIs exposed outside of WMI are implemented in wmi_unified_api.c and all the APIs forming the CMD or extracting the EVT is implemented in wmi_unified_tlv.c. Since WIN and MCL have a unified WMI layer in the converged component and there are features within WIN and MCL that are not common, there exists a good number of WMI APIs which are specific to WIN but compiled by MCL and vice-versa. Due to this inadvertent problem, there is a chunk of code and memory used up by WIN and MCL for features that are not used in their products. Featurize WMI APIs and TLVs that are specific to MCL - - DSRC - NAN - P2P - PMO - roaming - concurrency - STA - Generic MCL specific WMI (STA) Change-Id: I03a68b0db30a3aa585b269ab0a1745b37bc7e0b7 CRs-Fixed: 2316935 --- dispatcher/inc/wlan_p2p_public_struct.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/dispatcher/inc/wlan_p2p_public_struct.h b/dispatcher/inc/wlan_p2p_public_struct.h index 4f156c633d7c..0c8eb282e47a 100644 --- a/dispatcher/inc/wlan_p2p_public_struct.h +++ b/dispatcher/inc/wlan_p2p_public_struct.h @@ -27,6 +27,28 @@ #define P2P_MAX_NOA_DESC 4 +/** + * struct p2p_ps_params - P2P powersave related params + * @opp_ps: opportunistic power save + * @ctwindow: CT window + * @count: count + * @duration: duration + * @interval: interval + * @single_noa_duration: single shot noa duration + * @ps_selection: power save selection + * @session_id: session id + */ +struct p2p_ps_params { + uint8_t opp_ps; + uint32_t ctwindow; + uint8_t count; + uint32_t duration; + uint32_t interval; + uint32_t single_noa_duration; + uint8_t ps_selection; + uint8_t session_id; +}; + /** * struct p2p_roc_req - P2P roc request * @vdev_id: Vdev id on which this request has come From 42e98abae19fc862c26db3a2994fdd6fe606eff7 Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Thu, 27 Sep 2018 18:35:21 -0700 Subject: [PATCH 363/404] qcacmn: Add new INI/CFG infrastructure for Policy Manager Policy Manager component needs to adopt a new INI/CFG infrastructure Provide a new infrastructure and remove old INI/CFGs related to policy manager component. CRs-Fixed: 2324395 Change-Id: Ia16845c2aef3c5877b0b164fcef13fe7cd41c736 --- inc/wlan_policy_mgr_api.h | 91 ++++++++++ inc/wlan_policy_mgr_cfg.h | 255 ++++++++++++++++++++++++++++ inc/wlan_policy_mgr_ucfg.h | 143 ++++++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 122 +++++++++++++ src/wlan_policy_mgr_i.h | 23 +++ src/wlan_policy_mgr_ucfg.c | 123 ++++++++++++++ 6 files changed, 757 insertions(+) create mode 100644 inc/wlan_policy_mgr_cfg.h create mode 100644 inc/wlan_policy_mgr_ucfg.h create mode 100644 src/wlan_policy_mgr_ucfg.c diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index da66a3e47e8b..202896167519 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -64,6 +64,97 @@ typedef const enum policy_mgr_conc_next_action ((channel_select_logic_conc & PM_FW_MODE_STA_P2P_BIT_MASK) >> \ PM_FW_MODE_STA_P2P_BIT_POS) +/** + * policy_mgr_get_mcc_scc_switch() - To mcc to scc switch setting from INI + * @psoc: pointer to psoc + * @mcc_scc_switch: value to be filled + * + * This API pulls mcc to scc switch setting which is given as part of INI and + * stored in policy manager's CFGs. + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc, + uint8_t *mcc_scc_switch); +/** + * policy_mgr_get_sys_pref() - to get system preference + * @psoc: pointer to psoc + * @sys_pref: value to be filled + * + * This API pulls the system preference for policy manager to provide + * PCL + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, + uint8_t *sys_pref); +/** + * policy_mgr_get_max_conc_cxns() - to get max num of conc connections + * @psoc: pointer to psoc + * @max_conc_cxns: value to be filled + * + * This API pulls max number of active connections which can be allowed + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc, + uint8_t *max_conc_cxns); +/** + * policy_mgr_get_conc_rule1() - to find out if conc rule1 is enabled + * @psoc: pointer to psoc + * @conc_rule1: value to be filled + * + * This API is used to find out if conc rule-1 is enabled by user + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc, + uint8_t *conc_rule1); +/** + * policy_mgr_get_conc_rule2() - to find out if conc rule2 is enabled + * @psoc: pointer to psoc + * @conc_rule2: value to be filled + * + * This API is used to find out if conc rule-2 is enabled by user + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc, + uint8_t *conc_rule2); +/** + * policy_mgr_get_dbs_selection_plcy() - DBS HW mode selection setting + * @psoc: pointer to psoc + * @dbs_selection_policy: value to be filled + * + * This API is used to find out DBS HW mode preference. + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc, + uint32_t *dbs_selection_policy); +/** + * policy_mgr_get_vdev_priority_list() - to get vdev priority list + * @psoc: pointer to psoc + * @vdev_priority_list: value to be filled + * + * This API is used to find out vdev_priority_list setting + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc, + uint32_t *vdev_priority_list); +/** + * policy_mgr_get_chnl_select_plcy() - to get channel selection policy + * @psoc: pointer to psoc + * @chnl_select_plcy: value to be filled + * + * This API is used to find out which channel selection policy has been + * configured + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, + uint32_t *chnl_select_plcy); /** * policy_mgr_set_concurrency_mode() - To set concurrency mode * @psoc: PSOC object data diff --git a/inc/wlan_policy_mgr_cfg.h b/inc/wlan_policy_mgr_cfg.h new file mode 100644 index 000000000000..19b0495859ac --- /dev/null +++ b/inc/wlan_policy_mgr_cfg.h @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2012-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 + * 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. + */ + +#ifndef __CFG_POLICY_MGR +#define __CFG_POLICY_MGR +#include "qdf_types.h" + +/* + * + * gWlanMccToSccSwitchMode - Control SAP channel. + * @Min: 0 + * @Max: 5 + * @Default: 0 + * + * This ini is used to override SAP channel. + * If gWlanMccToSccSwitchMode = 0: disabled. + * If gWlanMccToSccSwitchMode = 1: Enable switch. + * If gWlainMccToSccSwitchMode = 2: Force switch with SAP restart. + * If gWlainMccToSccSwitchMode = 3: Force switch without SAP restart. + * If gWlainMccToSccSwitchMode = 4: Switch using + * fav channel(s)without SAP restart. + * If gWlainMccToSccSwitchMode = 5: Force switch without SAP restart.MCC allowed + * in exceptional cases. + * If gWlainMccToSccSwitchMode = 6: Force Switch without SAP restart only in + user preffered band. + * Related: None. + * + * Supported Feature: Concurrency + * + * Usage: Internal/External + * + * + */ +#define CFG_MCC_TO_SCC_SWITCH CFG_INI_UINT(\ + "gWlanMccToSccSwitchMode", \ + QDF_MCC_TO_SCC_SWITCH_DISABLE, \ + QDF_MCC_TO_SCC_SWITCH_MAX - 1, \ + QDF_MCC_TO_SCC_SWITCH_DISABLE, \ + CFG_VALUE_OR_DEFAULT, \ + "Provides MCC to SCC switch mode") +/* + * + * gSystemPref - Configure wlan system preference for PCL. + * @Min: 0 + * @Max: 2 + * @Default: 0 + * + * This ini is used to configure wlan system preference option to help + * policy manager decide on Preferred Channel List for a new connection. + * For possible values refer to enum hdd_conc_priority_mode + * + * Related: None. + * + * Supported Feature: DBS + * + * Usage: Internal/External + * + * + */ +#define CFG_CONC_SYS_PREF CFG_INI_UINT(\ + "gSystemPref", 0, 2, 0, \ + CFG_VALUE_OR_DEFAULT, \ + "System preference to predict PCL") +/* + * + * gMaxConcurrentActiveSessions - Maximum number of concurrent connections. + * @Min: 1 + * @Max: 4 + * @Default: 3 + * + * This ini is used to configure the maximum number of concurrent connections. + * + * Related: None. + * + * Supported Feature: Concurrency + * + * Usage: Internal/External + * + * + */ +#define CFG_MAX_CONC_CXNS CFG_INI_UINT(\ + "gMaxConcurrentActiveSessions", \ + 1, 4, 3, \ + CFG_VALUE_OR_DEFAULT, \ + "Config max num allowed connections") +/* + * + * channel_select_logic_conc - Set channel selection logic + * for different concurrency combinations to DBS or inter band + * MCC. Default is DBS for STA+STA and STA+P2P. + * @Min: 0x00000000 + * @Max: 0xFFFFFFFF + * @Default: 0x00000000 + * + * 0 - inter-band MCC + * 1 - DBS + * + * BIT 0: STA+STA + * BIT 1: STA+P2P + * BIT 2-31: Reserved + * + * Supported Feature: STA+STA, STA+P2P + * + * Usage: External + * + * + */ +#define CFG_CHNL_SELECT_LOGIC_CONC CFG_INI_UINT(\ + "channel_select_logic_conc",\ + 0x00000000, \ + 0xFFFFFFFF, \ + 0x00000003, \ + CFG_VALUE_OR_DEFAULT, \ + "Set channel selection policy for various concurrency") +/* + * + * dbs_selection_policy - Configure dbs selection policy. + * @Min: 0 + * @Max: 3 + * @Default: 0 + * + * set band preference or Vdev preference. + * bit[0] = 0: 5G 2x2 preferred to select 2x2 5G + 1x1 2G DBS mode. + * bit[0] = 1: 2G 2x2 preferred to select 2x2 2G + 1x1 5G DBS mode. + * bit[1] = 1: vdev priority enabled. The INI "vdev_priority_list" will + * specify the vdev priority. + * bit[1] = 0: vdev priority disabled. + * This INI only take effect for Genoa dual DBS hw. + * + * Supported Feature: DBS + * + * Usage: Internal/External + * + * + */ +#define CFG_DBS_SELECTION_PLCY CFG_INI_UINT(\ + "dbs_selection_policy", \ + 0, 3, 0, \ + CFG_VALUE_OR_DEFAULT, \ + "Configure dbs selection policy") +/* + * + * vdev_priority_list - Configure vdev priority list. + * @Min: 0 + * @Max: 0x4444 + * @Default: 0x4321 + * + * @vdev_priority_list: vdev priority list + * bit[0-3]: pri_id (policy_mgr_pri_id) of highest priority + * bit[4-7]: pri_id (policy_mgr_pri_id) of second priority + * bit[8-11]: pri_id (policy_mgr_pri_id) of third priority + * bit[12-15]: pri_id (policy_mgr_pri_id) of fourth priority + * example: 0x4321 - CLI < GO < SAP < STA + * vdev priority id mapping: + * PM_STA_PRI_ID = 1, + * PM_SAP_PRI_ID = 2, + * PM_P2P_GO_PRI_ID = 3, + * PM_P2P_CLI_PRI_ID = 4, + * When the previous INI "dbs_selection_policy" bit[1]=1, which means + * the vdev 2x2 prioritization enabled. Then this INI will be used to + * specify the vdev type priority list. For example : + * dbs_selection_policy=0x2 + * vdev_priority_list=0x4312 + * means: default preference 2x2 band is 5G, vdev 2x2 prioritization enabled. + * And the priority list is CLI < GO < STA < SAP + * + * This INI only take effect for Genoa dual DBS hw. + * + * Supported Feature: DBS + * + * Usage: Internal/External + * + * + */ +#define CFG_VDEV_CUSTOM_PRIORITY_LIST CFG_INI_UINT(\ + "vdev_priority_list", \ + 0, 0x4444, 0x4321, \ + CFG_VALUE_OR_DEFAULT, \ + "Configure vdev priority list") +/* + * + * gEnableCustomConcRule1 - Enable custom concurrency rule1. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable custom concurrency rule1. + * If SAP comes up first and STA comes up later then SAP needs to follow STA's + * channel. + * + * Related: None. + * + * Supported Feature: Concurrency + * + * Usage: Internal/External + * + * + */ +#define CFG_ENABLE_CONC_RULE1 CFG_INI_UINT(\ + "gEnableCustomConcRule1", \ + 0, 1, 0, \ + CFG_VALUE_OR_DEFAULT, \ + "Enable custom concurrency rule 1") +/* + * + * gEnableCustomConcRule2 - Enable custom concurrency rule2. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable custom concurrency rule2. + * If P2PGO comes up first and STA comes up later then P2PGO need to follow + * STA's channel in 5Ghz. In following if condition we are just adding sanity + * check to make sure that by this time P2PGO's channel is same as STA's + * channel. + * + * Related: None. + * + * Supported Feature: Concurrency + * + * Usage: Internal/External + * + * + */ +#define CFG_ENABLE_CONC_RULE2 CFG_INI_UINT(\ + "gEnableCustomConcRule2", \ + 0, 1, 0, \ + CFG_VALUE_OR_DEFAULT, \ + "Enable custom concurrency rule 2") + +#define CFG_POLICY_MGR_ALL \ + CFG(CFG_MCC_TO_SCC_SWITCH) \ + CFG(CFG_CONC_SYS_PREF) \ + CFG(CFG_MAX_CONC_CXNS) \ + CFG(CFG_DBS_SELECTION_PLCY) \ + CFG(CFG_VDEV_CUSTOM_PRIORITY_LIST) \ + CFG(CFG_CHNL_SELECT_LOGIC_CONC) \ + CFG(CFG_ENABLE_CONC_RULE1) \ + CFG(CFG_ENABLE_CONC_RULE2) +#endif diff --git a/inc/wlan_policy_mgr_ucfg.h b/inc/wlan_policy_mgr_ucfg.h new file mode 100644 index 000000000000..eb17a3c425da --- /dev/null +++ b/inc/wlan_policy_mgr_ucfg.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 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 + * 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. + */ +#ifndef __WLAN_POLICY_MGR_UCFG +#define __WLAN_POLICY_MGR_UCFG +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_objmgr_global_obj.h" +#include "qdf_status.h" + + +/** + * ucfg_policy_mgr_psoc_open() - This API sets CFGs to policy manager context + * + * This API pulls policy manager's context from PSOC and initialize the CFG + * structure of policy manager. + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc); +/** + * ucfg_policy_mgr_psoc_close() - This API resets CFGs for policy manager ctx + * + * This API pulls policy manager's context from PSOC and resets the CFG + * structure of policy manager. + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +void ucfg_policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc); +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * ucfg_policy_mgr_get_mcc_scc_switch() - To mcc to scc switch setting from INI + * @psoc: pointer to psoc + * @mcc_scc_switch: value to be filled + * + * This API pulls mcc to scc switch setting which is given as part of INI and + * stored in policy manager's CFGs. + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc, + uint8_t *mcc_scc_switch); +#else +static inline +QDF_STATUS ucfg_policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc, + uint8_t *mcc_scc_switch) +{ + return QDF_STATUS_SUCCESS; +} +#endif //FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * ucfg_policy_mgr_get_sys_pref() - to get system preference + * @psoc: pointer to psoc + * @sys_pref: value to be filled + * + * This API pulls the system preference for policy manager to provide + * PCL + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, + uint8_t *sys_pref); +/** + * ucfg_policy_mgr_get_max_conc_cxns() - to get max num of conc connections + * @psoc: pointer to psoc + * @max_conc_cxns: value to be filled + * + * This API pulls max number of active connections which can be allowed + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc, + uint8_t *max_conc_cxns); +/** + * ucfg_policy_mgr_get_conc_rule1() - to find out if conc rule1 is enabled + * @psoc: pointer to psoc + * @conc_rule1: value to be filled + * + * This API is used to find out if conc rule-1 is enabled by user + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc, + uint8_t *conc_rule1); +/** + * ucfg_policy_mgr_get_conc_rule2() - to find out if conc rule2 is enabled + * @psoc: pointer to psoc + * @conc_rule2: value to be filled + * + * This API is used to find out if conc rule-2 is enabled by user + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc, + uint8_t *conc_rule2); +/** + * ucfg_policy_mgr_get_dbs_selection_plcy() - DBS HW mode selection setting + * @psoc: pointer to psoc + * @dbs_selection_policy: value to be filled + * + * This API is used to find out DBS HW mode preference. + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc, + uint32_t *dbs_selection_policy); +/** + * ucfg_policy_mgr_get_vdev_priority_list() - to get vdev priority list + * @psoc: pointer to psoc + * @vdev_priority_list: value to be filled + * + * This API is used to find out vdev_priority_list setting + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc, + uint32_t *vdev_priority_list); +/** + * policy_mgr_get_chnl_select_plcy() - to get channel selection policy + * @psoc: pointer to psoc + * @chnl_select_plcy: value to be filled + * + * This API is used to find out which channel selection policy has been + * configured + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, + uint32_t *chnl_select_plcy); +#endif //__WLAN_POLICY_MGR_UCFG diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 3fdc26773b7b..0c65de943518 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -36,6 +36,128 @@ /* invalid channel id. */ #define INVALID_CHANNEL_ID 0 +QDF_STATUS policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc, + uint8_t *mcc_scc_switch) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *mcc_scc_switch = pm_ctx->cfg.mcc_to_scc_switch; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, + uint8_t *sys_pref) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *sys_pref = pm_ctx->cfg.sys_pref; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc, + uint8_t *max_conc_cxns) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *max_conc_cxns = pm_ctx->cfg.max_conc_cxns; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc, + uint8_t *conc_rule1) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *conc_rule1 = pm_ctx->cfg.conc_rule1; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc, + uint8_t *conc_rule2) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *conc_rule2 = pm_ctx->cfg.conc_rule2; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc, + uint32_t *dbs_selection_plcy) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *dbs_selection_plcy = pm_ctx->cfg.dbs_selection_plcy; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc, + uint32_t *vdev_priority_list) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *vdev_priority_list = pm_ctx->cfg.vdev_priority_list; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, + uint32_t *chnl_select_plcy) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *chnl_select_plcy = pm_ctx->cfg.chnl_select_plcy; + + return QDF_STATUS_SUCCESS; +} + + + void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, uint32_t new_hw_mode_index) { diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index c5a54dbd8d51..afc03034d421 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -213,6 +213,28 @@ struct sta_ap_intf_check_work_ctx { struct wlan_objmgr_psoc *psoc; }; +/** + * struct policy_mgr_cfg - all the policy manager owned configs + * @mcc_to_scc_switch: switch to indicate MCC to SCC config + * @sys_pref: system's preference while selecting PCLs + * @max_conc_cxns: Max allowed concurrenct active connections + * @conc_rule1: concurrency rule1 + * @conc_rule2: concurrency rule2 + * @dbs_selection_plcy: DBS selection policy for concurrency + * @vdev_priority_list: Priority list for various vdevs + * @chnl_select_plcy: Channel selection policy + */ +struct policy_mgr_cfg { + uint8_t mcc_to_scc_switch; + uint8_t sys_pref; + uint8_t max_conc_cxns; + uint8_t conc_rule1; + uint8_t conc_rule2; + uint32_t dbs_selection_plcy; + uint32_t vdev_priority_list; + uint32_t chnl_select_plcy; +}; + /** * struct policy_mgr_psoc_priv_obj - Policy manager private data * @psoc: pointer to PSOC object information @@ -298,6 +320,7 @@ struct policy_mgr_psoc_priv_obj { qdf_event_t channel_switch_complete_evt; send_mode_change_event_cb mode_change_cb; uint32_t user_config_sap_channel; + struct policy_mgr_cfg cfg; }; /** diff --git a/src/wlan_policy_mgr_ucfg.c b/src/wlan_policy_mgr_ucfg.c new file mode 100644 index 000000000000..70f9e851635c --- /dev/null +++ b/src/wlan_policy_mgr_ucfg.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 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 + * 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. + */ +#include "wlan_policy_mgr_ucfg.h" +#include "wlan_policy_mgr_i.h" +#include "cfg_ucfg_api.h" +#include "wlan_policy_mgr_api.h" + +static QDF_STATUS policy_mgr_init_cfg(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + struct policy_mgr_cfg *cfg; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + cfg = &pm_ctx->cfg; + + cfg->mcc_to_scc_switch = cfg_get(psoc, CFG_MCC_TO_SCC_SWITCH); + cfg->sys_pref = cfg_get(psoc, CFG_CONC_SYS_PREF); + cfg->max_conc_cxns = cfg_get(psoc, CFG_MAX_CONC_CXNS); + cfg->conc_rule1 = cfg_get(psoc, CFG_ENABLE_CONC_RULE1); + cfg->conc_rule2 = cfg_get(psoc, CFG_ENABLE_CONC_RULE2); + cfg->dbs_selection_plcy = cfg_get(psoc, CFG_DBS_SELECTION_PLCY); + cfg->vdev_priority_list = cfg_get(psoc, CFG_VDEV_CUSTOM_PRIORITY_LIST); + cfg->chnl_select_plcy = cfg_get(psoc, CFG_CHNL_SELECT_LOGIC_CONC); + + return QDF_STATUS_SUCCESS; +} + +static void policy_mgr_deinit_cfg(struct wlan_objmgr_psoc *psoc) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return; + } + + qdf_mem_zero(&pm_ctx->cfg, sizeof(pm_ctx->cfg)); +} + +QDF_STATUS ucfg_policy_mgr_psoc_open(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + + status = policy_mgr_init_cfg(psoc); + if (status != QDF_STATUS_SUCCESS) { + policy_mgr_err("pm_ctx is NULL"); + return status; + } + return QDF_STATUS_SUCCESS; +} + +void ucfg_policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc) +{ + policy_mgr_deinit_cfg(psoc); +} + +QDF_STATUS ucfg_policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc, + uint8_t *mcc_scc_switch) +{ + return policy_mgr_get_mcc_scc_switch(psoc, mcc_scc_switch); +} + +QDF_STATUS ucfg_policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, + uint8_t *sys_pref) +{ + return policy_mgr_get_sys_pref(psoc, sys_pref); +} + +QDF_STATUS ucfg_policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc, + uint8_t *max_conc_cxns) +{ + return policy_mgr_get_max_conc_cxns(psoc, max_conc_cxns);; +} + +QDF_STATUS ucfg_policy_mgr_get_conc_rule1(struct wlan_objmgr_psoc *psoc, + uint8_t *conc_rule1) +{ + return policy_mgr_get_conc_rule1(psoc, conc_rule1); +} + +QDF_STATUS ucfg_policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc, + uint8_t *conc_rule2) +{ + return policy_mgr_get_conc_rule2(psoc, conc_rule2); +} + +QDF_STATUS ucfg_policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc, + uint32_t *dbs_selection_plcy) +{ + return policy_mgr_get_dbs_selection_plcy(psoc, dbs_selection_plcy); +} + +QDF_STATUS ucfg_policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc, + uint32_t *vdev_priority_list) +{ + return policy_mgr_get_vdev_priority_list(psoc, vdev_priority_list); +} + +QDF_STATUS ucfg_policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, + uint32_t *chnl_select_plcy) +{ + return policy_mgr_get_chnl_select_plcy(psoc, chnl_select_plcy); +} From d36b207ac45045513de34fef5866bfe906511ec8 Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Wed, 26 Sep 2018 17:02:14 -0700 Subject: [PATCH 364/404] qcacmn: Refactor operation related to INI gWlanMccToSccSwitchMode Ownership of gWlanMccToSccSwitchMode is changed from HDD to Policy manager. So policy manager doesn't have to rely on HDD to obtain the INI setting. CRs-Fixed: 2324395 Change-Id: Id8bdee52ebf83b1c8b3c8f9132a2fc74b28f42a0 --- inc/wlan_policy_mgr_public_struct.h | 2 -- src/wlan_policy_mgr_action.c | 4 ++-- src/wlan_policy_mgr_core.c | 6 +++--- src/wlan_policy_mgr_get_set_utils.c | 8 ++++---- src/wlan_policy_mgr_i.h | 4 ++-- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 53ec91238654..7782f5c39f39 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1057,7 +1057,6 @@ enum policy_mgr_pri_id { * connections * @conc_system_pref: System preference for PCL table * @enable2x2: 2x2 chain mask user config - * @mcc_to_scc_switch_mode: Control SAP channel in concurrency * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled * @dbs_selection_policy: band preference or Vdev preference * bit[0] = 0: 5G 2x2 preferred to select 2x2 5G + 1x1 2G DBS mode. @@ -1076,7 +1075,6 @@ struct policy_mgr_user_cfg { uint8_t max_concurrent_active_sessions; uint8_t conc_system_pref; bool enable2x2; - uint32_t mcc_to_scc_switch_mode; bool sub_20_mhz_enabled; bool is_sta_sap_scc_allowed_on_dfs_chan; uint32_t channel_select_logic_conc; diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 5c1d4a344f6d..ac2ddf75df79 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1321,7 +1321,7 @@ static void __policy_mgr_check_sta_ap_concurrent_ch_intf(void *data) goto end; } mcc_to_scc_switch = - policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); + policy_mgr_get_mcc_to_scc_switch_mode(psoc); policy_mgr_info("Concurrent open sessions running: %d", policy_mgr_concurrent_open_sessions_running(psoc)); @@ -1556,7 +1556,7 @@ void policy_mgr_check_concurrent_intf_and_restart_sap( } mcc_to_scc_switch = - policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); + policy_mgr_get_mcc_to_scc_switch_mode(psoc); policy_mgr_info("MCC to SCC switch: %d chan: %d", mcc_to_scc_switch, operating_channel[0]); diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 6fb55a412f0c..e3f78bba11ce 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -155,7 +155,7 @@ bool policy_mgr_is_dual_mac_disabled_in_ini( return is_disabled; } -uint32_t policy_mgr_mcc_to_scc_switch_mode_in_user_cfg( +uint32_t policy_mgr_get_mcc_to_scc_switch_mode( struct wlan_objmgr_psoc *psoc) { struct policy_mgr_psoc_priv_obj *pm_ctx; @@ -166,7 +166,7 @@ uint32_t policy_mgr_mcc_to_scc_switch_mode_in_user_cfg( return 0; } - return pm_ctx->user_cfg.mcc_to_scc_switch_mode; + return pm_ctx->cfg.mcc_to_scc_switch; } /** @@ -2402,7 +2402,7 @@ bool policy_mgr_allow_new_home_channel(struct wlan_objmgr_psoc *psoc, return false; } mcc_to_scc_switch = - policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc); + policy_mgr_get_mcc_to_scc_switch_mode(psoc); qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); if (num_connections == 2) { diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 0c65de943518..3891909533b0 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -3094,13 +3094,13 @@ bool policy_mgr_is_force_scc(struct wlan_objmgr_psoc *psoc) return 0; } - return ((pm_ctx->user_cfg.mcc_to_scc_switch_mode == + return ((pm_ctx->cfg.mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_FORCE_WITHOUT_DISCONNECTION) || - (pm_ctx->user_cfg.mcc_to_scc_switch_mode == + (pm_ctx->cfg.mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_WITH_FAVORITE_CHANNEL) || - (pm_ctx->user_cfg.mcc_to_scc_switch_mode == + (pm_ctx->cfg.mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION) || - (pm_ctx->user_cfg.mcc_to_scc_switch_mode == + (pm_ctx->cfg.mcc_to_scc_switch == QDF_MCC_TO_SCC_WITH_PREFERRED_BAND)); } diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index afc03034d421..1be204cfdbaf 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -355,7 +355,7 @@ bool policy_mgr_is_dual_mac_disabled_in_ini( struct wlan_objmgr_psoc *psoc); /** - * policy_mgr_mcc_to_scc_switch_mode_in_user_cfg() - MCC to SCC + * policy_mgr_get_mcc_to_scc_switch_mode() - MCC to SCC * switch mode value in the user config * @psoc: PSOC object information * @@ -363,7 +363,7 @@ bool policy_mgr_is_dual_mac_disabled_in_ini( * * Return: MCC to SCC switch mode value */ -uint32_t policy_mgr_mcc_to_scc_switch_mode_in_user_cfg( +uint32_t policy_mgr_get_mcc_to_scc_switch_mode( struct wlan_objmgr_psoc *psoc); bool policy_mgr_get_dbs_config(struct wlan_objmgr_psoc *psoc); bool policy_mgr_get_agile_dfs_config(struct wlan_objmgr_psoc *psoc); From 6dd2208e936029ca973f82e29e8008e12c21c63f Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Thu, 27 Sep 2018 10:40:24 -0700 Subject: [PATCH 365/404] qcacmn: Refactor operation related to INI gSystemPref Ownership of gSystemPref is changed from HDD to Policy manager. So policy manager doesn't have to rely on HDD to obtain the INI setting. CRs-Fixed: 2324395 Change-Id: Ia586896ea55c6e71d8dcff705bf0e74879931dbb --- inc/wlan_policy_mgr_api.h | 12 ++++++++++++ inc/wlan_policy_mgr_public_struct.h | 2 -- inc/wlan_policy_mgr_ucfg.h | 12 ++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 17 ++++++++++++++++- src/wlan_policy_mgr_ucfg.c | 6 ++++++ 5 files changed, 46 insertions(+), 3 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 202896167519..28024645b332 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -88,6 +88,18 @@ QDF_STATUS policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, uint8_t *sys_pref); +/** + * policy_mgr_set_sys_pref() - to set system preference + * @psoc: pointer to psoc + * @sys_pref: value to be applied as new INI setting + * + * This API is meant to override original INI setting for system pref + * with new value which is used by policy manager to provide PCL + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc, + uint8_t sys_pref); /** * policy_mgr_get_max_conc_cxns() - to get max num of conc connections * @psoc: pointer to psoc diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 7782f5c39f39..a816b139d466 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1055,7 +1055,6 @@ enum policy_mgr_pri_id { * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler * @max_concurrent_active_sessions: User allowed maximum active * connections - * @conc_system_pref: System preference for PCL table * @enable2x2: 2x2 chain mask user config * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled * @dbs_selection_policy: band preference or Vdev preference @@ -1073,7 +1072,6 @@ enum policy_mgr_pri_id { struct policy_mgr_user_cfg { uint8_t enable_mcc_adaptive_scheduler; uint8_t max_concurrent_active_sessions; - uint8_t conc_system_pref; bool enable2x2; bool sub_20_mhz_enabled; bool is_sta_sap_scc_allowed_on_dfs_chan; diff --git a/inc/wlan_policy_mgr_ucfg.h b/inc/wlan_policy_mgr_ucfg.h index eb17a3c425da..ab6e51c192d3 100644 --- a/inc/wlan_policy_mgr_ucfg.h +++ b/inc/wlan_policy_mgr_ucfg.h @@ -73,6 +73,18 @@ QDF_STATUS ucfg_policy_mgr_get_mcc_scc_switch(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS ucfg_policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, uint8_t *sys_pref); +/** + * ucfg_policy_mgr_set_sys_pref() - to set system preference + * @psoc: pointer to psoc + * @sys_pref: value to be applied as new INI setting + * + * This API is meant to override original INI setting for system pref + * with new value which is used by policy manager to provide PCL + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc, + uint8_t sys_pref); /** * ucfg_policy_mgr_get_max_conc_cxns() - to get max num of conc connections * @psoc: pointer to psoc diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 3891909533b0..168d9876b212 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -66,6 +66,21 @@ QDF_STATUS policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc, + uint8_t sys_pref) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + pm_ctx->cfg.sys_pref = sys_pref; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc, uint8_t *max_conc_cxns) { @@ -2102,7 +2117,7 @@ QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, user_cfg->dbs_selection_policy); policy_mgr_debug("vdev_priority_list 0x%x", user_cfg->vdev_priority_list); - pm_ctx->cur_conc_system_pref = pm_ctx->user_cfg.conc_system_pref; + pm_ctx->cur_conc_system_pref = pm_ctx->cfg.sys_pref; return QDF_STATUS_SUCCESS; } diff --git a/src/wlan_policy_mgr_ucfg.c b/src/wlan_policy_mgr_ucfg.c index 70f9e851635c..aad715d8e80d 100644 --- a/src/wlan_policy_mgr_ucfg.c +++ b/src/wlan_policy_mgr_ucfg.c @@ -86,6 +86,12 @@ QDF_STATUS ucfg_policy_mgr_get_sys_pref(struct wlan_objmgr_psoc *psoc, return policy_mgr_get_sys_pref(psoc, sys_pref); } +QDF_STATUS ucfg_policy_mgr_set_sys_pref(struct wlan_objmgr_psoc *psoc, + uint8_t sys_pref) +{ + return policy_mgr_set_sys_pref(psoc, sys_pref); +} + QDF_STATUS ucfg_policy_mgr_get_max_conc_cxns(struct wlan_objmgr_psoc *psoc, uint8_t *max_conc_cxns) { From 1c7a1e9cf0682ba98f42cc15f617f3a7c27e48aa Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Thu, 27 Sep 2018 10:55:17 -0700 Subject: [PATCH 366/404] qcacmn: Refactor operation related to INI gMaxConcurrentActiveSessions Ownership of gMaxConcurrentActiveSessions is changed from HDD to Policy manager. So policy manager doesn't have to rely on HDD to obtain the INI setting. CRs-Fixed: 2324395 Change-Id: Iac1451fc457d9bceee73596affdae54895917040 --- inc/wlan_policy_mgr_public_struct.h | 3 --- src/wlan_policy_mgr_get_set_utils.c | 9 ++++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index a816b139d466..a52029f0f7a7 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1053,8 +1053,6 @@ enum policy_mgr_pri_id { /** * struct policy_mgr_user_cfg - Policy manager user config variables * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler - * @max_concurrent_active_sessions: User allowed maximum active - * connections * @enable2x2: 2x2 chain mask user config * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled * @dbs_selection_policy: band preference or Vdev preference @@ -1071,7 +1069,6 @@ enum policy_mgr_pri_id { */ struct policy_mgr_user_cfg { uint8_t enable_mcc_adaptive_scheduler; - uint8_t max_concurrent_active_sessions; bool enable2x2; bool sub_20_mhz_enabled; bool is_sta_sap_scc_allowed_on_dfs_chan; diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 168d9876b212..582db6828544 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -1499,9 +1499,9 @@ QDF_STATUS policy_mgr_incr_connection_count( } conn_index = policy_mgr_get_connection_count(psoc); - if (pm_ctx->user_cfg.max_concurrent_active_sessions < conn_index) { + if (pm_ctx->cfg.max_conc_cxns < conn_index) { policy_mgr_err("exceeded max connection limit %d", - pm_ctx->user_cfg.max_concurrent_active_sessions); + pm_ctx->cfg.max_conc_cxns); return status; } if (pm_ctx->wma_cbacks.wma_get_connection_info) { @@ -1730,8 +1730,7 @@ bool policy_mgr_max_concurrent_connections_reached( for (i = 0; i < QDF_MAX_NO_OF_MODE; i++) j += pm_ctx->no_of_active_sessions[i]; return j > - (pm_ctx->user_cfg. - max_concurrent_active_sessions - 1); + (pm_ctx->cfg.max_conc_cxns - 1); } return false; @@ -1800,7 +1799,7 @@ bool policy_mgr_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc, if (policy_mgr_max_concurrent_connections_reached(psoc)) { policy_mgr_err("Reached max concurrent connections: %d", - pm_ctx->user_cfg.max_concurrent_active_sessions); + pm_ctx->cfg.max_conc_cxns); goto done; } From d4e542be30efcdb6f9dae094d581e2d9238f70cd Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Thu, 27 Sep 2018 12:40:33 -0700 Subject: [PATCH 367/404] qcacmn: Refactor operation related to DBS/vdev/channel selection INIs Ownership of dbs_selection_policy, vdev_priority_list, channel_select_logic_conc INIs' are changed from HDD to Policy manager. So policy manager doesn't have to rely on HDD to obtain the INI setting. CRs-Fixed: 2324395 Change-Id: I8b38916d92931ef9cd1727481740bc61cad8f808 --- inc/wlan_policy_mgr_api.h | 4 ++-- inc/wlan_policy_mgr_public_struct.h | 14 -------------- inc/wlan_policy_mgr_ucfg.h | 4 ++-- src/wlan_policy_mgr_action.c | 16 ++++++++-------- src/wlan_policy_mgr_get_set_utils.c | 6 +++--- 5 files changed, 15 insertions(+), 29 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 28024645b332..59b645a28428 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -136,14 +136,14 @@ QDF_STATUS policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc, /** * policy_mgr_get_dbs_selection_plcy() - DBS HW mode selection setting * @psoc: pointer to psoc - * @dbs_selection_policy: value to be filled + * @dbs_selection_plcy: value to be filled * * This API is used to find out DBS HW mode preference. * * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. */ QDF_STATUS policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc, - uint32_t *dbs_selection_policy); + uint32_t *dbs_selection_plcy); /** * policy_mgr_get_vdev_priority_list() - to get vdev priority list * @psoc: pointer to psoc diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index a52029f0f7a7..89cb5c6ce7bd 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1055,27 +1055,13 @@ enum policy_mgr_pri_id { * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler * @enable2x2: 2x2 chain mask user config * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled - * @dbs_selection_policy: band preference or Vdev preference - * bit[0] = 0: 5G 2x2 preferred to select 2x2 5G + 1x1 2G DBS mode. - * bit[0] = 1: 2G 2x2 preferred to select 2x2 2G + 1x1 5G DBS mode. - * bit[1] = 1: vdev priority enabled. - * bit[1] = 0: vdev priority disabled. - * @vdev_priority_list: vdev priority list - * bit[0-3]: pri_id (policy_mgr_pri_id) of highest priority - * bit[4-7]: pri_id (policy_mgr_pri_id) of second priority - * bit[8-11]: pri_id (policy_mgr_pri_id) of third priority - * bit[12-15]: pri_id (policy_mgr_pri_id) of fourth priority - * example: 0x4321 - CLI < GO < SAP < STA */ struct policy_mgr_user_cfg { uint8_t enable_mcc_adaptive_scheduler; bool enable2x2; bool sub_20_mhz_enabled; bool is_sta_sap_scc_allowed_on_dfs_chan; - uint32_t channel_select_logic_conc; uint32_t sta_sap_scc_on_lte_coex_chan; - uint32_t dbs_selection_policy; - uint32_t vdev_priority_list; }; /** diff --git a/inc/wlan_policy_mgr_ucfg.h b/inc/wlan_policy_mgr_ucfg.h index ab6e51c192d3..33e246cfa3fa 100644 --- a/inc/wlan_policy_mgr_ucfg.h +++ b/inc/wlan_policy_mgr_ucfg.h @@ -121,14 +121,14 @@ QDF_STATUS ucfg_policy_mgr_get_conc_rule2(struct wlan_objmgr_psoc *psoc, /** * ucfg_policy_mgr_get_dbs_selection_plcy() - DBS HW mode selection setting * @psoc: pointer to psoc - * @dbs_selection_policy: value to be filled + * @dbs_selection_plcy: value to be filled * * This API is used to find out DBS HW mode preference. * * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. */ QDF_STATUS ucfg_policy_mgr_get_dbs_selection_plcy(struct wlan_objmgr_psoc *psoc, - uint32_t *dbs_selection_policy); + uint32_t *dbs_selection_plcy); /** * ucfg_policy_mgr_get_vdev_priority_list() - to get vdev priority list * @psoc: pointer to psoc diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index ac2ddf75df79..a7514fbd9a8b 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -392,6 +392,7 @@ bool policy_mgr_is_dbs_allowed_for_concurrency( struct policy_mgr_psoc_priv_obj *pm_ctx; uint32_t count, dbs_for_sta_sta, dbs_for_sta_p2p; bool ret = true; + uint32_t ch_sel_plcy; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -404,10 +405,9 @@ bool policy_mgr_is_dbs_allowed_for_concurrency( if (count != 1 || new_conn_mode == QDF_MAX_NO_OF_MODE) return ret; - dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(pm_ctx->user_cfg. - channel_select_logic_conc); - dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(pm_ctx->user_cfg. - channel_select_logic_conc); + ch_sel_plcy = pm_ctx->cfg.chnl_select_plcy; + dbs_for_sta_sta = PM_CHANNEL_SELECT_LOGIC_STA_STA_GET(ch_sel_plcy); + dbs_for_sta_p2p = PM_CHANNEL_SELECT_LOGIC_STA_P2P_GET(ch_sel_plcy); switch (pm_conc_connection_list[0].mode) { case PM_STA_MODE: @@ -592,12 +592,12 @@ policy_mgr_get_preferred_dbs_action_table( policy_mgr_debug("target only supports DBS1!"); goto DONE; } - if (PM_GET_BAND_PREFERRED(pm_ctx->user_cfg.dbs_selection_policy) == 1) + if (PM_GET_BAND_PREFERRED(pm_ctx->cfg.dbs_selection_plcy) == 1) band_pref_5g = false; if (PM_GET_VDEV_PRIORITY_ENABLED( - pm_ctx->user_cfg.dbs_selection_policy) == 1 && - pm_ctx->user_cfg.vdev_priority_list) + pm_ctx->cfg.dbs_selection_plcy) == 1 && + pm_ctx->cfg.vdev_priority_list) vdev_priority_enabled = true; if (!vdev_priority_enabled) @@ -619,7 +619,7 @@ policy_mgr_get_preferred_dbs_action_table( vdev_id, new_conn_op_mode, channel, reason); } - vdev_pri_list = pm_ctx->user_cfg.vdev_priority_list; + vdev_pri_list = pm_ctx->cfg.vdev_priority_list; while (vdev_pri_list) { vdev_pri_id = vdev_pri_list & 0xF; pri_conn_mode = policy_mgr_pri_id_to_con_mode(vdev_pri_id); diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 582db6828544..3aeddd794bac 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -2112,10 +2112,10 @@ QDF_STATUS policy_mgr_set_user_cfg(struct wlan_objmgr_psoc *psoc, } pm_ctx->user_cfg = *user_cfg; - policy_mgr_debug("dbs_selection_policy 0x%x", - user_cfg->dbs_selection_policy); + policy_mgr_debug("dbs_selection_plcy 0x%x", + pm_ctx->cfg.dbs_selection_plcy); policy_mgr_debug("vdev_priority_list 0x%x", - user_cfg->vdev_priority_list); + pm_ctx->cfg.vdev_priority_list); pm_ctx->cur_conc_system_pref = pm_ctx->cfg.sys_pref; return QDF_STATUS_SUCCESS; From c9af406975cfa5cabe4cd327232349a15abfaa47 Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Thu, 27 Sep 2018 14:31:20 -0700 Subject: [PATCH 368/404] qcacmn: Refactor operation related to gEnableMCCAdaptiveScheduler INI Ownership of gEnableMCCAdaptiveScheduler is changed from HDD to Policy manager. So policy manager doesn't have to rely on HDD to obtain the INI setting. CRs-Fixed: 2324395 Change-Id: Ib86004c4ee753b37b392de69551c777e3e9011de --- inc/wlan_policy_mgr_api.h | 25 ++++++++++++------------- inc/wlan_policy_mgr_cfg.h | 25 ++++++++++++++++++++++++- inc/wlan_policy_mgr_public_struct.h | 2 -- inc/wlan_policy_mgr_ucfg.h | 12 ++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 28 ++++++++++++++-------------- src/wlan_policy_mgr_i.h | 2 ++ src/wlan_policy_mgr_ucfg.c | 9 +++++++++ 7 files changed, 73 insertions(+), 30 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 59b645a28428..14c239e9af88 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -167,6 +167,18 @@ QDF_STATUS policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, uint32_t *chnl_select_plcy); + +/** + * policy_mgr_get_mcc_adaptive_sch() - to get mcc adaptive scheduler + * @psoc: pointer to psoc + * @enable_mcc_adaptive_sch: value to be filled + * + * This API is used to find out if mcc adaptive scheduler enabled or disabled + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_mcc_adaptive_sch); /** * policy_mgr_set_concurrency_mode() - To set concurrency mode * @psoc: PSOC object data @@ -2127,19 +2139,6 @@ enum policy_mgr_hw_mode_change policy_mgr_get_hw_mode_change_from_hw_mode_index( */ bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc); -/** - * policy_mgr_is_mcc_adaptive_scheduler_enabled() - Function to - * gets the policy manager mcc adaptive scheduler enabled - * @psoc: PSOC object information - * - * This function gets the value mcc adaptive scheduler - * - * Return: true if MCC adaptive scheduler is set else false - * - */ -bool policy_mgr_is_mcc_adaptive_scheduler_enabled( - struct wlan_objmgr_psoc *psoc); - /** * policy_mgr_set_user_cfg() - Function to set user cfg variables * required by policy manager component diff --git a/inc/wlan_policy_mgr_cfg.h b/inc/wlan_policy_mgr_cfg.h index 19b0495859ac..df63b6466e19 100644 --- a/inc/wlan_policy_mgr_cfg.h +++ b/inc/wlan_policy_mgr_cfg.h @@ -242,6 +242,28 @@ 0, 1, 0, \ CFG_VALUE_OR_DEFAULT, \ "Enable custom concurrency rule 2") +/* + * + * gEnableMCCAdaptiveScheduler - MCC Adaptive Scheduler feature. + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to enable/disable MCC Adaptive Scheduler feature. + * + * Related: None. + * + * Supported Feature: Concurrency + * + * Usage: Internal/External + * + * + */ +#define CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME CFG_INI_UINT(\ + "gEnableMCCAdaptiveScheduler", \ + 0, 1, 1, \ + CFG_VALUE_OR_DEFAULT, \ + "Enable/Disable MCC Adaptive Scheduler") #define CFG_POLICY_MGR_ALL \ CFG(CFG_MCC_TO_SCC_SWITCH) \ @@ -251,5 +273,6 @@ CFG(CFG_VDEV_CUSTOM_PRIORITY_LIST) \ CFG(CFG_CHNL_SELECT_LOGIC_CONC) \ CFG(CFG_ENABLE_CONC_RULE1) \ - CFG(CFG_ENABLE_CONC_RULE2) + CFG(CFG_ENABLE_CONC_RULE2) \ + CFG(CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME) #endif diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 89cb5c6ce7bd..53c605853ab0 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -1052,12 +1052,10 @@ enum policy_mgr_pri_id { /** * struct policy_mgr_user_cfg - Policy manager user config variables - * @enable_mcc_adaptive_scheduler: Enable MCC adaptive scheduler * @enable2x2: 2x2 chain mask user config * @sub_20_mhz_enabled: Is 5 or 10 Mhz enabled */ struct policy_mgr_user_cfg { - uint8_t enable_mcc_adaptive_scheduler; bool enable2x2; bool sub_20_mhz_enabled; bool is_sta_sap_scc_allowed_on_dfs_chan; diff --git a/inc/wlan_policy_mgr_ucfg.h b/inc/wlan_policy_mgr_ucfg.h index 33e246cfa3fa..bc27c19286a4 100644 --- a/inc/wlan_policy_mgr_ucfg.h +++ b/inc/wlan_policy_mgr_ucfg.h @@ -152,4 +152,16 @@ QDF_STATUS ucfg_policy_mgr_get_vdev_priority_list(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS ucfg_policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, uint32_t *chnl_select_plcy); +/** + * policy_mgr_get_mcc_adaptive_sch() - to get mcc adaptive scheduler + * @psoc: pointer to psoc + * @enable_mcc_adaptive_sch: value to be filled + * + * This API is used to find out if mcc adaptive scheduler enabled or disabled + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS +ucfg_policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_mcc_adaptive_sch); #endif //__WLAN_POLICY_MGR_UCFG diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 3aeddd794bac..3e640c749a78 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -172,6 +172,20 @@ QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, } +QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_mcc_adaptive_sch) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *enable_mcc_adaptive_sch = pm_ctx->cfg.enable_mcc_adaptive_sch; + + return QDF_STATUS_SUCCESS; +} void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, uint32_t new_hw_mode_index) @@ -2275,20 +2289,6 @@ bool policy_mgr_check_for_session_conc(struct wlan_objmgr_psoc *psoc, return true; } -bool policy_mgr_is_mcc_adaptive_scheduler_enabled( - struct wlan_objmgr_psoc *psoc) { - struct policy_mgr_psoc_priv_obj *pm_ctx; - - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid context"); - return false; - } - - return pm_ctx->user_cfg.enable_mcc_adaptive_scheduler ? - true : false; -} - /** * policy_mgr_change_mcc_go_beacon_interval() - Change MCC beacon interval * @psoc: PSOC object information diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 1be204cfdbaf..e5be24789e13 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -223,6 +223,7 @@ struct sta_ap_intf_check_work_ctx { * @dbs_selection_plcy: DBS selection policy for concurrency * @vdev_priority_list: Priority list for various vdevs * @chnl_select_plcy: Channel selection policy + * @enable_mcc_adaptive_sch: Enable/Disable MCC adaptive scheduler */ struct policy_mgr_cfg { uint8_t mcc_to_scc_switch; @@ -230,6 +231,7 @@ struct policy_mgr_cfg { uint8_t max_conc_cxns; uint8_t conc_rule1; uint8_t conc_rule2; + uint8_t enable_mcc_adaptive_sch; uint32_t dbs_selection_plcy; uint32_t vdev_priority_list; uint32_t chnl_select_plcy; diff --git a/src/wlan_policy_mgr_ucfg.c b/src/wlan_policy_mgr_ucfg.c index aad715d8e80d..80365392e685 100644 --- a/src/wlan_policy_mgr_ucfg.c +++ b/src/wlan_policy_mgr_ucfg.c @@ -40,6 +40,8 @@ static QDF_STATUS policy_mgr_init_cfg(struct wlan_objmgr_psoc *psoc) cfg->dbs_selection_plcy = cfg_get(psoc, CFG_DBS_SELECTION_PLCY); cfg->vdev_priority_list = cfg_get(psoc, CFG_VDEV_CUSTOM_PRIORITY_LIST); cfg->chnl_select_plcy = cfg_get(psoc, CFG_CHNL_SELECT_LOGIC_CONC); + cfg->enable_mcc_adaptive_sch = + cfg_get(psoc, CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME); return QDF_STATUS_SUCCESS; } @@ -127,3 +129,10 @@ QDF_STATUS ucfg_policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, { return policy_mgr_get_chnl_select_plcy(psoc, chnl_select_plcy); } + + +QDF_STATUS ucfg_policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, + uint8_t *mcc_adaptive_sch) +{ + return policy_mgr_get_mcc_adaptive_sch(psoc, mcc_adaptive_sch); +} From dd8bf40a4473ec7d086fabe045f65c119c3f878b Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Thu, 27 Sep 2018 17:34:25 -0700 Subject: [PATCH 369/404] qcacmn: Refactor operation related to gEnableStaConnectionIn5Ghz INI Ownership of gEnableStaConnectionIn5Ghz is changed from HDD to Policy manager. So policy manager doesn't have to rely on HDD to obtain the INI setting. CRs-Fixed: 2324395 Change-Id: I894467bab4b0bddf309463802b98904ef1150536 --- inc/wlan_policy_mgr_api.h | 14 ++++++++++++++ inc/wlan_policy_mgr_cfg.h | 26 +++++++++++++++++++++++++- inc/wlan_policy_mgr_ucfg.h | 14 ++++++++++++++ src/wlan_policy_mgr_get_set_utils.c | 15 +++++++++++++++ src/wlan_policy_mgr_i.h | 2 ++ src/wlan_policy_mgr_ucfg.c | 8 ++++++++ 6 files changed, 78 insertions(+), 1 deletion(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 14c239e9af88..31da207ed607 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -179,6 +179,20 @@ QDF_STATUS policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, uint8_t *enable_mcc_adaptive_sch); + +/** + * policy_mgr_get_sta_cxn_5g_band() - to get STA's connection in 5G config + * + * @psoc: pointer to psoc + * @enable_sta_cxn_5g_band: value to be filled + * + * This API is used to find out if STA connection in 5G band is allowed or + * disallowed. + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_sta_cxn_5g_band); /** * policy_mgr_set_concurrency_mode() - To set concurrency mode * @psoc: PSOC object data diff --git a/inc/wlan_policy_mgr_cfg.h b/inc/wlan_policy_mgr_cfg.h index df63b6466e19..22900022d06e 100644 --- a/inc/wlan_policy_mgr_cfg.h +++ b/inc/wlan_policy_mgr_cfg.h @@ -265,6 +265,29 @@ CFG_VALUE_OR_DEFAULT, \ "Enable/Disable MCC Adaptive Scheduler") +/* + * + * gEnableStaConnectionIn5Ghz - To enable/disable STA connection in 5G + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to enable/disable STA connection in 5G band + * + * Related: STA + * + * Supported Feature: Concurrency + * + * Usage: Internal/External + * + * + */ +#define CFG_ENABLE_STA_CONNECTION_IN_5GHZ CFG_INI_UINT(\ + "gEnableStaConnectionIn5Ghz", \ + 0, 1, 1, \ + CFG_VALUE_OR_DEFAULT, \ + "Enable/Disable STA connection in 5G") + #define CFG_POLICY_MGR_ALL \ CFG(CFG_MCC_TO_SCC_SWITCH) \ CFG(CFG_CONC_SYS_PREF) \ @@ -274,5 +297,6 @@ CFG(CFG_CHNL_SELECT_LOGIC_CONC) \ CFG(CFG_ENABLE_CONC_RULE1) \ CFG(CFG_ENABLE_CONC_RULE2) \ - CFG(CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME) + CFG(CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME)\ + CFG(CFG_ENABLE_STA_CONNECTION_IN_5GHZ) #endif diff --git a/inc/wlan_policy_mgr_ucfg.h b/inc/wlan_policy_mgr_ucfg.h index bc27c19286a4..661eebdec81e 100644 --- a/inc/wlan_policy_mgr_ucfg.h +++ b/inc/wlan_policy_mgr_ucfg.h @@ -164,4 +164,18 @@ QDF_STATUS ucfg_policy_mgr_get_chnl_select_plcy(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, uint8_t *enable_mcc_adaptive_sch); + +/** + * ucfg_policy_mgr_get_sta_cxn_5g_band() - to get STA's connection in 5G config + * + * @psoc: pointer to psoc + * @enable_sta_cxn_5g_band: value to be filled + * + * This API is used to find out if STA connection in 5G band is allowed or + * disallowed. + * + * Return: QDF_STATUS_SUCCESS up on success and any other status for failure. + */ +QDF_STATUS ucfg_policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_sta_cxn_5g_band); #endif //__WLAN_POLICY_MGR_UCFG diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 3e640c749a78..250b5fb94988 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -187,6 +187,21 @@ QDF_STATUS policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_sta_cxn_5g_band) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("pm_ctx is NULL"); + return QDF_STATUS_E_FAILURE; + } + *enable_sta_cxn_5g_band = pm_ctx->cfg.enable_sta_cxn_5g_band; + + return QDF_STATUS_SUCCESS; +} + void policy_mgr_update_new_hw_mode_index(struct wlan_objmgr_psoc *psoc, uint32_t new_hw_mode_index) { diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index e5be24789e13..cc8c3436c388 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -224,6 +224,7 @@ struct sta_ap_intf_check_work_ctx { * @vdev_priority_list: Priority list for various vdevs * @chnl_select_plcy: Channel selection policy * @enable_mcc_adaptive_sch: Enable/Disable MCC adaptive scheduler + * @enable_sta_cxn_5g_band: Enable/Disable STA connection in 5G band */ struct policy_mgr_cfg { uint8_t mcc_to_scc_switch; @@ -232,6 +233,7 @@ struct policy_mgr_cfg { uint8_t conc_rule1; uint8_t conc_rule2; uint8_t enable_mcc_adaptive_sch; + uint8_t enable_sta_cxn_5g_band; uint32_t dbs_selection_plcy; uint32_t vdev_priority_list; uint32_t chnl_select_plcy; diff --git a/src/wlan_policy_mgr_ucfg.c b/src/wlan_policy_mgr_ucfg.c index 80365392e685..310019ba3249 100644 --- a/src/wlan_policy_mgr_ucfg.c +++ b/src/wlan_policy_mgr_ucfg.c @@ -42,6 +42,8 @@ static QDF_STATUS policy_mgr_init_cfg(struct wlan_objmgr_psoc *psoc) cfg->chnl_select_plcy = cfg_get(psoc, CFG_CHNL_SELECT_LOGIC_CONC); cfg->enable_mcc_adaptive_sch = cfg_get(psoc, CFG_ENABLE_MCC_ADATIVE_SCH_ENABLED_NAME); + cfg->enable_sta_cxn_5g_band = + cfg_get(psoc, CFG_ENABLE_STA_CONNECTION_IN_5GHZ); return QDF_STATUS_SUCCESS; } @@ -136,3 +138,9 @@ QDF_STATUS ucfg_policy_mgr_get_mcc_adaptive_sch(struct wlan_objmgr_psoc *psoc, { return policy_mgr_get_mcc_adaptive_sch(psoc, mcc_adaptive_sch); } + +QDF_STATUS ucfg_policy_mgr_get_sta_cxn_5g_band(struct wlan_objmgr_psoc *psoc, + uint8_t *enable_sta_cxn_5g_band) +{ + return policy_mgr_get_sta_cxn_5g_band(psoc, enable_sta_cxn_5g_band); +} From fef8741bd1357d465a6b646f8dd9496d7fe06752 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Wed, 17 Oct 2018 12:18:01 +0530 Subject: [PATCH 370/404] qcacmn: Select non SRD channel for SAP in STA+SAP Currently the driver selects the first channel available in the PCL channel-list which could be STA channel itself, and it may happen that this STA channel is not valid for SAP bringup(SRD). Fix is to select a non SRD channel from PCL channel-list for SAP. Change-Id: Ia9d3bfc0534e28972a6ddb0d588b62a55e3f6e23 CRs-Fixed: 2308072 --- src/wlan_policy_mgr_pcl.c | 51 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/wlan_policy_mgr_pcl.c b/src/wlan_policy_mgr_pcl.c index 8f91e024aea6..46d1556c61d3 100644 --- a/src/wlan_policy_mgr_pcl.c +++ b/src/wlan_policy_mgr_pcl.c @@ -358,6 +358,46 @@ static QDF_STATUS policy_mgr_modify_sap_pcl_based_on_nol( return QDF_STATUS_SUCCESS; } +static QDF_STATUS +policy_mgr_modify_sap_pcl_based_on_srd(struct wlan_objmgr_psoc *psoc, + uint8_t *pcl_list_org, + uint8_t *weight_list_org, + uint32_t *pcl_len_org) +{ + uint32_t i, pcl_len = 0; + uint8_t pcl_list[QDF_MAX_NUM_CHAN]; + uint8_t weight_list[QDF_MAX_NUM_CHAN]; + struct policy_mgr_psoc_priv_obj *pm_ctx; + bool is_etsi13_srd_chan_allowed_in_mas_mode = true; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return QDF_STATUS_E_FAILURE; + } + is_etsi13_srd_chan_allowed_in_mas_mode = + wlan_reg_is_etsi13_srd_chan_allowed_master_mode(pm_ctx->pdev); + + if (is_etsi13_srd_chan_allowed_in_mas_mode) + return QDF_STATUS_SUCCESS; + + for (i = 0; i < *pcl_len_org; i++) { + if (wlan_reg_is_etsi13_srd_chan(pm_ctx->pdev, + pcl_list_org[i])) + continue; + pcl_list[pcl_len] = pcl_list_org[i]; + weight_list[pcl_len++] = weight_list_org[i]; + } + + qdf_mem_zero(pcl_list_org, QDF_ARRAY_SIZE(pcl_list_org)); + qdf_mem_zero(weight_list_org, QDF_ARRAY_SIZE(weight_list_org)); + qdf_mem_copy(pcl_list_org, pcl_list, pcl_len); + qdf_mem_copy(weight_list_org, weight_list, pcl_len); + *pcl_len_org = pcl_len; + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS policy_mgr_pcl_modification_for_sap( struct wlan_objmgr_psoc *psoc, uint8_t *pcl_channels, uint8_t *pcl_weight, @@ -390,6 +430,17 @@ static QDF_STATUS policy_mgr_pcl_modification_for_sap( policy_mgr_debug("chan:%d weight:%d", pcl_channels[i], pcl_weight[i]); + status = policy_mgr_modify_sap_pcl_based_on_srd + (psoc, pcl_channels, pcl_weight, len); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("failed to get modified pcl for SAP"); + return status; + } + policy_mgr_debug("modified final pcl len:%d", *len); + for (i = 0; i < *len; i++) + policy_mgr_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); + return QDF_STATUS_SUCCESS; } From dae31901cdbb14a220138148b231ec31accae76a Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Sun, 21 Oct 2018 23:40:06 -0400 Subject: [PATCH 371/404] qcacmn: Add original vdev info for NSS update API Add original hw mode change request vdev id to NSS update APIs, so that the correct vdev to be used to do post processing after hw mode change, such as doing connect for hidden SSID case. Change-Id: Ie7f7b55a100ec4e23be2fc710d9b0d83cb33088d CRs-Fixed: 2336439 --- inc/wlan_policy_mgr_api.h | 9 ++++++--- src/wlan_policy_mgr_action.c | 12 ++++++++---- src/wlan_policy_mgr_core.c | 22 +++++++++++++++------- src/wlan_policy_mgr_i.h | 4 +++- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 31da207ed607..423b4430e2b2 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1021,6 +1021,7 @@ typedef void (*policy_mgr_pdev_set_hw_mode_cback)(uint32_t status, * @next_action: next action to happen at policy mgr after * beacon update * @reason: Reason for nss update + * @original_vdev_id: original request hwmode change vdev id * * This function is the callback registered with SME at nss * update request time @@ -1031,7 +1032,8 @@ typedef void (*policy_mgr_nss_update_cback)(struct wlan_objmgr_psoc *psoc, uint8_t tx_status, uint8_t vdev_id, uint8_t next_action, - enum policy_mgr_conn_update_reason reason); + enum policy_mgr_conn_update_reason reason, + uint32_t original_vdev_id); /** * struct policy_mgr_sme_cbacks - SME Callbacks to be invoked @@ -1055,9 +1057,10 @@ struct policy_mgr_sme_cbacks { QDF_STATUS (*sme_pdev_set_hw_mode)(struct policy_mgr_hw_mode msg); QDF_STATUS (*sme_pdev_set_pcl)(struct policy_mgr_pcl_list *msg); QDF_STATUS (*sme_nss_update_request)(uint32_t vdev_id, - uint8_t new_nss, policy_mgr_nss_update_cback cback, + uint8_t new_nss, policy_mgr_nss_update_cback cback, uint8_t next_action, struct wlan_objmgr_psoc *psoc, - enum policy_mgr_conn_update_reason reason); + enum policy_mgr_conn_update_reason reason, + uint32_t original_vdev_id); QDF_STATUS (*sme_change_mcc_beacon_interval)(uint8_t session_id); QDF_STATUS (*sme_get_ap_channel_from_scan)( void *roam_profile, diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index a7514fbd9a8b..874ea495bafd 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1066,7 +1066,8 @@ QDF_STATUS policy_mgr_next_actions( * intially. If yes, update the beacon template & notify FW. */ status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_1, - PM_NOP, POLICY_MGR_ANY, reason); + PM_NOP, POLICY_MGR_ANY, reason, + session_id); break; case PM_UPGRADE: /* @@ -1074,7 +1075,8 @@ QDF_STATUS policy_mgr_next_actions( * intially. If yes, update the beacon template & notify FW. */ status = policy_mgr_nss_update(psoc, POLICY_MGR_RX_NSS_2, - PM_NOP, POLICY_MGR_ANY, reason); + PM_NOP, POLICY_MGR_ANY, reason, + session_id); break; case PM_DBS1_DOWNGRADE: status = policy_mgr_complete_action(psoc, POLICY_MGR_RX_NSS_1, @@ -1133,12 +1135,14 @@ QDF_STATUS policy_mgr_next_actions( case PM_UPGRADE_5G: status = policy_mgr_nss_update( psoc, POLICY_MGR_RX_NSS_2, - PM_NOP, POLICY_MGR_BAND_5, reason); + PM_NOP, POLICY_MGR_BAND_5, reason, + session_id); break; case PM_UPGRADE_2G: status = policy_mgr_nss_update( psoc, POLICY_MGR_RX_NSS_2, - PM_NOP, POLICY_MGR_BAND_24, reason); + PM_NOP, POLICY_MGR_BAND_24, reason, + session_id); break; default: policy_mgr_err("unexpected action value %d", action); diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index e3f78bba11ce..3b0a04b8f101 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2517,6 +2517,7 @@ bool policy_mgr_is_5g_channel_allowed(struct wlan_objmgr_psoc *psoc, * @next_action: next action to happen at policy mgr after * beacon update * @reason: Reason for nss update + * @original_vdev_id: original request hwmode change vdev id * * This function is the callback registered with SME at nss * update request time @@ -2527,7 +2528,8 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, uint8_t tx_status, uint8_t vdev_id, uint8_t next_action, - enum policy_mgr_conn_update_reason reason) + enum policy_mgr_conn_update_reason reason, + uint32_t original_vdev_id) { uint32_t conn_index = 0; QDF_STATUS ret; @@ -2545,9 +2547,11 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, return; } - policy_mgr_debug("nss update successful for vdev:%d", vdev_id); + policy_mgr_debug("nss update successful for vdev:%d ori %d reason %d", + vdev_id, original_vdev_id, reason); if (PM_NOP != next_action) - policy_mgr_next_actions(psoc, vdev_id, next_action, reason); + policy_mgr_next_actions(psoc, original_vdev_id, next_action, + reason); else { policy_mgr_debug("No action needed right now"); ret = policy_mgr_set_opportunistic_update(psoc); @@ -2561,7 +2565,8 @@ static void policy_mgr_nss_update_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, uint8_t new_nss, uint8_t next_action, enum policy_mgr_band band, - enum policy_mgr_conn_update_reason reason) + enum policy_mgr_conn_update_reason reason, + uint32_t original_vdev_id) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t index, count; @@ -2604,7 +2609,8 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, status = pm_ctx->sme_cbacks.sme_nss_update_request( vdev_id, new_nss, policy_mgr_nss_update_cb, - next_action, psoc, reason); + next_action, psoc, reason, + original_vdev_id); if (!QDF_IS_STATUS_SUCCESS(status)) { policy_mgr_err("sme_nss_update_request() failed for vdev %d", vdev_id); @@ -2637,7 +2643,8 @@ QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, status = pm_ctx->sme_cbacks.sme_nss_update_request( vdev_id, new_nss, policy_mgr_nss_update_cb, - next_action, psoc, reason); + next_action, psoc, reason, + original_vdev_id); if (!QDF_IS_STATUS_SUCCESS(status)) { policy_mgr_err("sme_nss_update_request() failed for vdev %d", vdev_id); @@ -2690,7 +2697,8 @@ QDF_STATUS policy_mgr_complete_action(struct wlan_objmgr_psoc *psoc, downgrade_band = POLICY_MGR_ANY; status = policy_mgr_nss_update(psoc, new_nss, next_action, - downgrade_band, reason); + downgrade_band, reason, + session_id); if (!QDF_IS_STATUS_SUCCESS(status)) status = policy_mgr_next_actions(psoc, session_id, next_action, reason); diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index cc8c3436c388..0a9d52b47050 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -534,6 +534,7 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, * @next_action: Next action after nss update * @band: update AP vdev on the Band. * @reason: action reason + * @original_vdev_id: original request hwmode change vdev id * * The function will update AP vdevs on specific band. * eg. band = POLICY_MGR_ANY will request to update all band (2g and 5g) @@ -543,7 +544,8 @@ void policy_mgr_reg_chan_change_callback(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_nss_update(struct wlan_objmgr_psoc *psoc, uint8_t new_nss, uint8_t next_action, enum policy_mgr_band band, - enum policy_mgr_conn_update_reason reason); + enum policy_mgr_conn_update_reason reason, + uint32_t original_vdev_id); /** * policy_mgr_is_concurrency_allowed() - Check for allowed From a82fdd95678983190e16f95a25ba3222b53d48c0 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 11 Oct 2018 14:34:37 +0530 Subject: [PATCH 372/404] qcacmn: Delete all peers in TDLS component In case of heartbeat failure or deauth from AP, From lim Del sta requests are sent to FW and with response required false, Since del sta response is not received TDLS component is not notified to reset the local tdls component structures and also upper layers are notified of this peer deletion. Change-Id: Ica0b150df7646af60868b2806432795896c75bcd CRs-Fixed: 2324559 --- core/src/wlan_tdls_main.c | 134 ++++++++++++++++++++++ core/src/wlan_tdls_main.h | 11 ++ dispatcher/inc/wlan_tdls_public_structs.h | 19 ++- dispatcher/inc/wlan_tdls_tgt_api.h | 14 ++- dispatcher/src/wlan_tdls_tgt_api.c | 47 ++++++++ 5 files changed, 223 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index d969d250693d..312a74bf6e77 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -358,6 +358,106 @@ static void tdls_get_all_peers_from_list( qdf_mem_free(get_tdls_peers); } +/** + * tdls_process_reset_all_peers() - Reset all tdls peers + * @delete_all_peers_ind: Delete all peers indication + * + * This function is called to reset all tdls peers and + * notify upper layers of teardown inidcation + * + * Return: QDF_STATUS + */ + +static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t staidx; + struct tdls_peer *curr_peer = NULL; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc; + uint8_t reset_session_id; + + status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("tdls objects are NULL "); + return status; + } + + if (!tdls_soc->connected_peer_count) { + tdls_debug("No tdls connected peers"); + return status; + } + + reset_session_id = tdls_vdev->session_id; + for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; + staidx++) { + if (tdls_soc->tdls_conn_info[staidx].sta_id + == INVALID_TDLS_PEER_ID) + continue; + if (tdls_soc->tdls_conn_info[staidx].session_id != + reset_session_id) + continue; + + curr_peer = + tdls_find_all_peer(tdls_soc, + tdls_soc->tdls_conn_info[staidx]. + peer_mac.bytes); + if (!curr_peer) + continue; + + tdls_notice("indicate TDLS teardown (staId %d)", + curr_peer->sta_id); + + /* Indicate teardown to supplicant */ + tdls_indicate_teardown(tdls_vdev, + curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + + tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); + + if (tdls_soc->tdls_dereg_peer) + tdls_soc->tdls_dereg_peer( + tdls_soc->tdls_peer_context, + wlan_vdev_get_id(vdev), + curr_peer->sta_id); + tdls_decrement_peer_count(tdls_soc); + tdls_soc->tdls_conn_info[staidx].sta_id = INVALID_TDLS_PEER_ID; + tdls_soc->tdls_conn_info[staidx].session_id = 255; + + qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, + sizeof(struct qdf_mac_addr)); + } + return status; +} + +/** + * tdls_reset_all_peers() - Reset all tdls peers + * @delete_all_peers_ind: Delete all peers indication + * + * This function is called to reset all tdls peers and + * notify upper layers of teardown inidcation + * + * Return: QDF_STATUS + */ +static QDF_STATUS tdls_reset_all_peers( + struct tdls_delete_all_peers_params *delete_all_peers_ind) +{ + QDF_STATUS status; + + if (!delete_all_peers_ind || !delete_all_peers_ind->vdev) { + tdls_err("invalid param"); + return QDF_STATUS_E_INVAL; + } + + status = tdls_process_reset_all_peers(delete_all_peers_ind->vdev); + + if (delete_all_peers_ind->callback) + delete_all_peers_ind->callback(delete_all_peers_ind->vdev); + + qdf_mem_free(delete_all_peers_ind); + return status; +} + QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -435,6 +535,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SET_SECOFFCHANOFFSET: tdls_process_set_secoffchanneloffset(msg->bodyptr); break; + case TDLS_DELETE_ALL_PEERS_INDICATION: + tdls_reset_all_peers(msg->bodyptr); + break; default: break; } @@ -1156,6 +1259,37 @@ QDF_STATUS tdls_peers_deleted_notification( return QDF_STATUS_SUCCESS; } +QDF_STATUS tdls_delete_all_peers_indication( + struct tdls_delete_all_peers_params *delete_peers_ind) +{ + struct scheduler_msg msg = {0, }; + struct tdls_delete_all_peers_params *indication; + QDF_STATUS status; + + indication = qdf_mem_malloc(sizeof(*indication)); + if (!indication) { + tdls_err("memory allocation failed !!!"); + return QDF_STATUS_E_NULL_VALUE; + } + + *indication = *delete_peers_ind; + + msg.bodyptr = indication; + msg.callback = tdls_process_cmd; + msg.type = TDLS_DELETE_ALL_PEERS_INDICATION; + + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(indication); + tdls_alert("message post failed "); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + /** * tdls_set_mode_in_vdev() - set TDLS mode * @tdls_vdev: tdls vdev object diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 421d6f2bd0d0..fc1230429131 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -725,4 +725,15 @@ void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, struct tdls_channel_switch_params *param); +/** + * tdls_delete_all_peers_indication() - update tdls status info + * @delete_peers_ind: Delete peers indication params + * + * Notify tdls component to cleanup all peers + * + * Return: QDF_STATUS. + */ + +QDF_STATUS tdls_delete_all_peers_indication( + struct tdls_delete_all_peers_params *delete_peers_ind); #endif diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 3aa85b71aeb5..261a1e9af8f3 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -193,6 +193,7 @@ enum tdls_feature_mode { * @TDLS_CMD_SET_OFFCHANNEL: tdls offchannel * @TDLS_CMD_SET_OFFCHANMODE: tdls offchannel mode * @TDLS_CMD_SET_SECOFFCHANOFFSET: tdls secondary offchannel offset + * @TDLS_DELETE_ALL_PEERS_INDICATION: tdls delete all peers indication */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -217,7 +218,8 @@ enum tdls_command_type { TDLS_CMD_ANTENNA_SWITCH, TDLS_CMD_SET_OFFCHANNEL, TDLS_CMD_SET_OFFCHANMODE, - TDLS_CMD_SET_SECOFFCHANOFFSET + TDLS_CMD_SET_SECOFFCHANOFFSET, + TDLS_DELETE_ALL_PEERS_INDICATION }; /** @@ -591,6 +593,11 @@ typedef void (*tdls_sta_notify_callback)(struct wlan_objmgr_vdev *vdev); /* This callback is to release vdev ref for tdls offchan param related msg */ typedef void (*tdls_offchan_parms_callback)(struct wlan_objmgr_vdev *vdev); +/* This callback is to release vdev ref for tdls_delete_all_peers_ + * callback related msg. + */ +typedef void (*tdls_delete_all_peers_callback)(struct wlan_objmgr_vdev *vdev); + /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -1072,6 +1079,16 @@ struct tdls_sta_notify_params { tdls_sta_notify_callback callback; }; +/** + * struct tdls_delete_all_peers_params - TDLS set mode params + * @vdev: vdev object + * @callback: callback to release vdev ref + */ +struct tdls_delete_all_peers_params { + struct wlan_objmgr_vdev *vdev; + tdls_delete_all_peers_callback callback; +}; + /** * struct tdls_set_mode_params - TDLS set mode params * @vdev: vdev object diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h index 4b1e99c4a302..14a19006b997 100644 --- a/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 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 @@ -158,4 +158,16 @@ QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, uint32_t session_id); +/** + * tgt_tdls_delete_all_peers_indication()- Indication to tdls component + * @psoc: soc object + * @session_id: session id + * + * This function called from legacy lim to tdls component to delete tdls peers. + * + * Return: None + */ +void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, + uint32_t session_id); + #endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index a6eb77716fc3..cf43a2f64b06 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -375,3 +375,50 @@ void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, } } +/** + * tgt_tdls_delete_all_peers_ind_callback()- Callback to call from + * TDLS component + * @psoc: soc object + * @session_id: session id + * + * This function release the obj mgr vdev ref + * + * Return: None + */ +static void tgt_tdls_delete_all_peers_ind_callback( + struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + tdls_err("vdev is NULL"); + return; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +} + +void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, + uint32_t session_id) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_delete_all_peers_params delete_peers_ind; + QDF_STATUS status; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + session_id, + WLAN_TDLS_SB_ID); + + if (!vdev) { + tdls_err("vdev not exist for the session id %d", + session_id); + return; + } + + delete_peers_ind.vdev = vdev; + delete_peers_ind.callback = tgt_tdls_delete_all_peers_ind_callback; + status = tdls_delete_all_peers_indication(&delete_peers_ind); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("tdls_delete_all_peers_indication failed"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + } +} + From 88ddf823c2c9c282b189b41b8b4cf38b02a7b4c3 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 25 May 2018 05:55:37 -0400 Subject: [PATCH 373/404] qcacmn: Add DBS to DBS switch for vdev Down Add DBS to DBS switch in opportunistic timer handler when vdev prioritization enabled. Change-Id: I902316d7f64427bcadf1131cc0b822d23fc172fa CRs-Fixed: 2338092 --- inc/wlan_policy_mgr_api.h | 32 +++++++++++++++------- inc/wlan_policy_mgr_public_struct.h | 5 ++++ src/wlan_policy_mgr_action.c | 41 +++++++++++++++++++++++------ src/wlan_policy_mgr_core.c | 5 ++-- 4 files changed, 64 insertions(+), 19 deletions(-) diff --git a/inc/wlan_policy_mgr_api.h b/inc/wlan_policy_mgr_api.h index 423b4430e2b2..f39b636346ed 100644 --- a/inc/wlan_policy_mgr_api.h +++ b/inc/wlan_policy_mgr_api.h @@ -1150,16 +1150,30 @@ struct policy_mgr_wma_cbacks { }; /** - * policy_mgr_need_opportunistic_upgrade() - Tells us if we really - * need an upgrade to 2x2 - * @psoc: PSOC object information - * This function returns if updrade to 2x2 is needed - * - * Return: PM_NOP = upgrade is not needed, otherwise upgrade is - * needed - */ +* policy_mgr_need_opportunistic_upgrade - check whether needs to change current +* HW mode to single mac 2x2 or the other DBS mode(for Dual DBS HW only). +* @psoc: PSOC object information +* @reason: enum policy_mgr_conn_update_reason +* +* This function is to check whether needs to change to single Mac mode. +* when opportunistic timer fired. But a special case for Dual DBS HW, this +* function will check DBS to DBS change is required or not: +* 1. For Dual DBS HW, if user set vdev priority list, we may need to do +* DBS to DBS switching. +* eg. P2P GO (2g) < SAP (5G) < STA (2g) in DBS2. +* If STA down, we need to switch to DBS1: P2P GO (2g) < SAP (5g). +* So, for opportunistic checking, we need to add DBS ->DBS checking +* as well. +* 2. Reason code : +* DBS -> Single MAC : POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC +* DBS -> DBS : POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE +* +* return: PM_NOP, upgrade is not needed, otherwise new action type +* and reason code be returned. +*/ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( - struct wlan_objmgr_psoc *psoc); + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_conn_update_reason *reason); /** * policy_mgr_next_actions() - initiates actions needed on current diff --git a/inc/wlan_policy_mgr_public_struct.h b/inc/wlan_policy_mgr_public_struct.h index 53c605853ab0..182afded647a 100644 --- a/inc/wlan_policy_mgr_public_struct.h +++ b/inc/wlan_policy_mgr_public_struct.h @@ -751,6 +751,10 @@ enum policy_mgr_band { * @POLICY_MGR_UPDATE_REASON_NSS_UPDATE: NSS update * @POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH: Channel switch * @POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA: Channel switch for STA + * @POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE: In Dual DBS HW, if the vdev based + * 2x2 preference enabled, the vdev down may cause prioritized active + * vdev change, then DBS hw mode may needs to change from one DBS mode + * to the other DBS mode. This reason code indicates such condition. */ enum policy_mgr_conn_update_reason { POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN, @@ -764,6 +768,7 @@ enum policy_mgr_conn_update_reason { POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH, POLICY_MGR_UPDATE_REASON_CHANNEL_SWITCH_STA, POLICY_MGR_UPDATE_REASON_PRE_CAC, + POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE, }; /** diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 874ea495bafd..27bf91d634e2 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -105,7 +105,7 @@ QDF_STATUS policy_mgr_check_n_start_opportunistic_timer( policy_mgr_err("PM ctx not valid. Oppurtunistic timer cannot start"); return QDF_STATUS_E_FAILURE; } - if (policy_mgr_need_opportunistic_upgrade(psoc)) { + if (policy_mgr_need_opportunistic_upgrade(psoc, NULL)) { /* let's start the timer */ qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); status = qdf_mc_timer_start( @@ -182,10 +182,12 @@ QDF_STATUS policy_mgr_pdev_set_hw_mode(struct wlan_objmgr_psoc *psoc, } enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( - struct wlan_objmgr_psoc *psoc) + struct wlan_objmgr_psoc *psoc, + enum policy_mgr_conn_update_reason *reason) { uint32_t conn_index; enum policy_mgr_conc_next_action upgrade = PM_NOP; + enum policy_mgr_conc_next_action preferred_dbs_action; uint8_t mac = 0; struct policy_mgr_hw_mode_params hw_mode; QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -194,22 +196,22 @@ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { policy_mgr_err("Invalid Context"); - goto done; + goto exit; } if (policy_mgr_is_hw_dbs_capable(psoc) == false) { policy_mgr_err("driver isn't dbs capable, no further action needed"); - goto done; + goto exit; } status = policy_mgr_get_current_hw_mode(psoc, &hw_mode); if (!QDF_IS_STATUS_SUCCESS(status)) { policy_mgr_err("policy_mgr_get_current_hw_mode failed"); - goto done; + goto exit; } if (!hw_mode.dbs_cap) { policy_mgr_debug("current HW mode is non-DBS capable"); - goto done; + goto exit; } qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); @@ -248,6 +250,8 @@ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( } /* Let's request for single MAC mode */ upgrade = PM_SINGLE_MAC; + if (reason) + *reason = POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC; /* Is there any connection had an initial connection with 2x2 */ for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; conn_index++) { @@ -261,6 +265,26 @@ enum policy_mgr_conc_next_action policy_mgr_need_opportunistic_upgrade( qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); done: + if (upgrade == PM_NOP && hw_mode.dbs_cap && + policy_mgr_is_2x2_1x1_dbs_capable(psoc)) { + preferred_dbs_action = + policy_mgr_get_preferred_dbs_action_table( + psoc, INVALID_VDEV_ID, 0, 0); + if (hw_mode.action_type == PM_DBS1 && + preferred_dbs_action == PM_DBS2) { + upgrade = PM_DBS2_DOWNGRADE; + if (reason) + *reason = + POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE; + } else if (hw_mode.action_type == PM_DBS2 && + preferred_dbs_action == PM_DBS1) { + upgrade = PM_DBS1_DOWNGRADE; + if (reason) + *reason = + POLICY_MGR_UPDATE_REASON_PRI_VDEV_CHANGE; + } + } +exit: return upgrade; } @@ -1908,6 +1932,7 @@ void policy_mgr_check_and_stop_opportunistic_timer( struct policy_mgr_psoc_priv_obj *pm_ctx; enum policy_mgr_conc_next_action action = PM_NOP; QDF_STATUS status = QDF_STATUS_E_FAILURE; + enum policy_mgr_conn_update_reason reason; pm_ctx = policy_mgr_get_context(psoc); if (!pm_ctx) { @@ -1917,11 +1942,11 @@ void policy_mgr_check_and_stop_opportunistic_timer( if (QDF_TIMER_STATE_RUNNING == pm_ctx->dbs_opportunistic_timer.state) { qdf_mc_timer_stop(&pm_ctx->dbs_opportunistic_timer); - action = policy_mgr_need_opportunistic_upgrade(psoc); + action = policy_mgr_need_opportunistic_upgrade(psoc, &reason); if (action) { qdf_event_reset(&pm_ctx->opportunistic_update_done_evt); status = policy_mgr_next_actions(psoc, id, action, - POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC); + reason); if (status != QDF_STATUS_SUCCESS) { policy_mgr_err("Failed in policy_mgr_next_actions"); return; diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index 3b0a04b8f101..de1763c75df2 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1394,6 +1394,7 @@ void pm_dbs_opportunistic_timer_handler(void *data) enum policy_mgr_conc_next_action action = PM_NOP; uint32_t session_id; struct wlan_objmgr_psoc *psoc = (struct wlan_objmgr_psoc *)data; + enum policy_mgr_conn_update_reason reason; if (!psoc) { policy_mgr_err("Invalid Context"); @@ -1401,13 +1402,13 @@ void pm_dbs_opportunistic_timer_handler(void *data) } /* if we still need it */ - action = policy_mgr_need_opportunistic_upgrade(psoc); + action = policy_mgr_need_opportunistic_upgrade(psoc, &reason); policy_mgr_debug("action:%d", action); if (!action) return; session_id = pm_get_vdev_id_of_first_conn_idx(psoc); policy_mgr_next_actions(psoc, session_id, action, - POLICY_MGR_UPDATE_REASON_OPPORTUNISTIC); + reason); } /** From 3515e05ceeb275c637f0708953f03ab5899bf683 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 23 Oct 2018 17:55:18 +0530 Subject: [PATCH 374/404] qcacmn: Take vdev ref before posting the tdls mgmt tx command Before posting the TDLS_CMD_TX_ACTION to scheduler thread take the vdev ref with module id TDLS and release the ref as part of freeing this command. Change-Id: Id05962a1c9fc415199f347c5d85d1e0670dc247c CRs-Fixed: 2338113 --- core/src/wlan_tdls_mgmt.c | 32 ++++++++++----------- dispatcher/src/wlan_tdls_ucfg_api.c | 43 ++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 8b051ac36871..0b4000e3fcd2 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -225,15 +225,10 @@ static QDF_STATUS tdls_activate_send_mgmt_request( if (!action_req || !action_req->vdev) return QDF_STATUS_E_NULL_VALUE; - if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(action_req->vdev, - WLAN_TDLS_SB_ID)) - return QDF_STATUS_E_NULL_VALUE; - - tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(action_req->vdev); if (!tdls_soc_obj) { status = QDF_STATUS_E_NULL_VALUE; - goto release_mgmt_ref; + goto release_cmd; } tdls_mgmt_req = qdf_mem_malloc(sizeof(struct tdls_send_mgmt_request) + @@ -242,7 +237,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request( status = QDF_STATUS_E_NOMEM; tdls_err("mem alloc failed "); QDF_ASSERT(0); - goto release_mgmt_ref; + goto release_cmd; } tdls_debug("session_id %d " @@ -274,7 +269,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request( status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID); if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(tdls_mgmt_req); - goto release_mgmt_ref; + goto release_cmd; } qdf_mem_copy(tdls_mgmt_req->bssid.bytes, @@ -309,9 +304,8 @@ static QDF_STATUS tdls_activate_send_mgmt_request( QDF_MODULE_ID_PE, &msg); wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); -release_mgmt_ref: - wlan_objmgr_vdev_release_ref(action_req->vdev, WLAN_TDLS_SB_ID); +release_cmd: /*update tdls nss infornation based on action code */ tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code); if (QDF_IS_STATUS_ERROR(status)) { @@ -352,13 +346,13 @@ tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd, */ status = tdls_internal_send_mgmt_tx_done(req, QDF_STATUS_E_FAILURE); - qdf_mem_free(req); break; case WLAN_SER_CB_RELEASE_MEM_CMD: /* command successfully completed. * release tdls_action_frame_request memory */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); qdf_mem_free(req); break; @@ -384,8 +378,7 @@ QDF_STATUS tdls_process_mgmt_req( if (status != QDF_STATUS_SUCCESS) { status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req, status); - qdf_mem_free(tdls_mgmt_req); - return status; + goto error_mgmt; } /* update the responder, status code information @@ -422,14 +415,17 @@ QDF_STATUS tdls_process_mgmt_req( case WLAN_SER_CMD_DENIED_LIST_FULL: case WLAN_SER_CMD_DENIED_RULES_FAILED: case WLAN_SER_CMD_DENIED_UNSPECIFIED: - /* free the request */ - qdf_mem_free(tdls_mgmt_req); - break; - + status = QDF_STATUS_E_FAILURE; + goto error_mgmt; default: QDF_ASSERT(0); status = QDF_STATUS_E_INVAL; - break; + goto error_mgmt; } return status; + +error_mgmt: + wlan_objmgr_vdev_release_ref(tdls_mgmt_req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(tdls_mgmt_req); + return status; } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index a87b42be126c..62e5a73c24f0 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -622,11 +622,28 @@ QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } +static QDF_STATUS tdls_send_mgmt_frame_flush_callback(struct scheduler_msg *msg) +{ + struct tdls_action_frame_request *req; + + if (!msg || !msg->bodyptr) { + tdls_err("msg or msg->bodyptr is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + req = msg->bodyptr; + if (req->vdev) + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + + qdf_mem_free(req); + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *req) { struct scheduler_msg msg = {0, }; struct tdls_action_frame_request *mgmt_req; + QDF_STATUS status; if (!req || !req->vdev) { tdls_err("Invalid mgmt req params %pK", req); @@ -653,14 +670,32 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( tdls_debug("vdev id: %d, session id : %d", mgmt_req->vdev_id, mgmt_req->session_id); + status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_TDLS_NB_ID); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Unable to get vdev reference for tdls module"); + goto mem_free; + } + msg.bodyptr = mgmt_req; msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_send_mgmt_frame_flush_callback; msg.type = TDLS_CMD_TX_ACTION; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to post the mgmt tx cmd to scheduler thread"); + goto release_ref; + } - return QDF_STATUS_SUCCESS; + return status; + +release_ref: + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); +mem_free: + qdf_mem_free(mgmt_req); + return status; } QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) From e85dfe6956f08c44fffdd2166adb8d107ae204a5 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Fri, 25 May 2018 06:31:57 -0400 Subject: [PATCH 375/404] qcacmn: Add chan change HW mode change Add policy_mgr_get_current_pref_hw_mode_dual_dbs API for dual dbs HW. In Dual DBS mode HW, it decides the actual DBS mode when DBS required. Change-Id: Ic45b09fa49e1ff923f1a2dad50a3ce7e4007a3fd CRs-Fixed: 2338105 --- src/wlan_policy_mgr_action.c | 4 +++- src/wlan_policy_mgr_core.c | 33 +++++++++++++++++++++++++++++++ src/wlan_policy_mgr_i.h | 14 +++++++++++++ src/wlan_policy_mgr_init_deinit.c | 3 +++ 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_action.c b/src/wlan_policy_mgr_action.c index 27bf91d634e2..809406cc8191 100644 --- a/src/wlan_policy_mgr_action.c +++ b/src/wlan_policy_mgr_action.c @@ -1855,7 +1855,9 @@ QDF_STATUS policy_mgr_set_hw_mode_on_channel_switch( action = (*policy_mgr_get_current_pref_hw_mode_ptr)(psoc); if ((action != PM_DBS_DOWNGRADE) && - (action != PM_SINGLE_MAC_UPGRADE)) { + (action != PM_SINGLE_MAC_UPGRADE) && + (action != PM_DBS1_DOWNGRADE) && + (action != PM_DBS2_DOWNGRADE)) { policy_mgr_err("Invalid action: %d", action); status = QDF_STATUS_SUCCESS; goto done; diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index de1763c75df2..a91ecd9c1f12 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -2955,6 +2955,39 @@ enum policy_mgr_conc_next_action return next_action; } +enum policy_mgr_conc_next_action +policy_mgr_get_current_pref_hw_mode_dual_dbs( + struct wlan_objmgr_psoc *psoc) +{ + enum policy_mgr_conc_next_action next_action; + struct policy_mgr_psoc_priv_obj *pm_ctx; + enum policy_mgr_conc_next_action preferred_dbs; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return PM_NOP; + } + + next_action = policy_mgr_get_current_pref_hw_mode_dbs_1x1(psoc); + policy_mgr_info("next_action %d", next_action); + if (next_action != PM_DBS_DOWNGRADE) + return next_action; + + preferred_dbs = policy_mgr_get_preferred_dbs_action_table( + psoc, INVALID_VDEV_ID, 0, 0); + if (preferred_dbs == PM_DBS1) { + next_action = PM_DBS1_DOWNGRADE; + } else if (preferred_dbs == PM_DBS2) { + next_action = PM_DBS2_DOWNGRADE; + } else { + policy_mgr_err("DBS1 and DBS2 hw mode not supported"); + return PM_NOP; + } + policy_mgr_info("preferred_dbs %d", next_action); + return next_action; +} + /** * policy_mgr_reset_sap_mandatory_channels() - Reset the SAP mandatory channels * diff --git a/src/wlan_policy_mgr_i.h b/src/wlan_policy_mgr_i.h index 0a9d52b47050..5f29c534f726 100644 --- a/src/wlan_policy_mgr_i.h +++ b/src/wlan_policy_mgr_i.h @@ -489,6 +489,20 @@ enum policy_mgr_conc_next_action enum policy_mgr_conc_next_action policy_mgr_get_current_pref_hw_mode_dbs_1x1( struct wlan_objmgr_psoc *psoc); + +/** + * policy_mgr_get_current_pref_hw_mode_dual_dbs() - Get the + * current preferred hw mode + * + * Get the preferred hw mode based on the current connection combinations + * + * Return: No change (PM_NOP), (PM_SINGLE_MAC_UPGRADE), + * DBS (PM_DBS1_DOWNGRADE or PM_DBS2_DOWNGRADE) + */ +enum policy_mgr_conc_next_action + policy_mgr_get_current_pref_hw_mode_dual_dbs( + struct wlan_objmgr_psoc *psoc); + QDF_STATUS policy_mgr_reset_sap_mandatory_channels( struct policy_mgr_psoc_priv_obj *pm_ctx); diff --git a/src/wlan_policy_mgr_init_deinit.c b/src/wlan_policy_mgr_init_deinit.c index 2dc015d3f404..3b99c7ce6620 100644 --- a/src/wlan_policy_mgr_init_deinit.c +++ b/src/wlan_policy_mgr_init_deinit.c @@ -423,6 +423,9 @@ QDF_STATUS policy_mgr_psoc_enable(struct wlan_objmgr_psoc *psoc) if (policy_mgr_is_hw_dbs_2x2_capable(psoc)) policy_mgr_get_current_pref_hw_mode_ptr = policy_mgr_get_current_pref_hw_mode_dbs_2x2; + else if (policy_mgr_is_2x2_1x1_dbs_capable(psoc)) + policy_mgr_get_current_pref_hw_mode_ptr = + policy_mgr_get_current_pref_hw_mode_dual_dbs; else policy_mgr_get_current_pref_hw_mode_ptr = policy_mgr_get_current_pref_hw_mode_dbs_1x1; From d89c5d5d6fa416d9f4fe8fbe33529e88867f2a73 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 19 Sep 2018 23:35:14 -0400 Subject: [PATCH 376/404] qcacmn: Action frame random mac addr tx support 1. Send add random mac addr rx filter WMI command to target 2. Add/Del the active random mac addr entry 3. Clear random mac addr from target if not active Change-Id: I9dcbdc20b76d9865da7a8db6ee013bf5e44e4407 CRs-Fixed: 2322097 --- core/src/wlan_p2p_main.c | 42 +- core/src/wlan_p2p_main.h | 91 +++ core/src/wlan_p2p_off_chan_tx.c | 894 +++++++++++++++++++++++- core/src/wlan_p2p_off_chan_tx.h | 151 ++++ dispatcher/inc/wlan_p2p_public_struct.h | 24 + dispatcher/inc/wlan_p2p_tgt_api.h | 27 + dispatcher/inc/wlan_p2p_ucfg_api.h | 16 +- dispatcher/src/wlan_p2p_tgt_api.c | 61 ++ dispatcher/src/wlan_p2p_ucfg_api.c | 14 +- 9 files changed, 1313 insertions(+), 7 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index a8989ad26af6..93d4edf40dc4 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -59,6 +59,8 @@ static char *p2p_get_cmd_type_str(enum p2p_cmd_type cmd_type) return "P2P cleanup roc"; case P2P_CLEANUP_TX: return "P2P cleanup tx"; + case P2P_SET_RANDOM_MAC: + return "P2P set random mac"; default: return "Invalid P2P command"; } @@ -85,6 +87,8 @@ static char *p2p_get_event_type_str(enum p2p_event_type event_type) return "P2P lo stop event"; case P2P_EVENT_NOA: return "P2P noa event"; + case P2P_EVENT_ADD_MAC_RSP: + return "P2P add mac filter resp event"; default: return "Invalid P2P event"; } @@ -202,8 +206,12 @@ static QDF_STATUS p2p_vdev_obj_create_notification( mode = wlan_vdev_mlme_get_opmode(vdev); p2p_debug("vdev mode:%d", mode); - if (mode != QDF_P2P_GO_MODE) { - p2p_debug("won't create p2p vdev private object if it is not GO"); + if (mode != QDF_P2P_GO_MODE && + mode != QDF_STA_MODE && + mode != QDF_P2P_CLIENT_MODE && + mode != QDF_P2P_DEVICE_MODE) { + p2p_debug("won't create p2p vdev private object for mode %d", + mode); return QDF_STATUS_SUCCESS; } @@ -217,11 +225,13 @@ static QDF_STATUS p2p_vdev_obj_create_notification( p2p_vdev_obj->vdev = vdev; p2p_vdev_obj->noa_status = true; p2p_vdev_obj->non_p2p_peer_count = 0; + p2p_init_random_mac_vdev(p2p_vdev_obj); status = wlan_objmgr_vdev_component_obj_attach(vdev, WLAN_UMAC_COMP_P2P, p2p_vdev_obj, QDF_STATUS_SUCCESS); if (status != QDF_STATUS_SUCCESS) { + p2p_deinit_random_mac_vdev(p2p_vdev_obj); qdf_mem_free(p2p_vdev_obj); p2p_err("Failed to attach p2p component to vdev, %d", status); @@ -257,8 +267,11 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( mode = wlan_vdev_mlme_get_opmode(vdev); p2p_debug("vdev mode:%d", mode); - if (mode != QDF_P2P_GO_MODE) { - p2p_debug("no p2p vdev private object if it is not GO"); + if (mode != QDF_P2P_GO_MODE && + mode != QDF_STA_MODE && + mode != QDF_P2P_CLIENT_MODE && + mode != QDF_P2P_DEVICE_MODE){ + p2p_debug("no p2p vdev private object for mode %d", mode); return QDF_STATUS_SUCCESS; } @@ -268,6 +281,7 @@ static QDF_STATUS p2p_vdev_obj_destroy_notification( p2p_debug("p2p vdev object is NULL"); return QDF_STATUS_SUCCESS; } + p2p_deinit_random_mac_vdev(p2p_vdev_obj); p2p_vdev_obj->vdev = NULL; @@ -313,6 +327,10 @@ static QDF_STATUS p2p_peer_obj_create_notification( } vdev = wlan_peer_get_vdev(peer); + mode = wlan_vdev_mlme_get_opmode(vdev); + if (mode != QDF_P2P_GO_MODE) + return QDF_STATUS_SUCCESS; + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_P2P); peer_type = wlan_peer_get_peer_type(peer); @@ -356,6 +374,10 @@ static QDF_STATUS p2p_peer_obj_destroy_notification( } vdev = wlan_peer_get_vdev(peer); + mode = wlan_vdev_mlme_get_opmode(vdev); + if (mode != QDF_P2P_GO_MODE) + return QDF_STATUS_SUCCESS; + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_P2P); psoc = wlan_vdev_get_psoc(vdev); @@ -842,6 +864,7 @@ QDF_STATUS p2p_psoc_start(struct wlan_objmgr_psoc *soc, /* register p2p lo stop and noa event */ tgt_p2p_register_lo_ev_handler(soc); tgt_p2p_register_noa_ev_handler(soc); + tgt_p2p_register_macaddr_rx_filter_evt_handler(soc, true); /* register scan request id */ p2p_soc_obj->scan_req_id = ucfg_scan_register_requester( @@ -892,6 +915,7 @@ QDF_STATUS p2p_psoc_stop(struct wlan_objmgr_psoc *soc) ucfg_scan_unregister_requester(soc, p2p_soc_obj->scan_req_id); /* unregister p2p lo stop and noa event */ + tgt_p2p_register_macaddr_rx_filter_evt_handler(soc, false); tgt_p2p_unregister_lo_ev_handler(soc); tgt_p2p_unregister_noa_ev_handler(soc); @@ -954,6 +978,11 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg) msg->bodyptr); qdf_mem_free(msg->bodyptr); break; + case P2P_SET_RANDOM_MAC: + status = p2p_process_set_rand_mac(msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; + default: p2p_err("drop unexpected message received %d", msg->type); @@ -997,6 +1026,11 @@ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg) (struct p2p_noa_event *) msg->bodyptr); break; + case P2P_EVENT_ADD_MAC_RSP: + status = p2p_process_set_rand_mac_rsp( + (struct p2p_mac_filter_rsp *) + msg->bodyptr); + break; default: p2p_err("Drop unexpected message received %d", msg->type); diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index ef0fc484794e..8a89d93e7303 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -34,6 +34,7 @@ #define P2P_NOA_ATTR_IND 0x1090 #define P2P_MODULE_NAME "P2P" #define P2P_INVALID_VDEV_ID 0xFFFFFFFF +#define MAX_RANDOM_MAC_ADDRS 4 #define p2p_debug(params ...) \ QDF_TRACE_DEBUG(QDF_MODULE_ID_P2P, params) @@ -73,6 +74,7 @@ struct tx_action_context; * @P2P_MGMT_TX_CANCEL: Cancel tx action frame request * @P2P_CLEANUP_ROC: Cleanup roc queue * @P2P_CLEANUP_TX: Cleanup tx mgmt queue + * @P2P_SET_RANDOM_MAC: Set Random MAC addr filter request */ enum p2p_cmd_type { P2P_ROC_REQ = 0, @@ -81,6 +83,7 @@ enum p2p_cmd_type { P2P_MGMT_TX_CANCEL, P2P_CLEANUP_ROC, P2P_CLEANUP_TX, + P2P_SET_RANDOM_MAC, }; /** @@ -90,6 +93,7 @@ enum p2p_cmd_type { * @P2P_EVENT_RX_MGMT: P2P rx mgmt frame * @P2P_EVENT_LO_STOPPED: P2P listen offload stopped event * @P2P_EVENT_NOA: P2P noa event + * @P2P_EVENT_ADD_MAC_RSP: Set Random MAC addr event */ enum p2p_event_type { P2P_EVENT_SCAN_EVENT = 0, @@ -97,6 +101,7 @@ enum p2p_event_type { P2P_EVENT_RX_MGMT, P2P_EVENT_LO_STOPPED, P2P_EVENT_NOA, + P2P_EVENT_ADD_MAC_RSP, }; /** @@ -141,6 +146,18 @@ struct p2p_noa_event { struct p2p_noa_info *noa_info; }; +/** + * struct p2p_mac_filter_rsp - p2p set mac filter respone + * @p2p_soc_obj: p2p soc private object + * @vdev_id: vdev id + * @status: successfully(1) or not (0) + */ +struct p2p_mac_filter_rsp { + struct p2p_soc_priv_obj *p2p_soc_obj; + uint32_t vdev_id; + uint32_t status; +}; + #ifdef WLAN_FEATURE_P2P_DEBUG /** * enum p2p_connection_status - p2p connection status @@ -224,18 +241,92 @@ struct p2p_soc_priv_obj { #endif }; +/** + * struct action_frame_cookie - Action frame cookie item in cookie list + * @cookie_node: qdf_list_node + * @cookie: Cookie value + */ +struct action_frame_cookie { + qdf_list_node_t cookie_node; + uint64_t cookie; +}; + +/** + * struct action_frame_random_mac - Action Frame random mac addr & + * related attrs + * @p2p_vdev_obj: p2p vdev private obj ptr + * @in_use: Checks whether random mac is in use + * @addr: Contains random mac addr + * @freq: Channel frequency + * @clear_timer: timer to clear random mac filter + * @cookie_list: List of cookies tied with random mac + */ +struct action_frame_random_mac { + struct p2p_vdev_priv_obj *p2p_vdev_obj; + bool in_use; + uint8_t addr[QDF_MAC_ADDR_SIZE]; + uint32_t freq; + qdf_mc_timer_t clear_timer; + qdf_list_t cookie_list; +}; + +/** + * p2p_request_mgr_callback_t() - callback to process set mac filter result + * @result: bool + * @context: callback context. + * + * Return: void + */ +typedef void (*p2p_request_mgr_callback_t)(bool result, void *context); + +/** + * struct random_mac_priv - request private data struct + * @result: result of request. + */ +struct random_mac_priv { + bool result; +}; + +/** + * struct p2p_set_mac_filter_req - set mac addr filter cmd data structure + * @soc: soc object + * @vdev_id: vdev id + * @mac: mac address to be set + * @freq: frequency + * @set: set or clear + * @cb: callback func to be called when the request completion + * @req_cookie: cookie to be used when request completed + */ +struct p2p_set_mac_filter_req { + struct wlan_objmgr_psoc *soc; + uint32_t vdev_id; + uint8_t mac[QDF_MAC_ADDR_SIZE]; + uint32_t freq; + bool set; + p2p_request_mgr_callback_t cb; + void *req_cookie; +}; + /** * struct p2p_vdev_priv_obj - Per vdev p2p private object * @vdev: Pointer to vdev context * @noa_info: NoA information * @noa_status: NoA status i.e. Enabled / Disabled (TRUE/FALSE) * @non_p2p_peer_count: Number of legacy stations connected to this GO + * @random_mac_lock: lock for random_mac list + * @random_mac: active random mac filter lists + * @pending_req: pending set mac filter request. */ struct p2p_vdev_priv_obj { struct wlan_objmgr_vdev *vdev; struct p2p_noa_info *noa_info; bool noa_status; uint16_t non_p2p_peer_count; + + /* random address management for management action frames */ + qdf_spinlock_t random_mac_lock; + struct action_frame_random_mac random_mac[MAX_RANDOM_MAC_ADDRS]; + struct p2p_set_mac_filter_req pending_req; }; /** diff --git a/core/src/wlan_p2p_off_chan_tx.c b/core/src/wlan_p2p_off_chan_tx.c index 71ac3ee5a87f..1309ccd08df1 100644 --- a/core/src/wlan_p2p_off_chan_tx.c +++ b/core/src/wlan_p2p_off_chan_tx.c @@ -32,6 +32,21 @@ #include "wlan_p2p_roc.h" #include "wlan_p2p_main.h" #include "wlan_p2p_off_chan_tx.h" +#include "wlan_osif_request_manager.h" + +/** + * p2p_psoc_get_tx_ops() - get p2p tx ops + * @psoc: psoc object + * + * This function returns p2p tx ops callbacks. + * + * Return: wlan_lmac_if_p2p_tx_ops + */ +static inline struct wlan_lmac_if_p2p_tx_ops * +p2p_psoc_get_tx_ops(struct wlan_objmgr_psoc *psoc) +{ + return &psoc->soc_cb.tx_ops.p2p; +} /** * p2p_tx_context_check_valid() - check tx action context @@ -469,6 +484,7 @@ static QDF_STATUS p2p_populate_mac_header( void *mac_addr; uint16_t seq_num; uint8_t pdev_id; + struct wlan_objmgr_vdev *vdev; psoc = tx_ctx->p2p_soc_obj->soc; @@ -482,7 +498,17 @@ static QDF_STATUS p2p_populate_mac_header( peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_P2P_ID); } - + if (!peer && tx_ctx->rand_mac_tx) { + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + tx_ctx->vdev_id, + WLAN_P2P_ID); + if (vdev) { + mac_addr = wlan_vdev_mlme_get_macaddr(vdev); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, + WLAN_P2P_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + } + } if (!peer) { p2p_err("no valid peer"); return QDF_STATUS_E_INVAL; @@ -855,6 +881,8 @@ static QDF_STATUS p2p_send_tx_conf(struct tx_action_context *tx_ctx, tx_cnf.action_cookie, tx_cnf.buf_len, tx_cnf.status, tx_cnf.buf); + p2p_rand_mac_tx_done(p2p_soc_obj->soc, tx_ctx); + start_param->tx_cnf_cb(start_param->tx_cnf_cb_data, &tx_cnf); return QDF_STATUS_SUCCESS; @@ -883,6 +911,7 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, struct wlan_objmgr_psoc *psoc; void *mac_addr; uint8_t pdev_id; + struct wlan_objmgr_vdev *vdev; psoc = tx_ctx->p2p_soc_obj->soc; mgmt_param.tx_frame = packet; @@ -907,6 +936,16 @@ static QDF_STATUS p2p_mgmt_tx(struct tx_action_context *tx_ctx, peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, WLAN_P2P_ID); } + if (!peer && tx_ctx->rand_mac_tx) { + vdev = wlan_objmgr_get_vdev_by_id_from_psoc( + psoc, tx_ctx->vdev_id, WLAN_P2P_ID); + if (vdev) { + mac_addr = wlan_vdev_mlme_get_macaddr(vdev); + peer = wlan_objmgr_get_peer(psoc, pdev_id, mac_addr, + WLAN_P2P_ID); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + } + } if (!peer) { p2p_err("no valid peer"); @@ -1770,6 +1809,857 @@ QDF_STATUS p2p_process_cleanup_tx_queue(struct p2p_cleanup_param *param) return QDF_STATUS_SUCCESS; } +bool p2p_check_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *random_mac_addr) +{ + uint32_t i = 0; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_debug("vdev is null"); + return false; + } + + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("p2p vdev object is NULL"); + return false; + } + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + if ((p2p_vdev_obj->random_mac[i].in_use) && + (!qdf_mem_cmp(p2p_vdev_obj->random_mac[i].addr, + random_mac_addr, QDF_MAC_ADDR_SIZE))) { + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + return true; + } + } + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return false; +} + +/** + * find_action_frame_cookie() - Checks for action cookie in cookie list + * @cookie_list: List of cookies + * @rnd_cookie: Cookie to be searched + * + * Return: If search is successful return pointer to action_frame_cookie + * object in which cookie item is encapsulated. + */ +static struct action_frame_cookie * +find_action_frame_cookie(qdf_list_t *cookie_list, uint64_t rnd_cookie) +{ + struct action_frame_cookie *action_cookie; + + qdf_list_for_each(cookie_list, action_cookie, cookie_node) { + if (action_cookie->cookie == rnd_cookie) + return action_cookie; + } + + return NULL; +} + +/** + * allocate_action_frame_cookie() - Allocate and add action cookie to + * given list + * @cookie_list: List of cookies + * @rnd_cookie: Cookie to be added + * + * Return: If allocation and addition is successful return pointer to + * action_frame_cookie object in which cookie item is encapsulated. + */ +static struct action_frame_cookie * +allocate_action_frame_cookie(qdf_list_t *cookie_list, uint64_t rnd_cookie) +{ + struct action_frame_cookie *action_cookie; + + action_cookie = qdf_mem_malloc(sizeof(*action_cookie)); + if (!action_cookie) + return NULL; + + action_cookie->cookie = rnd_cookie; + qdf_list_insert_front(cookie_list, &action_cookie->cookie_node); + + return action_cookie; +} + +/** + * delete_action_frame_cookie() - Delete the cookie from given list + * @cookie_list: List of cookies + * @action_cookie: Cookie to be deleted + * + * This function deletes the cookie item from given list and corresponding + * object in which it is encapsulated. + * + * Return: None + */ +static void +delete_action_frame_cookie(qdf_list_t *cookie_list, + struct action_frame_cookie *action_cookie) +{ + qdf_list_remove_node(cookie_list, &action_cookie->cookie_node); + qdf_mem_free(action_cookie); +} + +/** + * append_action_frame_cookie() - Append action cookie to given list + * @cookie_list: List of cookies + * @rnd_cookie: Cookie to be append + * + * This is a wrapper function which invokes allocate_action_frame_cookie + * if the cookie to be added is not duplicate + * + * Return: true - for successful case + * false - failed. + */ +static bool +append_action_frame_cookie(qdf_list_t *cookie_list, uint64_t rnd_cookie) +{ + struct action_frame_cookie *action_cookie; + + /* + * There should be no mac entry with empty cookie list, + * check and ignore if duplicate + */ + action_cookie = find_action_frame_cookie(cookie_list, rnd_cookie); + if (action_cookie) + /* random mac address is already programmed */ + return true; + + /* insert new cookie in cookie list */ + action_cookie = allocate_action_frame_cookie(cookie_list, rnd_cookie); + if (!action_cookie) + return false; + + return true; +} + +/** + * p2p_add_random_mac() - add or append random mac to given vdev rand mac list + * @soc: soc object + * @vdev_id: vdev id + * @mac: mac addr to be added or append + * @freq: frequency + * @rnd_cookie: random mac mgmt tx cookie + * + * This function will add or append the mac addr entry to vdev random mac list. + * Once the mac addr filter is not needed, it can be removed by + * p2p_del_random_mac. + * + * Return: QDF_STATUS_E_EXISTS - append to existing list + * QDF_STATUS_SUCCESS - add a new entry. + * other : failed to add the mac address entry. + */ +static QDF_STATUS +p2p_add_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *mac, uint32_t freq, uint64_t rnd_cookie) +{ + uint32_t i; + uint32_t first_unused = MAX_RANDOM_MAC_ADDRS; + struct action_frame_cookie *action_cookie; + int32_t append_ret; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct wlan_objmgr_vdev *vdev; + + p2p_debug("random_mac:vdev %d mac_addr:%pM rnd_cookie=%llu freq = %u", + vdev_id, mac, rnd_cookie, freq); + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_debug("vdev is null"); + + return QDF_STATUS_E_INVAL; + } + + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) { + p2p_debug("random_mac:p2p vdev object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return QDF_STATUS_E_INVAL; + } + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + /* + * Following loop checks whether random mac entry is already + * present, if present get the index of matched entry else + * get the first unused slot to store this new random mac + */ + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + if (!p2p_vdev_obj->random_mac[i].in_use) { + if (first_unused == MAX_RANDOM_MAC_ADDRS) + first_unused = i; + continue; + } + + if (!qdf_mem_cmp(p2p_vdev_obj->random_mac[i].addr, mac, + QDF_MAC_ADDR_SIZE)) + break; + } + + if (i != MAX_RANDOM_MAC_ADDRS) { + append_ret = append_action_frame_cookie( + &p2p_vdev_obj->random_mac[i].cookie_list, + rnd_cookie); + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("random_mac:append %d vdev %d freq %d %pM rnd_cookie %llu", + append_ret, vdev_id, freq, mac, rnd_cookie); + if (!append_ret) { + p2p_debug("random_mac:failed to append rnd_cookie"); + return QDF_STATUS_E_NOMEM; + } + + return QDF_STATUS_E_EXISTS; + } + + if (first_unused == MAX_RANDOM_MAC_ADDRS) { + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("random_mac:Reached the limit of Max random addresses"); + + return QDF_STATUS_E_RESOURCES; + } + + /* get the first unused buf and store new random mac */ + i = first_unused; + + action_cookie = allocate_action_frame_cookie( + &p2p_vdev_obj->random_mac[i].cookie_list, + rnd_cookie); + if (!action_cookie) { + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_err("random_mac:failed to alloc rnd cookie"); + + return QDF_STATUS_E_NOMEM; + } + qdf_mem_copy(p2p_vdev_obj->random_mac[i].addr, mac, QDF_MAC_ADDR_SIZE); + p2p_vdev_obj->random_mac[i].in_use = true; + p2p_vdev_obj->random_mac[i].freq = freq; + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("random_mac:add vdev %d freq %d %pM rnd_cookie %llu", + vdev_id, freq, mac, rnd_cookie); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +p2p_del_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint64_t rnd_cookie, uint32_t duration) +{ + uint32_t i; + struct action_frame_cookie *action_cookie; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct wlan_objmgr_vdev *vdev; + + p2p_debug("random_mac:vdev %d cookie %llu duration %d", vdev_id, + rnd_cookie, duration); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, + WLAN_P2P_ID); + if (!vdev) { + p2p_debug("vdev is null"); + return QDF_STATUS_E_INVAL; + } + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("p2p vdev object is NULL"); + return QDF_STATUS_E_INVAL; + } + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + struct action_frame_random_mac *random_mac; + + random_mac = &p2p_vdev_obj->random_mac[i]; + if (!random_mac->in_use) + continue; + + action_cookie = find_action_frame_cookie( + &random_mac->cookie_list, rnd_cookie); + if (!action_cookie) + continue; + + delete_action_frame_cookie( + &random_mac->cookie_list, + action_cookie); + + if (qdf_list_empty(&random_mac->cookie_list)) { + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + if (qdf_mc_timer_get_current_state( + &random_mac->clear_timer) == + QDF_TIMER_STATE_RUNNING) + qdf_mc_timer_stop(&random_mac->clear_timer); + qdf_mc_timer_start(&random_mac->clear_timer, duration); + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + p2p_debug("random_mac:noref on vdev %d addr %pM", + vdev_id, random_mac->addr); + } + break; + } + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return QDF_STATUS_SUCCESS; +} + +void p2p_del_all_rand_mac_vdev(struct wlan_objmgr_vdev *vdev) +{ + int32_t i; + uint32_t freq; + uint8_t addr[QDF_MAC_ADDR_SIZE]; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + + if (!vdev) + return; + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) + return; + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + struct action_frame_cookie *action_cookie; + struct action_frame_cookie *action_cookie_next; + + if (!p2p_vdev_obj->random_mac[i].in_use) + continue; + + /* empty the list and clear random addr */ + qdf_list_for_each_del(&p2p_vdev_obj->random_mac[i].cookie_list, + action_cookie, action_cookie_next, + cookie_node) { + qdf_list_remove_node( + &p2p_vdev_obj->random_mac[i].cookie_list, + &action_cookie->cookie_node); + qdf_mem_free(action_cookie); + } + + p2p_vdev_obj->random_mac[i].in_use = false; + freq = p2p_vdev_obj->random_mac[i].freq; + qdf_mem_copy(addr, p2p_vdev_obj->random_mac[i].addr, + QDF_MAC_ADDR_SIZE); + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + qdf_mc_timer_stop(&p2p_vdev_obj->random_mac[i].clear_timer); + p2p_clear_mac_filter(wlan_vdev_get_psoc(vdev), + wlan_vdev_get_id(vdev), addr, freq); + p2p_debug("random_mac:delall vdev %d freq %d addr %pM", + wlan_vdev_get_id(vdev), freq, addr); + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + } + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); +} + +static void +p2p_del_rand_mac_vdev_enum_handler(struct wlan_objmgr_psoc *psoc, + void *obj, void *arg) +{ + struct wlan_objmgr_vdev *vdev = obj; + + if (!vdev) { + p2p_err("random_mac:invalid vdev"); + return; + } + + if (!p2p_is_vdev_support_rand_mac(vdev)) + return; + + p2p_del_all_rand_mac_vdev(vdev); +} + +void p2p_del_all_rand_mac_soc(struct wlan_objmgr_psoc *soc) +{ + if (!soc) { + p2p_err("random_mac:soc object is NULL"); + return; + } + + wlan_objmgr_iterate_obj_list(soc, WLAN_VDEV_OP, + p2p_del_rand_mac_vdev_enum_handler, + NULL, 0, WLAN_P2P_ID); +} + +/** + * p2p_is_random_mac() - check mac addr is random mac for vdev + * @soc: soc object + * @vdev_id: vdev id + * @mac: mac addr to be added or append + * + * This function will check the source mac addr same as vdev's mac addr or not. + * If not same, then the source mac addr should be random mac addr. + * + * Return: true if mac is random mac, otherwise false + */ +static bool +p2p_is_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, uint8_t *mac) +{ + bool ret = false; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_debug("random_mac:vdev is null"); + return false; + } + + if (qdf_mem_cmp(wlan_vdev_mlme_get_macaddr(vdev), + mac, QDF_MAC_ADDR_SIZE)) + ret = true; + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return ret; +} + +static void p2p_set_mac_filter_callback(bool result, void *context) +{ + struct osif_request *request; + struct random_mac_priv *priv; + + p2p_debug("random_mac:set random mac filter result %d", result); + request = osif_request_get(context); + if (!request) { + p2p_err("random_mac:invalid response"); + return; + } + + priv = osif_request_priv(request); + priv->result = result; + + osif_request_complete(request); + osif_request_put(request); +} + +QDF_STATUS p2p_process_set_rand_mac_rsp(struct p2p_mac_filter_rsp *resp) +{ + struct wlan_objmgr_psoc *soc; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct wlan_objmgr_vdev *vdev; + + if (!resp || !resp->p2p_soc_obj || !resp->p2p_soc_obj->soc) { + p2p_debug("random_mac:set_filter_req is null"); + return QDF_STATUS_E_INVAL; + } + p2p_debug("random_mac:process rsp on vdev %d status %d", resp->vdev_id, + resp->status); + soc = resp->p2p_soc_obj->soc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, resp->vdev_id, + WLAN_P2P_ID); + if (!vdev) { + p2p_debug("random_mac:vdev is null vdev %d", resp->vdev_id); + return QDF_STATUS_E_INVAL; + } + + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("random_mac:p2p_vdev_obj is null vdev %d", + resp->vdev_id); + return QDF_STATUS_E_INVAL; + } + if (!p2p_vdev_obj->pending_req.soc) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + p2p_debug("random_mac:no pending set req for vdev %d", + resp->vdev_id); + return QDF_STATUS_E_INVAL; + } + + p2p_debug("random_mac:get pending req on vdev %d set %d mac filter %pM freq %d", + p2p_vdev_obj->pending_req.vdev_id, + p2p_vdev_obj->pending_req.set, p2p_vdev_obj->pending_req.mac, + p2p_vdev_obj->pending_req.freq); + if (p2p_vdev_obj->pending_req.cb) + p2p_vdev_obj->pending_req.cb( + !!resp->status, p2p_vdev_obj->pending_req.req_cookie); + + qdf_mem_zero(&p2p_vdev_obj->pending_req, + sizeof(p2p_vdev_obj->pending_req)); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +p2p_process_set_rand_mac(struct p2p_set_mac_filter_req *set_filter_req) +{ + struct wlan_objmgr_psoc *soc; + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct p2p_set_mac_filter param; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + struct wlan_objmgr_vdev *vdev; + + if (!set_filter_req || !set_filter_req->soc) { + p2p_debug("random_mac:set_filter_req is null"); + return QDF_STATUS_E_INVAL; + } + p2p_debug("random_mac:vdev %d set %d mac filter %pM freq %d", + set_filter_req->vdev_id, set_filter_req->set, + set_filter_req->mac, set_filter_req->freq); + + soc = set_filter_req->soc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc( + soc, set_filter_req->vdev_id, WLAN_P2P_ID); + if (!vdev) { + p2p_debug("random_mac:vdev is null vdev %d", + set_filter_req->vdev_id); + goto get_vdev_failed; + } + p2p_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj( + vdev, WLAN_UMAC_COMP_P2P); + if (!p2p_vdev_obj) { + p2p_debug("random_mac:p2p_vdev_obj is null vdev %d", + set_filter_req->vdev_id); + goto get_p2p_obj_failed; + } + if (p2p_vdev_obj->pending_req.soc) { + p2p_debug("random_mac:Busy on vdev %d set %d mac filter %pM freq %d", + p2p_vdev_obj->pending_req.vdev_id, + p2p_vdev_obj->pending_req.set, + p2p_vdev_obj->pending_req.mac, + p2p_vdev_obj->pending_req.freq); + goto get_p2p_obj_failed; + } + + p2p_ops = p2p_psoc_get_tx_ops(soc); + if (p2p_ops && p2p_ops->set_mac_addr_rx_filter_cmd) { + qdf_mem_zero(¶m, sizeof(param)); + param.vdev_id = set_filter_req->vdev_id; + qdf_mem_copy(param.mac, set_filter_req->mac, + QDF_MAC_ADDR_SIZE); + param.freq = set_filter_req->freq; + param.set = set_filter_req->set; + status = p2p_ops->set_mac_addr_rx_filter_cmd(soc, ¶m); + if (status == QDF_STATUS_SUCCESS && set_filter_req->set) + qdf_mem_copy(&p2p_vdev_obj->pending_req, + set_filter_req, sizeof(*set_filter_req)); + p2p_debug("random_mac:p2p set mac addr rx filter, status:%d", + status); + } + +get_p2p_obj_failed: + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + +get_vdev_failed: + if (status != QDF_STATUS_SUCCESS && + set_filter_req->cb) + set_filter_req->cb(false, set_filter_req->req_cookie); + + return status; +} + +/** + * p2p_set_mac_filter() - send set mac addr filter cmd + * @soc: soc + * @vdev_id: vdev id + * @mac: mac addr + * @freq: freq + * @set: set or clear + * @cb: callback func to be called when the request completed. + * @req_cookie: cookie to be returned + * + * This function send set random mac addr filter command to p2p component + * msg core + * + * Return: QDF_STATUS_SUCCESS - if sent successfully. + * otherwise : failed. + */ +static QDF_STATUS +p2p_set_mac_filter(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *mac, uint32_t freq, bool set, + p2p_request_mgr_callback_t cb, void *req_cookie) +{ + struct p2p_set_mac_filter_req *set_filter_req; + struct scheduler_msg msg = {0}; + QDF_STATUS status; + + p2p_debug("random_mac:vdev %d freq %d set %d %pM", + vdev_id, freq, set, mac); + + set_filter_req = qdf_mem_malloc(sizeof(*set_filter_req)); + if (!set_filter_req) + return QDF_STATUS_E_NOMEM; + + set_filter_req->soc = soc; + set_filter_req->vdev_id = vdev_id; + set_filter_req->freq = freq; + qdf_mem_copy(set_filter_req->mac, mac, QDF_MAC_ADDR_SIZE); + set_filter_req->set = set; + set_filter_req->cb = cb; + set_filter_req->req_cookie = req_cookie; + + msg.type = P2P_SET_RANDOM_MAC; + msg.bodyptr = set_filter_req; + msg.callback = p2p_process_cmd; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (status != QDF_STATUS_SUCCESS) + qdf_mem_free(set_filter_req); + + return status; +} + +QDF_STATUS +p2p_clear_mac_filter(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *mac, uint32_t freq) +{ + return p2p_set_mac_filter(soc, vdev_id, mac, freq, false, NULL, NULL); +} + +bool +p2p_is_vdev_support_rand_mac(struct wlan_objmgr_vdev *vdev) +{ + enum QDF_OPMODE mode; + + mode = wlan_vdev_mlme_get_opmode(vdev); + if (mode == QDF_STA_MODE || + mode == QDF_P2P_CLIENT_MODE || + mode == QDF_P2P_DEVICE_MODE) + return true; + return false; +} + +/** + * p2p_is_vdev_support_rand_mac_by_id() - check vdev type support random mac + * mgmt tx or not + * @soc: soc obj + * @vdev_id: vdev id + * + * Return: true: support random mac mgmt tx + * false: not support random mac mgmt tx. + */ +static bool +p2p_is_vdev_support_rand_mac_by_id(struct wlan_objmgr_psoc *soc, + uint32_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + bool ret = false; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(soc, vdev_id, WLAN_P2P_ID); + if (!vdev) + return false; + ret = p2p_is_vdev_support_rand_mac(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_P2P_ID); + + return ret; +} + +/** + * p2p_set_rand_mac() - set random mac address rx filter + * @soc: soc + * @vdev_id: vdev id + * @mac: mac addr + * @freq: freq + * @rnd_cookie: cookie to be returned + * + * This function will post msg to p2p core to set random mac addr rx filter. + * It will wait the respone and return the result to caller. + * + * Return: true: set successfully + * false: failed + */ +static bool +p2p_set_rand_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *mac, uint32_t freq, uint64_t rnd_cookie) +{ + bool ret = false; + int err; + QDF_STATUS status; + struct osif_request *request; + static const struct osif_request_params params = { + .priv_size = sizeof(struct random_mac_priv), + .timeout_ms = WLAN_WAIT_TIME_SET_RND, + }; + void *req_cookie; + struct random_mac_priv *priv; + + request = osif_request_alloc(¶ms); + if (!request) { + p2p_err("Request allocation failure"); + return false; + } + + req_cookie = osif_request_cookie(request); + + status = p2p_set_mac_filter(soc, vdev_id, mac, freq, true, + p2p_set_mac_filter_callback, req_cookie); + if (status != QDF_STATUS_SUCCESS) { + p2p_err("random_mac:set mac fitler failure %d", status); + } else { + err = osif_request_wait_for_response(request); + if (err) { + p2p_err("random_mac:timeout for set mac fitler %d", + err); + } else { + priv = osif_request_priv(request); + ret = priv->result; + p2p_debug("random_mac:vdev %d freq %d result %d %pM rnd_cookie %llu", + vdev_id, freq, priv->result, mac, rnd_cookie); + } + } + osif_request_put(request); + + return ret; +} + +/** + * p2p_request_random_mac() - request random mac mgmt tx + * @soc: soc + * @vdev_id: vdev id + * @mac: mac addr + * @freq: freq + * @rnd_cookie: cookie to be returned + * @duration: duration of tx timeout + * + * This function will add/append the random mac addr filter entry to vdev. + * If it is new added entry, it will request to set filter in target. + * + * Return: QDF_STATUS_SUCCESS: request successfully + * other: failed + */ +static QDF_STATUS +p2p_request_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *mac, uint32_t freq, uint64_t rnd_cookie, + uint32_t duration) +{ + QDF_STATUS status; + + status = p2p_add_random_mac(soc, vdev_id, mac, freq, rnd_cookie); + if (status == QDF_STATUS_E_EXISTS) + return QDF_STATUS_SUCCESS; + else if (status != QDF_STATUS_SUCCESS) + return status; + + if (!p2p_set_rand_mac(soc, vdev_id, mac, freq, rnd_cookie)) + status = p2p_del_random_mac(soc, vdev_id, rnd_cookie, + duration); + + return status; +} + +void p2p_rand_mac_tx(struct tx_action_context *tx_action) +{ + struct wlan_objmgr_psoc *soc; + QDF_STATUS status; + + if (!tx_action || !tx_action->p2p_soc_obj || + !tx_action->p2p_soc_obj->soc) + return; + soc = tx_action->p2p_soc_obj->soc; + + if (!tx_action->no_ack && tx_action->chan && + tx_action->buf_len > MIN_MAC_HEADER_LEN && + p2p_is_vdev_support_rand_mac_by_id(soc, tx_action->vdev_id) && + p2p_is_random_mac(soc, tx_action->vdev_id, + &tx_action->buf[SRC_MAC_ADDR_OFFSET])) { + status = p2p_request_random_mac( + soc, tx_action->vdev_id, + &tx_action->buf[SRC_MAC_ADDR_OFFSET], + wlan_chan_to_freq(tx_action->chan), + tx_action->id, + tx_action->duration); + if (status == QDF_STATUS_SUCCESS) + tx_action->rand_mac_tx = true; + else + tx_action->rand_mac_tx = false; + } +} + +void +p2p_rand_mac_tx_done(struct wlan_objmgr_psoc *soc, + struct tx_action_context *tx_ctx) +{ + if (!tx_ctx || !tx_ctx->rand_mac_tx || !soc) + return; + + p2p_del_random_mac(soc, tx_ctx->vdev_id, tx_ctx->id, tx_ctx->duration); +} + +/** + * p2p_mac_clear_timeout() - clear random mac filter timeout + * @context: timer context + * + * This function will clear the mac addr rx filter in target if no + * reference to it. + * + * Return: void + */ +static void p2p_mac_clear_timeout(void *context) +{ + struct action_frame_random_mac *random_mac = context; + struct p2p_vdev_priv_obj *p2p_vdev_obj; + uint32_t freq; + uint8_t addr[QDF_MAC_ADDR_SIZE]; + uint32_t vdev_id; + bool clear = false; + + if (!random_mac || !random_mac->p2p_vdev_obj) { + p2p_err("invalid context for mac_clear timeout"); + return; + } + p2p_vdev_obj = random_mac->p2p_vdev_obj; + if (!p2p_vdev_obj || !p2p_vdev_obj->vdev) + return; + + qdf_spin_lock(&p2p_vdev_obj->random_mac_lock); + if (qdf_list_empty(&random_mac->cookie_list)) { + random_mac->in_use = false; + clear = true; + } + freq = random_mac->freq; + qdf_mem_copy(addr, random_mac->addr, QDF_MAC_ADDR_SIZE); + qdf_spin_unlock(&p2p_vdev_obj->random_mac_lock); + + vdev_id = wlan_vdev_get_id(p2p_vdev_obj->vdev); + p2p_debug("random_mac:clear timeout vdev %d %pM freq %d clr %d", + vdev_id, addr, freq, clear); + if (clear) + p2p_clear_mac_filter(wlan_vdev_get_psoc(p2p_vdev_obj->vdev), + vdev_id, addr, freq); +} + +void p2p_init_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj) +{ + int32_t i; + + qdf_spinlock_create(&p2p_vdev_obj->random_mac_lock); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + qdf_mem_zero(&p2p_vdev_obj->random_mac[i], + sizeof(struct action_frame_random_mac)); + p2p_vdev_obj->random_mac[i].in_use = false; + p2p_vdev_obj->random_mac[i].p2p_vdev_obj = p2p_vdev_obj; + qdf_list_create(&p2p_vdev_obj->random_mac[i].cookie_list, 0); + qdf_mc_timer_init(&p2p_vdev_obj->random_mac[i].clear_timer, + QDF_TIMER_TYPE_SW, p2p_mac_clear_timeout, + &p2p_vdev_obj->random_mac[i]); + } +} + +void p2p_deinit_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj) +{ + int32_t i; + + p2p_del_all_rand_mac_vdev(p2p_vdev_obj->vdev); + for (i = 0; i < MAX_RANDOM_MAC_ADDRS; i++) { + qdf_mc_timer_destroy(&p2p_vdev_obj->random_mac[i].clear_timer); + qdf_list_destroy(&p2p_vdev_obj->random_mac[i].cookie_list); + } + qdf_spinlock_destroy(&p2p_vdev_obj->random_mac_lock); +} + QDF_STATUS p2p_process_mgmt_tx(struct tx_action_context *tx_ctx) { struct p2p_soc_priv_obj *p2p_soc_obj; @@ -1983,6 +2873,8 @@ QDF_STATUS p2p_process_mgmt_tx_ack_cnf( tx_cnf.action_cookie, tx_cnf.buf_len, tx_cnf.status, tx_cnf.buf); + p2p_rand_mac_tx_done(p2p_soc_obj->soc, tx_ctx); + /* disable tx timer */ p2p_disable_tx_timer(tx_ctx); diff --git a/core/src/wlan_p2p_off_chan_tx.h b/core/src/wlan_p2p_off_chan_tx.h index b7bb89876546..367ecd632587 100644 --- a/core/src/wlan_p2p_off_chan_tx.h +++ b/core/src/wlan_p2p_off_chan_tx.h @@ -59,6 +59,8 @@ #define P2P_GET_TYPE_FRM_FC(__fc__) (((__fc__) & 0x0F) >> 2) #define P2P_GET_SUBTYPE_FRM_FC(__fc__) (((__fc__) & 0xF0) >> 4) +#define WLAN_WAIT_TIME_SET_RND 100 + struct p2p_soc_priv_obj; struct cancel_roc_context; struct p2p_tx_conf_event; @@ -172,12 +174,54 @@ struct tx_action_context { bool off_chan; bool no_cck; bool no_ack; + bool rand_mac_tx; uint32_t duration; qdf_mc_timer_t tx_timer; struct p2p_frame_info frame_info; qdf_nbuf_t nbuf; }; +/** + * p2p_rand_mac_tx_done() - process random mac mgmt tx done + * @soc: soc + * @tx_ctx: tx context + * + * This function will remove the random mac addr filter reference. + * + * Return: void + */ +void +p2p_rand_mac_tx_done(struct wlan_objmgr_psoc *soc, + struct tx_action_context *tx_ctx); + +/** + * p2p_clear_mac_filter() - send clear mac addr filter cmd + * @soc: soc + * @vdev_id: vdev id + * @mac: mac addr + * @freq: freq + * + * This function send clear random mac addr filter command to p2p component + * msg core + * + * Return: QDF_STATUS_SUCCESS - if sent successfully. + * otherwise: failed. + */ +QDF_STATUS +p2p_clear_mac_filter(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *mac, uint32_t freq); + +/** + * p2p_is_vdev_support_rand_mac() - check vdev type support random mac mgmt + * tx or not + * @vdev: vdev object + * + * Return: true: support random mac mgmt tx + * false: not support random mac mgmt tx. + */ +bool +p2p_is_vdev_support_rand_mac(struct wlan_objmgr_vdev *vdev); + /** * p2p_dump_tx_queue() - dump tx queue * @p2p_soc_obj: p2p soc private object @@ -285,4 +329,111 @@ QDF_STATUS p2p_process_rx_mgmt( struct tx_action_context *p2p_find_tx_ctx_by_nbuf( struct p2p_soc_priv_obj *p2p_soc_obj, void *nbuf); +#define P2P_80211_FRM_SA_OFFSET 10 + +/** + * p2p_del_random_mac() - del mac fitler from given vdev rand mac list + * @soc: soc object + * @vdev_id: vdev id + * @rnd_cookie: random mac mgmt tx cookie + * @duration: timeout value to flush the addr in target. + * + * This function will del the mac addr filter from vdev random mac addr list. + * If there is no reference to mac addr, it will set a clear timer to flush it + * in target finally. + * + * Return: QDF_STATUS_SUCCESS - del successfully. + * other : failed to del the mac address entry. + */ +QDF_STATUS +p2p_del_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint64_t rnd_cookie, uint32_t duration); + +/** + * p2p_check_random_mac() - check random mac addr or not + * @soc: soc context + * @vdev_id: vdev id + * @random_mac_addr: mac addr to be checked + * + * This function check the input addr is random mac addr or not for vdev. + * + * Return: true if addr is random mac address else false. + */ +bool p2p_check_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *random_mac_addr); + +/** + * p2p_process_set_rand_mac() - process the set random mac command + * @set_filter_req: request data + * + * This function will process the set mac addr filter command. + * + * Return: QDF_STATUS_SUCCESS: if process successfully + * other: failed. + */ +QDF_STATUS p2p_process_set_rand_mac( + struct p2p_set_mac_filter_req *set_filter_req); + +/** + * p2p_process_set_rand_mac_rsp() - process the set random mac response + * @resp: response date + * + * This function will process the set mac addr filter event. + * + * Return: QDF_STATUS_SUCCESS: if process successfully + * other: failed. + */ +QDF_STATUS p2p_process_set_rand_mac_rsp(struct p2p_mac_filter_rsp *resp); + +/** + * p2p_del_all_rand_mac_vdev() - del all random mac filter in vdev + * @vdev: vdev object + * + * This function will del all random mac filter in vdev + * + * Return: void + */ +void p2p_del_all_rand_mac_vdev(struct wlan_objmgr_vdev *vdev); + +/** + * p2p_del_all_rand_mac_soc() - del all random mac filter in soc + * @soc: soc object + * + * This function will del all random mac filter in all vdev of soc + * + * Return: void + */ +void p2p_del_all_rand_mac_soc(struct wlan_objmgr_psoc *soc); + +/** + * p2p_rand_mac_tx() - handle random mac mgmt tx + * @tx_action: tx action context + * + * This function will check whether need to set random mac tx filter for a + * given mgmt tx request and do the mac addr filter process as needed. + * + * Return: void + */ +void p2p_rand_mac_tx(struct tx_action_context *tx_action); + +/** + * p2p_init_random_mac_vdev() - Init random mac data for vdev + * @p2p_vdev_obj: p2p vdev private object + * + * This function will init the per vdev random mac data structure. + * + * Return: void + */ +void p2p_init_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj); + +/** + * p2p_deinit_random_mac_vdev() - Init random mac data for vdev + * @p2p_vdev_obj: p2p vdev private object + * + * This function will deinit the per vdev random mac data structure. + * + * Return: void + */ +void p2p_deinit_random_mac_vdev(struct p2p_vdev_priv_obj *p2p_vdev_obj); + #endif /* _WLAN_P2P_OFF_CHAN_TX_H_ */ diff --git a/dispatcher/inc/wlan_p2p_public_struct.h b/dispatcher/inc/wlan_p2p_public_struct.h index 0c8eb282e47a..d1c597ff35f1 100644 --- a/dispatcher/inc/wlan_p2p_public_struct.h +++ b/dispatcher/inc/wlan_p2p_public_struct.h @@ -147,6 +147,30 @@ struct p2p_mgmt_tx { const uint8_t *buf; }; +/** + * struct p2p_set_mac_filter + * @vdev_id: Vdev id + * @mac: mac addr + * @freq: frequency + * @set: set or clear + */ +struct p2p_set_mac_filter { + uint32_t vdev_id; + uint8_t mac[QDF_MAC_ADDR_SIZE]; + uint32_t freq; + bool set; +}; + +/** + * struct p2p_set_mac_filter_evt + * @vdev_id: Vdev id + * @status: target reported result of set mac addr filter + */ +struct p2p_set_mac_filter_evt { + uint32_t vdev_id; + uint32_t status; +}; + /** * struct p2p_ps_config * @vdev_id: Vdev id diff --git a/dispatcher/inc/wlan_p2p_tgt_api.h b/dispatcher/inc/wlan_p2p_tgt_api.h index 5412063263bd..0ca20749892d 100644 --- a/dispatcher/inc/wlan_p2p_tgt_api.h +++ b/dispatcher/inc/wlan_p2p_tgt_api.h @@ -83,6 +83,19 @@ static inline QDF_STATUS tgt_p2p_unregister_lo_ev_handler( } #endif +/** + * tgt_p2p_register_macaddr_rx_filter_evt_handler() - register add mac rx + * filter status event + * @psoc: soc object + * @register: register or unregister + * + * p2p tgt api to register add mac rx filter status event + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS tgt_p2p_register_macaddr_rx_filter_evt_handler( + struct wlan_objmgr_psoc *psoc, bool register); + /** * tgt_p2p_register_noa_ev_handler() - register noa event * @psoc: soc object @@ -178,4 +191,18 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, struct p2p_noa_info *event_info); +/** + * tgt_p2p_add_mac_addr_status_event_cb() - Callback for set mac addr filter evt + * @psoc: soc object + * @event_info: event information type of p2p_set_mac_filter_evt + * + * This function gets called from target interface. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS +tgt_p2p_add_mac_addr_status_event_cb( + struct wlan_objmgr_psoc *psoc, + struct p2p_set_mac_filter_evt *event_info); + #endif /* _WLAN_P2P_TGT_API_H_ */ diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/dispatcher/inc/wlan_p2p_ucfg_api.h index 0cdc9bd32281..da397205140f 100644 --- a/dispatcher/inc/wlan_p2p_ucfg_api.h +++ b/dispatcher/inc/wlan_p2p_ucfg_api.h @@ -257,6 +257,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, /** * ucfg_p2p_mgmt_tx_cancel() - Cancel mgmt frame tx request * @soc: soc context + * @vdev: vdev object * @cookie: Find out the mgmt tx request by cookie * * This function delivers cancel mgmt frame tx request request to P2P @@ -265,7 +266,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, * Return: QDF_STATUS_SUCCESS - in case of success */ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, - uint64_t cookie); + struct wlan_objmgr_vdev *vdev, uint64_t cookie); /** * ucfg_p2p_set_ps() - P2P set power save @@ -331,6 +332,19 @@ void p2p_peer_authorized(struct wlan_objmgr_vdev *vdev, uint8_t *mac_addr); QDF_STATUS ucfg_p2p_set_noa(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, bool disable_noa); +/** + * ucfg_p2p_check_random_mac() - check random mac addr or not + * @soc: soc context + * @vdev_id: vdev id + * @random_mac_addr: mac addr to be checked + * + * This function check the input addr is random mac addr or not for vdev. + * + * Return: true if addr is random mac address else false. + */ +bool ucfg_p2p_check_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *random_mac_addr); + /** * ucfg_p2p_register_callbacks() - register p2p callbacks * @soc: soc context diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index 3dbc7ff0cd9c..fd10b349c155 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -124,6 +124,67 @@ QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, } #endif /* FEATURE_P2P_LISTEN_OFFLOAD */ +QDF_STATUS +tgt_p2p_add_mac_addr_status_event_cb(struct wlan_objmgr_psoc *psoc, + struct p2p_set_mac_filter_evt *event_info) +{ + struct p2p_mac_filter_rsp *mac_filter_rsp; + struct scheduler_msg msg = {0}; + struct p2p_soc_priv_obj *p2p_soc_obj; + QDF_STATUS status; + + if (!psoc) { + p2p_err("random_mac:psoc context passed is NULL"); + return QDF_STATUS_E_INVAL; + } + if (!event_info) { + p2p_err("random_mac:invalid event_info"); + return QDF_STATUS_E_INVAL; + } + + p2p_soc_obj = wlan_objmgr_psoc_get_comp_private_obj( + psoc, WLAN_UMAC_COMP_P2P); + if (!p2p_soc_obj) { + p2p_err("random_mac:p2p soc object is NULL"); + return QDF_STATUS_E_INVAL; + } + + mac_filter_rsp = qdf_mem_malloc(sizeof(*mac_filter_rsp)); + if (!mac_filter_rsp) { + p2p_err("random_mac:Failed to allocate mac_filter_rsp"); + return QDF_STATUS_E_NOMEM; + } + + mac_filter_rsp->p2p_soc_obj = p2p_soc_obj; + mac_filter_rsp->vdev_id = event_info->vdev_id; + mac_filter_rsp->status = event_info->status; + + msg.type = P2P_EVENT_ADD_MAC_RSP; + msg.bodyptr = mac_filter_rsp; + msg.callback = p2p_process_evt; + status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + if (status != QDF_STATUS_SUCCESS) + qdf_mem_free(mac_filter_rsp); + + return status; +} + +QDF_STATUS tgt_p2p_register_macaddr_rx_filter_evt_handler( + struct wlan_objmgr_psoc *psoc, bool reg) +{ + struct wlan_lmac_if_p2p_tx_ops *p2p_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + p2p_ops = wlan_psoc_get_p2p_tx_ops(psoc); + if (p2p_ops && p2p_ops->reg_mac_addr_rx_filter_handler) { + status = p2p_ops->reg_mac_addr_rx_filter_handler(psoc, reg); + p2p_debug("register mac addr rx filter event, register %d status:%d", + reg, status); + } + + return status; +} + QDF_STATUS tgt_p2p_register_noa_ev_handler( struct wlan_objmgr_psoc *psoc) { diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index da0f423b90b3..08e27a831440 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -280,6 +280,7 @@ QDF_STATUS ucfg_p2p_cleanup_tx_by_vdev(struct wlan_objmgr_vdev *vdev) p2p_err("null p2p soc obj"); return QDF_STATUS_E_FAILURE; } + p2p_del_all_rand_mac_vdev(vdev); return p2p_cleanup_tx_sync(obj, vdev); } @@ -298,6 +299,7 @@ QDF_STATUS ucfg_p2p_cleanup_tx_by_psoc(struct wlan_objmgr_psoc *psoc) p2p_err("null p2p soc obj"); return QDF_STATUS_E_FAILURE; } + p2p_del_all_rand_mac_soc(psoc); return p2p_cleanup_tx_sync(obj, NULL); } @@ -365,6 +367,9 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, qdf_mem_copy(tx_action->buf, mgmt_frm->buf, tx_action->buf_len); tx_action->nbuf = NULL; tx_action->id = id; + + p2p_rand_mac_tx(tx_action); + msg.type = P2P_MGMT_TX; msg.bodyptr = tx_action; msg.callback = p2p_process_cmd; @@ -376,7 +381,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, } QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, - uint64_t cookie) + struct wlan_objmgr_vdev *vdev, uint64_t cookie) { struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; @@ -402,6 +407,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, p2p_debug("invalid id"); return QDF_STATUS_E_INVAL; } + p2p_del_random_mac(soc, wlan_vdev_get_id(vdev), cookie, 20); cancel_tx = qdf_mem_malloc(sizeof(*cancel_tx)); if (!cancel_tx) { @@ -421,6 +427,12 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, return QDF_STATUS_SUCCESS; } +bool ucfg_p2p_check_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, + uint8_t *random_mac_addr) +{ + return p2p_check_random_mac(soc, vdev_id, random_mac_addr); +} + QDF_STATUS ucfg_p2p_set_ps(struct wlan_objmgr_psoc *soc, struct p2p_ps_config *ps_config) { From f0f79ffbd3bb6d98134d37d636f5b06a89631cb4 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 19 Sep 2018 23:35:14 -0400 Subject: [PATCH 377/404] qcacmn: Action frame random mac addr tx support 1. Send add random mac addr rx filter WMI command to target 2. Add/Del the active random mac addr entry 3. Clear random mac addr from target if not active Change-Id: I9dcbdc20b76d9865da7a8db6ee013bf5e44e4407 CRs-Fixed: 2322097 --- src/target_if_p2p.c | 85 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/target_if_p2p.c b/src/target_if_p2p.c index af30938c89f7..dbce5991f92f 100644 --- a/src/target_if_p2p.c +++ b/src/target_if_p2p.c @@ -368,6 +368,87 @@ QDF_STATUS target_if_p2p_set_noa(struct wlan_objmgr_psoc *psoc, return wmi_unified_vdev_set_param_send(wmi_handle, ¶m); } +static int target_p2p_mac_rx_filter_event_handler(ol_scn_t scn, uint8_t *data, + uint32_t datalen) +{ + struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; + struct p2p_set_mac_filter_evt event_info; + struct wlan_lmac_if_p2p_rx_ops *p2p_rx_ops; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (!scn || !data) { + target_if_err("scn: 0x%pK, data: 0x%pK", scn, data); + return -EINVAL; + } + + psoc = target_if_get_psoc_from_scn_hdl(scn); + if (!psoc) { + target_if_err("null psoc"); + return -EINVAL; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + target_if_err("null wmi handle"); + return -EINVAL; + } + + if (wmi_extract_mac_addr_rx_filter_evt_param(wmi_handle, data, + &event_info)) { + target_if_err("failed to extract wmi p2p noa event"); + return -EINVAL; + } + target_if_debug("vdev_id %d status %d", event_info.vdev_id, + event_info.status); + p2p_rx_ops = target_if_psoc_get_p2p_rx_ops(psoc); + if (p2p_rx_ops && p2p_rx_ops->add_mac_addr_filter_evt_handler) + status = p2p_rx_ops->add_mac_addr_filter_evt_handler( + psoc, &event_info); + else + target_if_debug("no add mac addr filter event handler"); + + return qdf_status_to_os_return(status); +} + +static QDF_STATUS target_if_p2p_register_macaddr_rx_filter_evt_handler( + struct wlan_objmgr_psoc *psoc, bool reg) +{ + int status; + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); + + target_if_debug("psoc:%pK, register %d mac addr rx evt", psoc, reg); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + if (reg) + status = wmi_unified_register_event( + wmi_handle, + wmi_vdev_add_macaddr_rx_filter_event_id, + target_p2p_mac_rx_filter_event_handler); + else + status = wmi_unified_unregister_event( + wmi_handle, + wmi_vdev_add_macaddr_rx_filter_event_id); + + return status == 0 ? QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE; +} + +static QDF_STATUS target_if_p2p_set_mac_addr_rx_filter_cmd( + struct wlan_objmgr_psoc *psoc, struct p2p_set_mac_filter *param) +{ + wmi_unified_t wmi_handle = lmac_get_wmi_unified_hdl(psoc); + + if (!wmi_handle) { + target_if_err("Invalid wmi handle"); + return QDF_STATUS_E_INVAL; + } + + return wmi_send_set_mac_addr_rx_filter_cmd(wmi_handle, param); +} + void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) { struct wlan_lmac_if_p2p_tx_ops *p2p_tx_ops; @@ -384,6 +465,10 @@ void target_if_p2p_register_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops) target_if_p2p_register_noa_event_handler; p2p_tx_ops->unreg_noa_ev_handler = target_if_p2p_unregister_noa_event_handler; + p2p_tx_ops->reg_mac_addr_rx_filter_handler = + target_if_p2p_register_macaddr_rx_filter_evt_handler; + p2p_tx_ops->set_mac_addr_rx_filter_cmd = + target_if_p2p_set_mac_addr_rx_filter_cmd; /* register P2P listen offload callbacks */ target_if_p2p_lo_register_tx_ops(p2p_tx_ops); } From e2492c05d3bef0117d0efec9b5275d606fcfd033 Mon Sep 17 00:00:00 2001 From: Liangwei Dong Date: Wed, 19 Sep 2018 23:35:14 -0400 Subject: [PATCH 378/404] qcacmn: Action frame random mac addr tx support 1. Send add random mac addr rx filter WMI command to target 2. Add/Del the active random mac addr entry 3. Clear random mac addr from target if not active Change-Id: I9dcbdc20b76d9865da7a8db6ee013bf5e44e4407 CRs-Fixed: 2322097 --- src/wlan_cfg80211_p2p.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wlan_cfg80211_p2p.c b/src/wlan_cfg80211_p2p.c index 2cfe0f3bf346..e4911ae8e23f 100644 --- a/src/wlan_cfg80211_p2p.c +++ b/src/wlan_cfg80211_p2p.c @@ -495,5 +495,5 @@ int wlan_cfg80211_mgmt_tx_cancel(struct wlan_objmgr_vdev *vdev, } return qdf_status_to_os_return( - ucfg_p2p_mgmt_tx_cancel(psoc, cookie)); + ucfg_p2p_mgmt_tx_cancel(psoc, vdev, cookie)); } From 223e95934e842e2a82d234ce4ba25ba3ae51a84c Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 29 Oct 2018 14:47:43 +0530 Subject: [PATCH 379/404] qcacmn: Delete connection in progress tdls peers TDLS peer has to be deleted before sending the TDLS disable command to FW, otherwise FW may assert due to the invalid sequence of peer delete and TDLS set state command. So Delete TDLS peers for those the connection is in progress along with the active TDLS peers before disabling the TDLS. Change-Id: Ic52c44dea947095cfe5e4dfe36eec271b1f46867 CRs-Fixed: 2340759 --- core/src/wlan_tdls_ct.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index d7c50ab7c68f..e81c2e5b428a 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1185,6 +1185,7 @@ void tdls_disable_offchan_and_teardown_links( struct tdls_soc_priv_obj *tdls_soc; QDF_STATUS status; uint8_t vdev_id; + bool tdls_in_progress = false; status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); if (QDF_STATUS_SUCCESS != status) { @@ -1199,9 +1200,11 @@ void tdls_disable_offchan_and_teardown_links( } connected_tdls_peers = tdls_soc->connected_peer_count; + if (tdls_is_progress(tdls_vdev, NULL, 0)) + tdls_in_progress = true; - if (!connected_tdls_peers) { - tdls_notice("No TDLS connected peers to delete"); + if (!(connected_tdls_peers || tdls_in_progress)) { + tdls_notice("No TDLS connected/progress peers to delete"); vdev_id = vdev->vdev_objmgr.vdev_id; if (tdls_soc->set_state_info.set_state_cnt > 0) { tdls_debug("Disable the tdls in FW as second interface is coming up"); From 43520acbbf30c5713306991aff91e5af1cb5c258 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Tue, 30 Oct 2018 18:43:57 +0800 Subject: [PATCH 380/404] qcacmn: Fix potential memory leak when post scheduler msg in P2P To avoid potential memory leak, add flush callback for some of P2P messages, handle post scheduler messages fail case. Change-Id: If700eba689bb2423ca84fbba08f7434cc75dbd14 CRs-Fixed: 2341756 --- core/src/wlan_p2p_main.c | 80 ++++++++++++++++++++++++++++-- core/src/wlan_p2p_main.h | 20 ++++++++ dispatcher/src/wlan_p2p_tgt_api.c | 64 ++++++++++++++++-------- dispatcher/src/wlan_p2p_ucfg_api.c | 74 +++++++++++++++++++-------- 4 files changed, 192 insertions(+), 46 deletions(-) diff --git a/core/src/wlan_p2p_main.c b/core/src/wlan_p2p_main.c index 93d4edf40dc4..711542da591b 100644 --- a/core/src/wlan_p2p_main.c +++ b/core/src/wlan_p2p_main.c @@ -429,6 +429,7 @@ static QDF_STATUS p2p_send_noa_to_pe(struct p2p_noa_info *noa_info) { struct p2p_noa_attr *noa_attr; struct scheduler_msg msg = {0}; + QDF_STATUS status; if (!noa_info) { p2p_err("noa info is null"); @@ -474,11 +475,16 @@ static QDF_STATUS p2p_send_noa_to_pe(struct p2p_noa_info *noa_info) msg.type = P2P_NOA_ATTR_IND; msg.bodyval = 0; msg.bodyptr = noa_attr; - scheduler_post_message(QDF_MODULE_ID_P2P, - QDF_MODULE_ID_P2P, - QDF_MODULE_ID_PE, &msg); + status = scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_PE, + &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(noa_attr); + p2p_err("post msg fail:%d", status); + } - return QDF_STATUS_SUCCESS; + return status; } /** @@ -1044,6 +1050,72 @@ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg) return status; } +QDF_STATUS p2p_msg_flush_callback(struct scheduler_msg *msg) +{ + struct tx_action_context *tx_action; + + if (!msg || !(msg->bodyptr)) { + p2p_err("invalid msg"); + return QDF_STATUS_E_INVAL; + } + + p2p_debug("flush msg, type:%d", msg->type); + switch (msg->type) { + case P2P_MGMT_TX: + tx_action = (struct tx_action_context *)msg->bodyptr; + qdf_mem_free(tx_action->buf); + qdf_mem_free(tx_action); + break; + default: + qdf_mem_free(msg->bodyptr); + break; + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS p2p_event_flush_callback(struct scheduler_msg *msg) +{ + struct p2p_noa_event *noa_event; + struct p2p_rx_mgmt_event *rx_mgmt_event; + struct p2p_tx_conf_event *tx_conf_event; + struct p2p_lo_stop_event *lo_stop_event; + + if (!msg || !(msg->bodyptr)) { + p2p_err("invalid msg"); + return QDF_STATUS_E_INVAL; + } + + p2p_debug("flush event, type:%d", msg->type); + switch (msg->type) { + case P2P_EVENT_NOA: + noa_event = (struct p2p_noa_event *)msg->bodyptr; + qdf_mem_free(noa_event->noa_info); + qdf_mem_free(noa_event); + break; + case P2P_EVENT_RX_MGMT: + rx_mgmt_event = (struct p2p_rx_mgmt_event *)msg->bodyptr; + qdf_mem_free(rx_mgmt_event->rx_mgmt); + qdf_mem_free(rx_mgmt_event); + break; + case P2P_EVENT_MGMT_TX_ACK_CNF: + tx_conf_event = (struct p2p_tx_conf_event *)msg->bodyptr; + qdf_mem_free(tx_conf_event); + qdf_nbuf_free(tx_conf_event->nbuf); + break; + case P2P_EVENT_LO_STOPPED: + lo_stop_event = (struct p2p_lo_stop_event *)msg->bodyptr; + qdf_mem_free(lo_stop_event->lo_event); + qdf_mem_free(lo_stop_event); + break; + default: + qdf_mem_free(msg->bodyptr); + break; + } + + return QDF_STATUS_SUCCESS; +} + #ifdef FEATURE_P2P_LISTEN_OFFLOAD QDF_STATUS p2p_process_lo_stop( struct p2p_lo_stop_event *lo_stop_event) diff --git a/core/src/wlan_p2p_main.h b/core/src/wlan_p2p_main.h index 8a89d93e7303..6a6632c44e3d 100644 --- a/core/src/wlan_p2p_main.h +++ b/core/src/wlan_p2p_main.h @@ -445,6 +445,26 @@ QDF_STATUS p2p_process_cmd(struct scheduler_msg *msg); */ QDF_STATUS p2p_process_evt(struct scheduler_msg *msg); +/** + * p2p_msg_flush_callback() - Callback used to flush P2P messages + * @msg: message information + * + * This callback will be called when scheduler flush some of P2P messages. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_msg_flush_callback(struct scheduler_msg *msg); + +/** + * p2p_event_flush_callback() - Callback used to flush P2P events + * @msg: event information + * + * This callback will be called when scheduler flush some of P2P events. + * + * Return: QDF_STATUS_SUCCESS - in case of success + */ +QDF_STATUS p2p_event_flush_callback(struct scheduler_msg *msg); + #ifdef FEATURE_P2P_LISTEN_OFFLOAD /** * p2p_process_lo_stop() - Process lo stop event diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/dispatcher/src/wlan_p2p_tgt_api.c index fd10b349c155..d6ee448947eb 100644 --- a/dispatcher/src/wlan_p2p_tgt_api.c +++ b/dispatcher/src/wlan_p2p_tgt_api.c @@ -80,6 +80,7 @@ QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, struct p2p_lo_stop_event *lo_stop_event; struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; + QDF_STATUS status; p2p_debug("soc:%pK, event_info:%pK", psoc, event_info); @@ -116,11 +117,18 @@ QDF_STATUS tgt_p2p_lo_event_cb(struct wlan_objmgr_psoc *psoc, msg.type = P2P_EVENT_LO_STOPPED; msg.bodyptr = lo_stop_event; msg.callback = p2p_process_evt; + msg.flush_callback = p2p_event_flush_callback; + status = scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_TARGET_IF, + &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(lo_stop_event->lo_event); + qdf_mem_free(lo_stop_event); + p2p_err("post msg fail:%d", status); + } - scheduler_post_message(QDF_MODULE_ID_P2P, - QDF_MODULE_ID_P2P, - QDF_MODULE_ID_TARGET_IF, &msg); - return QDF_STATUS_SUCCESS; + return status; } #endif /* FEATURE_P2P_LISTEN_OFFLOAD */ @@ -163,7 +171,7 @@ tgt_p2p_add_mac_addr_status_event_cb(struct wlan_objmgr_psoc *psoc, msg.bodyptr = mac_filter_rsp; msg.callback = p2p_process_evt; status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); - if (status != QDF_STATUS_SUCCESS) + if (QDF_IS_STATUS_ERROR(status)) qdf_mem_free(mac_filter_rsp); return status; @@ -261,17 +269,18 @@ QDF_STATUS tgt_p2p_mgmt_ota_comp_cb(void *context, qdf_nbuf_t buf, msg.type = P2P_EVENT_MGMT_TX_ACK_CNF; msg.bodyptr = tx_conf_event; msg.callback = p2p_process_evt; + msg.flush_callback = p2p_event_flush_callback; ret = scheduler_post_message(QDF_MODULE_ID_P2P, QDF_MODULE_ID_P2P, - QDF_MODULE_ID_TARGET_IF, &msg); - if (ret != QDF_STATUS_SUCCESS) { + QDF_MODULE_ID_TARGET_IF, + &msg); + if (QDF_IS_STATUS_ERROR(ret)) { qdf_mem_free(tx_conf_event); - qdf_mem_free(buf); - p2p_err("failed to post message"); - return status; + qdf_nbuf_free(buf); + p2p_err("post msg fail:%d", status); } - return QDF_STATUS_SUCCESS; + return ret; } QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, @@ -286,6 +295,7 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev; uint32_t vdev_id; uint8_t *pdata; + QDF_STATUS status; p2p_debug("psoc:%pK, peer:%pK, type:%d", psoc, peer, frm_type); @@ -349,13 +359,19 @@ QDF_STATUS tgt_p2p_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, msg.type = P2P_EVENT_RX_MGMT; msg.bodyptr = rx_mgmt_event; msg.callback = p2p_process_evt; - scheduler_post_message(QDF_MODULE_ID_P2P, - QDF_MODULE_ID_P2P, - QDF_MODULE_ID_TARGET_IF, &msg); - + msg.flush_callback = p2p_event_flush_callback; + status = scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_TARGET_IF, + &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(rx_mgmt_event->rx_mgmt); + qdf_mem_free(rx_mgmt_event); + p2p_err("post msg fail:%d", status); + } qdf_nbuf_free(buf); - return QDF_STATUS_SUCCESS; + return status; } QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, @@ -364,6 +380,7 @@ QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, struct p2p_noa_event *noa_event; struct scheduler_msg msg = {0}; struct p2p_soc_priv_obj *p2p_soc_obj; + QDF_STATUS status; p2p_debug("soc:%pK, event_info:%pK", psoc, event_info); @@ -400,9 +417,16 @@ QDF_STATUS tgt_p2p_noa_event_cb(struct wlan_objmgr_psoc *psoc, msg.type = P2P_EVENT_NOA; msg.bodyptr = noa_event; msg.callback = p2p_process_evt; - scheduler_post_message(QDF_MODULE_ID_P2P, - QDF_MODULE_ID_P2P, - QDF_MODULE_ID_TARGET_IF, &msg); + msg.flush_callback = p2p_event_flush_callback; + status = scheduler_post_message(QDF_MODULE_ID_P2P, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_TARGET_IF, + &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(noa_event->noa_info); + qdf_mem_free(noa_event); + p2p_err("post msg fail:%d", status); + } - return QDF_STATUS_SUCCESS; + return status; } diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/dispatcher/src/wlan_p2p_ucfg_api.c index 08e27a831440..f2a6c38aa6af 100644 --- a/dispatcher/src/wlan_p2p_ucfg_api.c +++ b/dispatcher/src/wlan_p2p_ucfg_api.c @@ -141,7 +141,7 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, } status = qdf_idr_alloc(&p2p_soc_obj->p2p_idr, roc_ctx, &id); - if (status != QDF_STATUS_SUCCESS) { + if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(roc_ctx); p2p_err("failed to alloc idr, status %d", status); return status; @@ -159,12 +159,18 @@ QDF_STATUS ucfg_p2p_roc_req(struct wlan_objmgr_psoc *soc, msg.type = P2P_ROC_REQ; msg.bodyptr = roc_ctx; msg.callback = p2p_process_cmd; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_P2P, - QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, + &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(roc_ctx); + qdf_idr_remove(&p2p_soc_obj->p2p_idr, id); + p2p_err("post msg fail:%d", status); + } p2p_debug("cookie = 0x%llx", *cookie); - return QDF_STATUS_SUCCESS; + return status; } QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, @@ -174,6 +180,7 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, struct p2p_soc_priv_obj *p2p_soc_obj; struct cancel_roc_context *cancel_roc; void *roc_ctx = NULL; + QDF_STATUS status; p2p_debug("soc:%pK, cookie:0x%llx", soc, cookie); @@ -189,8 +196,9 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, return QDF_STATUS_E_FAILURE; } - if (QDF_STATUS_SUCCESS != qdf_idr_find(&p2p_soc_obj->p2p_idr, - cookie, &roc_ctx)) { + status = qdf_idr_find(&p2p_soc_obj->p2p_idr, + cookie, &roc_ctx); + if (QDF_IS_STATUS_ERROR(status)) { p2p_err("invalid id"); return QDF_STATUS_E_INVAL; } @@ -206,11 +214,17 @@ QDF_STATUS ucfg_p2p_roc_cancel_req(struct wlan_objmgr_psoc *soc, msg.type = P2P_CANCEL_ROC_REQ; msg.bodyptr = cancel_roc; msg.callback = p2p_process_cmd; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_P2P, - QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, + &msg); - return QDF_STATUS_SUCCESS; + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(cancel_roc); + p2p_err("post msg fail:%d", status); + } + + return status; } QDF_STATUS ucfg_p2p_cleanup_roc_by_vdev(struct wlan_objmgr_vdev *vdev) @@ -342,7 +356,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, else { status = qdf_idr_alloc(&p2p_soc_obj->p2p_idr, tx_action, &id); - if (status != QDF_STATUS_SUCCESS) { + if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(tx_action); p2p_err("failed to alloc idr, status :%d", status); return status; @@ -373,11 +387,20 @@ QDF_STATUS ucfg_p2p_mgmt_tx(struct wlan_objmgr_psoc *soc, msg.type = P2P_MGMT_TX; msg.bodyptr = tx_action; msg.callback = p2p_process_cmd; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_P2P, - QDF_MODULE_ID_OS_IF, &msg); + msg.flush_callback = p2p_msg_flush_callback; + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, + &msg); + if (QDF_IS_STATUS_ERROR(status)) { + if (id) + qdf_idr_remove(&p2p_soc_obj->p2p_idr, id); + qdf_mem_free(tx_action->buf); + qdf_mem_free(tx_action); + p2p_err("post msg fail:%d", status); + } - return QDF_STATUS_SUCCESS; + return status; } QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, @@ -387,6 +410,7 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, struct p2p_soc_priv_obj *p2p_soc_obj; struct cancel_roc_context *cancel_tx; void *tx_ctx; + QDF_STATUS status; p2p_debug("soc:%pK, cookie:0x%llx", soc, cookie); @@ -402,8 +426,9 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, return QDF_STATUS_E_FAILURE; } - if (QDF_STATUS_SUCCESS != qdf_idr_find(&p2p_soc_obj->p2p_idr, - (int32_t)cookie, &tx_ctx)) { + status = qdf_idr_find(&p2p_soc_obj->p2p_idr, + (int32_t)cookie, &tx_ctx); + if (QDF_IS_STATUS_ERROR(status)) { p2p_debug("invalid id"); return QDF_STATUS_E_INVAL; } @@ -420,11 +445,16 @@ QDF_STATUS ucfg_p2p_mgmt_tx_cancel(struct wlan_objmgr_psoc *soc, msg.type = P2P_MGMT_TX_CANCEL; msg.bodyptr = cancel_tx; msg.callback = p2p_process_cmd; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_P2P, - QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_P2P, + QDF_MODULE_ID_OS_IF, + &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(cancel_tx); + p2p_err("post msg fail: %d", status); + } - return QDF_STATUS_SUCCESS; + return status; } bool ucfg_p2p_check_random_mac(struct wlan_objmgr_psoc *soc, uint32_t vdev_id, From af02af5f9e983a363dd8636f0078a0d71fecebb1 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 24 Oct 2018 15:08:00 +0800 Subject: [PATCH 381/404] 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 --- core/src/wlan_tdls_ct.c | 14 +++ core/src/wlan_tdls_main.c | 105 ++++++++++++++----- core/src/wlan_tdls_main.h | 16 +-- core/src/wlan_tdls_mgmt.c | 18 ++++ dispatcher/inc/wlan_tdls_public_structs.h | 11 -- dispatcher/src/wlan_tdls_tgt_api.c | 119 +++++++--------------- dispatcher/src/wlan_tdls_ucfg_api.c | 99 +++++++++++++++--- 7 files changed, 246 insertions(+), 136 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index e81c2e5b428a..7be612d4b0ce 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1121,6 +1121,15 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, return ret_value; } +static QDF_STATUS tdls_delete_all_tdls_peers_flush_cb(struct scheduler_msg *msg) +{ + if (msg && msg->bodyptr) + qdf_mem_free(msg->bodyptr); + + msg->bodyptr = NULL; + + return QDF_STATUS_SUCCESS; +} /** * tdls_delete_all_tdls_peers(): send request to delete tdls peers * @vdev: vdev object @@ -1166,10 +1175,15 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, msg.type = del_msg->msg_type; msg.bodyptr = del_msg; + msg.flush_callback = tdls_delete_all_tdls_peers_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_PE, QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post delete all peer req failed, status %d", status); + qdf_mem_free(del_msg); + } wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); return status; diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 312a74bf6e77..7295adda9689 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -451,10 +451,10 @@ static QDF_STATUS tdls_reset_all_peers( status = tdls_process_reset_all_peers(delete_all_peers_ind->vdev); - if (delete_all_peers_ind->callback) - delete_all_peers_ind->callback(delete_all_peers_ind->vdev); - + wlan_objmgr_vdev_release_ref(delete_all_peers_ind->vdev, + WLAN_TDLS_SB_ID); qdf_mem_free(delete_all_peers_ind); + return status; } @@ -890,6 +890,33 @@ struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, return NULL; } +static QDF_STATUS tdls_post_msg_flush_cb(struct scheduler_msg *msg) +{ + void *ptr = msg->bodyptr; + struct wlan_objmgr_vdev *vdev = NULL; + + switch (msg->type) { + case TDLS_NOTIFY_STA_DISCONNECTION: + vdev = ((struct tdls_sta_notify_params *)ptr)->vdev; + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(ptr); + break; + + case TDLS_DELETE_ALL_PEERS_INDICATION: + vdev = ((struct tdls_delete_all_peers_params *)ptr)->vdev; + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + qdf_mem_free(ptr); + break; + + case TDLS_CMD_SCAN_DONE: + case TDLS_CMD_SESSION_INCREMENT: + case TDLS_CMD_SESSION_DECREMENT: + break; + } + + return QDF_STATUS_SUCCESS; +} + /** * tdls_process_session_update() - update session count information * @psoc: soc object @@ -907,6 +934,7 @@ static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc, msg.bodyptr = psoc; msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_post_msg_flush_cb; msg.type = (uint16_t)cmd_type; status = scheduler_post_message(QDF_MODULE_ID_TDLS, @@ -1107,10 +1135,9 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) status = tdls_process_sta_connect(notify); - if (notify->callback) - notify->callback(notify->vdev); - + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); qdf_mem_free(notify); + return status; } @@ -1196,10 +1223,9 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) status = tdls_process_sta_disconnect(notify); - if (notify->callback) - notify->callback(notify->vdev); - + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); qdf_mem_free(notify); + return status; } @@ -1228,12 +1254,13 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); } -QDF_STATUS tdls_peers_deleted_notification( - struct tdls_sta_notify_params *notify_info) +QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) { struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; QDF_STATUS status; + struct wlan_objmgr_vdev *vdev; notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { @@ -1241,30 +1268,50 @@ QDF_STATUS tdls_peers_deleted_notification( return QDF_STATUS_E_NULL_VALUE; } - *notify = *notify_info; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + WLAN_TDLS_NB_ID); + + if (!vdev) { + tdls_err("vdev not exist for the vdev id %d", + vdev_id); + qdf_mem_free(notify); + return QDF_STATUS_E_INVAL; + } + + notify->lfr_roam = true; + notify->tdls_chan_swit_prohibited = false; + notify->tdls_prohibited = false; + notify->session_id = vdev_id; + notify->vdev = vdev; + notify->user_disconnect = false; msg.bodyptr = notify; msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_post_msg_flush_cb; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); qdf_mem_free(notify); tdls_alert("message post failed "); + return QDF_STATUS_E_FAILURE; } return QDF_STATUS_SUCCESS; } -QDF_STATUS tdls_delete_all_peers_indication( - struct tdls_delete_all_peers_params *delete_peers_ind) +QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) { struct scheduler_msg msg = {0, }; struct tdls_delete_all_peers_params *indication; QDF_STATUS status; + struct wlan_objmgr_vdev *vdev; indication = qdf_mem_malloc(sizeof(*indication)); if (!indication) { @@ -1272,16 +1319,29 @@ QDF_STATUS tdls_delete_all_peers_indication( return QDF_STATUS_E_NULL_VALUE; } - *indication = *delete_peers_ind; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + WLAN_TDLS_SB_ID); + + if (!vdev) { + tdls_err("vdev not exist for the session id %d", + vdev_id); + qdf_mem_free(indication); + return QDF_STATUS_E_INVAL; + } + + indication->vdev = vdev; msg.bodyptr = indication; msg.callback = tdls_process_cmd; msg.type = TDLS_DELETE_ALL_PEERS_INDICATION; + msg.flush_callback = tdls_post_msg_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); qdf_mem_free(indication); tdls_alert("message post failed "); return QDF_STATUS_E_FAILURE; @@ -1450,15 +1510,10 @@ QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode) if (!tdls_set_mode || !tdls_set_mode->vdev) return QDF_STATUS_E_INVAL; - if (QDF_STATUS_SUCCESS != - wlan_objmgr_vdev_try_get_ref(tdls_set_mode->vdev, - WLAN_TDLS_NB_ID)) - return QDF_STATUS_E_INVAL; - status = tdls_get_vdev_objects(tdls_set_mode->vdev, &tdls_vdev, &tdls_soc); - if (status != QDF_STATUS_SUCCESS) + if (QDF_IS_STATUS_ERROR(status)) goto release_mode_ref; tdls_set_current_mode(tdls_soc, @@ -1518,12 +1573,12 @@ static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) msg.bodyptr = tdls_soc; msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_post_msg_flush_cb; msg.type = TDLS_CMD_SCAN_DONE; - scheduler_post_message(QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_OS_IF, &msg); - return QDF_STATUS_SUCCESS; + return scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); } void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index fc1230429131..c03eb16abf36 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -575,7 +575,7 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); /** * tdls_notify_reset_adapter() - notify reset adapter - * @vdev: vdev object manager + * @vdev: vdev object * * Notify TDLS about the adapter reset * @@ -585,7 +585,8 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); /** * tdls_peers_deleted_notification() - peer delete notification - * @notify_info: peer info + * @psoc: soc object + * @vdev_id: vdev id * * Legacy lim layer will delete tdls peers for roaming and heart beat failures * and notify the component about the delete event to update the tdls. @@ -593,8 +594,8 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); * * Return: QDF_STATUS */ -QDF_STATUS tdls_peers_deleted_notification( - struct tdls_sta_notify_params *notify_info); +QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); /** * tdls_notify_decrement_session() - Notify the session decrement @@ -727,13 +728,14 @@ QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, /** * tdls_delete_all_peers_indication() - update tdls status info - * @delete_peers_ind: Delete peers indication params + * @psoc: soc object + * @vdev_id: vdev id * * Notify tdls component to cleanup all peers * * Return: QDF_STATUS. */ -QDF_STATUS tdls_delete_all_peers_indication( - struct tdls_delete_all_peers_params *delete_peers_ind); +QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); #endif diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 0b4000e3fcd2..47b30c4f9bc6 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -213,6 +213,19 @@ tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request *req, return QDF_STATUS_SUCCESS; } +static QDF_STATUS tdls_activate_send_mgmt_request_flush_cb( + struct scheduler_msg *msg) +{ + struct tdls_send_mgmt_request *tdls_mgmt_req; + + tdls_mgmt_req = msg->bodyptr; + + qdf_mem_free(tdls_mgmt_req); + msg->bodyptr = NULL; + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS tdls_activate_send_mgmt_request( struct tdls_action_frame_request *action_req) { @@ -298,10 +311,15 @@ static QDF_STATUS tdls_activate_send_mgmt_request( msg.type = tdls_soc_obj->tdls_send_mgmt_req; msg.bodyptr = tdls_mgmt_req; + msg.flush_callback = tdls_activate_send_mgmt_request_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to post msg, status %d", status); + qdf_mem_free(tdls_mgmt_req); + } wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 261a1e9af8f3..9fbb273eefe3 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -587,17 +587,9 @@ typedef QDF_STATUS uint32_t vdev_param, bool is_link_up); -/* This callback is to release vdev ref for tdls sta notify msg */ -typedef void (*tdls_sta_notify_callback)(struct wlan_objmgr_vdev *vdev); - /* This callback is to release vdev ref for tdls offchan param related msg */ typedef void (*tdls_offchan_parms_callback)(struct wlan_objmgr_vdev *vdev); -/* This callback is to release vdev ref for tdls_delete_all_peers_ - * callback related msg. - */ -typedef void (*tdls_delete_all_peers_callback)(struct wlan_objmgr_vdev *vdev); - /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -1076,17 +1068,14 @@ struct tdls_sta_notify_params { bool lfr_roam; bool user_disconnect; uint8_t session_id; - tdls_sta_notify_callback callback; }; /** * struct tdls_delete_all_peers_params - TDLS set mode params * @vdev: vdev object - * @callback: callback to release vdev ref */ struct tdls_delete_all_peers_params { struct wlan_objmgr_vdev *vdev; - tdls_delete_all_peers_callback callback; }; /** diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index cf43a2f64b06..bb09a0e8b4a1 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -170,6 +170,19 @@ QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +static QDF_STATUS tgt_tdls_event_flush_cb(struct scheduler_msg *msg) +{ + struct tdls_event_notify *notify; + + notify = msg->bodyptr; + if (notify && notify->vdev) { + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID); + qdf_mem_free(notify); + } + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, struct tdls_event_info *info) @@ -204,6 +217,7 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, msg.bodyptr = notify; msg.callback = tdls_process_evt; + msg.flush_callback = tgt_tdls_event_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, @@ -217,6 +231,23 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, return status; } +static QDF_STATUS tgt_tdls_mgmt_frame_rx_flush_cb(struct scheduler_msg *msg) +{ + struct tdls_rx_mgmt_event *rx_mgmt_event; + + rx_mgmt_event = msg->bodyptr; + + if (rx_mgmt_event) { + if (rx_mgmt_event->rx_mgmt) + qdf_mem_free(rx_mgmt_event->rx_mgmt); + + qdf_mem_free(rx_mgmt_event); + } + msg->bodyptr = NULL; + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( struct wlan_objmgr_psoc *psoc, @@ -285,9 +316,14 @@ QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( msg.type = TDLS_EVENT_RX_MGMT; msg.bodyptr = rx_mgmt_event; msg.callback = tdls_process_rx_frame; + msg.flush_callback = tgt_tdls_mgmt_frame_rx_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(rx_mgmt); + qdf_mem_free(rx_mgmt_event); + } qdf_nbuf_free(buf); @@ -333,92 +369,15 @@ release_nbuf: return status; } -static void tgt_tdls_peers_deleted_notification_callback( - struct wlan_objmgr_vdev *vdev) -{ - if (!vdev) { - tdls_err("vdev is NULL"); - return; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); -} - void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, - uint32_t session_id) + uint32_t session_id) { - struct wlan_objmgr_vdev *vdev; - struct tdls_sta_notify_params notify_info; - QDF_STATUS status; - - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, - session_id, - WLAN_TDLS_SB_ID); - - if (!vdev) { - tdls_err("vdev not exist for the session id %d", - session_id); - return; - } - - notify_info.lfr_roam = true; - notify_info.tdls_chan_swit_prohibited = false; - notify_info.tdls_prohibited = false; - notify_info.session_id = session_id; - notify_info.vdev = vdev; - notify_info.user_disconnect = false; - notify_info.callback = tgt_tdls_peers_deleted_notification_callback; - status = tdls_peers_deleted_notification(¬ify_info); - if (QDF_IS_STATUS_ERROR(status)) { - tdls_err("tdls_peers_deleted_notification failed"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); - } -} - -/** - * tgt_tdls_delete_all_peers_ind_callback()- Callback to call from - * TDLS component - * @psoc: soc object - * @session_id: session id - * - * This function release the obj mgr vdev ref - * - * Return: None - */ -static void tgt_tdls_delete_all_peers_ind_callback( - struct wlan_objmgr_vdev *vdev) -{ - if (!vdev) { - tdls_err("vdev is NULL"); - return; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + tdls_peers_deleted_notification(psoc, session_id); } void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, uint32_t session_id) { - struct wlan_objmgr_vdev *vdev; - struct tdls_delete_all_peers_params delete_peers_ind; - QDF_STATUS status; - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, - session_id, - WLAN_TDLS_SB_ID); - - if (!vdev) { - tdls_err("vdev not exist for the session id %d", - session_id); - return; - } - - delete_peers_ind.vdev = vdev; - delete_peers_ind.callback = tgt_tdls_delete_all_peers_ind_callback; - status = tdls_delete_all_peers_indication(&delete_peers_ind); - if (QDF_IS_STATUS_ERROR(status)) { - tdls_err("tdls_delete_all_peers_indication failed"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); - } + tdls_delete_all_peers_indication(psoc, session_id); } - diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 62e5a73c24f0..e1936cfc6252 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -638,6 +638,41 @@ static QDF_STATUS tdls_send_mgmt_frame_flush_callback(struct scheduler_msg *msg) return QDF_STATUS_SUCCESS; } +static QDF_STATUS ucfg_tdls_post_msg_flush_cb(struct scheduler_msg *msg) +{ + void *ptr = msg->bodyptr; + struct wlan_objmgr_vdev *vdev = NULL; + + switch (msg->type) { + case TDLS_CMD_TEARDOWN_LINKS: + case TDLS_NOTIFY_RESET_ADAPTERS: + ptr = NULL; + break; + case TDLS_NOTIFY_STA_CONNECTION: + vdev = ((struct tdls_sta_notify_params *)ptr)->vdev; + break; + case TDLS_NOTIFY_STA_DISCONNECTION: + vdev = ((struct tdls_sta_notify_params *)ptr)->vdev; + break; + case TDLS_CMD_SET_TDLS_MODE: + vdev = ((struct tdls_set_mode_params *)ptr)->vdev; + break; + case TDLS_CMD_TX_ACTION: + case TDLS_CMD_SET_RESPONDER: + break; + } + + if (vdev) + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + + if (ptr) + qdf_mem_free(ptr); + + msg->bodyptr = NULL; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *req) { @@ -719,10 +754,15 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) msg.bodyptr = msg_req; msg.callback = tdls_process_cmd; + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; msg.type = TDLS_CMD_SET_RESPONDER; status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to post msg, status %d", status); + qdf_mem_free(msg_req); + } return status; } @@ -740,6 +780,7 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) msg.bodyptr = vdev; msg.callback = tdls_process_cmd; + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; msg.type = TDLS_CMD_TEARDOWN_LINKS; status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS, @@ -761,6 +802,7 @@ QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) tdls_debug("Enter "); msg.bodyptr = vdev; msg.callback = tdls_process_cmd; + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; msg.type = TDLS_NOTIFY_RESET_ADAPTERS; status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS, @@ -769,10 +811,11 @@ QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) } QDF_STATUS ucfg_tdls_notify_sta_connect( - struct tdls_sta_notify_params *notify_info) + struct tdls_sta_notify_params *notify_info) { struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; + QDF_STATUS status; if (!notify_info || !notify_info->vdev) { tdls_err("notify_info %pK", notify_info); @@ -781,20 +824,28 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( tdls_debug("Enter "); notify = qdf_mem_malloc(sizeof(*notify)); - if (!notify) + if (!notify) { + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); return QDF_STATUS_E_NULL_VALUE; + } *notify = *notify_info; msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_CONNECTION; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_TARGET_IF, &msg); + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to post message, status %d", status); + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(notify); + } tdls_debug("Exit "); - return QDF_STATUS_SUCCESS; + return status; } QDF_STATUS ucfg_tdls_notify_sta_disconnect( @@ -802,6 +853,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( { struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; + QDF_STATUS status; if (!notify_info || !notify_info->vdev) { tdls_err("notify_info %pK", notify_info); @@ -819,9 +871,15 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_TARGET_IF, &msg); + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to post message, status %d", status); + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(notify); + } tdls_debug("Exit "); @@ -833,6 +891,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( { struct scheduler_msg msg = {0, }; struct tdls_set_mode_params *set_mode; + QDF_STATUS status; if (!set_mode_params || !set_mode_params->vdev) { tdls_err("set_mode_params %pK", set_mode_params); @@ -842,8 +901,17 @@ QDF_STATUS ucfg_tdls_set_operating_mode( tdls_debug("Enter "); set_mode = qdf_mem_malloc(sizeof(*set_mode)); - if (!set_mode) + if (!set_mode) { + tdls_err("memory allocate fail"); return QDF_STATUS_E_NULL_VALUE; + } + + status = wlan_objmgr_vdev_try_get_ref(set_mode->vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to get vdev ref"); + qdf_mem_free(set_mode); + return status; + } set_mode->source = set_mode_params->source; set_mode->tdls_mode = set_mode_params->tdls_mode; @@ -853,9 +921,14 @@ QDF_STATUS ucfg_tdls_set_operating_mode( msg.bodyptr = set_mode; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_SET_TDLS_MODE; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_OS_IF, &msg); + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + wlan_objmgr_vdev_release_ref(set_mode->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(set_mode); + } tdls_debug("Exit "); From de6fc0aa1125bc16ea6488616c4c65611d681fed Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 24 Oct 2018 15:08:00 +0800 Subject: [PATCH 382/404] 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 4cfc4d37d5b525cc9538321ac8c27e01f0d68d96 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 30 Oct 2018 15:18:14 +0530 Subject: [PATCH 383/404] qcacmn: Pass valid arguments to hdd_wmm_is_acm_allowed Currently pointer of the vdev object is sent to the callback hdd_wmm_is_acm_allowed to get the adapter. But this can't be used to get the adapter. Instead pass the vdev id to get the adapter. Change-Id: I3cb2f58d09a263c77a3696a36e863cc4137c7821 CRs-Fixed: 2341799 --- core/src/wlan_tdls_cmds_process.c | 4 +++- dispatcher/inc/wlan_tdls_public_structs.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 8c9f985a5e72..00c384ed41e3 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -664,6 +664,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) struct tdls_peer *curr_peer; struct tdls_peer *temp_peer; QDF_STATUS status; + uint8_t vdev_id; struct tdls_validate_action_req *tdls_validate = tdls_mgmt_req->chk_frame; @@ -723,7 +724,8 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) } /* call hdd_wmm_is_acm_allowed() */ - if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) { + vdev_id = wlan_vdev_get_id(tdls_validate->vdev); + if (!tdls_soc->tdls_wmm_cb(vdev_id)) { tdls_debug("admission ctrl set to VI, send the frame with least AC (BK) for action %d", tdls_validate->action_code); tdls_mgmt_req->use_default_ac = false; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 9fbb273eefe3..3e05b007b6fd 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -553,7 +553,7 @@ typedef void (*tdls_rx_callback)(void *user_data, * * Return: true or false */ -typedef bool (*tdls_wmm_check)(struct wlan_objmgr_vdev **vdev); +typedef bool (*tdls_wmm_check)(uint8_t vdev_id); /* This callback is used to report state change of peer to wpa_supplicant */ From 2a4e082ad71360a96eeeb4e3b234d87ab7e87ae9 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Mon, 29 Oct 2018 19:45:57 +0530 Subject: [PATCH 384/404] qcacmn: Reduce scan time when in GO+STA MCC Scan on STA interface is taking around 10 secs to complete. There is a 7secs expiry time used in nl which could result in scan results received for the first 3secs, which are from 2G channels, to be flushed. Fix is to not set offchannel simultaneous feature capability, decrease the active dwell time for 2G channels to 40msecs and increase burst duration to 240msecs when GO is active. Change-Id: If014b2115048018432943d863bbe184beb498408 CRs-Fixed: 2340516 --- src/wlan_policy_mgr_get_set_utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_get_set_utils.c b/src/wlan_policy_mgr_get_set_utils.c index 250b5fb94988..c41b794d0a6b 100644 --- a/src/wlan_policy_mgr_get_set_utils.c +++ b/src/wlan_policy_mgr_get_set_utils.c @@ -3025,7 +3025,8 @@ bool policy_mgr_is_scan_simultaneous_capable(struct wlan_objmgr_psoc *psoc) (ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN == wlan_objmgr_psoc_get_dual_mac_disable(psoc)) || (ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN == - wlan_objmgr_psoc_get_dual_mac_disable(psoc))) + wlan_objmgr_psoc_get_dual_mac_disable(psoc)) || + !policy_mgr_is_hw_dbs_capable(psoc)) return false; return true; From ce77466cdb32050c0824e2155047d7f4502743e5 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Fri, 2 Nov 2018 15:17:53 +0530 Subject: [PATCH 385/404] qcacmn: Send the supported channel list length correctly to FW Currently, peer supported channel list length is updated first, and then channel list updated by removing the DFS and invalid channels. So, Wrong channel list length is sent to FW. Change-Id: I1e71bdeae3d5368fbea85ae5e47e13c326e36375 CRs-Fixed: 2344729 --- core/src/wlan_tdls_peer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 3f8a132e0e87..ff4bf86379a4 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -493,7 +493,6 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, peer->off_channel_capable; peer_param->peer_cap.peer_curr_operclass = 0; peer_param->peer_cap.self_curr_operclass = 0; - peer_param->peer_cap.peer_chanlen = peer->supported_channels_len; peer_param->peer_cap.pref_off_channum = peer->pref_off_chan_num; peer_param->peer_cap.pref_off_chan_bandwidth = soc_obj->tdls_configs.tdls_pre_off_chan_bw; @@ -520,6 +519,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, peer_param->peer_cap.peer_chan[num].pwr = wlan_reg_get_channel_reg_power(pdev, chan_id); peer_param->peer_cap.peer_chan[num].dfs_set = false; + peer_param->peer_cap.peer_chanlen++; num++; } } From 862a3441dea6675f90b677fc28ba68a977c90a0d Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Tue, 6 Nov 2018 18:52:18 +0530 Subject: [PATCH 386/404] qcacmn: Possible Out of bound read in policy_mgr_get_channel_list To prepare the channel list suggestion for a new connection, policy_mgr_get_channel_list invokes policy_mgr_get_valid_chans to get the number of valid channels. Driver uses returned num channel and iterates channel list to divide the list into 2.4 & 5 GHz lists. In case if, num of valid channel returned by policy_mgr_get_valid_chans is greater than the maximum number of channel supported in the channel list, QDF_MAX_NUM_CHAN(128), possible OOB read occurs. Validate the value of chan_index of channel list in policy_mgr_get_channel_list against the maximum number of channels supported in the channel list. Change-Id: I6beb9231aaef491731557434d1ae210ac0bdb036 CRs-Fixed: 2346125 --- src/wlan_policy_mgr_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wlan_policy_mgr_core.c b/src/wlan_policy_mgr_core.c index a91ecd9c1f12..f4dc476c016c 100644 --- a/src/wlan_policy_mgr_core.c +++ b/src/wlan_policy_mgr_core.c @@ -1972,6 +1972,7 @@ QDF_STATUS policy_mgr_get_channel_list(struct wlan_objmgr_psoc *psoc, } while ((chan_index < num_channels) && + (chan_index < QDF_MAX_NUM_CHAN) && (chan_index_5 < QDF_MAX_NUM_CHAN)) { if ((true == skip_dfs_channel) && wlan_reg_is_dfs_ch(pm_ctx->pdev, @@ -3090,7 +3091,7 @@ void policy_mgr_init_sap_mandatory_2g_chan(struct wlan_objmgr_psoc *psoc) } pm_ctx->sap_mandatory_channels_len = 0; - for (i = 0; i < len; i++) { + for (i = 0; (i < len) && (i < QDF_MAX_NUM_CHAN); i++) { if (WLAN_REG_IS_24GHZ_CH(chan_list[i])) { policy_mgr_debug("Add chan %hu to mandatory list", chan_list[i]); From e9abcb6c8388c0b8efa4d3910843bdcd3565ffab Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 5 Nov 2018 17:56:53 +0530 Subject: [PATCH 387/404] qcacmn: Increase serialization command timeout Increase the serialization command timeout for add sta and del sta of tdls peers requests. Change-Id: If6ba6aa1297afaea1fd86bf406dcbb6e4e461d25 CRs-Fixed: 2345425 --- core/src/wlan_tdls_cmds_process.c | 6 +++--- core/src/wlan_tdls_mgmt.h | 5 +---- dispatcher/inc/wlan_tdls_public_structs.h | 7 +++++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 00c384ed41e3..a27c040ef63a 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -825,7 +825,7 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) cmd.umac_cmd = req; cmd.source = WLAN_UMAC_COMP_TDLS; cmd.is_high_priority = false; - cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; + cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; cmd.vdev = vdev; cmd.is_blocking = true; @@ -1035,7 +1035,7 @@ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) cmd.umac_cmd = req; cmd.source = WLAN_UMAC_COMP_TDLS; cmd.is_high_priority = false; - cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; + cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; cmd.vdev = req->vdev; cmd.is_blocking = true; @@ -1189,7 +1189,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) cmd.umac_cmd = req; cmd.source = WLAN_UMAC_COMP_TDLS; cmd.is_high_priority = false; - cmd.cmd_timeout_duration = WAIT_TIME_TDLS_DEL_STA; + cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; cmd.vdev = vdev; cmd.is_blocking = true; diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h index a6973f17d715..ce6f9307988f 100644 --- a/core/src/wlan_tdls_mgmt.h +++ b/core/src/wlan_tdls_mgmt.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 @@ -25,9 +25,6 @@ #ifndef _WLAN_TDLS_MGMT_H_ #define _WLAN_TDLS_MGMT_H_ -/* default tdls serialize timeout is set to 10 secs */ -#define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000 - #define TDLS_PUBLIC_ACTION_FRAME_OFFSET 24 #define TDLS_PUBLIC_ACTION_FRAME 4 #define TDLS_PUBLIC_ACTION_DISC_RESP 14 diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 3e05b007b6fd..dd8f1b9237f8 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -50,11 +50,14 @@ #define AC_PRIORITY_NUM 4 +/* default tdls serialize timeout is set to 10 secs */ +#define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000 + /** Maximum time(ms) to wait for tdls add sta to complete **/ -#define WAIT_TIME_TDLS_ADD_STA 1500 +#define WAIT_TIME_TDLS_ADD_STA (TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT + 1000) /** Maximum time(ms) to wait for tdls del sta to complete **/ -#define WAIT_TIME_TDLS_DEL_STA 1500 +#define WAIT_TIME_TDLS_DEL_STA (TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT + 1000) /** Maximum time(ms) to wait for Link Establish Req to complete **/ #define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500 From 6cca937c9c709a0e33cee529cedae8bdd81380c3 Mon Sep 17 00:00:00 2001 From: Min Liu Date: Mon, 10 Sep 2018 18:23:43 +0800 Subject: [PATCH 388/404] 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 87107dd933953ac4d3a4f4c9821a325af2830b95 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 13 Nov 2018 13:10:56 +0530 Subject: [PATCH 389/404] qcacmn: Avoid redefination of tdls_add_oper enum Enums tdls_add_oper and TdlsAddOper are same. Instead redefining use the same enum across different files. Change-Id: Ibb71b0f80e156e4bd3a345a56c7b4d99ce770ef7 CRs-Fixed: 2349643 --- core/src/wlan_tdls_cmds_process.h | 13 ------------- dispatcher/inc/wlan_tdls_public_structs.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index bebf1b099f54..e66b41aa69e5 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -29,19 +29,6 @@ ((TDLS_SETUP_REQUEST <= action) && \ (TDLS_SETUP_CONFIRM >= action)) - -/** - * enum tdls_add_oper - add peer type - * @TDLS_OPER_NONE: none - * @TDLS_OPER_ADD: add new peer - * @TDLS_OPER_UPDATE: used to update peer - */ -enum tdls_add_oper { - TDLS_OPER_NONE, - TDLS_OPER_ADD, - TDLS_OPER_UPDATE -}; - /** * enum legacy_result_code - defined to comply with tSirResultCodes, need refine * when mlme converged. diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index dd8f1b9237f8..07bc155d9591 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -80,6 +80,19 @@ #define INVALID_TDLS_PEER_ID 0xFF #define TDLS_STA_INDEX_CHECK(sta_id) \ (((sta_id) >= 0) && ((sta_id) < 0xFF)) + +/** + * enum tdls_add_oper - add peer type + * @TDLS_OPER_NONE: none + * @TDLS_OPER_ADD: add new peer + * @TDLS_OPER_UPDATE: used to update peer + */ +enum tdls_add_oper { + TDLS_OPER_NONE, + TDLS_OPER_ADD, + TDLS_OPER_UPDATE +}; + /** * enum tdls_conc_cap - tdls concurrency support * @TDLS_SUPPORTED_ONLY_ON_STA: only support sta tdls From 07c45b33e8533e006b8cf71eab64782e861957eb Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Fri, 16 Nov 2018 11:41:20 +0800 Subject: [PATCH 390/404] qcacmn: Fix KW issue in tdls Potential NULL pointer dereferences in below functions: tdls_delete_all_tdls_peers_flush_cb() ucfg_tdls_notify_sta_connect() Change-Id: Iee31d91b31c5921fbd5cc70e0b893093b496ee43 CRs-Fixed: 2350930 --- core/src/wlan_tdls_ct.c | 6 +++--- dispatcher/src/wlan_tdls_ucfg_api.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 7be612d4b0ce..d2fa6bb71acf 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1123,10 +1123,10 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, static QDF_STATUS tdls_delete_all_tdls_peers_flush_cb(struct scheduler_msg *msg) { - if (msg && msg->bodyptr) + if (msg && msg->bodyptr) { qdf_mem_free(msg->bodyptr); - - msg->bodyptr = NULL; + msg->bodyptr = NULL; + } return QDF_STATUS_SUCCESS; } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index e1936cfc6252..cd86729d8a02 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -825,7 +825,8 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { - wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); + wlan_objmgr_vdev_release_ref(notify_info->vdev, + WLAN_TDLS_NB_ID); return QDF_STATUS_E_NULL_VALUE; } From 21a51732582403984bc4a59f580dbb38f257d684 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Fri, 2 Nov 2018 15:14:44 +0530 Subject: [PATCH 391/404] qcacmn: Set TDLS channel offset correctly Set TDLS channel offset correctly when TDLSSECONDARYCHANNELOFFSET command is sent with offset 20. Change-Id: Ifac48da3fea0c83415f3d30caa2919a559f5c3c5 CRs-Fixed: 2341883 --- core/src/wlan_tdls_ct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index d2fa6bb71acf..f62a5e1fd929 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -975,7 +975,7 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, return -ENOTSUPP; } - tdls_soc->tdls_channel_offset = 0; + tdls_soc->tdls_channel_offset = BW_INVALID; switch (offchanoffset) { case TDLS_SEC_OFFCHAN_OFFSET_0: @@ -1054,7 +1054,7 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, switch (offchanmode) { case ENABLE_CHANSWITCH: if (tdls_soc->tdls_off_channel && - tdls_soc->tdls_channel_offset) { + tdls_soc->tdls_channel_offset != BW_INVALID) { chan_switch_params.tdls_off_ch = tdls_soc->tdls_off_channel; chan_switch_params.tdls_off_ch_bw_offset = From 224d38154f3647584638503c30e9ce0baa23874f Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Fri, 16 Nov 2018 17:58:38 -0800 Subject: [PATCH 392/404] qcacld-3.0: Refactor more dfs cfg items Refactor following DFS cfg items CFG_DISABLE_DFS_CH_SWITCH CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME CFG_IGNORE_CAC_NAME CFG_DFS_RADAR_PRI_MULTIPLIER_NAME CFG_SAP_TX_LEAKAGE_THRESHOLD_NAME CFG_DFS_BEACON_TX_ENHANCED CFG_DISABLE_DFS_JAPAN_W53 CFG_ENABLE_NON_DFS_CHAN_ON_RADAR Change-Id: I7f39ed0680919c6a383d9b8bae5864f979b6948c CRs-Fixed: 2351995 --- components/mlme/core/src/wlan_mlme_main.c | 15 +- components/mlme/dispatcher/inc/cfg_mlme_dfs.h | 138 +++++++++++++++- .../dispatcher/inc/wlan_mlme_public_struct.h | 12 ++ .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 87 +++++++++++ .../mlme/dispatcher/src/wlan_mlme_ucfg_api.c | 147 ++++++++++++++++++ core/cds/inc/cds_config.h | 3 - core/hdd/inc/wlan_hdd_cfg.h | 135 ---------------- core/hdd/src/wlan_hdd_cfg.c | 72 --------- core/hdd/src/wlan_hdd_hostapd.c | 15 +- core/hdd/src/wlan_hdd_main.c | 21 +-- core/mac/inc/ani_global.h | 1 - core/mac/src/pe/lim/lim_utils.c | 2 +- core/sap/inc/sap_api.h | 28 ---- core/sap/src/sap_api_link_cntl.c | 4 +- core/sap/src/sap_fsm.c | 35 +---- core/sap/src/sap_internal.h | 15 -- core/sap/src/sap_module.c | 64 -------- core/sme/inc/csr_api.h | 2 - core/sme/src/csr/csr_api_roam.c | 5 - 19 files changed, 421 insertions(+), 380 deletions(-) diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index f538a26d3f7d..b9a30f2ccd35 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -850,8 +850,19 @@ static void mlme_init_rates_in_cfg(struct wlan_objmgr_psoc *psoc, static void mlme_init_dfs_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_dfs_cfg *dfs_cfg) { - dfs_cfg->dfs_master_capable = cfg_get(psoc, - CFG_ENABLE_DFS_MASTER_CAPABILITY); + dfs_cfg->dfs_ignore_cac = cfg_get(psoc, CFG_IGNORE_CAC); + dfs_cfg->dfs_master_capable = + cfg_get(psoc, CFG_ENABLE_DFS_MASTER_CAPABILITY); + dfs_cfg->dfs_disable_channel_switch = + cfg_get(psoc, CFG_DISABLE_DFS_CH_SWITCH); + dfs_cfg->dfs_filter_offload = + cfg_get(psoc, CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD); + dfs_cfg->dfs_prefer_non_dfs = + cfg_get(psoc, CFG_ENABLE_NON_DFS_CHAN_ON_RADAR); + dfs_cfg->dfs_beacon_tx_enhanced = + cfg_get(psoc, CFG_DFS_BEACON_TX_ENHANCED); + dfs_cfg->sap_tx_leakage_threshold = + cfg_get(psoc, CFG_SAP_TX_LEAKAGE_THRESHOLD); } static void mlme_init_feature_flag_in_cfg( diff --git a/components/mlme/dispatcher/inc/cfg_mlme_dfs.h b/components/mlme/dispatcher/inc/cfg_mlme_dfs.h index e3dd2c583825..0a5ce30c5d1b 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_dfs.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_dfs.h @@ -23,6 +23,136 @@ #ifndef __CFG_MLME_DFS_H #define __CFG_MLME_DFS_H +/* + * + * gsap_tx_leakage_threshold - sap tx leakage threshold + * @Min: 100 + * @Max: 1000 + * @Default: 310 + * + * customer can set this value from 100 to 1000 which means + * sap tx leakage threshold is -10db to -100db + * + * Related: none + * + * Usage: External + * + * + */ +#define CFG_SAP_TX_LEAKAGE_THRESHOLD CFG_INI_UINT( \ + "gsap_tx_leakage_threshold", \ + 100, \ + 1000, \ + 310, \ + CFG_VALUE_OR_DEFAULT, \ + "sap tx leakage threshold") + +/* + * + * gDfsBeaconTxEnhanced - beacon tx enhanced + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enhance dfs beacon tx + * + * Related: none + * + * Usage: External + * + * + */ +#define CFG_DFS_BEACON_TX_ENHANCED CFG_INI_BOOL( \ + "gDfsBeaconTxEnhanced", \ + 0, \ + "beacon tx enhanced") + +/* + * + * gPreferNonDfsChanOnRadar - During random channel selection prefer non dfs + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * During random channel selection prefer non dfs. + * + * Related: none + * + * Usage: External + * + * + */ +#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR CFG_INI_BOOL( \ + "gPreferNonDfsChanOnRadar", \ + 0, \ + "channel selection prefer non dfs") + +/* + * + * dfsPhyerrFilterOffload - Enable dfs phyerror filtering offload in FW + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to to enable dfs phyerror filtering offload to firmware + * Enabling it will cause basic phy error to be discarding in firmware. + * Related: NA. + * + * Supported Feature: DFS + * + * Usage: Internal/External + * + * + */ +#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD CFG_INI_BOOL( \ + "dfsPhyerrFilterOffload", \ + 0, \ + "dfs phyerror filtering offload") + +/* + * + * gIgnoreCAC - Used to ignore CAC + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to set default CAC + * + * Related: None + * + * Supported Feature: DFS + * + * Usage: Internal/External + * + * + */ +#define CFG_IGNORE_CAC CFG_INI_BOOL( \ + "gIgnoreCAC", \ + 0, \ + "ignore CAC on DFS channel") + +/* + * + * gDisableDFSChSwitch - Disable channel switch if radar is found + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to disable channel switch if radar is found + * on that channel. + * Related: NA. + * + * Supported Feature: DFS + * + * Usage: Internal + * + * + */ +#define CFG_DISABLE_DFS_CH_SWITCH CFG_INI_BOOL( \ + "gDisableDFSChSwitch", \ + 0, \ + "Disable channel switch on radar") + /* * * gEnableDFSMasterCap - Enable DFS master capability @@ -47,6 +177,12 @@ "DFS master mode capability") #define CFG_DFS_ALL \ - CFG(CFG_ENABLE_DFS_MASTER_CAPABILITY) + CFG(CFG_IGNORE_CAC) \ + CFG(CFG_DISABLE_DFS_CH_SWITCH) \ + CFG(CFG_DFS_BEACON_TX_ENHANCED) \ + CFG(CFG_SAP_TX_LEAKAGE_THRESHOLD) \ + CFG(CFG_ENABLE_NON_DFS_CHAN_ON_RADAR) \ + CFG(CFG_ENABLE_DFS_MASTER_CAPABILITY) \ + CFG(CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD) #endif /* __CFG_MLME_DFS_H */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index a433c97c5f09..e3cb559f2615 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -573,9 +573,21 @@ struct wlan_mlme_cfg_sap { /** * struct wlan_mlme_dfs_cfg - DFS Capabilities related config items * @dfs_master_capable: Is DFS master mode support enabled + * @dfs_disable_channel_switch: disable channel switch on radar detection + * @dfs_ignore_cac: Disable cac + * @dfs_filter_offload: dfs filter offloaad + * @dfs_beacon_tx_enhanced: enhance dfs beacon tx + * @dfs_prefer_non_dfs: perefer non dfs channel after radar + * @sap_tx_leakage_threshold: sap tx leakage threshold */ struct wlan_mlme_dfs_cfg { bool dfs_master_capable; + bool dfs_disable_channel_switch; + bool dfs_ignore_cac; + bool dfs_filter_offload; + bool dfs_beacon_tx_enhanced; + bool dfs_prefer_non_dfs; + uint32_t sap_tx_leakage_threshold; }; /** diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 2dc36010df60..7041c01c0bea 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -702,6 +702,93 @@ QDF_STATUS ucfg_mlme_get_dfs_master_capability(struct wlan_objmgr_psoc *psoc, bool *val); +/* + * ucfg_mlme_get_dfs_disable_channel_switch() - Get the dfs channel switch + * @psoc: pointer to psoc object + * @dfs_disable_channel_switch: Pointer to the value which will be filled + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_dfs_disable_channel_switch(struct wlan_objmgr_psoc *psoc, + bool *dfs_disable_channel_switch); + +/* + * ucfg_mlme_set_dfs_disable_channel_switch() - Set the dfs channel switch + * @psoc: pointer to psoc object + * @dfs_disable_channel_switch: Value that needs to be set. + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_dfs_disable_channel_switch(struct wlan_objmgr_psoc *psoc, + bool dfs_disable_channel_switch); +/* + * ucfg_mlme_get_dfs_ignore_cac() - GSet the dfs ignore cac + * @psoc: pointer to psoc object + * @dfs_ignore_cac: Pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_dfs_ignore_cac(struct wlan_objmgr_psoc *psoc, + bool *dfs_ignore_cac); + +/* + * ucfg_mlme_set_dfs_ignore_cac() - Set the dfs ignore cac + * @psoc: pointer to psoc object + * @dfs_ignore_cac: Value that needs to be set. + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_dfs_ignore_cac(struct wlan_objmgr_psoc *psoc, + bool dfs_ignore_cac); + +/* + * ucfg_mlme_get_sap_tx_leakage_threshold() - Get sap tx leakage threshold + * @psoc: pointer to psoc object + * @sap_tx_leakage_threshold: Pointer to the value which will be filled + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_sap_tx_leakage_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t *sap_tx_leakage_threshold); + +/* + * ucfg_mlme_set_sap_tx_leakage_threshold() - Set sap tx leakage threshold + * @psoc: pointer to psoc object + * @sap_tx_leakage_threshold: Value that needs to be set. + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_sap_tx_leakage_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t sap_tx_leakage_threshold); + +/* + * ucfg_mlme_get_dfs_filter_offload() - Get the dfs filter offload + * @psoc: pointer to psoc object + * @dfs_filter_offload: Pointer to the value which will be filled + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_dfs_filter_offload(struct wlan_objmgr_psoc *psoc, + bool *dfs_filter_offload); + +/* + * ucfg_mlme_set_dfs_filter_offload() - Set the dfs filter offload + * @psoc: pointer to psoc object + * @dfs_filter_offload: Value that needs to be set. + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_dfs_filter_offload(struct wlan_objmgr_psoc *psoc, + bool dfs_filter_offload); + /** * ucfg_mlme_get_pmkid_modes() - Get PMKID modes * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index 9ec2246a36d3..abe96955e635 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -206,6 +206,153 @@ ucfg_mlme_get_dfs_master_capability(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS +ucfg_mlme_get_dfs_disable_channel_switch(struct wlan_objmgr_psoc *psoc, + bool *dfs_disable_channel_switch) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + *dfs_disable_channel_switch = + cfg_default(CFG_DISABLE_DFS_CH_SWITCH); + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + *dfs_disable_channel_switch = + mlme_obj->cfg.dfs_cfg.dfs_disable_channel_switch; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_dfs_disable_channel_switch(struct wlan_objmgr_psoc *psoc, + bool dfs_disable_channel_switch) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + mlme_obj->cfg.dfs_cfg.dfs_disable_channel_switch = + dfs_disable_channel_switch; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_dfs_ignore_cac(struct wlan_objmgr_psoc *psoc, + bool *dfs_ignore_cac) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + *dfs_ignore_cac = cfg_default(CFG_IGNORE_CAC); + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + *dfs_ignore_cac = mlme_obj->cfg.dfs_cfg.dfs_ignore_cac; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_dfs_ignore_cac(struct wlan_objmgr_psoc *psoc, + bool dfs_ignore_cac) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + mlme_obj->cfg.dfs_cfg.dfs_ignore_cac = dfs_ignore_cac; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_sap_tx_leakage_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t *sap_tx_leakage_threshold) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + *sap_tx_leakage_threshold = + cfg_default(CFG_SAP_TX_LEAKAGE_THRESHOLD); + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + *sap_tx_leakage_threshold = + mlme_obj->cfg.dfs_cfg.sap_tx_leakage_threshold; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_sap_tx_leakage_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t sap_tx_leakage_threshold) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + mlme_obj->cfg.dfs_cfg.sap_tx_leakage_threshold = + sap_tx_leakage_threshold; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_get_dfs_filter_offload(struct wlan_objmgr_psoc *psoc, + bool *dfs_filter_offload) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + *dfs_filter_offload = + cfg_default(CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD); + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + *dfs_filter_offload = mlme_obj->cfg.dfs_cfg.dfs_filter_offload; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_dfs_filter_offload(struct wlan_objmgr_psoc *psoc, + bool dfs_filter_offload) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + mlme_obj->cfg.dfs_cfg.dfs_filter_offload = dfs_filter_offload; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_mlme_get_pmkid_modes(struct wlan_objmgr_psoc *psoc, uint32_t *val) diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h index 4e66afe2e57d..6eb627f0cb46 100644 --- a/core/cds/inc/cds_config.h +++ b/core/cds/inc/cds_config.h @@ -63,7 +63,6 @@ enum active_apf_mode { * @sta_maxlimod_dtim: station max listen interval * @driver_type: Enumeration of Driver Type whether FTM or Mission mode * currently rest of bits are not used - * @dfs_phyerr_filter_offload: DFS Phyerror Filtering offload status from ini * Indicates whether support is enabled or not * @ap_disable_intrabss_fwd: pass intra-bss-fwd info to txrx module * @ap_maxoffload_peers: max offload peer @@ -110,7 +109,6 @@ struct cds_config_info { uint16_t max_bssid; uint8_t sta_maxlimod_dtim; enum qdf_driver_type driver_type; - uint8_t dfs_phyerr_filter_offload; uint8_t ap_maxoffload_peers; uint8_t ap_maxoffload_reorderbuffs; #ifdef FEATURE_WLAN_RA_FILTERING @@ -118,7 +116,6 @@ struct cds_config_info { bool is_ra_ratelimit_enabled; #endif uint8_t reorder_offload; - int32_t dfs_pri_multiplier; uint8_t uc_offload_enabled; uint32_t uc_txbuf_count; uint32_t uc_txbuf_size; diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index ab98bda4f0b3..881ea4502f7b 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -2201,70 +2201,6 @@ enum hdd_link_speed_rpt_type { eHDD_LINK_SPEED_REPORT_MAX_SCALED = 2, }; -/* - * - * gDisableDFSChSwitch - Disable channel switch if radar is found - * @Min: 0 - * @Max: 1 - * @Default: 0 - * - * This ini is used to disable channel switch if radar is found - * on that channel. - * Related: NA. - * - * Supported Feature: DFS - * - * Usage: Internal - * - * - */ -#define CFG_DISABLE_DFS_CH_SWITCH "gDisableDFSChSwitch" -#define CFG_DISABLE_DFS_CH_SWITCH_MIN (0) -#define CFG_DISABLE_DFS_CH_SWITCH_MAX (1) -#define CFG_DISABLE_DFS_CH_SWITCH_DEFAULT (0) - -/* - * - * gDisableDfsJapanW53 - Block W53 channels in random channel selection - * @Min: 0 - * @Max: 1 - * @Default: 0 - * - * This ini is used to block W53 Japan channel in random channel selection - * Related: NA. - * - * Supported Feature: DFS - * - * Usage: Internal/External - * - * - */ -#define CFG_DISABLE_DFS_JAPAN_W53 "gDisableDfsJapanW53" -#define CFG_DISABLE_DFS_JAPAN_W53_MIN (0) -#define CFG_DISABLE_DFS_JAPAN_W53_MAX (1) -#define CFG_DISABLE_DFS_JAPAN_W53_DEFAULT (0) - -/* - * - * dfsPhyerrFilterOffload - DFS PHY error filter offload - * @Min: 0 - * @Max: 1 - * @Default: 0 - * - * This ini is used to enable firmware to do DFS PHY error filtering. - * Related: NA. - * - * Supported Feature: DFS - * - * Usage: Internal/External - * - * - */ -#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME "dfsPhyerrFilterOffload" -#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MIN (0) -#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MAX (1) -#define CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_DEFAULT (0) - /* * * gReportMaxLinkSpeed - Reporting of max link speed @@ -2936,34 +2872,6 @@ enum hdd_link_speed_rpt_type { #endif /* MSM_PLATFORM */ -/* - * - * gIgnoreCAC - Used to ignore CAC - * @Min: 0 - * @Max: 1 - * @Default: 0 - * - * This ini is used to set default CAC - * - * Related: None - * - * Supported Feature: STA - * - * Usage: Internal/External - * - * - */ - -#define CFG_IGNORE_CAC_NAME "gIgnoreCAC" -#define CFG_IGNORE_CAC_MIN (0) -#define CFG_IGNORE_CAC_MAX (1) -#define CFG_IGNORE_CAC_DEFAULT (0) - -#define CFG_DFS_RADAR_PRI_MULTIPLIER_NAME "gDFSradarMappingPriMultiplier" -#define CFG_DFS_RADAR_PRI_MULTIPLIER_DEFAULT (4) -#define CFG_DFS_RADAR_PRI_MULTIPLIER_MIN (0) -#define CFG_DFS_RADAR_PRI_MULTIPLIER_MAX (10) - #define CFG_ENABLE_SAP_SUSPEND "gEnableSapSuspend" #define CFG_ENABLE_SAP_SUSPEND_MIN (0) #define CFG_ENABLE_SAP_SUSPEND_MAX (1) @@ -3101,11 +3009,6 @@ enum hdd_link_speed_rpt_type { #define CFG_GO_11AC_OVERRIDE_MAX (1) #define CFG_GO_11AC_OVERRIDE_DEFAULT (1) -#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR "gPreferNonDfsChanOnRadar" -#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_MIN (0) -#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_MAX (1) -#define CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_DEFAULT (0) - /* * set the self gen power value from * 0 to 0xffff @@ -3461,16 +3364,6 @@ enum hdd_link_speed_rpt_type { #define CFG_MARK_INDOOR_AS_DISABLE_MAX (1) #define CFG_MARK_INDOOR_AS_DISABLE_DEFAULT (0) -/* - * sap tx leakage threshold - * customer can set this value from 100 to 1000 which means - * sap tx leakage threshold is -10db to -100db - */ -#define CFG_SAP_TX_LEAKAGE_THRESHOLD_NAME "gsap_tx_leakage_threshold" -#define CFG_SAP_TX_LEAKAGE_THRESHOLD_MIN (100) -#define CFG_SAP_TX_LEAKAGE_THRESHOLD_MAX (1000) -#define CFG_SAP_TX_LEAKAGE_THRESHOLD_DEFAULT (310) - /* * * enable_5g_band_pref - Enable preference for 5G from INI. @@ -4231,26 +4124,6 @@ enum hdd_link_speed_rpt_type { #define CFG_ENABLE_PACKET_FILTERS_MAX (63) #endif /* WLAN_FEATURE_PACKET_FILTERING */ -/* - * - * gDfsBeaconTxEnhanced - beacon tx enhanced - * @Min: 0 - * @Max: 1 - * @Default: 0 - * - * This ini is used to enhance dfs beacon tx - * - * Related: none - * - * Usage: External - * - * - */ -#define CFG_DFS_BEACON_TX_ENHANCED "gDfsBeaconTxEnhanced" -#define CFG_DFS_BEACON_TX_ENHANCED_MIN (0) -#define CFG_DFS_BEACON_TX_ENHANCED_MAX (1) -#define CFG_DFS_BEACON_TX_ENHANCED_DEFAULT (0) - /* * * btm_offload_config - Configure BTM @@ -5241,8 +5114,6 @@ struct hdd_config { uint32_t ibssPs1RxChainInAtimEnable; uint32_t IpaConfig; bool IpaClkScalingEnable; - uint8_t disableDFSChSwitch; - bool fDfsPhyerrFilterOffload; uint8_t gDisableDfsJapanW53; bool gEnableOverLapCh; bool fRegChangeDefCountry; @@ -5250,12 +5121,8 @@ struct hdd_config { uint8_t enableFwModuleLogLevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH]; - uint8_t ignoreCAC; - bool enable_sap_mandatory_chan_list; - int32_t dfsRadarPriMultiplier; - #ifdef FEATURE_WLAN_FORCE_SAP_SCC uint8_t SapSccChanAvoidance; #endif /* FEATURE_WLAN_FORCE_SAP_SCC */ @@ -5273,7 +5140,6 @@ struct hdd_config { #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ uint8_t sap_11ac_override; uint8_t go_11ac_override; - uint8_t prefer_non_dfs_on_radar; /* parameter for defer timer for enabling TDLS on p2p listen */ uint32_t fine_time_meas_cap; uint8_t max_scan_count; @@ -5367,7 +5233,6 @@ struct hdd_config { #ifdef WLAN_FEATURE_PACKET_FILTERING uint8_t packet_filters_bitmap; #endif - uint8_t dfs_beacon_tx_enhanced; uint32_t btm_offload_config; #ifdef WLAN_FEATURE_SAE bool is_sae_enabled; diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index ea772992f7e3..8f1f6d76021c 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -48,14 +48,6 @@ #include "cfg_ucfg_api.h" #include "hdd_dp_cfg.h" -static void ch_notify_set_g_disable_dfs_japan_w53(struct hdd_context *hdd_ctx, - unsigned long notify_id) -{ - bool disabled = hdd_ctx->config->gDisableDfsJapanW53; - - wlansap_set_dfs_restrict_japan_w53(hdd_ctx->mac_handle, disabled); -} - struct reg_table_entry g_registry_table[] = { REG_VARIABLE(CFG_ENABLE_CONNECTED_SCAN_NAME, WLAN_PARAM_Integer, struct hdd_config, enable_connected_scan, @@ -495,22 +487,6 @@ struct reg_table_entry g_registry_table[] = { CFG_THROTTLE_DUTY_CYCLE_LEVEL3_MIN, CFG_THROTTLE_DUTY_CYCLE_LEVEL3_MAX), - REG_VARIABLE(CFG_DISABLE_DFS_CH_SWITCH, WLAN_PARAM_Integer, - struct hdd_config, disableDFSChSwitch, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_DISABLE_DFS_CH_SWITCH_DEFAULT, - CFG_DISABLE_DFS_CH_SWITCH_MIN, - CFG_DISABLE_DFS_CH_SWITCH_MAX), - - REG_DYNAMIC_VARIABLE(CFG_DISABLE_DFS_JAPAN_W53, WLAN_PARAM_Integer, - struct hdd_config, gDisableDfsJapanW53, - VAR_FLAGS_OPTIONAL | - VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_DISABLE_DFS_JAPAN_W53_DEFAULT, - CFG_DISABLE_DFS_JAPAN_W53_MIN, - CFG_DISABLE_DFS_JAPAN_W53_MAX, - ch_notify_set_g_disable_dfs_japan_w53, 0), - REG_VARIABLE(CFG_ENABLE_FIRST_SCAN_2G_ONLY_NAME, WLAN_PARAM_Integer, struct hdd_config, enableFirstScan2GOnly, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -640,14 +616,6 @@ struct reg_table_entry g_registry_table[] = { CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MIN, CFG_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_MAX), - REG_VARIABLE(CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_NAME, - WLAN_PARAM_Integer, - struct hdd_config, fDfsPhyerrFilterOffload, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_DEFAULT, - CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MIN, - CFG_ENABLE_DFS_PHYERR_FILTEROFFLOAD_MAX), - REG_VARIABLE(CFG_ENABLE_OVERLAP_CH, WLAN_PARAM_Integer, struct hdd_config, gEnableOverLapCh, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK, @@ -698,20 +666,6 @@ struct reg_table_entry g_registry_table[] = { VAR_FLAGS_OPTIONAL, (void *)CFG_ENABLE_FW_MODULE_LOG_DEFAULT), - REG_VARIABLE(CFG_IGNORE_CAC_NAME, WLAN_PARAM_Integer, - struct hdd_config, ignoreCAC, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_IGNORE_CAC_DEFAULT, - CFG_IGNORE_CAC_MIN, - CFG_IGNORE_CAC_MAX), - - REG_VARIABLE(CFG_DFS_RADAR_PRI_MULTIPLIER_NAME, WLAN_PARAM_Integer, - struct hdd_config, dfsRadarPriMultiplier, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_DFS_RADAR_PRI_MULTIPLIER_DEFAULT, - CFG_DFS_RADAR_PRI_MULTIPLIER_MIN, - CFG_DFS_RADAR_PRI_MULTIPLIER_MAX), - REG_VARIABLE(CFG_ENABLE_SAP_SUSPEND, WLAN_PARAM_Integer, struct hdd_config, enable_sap_suspend, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -773,13 +727,6 @@ struct reg_table_entry g_registry_table[] = { CFG_GO_11AC_OVERRIDE_MIN, CFG_GO_11AC_OVERRIDE_MAX), - REG_VARIABLE(CFG_ENABLE_NON_DFS_CHAN_ON_RADAR, WLAN_PARAM_Integer, - struct hdd_config, prefer_non_dfs_on_radar, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_DEFAULT, - CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_MIN, - CFG_ENABLE_NON_DFS_CHAN_ON_RADAR_MAX), - REG_VARIABLE(CFG_FINE_TIME_MEAS_CAPABILITY, WLAN_PARAM_HexInteger, struct hdd_config, fine_time_meas_cap, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -996,14 +943,6 @@ struct reg_table_entry g_registry_table[] = { CFG_MARK_INDOOR_AS_DISABLE_MIN, CFG_MARK_INDOOR_AS_DISABLE_MAX), - REG_VARIABLE(CFG_SAP_TX_LEAKAGE_THRESHOLD_NAME, - WLAN_PARAM_Integer, - struct hdd_config, sap_tx_leakage_threshold, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_SAP_TX_LEAKAGE_THRESHOLD_DEFAULT, - CFG_SAP_TX_LEAKAGE_THRESHOLD_MIN, - CFG_SAP_TX_LEAKAGE_THRESHOLD_MAX), - REG_VARIABLE(CFG_RESTART_BEACONING_ON_CH_AVOID_NAME, WLAN_PARAM_Integer, struct hdd_config, restart_beaconing_on_chan_avoid_event, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -1223,14 +1162,6 @@ struct reg_table_entry g_registry_table[] = { CFG_LATENCY_FLAGS_ULTRALOW_MIN, CFG_LATENCY_FLAGS_ULTRALOW_MAX), - - REG_VARIABLE(CFG_DFS_BEACON_TX_ENHANCED, WLAN_PARAM_Integer, - struct hdd_config, dfs_beacon_tx_enhanced, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_DFS_BEACON_TX_ENHANCED_DEFAULT, - CFG_DFS_BEACON_TX_ENHANCED_MIN, - CFG_DFS_BEACON_TX_ENHANCED_MAX), - REG_VARIABLE(CFG_BTM_ENABLE_NAME, WLAN_PARAM_HexInteger, struct hdd_config, btm_offload_config, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -3029,9 +2960,6 @@ QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx) hdd_ctx->config->sap_channel_avoidance; #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ - smeConfig->csrConfig.f_prefer_non_dfs_on_radar = - hdd_ctx->config->prefer_non_dfs_on_radar; - smeConfig->csrConfig.is_ps_enabled = hdd_ctx->config->is_ps_enabled; smeConfig->csrConfig.auto_bmps_timer_val = hdd_ctx->config->auto_bmps_timer_val; diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 3e1b6c66e673..2e115e71201f 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -4628,10 +4628,11 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, uint16_t prev_rsn_length = 0; enum dfs_mode mode; struct hdd_adapter *sta_adapter; - uint8_t ignore_cac = 0; + bool ignore_cac = 0; uint8_t beacon_fixed_len; int value; bool val; + uint32_t tx_leakage_threshold = 0; uint32_t auto_channel_select_weight = cfg_default(CFG_AUTO_CHANNEL_SELECT_WEIGHT); uint8_t pref_chan_location = 0; @@ -4768,7 +4769,6 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, hdd_err("ucfg_mlme_get_auto_channel_weight failed, set def"); pConfig->auto_channel_select_weight = auto_channel_select_weight; - pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch; ucfg_mlme_get_sap_chn_switch_bcn_count(hdd_ctx->psoc, &value); pConfig->sap_chanswitch_beacon_cnt = value; ucfg_mlme_get_sap_channel_switch_mode(hdd_ctx->psoc, &val); @@ -4793,7 +4793,6 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, ucfg_mlme_get_sap_reduces_beacon_interval(hdd_ctx->psoc, &value); pConfig->dtim_period = pBeacon->dtim_period; - pConfig->dfs_beacon_tx_enhanced = iniConfig->dfs_beacon_tx_enhanced; pConfig->reduced_beacon_interval = value; hdd_debug("acs_mode %d", pConfig->acs_cfg.acs_mode); @@ -4866,14 +4865,13 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, goto error; } - if (iniConfig->ignoreCAC || + ucfg_mlme_get_dfs_ignore_cac(hdd_ctx->psoc, &ignore_cac); + if (ignore_cac || ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) && iniConfig->sta_sap_scc_on_dfs_chan)) ignore_cac = 1; wlansap_set_dfs_ignore_cac(mac_handle, ignore_cac); - wlansap_set_dfs_restrict_japan_w53(mac_handle, - iniConfig->gDisableDfsJapanW53); ucfg_mlme_get_pref_chan_location(hdd_ctx->psoc, &pref_chan_location); wlansap_set_dfs_preferred_channel_location(mac_handle, @@ -4890,8 +4888,9 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, pConfig->ieee80211d = 0; } - wlansap_set_tx_leakage_threshold(mac_handle, - iniConfig->sap_tx_leakage_threshold); + ucfg_mlme_get_sap_tx_leakage_threshold(hdd_ctx->psoc, + &tx_leakage_threshold); + tgt_dfs_set_tx_leakage_threshold(hdd_ctx->pdev, tx_leakage_threshold); capab_info = pMgmt_frame->u.beacon.capab_info; diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 7f5b17d330ee..f5093a7ba8cb 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -2126,15 +2126,18 @@ bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) { struct hdd_adapter *adapter; struct hdd_ap_ctx *ap_ctx; + bool dfs_disable_channel_switch = false; if (!hdd_ctx) { hdd_info("Couldn't get hdd_ctx"); return true; } - if (hdd_ctx->config->disableDFSChSwitch) { + ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc, + &dfs_disable_channel_switch); + if (dfs_disable_channel_switch) { hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d", - hdd_ctx, hdd_ctx->config->disableDFSChSwitch); + hdd_ctx, dfs_disable_channel_switch); return true; } @@ -9712,14 +9715,6 @@ static int hdd_update_cds_config(struct hdd_context *hdd_ctx) ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc, &cds_cfg->sta_maxlimod_dtim); - /* - * Copy the DFS Phyerr Filtering Offload status. - * This parameter reflects the value of the - * dfs_phyerr_filter_offload flag as set in the ini. - */ - cds_cfg->dfs_phyerr_filter_offload = - hdd_ctx->config->fDfsPhyerrFilterOffload; - status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Failed to get crash inject ini config"); @@ -9754,8 +9749,6 @@ static int hdd_update_cds_config(struct hdd_context *hdd_ctx) &value); cds_cfg->ap_maxoffload_reorderbuffs = value; - cds_cfg->dfs_pri_multiplier = - hdd_ctx->config->dfsRadarPriMultiplier; cds_cfg->reorder_offload = cfg_get(hdd_ctx->psoc, CFG_DP_REORDER_OFFLOAD_SUPPORT); @@ -14229,11 +14222,11 @@ QDF_STATUS hdd_update_score_config( static int hdd_update_dfs_config(struct hdd_context *hdd_ctx) { struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc; - struct hdd_config *cfg = hdd_ctx->config; struct dfs_user_config dfs_cfg; QDF_STATUS status; - dfs_cfg.dfs_is_phyerr_filter_offload = !!cfg->fDfsPhyerrFilterOffload; + ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc, + &dfs_cfg.dfs_is_phyerr_filter_offload); status = ucfg_dfs_update_config(psoc, &dfs_cfg); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("failed dfs psoc configuration"); diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index b80009a417eb..d267aca8b03f 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -834,7 +834,6 @@ struct mac_context { uint8_t beacon_offload; bool pmf_offload; bool is_fils_roaming_supported; - uint8_t f_prefer_non_dfs_on_radar; uint32_t f_sta_miracast_mcc_rest_time_val; #ifdef WLAN_FEATURE_EXTWOW_SUPPORT csr_readyToExtWoWCallback readyToExtWoWCallback; diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 5c2a2b5f3342..cd96b2a8dfd1 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -7936,7 +7936,7 @@ void lim_process_ap_ecsa_timeout(void *data) ch = session->gLimChannelSwitch.primaryChannel; ch_width = session->gLimChannelSwitch.ch_width; - if (mac_ctx->sap.SapDfsInfo.dfs_beacon_tx_enhanced) + if (mac_ctx->mlme_cfg->dfs_cfg.dfs_beacon_tx_enhanced) /* Send Action frame after updating beacon */ lim_send_chan_switch_action_frame(mac_ctx, ch, ch_width, session); diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 47afecf70343..0794f9fa1773 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -587,7 +587,6 @@ typedef struct sap_config { uint32_t ap_table_expiration_time; uint32_t ht_op_mode_fixed; enum QDF_OPMODE persona; /* Tells us which persona, GO or AP */ - uint8_t disableDFSChSwitch; bool enOverLapCh; #ifdef WLAN_FEATURE_11W bool mfpRequired; @@ -625,7 +624,6 @@ typedef struct sap_config { uint8_t sap_chanswitch_beacon_cnt; uint8_t sap_chanswitch_mode; bool chan_switch_hostapd_rate_enabled; - bool dfs_beacon_tx_enhanced; uint16_t reduced_beacon_interval; } tsap_config_t; @@ -720,7 +718,6 @@ typedef struct sSapDfsInfo { /* beacon count before channel switch */ uint8_t sap_ch_switch_beacon_cnt; uint8_t sap_ch_switch_mode; - bool dfs_beacon_tx_enhanced; uint16_t reduced_beacon_interval; } tSapDfsInfo; @@ -1268,19 +1265,6 @@ QDF_STATUS wlansap_get_dfs_ignore_cac(mac_handle_t mac_handle, QDF_STATUS wlansap_set_dfs_ignore_cac(mac_handle_t mac_handle, uint8_t ignore_cac); -/** - * wlansap_set_dfs_restrict_japan_w53() - enable/disable dfS for japan - * @mac_handle: Opaque handle to the global MAC context - * @disable_dfs_w53: Indicates if Japan W53 is disabled when set to 1 - * Indicates if Japan W53 is enabled when set to 0 - * - * This API is used to enable or disable Japan W53 Band - * Return: The QDF_STATUS code associated with performing the operation - * QDF_STATUS_SUCCESS: Success - */ -QDF_STATUS wlansap_set_dfs_restrict_japan_w53(mac_handle_t mac_handle, - uint8_t disable_dfs_w53); - #ifdef FEATURE_AP_MCC_CH_AVOIDANCE QDF_STATUS wlan_sap_set_channel_avoidance(mac_handle_t mac_handle, @@ -1438,18 +1422,6 @@ QDF_STATUS wlansap_acs_chselect(struct sap_context *sap_context, */ uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx); -/** - * wlansap_set_tx_leakage_threshold() - set sap tx leakage threshold. - * @mac_handle: Opaque handle to the global MAC context - * @tx_leakage_threshold: sap tx leakage threshold - * - * This function set sap tx leakage threshold. - * - * Return: QDF_STATUS. - */ -QDF_STATUS wlansap_set_tx_leakage_threshold(mac_handle_t mac_handle, - uint16_t tx_leakage_threshold); - /* * wlansap_set_invalid_session() - set session ID to invalid * @sap_ctx: pointer to the SAP context diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c index 74d06117ba1a..96e267147f93 100644 --- a/core/sap/src/sap_api_link_cntl.c +++ b/core/sap/src/sap_api_link_cntl.c @@ -419,7 +419,7 @@ wlansap_roam_process_dfs_chansw_update(mac_handle_t mac_handle, uint8_t dfs_beacon_start_req = 0; bool sap_scc_dfs; - if (sap_ctx->csr_roamProfile.disableDFSChSwitch) { + if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("sapdfs: DFS channel switch disabled")); @@ -582,7 +582,7 @@ wlansap_roam_process_dfs_radar_found(tpAniSirGlobal mac_ctx, tWLAN_SAPEvent sap_event; if (sap_is_dfs_cac_wait_state(sap_ctx)) { - if (sap_ctx->csr_roamProfile.disableDFSChSwitch) { + if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, "sapdfs: DFS channel switch disabled"); diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 2e65f68f957c..828c6e09b3d6 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -193,7 +193,7 @@ static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) uint8_t ch_wd; struct wlan_objmgr_pdev *pdev = NULL; struct ch_params *ch_params; - uint32_t hw_mode; + uint32_t hw_mode, flag = 0; struct mac_context *mac_ctx; struct dfs_acs_info acs_info = {0}; @@ -226,8 +226,12 @@ static uint8_t sap_random_channel_sel(struct sap_context *sap_ctx) } else { acs_info.acs_mode = false; } + + if (mac_ctx->mlme_cfg->dfs_cfg.dfs_prefer_non_dfs) + flag |= DFS_RANDOM_CH_FLAG_NO_DFS_CH; + if (QDF_IS_STATUS_ERROR(utils_dfs_get_random_channel( - pdev, 0, ch_params, &hw_mode, &ch, &acs_info))) { + pdev, flag, ch_params, &hw_mode, &ch, &acs_info))) { /* No available channel found */ QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("No available channel found!!!")); @@ -544,34 +548,12 @@ void sap_dfs_set_current_channel(void *ctx) tgt_dfs_get_radars(pdev); } tgt_dfs_set_phyerr_filter_offload(pdev); - if (sap_ctx->csr_roamProfile.disableDFSChSwitch) + if (mac_ctx->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) tgt_dfs_control(pdev, DFS_SET_USENOL, &use_nol, sizeof(uint32_t), NULL, NULL, &error); } } -bool sap_dfs_is_w53_invalid(mac_handle_t mac_handle, uint8_t channel_id) -{ - tpAniSirGlobal mac; - - mac = MAC_CONTEXT(mac_handle); - if (NULL == mac) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL("invalid mac")); - return false; - } - - /* - * Check for JAPAN W53 Channel operation capability - */ - if (true == mac->sap.SapDfsInfo.is_dfs_w53_disabled && - true == IS_CHAN_JAPAN_W53(channel_id)) { - return true; - } - - return false; -} - bool sap_dfs_is_channel_in_preferred_location(mac_handle_t mac_handle, uint8_t channel_id) { @@ -2826,7 +2808,6 @@ sapconvert_to_csr_profile(tsap_config_t *pconfig_params, eCsrRoamBssType bssType profile->BSSType = eCSR_BSS_TYPE_INFRA_AP; profile->SSIDs.numOfSSIDs = 1; profile->csrPersona = pconfig_params->persona; - profile->disableDFSChSwitch = pconfig_params->disableDFSChSwitch; qdf_mem_zero(profile->SSIDs.SSIDList[0].SSID.ssId, sizeof(profile->SSIDs.SSIDList[0].SSID.ssId)); @@ -3462,7 +3443,7 @@ uint8_t sap_indicate_radar(struct sap_context *sap_ctx) if (sap_ctx->fsm_state == SAP_STARTED) mac->sap.SapDfsInfo.csaIERequired = true; - if (sap_ctx->csr_roamProfile.disableDFSChSwitch) + if (mac->mlme_cfg->dfs_cfg.dfs_disable_channel_switch) return sap_ctx->channel; /* set the Radar Found flag in SapDfsInfo */ diff --git a/core/sap/src/sap_internal.h b/core/sap/src/sap_internal.h index 764fd4f98a16..a3544eca5f4f 100644 --- a/core/sap/src/sap_internal.h +++ b/core/sap/src/sap_internal.h @@ -387,21 +387,6 @@ bool sap_is_conc_sap_doing_scc_dfs(mac_handle_t mac_handle, uint8_t sap_get_total_number_sap_intf(mac_handle_t mac_handle); -/** - * sap_dfs_is_w53_invalid() - Check to see if invalid W53 operation requested - * @mac_handle: Opaque handle to the global MAC context - * @channel_id: Channel number to be verified - * - * This function checks if the passed channel is W53 and, if so, if - * SAP W53 operation is allowed. - * - * Return: - * * true - operation is invalid because the channel is W53 and W53 - * operation has been disabled - * * false - operation is valid - */ -bool sap_dfs_is_w53_invalid(mac_handle_t mac_handle, uint8_t channel_id); - /** * sap_dfs_is_channel_in_preferred_location() - Verify a channel is valid * with respect to indoor/outdoor location setting diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index e9fb64f5adae..54b2468a9846 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -721,8 +721,6 @@ QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx, * Copy the DFS Test Mode setting to pmac for * access in lower layers */ - pmac->sap.SapDfsInfo.disable_dfs_ch_switch = - pConfig->disableDFSChSwitch; pmac->sap.SapDfsInfo.sap_ch_switch_beacon_cnt = pConfig->sap_chanswitch_beacon_cnt; pmac->sap.SapDfsInfo.sap_ch_switch_mode = @@ -733,8 +731,6 @@ QDF_STATUS wlansap_start_bss(struct sap_context *sap_ctx, sap_ctx->csr_roamProfile.csrPersona; pmac->sap.sapCtxList[sap_ctx->sessionId].sessionID = sap_ctx->sessionId; - pmac->sap.SapDfsInfo.dfs_beacon_tx_enhanced = - pConfig->dfs_beacon_tx_enhanced; pmac->sap.SapDfsInfo.reduced_beacon_interval = pConfig->reduced_beacon_interval; @@ -1857,47 +1853,6 @@ QDF_STATUS wlansap_set_dfs_ignore_cac(mac_handle_t mac_handle, return QDF_STATUS_SUCCESS; } -QDF_STATUS -wlansap_set_dfs_restrict_japan_w53(mac_handle_t mac_handle, - uint8_t disable_dfs_w53) -{ - tpAniSirGlobal mac = NULL; - QDF_STATUS status; - enum dfs_reg dfs_region; - - if (NULL != mac_handle) { - mac = MAC_CONTEXT(mac_handle); - } else { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: Invalid mac_handle pointer", __func__); - return QDF_STATUS_E_FAULT; - } - - wlan_reg_get_dfs_region(mac->pdev, &dfs_region); - - /* - * Set the JAPAN W53 restriction only if the current - * regulatory domain is JAPAN. - */ - if (DFS_MKK_REGION == dfs_region) { - mac->sap.SapDfsInfo.is_dfs_w53_disabled = disable_dfs_w53; - QDF_TRACE(QDF_MODULE_ID_SAP, - QDF_TRACE_LEVEL_INFO_LOW, - FL("sapdfs: SET DFS JAPAN W53 DISABLED = %d"), - mac->sap.SapDfsInfo.is_dfs_w53_disabled); - - status = QDF_STATUS_SUCCESS; - } else { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - FL - ("Regdomain not japan, set disable JP W53 not valid")); - - status = QDF_STATUS_E_FAULT; - } - - return status; -} - bool sap_is_auto_channel_select(struct sap_context *sapcontext) { if (NULL == sapcontext) { @@ -2448,25 +2403,6 @@ uint32_t wlansap_get_chan_width(struct sap_context *sap_ctx) return wlan_sap_get_vht_ch_width(sap_ctx); } -QDF_STATUS wlansap_set_tx_leakage_threshold(mac_handle_t mac_handle, - uint16_t tx_leakage_threshold) -{ - tpAniSirGlobal mac; - - if (NULL == mac_handle) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, - "%s: Invalid mac_handle pointer", __func__); - return QDF_STATUS_E_FAULT; - } - - mac = MAC_CONTEXT(mac_handle); - tgt_dfs_set_tx_leakage_threshold(mac->pdev, tx_leakage_threshold); - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, - "%s: leakage_threshold %d", __func__, - tx_leakage_threshold); - return QDF_STATUS_SUCCESS; -} - QDF_STATUS wlansap_set_invalid_session(struct sap_context *sap_ctx) { if (NULL == sap_ctx) { diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 8a85c171416d..a40b9233127f 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -880,7 +880,6 @@ struct csr_roam_profile { uint8_t wps_state; tCsrMobilityDomainInfo MDID; enum QDF_OPMODE csrPersona; - uint8_t disableDFSChSwitch; /* addIe params */ tSirAddIeParams addIeParams; uint16_t beacon_tx_rate; @@ -1119,7 +1118,6 @@ typedef struct tagCsrConfigParam { #ifdef FEATURE_AP_MCC_CH_AVOIDANCE bool sap_channel_avoidance; #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ - uint8_t f_prefer_non_dfs_on_radar; bool is_ps_enabled; uint32_t auto_bmps_timer_val; uint32_t dual_mac_feature_disable; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 35b1c245d8be..0c14f40d9509 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -2721,9 +2721,6 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal mac, pParam->sap_channel_avoidance; #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ - mac->f_prefer_non_dfs_on_radar = - pParam->f_prefer_non_dfs_on_radar; - mac->sme.ps_global_info.ps_enabled = pParam->is_ps_enabled; mac->sme.ps_global_info.auto_bmps_timer_val = @@ -2888,8 +2885,6 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal mac, tCsrConfigParam *pParam) pParam->sap_channel_avoidance = mac->sap.sap_channel_avoidance; #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ pParam->max_intf_count = mac->sme.max_intf_count; - pParam->f_prefer_non_dfs_on_radar = - mac->f_prefer_non_dfs_on_radar; pParam->dual_mac_feature_disable = mac->dual_mac_feature_disable; pParam->sta_sap_scc_on_dfs_chan = From 4966f697ef6c0b3beadc559f148e163759495da0 Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Tue, 27 Nov 2018 16:40:51 -0800 Subject: [PATCH 393/404] qcacld-3.0: Refactor CFG_WMI_WQ_WATCHDOG cfg Refactor following CFG_WMI_WQ_WATCHDOG cfg items. Change-Id: Ib65c6cda2a2574940604e8b67bc29a6749add842 CRs-Fixed: 2357070 --- components/mlme/core/src/wlan_mlme_main.c | 2 + .../mlme/dispatcher/inc/cfg_mlme_timeout.h | 27 ++++++++++++ .../dispatcher/inc/wlan_mlme_public_struct.h | 2 + .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 22 ++++++++++ .../mlme/dispatcher/src/wlan_mlme_ucfg_api.c | 43 +++++++++++++++++++ core/hdd/inc/wlan_hdd_cfg.h | 24 ----------- core/hdd/src/wlan_hdd_cfg.c | 7 --- 7 files changed, 96 insertions(+), 31 deletions(-) diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index b9a30f2ccd35..91729344a406 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -585,6 +585,8 @@ static void mlme_init_timeout_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_AP_LINK_MONITOR_TIMEOUT); timeouts->ps_data_inactivity_timeout = cfg_get(psoc, CFG_PS_DATA_INACTIVITY_TIMEOUT); + timeouts->wmi_wq_watchdog_timeout = + cfg_get(psoc, CFG_WMI_WQ_WATCHDOG); } static void mlme_init_ht_cap_in_cfg(struct wlan_objmgr_psoc *psoc, diff --git a/components/mlme/dispatcher/inc/cfg_mlme_timeout.h b/components/mlme/dispatcher/inc/cfg_mlme_timeout.h index 7caed90aa9e3..0c23fe357586 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_timeout.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_timeout.h @@ -285,6 +285,32 @@ CFG_VALUE_OR_DEFAULT, \ "PS data inactivity timeout") +/* + * + * wmi_wq_watchdog - Sets timeout period for wmi watchdog bite. + * @Min: 0 + * @Max: 30 + * @Default: 20 + * + * This ini is used to set timeout period for wmi watchdog bite. If it is + * 0 then wmi watchdog bite is disabled. + * + * Related: None + * + * Supported Feature: STA + * + * Usage: External + * + * + */ +#define CFG_WMI_WQ_WATCHDOG CFG_INI_UINT( \ + "wmi_wq_watchdog", \ + 0, \ + 30, \ + 20, \ + CFG_VALUE_OR_DEFAULT, \ + "timeout period for wmi watchdog bite") + #define CFG_TIMEOUT_ALL \ CFG(CFG_JOIN_FAILURE_TIMEOUT) \ CFG(CFG_AUTH_FAILURE_TIMEOUT) \ @@ -297,6 +323,7 @@ CFG(CFG_HEART_BEAT_THRESHOLD) \ CFG(CFG_AP_KEEP_ALIVE_TIMEOUT) \ CFG(CFG_AP_LINK_MONITOR_TIMEOUT) \ + CFG(CFG_WMI_WQ_WATCHDOG) \ CFG(CFG_PS_DATA_INACTIVITY_TIMEOUT) #endif /* __CFG_MLME_TIMEOUT_H */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index e3cb559f2615..09a9abb1e723 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1568,6 +1568,7 @@ struct wlan_mlme_power { * @ap_keep_alive_timeout: AP keep alive timeout value * @ap_link_monitor_timeout: AP link monitor timeout value * @ps_data_inactivity_timeout: PS data inactivity timeout + * @wmi_wq_watchdog_timeout: timeout period for wmi watchdog bite */ struct wlan_mlme_timeout { uint32_t join_failure_timeout; @@ -1582,6 +1583,7 @@ struct wlan_mlme_timeout { uint32_t ap_keep_alive_timeout; uint32_t ap_link_monitor_timeout; uint32_t ps_data_inactivity_timeout; + uint32_t wmi_wq_watchdog_timeout; }; /** diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 7041c01c0bea..5a388432ac4b 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -1203,6 +1203,28 @@ QDF_STATUS ucfg_mlme_set_fast_roam_in_concurrency_enabled(struct wlan_objmgr_psoc *psoc, bool val); +/** + * ucfg_mlme_get_wmi_wq_watchdog_timeout() - Get timeout for wmi watchdog bite + * @psoc: pointer to psoc object + * @wmi_wq_watchdog_timeout: buffer to hold value + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_wmi_wq_watchdog_timeout(struct wlan_objmgr_psoc *psoc, + uint32_t *wmi_wq_watchdog_timeout); + +/** + * ucfg_mlme_set_wmi_wq_watchdog_timeout() - Set timeout for wmi watchdog bite + * @psoc: pointer to psoc object + * @wmi_wq_watchdog_timeout: value to be set + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_wmi_wq_watchdog_timeout(struct wlan_objmgr_psoc *psoc, + uint32_t wmi_wq_watchdog_timeout); + /** * ucfg_mlme_get_ps_data_inactivity_timeout() - Get data inactivity timeout * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index abe96955e635..268c68fdec36 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -1118,6 +1118,49 @@ ucfg_mlme_get_current_mcs_set(struct wlan_objmgr_psoc *psoc, len); } +QDF_STATUS +ucfg_mlme_get_wmi_wq_watchdog_timeout(struct wlan_objmgr_psoc *psoc, + uint32_t *wmi_wq_watchdog_timeout) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + *wmi_wq_watchdog_timeout = cfg_default(CFG_WMI_WQ_WATCHDOG); + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + *wmi_wq_watchdog_timeout = + mlme_obj->cfg.timeouts.wmi_wq_watchdog_timeout; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_wmi_wq_watchdog_timeout(struct wlan_objmgr_psoc *psoc, + uint32_t wmi_wq_watchdog_timeout) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + mlme_err("mlme obj null"); + return QDF_STATUS_E_INVAL; + } + + if (!cfg_in_range(CFG_WMI_WQ_WATCHDOG, wmi_wq_watchdog_timeout)) { + mlme_err("wmi watchdog bite timeout is invalid %d", + wmi_wq_watchdog_timeout); + return QDF_STATUS_E_INVAL; + } + + mlme_obj->cfg.timeouts.wmi_wq_watchdog_timeout = + wmi_wq_watchdog_timeout; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_mlme_get_ps_data_inactivity_timeout(struct wlan_objmgr_psoc *psoc, uint32_t *inactivity_timeout) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 881ea4502f7b..91bd90df8b2c 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -4434,29 +4434,6 @@ enum hdd_link_speed_rpt_type { #define CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_MAX (300) #define CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_DEFAULT (3) -/* - * - * wmi_wq_watchdog - Sets timeout period for wmi watchdog bite - * @Min: 0 - * @Max: 30 - * @Default: 20 - * - * This ini is used to set timeout period for wmi watchdog bite. If it is - * 0 then wmi watchdog bite is disabled. - * - * Related: None - * - * Supported Feature: STA - * - * Usage: External - * - * - */ -#define CFG_WMI_WQ_WATCHDOG "wmi_wq_watchdog" -#define CFG_WMI_WQ_WATCHDOG_MIN (0) -#define CFG_WMI_WQ_WATCHDOG_MAX (30) /* 30s */ -#define CFG_WMI_WQ_WATCHDOG_DEFAULT (20) /* 20s */ - /* * * gEnableDTIMSelectionDiversity - Enable/Disable chain @@ -5253,7 +5230,6 @@ struct hdd_config { uint32_t neighbor_report_offload_max_req_cap; bool action_oui_enable; uint8_t action_oui_str[ACTION_OUI_MAXIMUM_ID][ACTION_OUI_MAX_STR_LEN]; - uint16_t wmi_wq_watchdog_timeout; uint8_t enable_tx_sch_delay; uint32_t enable_secondary_rate; bool is_unit_test_framework_enabled; diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 8f1f6d76021c..5942ef1581df 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -1272,13 +1272,6 @@ struct reg_table_entry g_registry_table[] = { CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_MIN, CFG_OFFLOAD_NEIGHBOR_REPORT_MAX_REQ_CAP_MAX), - REG_VARIABLE(CFG_WMI_WQ_WATCHDOG, WLAN_PARAM_Integer, - struct hdd_config, wmi_wq_watchdog_timeout, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_WMI_WQ_WATCHDOG_DEFAULT, - CFG_WMI_WQ_WATCHDOG_MIN, - CFG_WMI_WQ_WATCHDOG_MAX), - REG_VARIABLE(CFG_DTIM_SELECTION_DIVERSITY_NAME, WLAN_PARAM_Integer, struct hdd_config, enable_dtim_selection_diversity, From bd5194c5e0fe0c8e5837354005da82a6a17f61d5 Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Tue, 27 Nov 2018 19:01:15 -0800 Subject: [PATCH 394/404] qcacld-3.0: Refactor CFG_FINE_TIME_MEAS_CAPABILITY cfg Refactor following CFG_FINE_TIME_MEAS_CAPABILITY cfg items. Change-Id: I854e584e366490f788ee778adad3fec0c2b5c8cc CRs-Fixed: 2357070 --- components/mlme/core/inc/wlan_mlme_main.h | 5 +- components/mlme/core/src/wlan_mlme_main.c | 13 +++- components/mlme/dispatcher/inc/cfg_mlme.h | 2 + .../mlme/dispatcher/inc/cfg_mlme_wifi_pos.h | 74 +++++++++++++++++++ .../dispatcher/inc/wlan_mlme_public_struct.h | 10 +++ .../mlme/dispatcher/inc/wlan_mlme_ucfg_api.h | 22 ++++++ .../mlme/dispatcher/src/wlan_mlme_ucfg_api.c | 33 +++++++++ core/hdd/inc/wlan_hdd_cfg.h | 30 -------- core/hdd/src/wlan_hdd_cfg.c | 18 +---- core/hdd/src/wlan_hdd_cfg80211.c | 25 +++++-- core/hdd/src/wlan_hdd_main.c | 25 +++++-- 11 files changed, 197 insertions(+), 60 deletions(-) create mode 100644 components/mlme/dispatcher/inc/cfg_mlme_wifi_pos.h diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index 47f4f8a0a67d..a21089abac1e 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -181,6 +181,9 @@ QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc); * * Return: pointer to MLME object */ -struct wlan_mlme_psoc_obj *mlme_get_psoc_obj(struct wlan_objmgr_psoc *psoc); +#define mlme_get_psoc_obj(psoc) mlme_get_psoc_obj_fl(psoc, __func__, __LINE__) +struct wlan_mlme_psoc_obj *mlme_get_psoc_obj_fl(struct wlan_objmgr_psoc *psoc, + const char *func, + uint32_t line); #endif diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index 91729344a406..e21b3a854c4b 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -28,13 +28,16 @@ #define NUM_OF_SOUNDING_DIMENSIONS 1 /*Nss - 1, (Nss = 2 for 2x2)*/ -struct wlan_mlme_psoc_obj *mlme_get_psoc_obj(struct wlan_objmgr_psoc *psoc) +struct wlan_mlme_psoc_obj *mlme_get_psoc_obj_fl(struct wlan_objmgr_psoc *psoc, + const char *func, uint32_t line) { struct wlan_mlme_psoc_obj *mlme_obj; mlme_obj = (struct wlan_mlme_psoc_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_MLME); + if (!mlme_obj) + mlme_err("mlme obj is null, %s:%d", func, line); return mlme_obj; } @@ -1700,6 +1703,13 @@ static void mlme_init_wep_cfg(struct wlan_mlme_wep_cfg *wep_params) mlme_init_wep_keys(wep_params); } +static void mlme_init_wifi_pos_cfg(struct wlan_objmgr_psoc *psoc, + struct wlan_mlme_wifi_pos_cfg *wifi_pos_cfg) +{ + wifi_pos_cfg->fine_time_meas_cap = + cfg_get(psoc, CFG_FINE_TIME_MEAS_CAPABILITY); +} + #ifdef FEATURE_WLAN_ESE static void mlme_init_inactivity_intv(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_wmm_params *wmm_params) @@ -1857,6 +1867,7 @@ QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc) mlme_init_power_cfg(psoc, &mlme_cfg->power); mlme_init_oce_cfg(psoc, &mlme_cfg->oce); mlme_init_wep_cfg(&mlme_cfg->wep_params); + mlme_init_wifi_pos_cfg(psoc, &mlme_cfg->wifi_pos_cfg); mlme_init_wps_params_cfg(psoc, &mlme_cfg->wps_params); return status; diff --git a/components/mlme/dispatcher/inc/cfg_mlme.h b/components/mlme/dispatcher/inc/cfg_mlme.h index 3e95ad392c99..8b8292bb6471 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme.h +++ b/components/mlme/dispatcher/inc/cfg_mlme.h @@ -50,6 +50,7 @@ #include "cfg_mlme_threshold.h" #include "cfg_mlme_feature_flag.h" #include "cfg_mlme_wep_params.h" +#include "cfg_mlme_wifi_pos.h" /* Please Maintain Alphabetic Order here */ #define CFG_MLME_ALL \ @@ -80,6 +81,7 @@ CFG_TWT_ALL \ CFG_VHT_CAPS_ALL \ CFG_WEP_PARAMS_ALL \ + CFG_WIFI_POS_ALL \ CFG_WPS_ALL #endif /* __CFG_MLME_H */ diff --git a/components/mlme/dispatcher/inc/cfg_mlme_wifi_pos.h b/components/mlme/dispatcher/inc/cfg_mlme_wifi_pos.h new file mode 100644 index 000000000000..7904e8dee402 --- /dev/null +++ b/components/mlme/dispatcher/inc/cfg_mlme_wifi_pos.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2012-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 + * 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: This file contains centralized definitions of converged configuration. + */ + +#ifndef __CFG_MLME_WIFI_POS_H +#define __CFG_MLME_WIFI_POS_H + +/* + * + * gfine_time_meas_cap - fine timing measurement capability information + * @Min: 0x0000 + * @Max: 0x00BD + * @Default: 0x00BD + * + * fine timing measurement capability information + * + * <----- fine_time_meas_cap (in bits) -----> + * +----------+-----+-----+------+------+-------+-------+-----+-----+ + * | 8-31 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * +----------+-----+-----+------+------+-------+-------+-----+-----+ + * | reserved | SAP | SAP |P2P-GO|P2P-GO|P2P-CLI|P2P-CLI| STA | STA | + * | |resp |init |resp |init |resp |init |resp |init | + * +----------+-----+-----+------+------+-------+-------+-----+-----+ + * + * resp - responder role; init- initiator role + * + * CFG_FINE_TIME_MEAS_CAPABILITY_MAX computed based on the table + * +-----------------+-----------------+-----------+ + * | Device Role | Initiator | Responder | + * +-----------------+-----------------+-----------+ + * | Station | Y | N | + * | P2P-CLI | Y | Y | + * | P2P-GO | Y | Y | + * | SAP | N | Y | + * +-----------------+-----------------+-----------+ + * + * Related: None + * + * Supported Feature: WIFI POS + * + * Usage: Internal/External + * + * + */ +#define CFG_FINE_TIME_MEAS_CAPABILITY CFG_INI_UINT( \ + "gfine_time_meas_cap", \ + 0x0000, \ + 0x00BD, \ + 0x00BD, \ + CFG_VALUE_OR_DEFAULT, \ + "fine timing measurement capability") + +#define CFG_WIFI_POS_ALL \ + CFG(CFG_FINE_TIME_MEAS_CAPABILITY) + +#endif /* __CFG_MLME_WIFI_POS_H */ diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 09a9abb1e723..3a59cd7fa9a2 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -1644,6 +1644,14 @@ struct wlan_mlme_wep_cfg { struct mlme_cfg_str wep_default_key_4; }; +/** + * struct wlan_mlme_wifi_pos_cfg - WIFI POS configs + * @fine_time_meas_cap: fine timing measurement capability information + */ +struct wlan_mlme_wifi_pos_cfg { + uint32_t fine_time_meas_cap; +}; + /** * struct wlan_mlme_cfg - MLME config items * @chainmask_cfg: VHT chainmask related cfg items @@ -1672,6 +1680,7 @@ struct wlan_mlme_wep_cfg { * @acs: ACS related CFG items * @feature_flags: Feature flag config items * @wep_params: WEP related config items + * @wifi_pos_cfg: WIFI POS config * @wmm_params: WMM related CFG & INI Items * @wps_params: WPS related CFG itmes */ @@ -1704,6 +1713,7 @@ struct wlan_mlme_cfg { struct wlan_mlme_acs acs; struct wlan_mlme_feature_flag feature_flags; struct wlan_mlme_wep_cfg wep_params; + struct wlan_mlme_wifi_pos_cfg wifi_pos_cfg; struct wlan_mlme_wmm_params wmm_params; struct wlan_mlme_wps_params wps_params; }; diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index 5a388432ac4b..908d9bf768c6 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -789,6 +789,28 @@ QDF_STATUS ucfg_mlme_set_dfs_filter_offload(struct wlan_objmgr_psoc *psoc, bool dfs_filter_offload); +/** + * ucfg_mlme_get_fine_time_meas_cap() - Get fine timing measurement capability + * @psoc: pointer to psoc object + * @fine_time_meas_cap: Pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_get_fine_time_meas_cap(struct wlan_objmgr_psoc *psoc, + uint32_t *fine_time_meas_cap); + +/** + * ucfg_mlme_set_fine_time_meas_cap() - Set fine timing measurement capability + * @psoc: pointer to psoc object + * @fine_time_meas_cap: Value to be set + * + * Return: QDF Status + */ +QDF_STATUS +ucfg_mlme_set_fine_time_meas_cap(struct wlan_objmgr_psoc *psoc, + uint32_t fine_time_meas_cap); + /** * ucfg_mlme_get_pmkid_modes() - Get PMKID modes * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index 268c68fdec36..533e045dca38 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -206,6 +206,39 @@ ucfg_mlme_get_dfs_master_capability(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS +ucfg_mlme_get_fine_time_meas_cap(struct wlan_objmgr_psoc *psoc, + uint32_t *fine_time_meas_cap) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) { + *fine_time_meas_cap = + cfg_default(CFG_FINE_TIME_MEAS_CAPABILITY); + return QDF_STATUS_E_INVAL; + } + + *fine_time_meas_cap = mlme_obj->cfg.wifi_pos_cfg.fine_time_meas_cap; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +ucfg_mlme_set_fine_time_meas_cap(struct wlan_objmgr_psoc *psoc, + uint32_t fine_time_meas_cap) +{ + struct wlan_mlme_psoc_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + mlme_obj->cfg.wifi_pos_cfg.fine_time_meas_cap = fine_time_meas_cap; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_mlme_get_dfs_disable_channel_switch(struct wlan_objmgr_psoc *psoc, bool *dfs_disable_channel_switch) diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 91bd90df8b2c..242bf9ad7988 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -3018,34 +3018,6 @@ enum hdd_link_speed_rpt_type { #define CFG_SELF_GEN_FRM_PWR_MAX (0xffff) #define CFG_SELF_GEN_FRM_PWR_DEFAULT (0) -/* - * fine timing measurement capability information - * - * <----- fine_time_meas_cap (in bits) -----> - *+----------+-----+-----+------+------+-------+-------+-----+-----+ - *| 8-31 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | - *+----------+-----+-----+------+------+-------+-------+-----+-----+ - *| reserved | SAP | SAP |P2P-GO|P2P-GO|P2P-CLI|P2P-CLI| STA | STA | - *| |resp |init |resp |init |resp |init |resp |init | - *+----------+-----+-----+------+------+-------+-------+-----+-----+ - * - * resp - responder role; init- initiator role - * - * CFG_FINE_TIME_MEAS_CAPABILITY_MAX computed based on the table - * +-----------------+-----------------+-----------+ - * | Device Role | Initiator | Responder | - * +-----------------+-----------------+-----------+ - * | Station | Y | N | - * | P2P-CLI | Y | Y | - * | P2P-GO | Y | Y | - * | SAP | N | Y | - * +-----------------+-----------------+-----------+ - */ -#define CFG_FINE_TIME_MEAS_CAPABILITY "gfine_time_meas_cap" -#define CFG_FINE_TIME_MEAS_CAPABILITY_MIN (0x0000) -#define CFG_FINE_TIME_MEAS_CAPABILITY_MAX (0x00BD) -#define CFG_FINE_TIME_MEAS_CAPABILITY_DEFAULT (0x000D) - /* * * etsi13_srd_chan_in_master_mode - Enable/disable ETSI SRD channels in @@ -5117,8 +5089,6 @@ struct hdd_config { #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */ uint8_t sap_11ac_override; uint8_t go_11ac_override; - /* parameter for defer timer for enabling TDLS on p2p listen */ - uint32_t fine_time_meas_cap; uint8_t max_scan_count; bool etsi13_srd_chan_in_master_mode; uint32_t dual_mac_feature_disable; diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 5942ef1581df..c43d904e28c4 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -727,13 +727,6 @@ struct reg_table_entry g_registry_table[] = { CFG_GO_11AC_OVERRIDE_MIN, CFG_GO_11AC_OVERRIDE_MAX), - REG_VARIABLE(CFG_FINE_TIME_MEAS_CAPABILITY, WLAN_PARAM_HexInteger, - struct hdd_config, fine_time_meas_cap, - VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, - CFG_FINE_TIME_MEAS_CAPABILITY_DEFAULT, - CFG_FINE_TIME_MEAS_CAPABILITY_MIN, - CFG_FINE_TIME_MEAS_CAPABILITY_MAX), - REG_VARIABLE(CFG_MAX_SCAN_COUNT_NAME, WLAN_PARAM_Integer, struct hdd_config, max_scan_count, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -2464,16 +2457,11 @@ QDF_STATUS hdd_set_idle_ps_config(struct hdd_context *hdd_ctx, bool val) */ static void hdd_set_fine_time_meas_cap(struct hdd_context *hdd_ctx) { - struct hdd_config *config = hdd_ctx->config; - uint32_t capability = config->fine_time_meas_cap; + uint32_t capability = 0; - /* Make sure only supported capabilities are enabled in INI */ - capability &= CFG_FINE_TIME_MEAS_CAPABILITY_MAX; + ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &capability); ucfg_wifi_pos_set_ftm_cap(hdd_ctx->psoc, capability); - - hdd_debug("fine time meas capability - INI: %04x Enabled: %04x", - config->fine_time_meas_cap, - capability); + hdd_debug("fine time meas capability - Enabled: %04x", capability); } /** diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 6aa0e5e51527..6b0e24e826b0 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -5589,6 +5589,7 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, uint16_t latency_level; mac_handle_t mac_handle; bool b_value; + uint32_t fine_time_meas_cap = 0; struct wlan_objmgr_vdev *vdev; uint8_t bmiss_first_bcnt; uint8_t bmiss_final_bcnt; @@ -5616,16 +5617,26 @@ __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy, if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT]) { ftm_capab = nla_get_u32(tb[ QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT]); - hdd_ctx->config->fine_time_meas_cap = + fine_time_meas_cap = hdd_ctx->fine_time_meas_cap_target & ftm_capab; + + qdf_status = + ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc, + fine_time_meas_cap); + if (QDF_IS_STATUS_ERROR(qdf_status)) { + hdd_err("FTM capability: values 0x%x, 0x%x, 0x%x", + ftm_capab, hdd_ctx->fine_time_meas_cap_target, + fine_time_meas_cap); + return -EINVAL; + } + sme_update_fine_time_measurement_capab(mac_handle, - adapter->session_id, - hdd_ctx->config->fine_time_meas_cap); - ucfg_wifi_pos_set_ftm_cap(hdd_ctx->psoc, - hdd_ctx->config->fine_time_meas_cap); + adapter->session_id, + fine_time_meas_cap); + ucfg_wifi_pos_set_ftm_cap(hdd_ctx->psoc, fine_time_meas_cap); hdd_debug("FTM capability: user value: 0x%x, target value: 0x%x, final value: 0x%x", - ftm_capab, hdd_ctx->fine_time_meas_cap_target, - hdd_ctx->config->fine_time_meas_cap); + ftm_capab, hdd_ctx->fine_time_meas_cap_target, + fine_time_meas_cap); } if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM]) { diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index f5093a7ba8cb..9c3462c74374 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1885,6 +1885,7 @@ void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) mac_handle_t mac_handle; bool bval = false; uint8_t value = 0; + uint32_t fine_time_meas_cap = 0; if (!hdd_ctx) { hdd_err("HDD context is NULL"); @@ -2051,10 +2052,19 @@ void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg) hdd_update_hw_dbs_capable(hdd_ctx); hdd_ctx->dynamic_nss_chains_support = cfg->dynamic_nss_chains_support; - hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap; + ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap); + fine_time_meas_cap &= cfg->fine_time_measurement_cap; + status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc, + fine_time_meas_cap); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x", + fine_time_meas_cap, cfg->fine_time_measurement_cap); + ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, + &fine_time_meas_cap); + } + hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap; - hdd_debug("fine_time_meas_cap: 0x%x", - hdd_ctx->config->fine_time_meas_cap); + hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap); status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval); if (!QDF_IS_STATUS_SUCCESS(status)) @@ -9580,6 +9590,7 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) bool is_ssr = false; int ret; struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + uint32_t fine_time_meas_cap = 0; hdd_enter(); @@ -9609,12 +9620,14 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter) return ret; } - if (adapter->device_mode == QDF_SAP_MODE) + if (adapter->device_mode == QDF_SAP_MODE) { + ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, + &fine_time_meas_cap); sme_cli_set_command(adapter->session_id, WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE, - (bool)(hdd_ctx->config->fine_time_meas_cap & - WMI_FW_AP_RTT_RESPR), + (bool)(fine_time_meas_cap & WMI_FW_AP_RTT_RESPR), VDEV_CMD); + } status = hdd_init_ap_mode(adapter, is_ssr); From 3672a9ba9b43591c5862133cf84925eb0bb79d5b Mon Sep 17 00:00:00 2001 From: nshrivas Date: Tue, 4 Dec 2018 00:06:01 -0800 Subject: [PATCH 395/404] Release 5.2.0.109U Release 5.2.0.109U Change-Id: I50bdb2784d92108254797f5209d512967dedc7b2 CRs-Fixed: 774533 --- core/mac/inc/qwlan_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index da6559829e1c..0144037e5d22 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -32,9 +32,9 @@ #define QWLAN_VERSION_MAJOR 5 #define QWLAN_VERSION_MINOR 2 #define QWLAN_VERSION_PATCH 0 -#define QWLAN_VERSION_EXTRA "T" +#define QWLAN_VERSION_EXTRA "U" #define QWLAN_VERSION_BUILD 109 -#define QWLAN_VERSIONSTR "5.2.0.109T" +#define QWLAN_VERSIONSTR "5.2.0.109U" #endif /* QWLAN_VERSION_H */ From 11a56702a888d21af24931749b85c90c2c49f6c8 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 15:32:54 +0530 Subject: [PATCH 396/404] Move umac/p2p to components/p2p Change-Id: I8ca4c55470674422eca2dc80dd269cf45d4942ea --- {core => components/p2p/core}/src/wlan_p2p_main.c | 0 {core => components/p2p/core}/src/wlan_p2p_main.h | 0 {core => components/p2p/core}/src/wlan_p2p_off_chan_tx.c | 0 {core => components/p2p/core}/src/wlan_p2p_off_chan_tx.h | 0 {core => components/p2p/core}/src/wlan_p2p_roc.c | 0 {core => components/p2p/core}/src/wlan_p2p_roc.h | 0 {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_cfg.h | 0 {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_cfg_api.h | 0 .../p2p/dispatcher}/inc/wlan_p2p_public_struct.h | 0 {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_tgt_api.h | 0 {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_ucfg_api.h | 0 {dispatcher => components/p2p/dispatcher}/src/wlan_p2p_cfg.c | 0 {dispatcher => components/p2p/dispatcher}/src/wlan_p2p_tgt_api.c | 0 {dispatcher => components/p2p/dispatcher}/src/wlan_p2p_ucfg_api.c | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename {core => components/p2p/core}/src/wlan_p2p_main.c (100%) rename {core => components/p2p/core}/src/wlan_p2p_main.h (100%) rename {core => components/p2p/core}/src/wlan_p2p_off_chan_tx.c (100%) rename {core => components/p2p/core}/src/wlan_p2p_off_chan_tx.h (100%) rename {core => components/p2p/core}/src/wlan_p2p_roc.c (100%) rename {core => components/p2p/core}/src/wlan_p2p_roc.h (100%) rename {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_cfg.h (100%) rename {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_cfg_api.h (100%) rename {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_public_struct.h (100%) rename {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_tgt_api.h (100%) rename {dispatcher => components/p2p/dispatcher}/inc/wlan_p2p_ucfg_api.h (100%) rename {dispatcher => components/p2p/dispatcher}/src/wlan_p2p_cfg.c (100%) rename {dispatcher => components/p2p/dispatcher}/src/wlan_p2p_tgt_api.c (100%) rename {dispatcher => components/p2p/dispatcher}/src/wlan_p2p_ucfg_api.c (100%) diff --git a/core/src/wlan_p2p_main.c b/components/p2p/core/src/wlan_p2p_main.c similarity index 100% rename from core/src/wlan_p2p_main.c rename to components/p2p/core/src/wlan_p2p_main.c diff --git a/core/src/wlan_p2p_main.h b/components/p2p/core/src/wlan_p2p_main.h similarity index 100% rename from core/src/wlan_p2p_main.h rename to components/p2p/core/src/wlan_p2p_main.h diff --git a/core/src/wlan_p2p_off_chan_tx.c b/components/p2p/core/src/wlan_p2p_off_chan_tx.c similarity index 100% rename from core/src/wlan_p2p_off_chan_tx.c rename to components/p2p/core/src/wlan_p2p_off_chan_tx.c diff --git a/core/src/wlan_p2p_off_chan_tx.h b/components/p2p/core/src/wlan_p2p_off_chan_tx.h similarity index 100% rename from core/src/wlan_p2p_off_chan_tx.h rename to components/p2p/core/src/wlan_p2p_off_chan_tx.h diff --git a/core/src/wlan_p2p_roc.c b/components/p2p/core/src/wlan_p2p_roc.c similarity index 100% rename from core/src/wlan_p2p_roc.c rename to components/p2p/core/src/wlan_p2p_roc.c diff --git a/core/src/wlan_p2p_roc.h b/components/p2p/core/src/wlan_p2p_roc.h similarity index 100% rename from core/src/wlan_p2p_roc.h rename to components/p2p/core/src/wlan_p2p_roc.h diff --git a/dispatcher/inc/wlan_p2p_cfg.h b/components/p2p/dispatcher/inc/wlan_p2p_cfg.h similarity index 100% rename from dispatcher/inc/wlan_p2p_cfg.h rename to components/p2p/dispatcher/inc/wlan_p2p_cfg.h diff --git a/dispatcher/inc/wlan_p2p_cfg_api.h b/components/p2p/dispatcher/inc/wlan_p2p_cfg_api.h similarity index 100% rename from dispatcher/inc/wlan_p2p_cfg_api.h rename to components/p2p/dispatcher/inc/wlan_p2p_cfg_api.h diff --git a/dispatcher/inc/wlan_p2p_public_struct.h b/components/p2p/dispatcher/inc/wlan_p2p_public_struct.h similarity index 100% rename from dispatcher/inc/wlan_p2p_public_struct.h rename to components/p2p/dispatcher/inc/wlan_p2p_public_struct.h diff --git a/dispatcher/inc/wlan_p2p_tgt_api.h b/components/p2p/dispatcher/inc/wlan_p2p_tgt_api.h similarity index 100% rename from dispatcher/inc/wlan_p2p_tgt_api.h rename to components/p2p/dispatcher/inc/wlan_p2p_tgt_api.h diff --git a/dispatcher/inc/wlan_p2p_ucfg_api.h b/components/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h similarity index 100% rename from dispatcher/inc/wlan_p2p_ucfg_api.h rename to components/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h diff --git a/dispatcher/src/wlan_p2p_cfg.c b/components/p2p/dispatcher/src/wlan_p2p_cfg.c similarity index 100% rename from dispatcher/src/wlan_p2p_cfg.c rename to components/p2p/dispatcher/src/wlan_p2p_cfg.c diff --git a/dispatcher/src/wlan_p2p_tgt_api.c b/components/p2p/dispatcher/src/wlan_p2p_tgt_api.c similarity index 100% rename from dispatcher/src/wlan_p2p_tgt_api.c rename to components/p2p/dispatcher/src/wlan_p2p_tgt_api.c diff --git a/dispatcher/src/wlan_p2p_ucfg_api.c b/components/p2p/dispatcher/src/wlan_p2p_ucfg_api.c similarity index 100% rename from dispatcher/src/wlan_p2p_ucfg_api.c rename to components/p2p/dispatcher/src/wlan_p2p_ucfg_api.c From 7f1b42dbad527faf1d8851c115c0e3b66214da73 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 15:34:44 +0530 Subject: [PATCH 397/404] Move target_if/p2p to components/target_if/p2p Change-Id: I1ea8a2cc9f31223407fac0925b74e3c5a37bc6e5 --- {inc => components/target_if/p2p/inc}/target_if_p2p.h | 0 {src => components/target_if/p2p/src}/target_if_p2p.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {inc => components/target_if/p2p/inc}/target_if_p2p.h (100%) rename {src => components/target_if/p2p/src}/target_if_p2p.c (100%) diff --git a/inc/target_if_p2p.h b/components/target_if/p2p/inc/target_if_p2p.h similarity index 100% rename from inc/target_if_p2p.h rename to components/target_if/p2p/inc/target_if_p2p.h diff --git a/src/target_if_p2p.c b/components/target_if/p2p/src/target_if_p2p.c similarity index 100% rename from src/target_if_p2p.c rename to components/target_if/p2p/src/target_if_p2p.c From 22109fd1503fc59f44b7baf14b4582a025634be2 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 15:36:30 +0530 Subject: [PATCH 398/404] Move os_if/linux/p2p to components/os_if/linux/p2p Change-Id: I834f4ca6b8f5e56559a4de3f28c955d78deca7cb --- {inc => components/os_if/linux/p2p/inc}/wlan_cfg80211_p2p.h | 0 {src => components/os_if/linux/p2p/src}/wlan_cfg80211_p2p.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {inc => components/os_if/linux/p2p/inc}/wlan_cfg80211_p2p.h (100%) rename {src => components/os_if/linux/p2p/src}/wlan_cfg80211_p2p.c (100%) diff --git a/inc/wlan_cfg80211_p2p.h b/components/os_if/linux/p2p/inc/wlan_cfg80211_p2p.h similarity index 100% rename from inc/wlan_cfg80211_p2p.h rename to components/os_if/linux/p2p/inc/wlan_cfg80211_p2p.h diff --git a/src/wlan_cfg80211_p2p.c b/components/os_if/linux/p2p/src/wlan_cfg80211_p2p.c similarity index 100% rename from src/wlan_cfg80211_p2p.c rename to components/os_if/linux/p2p/src/wlan_cfg80211_p2p.c From 92728a078f8058ca2fa2366d99ee9d903a8381b5 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 15:47:36 +0530 Subject: [PATCH 399/404] Move umac/tdls to components/tdls Change-Id: I12eedee6215337be7f5dbcf6d546910cecedd3c3 --- {core => components/tdls/core}/src/wlan_tdls_cmds_process.c | 0 {core => components/tdls/core}/src/wlan_tdls_cmds_process.h | 0 {core => components/tdls/core}/src/wlan_tdls_ct.c | 0 {core => components/tdls/core}/src/wlan_tdls_ct.h | 0 {core => components/tdls/core}/src/wlan_tdls_main.c | 0 {core => components/tdls/core}/src/wlan_tdls_main.h | 0 {core => components/tdls/core}/src/wlan_tdls_mgmt.c | 0 {core => components/tdls/core}/src/wlan_tdls_mgmt.h | 0 {core => components/tdls/core}/src/wlan_tdls_peer.c | 0 {core => components/tdls/core}/src/wlan_tdls_peer.h | 0 {core => components/tdls/core}/src/wlan_tdls_txrx.c | 0 {core => components/tdls/core}/src/wlan_tdls_txrx.h | 0 {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_cfg.h | 0 .../tdls/dispatcher}/inc/wlan_tdls_cfg_api.h | 0 .../tdls/dispatcher}/inc/wlan_tdls_public_structs.h | 0 .../tdls/dispatcher}/inc/wlan_tdls_tgt_api.h | 0 .../tdls/dispatcher}/inc/wlan_tdls_ucfg_api.h | 0 {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_cfg.c | 0 .../tdls/dispatcher}/src/wlan_tdls_tgt_api.c | 0 .../tdls/dispatcher}/src/wlan_tdls_ucfg_api.c | 0 .../tdls/dispatcher}/src/wlan_tdls_utils_api.c | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename {core => components/tdls/core}/src/wlan_tdls_cmds_process.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_cmds_process.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_ct.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_ct.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_main.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_main.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_mgmt.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_mgmt.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_peer.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_peer.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_txrx.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_txrx.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_cfg.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_cfg_api.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_public_structs.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_tgt_api.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_ucfg_api.h (100%) rename {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_cfg.c (100%) rename {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_tgt_api.c (100%) rename {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_ucfg_api.c (100%) rename {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_utils_api.c (100%) diff --git a/core/src/wlan_tdls_cmds_process.c b/components/tdls/core/src/wlan_tdls_cmds_process.c similarity index 100% rename from core/src/wlan_tdls_cmds_process.c rename to components/tdls/core/src/wlan_tdls_cmds_process.c diff --git a/core/src/wlan_tdls_cmds_process.h b/components/tdls/core/src/wlan_tdls_cmds_process.h similarity index 100% rename from core/src/wlan_tdls_cmds_process.h rename to components/tdls/core/src/wlan_tdls_cmds_process.h diff --git a/core/src/wlan_tdls_ct.c b/components/tdls/core/src/wlan_tdls_ct.c similarity index 100% rename from core/src/wlan_tdls_ct.c rename to components/tdls/core/src/wlan_tdls_ct.c diff --git a/core/src/wlan_tdls_ct.h b/components/tdls/core/src/wlan_tdls_ct.h similarity index 100% rename from core/src/wlan_tdls_ct.h rename to components/tdls/core/src/wlan_tdls_ct.h diff --git a/core/src/wlan_tdls_main.c b/components/tdls/core/src/wlan_tdls_main.c similarity index 100% rename from core/src/wlan_tdls_main.c rename to components/tdls/core/src/wlan_tdls_main.c diff --git a/core/src/wlan_tdls_main.h b/components/tdls/core/src/wlan_tdls_main.h similarity index 100% rename from core/src/wlan_tdls_main.h rename to components/tdls/core/src/wlan_tdls_main.h diff --git a/core/src/wlan_tdls_mgmt.c b/components/tdls/core/src/wlan_tdls_mgmt.c similarity index 100% rename from core/src/wlan_tdls_mgmt.c rename to components/tdls/core/src/wlan_tdls_mgmt.c diff --git a/core/src/wlan_tdls_mgmt.h b/components/tdls/core/src/wlan_tdls_mgmt.h similarity index 100% rename from core/src/wlan_tdls_mgmt.h rename to components/tdls/core/src/wlan_tdls_mgmt.h diff --git a/core/src/wlan_tdls_peer.c b/components/tdls/core/src/wlan_tdls_peer.c similarity index 100% rename from core/src/wlan_tdls_peer.c rename to components/tdls/core/src/wlan_tdls_peer.c diff --git a/core/src/wlan_tdls_peer.h b/components/tdls/core/src/wlan_tdls_peer.h similarity index 100% rename from core/src/wlan_tdls_peer.h rename to components/tdls/core/src/wlan_tdls_peer.h diff --git a/core/src/wlan_tdls_txrx.c b/components/tdls/core/src/wlan_tdls_txrx.c similarity index 100% rename from core/src/wlan_tdls_txrx.c rename to components/tdls/core/src/wlan_tdls_txrx.c diff --git a/core/src/wlan_tdls_txrx.h b/components/tdls/core/src/wlan_tdls_txrx.h similarity index 100% rename from core/src/wlan_tdls_txrx.h rename to components/tdls/core/src/wlan_tdls_txrx.h diff --git a/dispatcher/inc/wlan_tdls_cfg.h b/components/tdls/dispatcher/inc/wlan_tdls_cfg.h similarity index 100% rename from dispatcher/inc/wlan_tdls_cfg.h rename to components/tdls/dispatcher/inc/wlan_tdls_cfg.h diff --git a/dispatcher/inc/wlan_tdls_cfg_api.h b/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h similarity index 100% rename from dispatcher/inc/wlan_tdls_cfg_api.h rename to components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h similarity index 100% rename from dispatcher/inc/wlan_tdls_public_structs.h rename to components/tdls/dispatcher/inc/wlan_tdls_public_structs.h diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/components/tdls/dispatcher/inc/wlan_tdls_tgt_api.h similarity index 100% rename from dispatcher/inc/wlan_tdls_tgt_api.h rename to components/tdls/dispatcher/inc/wlan_tdls_tgt_api.h diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/components/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h similarity index 100% rename from dispatcher/inc/wlan_tdls_ucfg_api.h rename to components/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h diff --git a/dispatcher/src/wlan_tdls_cfg.c b/components/tdls/dispatcher/src/wlan_tdls_cfg.c similarity index 100% rename from dispatcher/src/wlan_tdls_cfg.c rename to components/tdls/dispatcher/src/wlan_tdls_cfg.c diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/components/tdls/dispatcher/src/wlan_tdls_tgt_api.c similarity index 100% rename from dispatcher/src/wlan_tdls_tgt_api.c rename to components/tdls/dispatcher/src/wlan_tdls_tgt_api.c diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c similarity index 100% rename from dispatcher/src/wlan_tdls_ucfg_api.c rename to components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c diff --git a/dispatcher/src/wlan_tdls_utils_api.c b/components/tdls/dispatcher/src/wlan_tdls_utils_api.c similarity index 100% rename from dispatcher/src/wlan_tdls_utils_api.c rename to components/tdls/dispatcher/src/wlan_tdls_utils_api.c From d2bb8757a6df0f030414c0bab33cb90a58c8e089 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 15:49:52 +0530 Subject: [PATCH 400/404] Move target_if/tdls to components/target_if/tdls Change-Id: Ia72f8dddc21df49bab8ba63be38ce080d858c603 --- {inc => components/target_if/tdls/inc}/target_if_tdls.h | 0 {src => components/target_if/tdls/src}/target_if_tdls.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {inc => components/target_if/tdls/inc}/target_if_tdls.h (100%) rename {src => components/target_if/tdls/src}/target_if_tdls.c (100%) diff --git a/inc/target_if_tdls.h b/components/target_if/tdls/inc/target_if_tdls.h similarity index 100% rename from inc/target_if_tdls.h rename to components/target_if/tdls/inc/target_if_tdls.h diff --git a/src/target_if_tdls.c b/components/target_if/tdls/src/target_if_tdls.c similarity index 100% rename from src/target_if_tdls.c rename to components/target_if/tdls/src/target_if_tdls.c 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 401/404] 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 478b1fa7a87e646ad1bf8087753e42268bed50bd Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 15:59:42 +0530 Subject: [PATCH 402/404] Move umac/cmn_services/policy_mgr to components/cmn_services/policy_mgr Change-Id: Ie67730cd3f1a249c3dcbb2b6eaf95a55cbd08306 --- .../cmn_services/policy_mgr/inc}/wlan_policy_mgr_api.h | 0 .../cmn_services/policy_mgr/inc}/wlan_policy_mgr_cfg.h | 0 .../cmn_services/policy_mgr/inc}/wlan_policy_mgr_public_struct.h | 0 .../cmn_services/policy_mgr/inc}/wlan_policy_mgr_ucfg.h | 0 .../cmn_services/policy_mgr/src}/wlan_policy_mgr_action.c | 0 .../cmn_services/policy_mgr/src}/wlan_policy_mgr_core.c | 0 .../cmn_services/policy_mgr/src}/wlan_policy_mgr_get_set_utils.c | 0 .../cmn_services/policy_mgr/src}/wlan_policy_mgr_i.h | 0 .../cmn_services/policy_mgr/src}/wlan_policy_mgr_init_deinit.c | 0 .../cmn_services/policy_mgr/src}/wlan_policy_mgr_pcl.c | 0 .../policy_mgr/src}/wlan_policy_mgr_tables_1x1_dbs_i.h | 0 .../policy_mgr/src}/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h | 0 .../policy_mgr/src}/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h | 0 .../policy_mgr/src}/wlan_policy_mgr_tables_2x2_dbs_i.h | 0 .../policy_mgr/src}/wlan_policy_mgr_tables_no_dbs_i.h | 0 .../cmn_services/policy_mgr/src}/wlan_policy_mgr_ucfg.c | 0 16 files changed, 0 insertions(+), 0 deletions(-) rename {inc => components/cmn_services/policy_mgr/inc}/wlan_policy_mgr_api.h (100%) rename {inc => components/cmn_services/policy_mgr/inc}/wlan_policy_mgr_cfg.h (100%) rename {inc => components/cmn_services/policy_mgr/inc}/wlan_policy_mgr_public_struct.h (100%) rename {inc => components/cmn_services/policy_mgr/inc}/wlan_policy_mgr_ucfg.h (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_action.c (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_core.c (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_get_set_utils.c (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_i.h (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_init_deinit.c (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_pcl.c (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_tables_1x1_dbs_i.h (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_tables_2x2_dbs_i.h (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_tables_no_dbs_i.h (100%) rename {src => components/cmn_services/policy_mgr/src}/wlan_policy_mgr_ucfg.c (100%) diff --git a/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h similarity index 100% rename from inc/wlan_policy_mgr_api.h rename to components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h diff --git a/inc/wlan_policy_mgr_cfg.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h similarity index 100% rename from inc/wlan_policy_mgr_cfg.h rename to components/cmn_services/policy_mgr/inc/wlan_policy_mgr_cfg.h diff --git a/inc/wlan_policy_mgr_public_struct.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h similarity index 100% rename from inc/wlan_policy_mgr_public_struct.h rename to components/cmn_services/policy_mgr/inc/wlan_policy_mgr_public_struct.h diff --git a/inc/wlan_policy_mgr_ucfg.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h similarity index 100% rename from inc/wlan_policy_mgr_ucfg.h rename to components/cmn_services/policy_mgr/inc/wlan_policy_mgr_ucfg.h diff --git a/src/wlan_policy_mgr_action.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c similarity index 100% rename from src/wlan_policy_mgr_action.c rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c diff --git a/src/wlan_policy_mgr_core.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c similarity index 100% rename from src/wlan_policy_mgr_core.c rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_core.c diff --git a/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c similarity index 100% rename from src/wlan_policy_mgr_get_set_utils.c rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c diff --git a/src/wlan_policy_mgr_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h similarity index 100% rename from src/wlan_policy_mgr_i.h rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h diff --git a/src/wlan_policy_mgr_init_deinit.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c similarity index 100% rename from src/wlan_policy_mgr_init_deinit.c rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c diff --git a/src/wlan_policy_mgr_pcl.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c similarity index 100% rename from src/wlan_policy_mgr_pcl.c rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_pcl.c diff --git a/src/wlan_policy_mgr_tables_1x1_dbs_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h similarity index 100% rename from src/wlan_policy_mgr_tables_1x1_dbs_i.h rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_1x1_dbs_i.h diff --git a/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h similarity index 100% rename from src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_2g_1x1_5g.h diff --git a/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h similarity index 100% rename from src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_5g_1x1_2g.h diff --git a/src/wlan_policy_mgr_tables_2x2_dbs_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h similarity index 100% rename from src/wlan_policy_mgr_tables_2x2_dbs_i.h rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_2x2_dbs_i.h diff --git a/src/wlan_policy_mgr_tables_no_dbs_i.h b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_no_dbs_i.h similarity index 100% rename from src/wlan_policy_mgr_tables_no_dbs_i.h rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_tables_no_dbs_i.h diff --git a/src/wlan_policy_mgr_ucfg.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c similarity index 100% rename from src/wlan_policy_mgr_ucfg.c rename to components/cmn_services/policy_mgr/src/wlan_policy_mgr_ucfg.c From 09afffa36feb0bc3b474e514df981f9151c7afc6 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 16:04:42 +0530 Subject: [PATCH 403/404] Move to os_if/p2p Change-Id: I08c7707a4a1acc4caa1842acd21e2104ddbd084a --- {components/os_if/linux => os_if}/p2p/inc/wlan_cfg80211_p2p.h | 0 {components/os_if/linux => os_if}/p2p/src/wlan_cfg80211_p2p.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {components/os_if/linux => os_if}/p2p/inc/wlan_cfg80211_p2p.h (100%) rename {components/os_if/linux => os_if}/p2p/src/wlan_cfg80211_p2p.c (100%) diff --git a/components/os_if/linux/p2p/inc/wlan_cfg80211_p2p.h b/os_if/p2p/inc/wlan_cfg80211_p2p.h similarity index 100% rename from components/os_if/linux/p2p/inc/wlan_cfg80211_p2p.h rename to os_if/p2p/inc/wlan_cfg80211_p2p.h diff --git a/components/os_if/linux/p2p/src/wlan_cfg80211_p2p.c b/os_if/p2p/src/wlan_cfg80211_p2p.c similarity index 100% rename from components/os_if/linux/p2p/src/wlan_cfg80211_p2p.c rename to os_if/p2p/src/wlan_cfg80211_p2p.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 404/404] 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