qcacmn: Remove CDS instances in HIF

Remove CDS instances in HIF for WIN/MCL convergence.
a. Update con_mode param in HIF
b. Have callbacks to CDS from HIF to update CDS global context

Change-Id: Iceebf32271b8d53beb634031f7dbc005f5fe5ed0
CRs-Fixed: 967765
This commit is contained in:
Komal Seelam 2016-02-24 10:27:30 +05:30 • committed by Gerrit - the friendly Code Review server
commit bd7c51d1c5
14 changed files with 261 additions and 149 deletions

View file

@ -234,6 +234,15 @@ struct htc_callbacks {
int (*dsrHandler)(void *context);
};
struct hif_callbacks {
void *context;
void (*set_recovery_in_progress)(void *context, uint8_t val);
uint64_t (*get_monotonic_boottime)(void);
bool (*is_recovery_in_progress)(void *context);
bool (*is_load_unload_in_progress)(void *context);
bool (*is_driver_unloading)(void *context);
};
/* This API detaches the HTC layer from the HIF device */
void hif_detach_htc(struct hif_opaque_softc *scn);
@ -464,7 +473,9 @@ void hif_reset_soc(struct hif_opaque_softc *scn);
void hif_disable_aspm(struct hif_opaque_softc *);
void hif_save_htc_htt_config_endpoint(struct hif_opaque_softc *hif_ctx,
int htc_endpoint);
CDF_STATUS hif_open(cdf_device_t cdf_ctx, enum ath_hal_bus_type bus_type);
struct hif_opaque_softc *hif_open(cdf_device_t cdf_ctx, uint32_t mode,
enum ath_hal_bus_type bus_type,
struct hif_callbacks *cbk);
void hif_close(struct hif_opaque_softc *hif_ctx);
CDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
void *bdev, const hif_bus_id *bid,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2014, 2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -40,7 +40,6 @@
#elif defined(HIF_SDIO)
#include "if_ath_sdio.h"
#endif
#include "cds_api.h"
#include "hif_debug.h"
#define PROCFS_NAME "athdiagpfs"

View file

@ -43,7 +43,6 @@
#include "hif_main.h"
#include "ce_api.h"
#include "cdf_trace.h"
#include "cds_api.h"
#ifdef CONFIG_CNSS
#include <net/cnss.h>
#else

View file

@ -43,13 +43,11 @@
#include "hif_main.h"
#include "ce_api.h"
#include "cdf_trace.h"
#include "cds_api.h"
#ifdef CONFIG_CNSS
#include <net/cnss.h>
#endif
#include "hif_debug.h"
#include "epping_main.h"
#include "cds_concurrency.h"
void
hif_dump_target_memory(struct hif_opaque_softc *hif_ctx, void *ramdump_base,

View file

@ -316,8 +316,10 @@ enum hif_ce_event_type {
};
void ce_init_ce_desc_event_log(int ce_id, int size);
void hif_record_ce_desc_event(int ce_id, enum hif_ce_event_type type,
union ce_desc *descriptor, void *memory, int index);
void hif_record_ce_desc_event(struct hif_softc *scn, int ce_id,
enum hif_ce_event_type type,
union ce_desc *descriptor, void *memory,
int index);
enum ce_sendlist_type_e {
CE_SIMPLE_BUFFER_TYPE,

View file

@ -45,7 +45,6 @@
#endif
#include "ce_api.h"
#include "cdf_trace.h"
#include "cds_api.h"
#ifdef CONFIG_CNSS
#include <net/cnss.h>
#endif
@ -61,7 +60,6 @@
#include <soc/qcom/icnss.h>
#endif
#include "qwlan_version.h"
#include "cds_concurrency.h"
#define CE_POLL_TIMEOUT 10 /* ms */
@ -760,6 +758,7 @@ hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
struct hif_pci_softc *hif_sc = HIF_GET_PCI_SOFTC(hif_state);
struct hif_msg_callbacks *msg_callbacks =
&hif_state->msg_callbacks_current;
uint32_t count;
do {
hif_pm_runtime_mark_last_busy(hif_sc->dev);
@ -778,8 +777,8 @@ hif_pci_ce_recv_data(struct CE_handle *copyeng, void *ce_context,
/* Set up force_break flag if num of receices reaches
* MAX_NUM_OF_RECEIVES */
ce_state->receive_count++;
if (cdf_unlikely(hif_max_num_receives_reached(
ce_state->receive_count))) {
count = ce_state->receive_count;
if (cdf_unlikely(hif_max_num_receives_reached(scn, count))) {
ce_state->force_break = 1;
break;
}
@ -1525,7 +1524,7 @@ static void hif_sleep_entry(void *arg)
if (scn->recovery)
return;
if (cds_is_driver_unloading())
if (hif_is_driver_unloading(scn))
return;
cdf_spin_lock_irqsave(&hif_state->keep_awake_lock);
@ -1818,17 +1817,18 @@ done:
/**
* hif_wlan_enable(): call the platform driver to enable wlan
* @scn: HIF Context
*
* This function passes the con_mode and CE configuration to
* platform driver to enable wlan.
*
* Return: void
*/
static int hif_wlan_enable(void)
static int hif_wlan_enable(struct hif_softc *scn)
{
struct icnss_wlan_enable_cfg cfg;
enum icnss_driver_mode mode;
uint32_t con_mode = cds_get_conparam();
uint32_t con_mode = hif_get_conparam(scn);
cfg.num_ce_tgt_cfg = target_ce_config_sz /
sizeof(struct CE_pipe_config);
@ -1842,7 +1842,7 @@ static int hif_wlan_enable(void)
if (CDF_GLOBAL_FTM_MODE == con_mode)
mode = ICNSS_FTM;
else if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
else if (WLAN_IS_EPPING_ENABLED(con_mode))
mode = ICNSS_EPPING;
else
mode = ICNSS_MISSION;
@ -1859,6 +1859,7 @@ int hif_config_ce(struct hif_softc *scn)
{
struct HIF_CE_pipe_info *pipe_info;
int pipe_num;
uint32_t mode = hif_get_conparam(scn);
#ifdef ADRASTEA_SHADOW_REGISTERS
int i;
#endif
@ -1870,8 +1871,8 @@ int hif_config_ce(struct hif_softc *scn)
struct hif_target_info *tgt_info = hif_get_target_info_handle(hif_hdl);
/* if epping is enabled we need to use the epping configuration. */
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
if (WLAN_IS_EPPING_IRQ(cds_get_conparam()))
if (WLAN_IS_EPPING_ENABLED(mode)) {
if (WLAN_IS_EPPING_IRQ(mode))
host_ce_config = host_ce_config_wlan_epping_irq;
else
host_ce_config = host_ce_config_wlan_epping_poll;
@ -1883,7 +1884,7 @@ int hif_config_ce(struct hif_softc *scn)
sizeof(target_service_to_ce_map_wlan_epping);
}
ret = hif_wlan_enable();
ret = hif_wlan_enable(scn);
if (ret) {
HIF_ERROR("%s: hif_wlan_enable error = %d", __func__, ret);
@ -2286,11 +2287,12 @@ int hif_map_service_to_pipe(struct hif_opaque_softc *hif_hdl, uint16_t svc_id,
int status = CDF_STATUS_SUCCESS;
unsigned int i;
struct service_to_pipe element;
struct service_to_pipe *tgt_svc_map_to_use;
size_t sz_tgt_svc_map_to_use;
struct hif_softc *scn = HIF_GET_SOFTC(hif_hdl);
uint32_t mode = hif_get_conparam(scn);
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
if (WLAN_IS_EPPING_ENABLED(mode)) {
tgt_svc_map_to_use = target_service_to_ce_map_wlan_epping;
sz_tgt_svc_map_to_use =
sizeof(target_service_to_ce_map_wlan_epping);

View file

@ -40,7 +40,6 @@
#include "epping_main.h"
#include "hif_main.h"
#include "hif_debug.h"
#include "cds_concurrency.h"
#ifdef IPA_OFFLOAD
#ifdef QCA_WIFI_3_0
@ -127,22 +126,32 @@ static int get_next_record_index(cdf_atomic_t *table_index, int array_size)
/**
* hif_record_ce_desc_event() - record ce descriptor events
* @scn: hif_softc
* @ce_id: which ce is the event occuring on
* @type: what happened
* @descriptor: pointer to the descriptor posted/completed
* @memory: virtual address of buffer related to the descriptor
* @index: index that the descriptor was/will be at.
*/
void hif_record_ce_desc_event(int ce_id, enum hif_ce_event_type type,
union ce_desc *descriptor, void *memory, int index)
void hif_record_ce_desc_event(struct hif_softc *scn, int ce_id,
enum hif_ce_event_type type,
union ce_desc *descriptor,
void *memory, int index)
{
struct hif_callbacks *cbk = hif_get_callbacks_handle(scn);
int record_index = get_next_record_index(
&hif_ce_desc_history_index[ce_id], HIF_CE_HISTORY_MAX);
struct hif_ce_desc_event *event =
&hif_ce_desc_history[ce_id][record_index];
event->type = type;
event->time = cds_get_monotonic_boottime();
if (cbk && cbk->get_monotonic_boottime)
event->time = cbk->get_monotonic_boottime();
else
event->time = ((uint64_t)cdf_system_ticks_to_msecs(
cdf_system_ticks()) * 1000);
if (descriptor != NULL)
event->descriptor = *descriptor;
else
@ -163,7 +172,7 @@ void ce_init_ce_desc_event_log(int ce_id, int size)
cdf_atomic_init(&hif_ce_desc_history_index[ce_id]);
}
#else
void hif_record_ce_desc_event(
void hif_record_ce_desc_event(struct hif_softc *scn,
int ce_id, enum hif_ce_event_type type,
union ce_desc *descriptor, void *memory,
int index)
@ -343,7 +352,7 @@ ce_send_nolock(struct CE_handle *copyeng,
/* src_ring->write index hasn't been updated event though
* the register has allready been written to.
*/
hif_record_ce_desc_event(CE_state->id, event_type,
hif_record_ce_desc_event(scn, CE_state->id, event_type,
(union ce_desc *) shadow_src_desc, per_transfer_context,
src_ring->write_index);
@ -687,7 +696,7 @@ ce_recv_buf_enqueue(struct CE_handle *copyeng,
dest_ring->per_transfer_context[write_index] =
per_recv_context;
hif_record_ce_desc_event(CE_state->id, HIF_RX_DESC_POST,
hif_record_ce_desc_event(scn, CE_state->id, HIF_RX_DESC_POST,
(union ce_desc *) dest_desc, per_recv_context,
write_index);
@ -857,7 +866,7 @@ ce_completed_recv_next_nolock(struct CE_state *CE_state,
struct CE_ring_state *dest_ring = CE_state->dest_ring;
unsigned int nentries_mask = dest_ring->nentries_mask;
unsigned int sw_index = dest_ring->sw_index;
struct hif_softc *scn = CE_state->scn;
struct CE_dest_desc *dest_ring_base =
(struct CE_dest_desc *)dest_ring->base_addr_owner_space;
struct CE_dest_desc *dest_desc =
@ -881,7 +890,7 @@ ce_completed_recv_next_nolock(struct CE_state *CE_state,
goto done;
}
hif_record_ce_desc_event(CE_state->id, HIF_RX_DESC_COMPLETION,
hif_record_ce_desc_event(scn, CE_state->id, HIF_RX_DESC_COMPLETION,
(union ce_desc *) dest_desc,
dest_ring->per_transfer_context[sw_index],
sw_index);
@ -1047,7 +1056,8 @@ ce_completed_send_next_nolock(struct CE_state *CE_state,
struct CE_src_desc *src_desc =
CE_SRC_RING_TO_DESC(src_ring_base, sw_index);
#endif
hif_record_ce_desc_event(CE_state->id, HIF_TX_DESC_COMPLETION,
hif_record_ce_desc_event(scn, CE_state->id,
HIF_TX_DESC_COMPLETION,
(union ce_desc *) shadow_src_desc,
src_ring->per_transfer_context[sw_index],
sw_index);
@ -1200,7 +1210,7 @@ void ce_per_engine_servicereap(struct hif_softc *scn, unsigned int ce_id)
struct CE_state *CE_state = scn->ce_id_to_state[ce_id];
A_TARGET_ACCESS_BEGIN(scn);
hif_record_ce_desc_event(ce_id, HIF_CE_REAP_ENTRY,
hif_record_ce_desc_event(scn, ce_id, HIF_CE_REAP_ENTRY,
NULL, NULL, 0);
/* Since this function is called from both user context and
@ -1257,7 +1267,7 @@ void ce_per_engine_servicereap(struct hif_softc *scn, unsigned int ce_id)
cdf_spin_unlock_bh(&CE_state->ce_index_lock);
hif_record_ce_desc_event(ce_id, HIF_CE_REAP_EXIT,
hif_record_ce_desc_event(scn, ce_id, HIF_CE_REAP_EXIT,
NULL, NULL, 0);
A_TARGET_ACCESS_END(scn);
}
@ -1298,6 +1308,7 @@ int ce_per_engine_service(struct hif_softc *scn, unsigned int CE_id)
unsigned int more_snd_comp_cnt = 0;
unsigned int sw_idx, hw_idx;
uint32_t toeplitz_hash_result;
uint32_t mode = hif_get_conparam(scn);
if (Q_TARGET_ACCESS_BEGIN(scn) < 0) {
HIF_ERROR("[premature rc=0]\n");
@ -1375,7 +1386,7 @@ more_completions:
&toeplitz_hash_result) == CDF_STATUS_SUCCESS) {
if (CE_id != CE_HTT_H2T_MSG ||
WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
WLAN_IS_EPPING_ENABLED(mode)) {
cdf_spin_unlock(&CE_state->ce_index_lock);
CE_state->send_cb((struct CE_handle *)CE_state,
CE_context, transfer_context,
@ -1447,7 +1458,7 @@ more_watermarks:
* we find no more events to process.
*/
if (CE_state->recv_cb && ce_recv_entries_done_nolock(scn, CE_state)) {
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()) ||
if (WLAN_IS_EPPING_ENABLED(mode) ||
more_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) {
goto more_completions;
} else {
@ -1461,7 +1472,7 @@ more_watermarks:
}
if (CE_state->send_cb && ce_send_entries_done_nolock(scn, CE_state)) {
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()) ||
if (WLAN_IS_EPPING_ENABLED(mode) ||
more_snd_comp_cnt++ < CE_TXRX_COMP_CHECK_THRESHOLD) {
goto more_completions;
} else {

View file

@ -35,7 +35,6 @@
#include "cdf_lock.h"
#include "cdf_types.h"
#include "cdf_status.h"
#include "cds_api.h"
#include "regtable.h"
#include "hif.h"
#include "hif_io32.h"
@ -197,8 +196,8 @@ static void ce_tasklet(unsigned long data)
struct hif_softc *scn = HIF_GET_SOFTC(hif_ce_state);
struct CE_state *CE_state = scn->ce_id_to_state[tasklet_entry->ce_id];
hif_record_ce_desc_event(tasklet_entry->ce_id, HIF_CE_TASKLET_ENTRY,
NULL, NULL, 0);
hif_record_ce_desc_event(scn, tasklet_entry->ce_id,
HIF_CE_TASKLET_ENTRY, NULL, NULL, 0);
if (cdf_atomic_read(&scn->link_suspended)) {
HIF_ERROR("%s: ce %d tasklet fired after link suspend.",
@ -218,7 +217,7 @@ static void ce_tasklet(unsigned long data)
* Enable the interrupt only when there is no pending frames in
* any of the Copy Engine pipes.
*/
hif_record_ce_desc_event(tasklet_entry->ce_id,
hif_record_ce_desc_event(scn, tasklet_entry->ce_id,
HIF_CE_TASKLET_RESCHEDULE, NULL, NULL, 0);
ce_schedule_tasklet(tasklet_entry);
return;
@ -227,11 +226,12 @@ static void ce_tasklet(unsigned long data)
if (scn->target_status != OL_TRGET_STATUS_RESET)
ce_irq_enable(scn, tasklet_entry->ce_id);
hif_record_ce_desc_event(tasklet_entry->ce_id, HIF_CE_TASKLET_EXIT,
NULL, NULL, 0);
hif_record_ce_desc_event(scn, tasklet_entry->ce_id, HIF_CE_TASKLET_EXIT,
NULL, NULL, 0);
cdf_atomic_dec(&scn->active_tasklet_cnt);
}
/**
* ce_tasklet_init() - ce_tasklet_init
* @hif_ce_state: hif_ce_state
@ -304,7 +304,7 @@ static irqreturn_t ce_irq_handler(int irq, void *context)
ce_irq_disable(scn, ce_id);
ce_irq_status(scn, ce_id, &host_status);
cdf_atomic_inc(&scn->active_tasklet_cnt);
hif_record_ce_desc_event(ce_id, HIF_IRQ_EVENT, NULL, NULL, 0);
hif_record_ce_desc_event(scn, ce_id, HIF_IRQ_EVENT, NULL, NULL, 0);
if (hif_napi_enabled(hif_hdl, ce_id))
hif_napi_schedule(hif_hdl, ce_id);
else

View file

@ -47,7 +47,6 @@
#include "ce_tasklet.h"
#include "cdf_trace.h"
#include "cdf_status.h"
#include "cds_api.h"
#ifdef CONFIG_CNSS
#include <net/cnss.h>
#endif
@ -60,8 +59,6 @@
#include <soc/qcom/icnss.h>
#endif
#include "cds_concurrency.h"
#define AGC_DUMP 1
#define CHANINFO_DUMP 2
#define BB_WATCHDOG_DUMP 3
@ -367,15 +364,16 @@ uint32_t hif_hia_item_address(uint32_t target_type, uint32_t item_offset)
/**
* hif_max_num_receives_reached() - check max receive is reached
* @scn: HIF Context
* @count: unsigned int.
*
* Output check status as bool
*
* Return: bool
*/
bool hif_max_num_receives_reached(unsigned int count)
bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count)
{
if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
if (WLAN_IS_EPPING_ENABLED(hif_get_conparam(scn)))
return count > 120;
else
return count > MAX_NUM_OF_RECEIVES;
@ -455,41 +453,48 @@ void hif_get_hw_info(struct hif_opaque_softc *scn, u32 *version, u32 *revision,
/**
* hif_open(): hif_open
* @cdf_ctx: CDF Context
* @mode: Driver Mode
* @bus_type: Bus Type
* @cbk: CDS Callbacks
*
* Return: scn
* API to open HIF Context
*
* Return: HIF Opaque Pointer
*/
CDF_STATUS hif_open(cdf_device_t cdf_ctx, enum ath_hal_bus_type bus_type)
struct hif_opaque_softc *hif_open(cdf_device_t cdf_ctx, uint32_t mode,
enum ath_hal_bus_type bus_type,
struct hif_callbacks *cbk)
{
struct hif_opaque_softc *hif_hdl;
struct hif_softc *scn;
v_CONTEXT_t cds_context;
CDF_STATUS status = CDF_STATUS_SUCCESS;
int bus_context_size = hif_bus_get_context_size();
cds_context = cds_get_global_context();
status = cds_alloc_context(cds_context, CDF_MODULE_ID_HIF,
(void **)&scn, bus_context_size);
if (status != CDF_STATUS_SUCCESS) {
HIF_ERROR("%s: cannot alloc ol_sc", __func__);
return status;
scn = (struct hif_softc *)cdf_mem_malloc(bus_context_size);
if (!scn) {
HIF_ERROR("%s: cannot alloc memory for HIF context of size:%d",
__func__, bus_context_size);
return GET_HIF_OPAQUE_HDL(scn);
}
cdf_mem_zero(scn, bus_context_size);
hif_hdl = GET_HIF_OPAQUE_HDL(scn);
scn->cdf_dev = cdf_ctx;
scn->hif_con_param = mode;
cdf_atomic_init(&scn->active_tasklet_cnt);
cdf_atomic_init(&scn->link_suspended);
cdf_atomic_init(&scn->tasklet_from_intr);
scn->linkstate_vote = 0;
cdf_mem_copy(&scn->callbacks, cbk, sizeof(struct hif_callbacks));
status = hif_bus_open(scn, bus_type);
if (status != CDF_STATUS_SUCCESS) {
HIF_ERROR("%s: hif_bus_open error = %d, bus_type = %d",
__func__, status, bus_type);
cds_free_context(cds_context, CDF_MODULE_ID_HIF, scn);
cdf_mem_free(scn);
scn = NULL;
}
return status;
return GET_HIF_OPAQUE_HDL(scn);
}
/**
@ -513,8 +518,7 @@ void hif_close(struct hif_opaque_softc *hif_ctx)
}
hif_bus_close(scn);
cds_free_context(cds_get_global_context(),
CDF_MODULE_ID_HIF, hif_ctx);
cdf_mem_free(scn);
}
/**
@ -583,20 +587,21 @@ CDF_STATUS hif_enable(struct hif_opaque_softc *hif_ctx, struct device *dev,
/**
* hif_wlan_disable(): call the platform driver to disable wlan
* @scn: HIF Context
*
* This function passes the con_mode to platform driver to disable
* wlan.
*
* Return: void
*/
void hif_wlan_disable(void)
void hif_wlan_disable(struct hif_softc *scn)
{
enum icnss_driver_mode mode;
uint32_t con_mode = cds_get_conparam();
uint32_t con_mode = hif_get_conparam(scn);
if (CDF_GLOBAL_FTM_MODE == con_mode)
mode = ICNSS_FTM;
else if (WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
else if (WLAN_IS_EPPING_ENABLED(con_mode))
mode = ICNSS_EPPING;
else
mode = ICNSS_MISSION;
@ -622,7 +627,7 @@ void hif_disable(struct hif_opaque_softc *hif_ctx, enum hif_disable_type type)
hif_disable_bus(scn);
hif_wlan_disable();
hif_wlan_disable(scn);
scn->notice_send = false;
@ -674,7 +679,7 @@ void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx)
return;
}
if (cds_is_load_or_unload_in_progress()) {
if (hif_is_load_or_unload_in_progress(scn)) {
HIF_ERROR("%s: Load/unload is in progress, ignore!", __func__);
return;
}
@ -898,3 +903,78 @@ void hif_init_ini_config(struct hif_opaque_softc *hif_ctx,
cdf_mem_copy(&scn->hif_config, cfg, sizeof(struct hif_config_info));
}
/**
* hif_get_conparam() - API to get driver mode in HIF
* @scn: HIF Context
*
* Return: driver mode of operation
*/
uint32_t hif_get_conparam(struct hif_softc *scn)
{
if (!scn)
return 0;
return scn->hif_con_param;
}
/**
* hif_get_callbacks_handle() - API to get callbacks Handle
* @scn: HIF Context
*
* Return: pointer to HIF Callbacks
*/
struct hif_callbacks *hif_get_callbacks_handle(struct hif_softc *scn)
{
return &scn->callbacks;
}
/**
* hif_is_driver_unloading() - API to query upper layers if driver is unloading
* @scn: HIF Context
*
* Return: True/False
*/
bool hif_is_driver_unloading(struct hif_softc *scn)
{
struct hif_callbacks *cbk = hif_get_callbacks_handle(scn);
if (cbk && cbk->is_driver_unloading)
return cbk->is_driver_unloading(cbk->context);
return false;
}
/**
* hif_is_load_or_unload_in_progress() - API to query upper layers if
* load/unload in progress
* @scn: HIF Context
*
* Return: True/False
*/
bool hif_is_load_or_unload_in_progress(struct hif_softc *scn)
{
struct hif_callbacks *cbk = hif_get_callbacks_handle(scn);
if (cbk && cbk->is_load_unload_in_progress)
return cbk->is_load_unload_in_progress(cbk->context);
return false;
}
/**
* hif_is_recovery_in_progress() - API to query upper layers if recovery in
* progress
* @scn: HIF Context
*
* Return: True/False
*/
bool hif_is_recovery_in_progress(struct hif_softc *scn)
{
struct hif_callbacks *cbk = hif_get_callbacks_handle(scn);
if (cbk && cbk->is_recovery_in_progress)
return cbk->is_recovery_in_progress(cbk->context);
return false;
}

View file

@ -144,14 +144,15 @@ struct hif_softc {
#ifdef FEATURE_NAPI
struct qca_napi_data napi_data;
#endif /* FEATURE_NAPI */
struct hif_callbacks callbacks;
uint32_t hif_con_param;
};
A_target_id_t hif_get_target_id(struct hif_softc *scn);
void hif_dump_pipe_debug_count(struct hif_softc *scn);
bool hif_target_forced_awake(struct hif_softc *scn);
bool hif_max_num_receives_reached(unsigned int count);
bool hif_max_num_receives_reached(struct hif_softc *scn, unsigned int count);
int hif_config_ce(struct hif_softc *scn);
int athdiag_procfs_init(void *scn);
void athdiag_procfs_remove(void);
@ -179,4 +180,9 @@ void hif_disable_bus(struct hif_softc *scn);
void hif_bus_prevent_linkdown(struct hif_softc *scn, bool flag);
int hif_bus_get_context_size(void);
void hif_read_phy_mem_base(struct hif_softc *scn, cdf_dma_addr_t *bar_value);
uint32_t hif_get_conparam(struct hif_softc *scn);
struct hif_callbacks *hif_get_callbacks_handle(struct hif_softc *scn);
bool hif_is_driver_unloading(struct hif_softc *scn);
bool hif_is_load_or_unload_in_progress(struct hif_softc *scn);
bool hif_is_recovery_in_progress(struct hif_softc *scn);
#endif /* __HIF_MAIN_H__ */

View file

@ -33,7 +33,6 @@
#include <string.h> /* memset */
#include <cds_api.h>
#include <hif_napi.h>
#include <hif_debug.h>
#include <hif_io32.h>

View file

@ -32,7 +32,6 @@
#include <hif.h>
#include "regtable.h"
#include "hif_debug.h"
#include "cds_api.h"
#include "cdf_status.h"
#include "qwlan_version.h"
#include <net/cnss.h>

View file

@ -148,21 +148,21 @@ void war_pci_write32(char *addr, u32 offset, u32 value);
#define A_TARGET_ACCESS_BEGIN_RET_EXT(scn, val) \
do { \
if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && \
if (!WLAN_IS_EPPING_ENABLED(hif_get_conparam(scn)) && \
Q_TARGET_ACCESS_BEGIN(scn) < 0) \
val = -1; \
} while (0)
#define A_TARGET_ACCESS_BEGIN_RET(scn) \
do { \
if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && \
if (!WLAN_IS_EPPING_ENABLED(hif_get_conparam(scn)) && \
Q_TARGET_ACCESS_BEGIN(scn) < 0) \
return ATH_ISR_NOSCHED; \
} while (0)
#define A_TARGET_ACCESS_BEGIN_RET_PTR(scn) \
do { \
if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && \
if (!WLAN_IS_EPPING_ENABLED(hif_get_conparam(scn)) && \
Q_TARGET_ACCESS_BEGIN(scn) < 0) \
return NULL; \
} while (0)
@ -178,21 +178,21 @@ do { \
#define A_TARGET_ACCESS_END_RET(scn) \
do { \
if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && \
if (!WLAN_IS_EPPING_ENABLED(hif_get_conparam(scn)) && \
Q_TARGET_ACCESS_END(scn) < 0) \
return ATH_ISR_NOSCHED; \
} while (0)
#define A_TARGET_ACCESS_END_RET_EXT(scn, val) \
do { \
if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && \
if (!WLAN_IS_EPPING_ENABLED(hif_get_conparam(scn)) && \
Q_TARGET_ACCESS_END(scn) < 0) \
val = -1; \
} while (0)
#define A_TARGET_ACCESS_END_RET_PTR(scn) \
do { \
if (!WLAN_IS_EPPING_ENABLED(cds_get_conparam()) && \
if (!WLAN_IS_EPPING_ENABLED(hif_get_conparam(scn)) && \
Q_TARGET_ACCESS_END(scn) < 0) \
return NULL; \
} while (0)

View file

@ -46,9 +46,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <osapi_linux.h>
#include "cds_api.h"
#include "cdf_status.h"
#include "cds_sched.h"
#include "wma_api.h"
#include "cdf_atomic.h"
#include "wlan_hdd_power.h"
@ -70,7 +68,6 @@
#include "if_pci_internal.h"
#include "icnss_stub.h"
#include "ce_tasklet.h"
#include "cds_concurrency.h"
/* Maximum ms timeout for host to wake up target */
#define PCIE_WAKE_TIMEOUT 1000
@ -1045,14 +1042,14 @@ static void hif_pm_runtime_lock_timeout_fn(unsigned long data);
static void hif_pm_runtime_start(struct hif_pci_softc *sc)
{
struct hif_softc *ol_sc = HIF_GET_SOFTC(sc);
uint32_t mode = hif_get_con_param(ol_sc);
if (!ol_sc->enable_runtime_pm) {
HIF_INFO("%s: RUNTIME PM is disabled in ini\n", __func__);
return;
}
if (cds_get_conparam() == CDF_FTM_MODE ||
WLAN_IS_EPPING_ENABLED(cds_get_conparam())) {
if (mode == CDF_FTM_MODE || WLAN_IS_EPPING_ENABLED(mode)) {
HIF_INFO("%s: RUNTIME PM is disabled for FTM/EPPING mode\n",
__func__);
return;
@ -1079,12 +1076,12 @@ static void hif_pm_runtime_start(struct hif_pci_softc *sc)
static void hif_pm_runtime_stop(struct hif_pci_softc *sc)
{
struct hif_softc *ol_sc = HIF_GET_PCI_SOFTC(sc);
uint32_t mode = hif_get_conparam(ol_sc);
if (!ol_sc->enable_runtime_pm)
return;
if (cds_get_conparam() == CDF_FTM_MODE ||
WLAN_IS_EPPING_ENABLED(cds_get_conparam()))
if (mode == CDF_FTM_MODE || WLAN_IS_EPPING_ENABLED(mode))
return;
cnss_runtime_exit(sc->dev);
@ -2248,6 +2245,71 @@ static inline void hif_msm_pcie_debug_info(struct hif_pci_softc *sc)
static inline void hif_msm_pcie_debug_info(struct hif_pci_softc *sc) {};
#endif
/**
* hif_log_soc_wakeup_timeout() - API to log PCIe and SOC Info
* @sc: HIF PCIe Context
*
* API to log PCIe Config space and SOC info when SOC wakeup timeout happens
*
* Return: Failure to caller
*/
static int hif_log_soc_wakeup_timeout(struct hif_pci_softc *sc)
{
uint16_t val;
uint32_t bar;
struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(sc);
struct hif_softc *scn = HIF_GET_SOFTC(sc);
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(sc);
struct hif_config_info *cfg = hif_get_ini_handle(hif_hdl);
struct hif_callbacks *cbk = hif_get_callbacks_handle(scn);
A_target_id_t pci_addr = scn->mem;
HIF_ERROR("%s: keep_awake_count = %d",
__func__, hif_state->keep_awake_count);
pci_read_config_word(sc->pdev, PCI_VENDOR_ID, &val);
HIF_ERROR("%s: PCI Vendor ID = 0x%04x", __func__, val);
pci_read_config_word(sc->pdev, PCI_DEVICE_ID, &val);
HIF_ERROR("%s: PCI Device ID = 0x%04x", __func__, val);
pci_read_config_word(sc->pdev, PCI_COMMAND, &val);
HIF_ERROR("%s: PCI Command = 0x%04x", __func__, val);
pci_read_config_word(sc->pdev, PCI_STATUS, &val);
HIF_ERROR("%s: PCI Status = 0x%04x", __func__, val);
pci_read_config_dword(sc->pdev, PCI_BASE_ADDRESS_0, &bar);
HIF_ERROR("%s: PCI BAR 0 = 0x%08x", __func__, bar);
HIF_ERROR("%s: SOC_WAKE_ADDR 0%08x", __func__,
hif_read32_mb(pci_addr + PCIE_LOCAL_BASE_ADDRESS +
PCIE_SOC_WAKE_ADDRESS));
HIF_ERROR("%s: RTC_STATE_ADDR 0x%08x", __func__,
hif_read32_mb(pci_addr + PCIE_LOCAL_BASE_ADDRESS +
RTC_STATE_ADDRESS));
HIF_ERROR("%s:error, wakeup target", __func__);
hif_msm_pcie_debug_info(sc);
if (!cfg->enable_self_recovery)
CDF_BUG(0);
scn->recovery = true;
if (cbk->set_recovery_in_progress)
cbk->set_recovery_in_progress(cbk->context, true);
cnss_wlan_pci_link_down();
return -EACCES;
}
/*
* For now, we use simple on-demand sleep/wake.
* Some possible improvements:
@ -2293,10 +2355,7 @@ hif_target_sleep_state_adjust(struct hif_softc *scn,
A_target_id_t pci_addr = scn->mem;
static int max_delay;
struct hif_pci_softc *sc = HIF_GET_PCI_SOFTC(scn);
struct hif_opaque_softc *hif_hdl = GET_HIF_OPAQUE_HDL(scn);
static int debug;
struct hif_config_info *cfg = hif_get_ini_handle(hif_hdl);
if (scn->recovery)
return -EACCES;
@ -2364,62 +2423,9 @@ hif_target_sleep_state_adjust(struct hif_softc *scn,
(scn, pci_addr)) {
break;
}
if (tot_delay > PCIE_SLEEP_ADJUST_TIMEOUT) {
uint16_t val;
uint32_t bar;
HIF_ERROR("%s: keep_awake_count = %d",
__func__,
hif_state->keep_awake_count);
pci_read_config_word(sc->pdev,
PCI_VENDOR_ID,
&val);
HIF_ERROR("%s: PCI Vendor ID = 0x%04x",
__func__, val);
pci_read_config_word(sc->pdev,
PCI_DEVICE_ID,
&val);
HIF_ERROR("%s: PCI Device ID = 0x%04x",
__func__, val);
pci_read_config_word(sc->pdev,
PCI_COMMAND, &val);
HIF_ERROR("%s: PCI Command = 0x%04x",
__func__, val);
pci_read_config_word(sc->pdev,
PCI_STATUS, &val);
HIF_ERROR("%s: PCI Status = 0x%04x",
__func__, val);
pci_read_config_dword(sc->pdev,
PCI_BASE_ADDRESS_0, &bar);
HIF_ERROR("%s: PCI BAR 0 = 0x%08x",
__func__, bar);
HIF_ERROR("%s: SOC_WAKE_ADDR 0%08x",
__func__,
hif_read32_mb(pci_addr +
PCIE_LOCAL_BASE_ADDRESS
+ PCIE_SOC_WAKE_ADDRESS));
HIF_ERROR("%s: RTC_STATE_ADDR 0x%08x",
__func__,
hif_read32_mb(pci_addr +
PCIE_LOCAL_BASE_ADDRESS
+ RTC_STATE_ADDRESS));
HIF_ERROR("%s:error, wakeup target",
__func__);
hif_msm_pcie_debug_info(sc);
if (!cfg->enable_self_recovery)
CDF_BUG(0);
scn->recovery = true;
cds_set_recovery_in_progress(true);
cnss_wlan_pci_link_down();
return -EACCES;
}
if (tot_delay > PCIE_SLEEP_ADJUST_TIMEOUT)
return hif_log_soc_wakeup_timeout(sc);
OS_DELAY(curr_delay);
tot_delay += curr_delay;
@ -2708,14 +2714,14 @@ CDF_STATUS hif_enable_bus(struct hif_softc *ol_sc,
const struct pci_device_id *id = bid;
struct hif_target_info *tgt_info;
HIF_TRACE("%s: con_mode = 0x%x, device_id = 0x%x",
__func__, cds_get_conparam(), id->device);
if (!ol_sc) {
HIF_ERROR("%s: hif_ctx is NULL", __func__);
return CDF_STATUS_E_NOMEM;
}
HIF_TRACE("%s: con_mode = 0x%x, device_id = 0x%x",
__func__, hif_get_conparam(ol_sc), id->device);
sc->pdev = pdev;
sc->dev = &pdev->dev;
sc->devid = id->device;
@ -3179,13 +3185,13 @@ int hif_pm_runtime_prevent_suspend_timeout(struct hif_opaque_softc *ol_sc,
unsigned long flags;
struct hif_pm_runtime_lock *context = lock;
if (cds_is_load_unload_in_progress()) {
if (hif_is_load_or_unload_in_progress(sc)) {
HIF_ERROR("%s: Load/unload in progress, ignore!",
__func__);
return -EINVAL;
}
if (cds_is_logp_in_progress()) {
if (hif_is_recovery_in_progress(sc)) {
HIF_ERROR("%s: LOGP in progress, ignore!", __func__);
return -EINVAL;
}