[01/11] ath10k_sdio: sdio htt data transfer fixes
diff mbox

Message ID 1506793068-27445-2-git-send-email-alagusankar@silex-india.com
State New
Headers show

Commit Message

silexcommon@gmail.com Sept. 30, 2017, 5:37 p.m. UTC
From: Alagu Sankar <alagusankar@silex-india.com>

The ath10k sdio firmware does not allow transmitting packets with the
reduced tx completion HI_ACS option. sdio firmware uses 1544 as
alternate credit size, which is not big enough for the maximum sized
mac80211 frames. Disable both these HI_ACS flags for SDIO.

Transmit completion for SDIO is similar to PCIe, via the T2H message
HTT_T2H_MSG_TYPE_TX_COMPL_IND.  Modify the high latency path to allow
SDIO modules to use the htt transmit completion path. This differs from
the high latency path taken by the USB devices.

Signed-off-by: Alagu Sankar <alagusankar@silex-india.com>
---
 drivers/net/wireless/ath/ath10k/core.c   | 20 +++++++++++++++++---
 drivers/net/wireless/ath/ath10k/htt_rx.c |  6 ++++--
 drivers/net/wireless/ath/ath10k/htt_tx.c | 24 +++++++++++++++++++-----
 3 files changed, 40 insertions(+), 10 deletions(-)

Comments

Arend Van Spriel Oct. 2, 2017, 7:36 a.m. UTC | #1
On 9/30/2017 7:37 PM, silexcommon@gmail.com wrote:
> From: Alagu Sankar <alagusankar@silex-india.com>
>

[...]

>
> Signed-off-by: Alagu Sankar <alagusankar@silex-india.com>

Not really have a specific remark for this patch, but for the entire 
series. These patches are sent using an anonymous email address, apart 
from 'silex' being in there, which does not show up in the certificate 
of origin. Just wondering if this is acceptable?

Regards,
Arend

> ---
>   drivers/net/wireless/ath/ath10k/core.c   | 20 +++++++++++++++++---
>   drivers/net/wireless/ath/ath10k/htt_rx.c |  6 ++++--
>   drivers/net/wireless/ath/ath10k/htt_tx.c | 24 +++++++++++++++++++-----
>   3 files changed, 40 insertions(+), 10 deletions(-)
Alagu Sankar Oct. 2, 2017, 7:44 a.m. UTC | #2
Hi Arend,

On 2017-10-02 13:06, Arend van Spriel wrote:
> On 9/30/2017 7:37 PM, silexcommon@gmail.com wrote:
>> From: Alagu Sankar <alagusankar@silex-india.com>
>> 
> 
> [...]
> 
>> 
>> Signed-off-by: Alagu Sankar <alagusankar@silex-india.com>
> 
> Not really have a specific remark for this patch, but for the entire
> series. These patches are sent using an anonymous email address, apart
> from 'silex' being in there, which does not show up in the certificate
> of origin. Just wondering if this is acceptable?
> 
> Regards,
> Arend
> 
>> ---
>>   drivers/net/wireless/ath/ath10k/core.c   | 20 +++++++++++++++++---
>>   drivers/net/wireless/ath/ath10k/htt_rx.c |  6 ++++--
>>   drivers/net/wireless/ath/ath10k/htt_tx.c | 24 
>> +++++++++++++++++++-----
>>   3 files changed, 40 insertions(+), 10 deletions(-)
> 
Could not use git send-email from the official ID due to mail server 
restrictions. If this is not acceptable, I will figure out a way to 
overcome this.

Regards,
Alagu Sankar
Kalle Valo Oct. 4, 2017, 8:55 a.m. UTC | #3
Arend van Spriel <arend.vanspriel@broadcom.com> writes:

> On 9/30/2017 7:37 PM, silexcommon@gmail.com wrote:
>> From: Alagu Sankar <alagusankar@silex-india.com>
>>
>
> [...]
>
>>
>> Signed-off-by: Alagu Sankar <alagusankar@silex-india.com>
>
> Not really have a specific remark for this patch, but for the entire
> series. These patches are sent using an anonymous email address, apart
> from 'silex' being in there, which does not show up in the certificate
> of origin. Just wondering if this is acceptable?

As long as there's the "correct" From header as the first line in the
commit log, which git then uses as the author instead of the From line
from email header. And I see Alagu doing that here so there shouldn't be
any problems.

Patch
diff mbox

diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 4351341..b4f66cd 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -494,11 +494,25 @@  static void ath10k_init_sdio(struct ath10k *ar)
 	ath10k_bmi_write32(ar, hi_mbox_isr_yield_limit, 99);
 	ath10k_bmi_read32(ar, hi_acs_flags, &param);
 
