From patchwork Mon May 6 14:54:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miles Hu X-Patchwork-Id: 10931197 X-Patchwork-Delegate: kvalo@adurom.com Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3DE5D13AD for ; Mon, 6 May 2019 14:55:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2BB8B287C8 for ; Mon, 6 May 2019 14:55:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 201B7287CF; Mon, 6 May 2019 14:55:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7CA87287C8 for ; Mon, 6 May 2019 14:55:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=Y5XqDBmALsYut+nXpnoJ5JIvmljffTnJtBEyyaAEPIw=; b=gtKOp9rzE6zHXGT4HKag7jo4ac f3docTYILxt66zdTBOIXpskuX+0DJqfmJpgNw9exLv4OLodOHmqrzTB+bwpXXC5Qhih4ZFwH0RmcL FqywtcpiA9uluCU0ktF+D5vv7cCBg22Y3+Z45gyNTIZvF0uT8MZCrmeVS8bPKtGDD5HL8Kun5y2Yy 1cK9e1FciJJJLxdKYxBPQ0i3E6r6lp3bT6I6CQ83veHgC1dBTHLEGtBQ6Q/EekLlabWL5XDD8zwfc E0Fe6OcguGw+9fPU5Pzr46dcV3yCeyglaYICXFICLfsXSovJbnZEkl4WtXsh98RsrFuW0C7gEM8Me fRLOAH4g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1hNf1T-0002re-AN; Mon, 06 May 2019 14:55:19 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1hNf1Q-0002qB-FK for ath11k@lists.infradead.org; Mon, 06 May 2019 14:55:18 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id F18DA61132; Mon, 6 May 2019 14:55:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1557154516; bh=aU4DoMfyNzJ9aZ8l4o0qKhmFtp2SjVP3Jl1hv8eiCvI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=myXWV14sfJ/bDuybI2iTj+/3/vU+4lvrEv0a5mlKz8lq6iCxVp7uSzVB+zpv/trzR fOBG/417TxpJ9P+jkptmM+qSTZquVjQ9rWt960mQP5Nxt2bT5skqdLGvU8pV6h/Hpb xUrrv+udDUj8EDxOePkWx9OOinhX0sch9/Q3soew= Received: from smtp.codeaurora.org (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: milehu@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 8536861132; Mon, 6 May 2019 14:55:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1557154512; bh=aU4DoMfyNzJ9aZ8l4o0qKhmFtp2SjVP3Jl1hv8eiCvI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e469bZUtuqx1JBVmM19SofBmVnImFhgC6tj3mM9YhZP+G58jY6hw4u461Jq2c4awn 0icNoxWYn4bOOKFLxnkGMEsJXZygJK43HBKwk7PnZA3eh4kgAnVpHNonEclPMdxrtp WwyA6e6ZxIM7lPqhtP2GQYOCHjiveJMCm9eEVNHo= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 8536861132 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=milehu@codeaurora.org Received: by smtp.codeaurora.org (sSMTP sendmail emulation); Mon, 06 May 2019 07:55:10 -0700 From: Miles Hu To: ath11k@lists.infradead.org Subject: [PATCH v3 6/6] ath11k: merge msdu tlv process and status/destination ring process Date: Mon, 6 May 2019 07:54:56 -0700 Message-Id: <1557154496-12059-7-git-send-email-milehu@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1557154496-12059-1-git-send-email-milehu@codeaurora.org> References: <1557154496-12059-1-git-send-email-milehu@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190506_075516_544828_92108004 X-CRM114-Status: GOOD ( 13.15 ) X-BeenThere: ath11k@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Miles Hu MIME-Version: 1.0 Sender: "ath11k" Errors-To: ath11k-bounces+patchwork-ath11k=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP merge msdu list and process status. deliver mpdu to upper layer. process tlv in rx descriptor. status/destination ring process function. Signed-off-by: Miles Hu --- V2: - Move to ath11k-bringup branch drivers/net/wireless/ath/ath11k/dp_rx.c | 291 ++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index faadfd1..f61adf2 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -3567,6 +3567,297 @@ static inline void ath11k_dp_rx_msdus_set_payload(struct sk_buff *msdu) skb_pull(msdu, rx_pkt_offset + l2_hdr_offset); } +static inline struct sk_buff * +ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar, + u32 mac_id, struct sk_buff *head_msdu, + struct sk_buff *last_msdu, + struct ieee80211_rx_status *rxs) +{ + struct sk_buff *msdu, *mpdu_buf, *prev_buf; + u32 decap_format, wifi_hdr_len; + void *rx_desc; + char *hdr_desc; + u8 *dest; + struct ieee80211_hdr_3addr *wh; + + mpdu_buf = NULL; + + if (!head_msdu) + goto err_merge_fail; + + rx_desc = head_msdu->data; + + if (ath11k_dp_rxdesc_get_mpdulen_err(rx_desc)) + return NULL; + + decap_format = ath11k_dp_rxdesc_get_decap_format(rx_desc); + + ath11k_dp_rx_h_ppdu(ar, rx_desc, rxs); + + if (decap_format == DP_RX_DECAP_TYPE_RAW) { + ath11k_dp_rx_msdus_set_payload(head_msdu); + + prev_buf = head_msdu; + msdu = head_msdu->next; + + while (msdu) { + ath11k_dp_rx_msdus_set_payload(msdu); + + prev_buf = msdu; + msdu = msdu->next; + } + + prev_buf->next = NULL; + + skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN); + } else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) { + __le16 qos_field; + u8 qos_pkt = 0; + + rx_desc = head_msdu->data; + hdr_desc = ath11k_dp_rxdesc_get_80211hdr(rx_desc); + + /* Base size */ + wifi_hdr_len = sizeof(struct ieee80211_hdr_3addr); + wh = (struct ieee80211_hdr_3addr *)hdr_desc; + + if (ieee80211_is_data_qos(wh->frame_control)) { + struct ieee80211_qos_hdr *qwh = + (struct ieee80211_qos_hdr *)hdr_desc; + + qos_field = qwh->qos_ctrl; + qos_pkt = 1; + } + msdu = head_msdu; + + while (msdu) { + rx_desc = msdu->data; + hdr_desc = ath11k_dp_rxdesc_get_80211hdr(rx_desc); + + if (qos_pkt) { + dest = skb_push(msdu, sizeof(__le16)); + if (!dest) + goto err_merge_fail; + memcpy(dest, hdr_desc, wifi_hdr_len); + memcpy(dest + wifi_hdr_len, + (u8 *)&qos_field, sizeof(__le16)); + } + ath11k_dp_rx_msdus_set_payload(msdu); + prev_buf = msdu; + msdu = msdu->next; + } + dest = skb_put(prev_buf, HAL_RX_FCS_LEN); + if (!dest) + goto err_merge_fail; + + ath11k_dbg(ar->ab, ATH11K_DBG_DATA, + "mpdu_buf %pK mpdu_buf->len %u", + prev_buf, prev_buf->len); + } else { + ath11k_dbg(ar->ab, ATH11K_DBG_DATA, + "decap format %d is not supported!\n", + decap_format); + goto err_merge_fail; + } + + return head_msdu; + +err_merge_fail: + if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) { + ath11k_dbg(ar->ab, ATH11K_DBG_DATA, + "err_merge_fail mpdu_buf %pK", mpdu_buf); + /* Free the head buffer */ + dev_kfree_skb_any(mpdu_buf); + } + return NULL; +} + +int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id, + struct sk_buff *head_msdu, + struct sk_buff *tail_msdu, + struct napi_struct *napi) +{ + struct ath11k_pdev_dp *dp = &ar->dp; + struct sk_buff *mon_skb, *skb_next, *header; + struct ieee80211_rx_status *rxs = &dp->rx_status, *status; + + mon_skb = ath11k_dp_rx_mon_merg_msdus(ar, mac_id, head_msdu, + tail_msdu, rxs); + + if (!mon_skb) + goto mon_deliver_fail; + + header = mon_skb; + + do { + skb_next = mon_skb->next; + if (!skb_next) + rxs->flag &= ~RX_FLAG_AMSDU_MORE; + else + rxs->flag |= RX_FLAG_AMSDU_MORE; + + if (mon_skb == header) { + header = NULL; + rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN; + } else { + rxs->flag |= RX_FLAG_ALLOW_SAME_PN; + } + rxs->flag |= RX_FLAG_ONLY_MONITOR; + + status = IEEE80211_SKB_RXCB(mon_skb); + *status = *rxs; + + ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb); + mon_skb = skb_next; + } while (mon_skb && (mon_skb != tail_msdu)); + + return 0; + +mon_deliver_fail: + mon_skb = head_msdu; + while (mon_skb) { + skb_next = mon_skb->next; + dev_kfree_skb_any(mon_skb); + mon_skb = skb_next; + } + return -EINVAL; +} + +void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, u32 quota, + struct napi_struct *napi) +{ + struct ath11k_pdev_dp *dp = &ar->dp; + struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; + void *ring_entry; + void *mon_dst_srng; + u32 ppdu_id; + u32 rx_bufs_used; + struct ath11k_pdev_mon_stats *rx_mon_stats; + u32 npackets = 0; + + mon_dst_srng = &ar->ab->hal.srng_list[dp->rxdma_mon_dst_ring.ring_id]; + + if (!mon_dst_srng) { + ath11k_warn(ar->ab, + "HAL Monitor Destination Ring Init Failed -- %pK", + mon_dst_srng); + return; + } + + spin_lock_bh(&pmon->mon_lock); + + ath11k_hal_srng_access_begin(ar->ab, mon_dst_srng); + + ppdu_id = pmon->mon_ppdu_info.ppdu_id; + rx_bufs_used = 0; + rx_mon_stats = &pmon->rx_mon_stats; + + while ((ring_entry = ath11k_hal_srng_dst_peek(ar->ab, mon_dst_srng))) { + struct sk_buff *head_msdu, *tail_msdu; + + head_msdu = NULL; + tail_msdu = NULL; + + rx_bufs_used += ath11k_dp_rx_mon_mpdu_pop(ar, ring_entry, + &head_msdu, + &tail_msdu, + &npackets, &ppdu_id); + + if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) { + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + ath11k_dbg(ar->ab, ATH11K_DBG_DATA, + "dest_rx: new ppdu_id %x != status ppdu_id %x", + ppdu_id, pmon->mon_ppdu_info.ppdu_id); + break; + } + if (head_msdu && tail_msdu) { + ath11k_dp_rx_mon_deliver(ar, dp->mac_id, head_msdu, + tail_msdu, napi); + rx_mon_stats->dest_mpdu_done++; + } + + ring_entry = ath11k_hal_srng_dst_get_next_entry(ar->ab, + mon_dst_srng); + } + ath11k_hal_srng_access_end(ar->ab, mon_dst_srng); + + spin_unlock_bh(&pmon->mon_lock); + + if (rx_bufs_used) { + rx_mon_stats->dest_ppdu_done++; + ath11k_dp_rxbufs_replenish(ar->ab, dp->mac_id, + &dp->rxdma_mon_buf_ring, + rx_bufs_used, + HAL_RX_BUF_RBM_SW3_BM, GFP_ATOMIC); + } +} + +static inline void ath11k_dp_rx_mon_status_process_tlv(struct ath11k *ar, + u32 quota, + struct napi_struct *napi) +{ + struct ath11k_pdev_dp *dp = &ar->dp; + struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; + struct hal_rx_mon_ppdu_info *ppdu_info; + struct sk_buff *status_skb; + u8 *rx_tlv; + u8 *rx_tlv_start; + u32 tlv_status = HAL_TLV_STATUS_BUF_DONE; + struct ath11k_pdev_mon_stats *rx_mon_stats; + + ppdu_info = &pmon->mon_ppdu_info; + rx_mon_stats = &pmon->rx_mon_stats; + + if (pmon->mon_ppdu_status != DP_PPDU_STATUS_START) + return; + + while (!skb_queue_empty(&pmon->rx_status_q)) { + status_skb = skb_dequeue(&pmon->rx_status_q); + + rx_tlv = status_skb->data; + rx_tlv_start = rx_tlv; + + tlv_status = ath11k_hal_rx_parse_mon_status(ar->ab, ppdu_info, + rx_tlv); + if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) { + rx_mon_stats->status_ppdu_done++; + pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; + ath11k_dp_rx_mon_dest_process(ar, quota, napi); + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; + } + dev_kfree_skb_any(status_skb); + } +} + +int ath11k_dp_mon_process_rx(struct ath11k_base *ab, int mac_id, + struct napi_struct *napi, int budget) +{ + struct ath11k *ar = ab->pdevs[mac_id].ar; + struct ath11k_pdev_dp *dp = &ar->dp; + struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&dp->mon_data; + int num_buffs_reaped = 0; + + num_buffs_reaped = ath11k_dp_rx_reap_mon_status_ring(ar->ab, dp->mac_id, &budget, + &pmon->rx_status_q); + if (num_buffs_reaped) + ath11k_dp_rx_mon_status_process_tlv(ar, budget, napi); + + return num_buffs_reaped; +} + +int ath11k_dp_rx_process_mon_rings(struct ath11k_base *ab, int mac_id, + struct napi_struct *napi, int budget) +{ + struct ath11k *ar = ab->pdevs[mac_id].ar; + int ret = 0; + + if (test_bit(ATH11K_FLAG_MONITOR_ENABLED, &ar->monitor_flags)) + ret = ath11k_dp_mon_process_rx(ab, mac_id, napi, budget); + else + ret = ath11k_dp_rx_process_mon_status(ab, mac_id, napi, budget); + return ret; +} + int ath11k_dp_rx_pdev_mon_status_attach(struct ath11k *ar) { struct ath11k_pdev_dp *dp = &ar->dp;