diff options
| author | jiad <jiad@codeaurora.org> | 2018-04-09 15:04:38 +0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-04-13 18:13:51 -0700 |
| commit | 6ea2dc09c1c204dd56cb7c3c62444d05b7ce474d (patch) | |
| tree | 3101b99f726060b3e2c1d04815684b7926f37931 | |
| parent | dcc47066d2da55fda0a2d609cef098b3d47b74a0 (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.c | 84 |
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); |
