Commit d390509b authored by Govind Singh's avatar Govind Singh Committed by Kalle Valo

ath10k: add hif tx methods for wcn3990

Add hif tx/tx-complete methods for wcn3990
target.
Signed-off-by: default avatarGovind Singh <govinds@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 0fa4fbe9
...@@ -42,6 +42,9 @@ static char *const ce_name[] = { ...@@ -42,6 +42,9 @@ static char *const ce_name[] = {
"WLAN_CE_11", "WLAN_CE_11",
}; };
static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state);
static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state);
static const struct ath10k_snoc_drv_priv drv_priv = { static const struct ath10k_snoc_drv_priv drv_priv = {
.hw_rev = ATH10K_HW_WCN3990, .hw_rev = ATH10K_HW_WCN3990,
.dma_mask = DMA_BIT_MASK(37), .dma_mask = DMA_BIT_MASK(37),
...@@ -54,7 +57,7 @@ static struct ce_attr host_ce_config_wlan[] = { ...@@ -54,7 +57,7 @@ static struct ce_attr host_ce_config_wlan[] = {
.src_nentries = 16, .src_nentries = 16,
.src_sz_max = 2048, .src_sz_max = 2048,
.dest_nentries = 0, .dest_nentries = 0,
.send_cb = NULL, .send_cb = ath10k_snoc_htc_tx_cb,
}, },
/* CE1: target->host HTT + HTC control */ /* CE1: target->host HTT + HTC control */
...@@ -81,7 +84,7 @@ static struct ce_attr host_ce_config_wlan[] = { ...@@ -81,7 +84,7 @@ static struct ce_attr host_ce_config_wlan[] = {
.src_nentries = 32, .src_nentries = 32,
.src_sz_max = 2048, .src_sz_max = 2048,
.dest_nentries = 0, .dest_nentries = 0,
.send_cb = NULL, .send_cb = ath10k_snoc_htc_tx_cb,
}, },
/* CE4: host->target HTT */ /* CE4: host->target HTT */
...@@ -90,7 +93,7 @@ static struct ce_attr host_ce_config_wlan[] = { ...@@ -90,7 +93,7 @@ static struct ce_attr host_ce_config_wlan[] = {
.src_nentries = 256, .src_nentries = 256,
.src_sz_max = 256, .src_sz_max = 256,
.dest_nentries = 0, .dest_nentries = 0,
.send_cb = NULL, .send_cb = ath10k_snoc_htt_tx_cb,
}, },
/* CE5: target->host HTT (ipa_uc->target ) */ /* CE5: target->host HTT (ipa_uc->target ) */
...@@ -359,6 +362,117 @@ static void ath10k_snoc_rx_post(struct ath10k *ar) ...@@ -359,6 +362,117 @@ static void ath10k_snoc_rx_post(struct ath10k *ar)
ath10k_snoc_rx_post_pipe(&ar_snoc->pipe_info[i]); ath10k_snoc_rx_post_pipe(&ar_snoc->pipe_info[i]);
} }
static void ath10k_snoc_htc_tx_cb(struct ath10k_ce_pipe *ce_state)
{
struct ath10k *ar = ce_state->ar;
struct sk_buff_head list;
struct sk_buff *skb;
__skb_queue_head_init(&list);
while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
if (!skb)
continue;
__skb_queue_tail(&list, skb);
}
while ((skb = __skb_dequeue(&list)))
ath10k_htc_tx_completion_handler(ar, skb);
}
static void ath10k_snoc_htt_tx_cb(struct ath10k_ce_pipe *ce_state)
{
struct ath10k *ar = ce_state->ar;
struct sk_buff *skb;
while (ath10k_ce_completed_send_next(ce_state, (void **)&skb) == 0) {
if (!skb)
continue;
dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr,
skb->len, DMA_TO_DEVICE);
ath10k_htt_hif_tx_complete(ar, skb);
}
}
static int ath10k_snoc_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
struct ath10k_hif_sg_item *items, int n_items)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
struct ath10k_ce *ce = ath10k_ce_priv(ar);
struct ath10k_snoc_pipe *snoc_pipe;
struct ath10k_ce_pipe *ce_pipe;
int err, i = 0;
snoc_pipe = &ar_snoc->pipe_info[pipe_id];
ce_pipe = snoc_pipe->ce_hdl;
spin_lock_bh(&ce->ce_lock);
for (i = 0; i < n_items - 1; i++) {
ath10k_dbg(ar, ATH10K_DBG_SNOC,
"snoc tx item %d paddr %pad len %d n_items %d\n",
i, &items[i].paddr, items[i].len, n_items);
err = ath10k_ce_send_nolock(ce_pipe,
items[i].transfer_context,
items[i].paddr,
items[i].len,
items[i].transfer_id,
CE_SEND_FLAG_GATHER);
if (err)
goto err;
}
ath10k_dbg(ar, ATH10K_DBG_SNOC,
"snoc tx item %d paddr %pad len %d n_items %d\n",
i, &items[i].paddr, items[i].len, n_items);
err = ath10k_ce_send_nolock(ce_pipe,
items[i].transfer_context,
items[i].paddr,
items[i].len,
items[i].transfer_id,
0);
if (err)
goto err;
spin_unlock_bh(&ce->ce_lock);
return 0;
err:
for (; i > 0; i--)
__ath10k_ce_send_revert(ce_pipe);
spin_unlock_bh(&ce->ce_lock);
return err;
}
static u16 ath10k_snoc_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
{
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
ath10k_dbg(ar, ATH10K_DBG_SNOC, "hif get free queue number\n");
return ath10k_ce_num_free_src_entries(ar_snoc->pipe_info[pipe].ce_hdl);
}
static void ath10k_snoc_hif_send_complete_check(struct ath10k *ar, u8 pipe,
int force)
{
int resources;
ath10k_dbg(ar, ATH10K_DBG_SNOC, "snoc hif send complete check\n");
if (!force) {
resources = ath10k_snoc_hif_get_free_queue_number(ar, pipe);
if (resources > (host_ce_config_wlan[pipe].src_nentries >> 1))
return;
}
ath10k_ce_per_engine_service(ar, pipe);
}
static int ath10k_snoc_hif_map_service_to_pipe(struct ath10k *ar, static int ath10k_snoc_hif_map_service_to_pipe(struct ath10k *ar,
u16 service_id, u16 service_id,
u8 *ul_pipe, u8 *dl_pipe) u8 *ul_pipe, u8 *dl_pipe)
...@@ -587,6 +701,9 @@ static const struct ath10k_hif_ops ath10k_snoc_hif_ops = { ...@@ -587,6 +701,9 @@ static const struct ath10k_hif_ops ath10k_snoc_hif_ops = {
.get_default_pipe = ath10k_snoc_hif_get_default_pipe, .get_default_pipe = ath10k_snoc_hif_get_default_pipe,
.power_up = ath10k_snoc_hif_power_up, .power_up = ath10k_snoc_hif_power_up,
.power_down = ath10k_snoc_hif_power_down, .power_down = ath10k_snoc_hif_power_down,
.tx_sg = ath10k_snoc_hif_tx_sg,
.send_complete_check = ath10k_snoc_hif_send_complete_check,
.get_free_queue_number = ath10k_snoc_hif_get_free_queue_number,
}; };
static const struct ath10k_bus_ops ath10k_snoc_bus_ops = { static const struct ath10k_bus_ops ath10k_snoc_bus_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment