From 2cb002e3c29434b0159a3a4d343d460264dae2ac Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Tue, 2 Jun 2020 22:26:38 +0200 Subject: mt76: add missing lock configuring coverage class Coverage class callback can potentially run in parallel with other routines (e.g. mt7615_set_channel) that configures timing registers. Run coverage class callback holding mt76 mutex Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7603/main.c | 2 ++ drivers/net/wireless/mediatek/mt76/mt7615/main.c | 3 +++ drivers/net/wireless/mediatek/mt76/mt7915/main.c | 3 +++ 3 files changed, 8 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c index 26cb711b465f..83dfa6da4761 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c @@ -642,8 +642,10 @@ mt7603_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) { struct mt7603_dev *dev = hw->priv; + mutex_lock(&dev->mt76.mutex); dev->coverage_class = max_t(s16, coverage_class, 0); mt7603_mac_set_timing(dev); + mutex_unlock(&dev->mt76.mutex); } static void mt7603_tx(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index c26f99b368d9..52d6544698fe 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -735,9 +735,12 @@ static void mt7615_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) { struct mt7615_phy *phy = mt7615_hw_phy(hw); + struct mt7615_dev *dev = phy->dev; + mutex_lock(&dev->mt76.mutex); phy->coverage_class = max_t(s16, coverage_class, 0); mt7615_mac_set_timing(phy); + mutex_unlock(&dev->mt76.mutex); } static int diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 0575c259f245..05b5650c56c8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -716,9 +716,12 @@ static void mt7915_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) { struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct mt7915_dev *dev = phy->dev; + mutex_lock(&dev->mt76.mutex); phy->coverage_class = max_t(s16, coverage_class, 0); mt7915_mac_set_timing(phy); + mutex_unlock(&dev->mt76.mutex); } static int -- cgit v1.2.3 From 8fc49625a33ad070013773b923fb945340000e37 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 30 May 2020 23:51:27 +0200 Subject: mt76: mt7615: fix lmac queue debugsfs entry acs and wmm index are swapped in mt7615_queues_acq respect to the hw design Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c index fd3ef483a87c..d06afcf46d67 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c @@ -234,10 +234,11 @@ mt7615_queues_acq(struct seq_file *s, void *data) int i; for (i = 0; i < 16; i++) { - int j, acs = i / 4, index = i % 4; + int j, wmm_idx = i % MT7615_MAX_WMM_SETS; + int acs = i / MT7615_MAX_WMM_SETS; u32 ctrl, val, qlen = 0; - val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, index)); + val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, wmm_idx)); ctrl = BIT(31) | BIT(15) | (acs << 8); for (j = 0; j < 32; j++) { @@ -245,11 +246,11 @@ mt7615_queues_acq(struct seq_file *s, void *data) continue; mt76_wr(dev, MT_PLE_FL_Q0_CTRL, - ctrl | (j + (index << 5))); + ctrl | (j + (wmm_idx << 5))); qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL, GENMASK(11, 0)); } - seq_printf(s, "AC%d%d: queued=%d\n", acs, index, qlen); + seq_printf(s, "AC%d%d: queued=%d\n", wmm_idx, acs, qlen); } return 0; -- cgit v1.2.3 From 1fec635bcc9e14604f06d0947725fd3c613e1af0 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sun, 31 May 2020 00:32:04 +0200 Subject: mt76: mt7615: fix hw queue mapping mt7622/mt7663 chipsets rely on a fixed reverse queue map order respect to mac80211 one: - q(0): IEEE80211_AC_BK - q(1): IEEE80211_AC_BE - q(2): IEEE80211_AC_VI - q(3): IEEE80211_AC_VO Fixes: cdad4874057d ("mt76: mt7615: add dma and tx queue initialization for MT7622") Fixes: f40ac0f3d3c0 ("mt76: mt7615: introduce mt7663e support") Co-developed-by: Sean Wang Signed-off-by: Sean Wang Co-developed-by: Ryder Lee Signed-off-by: Ryder Lee Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7615/dma.c | 8 +++--- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7615/mac.h | 15 ----------- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 1 + drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 30 ++++++++++++++++++++++ drivers/net/wireless/mediatek/mt76/usb.c | 17 ++++++------ 6 files changed, 45 insertions(+), 28 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c index 5a124610d4af..83fdcf5db3c7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c @@ -36,10 +36,10 @@ static int mt7622_init_tx_queues_multi(struct mt7615_dev *dev) { static const u8 wmm_queue_map[] = { - MT7622_TXQ_AC0, - MT7622_TXQ_AC1, - MT7622_TXQ_AC2, - MT7622_TXQ_AC3, + [IEEE80211_AC_BK] = MT7622_TXQ_AC0, + [IEEE80211_AC_BE] = MT7622_TXQ_AC1, + [IEEE80211_AC_VI] = MT7622_TXQ_AC2, + [IEEE80211_AC_VO] = MT7622_TXQ_AC3, }; int ret; int i; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index 9f1c6ca7a665..5990355bc731 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -528,7 +528,7 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, if (ieee80211_is_data(fc) || ieee80211_is_bufferable_mmpdu(fc)) { q_idx = wmm_idx * MT7615_MAX_WMM_SETS + - skb_get_queue_mapping(skb); + mt7615_lmac_mapping(dev, skb_get_queue_mapping(skb)); p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT; } else if (beacon) { if (ext_phy) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.h b/drivers/net/wireless/mediatek/mt76/mt7615/mac.h index f0d4b29a52a2..81608ab656b8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.h @@ -124,21 +124,6 @@ enum tx_pkt_type { MT_TX_TYPE_FW, }; -enum tx_pkt_queue_idx { - MT_LMAC_AC00, - MT_LMAC_AC01, - MT_LMAC_AC02, - MT_LMAC_AC03, - MT_LMAC_ALTX0 = 0x10, - MT_LMAC_BMC0, - MT_LMAC_BCN0, - MT_LMAC_PSMP0, - MT_LMAC_ALTX1, - MT_LMAC_BMC1, - MT_LMAC_BCN1, - MT_LMAC_PSMP1, -}; - enum tx_port_idx { MT_TX_PORT_IDX_LMAC, MT_TX_PORT_IDX_MCU diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index 52d6544698fe..beaca8127680 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -397,6 +397,7 @@ mt7615_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; struct mt7615_dev *dev = mt7615_hw_dev(hw); + queue = mt7615_lmac_mapping(dev, queue); queue += mvif->wmm_idx * MT7615_MAX_WMM_SETS; return mt7615_mcu_set_wmm(dev, queue, params); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h index d6176d316bee..3e7d51bf42a4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h @@ -282,6 +282,21 @@ struct mt7615_dev { struct list_head wd_head; }; +enum tx_pkt_queue_idx { + MT_LMAC_AC00, + MT_LMAC_AC01, + MT_LMAC_AC02, + MT_LMAC_AC03, + MT_LMAC_ALTX0 = 0x10, + MT_LMAC_BMC0, + MT_LMAC_BCN0, + MT_LMAC_PSMP0, + MT_LMAC_ALTX1, + MT_LMAC_BMC1, + MT_LMAC_BCN1, + MT_LMAC_PSMP1, +}; + enum { HW_BSSID_0 = 0x0, HW_BSSID_1, @@ -447,6 +462,21 @@ static inline u16 mt7615_wtbl_size(struct mt7615_dev *dev) return MT7615_WTBL_SIZE; } +static inline u8 mt7615_lmac_mapping(struct mt7615_dev *dev, u8 ac) +{ + static const u8 lmac_queue_map[] = { + [IEEE80211_AC_BK] = MT_LMAC_AC00, + [IEEE80211_AC_BE] = MT_LMAC_AC01, + [IEEE80211_AC_VI] = MT_LMAC_AC02, + [IEEE80211_AC_VO] = MT_LMAC_AC03, + }; + + if (WARN_ON_ONCE(ac >= ARRAY_SIZE(lmac_queue_map))) + return MT_LMAC_AC01; /* BE */ + + return lmac_queue_map[ac]; +} + void mt7615_dma_reset(struct mt7615_dev *dev); void mt7615_scan_work(struct work_struct *work); void mt7615_roc_work(struct work_struct *work); diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index fb97ea25b4d4..27abcdb61a06 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -1010,17 +1010,18 @@ static void mt76u_tx_kick(struct mt76_dev *dev, struct mt76_queue *q) static u8 mt76u_ac_to_hwq(struct mt76_dev *dev, u8 ac) { if (mt76_chip(dev) == 0x7663) { - static const u8 wmm_queue_map[] = { - [IEEE80211_AC_VO] = 0, - [IEEE80211_AC_VI] = 1, - [IEEE80211_AC_BE] = 2, - [IEEE80211_AC_BK] = 4, + static const u8 lmac_queue_map[] = { + /* ac to lmac mapping */ + [IEEE80211_AC_BK] = 0, + [IEEE80211_AC_BE] = 1, + [IEEE80211_AC_VI] = 2, + [IEEE80211_AC_VO] = 4, }; - if (WARN_ON(ac >= ARRAY_SIZE(wmm_queue_map))) - return 2; /* BE */ + if (WARN_ON(ac >= ARRAY_SIZE(lmac_queue_map))) + return 1; /* BE */ - return wmm_queue_map[ac]; + return lmac_queue_map[ac]; } return mt76_ac_to_hwq(ac); -- cgit v1.2.3 From d3c829985234450c0278e4fad994b70c8376c3b6 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Mon, 1 Jun 2020 09:45:33 +0200 Subject: mt76: overwrite qid for non-bufferable mgmt frames Overwrite hw queue id for non-bufferable management frames if the hw support always txq (altxq) in order to be in sync with mac txwi code Fixes: cdad4874057d ("mt76: mt7615: add dma and tx queue initialization for MT7622") Fixes: f40ac0f3d3c0 ("mt76: mt7615: introduce mt7663e support") Suggested-by: Felix Fietkau Tested-by: Sean Wang Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + drivers/net/wireless/mediatek/mt76/mt7615/dma.c | 1 + drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 20 +++++++------------- drivers/net/wireless/mediatek/mt76/mt7615/mmio.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7615/usb.c | 2 +- drivers/net/wireless/mediatek/mt76/tx.c | 7 +++++++ 6 files changed, 18 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index dfe625a53c63..3d7db6ffb599 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -301,6 +301,7 @@ struct mt76_hw_cap { #define MT_DRV_TX_ALIGNED4_SKBS BIT(1) #define MT_DRV_SW_RX_AIRTIME BIT(2) #define MT_DRV_RX_DMA_HDR BIT(3) +#define MT_DRV_HW_MGMT_TXQ BIT(4) struct mt76_driver_ops { u32 drv_flags; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c index 83fdcf5db3c7..e5a965df899a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c @@ -100,6 +100,7 @@ mt7615_tx_cleanup(struct mt7615_dev *dev) int i; mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false); + mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false); if (is_mt7615(&dev->mt76)) { mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false); } else { diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index 5990355bc731..d97315ec7265 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -526,22 +526,16 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2; fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4; - if (ieee80211_is_data(fc) || ieee80211_is_bufferable_mmpdu(fc)) { - q_idx = wmm_idx * MT7615_MAX_WMM_SETS + - mt7615_lmac_mapping(dev, skb_get_queue_mapping(skb)); - p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT; - } else if (beacon) { - if (ext_phy) - q_idx = MT_LMAC_BCN1; - else - q_idx = MT_LMAC_BCN0; + if (beacon) { p_fmt = MT_TX_TYPE_FW; + q_idx = ext_phy ? MT_LMAC_BCN1 : MT_LMAC_BCN0; + } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { + p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT; + q_idx = ext_phy ? MT_LMAC_ALTX1 : MT_LMAC_ALTX0; } else { - if (ext_phy) - q_idx = MT_LMAC_ALTX1; - else - q_idx = MT_LMAC_ALTX0; p_fmt = is_usb ? MT_TX_TYPE_SF : MT_TX_TYPE_CT; + q_idx = wmm_idx * MT7615_MAX_WMM_SETS + + mt7615_lmac_mapping(dev, skb_get_queue_mapping(skb)); } val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c index e670393506f0..2e99845b9c96 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mmio.c @@ -146,7 +146,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base, static const struct mt76_driver_ops drv_ops = { /* txwi_size = txd size + txp size */ .txwi_size = MT_TXD_SIZE + sizeof(struct mt7615_txp_common), - .drv_flags = MT_DRV_TXWI_NO_FREE, + .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ, .survey_flags = SURVEY_INFO_TIME_TX | SURVEY_INFO_TIME_RX | SURVEY_INFO_TIME_BSS_RX, diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c index a50077eb24d7..f5dc1b828518 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/usb.c @@ -270,7 +270,7 @@ static int mt7663u_probe(struct usb_interface *usb_intf, { static const struct mt76_driver_ops drv_ops = { .txwi_size = MT_USB_TXD_SIZE, - .drv_flags = MT_DRV_RX_DMA_HDR, + .drv_flags = MT_DRV_RX_DMA_HDR | MT_DRV_HW_MGMT_TXQ, .tx_prepare_skb = mt7663u_tx_prepare_skb, .tx_complete_skb = mt7663u_tx_complete_skb, .tx_status_data = mt7663u_tx_status_data, diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index fca38ea2441f..f10c98aa883c 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -264,6 +264,13 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, skb_set_queue_mapping(skb, qid); } + if ((dev->drv->drv_flags & MT_DRV_HW_MGMT_TXQ) && + !ieee80211_is_data(hdr->frame_control) && + !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) { + qid = MT_TXQ_PSD; + skb_set_queue_mapping(skb, qid); + } + if (!(wcid->tx_info & MT_WCID_TX_INFO_SET)) ieee80211_get_tx_rates(info->control.vif, sta, skb, info->control.rates, 1); -- cgit v1.2.3 From a28bef561a5c144e7c6237626d748767fef7fc79 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 30 May 2020 17:19:45 +0200 Subject: mt76: mt7615: re-enable offloading of sequence number assignment Preparation for supporting more offload features Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 44 +++++++++++++++++----- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 5 +++ drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 1 + 3 files changed, 41 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index d97315ec7265..d150fac50c00 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -617,16 +617,19 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, } val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count); - if (ieee80211_is_data_qos(hdr->frame_control)) { - seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); - val |= MT_TXD3_SN_VALID; - } else if (ieee80211_is_back_req(hdr->frame_control)) { - struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; - - seqno = IEEE80211_SEQ_TO_SN(le16_to_cpu(bar->start_seq_num)); - val |= MT_TXD3_SN_VALID; + if (info->flags & IEEE80211_TX_CTL_INJECTED) { + seqno = le16_to_cpu(hdr->seq_ctrl); + + if (ieee80211_is_back_req(hdr->frame_control)) { + struct ieee80211_bar *bar; + + bar = (struct ieee80211_bar *)skb->data; + seqno = le16_to_cpu(bar->start_seq_num); + } + + val |= MT_TXD3_SN_VALID | + FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno)); } - val |= FIELD_PREP(MT_TXD3_SEQ, seqno); txwi[3] |= cpu_to_le32(val); @@ -893,6 +896,29 @@ mt7615_mac_queue_rate_update(struct mt7615_phy *phy, struct mt7615_sta *sta, return 0; } +u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid) +{ + u32 addr, val, val2; + u8 offset; + + addr = mt7615_mac_wtbl_addr(dev, wcid) + 11 * 4; + + offset = tid * 12; + addr += 4 * (offset / 32); + offset %= 32; + + val = mt76_rr(dev, addr); + val >>= (tid % 32); + + if (offset > 20) { + addr += 4; + val2 = mt76_rr(dev, addr); + val |= val2 << (32 - offset); + } + + return val & GENMASK(11, 0); +} + void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta, struct ieee80211_tx_rate *probe_rate, struct ieee80211_tx_rate *rates) diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index beaca8127680..dfebf86b86d6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -660,6 +660,9 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mtxq->aggr = true; mtxq->send_bar = false; mt7615_mcu_add_tx_ba(dev, params, true); + ssn = mt7615_mac_get_sta_tid_sn(dev, msta->wcid.idx, tid); + ieee80211_send_bar(vif, sta->addr, tid, + IEEE80211_SN_TO_SEQ(ssn)); break; case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: @@ -667,6 +670,8 @@ mt7615_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mt7615_mcu_add_tx_ba(dev, params, false); break; case IEEE80211_AMPDU_TX_START: + ssn = mt7615_mac_get_sta_tid_sn(dev, msta->wcid.idx, tid); + params->ssn = ssn; mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn); ret = IEEE80211_AMPDU_TX_START_IMMEDIATE; break; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h index 3e7d51bf42a4..640ff8b9b266 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h @@ -516,6 +516,7 @@ int mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, enum mt7615_cipher_type cipher, enum set_key_cmd cmd); void mt7615_mac_reset_work(struct work_struct *work); +u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid); int mt7615_mcu_wait_response(struct mt7615_dev *dev, int cmd, int seq); int mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data, -- cgit v1.2.3 From be49c5356f3923015ef7ace59c71be3013d18608 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Sat, 30 May 2020 23:48:56 +0200 Subject: mt76: usb: rely on mt76_for_each_q_rx Rely on mt76_for_each_q_rx whenever possible in order to simply the code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/debugfs.c | 3 -- drivers/net/wireless/mediatek/mt76/usb.c | 41 ++++++++-------------------- 2 files changed, 12 insertions(+), 32 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c index 3a5de1d1b121..9fda65db8cac 100644 --- a/drivers/net/wireless/mediatek/mt76/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c @@ -54,9 +54,6 @@ static int mt76_rx_queues_read(struct seq_file *s, void *data) mt76_for_each_q_rx(dev, i) { struct mt76_queue *q = &dev->q_rx[i]; - if (!q->ndesc) - continue; - queued = mt76_is_usb(dev) ? q->ndesc - q->queued : q->queued; seq_printf(s, "%d: queued=%d head=%d tail=%d\n", i, queued, q->head, q->tail); diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c index 27abcdb61a06..0ff3096f7455 100644 --- a/drivers/net/wireless/mediatek/mt76/usb.c +++ b/drivers/net/wireless/mediatek/mt76/usb.c @@ -672,17 +672,11 @@ mt76u_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) static void mt76u_rx_tasklet(unsigned long data) { struct mt76_dev *dev = (struct mt76_dev *)data; - struct mt76_queue *q; int i; rcu_read_lock(); - for (i = 0; i < __MT_RXQ_MAX; i++) { - q = &dev->q_rx[i]; - if (!q->ndesc) - continue; - - mt76u_process_rx_queue(dev, q); - } + mt76_for_each_q_rx(dev, i) + mt76u_process_rx_queue(dev, &dev->q_rx[i]); rcu_read_unlock(); } @@ -756,27 +750,19 @@ mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) static void mt76u_free_rx(struct mt76_dev *dev) { - struct mt76_queue *q; int i; - for (i = 0; i < __MT_RXQ_MAX; i++) { - q = &dev->q_rx[i]; - if (!q->ndesc) - continue; - - mt76u_free_rx_queue(dev, q); - } + mt76_for_each_q_rx(dev, i) + mt76u_free_rx_queue(dev, &dev->q_rx[i]); } void mt76u_stop_rx(struct mt76_dev *dev) { - struct mt76_queue *q; - int i, j; + int i; - for (i = 0; i < __MT_RXQ_MAX; i++) { - q = &dev->q_rx[i]; - if (!q->ndesc) - continue; + mt76_for_each_q_rx(dev, i) { + struct mt76_queue *q = &dev->q_rx[i]; + int j; for (j = 0; j < q->ndesc; j++) usb_poison_urb(q->entry[j].urb); @@ -788,14 +774,11 @@ EXPORT_SYMBOL_GPL(mt76u_stop_rx); int mt76u_resume_rx(struct mt76_dev *dev) { - struct mt76_queue *q; - int i, j, err; - - for (i = 0; i < __MT_RXQ_MAX; i++) { - q = &dev->q_rx[i]; + int i; - if (!q->ndesc) - continue; + mt76_for_each_q_rx(dev, i) { + struct mt76_queue *q = &dev->q_rx[i]; + int err, j; for (j = 0; j < q->ndesc; j++) usb_unpoison_urb(q->entry[j].urb); -- cgit v1.2.3 From 73741b9bee690ffd7c22e25c419b9f7979afadeb Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Sun, 7 Jun 2020 11:34:40 +0200 Subject: mt76: mt7663: introduce ARP filter offload Introduce ARP filter offload Co-developed-by: Wan-Feng Jiang Signed-off-by: Wan-Feng Jiang Co-developed-by: Soul Huang Signed-off-by: Soul Huang Co-developed-by: Lorenzo Bianconi Signed-off-by: Lorenzo Bianconi Signed-off-by: Sean Wang Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 3 + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 74 ++++++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt7615/mcu.h | 13 +++- drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 4 +- 4 files changed, 91 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index dfebf86b86d6..e6dbd7034bd7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -491,6 +491,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_PS) mt7615_mcu_set_vif_ps(dev, vif); + if (changed & BSS_CHANGED_ARP_FILTER) + mt7615_mcu_update_arp_filter(hw, vif, info); + mutex_unlock(&dev->mt76.mutex); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index 6e869b8c5e26..b76ecc24f333 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -3542,6 +3542,32 @@ mt7615_mcu_set_gtk_rekey(struct mt7615_dev *dev, &req, sizeof(req), true); } +static int +mt7615_mcu_set_arp_filter(struct mt7615_dev *dev, struct ieee80211_vif *vif, + bool suspend) +{ + struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; + struct { + struct { + u8 bss_idx; + u8 pad[3]; + } __packed hdr; + struct mt7615_arpns_tlv arpns; + } req = { + .hdr = { + .bss_idx = mvif->idx, + }, + .arpns = { + .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP), + .len = cpu_to_le16(sizeof(struct mt7615_arpns_tlv)), + .mode = suspend, + }, + }; + + return __mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_OFFLOAD, + &req, sizeof(req), true); +} + void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { @@ -3554,6 +3580,7 @@ void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac, mt7615_mcu_set_bss_pm(phy->dev, vif, suspend); mt7615_mcu_set_gtk_rekey(phy->dev, vif, suspend); + mt7615_mcu_set_arp_filter(phy->dev, vif, suspend); mt7615_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true); @@ -3653,6 +3680,53 @@ int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif, sizeof(req), false); } +int mt7615_mcu_update_arp_filter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info) +{ + struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; + struct mt7615_dev *dev = mt7615_hw_dev(hw); + struct sk_buff *skb; + int i, len = min_t(int, info->arp_addr_cnt, + IEEE80211_BSS_ARP_ADDR_LIST_LEN); + struct { + struct { + u8 bss_idx; + u8 pad[3]; + } __packed hdr; + struct mt7615_arpns_tlv arp; + } req_hdr = { + .hdr = { + .bss_idx = mvif->idx, + }, + .arp = { + .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP), + .len = cpu_to_le16(sizeof(struct mt7615_arpns_tlv)), + .ips_num = len, + .mode = 2, /* update */ + .option = 1, + }, + }; + + if (!mt7615_firmware_offload(dev)) + return 0; + + skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, + sizeof(req_hdr) + len * sizeof(__be32)); + if (!skb) + return -ENOMEM; + + skb_put_data(skb, &req_hdr, sizeof(req_hdr)); + for (i = 0; i < len; i++) { + u8 *addr = (u8 *)skb_put(skb, sizeof(__be32)); + + memcpy(addr, &info->arp_addr_list[i], sizeof(__be32)); + } + + return __mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_UNI_CMD_OFFLOAD, true); +} + int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h index 2314d0b23af1..64f7471a57bb 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h @@ -545,6 +545,15 @@ struct mt7615_roc_tlv { u8 rsv1[8]; } __packed; +struct mt7615_arpns_tlv { + __le16 tag; + __le16 len; + u8 mode; + u8 ips_num; + u8 option; + u8 pad[1]; +} __packed; + /* offload mcu commands */ enum { MCU_CMD_START_HW_SCAN = MCU_CE_PREFIX | 0x03, @@ -580,8 +589,8 @@ enum { }; enum { - UNI_OFFLOAD_OFFLOAD_ARPNS_IPV4, - UNI_OFFLOAD_OFFLOAD_ARPNS_IPV6, + UNI_OFFLOAD_OFFLOAD_ARP, + UNI_OFFLOAD_OFFLOAD_ND, UNI_OFFLOAD_OFFLOAD_GTK_REKEY, UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT, }; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h index 640ff8b9b266..913dac5c3006 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h @@ -586,7 +586,9 @@ void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac, int mt7615_mcu_update_gtk_rekey(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_gtk_rekey_data *key); - +int mt7615_mcu_update_arp_filter(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *info); int __mt7663_load_firmware(struct mt7615_dev *dev); /* usb */ -- cgit v1.2.3 From 642023d04335458a057b549da329ee4e30c8a838 Mon Sep 17 00:00:00 2001 From: Sean Wang Date: Tue, 9 Jun 2020 23:42:21 +0800 Subject: mt76: mt7615: fix up typo in Kconfig for MT7663U Fix up typo in Kconfig with indicating MT7663U is an 802.11ac device Fixes: eb99cc95c3b6 ("mt76: mt7615: introduce mt7663u support") Signed-off-by: Sean Wang Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7615/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/Kconfig b/drivers/net/wireless/mediatek/mt76/mt7615/Kconfig index e25db1135eda..c094260b0f89 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/Kconfig +++ b/drivers/net/wireless/mediatek/mt76/mt7615/Kconfig @@ -35,6 +35,6 @@ config MT7663U depends on MAC80211 depends on USB help - This adds support for MT7663U 802.11ax 2x2:2 wireless devices. + This adds support for MT7663U 802.11ac 2x2:2 wireless devices. To compile this driver as a module, choose M here. -- cgit v1.2.3 From 9da82fb76d6cea157e31bf0c247d2b4c6883cead Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Thu, 11 Jun 2020 14:40:22 +0200 Subject: mt76: allow more channels, allowed in ETSI domain While looking at the ETSI regulatory domain definitions and a patch, which allows more channels for ath10k, I also checked the channels allowed for mt76. ETSI regulations would possibly allow to add channels 32, 68, 96, 144, 169 and 173. IEEE 802.11-2016 defines no operating class for channels 32, 68 and 96. This leaves us channels 144, 169 and 173, which are included in this patch. I tested 169 and 173 with a mt76 based USB dongle (AVM AC 860) and they worked fine. If I saw that right, these channels are also covered by register definitions inside the driver. Channel 144 should also work, but gets disabled by the kernel as of now. Signed-off-by: Markus Theil Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 907098101898..4c10c8164aee 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -58,12 +58,15 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = { CHAN5G(132, 5660), CHAN5G(136, 5680), CHAN5G(140, 5700), + CHAN5G(144, 5720), CHAN5G(149, 5745), CHAN5G(153, 5765), CHAN5G(157, 5785), CHAN5G(161, 5805), CHAN5G(165, 5825), + CHAN5G(169, 5845), + CHAN5G(173, 5865), }; static const struct ieee80211_tpt_blink mt76_tpt_blink[] = { -- cgit v1.2.3 From e39da597e5782a5fcdad0c23dee61dbe05d327b8 Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Fri, 12 Jun 2020 10:05:23 +0200 Subject: mt76: fix include in pci.h kernel test robot found the following issue and Kalle Valo forwarded it to Linux wireless. drivers/net/wireless/mediatek/mt76/pci.c:8:6: warning: no previous prototype for 'mt76_pci_disable_aspm' Fix this by adding the missing include of mt76.h as Kalle suggested. Signed-off-by: Markus Theil Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/pci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/pci.c b/drivers/net/wireless/mediatek/mt76/pci.c index 04c5a692bc85..4c1c159fbb62 100644 --- a/drivers/net/wireless/mediatek/mt76/pci.c +++ b/drivers/net/wireless/mediatek/mt76/pci.c @@ -3,6 +3,7 @@ * Copyright (C) 2019 Lorenzo Bianconi */ +#include "mt76.h" #include void mt76_pci_disable_aspm(struct pci_dev *pdev) -- cgit v1.2.3 From 4a58d5d1097a6b1918c4e307a8d30211ba721932 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 12 Jun 2020 12:08:59 +0200 Subject: mt76: rely on register macros For consistency with the rest of the code always rely on defined macros for register access Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/debugfs.c | 4 ++-- drivers/net/wireless/mediatek/mt76/util.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c index 9fda65db8cac..5d58b16bfe9f 100644 --- a/drivers/net/wireless/mediatek/mt76/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c @@ -9,7 +9,7 @@ mt76_reg_set(void *data, u64 val) { struct mt76_dev *dev = data; - dev->bus->wr(dev, dev->debugfs_reg, val); + __mt76_wr(dev, dev->debugfs_reg, val); return 0; } @@ -18,7 +18,7 @@ mt76_reg_get(void *data, u64 *val) { struct mt76_dev *dev = data; - *val = dev->bus->rr(dev, dev->debugfs_reg); + *val = __mt76_rr(dev, dev->debugfs_reg); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c index ecde87465bf6..f53bb4ae5001 100644 --- a/drivers/net/wireless/mediatek/mt76/util.c +++ b/drivers/net/wireless/mediatek/mt76/util.c @@ -13,7 +13,7 @@ bool __mt76_poll(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, timeout /= 10; do { - cur = dev->bus->rr(dev, offset) & mask; + cur = __mt76_rr(dev, offset) & mask; if (cur == val) return true; @@ -31,7 +31,7 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, timeout /= 10; do { - cur = dev->bus->rr(dev, offset) & mask; + cur = __mt76_rr(dev, offset) & mask; if (cur == val) return true; -- cgit v1.2.3 From b807b368c4f9bbdb8410dcc6241d7903094f0bef Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 12 Jun 2020 13:46:31 +0200 Subject: mt76: add U-APSD support on AP side Introduce U-APSD support in mt76 driver for AP interface Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 4 ++- drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 46 +++++++++++++++++++++++-- drivers/net/wireless/mediatek/mt76/mt7615/mcu.h | 21 +++++++++++ 3 files changed, 68 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 4c10c8164aee..d8533d0c6e81 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -282,7 +282,8 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw) wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH | - WIPHY_FLAG_SUPPORTS_TDLS; + WIPHY_FLAG_SUPPORTS_TDLS | + WIPHY_FLAG_AP_UAPSD; wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS); @@ -292,6 +293,7 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw) wiphy->available_antennas_rx = dev->phy.antenna_mask; hw->txq_data_size = sizeof(struct mt76_txq); + hw->uapsd_max_sp_len = IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL; if (!hw->max_tx_fragments) hw->max_tx_fragments = 16; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c index b76ecc24f333..d3a8ada3b779 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c @@ -926,6 +926,38 @@ mt7615_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) } } +static void +mt7615_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct sta_rec_uapsd *uapsd; + struct tlv *tlv; + + if (vif->type != NL80211_IFTYPE_AP || !sta->wme) + return; + + tlv = mt7615_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd)); + uapsd = (struct sta_rec_uapsd *)tlv; + + if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) { + uapsd->dac_map |= BIT(3); + uapsd->tac_map |= BIT(3); + } + if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) { + uapsd->dac_map |= BIT(2); + uapsd->tac_map |= BIT(2); + } + if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) { + uapsd->dac_map |= BIT(1); + uapsd->tac_map |= BIT(1); + } + if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) { + uapsd->dac_map |= BIT(0); + uapsd->tac_map |= BIT(0); + } + uapsd->max_sp = sta->max_sp; +} + static void mt7615_mcu_wtbl_ba_tlv(struct sk_buff *skb, struct ieee80211_ampdu_params *params, @@ -1188,8 +1220,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_dev *dev, struct ieee80211_vif *vif, return PTR_ERR(sskb); mt7615_mcu_sta_basic_tlv(sskb, vif, sta, enable); - if (enable && sta) + if (enable && sta) { mt7615_mcu_sta_ht_tlv(sskb, sta); + mt7615_mcu_sta_uapsd(sskb, vif, sta); + } wtbl_hdr = mt7615_mcu_alloc_wtbl_req(dev, msta, WTBL_RESET_AND_SET, NULL, &wskb); @@ -1285,8 +1319,10 @@ mt7615_mcu_add_sta_cmd(struct mt7615_dev *dev, struct ieee80211_vif *vif, return PTR_ERR(skb); mt7615_mcu_sta_basic_tlv(skb, vif, sta, enable); - if (enable && sta) + if (enable && sta) { mt7615_mcu_sta_ht_tlv(skb, sta); + mt7615_mcu_sta_uapsd(skb, vif, sta); + } sta_wtbl = mt7615_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv)); @@ -1429,6 +1465,7 @@ mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif, u8 pad[3]; } __packed hdr; struct mt7615_bss_basic_tlv basic; + struct mt7615_bss_qos_tlv qos; } basic_req = { .hdr = { .bss_idx = mvif->idx, @@ -1444,6 +1481,11 @@ mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif, .active = true, /* keep bss deactivated */ .phymode = 0x38, }, + .qos = { + .tag = cpu_to_le16(UNI_BSS_INFO_QBSS), + .len = cpu_to_le16(sizeof(struct mt7615_bss_qos_tlv)), + .qos = vif->bss_conf.qos, + }, }; struct { struct { diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h index 64f7471a57bb..4f70c4de69a4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h @@ -454,6 +454,13 @@ struct mt7615_bss_basic_tlv { u8 pad[3]; } __packed; +struct mt7615_bss_qos_tlv { + __le16 tag; + __le16 len; + u8 qos; + u8 pad[3]; +} __packed; + struct mt7615_wow_ctrl_tlv { __le16 tag; __le16 len; @@ -578,6 +585,8 @@ enum { UNI_BSS_INFO_BASIC = 0, UNI_BSS_INFO_RLM = 2, UNI_BSS_INFO_BCN_CONTENT = 7, + UNI_BSS_INFO_QBSS = 15, + UNI_BSS_INFO_UAPSD = 19, }; enum { @@ -891,6 +900,7 @@ struct wtbl_raw { sizeof(struct sta_rec_basic) + \ sizeof(struct sta_rec_ht) + \ sizeof(struct sta_rec_vht) + \ + sizeof(struct sta_rec_uapsd) + \ sizeof(struct tlv) + \ MT7615_WTBL_UPDATE_MAX_SIZE) @@ -980,6 +990,17 @@ struct sta_rec_ba { __le16 winsize; } __packed; +struct sta_rec_uapsd { + __le16 tag; + __le16 len; + u8 dac_map; + u8 tac_map; + u8 max_sp; + u8 rsv0; + __le16 listen_interval; + u8 rsv1[2]; +} __packed; + enum { STA_REC_BASIC, STA_REC_RA, -- cgit v1.2.3 From b876658b5e554c6bd251720b7cd40de5b5f6c366 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Thu, 18 Jun 2020 12:41:48 +0800 Subject: mt76: mt7615: add .set_tsf callback It is useful for IBSS Mesh to adjust t_clockdrift. Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 21 +++++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt7615/regs.h | 1 + 2 files changed, 22 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index e6dbd7034bd7..f8ce485c8d19 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -740,6 +740,26 @@ mt7615_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) return tsf.t64; } +static void +mt7615_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u64 timestamp) +{ + struct mt7615_dev *dev = mt7615_hw_dev(hw); + union { + u64 t64; + u32 t32[2]; + } tsf = { .t64 = timestamp, }; + + mutex_lock(&dev->mt76.mutex); + + mt76_wr(dev, MT_LPON_UTTR0, tsf.t32[0]); + mt76_wr(dev, MT_LPON_UTTR1, tsf.t32[1]); + /* TSF software overwrite */ + mt76_set(dev, MT_LPON_T0CR, MT_LPON_T0CR_WRITE); + + mutex_unlock(&dev->mt76.mutex); +} + static void mt7615_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) { @@ -1038,6 +1058,7 @@ const struct ieee80211_ops mt7615_ops = { .channel_switch_beacon = mt7615_channel_switch_beacon, .get_stats = mt7615_get_stats, .get_tsf = mt7615_get_tsf, + .set_tsf = mt7615_set_tsf, .get_survey = mt76_get_survey, .get_antenna = mt76_get_antenna, .set_antenna = mt7615_set_antenna, diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h index aee433a9eff6..f0b36b162bf3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/regs.h @@ -417,6 +417,7 @@ enum mt7615_reg_base { #define MT_LPON_T0CR MT_LPON(0x010) #define MT_LPON_T0CR_MODE GENMASK(1, 0) +#define MT_LPON_T0CR_WRITE BIT(0) #define MT_LPON_UTTR0 MT_LPON(0x018) #define MT_LPON_UTTR1 MT_LPON(0x01c) -- cgit v1.2.3 From dcdecb128b2e0856e3131d93102d80bd748f2d9b Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Mon, 15 Jun 2020 02:23:34 +0800 Subject: mt76: mt7915: add a fixed AC queue mapping In MT7915, hardware queue map is flexible. However, certain firmware modules like MU and U-APSD presume a fixed queue order to adapt some devices that have DMA scheduler with a strict order, so this patch can help in the long run. Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/mac.h | 10 --------- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 3 +++ drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h | 25 ++++++++++++++++++++++ 4 files changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index a264e304a3df..660e1820cccf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -593,7 +593,7 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, if (ieee80211_is_data(fc) || ieee80211_is_bufferable_mmpdu(fc)) { q_idx = wmm_idx * MT7915_MAX_WMM_SETS + - skb_get_queue_mapping(skb); + mt7915_lmac_mapping(dev, skb_get_queue_mapping(skb)); p_fmt = MT_TX_TYPE_CT; } else if (beacon) { q_idx = MT_LMAC_BCN0; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h index b9bc8b25b031..4b0871ab2414 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.h @@ -149,16 +149,6 @@ enum tx_pkt_type { MT_TX_TYPE_FW, }; -enum tx_pkt_queue_idx { - MT_LMAC_AC00, - MT_LMAC_AC01, - MT_LMAC_AC02, - MT_LMAC_AC03, - MT_LMAC_ALTX0 = 0x10, - MT_LMAC_BMC0 = 0x10, - MT_LMAC_BCN0 = 0x12, -}; - enum tx_port_idx { MT_TX_PORT_IDX_LMAC, MT_TX_PORT_IDX_MCU diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 05b5650c56c8..e09899748c9b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -350,9 +350,12 @@ static int mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params) { + struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; /* no need to update right away, we'll get BSS_CHANGED_QOS */ + queue = mt7915_lmac_mapping(dev, queue); + mvif->wmm[queue].cw_min = params->cw_min; mvif->wmm[queue].cw_max = params->cw_max; mvif->wmm[queue].aifs = params->aifs; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 85d74ecd0351..b3b00d099236 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -199,6 +199,16 @@ enum { EXT_BSSID_END }; +enum { + MT_LMAC_AC00, + MT_LMAC_AC01, + MT_LMAC_AC02, + MT_LMAC_AC03, + MT_LMAC_ALTX0 = 0x10, + MT_LMAC_BMC0, + MT_LMAC_BCN0, +}; + enum { MT_RX_SEL0, MT_RX_SEL1, @@ -254,6 +264,21 @@ mt7915_ext_phy(struct mt7915_dev *dev) return phy->priv; } +static inline u8 mt7915_lmac_mapping(struct mt7915_dev *dev, u8 ac) +{ + static const u8 lmac_queue_map[] = { + [IEEE80211_AC_BK] = MT_LMAC_AC00, + [IEEE80211_AC_BE] = MT_LMAC_AC01, + [IEEE80211_AC_VI] = MT_LMAC_AC02, + [IEEE80211_AC_VO] = MT_LMAC_AC03, + }; + + if (WARN_ON_ONCE(ac >= ARRAY_SIZE(lmac_queue_map))) + return MT_LMAC_AC01; /* BE */ + + return lmac_queue_map[ac]; +} + static inline void mt7915_set_aggr_state(struct mt7915_sta *msta, u8 tid, enum mt7915_ampdu_state state) -- cgit v1.2.3 From f68e6a1f85c148f0b238bdaef22f31b01d5cf51e Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Mon, 15 Jun 2020 02:23:35 +0800 Subject: mt76: mt7915: add MU-MIMO support Enable MU-MIMO DL/UL and add relative counters in debugfs. Currently MU modules read WTBL first to notify BA changes to other cross modules, so adjust mt7915_mcu_sta_ba() accordingly. Tested-by: Evelyn Tsai Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7915/debugfs.c | 9 ++- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 77 ++++++++++++++++++++-- drivers/net/wireless/mediatek/mt76/mt7915/mcu.h | 6 +- drivers/net/wireless/mediatek/mt76/mt7915/regs.h | 5 ++ 4 files changed, 87 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c index 5278bee812f1..95e073c02ce6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c @@ -178,7 +178,14 @@ mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s) seq_printf(s, "Tx Beamformee feedback triggered counts: %ld\n", FIELD_GET(MT_ETBF_TX_FB_TRI, cnt)); - /* Tx SU counters */ + /* Tx SU & MU counters */ + cnt = mt76_rr(dev, MT_MIB_SDR34(ext_phy)); + seq_printf(s, "Tx multi-user Beamforming counts: %ld\n", + FIELD_GET(MT_MIB_MU_BF_TX_CNT, cnt)); + cnt = mt76_rr(dev, MT_MIB_DR8(ext_phy)); + seq_printf(s, "Tx multi-user MPDU counts: %d\n", cnt); + cnt = mt76_rr(dev, MT_MIB_DR9(ext_phy)); + seq_printf(s, "Tx multi-user successful MPDU counts: %d\n", cnt); cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy)); seq_printf(s, "Tx single-user successful MPDU counts: %d\n", cnt); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index c8c12c740c1a..ca3e700425b6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -1166,19 +1166,31 @@ mt7915_mcu_sta_ba(struct mt7915_dev *dev, struct wtbl_req_hdr *wtbl_hdr; struct tlv *sta_wtbl; struct sk_buff *skb; + int ret; skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, MT7915_STA_UPDATE_MAX_SIZE); if (IS_ERR(skb)) return PTR_ERR(skb); - mt7915_mcu_sta_ba_tlv(skb, params, enable, tx); sta_wtbl = mt7915_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv)); wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, sta_wtbl, &skb); mt7915_mcu_wtbl_ba_tlv(skb, params, enable, tx, sta_wtbl, wtbl_hdr); + ret = __mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_EXT_CMD_STA_REC_UPDATE, true); + if (ret) + return ret; + + skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, + MT7915_STA_UPDATE_MAX_SIZE); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + mt7915_mcu_sta_ba_tlv(skb, params, enable, tx); + return __mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_STA_REC_UPDATE, true); } @@ -1466,16 +1478,39 @@ mt7915_mcu_sta_muru_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) HE_PHY(CAP2_UL_MU_PARTIAL_MU_MIMO, elem->phy_cap_info[2]); } +static int +mt7915_mcu_add_mu(struct mt7915_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct sk_buff *skb; + int len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_muru); + + if (!sta->vht_cap.vht_supported && !sta->he_cap.has_he) + return 0; + + skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + /* starec muru */ + mt7915_mcu_sta_muru_tlv(skb, sta); + + return __mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_EXT_CMD_STA_REC_UPDATE, true); +} + static void mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb, struct ieee80211_sta *sta) { struct tlv *tlv; + /* starec ht */ if (sta->ht_cap.ht_supported) { struct sta_rec_ht *ht; - /* starec ht */ tlv = mt7915_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht)); ht = (struct sta_rec_ht *)tlv; ht->ht_cap = cpu_to_le16(sta->ht_cap.cap); @@ -1495,10 +1530,6 @@ mt7915_mcu_sta_tlv(struct mt7915_dev *dev, struct sk_buff *skb, /* starec he */ if (sta->he_cap.has_he) mt7915_mcu_sta_he_tlv(skb, sta); - - /* starec muru */ - if (sta->he_cap.has_he || sta->vht_cap.vht_supported) - mt7915_mcu_sta_muru_tlv(skb, sta); } static void @@ -2064,6 +2095,32 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, MCU_EXT_CMD_STA_REC_UPDATE, true); } +static int +mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ +#define MT_STA_BSS_GROUP 1 + struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; + struct { + __le32 action; + u8 wlan_idx_lo; + u8 status; + u8 wlan_idx_hi; + u8 rsv0[5]; + __le32 val; + u8 rsv1[8]; + } __packed req = { + .action = cpu_to_le32(MT_STA_BSS_GROUP), + .wlan_idx_lo = to_wcid_lo(msta->wcid.idx), + .wlan_idx_hi = to_wcid_hi(msta->wcid.idx), + .val = cpu_to_le32(mvif->idx), + }; + + return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_DRR_CTRL, + &req, sizeof(req), true); +} + int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool enable) { @@ -2073,10 +2130,18 @@ int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif, return 0; /* must keep the order */ + ret = mt7915_mcu_add_group(dev, vif, sta); + if (ret) + return ret; + ret = mt7915_mcu_add_txbf(dev, vif, sta, enable); if (ret) return ret; + ret = mt7915_mcu_add_mu(dev, vif, sta); + if (ret) + return ret; + if (enable) return mt7915_mcu_add_rate_ctrl(dev, vif, sta); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index c241dd7c4c36..cb35e718409a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -201,6 +201,7 @@ enum { MCU_EXT_CMD_EDCA_UPDATE = 0x27, MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A, MCU_EXT_CMD_THERMAL_CTRL = 0x2c, + MCU_EXT_CMD_SET_DRR_CTRL = 0x36, MCU_EXT_CMD_SET_RDD_CTRL = 0x3a, MCU_EXT_CMD_PROTECT_CTRL = 0x3e, MCU_EXT_CMD_MAC_INIT_CTRL = 0x46, @@ -653,7 +654,7 @@ struct sta_rec_muru { bool ofdma_ul_en; bool mimo_dl_en; bool mimo_ul_en; - bool rsv[4]; + u8 rsv[4]; } cfg; struct { @@ -664,7 +665,7 @@ struct sta_rec_muru { bool lt16_sigb; bool rx_su_comp_sigb; bool rx_su_non_comp_sigb; - bool rsv; + u8 rsv; } ofdma_dl; struct { @@ -951,7 +952,6 @@ enum { sizeof(struct sta_rec_ba) + \ sizeof(struct sta_rec_vht) + \ sizeof(struct tlv) + \ - sizeof(struct sta_rec_muru) + \ MT7915_WTBL_UPDATE_MAX_SIZE) #define MT7915_WTBL_UPDATE_BA_SIZE (sizeof(struct wtbl_req_hdr) + \ diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h index c121715f8bff..e0989141d9da 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h @@ -117,11 +117,16 @@ #define MT_MIB_SDR16(_band) MT_WF_MIB(_band, 0x048) #define MT_MIB_SDR16_BUSY_MASK GENMASK(23, 0) +#define MT_MIB_SDR34(_band) MT_WF_MIB(_band, 0x090) +#define MT_MIB_MU_BF_TX_CNT GENMASK(15, 0) + #define MT_MIB_SDR36(_band) MT_WF_MIB(_band, 0x098) #define MT_MIB_SDR36_TXTIME_MASK GENMASK(23, 0) #define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x09c) #define MT_MIB_SDR37_RXTIME_MASK GENMASK(23, 0) +#define MT_MIB_DR8(_band) MT_WF_MIB(_band, 0x0c0) +#define MT_MIB_DR9(_band) MT_WF_MIB(_band, 0x0c4) #define MT_MIB_DR11(_band) MT_WF_MIB(_band, 0x0cc) #define MT_MIB_MB_SDR0(_band, n) MT_WF_MIB(_band, 0x100 + ((n) << 4)) -- cgit v1.2.3 From 80c9934004046a99f29ec89140556a2733641783 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Mon, 15 Jun 2020 02:23:36 +0800 Subject: mt76: mt7915: use ieee80211_tx_queue_params to avoid open coded This is easy to add MU EDCA parameters in the future. This patch also fixes a wrong cw_min assignment. Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 6 +----- drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 14 +++++++------- drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h | 9 ++------- 3 files changed, 10 insertions(+), 19 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index e09899748c9b..0c1217d3acd8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -355,11 +355,7 @@ mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, /* no need to update right away, we'll get BSS_CHANGED_QOS */ queue = mt7915_lmac_mapping(dev, queue); - - mvif->wmm[queue].cw_min = params->cw_min; - mvif->wmm[queue].cw_max = params->cw_max; - mvif->wmm[queue].aifs = params->aifs; - mvif->wmm[queue].txop = params->txop; + mvif->queue_params[queue] = *params; return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index ca3e700425b6..fa9f32fa9f2e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -2888,23 +2888,23 @@ int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif) int ac; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { + struct ieee80211_tx_queue_params *q = &mvif->queue_params[ac]; struct edca *e = &req.edca[ac]; e->queue = ac + mvif->wmm_idx * MT7915_MAX_WMM_SETS; - e->aifs = mvif->wmm[ac].aifs; - e->txop = cpu_to_le16(mvif->wmm[ac].txop); + e->aifs = q->aifs; + e->txop = cpu_to_le16(q->txop); - if (mvif->wmm[ac].cw_min) - e->cw_min = fls(mvif->wmm[ac].cw_max); + if (q->cw_min) + e->cw_min = fls(q->cw_min); else e->cw_min = 5; - if (mvif->wmm[ac].cw_max) - e->cw_max = cpu_to_le16(fls(mvif->wmm[ac].cw_max)); + if (q->cw_max) + e->cw_max = cpu_to_le16(fls(q->cw_max)); else e->cw_max = cpu_to_le16(10); } - return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EDCA_UPDATE, &req, sizeof(req), true); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index b3b00d099236..4a063c1e5ea2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -99,15 +99,10 @@ struct mt7915_vif { u8 band_idx; u8 wmm_idx; - struct { - u16 cw_min; - u16 cw_max; - u16 txop; - u8 aifs; - } wmm[IEEE80211_NUM_ACS]; - struct mt7915_sta sta; struct mt7915_dev *dev; + + struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; }; struct mib_stats { -- cgit v1.2.3 From dc076af55b86b4992114f6b3b889fbc96c5d4fd4 Mon Sep 17 00:00:00 2001 From: Ryder Lee Date: Mon, 22 Jun 2020 10:16:55 +0800 Subject: mt76: mt7915: overwrite qid for non-bufferable mgmt frames Overwrite hw queue id for non-bufferable management frames if the hw/fw support always txq (altxq) in order to be in sync with mac txwi code Signed-off-by: Ryder Lee Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7915/dma.c | 21 +++++++++++---------- drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 15 ++++++++------- drivers/net/wireless/mediatek/mt76/mt7915/pci.c | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c index 766185d1aa21..a8832c5e6004 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/dma.c @@ -79,26 +79,27 @@ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, } } +static void +mt7915_tx_cleanup(struct mt7915_dev *dev) +{ + mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false); + mt76_queue_tx_cleanup(dev, MT_TXQ_MCU_WA, false); + mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false); + mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false); +} + static int mt7915_poll_tx(struct napi_struct *napi, int budget) { - static const u8 queue_map[] = { - MT_TXQ_MCU, - MT_TXQ_MCU_WA, - MT_TXQ_BE - }; struct mt7915_dev *dev; - int i; dev = container_of(napi, struct mt7915_dev, mt76.tx_napi); - for (i = 0; i < ARRAY_SIZE(queue_map); i++) - mt76_queue_tx_cleanup(dev, queue_map[i], false); + mt7915_tx_cleanup(dev); if (napi_complete_done(napi, 0)) mt7915_irq_enable(dev, MT_INT_TX_DONE_ALL); - for (i = 0; i < ARRAY_SIZE(queue_map); i++) - mt76_queue_tx_cleanup(dev, queue_map[i], false); + mt7915_tx_cleanup(dev); mt7915_mac_sta_poll(dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c index 660e1820cccf..822540e5df6b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c @@ -591,16 +591,16 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2; fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4; - if (ieee80211_is_data(fc) || ieee80211_is_bufferable_mmpdu(fc)) { - q_idx = wmm_idx * MT7915_MAX_WMM_SETS + - mt7915_lmac_mapping(dev, skb_get_queue_mapping(skb)); - p_fmt = MT_TX_TYPE_CT; - } else if (beacon) { - q_idx = MT_LMAC_BCN0; + if (beacon) { p_fmt = MT_TX_TYPE_FW; - } else { + q_idx = MT_LMAC_BCN0; + } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { + p_fmt = MT_TX_TYPE_CT; q_idx = MT_LMAC_ALTX0; + } else { p_fmt = MT_TX_TYPE_CT; + q_idx = wmm_idx * MT7915_MAX_WMM_SETS + + mt7915_lmac_mapping(dev, skb_get_queue_mapping(skb)); } val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + MT_TXD_SIZE) | @@ -616,6 +616,7 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, FIELD_PREP(MT_TXD1_TID, skb->priority & IEEE80211_QOS_CTL_TID_MASK) | FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx); + if (ext_phy && q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0) val |= MT_TXD1_TGID; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c index 7937c6965f59..0ec4e184b889 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c @@ -103,7 +103,7 @@ static int mt7915_pci_probe(struct pci_dev *pdev, static const struct mt76_driver_ops drv_ops = { /* txwi_size = txd size + txp size */ .txwi_size = MT_TXD_SIZE + sizeof(struct mt7915_txp), - .drv_flags = MT_DRV_TXWI_NO_FREE, + .drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ, .survey_flags = SURVEY_INFO_TIME_TX | SURVEY_INFO_TIME_RX | SURVEY_INFO_TIME_BSS_RX, -- cgit v1.2.3 From 6ed942af4f68173eb511bc342d53f2593182d449 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Thu, 18 Jun 2020 19:00:23 +0200 Subject: mt76: mt76x2e: rename routines in pci.c Rely on mt76x2e prefix in mt76x2/pci.c and align to the rest of mt76 code Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76x2/pci.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c index 53ca0cedf026..f36c71c1bc58 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c @@ -9,7 +9,7 @@ #include "mt76x2.h" -static const struct pci_device_id mt76pci_device_table[] = { +static const struct pci_device_id mt76x2e_device_table[] = { { PCI_DEVICE(0x14c3, 0x7662) }, { PCI_DEVICE(0x14c3, 0x7612) }, { PCI_DEVICE(0x14c3, 0x7602) }, @@ -17,7 +17,7 @@ static const struct pci_device_id mt76pci_device_table[] = { }; static int -mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +mt76x2e_probe(struct pci_dev *pdev, const struct pci_device_id *id) { static const struct mt76_driver_ops drv_ops = { .txwi_size = sizeof(struct mt76x02_txwi), @@ -93,7 +93,7 @@ error: } static void -mt76pci_remove(struct pci_dev *pdev) +mt76x2e_remove(struct pci_dev *pdev) { struct mt76_dev *mdev = pci_get_drvdata(pdev); struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); @@ -103,16 +103,16 @@ mt76pci_remove(struct pci_dev *pdev) mt76_free_device(mdev); } -MODULE_DEVICE_TABLE(pci, mt76pci_device_table); +MODULE_DEVICE_TABLE(pci, mt76x2e_device_table); MODULE_FIRMWARE(MT7662_FIRMWARE); MODULE_FIRMWARE(MT7662_ROM_PATCH); MODULE_LICENSE("Dual BSD/GPL"); static struct pci_driver mt76pci_driver = { .name = KBUILD_MODNAME, - .id_table = mt76pci_device_table, - .probe = mt76pci_probe, - .remove = mt76pci_remove, + .id_table = mt76x2e_device_table, + .probe = mt76x2e_probe, + .remove = mt76x2e_remove, }; module_pci_driver(mt76pci_driver); -- cgit v1.2.3 From 5bb923c767a4d2b4c20e7d4f437e35754ccd6554 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 17 Jun 2020 15:21:39 +0200 Subject: mt76: mt7615: schedule tx tasklet and sta poll on mac tx free Unlike on earlier chips, DMA completion on MT7615 does not imply actually having sent out any packets. Since AQL will prevent filling the hardware queues and will only allow more packets to be passed to the driver after tx completion, it makes much more sense to schedule the tx tasklet there. This is also needed for scheduling tx in testmode support Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7615/dma.c | 4 ---- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 6 ++++++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers