From patchwork Fri May 28 11:38:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deren Wu X-Patchwork-Id: 12286853 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5DD2C47087 for ; Fri, 28 May 2021 12:03:30 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3544F61176 for ; Fri, 28 May 2021 12:03:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3544F61176 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:CC :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=pmYXOgaqfZTnoMZuod6Hb5kLpDQ5nQRu7ZCSFYD3+k4=; b=ztWDOOYrXWgM05 QOQK1Z2w+EQg/sDrKhd4Rk+fYgyzi9MjXNl3BwUyA+JbziR+y21OE0+qEDvwnivXNv6pcbjOYo4mr yarA06GHoH43t8cVKwth5PKGbvwy/50kFR4uIaGIfvTKOvbP/6F+DLPxO3PcUcRUuCQQuuaxlLHQF Jf2QH0Fx45qAo6pn9KyeCHcRa3Ye33nD0ZQVcyc6wpv7MmaHfrOV6I9/VlQAfy5fK21K0u/nnD75D SaSGvD823RpyFwFXjAwhBGY2KPyjF7CBYoOuJLVzEeaWypo3EQc26cK8sBA4dfjQFGfyswn4XrZiu xcdd7Ns7bQ0mPwyoZuwA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1lmbCu-00FB8F-VD; Fri, 28 May 2021 12:03:16 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1lmap9-00Ew8b-DT for linux-mediatek@lists.infradead.org; Fri, 28 May 2021 11:38:46 +0000 X-UUID: 1bc98f0928f4438596db738c8c87ab57-20210528 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=NLrA2YLOW9BJrH14y7rtmuihBx5aJy3xXxUcVNK7S20=; b=e6QgDIkzKfdVEvn8STHUrZEDrJKluuUsYYYpDXUM/uGlGsm8Tlz4+YxZxRRBqjtTJErVB7XfCWjm2Ym2pbwt2M14u3hMSV9GFCjtR1d3LMsNWvO1Uuy4kwCP0Ji1uBnzeox+SnQENlyX7ghOt0lTqkZRdiLgoXDWmgAzkiKxHLk=; X-UUID: 1bc98f0928f4438596db738c8c87ab57-20210528 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 536345684; Fri, 28 May 2021 04:38:38 -0700 Received: from MTKMBS01N2.mediatek.inc (172.21.101.79) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 28 May 2021 04:38:36 -0700 Received: from mtkcas10.mediatek.inc (172.21.101.39) by mtkmbs01n2.mediatek.inc (172.21.101.79) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 28 May 2021 19:38:34 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas10.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 28 May 2021 19:38:35 +0800 From: Deren Wu To: Felix Fietkau , Lorenzo Bianconi CC: Sean Wang , Soul Huang , YN Chen , Leon Yen , "Eric-SY Chang" , Deren Wu , KM Lin , Robin Chiu , CH Yeh , Posh Sun , Eric Liang , Stella Chang , , , linux-wireless , linux-mediatek , Deren Wu Subject: [PATCH] mt76: mt7921: introduce mac tx done handling Date: Fri, 28 May 2021 19:38:09 +0800 Message-ID: X-Mailer: git-send-email 2.18.0 MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210528_043844_918366_68077BA8 X-CRM114-Status: GOOD ( 14.78 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Deren Wu Instead of read tx status from mac table, add new mechanisam to hanele tx done event for data frame, every 250ms This event indicate the real tx status of this pkt in mac layer and would help mac80211 correct status more frequently Signed-off-by: Deren Wu --- .../net/wireless/mediatek/mt76/mt7921/mac.c | 69 +++++++++++-------- .../net/wireless/mediatek/mt76/mt7921/mcu.c | 47 +++++++++++++ .../net/wireless/mediatek/mt76/mt7921/mcu.h | 28 ++++++++ .../wireless/mediatek/mt76/mt7921/mt7921.h | 2 + 4 files changed, 117 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index 212832b34674..9366d779cbc7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -13,6 +13,36 @@ #define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\ IEEE80211_RADIOTAP_HE_##f) +static u8 +mt7921_next_pid(struct mt7921_dev *dev, struct mt76_wcid *wcid) +{ + wcid->packet_id = (wcid->packet_id + 1) & MT_PACKET_ID_MASK; + if (wcid->packet_id == MT_PACKET_ID_NO_ACK || + wcid->packet_id == MT_PACKET_ID_NO_SKB) + wcid->packet_id = MT_PACKET_ID_FIRST; + return wcid->packet_id; +} + +unsigned long +mt7921_next_txs_set(struct mt7921_dev *dev, struct mt76_wcid *wcid, + u32 timeout) +{ + struct mt7921_sta *msta; + + msta = container_of(wcid, struct mt7921_sta, wcid); + msta->next_txs_ts = jiffies + msecs_to_jiffies(timeout); + return msta->next_txs_ts; +} + +bool +mt7921_next_txs_timeout(struct mt7921_dev *dev, struct mt76_wcid *wcid) +{ + struct mt7921_sta *msta; + + msta = container_of(wcid, struct mt7921_sta, wcid); + return time_is_before_jiffies(msta->next_txs_ts); +} + static struct mt76_wcid *mt7921_rx_get_wcid(struct mt7921_dev *dev, u16 idx, bool unicast) { @@ -726,7 +756,7 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_vif *vif = info->control.vif; struct mt76_phy *mphy = &dev->mphy; - u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0; + u8 pid, p_fmt, q_idx, omac_idx = 0, wmm_idx = 0; bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; u16 tx_count = 15; u32 val; @@ -795,6 +825,15 @@ void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, txwi[6] |= cpu_to_le32(val); txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); } + + if ((FIELD_GET(MT_TXD2_FRAME_TYPE, txwi[2]) & + (IEEE80211_FTYPE_DATA >> 2)) && + mt7921_next_txs_timeout(dev, wcid)) { + mt7921_next_txs_set(dev, wcid, 250); + pid = mt7921_next_pid(dev, wcid); + val = MT_TXD5_TX_STATUS_MCU | FIELD_PREP(MT_TXD5_PID, pid); + txwi[5] |= cpu_to_le32(val); + } } static void @@ -1380,30 +1419,6 @@ mt7921_mac_update_mib_stats(struct mt7921_phy *phy) } } -static void -mt7921_mac_sta_stats_work(struct mt7921_phy *phy) -{ - struct mt7921_dev *dev = phy->dev; - struct mt7921_sta *msta; - LIST_HEAD(list); - - spin_lock_bh(&dev->sta_poll_lock); - list_splice_init(&phy->stats_list, &list); - - while (!list_empty(&list)) { - msta = list_first_entry(&list, struct mt7921_sta, stats_list); - list_del_init(&msta->stats_list); - spin_unlock_bh(&dev->sta_poll_lock); - - /* query wtbl info to report tx rate for further devices */ - mt7921_get_wtbl_info(dev, msta->wcid.idx); - - spin_lock_bh(&dev->sta_poll_lock); - } - - spin_unlock_bh(&dev->sta_poll_lock); -} - void mt7921_mac_work(struct work_struct *work) { struct mt7921_phy *phy; @@ -1421,10 +1436,6 @@ void mt7921_mac_work(struct work_struct *work) mt7921_mac_update_mib_stats(phy); } - if (++phy->sta_work_count == 4) { - phy->sta_work_count = 0; - mt7921_mac_sta_stats_work(phy); - } mt7921_mutex_release(phy->dev); ieee80211_queue_delayed_work(phy->mt76->hw, &mphy->mac_work, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 5a4c695f73c9..e8cd767ea475 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -531,6 +531,49 @@ mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb) trace_lp_event(dev, event->state); } +static void +mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb) +{ + struct mt7921_mcu_tx_done_event *event; + struct mt7921_sta *msta; + struct mt7921_phy *mphy = &dev->phy; + struct mt7921_mcu_peer_cap peer; + struct ieee80211_sta *sta; + LIST_HEAD(list); + + skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + event = (struct mt7921_mcu_tx_done_event *)skb->data; + + spin_lock_bh(&dev->sta_poll_lock); + list_splice_init(&mphy->stats_list, &list); + + while (!list_empty(&list)) { + msta = list_first_entry(&list, struct mt7921_sta, stats_list); + list_del_init(&msta->stats_list); + + if (msta->wcid.idx != event->wlan_idx) + continue; + + spin_unlock_bh(&dev->sta_poll_lock); + + sta = wcid_to_sta(&msta->wcid); + + /* peer config based on IEEE SPEC */ + memset(&peer, 0x0, sizeof(peer)); + peer.bw = event->bw; + peer.g2 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20); + peer.g4 = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40); + peer.g8 = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80); + peer.g16 = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160); + mt7921_mcu_tx_rate_parse(mphy->mt76, &peer, + &msta->stats.tx_rate, event->tx_rate); + + spin_lock_bh(&dev->sta_poll_lock); + break; + } + spin_unlock_bh(&dev->sta_poll_lock); +} + static void mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb) { @@ -557,6 +600,9 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb) case MCU_EVENT_LP_INFO: mt7921_mcu_low_power_event(dev, skb); break; + case MCU_EVENT_TX_DONE: + mt7921_mcu_tx_done_event(dev, skb); + break; default: break; } @@ -577,6 +623,7 @@ void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb) rxd->eid == MCU_EVENT_SCHED_SCAN_DONE || rxd->eid == MCU_EVENT_BSS_ABSENCE || rxd->eid == MCU_EVENT_SCAN_DONE || + rxd->eid == MCU_EVENT_TX_DONE || rxd->eid == MCU_EVENT_DBG_MSG || rxd->eid == MCU_EVENT_COREDUMP || rxd->eid == MCU_EVENT_LP_INFO || diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h index 49823d0a3d0a..22ebef4add00 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h @@ -81,6 +81,7 @@ enum { MCU_EVENT_REG_ACCESS = 0x05, MCU_EVENT_LP_INFO = 0x07, MCU_EVENT_SCAN_DONE = 0x0d, + MCU_EVENT_TX_DONE = 0x0f, MCU_EVENT_BSS_ABSENCE = 0x11, MCU_EVENT_BSS_BEACON_LOSS = 0x13, MCU_EVENT_CH_PRIVILEGE = 0x18, @@ -407,4 +408,31 @@ struct mt7921_txpwr_event { struct mt7921_txpwr txpwr; } __packed; +struct mt7921_mcu_tx_done_event { + u8 pid; + u8 status; + u16 seq; + + u8 wlan_idx; + u8 tx_cnt; + u16 tx_rate; + + u8 flag; + u8 tid; + u8 rsp_rate; + u8 mcs; + + u8 bw; + u8 tx_pwr; + u8 reason; + u8 rsv0[1]; + + u32 delay; + u32 timestamp; + u32 applied_flag; + + u8 txs[28]; + + u8 rsv1[32]; +} __packed; #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 59862ea4951c..a1e4276273d8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -92,6 +92,8 @@ struct mt7921_sta { unsigned long ampdu_state; struct mt7921_sta_key_conf bip; + + unsigned long next_txs_ts; }; DECLARE_EWMA(rssi, 10, 8);