diff options
Diffstat (limited to 'drivers/net/wireless/mediatek/mt76/mt7921')
18 files changed, 636 insertions, 1716 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/Makefile b/drivers/net/wireless/mediatek/mt76/mt7921/Makefile index 0a146818c623..e5d2d2e131a2 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/Makefile +++ b/drivers/net/wireless/mediatek/mt76/mt7921/Makefile @@ -9,6 +9,7 @@ CFLAGS_trace.o := -I$(src) mt7921-common-y := mac.o mcu.o main.o init.o debugfs.o trace.o mt7921-common-$(CONFIG_NL80211_TESTMODE) += testmode.o +mt7921-common-$(CONFIG_ACPI) += acpi_sar.o mt7921e-y := pci.o pci_mac.o pci_mcu.o dma.o mt7921s-y := sdio.o sdio_mac.o sdio_mcu.o mt7921u-y := usb.o usb_mac.o diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c new file mode 100644 index 000000000000..be4f07ad3af9 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.c @@ -0,0 +1,279 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2022 MediaTek Inc. */ + +#include <linux/acpi.h> +#include "mt7921.h" + +static int +mt7921_acpi_read(struct mt7921_dev *dev, u8 *method, u8 **tbl, u32 *len) +{ + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *sar_root, *sar_unit; + struct mt76_dev *mdev = &dev->mt76; + acpi_handle root, handle; + acpi_status status; + u32 i = 0; + + root = ACPI_HANDLE(mdev->dev); + if (!root) + return -EOPNOTSUPP; + + status = acpi_get_handle(root, method, &handle); + if (ACPI_FAILURE(status)) + return -EIO; + + status = acpi_evaluate_object(handle, NULL, NULL, &buf); + if (ACPI_FAILURE(status)) + return -EIO; + + sar_root = buf.pointer; + if (sar_root->type != ACPI_TYPE_PACKAGE || + sar_root->package.count < 4 || + sar_root->package.elements[0].type != ACPI_TYPE_INTEGER) { + dev_err(mdev->dev, "sar cnt = %d\n", + sar_root->package.count); + goto free; + } + + if (!*tbl) { + *tbl = devm_kzalloc(mdev->dev, sar_root->package.count, + GFP_KERNEL); + if (!*tbl) + goto free; + } + if (len) + *len = sar_root->package.count; + + for (i = 0; i < sar_root->package.count; i++) { + sar_unit = &sar_root->package.elements[i]; + + if (sar_unit->type != ACPI_TYPE_INTEGER) + break; + *(*tbl + i) = (u8)sar_unit->integer.value; + } +free: + kfree(sar_root); + + return (i == sar_root->package.count) ? 0 : -EINVAL; +} + +/* MTCL : Country List Table for 6G band */ +static int +mt7921_asar_acpi_read_mtcl(struct mt7921_dev *dev, u8 **table, u8 *version) +{ + *version = (mt7921_acpi_read(dev, MT7921_ACPI_MTCL, table, NULL) < 0) + ? 1 : 2; + return 0; +} + +/* MTDS : Dynamic SAR Power Table */ +static int +mt7921_asar_acpi_read_mtds(struct mt7921_dev *dev, u8 **table, u8 version) +{ + int len, ret, sarlen, prelen, tblcnt; + bool enable; + + ret = mt7921_acpi_read(dev, MT7921_ACPI_MTDS, table, &len); + if (ret) + return ret; + + /* Table content validation */ + switch (version) { + case 1: + enable = ((struct mt7921_asar_dyn *)*table)->enable; + sarlen = sizeof(struct mt7921_asar_dyn_limit); + prelen = sizeof(struct mt7921_asar_dyn); + break; + case 2: + enable = ((struct mt7921_asar_dyn_v2 *)*table)->enable; + sarlen = sizeof(struct mt7921_asar_dyn_limit_v2); + prelen = sizeof(struct mt7921_asar_dyn_v2); + break; + default: + return -EINVAL; + } + + tblcnt = (len - prelen) / sarlen; + if (!enable || + tblcnt > MT7921_ASAR_MAX_DYN || tblcnt < MT7921_ASAR_MIN_DYN) + ret = -EINVAL; + + return ret; +} + +/* MTGS : Geo SAR Power Table */ +static int +mt7921_asar_acpi_read_mtgs(struct mt7921_dev *dev, u8 **table, u8 version) +{ + int len, ret = 0, sarlen, prelen, tblcnt; + + ret = mt7921_acpi_read(dev, MT7921_ACPI_MTGS, table, &len); + if (ret) + return ret; + + /* Table content validation */ + switch (version) { + case 1: + sarlen = sizeof(struct mt7921_asar_geo_limit); + prelen = sizeof(struct mt7921_asar_geo); + break; + case 2: + sarlen = sizeof(struct mt7921_asar_geo_limit_v2); + prelen = sizeof(struct mt7921_asar_geo_v2); + break; + default: + return -EINVAL; + } + + tblcnt = (len - prelen) / sarlen; + if (tblcnt > MT7921_ASAR_MAX_GEO || tblcnt < MT7921_ASAR_MIN_GEO) + ret = -EINVAL; + + return ret; +} + +int mt7921_init_acpi_sar(struct mt7921_dev *dev) +{ + struct mt7921_acpi_sar *asar; + int ret; + + asar = devm_kzalloc(dev->mt76.dev, sizeof(*asar), GFP_KERNEL); + if (!asar) + return -ENOMEM; + + mt7921_asar_acpi_read_mtcl(dev, (u8 **)&asar->countrylist, &asar->ver); + + /* MTDS is mandatory. Return error if table is invalid */ + ret = mt7921_asar_acpi_read_mtds(dev, (u8 **)&asar->dyn, asar->ver); + if (ret) { + devm_kfree(dev->mt76.dev, asar->dyn); + devm_kfree(dev->mt76.dev, asar->countrylist); + devm_kfree(dev->mt76.dev, asar); + return ret; + } + + /* MTGS is optional */ + ret = mt7921_asar_acpi_read_mtgs(dev, (u8 **)&asar->geo, asar->ver); + if (ret) { + devm_kfree(dev->mt76.dev, asar->geo); + asar->geo = NULL; + } + + dev->phy.acpisar = asar; + + return 0; +} + +static s8 +mt7921_asar_get_geo_pwr(struct mt7921_phy *phy, + enum nl80211_band band, s8 dyn_power) +{ + struct mt7921_acpi_sar *asar = phy->acpisar; + struct mt7921_asar_geo_band *band_pwr; + s8 geo_power; + u8 idx, max; + + if (!asar->geo) + return dyn_power; + + switch (phy->mt76->dev->region) { + case NL80211_DFS_FCC: + idx = 0; + break; + case NL80211_DFS_ETSI: + idx = 1; + break; + default: /* WW */ + idx = 2; + break; + } + + if (asar->ver == 1) { + band_pwr = &asar->geo->tbl[idx].band[0]; + max = ARRAY_SIZE(asar->geo->tbl[idx].band); + } else { + band_pwr = &asar->geo_v2->tbl[idx].band[0]; + max = ARRAY_SIZE(asar->geo_v2->tbl[idx].band); + } + + switch (band) { + case NL80211_BAND_2GHZ: + idx = 0; + break; + case NL80211_BAND_5GHZ: + idx = 1; + break; + case NL80211_BAND_6GHZ: + idx = 2; + break; + default: + return dyn_power; + } + + if (idx >= max) + return dyn_power; + + geo_power = (band_pwr + idx)->pwr; + dyn_power += (band_pwr + idx)->offset; + + return min(geo_power, dyn_power); +} + +static s8 +mt7921_asar_range_pwr(struct mt7921_phy *phy, + const struct cfg80211_sar_freq_ranges *range, + u8 idx) +{ + const struct cfg80211_sar_capa *capa = phy->mt76->hw->wiphy->sar_capa; + struct mt7921_acpi_sar *asar = phy->acpisar; + u8 *limit, band, max; + + if (!capa) + return 127; + + if (asar->ver == 1) { + limit = &asar->dyn->tbl[0].frp[0]; + max = ARRAY_SIZE(asar->dyn->tbl[0].frp); + } else { + limit = &asar->dyn_v2->tbl[0].frp[0]; + max = ARRAY_SIZE(asar->dyn_v2->tbl[0].frp); + } + + if (idx >= max) + return 127; + + if (range->start_freq >= 5945) + band = NL80211_BAND_6GHZ; + else if (range->start_freq >= 5150) + band = NL80211_BAND_5GHZ; + else + band = NL80211_BAND_2GHZ; + + return mt7921_asar_get_geo_pwr(phy, band, limit[idx]); +} + +int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default) +{ + const struct cfg80211_sar_capa *capa = phy->mt76->hw->wiphy->sar_capa; + int i; + + if (!phy->acpisar) + return 0; + + /* When ACPI SAR enabled in HW, we should apply rules for .frp + * 1. w/o .sar_specs : set ACPI SAR power as the defatul value + * 2. w/ .sar_specs : set power with min(.sar_specs, ACPI_SAR) + */ + for (i = 0; i < capa->num_freq_ranges; i++) { + struct mt76_freq_range_power *frp = &phy->mt76->frp[i]; + + frp->range = set_default ? &capa->freq_ranges[i] : frp->range; + if (!frp->range) + continue; + + frp->power = min_t(s8, set_default ? 127 : frp->power, + mt7921_asar_range_pwr(phy, frp->range, i)); + } + + return 0; +} diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h new file mode 100644 index 000000000000..23f86bfae0c0 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/mt7921/acpi_sar.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: ISC */ +/* Copyright (C) 2022 MediaTek Inc. */ + +#ifndef __MT7921_ACPI_SAR_H +#define __MT7921_ACPI_SAR_H + +#define MT7921_ASAR_MIN_DYN 1 +#define MT7921_ASAR_MAX_DYN 8 +#define MT7921_ASAR_MIN_GEO 3 +#define MT7921_ASAR_MAX_GEO 8 + +#define MT7921_ACPI_MTCL "MTCL" +#define MT7921_ACPI_MTDS "MTDS" +#define MT7921_ACPI_MTGS "MTGS" + +struct mt7921_asar_dyn_limit { + u8 idx; + u8 frp[5]; +} __packed; + +struct mt7921_asar_dyn { + u8 names[4]; + u8 enable; + u8 nr_tbl; + struct mt7921_asar_dyn_limit tbl[0]; +} __packed; + +struct mt7921_asar_dyn_limit_v2 { + u8 idx; + u8 frp[11]; +} __packed; + +struct mt7921_asar_dyn_v2 { + u8 names[4]; + u8 enable; + u8 rsvd; + u8 nr_tbl; + struct mt7921_asar_dyn_limit_v2 tbl[0]; +} __packed; + +struct mt7921_asar_geo_band { + u8 pwr; + u8 offset; +} __packed; + +struct mt7921_asar_geo_limit { + u8 idx; + /* 0:2G, 1:5G */ + struct mt7921_asar_geo_band band[2]; +} __packed; + +struct mt7921_asar_geo { + u8 names[4]; + u8 version; + u8 nr_tbl; + struct mt7921_asar_geo_limit tbl[0]; +} __packed; + +struct mt7921_asar_geo_limit_v2 { + u8 idx; + /* 0:2G, 1:5G, 2:6G */ + struct mt7921_asar_geo_band band[3]; +} __packed; + +struct mt7921_asar_geo_v2 { + u8 names[4]; + u8 version; + u8 rsvd; + u8 nr_tbl; + struct mt7921_asar_geo_limit_v2 tbl[0]; +} __packed; + +struct mt7921_asar_cl { + u8 names[4]; + u8 version; + u8 mode_6g; + u8 cl6g[6]; +} __packed; + +struct mt7921_acpi_sar { + u8 ver; + union { + struct mt7921_asar_dyn *dyn; + struct mt7921_asar_dyn_v2 *dyn_v2; + }; + union { + struct mt7921_asar_geo *geo; + struct mt7921_asar_geo_v2 *geo_v2; + }; + struct mt7921_asar_cl *countrylist; +}; + +#endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c index 3a6b158b779e..d1f10f6d9adc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c @@ -5,20 +5,6 @@ #include "../dma.h" #include "mac.h" -static int mt7921_init_tx_queues(struct mt7921_phy *phy, int idx, int n_desc) -{ - int i, err; - - err = mt76_init_tx_queue(phy->mt76, 0, idx, n_desc, MT_TX_RING_BASE, 0); - if (err < 0) - return err; - - for (i = 0; i <= MT_TXQ_PSD; i++) - phy->mt76->q_tx[i] = phy->mt76->q_tx[0]; - - return 0; -} - static int mt7921_poll_tx(struct napi_struct *napi, int budget) { struct mt7921_dev *dev; @@ -31,7 +17,7 @@ static int mt7921_poll_tx(struct napi_struct *napi, int budget) return 0; } - mt7921_mcu_tx_cleanup(dev); + mt76_connac_tx_cleanup(&dev->mt76); if (napi_complete(napi)) mt7921_irq_enable(dev, MT_INT_TX_DONE_ALL); mt76_connac_pm_unref(&dev->mphy, &dev->pm); @@ -250,8 +236,9 @@ int mt7921_dma_init(struct mt7921_dev *dev) return ret; /* init tx queue */ - ret = mt7921_init_tx_queues(&dev->phy, MT7921_TXQ_BAND0, - MT7921_TX_RING_SIZE); + ret = mt76_connac_init_tx_queues(dev->phy.mt76, MT7921_TXQ_BAND0, + MT7921_TX_RING_SIZE, + MT_TX_RING_BASE, 0); if (ret) return ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c index 4a8675634f80..cd960e23770f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -34,14 +34,13 @@ mt7921_regd_notifier(struct wiphy *wiphy, { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt7921_phy *phy = mt7921_hw_phy(hw); memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2)); dev->mt76.region = request->dfs_region; mt7921_mutex_acquire(dev); mt76_connac_mcu_set_channel_domain(hw->priv); - mt76_connac_mcu_set_rate_txpower(phy->mt76); + mt7921_set_tx_sar_pwr(hw, NULL); mt7921_mutex_release(dev); } @@ -53,8 +52,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw) struct wiphy *wiphy = hw->wiphy; hw->queues = 4; - hw->max_rx_aggregation_subframes = 64; - hw->max_tx_aggregation_subframes = 128; + hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; + hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE; hw->netdev_features = NETIF_F_RXCSUM; hw->radiotap_timestamp.units_pos = @@ -97,6 +96,8 @@ mt7921_init_wiphy(struct ieee80211_hw *hw) ieee80211_hw_set(hw, WANT_MONITOR_VIF); ieee80211_hw_set(hw, SUPPORTS_PS); ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); + ieee80211_hw_set(hw, CONNECTION_MONITOR); if (dev->pm.enable) ieee80211_hw_set(hw, CONNECTION_MONITOR); @@ -289,6 +290,8 @@ int mt7921_register_device(struct mt7921_dev *dev) if (!mt76_is_mmio(&dev->mt76)) hw->extra_tx_headroom += MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE; + mt7921_init_acpi_sar(dev); + ret = mt7921_init_wcid(dev); if (ret) return ret; @@ -304,7 +307,7 @@ int mt7921_register_device(struct mt7921_dev *dev) IEEE80211_HT_CAP_LDPC_CODING | IEEE80211_HT_CAP_MAX_AMSDU; dev->mphy.sband_5g.sband.vht_cap.cap |= - IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 | + IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c index a630ddbf19e5..47f0aa81ab02 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -9,10 +9,6 @@ #include "mac.h" #include "mcu.h" -#define HE_BITS(f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f) -#define HE_PREP(f, m, v) le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\ - IEEE80211_RADIOTAP_HE_##f) - static struct mt76_wcid *mt7921_rx_get_wcid(struct mt7921_dev *dev, u16 idx, bool unicast) { @@ -169,183 +165,6 @@ void mt7921_mac_sta_poll(struct mt7921_dev *dev) EXPORT_SYMBOL_GPL(mt7921_mac_sta_poll); static void -mt7921_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, - struct ieee80211_radiotap_he *he, - __le32 *rxv) -{ - u32 ru_h, ru_l; - u8 ru, offs = 0; - - ru_l = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC_L); - ru_h = le32_get_bits(rxv[1], MT_PRXV_HE_RU_ALLOC_H); - ru = (u8)(ru_l | ru_h << 4); - - status->bw = RATE_INFO_BW_HE_RU; - - switch (ru) { - case 0 ... 36: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26; - offs = ru; - break; - case 37 ... 52: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52; - offs = ru - 37; - break; - case 53 ... 60: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106; - offs = ru - 53; - break; - case 61 ... 64: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242; - offs = ru - 61; - break; - case 65 ... 66: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484; - offs = ru - 65; - break; - case 67: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996; - break; - case 68: - status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; - break; - } - - he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); - he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) | - le16_encode_bits(offs, - IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET); -} - -static void -mt7921_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32 *rxv) -{ - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - static const struct ieee80211_radiotap_he_mu mu_known = { - .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | - HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) | - HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) | - HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN) | - HE_BITS(MU_FLAGS1_SIG_B_COMP_KNOWN), - .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN) | - HE_BITS(MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN), - }; - struct ieee80211_radiotap_he_mu *he_mu; - - status->flag |= RX_FLAG_RADIOTAP_HE_MU; - - he_mu = skb_push(skb, sizeof(mu_known)); - memcpy(he_mu, &mu_known, sizeof(mu_known)); - -#define MU_PREP(f, v) le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f) - - he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx); - if (status->he_dcm) - he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm); - - he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) | - MU_PREP(FLAGS2_SIG_B_SYMS_USERS, - le32_get_bits(rxv[2], MT_CRXV_HE_NUM_USER)); - - he_mu->ru_ch1[0] = le32_get_bits(rxv[3], MT_CRXV_HE_RU0); - - if (status->bw >= RATE_INFO_BW_40) { - he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN); - he_mu->ru_ch2[0] = - le32_get_bits(rxv[3], MT_CRXV_HE_RU1); - } - - if (status->bw >= RATE_INFO_BW_80) { - he_mu->ru_ch1[1] = - le32_get_bits(rxv[3], MT_CRXV_HE_RU2); - he_mu->ru_ch2[1] = - le32_get_bits(rxv[3], MT_CRXV_HE_RU3); - } -} - -static void -mt7921_mac_decode_he_radiotap(struct sk_buff *skb, __le32 *rxv, u32 mode) -{ - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - static const struct ieee80211_radiotap_he known = { - .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) | - HE_BITS(DATA1_DATA_DCM_KNOWN) | - HE_BITS(DATA1_STBC_KNOWN) | - HE_BITS(DATA1_CODING_KNOWN) | - HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) | - HE_BITS(DATA1_DOPPLER_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE_KNOWN) | - HE_BITS(DATA1_BSS_COLOR_KNOWN), - .data2 = HE_BITS(DATA2_GI_KNOWN) | - HE_BITS(DATA2_TXBF_KNOWN) | - HE_BITS(DATA2_PE_DISAMBIG_KNOWN) | - HE_BITS(DATA2_TXOP_KNOWN), - }; - struct ieee80211_radiotap_he *he = NULL; - u32 ltf_size = le32_get_bits(rxv[2], MT_CRXV_HE_LTF_SIZE) + 1; - - status->flag |= RX_FLAG_RADIOTAP_HE; - - he = skb_push(skb, sizeof(known)); - memcpy(he, &known, sizeof(known)); - - he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[14]) | - HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[2]); - he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]); - he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[2]) | - le16_encode_bits(ltf_size, - IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE); - if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF) - he->data5 |= HE_BITS(DATA5_TXBF); - he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) | - HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]); - - switch (mode) { - case MT_PHY_TYPE_HE_SU: - he->data1 |= HE_BITS(DATA1_FORMAT_SU) | - HE_BITS(DATA1_UL_DL_KNOWN) | - HE_BITS(DATA1_BEAM_CHANGE_KNOWN) | - HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); - - he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[14]) | - HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); - break; - case MT_PHY_TYPE_HE_EXT_SU: - he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) | - HE_BITS(DATA1_UL_DL_KNOWN) | - HE_BITS(DATA1_BW_RU_ALLOC_KNOWN); - - he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); - break; - case MT_PHY_TYPE_HE_MU: - he->data1 |= HE_BITS(DATA1_FORMAT_MU) | - HE_BITS(DATA1_UL_DL_KNOWN); - - he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]); - he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[7]); - - mt7921_mac_decode_he_radiotap_ru(status, he, rxv); - mt7921_mac_decode_he_mu_radiotap(skb, rxv); - break; - case MT_PHY_TYPE_HE_TB: - he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) | - HE_BITS(DATA1_SPTL_REUSE2_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE3_KNOWN) | - HE_BITS(DATA1_SPTL_REUSE4_KNOWN); - - he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[11]) | - HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[11]) | - HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[11]) | - HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[11]); - - mt7921_mac_decode_he_radiotap_ru(status, he, rxv); - break; - default: - break; - } -} - -static void mt7921_get_status_freq_info(struct mt7921_dev *dev, struct mt76_phy *mphy, struct mt76_rx_status *status, u8 chfreq) { @@ -399,86 +218,6 @@ mt7921_mac_assoc_rssi(struct mt7921_dev *dev, struct sk_buff *skb) mt7921_mac_rssi_iter, skb); } -/* The HW does not translate the mac header to 802.3 for mesh point */ -static int mt7921_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap) -{ - struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb; - struct ethhdr *eth_hdr = (struct ethhdr *)(skb->data + hdr_gap); - struct mt7921_sta *msta = (struct mt7921_sta *)status->wcid; - __le32 *rxd = (__le32 *)skb->data; - struct ieee80211_sta *sta; - struct ieee80211_vif *vif; - struct ieee80211_hdr hdr; - u16 frame_control; - - if (le32_get_bits(rxd[3], MT_RXD3_NORMAL_ADDR_TYPE) != - MT_RXD3_NORMAL_U2M) - return -EINVAL; - - if (!(le32_to_cpu(rxd[1]) & MT_RXD1_NORMAL_GROUP_4)) - return -EINVAL; - - if (!msta || !msta->vif) - return -EINVAL; - - sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); - vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); - - /* store the info from RXD and ethhdr to avoid being overridden */ - frame_control = le32_get_bits(rxd[6], MT_RXD6_FRAME_CONTROL); - hdr.frame_control = cpu_to_le16(frame_control); - hdr.seq_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_SEQ_CTRL)); - hdr.duration_id = 0; - - ether_addr_copy(hdr.addr1, vif->addr); - ether_addr_copy(hdr.addr2, sta->addr); - switch (frame_control & (IEEE80211_FCTL_TODS | - IEEE80211_FCTL_FROMDS)) { - case 0: - ether_addr_copy(hdr.addr3, vif->bss_conf.bssid); - break; - case IEEE80211_FCTL_FROMDS: - ether_addr_copy(hdr.addr3, eth_hdr->h_source); - break; - case IEEE80211_FCTL_TODS: - ether_addr_copy(hdr.addr3, eth_hdr->h_dest); - break; - case IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS: - ether_addr_copy(hdr.addr3, eth_hdr->h_dest); - ether_addr_copy(hdr.addr4, eth_hdr->h_source); - break; - default: - break; - } - - skb_pull(skb, hdr_gap + sizeof(struct ethhdr) - 2); - if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) || - eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX)) - ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header); - else if (be16_to_cpu(eth_hdr->h_proto) >= ETH_P_802_3_MIN) - ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header); - else - skb_pull(skb, 2); - - if (ieee80211_has_order(hdr.frame_control)) - memcpy(skb_push(skb, IEEE80211_HT_CTL_LEN), &rxd[9], - IEEE80211_HT_CTL_LEN); - if (ieee80211_is_data_qos(hdr.frame_control)) { - __le16 qos_ctrl; - - qos_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_QOS_CTL)); - memcpy(skb_push(skb, IEEE80211_QOS_CTL_LEN), &qos_ctrl, - IEEE80211_QOS_CTL_LEN); - } - - if (ieee80211_has_a4(hdr.frame_control)) - memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr)); - else - memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6); - - return 0; -} - static int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) { @@ -496,9 +235,10 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) u32 rxd2 = le32_to_cpu(rxd[2]); u32 rxd3 = le32_to_cpu(rxd[3]); u32 rxd4 = le32_to_cpu(rxd[4]); + struct mt7921_sta *msta; u16 seq_ctrl = 0; __le16 fc = 0; - u32 mode = 0; + u8 mode = 0; int i, idx; memset(status, 0, sizeof(*status)); @@ -526,8 +266,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) status->wcid = mt7921_rx_get_wcid(dev, idx, unicast); if (status->wcid) { - struct mt7921_sta *msta; - msta = container_of(status->wcid, struct mt7921_sta, wcid); spin_lock_bh(&dev->sta_poll_lock); if (list_empty(&msta->poll_list)) @@ -642,9 +380,8 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) /* RXD Group 3 - P-RXV */ if (rxd1 & MT_RXD1_NORMAL_GROUP_3) { - u8 stbc, gi; u32 v0, v1; - bool cck; + int ret; rxv = rxd; rxd += 2; @@ -672,79 +409,10 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) status->chain_signal[i]); } - stbc = FIELD_GET(MT_PRXV_STBC, v0); - gi = FIELD_GET(MT_PRXV_SGI, v0); - cck = false; - - idx = i = FIELD_GET(MT_PRXV_TX_RATE, v0); - mode = FIELD_GET(MT_PRXV_TX_MODE, v0); - - switch (mode) { - case MT_PHY_TYPE_CCK: - cck = true; - fallthrough; - case MT_PHY_TYPE_OFDM: - i = mt76_get_rate(&dev->mt76, sband, i, cck); - break; - case MT_PHY_TYPE_HT_GF: - case MT_PHY_TYPE_HT: - status->encoding = RX_ENC_HT; - if (i > 31) - return -EINVAL; - break; - case MT_PHY_TYPE_VHT: - status->nss = - FIELD_GET(MT_PRXV_NSTS, v0) + 1; - status->encoding = RX_ENC_VHT; - if (i > 11) - return -EINVAL; - break; - case MT_PHY_TYPE_HE_MU: - case MT_PHY_TYPE_HE_SU: - case MT_PHY_TYPE_HE_EXT_SU: - case MT_PHY_TYPE_HE_TB: - status->nss = - FIELD_GET(MT_PRXV_NSTS, v0) + 1; - status->encoding = RX_ENC_HE; - i &= GENMASK(3, 0); - - if (gi <= NL80211_RATE_INFO_HE_GI_3_2) - status->he_gi = gi; - - status->he_dcm = !!(idx & MT_PRXV_TX_DCM); - break; - default: - return -EINVAL; - } - - status->rate_idx = i; - - switch (FIELD_GET(MT_PRXV_FRAME_MODE, v0)) { - case IEEE80211_STA_RX_BW_20: - break; - case IEEE80211_STA_RX_BW_40: - if (mode & MT_PHY_TYPE_HE_EXT_SU && - (idx & MT_PRXV_TX_ER_SU_106T)) { - status->bw = RATE_INFO_BW_HE_RU; - status->he_ru = - NL80211_RATE_INFO_HE_RU_ALLOC_106; - } else { - status->bw = RATE_INFO_BW_40; - } - break; - case IEEE80211_STA_RX_BW_80: - status->bw = RATE_INFO_BW_80; - break; - case IEEE80211_STA_RX_BW_160: - status->bw = RATE_INFO_BW_160; - break; - default: - return -EINVAL; - } - - status->enc_flags |= RX_ENC_FLAG_STBC_MASK * stbc; - if (mode < MT_PHY_TYPE_HE_SU && gi) - status->enc_flags |= RX_ENC_FLAG_SHORT_GI; + ret = mt76_connac2_mac_fill_rx_rate(&dev->mt76, status, sband, + rxv, &mode); + if (ret < 0) + return ret; if (rxd1 & MT_RXD1_NORMAL_GROUP_5) { rxd += 18; @@ -762,8 +430,18 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) hdr_gap = (u8 *)rxd - skb->data + 2 * remove_pad; if (hdr_trans && ieee80211_has_morefrags(fc)) { - if (mt7921_reverse_frag0_hdr_trans(skb, hdr_gap)) + struct ieee80211_vif *vif; + int err; + + if (!msta || !msta->vif) return -EINVAL; + + vif = container_of((void *)msta->vif, struct ieee80211_vif, + drv_priv); + err = mt76_connac2_reverse_frag0_hdr_trans(vif, skb, hdr_gap); + if (err) + return err; + hdr_trans = false; } else { skb_pull(skb, hdr_gap); @@ -796,7 +474,7 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) mt7921_mac_assoc_rssi(dev, skb); if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023)) - mt7921_mac_decode_he_radiotap(skb, rxv, mode); + mt76_connac2_mac_decode_he_radiotap(&dev->mt76, skb, rxv, mode); if (!status->wcid || !ieee80211_is_data_qos(fc)) return 0; @@ -808,217 +486,6 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) return 0; } -static void -mt7921_mac_write_txwi_8023(struct mt7921_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct mt76_wcid *wcid) -{ - u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - u8 fc_type, fc_stype; - u16 ethertype; - bool wmm = false; - u32 val; - - if (wcid->sta) { - struct ieee80211_sta *sta; - - sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv); - wmm = sta->wme; - } - - val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) | - FIELD_PREP(MT_TXD1_TID, tid); - - ethertype = get_unaligned_be16(&skb->data[12]); - if (ethertype >= ETH_P_802_3_MIN) - val |= MT_TXD1_ETH_802_3; - - txwi[1] |= cpu_to_le32(val); - - fc_type = IEEE80211_FTYPE_DATA >> 2; - fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0; - - val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | - FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype); - - txwi[2] |= cpu_to_le32(val); - - val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | - FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); - txwi[7] |= cpu_to_le32(val); -} - -static void -mt7921_mac_write_txwi_80211(struct mt7921_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct ieee80211_key_conf *key) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - bool multicast = is_multicast_ether_addr(hdr->addr1); - u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; - __le16 fc = hdr->frame_control; - u8 fc_type, fc_stype; - u32 val; - - if (ieee80211_is_action(fc) && - mgmt->u.action.category == WLAN_CATEGORY_BACK && - mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { - u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); - - txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA); - tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK; - } else if (ieee80211_is_back_req(hdr->frame_control)) { - struct ieee80211_bar *bar = (struct ieee80211_bar *)hdr; - u16 control = le16_to_cpu(bar->control); - - tid = FIELD_GET(IEEE80211_BAR_CTRL_TID_INFO_MASK, control); - } - - val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) | - FIELD_PREP(MT_TXD1_HDR_INFO, - ieee80211_get_hdrlen_from_skb(skb) / 2) | - FIELD_PREP(MT_TXD1_TID, tid); - txwi[1] |= cpu_to_le32(val); - - fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2; - fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4; - - val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) | - FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) | - FIELD_PREP(MT_TXD2_MULTICAST, multicast); - - if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) && - key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { - val |= MT_TXD2_BIP; - txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); - } - - if (!ieee80211_is_data(fc) || multicast || - info->flags & IEEE80211_TX_CTL_USE_MINRATE) - val |= MT_TXD2_FIX_RATE; - - txwi[2] |= cpu_to_le32(val); - - if (ieee80211_is_beacon(fc)) { - txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT); - txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT); - } - - if (info->flags & IEEE80211_TX_CTL_INJECTED) { - u16 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)); - txwi[3] |= cpu_to_le32(val); - txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU); - } - - if (mt76_is_mmio(&dev->mt76)) { - val = FIELD_PREP(MT_TXD7_TYPE, fc_type) | - FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype); - txwi[7] |= cpu_to_le32(val); - } else { - val = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) | - FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype); - txwi[8] |= cpu_to_le32(val); - } -} - -void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct mt76_wcid *wcid, - struct ieee80211_key_conf *key, int pid, - bool beacon) -{ - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_vif *vif = info->control.vif; - struct mt76_phy *mphy = &dev->mphy; - u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0; - bool is_mmio = mt76_is_mmio(&dev->mt76); - u32 sz_txd = is_mmio ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE; - bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; - u16 tx_count = 15; - u32 val; - - if (vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; - - omac_idx = mvif->omac_idx; - wmm_idx = mvif->wmm_idx; - } - - if (beacon) { - p_fmt = MT_TX_TYPE_FW; - q_idx = MT_LMAC_BCN0; - } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { - p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; - q_idx = MT_LMAC_ALTX0; - } else { - p_fmt = is_mmio ? MT_TX_TYPE_CT : MT_TX_TYPE_SF; - q_idx = wmm_idx * MT7921_MAX_WMM_SETS + - mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); - } - - val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | - FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) | - FIELD_PREP(MT_TXD0_Q_IDX, q_idx); - txwi[0] = cpu_to_le32(val); - - val = MT_TXD1_LONG_FORMAT | - FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) | - FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx); - - txwi[1] = cpu_to_le32(val); - txwi[2] = 0; - - val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count); - if (key) - val |= MT_TXD3_PROTECT_FRAME; - if (info->flags & IEEE80211_TX_CTL_NO_ACK) - val |= MT_TXD3_NO_ACK; - - txwi[3] = cpu_to_le32(val); - txwi[4] = 0; - - val = FIELD_PREP(MT_TXD5_PID, pid); - if (pid >= MT_PACKET_ID_FIRST) - val |= MT_TXD5_TX_STATUS_HOST; - txwi[5] = cpu_to_le32(val); - - txwi[6] = 0; - txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0; - - if (is_8023) - mt7921_mac_write_txwi_8023(dev, txwi, skb, wcid); - else - mt7921_mac_write_txwi_80211(dev, txwi, skb, key); - - if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) { - int rateidx = vif ? ffs(vif->bss_conf.basic_rates) - 1 : 0; - u16 rate, mode; - - /* hardware won't add HTC for mgmt/ctrl frame */ - txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD); - - rate = mt76_calculate_default_rate(mphy, rateidx); - mode = rate >> 8; - rate &= GENMASK(7, 0); - rate |= FIELD_PREP(MT_TX_RATE_MODE, mode); - - val = MT_TXD6_FIXED_BW | - FIELD_PREP(MT_TXD6_TX_RATE, rate); - txwi[6] |= cpu_to_le32(val); - txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); - } -} -EXPORT_SYMBOL_GPL(mt7921_mac_write_txwi); - void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) { struct mt7921_sta *msta; @@ -1044,123 +511,6 @@ void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) } EXPORT_SYMBOL_GPL(mt7921_tx_check_aggr); -static bool -mt7921_mac_add_txs_skb(struct mt7921_dev *dev, struct mt76_wcid *wcid, int pid, - __le32 *txs_data) -{ - struct mt7921_sta *msta = container_of(wcid, struct mt7921_sta, wcid); - struct mt76_sta_stats *stats = &msta->stats; - struct ieee80211_supported_band *sband; - struct mt76_dev *mdev = &dev->mt76; - struct ieee80211_tx_info *info; - struct rate_info rate = {}; - struct sk_buff_head list; - u32 txrate, txs, mode; - struct sk_buff *skb; - bool cck = false; - - mt76_tx_status_lock(mdev, &list); - skb = mt76_tx_status_skb_get(mdev, wcid, pid, &list); - if (!skb) - goto out; - - info = IEEE80211_SKB_CB(skb); - txs = le32_to_cpu(txs_data[0]); - if (!(txs & MT_TXS0_ACK_ERROR_MASK)) - info->flags |= IEEE80211_TX_STAT_ACK; - - info->status.ampdu_len = 1; - info->status.ampdu_ack_len = !!(info->flags & - IEEE80211_TX_STAT_ACK); - - info->status.rates[0].idx = -1; - - if (!wcid->sta) - goto out; - - txrate = FIELD_GET(MT_TXS0_TX_RATE, txs); - - rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate); - rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1; - - if (rate.nss - 1 < ARRAY_SIZE(stats->tx_nss)) - stats->tx_nss[rate.nss - 1]++; - if (rate.mcs < ARRAY_SIZE(stats->tx_mcs)) - stats->tx_mcs[rate.mcs]++; - - mode = FIELD_GET(MT_TX_RATE_MODE, txrate); - switch (mode) { - case MT_PHY_TYPE_CCK: - cck = true; - fallthrough; - case MT_PHY_TYPE_OFDM: - if (dev->mphy.chandef.chan->band == NL80211_BAND_5GHZ) - sband = &dev->mphy.sband_5g.sband; - else - sband = &dev->mphy.sband_2g.sband; - - rate.mcs = mt76_get_rate(dev->mphy.dev, sband, rate.mcs, cck); - rate.legacy = sband->bitrates[rate.mcs].bitrate; - break; - case MT_PHY_TYPE_HT: - case MT_PHY_TYPE_HT_GF: - if (rate.mcs > 31) - goto out; - - rate.flags = RATE_INFO_FLAGS_MCS; - if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI) - rate.flags |= RATE_INFO_FLAGS_SHORT_GI; - break; - case MT_PHY_TYPE_VHT: - if (rate.mcs > 9) - goto out; - - rate.flags = RATE_INFO_FLAGS_VHT_MCS; - break; - case MT_PHY_TYPE_HE_SU: - case MT_PHY_TYPE_HE_EXT_SU: - case MT_PHY_TYPE_HE_TB: - case MT_PHY_TYPE_HE_MU: - if (rate.mcs > 11) - goto out; - - rate.he_gi = wcid->rate.he_gi; - rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate); - rate.flags = RATE_INFO_FLAGS_HE_MCS; - break; - default: - goto out; - } - stats->tx_mode[mode]++; - - switch (FIELD_GET(MT_TXS0_BW, txs)) { - case IEEE80211_STA_RX_BW_160: - rate.bw = RATE_INFO_BW_160; - stats->tx_bw[3]++; - break; - case IEEE80211_STA_RX_BW_80: - rate.bw = RATE_INFO_BW_80; - stats->tx_bw[2]++; - break; - case IEEE80211_STA_RX_BW_40: - rate.bw = RATE_INFO_BW_40; - stats->tx_bw[1]++; - break; - default: - rate.bw = RATE_INFO_BW_20; - stats->tx_bw[0]++; - break; - } - wcid->rate = rate; - -out: - if (skb) - mt76_tx_status_skb_done(mdev, skb, &list); - mt76_tx_status_unlock(mdev, &list); - - return !!skb; -} - void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) { struct mt7921_sta *msta = NULL; @@ -1187,12 +537,13 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) if (!wcid) goto out; - mt7921_mac_add_txs_skb(dev, wcid, pid, txs_data); + msta = container_of(wcid, struct mt7921_sta, wcid); + mt76_connac2_mac_add_txs_skb(&dev->mt76, wcid, pid, txs_data, + &msta->stats); if (!wcid->sta) goto out; - msta = container_of(wcid, struct mt7921_sta, wcid); spin_lock_bh(&dev->sta_poll_lock); if (list_empty(&msta->poll_list)) list_add_tail(&msta->poll_list, &dev->sta_poll_list); @@ -1387,9 +738,9 @@ void mt7921_mac_reset_work(struct work_struct *work) reset_work); struct ieee80211_hw *hw = mt76_hw(dev); struct mt76_connac_pm *pm = &dev->pm; - int i; + int i, ret; - dev_err(dev->mt76.dev, "chip reset\n"); + dev_dbg(dev->mt76.dev, "chip reset\n"); dev->hw_full_reset = true; ieee80211_stop_queues(hw); @@ -1397,11 +748,14 @@ void mt7921_mac_reset_work(struct work_struct *work) cancel_delayed_work_sync(&pm->ps_work); cancel_work_sync(&pm->wake_work); - mutex_lock(&dev->mt76.mutex); - for (i = 0; i < 10; i++) - if (!mt7921_dev_reset(dev)) + for (i = 0; i < 10; i++) { + mutex_lock(&dev->mt76.mutex); + ret = mt7921_dev_reset(dev); + mutex_unlock(&dev->mt76.mutex); + + if (!ret) break; - mutex_unlock(&dev->mt76.mutex); + } if (i == 10) dev_err(dev->mt76.dev, "chip reset failed\n"); @@ -1538,10 +892,12 @@ void mt7921_pm_wake_work(struct work_struct *work) mt76_connac_pm_dequeue_skbs(mphy, &dev->pm); mt76_worker_schedule(&mdev->sdio.txrx_worker); } else { + local_bh_disable(); mt76_for_each_q_rx(mdev, i) napi_schedule(&mdev->napi[i]); + local_bh_enable(); mt76_connac_pm_dequeue_skbs(mphy, &dev->pm); - mt7921_mcu_tx_cleanup(dev); + mt76_connac_tx_cleanup(mdev); } if (test_bit(MT76_STATE_RUNNING, &mphy->state)) ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work, @@ -1617,7 +973,7 @@ void mt7921_coredump_work(struct work_struct *work) if (!skb) break; - skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd)); if (!dump || data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) { dev_kfree_skb(skb); continue; @@ -1646,7 +1002,7 @@ mt7921_usb_sdio_write_txwi(struct mt7921_dev *dev, struct mt76_wcid *wcid, __le32 *txwi = (__le32 *)(skb->data - MT_SDIO_TXD_SIZE); memset(txwi, 0, MT_SDIO_TXD_SIZE); - mt7921_mac_write_txwi(dev, txwi, skb, wcid, key, pid, false); + mt76_connac2_mac_write_txwi(&dev->mt76, txwi, skb, wcid, key, pid, qid, 0); skb_push(skb, MT_SDIO_TXD_SIZE); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h index 79447e2d0143..8afec600364f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h @@ -4,6 +4,8 @@ #ifndef __MT7921_MAC_H #define __MT7921_MAC_H +#include "../mt76_connac2_mac.h" + #define MT_CT_PARSE_LEN 72 #define MT_CT_DMA_BUF_NUM 2 @@ -27,294 +29,6 @@ enum rx_pkt_type { PKT_TYPE_NORMAL_MCU, }; -/* RXD DW1 */ -#define MT_RXD1_NORMAL_WLAN_IDX GENMASK(9, 0) -#define MT_RXD1_NORMAL_GROUP_1 BIT(11) -#define MT_RXD1_NORMAL_GROUP_2 BIT(12) -#define MT_RXD1_NORMAL_GROUP_3 BIT(13) -#define MT_RXD1_NORMAL_GROUP_4 BIT(14) -#define MT_RXD1_NORMAL_GROUP_5 BIT(15) -#define MT_RXD1_NORMAL_SEC_MODE GENMASK(20, 16) -#define MT_RXD1_NORMAL_KEY_ID GENMASK(22, 21) -#define MT_RXD1_NORMAL_CM BIT(23) -#define MT_RXD1_NORMAL_CLM BIT(24) -#define MT_RXD1_NORMAL_ICV_ERR BIT(25) -#define MT_RXD1_NORMAL_TKIP_MIC_ERR BIT(26) -#define MT_RXD1_NORMAL_FCS_ERR BIT(27) -#define MT_RXD1_NORMAL_BAND_IDX BIT(28) -#define MT_RXD1_NORMAL_SPP_EN BIT(29) -#define MT_RXD1_NORMAL_ADD_OM BIT(30) -#define MT_RXD1_NORMAL_SEC_DONE BIT(31) - -/* RXD DW2 */ -#define MT_RXD2_NORMAL_BSSID GENMASK(5, 0) -#define MT_RXD2_NORMAL_CO_ANT BIT(6) -#define MT_RXD2_NORMAL_BF_CQI BIT(7) -#define MT_RXD2_NORMAL_MAC_HDR_LEN GENMASK(12, 8) -#define MT_RXD2_NORMAL_HDR_TRANS BIT(13) -#define MT_RXD2_NORMAL_HDR_OFFSET GENMASK(15, 14) -#define MT_RXD2_NORMAL_TID GENMASK(19, 16) -#define MT_RXD2_NORMAL_MU_BAR BIT(21) -#define MT_RXD2_NORMAL_SW_BIT BIT(22) -#define MT_RXD2_NORMAL_AMSDU_ERR BIT(23) -#define MT_RXD2_NORMAL_MAX_LEN_ERROR BIT(24) -#define MT_RXD2_NORMAL_HDR_TRANS_ERROR BIT(25) -#define MT_RXD2_NORMAL_INT_FRAME BIT(26) -#define MT_RXD2_NORMAL_FRAG BIT(27) -#define MT_RXD2_NORMAL_NULL_FRAME BIT(28) -#define MT_RXD2_NORMAL_NDATA BIT(29) -#define MT_RXD2_NORMAL_NON_AMPDU BIT(30) -#define MT_RXD2_NORMAL_BF_REPORT BIT(31) - -/* RXD DW3 */ -#define MT_RXD3_NORMAL_RXV_SEQ GENMASK(7, 0) -#define MT_RXD3_NORMAL_CH_FREQ GENMASK(15, 8) -#define MT_RXD3_NORMAL_ADDR_TYPE GENMASK(17, 16) -#define MT_RXD3_NORMAL_U2M BIT(0) -#define MT_RXD3_NORMAL_HTC_VLD BIT(0) -#define MT_RXD3_NORMAL_TSF_COMPARE_LOSS BIT(19) -#define MT_RXD3_NORMAL_BEACON_MC BIT(20) -#define MT_RXD3_NORMAL_BEACON_UC BIT(21) -#define MT_RXD3_NORMAL_AMSDU BIT(22) -#define MT_RXD3_NORMAL_MESH BIT(23) -#define MT_RXD3_NORMAL_MHCP BIT(24) -#define MT_RXD3_NORMAL_NO_INFO_WB BIT(25) -#define MT_RXD3_NORMAL_DISABLE_RX_HDR_TRANS BIT(26) -#define MT_RXD3_NORMAL_POWER_SAVE_STAT BIT(27) -#define MT_RXD3_NORMAL_MORE BIT(28) -#define MT_RXD3_NORMAL_UNWANT BIT(29) -#define MT_RXD3_NORMAL_RX_DROP BIT(30) -#define MT_RXD3_NORMAL_VLAN2ETH BIT(31) - -/* RXD DW4 */ -#define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0) -#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0) -#define MT_RXD4_MID_AMSDU_FRAME BIT(1) -#define MT_RXD4_LAST_AMSDU_FRAME BIT(0) -#define MT_RXD4_NORMAL_PATTERN_DROP BIT(9) -#define MT_RXD4_NORMAL_CLS BIT(10) -#define MT_RXD4_NORMAL_OFLD GENMASK(12, 11) -#define MT_RXD4_NORMAL_MAGIC_PKT BIT(13) -#define MT_RXD4_NORMAL_WOL GENMASK(18, 14) -#define MT_RXD4_NORMAL_CLS_BITMAP GENMASK(28, 19) -#define MT_RXD3_NORMAL_PF_MODE BIT(29) -#define MT_RXD3_NORMAL_PF_STS GENMASK(31, 30) - -/* RXD GROUP4 */ -#define MT_RXD6_FRAME_CONTROL GENMASK(15, 0) -#define MT_RXD6_TA_LO GENMASK(31, 16) - -#define MT_RXD7_TA_HI GENMASK(31, 0) - -#define MT_RXD8_SEQ_CTRL GENMASK(15, 0) -#define MT_RXD8_QOS_CTL GENMASK(31, 16) - -#define MT_RXD9_HT_CONTROL GENMASK(31, 0) - -/* P-RXV DW0 */ -#define MT_PRXV_TX_RATE GENMASK(6, 0) -#define MT_PRXV_TX_DCM BIT(4) -#define MT_PRXV_TX_ER_SU_106T BIT(5) -#define MT_PRXV_NSTS GENMASK(9, 7) -#define MT_PRXV_TXBF BIT(10) -#define MT_PRXV_HT_AD_CODE BIT(11) -#define MT_PRXV_FRAME_MODE GENMASK(14, 12) -#define MT_PRXV_SGI GENMASK(16, 15) -#define MT_PRXV_STBC GENMASK(23, 22) -#define MT_PRXV_TX_MODE GENMASK(27, 24) -#define MT_PRXV_HE_RU_ALLOC_L GENMASK(31, 28) - -/* P-RXV DW1 */ -#define MT_PRXV_RCPI3 GENMASK(31, 24) -#define MT_PRXV_RCPI2 GENMASK(23, 16) -#define MT_PRXV_RCPI1 GENMASK(15, 8) -#define MT_PRXV_RCPI0 GENMASK(7, 0) -#define MT_PRXV_HE_RU_ALLOC_H GENMASK(3, 0) - -/* C-RXV */ -#define MT_CRXV_HT_STBC GENMASK(1, 0) -#define MT_CRXV_TX_MODE GENMASK(7, 4) -#define MT_CRXV_FRAME_MODE GENMASK(10, 8) -#define MT_CRXV_HT_SHORT_GI GENMASK(14, 13) -#define MT_CRXV_HE_LTF_SIZE GENMASK(18, 17) -#define MT_CRXV_HE_LDPC_EXT_SYM BIT(20) -#define MT_CRXV_HE_PE_DISAMBIG BIT(23) -#define MT_CRXV_HE_NUM_USER GENMASK(30, 24) -#define MT_CRXV_HE_UPLINK BIT(31) - -#define MT_CRXV_HE_RU0 GENMASK(7, 0) -#define MT_CRXV_HE_RU1 GENMASK(15, 8) -#define MT_CRXV_HE_RU2 GENMASK(23, 16) -#define MT_CRXV_HE_RU3 GENMASK(31, 24) -#define MT_CRXV_HE_MU_AID GENMASK(30, 20) - -#define MT_CRXV_HE_SR_MASK GENMASK(11, 8) -#define MT_CRXV_HE_SR1_MASK GENMASK(16, 12) -#define MT_CRXV_HE_SR2_MASK GENMASK(20, 17) -#define MT_CRXV_HE_SR3_MASK GENMASK(24, 21) - -#define MT_CRXV_HE_BSS_COLOR GENMASK(5, 0) -#define MT_CRXV_HE_TXOP_DUR GENMASK(12, 6) -#define MT_CRXV_HE_BEAM_CHNG BIT(13) -#define MT_CRXV_HE_DOPPLER BIT(16) - -#define MT_CRXV_SNR GENMASK(18, 13) -#define MT_CRXV_FOE_LO GENMASK(31, 19) -#define MT_CRXV_FOE_HI GENMASK(6, 0) -#define MT_CRXV_FOE_SHIFT 13 - -enum tx_header_format { - MT_HDR_FORMAT_802_3, - MT_HDR_FORMAT_CMD, - MT_HDR_FORMAT_802_11, - MT_HDR_FORMAT_802_11_EXT, -}; - -enum tx_pkt_type { - MT_TX_TYPE_CT, - MT_TX_TYPE_SF, - MT_TX_TYPE_CMD, - MT_TX_TYPE_FW, -}; - -enum tx_port_idx { - MT_TX_PORT_IDX_LMAC, - MT_TX_PORT_IDX_MCU -}; - -enum tx_mcu_port_q_idx { - MT_TX_MCU_PORT_RX_Q0 = 0x20, - MT_TX_MCU_PORT_RX_Q1, - MT_TX_MCU_PORT_RX_Q2, - MT_TX_MCU_PORT_RX_Q3, - MT_TX_MCU_PORT_RX_FWDL = 0x3e -}; - -#define MT_CT_INFO_APPLY_TXD BIT(0) -#define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1) -#define MT_CT_INFO_MGMT_FRAME BIT(2) -#define MT_CT_INFO_NONE_CIPHER_FRAME BIT(3) -#define MT_CT_INFO_HSR2_TX BIT(4) -#define MT_CT_INFO_FROM_HOST BIT(7) - -#define MT_TXD_SIZE (8 * 4) - -#define MT_SDIO_TXD_SIZE (MT_TXD_SIZE + 8 * 4) -#define MT_SDIO_TAIL_SIZE 8 -#define MT_SDIO_HDR_SIZE 4 -#define MT_USB_TAIL_SIZE 4 - -#define MT_TXD0_Q_IDX GENMASK(31, 25) -#define MT_TXD0_PKT_FMT GENMASK(24, 23) -#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) -#define MT_TXD0_TX_BYTES GENMASK(15, 0) - -#define MT_TXD1_LONG_FORMAT BIT(31) -#define MT_TXD1_TGID BIT(30) -#define MT_TXD1_OWN_MAC GENMASK(29, 24) -#define MT_TXD1_AMSDU BIT(23) -#define MT_TXD1_TID GENMASK(22, 20) -#define MT_TXD1_HDR_PAD GENMASK(19, 18) -#define MT_TXD1_HDR_FORMAT GENMASK(17, 16) -#define MT_TXD1_HDR_INFO GENMASK(15, 11) -#define MT_TXD1_ETH_802_3 BIT(15) -#define MT_TXD1_VTA BIT(10) -#define MT_TXD1_WLAN_IDX GENMASK(9, 0) - -#define MT_TXD2_FIX_RATE BIT(31) -#define MT_TXD2_FIXED_RATE BIT(30) -#define MT_TXD2_POWER_OFFSET GENMASK(29, 24) -#define MT_TXD2_MAX_TX_TIME GENMASK(23, 16) -#define MT_TXD2_FRAG GENMASK(15, 14) -#define MT_TXD2_HTC_VLD BIT(13) -#define MT_TXD2_DURATION BIT(12) -#define MT_TXD2_BIP BIT(11) -#define MT_TXD2_MULTICAST BIT(10) -#define MT_TXD2_RTS BIT(9) -#define MT_TXD2_SOUNDING BIT(8) -#define MT_TXD2_NDPA BIT(7) -#define MT_TXD2_NDP BIT(6) -#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) -#define MT_TXD2_SUB_TYPE GENMASK(3, 0) - -#define MT_TXD3_SN_VALID BIT(31) -#define MT_TXD3_PN_VALID BIT(30) -#define MT_TXD3_SW_POWER_MGMT BIT(29) -#define MT_TXD3_BA_DISABLE BIT(28) -#define MT_TXD3_SEQ GENMASK(27, 16) -#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) -#define MT_TXD3_TX_COUNT GENMASK(10, 6) -#define MT_TXD3_TIMING_MEASURE BIT(5) -#define MT_TXD3_DAS BIT(4) -#define MT_TXD3_EEOSP BIT(3) -#define MT_TXD3_EMRD BIT(2) -#define MT_TXD3_PROTECT_FRAME BIT(1) -#define MT_TXD3_NO_ACK BIT(0) - -#define MT_TXD4_PN_LOW GENMASK(31, 0) - -#define MT_TXD5_PN_HIGH GENMASK(31, 16) -#define MT_TXD5_MD BIT(15) -#define MT_TXD5_ADD_BA BIT(14) -#define MT_TXD5_TX_STATUS_HOST BIT(10) -#define MT_TXD5_TX_STATUS_MCU BIT(9) -#define MT_TXD5_TX_STATUS_FMT BIT(8) -#define MT_TXD5_PID GENMASK(7, 0) - -#define MT_TXD6_TX_IBF BIT(31) -#define MT_TXD6_TX_EBF BIT(30) -#define MT_TXD6_TX_RATE GENMASK(29, 16) -#define MT_TXD6_SGI GENMASK(15, 14) -#define MT_TXD6_HELTF GENMASK(13, 12) -#define MT_TXD6_LDPC BIT(11) -#define MT_TXD6_SPE_ID_IDX BIT(10) -#define MT_TXD6_ANT_ID GENMASK(7, 4) -#define MT_TXD6_DYN_BW BIT(3) -#define MT_TXD6_FIXED_BW BIT(2) -#define MT_TXD6_BW GENMASK(1, 0) - -#define MT_TXD7_TXD_LEN GENMASK(31, 30) -#define MT_TXD7_UDP_TCP_SUM BIT(29) -#define MT_TXD7_IP_SUM BIT(28) - -#define MT_TXD7_TYPE GENMASK(21, 20) -#define MT_TXD7_SUB_TYPE GENMASK(19, 16) - -#define MT_TXD7_PSE_FID GENMASK(27, 16) -#define MT_TXD7_SPE_IDX GENMASK(15, 11) -#define MT_TXD7_HW_AMSDU BIT(10) -#define MT_TXD7_TX_TIME GENMASK(9, 0) - -#define MT_TXD8_L_TYPE GENMASK(5, 4) -#define MT_TXD8_L_SUB_TYPE GENMASK(3, 0) - -#define MT_TX_RATE_STBC BIT(13) -#define MT_TX_RATE_NSS GENMASK(12, 10) -#define MT_TX_RATE_MODE GENMASK(9, 6) -#define MT_TX_RATE_SU_EXT_TONE BIT(5) -#define MT_TX_RATE_DCM BIT(4) -#define MT_TX_RATE_IDX GENMASK(3, 0) - -#define MT_TXP_MAX_BUF_NUM 6 - -struct mt7921_txp { - __le16 flags; - __le16 token; - u8 bss_idx; - __le16 rept_wds_wcid; - u8 nbuf; - __le32 buf[MT_TXP_MAX_BUF_NUM]; - __le16 len[MT_TXP_MAX_BUF_NUM]; -} __packed __aligned(4); - -struct mt7921_tx_free { - __le16 rx_byte_cnt; - __le16 ctrl; - u8 txd_cnt; - u8 rsv[3]; - __le32 info[]; -} __packed __aligned(4); - #define MT_TX_FREE_MSDU_CNT GENMASK(9, 0) #define MT_TX_FREE_WLAN_ID GENMASK(23, 14) #define MT_TX_FREE_LATENCY GENMASK(12, 0) @@ -325,56 +39,6 @@ struct mt7921_tx_free { /* will support this field in further revision */ #define MT_TX_FREE_RATE GENMASK(13, 0) -#define MT_TXS0_BW GENMASK(30, 29) -#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) -#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) -#define MT_TXS0_TX_RATE GENMASK(13, 0) - -#define MT_TXS2_WCID GENMASK(25, 16) - -#define MT_TXS3_PID GENMASK(31, 24) - -static inline struct mt7921_txp_common * -mt7921_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t) -{ - u8 *txwi; - - if (!t) - return NULL; - - txwi = mt76_get_txwi_ptr(dev, t); - - return (struct mt7921_txp_common *)(txwi + MT_TXD_SIZE); -} - -#define MT_HW_TXP_MAX_MSDU_NUM 4 -#define MT_HW_TXP_MAX_BUF_NUM 4 - -#define MT_MSDU_ID_VALID BIT(15) - -#define MT_TXD_LEN_MASK GENMASK(11, 0) -#define MT_TXD_LEN_MSDU_LAST BIT(14) -#define MT_TXD_LEN_AMSDU_LAST BIT(15) -#define MT_TXD_LEN_LAST BIT(15) - -struct mt7921_txp_ptr { - __le32 buf0; - __le16 len0; - __le16 len1; - __le32 buf1; -} __packed __aligned(4); - -struct mt7921_hw_txp { - __le16 msdu_id[MT_HW_TXP_MAX_MSDU_NUM]; - struct mt7921_txp_ptr ptr[MT_HW_TXP_MAX_BUF_NUM / 2]; -} __packed __aligned(4); - -struct mt7921_txp_common { - union { - struct mt7921_hw_txp hw; - }; -}; - #define MT_WTBL_TXRX_CAP_RATE_OFFSET 7 #define MT_WTBL_TXRX_RATE_G2_HE 24 #define MT_WTBL_TXRX_RATE_G2 12 diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 63583605d1cd..1438a9f8d1fd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -257,7 +257,7 @@ int __mt7921_start(struct mt7921_phy *phy) if (err) return err; - err = mt76_connac_mcu_set_rate_txpower(phy->mt76); + err = mt7921_set_tx_sar_pwr(mphy->hw, NULL); if (err) return err; @@ -322,7 +322,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, mvif->mt76.omac_idx = mvif->mt76.idx; mvif->phy = phy; mvif->mt76.band_idx = 0; - mvif->mt76.wmm_idx = mvif->mt76.idx % MT7921_MAX_WMM_SETS; + mvif->mt76.wmm_idx = mvif->mt76.idx % MT76_CONNAC_MAX_WMM_SETS; ret = mt76_connac_mcu_uni_add_dev(&dev->mphy, vif, &mvif->sta.wcid, true); @@ -336,7 +336,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, INIT_LIST_HEAD(&mvif->sta.poll_list); mvif->sta.wcid.idx = idx; - mvif->sta.wcid.ext_phy = mvif->mt76.band_idx; + mvif->sta.wcid.phy_idx = mvif->mt76.band_idx; mvif->sta.wcid.hw_key_idx = -1; mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET; mt76_packet_id_init(&mvif->sta.wcid); @@ -352,6 +352,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, mtxq->wcid = idx; } + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; out: mt7921_mutex_release(dev); @@ -495,8 +496,21 @@ static void mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { struct mt7921_dev *dev = priv; + struct ieee80211_hw *hw = mt76_hw(dev); + bool pm_enable = dev->pm.enable; + int err; + + err = mt7921_mcu_set_beacon_filter(dev, vif, pm_enable); + if (err < 0) + return; - mt7921_mcu_set_beacon_filter(dev, vif, dev->pm.enable); + if (pm_enable) { + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + ieee80211_hw_set(hw, CONNECTION_MONITOR); + } else { + vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER; + __clear_bit(IEEE80211_HW_CONNECTION_MONITOR, hw->flags); + } } static void @@ -548,7 +562,7 @@ static int mt7921_config(struct ieee80211_hw *hw, u32 changed) mt7921_mutex_acquire(dev); if (changed & IEEE80211_CONF_CHANGE_POWER) { - ret = mt76_connac_mcu_set_rate_txpower(phy->mt76); + ret = mt7921_set_tx_sar_pwr(hw, NULL); if (ret) goto out; } @@ -567,7 +581,8 @@ out: } static int -mt7921_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, +mt7921_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, const struct ieee80211_tx_queue_params *params) { struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; @@ -653,15 +668,6 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) { - struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; - - mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, - true); - mt7921_mcu_sta_update(dev, NULL, vif, true, - MT76_STA_INFO_STATE_NONE); - } - if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) mt7921_mcu_uni_add_beacon_offload(dev, hw, vif, @@ -677,8 +683,7 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) { mt7921_mcu_sta_update(dev, NULL, vif, true, MT76_STA_INFO_STATE_ASSOC); - if (dev->pm.enable) - mt7921_mcu_set_beacon_filter(dev, vif, vif->cfg.assoc); + mt7921_mcu_set_beacon_filter(dev, vif, vif->cfg.assoc); } if (changed & BSS_CHANGED_ARP_FILTER) { @@ -707,7 +712,7 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, msta->vif = mvif; msta->wcid.sta = 1; msta->wcid.idx = idx; - msta->wcid.ext_phy = mvif->mt76.band_idx; + msta->wcid.phy_idx = mvif->mt76.band_idx; msta->wcid.tx_info |= MT_WCID_TX_INFO_SET; msta->last_txs = jiffies; @@ -1177,7 +1182,7 @@ void mt7921_scan_work(struct work_struct *work) scan_work.work); while (true) { - struct mt7921_mcu_rxd *rxd; + struct mt76_connac2_mcu_rxd *rxd; struct sk_buff *skb; spin_lock_bh(&phy->dev->mt76.lock); @@ -1187,7 +1192,7 @@ void mt7921_scan_work(struct work_struct *work) if (!skb) break; - rxd = (struct mt7921_mcu_rxd *)skb->data; + rxd = (struct mt76_connac2_mcu_rxd *)skb->data; if (rxd->eid == MCU_EVENT_SCHED_SCAN_DONE) { ieee80211_sched_scan_results(phy->mt76->hw); } else if (test_and_clear_bit(MT76_HW_SCANNING, @@ -1450,15 +1455,14 @@ static void mt7921_ipv6_addr_change(struct ieee80211_hw *hw, if (!idx) return; - skb = __mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req_hdr) + - idx * sizeof(struct in6_addr), GFP_ATOMIC); - if (!skb) - return; - req_hdr.arpns.ips_num = idx; req_hdr.arpns.len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv) + idx * sizeof(struct in6_addr)); - skb_put_data(skb, &req_hdr, sizeof(req_hdr)); + skb = __mt76_mcu_msg_alloc(&dev->mt76, &req_hdr, + sizeof(req_hdr) + idx * sizeof(struct in6_addr), + sizeof(req_hdr), GFP_ATOMIC); + if (!skb) + return; for (i = 0; i < idx; i++) skb_put_data(skb, &ns_addrs[i].in6_u, sizeof(struct in6_addr)); @@ -1469,20 +1473,33 @@ static void mt7921_ipv6_addr_change(struct ieee80211_hw *hw, } #endif +int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw, + const struct cfg80211_sar_specs *sar) +{ + struct mt76_phy *mphy = hw->priv; + int err; + + if (sar) { + err = mt76_init_sar_power(hw, sar); + if (err) + return err; + } + + mt7921_init_acpi_sar_power(mt7921_hw_phy(hw), !sar); + + err = mt76_connac_mcu_set_rate_txpower(mphy); + + return err; +} + static int mt7921_set_sar_specs(struct ieee80211_hw *hw, const struct cfg80211_sar_specs *sar) { struct mt7921_dev *dev = mt7921_hw_dev(hw); - struct mt76_phy *mphy = hw->priv; int err; mt7921_mutex_acquire(dev); - err = mt76_init_sar_power(hw, sar); - if (err) - goto out; - - err = mt76_connac_mcu_set_rate_txpower(mphy); -out: + err = mt7921_set_tx_sar_pwr(hw, sar); mt7921_mutex_release(dev); return err; @@ -1500,6 +1517,44 @@ mt7921_channel_switch_beacon(struct ieee80211_hw *hw, mt7921_mutex_release(dev); } +static int +mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt7921_dev *dev = mt7921_hw_dev(hw); + int err; + + err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, + true); + if (err) + return err; + + err = mt7921_mcu_set_bss_pm(dev, vif, true); + if (err) + return err; + + return mt7921_mcu_sta_update(dev, NULL, vif, true, + MT76_STA_INFO_STATE_NONE); +} + +static void +mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; + struct mt7921_phy *phy = mt7921_hw_phy(hw); + struct mt7921_dev *dev = mt7921_hw_dev(hw); + int err; + + err = mt7921_mcu_set_bss_pm(dev, vif, false); + if (err) + return; + + mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, false); +} + const struct ieee80211_ops mt7921_ops = { .tx = mt7921_tx, .start = mt7921_start, @@ -1510,6 +1565,8 @@ const struct ieee80211_ops mt7921_ops = { .conf_tx = mt7921_conf_tx, .configure_filter = mt7921_configure_filter, .bss_info_changed = mt7921_bss_info_changed, + .start_ap = mt7921_start_ap, + .stop_ap = mt7921_stop_ap, .sta_state = mt7921_sta_state, .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove, .set_key = mt7921_set_key, diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 3b5b475b0875..da12d0ae0835 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1,79 +1,15 @@ // SPDX-License-Identifier: ISC /* Copyright (C) 2020 MediaTek Inc. */ -#include <linux/firmware.h> #include <linux/fs.h> #include "mt7921.h" #include "mt7921_trace.h" #include "mcu.h" #include "mac.h" -struct mt7921_patch_hdr { - char build_date[16]; - char platform[4]; - __be32 hw_sw_ver; - __be32 patch_ver; - __be16 checksum; - u16 reserved; - struct { - __be32 patch_ver; - __be32 subsys; - __be32 feature; - __be32 n_region; - __be32 crc; - u32 reserved[11]; - } desc; -} __packed; - -struct mt7921_patch_sec { - __be32 type; - __be32 offs; - __be32 size; - union { - __be32 spec[13]; - struct { - __be32 addr; - __be32 len; - __be32 sec_key_idx; - __be32 align_len; - u32 reserved[9]; - } info; - }; -} __packed; - -struct mt7921_fw_trailer { - u8 chip_id; - u8 eco_code; - u8 n_region; - u8 format_ver; - u8 format_flag; - u8 reserved[2]; - char fw_ver[10]; - char build_date[15]; - u32 crc; -} __packed; - -struct mt7921_fw_region { - __le32 decomp_crc; - __le32 decomp_len; - __le32 decomp_blk_sz; - u8 reserved[4]; - __le32 addr; - __le32 len; - u8 feature_set; - u8 reserved1[15]; -} __packed; - #define MT_STA_BFER BIT(0) #define MT_STA_BFEE BIT(1) -#define PATCH_SEC_ENC_TYPE_MASK GENMASK(31, 24) -#define PATCH_SEC_ENC_TYPE_PLAIN 0x00 -#define PATCH_SEC_ENC_TYPE_AES 0x01 -#define PATCH_SEC_ENC_TYPE_SCRAMBLE 0x02 -#define PATCH_SEC_ENC_SCRAMBLE_INFO_MASK GENMASK(15, 0) -#define PATCH_SEC_ENC_AES_KEY_MASK GENMASK(7, 0) - static int mt7921_mcu_parse_eeprom(struct mt76_dev *dev, struct sk_buff *skb) { @@ -83,7 +19,7 @@ mt7921_mcu_parse_eeprom(struct mt76_dev *dev, struct sk_buff *skb) if (!skb) return -EINVAL; - skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd)); res = (struct mt7921_mcu_eeprom_info *)skb->data; buf = dev->eeprom.data + le32_to_cpu(res->addr); @@ -96,7 +32,7 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, struct sk_buff *skb, int seq) { int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd); - struct mt7921_mcu_rxd *rxd; + struct mt76_connac2_mcu_rxd *rxd; int ret = 0; if (!skb) { @@ -107,11 +43,12 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, return -ETIMEDOUT; } - rxd = (struct mt7921_mcu_rxd *)skb->data; + rxd = (struct mt76_connac2_mcu_rxd *)skb->data; if (seq != rxd->seq) return -EAGAIN; - if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) { + if (cmd == MCU_CMD(PATCH_SEM_CONTROL) || + cmd == MCU_CMD(PATCH_FINISH_REQ)) { skb_pull(skb, sizeof(*rxd) - 4); ret = *skb->data; } else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) { @@ -140,90 +77,13 @@ int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, event = (struct mt7921_mcu_reg_event *)skb->data; ret = (int)le32_to_cpu(event->val); } else { - skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd)); } return ret; } EXPORT_SYMBOL_GPL(mt7921_mcu_parse_response); -int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb, - int cmd, int *wait_seq) -{ - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); - int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd); - struct mt7921_uni_txd *uni_txd; - struct mt7921_mcu_txd *mcu_txd; - __le32 *txd; - u32 val; - u8 seq; - - if (cmd == MCU_UNI_CMD(HIF_CTRL) || - cmd == MCU_UNI_CMD(SUSPEND) || - cmd == MCU_UNI_CMD(OFFLOAD)) - mdev->mcu.timeout = HZ; - else - mdev->mcu.timeout = 3 * HZ; - - seq = ++dev->mt76.mcu.msg_seq & 0xf; - if (!seq) - seq = ++dev->mt76.mcu.msg_seq & 0xf; - - if (cmd == MCU_CMD(FW_SCATTER)) - goto exit; - - txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd); - txd = (__le32 *)skb_push(skb, txd_len); - - val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) | - FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) | - FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0); - txd[0] = cpu_to_le32(val); - - val = MT_TXD1_LONG_FORMAT | - FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD); - txd[1] = cpu_to_le32(val); - - if (cmd & __MCU_CMD_FIELD_UNI) { - uni_txd = (struct mt7921_uni_txd *)txd; - uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd)); - uni_txd->option = MCU_CMD_UNI_EXT_ACK; - uni_txd->cid = cpu_to_le16(mcu_cmd); - uni_txd->s2d_index = MCU_S2D_H2N; - uni_txd->pkt_type = MCU_PKT_ID; - uni_txd->seq = seq; - - goto exit; - } - - mcu_txd = (struct mt7921_mcu_txd *)txd; - mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd)); - mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU, - MT_TX_MCU_PORT_RX_Q0)); - mcu_txd->pkt_type = MCU_PKT_ID; - mcu_txd->seq = seq; - mcu_txd->cid = mcu_cmd; - mcu_txd->s2d_index = MCU_S2D_H2N; - mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd); - - if (mcu_txd->ext_cid || (cmd & __MCU_CMD_FIELD_CE)) { - if (cmd & __MCU_CMD_FIELD_QUERY) - mcu_txd->set_query = MCU_Q_QUERY; - else - mcu_txd->set_query = MCU_Q_SET; - mcu_txd->ext_cid_ack = !!mcu_txd->ext_cid; - } else { - mcu_txd->set_query = MCU_Q_NA; - } - -exit: - if (wait_seq) - *wait_seq = seq; - - return 0; -} -EXPORT_SYMBOL_GPL(mt7921_mcu_fill_message); - #ifdef CONFIG_PM static int @@ -304,7 +164,7 @@ mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb) struct mt76_connac_beacon_loss_event *event; struct mt76_phy *mphy = &dev->mt76.phy; - skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd)); event = (struct mt76_connac_beacon_loss_event *)skb->data; ieee80211_iterate_active_interfaces_atomic(mphy->hw, @@ -318,7 +178,7 @@ mt7921_mcu_bss_event(struct mt7921_dev *dev, struct sk_buff *skb) struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_connac_mcu_bss_event *event; - skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd)); event = (struct mt76_connac_mcu_bss_event *)skb->data; if (event->is_absent) ieee80211_stop_queues(mphy->hw); @@ -338,7 +198,7 @@ mt7921_mcu_debug_msg_event(struct mt7921_dev *dev, struct sk_buff *skb) u8 content[512]; } __packed * msg; - skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd)); msg = (struct mt7921_debug_msg *)skb->data; if (msg->type == 3) { /* fw log */ @@ -361,7 +221,7 @@ mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb) u8 reserved[3]; } __packed * event; - skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd)); event = (struct mt7921_mcu_lp_event *)skb->data; trace_lp_event(dev, event->state); @@ -372,7 +232,7 @@ mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb) { struct mt7921_mcu_tx_done_event *event; - skb_pull(skb, sizeof(struct mt7921_mcu_rxd)); + skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd)); event = (struct mt7921_mcu_tx_done_event *)skb->data; mt7921_mac_add_txs(dev, event->txs); @@ -381,8 +241,9 @@ mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb) static void mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb) { - struct mt7921_mcu_rxd *rxd = (struct mt7921_mcu_rxd *)skb->data; + struct mt76_connac2_mcu_rxd *rxd; + rxd = (struct mt76_connac2_mcu_rxd *)skb->data; switch (rxd->eid) { case MCU_EVENT_BSS_BEACON_LOSS: mt7921_mcu_connection_loss_event(dev, skb); @@ -416,12 +277,12 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb) void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb) { - struct mt7921_mcu_rxd *rxd; + struct mt76_connac2_mcu_rxd *rxd; if (skb_linearize(skb)) return; - rxd = (struct mt7921_mcu_rxd *)skb->data; + rxd = (struct mt76_connac2_mcu_rxd *)skb->data; if (rxd->eid == 0x6) { mt76_mcu_rx_event(&dev->mt76, skb); @@ -469,34 +330,6 @@ int mt7921_mcu_uni_rx_ba(struct mt7921_dev *dev, enable, false); } -static u32 mt7921_get_data_mode(struct mt7921_dev *dev, u32 info) -{ - u32 mode = DL_MODE_NEED_RSP; - - if (info == PATCH_SEC_NOT_SUPPORT) - return mode; - - switch (FIELD_GET(PATCH_SEC_ENC_TYPE_MASK, info)) { - case PATCH_SEC_ENC_TYPE_PLAIN: - break; - case PATCH_SEC_ENC_TYPE_AES: - mode |= DL_MODE_ENCRYPT; - mode |= FIELD_PREP(DL_MODE_KEY_IDX, - (info & PATCH_SEC_ENC_AES_KEY_MASK)) & DL_MODE_KEY_IDX; - mode |= DL_MODE_RESET_SEC_IV; - break; - case PATCH_SEC_ENC_TYPE_SCRAMBLE: - mode |= DL_MODE_ENCRYPT; - mode |= DL_CONFIG_ENCRY_MODE_SEL; - mode |= DL_MODE_RESET_SEC_IV; - break; - default: - dev_err(dev->mt76.dev, "Encryption type not support!\n"); - } - - return mode; -} - static char *mt7921_patch_name(struct mt7921_dev *dev) { char *ret; @@ -509,152 +342,6 @@ static char *mt7921_patch_name(struct mt7921_dev *dev) return ret; } -static int mt7921_load_patch(struct mt7921_dev *dev) -{ - const struct mt7921_patch_hdr *hdr; - const struct firmware *fw = NULL; - int i, ret, sem, max_len; - - max_len = mt76_is_sdio(&dev->mt76) ? 2048 : 4096; - - sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, true); - switch (sem) { - case PATCH_IS_DL: - return 0; - case PATCH_NOT_DL_SEM_SUCCESS: - break; - default: - dev_err(dev->mt76.dev, "Failed to get patch semaphore\n"); - return -EAGAIN; - } - - ret = request_firmware(&fw, mt7921_patch_name(dev), dev->mt76.dev); - if (ret) - goto out; - - if (!fw || !fw->data || fw->size < sizeof(*hdr)) { - dev_err(dev->mt76.dev, "Invalid firmware\n"); - ret = -EINVAL; - goto out; - } - - hdr = (const struct mt7921_patch_hdr *)(fw->data); - - dev_info(dev->mt76.dev, "HW/SW Version: 0x%x, Build Time: %.16s\n", - be32_to_cpu(hdr->hw_sw_ver), hdr->build_date); - - for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) { - struct mt7921_patch_sec *sec; - const u8 *dl; - u32 len, addr, mode; - u32 sec_info = 0; - - sec = (struct mt7921_patch_sec *)(fw->data + sizeof(*hdr) + - i * sizeof(*sec)); - if ((be32_to_cpu(sec->type) & PATCH_SEC_TYPE_MASK) != - PATCH_SEC_TYPE_INFO) { - ret = -EINVAL; - goto out; - } - - addr = be32_to_cpu(sec->info.addr); - len = be32_to_cpu(sec->info.len); - dl = fw->data + be32_to_cpu(sec->offs); - sec_info = be32_to_cpu(sec->info.sec_key_idx); - mode = mt7921_get_data_mode(dev, sec_info); - - ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len, - mode); - if (ret) { - dev_err(dev->mt76.dev, "Download request failed\n"); - goto out; - } - - ret = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER), - dl, len, max_len); - if (ret) { - dev_err(dev->mt76.dev, "Failed to send patch\n"); - goto out; - } - } - - ret = mt76_connac_mcu_start_patch(&dev->mt76); - if (ret) - dev_err(dev->mt76.dev, "Failed to start patch\n"); - - if (mt76_is_sdio(&dev->mt76)) { - /* activate again */ - ret = __mt7921_mcu_fw_pmctrl(dev); - if (!ret) - ret = __mt7921_mcu_drv_pmctrl(dev); - } - -out: - sem = mt76_connac_mcu_patch_sem_ctrl(&dev->mt76, false); - switch (sem) { - case PATCH_REL_SEM_SUCCESS: - break; - default: - ret = -EAGAIN; - dev_err(dev->mt76.dev, "Failed to release patch semaphore\n"); - break; - } - release_firmware(fw); - - return ret; -} - -static int -mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev, - const struct mt7921_fw_trailer *hdr, - const u8 *data, bool is_wa) -{ - int i, offset = 0, max_len; - u32 override = 0, option = 0; - - max_len = mt76_is_sdio(&dev->mt76) ? 2048 : 4096; - - for (i = 0; i < hdr->n_region; i++) { - const struct mt7921_fw_region *region; - int err; - u32 len, addr, mode; - - region = (const struct mt7921_fw_region *)((const u8 *)hdr - - (hdr->n_region - i) * sizeof(*region)); - mode = mt76_connac_mcu_gen_dl_mode(&dev->mt76, - region->feature_set, is_wa); - len = le32_to_cpu(region->len); - addr = le32_to_cpu(region->addr); - - if (region->feature_set & FW_FEATURE_OVERRIDE_ADDR) - override = addr; - - err = mt76_connac_mcu_init_download(&dev->mt76, addr, len, - mode); - if (err) { - dev_err(dev->mt76.dev, "Download request failed\n"); - return err; - } - - err = __mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER), - data + offset, len, max_len); - if (err) { - dev_err(dev->mt76.dev, "Failed to send firmware.\n"); - return err; - } - - offset += len; - } - - if (override) - option |= FW_START_OVERRIDE; - - if (is_wa) - option |= FW_START_WORKING_PDA_CR4; - - return mt76_connac_mcu_start_firmware(&dev->mt76, override, option); -} - static char *mt7921_ram_name(struct mt7921_dev *dev) { char *ret; @@ -667,44 +354,6 @@ static char *mt7921_ram_name(struct mt7921_dev *dev) return ret; } -static int mt7921_load_ram(struct mt7921_dev *dev) -{ - const struct mt7921_fw_trailer *hdr; - const struct firmware *fw; - int ret; - - ret = request_firmware(&fw, mt7921_ram_name(dev), dev->mt76.dev); - if (ret) - return ret; - - if (!fw || !fw->data || fw->size < sizeof(*hdr)) { - dev_err(dev->mt76.dev, "Invalid firmware\n"); - ret = -EINVAL; - goto out; - } - - hdr = (const struct mt7921_fw_trailer *)(fw->data + fw->size - - sizeof(*hdr)); - - dev_info(dev->mt76.dev, "WM Firmware Version: %.10s, Build Time: %.15s\n", - hdr->fw_ver, hdr->build_date); - - ret = mt7921_mcu_send_ram_firmware(dev, hdr, fw->data, false); - if (ret) { - dev_err(dev->mt76.dev, "Failed to start WM firmware\n"); - goto out; - } - - snprintf(dev->mt76.hw->wiphy->fw_version, - sizeof(dev->mt76.hw->wiphy->fw_version), - "%.10s-%.15s", hdr->fw_ver, hdr->build_date); - -out: - release_firmware(fw); - - return ret; -} - static int mt7921_load_firmware(struct mt7921_dev *dev) { int ret; @@ -715,11 +364,18 @@ static int mt7921_load_firmware(struct mt7921_dev *dev) goto fw_loaded; } - ret = mt7921_load_patch(dev); + ret = mt76_connac2_load_patch(&dev->mt76, mt7921_patch_name(dev)); if (ret) return ret; - ret = mt7921_load_ram(dev); + if (mt76_is_sdio(&dev->mt76)) { + /* activate again */ + ret = __mt7921_mcu_fw_pmctrl(dev); + if (!ret) + ret = __mt7921_mcu_drv_pmctrl(dev); + } + + ret = mt76_connac2_load_ram(&dev->mt76, mt7921_ram_name(dev), NULL); if (ret) return ret; @@ -771,12 +427,6 @@ int mt7921_run_firmware(struct mt7921_dev *dev) } EXPORT_SYMBOL_GPL(mt7921_run_firmware); -void mt7921_mcu_exit(struct mt7921_dev *dev) -{ - skb_queue_purge(&dev->mt76.mcu.res_q); -} -EXPORT_SYMBOL_GPL(mt7921_mcu_exit); - int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif) { struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv; @@ -972,7 +622,7 @@ int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif) .ps = { .tag = cpu_to_le16(UNI_BSS_INFO_PS), .len = cpu_to_le16(sizeof(struct ps_tlv)), - .ps_state = vif->bss_conf.ps ? 2 : 0, + .ps_state = vif->cfg.ps ? 2 : 0, }, }; @@ -1019,7 +669,7 @@ mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif, &bcnft_req, sizeof(bcnft_req), true); } -static int +int mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, bool enable) { @@ -1048,9 +698,6 @@ mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, }; int err; - if (vif->type != NL80211_IFTYPE_STATION) - return 0; - err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT), &req_hdr, sizeof(req_hdr), false); if (err < 0 || !enable) @@ -1132,7 +779,6 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev, struct ieee80211_vif *vif, bool enable) { - struct ieee80211_hw *hw = mt76_hw(dev); int err; if (enable) { @@ -1140,8 +786,6 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev, if (err) return err; - vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; - ieee80211_hw_set(hw, CONNECTION_MONITOR); mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON); return 0; @@ -1151,8 +795,6 @@ int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev, if (err) return err; - vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER; - __clear_bit(IEEE80211_HW_CONNECTION_MONITOR, hw->flags); mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON); return 0; @@ -1255,8 +897,11 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, }; struct sk_buff *skb; + /* support enable/update process only + * disable flow would be handled in bss stop handler automatically + */ if (!enable) - goto out; + return -EOPNOTSUPP; skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs, 0); if (!skb) @@ -1268,8 +913,8 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, return -EINVAL; } - mt7921_mac_write_txwi(dev, (__le32 *)(req.beacon_tlv.pkt), skb, - wcid, NULL, 0, true); + mt76_connac2_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt), + skb, wcid, NULL, 0, 0, BSS_CHANGED_BEACON); memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len); req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len); req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset); @@ -1282,7 +927,6 @@ mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, } dev_kfree_skb(skb); -out: return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE), &req, sizeof(req), true); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h index 77cc0cc5b436..0d20f7d8d474 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h @@ -6,76 +6,6 @@ #include "../mt76_connac_mcu.h" -struct mt7921_mcu_txd { - __le32 txd[8]; - - __le16 len; - __le16 pq_id; - - u8 cid; - u8 pkt_type; - u8 set_query; /* FW don't care */ - u8 seq; - - u8 uc_d2b0_rev; - u8 ext_cid; - u8 s2d_index; - u8 ext_cid_ack; - - u32 reserved[5]; -} __packed __aligned(4); - -/** - * struct mt7921_uni_txd - mcu command descriptor for firmware v3 - * @txd: hardware descriptor - * @len: total length not including txd - * @cid: command identifier - * @pkt_type: must be 0xa0 (cmd packet by long format) - * @frag_n: fragment number - * @seq: sequence number - * @checksum: 0 mean there is no checksum - * @s2d_index: index for command source and destination - * Definition | value | note - * CMD_S2D_IDX_H2N | 0x00 | command from HOST to WM - * CMD_S2D_IDX_C2N | 0x01 | command from WA to WM - * CMD_S2D_IDX_H2C | 0x02 | command from HOST to WA - * CMD_S2D_IDX_H2N_AND_H2C | 0x03 | command from HOST to WA and WM - * - * @option: command option - * BIT[0]: UNI_CMD_OPT_BIT_ACK - * set to 1 to request a fw reply - * if UNI_CMD_OPT_BIT_0_ACK is set and UNI_CMD_OPT_BIT_2_SET_QUERY - * is set, mcu firmware will send response event EID = 0x01 - * (UNI_EVENT_ID_CMD_RESULT) to the host. - * BIT[1]: UNI_CMD_OPT_BIT_UNI_CMD - * 0: original command - * 1: unified command - * BIT[2]: UNI_CMD_OPT_BIT_SET_QUERY - * 0: QUERY command - * 1: SET command - */ -struct mt7921_uni_txd { - __le32 txd[8]; - - /* DW1 */ - __le16 len; - __le16 cid; - - /* DW2 */ - u8 reserved; - u8 pkt_type; - u8 frag_n; - u8 seq; - - /* DW3 */ - __le16 checksum; - u8 s2d_index; - u8 option; - - /* DW4 */ - u8 reserved2[4]; -} __packed __aligned(4); - struct mt7921_mcu_tx_done_event { u8 pid; u8 status; @@ -108,21 +38,6 @@ enum { MCU_EXT_EVENT_RATE_REPORT = 0x87, }; -struct mt7921_mcu_rxd { - __le32 rxd[6]; - - __le16 len; - __le16 pkt_type_id; - - u8 eid; - u8 seq; - __le16 __rsv; - - u8 ext_eid; - u8 __rsv1[2]; - u8 s2d_index; -}; - struct mt7921_mcu_eeprom_info { __le32 addr; __le32 valid; @@ -135,9 +50,6 @@ struct mt7921_mcu_eeprom_info { #define MT_RA_RATE_DCM_EN BIT(4) #define MT_RA_RATE_BW GENMASK(14, 13) -#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10)) -#define MCU_PKT_ID 0xa0 - struct mt7921_mcu_uni_event { u8 cid; u8 pad[3]; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 5ca584bb2fc6..c161031ac62a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -8,9 +8,9 @@ #include <linux/ktime.h> #include "../mt76_connac_mcu.h" #include "regs.h" +#include "acpi_sar.h" #define MT7921_MAX_INTERFACES 4 -#define MT7921_MAX_WMM_SETS 4 #define MT7921_WTBL_SIZE 20 #define MT7921_WTBL_RESERVED (MT7921_WTBL_SIZE - 1) #define MT7921_WTBL_STA (MT7921_WTBL_RESERVED - \ @@ -171,6 +171,9 @@ struct mt7921_phy { struct sk_buff_head scan_event_list; struct delayed_work scan_work; +#ifdef CONFIG_ACPI + struct mt7921_acpi_sar *acpisar; +#endif }; #define mt7921_init_reset(dev) ((dev)->hif_ops->init_reset(dev)) @@ -247,16 +250,6 @@ struct mt7921_txpwr { } data[TXPWR_MAX_NUM]; }; -enum { - MT_LMAC_AC00, - MT_LMAC_AC01, - MT_LMAC_AC02, - MT_LMAC_AC03, - MT_LMAC_ALTX0 = 0x10, - MT_LMAC_BMC0, - MT_LMAC_BCN0, -}; - static inline struct mt7921_phy * mt7921_hw_phy(struct ieee80211_hw *hw) { @@ -279,7 +272,6 @@ mt7921_hw_dev(struct ieee80211_hw *hw) mt76_connac_mutex_release(&(dev)->mt76, &(dev)->pm) extern const struct ieee80211_ops mt7921_ops; -extern struct pci_driver mt7921_pci_driver; u32 mt7921_reg_map(struct mt7921_dev *dev, u32 addr); @@ -291,6 +283,8 @@ int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force); int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev); void mt7921_dma_cleanup(struct mt7921_dev *dev); int mt7921_run_firmware(struct mt7921_dev *dev); +int mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif, + bool enable); int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta, struct ieee80211_vif *vif, bool enable, enum mt76_sta_info_state state); @@ -301,7 +295,6 @@ int mt7921_mcu_get_rx_rate(struct mt7921_phy *phy, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct rate_info *rate); int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl); void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb); -void mt7921_mcu_exit(struct mt7921_dev *dev); static inline void mt7921_irq_enable(struct mt7921_dev *dev, u32 mask) { @@ -352,12 +345,6 @@ static inline bool mt7921_dma_need_reinit(struct mt7921_dev *dev) return !mt76_get_field(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT); } -static inline void mt7921_mcu_tx_cleanup(struct mt7921_dev *dev) -{ - mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false); - mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WA], false); -} - static inline void mt7921_skb_add_usb_sdio_hdr(struct mt7921_dev *dev, struct sk_buff *skb, int type) @@ -392,7 +379,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct mt76_tx_info *tx_info); void mt7921_tx_worker(struct mt76_worker *w); -void mt7921e_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e); void mt7921_tx_token_put(struct mt7921_dev *dev); void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, struct sk_buff *skb); @@ -424,14 +410,8 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len); int mt7921_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, struct netlink_callback *cb, void *data, int len); -void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi, - struct sk_buff *skb, struct mt76_wcid *wcid, - struct ieee80211_key_conf *key, int pid, - bool beacon); void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi); void mt7921_mac_sta_poll(struct mt7921_dev *dev); -int mt7921_mcu_fill_message(struct mt76_dev *mdev, struct sk_buff *skb, - int cmd, int *wait_seq); int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd, struct sk_buff *skb, int seq); @@ -481,4 +461,22 @@ int mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev, struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool enable); +#ifdef CONFIG_ACPI +int mt7921_init_acpi_sar(struct mt7921_dev *dev); +int mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default); +#else +static inline int +mt7921_init_acpi_sar(struct mt7921_dev *dev) +{ + return 0; +} + +static inline int +mt7921_init_acpi_sar_power(struct mt7921_phy *phy, bool set_default) +{ + return 0; +} +#endif +int mt7921_set_tx_sar_pwr(struct ieee80211_hw *hw, + const struct cfg80211_sar_specs *sar); #endif diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index b5fb22b8e086..ea3069d18c35 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -116,7 +116,7 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev) mt7921_mcu_drv_pmctrl(dev); mt7921_dma_cleanup(dev); mt7921_wfsys_reset(dev); - mt7921_mcu_exit(dev); + skb_queue_purge(&dev->mt76.mcu.res_q); tasklet_disable(&dev->irq_tasklet); } @@ -230,14 +230,14 @@ static int mt7921_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 mt7921_txp_common), + .txwi_size = MT_TXD_SIZE + sizeof(struct mt76_connac_hw_txp), .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, .token_size = MT7921_TOKEN_SIZE, .tx_prepare_skb = mt7921e_tx_prepare_skb, - .tx_complete_skb = mt7921e_tx_complete_skb, + .tx_complete_skb = mt76_connac_tx_complete_skb, .rx_check = mt7921e_rx_check, .rx_skb = mt7921e_queue_rx_skb, .rx_poll_complete = mt7921_rx_poll_complete, @@ -247,7 +247,6 @@ static int mt7921_pci_probe(struct pci_dev *pdev, .sta_remove = mt7921_mac_sta_remove, .update_survey = mt7921_update_channel, }; - static const struct mt7921_hif_ops mt7921_pcie_ops = { .init_reset = mt7921e_init_reset, .reset = mt7921e_mac_reset, @@ -359,9 +358,9 @@ static void mt7921_pci_remove(struct pci_dev *pdev) pci_free_irq_vectors(pdev); } -#ifdef CONFIG_PM -static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state) +static int mt7921_pci_suspend(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct mt76_dev *mdev = pci_get_drvdata(pdev); struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); struct mt76_connac_pm *pm = &dev->pm; @@ -391,8 +390,6 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state) napi_disable(&mdev->napi[i]); } - pci_enable_wake(pdev, pci_choose_state(pdev, state), true); - /* wait until dma is idle */ mt76_poll(dev, MT_WFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_TX_DMA_BUSY | @@ -412,8 +409,6 @@ static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state) if (err) goto restore_napi; - pci_save_state(pdev); - err = pci_set_power_state(pdev, pci_choose_state(pdev, state)); if (err) goto restore_napi; @@ -436,19 +431,14 @@ restore_suspend: return err; } -static int mt7921_pci_resume(struct pci_dev *pdev) +static int mt7921_pci_resume(struct device *device) { + struct pci_dev *pdev = to_pci_dev(device); struct mt76_dev *mdev = pci_get_drvdata(pdev); struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); struct mt76_connac_pm *pm = &dev->pm; int i, err; - err = pci_set_power_state(pdev, PCI_D0); - if (err) - return err; - - pci_restore_state(pdev); - err = mt7921_mcu_drv_pmctrl(dev); if (err < 0) return err; @@ -488,17 +478,15 @@ static int mt7921_pci_resume(struct pci_dev *pdev) return err; } -#endif /* CONFIG_PM */ -struct pci_driver mt7921_pci_driver = { +static DEFINE_SIMPLE_DEV_PM_OPS(mt7921_pm_ops, mt7921_pci_suspend, mt7921_pci_resume); + +static struct pci_driver mt7921_pci_driver = { .name = KBUILD_MODNAME, .id_table = mt7921_pci_device_table, .probe = mt7921_pci_probe, .remove = mt7921_pci_remove, -#ifdef CONFIG_PM - .suspend = mt7921_pci_suspend, - .resume = mt7921_pci_resume, -#endif /* CONFIG_PM */ + .driver.pm = pm_sleep_ptr(&mt7921_pm_ops), }; module_pci_driver(mt7921_pci_driver); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c index 5ca14dbbdd26..e1800674089a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c @@ -5,37 +5,6 @@ #include "../dma.h" #include "mac.h" -static void -mt7921_write_hw_txp(struct mt7921_dev *dev, struct mt76_tx_info *tx_info, - void *txp_ptr, u32 id) -{ - struct mt7921_hw_txp *txp = txp_ptr; - struct mt7921_txp_ptr *ptr = &txp->ptr[0]; - int i, nbuf = tx_info->nbuf - 1; - - tx_info->buf[0].len = MT_TXD_SIZE + sizeof(*txp); - tx_info->nbuf = 1; - - txp->msdu_id[0] = cpu_to_le16(id | MT_MSDU_ID_VALID); - - for (i = 0; i < nbuf; i++) { - u16 len = tx_info->buf[i + 1].len & MT_TXD_LEN_MASK; - u32 addr = tx_info->buf[i + 1].addr; - - if (i == nbuf - 1) - len |= MT_TXD_LEN_LAST; - - if (i & 1) { - ptr->buf1 = cpu_to_le32(addr); - ptr->len1 = cpu_to_le16(len); - ptr++; - } else { - ptr->buf0 = cpu_to_le32(addr); - ptr->len0 = cpu_to_le16(len); - } - } -} - int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, enum mt76_txq_id qid, struct mt76_wcid *wcid, struct ieee80211_sta *sta, @@ -44,8 +13,8 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_info->skb); struct ieee80211_key_conf *key = info->control.hw_key; + struct mt76_connac_hw_txp *txp; struct mt76_txwi_cache *t; - struct mt7921_txp_common *txp; int id, pid; u8 *txwi = (u8 *)txwi_ptr; @@ -72,12 +41,12 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, } pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); - mt7921_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key, - pid, false); + mt76_connac2_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, key, + pid, qid, 0); - txp = (struct mt7921_txp_common *)(txwi + MT_TXD_SIZE); - memset(txp, 0, sizeof(struct mt7921_txp_common)); - mt7921_write_hw_txp(dev, tx_info, txp, id); + txp = (struct mt76_connac_hw_txp *)(txwi + MT_TXD_SIZE); + memset(txp, 0, sizeof(struct mt76_connac_hw_txp)); + mt76_connac_write_hw_txp(mdev, tx_info, txp, id); tx_info->skb = DMA_DUMMY_DATA; @@ -85,37 +54,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, } static void -mt7921_txp_skb_unmap(struct mt76_dev *dev, struct mt76_txwi_cache *t) -{ - struct mt7921_txp_common *txp; - int i; - - txp = mt7921_txwi_to_txp(dev, t); - - for (i = 0; i < ARRAY_SIZE(txp->hw.ptr); i++) { - struct mt7921_txp_ptr *ptr = &txp->hw.ptr[i]; - bool last; - u16 len; - - len = le16_to_cpu(ptr->len0); - last = len & MT_TXD_LEN_LAST; - len &= MT_TXD_LEN_MASK; - dma_unmap_single(dev->dev, le32_to_cpu(ptr->buf0), len, - DMA_TO_DEVICE); - if (last) - break; - - len = le16_to_cpu(ptr->len1); - last = len & MT_TXD_LEN_LAST; - len &= MT_TXD_LEN_MASK; - dma_unmap_single(dev->dev, le32_to_cpu(ptr->buf1), len, - DMA_TO_DEVICE); - if (last) - break; - } -} - -static void mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t, struct ieee80211_sta *sta, bool clear_status, struct list_head *free_list) @@ -124,7 +62,7 @@ mt7921_txwi_free(struct mt7921_dev *dev, struct mt76_txwi_cache *t, __le32 *txwi; u16 wcid_idx; - mt7921_txp_skb_unmap(mdev, t); + mt76_connac_txp_skb_unmap(mdev, t); if (!t->skb) goto out; @@ -150,7 +88,8 @@ out: static void mt7921e_mac_tx_free(struct mt7921_dev *dev, void *data, int len) { - struct mt7921_tx_free *free = (struct mt7921_tx_free *)data; + struct mt76_connac_tx_free *free = data; + __le32 *tx_info = (__le32 *)(data + sizeof(*free)); struct mt76_dev *mdev = &dev->mt76; struct mt76_txwi_cache *txwi; struct ieee80211_sta *sta = NULL; @@ -165,11 +104,11 @@ mt7921e_mac_tx_free(struct mt7921_dev *dev, void *data, int len) mt76_queue_tx_cleanup(dev, dev->mphy.q_tx[MT_TXQ_BE], false); count = le16_get_bits(free->ctrl, MT_TX_FREE_MSDU_CNT); - if (WARN_ON_ONCE((void *)&free->info[count] > end)) + if (WARN_ON_ONCE((void *)&tx_info[count] > end)) return; for (i = 0; i < count; i++) { - u32 msdu, info = le32_to_cpu(free->info[i]); + u32 msdu, info = le32_to_cpu(tx_info[i]); u8 stat; /* 1'b1: new wcid pair. @@ -262,29 +201,6 @@ void mt7921e_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, } } -void mt7921e_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e) -{ - if (!e->txwi) { - dev_kfree_skb_any(e->skb); - return; - } - - /* error path */ - if (e->skb == DMA_DUMMY_DATA) { - struct mt76_txwi_cache *t; - struct mt7921_txp_common *txp; - u16 token; - - txp = mt7921_txwi_to_txp(mdev, e->txwi); - token = le16_to_cpu(txp->hw.msdu_id[0]) & ~MT_MSDU_ID_VALID; - t = mt76_token_put(mdev, token); - e->skb = t ? t->skb : NULL; - } - - if (e->skb) - mt76_tx_complete_skb(mdev, e->wcid, e->skb); -} - void mt7921_tx_token_put(struct mt7921_dev *dev) { struct mt76_txwi_cache *txwi; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c index 36669e5aeef3..5efda694fb9d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c @@ -26,10 +26,17 @@ mt7921_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, enum mt76_mcuq_id txq = MT_MCUQ_WM; int ret; - ret = mt7921_mcu_fill_message(mdev, skb, cmd, seq); + ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq); if (ret) return ret; + if (cmd == MCU_UNI_CMD(HIF_CTRL) || + cmd == MCU_UNI_CMD(SUSPEND) || + cmd == MCU_UNI_CMD(OFFLOAD)) + mdev->mcu.timeout = HZ; + else + mdev->mcu.timeout = 3 * HZ; + if (cmd == MCU_CMD(FW_SCATTER)) txq = MT_MCUQ_FWDL; @@ -39,7 +46,7 @@ mt7921_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, int mt7921e_mcu_init(struct mt7921_dev *dev) { static const struct mt76_mcu_ops mt7921_mcu_ops = { - .headroom = sizeof(struct mt7921_mcu_txd), + .headroom = sizeof(struct mt76_connac2_mcu_txd), .mcu_skb_send_msg = mt7921_mcu_send_message, .mcu_parse_response = mt7921_mcu_parse_response, .mcu_restart = mt76_connac_mcu_restart, @@ -102,7 +109,7 @@ int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev) { struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_connac_pm *pm = &dev->pm; - int i, err = 0; + int i; for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) { mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_SET_OWN); @@ -114,12 +121,12 @@ int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev) if (i == MT7921_DRV_OWN_RETRY_COUNT) { dev_err(dev->mt76.dev, "firmware own failed\n"); clear_bit(MT76_STATE_PM, &mphy->state); - err = -EIO; + return -EIO; } pm->stats.last_doze_event = jiffies; pm->stats.awake_time += pm->stats.last_doze_event - pm->stats.last_wake_event; - return err; + return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c index af26d59fa2f0..487acd6e2be8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c @@ -48,7 +48,7 @@ static void mt7921s_unregister_device(struct mt7921_dev *dev) mt76s_deinit(&dev->mt76); mt7921s_wfsys_reset(dev); - mt7921_mcu_exit(dev); + skb_queue_purge(&dev->mt76.mcu.res_q); mt76_free_device(&dev->mt76); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c index 54a5c712a3c3..e038d7404323 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mcu.c @@ -29,10 +29,17 @@ mt7921s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, if (dev->fw_assert) return -EBUSY; - ret = mt7921_mcu_fill_message(mdev, skb, cmd, seq); + ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq); if (ret) return ret; + if (cmd == MCU_UNI_CMD(HIF_CTRL) || + cmd == MCU_UNI_CMD(SUSPEND) || + cmd == MCU_UNI_CMD(OFFLOAD)) + mdev->mcu.timeout = HZ; + else + mdev->mcu.timeout = 3 * HZ; + if (cmd == MCU_CMD(FW_SCATTER)) type = MT7921_SDIO_FWDL; @@ -72,7 +79,8 @@ static u32 mt7921s_clear_rm3r_drv_own(struct mt7921_dev *dev) int mt7921s_mcu_init(struct mt7921_dev *dev) { static const struct mt76_mcu_ops mt7921s_mcu_ops = { - .headroom = MT_SDIO_HDR_SIZE + sizeof(struct mt7921_mcu_txd), + .headroom = MT_SDIO_HDR_SIZE + + sizeof(struct mt76_connac2_mcu_txd), .tailroom = MT_SDIO_TAIL_SIZE, .mcu_skb_send_msg = mt7921s_mcu_send_message, .mcu_parse_response = mt7921_mcu_parse_response, @@ -99,8 +107,8 @@ int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev) struct sdio_func *func = dev->mt76.sdio.func; struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_connac_pm *pm = &dev->pm; - int err = 0; u32 status; + int err; sdio_claim_host(func); @@ -118,8 +126,7 @@ int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev) if (err < 0) { dev_err(dev->mt76.dev, "driver own failed\n"); - err = -EIO; - goto out; + return -EIO; } clear_bit(MT76_STATE_PM, &mphy->state); @@ -127,8 +134,8 @@ int mt7921s_mcu_drv_pmctrl(struct mt7921_dev *dev) pm->stats.last_wake_event = jiffies; pm->stats.doze_time += pm->stats.last_wake_event - pm->stats.last_doze_event; -out: - return err; + + return 0; } int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev) @@ -136,8 +143,8 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev) struct sdio_func *func = dev->mt76.sdio.func; struct mt76_phy *mphy = &dev->mt76.phy; struct mt76_connac_pm *pm = &dev->pm; - int err = 0; u32 status; + int err; sdio_claim_host(func); @@ -148,7 +155,7 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev) 2000, 1000000); if (err < 0) { dev_err(dev->mt76.dev, "mailbox ACK not cleared\n"); - goto err; + goto out; } } @@ -156,18 +163,18 @@ int mt7921s_mcu_fw_pmctrl(struct mt7921_dev *dev) err = readx_poll_timeout(mt76s_read_pcr, &dev->mt76, status, !(status & WHLPCR_IS_DRIVER_OWN), 2000, 1000000); +out: sdio_release_host(func); -err: if (err < 0) { dev_err(dev->mt76.dev, "firmware own failed\n"); clear_bit(MT76_STATE_PM, &mphy->state); - err = -EIO; + return -EIO; } pm->stats.last_doze_event = jiffies; pm->stats.awake_time += pm->stats.last_doze_event - pm->stats.last_wake_event; - return err; + return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c index dc38baef273a..dd3b8884e162 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb.c @@ -102,10 +102,17 @@ mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, u32 pad, ep; int ret; - ret = mt7921_mcu_fill_message(mdev, skb, cmd, seq); + ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq); if (ret) return ret; + if (cmd == MCU_UNI_CMD(HIF_CTRL) || + cmd == MCU_UNI_CMD(SUSPEND) || + cmd == MCU_UNI_CMD(OFFLOAD)) + mdev->mcu.timeout = HZ; + else + mdev->mcu.timeout = 3 * HZ; + if (cmd != MCU_CMD(FW_SCATTER)) ep = MT_EP_OUT_INBAND_CMD; else @@ -125,7 +132,8 @@ mt7921u_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, static int mt7921u_mcu_init(struct mt7921_dev *dev) { static const struct mt76_mcu_ops mcu_ops = { - .headroom = MT_SDIO_HDR_SIZE + sizeof(struct mt7921_mcu_txd), + .headroom = MT_SDIO_HDR_SIZE + + sizeof(struct mt76_connac2_mcu_txd), .tailroom = MT_USB_TAIL_SIZE, .mcu_skb_send_msg = mt7921u_mcu_send_message, .mcu_parse_response = mt7921_mcu_parse_response, @@ -158,7 +166,7 @@ static void mt7921u_cleanup(struct mt7921_dev *dev) { clear_bit(MT76_STATE_INITIALIZED, &dev->mphy.state); mt7921u_wfsys_reset(dev); - mt7921_mcu_exit(dev); + skb_queue_purge(&dev->mt76.mcu.res_q); mt76u_queues_deinit(&dev->mt76); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/usb_mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/usb_mac.c index cd2f09743d2f..efbd3954c883 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/usb_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/usb_mac.c @@ -185,7 +185,7 @@ int mt7921u_init_reset(struct mt7921_dev *dev) set_bit(MT76_RESET, &dev->mphy.state); wake_up(&dev->mt76.mcu.wait); - mt7921_mcu_exit(dev); + skb_queue_purge(&dev->mt76.mcu.res_q); mt76u_stop_rx(&dev->mt76); mt76u_stop_tx(&dev->mt76); @@ -208,7 +208,7 @@ int mt7921u_mac_reset(struct mt7921_dev *dev) set_bit(MT76_MCU_RESET, &dev->mphy.state); wake_up(&dev->mt76.mcu.wait); - mt7921_mcu_exit(dev); + skb_queue_purge(&dev->mt76.mcu.res_q); mt76u_stop_rx(&dev->mt76); mt76u_stop_tx(&dev->mt76); |