Commit fbc03a46 authored by Peter Oh's avatar Peter Oh Committed by Kalle Valo

ath10k: update tx path to support QCA99X0

Since QCA99X0 uses fragmentation descriptor differently from
other ones on tx path, we need to handle it separately.

QCA99X0 is using 48 bits for address and 16 bits for length
out of 2 dword and each values have to be programmed by frag
desc base addr + msdu id, so that hardware can retrieve
corresponding frag data.
Signed-off-by: default avatarPeter Oh <poh@qca.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent acd19580
...@@ -83,8 +83,17 @@ struct htt_ver_req { ...@@ -83,8 +83,17 @@ struct htt_ver_req {
* around the mask + shift defs. * around the mask + shift defs.
*/ */
struct htt_data_tx_desc_frag { struct htt_data_tx_desc_frag {
__le32 paddr; union {
__le32 len; struct double_word_addr {
__le32 paddr;
__le32 len;
} __packed dword_addr;
struct triple_word_addr {
__le32 paddr_lo;
__le16 paddr_hi;
__le16 len_16;
} __packed tword_addr;
} __packed;
} __packed; } __packed;
struct htt_msdu_ext_desc { struct htt_msdu_ext_desc {
......
...@@ -63,7 +63,8 @@ int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb) ...@@ -63,7 +63,8 @@ int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb)
lockdep_assert_held(&htt->tx_lock); lockdep_assert_held(&htt->tx_lock);
ret = idr_alloc(&htt->pending_tx, skb, 0, 0x10000, GFP_ATOMIC); ret = idr_alloc(&htt->pending_tx, skb, 0,
htt->max_num_pending_tx, GFP_ATOMIC);
ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", ret); ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", ret);
...@@ -259,6 +260,7 @@ int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt) ...@@ -259,6 +260,7 @@ int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt)
cmd->frag_desc_bank_cfg.desc_size = sizeof(struct htt_msdu_ext_desc); cmd->frag_desc_bank_cfg.desc_size = sizeof(struct htt_msdu_ext_desc);
cmd->frag_desc_bank_cfg.bank_base_addrs[0] = cmd->frag_desc_bank_cfg.bank_base_addrs[0] =
__cpu_to_le32(htt->frag_desc.paddr); __cpu_to_le32(htt->frag_desc.paddr);
cmd->frag_desc_bank_cfg.bank_id[0].bank_min_id = 0;
cmd->frag_desc_bank_cfg.bank_id[0].bank_max_id = cmd->frag_desc_bank_cfg.bank_id[0].bank_max_id =
__cpu_to_le16(htt->max_num_pending_tx - 1); __cpu_to_le16(htt->max_num_pending_tx - 1);
...@@ -537,16 +539,29 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) ...@@ -537,16 +539,29 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT; flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT;
/* pass through */ /* pass through */
case ATH10K_HW_TXRX_ETHERNET: case ATH10K_HW_TXRX_ETHERNET:
frags = skb_cb->htt.txbuf->frags; if (ar->hw_params.continuous_frag_desc) {
frags = (struct htt_data_tx_desc_frag *)
frags[0].paddr = __cpu_to_le32(skb_cb->paddr); &htt->frag_desc.vaddr[msdu_id].frags;
frags[0].len = __cpu_to_le32(msdu->len); frags[0].tword_addr.paddr_lo =
frags[1].paddr = 0; __cpu_to_le32(skb_cb->paddr);
frags[1].len = 0; frags[0].tword_addr.paddr_hi = 0;
frags[0].tword_addr.len_16 = __cpu_to_le16(msdu->len);
frags[1].tword_addr.paddr_lo = 0;
frags[1].tword_addr.paddr_hi = 0;
frags_paddr = htt->frag_desc.paddr +
(sizeof(struct htt_msdu_ext_desc) * msdu_id);
} else {
frags = skb_cb->htt.txbuf->frags;
frags[0].dword_addr.paddr =
__cpu_to_le32(skb_cb->paddr);
frags[0].dword_addr.len = __cpu_to_le32(msdu->len);
frags[1].dword_addr.paddr = 0;
frags[1].dword_addr.len = 0;
frags_paddr = skb_cb->htt.txbuf_paddr;
}
flags0 |= SM(skb_cb->txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE); flags0 |= SM(skb_cb->txmode, HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE);
frags_paddr = skb_cb->htt.txbuf_paddr;
break; break;
case ATH10K_HW_TXRX_MGMT: case ATH10K_HW_TXRX_MGMT:
flags0 |= SM(ATH10K_HW_TXRX_MGMT, flags0 |= SM(ATH10K_HW_TXRX_MGMT,
......
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