-	param |= (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET |
-		  HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET |
-		  HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE);
+	/* Data transfer is not initiated, when reduced Tx completion
+	 * is used for SDIO. disable it until fixed
+	 */
+	param &= ~HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
+
+	/* Alternate credit size of 1544 as used by SDIO firmware is
+	 * not big enough for mac80211 / native wifi frames. disable it
+	 */
+	param &= ~HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
 
+	param |= HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;
 	ath10k_bmi_write32(ar, hi_acs_flags, param);
+
+	/* Explicitly set fwlog prints to zero as target may turn it on
+	 * based on scratch registers.
+	 */
+	ath10k_bmi_read32(ar, hi_option_flag, &param);
+	param |= HI_OPTION_DISABLE_DBGLOG;
+	ath10k_bmi_write32(ar, hi_option_flag, param);
 }
 
 static int ath10k_init_configure_target(struct ath10k *ar)
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 569edd0..f025363 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1764,7 +1764,9 @@  static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
 		 *  Note that with only one concurrent reader and one concurrent
 		 *  writer, you don't need extra locking to use these macro.
 		 */
-		if (!kfifo_put(&htt->txdone_fifo, tx_done)) {
+		if (ar->hif.bus == ATH10K_BUS_SDIO) {
+			ath10k_txrx_tx_unref(htt, &tx_done);
+		} else if (!kfifo_put(&htt->txdone_fifo, tx_done)) {
 			ath10k_warn(ar, "txdone fifo overrun, msdu_id %d status %d\n",
 				    tx_done.msdu_id, tx_done.status);
 			ath10k_txrx_tx_unref(htt, &tx_done);
@@ -2541,7 +2543,7 @@  bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
 		break;
 	}
 	case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
-		if (!ar->is_high_latency)
+		if (!(ar->hif.bus == ATH10K_BUS_USB))
 			ath10k_htt_rx_tx_compl_ind(htt->ar, skb);
 		break;
 	case HTT_T2H_MSG_TYPE_SEC_IND: {
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index c74fc13..d7f59a2 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -153,7 +153,7 @@  void ath10k_htt_tx_txq_update(struct ieee80211_hw *hw,
 
 void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt)
 {
-	if (htt->ar->is_high_latency)
+	if (htt->ar->hif.bus == ATH10K_BUS_USB)
 		return;
 
 	lockdep_assert_held(&htt->tx_lock);
@@ -165,7 +165,7 @@  void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt)
 
 int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt)
 {
-	if (htt->ar->is_high_latency)
+	if (htt->ar->hif.bus == ATH10K_BUS_USB)
 		return 0;
 
 	lockdep_assert_held(&htt->tx_lock);
@@ -454,7 +454,7 @@  void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
 		return;
 
 	ath10k_htt_tx_free_cont_txbuf(htt);
-	if (!htt->ar->is_high_latency)
+	if (!(htt->ar->hif.bus == ATH10K_BUS_USB))
 		ath10k_htt_tx_free_txq(htt);
 	ath10k_htt_tx_free_cont_frag_desc(htt);
 	ath10k_htt_tx_free_txdone_fifo(htt);
@@ -475,7 +475,8 @@  void ath10k_htt_tx_free(struct ath10k_htt *htt)
 
 void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
 {
-	dev_kfree_skb_any(skb);
+	if (!(ar->hif.bus == ATH10K_BUS_SDIO))
+		dev_kfree_skb_any(skb);
 }
 
 void ath10k_htt_hif_tx_complete(struct ath10k *ar, struct sk_buff *skb)
@@ -975,6 +976,7 @@  int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
 	u8 tid = ath10k_htt_tx_get_tid(msdu, is_eth);
 	u8 flags0 = 0;
 	u16 flags1 = 0;
+	u16 msdu_id = 0;
 
 	data_len = msdu->len;
 
@@ -1022,6 +1024,18 @@  int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
 		}
 	}
 
+	if (ar->hif.bus == ATH10K_BUS_SDIO) {
+		flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED;
+		spin_lock_bh(&htt->tx_lock);
+		res = ath10k_htt_tx_alloc_msdu_id(htt, msdu);
+		spin_unlock_bh(&htt->tx_lock);
+		if (res < 0) {
+			ath10k_err(ar, "msdu_id allocation failed %d\n", res);
+			goto out;
+		}
+		msdu_id = res;
+	}
+
 	skb_push(msdu, sizeof(*cmd_hdr));
 	skb_push(msdu, sizeof(*tx_desc));
 	cmd_hdr = (struct htt_cmd_hdr *)msdu->data;
@@ -1031,7 +1045,7 @@  int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txmode,
 	tx_desc->flags0 = flags0;
 	tx_desc->flags1 = __cpu_to_le16(flags1);
 	tx_desc->len = __cpu_to_le16(data_len);
-	tx_desc->id = 0;
+	tx_desc->id = __cpu_to_le16(msdu_id);
 	tx_desc->frags_paddr = 0; /* always zero */
 	/* Initialize peer_id to INVALID_PEER because this is NOT
 	 * Reinjection path