summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjiad <jiad@codeaurora.org>2018-04-09 15:04:38 +0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-04-13 18:13:51 -0700
commit6ea2dc09c1c204dd56cb7c3c62444d05b7ce474d (patch)
tree3101b99f726060b3e2c1d04815684b7926f37931
parentdcc47066d2da55fda0a2d609cef098b3d47b74a0 (diff)
qcacld-3.0: Fix IPA issues when wlan loaded at boot-up
If IPA uC ready callback is invoked after hdd_ipa_uc_ol_init, IPA pipes will not be connected since uc_loaded is already true. Another issue is IPA doorbell physical addresses are not propagated to WLAN FW. Fix is to 1. Set uc_loaded to true only when IPA uC ready callback is invoked before hdd_ipa_uc_ol_init. 2. Get IPA doorbell physical address via ipa_uc_wdi_get_dbpa when IPA uC is not yet ready. Change-Id: I5ee4102c689e4ce6a2f621cdb235997ceee9cece CRs-Fixed: 2218425
-rw-r--r--core/hdd/src/wlan_hdd_ipa.c84
1 files changed, 46 insertions, 38 deletions
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index 00022a92d97c..b3d54bff60fb 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -656,6 +656,26 @@ static int hdd_ipa_uc_enable_pipes(struct hdd_ipa_priv *hdd_ipa);
static int hdd_ipa_wdi_init(struct hdd_ipa_priv *hdd_ipa);
/**
+ * hdd_ipa_uc_get_db_paddr() - Get Doorbell physical address
+ * @db_paddr: Doorbell physical address given by IPA
+ * @client: IPA client type
+ *
+ * Query doorbell physical address from IPA
+ * IPA will give physical address for TX COMP and RX READY
+ *
+ * Return: None
+ */
+static void hdd_ipa_uc_get_db_paddr(qdf_dma_addr_t *db_paddr,
+ enum ipa_client_type client)
+{
+ struct ipa_wdi_db_params dbpa;
+
+ dbpa.client = client;
+ ipa_uc_wdi_get_dbpa(&dbpa);
+ *db_paddr = dbpa.uc_door_bell_pa;
+}
+
+/**
* hdd_ipa_uc_loaded_uc_cb() - IPA UC loaded event callback
* @priv_ctxt: hdd ipa local context
*
@@ -676,13 +696,14 @@ static void hdd_ipa_uc_loaded_uc_cb(void *priv_ctxt)
}
hdd_ipa = (struct hdd_ipa_priv *)priv_ctxt;
- hdd_ipa->uc_loaded = true;
uc_op_work = &hdd_ipa->uc_op_work[HDD_IPA_UC_OPCODE_UC_READY];
- if (!list_empty(&uc_op_work->work.entry))
+ if (!list_empty(&uc_op_work->work.entry)) {
/* uc_op_work is not initialized yet */
+ hdd_ipa->uc_loaded = true;
return;
+ }
msg = (struct op_msg_type *)qdf_mem_malloc(sizeof(*msg));
if (!msg) {
@@ -3707,8 +3728,6 @@ static void hdd_ipa_uc_loaded_handler(struct hdd_ipa_priv *ipa_ctxt)
struct ol_txrx_ipa_resources *ipa_res = &ipa_ctxt->ipa_resource;
qdf_device_t osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
struct ol_txrx_pdev_t *pdev;
- uint32_t tx_comp_db_dmaaddr = 0;
- uint32_t rx_rdy_db_dmaaddr = 0;
int ret;
HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "UC READY");
@@ -3717,6 +3736,8 @@ static void hdd_ipa_uc_loaded_handler(struct hdd_ipa_priv *ipa_ctxt)
return;
}
+ ipa_ctxt->uc_loaded = true;
+
if (!osdev) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_FATAL, "invalid qdf dev context");
return;
@@ -3736,24 +3757,6 @@ static void hdd_ipa_uc_loaded_handler(struct hdd_ipa_priv *ipa_ctxt)
return;
}
- if (hdd_ipa_wdi_is_smmu_enabled(ipa_ctxt, osdev)) {
- pld_smmu_map(osdev->dev,
- ipa_ctxt->tx_comp_doorbell_dmaaddr,
- &tx_comp_db_dmaaddr,
- sizeof(uint32_t));
- ipa_ctxt->tx_comp_doorbell_dmaaddr = tx_comp_db_dmaaddr;
-
- pld_smmu_map(osdev->dev,
- ipa_ctxt->rx_ready_doorbell_dmaaddr,
- &rx_rdy_db_dmaaddr,
- sizeof(uint32_t));
- ipa_ctxt->rx_ready_doorbell_dmaaddr = rx_rdy_db_dmaaddr;
- }
-
- ol_txrx_ipa_uc_set_doorbell_paddr(pdev,
- ipa_ctxt->tx_comp_doorbell_dmaaddr,
- ipa_ctxt->rx_ready_doorbell_dmaaddr);
-
/* If already any STA connected, enable IPA/FW PIPEs */
if (ipa_ctxt->sap_num_connected_sta) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_DEBUG,
@@ -4571,26 +4574,31 @@ QDF_STATUS hdd_ipa_uc_ol_init(hdd_context_t *hdd_ctx)
stat = QDF_STATUS_E_FAILURE;
goto fail_return;
}
+ } else {
+ hdd_ipa_uc_get_db_paddr(&ipa_ctxt->tx_comp_doorbell_dmaaddr,
+ IPA_CLIENT_WLAN1_CONS);
+ hdd_ipa_uc_get_db_paddr(&ipa_ctxt->rx_ready_doorbell_dmaaddr,
+ IPA_CLIENT_WLAN1_PROD);
+ }
- if (hdd_ipa_wdi_is_smmu_enabled(ipa_ctxt, osdev)) {
- pld_smmu_map(osdev->dev,
- ipa_ctxt->tx_comp_doorbell_dmaaddr,
- &tx_comp_db_dmaaddr,
- sizeof(uint32_t));
- ipa_ctxt->tx_comp_doorbell_dmaaddr = tx_comp_db_dmaaddr;
-
- pld_smmu_map(osdev->dev,
- ipa_ctxt->rx_ready_doorbell_dmaaddr,
- &rx_rdy_db_dmaaddr,
- sizeof(uint32_t));
- ipa_ctxt->rx_ready_doorbell_dmaaddr = rx_rdy_db_dmaaddr;
- }
-
- ol_txrx_ipa_uc_set_doorbell_paddr(pdev,
+ if (hdd_ipa_wdi_is_smmu_enabled(ipa_ctxt, osdev)) {
+ pld_smmu_map(osdev->dev,
ipa_ctxt->tx_comp_doorbell_dmaaddr,
- ipa_ctxt->rx_ready_doorbell_dmaaddr);
+ &tx_comp_db_dmaaddr,
+ sizeof(uint32_t));
+ ipa_ctxt->tx_comp_doorbell_dmaaddr = tx_comp_db_dmaaddr;
+
+ pld_smmu_map(osdev->dev,
+ ipa_ctxt->rx_ready_doorbell_dmaaddr,
+ &rx_rdy_db_dmaaddr,
+ sizeof(uint32_t));
+ ipa_ctxt->rx_ready_doorbell_dmaaddr = rx_rdy_db_dmaaddr;
}
+ ol_txrx_ipa_uc_set_doorbell_paddr(pdev,
+ ipa_ctxt->tx_comp_doorbell_dmaaddr,
+ ipa_ctxt->rx_ready_doorbell_dmaaddr);
+
for (i = 0; i < HDD_IPA_UC_OPCODE_MAX; i++) {
hdd_ipa_init_uc_op_work(&ipa_ctxt->uc_op_work[i].work,
hdd_ipa_uc_fw_op_event_handler);