* [PATCH 0/7] MT7915: add TxBF support
@ 2020-05-11 16:06 Ryder Lee
2020-05-11 16:06 ` [PATCH 1/7] mt76: mt7915: introduce mt7915_get_he_phy_cap Ryder Lee
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Ryder Lee @ 2020-05-11 16:06 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: linux-mediatek, Sean Wang, linux-wireless, Ryder Lee, Shayne Chen
This enables the SU Tx beamforming support on MT7915, and will enable MU part soon.
Ryder
Ryder Lee (7):
mt76: mt7915: introduce mt7915_get_he_phy_cap
mt76: mt7915: add Tx beamformer support
mt76: mt7915: add Tx beamformee support
mt76: mt7915: add TxBF capabilities
mt76: mt7915: add debugfs to track TxBF status
mt76: mt7915: allocate proper size for tlv tags
mt76: mt7915: fix possible deadlock in mt7915_stop
.../wireless/mediatek/mt76/mt7915/debugfs.c | 45 ++
.../net/wireless/mediatek/mt76/mt7915/init.c | 118 ++++-
.../net/wireless/mediatek/mt76/mt7915/mac.c | 49 +-
.../net/wireless/mediatek/mt76/mt7915/main.c | 28 +-
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 457 ++++++++++++++++--
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 99 +++-
.../wireless/mediatek/mt76/mt7915/mt7915.h | 9 +-
.../net/wireless/mediatek/mt76/mt7915/regs.h | 20 +
8 files changed, 734 insertions(+), 91 deletions(-)
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/7] mt76: mt7915: introduce mt7915_get_he_phy_cap
2020-05-11 16:06 [PATCH 0/7] MT7915: add TxBF support Ryder Lee
@ 2020-05-11 16:06 ` Ryder Lee
2020-05-11 16:06 ` [PATCH 2/7] mt76: mt7915: add Tx beamformer support Ryder Lee
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ryder Lee @ 2020-05-11 16:06 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: linux-mediatek, Sean Wang, linux-wireless, Ryder Lee, Shayne Chen
Add a helper to reduce duplicate codes.
This is a preliminary patch to add Tx beamforming support.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 31 +++++++++++--------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 3e3d6f1d555a..c147a033250a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -134,6 +134,18 @@ static u8 mt7915_mcu_chan_bw(struct cfg80211_chan_def *chandef)
return width_to_bw[chandef->width];
}
+static const struct ieee80211_sta_he_cap *
+mt7915_get_he_phy_cap(struct mt7915_phy *phy, struct ieee80211_vif *vif)
+{
+ struct ieee80211_supported_band *sband;
+ enum nl80211_band band;
+
+ band = phy->mt76->chandef.chan->band;
+ sband = phy->mt76->hw->wiphy->bands[band];
+
+ return ieee80211_get_he_iftype_cap(sband, vif->type);
+}
+
static u8
mt7915_get_phy_mode(struct mt7915_dev *dev, struct ieee80211_vif *vif,
enum nl80211_band band, struct ieee80211_sta *sta)
@@ -149,11 +161,12 @@ mt7915_get_phy_mode(struct mt7915_dev *dev, struct ieee80211_vif *vif,
he_cap = &sta->he_cap;
} else {
struct ieee80211_supported_band *sband;
+ struct mt7915_phy *phy;
+ struct mt7915_vif *mvif;
- if (band == NL80211_BAND_2GHZ)
- sband = &dev->mphy.sband_2g.sband;
- else
- sband = &dev->mphy.sband_5g.sband;
+ mvif = (struct mt7915_vif *)vif->drv_priv;
+ phy = mvif->band_idx ? mt7915_ext_phy(dev) : &dev->phy;
+ sband = phy->mt76->hw->wiphy->bands[band];
ht_cap = &sband->ht_cap;
vht_cap = &sband->vht_cap;
@@ -884,19 +897,11 @@ mt7915_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
{
#define DEFAULT_HE_PE_DURATION 4
#define DEFAULT_HE_DURATION_RTS_THRES 1023
- struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
- enum nl80211_band band = chandef->chan->band;
- struct ieee80211_supported_band *sband;
const struct ieee80211_sta_he_cap *cap;
struct bss_info_he *he;
struct tlv *tlv;
- if (band == NL80211_BAND_2GHZ)
- sband = &phy->mt76->sband_2g.sband;
- else
- sband = &phy->mt76->sband_5g.sband;
-
- cap = ieee80211_get_he_iftype_cap(sband, vif->type);
+ cap = mt7915_get_he_phy_cap(phy, vif);
tlv = mt7915_mcu_add_tlv(skb, BSS_INFO_HE_BASIC, sizeof(*he));
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/7] mt76: mt7915: add Tx beamformer support
2020-05-11 16:06 [PATCH 0/7] MT7915: add TxBF support Ryder Lee
2020-05-11 16:06 ` [PATCH 1/7] mt76: mt7915: introduce mt7915_get_he_phy_cap Ryder Lee
@ 2020-05-11 16:06 ` Ryder Lee
2020-05-11 16:06 ` [PATCH 3/7] mt76: mt7915: add Tx beamformee support Ryder Lee
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ryder Lee @ 2020-05-11 16:06 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: linux-mediatek, Sean Wang, linux-wireless, Ryder Lee, Shayne Chen
Enable TxBF modules and trigger sounding process to support Tx beamformer.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com
---
.../net/wireless/mediatek/mt76/mt7915/init.c | 20 +
.../net/wireless/mediatek/mt76/mt7915/main.c | 9 +-
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 358 +++++++++++++++++-
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 78 ++--
.../wireless/mediatek/mt76/mt7915/mt7915.h | 4 +
5 files changed, 434 insertions(+), 35 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 7d59571216e3..3721bd632b4d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -57,6 +57,25 @@ static void mt7915_mac_init(struct mt7915_dev *dev)
mt7915_mcu_set_rts_thresh(&dev->phy, 0x92b);
}
+static int mt7915_txbf_init(struct mt7915_dev *dev)
+{
+ int ret;
+
+ /*
+ * TODO: DBDC & check whether iBF phase calibration data has
+ * been stored in eeprom offset 0x651~0x7b8, then write down
+ * 0x1111 into 0x651 and 0x651 to trigger iBF.
+ */
+
+ /* trigger sounding packets */
+ ret = mt7915_mcu_set_txbf_sounding(dev);
+ if (ret)
+ return ret;
+
+ /* enable iBF & eBF */
+ return mt7915_mcu_set_txbf_type(dev);
+}
+
static void
mt7915_init_txpower_band(struct mt7915_dev *dev,
struct ieee80211_supported_band *sband)
@@ -97,6 +116,7 @@ static void mt7915_init_work(struct work_struct *work)
mt7915_mcu_set_eeprom(dev);
mt7915_mac_init(dev);
mt7915_init_txpower(dev);
+ mt7915_txbf_init(dev);
}
static int mt7915_init_hardware(struct mt7915_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 697045e65b24..f3a373fc07e5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -485,7 +485,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
- int idx;
+ int ret, idx;
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA - 1);
if (idx < 0)
@@ -504,9 +504,11 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
mt7915_mac_wtbl_update(dev, idx,
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
- mt7915_mcu_add_sta(dev, vif, sta, true);
+ ret = mt7915_mcu_add_sta(dev, vif, sta, true);
+ if (ret)
+ return ret;
- return 0;
+ return mt7915_mcu_add_sta_adv(dev, vif, sta, true);
}
void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
@@ -515,6 +517,7 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ mt7915_mcu_add_sta_adv(dev, vif, sta, false);
mt7915_mcu_add_sta(dev, vif, sta, false);
mt7915_mac_wtbl_update(dev, msta->wcid.idx,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index c147a033250a..58d0adca8b31 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -66,6 +66,8 @@ struct mt7915_fw_region {
#define MCU_PATCH_ADDRESS 0x200000
+#define MT_STA_BFER BIT(0)
+
#define FW_FEATURE_SET_ENCRYPT BIT(0)
#define FW_FEATURE_SET_KEY_IDX GENMASK(2, 1)
#define FW_FEATURE_OVERRIDE_ADDR BIT(5)
@@ -197,6 +199,21 @@ mt7915_get_phy_mode(struct mt7915_dev *dev, struct ieee80211_vif *vif,
return mode;
}
+static u8
+mt7915_mcu_get_sta_nss(u16 mcs_map)
+{
+ u8 nss;
+
+ for (nss = 8; nss > 0; nss--) {
+ u8 nss_mcs = (mcs_map >> (2 * (nss - 1))) & 3;
+
+ if (nss_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED)
+ break;
+ }
+
+ return nss - 1;
+}
+
static int __mt7915_mcu_msg_send(struct mt7915_dev *dev, struct sk_buff *skb,
int cmd, int *wait_seq)
{
@@ -1561,6 +1578,279 @@ int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
MCU_EXT_CMD_STA_REC_UPDATE, true);
}
+static void
+mt7915_mcu_sta_sounding_rate(struct sta_rec_bf *bf)
+{
+ bf->sounding_phy = MT_PHY_TYPE_OFDM;
+ bf->ndp_rate = 0; /* mcs0 */
+ bf->ndpa_rate = MT7915_CFEND_RATE_DEFAULT; /* ofdm 24m */
+ bf->rept_poll_rate = MT7915_CFEND_RATE_DEFAULT; /* ofdm 24m */
+}
+
+static void
+mt7915_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct sta_rec_bf *bf)
+{
+ struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
+ u8 n = 0;
+
+ bf->tx_mode = MT_PHY_TYPE_HT;
+ bf->bf_cap |= MT_IBF;
+
+ if (mcs->tx_params & IEEE80211_HT_MCS_TX_RX_DIFF &&
+ (mcs->tx_params & IEEE80211_HT_MCS_TX_DEFINED))
+ n = FIELD_GET(IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK,
+ mcs->tx_params);
+ else if (mcs->rx_mask[3])
+ n = 3;
+ else if (mcs->rx_mask[2])
+ n = 2;
+ else if (mcs->rx_mask[1])
+ n = 1;
+
+ bf->nc = min_t(u8, bf->nr, n);
+ bf->ibf_ncol = bf->nc;
+
+ if (sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->nc)
+ bf->ibf_timeout = 0x48;
+}
+
+static void
+mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
+ struct sta_rec_bf *bf)
+{
+ struct ieee80211_sta_vht_cap *pc = &sta->vht_cap;
+ struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap;
+ u8 bfee_nr, bfer_nr, n, tx_ant = hweight8(phy->chainmask) - 1;
+ u16 mcs_map;
+
+ bf->tx_mode = MT_PHY_TYPE_VHT;
+ bf->bf_cap |= MT_EBF;
+
+ mt7915_mcu_sta_sounding_rate(bf);
+
+ bfee_nr = FIELD_GET(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK,
+ pc->cap);
+ bfer_nr = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
+ vc->cap);
+ mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map);
+
+ n = min_t(u8, bfer_nr, bfee_nr);
+ bf->nr = min_t(u8, n, tx_ant);
+ n = mt7915_mcu_get_sta_nss(mcs_map);
+
+ bf->nc = min_t(u8, n, bf->nr);
+ bf->ibf_ncol = bf->nc;
+
+ /* force nr from 4 to 2 */
+ if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
+ bf->nr = 1;
+}
+
+static void
+mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
+ struct mt7915_phy *phy, struct sta_rec_bf *bf)
+{
+ struct ieee80211_sta_he_cap *pc = &sta->he_cap;
+ struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
+ const struct ieee80211_he_cap_elem *ve;
+ const struct ieee80211_sta_he_cap *vc;
+ u8 bfee_nr, bfer_nr, nss_mcs;
+ u16 mcs_map;
+
+ vc = mt7915_get_he_phy_cap(phy, vif);
+ ve = &vc->he_cap_elem;
+
+ bf->tx_mode = MT_PHY_TYPE_HE_SU;
+ bf->bf_cap |= MT_EBF;
+
+ mt7915_mcu_sta_sounding_rate(bf);
+
+ bf->trigger_su = HE_PHY(CAP6_TRIG_SU_BEAMFORMER_FB,
+ pe->phy_cap_info[6]);
+ bf->trigger_mu = HE_PHY(CAP6_TRIG_MU_BEAMFORMER_FB,
+ pe->phy_cap_info[6]);
+ bfer_nr = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
+ ve->phy_cap_info[5]);
+ bfee_nr = HE_PHY(CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK,
+ pe->phy_cap_info[4]);
+
+ mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.tx_mcs_80);
+ nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
+
+ bf->nr = min_t(u8, bfer_nr, bfee_nr);
+ bf->nc = min_t(u8, nss_mcs, bf->nr);
+ bf->ibf_ncol = bf->nc;
+
+ if (sta->bandwidth != IEEE80211_STA_RX_BW_160)
+ return;
+
+ /* go over for 160MHz and 80p80 */
+ if (pe->phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G) {
+ mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_160);
+ nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
+
+ bf->nc_bw160 = nss_mcs;
+ }
+
+ if (pe->phy_cap_info[0] &
+ IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) {
+ mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80p80);
+ nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
+
+ if (bf->nc_bw160)
+ bf->nc_bw160 = min_t(u8, bf->nc_bw160, nss_mcs);
+ else
+ bf->nc_bw160 = nss_mcs;
+ }
+
+ bfer_nr = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK,
+ ve->phy_cap_info[5]);
+ bfee_nr = HE_PHY(CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_MASK,
+ pe->phy_cap_info[4]);
+
+ bf->nr_bw160 = min_t(int, bfer_nr, bfee_nr);
+}
+
+static void
+mt7915_mcu_sta_bfer_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+ struct ieee80211_vif *vif, struct mt7915_phy *phy,
+ bool enable)
+{
+ struct sta_rec_bf *bf;
+ struct tlv *tlv;
+ int tx_ant = hweight8(phy->chainmask) - 1;
+ const u8 matrix[4][4] = {
+ {0, 0, 0, 0},
+ {1, 1, 0, 0}, /* 2x1, 2x2, 2x3, 2x4 */
+ {2, 4, 4, 0}, /* 3x1, 3x2, 3x3, 3x4 */
+ {3, 5, 6, 0} /* 4x1, 4x2, 4x3, 4x4 */
+ };
+
+#define MT_BFER_FREE cpu_to_le16(GENMASK(15, 0))
+
+ tlv = mt7915_mcu_add_tlv(skb, STA_REC_BF, sizeof(*bf));
+ bf = (struct sta_rec_bf *)tlv;
+
+ if (!enable) {
+ bf->pfmu = MT_BFER_FREE;
+ return;
+ }
+
+ bf->bw = sta->bandwidth;
+ bf->ibf_dbw = sta->bandwidth;
+ bf->ibf_nrow = tx_ant;
+ bf->ibf_timeout = 0x18;
+
+ if (sta->he_cap.has_he)
+ mt7915_mcu_sta_bfer_he(sta, vif, phy, bf);
+ else if (sta->vht_cap.vht_supported)
+ mt7915_mcu_sta_bfer_vht(sta, phy, bf);
+ else if (sta->ht_cap.ht_supported)
+ mt7915_mcu_sta_bfer_ht(sta, bf);
+
+ if (bf->bf_cap & MT_EBF && bf->nr != tx_ant)
+ bf->mem_20m = matrix[tx_ant][bf->nc];
+ else
+ bf->mem_20m = matrix[bf->nr][bf->nc];
+
+ switch (sta->bandwidth) {
+ case IEEE80211_STA_RX_BW_160:
+ case IEEE80211_STA_RX_BW_80:
+ bf->mem_total = bf->mem_20m * 2;
+ break;
+ case IEEE80211_STA_RX_BW_40:
+ bf->mem_total = bf->mem_20m;
+ break;
+ case IEEE80211_STA_RX_BW_20:
+ default:
+ break;
+ }
+}
+
+static u8
+mt7915_mcu_sta_txbf_type(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
+{
+ struct mt7915_sta *msta;
+ u8 type = 0;
+
+ if (vif->type != NL80211_IFTYPE_STATION &&
+ vif->type != NL80211_IFTYPE_AP)
+ return 0;
+
+ msta = (struct mt7915_sta *)sta->drv_priv;
+
+ if (sta->he_cap.has_he) {
+ struct ieee80211_he_cap_elem *pe;
+ const struct ieee80211_he_cap_elem *ve;
+ const struct ieee80211_sta_he_cap *vc;
+
+ pe = &sta->he_cap.he_cap_elem;
+ vc = mt7915_get_he_phy_cap(phy, vif);
+ ve = &vc->he_cap_elem;
+
+ if ((HE_PHY(CAP3_SU_BEAMFORMER, ve->phy_cap_info[3]) ||
+ HE_PHY(CAP4_MU_BEAMFORMER, ve->phy_cap_info[4])) &&
+ HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]))
+ type |= MT_STA_BFER;
+ } else if (sta->vht_cap.vht_supported) {
+ struct ieee80211_sta_vht_cap *pc;
+ struct ieee80211_sta_vht_cap *vc;
+ u32 cr, ce;
+
+ pc = &sta->vht_cap;
+ vc = &phy->mt76->sband_5g.sband.vht_cap;
+ cr = IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
+ IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
+ ce = IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+ IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+
+ if ((vc->cap & cr) && (pc->cap & ce))
+ type |= MT_STA_BFER;
+ } else if (sta->ht_cap.ht_supported) {
+ /* TODO: iBF */
+ }
+
+ return type;
+}
+
+static int
+mt7915_mcu_add_txbf(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, bool enable)
+{
+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+ struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+ struct mt7915_phy *phy;
+ struct sk_buff *skb;
+ int r, len;
+ u8 type;
+
+ phy = mvif->band_idx ? mt7915_ext_phy(dev) : &dev->phy;
+
+ type = mt7915_mcu_sta_txbf_type(phy, vif, sta);
+
+ /* must keep each tag independent */
+
+ /* starec bf */
+ if (type & MT_STA_BFER) {
+ len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_bf);
+
+ skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ mt7915_mcu_sta_bfer_tlv(skb, sta, vif, phy, enable);
+
+ r = __mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD_STA_REC_UPDATE, true);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+
static void
mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev,
struct ieee80211_vif *vif,
@@ -1724,6 +2014,25 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
MCU_EXT_CMD_STA_REC_UPDATE, true);
}
+int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, bool enable)
+{
+ int ret;
+
+ if (!sta)
+ return 0;
+
+ /* must keep the order */
+ ret = mt7915_mcu_add_txbf(dev, vif, sta, enable);
+ if (ret)
+ return ret;
+
+ if (enable)
+ return mt7915_mcu_add_rate_ctrl(dev, vif, sta);
+
+ return 0;
+}
+
int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable)
{
@@ -1732,7 +2041,6 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct mt7915_sta *msta;
struct tlv *sta_wtbl;
struct sk_buff *skb;
- int ret;
msta = sta ? (struct mt7915_sta *)sta->drv_priv : &mvif->sta;
@@ -1755,15 +2063,8 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
mt7915_mcu_wtbl_ht_tlv(skb, sta, sta_wtbl, wtbl_hdr);
}
- ret = __mt76_mcu_skb_send_msg(&dev->mt76, skb,
- MCU_EXT_CMD_STA_REC_UPDATE, true);
- if (ret)
- return ret;
-
- if (enable && sta)
- return mt7915_mcu_add_rate_ctrl(dev, vif, sta);
-
- return 0;
+ return __mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD_STA_REC_UPDATE, true);
}
int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
@@ -2767,3 +3068,40 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_SER_TRIGGER,
&req, sizeof(req), false);
}
+
+int mt7915_mcu_set_txbf_type(struct mt7915_dev *dev)
+{
+#define MT_BF_TYPE_UPDATE 20
+ struct {
+ u8 action;
+ bool ebf;
+ bool ibf;
+ u8 rsv;
+ } __packed req = {
+ .action = MT_BF_TYPE_UPDATE,
+ .ebf = true,
+ .ibf = false,
+ };
+
+ return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_TXBF_ACTION,
+ &req, sizeof(req), true);
+}
+
+int mt7915_mcu_set_txbf_sounding(struct mt7915_dev *dev)
+{
+#define MT_BF_PROCESSING 4
+ struct {
+ u8 action;
+ u8 snd_mode;
+ u8 sta_num;
+ u8 rsv;
+ u8 wlan_idx[4];
+ __le32 snd_period; /* ms */
+ } __packed req = {
+ .action = true,
+ .snd_mode = MT_BF_PROCESSING,
+ };
+
+ return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_TXBF_ACTION,
+ &req, sizeof(req), true);
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index f68d2094ac6f..53d1e1f0cea9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -194,6 +194,7 @@ enum {
MCU_EXT_CMD_PM_STATE_CTRL = 0x07,
MCU_EXT_CMD_CHANNEL_SWITCH = 0x08,
MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
+ MCU_EXT_CMD_TXBF_ACTION = 0x1e,
MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
@@ -571,18 +572,6 @@ struct wtbl_ba {
u8 rsv1[4];
} __packed;
-struct wtbl_bf {
- __le16 tag;
- __le16 len;
- u8 ibf;
- u8 ebf;
- u8 ibf_vht;
- u8 ebf_vht;
- u8 gid;
- u8 pfmu_idx;
- u8 rsv[2];
-} __packed;
-
struct wtbl_smps {
__le16 tag;
__le16 len;
@@ -590,13 +579,6 @@ struct wtbl_smps {
u8 rsv[3];
} __packed;
-struct wtbl_spe {
- __le16 tag;
- __le16 len;
- u8 spe_idx;
- u8 rsv[3];
-} __packed;
-
enum {
WTBL_GENERIC,
WTBL_RX,
@@ -834,6 +816,55 @@ struct sta_rec_ra_fixed {
#define RATE_CFG_LDPC GENMASK(23, 20)
#define RATE_CFG_PHY_TYPE GENMASK(27, 24)
+struct sta_rec_bf {
+ __le16 tag;
+ __le16 len;
+
+ __le16 pfmu; /* 0xffff: no access right for PFMU */
+ bool su_mu; /* 0: SU, 1: MU */
+ u8 bf_cap; /* 0: iBF, 1: eBF */
+ u8 sounding_phy; /* 0: legacy, 1: OFDM, 2: HT, 4: VHT */
+ u8 ndpa_rate;
+ u8 ndp_rate;
+ u8 rept_poll_rate;
+ u8 tx_mode; /* 0: legacy, 1: OFDM, 2: HT, 4: VHT ... */
+ u8 nc;
+ u8 nr;
+ u8 bw; /* 0: 20M, 1: 40M, 2: 80M, 3: 160M */
+
+ u8 mem_total;
+ u8 mem_20m;
+ struct {
+ u8 row;
+ u8 col: 6, row_msb: 2;
+ } mem[4];
+
+ __le16 smart_ant;
+ u8 se_idx;
+ u8 auto_sounding; /* b7: low traffic indicator
+ * b6: Stop sounding for this entry
+ * b5 ~ b0: postpone sounding
+ */
+ u8 ibf_timeout;
+ u8 ibf_dbw;
+ u8 ibf_ncol;
+ u8 ibf_nrow;
+ u8 nr_bw160;
+ u8 nc_bw160;
+ u8 ru_start_idx;
+ u8 ru_end_idx;
+
+ bool trigger_su;
+ bool trigger_mu;
+ bool ng16_su;
+ bool ng16_mu;
+ bool codebook42_su;
+ bool codebook75_mu;
+
+ u8 he_ltf;
+ u8 rsv[2];
+} __packed;
+
enum {
STA_REC_BASIC,
STA_REC_RA,
@@ -890,15 +921,18 @@ enum {
THERMAL_SENSOR_TASK_CTRL,
};
+enum {
+ MT_EBF = BIT(0), /* explicit beamforming */
+ MT_IBF = BIT(1) /* implicit beamforming */
+};
+
#define MT7915_WTBL_UPDATE_MAX_SIZE (sizeof(struct wtbl_req_hdr) + \
sizeof(struct wtbl_generic) + \
sizeof(struct wtbl_rx) + \
sizeof(struct wtbl_ht) + \
sizeof(struct wtbl_vht) + \
sizeof(struct wtbl_ba) + \
- sizeof(struct wtbl_bf) + \
- sizeof(struct wtbl_smps) + \
- sizeof(struct wtbl_spe))
+ sizeof(struct wtbl_smps))
#define MT7915_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
sizeof(struct sta_rec_basic) + \
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 43c956bc09f5..0d5b448292b5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -286,6 +286,8 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
struct ieee80211_vif *vif, int enable);
int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, bool enable);
+int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, bool enable);
int mt7915_mcu_add_tx_ba(struct mt7915_dev *dev,
struct ieee80211_ampdu_params *params,
bool add);
@@ -315,6 +317,8 @@ int mt7915_mcu_set_rts_thresh(struct mt7915_phy *phy, u32 val);
int mt7915_mcu_set_pm(struct mt7915_dev *dev, int band, int enter);
int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
int mt7915_mcu_set_sku(struct mt7915_phy *phy);
+int mt7915_mcu_set_txbf_type(struct mt7915_dev *dev);
+int mt7915_mcu_set_txbf_sounding(struct mt7915_dev *dev);
int mt7915_mcu_set_fcc5_lpn(struct mt7915_dev *dev, int val);
int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev,
const struct mt7915_dfs_pulse *pulse);
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/7] mt76: mt7915: add Tx beamformee support
2020-05-11 16:06 [PATCH 0/7] MT7915: add TxBF support Ryder Lee
2020-05-11 16:06 ` [PATCH 1/7] mt76: mt7915: introduce mt7915_get_he_phy_cap Ryder Lee
2020-05-11 16:06 ` [PATCH 2/7] mt76: mt7915: add Tx beamformer support Ryder Lee
@ 2020-05-11 16:06 ` Ryder Lee
2020-05-11 16:06 ` [PATCH 4/7] mt76: mt7915: add TxBF capabilities Ryder Lee
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ryder Lee @ 2020-05-11 16:06 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: linux-mediatek, Sean Wang, linux-wireless, Ryder Lee, Shayne Chen
Enable beamformee support.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 54 +++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/mcu.h | 9 ++++
2 files changed, 63 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 58d0adca8b31..52e349b17246 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -67,6 +67,7 @@ struct mt7915_fw_region {
#define MCU_PATCH_ADDRESS 0x200000
#define MT_STA_BFER BIT(0)
+#define MT_STA_BFEE BIT(1)
#define FW_FEATURE_SET_ENCRYPT BIT(0)
#define FW_FEATURE_SET_KEY_IDX GENMASK(2, 1)
@@ -1768,6 +1769,35 @@ mt7915_mcu_sta_bfer_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
}
}
+static void
+mt7915_mcu_sta_bfee_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
+ struct mt7915_phy *phy)
+{
+ struct sta_rec_bfee *bfee;
+ struct tlv *tlv;
+ int tx_ant = hweight8(phy->chainmask) - 1;
+ u8 nr = 0;
+
+ tlv = mt7915_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee));
+ bfee = (struct sta_rec_bfee *)tlv;
+
+ if (sta->he_cap.has_he) {
+ struct ieee80211_he_cap_elem *pe = &sta->he_cap.he_cap_elem;
+
+ nr = HE_PHY(CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK,
+ pe->phy_cap_info[5]);
+ } else if (sta->vht_cap.vht_supported) {
+ struct ieee80211_sta_vht_cap *pc = &sta->vht_cap;
+
+ nr = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
+ pc->cap);
+ }
+
+ /* reply with identity matrix to avoid 2x2 BF negative gain */
+ if (nr == 1 && tx_ant == 2)
+ bfee->fb_identity_matrix = true;
+}
+
static u8
mt7915_mcu_sta_txbf_type(struct mt7915_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
@@ -1790,6 +1820,11 @@ mt7915_mcu_sta_txbf_type(struct mt7915_phy *phy, struct ieee80211_vif *vif,
vc = mt7915_get_he_phy_cap(phy, vif);
ve = &vc->he_cap_elem;
+ if ((HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]) ||
+ HE_PHY(CAP4_MU_BEAMFORMER, pe->phy_cap_info[4])) &&
+ HE_PHY(CAP4_SU_BEAMFORMEE, ve->phy_cap_info[4]))
+ type |= MT_STA_BFEE;
+
if ((HE_PHY(CAP3_SU_BEAMFORMER, ve->phy_cap_info[3]) ||
HE_PHY(CAP4_MU_BEAMFORMER, ve->phy_cap_info[4])) &&
HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]))
@@ -1806,6 +1841,9 @@ mt7915_mcu_sta_txbf_type(struct mt7915_phy *phy, struct ieee80211_vif *vif,
ce = IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
+ if ((pc->cap & cr) && (vc->cap & ce))
+ type |= MT_STA_BFEE;
+
if ((vc->cap & cr) && (pc->cap & ce))
type |= MT_STA_BFER;
} else if (sta->ht_cap.ht_supported) {
@@ -1848,6 +1886,22 @@ mt7915_mcu_add_txbf(struct mt7915_dev *dev, struct ieee80211_vif *vif,
return r;
}
+ /* starec bfee */
+ if (type & MT_STA_BFEE) {
+ len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_bfee);
+
+ skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ mt7915_mcu_sta_bfee_tlv(skb, sta, phy);
+
+ r = __mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_EXT_CMD_STA_REC_UPDATE, true);
+ if (r)
+ return r;
+ }
+
return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 53d1e1f0cea9..cdeba5a0ef34 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -865,6 +865,14 @@ struct sta_rec_bf {
u8 rsv[2];
} __packed;
+struct sta_rec_bfee {
+ __le16 tag;
+ __le16 len;
+ bool fb_identity_matrix; /* 1: feedback identity matrix */
+ bool ignore_feedback; /* 1: ignore */
+ u8 rsv[2];
+} __packed;
+
enum {
STA_REC_BASIC,
STA_REC_RA,
@@ -886,6 +894,7 @@ enum {
STA_REC_KEY_V2,
STA_REC_MURU,
STA_REC_MUEDCA,
+ STA_REC_BFEE,
STA_REC_MAX_NUM
};
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/7] mt76: mt7915: add TxBF capabilities
2020-05-11 16:06 [PATCH 0/7] MT7915: add TxBF support Ryder Lee
` (2 preceding siblings ...)
2020-05-11 16:06 ` [PATCH 3/7] mt76: mt7915: add Tx beamformee support Ryder Lee
@ 2020-05-11 16:06 ` Ryder Lee
2020-05-11 16:06 ` [PATCH 5/7] mt76: mt7915: add debugfs to track TxBF status Ryder Lee
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Ryder Lee @ 2020-05-11 16:06 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: linux-mediatek, Sean Wang, linux-wireless, Ryder Lee, Shayne Chen
This allows to set HE TxBF runtime stream capabilities
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Tested-by: Evelyn Tsai <evelyn.tsai@mediatek.com
---
.../net/wireless/mediatek/mt76/mt7915/init.c | 95 ++++++++++++++++++-
.../net/wireless/mediatek/mt76/mt7915/main.c | 1 +
.../wireless/mediatek/mt76/mt7915/mt7915.h | 1 +
3 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 3721bd632b4d..e2b0ea33053c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -259,6 +259,94 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
hw->max_tx_fragments = 4;
}
+void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy)
+{
+ int nss = hweight8(phy->chainmask);
+ u32 *cap = &phy->mt76->sband_5g.sband.vht_cap.cap;
+
+ *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
+ IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
+ (3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
+
+ *cap &= ~(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK |
+ IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
+ IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);
+
+ if (nss < 2)
+ return;
+
+ *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
+ IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE |
+ FIELD_PREP(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
+ nss - 1);
+}
+
+static void
+mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap,
+ int vif, int nss)
+{
+ struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
+ struct ieee80211_he_mcs_nss_supp *mcs = &he_cap->he_mcs_nss_supp;
+ u8 c;
+
+#ifdef CONFIG_MAC80211_MESH
+ if (vif == NL80211_IFTYPE_MESH_POINT)
+ return;
+#endif
+
+ elem->phy_cap_info[3] &= ~IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
+ elem->phy_cap_info[4] &= ~IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
+
+ c = IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK |
+ IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
+ elem->phy_cap_info[5] &= ~c;
+
+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
+ elem->phy_cap_info[6] &= ~c;
+
+ elem->phy_cap_info[7] &= ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;
+
+ c = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
+ IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
+ elem->phy_cap_info[2] |= c;
+
+ c = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 |
+ IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4;
+ elem->phy_cap_info[4] |= c;
+
+ /* do not support NG16 due to spec D4.0 changes subcarrier idx */
+ c = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
+ IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU;
+
+ if (vif == NL80211_IFTYPE_STATION)
+ c |= IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;
+
+ elem->phy_cap_info[6] |= c;
+
+ if (nss < 2)
+ return;
+
+ if (vif != NL80211_IFTYPE_AP)
+ return;
+
+ elem->phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
+ elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
+
+ /* num_snd_dim */
+ c = (nss - 1) | (max_t(int, mcs->tx_mcs_160, 1) << 3);
+ elem->phy_cap_info[5] |= c;
+
+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
+ elem->phy_cap_info[6] |= c;
+
+ /* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */
+ elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3;
+}
+
static void
mt7915_gen_ppe_thresh(u8 *he_ppet)
{
@@ -352,11 +440,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
he_cap_elem->phy_cap_info[1] =
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
he_cap_elem->phy_cap_info[2] =
- IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ;
- /* TODO: TxBF & MU & MESH */
+ /* TODO: OFDMA */
switch (i) {
case NL80211_IFTYPE_AP:
@@ -407,6 +494,8 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
he_mcs->rx_mcs_80p80 = cpu_to_le16(mcs_map);
he_mcs->tx_mcs_80p80 = cpu_to_le16(mcs_map);
+ mt7915_set_stream_he_txbf_caps(he_cap, i, nss);
+
memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
if (he_cap_elem->phy_cap_info[6] &
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
@@ -464,6 +553,7 @@ mt7915_cap_dbdc_enable(struct mt7915_dev *dev)
dev->mphy.hw->wiphy->available_antennas_tx = dev->phy.chainmask;
mt76_set_stream_caps(&dev->mphy, true);
+ mt7915_set_stream_vht_txbf_caps(&dev->phy);
mt7915_set_stream_he_caps(&dev->phy);
}
@@ -480,6 +570,7 @@ mt7915_cap_dbdc_disable(struct mt7915_dev *dev)
dev->mphy.hw->wiphy->available_antennas_tx = dev->chainmask;
mt76_set_stream_caps(&dev->mphy, true);
+ mt7915_set_stream_vht_txbf_caps(&dev->phy);
mt7915_set_stream_he_caps(&dev->phy);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index f3a373fc07e5..147ab7da7aa9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -745,6 +745,7 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
phy->chainmask = tx_ant;
mt76_set_stream_caps(phy->mt76, true);
+ mt7915_set_stream_vht_txbf_caps(phy);
mt7915_set_stream_he_caps(phy);
mutex_unlock(&dev->mt76.mutex);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 0d5b448292b5..537fc126289f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -454,6 +454,7 @@ void mt7915_txp_skb_unmap(struct mt76_dev *dev,
int mt76_dfs_start_rdd(struct mt7915_dev *dev, bool force);
int mt7915_dfs_init_radar_detector(struct mt7915_phy *phy);
void mt7915_set_stream_he_caps(struct mt7915_phy *phy);
+void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy);
void mt7915_update_channel(struct mt76_dev *mdev);
int mt7915_init_debugfs(struct mt7915_dev *dev);
#ifdef CONFIG_MAC80211_DEBUGFS
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/7] mt76: mt7915: add debugfs to track TxBF status
2020-05-11 16:06 [PATCH 0/7] MT7915: add TxBF support Ryder Lee
` (3 preceding siblings ...)
2020-05-11 16:06 ` [PATCH 4/7] mt76: mt7915: add TxBF capabilities Ryder Lee
@ 2020-05-11 16:06 ` Ryder Lee
2020-05-11 16:06 ` [PATCH 6/7] mt76: mt7915: allocate proper size for tlv tags Ryder Lee
2020-05-11 16:06 ` [PATCH 7/7] mt76: mt7915: fix possible deadlock in mt7915_stop Ryder Lee
6 siblings, 0 replies; 8+ messages in thread
From: Ryder Lee @ 2020-05-11 16:06 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: linux-mediatek, Sean Wang, linux-wireless, Ryder Lee, Shayne Chen
Add debug counters to track status of beamformer and beamformee.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
.../wireless/mediatek/mt76/mt7915/debugfs.c | 45 +++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7915/regs.h | 20 +++++++++
2 files changed, 65 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
index c6c009cd773e..ee0066fedd04 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -143,6 +143,48 @@ mt7915_ampdu_stat_read_phy(struct mt7915_phy *phy,
seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
}
+static void
+mt7915_txbf_stat_read_phy(struct mt7915_phy *phy, struct seq_file *s)
+{
+ struct mt7915_dev *dev = s->private;
+ bool ext_phy = phy != &dev->phy;
+ int cnt;
+
+ if (!phy)
+ return;
+
+ /* Tx Beamformer monitor */
+ seq_puts(s, "\nTx Beamformer applied PPDU counts: ");
+
+ cnt = mt76_rr(dev, MT_ETBF_TX_APP_CNT(ext_phy));
+ seq_printf(s, "iBF: %ld, eBF: %ld\n",
+ FIELD_GET(MT_ETBF_TX_IBF_CNT, cnt),
+ FIELD_GET(MT_ETBF_TX_EBF_CNT, cnt));
+
+ /* Tx Beamformer Rx feedback monitor */
+ seq_puts(s, "Tx Beamformer Rx feedback statistics: ");
+
+ cnt = mt76_rr(dev, MT_ETBF_RX_FB_CNT(ext_phy));
+ seq_printf(s, "All: %ld, HE: %ld, VHT: %ld, HT: %ld\n",
+ FIELD_GET(MT_ETBF_RX_FB_ALL, cnt),
+ FIELD_GET(MT_ETBF_RX_FB_HE, cnt),
+ FIELD_GET(MT_ETBF_RX_FB_VHT, cnt),
+ FIELD_GET(MT_ETBF_RX_FB_HT, cnt));
+
+ /* Tx Beamformee Rx NDPA & Tx feedback report */
+ cnt = mt76_rr(dev, MT_ETBF_TX_NDP_BFRP(ext_phy));
+ seq_printf(s, "Tx Beamformee sucessful feedback frames: %ld\n",
+ FIELD_GET(MT_ETBF_TX_FB_CPL, cnt));
+ seq_printf(s, "Tx Beamformee feedback triggerd counts: %ld\n",
+ FIELD_GET(MT_ETBF_TX_FB_TRI, cnt));
+
+ /* Tx SU counters */
+ cnt = mt76_rr(dev, MT_MIB_DR11(ext_phy));
+ seq_printf(s, "Tx single-user sucessful MPDU counts: %d\n", cnt);
+
+ seq_puts(s, "\n");
+}
+
static int
mt7915_tx_stats_read(struct seq_file *file, void *data)
{
@@ -150,7 +192,10 @@ mt7915_tx_stats_read(struct seq_file *file, void *data)
int stat[8], i, n;
mt7915_ampdu_stat_read_phy(&dev->phy, file);
+ mt7915_txbf_stat_read_phy(&dev->phy, file);
+
mt7915_ampdu_stat_read_phy(mt7915_ext_phy(dev), file);
+ mt7915_txbf_stat_read_phy(mt7915_ext_phy(dev), file);
/* Tx amsdu info */
seq_puts(file, "Tx MSDU stat:\n");
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index 6600fc625196..c121715f8bff 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -75,6 +75,24 @@
#define MT_DMA_DCR0_MAX_RX_LEN GENMASK(15, 3)
#define MT_DMA_DCR0_RXD_G5_EN BIT(23)
+/* ETBF: band 0(0x24000), band 1(0xa4000) */
+#define MT_WF_ETBF_BASE(_band) ((_band) ? 0xa4000 : 0x24000)
+#define MT_WF_ETBF(_band, ofs) (MT_WF_ETBF_BASE(_band) + (ofs))
+
+#define MT_ETBF_TX_NDP_BFRP(_band) MT_WF_ETBF(_band, 0x040)
+#define MT_ETBF_TX_FB_CPL GENMASK(31, 16)
+#define MT_ETBF_TX_FB_TRI GENMASK(15, 0)
+
+#define MT_ETBF_TX_APP_CNT(_band) MT_WF_ETBF(_band, 0x0f0)
+#define MT_ETBF_TX_IBF_CNT GENMASK(31, 16)
+#define MT_ETBF_TX_EBF_CNT GENMASK(15, 0)
+
+#define MT_ETBF_RX_FB_CNT(_band) MT_WF_ETBF(_band, 0x0f8)
+#define MT_ETBF_RX_FB_ALL GENMASK(31, 24)
+#define MT_ETBF_RX_FB_HE GENMASK(23, 16)
+#define MT_ETBF_RX_FB_VHT GENMASK(15, 8)
+#define MT_ETBF_RX_FB_HT GENMASK(7, 0)
+
/* LPON: band 0(0x24200), band 1(0xa4200) */
#define MT_WF_LPON_BASE(_band) ((_band) ? 0xa4200 : 0x24200)
#define MT_WF_LPON(_band, ofs) (MT_WF_LPON_BASE(_band) + (ofs))
@@ -104,6 +122,8 @@
#define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x09c)
#define MT_MIB_SDR37_RXTIME_MASK GENMASK(23, 0)
+#define MT_MIB_DR11(_band) MT_WF_MIB(_band, 0x0cc)
+
#define MT_MIB_MB_SDR0(_band, n) MT_WF_MIB(_band, 0x100 + ((n) << 4))
#define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16)
#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0)
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/7] mt76: mt7915: allocate proper size for tlv tags
2020-05-11 16:06 [PATCH 0/7] MT7915: add TxBF support Ryder Lee
` (4 preceding siblings ...)
2020-05-11 16:06 ` [PATCH 5/7] mt76: mt7915: add debugfs to track TxBF status Ryder Lee
@ 2020-05-11 16:06 ` Ryder Lee
2020-05-11 16:06 ` [PATCH 7/7] mt76: mt7915: fix possible deadlock in mt7915_stop Ryder Lee
6 siblings, 0 replies; 8+ messages in thread
From: Ryder Lee @ 2020-05-11 16:06 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: linux-mediatek, Sean Wang, linux-wireless, Ryder Lee, Shayne Chen
Allocating proper memory size according to tlv usage.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c | 14 +++++++-------
drivers/net/wireless/mediatek/mt76/mt7915/mcu.h | 12 ++++++++++--
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 52e349b17246..f00ad2b66761 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -997,7 +997,7 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
struct sk_buff *skb;
skb = mt7915_mcu_alloc_sta_req(phy->dev, mvif, NULL,
- MT7915_STA_UPDATE_MAX_SIZE);
+ MT7915_BSS_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
@@ -1092,10 +1092,10 @@ int mt7915_mcu_add_key(struct mt7915_dev *dev, struct ieee80211_vif *vif,
{
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct sk_buff *skb;
+ int len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_sec);
int ret;
- skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
- MT7915_STA_UPDATE_MAX_SIZE);
+ skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
@@ -2056,9 +2056,9 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
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_ra);
- skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
- MT7915_STA_UPDATE_MAX_SIZE);
+ skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
@@ -2129,9 +2129,9 @@ int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
struct sta_rec_ra_fixed *ra;
struct sk_buff *skb;
struct tlv *tlv;
+ int len = sizeof(struct sta_req_hdr) + sizeof(*ra);
- skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
- MT7915_STA_UPDATE_MAX_SIZE);
+ skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
if (IS_ERR(skb))
return PTR_ERR(skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index cdeba5a0ef34..34ace6e672d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -951,13 +951,21 @@ enum {
sizeof(struct sta_rec_vht) + \
sizeof(struct tlv) + \
sizeof(struct sta_rec_muru) + \
- sizeof(struct sta_rec_sec) + \
- sizeof(struct sta_rec_ra) + \
MT7915_WTBL_UPDATE_MAX_SIZE)
#define MT7915_WTBL_UPDATE_BA_SIZE (sizeof(struct wtbl_req_hdr) + \
sizeof(struct wtbl_ba))
+#define MT7915_BSS_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
+ sizeof(struct bss_info_omac) + \
+ sizeof(struct bss_info_basic) +\
+ sizeof(struct bss_info_rf_ch) +\
+ sizeof(struct bss_info_ra) + \
+ sizeof(struct bss_info_he) + \
+ sizeof(struct bss_info_bmc_rate) +\
+ sizeof(struct bss_info_ext_bss) +\
+ sizeof(struct bss_info_sync_mode))
+
#define MT7915_BEACON_UPDATE_SIZE (sizeof(struct sta_req_hdr) + \
sizeof(struct bss_info_bcn_csa) + \
sizeof(struct bss_info_bcn_bcc) + \
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 7/7] mt76: mt7915: fix possible deadlock in mt7915_stop
2020-05-11 16:06 [PATCH 0/7] MT7915: add TxBF support Ryder Lee
` (5 preceding siblings ...)
2020-05-11 16:06 ` [PATCH 6/7] mt76: mt7915: allocate proper size for tlv tags Ryder Lee
@ 2020-05-11 16:06 ` Ryder Lee
6 siblings, 0 replies; 8+ messages in thread
From: Ryder Lee @ 2020-05-11 16:06 UTC (permalink / raw)
To: Felix Fietkau, Lorenzo Bianconi
Cc: linux-mediatek, Sean Wang, linux-wireless, Ryder Lee, Shayne Chen
make mac_work per phy instead of per device and fix a possible deadlock
in mt7915_stop since mt7915_mac_work runs holding mt76 mutex
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt7915/init.c | 3 +-
.../net/wireless/mediatek/mt76/mt7915/mac.c | 49 +++++++++++--------
.../net/wireless/mediatek/mt76/mt7915/main.c | 18 +++----
.../wireless/mediatek/mt76/mt7915/mt7915.h | 4 +-
4 files changed, 42 insertions(+), 32 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index e2b0ea33053c..6f200ab3ac28 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -592,6 +592,7 @@ int mt7915_register_ext_phy(struct mt7915_dev *dev)
if (phy)
return 0;
+ INIT_DELAYED_WORK(&phy->mac_work, mt7915_mac_work);
mt7915_cap_dbdc_enable(dev);
mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7915_ops);
if (!mphy)
@@ -642,7 +643,7 @@ int mt7915_register_device(struct mt7915_dev *dev)
dev->phy.dev = dev;
dev->phy.mt76 = &dev->mt76.phy;
dev->mt76.phy.priv = &dev->phy;
- INIT_DELAYED_WORK(&dev->mt76.mac_work, mt7915_mac_work);
+ INIT_DELAYED_WORK(&dev->phy.mac_work, mt7915_mac_work);
INIT_LIST_HEAD(&dev->sta_poll_list);
spin_lock_init(&dev->sta_poll_lock);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 751363b4b7a2..7ad7c2b7afdc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -1156,26 +1156,32 @@ mt7915_dma_reset(struct mt7915_dev *dev)
/* system error recovery */
void mt7915_mac_reset_work(struct work_struct *work)
{
+ struct mt7915_phy *phy2;
+ struct mt76_phy *ext_phy;
struct mt7915_dev *dev;
dev = container_of(work, struct mt7915_dev, reset_work);
+ ext_phy = dev->mt76.phy2;
+ phy2 = ext_phy ? ext_phy->priv : NULL;
if (!(READ_ONCE(dev->reset_state) & MT_MCU_CMD_STOP_DMA))
return;
ieee80211_stop_queues(mt76_hw(dev));
- if (dev->mt76.phy2)
- ieee80211_stop_queues(dev->mt76.phy2->hw);
+ if (ext_phy)
+ ieee80211_stop_queues(ext_phy->hw);
set_bit(MT76_RESET, &dev->mphy.state);
set_bit(MT76_MCU_RESET, &dev->mphy.state);
wake_up(&dev->mt76.mcu.wait);
- cancel_delayed_work_sync(&dev->mt76.mac_work);
+ cancel_delayed_work_sync(&dev->phy.mac_work);
+ if (phy2)
+ cancel_delayed_work_sync(&phy2->mac_work);
/* lock/unlock all queues to ensure that no tx is pending */
mt76_txq_schedule_all(&dev->mphy);
- if (dev->mt76.phy2)
- mt76_txq_schedule_all(dev->mt76.phy2);
+ if (ext_phy)
+ mt76_txq_schedule_all(ext_phy);
tasklet_disable(&dev->mt76.tx_tasklet);
napi_disable(&dev->mt76.napi[0]);
@@ -1211,8 +1217,8 @@ void mt7915_mac_reset_work(struct work_struct *work)
napi_schedule(&dev->mt76.napi[2]);
ieee80211_wake_queues(mt76_hw(dev));
- if (dev->mt76.phy2)
- ieee80211_wake_queues(dev->mt76.phy2->hw);
+ if (ext_phy)
+ ieee80211_wake_queues(ext_phy->hw);
mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
mt7915_wait_reset_state(dev, MT_MCU_CMD_NORMAL_STATE);
@@ -1221,8 +1227,11 @@ void mt7915_mac_reset_work(struct work_struct *work)
mt7915_update_beacons(dev);
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->phy.mac_work,
MT7915_WATCHDOG_TIME);
+ if (phy2)
+ ieee80211_queue_delayed_work(ext_phy->hw, &phy2->mac_work,
+ MT7915_WATCHDOG_TIME);
}
static void
@@ -1307,25 +1316,25 @@ void mt7915_mac_sta_stats_work(struct work_struct *work)
void mt7915_mac_work(struct work_struct *work)
{
- struct mt7915_dev *dev;
+ struct mt7915_phy *phy;
+ struct mt76_dev *mdev;
- dev = (struct mt7915_dev *)container_of(work, struct mt76_dev,
+ phy = (struct mt7915_phy *)container_of(work, struct mt7915_phy,
mac_work.work);
+ mdev = &phy->dev->mt76;
- mutex_lock(&dev->mt76.mutex);
- mt76_update_survey(&dev->mt76);
- if (++dev->mac_work_count == 5) {
- struct mt7915_phy *ext_phy = mt7915_ext_phy(dev);
+ mutex_lock(&mdev->mutex);
- mt7915_mac_update_mib_stats(&dev->phy);
- if (ext_phy)
- mt7915_mac_update_mib_stats(ext_phy);
+ mt76_update_survey(mdev);
+ if (++phy->mac_work_count == 5) {
+ phy->mac_work_count = 0;
- dev->mac_work_count = 0;
+ mt7915_mac_update_mib_stats(phy);
}
- mutex_unlock(&dev->mt76.mutex);
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
+ mutex_unlock(&mdev->mutex);
+
+ ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
MT7915_WATCHDOG_TIME);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
index 147ab7da7aa9..98567374c2c9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c
@@ -47,14 +47,12 @@ static int mt7915_start(struct ieee80211_hw *hw)
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
- if (running)
- goto out;
+ ieee80211_queue_delayed_work(hw, &phy->mac_work,
+ MT7915_WATCHDOG_TIME);
- mt7915_mac_reset_counters(phy);
+ if (!running)
+ mt7915_mac_reset_counters(phy);
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
- MT7915_WATCHDOG_TIME);
-out:
mutex_unlock(&dev->mt76.mutex);
return 0;
@@ -65,6 +63,8 @@ static void mt7915_stop(struct ieee80211_hw *hw)
struct mt7915_dev *dev = mt7915_hw_dev(hw);
struct mt7915_phy *phy = mt7915_hw_phy(hw);
+ cancel_delayed_work_sync(&phy->mac_work);
+
mutex_lock(&dev->mt76.mutex);
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
@@ -75,8 +75,6 @@ static void mt7915_stop(struct ieee80211_hw *hw)
}
if (!mt7915_dev_running(dev)) {
- cancel_delayed_work_sync(&dev->mt76.mac_work);
-
mt7915_mcu_set_pm(dev, 0, 1);
mt7915_mcu_set_mac(dev, 0, false, false);
}
@@ -230,7 +228,7 @@ static int mt7915_set_channel(struct mt7915_phy *phy)
struct mt7915_dev *dev = phy->dev;
int ret;
- cancel_delayed_work_sync(&dev->mt76.mac_work);
+ cancel_delayed_work_sync(&phy->mac_work);
mutex_lock(&dev->mt76.mutex);
set_bit(MT76_RESET, &phy->mt76->state);
@@ -254,7 +252,7 @@ static int mt7915_set_channel(struct mt7915_phy *phy)
mutex_unlock(&dev->mt76.mutex);
mt76_txq_schedule_all(phy->mt76);
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
+ ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
MT7915_WATCHDOG_TIME);
return ret;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 537fc126289f..5392292a838e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -141,6 +141,9 @@ struct mt7915_phy {
u32 ampdu_ref;
struct mib_stats mib;
+
+ struct delayed_work mac_work;
+ u8 mac_work_count;
};
struct mt7915_dev {
@@ -168,7 +171,6 @@ struct mt7915_dev {
s8 **rate_power; /* TODO: use mt76_rate_power */
- u8 mac_work_count;
bool fw_debug;
};
--
2.18.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-05-11 16:07 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-11 16:06 [PATCH 0/7] MT7915: add TxBF support Ryder Lee
2020-05-11 16:06 ` [PATCH 1/7] mt76: mt7915: introduce mt7915_get_he_phy_cap Ryder Lee
2020-05-11 16:06 ` [PATCH 2/7] mt76: mt7915: add Tx beamformer support Ryder Lee
2020-05-11 16:06 ` [PATCH 3/7] mt76: mt7915: add Tx beamformee support Ryder Lee
2020-05-11 16:06 ` [PATCH 4/7] mt76: mt7915: add TxBF capabilities Ryder Lee
2020-05-11 16:06 ` [PATCH 5/7] mt76: mt7915: add debugfs to track TxBF status Ryder Lee
2020-05-11 16:06 ` [PATCH 6/7] mt76: mt7915: allocate proper size for tlv tags Ryder Lee
2020-05-11 16:06 ` [PATCH 7/7] mt76: mt7915: fix possible deadlock in mt7915_stop Ryder Lee
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).