diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2018-04-04 05:46:59 -0600 |
|---|---|---|
| committer | Linux Build Service Account <lnxbuild@localhost> | 2018-04-04 05:46:59 -0600 |
| commit | 199bde0772b89e05bcb51d1331dd4769659d980a (patch) | |
| tree | 6f8b0c4d969642a87b982277336ef69e657eda16 | |
| parent | 8385ce6631615c5427dbe9ad8bcd121ca19f8a6a (diff) | |
| parent | c4de9154895c61d19cbe33e03d99c67ea664fa2b (diff) | |
Merge c4de9154895c61d19cbe33e03d99c67ea664fa2b on remote branch
Change-Id: I8c2163ab7a28b1ba4dec9b1ac28456546c83b27d
52 files changed, 1997 insertions, 222 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_rx.c b/CORE/CLD_TXRX/HTT/htt_rx.c index 53c82ad2fa82..bf44d237592e 100644 --- a/CORE/CLD_TXRX/HTT/htt_rx.c +++ b/CORE/CLD_TXRX/HTT/htt_rx.c @@ -1598,15 +1598,81 @@ unsigned char get_nr_antenna(struct htt_host_rx_desc_base *rx_desc) } /** - * htt_get_radiotap_rx_status() - Update information about the rx status, which - * is used later for radiotap updation. + * get_ht_vht_info_ll() - get ht/vht information + * @rx_desc: pointer to PPDU start + * @rx_status: pointer to mon_rx_status. + * + * This function retrieve MCS/VHT info by parsing preamble, + * vht_sig_a1 and vht_sig_a2, which follows ieee80211 spec. + * + * Return: None. + */ +static void get_ht_vht_info_ll(struct rx_ppdu_start rx_desc, + struct mon_rx_status *rx_status) +{ + uint8_t preamble_type = + (uint8_t)rx_desc.preamble_type; + uint32_t ht_sig_vht_sig_a_1 = rx_desc.ht_sig_vht_sig_a_1; + uint32_t ht_sig_vht_sig_a_2 = rx_desc.ht_sig_vht_sig_a_2; + switch (preamble_type) { + case 8: + case 9: + rx_status->mcs_info.valid = 1; + rx_status->vht_info.valid = 0; + rx_status->mcs_info.mcs = ht_sig_vht_sig_a_1 & 0x7f; + rx_status->nr_ant = rx_status->mcs_info.mcs >> 3; + rx_status->mcs_info.bw = (ht_sig_vht_sig_a_1 >> 7) & 0x1; + rx_status->mcs_info.smoothing = ht_sig_vht_sig_a_2 & 0x1; + rx_status->mcs_info.not_sounding = + (ht_sig_vht_sig_a_2 >> 1) & 0x1; + rx_status->mcs_info.aggregation = + (ht_sig_vht_sig_a_2 >> 3) & 0x1; + rx_status->mcs_info.stbc = (ht_sig_vht_sig_a_2 >> 4) & 0x3; + rx_status->mcs_info.fec = (ht_sig_vht_sig_a_2 >> 6) & 0x1; + rx_status->mcs_info.sgi = (ht_sig_vht_sig_a_2 >> 7) & 0x1; + rx_status->mcs_info.ness = (ht_sig_vht_sig_a_2 >> 8) & 0x3; + break; + case 0x0c: /* VHT w/o TxBF */ + case 0x0d: /* VHT w/ TxBF */ + rx_status->vht_info.valid = 1; + rx_status->mcs_info.valid = 0; + rx_status->vht_info.bw = ht_sig_vht_sig_a_1 & 0x3; + rx_status->vht_info.stbc = (ht_sig_vht_sig_a_1 >> 3) & 0x1; + /* Currently only handle SU case */ + rx_status->vht_info.gid = (ht_sig_vht_sig_a_1 >> 4) & 0x3f; + rx_status->vht_info.nss = (ht_sig_vht_sig_a_1 >> 10) & 0x7; + rx_status->nr_ant = (ht_sig_vht_sig_a_1 >> 10) & 0x7; + rx_status->vht_info.paid = (ht_sig_vht_sig_a_1 >> 13) & 0x1ff; + rx_status->vht_info.txps_forbidden = + (ht_sig_vht_sig_a_1 >> 22) & 0x1; + rx_status->vht_info.sgi = ht_sig_vht_sig_a_2 & 0x1; + rx_status->vht_info.sgi_disambiguation = + (ht_sig_vht_sig_a_2 >> 1) & 0x1; + rx_status->vht_info.coding = (ht_sig_vht_sig_a_2 >> 2) & 0x1; + rx_status->vht_info.ldpc_extra_symbol = + (ht_sig_vht_sig_a_2 >> 3) & 0x1; + rx_status->vht_info.mcs = (ht_sig_vht_sig_a_2 >> 4) & 0xf; + rx_status->vht_info.beamformed = + (ht_sig_vht_sig_a_2 >> 8) & 0x1; + break; + default: + rx_status->mcs_info.valid = 0; + rx_status->vht_info.valid = 0; + rx_status->nr_ant = 1; + break; + } +} + +/** + * htt_get_radiotap_rx_status_ll() - Update information about the rx status, + * which is used later for radiotap updation. * @rx_desc: Pointer to struct htt_host_rx_desc_base * @rx_status: Return variable updated with rx_status * * Return: None */ -void htt_get_radiotap_rx_status(struct htt_host_rx_desc_base *rx_desc, struct - mon_rx_status *rx_status) +void htt_get_radiotap_rx_status_ll(struct htt_host_rx_desc_base *rx_desc, + struct mon_rx_status *rx_status) { uint16_t channel_flags = 0; @@ -1620,8 +1686,11 @@ void htt_get_radiotap_rx_status(struct htt_host_rx_desc_base *rx_desc, struct rx_status->chan_flags = channel_flags; rx_status->ant_signal_db = rx_desc->ppdu_start.rssi_comb; rx_status->nr_ant = get_nr_antenna(rx_desc); + get_ht_vht_info_ll(rx_desc->ppdu_start, rx_status); } +struct mon_rx_status g_ll_rx_status; + /** * htt_rx_mon_amsdu_rx_in_order_pop_ll() - Monitor mode HTT Rx in order pop * function @@ -1646,14 +1715,18 @@ htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, uint32_t msdu_count = 0; struct htt_host_rx_desc_base *rx_desc; struct mon_rx_status rx_status = {0}; + struct htt_rx_in_ord_paddr_ind_hdr_t *host_msg_hdr; uint32_t amsdu_len; uint32_t len; uint32_t last_frag; + uint32_t ch_freq; HTT_ASSERT1(htt_rx_in_order_ring_elems(pdev) != 0); rx_ind_data = adf_nbuf_data(rx_ind_msg); msg_word = (uint32_t *)rx_ind_data; + host_msg_hdr = (struct htt_rx_in_ord_paddr_ind_hdr_t *)rx_ind_data; + ch_freq = vos_chan_to_freq(host_msg_hdr->reserved_1); HTT_PKT_DUMP(vos_trace_hex_dump(VOS_MODULE_ID_TXRX, VOS_TRACE_LEVEL_FATAL, @@ -1695,12 +1768,17 @@ htt_rx_mon_amsdu_rx_in_order_pop_ll(htt_pdev_handle pdev, adf_nbuf_t rx_ind_msg, * Make the netbuf's data pointer point to the payload rather * than the descriptor. */ - htt_get_radiotap_rx_status(rx_desc, &rx_status); + if(rx_desc->attention.first_mpdu) { + memset(&rx_status, 0, sizeof(struct mon_rx_status)); + rx_status.chan = (uint16_t)ch_freq; + htt_get_radiotap_rx_status_ll(rx_desc, &rx_status); + memcpy(&g_ll_rx_status,&rx_status,sizeof(struct mon_rx_status)); + } /* * 250 bytes of RX_STD_DESC size should be sufficient for * radiotap. */ - adf_nbuf_update_radiotap(&rx_status, msdu, + adf_nbuf_update_radiotap(&g_ll_rx_status, msdu, HTT_RX_STD_DESC_RESERVATION); amsdu_len = HTT_RX_IN_ORD_PADDR_IND_MSDU_LEN_GET(*(msg_word + 1)); diff --git a/CORE/CLD_TXRX/TXRX/ol_rx.c b/CORE/CLD_TXRX/TXRX/ol_rx.c index a44a4b065b73..3a66b13dac0a 100644 --- a/CORE/CLD_TXRX/TXRX/ol_rx.c +++ b/CORE/CLD_TXRX/TXRX/ol_rx.c @@ -1412,6 +1412,13 @@ ol_rx_in_order_indication_handler( int status; adf_nbuf_t head_msdu, tail_msdu = NULL; + if (tid >= OL_TXRX_NUM_EXT_TIDS) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: invalid tid, %u\n", __FUNCTION__, tid); + WARN_ON(1); + return; + } + if (pdev) { peer = ol_txrx_peer_find_by_id(pdev, peer_id); if (VOS_MONITOR_MODE == vos_get_conparam()) diff --git a/CORE/EPPING/src/epping_txrx.c b/CORE/EPPING/src/epping_txrx.c index 5fdad1ec1d4f..2b408ce8ebb4 100644 --- a/CORE/EPPING/src/epping_txrx.c +++ b/CORE/EPPING/src/epping_txrx.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. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -246,8 +246,10 @@ static void epping_stop_adapter(epping_adapter_t *pAdapter) netif_carrier_off(pAdapter->dev); pAdapter->started = false; dev = pAdapter->pEpping_ctx->parent_dev; +#ifdef FEATURE_BUS_BANDWIDTH if (dev) vos_request_bus_bandwidth(dev, CNSS_BUS_WIDTH_LOW); +#endif } } @@ -262,8 +264,10 @@ static int epping_start_adapter(epping_adapter_t *pAdapter) } if (!pAdapter->started) { dev = pAdapter->pEpping_ctx->parent_dev; +#ifdef FEATURE_BUS_BANDWIDTH if (dev) vos_request_bus_bandwidth(dev, CNSS_BUS_WIDTH_HIGH); +#endif netif_carrier_on(pAdapter->dev); EPPING_LOG(LOG1, FL("Enabling queues")); netif_tx_start_all_queues(pAdapter->dev); diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h index 3a73e5ef169c..193c924a19e9 100644 --- a/CORE/HDD/inc/wlan_hdd_assoc.h +++ b/CORE/HDD/inc/wlan_hdd_assoc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -230,12 +230,6 @@ typedef struct connection_info_s /** holds assoc fail reason */ int32_t assoc_status_code; - /** holds last SSID info */ - tCsrSSIDInfo last_ssid; - - /** holds last auth type */ - eCsrAuthType last_auth_type; - /* ptk installed state */ bool ptk_installed; diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index a4dc09df44a5..f9fb2c40839b 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -2395,6 +2395,57 @@ typedef enum #endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ /* + * <ini> + * gDPDRecalibEnable - Enable/Disable Runtime DPD Recaliberation feature + * The parameter ‘enable’ in WMI is used to enable + * feature and debug log. Set bit0 to enable feature, + * set bit1 is to enable FW log to host, and set bit2 is + * to enable UART output. + * + * @Min: 0 + * @Max: 7 + * @Default: 1 + * + * This ini is used to enable/disable DPD Recaliberation feature + * + * Usage: Internal + * + * </ini> + */ + +#define CFG_DPD_RECALIB_ENABLE_NAME "gDPDRecalibEnable" +#define CFG_DPD_RECALIB_ENABLE_MIN ( 0 ) +#define CFG_DPD_RECALIB_ENABLE_MAX ( 7 ) +#define CFG_DPD_RECALIB_ENABLE_DEFAULT ( 1 ) + +/*Thermal thresholds: DPD will be triggered + when current temperature above this threshold */ + +/* Delta degree C above first DPD cal after chip is on. Unit: degree C. */ +#define CFG_DPD_RECALIB_DELTA_DEGREE_HIGH_NAME "gDPDRecalibDeltaDegreeHigh" +#define CFG_DPD_RECALIB_DELTA_DEGREE_HIGH_MIN ( 10 ) +#define CFG_DPD_RECALIB_DELTA_DEGREE_HIGH_MAX ( 60 ) +#define CFG_DPD_RECALIB_DELTA_DEGREE_HIGH_DEFAULT ( 35 ) + +/* Delta degree C above first DPD cal after chip is on. Unit: degree C. */ +#define CFG_DPD_RECALIB_DELTA_DEGREE_LOW_NAME "gDPDRecalibDeltaDegreeLow" +#define CFG_DPD_RECALIB_DELTA_DEGREE_LOW_MIN ( 10 ) +#define CFG_DPD_RECALIB_DELTA_DEGREE_LOW_MAX ( 60 ) +#define CFG_DPD_RECALIB_DELTA_DEGREE_LOW_DEFAULT ( 25 ) + +/* Cold down time between two DPD re-cal. Unit: ms*/ +#define CFG_DPD_RECALIB_COOLING_TIME_NAME "gDPDRecalibCoolingTime" +#define CFG_DPD_RECALIB_COOLING_TIME_MIN ( 0 ) +#define CFG_DPD_RECALIB_COOLING_TIME_MAX ( 5 ) +#define CFG_DPD_RECALIB_COOLING_TIME_DEFAULT ( 1 ) + +/* Max duration for dpd re-cal. Unit: ms */ +#define CFG_DPD_RECALIB_DURATION_MAX_NAME "gDPDRecalibDurationMax" +#define CFG_DPD_RECALIB_DURATION_MAX_MIN ( 30 ) +#define CFG_DPD_RECALIB_DURATION_MAX_MAX ( 180 ) +#define CFG_DPD_RECALIB_DURATION_MAX_DEFAULT ( 120 ) + +/* * Enable/Disable Modulated DTIM feature * Default: Disable */ @@ -5061,6 +5112,15 @@ FG_BTC_BT_INTERVAL_PAGE_P2P_STA_DEFAULT #define CFG_ENABLE_MONITOR_ON_STA_MAX (1) #define CFG_ENABLE_MONITOR_ON_STA_DEFAULT (0) +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +/*SAP Channel Switch Support*/ +#define CFG_SAP_CHANNEL_SWITCH_WITH_CSA_NAME "gSAPChannelSwitchWithCSA" +#define CFG_SAP_CHANNEL_SWITCH_WITH_CSA_MIN (0) +#define CFG_SAP_CHANNEL_SWITCH_WITH_CSA_MAX (1) +#define CFG_SAP_CHANNEL_SWITCH_WITH_CSA_DEFAULT (0) + +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + /*--------------------------------------------------------------------------- Type declarations -------------------------------------------------------------------------*/ @@ -5957,6 +6017,15 @@ struct hdd_config { uint32_t cca_threshold_2g; uint32_t cca_threshold_5g; uint8_t mon_on_sta_enable; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + uint32_t sap_ch_switch_with_csa; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + + uint32_t dpd_recalib_enabled; + uint32_t dpd_recalib_delta_degreehigh; + uint32_t dpd_recalib_delta_degreelow; + uint32_t dpd_recalib_cooling_time; + uint32_t dpd_recalib_duration_max; }; typedef struct hdd_config hdd_config_t; diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h index 821ae60183a5..5b3568e8a86f 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg80211.h +++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h @@ -306,6 +306,11 @@ enum qca_nl80211_vendor_subcmds { QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE = 148, /* subcommand to flush peer tids */ QCA_NL80211_VENDOR_SUBCMD_PEER_FLUSH_PENDING = 162, +#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN + /* Thermal Shutdown cmds to protect chip */ + QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD = 167, + QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT = 168, +#endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ }; /** @@ -422,6 +427,10 @@ enum qca_nl80211_vendor_subcmds_index { QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND_INDEX, #endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN + QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT_INDEX, +#endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ + /* OCB events */ QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX, QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX, @@ -1567,6 +1576,96 @@ enum qca_wlan_vendor_attr_nd_offload { QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_AFTER_LAST - 1, }; +#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN +/** + * enum qca_wlan_vendor_attr_thermal_get_temperature - vendor subcmd attributes + * to get chip temperature by user. + * enum values are used for NL attributes for data used by + * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE command for data used + * by QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_thermal_get_temperature { + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_INVALID = 0, + /* Temperature value (degree Celsius) from driver. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_DATA, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_get_thermal_params_rsp - vendor subcmd attributes + * to get configuration parameters of thermal shutdown feature. Enum values are + * used by QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS command for data + * used by QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_get_thermal_params_rsp { + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_INVALID = 0, + /* Indicate if the thermal shutdown feature is enabled. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SHUTDOWN_EN, + /* Indicate if the auto mode is enabled. + * Enable: Driver triggers the suspend/resume action. + * Disable: User space triggers the suspend/resume action. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SHUTDOWN_AUTO_EN, + /* Thermal resume threshold (degree Celsius). Issue the resume command + * if the temperature value is lower than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_RESUME_THRESH, + /* Thermal warning threshold (degree Celsius). FW reports temperature + * to driver if it's higher than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_WARNING_THRESH, + /* Thermal suspend threshold (degree Celsius). Issue the suspend command + * if the temperature value is higher than this threshold. + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SUSPEND_THRESH, + /* FW reports temperature data periodically at this interval (ms). + * u16 attribute. + */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SAMPLE_RATE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_MAX = + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_AFTER_LAST - 1, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_event - vendor subcmd attributes to + * report thermal events from driver to user space. + * enum values are used for NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT sub command. + */ +enum qca_wlan_vendor_attr_thermal_event { + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_INVALID = 0, + /* Temperature value (degree Celsius) from driver. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_TEMPERATURE, + /* Indication of resume completion from power save mode. + * NLA_FLAG attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_RESUME_COMPLETE, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_AFTER_LAST - 1, +}; + +#endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ + /** * enum qca_wlan_vendor_features - vendor device/driver features * @QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD: Device supports key @@ -2650,6 +2749,53 @@ enum qca_wlan_vendor_attr_ll_stats_ext { QCA_WLAN_VENDOR_ATTR_LL_STATS_EXT_LAST - 1, }; +#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN +/** + * qca_wlan_vendor_attr_thermal_cmd_type: Attribute values for + * QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE to the vendor subcmd + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD. This represents the + * thermal command types sent to driver. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS: Request to + * get thermal shutdown configuration parameters for display. Parameters + * responded from driver are defined in enum + * qca_wlan_vendor_attr_get_thermal_params_rsp. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE: Request to + * get temperature. Host should respond with a temperature data. It is defined + * in enum qca_wlan_vendor_attr_thermal_get_temperature. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND: Request to execute thermal + * suspend action. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME: Request to execute thermal + * resume action. + */ +enum qca_wlan_vendor_attr_thermal_cmd_type { + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME, +}; + +/** + * enum qca_wlan_vendor_attr_thermal_cmd - Vendor subcmd attributes to set + * cmd value. Used for NL attributes for data used by + * QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD sub command. + */ +enum qca_wlan_vendor_attr_thermal_cmd { + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_INVALID = 0, + /* The value of command, driver will implement different operations + * according to this value. It uses values defined in + * enum qca_wlan_vendor_attr_thermal_cmd_type. + * u32 attribute. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE = 1, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST - 1 +}; + +#endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)) /** * enum ieee80211_band - supported frequency bands diff --git a/CORE/HDD/inc/wlan_hdd_hostapd.h b/CORE/HDD/inc/wlan_hdd_hostapd.h index 2a08dc9b0319..a45564def0d4 100644 --- a/CORE/HDD/inc/wlan_hdd_hostapd.h +++ b/CORE/HDD/inc/wlan_hdd_hostapd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -123,7 +123,20 @@ hdd_set_sap_auth_offload(hdd_adapter_t *pHostapdAdapter, bool enabled) { } #endif /* SAP_AUTH_OFFLOAD */ + +int hdd_softap_set_channel_change(struct net_device *dev, int target_channel); +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +VOS_STATUS hdd_sta_state_sap_notify(hdd_context_t *hdd_context, + sta_sap_notifications event, + struct wlan_sap_csa_info csa_info); +VOS_STATUS hdd_send_sap_event(struct net_device *dev, + sta_sap_notifications event, + struct wlan_sap_csa_info csa_info, + struct wireless_dev *wdev); +void hdd_hostapd_chan_switch_cb(v_PVOID_t usrDataForCallback); + int hdd_softap_set_channel_change(struct net_device *dev, int target_channel); +#endif //WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN /** * hdd_is_sta_connection_pending() - This function will check if sta connection diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 82e8d7d89774..c786dfbb696e 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -801,6 +801,8 @@ struct hdd_station_ctx /**Connection information*/ connection_info_t conn_info; + connection_info_t cache_conn_info; + roaming_info_t roam_info; #if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) @@ -1735,6 +1737,21 @@ struct hdd_scan_chan_info { uint32_t clock_freq; }; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +typedef struct sap_ch_switch_with_csa_ctx +{ + v_BOOL_t is_ch_sw_through_sta_csa; + u_int8_t tbtt_count; + v_U8_t csa_to_channel; //channel on which SAP will move after sending CSA + v_U8_t sap_chan_sw_pending; //SAP channel switch pending after STA disconnect + vos_timer_t hdd_ap_chan_switch_timer; //timer to init SAP chan switch + v_BOOL_t chan_sw_timer_initialized; + v_U8_t def_csa_channel_on_disc; + v_BOOL_t scan_only_dfs_channels; + struct mutex sap_ch_sw_lock; //Synchronize access to sap_chan_sw_pending +}sap_ch_switch_ctx; +#endif + /** Adapter stucture definition */ struct hdd_context_s @@ -2134,6 +2151,9 @@ struct hdd_context_s /* flag to show whether moniotr mode is enabled */ bool is_mon_enable; v_MACADDR_t hw_macaddr; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + sap_ch_switch_ctx ch_switch_ctx; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_CHAN }; /*--------------------------------------------------------------------------- diff --git a/CORE/HDD/inc/wlan_hdd_tdls.h b/CORE/HDD/inc/wlan_hdd_tdls.h index 7f094ab2cc95..7a678a22a3a7 100644 --- a/CORE/HDD/inc/wlan_hdd_tdls.h +++ b/CORE/HDD/inc/wlan_hdd_tdls.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -549,6 +549,18 @@ wlan_hdd_start_stop_tdls_source_timer(hdd_context_t *pHddCtx, { } +static inline int hdd_set_tdls_offchannel(hdd_context_t *pHddCtx, int offchannel) +{ + return 0; +} +static inline int hdd_set_tdls_offchannelmode(hdd_adapter_t *pAdapter, int offchanmode) +{ + return 0; +} +static inline int hdd_set_tdls_secoffchanneloffset(hdd_context_t *pHddCtx, int offchanoffset) +{ + return 0; +} #endif #endif // __HDD_TDSL_H diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index d2166d0f1805..8b51856adf47 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -75,6 +75,10 @@ #include "adf_trace.h" +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +#include "wlan_hdd_hostapd.h" +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + struct ether_addr { u_char ether_addr_octet[6]; @@ -811,6 +815,9 @@ static void hdd_save_bss_info(hdd_adapter_t *adapter, } else { hdd_sta_ctx->conn_info.conn_flag.vht_op_present = false; } + /* Cache last connection info */ + vos_mem_copy(&hdd_sta_ctx->cache_conn_info, &hdd_sta_ctx->conn_info, + sizeof(connection_info_t)); } static void @@ -867,15 +874,11 @@ hdd_connSaveConnectInfo(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, pHddStaCtx->conn_info.ucEncryptionType = encryptType; pHddStaCtx->conn_info.authType = pRoamInfo->u.pConnectedProfile->AuthType; - pHddStaCtx->conn_info.last_auth_type = pHddStaCtx->conn_info.authType; pHddStaCtx->conn_info.operationChannel = pRoamInfo->u.pConnectedProfile->operationChannel; // Save the ssid for the connection vos_mem_copy( &pHddStaCtx->conn_info.SSID.SSID, &pRoamInfo->u.pConnectedProfile->SSID, sizeof( tSirMacSSid ) ); - vos_mem_copy(&pHddStaCtx->conn_info.last_ssid.SSID, - &pRoamInfo->u.pConnectedProfile->SSID, - sizeof(tSirMacSSid)); // Save dot11mode in which STA associated to AP pHddStaCtx->conn_info.dot11Mode = pRoamInfo->u.pConnectedProfile->dot11Mode; @@ -1477,10 +1480,10 @@ static void hdd_print_bss_info(hdd_station_ctx_t *hdd_sta_ctx) hddLog(VOS_TRACE_LEVEL_INFO, "dot11mode: %d", hdd_sta_ctx->conn_info.dot11Mode); hddLog(VOS_TRACE_LEVEL_INFO, "AKM: %d", - hdd_sta_ctx->conn_info.last_auth_type); + hdd_sta_ctx->cache_conn_info.authType); hddLog(VOS_TRACE_LEVEL_INFO, "ssid: %.*s", - hdd_sta_ctx->conn_info.last_ssid.SSID.length, - hdd_sta_ctx->conn_info.last_ssid.SSID.ssId); + hdd_sta_ctx->cache_conn_info.SSID.SSID.length, + hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId); hddLog(VOS_TRACE_LEVEL_INFO, "roam count: %d", hdd_sta_ctx->conn_info.roam_count); hddLog(VOS_TRACE_LEVEL_INFO, "ant_info: %d", @@ -1635,6 +1638,21 @@ static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo * } #endif +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + if((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) && + vos_is_ch_switch_with_csa_enabled()) + { + struct wlan_sap_csa_info csa_info; + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Indicate disconnected event to HostApd", + __func__); + + csa_info.sta_channel = 0; + /*Indicate to HostApd about Station interface state change*/ + hdd_sta_state_sap_notify(pHddCtx, STA_NOTIFY_DISCONNECTED, csa_info); + } +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + //If the Device Mode is Station // and the P2P Client is Connected //Enable BMPS @@ -2036,6 +2054,45 @@ static inline int hdd_send_roam_auth_event(hdd_context_t *hdd_ctx, } #endif +/** + * hdd_send_roamed_ind() - send roamed indication to cfg80211 + * @dev: network device + * @bss: cfg80211 roamed bss pointer + * @req_ie: IEs used in reassociation request + * @req_ie_len: Length of the @req_ie + * @resp_ie: IEs received in successful reassociation response + * @resp_ie_len: Length of @resp_ie + * + * Return: none + */ +#if defined CFG80211_ROAMED_API_UNIFIED || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) +static void hdd_send_roamed_ind(struct net_device *dev, + struct cfg80211_bss *bss, const uint8_t *req_ie, + size_t req_ie_len, const uint8_t *resp_ie, + size_t resp_ie_len) +{ + struct cfg80211_roam_info info = {0}; + + info.bss = bss; + info.req_ie = req_ie; + info.req_ie_len = req_ie_len; + info.resp_ie = resp_ie; + info.resp_ie_len = resp_ie_len; + cfg80211_roamed(dev, &info, GFP_KERNEL); +} +#else +static inline void hdd_send_roamed_ind(struct net_device *dev, + struct cfg80211_bss *bss, + const uint8_t *req_ie, size_t req_ie_len, + const uint8_t *resp_ie, + size_t resp_ie_len) +{ + cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie, resp_ie_len, + GFP_KERNEL); +} +#endif + static void hdd_SendReAssocEvent(struct net_device *dev, hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo, v_U8_t *reqRsnIe, @@ -2128,9 +2185,9 @@ static void hdd_SendReAssocEvent(struct net_device *dev, hddLog(LOG2, FL("Req RSN IE:")); VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, final_req_ie, (ssid_ie_len +reqRsnLength)); - cfg80211_roamed_bss(dev, bss, - final_req_ie, (ssid_ie_len + reqRsnLength), - rspRsnIe, rspRsnLength, GFP_KERNEL); + hdd_send_roamed_ind(dev, bss, final_req_ie, + (ssid_ie_len + reqRsnLength), rspRsnIe, + rspRsnLength); hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid, reqRsnIe, reqRsnLength, rspRsnIe, @@ -2557,10 +2614,13 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs pConnectedProfile->SSID.ssId, pRoamInfo->u. pConnectedProfile->SSID.length); - cfg80211_roamed_bss(dev, roam_bss, - pFTAssocReq, assocReqlen, - pFTAssocRsp, assocRsplen, - GFP_KERNEL); + hdd_send_roamed_ind( + dev, + roam_bss, + pFTAssocReq, + assocReqlen, + pFTAssocRsp, + assocRsplen); } if (sme_GetFTPTKState(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId)) diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index a1e8202d44ca..3d3aae5ad367 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -3401,6 +3401,43 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_THERMAL_SAMPLE_RATE_MAX), #endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ + /* Runtime DPD Recaliberation INI Parameters BEGINS */ + REG_VARIABLE( CFG_DPD_RECALIB_ENABLE_NAME, WLAN_PARAM_Integer, + hdd_config_t, dpd_recalib_enabled, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DPD_RECALIB_ENABLE_DEFAULT, + CFG_DPD_RECALIB_ENABLE_MIN, + CFG_DPD_RECALIB_ENABLE_MAX), + + REG_VARIABLE( CFG_DPD_RECALIB_DELTA_DEGREE_HIGH_NAME, WLAN_PARAM_Integer, + hdd_config_t, dpd_recalib_delta_degreehigh, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DPD_RECALIB_DELTA_DEGREE_HIGH_DEFAULT, + CFG_DPD_RECALIB_DELTA_DEGREE_HIGH_MIN, + CFG_DPD_RECALIB_DELTA_DEGREE_HIGH_MAX), + + REG_VARIABLE( CFG_DPD_RECALIB_DELTA_DEGREE_LOW_NAME, WLAN_PARAM_Integer, + hdd_config_t, dpd_recalib_delta_degreelow, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DPD_RECALIB_DELTA_DEGREE_LOW_DEFAULT, + CFG_DPD_RECALIB_DELTA_DEGREE_LOW_MIN, + CFG_DPD_RECALIB_DELTA_DEGREE_LOW_MAX), + + REG_VARIABLE( CFG_DPD_RECALIB_COOLING_TIME_NAME, WLAN_PARAM_Integer, + hdd_config_t, dpd_recalib_cooling_time, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DPD_RECALIB_COOLING_TIME_DEFAULT, + CFG_DPD_RECALIB_COOLING_TIME_MIN, + CFG_DPD_RECALIB_COOLING_TIME_MAX), + + REG_VARIABLE( CFG_DPD_RECALIB_DURATION_MAX_NAME, WLAN_PARAM_Integer, + hdd_config_t, dpd_recalib_duration_max, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_DPD_RECALIB_DURATION_MAX_DEFAULT, + CFG_DPD_RECALIB_DURATION_MAX_MIN, + CFG_DPD_RECALIB_DURATION_MAX_MAX), + /* DPD Runtime Recaliberation INI Parameters END */ + REG_VARIABLE( CFG_SET_TXPOWER_LIMIT2G_NAME , WLAN_PARAM_Integer, hdd_config_t, TxPower2g, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -4279,6 +4316,16 @@ REG_TABLE_ENTRY g_registry_table[] = CFG_CONNECT_BLOCK_DURATION_MAX ), #endif /* SAP_AUTH_OFFLOAD */ +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + REG_VARIABLE( CFG_SAP_CHANNEL_SWITCH_WITH_CSA_NAME, WLAN_PARAM_Integer, + hdd_config_t, sap_ch_switch_with_csa, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_SAP_CHANNEL_SWITCH_WITH_CSA_DEFAULT, + CFG_SAP_CHANNEL_SWITCH_WITH_CSA_MIN, + CFG_SAP_CHANNEL_SWITCH_WITH_CSA_MAX ), + +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + REG_VARIABLE(CFG_DOT11P_MODE_NAME, WLAN_PARAM_Integer, hdd_config_t, dot11p_mode, VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, @@ -8276,6 +8323,9 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx ) smeConfig->sta_change_cc_via_beacon = pHddCtx->cfg_ini->sta_change_cc_via_beacon; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + smeConfig->csrConfig.sap_ch_switch_with_csa = pHddCtx->cfg_ini->sap_ch_switch_with_csa; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN halStatus = sme_UpdateConfig( pHddCtx->hHal, smeConfig); if ( !HAL_STATUS_SUCCESS( halStatus ) ) { diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index f805735c4687..439c7902bc42 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -1384,6 +1384,12 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST }, #endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN + [QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT + }, +#endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ /* OCB events */ [QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX] = { .vendor_id = QCA_NL80211_VENDOR_ID, @@ -8195,6 +8201,305 @@ wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy, return ret; } +#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN +static const struct nla_policy +qca_wlan_vendor_thermal_cmd_policy[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE] = { + .type = NLA_U32 + }, +}; + +/** + * wlan_hdd_thermal_cmd_get_temperature() - Fetch temperature and send it to ap + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * + * This is called by thermal cmd and data is sent to user space. + * + * Return: Return the Success or Failure code. + */ + +static int +wlan_hdd_thermal_cmd_get_temperature(struct wiphy *wiphy, + struct wireless_dev *wdev) +{ + eHalStatus status; + struct statsContext temp_context; + unsigned long rc; + struct sk_buff *nl_resp = 0; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct net_device *dev = wdev->netdev; + hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + if (wlan_hdd_validate_context(hdd_ctx)) + return -EINVAL; + + /* prepare callback context and magic pattern */ + init_completion(&temp_context.completion); + temp_context.pAdapter = adapter; + temp_context.magic = TEMP_CONTEXT_MAGIC; + + status = sme_GetTemperature(WLAN_HDD_GET_HAL_CTX(adapter), + &temp_context, hdd_GetTemperatureCB); + if (eHAL_STATUS_SUCCESS != status) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Unable to get temperature")); + } else { + rc = wait_for_completion_timeout(&temp_context.completion, + msecs_to_jiffies(1000)); + if (!rc) { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("SME timed out while getting temperature")); + return -EBUSY; + } + } + + spin_lock(&hdd_context_lock); + temp_context.magic = 0; + spin_unlock(&hdd_context_lock); + + nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 4 + NLMSG_HDRLEN); + if (!nl_resp) { + hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + rc = -ENOMEM; + goto exit; + } + + rc = nla_put_u32(nl_resp, QCA_WLAN_VENDOR_ATTR_THERMAL_GET_TEMPERATURE_DATA, + adapter->temperature); + if (rc) { + kfree_skb(nl_resp); + goto exit; + } + + rc = cfg80211_vendor_cmd_reply(nl_resp); + if (rc) { + hddLog(LOGE, FL("cfg80211_vendor_cmd_reply failed: %ld"), rc); + goto exit; + } +exit: + return rc; +} + + +/** + * wlan_hdd_thermal_cmd_get_params() - Get thermal parameters and send them + * to app + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * + * This is called by thermal cmd and data is sent to user space. + * + * Return: Return the Success or Failure code. + */ + +static int +wlan_hdd_thermal_cmd_get_params(struct wiphy *wiphy) +{ + int rc; + struct sk_buff *nl_resp = 0; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + uint32_t nl_buf_len; + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + if (wlan_hdd_validate_context(hdd_ctx)) + return -EINVAL; + + nl_buf_len = NLMSG_HDRLEN; + nl_buf_len += (sizeof(hdd_ctx->cfg_ini->thermal_shutdown_enabled) + + NLA_HDRLEN) + (sizeof(hdd_ctx->cfg_ini->thermal_shutdown_auto_enabled) + + NLA_HDRLEN) + (sizeof(hdd_ctx->cfg_ini->thermal_resume_threshold) + + NLA_HDRLEN) + (sizeof(hdd_ctx->cfg_ini->thermal_warning_threshold) + + NLA_HDRLEN) + (sizeof(hdd_ctx->cfg_ini->thermal_suspend_threshold) + + NLA_HDRLEN) + (sizeof(hdd_ctx->cfg_ini->thermal_sample_rate) + + NLA_HDRLEN); + + nl_resp = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, nl_buf_len); + if (!nl_resp) { + hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed")); + rc = -ENOMEM; + goto exit; + } + + nla_put_u8(nl_resp, QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SHUTDOWN_EN, + hdd_ctx->cfg_ini->thermal_shutdown_enabled); + nla_put_u8(nl_resp, + QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SHUTDOWN_AUTO_EN, + hdd_ctx->cfg_ini->thermal_shutdown_auto_enabled); + nla_put_u16(nl_resp, QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_RESUME_THRESH, + hdd_ctx->cfg_ini->thermal_resume_threshold); + nla_put_u16(nl_resp, QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_WARNING_THRESH, + hdd_ctx->cfg_ini->thermal_warning_threshold); + nla_put_u16(nl_resp, QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SUSPEND_THRESH, + hdd_ctx->cfg_ini->thermal_suspend_threshold); + nla_put_u16(nl_resp, QCA_WLAN_VENDOR_ATTR_GET_THERMAL_PARAMS_RSP_SAMPLE_RATE, + hdd_ctx->cfg_ini->thermal_sample_rate); + + rc = cfg80211_vendor_cmd_reply(nl_resp); + if (rc) { + hddLog(LOGE, FL("cfg80211_vendor_cmd_reply failed: %d"), rc); + goto exit; + } +exit: + return rc; +} + +/** + * wlan_hdd_thermal_cmd_suspend() - Execute the suspend command + * + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * + * This is called by thermal cmd. + * + * Return: Return the Success or Failure code. + */ +static int wlan_hdd_thermal_cmd_suspend(struct wiphy *wiphy) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + + if (!hdd_ctx->cfg_ini->thermal_shutdown_enabled) + return -ENOSYS; + + if (hdd_ctx->cfg_ini->thermal_shutdown_auto_enabled) + return -EINVAL; + + if (hdd_thermal_suspend_state(hdd_ctx) == HDD_WLAN_THERMAL_ACTIVE) + if (hdd_thermal_suspend_queue_work(hdd_ctx, 0)) + return 0; + + return -EBUSY; +} + +/** + * wlan_hdd_thermal_cmd_resume() - Execute the resume command + * + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * + * This is called by thermal cmd. + * + * Return: Return the Success or Failure code. + */ +static int wlan_hdd_thermal_cmd_resume(struct wiphy *wiphy) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + + if (!hdd_ctx->cfg_ini->thermal_shutdown_enabled) + return -ENOSYS; + + if (hdd_ctx->cfg_ini->thermal_shutdown_auto_enabled) + return -EINVAL; + + if (hdd_thermal_suspend_state(hdd_ctx) == HDD_WLAN_THERMAL_ACTIVE) + if (hdd_thermal_suspend_queue_work(hdd_ctx, 0)) + return 0; + + return -EBUSY; +} + +/** + * __wlan_hdd_cfg80211_thermal_cmd() - Parse the thermal command from user space + * and call the function according to different commands. + * + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the Key data + * @data_len:Length of the data passed + * + * This is called when the wlan_ts tool execute commands. + * + * Return: Return the Success or Failure code. + */ +static int +__wlan_hdd_cfg80211_thermal_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX + 1]; + uint32_t ts_cmd; + + if (VOS_FTM_MODE == hdd_get_conparam()) { + hddLog(LOGE, FL("Command not allowed in FTM mode")); + return -EINVAL; + } + + if (wlan_hdd_validate_context(hdd_ctx)) + return -EINVAL; + + if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE, + data, data_len, + qca_wlan_vendor_thermal_cmd_policy)) { + hddLog(LOGE, FL("Invalid ATTR")); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE]) { + hddLog(LOGE, FL("attr thermal cmd failed")); + return -EINVAL; + } + ts_cmd = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_VALUE]); + + switch(ts_cmd) { + case QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS: + ret = wlan_hdd_thermal_cmd_get_params(wiphy); + break; + case QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_TEMPERATURE: + ret = wlan_hdd_thermal_cmd_get_temperature(wiphy, wdev); + break; + case QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND: + ret = wlan_hdd_thermal_cmd_suspend(wiphy); + break; + case QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME: + ret = wlan_hdd_thermal_cmd_resume(wiphy); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +/** + * wlan_hdd_cfg80211_thermal_cmd() - Parse the thermal command from user space + * and call the function according to different commands. + * + * @wiphy: pointer to wireless wiphy structure. + * @wdev: pointer to wireless_dev structure. + * @data: Pointer to the Key data + * @data_len:Length of the data passed + * + * This is called when the wlan_ts tool execute commands. + * + * Return: Return the Success or Failure code. + */ + +static int +wlan_hdd_cfg80211_thermal_cmd(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_thermal_cmd(wiphy, wdev, data, data_len); + vos_ssr_unprotect(__func__); + + return ret; +} + +#endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ + #ifdef FEATURE_WLAN_TDLS /* EXT TDLS */ static const struct nla_policy @@ -13561,17 +13866,17 @@ static int32_t hdd_add_tx_bitrate(struct sk_buff *skb, if (!nla_attr) goto fail; /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ - txrate.flags = hdd_sta_ctx->conn_info.txrate.flags; - txrate.mcs = hdd_sta_ctx->conn_info.txrate.mcs; - txrate.legacy = hdd_sta_ctx->conn_info.txrate.legacy; - txrate.nss = hdd_sta_ctx->conn_info.txrate.nss; + txrate.flags = hdd_sta_ctx->cache_conn_info.txrate.flags; + txrate.mcs = hdd_sta_ctx->cache_conn_info.txrate.mcs; + txrate.legacy = hdd_sta_ctx->cache_conn_info.txrate.legacy; + txrate.nss = hdd_sta_ctx->cache_conn_info.txrate.nss; bitrate = cfg80211_calculate_bitrate(&txrate); - hdd_sta_ctx->conn_info.txrate.flags = txrate.flags; - hdd_sta_ctx->conn_info.txrate.mcs = txrate.mcs; - hdd_sta_ctx->conn_info.txrate.legacy = txrate.legacy; - hdd_sta_ctx->conn_info.txrate.nss = txrate.nss; + hdd_sta_ctx->cache_conn_info.txrate.flags = txrate.flags; + hdd_sta_ctx->cache_conn_info.txrate.mcs = txrate.mcs; + hdd_sta_ctx->cache_conn_info.txrate.legacy = txrate.legacy; + hdd_sta_ctx->cache_conn_info.txrate.nss = txrate.nss; /* report 16-bit bitrate only if we can */ bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; @@ -13586,7 +13891,7 @@ static int32_t hdd_add_tx_bitrate(struct sk_buff *skb, goto fail; } if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS, - hdd_sta_ctx->conn_info.txrate.nss)) { + hdd_sta_ctx->cache_conn_info.txrate.nss)) { hddLog(LOGE, FL("put fail nss")); goto fail; } @@ -13613,7 +13918,7 @@ static int32_t hdd_add_sta_info(struct sk_buff *skb, if (!nla_attr) goto fail; if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, - (hdd_sta_ctx->conn_info.signal + 100))) { + (hdd_sta_ctx->cache_conn_info.signal + 100))) { hddLog(LOGE, FL("put fail signal")); goto fail; } @@ -13643,9 +13948,9 @@ static int32_t hdd_add_survey_info(struct sk_buff *skb, if (!nla_attr) goto fail; if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY, - hdd_sta_ctx->conn_info.freq) || + hdd_sta_ctx->cache_conn_info.freq) || nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE, - (hdd_sta_ctx->conn_info.noise + 100))) { + (hdd_sta_ctx->cache_conn_info.noise + 100))) { hddLog(LOGE, FL("put fail noise")); goto fail; } @@ -13674,11 +13979,14 @@ hdd_add_link_standard_info(struct sk_buff *skb, goto fail; if (nla_put(skb, NL80211_ATTR_SSID, - hdd_sta_ctx->conn_info.last_ssid.SSID.length, - hdd_sta_ctx->conn_info.last_ssid.SSID.ssId)) { + hdd_sta_ctx->cache_conn_info.SSID.SSID.length, + hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) { hddLog(LOGE, FL("put fail ssid")); goto fail; } + if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE, + hdd_sta_ctx->cache_conn_info.bssId)) + goto fail; if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO)) goto fail; if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO)) @@ -13706,17 +14014,17 @@ hdd_add_ap_standard_info(struct sk_buff *skb, nla_attr = nla_nest_start(skb, idx); if (!nla_attr) goto fail; - if (hdd_sta_ctx->conn_info.conn_flag.vht_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present) if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY, - sizeof(hdd_sta_ctx->conn_info.vht_caps), - &hdd_sta_ctx->conn_info.vht_caps)) { + sizeof(hdd_sta_ctx->cache_conn_info.vht_caps), + &hdd_sta_ctx->cache_conn_info.vht_caps)) { hddLog(LOGE, FL("put fail vht cap")); goto fail; } - if (hdd_sta_ctx->conn_info.conn_flag.ht_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present) if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY, - sizeof(hdd_sta_ctx->conn_info.ht_caps), - &hdd_sta_ctx->conn_info.ht_caps)) { + sizeof(hdd_sta_ctx->cache_conn_info.ht_caps), + &hdd_sta_ctx->cache_conn_info.ht_caps)) { hddLog(LOGE, FL("put fail ht cap")); goto fail; } @@ -13744,28 +14052,33 @@ static int hdd_get_station_info(hdd_context_t *hdd_ctx, hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); nl_buf_len = NLMSG_HDRLEN; - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.last_ssid.SSID.length) + - sizeof(hdd_sta_ctx->conn_info.freq) + - sizeof(hdd_sta_ctx->conn_info.noise) + - sizeof(hdd_sta_ctx->conn_info.signal) + + nl_buf_len += sizeof(hdd_sta_ctx-> + cache_conn_info.SSID.SSID.length) + + VOS_MAC_ADDR_SIZE + + sizeof(hdd_sta_ctx->cache_conn_info.freq) + + sizeof(hdd_sta_ctx->cache_conn_info.noise) + + sizeof(hdd_sta_ctx->cache_conn_info.signal) + (sizeof(uint32_t) * 2) + - sizeof(hdd_sta_ctx->conn_info.txrate.nss) + - sizeof(hdd_sta_ctx->conn_info.roam_count) + - sizeof(hdd_sta_ctx->conn_info.last_auth_type) + - sizeof(hdd_sta_ctx->conn_info.dot11Mode); - if (hdd_sta_ctx->conn_info.conn_flag.vht_present) - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps); - if (hdd_sta_ctx->conn_info.conn_flag.ht_present) - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps); - if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) { - tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie); - nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - - 1); - } - if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present) - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation); - if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present) - nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation); + sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) + + sizeof(hdd_sta_ctx->cache_conn_info.roam_count) + + sizeof(hdd_sta_ctx->cache_conn_info.authType) + + sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode); + if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present) + nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps); + if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present) + nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps); + if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) { + tmp_hs20 = (uint8_t *)&hdd_sta_ctx-> + cache_conn_info.hs20vendor_ie; + nl_buf_len += (sizeof(hdd_sta_ctx-> + cache_conn_info.hs20vendor_ie) - 1); + } + if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present) + nl_buf_len += sizeof(hdd_sta_ctx-> + cache_conn_info.ht_operation); + if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present) + nl_buf_len += sizeof(hdd_sta_ctx-> + cache_conn_info.vht_operation); skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len); @@ -13785,33 +14098,35 @@ static int hdd_get_station_info(hdd_context_t *hdd_ctx, goto fail; } if (nla_put_u32(skb, INFO_ROAM_COUNT, - hdd_sta_ctx->conn_info.roam_count) || + hdd_sta_ctx->cache_conn_info.roam_count) || nla_put_u32(skb, INFO_AKM, hdd_convert_auth_type( - hdd_sta_ctx->conn_info.last_auth_type)) || + hdd_sta_ctx->cache_conn_info.authType)) || nla_put_u32(skb, WLAN802_11_MODE, hdd_convert_dot11mode( - hdd_sta_ctx->conn_info.dot11Mode))) { + hdd_sta_ctx->cache_conn_info.dot11Mode))) { hddLog(LOGE, FL("put fail roam_count, etc.")); goto fail; } - if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present) if (nla_put(skb, HT_OPERATION, - (sizeof(hdd_sta_ctx->conn_info.ht_operation)), - &hdd_sta_ctx->conn_info.ht_operation)) { + (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)), + &hdd_sta_ctx->cache_conn_info.ht_operation)) { hddLog(LOGE, FL("put fail HT oper")); goto fail; } - if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present) if (nla_put(skb, VHT_OPERATION, - (sizeof(hdd_sta_ctx->conn_info.vht_operation)), - &hdd_sta_ctx->conn_info.vht_operation)) { + (sizeof(hdd_sta_ctx-> + cache_conn_info.vht_operation)), + &hdd_sta_ctx->cache_conn_info.vht_operation)) { hddLog(LOGE, FL("put fail VHT oper")); goto fail; } - if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) + if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) if (nla_put(skb, AP_INFO_HS20_INDICATION, - (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1), + (sizeof(hdd_sta_ctx-> + cache_conn_info.hs20vendor_ie) - 1), tmp_hs20 + 1)) { hddLog(LOGE, FL("put fail HS20 IND")); goto fail; @@ -15366,6 +15681,15 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = wlan_hdd_cfg80211_peer_flush_pending }, +#ifdef FEATURE_WLAN_THERMAL_SHUTDOWN + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV, + .doit = wlan_hdd_cfg80211_thermal_cmd + }, +#endif /* FEATURE_WLAN_THERMAL_SHUTDOWN */ }; /* @@ -19823,6 +20147,13 @@ static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy, if (0 != status) return status; + if (pHddCtx->isUnloadInProgress || + pHddCtx->isLogpInProgress) { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: Unloading or SSR in Progress, Ignore!!!", __func__); + return 0; + } + if (VOS_FTM_MODE == hdd_get_conparam()) { hddLog(LOGE, FL("Command not allowed in FTM mode")); return -EINVAL; @@ -22563,6 +22894,8 @@ int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter, vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId), ssid, ssid_len); + pRoamProfile->do_not_roam = false; + /* cleanup bssid hint and bssid */ vos_mem_zero(pRoamProfile->bssid_hint, VOS_MAC_ADDR_SIZE); vos_mem_zero(pRoamProfile->BSSIDs.bssid, VOS_MAC_ADDR_SIZE); @@ -22635,6 +22968,14 @@ int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter, pRoamProfile->mcEncryptionType.numEntries = 1; pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI; } +#if defined(WLAN_FEATURE_11AC) && defined(WLAN_WAPI_MODE_11AC_DISABLE) + if( (pRoamProfile->phyMode & eCSR_DOT11_MODE_11ac) || + (pRoamProfile->phyMode & eCSR_DOT11_MODE_11ac_ONLY) ) + { + pRoamProfile->phyMode &= ~eCSR_DOT11_MODE_11ac; + pRoamProfile->phyMode &= ~eCSR_DOT11_MODE_11ac_ONLY; + } +#endif } #endif /* FEATURE_WLAN_WAPI */ #ifdef WLAN_FEATURE_GTK_OFFLOAD @@ -24258,6 +24599,12 @@ static int wlan_hdd_cfg80211_set_privacy_ibss( if (NULL != ie) { pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA; + if (ie[1] < DOT11F_IE_WPA_MIN_LEN || + ie[1] > DOT11F_IE_WPA_MAX_LEN) { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid ie len:%d"), + ie[1]); + return -EINVAL; + } // Unpack the WPA IE //Skip past the EID byte and length byte - and four byte WiFi OUI dot11fUnpackIeWPA((tpAniSirGlobal) halHandle, @@ -26015,8 +26362,10 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, wlan_hdd_get_rssi(pAdapter, &sinfo->signal); wlan_hdd_get_snr(pAdapter, &snr); pHddStaCtx->conn_info.signal = sinfo->signal; + pHddStaCtx->cache_conn_info.signal = sinfo->signal; pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr; + pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise; #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) sinfo->filled |= STATION_INFO_SIGNAL; #else @@ -26492,6 +26841,9 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, pHddStaCtx->conn_info.txrate.mcs = sinfo->txrate.mcs; pHddStaCtx->conn_info.txrate.legacy = sinfo->txrate.legacy; pHddStaCtx->conn_info.txrate.nss = sinfo->txrate.nss; + vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate, + &pHddStaCtx->conn_info.txrate, + sizeof(pHddStaCtx->conn_info.txrate)); #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) sinfo->filled |= STATION_INFO_TX_BITRATE | @@ -29996,7 +30348,10 @@ int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy, bool thermal) } } dev = pHddCtx->parent_dev; + +#ifdef FEATURE_BUS_BANDWIDTH vos_request_bus_bandwidth(dev, CNSS_BUS_WIDTH_MEDIUM); +#endif /* Resume MC thread */ if (pHddCtx->isMcThreadSuspended) { @@ -30295,7 +30650,9 @@ int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, NO_SESSION, pHddCtx->isWiphySuspended)); pHddCtx->isWiphySuspended = TRUE; +#ifdef FEATURE_BUS_BANDWIDTH vos_request_bus_bandwidth(dev, CNSS_BUS_WIDTH_NONE); +#endif if (thermal) { wlan_hdd_thermal_suspend(pHddCtx); @@ -30312,7 +30669,9 @@ int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, EXIT(); return 0; fail_suspend: +#ifdef FEATURE_BUS_BANDWIDTH vos_request_bus_bandwidth(dev, CNSS_BUS_WIDTH_MEDIUM); +#endif pHddCtx->isWiphySuspended = FALSE; #ifdef QCA_CONFIG_SMP complete(&vosSchedContext->ResumeTlshimRxEvent); diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index 3138bd1c78d2..3b8373f6d601 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -97,6 +97,10 @@ extern int process_wma_set_command(int sessid, int paramid, #include "wlan_hdd_tsf.h" #include "wlan_hdd_oemdata.h" +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +#include <vos_utils.h> +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + #define IS_UP(_dev) \ (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP)) #define IS_UP_AUTO(_ic) \ @@ -1129,6 +1133,46 @@ void hdd_hostapd_inactivity_timer_cb(v_PVOID_t usrDataForCallback) EXIT(); } +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +//This function runs in the timer context of hdd_ap_chan_switch_timer. +void hdd_hostapd_chan_switch_cb(v_PVOID_t usrDataForCallback) +{ + hdd_adapter_t *pHostapdAdapter = NULL; + hdd_context_t *pHddCtx = NULL; + int ret = 0; + + ENTER(); + + if(usrDataForCallback) + { + pHostapdAdapter = (struct hdd_adapter_s *)usrDataForCallback; + } + else + { + hddLog(LOGE, FL("hdd_hostapd_chan_switch_cb NULL cb pointer!!\n")); + EXIT(); + return; + } + pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter); + + mutex_lock(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock); + if(pHddCtx->ch_switch_ctx.sap_chan_sw_pending) + { + vos_ssr_protect(__func__); + ret = hdd_softap_set_channel_change(pHostapdAdapter->dev, pHddCtx->ch_switch_ctx.def_csa_channel_on_disc); + vos_ssr_unprotect(__func__); + if (ret) + { + hddLog(LOGE, FL("hdd_softap_set_channel_change failed!!")); + } + pHddCtx->ch_switch_ctx.sap_chan_sw_pending = 0; + } + mutex_unlock(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock); + + EXIT(); +} +#endif //#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + static VOS_STATUS hdd_change_mcc_go_beacon_interval(hdd_adapter_t *pHostapdAdapter) { @@ -1507,6 +1551,218 @@ VOS_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter, return VOS_STATUS_SUCCESS; } +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +VOS_STATUS hdd_send_sap_event(struct net_device *dev, + sta_sap_notifications event, + struct wlan_sap_csa_info csa_info, + struct wireless_dev *wdev) +{ + uint32_t freq = 0, ret; + + hdd_wlan_get_freq(csa_info.sta_channel, &freq); + + hddLog(LOG1, FL(" Set Freq %d Chan= %d"), freq, csa_info.sta_channel ); + + vos_ssr_protect(__func__); + ret = hdd_softap_set_channel_change(dev, csa_info.sta_channel); + vos_ssr_unprotect(__func__); + + return ret; +} + +VOS_STATUS hdd_sta_state_sap_notify(hdd_context_t *hdd_context, + sta_sap_notifications event, + struct wlan_sap_csa_info csa_info) +{ + /* Get the HostApd Adapter. If present proceed further. + * Check the current state of SAP. If its in active state, get the channel in which it is running. + * Verify the channel and band. Based on the event type, take a decision. + * If it is a disconnection event and SAP is running in 2.4 band channel, no action should be taken. + * If its a connection event and SAP needs to do a CSA to the HomeAP channel. + */ + + hdd_adapter_t *pHostapdAdapter = NULL; + hdd_ap_ctx_t *pHddApCtx = NULL; + hdd_hostapd_state_t *pHostapdState = NULL; + VOS_STATUS status = VOS_STATUS_SUCCESS; + tsap_Config_t *sap_config; + uint32_t ret = 0; + + hddLog(LOGE, FL("%s Entry event = %d channel = %d"), + __func__, event, csa_info.sta_channel); + + if (!hdd_context) { + hddLog(LOGE, FL("HDD context is NULL")); + return VOS_STATUS_E_FAILURE; + } + + ret = wlan_hdd_validate_context(hdd_context); + + if (ret != 0) { + + hddLog(LOGE, FL("%s Failed in hdd_validate_context ret=%d"), __func__, ret); + return ret; + } + + /*Get the Adapter of SAP*/ + pHostapdAdapter = hdd_get_adapter(hdd_context, WLAN_HDD_SOFTAP); + + if(!pHostapdAdapter) + { + hddLog(LOGE, FL("Hostapd adapter context is NULL")); + return VOS_STATUS_E_FAILURE; + } + + pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter); + + pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter); + + /*Verify the state*/ + if(pHostapdState->vosStatus != VOS_STATUS_SUCCESS || + pHostapdState->bssState != BSS_START) + { + hddLog(LOGE, FL("Invalid HostApd State vosStatus=%d bssState=%d"), + pHostapdState->vosStatus, pHostapdState->bssState); + return VOS_STATUS_E_FAILURE; + } + + switch(event) + { + case STA_NOTIFY_DISCONNECTED: + { + /* check for the operating channel + * If operating in 2.4, just ignore and return + * else start ACS & find the strongest signal channel and do initiate CSA to that channel. + */ + if((pHddApCtx->operatingChannel >= 1 && pHddApCtx->operatingChannel <= 14)) + { + hddLog(LOGE, FL("Hostapd is operating in 2.4Band Channel=%d, Avoid channel switch"), + pHddApCtx->operatingChannel); + } + else + { + sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->sapConfig); + if (VOS_IS_DFS_CH(pHddApCtx->operatingChannel) && + ( VOS_IS_DFS_CH(sap_config->channel) || + (sap_config->channel == AUTO_CHANNEL_SELECT) )){ + hddLog(LOGE, FL("SAP CUR CH %d(DFS) Hostapd Conf CH=%d(%s) Switch to CH %d"), + pHddApCtx->operatingChannel, pHddApCtx->operatingChannel, + (sap_config->channel == AUTO_CHANNEL_SELECT)?"AUTO":"DFS", 36); + hdd_context->ch_switch_ctx.def_csa_channel_on_disc = 36; + }else if (VOS_IS_DFS_CH(pHddApCtx->operatingChannel) && + !VOS_IS_DFS_CH(sap_config->channel)){ + hddLog(LOGE, FL("SAP CUR CH %d(DFS) Hostapd Conf CH=%d(Non-DFS) Switch to %d"), + pHddApCtx->operatingChannel, sap_config->channel, sap_config->channel); + hdd_context->ch_switch_ctx.def_csa_channel_on_disc = sap_config->channel; //channel from the hostapd + }else{ + hddLog(LOGE, FL("SAP is operating in 5Ghz Band Non DFS Channel=%d, Avoid channel switch"), + pHddApCtx->operatingChannel); + return status; + } + mutex_lock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock); + hdd_context->ch_switch_ctx.sap_chan_sw_pending = 1; + mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock); + + //Set the timer to initiate channel switch + if(hdd_context->ch_switch_ctx.chan_sw_timer_initialized == VOS_TRUE) + { + status = vos_timer_start(&hdd_context->ch_switch_ctx.hdd_ap_chan_switch_timer, 10000); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(LOGE, FL("Failed to start AP channel switch timer!!")); + break; + } + } + } + } + break; + case STA_NOTIFY_CONNECTED: + { + //stop the channel switch timer first + if (hdd_context->ch_switch_ctx.hdd_ap_chan_switch_timer.state == VOS_TIMER_STATE_RUNNING) + { + status = vos_timer_stop(&hdd_context->ch_switch_ctx.hdd_ap_chan_switch_timer); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(LOGE, FL("Failed to stop AP channel switch timer!!")); + break; + } + } + if(pHddApCtx->operatingChannel != csa_info.sta_channel) + { + mutex_lock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock); + hddLog(LOGE, FL("Switching Hostapd to Station channel %d"), csa_info.sta_channel); + status = hdd_send_sap_event(pHostapdAdapter->dev, + event, + csa_info, + &pHostapdAdapter->wdev); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(LOGE, FL("Failed to send channel switch event!!")); + mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock); + break; + } + hdd_context->ch_switch_ctx.sap_chan_sw_pending = 0; + mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock); + } + else + { + hddLog(LOGE, FL("Hostapd and Sta are operating in same channel : %d\n"), + pHddApCtx->operatingChannel); + } + } + break; + case STA_NOTIFY_CSA: + { + mutex_lock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock); + if(pHddApCtx->operatingChannel != csa_info.sta_channel) + { + if(!(hdd_context->ch_switch_ctx.is_ch_sw_through_sta_csa && + hdd_context->ch_switch_ctx.csa_to_channel == csa_info.sta_channel)) + { + hdd_context->ch_switch_ctx.is_ch_sw_through_sta_csa = VOS_TRUE; + + hddLog(LOGE, FL("Switching Hostapd to Station channel %d"), csa_info.sta_channel); + status = hdd_send_sap_event(pHostapdAdapter->dev, + event, + csa_info, + &pHostapdAdapter->wdev); + if(!VOS_IS_STATUS_SUCCESS(status)) + { + hddLog(LOGE, FL("Failed to send channel switch event!!")); + mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock); + break; + } + + hdd_context->ch_switch_ctx.csa_to_channel = csa_info.sta_channel; + } + else + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : CSA Sta interface for Channel %d is already notified", + __func__, csa_info.sta_channel); + } + } + else + { + hddLog(LOGE, FL("Hostapd and Sta are operating in same channel : %d\n"), + pHddApCtx->operatingChannel); + } + mutex_unlock(&hdd_context->ch_switch_ctx.sap_ch_sw_lock); + } + break; + default: + { + hddLog(LOGE, FL("%s Invalid event %d"), __func__, event); + } + break; + } + + hddLog(LOGE, FL("%s Exit ret = %d"), __func__, status); + + return status; +} +#endif //#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN /** * hdd_send_radar_event() - Function to send radar events to user space * @hdd_context: HDD context @@ -2184,6 +2440,19 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa we_event = IWEVCUSTOM; we_custom_event_generic = we_custom_start_event; hdd_dump_concurrency_info(pHddCtx); +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + if(pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) + { + mutex_lock(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock); + if(pHddCtx->ch_switch_ctx.is_ch_sw_through_sta_csa && + (pHddApCtx->operatingChannel == pHddCtx->ch_switch_ctx.csa_to_channel)){ + hddLog(LOG1, FL("Successfully Channel Switch is done to CH = %d"), + pHddApCtx->operatingChannel); + pHddCtx->ch_switch_ctx.is_ch_sw_through_sta_csa = VOS_FALSE; + } + mutex_unlock(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock); + } +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN break; //Event will be sent after Switch-Case stmt case eSAP_STOP_BSS_EVENT: diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 066046c4c891..71bf1c6bfde6 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -408,6 +408,14 @@ uint8_t wlan_hdd_find_opclass(tHalHandle hal, uint8_t channel, return opclass; } +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +void hdd_csa_notify_cb +( + void *hdd_context, + void *indi_param +); +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + #ifdef FEATURE_GREEN_AP static void hdd_wlan_green_ap_timer_fn(void *phddctx) @@ -1038,7 +1046,10 @@ void wlan_hdd_restart_sap(hdd_adapter_t *ap_adapter) clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags); wlan_hdd_decr_active_session(pHddCtx, ap_adapter->device_mode); hddLog(LOGE, FL("SAP Stop Success")); - +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + /*this delay is needed to ensure proper resource cleanup of SAP*/ + vos_sleep(1000); +#endif //#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN if (pHddCtx->cfg_ini->apOBSSProtEnabled) vos_runtime_pm_allow_suspend(pHddCtx->runtime_context.obss); if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) { @@ -1790,6 +1801,15 @@ hdd_system_suspend_state(hdd_context_t *hdd_ctx) return s; } +/** + * hdd_system_suspend_state_set() - Set the system suspended state + * @hdd_ctx: Pointer to hdd_context_t + * @state: The target state to be set + * + * Set the system suspended state + * + * Return: The state before set. + */ bool hdd_system_suspend_state_set(hdd_context_t *hdd_ctx, bool state) { @@ -1804,7 +1824,14 @@ hdd_system_suspend_state_set(hdd_context_t *hdd_ctx, bool state) return old; } - +/** + * hdd_thermal_suspend_state() - Get the thermal suspend state + * @hdd_ctx: Pointer to hdd_context_t + * + * Get the thermal suspend state + * + * Return: The current thermal suspend state + */ int hdd_thermal_suspend_state(hdd_context_t *hdd_ctx) { @@ -1888,6 +1915,30 @@ hdd_thermal_suspend_cleanup(hdd_context_t *hdd_ctx) } } +static inline void +hdd_thermal_resume_complete_ind(struct wiphy *wiphy) +{ + struct sk_buff *vendor_event; + + hddLog(LOG1, FL("Thermal resume complete indication")); + + vendor_event = cfg80211_vendor_event_alloc(wiphy, NULL, + sizeof(uint8_t) + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT_INDEX, + GFP_KERNEL); + if (!vendor_event) { + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); + return; + } + + nla_put_flag(vendor_event, + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_RESUME_COMPLETE); + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); +} + + + static void hdd_thermal_suspend_work(struct work_struct *work) { @@ -1952,6 +2003,26 @@ hdd_thermal_suspend_queue_work(hdd_context_t *hdd_ctx, unsigned long ms) static void hdd_thermal_temp_ind_event_cb(hdd_context_t *hdd_ctx, uint32_t degreeC) { + struct sk_buff *vendor_event; + + vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, + NULL, sizeof(uint32_t) + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_THERMAL_EVENT_INDEX, + GFP_KERNEL); + if (!vendor_event) { + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); + return; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_THERMAL_EVENT_TEMPERATURE, degreeC)) { + hddLog(LOGE, FL("nla put failed")); + kfree_skb(vendor_event); + return; + } + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + if (!hdd_ctx->cfg_ini->thermal_shutdown_auto_enabled) { return; } @@ -1960,10 +2031,9 @@ hdd_thermal_temp_ind_event_cb(hdd_context_t *hdd_ctx, uint32_t degreeC) * Here, we only do thermal suspend. * * We can only resume FW elsewhere in two ways: - * 1. triggered by wakeup interrupt from FW when it detects T < Tresume + * 1. triggered by host when it detects FW reported T is less than Tr * 2. user space app launch thermal resume after suspend as app wants * - * Key factor: FW cannot provide temperature when it suspended. */ if ((hdd_thermal_suspend_state(hdd_ctx) == HDD_WLAN_THERMAL_ACTIVE && degreeC >= hdd_ctx->cfg_ini->thermal_suspend_threshold) || @@ -11892,6 +11962,8 @@ hdd_adapter_t *hdd_open_adapter(hdd_context_t *hdd_ctx, if (session_type == WLAN_HDD_P2P_CLIENT) adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT; + else if (VOS_MONITOR_MODE == vos_get_conparam()) + adapter->wdev.iftype = NL80211_IFTYPE_MONITOR; else adapter->wdev.iftype = NL80211_IFTYPE_STATION; @@ -12701,6 +12773,27 @@ VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, wlan_hdd_reset_prob_rspies(pAdapter); kfree(pAdapter->sessionCtx.ap.beacon); pAdapter->sessionCtx.ap.beacon = NULL; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + if (pAdapter->device_mode == WLAN_HDD_SOFTAP) + { + if(pHddCtx->ch_switch_ctx.chan_sw_timer_initialized == VOS_TRUE) + { + //Stop the channel switch timer + if (VOS_TIMER_STATE_RUNNING == + vos_timer_getCurrentState(&pHddCtx->ch_switch_ctx.hdd_ap_chan_switch_timer)) + { + vos_timer_stop(&pHddCtx->ch_switch_ctx.hdd_ap_chan_switch_timer); + } + //Destroy the channel switch timer + if (!VOS_IS_STATUS_SUCCESS(vos_timer_destroy( + &pHddCtx->ch_switch_ctx.hdd_ap_chan_switch_timer))) + { + hddLog(LOGE, FL("Failed to destroy AP channel switch timer!!")); + } + pHddCtx->ch_switch_ctx.chan_sw_timer_initialized = VOS_FALSE; + } + } +#endif //WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN } mutex_unlock(&pHddCtx->sap_lock); @@ -15378,6 +15471,10 @@ void hdd_cnss_request_bus_bandwidth(hdd_context_t *pHddCtx, "%s: TCP DELACK trigger level %d, average_rx: %llu", __func__, next_rx_level, temp_rx); pHddCtx->cur_rx_level = next_rx_level; +#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK + if (pHddCtx->cfg_ini->del_ack_enable) + next_rx_level = WLAN_SVC_TP_LOW; +#endif wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index, WLAN_SVC_WLAN_TP_IND, &next_rx_level, @@ -16192,13 +16289,11 @@ static int hdd_initialize_mac_address(hdd_context_t *hdd_ctx) if (!hdd_ctx->cfg_ini->skip_mac_config) { status = hdd_update_mac_config(hdd_ctx); - if (status != VOS_STATUS_SUCCESS) { - hddLog(LOGW, - FL("Failed to update MAC from %s status: %d"), - WLAN_MAC_FILE, status); - return -EIO; - } - return 0; + if (status == VOS_STATUS_SUCCESS) + return 0; + + hddLog(LOGW, FL("Can't update MAC from %s status: %d"), + WLAN_MAC_FILE, status); } if (!vos_is_macaddr_zero(&hdd_ctx->hw_macaddr)) { @@ -16218,6 +16313,21 @@ static int hdd_initialize_mac_address(hdd_context_t *hdd_ctx) return 0; } +static void hdd_get_DPD_Recaliberation_ini_param(tSmeDPDRecalParams *pDPDParam, + hdd_context_t *pHddCtx) +{ + pDPDParam->enable = + pHddCtx->cfg_ini->dpd_recalib_enabled; + pDPDParam->delta_degreeHigh = + pHddCtx->cfg_ini->dpd_recalib_delta_degreehigh; + pDPDParam->delta_degreeLow = + pHddCtx->cfg_ini->dpd_recalib_delta_degreelow; + pDPDParam->cooling_time = + pHddCtx->cfg_ini->dpd_recalib_cooling_time; + pDPDParam->dpd_dur_max = + pHddCtx->cfg_ini->dpd_recalib_duration_max; +} + #ifdef FEATURE_WLAN_THERMAL_SHUTDOWN static VOS_STATUS hdd_init_thermal_ctx(hdd_context_t *pHddCtx) { @@ -16287,6 +16397,7 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) struct wiphy *wiphy; unsigned long rc; tSmeThermalParams thermalParam; + tSmeDPDRecalParams DPDParam; tSirTxPowerLimit *hddtxlimit; #ifdef FEATURE_WLAN_CH_AVOID #ifdef CONFIG_CNSS @@ -16892,6 +17003,13 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) #endif #endif /* FEATURE_WLAN_CH_AVOID */ +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + /* Initialize the lock*/ + mutex_init(&pHddCtx->ch_switch_ctx.sap_ch_sw_lock); + /*Register the CSA Notification callback*/ + sme_AddCSAIndCallback(pHddCtx->hHal, hdd_csa_notify_cb); +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + status = hdd_post_voss_start_config( pHddCtx ); if ( !VOS_IS_STATUS_SUCCESS( status ) ) { @@ -16930,6 +17048,7 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) rtnl_lock_enable); #ifdef WLAN_OPEN_P2P_INTERFACE + if(VOS_MONITOR_MODE != vos_get_conparam()){ /* Open P2P device interface */ if (pAdapter != NULL && !hdd_cfg_is_sub20_channel_width_enabled(pHddCtx)) { @@ -16966,6 +17085,7 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) goto err_close_adapter; } } + } #endif /* WLAN_OPEN_P2P_INTERFACE */ /* Open 802.11p Interface */ @@ -17245,6 +17365,15 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) "%s: Error while initializing thermal information", __func__); } + /* Runtime DPD Recaliberation config*/ + hdd_get_DPD_Recaliberation_ini_param(&DPDParam, pHddCtx); + + if (eHAL_STATUS_SUCCESS != sme_InitDPDRecalInfo(pHddCtx->hHal, DPDParam)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Error while initializing Runtime DPD Recaliberation information", __func__); + } + /* Plug in set thermal level callback */ sme_add_set_thermal_level_callback(pHddCtx->hHal, (tSmeSetThermalLevelCallback)hdd_set_thermal_level_cb); @@ -19556,18 +19685,85 @@ void wlan_hdd_check_sta_ap_concurrent_ch_intf(void *data) pHddApCtx->sapConfig.channel, intf_ch); pHddApCtx->sapConfig.channel = intf_ch; - pHddApCtx->bss_stop_reason = BSS_STOP_DUE_TO_MCC_SCC_SWITCH; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + if(vos_is_ch_switch_with_csa_enabled()) + { + struct wlan_sap_csa_info csa_info; + + csa_info.sta_channel = intf_ch; - sme_SelectCBMode(hHal, + hddLog(VOS_TRACE_LEVEL_INFO_HIGH, + "%s: Indicate connected event to HostApd Chan=%d", + __func__, csa_info.sta_channel); + + /*Indicate to HostApd about Station interface state change*/ + hdd_sta_state_sap_notify(pHddCtx, STA_NOTIFY_CONNECTED, csa_info); + }else{ +#endif + pHddApCtx->bss_stop_reason = BSS_STOP_DUE_TO_MCC_SCC_SWITCH; + sme_SelectCBMode(hHal, pHddApCtx->sapConfig.SapHw_mode, pHddApCtx->sapConfig.channel, pHddApCtx->sapConfig.sec_ch, &vht_channel_width, pHddApCtx->sapConfig.ch_width_orig); - wlan_sap_set_vht_ch_width(pHddApCtx->sapContext, vht_channel_width); - wlan_hdd_restart_sap(ap_adapter); + wlan_sap_set_vht_ch_width(pHddApCtx->sapContext, vht_channel_width); + wlan_hdd_restart_sap(ap_adapter); +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + } +#endif } #endif +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + +void hdd_csa_notify_cb +( + void *hdd_context, + void *indi_param +) +{ + tpSmeCsaOffloadInd csa_params = NULL; + hdd_context_t *hdd_ctxt = NULL; + struct wlan_sap_csa_info csa_info; + v_U32_t ret = 0; + /* Basic sanity */ + + if(!vos_is_ch_switch_with_csa_enabled()) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s : SAP channel switch with CSA not enabled", __func__); + return; + } + + if (!hdd_context || !indi_param) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s : Invalid arguments", __func__); + return; + } + + hdd_ctxt = (hdd_context_t *)hdd_context; + + csa_params = (tpSmeCsaOffloadInd)indi_param; + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s : tbtt count %d Channel = %d", + __func__,csa_params->tbtt_count, csa_params->channel); + hdd_ctxt->ch_switch_ctx.tbtt_count = csa_params->tbtt_count - 1; /* Will reduce the count by 1, + as the switch might take time. + Currently of No Use, as this will be + override by ini g_sap_chanswitch_beacon_cnt */ + csa_info.sta_channel = csa_params->channel; + ret = hdd_sta_state_sap_notify(hdd_ctxt, STA_NOTIFY_CSA, csa_info); + if(ret != 0) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s : Failed to trigger Channel Switch Ch:%d ret=%d", + __func__,csa_params->channel, ret); + } +} +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + /** * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's * and sta's operating channel. diff --git a/CORE/HDD/src/wlan_hdd_memdump.c b/CORE/HDD/src/wlan_hdd_memdump.c index cb6947230c30..09deb2e6105c 100644 --- a/CORE/HDD/src/wlan_hdd_memdump.c +++ b/CORE/HDD/src/wlan_hdd_memdump.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -42,14 +42,14 @@ #include <linux/proc_fs.h> /* Necessary because we use the proc fs */ #include <linux/uaccess.h> /* for copy_to_user */ -#define PROCFS_DRIVER_DUMP_DIR "debugdriver" - #ifdef MULTI_IF_NAME -#define PROCFS_DRIVER_DUMP_NAME "driverdump" MULTI_IF_NAME +#define PROCFS_DRIVER_DUMP_DIR "debugdriver" MULTI_IF_NAME #else -#define PROCFS_DRIVER_DUMP_NAME "driverdump" +#define PROCFS_DRIVER_DUMP_DIR "debugdriver" #endif +#define PROCFS_DRIVER_DUMP_NAME "driverdump" + #define PROCFS_DRIVER_DUMP_PERM 0444 static struct proc_dir_entry *proc_file_driver, *proc_dir_driver; diff --git a/CORE/HDD/src/wlan_hdd_ocb.c b/CORE/HDD/src/wlan_hdd_ocb.c index d511f9b097be..8de1fd9cf7b1 100644 --- a/CORE/HDD/src/wlan_hdd_ocb.c +++ b/CORE/HDD/src/wlan_hdd_ocb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1013,18 +1013,10 @@ static int __wlan_hdd_cfg80211_ocb_set_config(struct wiphy *wiphy, tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_SCHEDULE_SIZE]); /* Get the ndl chan array and the ndl active state array. */ - if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY]) { - hddLog(LOGE, FL("NDL_CHANNEL_ARRAY is not present")); - return -EINVAL; - } ndl_chan_list = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_CHANNEL_ARRAY]; ndl_chan_list_len = (ndl_chan_list ? nla_len(ndl_chan_list) : 0); - if (!tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY]) { - hddLog(LOGE, FL("NDL_ACTIVE_STATE_ARRAY is not present")); - return -EINVAL; - } ndl_active_state_list = tb[QCA_WLAN_VENDOR_ATTR_OCB_SET_CONFIG_NDL_ACTIVE_STATE_ARRAY]; ndl_active_state_list_len = (ndl_active_state_list ? diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index 363d1a1076cc..77a60bb2dc46 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1174,12 +1174,18 @@ static int wlan_hdd_execute_remain_on_channel(hdd_adapter_t *pAdapter, return -EINVAL; } - if (REMAIN_ON_CHANNEL_REQUEST == pRemainChanCtx->rem_on_chan_request) { + mutex_lock(&cfgState->remain_on_chan_ctx_lock); + pRemainChanCtx = cfgState->remain_on_chan_ctx; + if ((pRemainChanCtx)&&(REMAIN_ON_CHANNEL_REQUEST == + pRemainChanCtx->rem_on_chan_request)) { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); if (eHAL_STATUS_SUCCESS != sme_RegisterMgmtFrame( WLAN_HDD_GET_HAL_CTX(pAdapter), sessionId, (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_PROBE_REQ << 4), NULL, 0)) hddLog(LOGE, FL("sme_RegisterMgmtFrame returned failure")); + } else { + mutex_unlock(&cfgState->remain_on_chan_ctx_lock); } } else if ( ( WLAN_HDD_SOFTAP== pAdapter->device_mode ) || @@ -2965,6 +2971,25 @@ struct wireless_dev* __wlan_hdd_add_virtual_intf( hddLog(VOS_TRACE_LEVEL_ERROR,"%s: hdd_open_adapter failed",__func__); return ERR_PTR(-ENOSPC); } +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + if(pAdapter->device_mode == WLAN_HDD_SOFTAP) + { + if(pHddCtx->ch_switch_ctx.chan_sw_timer_initialized == VOS_FALSE) + { + //Initialize the channel switch timer + ret = vos_timer_init(&pHddCtx->ch_switch_ctx.hdd_ap_chan_switch_timer, VOS_TIMER_TYPE_SW, + hdd_hostapd_chan_switch_cb, (v_PVOID_t)pAdapter); + if(!VOS_IS_STATUS_SUCCESS(ret)) + { + hddLog(LOGE, FL("Failed to initialize AP channel switch timer!!\n")); + EXIT(); + return ERR_PTR(ret); + } + pHddCtx->ch_switch_ctx.chan_sw_timer_initialized = VOS_TRUE; + } + } +#endif //WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + EXIT(); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0)) || defined(WITH_BACKPORTS) return pAdapter->dev->ieee80211_ptr; diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c index d4841595ff21..8e9464fb8a47 100644 --- a/CORE/HDD/src/wlan_hdd_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -1143,29 +1143,37 @@ bool drop_ip6_mcast(struct sk_buff *skb) * For HL monitor mode, radiotap is appended to tail when update radiotap * info in htt layer. Need to copy it ahead of skb before indicating to OS. */ -static void hdd_move_radiotap_header_forward(struct sk_buff *skb) +static VOS_STATUS hdd_move_radiotap_header_forward(struct sk_buff *skb) { adf_nbuf_t msdu = (adf_nbuf_t)skb; struct ieee80211_radiotap_header *rthdr; uint8_t rtap_len; - adf_nbuf_put_tail(msdu, + if (!adf_nbuf_put_tail(msdu, + sizeof(struct ieee80211_radiotap_header))) + return VOS_STATUS_E_NOMEM; + else { + rthdr = (struct ieee80211_radiotap_header *) + (adf_nbuf_data(msdu) + adf_nbuf_len(msdu) - sizeof(struct ieee80211_radiotap_header)); - rthdr = (struct ieee80211_radiotap_header *) - (adf_nbuf_data(msdu) + adf_nbuf_len(msdu) - - sizeof(struct ieee80211_radiotap_header)); - rtap_len = rthdr->it_len; - adf_nbuf_put_tail(msdu, + rtap_len = rthdr->it_len; + if (!adf_nbuf_put_tail(msdu, rtap_len - - sizeof(struct ieee80211_radiotap_header)); - adf_nbuf_push_head(msdu, rtap_len); - adf_os_mem_copy(adf_nbuf_data(msdu), rthdr, rtap_len); - adf_nbuf_trim_tail(msdu, rtap_len); + sizeof(struct ieee80211_radiotap_header))) + return VOS_STATUS_E_NOMEM; + else { + adf_nbuf_push_head(msdu, rtap_len); + adf_os_mem_copy(adf_nbuf_data(msdu), rthdr, rtap_len); + adf_nbuf_trim_tail(msdu, rtap_len); + } + } + return VOS_STATUS_SUCCESS; } #else -static inline void hdd_move_radiotap_header_forward(struct sk_buff *skb) +static inline VOS_STATUS hdd_move_radiotap_header_forward(struct sk_buff *skb) { /* no-op */ + return VOS_STATUS_SUCCESS; } #endif @@ -1218,11 +1226,14 @@ VOS_STATUS hdd_mon_rx_packet_cbk(v_VOID_t *vos_ctx, adf_nbuf_t rx_buf, /* walk the chain until all are processed */ skb = (struct sk_buff *) rx_buf; while (NULL != skb) { - hdd_move_radiotap_header_forward(skb); - skb_next = skb->next; skb->dev = adapter->dev; + if(hdd_move_radiotap_header_forward(skb)) { + skb = skb_next; + continue; + } + ++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index]; ++adapter->stats.rx_packets; adapter->stats.rx_bytes += skb->len; diff --git a/CORE/HDD/src/wlan_hdd_wext.c b/CORE/HDD/src/wlan_hdd_wext.c index bcc796739090..eeeeab621601 100644 --- a/CORE/HDD/src/wlan_hdd_wext.c +++ b/CORE/HDD/src/wlan_hdd_wext.c @@ -253,6 +253,10 @@ typedef enum eMonFilterType{ MON_ALL_PKT, } tMonFilterType; +#define WE_SET_TDLS_OFFCHANNEL_MODE 90 +#define WE_SET_TDLS_OFFCHANNEL 91 +#define WE_SET_TDLS_OFFCHANNEL_SEC_OFFSET 92 + /* Private ioctls and their sub-ioctls */ #define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1) #define WE_GET_11D_STATE 1 @@ -2177,8 +2181,13 @@ __iw_get_mode(struct net_device *dev, struct iw_request_info *info, switch (pWextState->roamProfile.BSSType) { case eCSR_BSS_TYPE_INFRASTRUCTURE: - hddLog(LOG1, FL("returns IW_MODE_INFRA")); - wrqu->mode = IW_MODE_INFRA; + if(VOS_MONITOR_MODE == vos_get_conparam()){ + hddLog(LOG1, FL("returns IW_MODE_MONITOR")); + wrqu->mode = IW_MODE_MONITOR; + }else{ + hddLog(LOG1, FL("returns IW_MODE_INFRA")); + wrqu->mode = IW_MODE_INFRA; + } break; case eCSR_BSS_TYPE_IBSS: case eCSR_BSS_TYPE_START_IBSS: @@ -7398,6 +7407,32 @@ static int __iw_setint_getnone(struct net_device *dev, wlan_hdd_mnt_filter_type_cmd(pAdapter, &filter_type,sizeof(v_U8_t)); break; } + case WE_SET_TDLS_OFFCHANNEL_MODE: + { + hddLog(LOG1, "SET tdls_offchannel_mode val %d", set_value); + ret = hdd_set_tdls_offchannelmode(pAdapter, set_value); + break; + } + case WE_SET_TDLS_OFFCHANNEL: + { + hddLog(LOG1, "SET tdls_offchannel val %d", set_value); + + if (VOS_IS_DFS_CH(set_value)) { + hddLog(LOGE, + FL("DFS channel %d is passed for hdd_set_tdls_offchannel"), + set_value); + ret = -EINVAL; + break; + } + ret = hdd_set_tdls_offchannel(pHddCtx, set_value); + break; + } + case WE_SET_TDLS_OFFCHANNEL_SEC_OFFSET: + { + hddLog(LOG1, "SET tdls_offchannel_mode val %d", set_value); + ret = hdd_set_tdls_secoffchanneloffset(pHddCtx, set_value); + break; + } default: { hddLog(LOGE, "%s: Invalid sub command %d", __func__, sub_cmd); @@ -12107,6 +12142,23 @@ static const struct iw_priv_args we_private_args[] = { WE_SET_MON_FILTER, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMonFilter" }, +#ifdef FEATURE_WLAN_TDLS + { + WE_SET_TDLS_OFFCHANNEL_MODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tdlsoffchnmode" }, + { + WE_SET_TDLS_OFFCHANNEL, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tdlsoffchan" }, + { + WE_SET_TDLS_OFFCHANNEL_SEC_OFFSET, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + 0, + "tdlsecchnoffst" }, +#endif /* handlers for sub-ioctl */ { WE_GET_11D_STATE, diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h index 367fc9482be9..d80ed78b7c39 100644 --- a/CORE/MAC/inc/aniGlobal.h +++ b/CORE/MAC/inc/aniGlobal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1008,7 +1008,6 @@ tLimMlmOemDataRsp *gpLimMlmOemDataRsp; tLimDisassocDeauthCnfReq limDisassocDeauthCnfReq; tANI_U8 deferredMsgCnt; tSirDFSChannelList dfschannelList; - tANI_U8 deauthMsgCnt; tANI_U8 gLimIbssStaLimit; /* Number of channel switch IEs sent so far */ diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 0b50aee66ed3..0e958d093f65 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -3186,6 +3186,10 @@ typedef struct sSmeCsaOffloadInd tANI_U16 mesgType; // eWNI_SME_CSA_OFFLOAD_EVENT tANI_U16 mesgLen; tSirMacAddr bssId; // BSSID +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + tANI_U16 channel; + tANI_U16 tbtt_count; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN } tSmeCsaOffloadInd, *tpSmeCsaOffloadInd; /// WOW related structures @@ -5259,6 +5263,9 @@ typedef struct sSirDfsCsaIeRequest uint8_t ch_switch_mode; uint8_t dfs_ch_switch_disable; uint8_t sub20_switch_mode; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + tANI_U8 csaSwitchCount; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN }tSirDfsCsaIeRequest, *tpSirDfsCsaIeRequest; /* Indication from lower layer indicating the completion of first beacon send @@ -5313,6 +5320,14 @@ typedef struct{ } t_thermal_mgmt, *tp_thermal_mgmt; +typedef struct{ + u_int32_t dpd_enable; + u_int32_t dpd_delta_degreeHigh; + u_int32_t dpd_delta_degreeLow; + u_int32_t dpd_cooling_time; + u_int32_t dpd_duration_max; +} t_dpd_recal_mgmt, *tp_dpd_recal_mgmt; + typedef struct sSirTxPowerLimit { /* Thermal limits for 2g and 5g */ diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 4bf2841f0242..fb06a65400a7 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -797,8 +797,9 @@ typedef struct sSirMbMsgP2p #define SIR_HAL_PEER_FLUSH_PENDING (SIR_HAL_ITC_MSG_TYPES_BEGIN + 375) #define SIR_HAL_SET_AC_TXQ_OPTIMIZE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 376) - #define SIR_HAL_MNT_FILTER_TYPE_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 377) + +#define SIR_HAL_INIT_DPD_RECAL_INFO_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 378) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) // CFG message types diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h index a8eafaa348a4..baf619b60f72 100644 --- a/CORE/MAC/src/pe/include/limSession.h +++ b/CORE/MAC/src/pe/include/limSession.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -529,6 +529,8 @@ typedef struct sPESession // Added to Support BT-AMP #ifdef WLAN_FEATURE_FILS_SK struct pe_fils_session *fils_info; #endif + uint8_t deauthmsgcnt; + uint8_t disassocmsgcnt; } tPESession, *tpPESession; /*------------------------------------------------------------------------- diff --git a/CORE/MAC/src/pe/lim/limApi.c b/CORE/MAC/src/pe/lim/limApi.c index 6a1ac07aa26d..1ca8e1106e94 100644 --- a/CORE/MAC/src/pe/lim/limApi.c +++ b/CORE/MAC/src/pe/lim/limApi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -958,7 +958,6 @@ tSirRetStatus peOpen(tpAniSirGlobal pMac, tMacOpenParameters *pMacOpenParam) status = eSIR_FAILURE; goto pe_open_lock_fail; } - pMac->lim.deauthMsgCnt = 0; pMac->lim.retry_packet_cnt = 0; pMac->lim.gLimIbssRetryCnt = 0; diff --git a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c index a4b14d6e0c1e..901f4aa2dd5b 100644 --- a/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c +++ b/CORE/MAC/src/pe/lim/limLinkMonitoringAlgo.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -184,6 +184,19 @@ limDeleteStaContext(tpAniSirGlobal pMac, tpSirMsgQ limMsg) vos_mem_free(pMsg); return; } + if (!((psessionEntry->limMlmState == + eLIM_MLM_LINK_ESTABLISHED_STATE) && + (psessionEntry->limSmeState != + eLIM_SME_WT_DISASSOC_STATE) && + (psessionEntry->limSmeState != + eLIM_SME_WT_DEAUTH_STATE))) { + limLog(pMac, LOGE, FL("Do not process in limMlmState %s(%x) limSmeState (%x)"), + limMlmStateStr(psessionEntry->limMlmState), + psessionEntry->limMlmState, + psessionEntry->limSmeState); + vos_mem_free(pMsg); + return; + } pStaDs = dphGetHashEntry(pMac, DPH_STA_HASH_INDEX_PEER, &psessionEntry->dph.dphHashTable); diff --git a/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c index 24c41d3e7222..72b03eb60250 100644 --- a/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c +++ b/CORE/MAC/src/pe/lim/limProcessDeauthFrame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014, 2016-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -94,16 +94,16 @@ limProcessDeauthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession p (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))) { /*Every 15th deauth frame will be logged in kmsg*/ - if(!(pMac->lim.deauthMsgCnt & 0xF)) + if(!(psessionEntry->deauthmsgcnt & 0xF)) { - PELOGE(limLog(pMac, LOGE, + limLog(pMac, LOGE, FL("received Deauth frame in DEAUTH_WT_STATE" "(already processing previously received DEAUTH frame).." - "Dropping this.. Deauth Failed %d"),++pMac->lim.deauthMsgCnt);) + "Dropping this.. Deauth Failed %d"),++psessionEntry->deauthmsgcnt); } else { - pMac->lim.deauthMsgCnt++; + psessionEntry->deauthmsgcnt++; } return; } @@ -535,12 +535,14 @@ limProcessDeauthFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession p eSIR_MAC_UNSPEC_FAILURE_STATUS, psessionEntry); return; } - /* reset the deauthMsgCnt here since we are able to Process - * the deauth frame and sending up the indication as well */ - if(pMac->lim.deauthMsgCnt != 0) - { - pMac->lim.deauthMsgCnt = 0; - } + + /* + * reset the deauthMsgCnt here since we are able to Process + * the deauth frame and sending up the indication as well + */ + if (psessionEntry->deauthmsgcnt != 0) + psessionEntry->deauthmsgcnt = 0; + if (LIM_IS_STA_ROLE(psessionEntry)) WDA_TxAbort(psessionEntry->smeSessionId); diff --git a/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c b/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c index c9b192103173..fb803eb90211 100644 --- a/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c +++ b/CORE/MAC/src/pe/lim/limProcessDisassocFrame.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -112,18 +112,17 @@ limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession } if (LIM_IS_STA_ROLE(psessionEntry) && - (eLIM_SME_WT_DISASSOC_STATE == psessionEntry->limSmeState)) { - if (pHdr->fc.retry > 0) { - /* - * This can happen when first disassoc frame is received - * but ACK from this STA is lost, in this case 2nd disassoc frame is - * already in transmission queue - */ - PELOGE(limLog(pMac, LOGE, - FL("AP is sending disassoc after ACK lost..."));) - return; + ((eLIM_SME_WT_DISASSOC_STATE == psessionEntry->limSmeState) || + (eLIM_SME_WT_DEAUTH_STATE == psessionEntry->limSmeState))) { + /*Every 15th deauth frame will be logged in kmsg*/ + if(!(psessionEntry->disassocmsgcnt & 0xF)) { + limLog(pMac, LOGE, + FL("Already processing previously received DEAUTH/Disassoc..Dropping this.. Deauth Failed cnt %d"), + ++psessionEntry->disassocmsgcnt); + } else { + psessionEntry->disassocmsgcnt++; } - + return; } @@ -337,6 +336,13 @@ limProcessDisassocFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tpPESession /* Update PE session Id */ mlmDisassocInd.sessionId = psessionEntry->peSessionId; + /* + * reset the deauthMsgCnt here since we are able to Process + * the deauth frame and sending up the indication as well + */ + if (psessionEntry->disassocmsgcnt != 0) + psessionEntry->disassocmsgcnt = 0; + if (limIsReassocInProgress(pMac,psessionEntry)) { /* If we're in the middle of ReAssoc and received disassoc from diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index 83c5afc1f19b..10f886d9fdec 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -7612,8 +7612,6 @@ limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg) psessionEntry->gLimChannelSwitch.secondarySubBand, psessionEntry); } - - psessionEntry->gLimChannelSwitch.switchCount--; } return; } diff --git a/CORE/MAC/src/pe/lim/limSendMessages.c b/CORE/MAC/src/pe/lim/limSendMessages.c index 3f0655c32077..f2eee7bfc33e 100644 --- a/CORE/MAC/src/pe/lim/limSendMessages.c +++ b/CORE/MAC/src/pe/lim/limSendMessages.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2014, 2016, 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014, 2016, 2017, 2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -273,6 +273,7 @@ tSirRetStatus limSendSwitchChnlParams(tpAniSirGlobal pMac, pChnlParams->restart_on_chan_switch = is_restart; pChnlParams->reduced_beacon_interval = pMac->sap.SapDfsInfo.reduced_beacon_interval; + pChnlParams->beacon_tx_rate = pSessionEntry->beacon_tx_rate; if (pSessionEntry->sub20_channelwidth == SUB20_MODE_5MHZ) pChnlParams->channelwidth = CH_WIDTH_5MHZ; diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c index e00b4e6c9ff3..698f5381c78c 100644 --- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c +++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -3119,6 +3119,10 @@ void limHandleCSAoffloadMsg(tpAniSirGlobal pMac,tpSirMsgQ MsgQ) mmhMsg.type = eWNI_SME_CSA_OFFLOAD_EVENT; mmhMsg.bodyptr = pCsaOffloadInd; mmhMsg.bodyval = 0; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + pCsaOffloadInd->tbtt_count = csa_params->csa_tbtt_count; + pCsaOffloadInd->channel = csa_params->channel; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN PELOG1(limLog(pMac, LOG1, FL("Sending eWNI_SME_CSA_OFFLOAD_EVENT to SME. "));) MTRACE(macTraceMsgTx(pMac, psessionEntry->peSessionId, mmhMsg.type)); limDiagEventReport(pMac, WLAN_PE_DIAG_SWITCH_CHL_REQ_EVENT, psessionEntry, @@ -3497,6 +3501,8 @@ limProcessBeaconTxSuccessInd(tpAniSirGlobal pMac, tANI_U16 msgType, void *event) if (LIM_IS_AP_ROLE(psessionEntry) && VOS_TRUE == psessionEntry->dfsIncludeChanSwIe) { + /* Decrement the Channel Switch Count in CSAIE */ + psessionEntry->gLimChannelSwitch.switchCount--; /* Send only 5 beacons with CSA IE Set in when a radar is detected */ if (psessionEntry->gLimChannelSwitch.switchCount > 0) { @@ -3513,8 +3519,6 @@ limProcessBeaconTxSuccessInd(tpAniSirGlobal pMac, tANI_U16 msgType, void *event) psessionEntry); } - /* Decrement the IE count */ - psessionEntry->gLimChannelSwitch.switchCount--; } else { diff --git a/CORE/MAC/src/pe/lim/lim_process_fils.c b/CORE/MAC/src/pe/lim/lim_process_fils.c index 5ab7e27bab0d..1b41d5574c98 100644 --- a/CORE/MAC/src/pe/lim/lim_process_fils.c +++ b/CORE/MAC/src/pe/lim/lim_process_fils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1412,6 +1412,11 @@ static VOS_STATUS lim_parse_kde_elements(tpAniSirGlobal mac_ctx, elem_len = *temp_ie++; rem_len -= 2; + if (elem_len < KDE_IE_DATA_OFFSET) { + limLog(mac_ctx, LOGE, FL("Not enough len to parse elem_len %d"), + elem_len); + return VOS_STATUS_E_FAILURE; + } if (lim_check_if_vendor_oui_match(mac_ctx, KDE_OUI_TYPE, KDE_OUI_TYPE_SIZE, current_ie, elem_len)) { data_type = *(temp_ie + KDE_DATA_TYPE_OFFSET); @@ -1420,6 +1425,12 @@ static VOS_STATUS lim_parse_kde_elements(tpAniSirGlobal mac_ctx, switch(data_type) { /* TODO - is anymore KDE type expected */ case DATA_TYPE_GTK: + if (data_len < GTK_OFFSET) { + limLog(mac_ctx, LOGE, + FL("Invalid KDE data_len %d"), + data_len); + return VOS_STATUS_E_FAILURE; + } limLog(mac_ctx, LOG1, FL("GTK found ")); vos_mem_copy(fils_info->gtk, (ie_data + GTK_OFFSET), (data_len - @@ -1427,6 +1438,12 @@ static VOS_STATUS lim_parse_kde_elements(tpAniSirGlobal mac_ctx, fils_info->gtk_len = (data_len - GTK_OFFSET); break; case DATA_TYPE_IGTK: + if (data_len < IGTK_OFFSET) { + limLog(mac_ctx, LOGE, + FL("Invalid KDE data_len %d"), + data_len); + return VOS_STATUS_E_FAILURE; + } limLog(mac_ctx, LOG1, FL("IGTK found")); fils_info->igtk_len = (data_len - IGTK_OFFSET); vos_mem_copy(fils_info->igtk, (ie_data + diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h index 1c34ba5a1ab4..9cc3f09e4854 100644 --- a/CORE/SAP/inc/sapApi.h +++ b/CORE/SAP/inc/sapApi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -194,6 +194,9 @@ typedef enum { eSAP_ACS_SCAN_SUCCESS_EVENT, eSAP_ACS_CHANNEL_SELECTED, eSAP_ECSA_CHANGE_CHAN_IND, +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + eSAP_CHANNEL_SWITCH_NOTIFICATION, +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN } eSapHddEvent; typedef enum { @@ -739,6 +742,9 @@ typedef struct sSapDfsInfo bool dfs_beacon_tx_enhanced; uint16_t reduced_beacon_interval; enum sub20_chan_switch_mode sub20_switch_mode; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + v_U8_t csaSwitchCount; +#endif } tSapDfsInfo; typedef struct tagSapCtxList diff --git a/CORE/SAP/src/sapFsm.c b/CORE/SAP/src/sapFsm.c index 3a258830910d..254f5a1b7b7c 100644 --- a/CORE/SAP/src/sapFsm.c +++ b/CORE/SAP/src/sapFsm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2357,7 +2357,7 @@ static VOS_STATUS sap_check_mcc_valid( /* * 3. Don't support MCC on DFS channel. */ - if (chan_cnt > 1) { + if (chan_cnt > 0) { for (j = 0; j < chan_cnt; j++) { if (channels[j] != 0 && vos_nv_getChannelEnabledState(channels[j]) diff --git a/CORE/SERVICES/BMI/ol_fw.c b/CORE/SERVICES/BMI/ol_fw.c index ec9cdf9c44c4..83ae0d904d8c 100644 --- a/CORE/SERVICES/BMI/ol_fw.c +++ b/CORE/SERVICES/BMI/ol_fw.c @@ -1326,14 +1326,15 @@ void ol_ramdump_handler(struct ol_softc *scn) return; } + if (scn->enableFwSelfRecovery || scn->enableRamdumpCollection) + vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); + reg = (A_UINT32 *) (data + 4); print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, 16, 4, reg, min_t(A_UINT32, len - 4, FW_REG_DUMP_CNT * 4), false); scn->fw_ram_dumping = 0; - if (scn->enableFwSelfRecovery || scn->enableRamdumpCollection) - vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); } else if (pattern == FW_REG_PATTERN) { reg = (A_UINT32 *) (data + 4); @@ -1358,11 +1359,6 @@ void ol_ramdump_handler(struct ol_softc *scn) remaining -= 16; reg += 4; } - if ((scn->enableFwSelfRecovery || scn->enableRamdumpCollection) && - (scn->fw_ram_dumping == 0)){ - kobject_uevent(&scn->adf_dev->dev->kobj, KOBJ_OFFLINE); - vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, FALSE); - } } else if ((!scn->enableFwSelfRecovery)&& ((pattern & FW_RAMDUMP_PATTERN_MASK) == diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c index 508aac9566c8..0e91878f83a4 100644 --- a/CORE/SERVICES/HIF/PCIe/hif_pci.c +++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2837,6 +2837,9 @@ HIFTargetSleepStateAdjust(A_target_id_t targid, if (tot_delay > PCIE_WAKE_TIMEOUT) { u_int16_t val; +#ifdef CONFIG_NON_QC_PLATFORM_PCI + u_int16_t devid; +#endif u_int32_t bar; printk("%s: keep_awake_count = %d\n", __func__, @@ -2847,6 +2850,9 @@ HIFTargetSleepStateAdjust(A_target_id_t targid, pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &val); printk("%s: PCI Device ID = 0x%04x\n", __func__, val); +#ifdef CONFIG_NON_QC_PLATFORM_PCI + devid = val; +#endif pci_read_config_word(sc->pdev, PCI_COMMAND, &val); printk("%s: PCI Command = 0x%04x\n", __func__, val); @@ -2866,6 +2872,10 @@ HIFTargetSleepStateAdjust(A_target_id_t targid, printk("%s:error, can't wakeup target\n", __func__); hif_msm_pcie_debug_info(sc); +#ifdef CONFIG_NON_QC_PLATFORM_PCI + if (sc->devid != devid) + return -EACCES; +#endif if (!vos_is_logp_in_progress(VOS_MODULE_ID_VOSS, NULL)) { sc->recovery = true; diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 3252d3d4e7d9..494227c64367 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -455,7 +455,8 @@ void wma_process_roam_synch_fail(WMA_HANDLE handle, static VOS_STATUS wma_set_thermal_mgmt(tp_wma_handle wma_handle, t_thermal_cmd_params thermal_info); - +static VOS_STATUS wma_set_dpd_recal_mgmt(tp_wma_handle wma_handle, + t_dpd_recal_cmd_params recal_info); #ifdef FEATURE_WLAN_CH_AVOID VOS_STATUS wma_process_ch_avoid_update_req(tp_wma_handle wma_handle, tSirChAvoidUpdateReq *ch_avoid_update_req); @@ -4845,7 +4846,8 @@ static int wma_passpoint_match_event_handler(void *handle, struct wifi_passpoint_match *dest_match; tSirWifiScanResult *dest_ap; uint8_t *buf_ptr; - + uint32_t buf_len = 0; + bool excess_data = false; tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context( VOS_MODULE_ID_PE, wma->vos_context); if (!pMac) { @@ -4864,14 +4866,28 @@ static int wma_passpoint_match_event_handler(void *handle, event = param_buf->fixed_param; buf_ptr = (uint8_t *)param_buf->fixed_param; - /* - * All the below lengths are UINT32 and summing up and checking - * against a constant should not be an issue. - */ - if ((sizeof(*event) + event->ie_length + event->anqp_length) > - WMA_SVC_MSG_MAX_SIZE) { - WMA_LOGE("IE Length: %d or ANQP Length: %d is huge", - event->ie_length, event->anqp_length); + do { + if (event->ie_length > (WMA_SVC_MSG_MAX_SIZE)) { + excess_data = true; + break; + } else { + buf_len = event->ie_length; + } + + if (event->anqp_length > (WMA_SVC_MSG_MAX_SIZE)) { + excess_data = true; + break; + } else { + buf_len += event->anqp_length; + } + } while (0); + + if (excess_data || buf_len > (WMA_SVC_MSG_MAX_SIZE - sizeof(*event)) || + buf_len > (WMA_SVC_MSG_MAX_SIZE - sizeof(*dest_match)) || + (event->ie_length + event->anqp_length) > param_buf->num_bufp) { + WMA_LOGE("IE Length: %d or ANQP Length: %d is huge, num_bufp %d", + event->ie_length, event->anqp_length, + param_buf->num_bufp); return -EINVAL; } if (event->ssid.ssid_len > SIR_MAC_MAX_SSID_LENGTH) { @@ -4879,8 +4895,7 @@ static int wma_passpoint_match_event_handler(void *handle, __func__, event->ssid.ssid_len); event->ssid.ssid_len = SIR_MAC_MAX_SSID_LENGTH; } - dest_match = vos_mem_malloc(sizeof(*dest_match) + - event->ie_length + event->anqp_length); + dest_match = vos_mem_malloc(sizeof(*dest_match) + buf_len); if (!dest_match) { WMA_LOGE("%s: vos_mem_malloc failed", __func__); return -EINVAL; @@ -5443,12 +5458,7 @@ static int wma_unified_link_radio_stats_event_handler(void *handle, return 0; } - pMac->sme.pLinkLayerStatsIndCallback(pMac->hHdd, - WDA_LINK_LAYER_STATS_RESULTS_RSP, - link_stats_results); - vos_mem_free(wma_handle->link_stats_results); WMA_LOGD(FL("Radio Stats event posted to HDD")); - wma_handle->link_stats_results = NULL; return 0; } @@ -7131,11 +7141,17 @@ static int wma_csa_offload_handler(void *handle, u_int8_t *event, u_int32_t len) csa_ie = (struct ieee80211_channelswitch_ie *)(&csa_event->csa_ie[0]); csa_offload_event->channel = csa_ie->newchannel; csa_offload_event->switchmode = csa_ie->switchmode; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + csa_offload_event->csa_tbtt_count = csa_ie->tbttcount; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN } else if (csa_event->ies_present_flag & WMI_XCSA_IE_PRESENT) { xcsa_ie = (struct ieee80211_extendedchannelswitch_ie*)(&csa_event->xcsa_ie[0]); csa_offload_event->channel = xcsa_ie->newchannel; csa_offload_event->switchmode = xcsa_ie->switchmode; csa_offload_event->new_op_class = xcsa_ie->newClass; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + csa_offload_event->csa_tbtt_count = xcsa_ie->tbttcount; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN } else { WMA_LOGE("CSA Event error: No CSA IE present"); vos_mem_free(csa_offload_event); @@ -10385,11 +10401,11 @@ static inline void wma_get_link_probe_timeout(struct sAniSirGlobal *mac, /** * wma_verify_rate_code() - verify if rate code is valid. * @rate_code: rate code - * @curr_band: current band that device working on + * @band: band information * * Return: verify result */ -static bool wma_verify_rate_code(u_int32_t rate_code, uint8_t curr_band) +static bool wma_verify_rate_code(u_int32_t rate_code, uint8_t band) { uint8_t preamble, nss, rate; bool valid = true; @@ -10400,7 +10416,7 @@ static bool wma_verify_rate_code(u_int32_t rate_code, uint8_t curr_band) switch (preamble) { case WMI_RATE_PREAMBLE_CCK: - if (nss != 0 || rate > 3 || curr_band == VOS_BAND_5GHZ) + if (nss != 0 || rate > 3 || band == VOS_BAND_5GHZ) valid = false; break; case WMI_RATE_PREAMBLE_OFDM: @@ -10438,8 +10454,7 @@ static void wma_set_vdev_mgmt_rate(tp_wma_handle wma, u_int8_t vdev_id) uint32_t cfg_val; int ret; uint32_t per_band_mgmt_tx_rate = 0; - uint32_t current_chan; - uint8_t current_band; + uint8_t band = 0; struct sAniSirGlobal *mac = (struct sAniSirGlobal*)vos_get_context(VOS_MODULE_ID_PE, wma->vos_context); @@ -10449,13 +10464,11 @@ static void wma_set_vdev_mgmt_rate(tp_wma_handle wma, u_int8_t vdev_id) return; } - current_chan = vos_freq_to_chan(wma->interfaces[vdev_id].mhz); - current_band = vos_chan_to_band(current_chan); - if (wlan_cfgGetInt(mac, WNI_CFG_RATE_FOR_TX_MGMT, &cfg_val) == eSIR_SUCCESS) { + band = 0; if ((cfg_val == WNI_CFG_RATE_FOR_TX_MGMT_STADEF) || - !wma_verify_rate_code(cfg_val, current_band)) { + !wma_verify_rate_code(cfg_val, band)) { WMA_LOGE("invalid rate code, ignore."); } else { ret = wmi_unified_vdev_set_param_send( @@ -10474,8 +10487,10 @@ static void wma_set_vdev_mgmt_rate(tp_wma_handle wma, u_int8_t vdev_id) if (wlan_cfgGetInt(mac, WNI_CFG_RATE_FOR_TX_MGMT_2G, &cfg_val) == eSIR_SUCCESS) { + band = VOS_BAND_2GHZ; if ((cfg_val == WNI_CFG_RATE_FOR_TX_MGMT_2G_STADEF) || - !wma_verify_rate_code(cfg_val, current_band)) { + !wma_verify_rate_code(cfg_val, band)) { + WMA_LOGD("use default 2G MGMT rate."); per_band_mgmt_tx_rate &= ~(1 << TX_MGMT_RATE_2G_ENABLE_OFFSET); } else { @@ -10490,8 +10505,10 @@ static void wma_set_vdev_mgmt_rate(tp_wma_handle wma, u_int8_t vdev_id) if (wlan_cfgGetInt(mac, WNI_CFG_RATE_FOR_TX_MGMT_5G, &cfg_val) == eSIR_SUCCESS) { + band = VOS_BAND_5GHZ; if ((cfg_val == WNI_CFG_RATE_FOR_TX_MGMT_5G_STADEF) || - !wma_verify_rate_code(cfg_val, current_band)) { + !wma_verify_rate_code(cfg_val, band)) { + WMA_LOGD("use default 5G MGMT rate."); per_band_mgmt_tx_rate &= ~(1 << TX_MGMT_RATE_5G_ENABLE_OFFSET); } else { @@ -15623,6 +15640,7 @@ static void wma_set_channel(tp_wma_handle wma, tpSwitchChannelParams params) " interval reset req", __func__); } } + req.beacon_tx_rate= params->beacon_tx_rate; } if ((VOS_MONITOR_MODE == vos_get_conparam()) && wma_is_vdev_up(0)) { @@ -29175,6 +29193,57 @@ VOS_STATUS wma_process_init_thermal_info(tp_wma_handle wma, return VOS_STATUS_SUCCESS; } +/* function : wma_process_init_dpd_recal_info + * Description : This function initializes the dpd recaliberation in WMA, + sends down the initial high/low temperature limits to the firmware. + * Args : + wma : Pointer to WMA handle + * pDPDRecalParams: Pointer to DPD Recal parameters + * Returns : + * VOS_STATUS_SUCCESS for success otherwise failure + */ +VOS_STATUS wma_process_init_dpd_recal_info(tp_wma_handle wma, + t_dpd_recal_mgmt *pDPDRecalParams) +{ + t_dpd_recal_cmd_params dpd_recal_params; + + if (NULL == wma || NULL == pDPDRecalParams) { + WMA_LOGE("DPD Recal Invalid input"); + return VOS_STATUS_E_FAILURE; + } + + wma->dpd_recal_info.dpd_enable = pDPDRecalParams->dpd_enable; + wma->dpd_recal_info.dpd_delta_degreeHigh = pDPDRecalParams->dpd_delta_degreeHigh; + wma->dpd_recal_info.dpd_delta_degreeLow = pDPDRecalParams->dpd_delta_degreeLow; + wma->dpd_recal_info.dpd_cooling_time = pDPDRecalParams->dpd_cooling_time; + wma->dpd_recal_info.dpd_duration_max = pDPDRecalParams->dpd_duration_max; + if (wma->dpd_recal_info.dpd_enable) + { + /* Get the temperature thresholds to set in firmware */ + dpd_recal_params.enable = wma->dpd_recal_info.dpd_enable; + dpd_recal_params.delta_degreeHigh = wma->dpd_recal_info.dpd_delta_degreeHigh; + dpd_recal_params.delta_degreeLow = wma->dpd_recal_info.dpd_delta_degreeLow; + dpd_recal_params.cooling_time = wma->dpd_recal_info.dpd_cooling_time; + dpd_recal_params.dpd_dur_max = wma->dpd_recal_info.dpd_duration_max; + + WMA_LOGE("DPD Recal sending the following to firmware: delta_degreeLow %d " + "delta_degreehigh %d enable %d cooling_time %d " + "dpd_max_duration %d ", + dpd_recal_params.delta_degreeLow, + dpd_recal_params.delta_degreeHigh, + dpd_recal_params.enable, + dpd_recal_params.cooling_time, + dpd_recal_params.dpd_dur_max); + + if(VOS_STATUS_SUCCESS != wma_set_dpd_recal_mgmt(wma, dpd_recal_params)) + { + WMA_LOGE("Could not send thermal mgmt command to the firmware!"); + } + }else + WMA_LOGE("Runtime DPD Recaliberation not enable!"); + + return VOS_STATUS_SUCCESS; +} static void wma_set_thermal_level_ind(u_int8_t level) { @@ -34212,6 +34281,9 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) wma_process_init_thermal_info(wma_handle, (t_thermal_mgmt *)msg->bodyptr); vos_mem_free(msg->bodyptr); break; + case WDA_INIT_DPD_RECAL_INFO_CMD: + wma_process_init_dpd_recal_info(wma_handle, (t_dpd_recal_mgmt *)msg->bodyptr); + break; case WDA_SET_THERMAL_LEVEL: wma_process_set_thermal_level(wma_handle, msg->bodyval); @@ -35564,6 +35636,61 @@ static VOS_STATUS wma_set_thermal_mgmt(tp_wma_handle wma_handle, return eHAL_STATUS_SUCCESS; } +/* function : wma_set_dpd_recal_mgmt + * Description : This function sends the runtime DPD recaliberation params to the firmware + * Args : + wma_handle : Pointer to WMA handle + * dpd_recal_info : DPD recaliberation data + * Returns : + * VOS_STATUS_SUCCESS for success otherwise failure + */ +static VOS_STATUS wma_set_dpd_recal_mgmt(tp_wma_handle wma_handle, + t_dpd_recal_cmd_params recal_info) +{ + wmi_runtime_dpd_recal_cmd_fixed_param *cmd = NULL; + wmi_buf_t buf = NULL; + int status = 0; + u_int32_t len = 0; + + len = sizeof(*cmd); + + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE("Failed to allocate buffer to send set key cmd"); + return eHAL_STATUS_FAILURE; + } + + cmd = (wmi_runtime_dpd_recal_cmd_fixed_param *) wmi_buf_data (buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_runtime_dpd_recal_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_runtime_dpd_recal_cmd_fixed_param)); + + cmd->enable = recal_info.enable; + cmd->dlt_tmpt_c_l = recal_info.delta_degreeLow; + cmd->dlt_tmpt_c_h = recal_info.delta_degreeHigh; + cmd->cooling_time_ms = recal_info.cooling_time; + cmd->dpd_dur_max_ms = recal_info.dpd_dur_max; + + WMA_LOGE("Sending DPD Recal cmd: low temp %d, high temp %d, enabled %d " + "cooling_time %d, dpd_dur_max %d", + cmd->dlt_tmpt_c_l, + cmd->dlt_tmpt_c_h, + cmd->enable,cmd->cooling_time_ms, + cmd->dpd_dur_max_ms); + + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_RUNTIME_DPD_RECAL_CMDID); + if (status) { + wmi_buf_free(buf); + WMA_LOGE("%s:Failed to send dpd runtime recal command", __func__); + return eHAL_STATUS_FAILURE; + } + + return eHAL_STATUS_SUCCESS; +} + + /* function : wma_thermal_mgmt_get_level * Description : This function returns the thermal(throttle) level given the temperature * Args : diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index b5eb6d6466e3..2e1910df7756 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -954,6 +954,7 @@ typedef struct wma_handle { tSirAddonPsReq psSetting; bool sub_20_support; bool get_one_peer_info; + t_dpd_recal_mgmt dpd_recal_info; }t_wma_handle, *tp_wma_handle; struct wma_target_cap { @@ -1412,6 +1413,14 @@ typedef struct { u_int8_t thermalEnable; } t_thermal_cmd_params, *tp_thermal_cmd_params; +typedef struct { + u_int8_t enable; + u_int32_t delta_degreeHigh; + u_int32_t delta_degreeLow; + u_int32_t cooling_time; //time in ms + u_int32_t dpd_dur_max; //time in ms +} t_dpd_recal_cmd_params, *tp_dpd_recal_cmd_params; + /* Powersave Related */ /* Default InActivity Time is 200 ms */ #define POWERSAVE_DEFAULT_INACTIVITY_TIME 200 diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h index 6b0b7a7516bf..6327daef9e28 100644 --- a/CORE/SME/inc/csrApi.h +++ b/CORE/SME/inc/csrApi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1406,6 +1406,9 @@ typedef struct tagCsrConfigParam #ifdef WLAN_FEATURE_FILS_SK uint8_t fils_max_chan_guard_time; #endif +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + tANI_U32 sap_ch_switch_with_csa; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN }tCsrConfigParam; //Tush diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h index d63c9a92e49b..0b5adb61a541 100644 --- a/CORE/SME/inc/smeInternal.h +++ b/CORE/SME/inc/smeInternal.h @@ -266,6 +266,10 @@ typedef struct tagSmeStruct void (*stats_ext2_cb)(void *, struct stats_ext2_event *); void (*chip_power_save_fail_cb)(void *, struct chip_pwr_save_fail_detected_params *); +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + /*call back to indicate CSA notification received on STA interfce to SAP*/ + void (*pCSASAPIndCb) (void * hdd_context, void *indi_param); +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN } tSmeStruct, *tpSmeStruct; diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 777f7eb9bc26..530c9ff144e1 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -257,6 +257,14 @@ typedef struct { } tSmeThermalParams; +typedef struct { + u_int32_t enable; + u_int32_t delta_degreeHigh; + u_int32_t delta_degreeLow; + u_int32_t cooling_time; + u_int32_t dpd_dur_max; +} tSmeDPDRecalParams; + #ifdef WLAN_FEATURE_APFIND struct sme_ap_find_request_req{ u_int16_t request_data_len; @@ -3825,6 +3833,14 @@ eHalStatus sme_RoamCsaIeRequest(tHalHandle hHal, tCsrBssid bssid, eHalStatus sme_InitThermalInfo( tHalHandle hHal, tSmeThermalParams thermalParam ); /* --------------------------------------------------------------------------- \fn sme_InitThermalInfo + \brief SME API to initialize the thermal mitigation parameters + \param hHal + \param thermalParam : thermal mitigation parameters + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_InitDPDRecalInfo( tHalHandle hHal, tSmeDPDRecalParams thermalParam ); +/* --------------------------------------------------------------------------- + \fn sme_InitThermalInfo \brief SME API to set the thermal mitigation level \param hHal \param level : thermal mitigation level @@ -4524,6 +4540,14 @@ eHalStatus sme_set_tsfcb(tHalHandle hHal, VOS_STATUS sme_apfind_set_cmd(struct sme_ap_find_request_req *input); #endif /* WLAN_FEATURE_APFIND */ +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +eHalStatus sme_AddCSAIndCallback +( + tHalHandle hHal, + void (*pCallbackfn)(void *pAdapter, void *CSAindParam) +); +#endif//#ifdef + /** * sme_enable_disable_mas() - Function to set MAS value to UMAC * @val: 1-Enable, 0-Disable diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index 779b1128b98a..70e65a01b720 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -9574,7 +9574,11 @@ void csrRoamingStateMsgProcessor( tpAniSirGlobal pMac, void *pMsgBuf ) */ csrRemoveCmdWithSessionIdFromPendingList(pMac, pSmeRsp->sessionId, - &pMac->sme.smeScanCmdPendingList, + &pMac->sme.smeCmdPendingList, + eSmeCommandWmStatusChange); + csrRemoveCmdWithSessionIdFromPendingList(pMac, + pSmeRsp->sessionId, + &pMac->roam.roamCmdPendingList, eSmeCommandWmStatusChange); csrRoamRoamingStateDeauthRspProcessor( pMac, (tSirSmeDeauthRsp *)pSmeRsp ); } @@ -14485,6 +14489,16 @@ eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDe ucDot11Mode = WNI_CFG_DOT11_MODE_11N; } +#if defined(FEATURE_WLAN_WAPI) && defined(WLAN_WAPI_MODE_11AC_DISABLE) + if( csrIsProfileWapi( pProfile ) && + ((ucDot11Mode == WNI_CFG_DOT11_MODE_11AC) || + (ucDot11Mode == WNI_CFG_DOT11_MODE_11AC_ONLY)) ) + { + //Disable 11ac when WAPI is used + ucDot11Mode = WNI_CFG_DOT11_MODE_11N; + } +#endif + smsLog(pMac, LOG1, FL("dot11mode %d uCfgDot11Mode %d"), ucDot11Mode, pSession->bssParams.uCfgDot11Mode); diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c index b29c3671b0c8..2d4b90d52b31 100644 --- a/CORE/SME/src/csr/csrUtil.c +++ b/CORE/SME/src/csr/csrUtil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -44,7 +44,9 @@ #include "smeQosInternal.h" #include "wlan_qct_wda.h" #include "vos_utils.h" - +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +#include "limApi.h" +#endif #if defined(FEATURE_WLAN_ESE) && !defined(FEATURE_WLAN_ESE_UPLOAD) #include "csrEse.h" #endif /* FEATURE_WLAN_ESE && !FEATURE_WLAN_ESE_UPLOAD*/ @@ -1108,6 +1110,7 @@ tANI_BOOLEAN csr_find_sta_session_info( tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); tCsrRoamSession *pSession = NULL; v_U8_t i = 0; + tpPESession psessionEntry; for( i = 0; i < CSR_ROAM_SESSION_MAX; i++ ) { if( !CSR_IS_SESSION_VALID( pMac, i ) ) @@ -1121,8 +1124,21 @@ tANI_BOOLEAN csr_find_sta_session_info( VOS_P2P_CLIENT_MODE)) && (pSession->connectState == eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) { - info->och = - pSession->connectedProfile.operationChannel; + if(vos_is_ch_switch_with_csa_enabled()){ + psessionEntry = peFindSessionBySessionId(pMac, + pMac->lim.limTimers.gLimChannelSwitchTimer.sessionId); + if (psessionEntry && LIM_IS_STA_ROLE(psessionEntry)) { + info->och = psessionEntry->gLimChannelSwitch.primaryChannel; + smsLog(pMac, LOGP, + FL("SAP channel switch with CSA enabled (SAP new ch: %d)"), info->och); + }else{ + info->och = + pSession->connectedProfile.operationChannel; + } + }else{ + info->och = + pSession->connectedProfile.operationChannel; + } csrGetChFromHTProfile(pMac, &pSession->connectedProfile.HTProfile, info->och, &info->cfreq, &info->hbw); diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index e6c6ae482d11..c5841a4d8a8d 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -3257,6 +3257,15 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) case eWNI_SME_CSA_OFFLOAD_EVENT: if (pMsg->bodyptr) { +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + /*Indicate to HostApd*/ + if(pMac->sme.pCSASAPIndCb) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: CSA Notification to SAP", __func__); + pMac->sme.pCSASAPIndCb(pMac->hHdd, pMsg->bodyptr); + } +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN csrScanFlushBssEntry(pMac, pMsg->bodyptr); vos_mem_free(pMsg->bodyptr); } @@ -15357,6 +15366,57 @@ eHalStatus sme_InitThermalInfo( tHalHandle hHal, return eHAL_STATUS_FAILURE; } +/* --------------------------------------------------------------------------- + \fn sme_InitDPDRecalInfo + \brief SME API to initialize the Runtime DPD Recaliberation parameters + \param hHal + \param DPDParam : DPD Recal parameters + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_InitDPDRecalInfo( tHalHandle hHal, + tSmeDPDRecalParams DPDParam ) +{ + t_dpd_recal_mgmt * pWdaParam; + vos_msg_t msg; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + pWdaParam = (t_dpd_recal_mgmt *)vos_mem_malloc(sizeof(t_dpd_recal_mgmt)); + if (NULL == pWdaParam) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: could not allocate t_dpd_recal_mgmt", __func__); + return eHAL_STATUS_E_MALLOC_FAILED; + } + + vos_mem_zero((void*)pWdaParam, sizeof(t_dpd_recal_mgmt)); + pWdaParam->dpd_enable = DPDParam.enable; + pWdaParam->dpd_delta_degreeHigh = DPDParam.delta_degreeHigh; + pWdaParam->dpd_delta_degreeLow = DPDParam.delta_degreeLow; + pWdaParam->dpd_cooling_time = DPDParam.cooling_time; + pWdaParam->dpd_duration_max = DPDParam.dpd_dur_max; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + msg.type = WDA_INIT_DPD_RECAL_INFO_CMD; + msg.bodyptr = pWdaParam; + + if (!VOS_IS_STATUS_SUCCESS( + vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to post WDA_INIT_DPD_RECAL_INFO_CMD to WDA!", + __func__); + vos_mem_free(pWdaParam); + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + return eHAL_STATUS_SUCCESS; + } + vos_mem_free(pWdaParam); + return eHAL_STATUS_FAILURE; +} + /* * Plug in set thermal level callback */ @@ -17639,6 +17699,34 @@ VOS_STATUS sme_apfind_set_cmd(struct sme_ap_find_request_req *input) return VOS_STATUS_SUCCESS; } #endif /* WLAN_FEATURE_APFIND */ + +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +eHalStatus sme_AddCSAIndCallback +( + tHalHandle hHal, + void (*pCallbackfn)(void *pAdapter, void *CSAindParam) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Plug in CSA Notify CB", __func__); + + status = sme_AcquireGlobalLock(&pMac->sme); + if (eHAL_STATUS_SUCCESS == status) + { + if (NULL != pCallbackfn) + { + pMac->sme.pCSASAPIndCb = pCallbackfn; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + + return(status); + +} +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH /* * sme_validate_sap_channel_switch() - validate target channel switch w.r.t diff --git a/CORE/SVC/external/wlan_nlink_common.h b/CORE/SVC/external/wlan_nlink_common.h index 0b3604cbc43e..220e8459ff9d 100644 --- a/CORE/SVC/external/wlan_nlink_common.h +++ b/CORE/SVC/external/wlan_nlink_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -222,5 +222,16 @@ enum wlan_tp_level { WLAN_SVC_TP_MEDIUM, WLAN_SVC_TP_HIGH, }; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +typedef enum sta_sap_notifications +{ + STA_NOTIFY_DISCONNECTED, + STA_NOTIFY_CONNECTED, + STA_NOTIFY_CSA, +}sta_sap_notifications; +struct wlan_sap_csa_info { + uint32_t sta_channel; +}; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN #endif //WLAN_NLINK_COMMON_H__ diff --git a/CORE/UTILS/FWLOG/dbglog_host.c b/CORE/UTILS/FWLOG/dbglog_host.c index 7a7be6ddade9..8e4201a54cc2 100644 --- a/CORE/UTILS/FWLOG/dbglog_host.c +++ b/CORE/UTILS/FWLOG/dbglog_host.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1892,7 +1892,7 @@ dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length) char parseArgsString[DBGLOG_PARSE_ARGS_STRING_LENGTH]; char *dbgidString; - while (count < length) { + while (count + 1 < length) { debugid = DBGLOG_GET_DBGID(buffer[count + 1]); moduleid = DBGLOG_GET_MODULEID(buffer[count + 1]); @@ -1904,12 +1904,16 @@ dbglog_print_raw_data(A_UINT32 *buffer, A_UINT32 length) OS_MEMZERO(parseArgsString, sizeof(parseArgsString)); totalWriteLen = 0; + if (!numargs || (count + numargs + 2 > length)) + goto skip_args_processing; + for (curArgs = 0; curArgs < numargs; curArgs++){ // Using sprintf_s instead of sprintf, to avoid length overflow writeLen = snprintf(parseArgsString + totalWriteLen, DBGLOG_PARSE_ARGS_STRING_LENGTH - totalWriteLen, "%x ", buffer[count + 2 + curArgs]); totalWriteLen += writeLen; } +skip_args_processing: if (debugid < MAX_DBG_MSGS){ dbgidString = DBG_MSG_ARR[moduleid][debugid]; if (dbgidString != NULL) { @@ -2398,6 +2402,11 @@ dbglog_parse_debug_logs(ol_scn_t scn, u_int8_t *data, u_int32_t datalen) len = param_buf->num_bufp; } + if (len < sizeof(dropped)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid length\n")); + return -1; + } + dropped = *((A_UINT32 *)datap); if (dropped > 0) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC , ("%d log buffers are dropped \n", dropped)); diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h index dc7d90f1afa5..66aa196adb19 100644 --- a/CORE/VOSS/inc/vos_api.h +++ b/CORE/VOSS/inc/vos_api.h @@ -437,5 +437,5 @@ bool vos_is_probe_rsp_offload_enabled(void); * true: monitor mode is on */ bool vos_is_mon_enable(void); - +v_BOOL_t vos_is_ch_switch_with_csa_enabled(void); #endif // if !defined __VOS_API_H diff --git a/CORE/VOSS/inc/vos_cnss.h b/CORE/VOSS/inc/vos_cnss.h index fa2d7f8d508e..8bfae8619cb4 100644 --- a/CORE/VOSS/inc/vos_cnss.h +++ b/CORE/VOSS/inc/vos_cnss.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 @@ -579,6 +579,18 @@ static inline int vos_cache_boarddata(unsigned int offset, #endif #if defined(CONFIG_CNSS) && defined(HIF_SDIO) +#include <linux/version.h> +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) +static inline bool vos_oob_enabled(void) +{ + bool enabled = true; + + if (-EINVAL == cnss_wlan_query_oob_status()) + enabled = false; + + return enabled; +} +#else static inline bool vos_oob_enabled(void) { bool enabled = true; @@ -588,6 +600,7 @@ static inline bool vos_oob_enabled(void) return enabled; } +#endif static inline int vos_register_oob_irq_handler(oob_irq_handler_t handler, void *pm_oob) diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index 360237d032d9..3d49c794da9b 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -3320,3 +3320,24 @@ bool vos_is_mon_enable(void) return phdd_ctx->is_mon_enable; } +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN +v_BOOL_t vos_is_ch_switch_with_csa_enabled(void) +{ + hdd_context_t *pHddCtx; + + pHddCtx = (hdd_context_t*)(gpVosContext->pHDDContext); + if((NULL == pHddCtx) || + (NULL == pHddCtx->cfg_ini)) + { + VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, + "%s: Hdd Context is Null", __func__); + return FALSE; + } + return pHddCtx->cfg_ini->sap_ch_switch_with_csa; +} +#else +v_BOOL_t vos_is_ch_switch_with_csa_enabled(void) +{ + return FALSE; +} +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN diff --git a/CORE/VOSS/src/vos_nvitem.c b/CORE/VOSS/src/vos_nvitem.c index bd463d037aac..d5d00d18edfb 100644 --- a/CORE/VOSS/src/vos_nvitem.c +++ b/CORE/VOSS/src/vos_nvitem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -976,7 +976,7 @@ static void vos_set_5g_channel_params(uint16_t oper_ch, struct ch_params_s *ch_params) { eNVChannelEnabledType chan_state = NV_CHANNEL_ENABLE; - const struct bonded_chan *bonded_chan_ptr; + const struct bonded_chan *bonded_chan_ptr = NULL; uint16_t center_chan; if (CH_WIDTH_MAX <= ch_params->ch_width) @@ -1782,7 +1782,7 @@ bool vos_is_channel_support_sub20(uint16_t operation_channel, eNVChannelEnabledType channel_state; if (VOS_IS_CHANNEL_5GHZ(operation_channel)) { - const struct bonded_chan *bonded_chan_ptr; + const struct bonded_chan *bonded_chan_ptr = NULL; channel_state = vos_search_5g_bonded_channel(operation_channel, diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h index 0c3a8c7dd5d4..3de568bd1de8 100644 --- a/CORE/WDA/inc/legacy/halMsgApi.h +++ b/CORE/WDA/inc/legacy/halMsgApi.h @@ -1043,6 +1043,7 @@ typedef struct uint32_t channelwidth; uint16_t reduced_beacon_interval; + uint16_t beacon_tx_rate; }tSwitchChannelParams, *tpSwitchChannelParams; typedef struct CSAOffloadParams { @@ -1056,6 +1057,9 @@ typedef struct CSAOffloadParams { tANI_U8 new_sub20_channelwidth; /* 5MHz or 10Mhz channel width */ tANI_U32 ies_present_flag; /* WMI_CSA_EVENT_IES_PRESENT_FLAG */ tSirMacAddr bssId; +#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN + tANI_U32 csa_tbtt_count; +#endif//#ifdef WLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN }*tpCSAOffloadParams, tCSAOffloadParams; typedef void (*tpSetLinkStateCallback)(tpAniSirGlobal pMac, void *msgParam, diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h index 8f016c57fc91..38914e161b37 100644 --- a/CORE/WDA/inc/wlan_qct_wda.h +++ b/CORE/WDA/inc/wlan_qct_wda.h @@ -924,6 +924,7 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); #define WDA_RATE_UPDATE_IND SIR_HAL_RATE_UPDATE_IND #define WDA_INIT_THERMAL_INFO_CMD SIR_HAL_INIT_THERMAL_INFO_CMD +#define WDA_INIT_DPD_RECAL_INFO_CMD SIR_HAL_INIT_DPD_RECAL_INFO_CMD #define WDA_SET_THERMAL_LEVEL SIR_HAL_SET_THERMAL_LEVEL #define WDA_RMC_ENABLE_IND SIR_HAL_RMC_ENABLE_IND @@ -1080,7 +1080,8 @@ ifeq ($(CONFIG_QCA_WIFI_AUTOMOTIVE_CONC), y) CDEFINES += -DWLAN_FEATURE_MBSSID \ -DFEATURE_WLAN_MCC_TO_SCC_SWITCH \ -DFEATURE_WLAN_CH_AVOID \ - -DFEATURE_WLAN_STA_AP_MODE_DFS_DISABLE + -DFEATURE_WLAN_STA_AP_MODE_DFS_DISABLE \ + -DWLAN_FEATURE_SAP_TO_FOLLOW_STA_CHAN endif ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) @@ -1690,6 +1691,10 @@ CDEFINES += -DFEATURE_WLAN_THERMAL_SHUTDOWN CDEFINES += -DFEATURE_WLAN_AUTO_SHUTDOWN endif +ifeq ($(CONFIG_WLAN_WAPI_MODE_11AC_DISABLE), y) +CDEFINES += -DWLAN_WAPI_MODE_11AC_DISABLE +endif + KBUILD_CPPFLAGS += $(CDEFINES) # Currently, for versions of gcc which support it, the kernel Makefile |
