[RFC v3 06/11] ath10k: htt: High latency RX support
Kalle Valo
kvalo at qca.qualcomm.com
Fri Dec 22 07:32:09 PST 2017
Erik Stromdahl <erik.stromdahl at gmail.com> writes:
> Special HTT RX handling for high latency interfaces.
>
> Since no DMA physical addresses are used in the RX ring
> config message (this is not supported by the high latency
> devices), no RX ring is allocated.
> All RX skb's are allocated by the driver and passed directly
> to mac80211 in the HTT RX indication handler.
>
> A nice side effect of this is that no huge buffer will be
> allocated with dma_alloc_coherent. On embedded systems with
> limited memory resources, the allocation of the RX ring is
> prone to fail.
>
> Some tweaks made to "make it work":
>
> Removal of protected bit in 802.11 header frame control field.
> The chipset seems to do hw decryption but the frame_control
> protected bit is still set.
>
> This is necessary for mac80211 not to drop the frame.
>
> Signed-off-by: Erik Stromdahl <erik.stromdahl at gmail.com>
> ---
> drivers/net/wireless/ath/ath10k/core.c | 27 ++++---
> drivers/net/wireless/ath/ath10k/htt.h | 47 ++++++++++++
> drivers/net/wireless/ath/ath10k/htt_rx.c | 119 +++++++++++++++++++++++++++++-
> drivers/net/wireless/ath/ath10k/rx_desc.h | 15 ++++
> 4 files changed, 195 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
> index c21227a74996..1880570989ae 100644
> --- a/drivers/net/wireless/ath/ath10k/core.c
> +++ b/drivers/net/wireless/ath/ath10k/core.c
> @@ -2083,10 +2083,12 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
> ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
> ar->wmi.svc_map));
>
> - status = ath10k_htt_rx_alloc(&ar->htt);
> - if (status) {
> - ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
> - goto err_htt_tx_detach;
> + if (!ar->is_high_latency) {
> + status = ath10k_htt_rx_alloc(&ar->htt);
> + if (status) {
> + ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
> + goto err_htt_tx_detach;
> + }
> }
Wouldn't it be cleaner code to have the is_high_latency check within
ath10k_htt_rx_alloc() call?
> @@ -2203,10 +2205,13 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
> }
> }
>
> - status = ath10k_htt_rx_ring_refill(ar);
> - if (status) {
> - ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);
> - goto err_hif_stop;
> + if (!ar->is_high_latency) {
> + status = ath10k_htt_rx_ring_refill(ar);
> + if (status) {
> + ath10k_err(ar, "failed to refill htt rx ring: %d\n",
> + status);
> + goto err_hif_stop;
> + }
> }
Ditto.
> @@ -2235,7 +2240,8 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
> err_hif_stop:
> ath10k_hif_stop(ar);
> err_htt_rx_detach:
> - ath10k_htt_rx_free(&ar->htt);
> + if (!ar->is_high_latency)
> + ath10k_htt_rx_free(&ar->htt);
> err_htt_tx_detach:
> ath10k_htt_tx_free(&ar->htt);
> err_wmi_detach:
Ditto.
> @@ -2280,7 +2286,8 @@ void ath10k_core_stop(struct ath10k *ar)
>
> ath10k_hif_stop(ar);
> ath10k_htt_tx_stop(&ar->htt);
> - ath10k_htt_rx_free(&ar->htt);
> + if (!ar->is_high_latency)
> + ath10k_htt_rx_free(&ar->htt);
> ath10k_wmi_detach(ar);
> ar->is_started = false;
> }
Ditto.
> + /* Not entirely sure about this, but all frames from the chipset has
> + * the protected flag set even though they have already been decrypted.
> + * Unmasking this flag is necessary in order for mac80211 not to drop
> + * the frame.
> + * TODO: Verify this is always the case or find out a way to check
> + * if there has been hw decryption.
> + */
> + if (ieee80211_has_protected(hdr->frame_control)) {
> + hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
> + rx_status->flag |= RX_FLAG_DECRYPTED |
> + RX_FLAG_IV_STRIPPED |
> + RX_FLAG_MMIC_STRIPPED;
> + }
> +
> + local_bh_disable();
> + ieee80211_rx(ar->hw, skb);
> + local_bh_enable();
ieee80211_rx_ni()?
--
Kalle Valo
More information about the ath10k
mailing list