From bb116f2d4f958683f2ce560737d8947b894b62c4 Mon Sep 17 00:00:00 2001 From: Yuanyuan Liu Date: Thu, 21 Apr 2016 09:32:30 -0700 Subject: qcacld-3.0: Fix compilation error for msmcobalt Fix compilation error for msmcobalt when enable CONFIG_WLAN_TX_FLOW_CONTROL_V2 feature. CRs-Fixed: 1006068 Change-Id: Iab1c632c00a65a2c972c7701d66f3adff3073221 --- core/dp/txrx/ol_tx_queue.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/dp/txrx/ol_tx_queue.c b/core/dp/txrx/ol_tx_queue.c index 17030f1772bb..5490bff84ee0 100644 --- a/core/dp/txrx/ol_tx_queue.c +++ b/core/dp/txrx/ol_tx_queue.c @@ -182,6 +182,7 @@ ol_txrx_map_to_netif_reason_type(uint32_t reason) } } +#ifndef CONFIG_ICNSS /** * ol_txrx_vdev_pause() - pause vdev network queues * @vdev: vdev handle @@ -233,6 +234,7 @@ void ol_txrx_vdev_unpause(ol_txrx_vdev_handle vdev, uint32_t reason) netif_reason); } +#endif /** * ol_txrx_pdev_pause() - pause network queues for each vdev -- cgit v1.2.3 From 0696eef313b507aacbd7b3864a52869013851e5f Mon Sep 17 00:00:00 2001 From: Mohit Khanna Date: Thu, 14 Apr 2016 16:14:08 -0700 Subject: qcacld-3.0: Fix RX data, peer unmap race condition During peer unmap handler, while the peer is being deleted, there is a possible race condition if the OL Rx thread is processing RX packets and accesses the peer structure after its contents have been nulled. Remove race condition by - * Flush all RX packets in ol_txrx_peer_detach function which happens before peer unmap event is received from firmware * Avoid use of peer data structures (for example peer->local_id) outside of peer->info_lock in ol_rx_data_cb function. Use cached local copies of peer data structures instead Crash signature due to the race condition: wlan: [0:E :CDF] TXRX: Deleting peer ffffffc012fd13c0 (02:a0:c6:81:f8:c0) Unable to handle kernel paging request at virtual address 400000001 pgd = ffffffc0018b4000 [400000001] *pgd=0000000000000000, *pud=0000000000000000 Internal error: Oops: 96000005 [#1] PREEMPT SMP Modules linked in: wlan(O) [last unloaded: wlan] CPU: 1 PID: 29506 Comm: cds_ol_rx_threa Tainted: G W O 3.18.20-g5222edf-13780-g2219ed2 #1 Hardware name: Qualcomm Technologies, Inc. MSM 8996 v3 + PMI8996 CD (DT) task: ffffffc09350d400 ti: ffffffc0556a4000 task.ti: ffffffc0556a4000 PC is at hdd_rx_packet_cbk+0x84/0x224 [wlan] LR is at hdd_rx_packet_cbk+0x48/0x224 [wlan] pc : [] lr : [] pstate: 80000145 Change-Id: I4b32313024ec214f33dcdcfc401aadfa8af9d692 CRs-Fixed: 1002081 --- core/cds/inc/cds_sched.h | 65 +++++++++++++++++++++++++++- core/dp/txrx/ol_txrx.c | 109 ++++++++++++++++++++++++++--------------------- 2 files changed, 125 insertions(+), 49 deletions(-) diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h index 7325b6155e26..46908e6701f6 100644 --- a/core/cds/inc/cds_sched.h +++ b/core/cds/inc/cds_sched.h @@ -296,7 +296,6 @@ typedef struct _cds_context_type { /*--------------------------------------------------------------------------- Function declarations and documenation ---------------------------------------------------------------------------*/ - #ifdef QCA_CONFIG_SMP /*--------------------------------------------------------------------------- \brief cds_drop_rxpkt_by_staid() - API to drop pending Rx packets for a sta @@ -357,6 +356,70 @@ void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext, \sa cds_free_ol_rx_pkt_freeq() -------------------------------------------------------------------------*/ void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext); +#else +/** + * cds_drop_rxpkt_by_staid() - api to drop pending rx packets for a sta + * @pSchedContext: Pointer to the global CDS Sched Context + * @staId: Station Id + * + * This api drops queued packets for a station, to drop all the pending + * packets the caller has to send WLAN_MAX_STA_COUNT as staId. + * + * Return: none + */ +static inline +void cds_drop_rxpkt_by_staid(p_cds_sched_context pSchedContext, uint16_t staId) +{ +} + +/** + * cds_indicate_rxpkt() - API to Indicate rx data packet + * @pSchedContext: pointer to CDS Sched Context + * @pkt: CDS OL RX pkt pointer containing to RX data message buffer + * + * Return: none + */ +static inline +void cds_indicate_rxpkt(p_cds_sched_context pSchedContext, + struct cds_ol_rx_pkt *pkt) +{ +} + +/** + * cds_alloc_ol_rx_pkt() - API to return next available cds message + * @pSchedContext: pointer to CDS Sched Context + * + * Return: none + */ +static inline +struct cds_ol_rx_pkt *cds_alloc_ol_rx_pkt(p_cds_sched_context pSchedContext) +{ +} + +/** + * cds_free_ol_rx_pkt() - API to release cds message to the freeq + * @pSchedContext: pointer to CDS Sched Context + * @pkt: CDS message buffer to be returned to free queue + * + * Return: none + */ +static inline +void cds_free_ol_rx_pkt(p_cds_sched_context pSchedContext, + struct cds_ol_rx_pkt *pkt) +{ +} + +/** + * cds_free_ol_rx_pkt_freeq() - Free cds buffer free queue + * @pSchedContext: pointer to CDS Sched Context + * @pkt: CDS message buffer to be returned to free queue + * + * Return: none + */ +static inline +void cds_free_ol_rx_pkt_freeq(p_cds_sched_context pSchedContext) +{ +} #endif /*--------------------------------------------------------------------------- diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index 2316b1e5cd4f..c2d85772e6df 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -2226,6 +2226,62 @@ void ol_txrx_peer_unref_delete(ol_txrx_peer_handle peer) } } +/** + * ol_txrx_clear_peer_internal() - ol internal function to clear peer + * @peer: pointer to ol txrx peer structure + * + * Return: QDF Status + */ +static QDF_STATUS +ol_txrx_clear_peer_internal(struct ol_txrx_peer_t *peer) +{ + p_cds_sched_context sched_ctx = get_cds_sched_ctxt(); + /* Drop pending Rx frames in CDS */ + if (sched_ctx) + cds_drop_rxpkt_by_staid(sched_ctx, peer->local_id); + + /* Purge the cached rx frame queue */ + ol_txrx_flush_rx_frames(peer, 1); + + qdf_spin_lock_bh(&peer->peer_info_lock); + peer->vdev->rx = NULL; + peer->state = OL_TXRX_PEER_STATE_DISC; + qdf_spin_unlock_bh(&peer->peer_info_lock); + + return QDF_STATUS_SUCCESS; +} + +/** + * ol_txrx_clear_peer() - clear peer + * @sta_id: sta id + * + * Return: QDF Status + */ +QDF_STATUS ol_txrx_clear_peer(uint8_t sta_id) +{ + struct ol_txrx_peer_t *peer; + struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); + + if (!pdev) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: Unable to find pdev!", + __func__); + return QDF_STATUS_E_FAILURE; + } + + if (sta_id >= WLAN_MAX_STA_COUNT) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Invalid sta id %d", sta_id); + return QDF_STATUS_E_INVAL; + } + + + peer = ol_txrx_peer_find_by_local_id(pdev, sta_id); + if (!peer) + return QDF_STATUS_E_FAULT; + + return ol_txrx_clear_peer_internal(peer); + +} + /** * ol_txrx_peer_detach - Delete a peer's data object. * @data_peer - the object to delete @@ -2245,6 +2301,8 @@ void ol_txrx_peer_detach(ol_txrx_peer_handle peer) peer->valid = 0; + /* flush all rx packets before clearing up the peer local_id */ + ol_txrx_clear_peer_internal(peer); ol_txrx_local_peer_id_free(peer->vdev->pdev, peer); /* debug print to dump rx reorder state */ @@ -2256,7 +2314,6 @@ void ol_txrx_peer_detach(ol_txrx_peer_handle peer) peer->mac_addr.raw[0], peer->mac_addr.raw[1], peer->mac_addr.raw[2], peer->mac_addr.raw[3], peer->mac_addr.raw[4], peer->mac_addr.raw[5]); - ol_txrx_flush_rx_frames(peer, 1); if (peer->vdev->last_real_peer == peer) peer->vdev->last_real_peer = NULL; @@ -3455,6 +3512,7 @@ static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev, qdf_nbuf_t buf_list, uint16_t staid) { void *cds_ctx = cds_get_global_context(); + void *osif_dev; qdf_nbuf_t buf, next_buf; QDF_STATUS ret; ol_txrx_rx_fp data_rx = NULL; @@ -3478,6 +3536,7 @@ static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev, } data_rx = peer->vdev->rx; + osif_dev = peer->vdev->osif_dev; qdf_spin_unlock_bh(&peer->peer_info_lock); qdf_spin_lock_bh(&peer->bufq_lock); @@ -3492,7 +3551,7 @@ static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev, while (buf) { next_buf = qdf_nbuf_queue_next(buf); qdf_nbuf_set_next(buf, NULL); /* Add NULL terminator */ - ret = data_rx(peer->vdev->osif_dev, buf); + ret = data_rx(osif_dev, buf); if (ret != QDF_STATUS_SUCCESS) { TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Frame Rx to HDD failed"); qdf_nbuf_free(buf); @@ -3660,52 +3719,6 @@ QDF_STATUS ol_txrx_register_peer(struct ol_txrx_desc_type *sta_desc) return QDF_STATUS_SUCCESS; } -/** - * ol_txrx_clear_peer() - clear peer - * @sta_id: sta id - * - * Return: QDF Status - */ -QDF_STATUS ol_txrx_clear_peer(uint8_t sta_id) -{ - struct ol_txrx_peer_t *peer; - struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - - if (!pdev) { - TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: Unable to find pdev!", - __func__); - return QDF_STATUS_E_FAILURE; - } - - if (sta_id >= WLAN_MAX_STA_COUNT) { - TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Invalid sta id %d", sta_id); - return QDF_STATUS_E_INVAL; - } - -#ifdef QCA_CONFIG_SMP - { - p_cds_sched_context sched_ctx = get_cds_sched_ctxt(); - /* Drop pending Rx frames in CDS */ - if (sched_ctx) - cds_drop_rxpkt_by_staid(sched_ctx, sta_id); - } -#endif - - peer = ol_txrx_peer_find_by_local_id(pdev, sta_id); - if (!peer) - return QDF_STATUS_E_FAULT; - - /* Purge the cached rx frame queue */ - ol_txrx_flush_rx_frames(peer, 1); - - qdf_spin_lock_bh(&peer->peer_info_lock); - peer->vdev->rx = NULL; - peer->state = OL_TXRX_PEER_STATE_DISC; - qdf_spin_unlock_bh(&peer->peer_info_lock); - - return QDF_STATUS_SUCCESS; -} - /** * ol_txrx_register_ocb_peer - Function to register the OCB peer * @cds_ctx: Pointer to the global OS context -- cgit v1.2.3 From 194ce08855b8eeedfb49bb61269e94f291cae692 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Fri, 15 Apr 2016 14:02:11 +0530 Subject: qcacld-3.0: Add HTT packet in misc_list to avoid memleak Add HTT packet buffer in misc_list for HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG command to avoid memleak. Change-Id: I1c3fb6232c4b7dab6c10459d53e611d3358b69cc CRs-Fixed: 1001996 --- core/dp/htt/htt_h2t.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/dp/htt/htt_h2t.c b/core/dp/htt/htt_h2t.c index a1c020279d4c..9662eb4d6980 100644 --- a/core/dp/htt/htt_h2t.c +++ b/core/dp/htt/htt_h2t.c @@ -178,6 +178,10 @@ A_STATUS htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev) SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg); rc = htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt); +#ifdef ATH_11AC_TXCOMPACT + if (rc == A_OK) + htt_htc_misc_pkt_list_add(pdev, pkt); +#endif return rc; } -- cgit v1.2.3 From 7a0a90597bd3da92253903317e61f743be626a5c Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Thu, 14 Apr 2016 16:52:21 +0530 Subject: qcacld-3.0: Free all TX descriptors in error scenario Forcefully free all TX descriptors during driver unload which is not freed because of unmap event missing from firmware to avoid memory leak. Change-Id: I47ff7e6a8f2aa130c77ac68a92eee9373d152e87 CRs-Fixed: 1001994 --- core/dp/ol/inc/ol_txrx_ctrl_api.h | 5 +++-- core/dp/txrx/ol_txrx.c | 2 +- core/dp/txrx/ol_txrx_flow_control.c | 34 +++++++++++++++++++++++++--------- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/core/dp/ol/inc/ol_txrx_ctrl_api.h b/core/dp/ol/inc/ol_txrx_ctrl_api.h index 203eb6983526..cb937ba6f75f 100644 --- a/core/dp/ol/inc/ol_txrx_ctrl_api.h +++ b/core/dp/ol/inc/ol_txrx_ctrl_api.h @@ -517,7 +517,7 @@ void ol_tx_flow_pool_unmap_handler(uint8_t flow_id, uint8_t flow_type, uint8_t flow_pool_id); struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id, uint16_t flow_pool_size); -int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool); +int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, bool force); #else static inline void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev) @@ -551,7 +551,8 @@ static inline struct ol_tx_flow_pool_t *ol_tx_create_flow_pool( { return NULL; } -static inline int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool) +static inline int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, + bool force) { return 0; } diff --git a/core/dp/txrx/ol_txrx.c b/core/dp/txrx/ol_txrx.c index c2d85772e6df..ad2dc54b6c48 100644 --- a/core/dp/txrx/ol_txrx.c +++ b/core/dp/txrx/ol_txrx.c @@ -1025,7 +1025,6 @@ void ol_txrx_pdev_detach(ol_txrx_pdev_handle pdev, int force) #endif #endif ol_tso_seg_list_deinit(pdev); - ol_tx_deregister_flow_control(pdev); if (force) { /* @@ -1045,6 +1044,7 @@ void ol_txrx_pdev_detach(ol_txrx_pdev_handle pdev, int force) ol_txrx_peer_find_hash_erase(pdev); } + ol_tx_deregister_flow_control(pdev); /* Stop the communication between HTT and target at first */ htt_detach_target(pdev->htt_pdev); diff --git a/core/dp/txrx/ol_txrx_flow_control.c b/core/dp/txrx/ol_txrx_flow_control.c index a0d4404cb0d4..920f825f1ef5 100644 --- a/core/dp/txrx/ol_txrx_flow_control.c +++ b/core/dp/txrx/ol_txrx_flow_control.c @@ -82,7 +82,7 @@ ol_tx_register_global_mgmt_pool(struct ol_txrx_pdev_t *pdev) static void ol_tx_deregister_global_mgmt_pool(struct ol_txrx_pdev_t *pdev) { - ol_tx_delete_flow_pool(pdev->mgmt_pool); + ol_tx_delete_flow_pool(pdev->mgmt_pool, false); return; } #else @@ -121,14 +121,27 @@ void ol_tx_register_flow_control(struct ol_txrx_pdev_t *pdev) */ void ol_tx_deregister_flow_control(struct ol_txrx_pdev_t *pdev) { + int i = 0; + struct ol_tx_flow_pool_t *pool = NULL; + if (!ol_tx_get_is_mgmt_over_wmi_enabled()) ol_tx_deregister_global_mgmt_pool(pdev); - qdf_spinlock_destroy(&pdev->tx_desc.flow_pool_list_lock); - if (!TAILQ_EMPTY(&pdev->tx_desc.flow_pool_list)) { + qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); + while (!TAILQ_EMPTY(&pdev->tx_desc.flow_pool_list)) { + pool = TAILQ_FIRST(&pdev->tx_desc.flow_pool_list); + if (!pool) + break; + qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock); TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, - "flow pool list is not empty!!!\n"); + "flow pool list is not empty %d!!!\n", i++); + if (i == 1) + ol_tx_dump_flow_pool_info(); + ol_tx_delete_flow_pool(pool, true); + qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock); } + qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock); + qdf_spinlock_destroy(&pdev->tx_desc.flow_pool_list_lock); } /** @@ -381,13 +394,16 @@ struct ol_tx_flow_pool_t *ol_tx_create_flow_pool(uint8_t flow_pool_id, /** * ol_tx_delete_flow_pool() - delete flow pool * @pool: flow pool pointer + * @force: free pool forcefully * * Delete flow_pool if all tx descriptors are available. * Otherwise put it in FLOW_POOL_INVALID state. + * If force is set then pull all available descriptors to + * global pool. * * Return: 0 for success or error */ -int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool) +int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, bool force) { struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); uint16_t i, size; @@ -405,7 +421,7 @@ int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool) qdf_spin_unlock_bh(&pdev->tx_desc.flow_pool_list_lock); qdf_spin_lock_bh(&pool->flow_pool_lock); - if (pool->avail_desc == pool->flow_pool_size) + if (pool->avail_desc == pool->flow_pool_size || force == true) pool->status = FLOW_POOL_INACTIVE; else pool->status = FLOW_POOL_INVALID; @@ -481,7 +497,7 @@ int ol_tx_free_invalid_flow_pool(struct ol_tx_flow_pool_t *pool) "%s: invalid pool deleted %d\n", __func__, pdev->tx_desc.num_invalid_bin); - return ol_tx_delete_flow_pool(pool); + return ol_tx_delete_flow_pool(pool, false); } /** @@ -624,7 +640,7 @@ void ol_tx_flow_pool_map_handler(uint8_t flow_id, uint8_t flow_type, break; default: if (pool_create) - ol_tx_delete_flow_pool(pool); + ol_tx_delete_flow_pool(pool, false); TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "%s: flow type %d not supported !!!\n", __func__, type); @@ -684,7 +700,7 @@ void ol_tx_flow_pool_unmap_handler(uint8_t flow_id, uint8_t flow_type, } /* only delete if all descriptors are available */ - ol_tx_delete_flow_pool(pool); + ol_tx_delete_flow_pool(pool, false); return; } -- cgit v1.2.3 From 7009f2539933e812f112b4144f1fa94f9657db85 Mon Sep 17 00:00:00 2001 From: Manishekar Chandrasekaran Date: Thu, 21 Apr 2016 19:14:15 +0530 Subject: qcacld-3.0: Replace WMI_SOC_SET_PCL_CMDID with WMI_PDEV_SET_PCL_CMDID Replace the obsolete WMI command WMI_SOC_SET_PCL_CMDID with WMI_PDEV_SET_PCL_CMDID. WMI_PDEV_SET_PCL_CMDID carries the weightage for all the channels (preferred and non-preferred) in the same order and length as that of the command WMI_SCAN_CHAN_LIST_CMDID. This is in contrast to the command WMI_SOC_SET_PCL_CMDID which carries only the preferred channel list. Change-Id: I040f4307491d3242d2e9409dbbe8005c4b307bf5 CRs-Fixed: 989502 --- core/cds/inc/cds_concurrency.h | 52 +++- core/cds/src/cds_concurrency.c | 302 ++++++++++++++++++---- core/hdd/src/wlan_hdd_cfg80211.c | 11 +- core/hdd/src/wlan_hdd_conc_ut.c | 16 +- core/hdd/src/wlan_hdd_wext.c | 4 +- core/mac/inc/sir_api.h | 23 ++ core/mac/src/include/sir_params.h | 2 +- core/mac/src/sys/legacy/src/utils/src/mac_trace.c | 2 +- core/sap/src/sap_fsm.c | 3 +- core/sme/inc/sme_api.h | 2 +- core/sme/src/common/sme_api.c | 14 +- core/sme/src/csr/csr_api_scan.c | 4 +- core/wma/inc/wma.h | 17 +- core/wma/src/wma_main.c | 38 ++- core/wma/src/wma_scan_roam.c | 6 +- 15 files changed, 411 insertions(+), 85 deletions(-) diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index 14a5f860d63e..45e37f8b0f94 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/core/cds/inc/cds_concurrency.h @@ -47,6 +47,51 @@ #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 cds_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_NON_PCL_CHANNELS 1 + +/** + * enum cds_pcl_group_id - Identifies the pcl groups to be used + * @CDS_PCL_GROUP_ID1_ID2: Use weights of group1 and group2 + * @CDS_PCL_GROUP_ID2_ID2: Use weights of group2 and group3 + * + * Since maximum of three groups are possible, this will indicate which + * PCL group needs to be used. + */ +enum cds_pcl_group_id { + CDS_PCL_GROUP_ID1_ID2, + CDS_PCL_GROUP_ID2_ID3, +}; + +/** + * cds_pcl_channel_order - Order in which the PCL is requested + * @CDS_PCL_ORDER_NONE: no order + * @CDS_PCL_ORDER_24G_THEN_5G: 2.4 Ghz channel followed by 5 Ghz channel + * @CDS_PCL_ORDER_5G_THEN_2G: 5 Ghz channel followed by 2.4 Ghz channel + * + * Order in which the PCL is requested + */ +enum cds_pcl_channel_order { + CDS_PCL_ORDER_NONE, + CDS_PCL_ORDER_24G_THEN_5G, + CDS_PCL_ORDER_5G_THEN_2G, +}; /** * enum cds_max_rx_ss - Maximum number of receive spatial streams @@ -588,7 +633,8 @@ void cds_decr_session_set_pcl(enum tQDF_ADAPTER_MODE mode, QDF_STATUS cds_init_policy_mgr(void); QDF_STATUS cds_deinit_policy_mgr(void); QDF_STATUS cds_get_pcl(enum cds_con_mode mode, - uint8_t *pcl_Channels, uint32_t *len); + uint8_t *pcl_channels, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len); uint8_t cds_get_nondfs_preferred_channel(enum cds_con_mode mode, bool for_existing_conn); bool cds_is_any_nondfs_chnl_present(uint8_t *channel); @@ -697,5 +743,7 @@ QDF_STATUS cds_register_sap_restart_channel_switch_cb( void (*sap_restart_chan_switch_cb)(void *, uint32_t, uint32_t)); #endif QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode, - uint8_t *pcl_ch, uint32_t *len); + uint8_t *pcl_ch, uint32_t *len, + uint8_t *weight_list, uint32_t weight_len); +QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight); #endif /* __CDS_CONCURRENCY_H */ diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 2e8d9002b8ed..f211ace0dfc5 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -3438,16 +3438,16 @@ void cds_clear_concurrency_mode(enum tQDF_ADAPTER_MODE mode) } /** - * cds_soc_set_pcl() - Sets PCL to FW + * cds_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_SOC_SET_PCL_CMDID to the fw + * command WMI_PDEV_SET_PCL_CMDID to the fw * * Return: None */ -static void cds_soc_set_pcl(enum tQDF_ADAPTER_MODE mode) +static void cds_pdev_set_pcl(enum tQDF_ADAPTER_MODE mode) { QDF_STATUS status; enum cds_con_mode con_mode; @@ -3485,13 +3485,14 @@ static void cds_soc_set_pcl(enum tQDF_ADAPTER_MODE mode) cds_debug("get pcl to set it to the FW"); status = cds_get_pcl(con_mode, - pcl.pcl_list, &pcl.pcl_len); + pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); if (status != QDF_STATUS_SUCCESS) { cds_err("Unable to set PCL to FW, Get PCL failed"); return; } - status = sme_soc_set_pcl(hdd_ctx->hHal, pcl); + status = sme_pdev_set_pcl(hdd_ctx->hHal, pcl); if (status != QDF_STATUS_SUCCESS) cds_err("Send soc set PCL to SME failed"); else @@ -3552,7 +3553,7 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode, */ if (mode == QDF_STA_MODE) { /* Set PCL of STA to the FW */ - cds_soc_set_pcl(mode); + cds_pdev_set_pcl(mode); cds_info("Set PCL of STA to FW"); } cds_incr_connection_count(session_id); @@ -3671,7 +3672,7 @@ static void cds_set_pcl_for_existing_combo(enum cds_con_mode mode) /* Check, store and temp delete the mode's parameter */ cds_store_and_del_conn_info(mode, &info); /* Set the PCL to the FW since connection got updated */ - cds_soc_set_pcl(pcl_mode); + cds_pdev_set_pcl(pcl_mode); cds_info("Set PCL to FW for mode:%d", mode); /* Restore the connection info */ cds_restore_deleted_conn_info(&info); @@ -3681,13 +3682,18 @@ static void cds_set_pcl_for_existing_combo(enum cds_con_mode mode) /** * cds_get_pcl_for_existing_conn() - Get PCL for existing connection * @mode: Connection mode of type 'cds_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 cds_get_pcl_for_existing_conn(enum cds_con_mode mode, - uint8_t *pcl_ch, uint32_t *len) + uint8_t *pcl_ch, uint32_t *len, + uint8_t *pcl_weight, uint32_t weight_len) { struct cds_conc_connection_info info; @@ -3703,7 +3709,7 @@ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode, /* Check, store and temp delete the mode's parameter */ cds_store_and_del_conn_info(mode, &info); /* Set the PCL to the FW since connection got updated */ - status = cds_get_pcl(mode, pcl_ch, len); + status = cds_get_pcl(mode, pcl_ch, len, pcl_weight, weight_len); cds_info("Get PCL to FW for mode:%d", mode); /* Restore the connection info */ cds_restore_deleted_conn_info(&info); @@ -4289,6 +4295,10 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id) * @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 @@ -4297,11 +4307,14 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id) * Return: QDF_STATUS */ QDF_STATUS cds_get_connection_channels(uint8_t *channels, - uint32_t *len, uint8_t order, - bool skip_dfs_channel) + uint32_t *len, enum cds_pcl_channel_order order, + bool skip_dfs_channel, + uint8_t *pcl_weight, uint32_t weight_len, + uint32_t *index, enum cds_pcl_group_id group_id) { QDF_STATUS status = QDF_STATUS_SUCCESS; uint32_t conn_index = 0, num_channels = 0; + uint32_t weight1, weight2; if ((NULL == channels) || (NULL == len)) { cds_err("channels or len is NULL"); @@ -4309,58 +4322,99 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, return status; } - if (0 == order) { + /* CDS_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 CDS_PCL_GROUP_ID2_ID3 indicates that + * 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 CDS_PCL_ORDER_24G_THEN_5G and group id is + * CDS_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 == CDS_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; + } + + if (CDS_PCL_ORDER_NONE == order) { while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && CDS_IS_DFS_CH( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { conn_index++; - else + } else { channels[num_channels++] = conc_connection_list[conn_index++].chan; + if (*index < weight_len) + pcl_weight[(*index)++] = weight1; + } } *len = num_channels; - } else if (1 == order) { + } else if (CDS_PCL_ORDER_24G_THEN_5G == order) { while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (CDS_IS_CHANNEL_24GHZ( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { channels[num_channels++] = conc_connection_list[conn_index++].chan; - else + if (*index < weight_len) + pcl_weight[(*index)++] = weight1; + } else { conn_index++; + } } conn_index = 0; while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && CDS_IS_DFS_CH( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { conn_index++; - else if (CDS_IS_CHANNEL_5GHZ( - conc_connection_list[conn_index].chan)) + } else if (CDS_IS_CHANNEL_5GHZ( + conc_connection_list[conn_index].chan)) { channels[num_channels++] = conc_connection_list[conn_index++].chan; - else + if (*index < weight_len) + pcl_weight[(*index)++] = weight2; + } else { conn_index++; + } } *len = num_channels; - } else if (2 == order) { + } else if (CDS_PCL_ORDER_5G_THEN_2G == order) { while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (skip_dfs_channel && CDS_IS_DFS_CH( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { conn_index++; - else if (CDS_IS_CHANNEL_5GHZ( - conc_connection_list[conn_index].chan)) + } else if (CDS_IS_CHANNEL_5GHZ( + conc_connection_list[conn_index].chan)) { channels[num_channels++] = conc_connection_list[conn_index++].chan; - else + if (*index < weight_len) + pcl_weight[(*index)++] = weight1; + } else { conn_index++; + } } conn_index = 0; while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) { if (CDS_IS_CHANNEL_24GHZ( - conc_connection_list[conn_index].chan)) + conc_connection_list[conn_index].chan)) { channels[num_channels++] = conc_connection_list[conn_index++].chan; - else + if (*index < weight_len) + pcl_weight[(*index)++] = weight2; + + } else { conn_index++; + } } *len = num_channels; } else { @@ -4376,6 +4430,8 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, * 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 @@ -4383,10 +4439,12 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels, * Return: None */ #ifdef CONFIG_CNSS -void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) +void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len, + uint8_t *weight_list, uint32_t weight_len) { uint16_t unsafe_channel_list[MAX_NUM_CHAN]; uint8_t current_channel_list[MAX_NUM_CHAN]; + uint8_t org_weight_list[MAX_NUM_CHAN]; uint16_t unsafe_channel_count = 0; uint8_t is_unsafe = 1; uint8_t i, j; @@ -4409,6 +4467,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) qdf_mem_zero(pcl_channels, sizeof(*pcl_channels)*current_channel_count); + qdf_mem_copy(org_weight_list, weight_list, 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 < unsafe_channel_count; j++) { @@ -4424,6 +4485,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) 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]; } } *len = safe_channel_count; @@ -4431,7 +4495,8 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) return; } #else -void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) +void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len, + uint8_t *weight_list, uint32_t weight_len) { return; } @@ -4439,11 +4504,12 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) /** * cds_get_channel_list() - provides the channel list * suggestion for new connection - * @hdd_ctx: HDD Context * @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 @@ -4452,7 +4518,9 @@ void cds_update_with_safe_channel_list(uint8_t *pcl_channels, uint32_t *len) * Return: Channel List */ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, - uint8_t *pcl_channels, uint32_t *len, enum cds_con_mode mode) + uint8_t *pcl_channels, uint32_t *len, + enum cds_con_mode mode, + uint8_t *pcl_weights, uint32_t weight_len) { QDF_STATUS status = QDF_STATUS_E_FAILURE; uint32_t num_channels = WNI_CFG_VALID_CHANNEL_LIST_LEN; @@ -4462,6 +4530,7 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, uint8_t channel_list_5[MAX_NUM_CHAN] = {0}; bool skip_dfs_channel = false; hdd_context_t *hdd_ctx; + uint32_t i = 0, j = 0; hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); if (!hdd_ctx) { @@ -4529,23 +4598,61 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, } num_channels = 0; + /* In the below switch case, the channel list is populated based on the + * pcl. e.g., if the pcl is CDS_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 CDS_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 + * cds_get_connection_channels(), the order of weights to be used is + * passed as an argument to the function cds_get_connection_channels() + * using 'enum cds_pcl_group_id' which indicates the next available + * weights to be used and cds_get_connection_channels() will take care + * of the weight assignments. + * + * e.g., 'enum cds_pcl_group_id' value of CDS_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 CDS_PCL_ORDER_24G_THEN_5G, + * cds_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 CDS_24G: qdf_mem_copy(pcl_channels, channel_list_24, chan_index_24); *len = chan_index_24; + for (i = 0; ((i < *len) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_5G: 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; case CDS_SCC_CH: case CDS_MCC_CH: cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; status = QDF_STATUS_SUCCESS; @@ -4553,24 +4660,33 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, case CDS_SCC_CH_24G: case CDS_MCC_CH_24G: cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *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 < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; + status = QDF_STATUS_SUCCESS; break; case CDS_SCC_CH_5G: case CDS_MCC_CH_5G: cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *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 < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP2_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_24G_SCC_CH: @@ -4578,8 +4694,12 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, 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; cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID2_ID3); qdf_mem_copy(&pcl_channels[chan_index_24], channel_list, num_channels); *len += num_channels; @@ -4590,8 +4710,12 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, qdf_mem_copy(pcl_channels, channel_list_5, chan_index_5); *len = chan_index_5; + for (i = 0; ((i < chan_index_5) && (i < weight_len)); i++) + pcl_weights[i] = WEIGHT_OF_GROUP1_PCL_CHANNELS; cds_get_connection_channels( - channel_list, &num_channels, 0, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_NONE, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID2_ID3); qdf_mem_copy(&pcl_channels[chan_index_5], channel_list, num_channels); *len += num_channels; @@ -4599,7 +4723,9 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, break; case CDS_SCC_ON_24_SCC_ON_5: cds_get_connection_channels( - channel_list, &num_channels, 1, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; @@ -4607,49 +4733,67 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, break; case CDS_SCC_ON_5_SCC_ON_24: cds_get_connection_channels( - channel_list, &num_channels, 2, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *len = num_channels; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_ON_24_SCC_ON_5_24G: cds_get_connection_channels( - channel_list, &num_channels, 1, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *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 < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_ON_24_SCC_ON_5_5G: cds_get_connection_channels( - channel_list, &num_channels, 1, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_24G_THEN_5G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *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 < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_ON_5_SCC_ON_24_24G: cds_get_connection_channels( - channel_list, &num_channels, 2, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *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 < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; case CDS_SCC_ON_5_SCC_ON_24_5G: cds_get_connection_channels( - channel_list, &num_channels, 2, skip_dfs_channel); + channel_list, &num_channels, CDS_PCL_ORDER_5G_THEN_2G, + skip_dfs_channel, pcl_weights, weight_len, &i, + CDS_PCL_GROUP_ID1_ID2); qdf_mem_copy(pcl_channels, channel_list, num_channels); *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 < weight_len)); i++, j++) + pcl_weights[i] = WEIGHT_OF_GROUP3_PCL_CHANNELS; status = QDF_STATUS_SUCCESS; break; default: @@ -4657,8 +4801,13 @@ QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, break; } + if ((*len != 0) && (*len != i)) + cds_info("pcl len (%d) and weight list len mismatch (%d)", + *len, i); + /* check the channel avoidance list */ - cds_update_with_safe_channel_list(pcl_channels, len); + cds_update_with_safe_channel_list(pcl_channels, len, + pcl_weights, weight_len); return status; } @@ -4708,6 +4857,8 @@ bool cds_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, * @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 @@ -4717,7 +4868,8 @@ bool cds_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode, * Return: QDF_STATUS */ QDF_STATUS cds_get_pcl(enum cds_con_mode mode, - uint8_t *pcl_channels, uint32_t *len) + 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; @@ -4805,12 +4957,14 @@ QDF_STATUS cds_get_pcl(enum cds_con_mode mode, /* once the PCL enum is obtained find out the exact channel list with * help from sme_get_cfg_valid_channels */ - status = cds_get_channel_list(pcl, pcl_channels, len, mode); + status = cds_get_channel_list(pcl, pcl_channels, len, mode, + pcl_weight, weight_len); if (status == QDF_STATUS_SUCCESS) { uint32_t i; cds_debug("pcl len:%d", *len); for (i = 0; i < *len; i++) - cds_debug("chan:%d", pcl_channels[i]); + cds_debug("chan:%d weight:%d", + pcl_channels[i], pcl_weight[i]); } return status; @@ -8217,6 +8371,8 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode, bool for_existing_conn) { uint8_t pcl_channels[NUM_CHANNELS]; + uint8_t pcl_weight[NUM_CHANNELS]; + /* * in worst case if we can't find any channel at all * then return 2.4G channel, so atleast we won't fall @@ -8235,11 +8391,13 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode, return channel; if (QDF_STATUS_SUCCESS != cds_get_pcl_for_existing_conn(mode, - &pcl_channels[0], &pcl_len)) + &pcl_channels[0], &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) return channel; } else { if (QDF_STATUS_SUCCESS != cds_get_pcl(mode, - &pcl_channels[0], &pcl_len)) + &pcl_channels[0], &pcl_len, + pcl_weight, QDF_ARRAY_SIZE(pcl_weight))) return channel; } @@ -8263,6 +8421,8 @@ cds_get_nondfs_preferred_channel(enum cds_con_mode mode, } return channel; } + + /** * cds_is_any_nondfs_chnl_present() - Find any non-dfs channel from conc table * @channel: pointer to channel which needs to be filled @@ -8296,3 +8456,47 @@ bool cds_is_any_nondfs_chnl_present(uint8_t *channel) return status; } +/** + * cds_get_valid_chan_weights() - Get the weightage for all valid channels + * @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 cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight) +{ + uint32_t i, j; + + if (!weight->pcl_list) { + cds_err("Invalid pcl"); + return QDF_STATUS_E_FAILURE; + } + + if (!weight->saved_chan_list) { + cds_err("Invalid valid channel list"); + return QDF_STATUS_E_FAILURE; + } + + if (!weight->weighed_valid_list) { + cds_err("Invalid weighed valid channel list"); + return QDF_STATUS_E_FAILURE; + } + + for (i = 0; i < weight->saved_num_chan; i++) { + weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS; + 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; +} diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 7db20291e808..c8af93844f02 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -1396,6 +1396,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1]; bool ht_enabled, ht40_enabled, vht_enabled; uint8_t ch_width; + uint8_t weight_list[MAX_NUM_CHAN]; /* ***Note*** Donot set SME config related to ACS operation here because * ACS operation is not synchronouse and ACS for Second AP may come when @@ -1532,8 +1533,9 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy, /* consult policy manager to get PCL */ status = cds_get_pcl(CDS_SAP_MODE, - sap_config->acs_cfg.pcl_channels, - &sap_config->acs_cfg.pcl_ch_count); + sap_config->acs_cfg.pcl_channels, + &sap_config->acs_cfg.pcl_ch_count, + weight_list, QDF_ARRAY_SIZE(weight_list)); if (QDF_STATUS_SUCCESS != status) hddLog(LOGE, FL("Get PCL failed")); @@ -4215,7 +4217,7 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy, hdd_context_t *hdd_ctx = wiphy_priv(wiphy); int i, ret = 0; QDF_STATUS status; - uint8_t pcl[MAX_NUM_CHAN]; + uint8_t pcl[MAX_NUM_CHAN], weight_list[MAX_NUM_CHAN]; uint32_t pcl_len = 0; uint32_t freq_list[MAX_NUM_CHAN]; enum cds_con_mode intf_mode; @@ -4249,7 +4251,8 @@ static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy, hdd_debug("Userspace requested pref freq list"); - status = cds_get_pcl(intf_mode, pcl, &pcl_len); + status = cds_get_pcl(intf_mode, pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); if (status != QDF_STATUS_SUCCESS) { hdd_err("Get pcl failed"); return -EINVAL; diff --git a/core/hdd/src/wlan_hdd_conc_ut.c b/core/hdd/src/wlan_hdd_conc_ut.c index 8b7882e3990d..d42391602485 100644 --- a/core/hdd/src/wlan_hdd_conc_ut.c +++ b/core/hdd/src/wlan_hdd_conc_ut.c @@ -625,7 +625,7 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx) enum cds_con_mode sub_type; enum cds_conc_priority_mode system_pref = hdd_ctx->config->conc_system_pref; - uint8_t pcl[MAX_NUM_CHAN] = {0}; + uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0; bool status = false; enum cds_pcl_type pcl_type; @@ -651,7 +651,8 @@ void wlan_hdd_one_connection_scenario(hdd_context_t *hdd_ctx) pcl_type = get_pcl_from_first_conn_table(sub_type, system_pref); /* check PCL value for second connection is correct or no */ - cds_get_pcl(sub_type, pcl, &pcl_len); + cds_get_pcl(sub_type, pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, 0, 0, reason, sizeof(reason)); @@ -671,7 +672,7 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx, { uint8_t vdevid = 0, tx_stream = 2, rx_stream = 2; uint8_t type = WMI_VDEV_TYPE_STA, channel_id = first_chnl, mac_id = 1; - uint8_t pcl[MAX_NUM_CHAN] = {0}; + uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0; enum cds_chain_mode chain_mask = first_chain_mask; enum cds_con_mode sub_type, next_sub_type, dummy_type; @@ -723,7 +724,8 @@ void wlan_hdd_two_connections_scenario(hdd_context_t *hdd_ctx, next_sub_type, system_pref, wma_is_hw_dbs_capable()); /* check PCL for second connection is correct or no */ - cds_get_pcl(next_sub_type, pcl, &pcl_len); + cds_get_pcl(next_sub_type, pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, channel_id, 0, reason, sizeof(reason)); @@ -749,7 +751,7 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx, uint8_t channel_id_1 = first_chnl, channel_id_2 = second_chnl; uint8_t mac_id_1, mac_id_2; uint8_t type_1 = WMI_VDEV_TYPE_STA, type_2 = WMI_VDEV_TYPE_STA; - uint8_t pcl[MAX_NUM_CHAN] = {0}; + uint8_t pcl[MAX_NUM_CHAN] = {0}, weight_list[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0; enum cds_chain_mode chain_mask_1; enum cds_chain_mode chain_mask_2; @@ -838,7 +840,9 @@ void wlan_hdd_three_connections_scenario(hdd_context_t *hdd_ctx, system_pref, wma_is_hw_dbs_capable()); cds_get_pcl(next_sub_type, - pcl, &pcl_len); + pcl, &pcl_len, + weight_list, + QDF_ARRAY_SIZE(weight_list)); status = wlan_hdd_validate_pcl(hdd_ctx, pcl_type, pcl, pcl_len, channel_id_1, channel_id_2, diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c index 124d601a2cdb..f8f4137c4e6c 100644 --- a/core/hdd/src/wlan_hdd_wext.c +++ b/core/hdd/src/wlan_hdd_wext.c @@ -7927,13 +7927,15 @@ static int __iw_set_var_ints_getnone(struct net_device *dev, case WE_POLICY_MANAGER_PCL_CMD: { uint8_t pcl[MAX_NUM_CHAN] = {0}; + uint8_t weight_list[MAX_NUM_CHAN] = {0}; uint32_t pcl_len = 0, i = 0; hddLog(LOGE, FL(" is called\n")); cds_get_pcl(apps_args[0], - pcl, &pcl_len); + pcl, &pcl_len, + weight_list, QDF_ARRAY_SIZE(weight_list)); pr_info("PCL list for role[%d] is {", apps_args[0]); for (i = 0 ; i < pcl_len; i++) pr_info(" %d, ", pcl[i]); diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index cf0870c5f891..5c5ff30e87f9 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -3205,13 +3205,36 @@ enum set_hw_mode_status { /** * struct sir_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 sir_pcl_list { uint8_t pcl_list[128]; + uint8_t weight_list[128]; uint32_t pcl_len; }; +/** + * struct sir_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 sir_pcl_chan_weights { + uint8_t pcl_list[128]; + uint32_t pcl_len; + uint8_t saved_chan_list[128]; + uint32_t saved_num_chan; + uint8_t weighed_valid_list[128]; + uint8_t weight_list[128]; +}; + /** * struct sir_hw_mode_params - HW mode params * @mac0_tx_ss: MAC0 Tx spatial stream diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index b1e08297c0ed..6287638b2b8f 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -421,7 +421,7 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_FLUSH_LOG_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 160) -#define SIR_HAL_SOC_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) +#define SIR_HAL_PDEV_SET_PCL_TO_FW (SIR_HAL_ITC_MSG_TYPES_BEGIN + 161) /* 162 unused */ diff --git a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c index 75b4b5a06be0..db836f05c46f 100644 --- a/core/mac/src/sys/legacy/src/utils/src/mac_trace.c +++ b/core/mac/src/sys/legacy/src/utils/src/mac_trace.c @@ -526,7 +526,7 @@ uint8_t *mac_trace_get_wma_msg_string(uint16_t wma_msg) CASE_RETURN_STRING(SIR_HAL_CONFIG_GUARD_TIME); CASE_RETURN_STRING(SIR_HAL_START_STOP_LOGGING); CASE_RETURN_STRING(SIR_HAL_FLUSH_LOG_TO_FW); - CASE_RETURN_STRING(SIR_HAL_SOC_SET_PCL_TO_FW); + CASE_RETURN_STRING(SIR_HAL_PDEV_SET_PCL_TO_FW); CASE_RETURN_STRING(SIR_HAL_SOC_SET_HW_MODE); CASE_RETURN_STRING(SIR_HAL_SOC_DUAL_MAC_CFG_REQ); CASE_RETURN_STRING(WMA_RADAR_DETECTED_IND); diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index fbb94a8b3394..9be884d40020 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -4488,7 +4488,8 @@ static QDF_STATUS sap_get_5ghz_channel_list(ptSapContext sapContext) } status = cds_get_pcl_for_existing_conn(CDS_SAP_MODE, - pcl.pcl_list, &pcl.pcl_len); + pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); if (status != QDF_STATUS_SUCCESS) { cds_err("Get PCL failed"); return status; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index a41f85b5a9bf..d836a36a0389 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -986,7 +986,7 @@ QDF_STATUS sme_update_nss(tHalHandle h_hal, uint8_t nss); bool sme_is_any_session_in_connected_state(tHalHandle h_hal); -QDF_STATUS sme_soc_set_pcl(tHalHandle hal, +QDF_STATUS sme_pdev_set_pcl(tHalHandle hal, struct sir_pcl_list msg); QDF_STATUS sme_soc_set_hw_mode(tHalHandle hal, struct sir_hw_mode msg); diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 52439872e079..c12aef820c50 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -14797,20 +14797,20 @@ QDF_STATUS sme_fw_mem_dump(tHalHandle hHal, void *recvd_req) #endif /* WLAN_FEATURE_MEMDUMP */ /* - * sme_soc_set_pcl() - Send WMI_SOC_SET_PCL_CMDID to the WMA + * sme_pdev_set_pcl() - Send WMI_PDEV_SET_PCL_CMDID to the WMA * @hal: Handle returned by macOpen * @msg: PCL channel list and length structure * - * Sends the command to WMA to send WMI_SOC_SET_PCL_CMDID to FW + * Sends the command to WMA to send WMI_PDEV_SET_PCL_CMDID to FW * Return: QDF_STATUS_SUCCESS on successful posting */ -QDF_STATUS sme_soc_set_pcl(tHalHandle hal, +QDF_STATUS sme_pdev_set_pcl(tHalHandle hal, struct sir_pcl_list msg) { QDF_STATUS status = QDF_STATUS_SUCCESS; tpAniSirGlobal mac = PMAC_STRUCT(hal); cds_msg_t cds_message; - struct sir_pcl_list *req_msg; + struct wmi_pcl_chan_weights *req_msg; uint32_t len, i; len = sizeof(*req_msg); @@ -14823,8 +14823,10 @@ QDF_STATUS sme_soc_set_pcl(tHalHandle hal, qdf_mem_zero(req_msg, len); - for (i = 0; i < msg.pcl_len; i++) + for (i = 0; i < msg.pcl_len; i++) { req_msg->pcl_list[i] = msg.pcl_list[i]; + req_msg->weight_list[i] = msg.weight_list[i]; + } req_msg->pcl_len = msg.pcl_len; @@ -14839,7 +14841,7 @@ QDF_STATUS sme_soc_set_pcl(tHalHandle hal, /* Serialize the req through MC thread */ cds_message.bodyptr = req_msg; - cds_message.type = SIR_HAL_SOC_SET_PCL_TO_FW; + cds_message.type = SIR_HAL_PDEV_SET_PCL_TO_FW; status = cds_mq_post_message(CDS_MQ_ID_WMA, &cds_message); if (!QDF_IS_STATUS_SUCCESS(status)) { sms_log(mac, LOGE, diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index a7cd0987b30c..87ceec5baa58 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -1991,6 +1991,7 @@ csr_parse_scan_results(tpAniSirGlobal pMac, eCsrAuthType auth = eCSR_AUTH_TYPE_OPEN_SYSTEM; uint32_t len = 0; enum cds_con_mode new_mode; + uint8_t weight_list[MAX_NUM_CHAN]; csr_ll_lock(&pMac->scan.scanResultList); @@ -1999,7 +2000,8 @@ csr_parse_scan_results(tpAniSirGlobal pMac, if (cds_map_concurrency_mode( &pFilter->csrPersona, &new_mode)) { status = cds_get_pcl(new_mode, - &pFilter->pcl_channels.channelList[0], &len); + &pFilter->pcl_channels.channelList[0], &len, + weight_list, QDF_ARRAY_SIZE(weight_list)); pFilter->pcl_channels.numChannels = (uint8_t)len; } } diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index e9553ffe94f6..ff9dca2f5a70 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1041,6 +1041,17 @@ struct wma_ini_config { uint8_t max_no_of_peers; }; +/** + * struct wmi_valid_channels - Channel details part of WMI_SCAN_CHAN_LIST_CMDID + * @num_channels: Number of channels + * @channel_list: Channel list + */ +struct wma_valid_channels { + uint8_t num_channels; + uint8_t channel_list[MAX_NUM_CHAN]; +}; + + /** * struct t_wma_handle - wma context * @wmi_handle: wmi handle @@ -1165,6 +1176,7 @@ struct wma_ini_config { * @service_ready_ext_evt: Wait event for service ready ext * @wmi_cmd_rsp_wake_lock: wmi command response wake lock * @wmi_cmd_rsp_runtime_lock: wmi command response bus lock + * @saved_chan: saved channel list sent as part of WMI_SCAN_CHAN_LIST_CMDID */ typedef struct { void *wmi_handle; @@ -1350,6 +1362,7 @@ typedef struct { qdf_runtime_lock_t wma_runtime_resume_lock; uint32_t fine_time_measurement_cap; struct wma_ini_config ini_config; + struct wma_valid_channels saved_chan; } t_wma_handle, *tp_wma_handle; /** @@ -1956,8 +1969,8 @@ void wma_log_completion_timeout(void *data); QDF_STATUS wma_set_rssi_monitoring(tp_wma_handle wma, struct rssi_monitor_req *req); -QDF_STATUS wma_send_soc_set_pcl_cmd(tp_wma_handle wma_handle, - struct sir_pcl_list *msg); +QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, + struct wmi_pcl_chan_weights *msg); QDF_STATUS wma_send_soc_set_hw_mode_cmd(tp_wma_handle wma_handle, struct sir_hw_mode *msg); diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 06e5da0b548a..723ff4921eb8 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -1798,6 +1798,7 @@ QDF_STATUS wma_open(void *cds_context, wma_handle->dfs_radar_indication_cb = radar_ind_cb; wma_handle->old_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX; wma_handle->new_hw_mode_index = WMA_DEFAULT_HW_MODE_INDEX; + wma_handle->saved_chan.num_channels = 0; qdf_status = qdf_event_create(&wma_handle->wma_ready_event); if (qdf_status != QDF_STATUS_SUCCESS) { @@ -5165,9 +5166,9 @@ QDF_STATUS wma_mc_process_msg(void *cds_context, cds_msg_t *msg) (struct fw_dump_req *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; - case SIR_HAL_SOC_SET_PCL_TO_FW: - wma_send_soc_set_pcl_cmd(wma_handle, - (struct sir_pcl_list *)msg->bodyptr); + case SIR_HAL_PDEV_SET_PCL_TO_FW: + wma_send_pdev_set_pcl_cmd(wma_handle, + (struct wmi_pcl_chan_weights *)msg->bodyptr); qdf_mem_free(msg->bodyptr); break; case SIR_HAL_SOC_SET_HW_MODE: @@ -5297,30 +5298,49 @@ void wma_log_completion_timeout(void *data) } /** - * wma_send_soc_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW + * wma_send_pdev_set_pcl_cmd() - Send WMI_SOC_SET_PCL_CMDID to FW * @wma_handle: WMA handle * @msg: PCL structure containing the PCL and the number of channels * - * WMI_SOC_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN + * WMI_PDEV_SET_PCL_CMDID provides a Preferred Channel List (PCL) to the WLAN * firmware. The DBS Manager is the consumer of this information in the WLAN * firmware. The channel list will be used when a Virtual DEVice (VDEV) needs * to migrate to a new channel without host driver involvement. An example of * this behavior is Legacy Fast Roaming (LFR 3.0). Generally, the host will * manage the channel selection without firmware involvement. * + * WMI_PDEV_SET_PCL_CMDID will carry only the weight list and not the actual + * channel list. The weights corresponds to the channels sent in + * WMI_SCAN_CHAN_LIST_CMDID. The channels from PCL would be having a higher + * weightage compared to the non PCL channels. + * * Return: Success if the cmd is sent successfully to the firmware */ -QDF_STATUS wma_send_soc_set_pcl_cmd(tp_wma_handle wma_handle, - struct sir_pcl_list *msg) +QDF_STATUS wma_send_pdev_set_pcl_cmd(tp_wma_handle wma_handle, + struct wmi_pcl_chan_weights *msg) { + uint32_t i; + QDF_STATUS status; + if (!wma_handle) { WMA_LOGE("%s: WMA handle is NULL. Cannot issue command", __func__); return QDF_STATUS_E_NULL_VALUE; } - if (wmi_unified_soc_set_pcl_cmd(wma_handle->wmi_handle, - (struct wmi_pcl_list *) msg)) + for (i = 0; i < wma_handle->saved_chan.num_channels; i++) { + msg->saved_chan_list[i] = + wma_handle->saved_chan.channel_list[i]; + } + + msg->saved_num_chan = wma_handle->saved_chan.num_channels; + status = cds_get_valid_chan_weights((struct sir_pcl_chan_weights *)msg); + if (!QDF_IS_STATUS_SUCCESS(status)) { + WMA_LOGE("%s: Error in creating weighed pcl", __func__); + return status; + } + + if (wmi_unified_pdev_set_pcl_cmd(wma_handle->wmi_handle, msg)) return QDF_STATUS_E_FAILURE; return QDF_STATUS_SUCCESS; diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index 78d57ac32921..295cde659da1 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -642,6 +642,7 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, WMA_LOGD("no of channels = %d", chan_list->numChan); tchan_info = scan_ch_param.chan_info; scan_ch_param.num_scan_chans = chan_list->numChan; + wma_handle->saved_chan.num_channels = chan_list->numChan; for (i = 0; i < chan_list->numChan; ++i) { tchan_info->mhz = @@ -649,8 +650,11 @@ QDF_STATUS wma_update_channel_list(WMA_HANDLE handle, tchan_info->band_center_freq1 = tchan_info->mhz; tchan_info->band_center_freq2 = 0; + wma_handle->saved_chan.channel_list[i] = + chan_list->chanParam[i].chanId; - WMA_LOGD("chan[%d] = %u", i, tchan_info->mhz); + WMA_LOGD("chan[%d] = freq:%u chan:%d", i, tchan_info->mhz, + chan_list->chanParam[i].chanId); if (chan_list->chanParam[i].dfsSet) { WMI_SET_CHANNEL_FLAG(tchan_info, WMI_CHAN_FLAG_PASSIVE); WMA_LOGI("chan[%d] DFS[%d]\n", -- cgit v1.2.3 From b2d9fa14f4b724b9e47f19d55dc7144bbaf699cf Mon Sep 17 00:00:00 2001 From: "Chandrasekaran, Manishekar" Date: Thu, 7 Apr 2016 12:00:10 +0530 Subject: qcacld-3.0: Enable packet tracker for non performance builds Enable the packet tracker feature for non performance builds by enabling the macro QCA_PKT_PROTO_TRACE and set the default packet tracker log level to dump the DHCP, EAPOL and management packet details. The necessary log level can be modified using the ini 'gEnableDebugLog' entry either at compile time or at run time using the IOCTL 'setDbgLvl'. The logs are dumped using the same IOCTL 'setDbgLvl'. e.g., To enable all the packet trace features - iwpriv wlan0 setDbgLvl 0x0f To dump the packet trace - iwpriv wlan0 setDbgLvl 9999 Change-Id: I4fe82e0091517f0614baedf620976dd37b94a974 CRs-Fixed: 998642 --- Kbuild | 27 ++++++++++++++++++++++++++- Kconfig | 4 ++++ core/hdd/inc/wlan_hdd_cfg.h | 7 +++++-- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/Kbuild b/Kbuild index fe20723231d4..4da1a543caa9 100755 --- a/Kbuild +++ b/Kbuild @@ -41,6 +41,31 @@ ifeq ($(KERNEL_BUILD), 0) CONFIG_MOBILE_ROUTER := y endif + # As per target team, build is done as follows: + # Defconfig : build with default flags + # Slub : defconfig + CONFIG_SLUB_DEBUG=y + + # CONFIG_SLUB_DEBUG_ON=y + CONFIG_PAGE_POISONING=y + # Perf : Using appropriate msmXXXX-perf_defconfig + # + # Shipment builds (user variants) should not have any debug feature + # enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds + # are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since + # there is no other way to identify defconfig builds, QCOMs internal + # representation of perf builds (identified using the string 'perf'), + # is used to identify if the build is a slub or defconfig one. This + # way no critical debug feature will be enabled for perf and shipment + # builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT + # config. + ifneq ($(TARGET_BUILD_VARIANT),user) + ifeq ($(CONFIG_SLUB_DEBUG_ON),y) + CONFIG_PKT_PROTO_TRACE := y + else + ifeq ($(findstring perf,$(KERNEL_DEFCONFIG)),) + CONFIG_PKT_PROTO_TRACE := y + endif + endif + endif + #Flag to enable Legacy Fast Roaming2(LFR2) CONFIG_QCACLD_WLAN_LFR2 := y #Flag to enable Legacy Fast Roaming3(LFR3) @@ -979,7 +1004,7 @@ CDEFINES += -DQCA_LL_LEGACY_TX_FLOW_CONTROL endif endif -ifeq ($(CONFIG_DEBUG_LL),y) +ifeq ($(CONFIG_PKT_PROTO_TRACE), y) CDEFINES += -DQCA_PKT_PROTO_TRACE endif diff --git a/Kconfig b/Kconfig index 13c92b848e28..7155ea2a2b4d 100644 --- a/Kconfig +++ b/Kconfig @@ -119,4 +119,8 @@ config QCACLD_WLAN_LFR2 bool "Enable the WLAN Legacy Fast Roaming feature Version 2" default n +config PKT_PROTO_TRACE + bool "Enable packet trace feature" + default n + endif # QCA_CLD_WLAN diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index 2d7795fa264c..98c9f9a35855 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -2121,15 +2121,18 @@ typedef enum { /* * Connection related log Enable/Disable. - * 0x1 - Enable mgmt pkt logs (no probe req/rsp). + * 0x1 - Enable mgmt pkt logs (excpet probe req/rsp, beacons). * 0x2 - Enable EAPOL pkt logs. * 0x4 - Enable DHCP pkt logs. + * 0x8 - Enable mgmt action frames logs. * 0x0 - Disable all the above connection related logs. + * + * The default value of 0x0F will enable all the above logs. */ #define CFG_ENABLE_DEBUG_CONNECT_ISSUE "gEnableDebugLog" #define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MIN (0) #define CFG_ENABLE_DEBUG_CONNECT_ISSUE_MAX (0xFF) -#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0) +#define CFG_ENABLE_DEBUG_CONNECT_ISSUE_DEFAULT (0x0F) /* This will be used only for debugging purpose, will be removed after sometime */ #define CFG_ENABLE_RX_THREAD "gEnableRxThread" -- cgit v1.2.3 From 1e382ffa9ba28bfa692a7308c68fd73c4e429f1a Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Thu, 21 Apr 2016 12:04:26 -0700 Subject: qcacld-3.0: Add new method to build/use driver based on targets Add the change to build and set WLAN driver as default for different targets based on target specific flags WIFI_DRIVER_BUILT and WIFI_DRIVER_DEFAULT. KERNEL_TO_BUILD_ROOT_OFFSET needs to be set a default value if upper level makefiles do not define it. Change-Id: I4768b8c75a5d4042d01c3ddfb67b20c13e42463a CRs-fixed: 1005069 --- Android.mk | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/Android.mk b/Android.mk index 1454e42d94fa..4602cf9b787c 100644 --- a/Android.mk +++ b/Android.mk @@ -5,37 +5,43 @@ WLAN_CHIPSET := ifeq ($(BOARD_HAS_QCOM_WLAN), true) -# Build/Package options for 8084/8092/8960/8992/8994 target -ifeq ($(call is-board-platform-in-list, msm8994 msm8996 msm8998 msmcobalt),true) +# Check if this driver needs be built for current target +ifneq ($(findstring qca_cld3,$(WIFI_DRIVER_BUILT)),) WLAN_CHIPSET := qca_cld3 WLAN_SELECT := CONFIG_QCA_CLD_WLAN=m -endif # platform +endif # Build/Package only in case of supported target ifneq ($(WLAN_CHIPSET),) -# If TARGET_KERNEL_VERSION is not defined, using default kernel path, -# otherwise kernel path should come from top level Android makefiles. +# If kernel version is not defined, using default kernel path, otherwise +# kernel path offset should come from top level Android makefiles. ifeq ($(TARGET_KERNEL_VERSION),) -$(info "WLAN: TARGET_KERNEL_VERSION not defined, assuming default") +$(info "$(WLAN_CHIPSET): TARGET_KERNEL_VERSION not defined, assuming default") TARGET_KERNEL_SOURCE := kernel KERNEL_TO_BUILD_ROOT_OFFSET := ../ endif +# If kernel path offset is not defined, assume old kernel structure +ifeq ($(KERNEL_TO_BUILD_ROOT_OFFSET),) +$(info "$(WLAN_CHIPSET): KERNEL_TO_BUILD_ROOT_OFFSET not defined, assuming default") +KERNEL_TO_BUILD_ROOT_OFFSET := ../ +endif + LOCAL_PATH := $(call my-dir) # This makefile is only for DLKM ifneq ($(findstring vendor,$(LOCAL_PATH)),) ifneq ($(findstring opensource,$(LOCAL_PATH)),) - WLAN_BLD_DIR := vendor/qcom/opensource/wlan + WLAN_BLD_DIR := vendor/qcom/opensource/wlan endif # opensource # DLKM_DIR was moved for JELLY_BEAN (PLATFORM_SDK 16) ifeq ($(call is-platform-sdk-version-at-least,16),true) - DLKM_DIR := $(TOP)/device/qcom/common/dlkm + DLKM_DIR := $(TOP)/device/qcom/common/dlkm else - DLKM_DIR := build/dlkm + DLKM_DIR := build/dlkm endif # platform-sdk-version # Build wlan.ko as $(WLAN_CHIPSET)_wlan.ko @@ -63,9 +69,12 @@ include $(DLKM_DIR)/AndroidKernelModule.mk ########################################################### # Create Symbolic link +ifneq ($(findstring $(WLAN_CHIPSET),$(WIFI_DRIVER_DEFAULT)),) +$(shell mkdir -p $(TARGET_OUT)/lib/modules; \ + ln -sf /system/lib/modules/$(WLAN_CHIPSET)/$(LOCAL_MODULE) $(TARGET_OUT)/lib/modules/wlan.ko) +endif $(shell ln -sf /persist/wlan_mac.bin $(TARGET_OUT_ETC)/firmware/wlan/qca_cld/wlan_mac.bin) endif # DLKM check - endif # supported target check endif # WLAN enabled check -- cgit v1.2.3 From df224b8fb8f094b7a4fb95adb6c008cdb9c56004 Mon Sep 17 00:00:00 2001 From: Yue Ma Date: Thu, 21 Apr 2016 12:46:04 -0700 Subject: qcacld-3.0: Fix conditional logic checking in Kbuild In msm-4.4 kernel, CONFIG_ARCH_MSM is replaced by CONFIG_ARCH_QCOM, hence add it to the list so that MSM_PLATFORM can be correctly enabled for the driver. Also filter function works in a exclusive way that will causes problem when several flags are defined at the same time. Fix it so that multiple flags can be defined. Change-Id: Ic5445951516c8d2cd79a71aefebd42b3f178c727 CRs-fixed: 1005069 --- Kbuild | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Kbuild b/Kbuild index 4da1a543caa9..4058e486056f 100755 --- a/Kbuild +++ b/Kbuild @@ -98,7 +98,7 @@ ifeq ($(KERNEL_BUILD), 0) CONFIG_QCOM_VOWIFI_11R := y ifneq ($(CONFIG_QCA_CLD_WLAN),) - ifeq (y,$(filter y,$(CONFIG_CNSS) $(CONFIG_ICNSS))) + ifeq (y,$(findstring y,$(CONFIG_CNSS) $(CONFIG_ICNSS))) #Flag to enable Protected Managment Frames (11w) feature CONFIG_WLAN_FEATURE_11W := y #Flag to enable LTE CoEx feature @@ -985,11 +985,7 @@ ifeq ($(CONFIG_FEATURE_BMI_2), y) CDEFINES += -DFEATURE_BMI_2 endif -ifeq ($(CONFIG_ARCH_MSM), y) -CDEFINES += -DMSM_PLATFORM -endif - -ifeq ($(CONFIG_ARCH_MSMCOBALT), y) +ifeq (y,$(findstring y,$(CONFIG_ARCH_MSM) $(CONFIG_ARCH_QCOM))) CDEFINES += -DMSM_PLATFORM endif -- cgit v1.2.3 From 34e9616ebb858af4b93a857ed4a69e49c70cba2c Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Thu, 21 Apr 2016 16:19:31 -0700 Subject: qcacld-3.0: Make NAPI stubs neutral When the feature is not defined, make sure that NAPI API calls return success (0) so that the callers don't need to add any code to check return values. Acked-by: Orhan K AKYILDIZ Change-Id: Ibfb8d407cb902ecc2b61dd971262904aa25aa9ba CRs-Fixed: 999422 --- core/hdd/inc/wlan_hdd_napi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_napi.h b/core/hdd/inc/wlan_hdd_napi.h index 3c1683ded84c..f4bfa75f169a 100644 --- a/core/hdd/inc/wlan_hdd_napi.h +++ b/core/hdd/inc/wlan_hdd_napi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -68,7 +68,7 @@ struct qca_napi_data *hdd_napi_get_all(void); #define HDD_NAPI_ANY (-1) static inline int hdd_napi_enabled(int id) { return 0; } -static inline int hdd_napi_create(void) { return -EPERM; } +static inline int hdd_napi_create(void) { return 0; } static inline int hdd_napi_destroy(int force) { return 0; } static inline int hdd_napi_stats(char *buf, int max, char *indp, struct qca_napi_data *napid) -- cgit v1.2.3 From 9dd19130fe6652e5395ac90fd05d82e8f31b9263 Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Thu, 21 Apr 2016 16:27:04 -0700 Subject: qcacld-3.0: Fix NAPI creation with 0 instances If NAPI does not find any instances to create, then it would return a bitmap of 0. Make this a condition that is reportable as a warning, but do not break initialization sequence with an error. Acked-by: Orhan K AKYILDIZ Change-Id: I38a7a845c5b9ed3ab5ce691917e981ee2c8f7b1c CRs-Fixed: 999422 --- core/hdd/src/wlan_hdd_driver_ops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 3d72466d9608..1649840e98ae 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -256,7 +256,9 @@ static int hdd_hif_open(struct device *dev, void *bdev, const hif_bus_id *bid, } else { ret = hdd_napi_create(); hdd_info("hdd_napi_create returned: %d", ret); - if (ret <= 0) { + if (ret == 0) + hdd_warn("NAPI: no instances are created"); + else if (ret < 0) { hdd_err("NAPI creation error, rc: 0x%x, reinit = %d", ret, reinit); ret = -EFAULT; -- cgit v1.2.3 From fa345994b592fa64e60231add912ea63796e5de9 Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Thu, 21 Apr 2016 16:45:40 -0700 Subject: qcacld-3.0: Enable V2 FLOW CONTROL for SNOC Enable "tx flow control v2" for SNOC. Acked-by: Orhan K AKYILDIZ Change-Id: Ifaca9c97d78e6b09876e3d0a7a9e85d763e67e09 CRs-Fixed: 999422 --- Kbuild | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Kbuild b/Kbuild index 4058e486056f..f1c35d6a2f47 100755 --- a/Kbuild +++ b/Kbuild @@ -164,6 +164,10 @@ ifeq ($(KERNEL_BUILD), 0) endif endif +ifeq ($(CONFIG_ROME_IF), snoc) + CONFIG_WLAN_TX_FLOW_CONTROL_V2 := y +endif + # Flag to enable LFR Subnet Detection CONFIG_LFR_SUBNET_DETECTION := y -- cgit v1.2.3 From 52ec66908970b97081386a6e0b2f4d2899a5170f Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Thu, 21 Apr 2016 16:36:45 -0700 Subject: qcacld-3.0: Fix compilation errors for msmcobalt (2/2) Fix compilation errors when building for msmcobalt. Change-Id: I2e1d968e967f493fb927440777d1d01f7e3f66b0 CRs-Fixed: 1006068 --- Kbuild | 11 +++++--- core/bmi/src/bmi.c | 50 ++++++++++++++++++++++++------------- core/bmi/src/ol_fw.c | 19 ++++++++++++-- core/hdd/src/wlan_hdd_assoc.c | 2 +- core/utils/epping/src/epping_txrx.c | 9 +++---- core/wma/src/wma_features.c | 8 ++---- 6 files changed, 64 insertions(+), 35 deletions(-) diff --git a/Kbuild b/Kbuild index f1c35d6a2f47..d4da7c54807a 100755 --- a/Kbuild +++ b/Kbuild @@ -22,8 +22,8 @@ ifeq ($(KERNEL_BUILD),1) # Need to explicitly define for Kernel-based builds MODNAME := wlan WLAN_ROOT := drivers/staging/qcacld-3.0 - WLAN_COMMON_ROOT := drivers/staging/qca-wifi-host-cmn - WLAN_COMMON_INC := $(WLAN_COMMON_ROOT) + WLAN_COMMON_ROOT := ../qca-wifi-host-cmn + WLAN_COMMON_INC := $(WLAN_ROOT)/$(WLAN_COMMON_ROOT) endif # Make WLAN as open-source driver by default @@ -227,6 +227,11 @@ endif ifeq ($(CONFIG_ROME_IF),pci) CONFIG_ATH_PCI := 1 endif + +ifeq ($(CONFIG_ROME_IF),snoc) + CONFIG_HIF_SNOC:= 1 +endif + ifeq ($(CONFIG_ROME_IF),usb) #CONFIG_ATH_PCI := 1 endif @@ -784,6 +789,7 @@ HIF_INC += -I$(WLAN_COMMON_INC)/$(HIF_SNOC_DIR) endif HIF_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/ath_procfs.o \ + $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_bmi.o \ $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_diag.o \ $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_main.o \ $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_service.o \ @@ -801,7 +807,6 @@ HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DIR)/src/hif_napi.o endif HIF_PCIE_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_PCIE_DIR)/if_pci.o -HIF_PCIE_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_CE_DIR)/ce_bmi.o HIF_SNOC_OBJS := $(WLAN_COMMON_ROOT)/$(HIF_SNOC_DIR)/if_snoc.o HIF_OBJS += $(WLAN_COMMON_ROOT)/$(HIF_DISPATCHER_DIR)/multibus.o diff --git a/core/bmi/src/bmi.c b/core/bmi/src/bmi.c index 0a15dd41267e..5752ccc0d6e9 100644 --- a/core/bmi/src/bmi.c +++ b/core/bmi/src/bmi.c @@ -37,6 +37,12 @@ /* Enable BMI_TEST COMMANDs; The Value 0x09 is randomly choosen */ #define BMI_TEST_ENABLE (0x09) +#ifndef CONFIG_CNSS +#define SHOULD_RUN_BMI_TEST_COMMANDS false +#else +#define SHOULD_RUN_BMI_TEST_COMMANDS (BMI_TEST_ENABLE == cnss_get_bmi_setup()) +#endif + static QDF_STATUS bmi_command_test(uint32_t command, uint32_t address, uint8_t *data, uint32_t length, struct ol_context *ol_ctx) @@ -220,11 +226,33 @@ static inline uint32_t bmi_get_test_addr(void) } #endif -QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx) +/** + * run_bmi_test() - run some bmi tests + * @ol_ctx: bmi context + * + */ +static void run_bmi_test(struct ol_context *ol_ctx) { uint8_t data[10], out[10]; uint32_t address; int32_t ret; + + ret = snprintf(data, 10, "ABCDEFGHI"); + BMI_DBG("ret:%d writing data:%s\n", ret, data); + address = bmi_get_test_addr(); + + if (bmi_init(ol_ctx) != QDF_STATUS_SUCCESS) { + BMI_WARN("BMI_INIT Failed; No Memory!"); + return; + } + bmi_command_test(BMI_NO_COMMAND, address, data, 9, ol_ctx); + bmi_command_test(BMI_WRITE_MEMORY, address, data, 9, ol_ctx); + bmi_command_test(BMI_READ_MEMORY, address, out, 9, ol_ctx); + BMI_DBG("Output:%s", out); +} + +QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx) +{ struct hif_opaque_softc *scn = ol_ctx->scn; if (NO_BMI || !hif_needs_bmi(scn)) @@ -235,23 +263,9 @@ QDF_STATUS bmi_download_firmware(struct ol_context *ol_ctx) bmi_assert(0); return QDF_STATUS_NOT_INITIALIZED; } -#ifdef CONFIG_CNSS - if (BMI_TEST_ENABLE == cnss_get_bmi_setup()) { - ret = snprintf(data, 10, "ABCDEFGHI"); - BMI_DBG("ret:%d writing data:%s\n", ret, data); - address = bmi_get_test_addr(); - - if (bmi_init(ol_ctx) != QDF_STATUS_SUCCESS) { - BMI_WARN("BMI_INIT Failed; No Memory!"); - goto end; - } - bmi_command_test(BMI_NO_COMMAND, address, data, 9, ol_ctx); - bmi_command_test(BMI_WRITE_MEMORY, address, data, 9, ol_ctx); - bmi_command_test(BMI_READ_MEMORY, address, out, 9, ol_ctx); - BMI_DBG("Output:%s", out); - } -#endif -end: + + if (SHOULD_RUN_BMI_TEST_COMMANDS) + run_bmi_test(ol_ctx); return bmi_firmware_download(ol_ctx); } diff --git a/core/bmi/src/ol_fw.c b/core/bmi/src/ol_fw.c index 79bc5625f106..e47ff72fa311 100644 --- a/core/bmi/src/ol_fw.c +++ b/core/bmi/src/ol_fw.c @@ -59,8 +59,11 @@ static uint32_t refclk_speed_to_hz[] = { 52000000, /* SOC_REFCLK_52_MHZ */ }; +#if defined(CONFIG_CNSS) static int ol_target_coredump(void *inst, void *memory_block, uint32_t block_len); +#endif + #ifdef FEATURE_SECURE_FIRMWARE static int ol_check_fw_hash(const u8 *data, u32 fw_size, ATH_BIN_FILE file) { @@ -150,7 +153,9 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file, #endif struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); uint32_t target_type = tgt_info->target_type; +#if defined(CONFIG_CNSS) struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx); +#endif qdf_device_t qdf_dev = ol_ctx->qdf_dev; switch (file) { @@ -612,8 +617,10 @@ void ol_target_failure(void *instance, QDF_STATUS status) struct ol_context *ol_ctx = instance; struct hif_opaque_softc *scn = ol_ctx->scn; tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); +#ifdef CONFIG_CNSS struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); int ret; +#endif ol_target_status target_status = hif_get_target_status(scn); @@ -1218,9 +1225,9 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx) struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); uint32_t target_type = tgt_info->target_type; uint32_t target_version = tgt_info->target_version; +#ifdef CONFIG_CNSS struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx); -#ifdef CONFIG_CNSS if (0 != cnss_get_fw_files_for_target(&bmi_ctx->fw_files, target_type, target_version)) { @@ -1328,7 +1335,7 @@ QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx) if (ini_cfg->enable_uart_print || (WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && WLAN_IS_EPPING_FW_UART(cds_get_conparam()))) { - switch (tgt_info->target_version) { + switch (target_version) { case AR6004_VERSION_REV1_3: param = 11; break; @@ -1427,6 +1434,7 @@ int ol_diag_read(struct hif_opaque_softc *scn, uint8_t *buffer, return -EIO; } +#if defined(CONFIG_CNSS) static int ol_ath_get_reg_table(uint32_t target_version, tgt_reg_table *reg_table) { @@ -1461,7 +1469,10 @@ static int ol_ath_get_reg_table(uint32_t target_version, return section_len; } +#endif + +#if defined(CONFIG_CNSS) static int ol_diag_read_reg_loc(struct hif_opaque_softc *scn, uint8_t *buffer, uint32_t buffer_len) { @@ -1527,6 +1538,7 @@ static int ol_diag_read_reg_loc(struct hif_opaque_softc *scn, uint8_t *buffer, out: return result; } +#endif void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block) { @@ -1552,6 +1564,8 @@ void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block) } } + +#if defined(CONFIG_CNSS) /** * ol_target_coredump() - API to collect target ramdump * @inst - private context @@ -1638,6 +1652,7 @@ static int ol_target_coredump(void *inst, void *memory_block, } return ret; } +#endif /** * ol_get_ini_handle() - API to get Ol INI configuration diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index cad7ae03bc89..67066ebc1733 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1259,7 +1259,6 @@ QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter, QDF_STATUS err; uint8_t *peer_mac_addr; struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); - ol_txrx_vdev_handle vdev; ol_txrx_peer_handle peer; if (!pdev) { @@ -1309,6 +1308,7 @@ QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter, if (pAdapter->device_mode == QDF_STA_MODE || pAdapter->device_mode == QDF_P2P_CLIENT_MODE) { #if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2) + ol_txrx_vdev_handle vdev; unsigned long rc; /* wait for event from firmware to set the event */ diff --git a/core/utils/epping/src/epping_txrx.c b/core/utils/epping/src/epping_txrx.c index 4586b1033fe8..8196bf908056 100644 --- a/core/utils/epping/src/epping_txrx.c +++ b/core/utils/epping/src/epping_txrx.c @@ -390,7 +390,6 @@ epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx, int epping_connect_service(epping_context_t *pEpping_ctx) { int status, i; - int ret = -1; HTC_SERVICE_CONNECT_REQ connect; HTC_SERVICE_CONNECT_RESP response; @@ -421,9 +420,9 @@ int epping_connect_service(epping_context_t *pEpping_ctx) status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response); if (status != EOK) { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, - "Failed to connect to Endpoint Ping BE service status:%d \n", + "Failed to connect to Endpoint Ping BE service status:%d\n", status); - return -1;; + return status; } else { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "eppingtest BE endpoint:%d\n", response.Endpoint); @@ -435,9 +434,9 @@ int epping_connect_service(epping_context_t *pEpping_ctx) status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response); if (status != EOK) { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, - "Failed to connect to Endpoint Ping BK service status:%d \n", + "Failed to connect to Endpoint Ping BK service status:%d\n", status); - return ret; + return status; } else { EPPING_LOG(QDF_TRACE_LEVEL_FATAL, "eppingtest BK endpoint:%d\n", response.Endpoint); diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index fe9d40f56b34..23312de758f2 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -5695,21 +5695,18 @@ QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr) QDF_STATUS status; struct suspend_params param = {0}; -#ifdef CONFIG_CNSS tpAniSirGlobal pmac = cds_get_context(QDF_MODULE_ID_PE); -#endif if (!wma_handle || !wma_handle->wmi_handle) { WMA_LOGE("WMA is closed. can not issue suspend cmd"); return QDF_STATUS_E_INVAL; } -#ifdef CONFIG_CNSS if (NULL == pmac) { WMA_LOGE("%s: Unable to get PE context", __func__); return QDF_STATUS_E_INVAL; } -#endif + qdf_event_reset(&wma_handle->target_suspend); param.disable_target_intr = disable_target_intr; status = wmi_unified_suspend_send(wma_handle->wmi_handle, @@ -5772,7 +5769,6 @@ void wma_target_suspend_acknowledge(void *context) */ QDF_STATUS wma_resume_target(WMA_HANDLE handle) { - int ret; tp_wma_handle wma = (tp_wma_handle) handle; QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; #ifdef CONFIG_CNSS @@ -5818,7 +5814,7 @@ QDF_STATUS wma_resume_target(WMA_HANDLE handle) if (QDF_STATUS_SUCCESS == qdf_status) wmi_set_target_suspend(wma->wmi_handle, false); - return ret; + return qdf_status; } #ifdef FEATURE_WLAN_TDLS -- cgit v1.2.3 From 8b39d2eece330b0bc95273003867250c70a2a576 Mon Sep 17 00:00:00 2001 From: Manjunathappa Prakash Date: Fri, 22 Apr 2016 11:23:33 -0700 Subject: qcacld-3.0: Use CDS PKT_TRACE macro CDS_PKT_TRAC_TYPE_MGMT_ACTION Fix build error, missing definition of NBUF_PKT_TRAC_TYPE_MGMT_ACTION. Use CDS macro. Change-Id: I65a169397236177c92b1980397794f6364ad24cb CRs-Fixed: 1005069 --- core/wma/src/wma_data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 42ca332a8646..572b7d91a1d8 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -2633,8 +2633,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, if (pFc->subType == SIR_MAC_MGMT_ACTION) proto_type = cds_pkt_get_proto_type(tx_frame, pMac->fEnableDebugLog, - NBUF_PKT_TRAC_TYPE_MGMT_ACTION); - if (proto_type & NBUF_PKT_TRAC_TYPE_MGMT_ACTION) + CDS_PKT_TRAC_TYPE_MGMT_ACTION); + if (proto_type & CDS_PKT_TRAC_TYPE_MGMT_ACTION) cds_pkt_trace_buf_update("WM:T:MACT"); qdf_nbuf_trace_set_proto_type(tx_frame, proto_type); #endif /* QCA_PKT_PROTO_TRACE */ -- cgit v1.2.3 From 24e697ff3e3063098407ad56dc4e74de57db0ee6 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Fri, 22 Apr 2016 10:49:45 +0530 Subject: qcacld-3.0: Update htc_endpoint only for htt tx endpoint Update htc_endpoint only for htt tx endpoint to avoid double freeing of Tx Queue packets as it will be freed in htt_htc_misc_pkt_pool_free. Rename htc_endpoint to htc_htt_tx_endpoint to reflect it's appropriate use. Change-Id: I736ba08505acc829eb15be30538553dd945695f6 CRs-Fixed: 1006498 --- core/dp/htt/htt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/dp/htt/htt.c b/core/dp/htt/htt.c index 58860948dd5e..1672a39c2ea5 100644 --- a/core/dp/htt/htt.c +++ b/core/dp/htt/htt.c @@ -434,9 +434,10 @@ int htt_update_endpoint(struct htt_pdev_t *pdev, QDF_BUG(service_id == HTT_DATA_MSG_SVC); pdev->htc_tx_endpoint = ep; + hif_save_htc_htt_config_endpoint(hif_ctx, ep); rc = 1; } - return rc; + return rc; } int htt_htc_attach(struct htt_pdev_t *pdev, uint16_t service_id) -- cgit v1.2.3 From 805e7dfeee2553ffa34188c2cc55e454a666a1a6 Mon Sep 17 00:00:00 2001 From: Vishwajith Upendra Date: Thu, 21 Apr 2016 20:25:38 -0700 Subject: Release 5.1.0.4 Release including SU173 changes on unconverged CLD3.0 with additional changes. Change-Id: Id36746e7b3f1eed3c3d07b66f9bad37a94e48738 CRs-Fixed: 688141 --- core/mac/inc/qwlan_version.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index 494519e7cc59..e2bc89c4297a 100644 --- a/core/mac/inc/qwlan_version.h +++ b/core/mac/inc/qwlan_version.h @@ -41,10 +41,10 @@ #define QWLAN_VERSION_MAJOR 5 #define QWLAN_VERSION_MINOR 1 #define QWLAN_VERSION_PATCH 0 -#define QWLAN_VERSION_EXTRA "A" -#define QWLAN_VERSION_BUILD 3 +#define QWLAN_VERSION_EXTRA "" +#define QWLAN_VERSION_BUILD 4 -#define QWLAN_VERSIONSTR "5.1.0.3A" +#define QWLAN_VERSIONSTR "5.1.0.4" /* 172 */ #endif /* QWLAN_VERSION_H */ -- cgit v1.2.3