diff options
48 files changed, 925 insertions, 529 deletions
@@ -352,6 +352,8 @@ endif ifneq ($(CONFIG_MOBILE_ROUTER), y) #Enable IBSS support on CLD CONFIG_QCA_IBSS_SUPPORT := 1 + +CONFIG_WLAN_SYSFS := y endif #Enable power management suspend/resume functionality to PCI @@ -466,13 +468,16 @@ HDD_OBJS := $(HDD_SRC_DIR)/wlan_hdd_assoc.o \ $(HDD_SRC_DIR)/wlan_hdd_request_manager.o \ $(HDD_SRC_DIR)/wlan_hdd_scan.o \ $(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \ - $(HDD_SRC_DIR)/wlan_hdd_sysfs.o \ $(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \ $(HDD_SRC_DIR)/wlan_hdd_trace.o \ $(HDD_SRC_DIR)/wlan_hdd_wext.o \ $(HDD_SRC_DIR)/wlan_hdd_wmm.o \ $(HDD_SRC_DIR)/wlan_hdd_wowl.o +ifeq ($(CONFIG_WLAN_SYSFS), y) +HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_sysfs.o +endif + ifeq ($(CONFIG_WLAN_DEBUGFS), y) HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs.o HDD_OBJS += $(HDD_SRC_DIR)/wlan_hdd_debugfs_llstat.o @@ -1487,6 +1492,10 @@ ifeq ($(CONFIG_QCA_IBSS_SUPPORT), 1) CDEFINES += -DQCA_IBSS_SUPPORT endif +ifeq ($(CONFIG_WLAN_SYSFS), y) +CDEFINES += -DWLAN_SYSFS +endif + #Enable OL debug and wmi unified functions ifeq ($(CONFIG_ATH_PERF_PWR_OFFLOAD), 1) CDEFINES += -DATH_PERF_PWR_OFFLOAD diff --git a/core/bmi/src/bmi.c b/core/bmi/src/bmi.c index aeba859b2a34..ecce29ec08af 100644 --- a/core/bmi/src/bmi.c +++ b/core/bmi/src/bmi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-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 @@ -415,8 +415,8 @@ QDF_STATUS bmi_sign_stream_start(uint32_t address, uint8_t *buffer, src = &buffer[length - remaining]; if (remaining < (BMI_DATASZ_MAX - header)) { if (remaining & 0x3) { - remaining = remaining + (4 - (remaining & 0x3)); memcpy(aligned_buf, src, remaining); + remaining = remaining + (4 - (remaining & 0x3)); src = aligned_buf; } txlen = remaining; diff --git a/core/cds/inc/cds_concurrency.h b/core/cds/inc/cds_concurrency.h index b81dc61d702f..874a37faf93c 100644 --- a/core/cds/inc/cds_concurrency.h +++ b/core/cds/inc/cds_concurrency.h @@ -751,6 +751,23 @@ bool cds_is_any_nondfs_chnl_present(uint8_t *channel); bool cds_is_any_dfs_beaconing_session_present(uint8_t *channel); bool cds_allow_concurrency(enum cds_con_mode mode, uint8_t channel, enum hw_mode_bandwidth bw); +/** + * cds_is_concurrency_allowed() - Check for allowed + * concurrency combination + * @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 cds_is_concurrency_allowed(enum cds_con_mode mode, + uint8_t channel, + enum hw_mode_bandwidth bw); /** * cds_check_privacy_with_concurrency() - privacy/concurrency checker diff --git a/core/cds/inc/cds_regdomain.h b/core/cds/inc/cds_regdomain.h index 2d49c4d1efdd..6f9a88989768 100644 --- a/core/cds/inc/cds_regdomain.h +++ b/core/cds/inc/cds_regdomain.h @@ -302,6 +302,7 @@ enum reg_domain { ETSI10_WORLD = 0x24, ETSI11_WORLD = 0x26, ETSI13_WORLD = 0x28, + ETSI15_WORLD = 0x31, APL4_WORLD = 0x42, APL3_FCCA = 0x50, @@ -405,6 +406,7 @@ enum reg_domain { ETSI10 = 0x0D30, ETSI11 = 0x0E30, ETSI13 = 0x0E39, + ETSI15 = 0x0E41, APL1 = 0x0150, APL2 = 0x0250, diff --git a/core/cds/inc/cds_utils.h b/core/cds/inc/cds_utils.h index 00988a8d6562..c1f2535f1688 100644 --- a/core/cds/inc/cds_utils.h +++ b/core/cds/inc/cds_utils.h @@ -102,7 +102,10 @@ enum cds_band_type { * 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 + * 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, @@ -111,6 +114,7 @@ enum dbs_support { 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_SIMULTANEOUS_SCAN, }; /*------------------------------------------------------------------------- diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c index 145b2607f114..f0ab58c58c46 100644 --- a/core/cds/src/cds_concurrency.c +++ b/core/cds/src/cds_concurrency.c @@ -5497,12 +5497,14 @@ static QDF_STATUS cds_get_channel_list(enum cds_pcl_type pcl, cds_debug("pcl len (%d) and weight list len mismatch (%d)", *len, i); - /* check the channel avoidance list */ + /* check the channel avoidance list for beaconing entities */ + if ((mode == CDS_SAP_MODE) || (mode == CDS_P2P_GO_MODE)) cds_update_with_safe_channel_list(pcl_channels, len, pcl_weights, weight_len); - cds_remove_dfs_passive_channels_from_pcl(pcl_channels, len, - pcl_weights, weight_len); + cds_remove_dfs_passive_channels_from_pcl(pcl_channels, + len, pcl_weights, + weight_len); return status; } @@ -6076,29 +6078,15 @@ bool cds_allow_sap_go_concurrency(enum cds_con_mode mode, uint8_t channel) return true; } -/** - * cds_allow_concurrency() - Check for allowed concurrency - * combination - * @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 cds_allow_concurrency(enum cds_con_mode mode, - uint8_t channel, enum hw_mode_bandwidth bw) +bool cds_is_concurrency_allowed(enum cds_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]; hdd_context_t *hdd_ctx; cds_context_type *cds_ctx; - QDF_STATUS ret; - struct sir_pcl_list pcl; bool is_sta_sap_on_dfs_chan; @@ -6114,15 +6102,6 @@ bool cds_allow_concurrency(enum cds_con_mode mode, return status; } - - qdf_mem_zero(&pcl, sizeof(pcl)); - ret = cds_get_pcl(mode, pcl.pcl_list, &pcl.pcl_len, - pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list)); - if (QDF_IS_STATUS_ERROR(ret)) { - cds_err("disallow connection:%d", ret); - goto done; - } - /* find the current connection state from conc_connection_list*/ num_connections = cds_get_connection_count(); @@ -6297,6 +6276,37 @@ done: } /** + * cds_allow_concurrency() - Check for allowed concurrency + * combination consulting the PCL + * @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 cds_allow_concurrency(enum cds_con_mode mode, + uint8_t channel, + enum hw_mode_bandwidth bw) +{ + struct sir_pcl_list pcl; + QDF_STATUS status; + + qdf_mem_zero(&pcl, sizeof(pcl)); + status = cds_get_pcl(mode, pcl.pcl_list, &pcl.pcl_len, + pcl.weight_list, + QDF_ARRAY_SIZE(pcl.weight_list)); + if (QDF_IS_STATUS_ERROR(status)) { + cds_err("disallow connection:%d", status); + return false; + } + return cds_is_concurrency_allowed(mode, channel, bw); +} + +/** * cds_get_first_connection_pcl_table_index() - provides the * row index to firstConnectionPclTable to get to the correct * pcl @@ -10329,9 +10339,9 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight, cds_store_and_del_conn_info(CDS_STA_MODE, false, info, &num_cxn_del); for (i = 0; i < weight->saved_num_chan; i++) { - if (cds_allow_concurrency(CDS_STA_MODE, - weight->saved_chan_list[i], - HW_MODE_20_MHZ)) { + if (cds_is_concurrency_allowed(CDS_STA_MODE, + weight->saved_chan_list[i], + HW_MODE_20_MHZ)) { weight->weighed_valid_list[i] = WEIGHT_OF_NON_PCL_CHANNELS; } diff --git a/core/cds/src/cds_regdomain.c b/core/cds/src/cds_regdomain.c index c388b948ce24..21c61b563c0a 100644 --- a/core/cds/src/cds_regdomain.c +++ b/core/cds/src/cds_regdomain.c @@ -175,6 +175,7 @@ static const struct reg_dmn_pair g_reg_dmn_pairs[] = { {ETSI8_WORLD, ETSI8, WORLD, CTRY_DEFAULT}, {ETSI9_WORLD, ETSI9, WORLD, CTRY_DEFAULT}, {ETSI13_WORLD, ETSI13, WORLD, CTRY_DEFAULT}, + {ETSI15_WORLD, ETSI15, WORLD, CTRY_DEFAULT}, {APL4_WORLD, APL4, WORLD, CTRY_DEFAULT}, {APL2_WORLD, APL2, WORLD, CTRY_DEFAULT}, {APL2_FCCA, APL2, FCCA, CTRY_DEFAULT}, @@ -348,7 +349,7 @@ static const struct country_code_to_reg_dmn g_all_countries[] = { {CTRY_SAINT_PIERRE_AND_MIQUELON, ETSI13_WORLD, "PM", "SAINT PIERRE"}, {CTRY_SAINT_VINCENT_AND_THE_GRENADIENS, ETSI13_WORLD, "VC", "VINCENT"}, {CTRY_SAMOA, ETSI1_WORLD, "WS", "SAMOA"}, - {CTRY_SAUDI_ARABIA, ETSI1_WORLD, "SA", "SAUDI ARABIA"}, + {CTRY_SAUDI_ARABIA, ETSI15_WORLD, "SA", "SAUDI ARABIA"}, {CTRY_SENEGAL, FCC13_WORLD, "SN", "SENEGAL"}, {CTRY_SERBIA, ETSI13_WORLD, "RS", "REPUBLIC OF SERBIA"}, {CTRY_SINGAPORE, FCC3_WORLD, "SG", "SINGAPORE"}, @@ -411,6 +412,7 @@ static const struct reg_dmn g_reg_dmns[] = { {ETSI10, ETSI}, {ETSI11, ETSI}, {ETSI13, ETSI}, + {ETSI15, ETSI}, {APL1, ETSI}, {APL2, ETSI}, {APL3, ETSI}, diff --git a/core/dp/htt/htt_rx.c b/core/dp/htt/htt_rx.c index 06c9e2665752..94b3e01e8e0b 100644 --- a/core/dp/htt/htt_rx.c +++ b/core/dp/htt/htt_rx.c @@ -2163,6 +2163,9 @@ static int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, uint32_t len; uint32_t last_frag; qdf_dma_addr_t paddr; + static uint8_t preamble_type; + static uint32_t vht_sig_a_1; + static uint32_t vht_sig_a_2; HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0); @@ -2237,6 +2240,33 @@ static int htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, prev = msdu; HTT_PKT_DUMP(htt_print_rx_desc(rx_desc)); + + /* + * Only the first mpdu has valid preamble type, so use it + * till the last mpdu is reached + */ + if (rx_desc->attention.first_mpdu) { + preamble_type = rx_desc->ppdu_start.preamble_type; + if (preamble_type == 8 || preamble_type == 9 || + preamble_type == 0x0c || preamble_type == 0x0d) { + vht_sig_a_1 = VHT_SIG_A_1(rx_desc); + vht_sig_a_2 = VHT_SIG_A_2(rx_desc); + } + } else { + rx_desc->ppdu_start.preamble_type = preamble_type; + if (preamble_type == 8 || preamble_type == 9 || + preamble_type == 0x0c || preamble_type == 0x0d) { + VHT_SIG_A_1(rx_desc) = vht_sig_a_1; + VHT_SIG_A_2(rx_desc) = vht_sig_a_2; + } + } + + if (rx_desc->attention.last_mpdu) { + preamble_type = 0; + vht_sig_a_1 = 0; + vht_sig_a_2 = 0; + } + /* * Make the netbuf's data pointer point to the payload rather * than the descriptor. diff --git a/core/dp/ol/inc/ol_htt_rx_api.h b/core/dp/ol/inc/ol_htt_rx_api.h index 61e7e9343ea1..d67d70285c93 100644 --- a/core/dp/ol/inc/ol_htt_rx_api.h +++ b/core/dp/ol/inc/ol_htt_rx_api.h @@ -806,6 +806,12 @@ void htt_rx_msdu_buff_replenish(htt_pdev_handle pdev); * Return: number of buffers actually replenished */ int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num); +#else +static inline +int htt_rx_msdu_buff_in_order_replenish(htt_pdev_handle pdev, uint32_t num) +{ + return 0; +} #endif /** diff --git a/core/dp/txrx/ol_rx_defrag.c b/core/dp/txrx/ol_rx_defrag.c index 74e2e7b6a467..a58047242ed4 100644 --- a/core/dp/txrx/ol_rx_defrag.c +++ b/core/dp/txrx/ol_rx_defrag.c @@ -307,6 +307,26 @@ void ol_rx_frag_send_pktlog_event(struct ol_txrx_pdev_t *pdev, #endif +#ifndef CONFIG_HL_SUPPORT +static int ol_rx_frag_get_inord_msdu_cnt(qdf_nbuf_t rx_ind_msg) +{ + uint32_t *msg_word; + uint8_t *rx_ind_data; + uint32_t msdu_cnt; + + rx_ind_data = qdf_nbuf_data(rx_ind_msg); + msg_word = (uint32_t *)rx_ind_data; + msdu_cnt = HTT_RX_IN_ORD_PADDR_IND_MSDU_CNT_GET(*(msg_word + 1)); + + return msdu_cnt; +} +#else +static int ol_rx_frag_get_inord_msdu_cnt(qdf_nbuf_t rx_ind_msg) +{ + return 0; +} +#endif + /* * Process incoming fragments */ @@ -344,7 +364,10 @@ ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev, * separate from normal frames */ ol_rx_reorder_flush_frag(htt_pdev, peer, tid, seq_num_start); + } else { + msdu_count = ol_rx_frag_get_inord_msdu_cnt(rx_frag_ind_msg); } + pktlog_bit = (htt_rx_amsdu_rx_in_order_get_pktlog(rx_frag_ind_msg) == 0x01); ret = htt_rx_frag_pop(htt_pdev, rx_frag_ind_msg, &head_msdu, @@ -380,7 +403,11 @@ ol_rx_frag_indication_handler(ol_txrx_pdev_handle pdev, htt_rx_desc_frame_free(htt_pdev, head_msdu); } /* request HTT to provide new rx MSDU buffers for the target to fill. */ - htt_rx_msdu_buff_replenish(htt_pdev); + if (ol_cfg_is_full_reorder_offload(pdev->ctrl_pdev) && + !pdev->cfg.is_high_latency) + htt_rx_msdu_buff_in_order_replenish(htt_pdev, msdu_count); + else + htt_rx_msdu_buff_replenish(htt_pdev); } /* diff --git a/core/dp/txrx/ol_tx_desc.c b/core/dp/txrx/ol_tx_desc.c index 0232296e745d..0f94e7f27152 100644 --- a/core/dp/txrx/ol_tx_desc.c +++ b/core/dp/txrx/ol_tx_desc.c @@ -190,7 +190,6 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, if (qdf_unlikely(pool->avail_desc < pool->stop_th) && (pool->status != FLOW_POOL_ACTIVE_PAUSED)) { pool->status = FLOW_POOL_ACTIVE_PAUSED; - qdf_spin_unlock_bh(&pool->flow_pool_lock); /* pause network queues */ pdev->pause_cb(vdev->vdev_id, WLAN_STOP_ALL_NETIF_QUEUE, @@ -199,13 +198,14 @@ struct ol_tx_desc_t *ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, pdev->pause_cb(vdev->vdev_id, WLAN_NETIF_PRIORITY_QUEUE_ON, WLAN_DATA_FLOW_CONTROL_PRIORITY); + qdf_spin_unlock_bh(&pool->flow_pool_lock); } else if (qdf_unlikely(pool->avail_desc < pool->stop_priority_th)) { - qdf_spin_unlock_bh(&pool->flow_pool_lock); /* pause priority queue */ pdev->pause_cb(vdev->vdev_id, WLAN_NETIF_PRIORITY_QUEUE_OFF, WLAN_DATA_FLOW_CONTROL_PRIORITY); + qdf_spin_unlock_bh(&pool->flow_pool_lock); } else { qdf_spin_unlock_bh(&pool->flow_pool_lock); } diff --git a/core/dp/txrx/ol_txrx_peer_find.c b/core/dp/txrx/ol_txrx_peer_find.c index 3fd5e18a2d90..9e6d0f710e73 100644 --- a/core/dp/txrx/ol_txrx_peer_find.c +++ b/core/dp/txrx/ol_txrx_peer_find.c @@ -101,6 +101,9 @@ void ol_txrx_peer_delete_roam_stale_peer(struct ol_txrx_pdev_t *pdev) for (i = 0; i < MAX_NUM_PEER_ID_PER_PEER; i++) { peer_id = peer->peer_ids[i]; + if (peer_id == HTT_INVALID_PEER) + continue; + if (pdev->peer_id_to_obj_map[peer_id].peer_ref != peer) continue; diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index cf9182fc9c51..f111678f6831 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -9687,6 +9687,8 @@ enum dot11p_mode { * 4 - enable DBS for connection as well as for scan with async * scan policy disabled. * 5 - enable DBS for connection but disable dbs for scan. + * 6 - enable DBS for connection but disable simultaneous scan + * from upper layer (DBS scan remains enabled in FW). * * Note: INI item value should match 'enum dbs_support' * @@ -9700,7 +9702,7 @@ enum dot11p_mode { */ #define CFG_DUAL_MAC_FEATURE_DISABLE "gDualMacFeatureDisable" #define CFG_DUAL_MAC_FEATURE_DISABLE_MIN (0) -#define CFG_DUAL_MAC_FEATURE_DISABLE_MAX (5) +#define CFG_DUAL_MAC_FEATURE_DISABLE_MAX (6) #define CFG_DUAL_MAC_FEATURE_DISABLE_DEFAULT (0) /* @@ -12328,6 +12330,9 @@ enum hw_filter_mode { * * <OUI> is mandatory and it can be either 3 or 5 bytes means 6 or 10 * hexa-decimal characters + * If the OUI and Data checks needs to be ignored, the oui FFFFFF + * needs to be provided as OUI and bit 0 of Info_Presence_Bit should + * be set to 0. * * <Data_Length> is mandatory field and should give length of * the <Data> if present else zero @@ -12348,8 +12353,8 @@ enum hw_filter_mode { * Presence of <Mac_Address> and <Capability> is * controlled by <Info_Presence_Bit> which is mandatory * <Info_Presence_Bit> will give the information for - * OUI – bit 0 (set/reset don't effect the behaviour, - * always enabled in the code) + * OUI – bit 0 Should be set to 1 + * Setting to 0 will ignore OUI and data check * Mac Address present – bit 1 * NSS – bit 2 * HT check – bit 3 @@ -14574,7 +14579,7 @@ enum hw_filter_mode { #define CFG_ENABLE_GCMP_NAME "gcmp_enabled" #define CFG_ENABLE_GCMP_MIN (0) #define CFG_ENABLE_GCMP_MAX (1) -#define CFG_ENABLE_GCMP_DEFAULT (1) +#define CFG_ENABLE_GCMP_DEFAULT (0) /* * <ini> diff --git a/core/hdd/inc/wlan_hdd_lro.h b/core/hdd/inc/wlan_hdd_lro.h index c744c3b100d0..cc9fc91d1584 100644 --- a/core/hdd/inc/wlan_hdd_lro.h +++ b/core/hdd/inc/wlan_hdd_lro.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-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 @@ -132,6 +132,8 @@ struct hdd_lro_s { struct hdd_lro_desc_info lro_desc_info; }; +int hdd_is_lro_enabled(hdd_context_t *hdd_ctx); + int hdd_lro_enable(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter); @@ -153,6 +155,11 @@ QDF_STATUS hdd_lro_set_reset(hdd_context_t *hdd_ctx, #else struct hdd_lro_s {}; +static inline int hdd_is_lro_enabled(hdd_context_t *hdd_ctx) +{ + return -EOPNOTSUPP; +} + static inline int hdd_lro_enable(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter) { diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 360a073b3bb8..8bb825b9e4ef 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -444,11 +444,8 @@ extern struct mutex hdd_init_deinit_lock; #define STATS_CONTEXT_MAGIC 0x53544154 /* STAT */ #define PEER_INFO_CONTEXT_MAGIC 0x50494E46 /* PEER_INFO(PINF) */ -#define POWER_CONTEXT_MAGIC 0x504F5752 /* POWR */ #define SNR_CONTEXT_MAGIC 0x534E5200 /* SNR */ -#define LINK_STATUS_MAGIC 0x4C4B5354 /* LINKSTATUS(LNST) */ #define APF_CONTEXT_MAGIC 0x4575354 /* APF */ -#define POWER_STATS_MAGIC 0x14111990 #define ACTION_FRAME_RANDOM_CONTEXT_MAGIC 0x87878787 /* MAX OS Q block time value in msec @@ -1625,7 +1622,6 @@ struct hdd_adapter_s { * channel needs to be moved from the existing 2.4GHz channel. */ uint8_t pre_cac_chan; - struct power_stats_response *chip_power_stats; /* rcpi information */ struct rcpi_info rcpi; @@ -2253,10 +2249,6 @@ struct hdd_context_s { uint32_t num_derived_addr; unsigned long provisioned_intf_addr_mask; unsigned long derived_intf_addr_mask; -#ifdef WLAN_POWER_DEBUGFS - /* mutex lock to block concurrent access */ - struct mutex power_stats_lock; -#endif struct hdd_cache_channels *original_channels; qdf_mutex_t cache_channel_lock; diff --git a/core/hdd/inc/wlan_hdd_sysfs.h b/core/hdd/inc/wlan_hdd_sysfs.h index 3d34791dbc60..79ff514dd541 100644 --- a/core/hdd/inc/wlan_hdd_sysfs.h +++ b/core/hdd/inc/wlan_hdd_sysfs.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 @@ -16,6 +16,10 @@ * PERFORMANCE OF THIS SOFTWARE. */ +#ifndef _WLAN_HDD_SYSFS_H_ +#define _WLAN_HDD_SYSFS_H_ + +#ifdef WLAN_SYSFS /** * hdd_sysfs_create_version_interface - create version interface * @@ -29,3 +33,13 @@ void hdd_sysfs_create_version_interface(void); * Return: none */ void hdd_sysfs_destroy_version_interface(void); +#else +static inline void hdd_sysfs_create_version_interface(void) +{ +} + +static inline void hdd_sysfs_destroy_version_interface(void) +{ +} +#endif +#endif diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index f607bd06b586..930cf98bddf2 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -4085,6 +4085,12 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, status = QDF_STATUS_E_FAILURE; hdd_debug("no available slot in conn_info. staId: %d cannot be stored", pRoamInfo->staId); + sme_delete_tdls_peer_sta(WLAN_HDD_GET_HAL_CTX + (pAdapter), + pAdapter->sessionId, + pRoamInfo-> + peerMac.bytes); + } pAdapter->tdlsAddStaStatus = status; } @@ -4267,7 +4273,8 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, tdlsConnInfo[staIdx]. peerMac, QDF_MAC_ADDR_SIZE); - pHddCtx->tdlsConnInfo[staIdx].staId = 0; + pHddCtx->tdlsConnInfo[staIdx].staId = + HDD_WLAN_INVALID_STA_ID; pHddCtx->tdlsConnInfo[staIdx]. sessionId = 255; @@ -5003,6 +5010,12 @@ static void hdd_roam_channel_switch_handler(hdd_adapter_t *adapter, hdd_debug("channel switch for session:%d to channel:%d", adapter->sessionId, roam_info->chan_info.chan_id); + /* Enable Roaming on the interface which was disabled before CSA */ + if (adapter->device_mode == QDF_STA_MODE) + sme_start_roaming(WLAN_HDD_GET_HAL_CTX(adapter), + adapter->sessionId, + REASON_DRIVER_ENABLED); + chan_change.chan = roam_info->chan_info.chan_id; chan_change.chan_params.ch_width = roam_info->chan_info.ch_width; diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 1ecf923053fc..fecc873469b8 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -9170,7 +9170,6 @@ hdd_validate_and_convert_info_mask(uint8_t *token, info_mask = hex_value; - info_mask |= WMI_ACTION_OUI_INFO_OUI; hdd_ext->info_mask = info_mask; if (!info_mask || !(info_mask & ~WMI_ACTION_OUI_INFO_OUI)) { @@ -9183,6 +9182,16 @@ hdd_validate_and_convert_info_mask(uint8_t *token, return false; } + /* + * If OUI bit is not set in the info presence, we need to ignore the + * OUI and OUI Data. Set OUI and OUI data length to 0 here. + */ + if (!(info_mask & WMI_ACTION_OUI_INFO_OUI)) { + hdd_ext->oui_length = 0; + hdd_ext->data_length = 0; + hdd_ext->data_mask_length = 0; + } + if (info_mask & WMI_ACTION_OUI_INFO_MAC_ADDRESS) { *action_token = HDD_ACTION_OUI_MAC_ADDR_TOKEN; return true; @@ -9351,11 +9360,6 @@ hdd_set_action_oui_ext(hdd_context_t *hdd_ctx, int ret = 0; QDF_STATUS qdf_status; - if (!hdd_ext.oui_length) { - hdd_err("Invalid oui length"); - return -EINVAL; - } - wmi_ext = qdf_mem_malloc(sizeof(*wmi_ext)); if (!wmi_ext) { hdd_err("Failed to allocate memory for action oui extension"); diff --git a/core/hdd/src/wlan_hdd_debugfs.c b/core/hdd/src/wlan_hdd_debugfs.c index c757a6be00c0..a7d5dd4a5813 100644 --- a/core/hdd/src/wlan_hdd_debugfs.c +++ b/core/hdd/src/wlan_hdd_debugfs.c @@ -31,6 +31,7 @@ #include <wlan_hdd_wowl.h> #include <cds_sched.h> #include <wlan_hdd_debugfs_llstat.h> +#include <wlan_hdd_request_manager.h> #define MAX_USER_COMMAND_SIZE_WOWL_ENABLE 8 #define MAX_USER_COMMAND_SIZE_WOWL_PATTERN 512 @@ -545,72 +546,65 @@ static ssize_t wcnss_patterngen_write(struct file *file, } #ifdef WLAN_POWER_DEBUGFS +struct power_stats_priv { + struct power_stats_response power_stats; +}; + +static void hdd_power_debugstats_dealloc(void *priv) +{ + struct power_stats_priv *stats = priv; + + if (stats->power_stats.debug_registers) { + qdf_mem_free(stats->power_stats.debug_registers); + stats->power_stats.debug_registers = NULL; + } +} + /** * hdd_power_debugstats_cb() - callback routine for Power stats debugs * @response: Pointer to Power stats response - * @context: Pointer to statsContext + * @context: Callback context * * Return: None */ static void hdd_power_debugstats_cb(struct power_stats_response *response, - void *context) + void *context) { - struct statsContext *stats_context; - struct power_stats_response *power_stats; - hdd_adapter_t *adapter; - uint32_t power_stats_len; - uint32_t stats_registers_len; + struct hdd_request *request; + struct power_stats_priv *priv; + uint32_t *debug_registers; + uint32_t debug_registers_len; ENTER(); - if (!context) { - hdd_err("context is NULL"); - return; - } - - stats_context = (struct statsContext *)context; - spin_lock(&hdd_context_lock); - adapter = stats_context->pAdapter; - if ((POWER_STATS_MAGIC != stats_context->magic) || - (!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) { - spin_unlock(&hdd_context_lock); - hdd_err("Invalid context, adapter [%pK] magic [%08x]", - adapter, stats_context->magic); + request = hdd_request_get(context); + if (!request) { + hdd_err("Obsolete request"); return; } - stats_context->magic = 0; - stats_registers_len = (sizeof(response->debug_registers[0]) * - response->num_debug_register); - power_stats_len = stats_registers_len + sizeof(*power_stats); - adapter->chip_power_stats = qdf_mem_malloc(power_stats_len); - if (!adapter->chip_power_stats) { - hdd_err("Power stats memory alloc fails!"); - goto exit_stats_cb; - } - - power_stats = adapter->chip_power_stats; - power_stats->cumulative_sleep_time_ms - = response->cumulative_sleep_time_ms; - power_stats->cumulative_total_on_time_ms - = response->cumulative_total_on_time_ms; - power_stats->deep_sleep_enter_counter - = response->deep_sleep_enter_counter; - power_stats->last_deep_sleep_enter_tstamp_ms - = response->last_deep_sleep_enter_tstamp_ms; - power_stats->debug_register_fmt - = response->debug_register_fmt; - power_stats->num_debug_register - = response->num_debug_register; - - power_stats->debug_registers = (uint32_t *)(power_stats + 1); - - qdf_mem_copy(power_stats->debug_registers, - response->debug_registers, stats_registers_len); - -exit_stats_cb: - complete(&stats_context->completion); - spin_unlock(&hdd_context_lock); + priv = hdd_request_priv(request); + + /* copy fixed-sized data */ + priv->power_stats = *response; + + /* copy variable-size data */ + if (response->num_debug_register) { + debug_registers_len = (sizeof(response->debug_registers[0]) * + response->num_debug_register); + debug_registers = qdf_mem_malloc(debug_registers_len); + priv->power_stats.debug_registers = debug_registers; + if (debug_registers) { + qdf_mem_copy(debug_registers, + response->debug_registers, + debug_registers_len); + } else { + hdd_err("Power stats memory alloc fails!"); + priv->power_stats.num_debug_register = 0; + } + } + hdd_request_complete(request); + hdd_request_put(request); EXIT(); } @@ -629,12 +623,20 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file, { hdd_adapter_t *adapter; hdd_context_t *hdd_ctx; - static struct statsContext context; + QDF_STATUS status; struct power_stats_response *chip_power_stats; ssize_t ret_cnt = 0; - int rc = 0, j; + int j; unsigned int len = 0; - char *power_debugfs_buf; + char *power_debugfs_buf = NULL; + void *cookie; + struct hdd_request *request; + struct power_stats_priv *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_POWER_STATS, + .dealloc = hdd_power_debugstats_dealloc, + }; ENTER(); adapter = (hdd_adapter_t *)file->private_data; @@ -651,52 +653,39 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file, if (!wlan_hdd_modules_are_enabled(hdd_ctx)) return -EINVAL; - mutex_lock(&hdd_ctx->power_stats_lock); - if (adapter->chip_power_stats) - qdf_mem_free(adapter->chip_power_stats); - - adapter->chip_power_stats = NULL; - context.pAdapter = adapter; - context.magic = POWER_STATS_MAGIC; - - init_completion(&context.completion); + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return -ENOMEM; + } + cookie = hdd_request_cookie(request); - if (QDF_STATUS_SUCCESS != - sme_power_debug_stats_req(hdd_ctx->hHal, - hdd_power_debugstats_cb, - &context)) { - mutex_unlock(&hdd_ctx->power_stats_lock); + status = sme_power_debug_stats_req(hdd_ctx->hHal, + hdd_power_debugstats_cb, + cookie); + if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("chip power stats request failed"); - return -EINVAL; + ret_cnt = -EINVAL; + goto cleanup; } - rc = wait_for_completion_timeout(&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_POWER_STATS)); - if (!rc) { - mutex_unlock(&hdd_ctx->power_stats_lock); + ret_cnt = hdd_request_wait_for_response(request); + if (ret_cnt) { hdd_err("Target response timed out Power stats"); - /* Invalidate the Stats context magic */ - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); - return -ETIMEDOUT; + ret_cnt = -ETIMEDOUT; + goto cleanup; } - chip_power_stats = adapter->chip_power_stats; - if (!chip_power_stats) { - mutex_unlock(&hdd_ctx->power_stats_lock); - hdd_err("Power stats retrieval fails!"); - return -EINVAL; - } + priv = hdd_request_priv(request); + chip_power_stats = &priv->power_stats; + power_debugfs_buf = qdf_mem_malloc(POWER_DEBUGFS_BUFFER_MAX_LEN); if (!power_debugfs_buf) { - qdf_mem_free(chip_power_stats); - adapter->chip_power_stats = NULL; - mutex_unlock(&hdd_ctx->power_stats_lock); hdd_err("Power stats buffer alloc fails!"); - return -EINVAL; + ret_cnt = -EINVAL; + goto cleanup; } len += scnprintf(power_debugfs_buf, POWER_DEBUGFS_BUFFER_MAX_LEN, @@ -724,13 +713,15 @@ static ssize_t __wlan_hdd_read_power_debugfs(struct file *file, j = chip_power_stats->num_debug_register; } - qdf_mem_free(chip_power_stats); - adapter->chip_power_stats = NULL; - mutex_unlock(&hdd_ctx->power_stats_lock); - ret_cnt = simple_read_from_buffer(buf, count, pos, power_debugfs_buf, len); - qdf_mem_free(power_debugfs_buf); + +cleanup: + if (power_debugfs_buf) + qdf_mem_free(power_debugfs_buf); + + hdd_request_put(request); + return ret_cnt; } @@ -876,43 +867,18 @@ static const struct file_operations fops_powerdebugs = { */ static QDF_STATUS wlan_hdd_init_power_stats_debugfs(hdd_adapter_t *adapter) { - hdd_context_t *hdd_ctx; - if (!debugfs_create_file("power_stats", 00400 | 00040 | 00004, adapter->debugfs_phy, adapter, &fops_powerdebugs)) return QDF_STATUS_E_FAILURE; - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (hdd_ctx) - mutex_init(&hdd_ctx->power_stats_lock); - return QDF_STATUS_SUCCESS; } - -/** - * wlan_hdd_deinit_power_stats_debugfs() - API to deinit power stats debugfs - * @hdd_ctx: hdd context pointer - * - * Return: None - */ -static void wlan_hdd_deinit_power_stats_debugfs(hdd_adapter_t *adapter) -{ - hdd_context_t *hdd_ctx; - - hdd_ctx = WLAN_HDD_GET_CTX(adapter); - if (hdd_ctx) - mutex_destroy(&hdd_ctx->power_stats_lock); -} #else static QDF_STATUS wlan_hdd_init_power_stats_debugfs(hdd_adapter_t *adapter) { return QDF_STATUS_SUCCESS; } - -static void wlan_hdd_deinit_power_stats_debugfs(hdd_adapter_t *adapter) -{ -} #endif /** @@ -970,7 +936,6 @@ QDF_STATUS hdd_debugfs_init(hdd_adapter_t *adapter) */ void hdd_debugfs_exit(hdd_adapter_t *adapter) { - wlan_hdd_deinit_power_stats_debugfs(adapter); debugfs_remove_recursive(adapter->debugfs_phy); } #endif /* #ifdef WLAN_OPEN_SOURCE */ diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 507ae0145a38..c6824643b1d3 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -770,6 +770,11 @@ static int __wlan_hdd_bus_suspend_noirq(void) return err; } + if (hdd_ctx->driver_status == DRIVER_MODULES_OPENED) { + hdd_err("Driver open state, can't suspend"); + return -EAGAIN; + } + if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver Module closed return success"); return 0; @@ -851,6 +856,11 @@ static int __wlan_hdd_bus_resume(void) return status; } + if (hdd_ctx->driver_status == DRIVER_MODULES_OPENED) { + hdd_err("Driver open state, can't suspend"); + return -EAGAIN; + } + if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) { hdd_debug("Driver Module closed; return success"); return 0; diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index af93917b5634..f64f9dccbfe0 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -23,6 +23,7 @@ #include "wlan_hdd_trace.h" #include "wlan_hdd_ioctl.h" #include "wlan_hdd_power.h" +#include "wlan_hdd_request_manager.h" #include "wlan_hdd_driver_ops.h" #include "cds_concurrency.h" #include "wlan_hdd_hostapd.h" @@ -2520,46 +2521,25 @@ sme_config_free: } #endif +struct link_status_priv { + uint8_t link_status; +}; + static void hdd_get_link_status_cb(uint8_t status, void *context) { - struct statsContext *pLinkContext; - hdd_adapter_t *adapter; - - if (NULL == context) { - hdd_err("Bad context [%pK]", context); - return; - } - - pLinkContext = context; - adapter = pLinkContext->pAdapter; - - spin_lock(&hdd_context_lock); + struct hdd_request *request; + struct link_status_priv *priv; - if ((NULL == adapter) || - (LINK_STATUS_MAGIC != pLinkContext->magic)) { - /* - * the caller presumably timed out so there is - * nothing we can do - */ - spin_unlock(&hdd_context_lock); - hdd_warn("Invalid context, adapter [%pK] magic [%08x]", - adapter, pLinkContext->magic); + request = hdd_request_get(context); + if (!request) { + hdd_err("Obsolete request"); return; } - /* context is valid so caller is still waiting */ - - /* paranoia: invalidate the magic */ - pLinkContext->magic = 0; - - /* copy over the status */ - adapter->linkStatus = status; - - /* notify the caller */ - complete(&pLinkContext->completion); - - /* serialization is complete */ - spin_unlock(&hdd_context_lock); + priv = hdd_request_priv(request); + priv->link_status = status; + hdd_request_complete(request); + hdd_request_put(request); } /** @@ -2579,9 +2559,15 @@ static int wlan_hdd_get_link_status(hdd_adapter_t *adapter) hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); - static struct statsContext context; QDF_STATUS hstatus; - unsigned long rc; + int ret; + void *cookie; + struct hdd_request *request; + struct link_status_priv *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_LINK_STATUS, + }; if (cds_is_driver_recovering() || cds_is_driver_in_bad_state()) { hdd_warn("Recovery in Progress. State: 0x%x Ignore!!!", @@ -2606,26 +2592,38 @@ static int wlan_hdd_get_link_status(hdd_adapter_t *adapter) return 0; } - init_completion(&context.completion); - context.pAdapter = adapter; - context.magic = LINK_STATUS_MAGIC; + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return 0; + } + cookie = hdd_request_cookie(request); + hstatus = sme_get_link_status(WLAN_HDD_GET_HAL_CTX(adapter), hdd_get_link_status_cb, - &context, adapter->sessionId); + cookie, adapter->sessionId); if (QDF_STATUS_SUCCESS != hstatus) { hdd_err("Unable to retrieve link status"); /* return a cached value */ } else { /* request is sent -- wait for the response */ - rc = wait_for_completion_timeout(&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_LINK_STATUS)); - if (!rc) + ret = hdd_request_wait_for_response(request); + if (ret) { hdd_err("SME timed out while retrieving link status"); + /* return a cached value */ + } else { + /* update the adapter with the fresh results */ + priv = hdd_request_priv(request); + adapter->linkStatus = priv->link_status; + } } - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. + */ + hdd_request_put(request); /* either callback updated adapter stats or it has cached data */ return adapter->linkStatus; diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c index 03da26eebc20..92fbbf6575e3 100644 --- a/core/hdd/src/wlan_hdd_ipa.c +++ b/core/hdd/src/wlan_hdd_ipa.c @@ -805,6 +805,34 @@ static inline bool hdd_ipa_uc_sta_is_enabled(hdd_context_t *hdd_ctx) return HDD_IPA_IS_CONFIG_ENABLED(hdd_ctx, HDD_IPA_UC_STA_ENABLE_MASK); } + +/** + * hdd_ipa_uc_sta_only_offload_is_enabled() + * + * STA only IPA offload is needed on MDM platforms to support + * tethering scenarios in STA-SAP configurations when SAP is idle. + * + * Currently in STA-SAP configurations, IPA pipes are enabled only + * when a wifi client is connected to SAP. + * + * Impact of this API is only limited to when IPA pipes are enabled + * and disabled. To take effect, HDD_IPA_UC_STA_ENABLE_MASK needs to + * set to 1. + * + * Return: true if MDM_PLATFORM is defined, false otherwise + */ +#ifdef MDM_PLATFORM +static inline bool hdd_ipa_uc_sta_only_offload_is_enabled(void) +{ + return true; +} +#else +static inline bool hdd_ipa_uc_sta_only_offload_is_enabled(void) +{ + return false; +} +#endif + /** * hdd_ipa_uc_sta_reset_sta_connected() - Reset sta_connected flag * @hdd_ipa: Global HDD IPA context @@ -2228,6 +2256,12 @@ static int hdd_ipa_wdi_enable_pipes(struct hdd_ipa_priv *hdd_ipa) struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); int result; + if (!pdev) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "pdev is NULL"); + result = QDF_STATUS_E_FAILURE; + return result; + } + /* Map IPA SMMU for all Rx hash table */ result = ol_txrx_rx_hash_smmu_map(pdev, true); if (result) { @@ -2291,6 +2325,12 @@ static int hdd_ipa_wdi_disable_pipes(struct hdd_ipa_priv *hdd_ipa) struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX); int result; + if (!pdev) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "pdev is NULL"); + result = QDF_STATUS_E_FAILURE; + return result; + } + HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, "Disable RX PIPE"); result = ipa_suspend_wdi_pipe(hdd_ipa->rx_pipe_handle); if (result) { @@ -6749,7 +6789,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, struct ipa_msg_meta meta; struct ipa_wlan_msg *msg; struct ipa_wlan_msg_ex *msg_ex = NULL; - int ret; + int ret = 0; if (hdd_validate_adapter(adapter)) { HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "Invalid adapter: 0x%pK", @@ -6874,7 +6914,8 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, } if (hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx) && - (hdd_ipa->sap_num_connected_sta > 0) && + (hdd_ipa->sap_num_connected_sta > 0 || + hdd_ipa_uc_sta_only_offload_is_enabled()) && !hdd_ipa->sta_connected) { qdf_mutex_release(&hdd_ipa->event_lock); hdd_ipa_uc_offload_enable_disable(adapter, @@ -6882,6 +6923,22 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, qdf_mutex_acquire(&hdd_ipa->event_lock); } + if (!hdd_ipa_uc_sta_only_offload_is_enabled()) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, + "IPA uC STA only offload not enabled"); + } else if (!hdd_ipa->sap_num_connected_sta && + !hdd_ipa->sta_connected) { + ret = hdd_ipa_uc_handle_first_con(hdd_ipa); + if (ret) { + qdf_mutex_release(&hdd_ipa->event_lock); + HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, + "handle 1st conn ret %d", ret); + hdd_ipa_uc_offload_enable_disable(adapter, + SIR_STA_RX_DATA_OFFLOAD, false); + goto end; + } + } + hdd_ipa->vdev_to_iface[adapter->sessionId] = ((struct hdd_ipa_iface_context *) (adapter->ipa_context))->iface_id; @@ -6946,15 +7003,23 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, hdd_debug("%s: IPA UC OFFLOAD NOT ENABLED", msg_ex->name); } else { - /* Disable IPA UC TX PIPE when STA disconnected */ - if ((1 == hdd_ipa->num_iface) && + /* + * Disable IPA UC TX PIPE when + * 1. STA is the last interface, Or + * 2. STA only offload enabled and no clients connected + * to SAP + */ + if (((1 == hdd_ipa->num_iface) || + (hdd_ipa_uc_sta_only_offload_is_enabled() && + !hdd_ipa->sap_num_connected_sta)) && hdd_ipa_is_fw_wdi_actived(hdd_ipa->hdd_ctx) && !hdd_ipa->ipa_pipes_down) hdd_ipa_uc_handle_last_discon(hdd_ipa); } if (hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx) && - (hdd_ipa->sap_num_connected_sta > 0)) { + (hdd_ipa->sap_num_connected_sta > 0 || + hdd_ipa_uc_sta_only_offload_is_enabled())) { qdf_mutex_release(&hdd_ipa->event_lock); hdd_ipa_uc_offload_enable_disable(adapter, SIR_STA_RX_DATA_OFFLOAD, false); @@ -7042,7 +7107,8 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, if (hdd_ipa->sap_num_connected_sta == 0 && hdd_ipa->uc_loaded == true) { if (hdd_ipa_uc_sta_is_enabled(hdd_ipa->hdd_ctx) && - hdd_ipa->sta_connected) { + hdd_ipa->sta_connected && + !hdd_ipa_uc_sta_only_offload_is_enabled()) { qdf_mutex_release(&hdd_ipa->event_lock); hdd_ipa_uc_offload_enable_disable( hdd_get_adapter(hdd_ipa->hdd_ctx, @@ -7051,8 +7117,15 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, qdf_mutex_acquire(&hdd_ipa->event_lock); } - ret = hdd_ipa_uc_handle_first_con(hdd_ipa); - if (ret) { + /* + * IPA pipes already enabled if STA only offload + * is enabled and STA is connected. + */ + if (hdd_ipa_uc_sta_only_offload_is_enabled() && + hdd_ipa->sta_connected) { + HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG, + "IPA pipes already enabled"); + } else if (hdd_ipa_uc_handle_first_con(hdd_ipa)) { HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR, "%s: handle 1st con ret %d", adapter->dev->name, ret); @@ -7070,7 +7143,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, qdf_mutex_release(&hdd_ipa->event_lock); } - return ret; + return -EPERM; } } @@ -7139,9 +7212,15 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id, } hdd_ipa->sap_num_connected_sta--; - /* Disable IPA UC TX PIPE when last STA disconnected */ + /* + * Disable IPA UC TX PIPE when + * 1. last client disconnected SAP and + * 2. STA is not connected + */ if (!hdd_ipa->sap_num_connected_sta && - hdd_ipa->uc_loaded == true) { + (hdd_ipa->uc_loaded == true) && + !(hdd_ipa_uc_sta_only_offload_is_enabled() && + hdd_ipa->sta_connected)) { if ((false == hdd_ipa->resource_unloading) && hdd_ipa_is_fw_wdi_actived(hdd_ipa->hdd_ctx) && !hdd_ipa->ipa_pipes_down) { diff --git a/core/hdd/src/wlan_hdd_lro.c b/core/hdd/src/wlan_hdd_lro.c index fca8b5f86697..1483ddf84762 100644 --- a/core/hdd/src/wlan_hdd_lro.c +++ b/core/hdd/src/wlan_hdd_lro.c @@ -462,6 +462,22 @@ static void *hdd_init_lro_mgr(void) } /** + * hdd_is_lro_enabled() - Is LRO enabled + * @hdd_ctx: HDD context + * + * This function checks if LRO is enabled in HDD context. + * + * Return: 0 - success, < 0 - failure + */ +int hdd_is_lro_enabled(hdd_context_t *hdd_ctx) +{ + if (hdd_ctx->ol_enable != CFG_LRO_ENABLED) + return -EOPNOTSUPP; + + return 0; +} + +/** * hdd_lro_enable() - enable LRO * @hdd_ctx: HDD context * @adapter: HDD adapter diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 8efe2de0fc67..072ce80a5a9e 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1129,7 +1129,9 @@ static void hdd_update_hw_dbs_capable(hdd_context_t *hdd_ctx) ((cfg_ini->dual_mac_feature_disable == ENABLE_DBS_CXN_AND_SCAN) || (cfg_ini->dual_mac_feature_disable == - ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF))) + ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF) || + (cfg_ini->dual_mac_feature_disable == + ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN))) hw_dbs_capable = 1; sme_update_hw_dbs_capable(hdd_ctx->hHal, hw_dbs_capable); @@ -2530,7 +2532,8 @@ static int __hdd_open(struct net_device *dev) goto err_hdd_hdd_init_deinit_lock; set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); - hdd_info("%s interface up", dev->name); + hdd_info("%s interface up, event-flags: %lx ", dev->name, + adapter->event_flags); if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) { hdd_info("Enabling Tx Queues"); @@ -2614,9 +2617,9 @@ static int __hdd_stop(struct net_device *dev) * Disable TX on the interface, after this hard_start_xmit() will not * be called on that interface */ - hdd_info("Disabling queues, adapter device mode: %s(%d)", + hdd_info("Disabling queues, adapter device mode: %s(%d), event-flags: %lx ", hdd_device_mode_to_string(adapter->device_mode), - adapter->device_mode); + adapter->device_mode, adapter->event_flags); wlan_hdd_netif_queue_control(adapter, WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, @@ -3408,6 +3411,46 @@ static QDF_STATUS hdd_check_and_init_tdls(hdd_adapter_t *adapter, uint32_t type) } #endif +/** + * hdd_update_ini_params() - Update config values to default ini param values + * @hdd_ctx: hdd context + * + * This function is used to update the specific config values that can change + * at run time to its default ini param values. For example in LONU driver + * if initial_scan_no_dfs_chnl is set to 1 by default, after scan request it + * is setting to 0 in csr_scan_request() which leads to scan DFS channels also. + * So, we need to update initial_scan_no_dfs_chnl to its default ini value. + * + * Return: QDF_STATUS + */ +static QDF_STATUS hdd_update_ini_params(hdd_context_t *hdd_ctx) +{ + QDF_STATUS status; + tSmeConfigParams *sme_config; + + sme_config = qdf_mem_malloc(sizeof(*sme_config)); + if (!sme_config) { + hdd_err("unable to allocate sme_config"); + return QDF_STATUS_E_NOMEM; + } + + status = sme_get_config_param(hdd_ctx->hHal, sme_config); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("sme get config failed"); + goto err; + } + + sme_config->csrConfig.initial_scan_no_dfs_chnl = + hdd_ctx->config->initial_scan_no_dfs_chnl; + + status = sme_update_config(hdd_ctx->hHal, sme_config); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("sme update config failed"); +err: + qdf_mem_free(sme_config); + return status; +} + QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter) { struct net_device *pWlanDev = adapter->dev; @@ -3565,6 +3608,12 @@ QDF_STATUS hdd_init_station_mode(hdd_adapter_t *adapter) /* rcpi info initialization */ qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi)); + if ((adapter->device_mode == QDF_STA_MODE) || + (adapter->device_mode == QDF_P2P_CLIENT_MODE)) { + ret_val = hdd_update_ini_params(hdd_ctx); + return ret_val; + } + return QDF_STATUS_SUCCESS; error_tdls_init: @@ -4792,7 +4841,7 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) { hdd_err("session %d is not open %lu", - adapter->device_mode, adapter->event_flags); + adapter->sessionId, adapter->event_flags); return -ENODEV; } diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c index 2bd96b39c0cc..902c8d2f1b98 100644 --- a/core/hdd/src/wlan_hdd_power.c +++ b/core/hdd/src/wlan_hdd_power.c @@ -1599,6 +1599,7 @@ void hdd_is_interface_down_during_ssr(hdd_context_t *hdd_ctx) while (NULL != adapternode && QDF_STATUS_SUCCESS == status) { adapter = adapternode->pAdapter; if (test_bit(DOWN_DURING_SSR, &adapter->event_flags)) { + clear_bit(DOWN_DURING_SSR, &adapter->event_flags); hdd_stop_adapter(hdd_ctx, adapter, true); clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags); } @@ -1990,6 +1991,13 @@ static int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, return rc; mutex_lock(&pHddCtx->iface_change_lock); + + if (pHddCtx->driver_status == DRIVER_MODULES_OPENED) { + mutex_unlock(&pHddCtx->iface_change_lock); + hdd_err("Driver open state, can't suspend"); + return -EAGAIN; + } + if (pHddCtx->driver_status != DRIVER_MODULES_ENABLED) { mutex_unlock(&pHddCtx->iface_change_lock); hdd_debug("Driver Modules not Enabled "); diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 7c7a8a70a9e2..786b6723187f 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -3877,6 +3877,7 @@ int wlan_hdd_tdls_add_station(struct wiphy *wiphy, unsigned long rc; int ret; int rate_idx; + hdd_station_ctx_t *hdd_sta_ctx; ENTER(); @@ -3895,6 +3896,26 @@ int wlan_hdd_tdls_add_station(struct wiphy *wiphy, return -ENOTSUPP; } + hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + + /* + * STA or P2P client should be connected and authenticated before + * adding TDLS STA. + */ + if ((eConnectionState_Associated != + hdd_sta_ctx->conn_info.connState) || + (false == hdd_sta_ctx->conn_info.uIsAuthenticated)) { + hdd_debug("STA is not connected or not authenticated. connState %u, uIsAuthenticated %u", + hdd_sta_ctx->conn_info.connState, + hdd_sta_ctx->conn_info.uIsAuthenticated); + return -EAGAIN; + } + + if (!cds_check_is_tdls_allowed(pAdapter->device_mode)) { + hdd_debug("TDLS not allowed, reject TDLS add station"); + return -EPERM; + } + mutex_lock(&pHddCtx->tdls_lock); pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac); diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index e8640faab7b4..1367eca44ffb 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -1682,7 +1682,7 @@ static inline void hdd_register_rx_ol(void) hdd_ctx->tcp_delack_on = 0; - if (hdd_ctx->ol_enable == CFG_LRO_ENABLED) { + if (!hdd_is_lro_enabled(hdd_ctx)) { hdd_ctx->receive_offload_cb = hdd_lro_rx; /* Register the flush callback */ hdd_lro_create(); diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index 7c831aacb4c6..bfb3d7cb2476 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -827,6 +827,8 @@ typedef struct sAniSirLim { uint32_t scan_id, uint32_t flags); QDF_STATUS(*sme_msg_callback) (tHalHandle hal, cds_msg_t *msg); + QDF_STATUS(*stop_roaming_callback) + (tHalHandle hal, uint8_t session_id, uint8_t reason); uint8_t retry_packet_cnt; uint8_t scan_disabled; uint8_t beacon_probe_rsp_cnt_per_scan; diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h index 890979d79b99..43bc98147283 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 1 #define QWLAN_VERSION_PATCH 1 -#define QWLAN_VERSION_EXTRA "Z" -#define QWLAN_VERSION_BUILD 63 +#define QWLAN_VERSION_EXTRA "A" +#define QWLAN_VERSION_BUILD 65 -#define QWLAN_VERSIONSTR "5.1.1.63Z" +#define QWLAN_VERSIONSTR "5.1.1.65A" #endif /* QWLAN_VERSION_H */ diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 9f282ccae43e..89540f72606f 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -517,6 +517,7 @@ typedef struct sSirSmeReadyReq { void *csr_roam_synch_cb; void *pe_roam_synch_cb; void *sme_msg_cb; + void *stop_roaming_cb; } tSirSmeReadyReq, *tpSirSmeReadyReq; /** diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index aa2663b1f879..9fd6a95ede24 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -83,6 +83,10 @@ typedef struct join_params { tSirResultCodes result_code; } join_params; +struct session_params { + uint16_t session_id; +}; + typedef struct sPESession /* Added to Support BT-AMP */ { /* To check session table is in use or free */ @@ -443,6 +447,8 @@ typedef struct sPESession /* Added to Support BT-AMP */ uint8_t is_key_installed; /* timer for reseting protection fileds at regular intervals */ qdf_mc_timer_t protection_fields_reset_timer; + /* timer to decrement CSA/ECSA count */ + qdf_mc_timer_t ap_ecsa_timer; void *mac_ctx; /* * variable to store state of various protection struct like diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index c14be9b74fd8..1ac14a200920 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -890,6 +890,7 @@ tSirRetStatus pe_start(tpAniSirGlobal pMac) void pe_stop(tpAniSirGlobal pMac) { lim_cleanup(pMac); + pe_debug(" PE STOP: Set LIM state to eLIM_MLM_OFFLINE_STATE"); SET_LIM_MLM_STATE(pMac, eLIM_MLM_OFFLINE_STATE); return; } @@ -898,6 +899,7 @@ static void pe_free_nested_messages(tSirMsgQ *msg) { switch (msg->type) { case WMA_SET_LINK_STATE_RSP: + pe_debug("pe_free_nested_messages: WMA_SET_LINK_STATE_RSP"); qdf_mem_free(((tpLinkStateParams) msg->bodyptr)->callbackArg); break; default: diff --git a/core/mac/src/pe/lim/lim_process_deauth_frame.c b/core/mac/src/pe/lim/lim_process_deauth_frame.c index 1dac3953a249..b125c0626a12 100644 --- a/core/mac/src/pe/lim/lim_process_deauth_frame.c +++ b/core/mac/src/pe/lim/lim_process_deauth_frame.c @@ -501,18 +501,20 @@ void lim_perform_deauth(tpAniSirGlobal mac_ctx, tpPESession pe_session, } if ((sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || - (sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) { + (sta_ds->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) || + sta_ds->sta_deletion_in_progress) { /** * Already in the process of deleting context for the peer * and received Deauthentication frame. Log and Ignore. */ - pe_err("received Deauth frame from peer that is in state %X, addr " - MAC_ADDRESS_STR, sta_ds->mlmStaContext.mlmState, - MAC_ADDR_ARRAY(addr)); + pe_debug("Deletion is in progress (%d) for peer:%pM in mlmState %d", + sta_ds->sta_deletion_in_progress, addr, + sta_ds->mlmStaContext.mlmState); return; } sta_ds->mlmStaContext.disassocReason = (tSirMacReasonCodes) rc; sta_ds->mlmStaContext.cleanupTrigger = eLIM_PEER_ENTITY_DEAUTH; + sta_ds->sta_deletion_in_progress = true; /* / Issue Deauth Indication to SME. */ qdf_mem_copy((uint8_t *) &mlmDeauthInd.peerMacAddr, diff --git a/core/mac/src/pe/lim/lim_process_disassoc_frame.c b/core/mac/src/pe/lim/lim_process_disassoc_frame.c index 2819fa18bdda..b24916fd99a0 100644 --- a/core/mac/src/pe/lim/lim_process_disassoc_frame.c +++ b/core/mac/src/pe/lim/lim_process_disassoc_frame.c @@ -281,16 +281,18 @@ lim_process_disassoc_frame(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo, } if ((pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_STA_RSP_STATE) || - (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE)) { + (pStaDs->mlmStaContext.mlmState == eLIM_MLM_WT_DEL_BSS_RSP_STATE) || + pStaDs->sta_deletion_in_progress) { /** * Already in the process of deleting context for the peer * and received Disassociation frame. Log and Ignore. */ - pe_err("received Disassoc frame in state: %d from" - MAC_ADDRESS_STR, pStaDs->mlmStaContext.mlmState, - MAC_ADDR_ARRAY(pHdr->sa)); + pe_debug("Deletion is in progress (%d) for peer:%pM in mlmState %d", + pStaDs->sta_deletion_in_progress, pHdr->sa, + pStaDs->mlmStaContext.mlmState); return; } + pStaDs->sta_deletion_in_progress = true; lim_disassoc_tdls_peers(pMac, psessionEntry, pHdr->sa); if (pStaDs->mlmStaContext.mlmState != eLIM_MLM_LINK_ESTABLISHED_STATE) { /** diff --git a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c index b86b8f8e0d50..9af8233c980f 100644 --- a/core/mac/src/pe/lim/lim_process_mlm_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_mlm_req_messages.c @@ -764,8 +764,18 @@ static void lim_post_join_set_link_state_callback(tpAniSirGlobal mac, void *callback_arg, bool status) { uint8_t chan_num, sec_chan_offset; - tpPESession session_entry = (tpPESession) callback_arg; + struct session_params *session_cb_param = + (struct session_params *) callback_arg; tLimMlmJoinCnf mlm_join_cnf; + tpPESession session_entry = pe_find_session_by_session_id(mac, + session_cb_param->session_id); + if (session_entry == NULL) { + pe_err("sessionId:%d does not exist", + session_cb_param->session_id); + qdf_mem_free(session_cb_param); + return; + } + qdf_mem_free(session_cb_param); pe_debug("Sessionid %d set link state(%d) cb status: %d", session_entry->peSessionId, session_entry->limMlmState, @@ -835,6 +845,7 @@ lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx, tLimMlmJoinCnf mlm_join_cnf; tpPESession session = (tpPESession) ctx; tSirLinkState lnk_state; + struct session_params *pe_session_param = NULL; if (QDF_STATUS_SUCCESS != status) { pe_err("Sessionid %d Suspend link(NOTIFY_BSS) failed. Still proceeding with join", @@ -850,11 +861,18 @@ lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx, pe_debug("[lim_process_mlm_join_req]: lnk_state: %d", lnk_state); + pe_session_param = qdf_mem_malloc(sizeof(struct session_params)); + if (pe_session_param != NULL) { + pe_session_param->session_id = session->peSessionId; + } else { + pe_err("insufficient memory"); + goto error; + } if (lim_set_link_state(mac_ctx, lnk_state, session->pLimMlmJoinReq->bssDescription.bssId, session->selfMacAddr, lim_post_join_set_link_state_callback, - session) != eSIR_SUCCESS) { + pe_session_param) != eSIR_SUCCESS) { pe_err("SessionId:%d lim_set_link_state to eSIR_LINK_PREASSOC_STATE Failed!!", session->peSessionId); lim_print_mac_addr(mac_ctx, @@ -863,6 +881,7 @@ lim_process_mlm_post_join_suspend_link(tpAniSirGlobal mac_ctx, session->limMlmState = eLIM_MLM_IDLE_STATE; MTRACE(mac_trace(mac_ctx, TRACE_CODE_MLM_STATE, session->peSessionId, session->limMlmState)); + qdf_mem_free(pe_session_param); goto error; } diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 0fad542d3825..6f13e40044a9 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -539,6 +539,7 @@ static bool __lim_process_sme_sys_ready_ind(tpAniSirGlobal pMac, uint32_t *pMsgB pe_register_callbacks_with_wma(pMac, ready_req); pMac->lim.add_bssdescr_callback = ready_req->add_bssdescr_cb; pMac->lim.sme_msg_callback = ready_req->sme_msg_cb; + pMac->lim.stop_roaming_callback = ready_req->stop_roaming_cb; } pe_debug("sending WMA_SYS_READY_IND msg to HAL"); MTRACE(mac_trace_msg_tx(pMac, NO_SESSION, msg.type)); @@ -628,6 +629,7 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) uint32_t chanwidth; struct vdev_type_nss *vdev_type_nss; tSirRetStatus cfg_get_wmi_dfs_master_param = eSIR_SUCCESS; + struct sir_hw_mode_params hw_mode; /* FEATURE_WLAN_DIAG_SUPPORT */ #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM @@ -889,7 +891,14 @@ __lim_handle_sme_start_bss_request(tpAniSirGlobal mac_ctx, uint32_t *msg_buf) session->ch_center_freq_seg1 = 0; } } - + /* check for the current HW index to update nss */ + if (wma_is_hw_dbs_capable() && + (wma_get_current_hw_mode(&hw_mode) == QDF_STATUS_SUCCESS) && + hw_mode.dbs_cap) { + session->nss = 1; + pe_debug("HW_mode is DBS .Nss set to [%d]", + session->nss); + } if (session->vhtCapability && (session->ch_width > CH_WIDTH_80MHZ)) { session->nss = 1; @@ -6124,18 +6133,7 @@ static void lim_process_sme_dfs_csa_ie_request(tpAniSirGlobal mac_ctx, dfs_csa_ie_req->ch_params.center_freq_seg0; skip_vht: /* Send CSA IE request from here */ - if (sch_set_fixed_beacon_fields(mac_ctx, session_entry) != - eSIR_SUCCESS) { - pe_err("Unable to set CSA IE in beacon"); - return; - } - - /* - * First beacon update request is sent here, the remaining updates are - * done when the FW responds back after sending the first beacon after - * the template update - */ - lim_send_beacon_ind(mac_ctx, session_entry); + lim_send_dfs_chan_sw_ie_update(mac_ctx, session_entry); if (dfs_csa_ie_req->ch_params.ch_width == CH_WIDTH_80MHZ) ch_offset = BW80; @@ -6153,6 +6151,7 @@ skip_vht: lim_send_chan_switch_action_frame(mac_ctx, session_entry->gLimChannelSwitch.primaryChannel, ch_offset, session_entry); + } /** diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index d21b1b12d15f..933972ad11c5 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -926,7 +926,12 @@ lim_send_sme_disassoc_ntf(tpAniSirGlobal pMac, pe_err("could not Add STA with assocId: %d", sta_ds->assocId); } - failure = true; + status = lim_prepare_disconnect_done_ind(pMac, &pMsg, + smesessionId, reasonCode, &peerMacAddr[0]); + if (!QDF_IS_STATUS_SUCCESS(status)) { + pe_err("Failed to prepare message"); + return; + } break; case eLIM_HOST_DISASSOC: @@ -2421,6 +2426,12 @@ void lim_handle_csa_offload_msg(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) (session_entry->dot11mode == WNI_CFG_DOT11_MODE_11G_ONLY))) session_entry->dot11mode = WNI_CFG_DOT11_MODE_11A; + /* Send RSO Stop to FW before triggering the vdev restart for CSA */ + if (mac_ctx->lim.stop_roaming_callback) + mac_ctx->lim.stop_roaming_callback(mac_ctx, + session_entry->smeSessionId, + eCsrDriverDisabled); + lim_prepare_for11h_channel_switch(mac_ctx, session_entry); csa_offload_ind->mesgType = eWNI_SME_CSA_OFFLOAD_EVENT; @@ -2564,32 +2575,6 @@ lim_send_sme_dfs_event_notify(tpAniSirGlobal pMac, uint16_t msgType, void *event return; } -/*-------------------------------------------------------------------------- - \brief lim_send_dfs_chan_sw_ie_update() - This timer handler updates the channel switch IE in beacon template - - \param pMac - pointer to global adapter context - \return - channel to scan from valid session else zero. - \sa - --------------------------------------------------------------------------*/ -static void -lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal pMac, tpPESession psessionEntry) -{ - - /* Update the beacon template and send to FW */ - if (sch_set_fixed_beacon_fields(pMac, psessionEntry) != eSIR_SUCCESS) { - pe_err("Unable to set CSA IE in beacon"); - return; - } - - /* Send update beacon template message */ - lim_send_beacon_ind(pMac, psessionEntry); - pe_debug("Updated CSA IE, IE COUNT: %d", - psessionEntry->gLimChannelSwitch.switchCount); - - return; -} - /** ----------------------------------------------------------------- \brief lim_send_sme_ap_channel_switch_resp() - sends eWNI_SME_CHANNEL_CHANGE_RSP @@ -2670,113 +2655,54 @@ lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac, return; } -/** ----------------------------------------------------------------- - \brief lim_process_beacon_tx_success_ind() - This function is used - explicitely to handle successful beacon transmission indication - from the FW. This is a generic event generated by the FW afer the - first beacon is sent out after the beacon template update by the - host - \param pMac - global mac structure - \param psessionEntry - session info - \return none - \sa - ----------------------------------------------------------------- */ -void -lim_process_beacon_tx_success_ind(tpAniSirGlobal pMac, uint16_t msgType, void *event) +void lim_process_beacon_tx_success_ind(tpAniSirGlobal mac_ctx, + uint16_t msg_type, void *event) { - /* Currently, this event is used only for DFS channel switch announcement - * IE update in the template. If required to be used for other IE updates - * add appropriate code by introducing a state variable - */ - tpPESession psessionEntry; - tSirMsgQ mmhMsg; - tSirSmeCSAIeTxCompleteRsp *pChanSwTxResponse; - struct sir_beacon_tx_complete_rsp *beacon_tx_comp_rsp_ptr; - uint8_t length = sizeof(tSirSmeCSAIeTxCompleteRsp); - tpSirFirstBeaconTxCompleteInd pBcnTxInd = + tpPESession session; + cds_msg_t msg = {0}; + struct sir_beacon_tx_complete_rsp *bcn_tx_comp_rsp; + tpSirFirstBeaconTxCompleteInd bcn_ind = (tSirFirstBeaconTxCompleteInd *) event; - uint8_t ch, ch_width; + QDF_STATUS status; - psessionEntry = pe_find_session_by_bss_idx(pMac, pBcnTxInd->bssIdx); - if (psessionEntry == NULL) { - pe_err("Session Does not exist for given sessionID"); + session = pe_find_session_by_bss_idx(mac_ctx, bcn_ind->bssIdx); + if (session == NULL) { + pe_err("Session does not exist for given sessionID"); return; } - pe_debug("role: %d swIe: %d opIe: %d", - GET_LIM_SYSTEM_ROLE(psessionEntry), - psessionEntry->dfsIncludeChanSwIe, - psessionEntry->gLimOperatingMode.present); - - if (LIM_IS_AP_ROLE(psessionEntry) && - true == psessionEntry->dfsIncludeChanSwIe) { + pe_debug("role: %d opIe: %d dfsIncludeChanSwIe:%d Switch count:%d", + GET_LIM_SYSTEM_ROLE(session), + session->gLimOperatingMode.present, + session->dfsIncludeChanSwIe, + session->gLimChannelSwitch.switchCount); - if (psessionEntry->gLimChannelSwitch.switchCount) { - /* Decrement the beacon switch count */ - psessionEntry->gLimChannelSwitch.switchCount--; - pe_debug("current beacon count %d", - psessionEntry->gLimChannelSwitch.switchCount); - } - - /* Send only 5 beacons with CSA IE Set in when a radar is detected */ - if (psessionEntry->gLimChannelSwitch.switchCount > 0) { - /* - * Send the next beacon with updated CSA IE count - */ - lim_send_dfs_chan_sw_ie_update(pMac, psessionEntry); - - ch = psessionEntry->gLimChannelSwitch.primaryChannel; - ch_width = psessionEntry->gLimChannelSwitch.ch_width; - if (pMac->sap.SapDfsInfo.dfs_beacon_tx_enhanced) - /* Send Action frame after updating beacon */ - lim_send_chan_switch_action_frame(pMac, - ch, ch_width, psessionEntry); - - } else { - /* Done with CSA IE update, send response back to SME */ - psessionEntry->gLimChannelSwitch.switchCount = 0; - if (pMac->sap.SapDfsInfo.disable_dfs_ch_switch == false) - psessionEntry->gLimChannelSwitch.switchMode = 0; - psessionEntry->dfsIncludeChanSwIe = false; - psessionEntry->dfsIncludeChanWrapperIe = false; - - pChanSwTxResponse = (tSirSmeCSAIeTxCompleteRsp *) - qdf_mem_malloc(length); - - if (NULL == pChanSwTxResponse) { - pe_err("AllocateMemory failed for tSirSmeCSAIeTxCompleteRsp"); - return; - } - - pChanSwTxResponse->sessionId = - psessionEntry->smeSessionId; - pChanSwTxResponse->chanSwIeTxStatus = - QDF_STATUS_SUCCESS; + if (!LIM_IS_AP_ROLE(session)) + return; - mmhMsg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND; - mmhMsg.bodyptr = pChanSwTxResponse; - mmhMsg.bodyval = 0; - lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); - } - } + if (session->dfsIncludeChanSwIe && + (session->gLimChannelSwitch.switchCount == + mac_ctx->sap.SapDfsInfo.sap_ch_switch_beacon_cnt)) + lim_process_ap_ecsa_timeout(session); - if (LIM_IS_AP_ROLE(psessionEntry) && - psessionEntry->gLimOperatingMode.present) { + if (session->gLimOperatingMode.present) { /* Done with nss update, send response back to SME */ - psessionEntry->gLimOperatingMode.present = 0; - beacon_tx_comp_rsp_ptr = (struct sir_beacon_tx_complete_rsp *) - qdf_mem_malloc(sizeof(*beacon_tx_comp_rsp_ptr)); - if (NULL == beacon_tx_comp_rsp_ptr) { - pe_err("AllocateMemory failed for beacon_tx_comp_rsp_ptr"); + session->gLimOperatingMode.present = 0; + bcn_tx_comp_rsp = (struct sir_beacon_tx_complete_rsp *) + qdf_mem_malloc(sizeof(*bcn_tx_comp_rsp)); + if (NULL == bcn_tx_comp_rsp) { + pe_err("AllocateMemory failed for bcn_tx_comp_rsp"); return; } - beacon_tx_comp_rsp_ptr->session_id = - psessionEntry->smeSessionId; - beacon_tx_comp_rsp_ptr->tx_status = QDF_STATUS_SUCCESS; - mmhMsg.type = eWNI_SME_NSS_UPDATE_RSP; - mmhMsg.bodyptr = beacon_tx_comp_rsp_ptr; - mmhMsg.bodyval = 0; - lim_sys_process_mmh_msg_api(pMac, &mmhMsg, ePROT); + bcn_tx_comp_rsp->session_id = session->smeSessionId; + bcn_tx_comp_rsp->tx_status = QDF_STATUS_SUCCESS; + msg.type = eWNI_SME_NSS_UPDATE_RSP; + msg.bodyptr = bcn_tx_comp_rsp; + + status = cds_mq_post_message(QDF_MODULE_ID_SME, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to post eWNI_SME_NSS_UPDATE_RSP"); + qdf_mem_free(bcn_tx_comp_rsp); + } } - return; } diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h index 44c4e9bfe7a5..4082040cc54f 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.h @@ -121,8 +121,19 @@ void lim_send_sme_dfs_event_notify(tpAniSirGlobal pMac, uint16_t msgType, void lim_send_sme_ap_channel_switch_resp(tpAniSirGlobal pMac, tpPESession psessionEntry, tpSwitchChannelParams pChnlParams); + +/* + * lim_process_beacon_tx_success_ind() - handle successful beacon transmission + * indication from the FW This is a generic event generated by the FW afer the + * first beacon is sent out after the beacon template update by the + * host. + * @mac_ctx: Global mac_ctx + * @msg_type: msg_type + * + * Return: none + */ void -lim_process_beacon_tx_success_ind(tpAniSirGlobal pMac, uint16_t msgType, +lim_process_beacon_tx_success_ind(tpAniSirGlobal mac_ctx, uint16_t msg_type, void *event); typedef enum { diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c index 9f80c4ffafe6..c3a961124ed7 100644 --- a/core/mac/src/pe/lim/lim_session.c +++ b/core/mac/src/pe/lim/lim_session.c @@ -123,6 +123,15 @@ static void pe_reset_protection_callback(void *ptr) return; } + /* + * If dfsIncludeChanSwIe is set restrat timer as we are going to change + * channel and no point in checking protection mode for this channel. + */ + if (pe_session_entry->dfsIncludeChanSwIe) { + pe_err("CSA going on restart timer"); + goto restart_timer; + } + current_protection_state |= pe_session_entry->gLimOverlap11gParams.protectionEnabled | pe_session_entry->gLimOverlap11aParams.protectionEnabled << 1 | @@ -223,7 +232,9 @@ static void pe_reset_protection_callback(void *ptr) lim_send_beacon_params(mac_ctx, &beacon_params, pe_session_entry); } + pe_session_entry->old_protection_state = current_protection_state; +restart_timer: if (qdf_mc_timer_start(&pe_session_entry-> protection_fields_reset_timer, SCH_PROTECTION_RESET_TIME) @@ -528,6 +539,11 @@ pe_create_session(tpAniSirGlobal pMac, uint8_t *bssid, uint8_t *sessionId, } if (status != QDF_STATUS_SUCCESS) pe_err("cannot create or start protectionFieldsResetTimer"); + status = qdf_mc_timer_init(&session_ptr->ap_ecsa_timer, + QDF_TIMER_TYPE_WAKE_APPS, lim_process_ap_ecsa_timeout, + (void *)&pMac->lim.gpSession[i]); + if (status != QDF_STATUS_SUCCESS) + pe_err("cannot create ap_ecsa_timer"); } pe_init_fils_info(session_ptr); pe_init_pmf_comeback_timer(pMac, session_ptr, *sessionId); @@ -698,6 +714,8 @@ void pe_delete_session(tpAniSirGlobal mac_ctx, tpPESession session) if (LIM_IS_AP_ROLE(session)) { qdf_mc_timer_stop(&session->protection_fields_reset_timer); qdf_mc_timer_destroy(&session->protection_fields_reset_timer); + qdf_mc_timer_stop(&session->ap_ecsa_timer); + qdf_mc_timer_destroy(&session->ap_ecsa_timer); lim_del_pmf_sa_query_timer(mac_ctx, session); } diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c index 468239a8fc89..a5e9b3f8b947 100644 --- a/core/mac/src/pe/lim/lim_utils.c +++ b/core/mac/src/pe/lim/lim_utils.c @@ -7459,3 +7459,104 @@ enum rateid lim_get_min_session_txrate(tpPESession session) return rid; } + +void +lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal mac_ctx, tpPESession session) +{ + + /* Update the beacon template and send to FW */ + if (sch_set_fixed_beacon_fields(mac_ctx, session) != eSIR_SUCCESS) { + pe_err("Unable to set CSA IE in beacon"); + return; + } + + /* Send update beacon template message */ + lim_send_beacon_ind(mac_ctx, session); + pe_debug("Updated CSA IE, IE COUNT: %d", + session->gLimChannelSwitch.switchCount); +} + +void lim_process_ap_ecsa_timeout(void *data) +{ + tpPESession session = (tpPESession)data; + tpAniSirGlobal mac_ctx; + uint8_t bcn_int, ch, ch_width; + QDF_STATUS status; + + if (!session) { + pe_err("Session is NULL"); + return; + } + + mac_ctx = (tpAniSirGlobal)session->mac_ctx; + + if (!session->dfsIncludeChanSwIe) { + pe_debug("session->dfsIncludeChanSwIe not set"); + return; + } + + if (session->gLimChannelSwitch.switchCount) { + /* Decrement the beacon switch count */ + session->gLimChannelSwitch.switchCount--; + pe_debug("current beacon count %d", + session->gLimChannelSwitch.switchCount); + } + + /* + * Send only g_sap_chanswitch_beacon_cnt beacons with CSA IE Set in + * when a radar is detected + */ + if (session->gLimChannelSwitch.switchCount > 0) { + /* Send the next beacon with updated CSA IE count */ + lim_send_dfs_chan_sw_ie_update(mac_ctx, session); + + ch = session->gLimChannelSwitch.primaryChannel; + ch_width = session->gLimChannelSwitch.ch_width; + + if (mac_ctx->sap.SapDfsInfo.dfs_beacon_tx_enhanced) + /* Send Action frame after updating beacon */ + lim_send_chan_switch_action_frame(mac_ctx, ch, ch_width, + session); + + /* Restart the timer */ + if (session->beaconParams.beaconInterval) + bcn_int = session->beaconParams.beaconInterval; + else + bcn_int = WNI_CFG_BEACON_INTERVAL_STADEF; + + status = qdf_mc_timer_start(&session->ap_ecsa_timer, bcn_int); + if (QDF_IS_STATUS_ERROR(status)) { + pe_err("cannot start ap_ecsa_timer"); + lim_process_ap_ecsa_timeout(session); + } + } else { + tSirSmeCSAIeTxCompleteRsp *chan_switch_tx_rsp; + cds_msg_t msg = {0}; + uint8_t length = sizeof(*chan_switch_tx_rsp); + + /* Done with CSA IE update, send response back to SME */ + session->gLimChannelSwitch.switchCount = 0; + if (mac_ctx->sap.SapDfsInfo.disable_dfs_ch_switch == false) + session->gLimChannelSwitch.switchMode = 0; + session->dfsIncludeChanSwIe = false; + session->dfsIncludeChanWrapperIe = false; + + chan_switch_tx_rsp = qdf_mem_malloc(length); + if (!chan_switch_tx_rsp) { + pe_err("AllocateMemory failed for tSirSmeCSAIeTxCompleteRsp"); + return; + } + + chan_switch_tx_rsp->sessionId = session->smeSessionId; + chan_switch_tx_rsp->chanSwIeTxStatus = QDF_STATUS_SUCCESS; + + msg.type = eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND; + msg.bodyptr = chan_switch_tx_rsp; + + status = cds_mq_post_message(QDF_MODULE_ID_SME, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + sme_err("Failed to post eWNI_SME_DFS_CSAIE_TX_COMPLETE_IND"); + qdf_mem_free(chan_switch_tx_rsp); + } + } +} diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h index f92382176e4d..ae8b389ec259 100644 --- a/core/mac/src/pe/lim/lim_utils.h +++ b/core/mac/src/pe/lim/lim_utils.h @@ -766,6 +766,26 @@ QDF_STATUS lim_util_get_type_subtype(void *pkt, uint8_t *type, uint8_t *subtype); /** + * lim_send_dfs_chan_sw_ie_update() -updates the channel switch IE in beacon + * template + * @mac_ctx - pointer to global mac context + * @session - A pointer to pesession + * + * Return None + */ +void lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal mac_ctx, + tpPESession session); + +/** + * lim_process_ap_ecsa_timeout() -process ECSA timeout which decrement csa count + * in beacon and update beacon template in firmware + * @data - A pointer to pesession + * + * Return None + */ +void lim_process_ap_ecsa_timeout(void *session); + +/** * lim_send_chan_switch_action_frame()- function to send ECSA/CSA * action frame for each sta connected to SAP/GO and AP in case of * STA . diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c index 2e5fdd56002a..8cd0d6156f00 100644 --- a/core/sap/src/sap_ch_select.c +++ b/core/sap/src/sap_ch_select.c @@ -1737,8 +1737,10 @@ static void sap_compute_spect_weight(tSapChSelSpectInfo *pSpectInfoParams, if (rssi < SOFTAP_MIN_RSSI) rssi = SOFTAP_MIN_RSSI; - if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX) + if (pSpectCh->weight == SAP_ACS_WEIGHT_MAX) { + pSpectCh->weight_copy = pSpectCh->weight; goto debug_info; + } /* There may be channels in scanlist, which were not sent to * FW for scanning as part of ACS scan list, but they do have an diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index f834505780cb..302e1b5f78b8 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -1674,6 +1674,7 @@ QDF_STATUS sme_hdd_ready_ind(tHalHandle hHal) msg->add_bssdescr_cb = csr_scan_process_single_bssdescr; msg->csr_roam_synch_cb = csr_roam_synch_callback; msg->sme_msg_cb = sme_process_msg_callback; + msg->stop_roaming_cb = sme_stop_roaming; if (eSIR_FAILURE != u_mac_post_ctrl_msg(hHal, (tSirMbMsg *) msg)) @@ -9320,7 +9321,8 @@ QDF_STATUS sme_stop_roaming(tHalHandle hal, uint8_t session_id, uint8_t reason) * is not enabled on this session so that roam start requests for * this session can be blocked until driver enables roaming */ - if (reason == eCsrDriverDisabled && session->pCurRoamProfile) { + if (reason == eCsrDriverDisabled && session->pCurRoamProfile && + session->pCurRoamProfile->csrPersona == QDF_STA_MODE) { session->pCurRoamProfile->driver_disabled_roaming = true; sme_debug("driver_disabled_roaming set for session %d", session_id); diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index b8cdc3fe0f8d..3888513458a0 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -11434,7 +11434,7 @@ bool csr_roam_issue_wm_status_change(tpAniSirGlobal pMac, uint32_t sessionId, DeauthIndMsg)); } if (QDF_IS_STATUS_SUCCESS - (csr_queue_sme_command(pMac, pCommand, true))) { + (csr_queue_sme_command(pMac, pCommand, false))) { fCommandQueued = true; } else { sme_err(" fail to send message "); @@ -15611,6 +15611,7 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, QDF_STATUS qdf_status; uint8_t *oui_ptr; uint8_t *ie_fields = (uint8_t *)bss_desc->ieFields; + bool wildcard_oui = false; if (action_id >= WMI_ACTION_OUI_MAXIMUM_ID) { sme_debug("Invalid OUI action ID"); @@ -15647,7 +15648,16 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, extension = &sme_ext->extension; - if (!extension->oui_length) + /* + * If a wildcard OUI 0xFFFFFF is defined in the INI, proceed + * to other checks skipping the OUI and vendor data checks + */ + if (!(extension->info_mask & WMI_ACTION_OUI_INFO_OUI)) { + sme_debug("Wildcard OUI found"); + wildcard_oui = true; + } + + if (!extension->oui_length && !wildcard_oui) goto next; oui_ptr = cfg_get_vendor_ie_ptr_from_oui(mac_ctx, @@ -15655,7 +15665,7 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, extension->oui_length, (uint8_t *)ie_fields, ie_len); - if (!oui_ptr) { + if (!oui_ptr && !wildcard_oui) { sme_debug("No matching IE found for OUI"); QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, @@ -15670,7 +15680,7 @@ csr_check_vendor_ap_present(tpAniSirGlobal mac_ctx, extension->oui, extension->oui_length); - if (extension->data_length && + if (extension->data_length && !wildcard_oui && !csr_check_for_vendor_oui_data(extension, oui_ptr)) { sme_debug("Vendor IE Data mismatch"); goto next; @@ -15702,6 +15712,7 @@ next: node = next_node; next_node = NULL; + wildcard_oui = false; } qdf_mutex_release(&sme_action->oui_ext_list_lock); @@ -20594,14 +20605,6 @@ csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id, return QDF_STATUS_E_FAILURE; } - if ((ROAM_SCAN_OFFLOAD_START == command && - REASON_CTX_INIT != reason) && - (session->pCurRoamProfile && - session->pCurRoamProfile->supplicant_disabled_roaming)) { - sme_debug("Supplicant disabled driver roaming"); - return QDF_STATUS_E_FAILURE; - } - if ((command == ROAM_SCAN_OFFLOAD_START) && (session->pCurRoamProfile && session->pCurRoamProfile->driver_disabled_roaming)) { @@ -20617,6 +20620,14 @@ csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id, } } + if ((ROAM_SCAN_OFFLOAD_START == command && + REASON_CTX_INIT != reason) && + (session->pCurRoamProfile && + session->pCurRoamProfile->supplicant_disabled_roaming)) { + sme_debug("Supplicant disabled driver roaming"); + return QDF_STATUS_E_FAILURE; + } + if (0 == csr_roam_is_roam_offload_scan_enabled(mac_ctx)) { sme_err("isRoamOffloadScanEnabled not set"); return QDF_STATUS_E_FAILURE; @@ -20638,7 +20649,7 @@ csr_roam_offload_scan(tpAniSirGlobal mac_ctx, uint8_t session_id, /* Roaming is not supported currently for FILS akm */ if (session->pCurRoamProfile && CSR_IS_AUTH_TYPE_FILS( session->pCurRoamProfile->AuthType.authType[0]) && - !mac_ctx->is_fils_roaming_supported) { + !mac_ctx->is_fils_roaming_supported) { sme_info("FILS Roaming not suppprted by fw"); return QDF_STATUS_SUCCESS; } diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 73e8361e00df..6727fedcc2dd 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -457,23 +457,6 @@ static void wma_vdev_detach_callback(void *ctx) qdf_mem_free(req_msg); } } - if (iface->addBssStaContext) - qdf_mem_free(iface->addBssStaContext); - - - if (iface->staKeyParams) - qdf_mem_free(iface->staKeyParams); - - if (iface->stats_rsp) - qdf_mem_free(iface->stats_rsp); - - if (iface->roam_scan_stats_req) { - struct sir_roam_scan_stats *roam_scan_stats_req = - iface->roam_scan_stats_req; - - iface->roam_scan_stats_req = NULL; - qdf_mem_free(roam_scan_stats_req); - } wma_vdev_deinit(iface); qdf_mem_zero(iface, sizeof(*iface)); @@ -596,6 +579,7 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d", __func__, vdev_id); status = QDF_STATUS_E_NOMEM; + iface->del_staself_req = NULL; goto out; } @@ -622,11 +606,6 @@ out: vdev_id, generate_rsp); wma_ol_txrx_vdev_detach(wma_handle, vdev_id); - if (iface->addBssStaContext) - qdf_mem_free(iface->addBssStaContext); - if (iface->staKeyParams) - qdf_mem_free(iface->staKeyParams); - wma_vdev_deinit(iface); qdf_mem_zero(iface, sizeof(*iface)); wma_vdev_init(iface); @@ -1649,6 +1628,7 @@ static void wma_cleanup_target_req_param(struct wma_target_req *tgt_req) tpLinkStateParams params = (tpLinkStateParams) tgt_req->user_data; qdf_mem_free(params->callbackArg); + params->callbackArg = NULL; qdf_mem_free(tgt_req->user_data); tgt_req->user_data = NULL; } @@ -3462,16 +3442,7 @@ void wma_vdev_resp_timer(void *data) iface->del_staself_req = NULL; } else { wma_send_del_sta_self_resp(iface->del_staself_req); - } - - if (iface->addBssStaContext) { - qdf_mem_free(iface->addBssStaContext); - iface->addBssStaContext = NULL; - } - - if (iface->staKeyParams) { - qdf_mem_free(iface->staKeyParams); - iface->staKeyParams = NULL; + iface->del_staself_req = NULL; } wma_vdev_deinit(iface); @@ -4200,15 +4171,18 @@ static void wma_add_bss_sta_mode(tp_wma_handle wma, tpAddBssParams add_bss) else WMA_LOGD("Sent PKT_PWR_SAVE_5G_EBT cmd to target, val = %x, status = %d", pps_val, status); - wma_send_peer_assoc(wma, add_bss->nwType, + status = wma_send_peer_assoc(wma, add_bss->nwType, &add_bss->staContext); + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("Failed to send peer assoc status:%d", status); + goto peer_cleanup; + } + peer_assoc_sent = true; /* we just had peer assoc, so install key will be done later */ if (add_bss->staContext.encryptType != eSIR_ED_NONE) iface->is_waiting_for_key = true; - peer_assoc_sent = true; - if (add_bss->rmfEnabled) wma_set_mgmt_frame_protection(wma); diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 31550a4fa467..bd6d0357581c 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -11060,6 +11060,11 @@ int wma_unified_power_debug_stats_event_handler(void *handle, tpAniSirGlobal mac = (tpAniSirGlobal)cds_get_context(QDF_MODULE_ID_PE); + if (!cmd_param_info) { + WMA_LOGE("cmd_param_info got NULL"); + return -EINVAL; + } + param_tlvs = (WMI_PDEV_CHIP_POWER_STATS_EVENTID_param_tlvs *) cmd_param_info; diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index eb51085f6027..dd6e19c7cbe1 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2243,6 +2243,89 @@ void wma_vdev_init(struct wma_txrx_node *vdev) void wma_vdev_deinit(struct wma_txrx_node *vdev) { + struct beacon_info *bcn; + tp_wma_handle wma_handle; + + wma_handle = cds_get_context(QDF_MODULE_ID_WMA); + /* validate the wma_handle */ + if (!wma_handle) { + WMA_LOGE("%s: Invalid wma handle", __func__); + return; + } + + bcn = vdev->beacon; + if (bcn) { + if (bcn->dma_mapped) + qdf_nbuf_unmap_single(wma_handle->qdf_dev, + bcn->buf, QDF_DMA_TO_DEVICE); + qdf_nbuf_free(bcn->buf); + qdf_mem_free(bcn); + vdev->beacon = NULL; + } + + if (vdev->handle) { + qdf_mem_free(vdev->handle); + vdev->handle = NULL; + } + + if (vdev->addBssStaContext) { + qdf_mem_free(vdev->addBssStaContext); + vdev->addBssStaContext = NULL; + } + + if (vdev->staKeyParams) { + qdf_mem_free(vdev->staKeyParams); + vdev->staKeyParams = NULL; + } + + if (vdev->del_staself_req) { + qdf_mem_free(vdev->del_staself_req); + vdev->del_staself_req = NULL; + } + + if (vdev->stats_rsp) { + qdf_mem_free(vdev->stats_rsp); + vdev->stats_rsp = NULL; + } + + if (vdev->psnr_req) { + qdf_mem_free(vdev->psnr_req); + vdev->psnr_req = NULL; + } + + if (vdev->rcpi_req) { + qdf_mem_free(vdev->rcpi_req); + vdev->rcpi_req = NULL; + } + + if (vdev->action_frame_filter) { + qdf_mem_free(vdev->action_frame_filter); + vdev->action_frame_filter = NULL; + } + + if (vdev->roam_scan_stats_req) { + struct sir_roam_scan_stats *req; + + req = vdev->roam_scan_stats_req; + vdev->roam_scan_stats_req = NULL; + qdf_mem_free(req); + } + + if (vdev->roam_synch_frame_ind.bcn_probe_rsp) { + qdf_mem_free(vdev->roam_synch_frame_ind.bcn_probe_rsp); + vdev->roam_synch_frame_ind.bcn_probe_rsp = NULL; + } + + if (vdev->roam_synch_frame_ind.reassoc_req) { + qdf_mem_free(vdev->roam_synch_frame_ind.reassoc_req); + vdev->roam_synch_frame_ind.reassoc_req = NULL; + } + + if (vdev->roam_synch_frame_ind.reassoc_rsp) { + qdf_mem_free(vdev->roam_synch_frame_ind.reassoc_rsp); + vdev->roam_synch_frame_ind.reassoc_rsp = NULL; + } + qdf_wake_lock_destroy(&vdev->vdev_start_wakelock); qdf_wake_lock_destroy(&vdev->vdev_stop_wakelock); qdf_wake_lock_destroy(&vdev->vdev_set_key_wakelock); @@ -3829,7 +3912,6 @@ end: QDF_STATUS wma_wmi_service_close(void *cds_ctx) { tp_wma_handle wma_handle; - struct beacon_info *bcn; int i; WMA_LOGD("%s: Enter", __func__); @@ -3854,88 +3936,6 @@ QDF_STATUS wma_wmi_service_close(void *cds_ctx) wma_handle->wmi_handle = NULL; for (i = 0; i < wma_handle->max_bssid; i++) { - bcn = wma_handle->interfaces[i].beacon; - - if (bcn) { - if (bcn->dma_mapped) - qdf_nbuf_unmap_single(wma_handle->qdf_dev, - bcn->buf, QDF_DMA_TO_DEVICE); - qdf_nbuf_free(bcn->buf); - qdf_mem_free(bcn); - wma_handle->interfaces[i].beacon = NULL; - } - - if (wma_handle->interfaces[i].handle) { - qdf_mem_free(wma_handle->interfaces[i].handle); - wma_handle->interfaces[i].handle = NULL; - } - - if (wma_handle->interfaces[i].addBssStaContext) { - qdf_mem_free(wma_handle-> - interfaces[i].addBssStaContext); - wma_handle->interfaces[i].addBssStaContext = NULL; - } - - if (wma_handle->interfaces[i].del_staself_req) { - qdf_mem_free(wma_handle->interfaces[i].del_staself_req); - wma_handle->interfaces[i].del_staself_req = NULL; - } - - if (wma_handle->interfaces[i].stats_rsp) { - qdf_mem_free(wma_handle->interfaces[i].stats_rsp); - wma_handle->interfaces[i].stats_rsp = NULL; - } - - if (wma_handle->interfaces[i].psnr_req) { - qdf_mem_free(wma_handle-> - interfaces[i].psnr_req); - wma_handle->interfaces[i].psnr_req = NULL; - } - - if (wma_handle->interfaces[i].rcpi_req) { - qdf_mem_free(wma_handle-> - interfaces[i].rcpi_req); - wma_handle->interfaces[i].rcpi_req = NULL; - } - - if (wma_handle->interfaces[i].action_frame_filter) { - qdf_mem_free(wma_handle-> - interfaces[i].action_frame_filter); - wma_handle->interfaces[i].action_frame_filter = NULL; - } - - if (wma_handle->interfaces[i].roam_scan_stats_req) { - struct sir_roam_scan_stats *req; - - req = wma_handle->interfaces[i].roam_scan_stats_req; - wma_handle->interfaces[i].roam_scan_stats_req = NULL; - qdf_mem_free(req); - } - - if (wma_handle->interfaces[i].roam_synch_frame_ind. - bcn_probe_rsp) { - qdf_mem_free(wma_handle->interfaces[i]. - roam_synch_frame_ind.bcn_probe_rsp); - wma_handle->interfaces[i].roam_synch_frame_ind. - bcn_probe_rsp = NULL; - } - - if (wma_handle->interfaces[i].roam_synch_frame_ind. - reassoc_req) { - qdf_mem_free(wma_handle->interfaces[i]. - roam_synch_frame_ind.reassoc_req); - wma_handle->interfaces[i].roam_synch_frame_ind. - reassoc_req = NULL; - } - - if (wma_handle->interfaces[i].roam_synch_frame_ind. - reassoc_rsp) { - qdf_mem_free(wma_handle->interfaces[i]. - roam_synch_frame_ind.reassoc_rsp); - wma_handle->interfaces[i].roam_synch_frame_ind. - reassoc_rsp = NULL; - } - wma_vdev_deinit(&wma_handle->interfaces[i]); } diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 1b3b58828e14..ea224bfe2178 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -5571,8 +5571,10 @@ bool wma_is_scan_simultaneous_capable(void) } if ((mac->dual_mac_feature_disable == DISABLE_DBS_CXN_AND_SCAN) || - (mac->dual_mac_feature_disable == - ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN)) + (mac->dual_mac_feature_disable == + ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN) || + (mac->dual_mac_feature_disable == + ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN)) return false; return true; |
