Commit 2551a922 authored by Kalle Valo's avatar Kalle Valo

Merge tag 'mt76-for-kvalo-2022-12-01' of https://github.com/nbd168/wireless

mt76 patches for 6.2

- fixes
- WED support for mt7986 + mt7915 for flow offloading
- new driver for the mt7996 wifi-7 chipset
parents 94b9b9de f23a0cea
...@@ -34,3 +34,4 @@ source "drivers/net/wireless/mediatek/mt76/mt7603/Kconfig" ...@@ -34,3 +34,4 @@ source "drivers/net/wireless/mediatek/mt76/mt7603/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7615/Kconfig" source "drivers/net/wireless/mediatek/mt76/mt7615/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7915/Kconfig" source "drivers/net/wireless/mediatek/mt76/mt7915/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7921/Kconfig" source "drivers/net/wireless/mediatek/mt76/mt7921/Kconfig"
source "drivers/net/wireless/mediatek/mt76/mt7996/Kconfig"
...@@ -35,3 +35,4 @@ obj-$(CONFIG_MT7603E) += mt7603/ ...@@ -35,3 +35,4 @@ obj-$(CONFIG_MT7603E) += mt7603/
obj-$(CONFIG_MT7615_COMMON) += mt7615/ obj-$(CONFIG_MT7615_COMMON) += mt7615/
obj-$(CONFIG_MT7915E) += mt7915/ obj-$(CONFIG_MT7915E) += mt7915/
obj-$(CONFIG_MT7921_COMMON) += mt7921/ obj-$(CONFIG_MT7921_COMMON) += mt7921/
obj-$(CONFIG_MT7996E) += mt7996/
...@@ -100,23 +100,6 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str, ...@@ -100,23 +100,6 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str,
} }
EXPORT_SYMBOL_GPL(mt76_seq_puts_array); EXPORT_SYMBOL_GPL(mt76_seq_puts_array);
static int mt76_read_rate_txpower(struct seq_file *s, void *data)
{
struct mt76_dev *dev = dev_get_drvdata(s->private);
mt76_seq_puts_array(s, "CCK", dev->rate_power.cck,
ARRAY_SIZE(dev->rate_power.cck));
mt76_seq_puts_array(s, "OFDM", dev->rate_power.ofdm,
ARRAY_SIZE(dev->rate_power.ofdm));
mt76_seq_puts_array(s, "STBC", dev->rate_power.stbc,
ARRAY_SIZE(dev->rate_power.stbc));
mt76_seq_puts_array(s, "HT", dev->rate_power.ht,
ARRAY_SIZE(dev->rate_power.ht));
mt76_seq_puts_array(s, "VHT", dev->rate_power.vht,
ARRAY_SIZE(dev->rate_power.vht));
return 0;
}
struct dentry * struct dentry *
mt76_register_debugfs_fops(struct mt76_phy *phy, mt76_register_debugfs_fops(struct mt76_phy *phy,
const struct file_operations *ops) const struct file_operations *ops)
...@@ -137,8 +120,6 @@ mt76_register_debugfs_fops(struct mt76_phy *phy, ...@@ -137,8 +120,6 @@ mt76_register_debugfs_fops(struct mt76_phy *phy,
debugfs_create_blob("eeprom", 0400, dir, &dev->eeprom); debugfs_create_blob("eeprom", 0400, dir, &dev->eeprom);
if (dev->otp.data) if (dev->otp.data)
debugfs_create_blob("otp", 0400, dir, &dev->otp); debugfs_create_blob("otp", 0400, dir, &dev->otp);
debugfs_create_devm_seqfile(dev->dev, "rate_txpower", dir,
mt76_read_rate_txpower);
debugfs_create_devm_seqfile(dev->dev, "rx-queues", dir, debugfs_create_devm_seqfile(dev->dev, "rx-queues", dir,
mt76_rx_queues_read); mt76_rx_queues_read);
......
This diff is collapsed.
...@@ -15,6 +15,14 @@ ...@@ -15,6 +15,14 @@
#define MT_DMA_CTL_SD_LEN0 GENMASK(29, 16) #define MT_DMA_CTL_SD_LEN0 GENMASK(29, 16)
#define MT_DMA_CTL_LAST_SEC0 BIT(30) #define MT_DMA_CTL_LAST_SEC0 BIT(30)
#define MT_DMA_CTL_DMA_DONE BIT(31) #define MT_DMA_CTL_DMA_DONE BIT(31)
#define MT_DMA_CTL_TO_HOST BIT(8)
#define MT_DMA_CTL_TO_HOST_A BIT(12)
#define MT_DMA_CTL_DROP BIT(14)
#define MT_DMA_CTL_TOKEN GENMASK(31, 16)
#define MT_DMA_PPE_CPU_REASON GENMASK(15, 11)
#define MT_DMA_PPE_ENTRY GENMASK(30, 16)
#define MT_DMA_INFO_PPE_VLD BIT(31)
#define MT_DMA_HDR_LEN 4 #define MT_DMA_HDR_LEN 4
#define MT_RX_INFO_LEN 4 #define MT_RX_INFO_LEN 4
......
...@@ -443,8 +443,12 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw) ...@@ -443,8 +443,12 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw)
ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS); ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU); ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
ieee80211_hw_set(hw, TX_AMSDU);
ieee80211_hw_set(hw, TX_FRAG_LIST); if (!(dev->drv->drv_flags & MT_DRV_AMSDU_OFFLOAD)) {
ieee80211_hw_set(hw, TX_AMSDU);
ieee80211_hw_set(hw, TX_FRAG_LIST);
}
ieee80211_hw_set(hw, MFP_CAPABLE); ieee80211_hw_set(hw, MFP_CAPABLE);
ieee80211_hw_set(hw, AP_LINK_PS); ieee80211_hw_set(hw, AP_LINK_PS);
ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS); ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
...@@ -568,6 +572,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size, ...@@ -568,6 +572,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
spin_lock_init(&dev->lock); spin_lock_init(&dev->lock);
spin_lock_init(&dev->cc_lock); spin_lock_init(&dev->cc_lock);
spin_lock_init(&dev->status_lock); spin_lock_init(&dev->status_lock);
spin_lock_init(&dev->wed_lock);
mutex_init(&dev->mutex); mutex_init(&dev->mutex);
init_waitqueue_head(&dev->tx_wait); init_waitqueue_head(&dev->tx_wait);
...@@ -590,9 +595,13 @@ mt76_alloc_device(struct device *pdev, unsigned int size, ...@@ -590,9 +595,13 @@ mt76_alloc_device(struct device *pdev, unsigned int size,
spin_lock_init(&dev->token_lock); spin_lock_init(&dev->token_lock);
idr_init(&dev->token); idr_init(&dev->token);
spin_lock_init(&dev->rx_token_lock);
idr_init(&dev->rx_token);
INIT_LIST_HEAD(&dev->wcid_list); INIT_LIST_HEAD(&dev->wcid_list);
INIT_LIST_HEAD(&dev->txwi_cache); INIT_LIST_HEAD(&dev->txwi_cache);
INIT_LIST_HEAD(&dev->rxwi_cache);
dev->token_size = dev->drv->token_size; dev->token_size = dev->drv->token_size;
for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++)
...@@ -947,14 +956,12 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid, ...@@ -947,14 +956,12 @@ void mt76_wcid_key_setup(struct mt76_dev *dev, struct mt76_wcid *wcid,
} }
EXPORT_SYMBOL(mt76_wcid_key_setup); EXPORT_SYMBOL(mt76_wcid_key_setup);
static int int mt76_rx_signal(u8 chain_mask, s8 *chain_signal)
mt76_rx_signal(struct mt76_rx_status *status)
{ {
s8 *chain_signal = status->chain_signal;
int signal = -128; int signal = -128;
u8 chains; u8 chains;
for (chains = status->chains; chains; chains >>= 1, chain_signal++) { for (chains = chain_mask; chains; chains >>= 1, chain_signal++) {
int cur, diff; int cur, diff;
cur = *chain_signal; cur = *chain_signal;
...@@ -976,6 +983,7 @@ mt76_rx_signal(struct mt76_rx_status *status) ...@@ -976,6 +983,7 @@ mt76_rx_signal(struct mt76_rx_status *status)
return signal; return signal;
} }
EXPORT_SYMBOL(mt76_rx_signal);
static void static void
mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
...@@ -1005,7 +1013,7 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, ...@@ -1005,7 +1013,7 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb,
status->ampdu_reference = mstat.ampdu_ref; status->ampdu_reference = mstat.ampdu_ref;
status->device_timestamp = mstat.timestamp; status->device_timestamp = mstat.timestamp;
status->mactime = mstat.timestamp; status->mactime = mstat.timestamp;
status->signal = mt76_rx_signal(&mstat); status->signal = mt76_rx_signal(mstat.chains, mstat.chain_signal);
if (status->signal <= -128) if (status->signal <= -128)
status->flag |= RX_FLAG_NO_SIGNAL_VAL; status->flag |= RX_FLAG_NO_SIGNAL_VAL;
...@@ -1289,7 +1297,10 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, ...@@ -1289,7 +1297,10 @@ void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) { while ((skb = __skb_dequeue(&dev->rx_skb[q])) != NULL) {
mt76_check_sta(dev, skb); mt76_check_sta(dev, skb);
mt76_rx_aggr_reorder(skb, &frames); if (mtk_wed_device_active(&dev->mmio.wed))
__skb_queue_tail(&frames, skb);
else
mt76_rx_aggr_reorder(skb, &frames);
} }
mt76_rx_complete(dev, &frames, napi); mt76_rx_complete(dev, &frames, napi);
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \ FIELD_PREP(MT_QFLAG_WED_TYPE, _type) | \
FIELD_PREP(MT_QFLAG_WED_RING, _n)) FIELD_PREP(MT_QFLAG_WED_RING, _n))
#define MT_WED_Q_TX(_n) __MT_WED_Q(MT76_WED_Q_TX, _n) #define MT_WED_Q_TX(_n) __MT_WED_Q(MT76_WED_Q_TX, _n)
#define MT_WED_Q_RX(_n) __MT_WED_Q(MT76_WED_Q_RX, _n)
#define MT_WED_Q_TXFREE __MT_WED_Q(MT76_WED_Q_TXFREE, 0) #define MT_WED_Q_TXFREE __MT_WED_Q(MT76_WED_Q_TXFREE, 0)
struct mt76_dev; struct mt76_dev;
...@@ -56,6 +57,7 @@ enum mt76_bus_type { ...@@ -56,6 +57,7 @@ enum mt76_bus_type {
enum mt76_wed_type { enum mt76_wed_type {
MT76_WED_Q_TX, MT76_WED_Q_TX,
MT76_WED_Q_TXFREE, MT76_WED_Q_TXFREE,
MT76_WED_Q_RX,
}; };
struct mt76_bus_ops { struct mt76_bus_ops {
...@@ -271,9 +273,15 @@ struct mt76_sta_stats { ...@@ -271,9 +273,15 @@ struct mt76_sta_stats {
u64 tx_nss[4]; /* 1, 2, 3, 4 */ u64 tx_nss[4]; /* 1, 2, 3, 4 */
u64 tx_mcs[16]; /* mcs idx */ u64 tx_mcs[16]; /* mcs idx */
u64 tx_bytes; u64 tx_bytes;
/* WED TX */
u32 tx_packets; u32 tx_packets;
u32 tx_retries; u32 tx_retries;
u32 tx_failed; u32 tx_failed;
/* WED RX */
u64 rx_bytes;
u32 rx_packets;
u32 rx_errors;
u32 rx_drops;
}; };
enum mt76_wcid_flags { enum mt76_wcid_flags {
...@@ -339,7 +347,10 @@ struct mt76_txwi_cache { ...@@ -339,7 +347,10 @@ struct mt76_txwi_cache {
struct list_head list; struct list_head list;
dma_addr_t dma_addr; dma_addr_t dma_addr;
struct sk_buff *skb; union {
struct sk_buff *skb;
void *ptr;
};
}; };
struct mt76_rx_tid { struct mt76_rx_tid {
...@@ -415,6 +426,7 @@ struct mt76_hw_cap { ...@@ -415,6 +426,7 @@ struct mt76_hw_cap {
#define MT_DRV_SW_RX_AIRTIME BIT(2) #define MT_DRV_SW_RX_AIRTIME BIT(2)
#define MT_DRV_RX_DMA_HDR BIT(3) #define MT_DRV_RX_DMA_HDR BIT(3)
#define MT_DRV_HW_MGMT_TXQ BIT(4) #define MT_DRV_HW_MGMT_TXQ BIT(4)
#define MT_DRV_AMSDU_OFFLOAD BIT(5)
struct mt76_driver_ops { struct mt76_driver_ops {
u32 drv_flags; u32 drv_flags;
...@@ -438,7 +450,7 @@ struct mt76_driver_ops { ...@@ -438,7 +450,7 @@ struct mt76_driver_ops {
bool (*rx_check)(struct mt76_dev *dev, void *data, int len); bool (*rx_check)(struct mt76_dev *dev, void *data, int len);
void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q, void (*rx_skb)(struct mt76_dev *dev, enum mt76_rxq_id q,
struct sk_buff *skb); struct sk_buff *skb, u32 *info);
void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q); void (*rx_poll_complete)(struct mt76_dev *dev, enum mt76_rxq_id q);
...@@ -470,19 +482,6 @@ struct mt76_sband { ...@@ -470,19 +482,6 @@ struct mt76_sband {
struct mt76_channel_state *chan; struct mt76_channel_state *chan;
}; };
struct mt76_rate_power {
union {
struct {
s8 cck[4];
s8 ofdm[8];
s8 stbc[10];
s8 ht[16];
s8 vht[10];
};
s8 all[48];
};
};
/* addr req mask */ /* addr req mask */
#define MT_VEND_TYPE_EEPROM BIT(31) #define MT_VEND_TYPE_EEPROM BIT(31)
#define MT_VEND_TYPE_CFG BIT(30) #define MT_VEND_TYPE_CFG BIT(30)
...@@ -705,6 +704,8 @@ struct mt76_phy { ...@@ -705,6 +704,8 @@ struct mt76_phy {
enum mt76_dfs_state dfs_state; enum mt76_dfs_state dfs_state;
ktime_t survey_time; ktime_t survey_time;
u32 aggr_stats[32];
struct mt76_hw_cap cap; struct mt76_hw_cap cap;
struct mt76_sband sband_2g; struct mt76_sband sband_2g;
struct mt76_sband sband_5g; struct mt76_sband sband_5g;
...@@ -738,6 +739,7 @@ struct mt76_dev { ...@@ -738,6 +739,7 @@ struct mt76_dev {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
spinlock_t wed_lock;
spinlock_t lock; spinlock_t lock;
spinlock_t cc_lock; spinlock_t cc_lock;
...@@ -764,6 +766,7 @@ struct mt76_dev { ...@@ -764,6 +766,7 @@ struct mt76_dev {
struct sk_buff_head rx_skb[__MT_RXQ_MAX]; struct sk_buff_head rx_skb[__MT_RXQ_MAX];
struct list_head txwi_cache; struct list_head txwi_cache;
struct list_head rxwi_cache;
struct mt76_queue *q_mcu[__MT_MCUQ_MAX]; struct mt76_queue *q_mcu[__MT_MCUQ_MAX];
struct mt76_queue q_rx[__MT_RXQ_MAX]; struct mt76_queue q_rx[__MT_RXQ_MAX];
const struct mt76_queue_ops *queue_ops; const struct mt76_queue_ops *queue_ops;
...@@ -778,6 +781,10 @@ struct mt76_dev { ...@@ -778,6 +781,10 @@ struct mt76_dev {
u16 token_count; u16 token_count;
u16 token_size; u16 token_size;
spinlock_t rx_token_lock;
struct idr rx_token;
u16 rx_token_size;
wait_queue_head_t tx_wait; wait_queue_head_t tx_wait;
/* spinclock used to protect wcid pktid linked list */ /* spinclock used to protect wcid pktid linked list */
spinlock_t status_lock; spinlock_t status_lock;
...@@ -793,8 +800,6 @@ struct mt76_dev { ...@@ -793,8 +800,6 @@ struct mt76_dev {
u32 rev; u32 rev;
u32 aggr_stats[32];
struct tasklet_struct pre_tbtt_tasklet; struct tasklet_struct pre_tbtt_tasklet;
int beacon_int; int beacon_int;
u8 beacon_mask; u8 beacon_mask;
...@@ -802,8 +807,6 @@ struct mt76_dev { ...@@ -802,8 +807,6 @@ struct mt76_dev {
struct debugfs_blob_wrapper eeprom; struct debugfs_blob_wrapper eeprom;
struct debugfs_blob_wrapper otp; struct debugfs_blob_wrapper otp;
struct mt76_rate_power rate_power;
char alpha2[3]; char alpha2[3];
enum nl80211_dfs_regions region; enum nl80211_dfs_regions region;
...@@ -1107,8 +1110,9 @@ static inline bool mt76_is_skb_pktid(u8 pktid) ...@@ -1107,8 +1110,9 @@ static inline bool mt76_is_skb_pktid(u8 pktid)
static inline u8 mt76_tx_power_nss_delta(u8 nss) static inline u8 mt76_tx_power_nss_delta(u8 nss)
{ {
static const u8 nss_delta[4] = { 0, 6, 9, 12 }; static const u8 nss_delta[4] = { 0, 6, 9, 12 };
u8 idx = nss - 1;
return nss_delta[nss - 1]; return (idx < ARRAY_SIZE(nss_delta)) ? nss_delta[idx] : 0;
} }
static inline bool mt76_testmode_enabled(struct mt76_phy *phy) static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
...@@ -1163,6 +1167,7 @@ void mt76_update_survey(struct mt76_phy *phy); ...@@ -1163,6 +1167,7 @@ void mt76_update_survey(struct mt76_phy *phy);
void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time); void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time);
int mt76_get_survey(struct ieee80211_hw *hw, int idx, int mt76_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey); struct survey_info *survey);
int mt76_rx_signal(u8 chain_mask, s8 *chain_signal);
void mt76_set_stream_caps(struct mt76_phy *phy, bool vht); void mt76_set_stream_caps(struct mt76_phy *phy, bool vht);
int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid, int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tid,
...@@ -1260,6 +1265,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) ...@@ -1260,6 +1265,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb)
} }
void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
void mt76_put_rxwi(struct mt76_dev *dev, struct mt76_txwi_cache *t);
struct mt76_txwi_cache *mt76_get_rxwi(struct mt76_dev *dev);
void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
struct napi_struct *napi); struct napi_struct *napi);
void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q, void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
...@@ -1404,6 +1411,9 @@ struct mt76_txwi_cache * ...@@ -1404,6 +1411,9 @@ struct mt76_txwi_cache *
mt76_token_release(struct mt76_dev *dev, int token, bool *wake); mt76_token_release(struct mt76_dev *dev, int token, bool *wake);
int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi); int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi);
void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked);
struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token);
int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr,
struct mt76_txwi_cache *r, dma_addr_t phys);
static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked)
{ {
......
...@@ -85,7 +85,7 @@ mt7603_ampdu_stat_show(struct seq_file *file, void *data) ...@@ -85,7 +85,7 @@ mt7603_ampdu_stat_show(struct seq_file *file, void *data)
bound[i], bound[i + 1]); bound[i], bound[i + 1]);
seq_puts(file, "\nCount: "); seq_puts(file, "\nCount: ");
for (i = 0; i < ARRAY_SIZE(bound); i++) for (i = 0; i < ARRAY_SIZE(bound); i++)
seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i]); seq_printf(file, "%8d | ", dev->mphy.aggr_stats[i]);
seq_puts(file, "\n"); seq_puts(file, "\n");
return 0; return 0;
......
...@@ -69,7 +69,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb) ...@@ -69,7 +69,7 @@ mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
} }
void mt7603_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void mt7603_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb) struct sk_buff *skb, u32 *info)
{ {
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76); struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
__le32 *rxd = (__le32 *)skb->data; __le32 *rxd = (__le32 *)skb->data;
......
...@@ -39,7 +39,7 @@ void mt7603_mac_reset_counters(struct mt7603_dev *dev) ...@@ -39,7 +39,7 @@ void mt7603_mac_reset_counters(struct mt7603_dev *dev)
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
mt76_rr(dev, MT_TX_AGG_CNT(i)); mt76_rr(dev, MT_TX_AGG_CNT(i));
memset(dev->mt76.aggr_stats, 0, sizeof(dev->mt76.aggr_stats)); memset(dev->mphy.aggr_stats, 0, sizeof(dev->mphy.aggr_stats));
} }
void mt7603_mac_set_timing(struct mt7603_dev *dev) void mt7603_mac_set_timing(struct mt7603_dev *dev)
...@@ -1827,8 +1827,8 @@ void mt7603_mac_work(struct work_struct *work) ...@@ -1827,8 +1827,8 @@ void mt7603_mac_work(struct work_struct *work)
for (i = 0, idx = 0; i < 2; i++) { for (i = 0, idx = 0; i < 2; i++) {
u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i)); u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
dev->mt76.aggr_stats[idx++] += val & 0xffff; dev->mphy.aggr_stats[idx++] += val & 0xffff;
dev->mt76.aggr_stats[idx++] += val >> 16; dev->mphy.aggr_stats[idx++] += val >> 16;
} }
if (dev->mphy.mac_work_count == 10) if (dev->mphy.mac_work_count == 10)
......
...@@ -244,7 +244,7 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, ...@@ -244,7 +244,7 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e); void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
void mt7603_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void mt7603_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb); struct sk_buff *skb, u32 *info);
void mt7603_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); void mt7603_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q);
void mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps); void mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps);
int mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, int mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
......
...@@ -278,7 +278,6 @@ mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy, ...@@ -278,7 +278,6 @@ mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
{ {
struct mt7615_dev *dev = file->private; struct mt7615_dev *dev = file->private;
u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0; u32 reg = is_mt7663(&dev->mt76) ? MT_MIB_ARNG(0) : MT_AGG_ASRCR0;
bool ext_phy = phy != &dev->phy;
int bound[7], i, range; int bound[7], i, range;
if (!phy) if (!phy)
...@@ -292,7 +291,7 @@ mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy, ...@@ -292,7 +291,7 @@ mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1; bound[i + 4] = MT_AGG_ASRCR_RANGE(range, i) + 1;
seq_printf(file, "\nPhy %d\n", ext_phy); seq_printf(file, "\nPhy %d\n", phy != &dev->phy);
seq_printf(file, "Length: %8d | ", bound[0]); seq_printf(file, "Length: %8d | ", bound[0]);
for (i = 0; i < ARRAY_SIZE(bound) - 1; i++) for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
...@@ -300,9 +299,8 @@ mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy, ...@@ -300,9 +299,8 @@ mt7615_ampdu_stat_read_phy(struct mt7615_phy *phy,
bound[i], bound[i + 1]); bound[i], bound[i + 1]);
seq_puts(file, "\nCount: "); seq_puts(file, "\nCount: ");
range = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
for (i = 0; i < ARRAY_SIZE(bound); i++) for (i = 0; i < ARRAY_SIZE(bound); i++)
seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i + range]); seq_printf(file, "%8d | ", phy->mt76->aggr_stats[i]);
seq_puts(file, "\n"); seq_puts(file, "\n");
seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt); seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
......
...@@ -107,9 +107,9 @@ static struct mt76_wcid *mt7615_rx_get_wcid(struct mt7615_dev *dev, ...@@ -107,9 +107,9 @@ static struct mt76_wcid *mt7615_rx_get_wcid(struct mt7615_dev *dev,
return &sta->vif->sta.wcid; return &sta->vif->sta.wcid;
} }
void mt7615_mac_reset_counters(struct mt7615_dev *dev) void mt7615_mac_reset_counters(struct mt7615_phy *phy)
{ {
struct mt76_phy *mphy_ext = dev->mt76.phys[MT_BAND1]; struct mt7615_dev *dev = phy->dev;
int i; int i;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
...@@ -117,10 +117,8 @@ void mt7615_mac_reset_counters(struct mt7615_dev *dev) ...@@ -117,10 +117,8 @@ void mt7615_mac_reset_counters(struct mt7615_dev *dev)
mt76_rr(dev, MT_TX_AGG_CNT(1, i)); mt76_rr(dev, MT_TX_AGG_CNT(1, i));
} }
memset(dev->mt76.aggr_stats, 0, sizeof(dev->mt76.aggr_stats)); memset(phy->mt76->aggr_stats, 0, sizeof(phy->mt76->aggr_stats));
dev->mt76.phy.survey_time = ktime_get_boottime(); phy->mt76->survey_time = ktime_get_boottime();
if (mphy_ext)
mphy_ext->survey_time = ktime_get_boottime();
/* reset airtime counters */ /* reset airtime counters */
mt76_rr(dev, MT_MIB_SDR9(0)); mt76_rr(dev, MT_MIB_SDR9(0));
...@@ -1177,6 +1175,21 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta, ...@@ -1177,6 +1175,21 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
} }
EXPORT_SYMBOL_GPL(mt7615_mac_set_rates); EXPORT_SYMBOL_GPL(mt7615_mac_set_rates);
void mt7615_mac_enable_rtscts(struct mt7615_dev *dev,
struct ieee80211_vif *vif, bool enable)
{
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
u32 addr;
addr = mt7615_mac_wtbl_addr(dev, mvif->sta.wcid.idx) + 3 * 4;
if (enable)
mt76_set(dev, addr, MT_WTBL_W3_RTS);
else
mt76_clear(dev, addr, MT_WTBL_W3_RTS);
}
EXPORT_SYMBOL_GPL(mt7615_mac_enable_rtscts);
static int static int
mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid, mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
struct ieee80211_key_conf *key, struct ieee80211_key_conf *key,
...@@ -1653,7 +1666,7 @@ bool mt7615_rx_check(struct mt76_dev *mdev, void *data, int len) ...@@ -1653,7 +1666,7 @@ bool mt7615_rx_check(struct mt76_dev *mdev, void *data, int len)
EXPORT_SYMBOL_GPL(mt7615_rx_check); EXPORT_SYMBOL_GPL(mt7615_rx_check);
void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb) struct sk_buff *skb, u32 *info)
{ {
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
__le32 *rxd = (__le32 *)skb->data; __le32 *rxd = (__le32 *)skb->data;
...@@ -1999,7 +2012,7 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy) ...@@ -1999,7 +2012,7 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy)
struct mt7615_dev *dev = phy->dev; struct mt7615_dev *dev = phy->dev;
struct mib_stats *mib = &phy->mib; struct mib_stats *mib = &phy->mib;
bool ext_phy = phy != &dev->phy; bool ext_phy = phy != &dev->phy;
int i, aggr; int i, aggr = 0;
u32 val, val2; u32 val, val2;
mib->fcs_err_cnt += mt76_get_field(dev, MT_MIB_SDR3(ext_phy), mib->fcs_err_cnt += mt76_get_field(dev, MT_MIB_SDR3(ext_phy),
...@@ -2013,7 +2026,6 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy) ...@@ -2013,7 +2026,6 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy)
mib->aggr_per = 1000 * (val - val2) / val; mib->aggr_per = 1000 * (val - val2) / val;
} }
aggr = ext_phy ? ARRAY_SIZE(dev->mt76.aggr_stats) / 2 : 0;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
val = mt76_rr(dev, MT_MIB_MB_SDR1(ext_phy, i)); val = mt76_rr(dev, MT_MIB_MB_SDR1(ext_phy, i));
mib->ba_miss_cnt += FIELD_GET(MT_MIB_BA_MISS_COUNT_MASK, val); mib->ba_miss_cnt += FIELD_GET(MT_MIB_BA_MISS_COUNT_MASK, val);
...@@ -2026,8 +2038,8 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy) ...@@ -2026,8 +2038,8 @@ mt7615_mac_update_mib_stats(struct mt7615_phy *phy)
val); val);
val = mt76_rr(dev, MT_TX_AGG_CNT(ext_phy, i)); val = mt76_rr(dev, MT_TX_AGG_CNT(ext_phy, i));
dev->mt76.aggr_stats[aggr++] += val & 0xffff; phy->mt76->aggr_stats[aggr++] += val & 0xffff;
dev->mt76.aggr_stats[aggr++] += val >> 16; phy->mt76->aggr_stats[aggr++] += val >> 16;
} }
} }
......
...@@ -83,7 +83,7 @@ static int mt7615_start(struct ieee80211_hw *hw) ...@@ -83,7 +83,7 @@ static int mt7615_start(struct ieee80211_hw *hw)
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, timeout); ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work, timeout);
if (!running) if (!running)
mt7615_mac_reset_counters(dev); mt7615_mac_reset_counters(phy);
out: out:
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
...@@ -320,7 +320,7 @@ int mt7615_set_channel(struct mt7615_phy *phy) ...@@ -320,7 +320,7 @@ int mt7615_set_channel(struct mt7615_phy *phy)
if (ret) if (ret)
goto out; goto out;
mt7615_mac_reset_counters(dev); mt7615_mac_reset_counters(phy);
phy->noise = 0; phy->noise = 0;
phy->chfreq = mt76_rr(dev, MT_CHFREQ(ext_phy)); phy->chfreq = mt76_rr(dev, MT_CHFREQ(ext_phy));
...@@ -572,6 +572,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw, ...@@ -572,6 +572,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
} }
} }
if (changed & BSS_CHANGED_ERP_CTS_PROT)
mt7615_mac_enable_rtscts(dev, vif, info->use_cts_prot);
if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) { if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
mt7615_mcu_add_bss_info(phy, vif, NULL, true); mt7615_mcu_add_bss_info(phy, vif, NULL, true);
mt7615_mcu_sta_add(phy, vif, NULL, true); mt7615_mcu_sta_add(phy, vif, NULL, true);
......
...@@ -1119,7 +1119,7 @@ mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif, ...@@ -1119,7 +1119,7 @@ mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif,
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv; struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
return mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, return mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,
enable); enable, NULL);
} }
static inline int static inline int
......
...@@ -469,10 +469,12 @@ void mt7615_init_work(struct mt7615_dev *dev); ...@@ -469,10 +469,12 @@ void mt7615_init_work(struct mt7615_dev *dev);
int mt7615_mcu_restart(struct mt76_dev *dev); int mt7615_mcu_restart(struct mt76_dev *dev);
void mt7615_update_channel(struct mt76_phy *mphy); void mt7615_update_channel(struct mt76_phy *mphy);
bool mt7615_mac_wtbl_update(struct mt7615_dev *dev, int idx, u32 mask); bool mt7615_mac_wtbl_update(struct mt7615_dev *dev, int idx, u32 mask);
void mt7615_mac_reset_counters(struct mt7615_dev *dev); void mt7615_mac_reset_counters(struct mt7615_phy *phy);
void mt7615_mac_cca_stats_reset(struct mt7615_phy *phy); void mt7615_mac_cca_stats_reset(struct mt7615_phy *phy);
void mt7615_mac_set_scs(struct mt7615_phy *phy, bool enable); void mt7615_mac_set_scs(struct mt7615_phy *phy, bool enable);
void mt7615_mac_enable_nf(struct mt7615_dev *dev, bool ext_phy); void mt7615_mac_enable_nf(struct mt7615_dev *dev, bool ext_phy);
void mt7615_mac_enable_rtscts(struct mt7615_dev *dev,
struct ieee80211_vif *vif, bool enable);
void mt7615_mac_sta_poll(struct mt7615_dev *dev); void mt7615_mac_sta_poll(struct mt7615_dev *dev);
int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid, struct sk_buff *skb, struct mt76_wcid *wcid,
...@@ -511,7 +513,7 @@ void mt7615_tx_worker(struct mt76_worker *w); ...@@ -511,7 +513,7 @@ void mt7615_tx_worker(struct mt76_worker *w);
void mt7615_tx_token_put(struct mt7615_dev *dev); void mt7615_tx_token_put(struct mt7615_dev *dev);
bool mt7615_rx_check(struct mt76_dev *mdev, void *data, int len); bool mt7615_rx_check(struct mt76_dev *mdev, void *data, int len);
void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb); struct sk_buff *skb, u32 *info);
void mt7615_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps); void mt7615_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps);
int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta); struct ieee80211_sta *sta);
......
...@@ -446,6 +446,8 @@ enum mt7615_reg_base { ...@@ -446,6 +446,8 @@ enum mt7615_reg_base {
#define MT_WTBL_RIUCR3_RATE6 GENMASK(19, 8) #define MT_WTBL_RIUCR3_RATE6 GENMASK(19, 8)
#define MT_WTBL_RIUCR3_RATE7 GENMASK(31, 20) #define MT_WTBL_RIUCR3_RATE7 GENMASK(31, 20)
#define MT_WTBL_W3_RTS BIT(22)
#define MT_WTBL_W5_CHANGE_BW_RATE GENMASK(7, 5) #define MT_WTBL_W5_CHANGE_BW_RATE GENMASK(7, 5)
#define MT_WTBL_W5_SHORT_GI_20 BIT(8) #define MT_WTBL_W5_SHORT_GI_20 BIT(8)
#define MT_WTBL_W5_SHORT_GI_40 BIT(9) #define MT_WTBL_W5_SHORT_GI_40 BIT(9)
......
...@@ -187,6 +187,11 @@ static inline bool is_mt7986(struct mt76_dev *dev) ...@@ -187,6 +187,11 @@ static inline bool is_mt7986(struct mt76_dev *dev)
return mt76_chip(dev) == 0x7986; return mt76_chip(dev) == 0x7986;
} }
static inline bool is_mt7996(struct mt76_dev *dev)
{
return mt76_chip(dev) == 0x7990;
}
static inline bool is_mt7622(struct mt76_dev *dev) static inline bool is_mt7622(struct mt76_dev *dev)
{ {
if (!IS_ENABLED(CONFIG_MT7622_WMAC)) if (!IS_ENABLED(CONFIG_MT7622_WMAC))
...@@ -261,6 +266,17 @@ mt76_connac_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t) ...@@ -261,6 +266,17 @@ mt76_connac_txwi_to_txp(struct mt76_dev *dev, struct mt76_txwi_cache *t)
return (void *)(txwi + MT_TXD_SIZE); return (void *)(txwi + MT_TXD_SIZE);
} }
static inline u8 mt76_connac_spe_idx(u8 antenna_mask)
{
static const u8 ant_to_spe[] = {0, 0, 1, 0, 3, 2, 4, 0,
9, 8, 6, 10, 16, 12, 18, 0};
if (antenna_mask >= sizeof(ant_to_spe))
return 0;
return ant_to_spe[antenna_mask];
}
int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm); int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm);
void mt76_connac_power_save_sched(struct mt76_phy *phy, void mt76_connac_power_save_sched(struct mt76_phy *phy,
struct mt76_connac_pm *pm); struct mt76_connac_pm *pm);
......
...@@ -417,9 +417,6 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, ...@@ -417,9 +417,6 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
if (ieee80211_is_beacon(fc)) { if (ieee80211_is_beacon(fc)) {
txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT); txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT);
txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT); txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
if (!is_mt7921(dev))
txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
0x18));
} }
if (info->flags & IEEE80211_TX_CTL_INJECTED) { if (info->flags & IEEE80211_TX_CTL_INJECTED) {
...@@ -550,6 +547,14 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, ...@@ -550,6 +547,14 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
val |= FIELD_PREP(MT_TXD6_TX_RATE, rate); val |= FIELD_PREP(MT_TXD6_TX_RATE, rate);
txwi[6] |= cpu_to_le32(val); txwi[6] |= cpu_to_le32(val);
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
if (!is_mt7921(dev)) {
u8 spe_idx = mt76_connac_spe_idx(mphy->antenna_mask);
if (!spe_idx)
spe_idx = 24 + phy_idx;
txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX, spe_idx));
}
} }
} }
EXPORT_SYMBOL_GPL(mt76_connac2_mac_write_txwi); EXPORT_SYMBOL_GPL(mt76_connac2_mac_write_txwi);
...@@ -562,7 +567,7 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, ...@@ -562,7 +567,7 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
struct mt76_phy *mphy; struct mt76_phy *mphy;
struct rate_info rate = {}; struct rate_info rate = {};
bool cck = false; bool cck = false;
u32 txrate, txs, mode; u32 txrate, txs, mode, stbc;
txs = le32_to_cpu(txs_data[0]); txs = le32_to_cpu(txs_data[0]);
...@@ -582,6 +587,10 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, ...@@ -582,6 +587,10 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid,
rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate); rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate);
rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1; rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1;
stbc = FIELD_GET(MT_TX_RATE_STBC, txrate);
if (stbc && rate.nss > 1)
rate.nss >>= 1;
if (rate.nss - 1 < ARRAY_SIZE(stats->tx_nss)) if (rate.nss - 1 < ARRAY_SIZE(stats->tx_nss))
stats->tx_nss[rate.nss - 1]++; stats->tx_nss[rate.nss - 1]++;
......
...@@ -65,7 +65,8 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len, ...@@ -65,7 +65,8 @@ int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
int cmd; int cmd;
if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) || if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
(is_mt7921(dev) && addr == 0x900000)) (is_mt7921(dev) && addr == 0x900000) ||
(is_mt7996(dev) && addr == 0x900000))
cmd = MCU_CMD(PATCH_START_REQ); cmd = MCU_CMD(PATCH_START_REQ);
else else
cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ); cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ);
...@@ -744,6 +745,39 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) ...@@ -744,6 +745,39 @@ mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
he->pkt_ext = 2; he->pkt_ext = 2;
} }
static void
mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
{
struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
struct sta_rec_he_v2 *he;
struct tlv *tlv;
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_V2, sizeof(*he));
he = (struct sta_rec_he_v2 *)tlv;
memcpy(he->he_phy_cap, elem->phy_cap_info, sizeof(he->he_phy_cap));
memcpy(he->he_mac_cap, elem->mac_cap_info, sizeof(he->he_mac_cap));
switch (sta->deflink.bandwidth) {
case IEEE80211_STA_RX_BW_160:
if (elem->phy_cap_info[0] &
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
he->max_nss_mcs[CMD_HE_MCS_BW8080] =
he_cap->he_mcs_nss_supp.rx_mcs_80p80;
he->max_nss_mcs[CMD_HE_MCS_BW160] =
he_cap->he_mcs_nss_supp.rx_mcs_160;
fallthrough;
default:
he->max_nss_mcs[CMD_HE_MCS_BW80] =
he_cap->he_mcs_nss_supp.rx_mcs_80;
break;
}
he->pkt_ext = IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US;
}
static u8 static u8
mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif, mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
enum nl80211_band band, struct ieee80211_sta *sta) enum nl80211_band band, struct ieee80211_sta *sta)
...@@ -838,6 +872,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, ...@@ -838,6 +872,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
/* starec he */ /* starec he */
if (sta->deflink.he_cap.has_he) { if (sta->deflink.he_cap.has_he) {
mt76_connac_mcu_sta_he_tlv(skb, sta); mt76_connac_mcu_sta_he_tlv(skb, sta);
mt76_connac_mcu_sta_he_tlv_v2(skb, sta);
if (band == NL80211_BAND_6GHZ && if (band == NL80211_BAND_6GHZ &&
sta_state == MT76_STA_INFO_STATE_ASSOC) { sta_state == MT76_STA_INFO_STATE_ASSOC) {
struct sta_rec_he_6g_capa *he_6g_capa; struct sta_rec_he_6g_capa *he_6g_capa;
...@@ -1184,6 +1219,16 @@ void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb, ...@@ -1184,6 +1219,16 @@ void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
} }
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv); EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb)
{
if (!mtk_wed_device_active(&dev->mmio.wed))
return 0;
return mtk_wed_device_update_msg(&dev->mmio.wed, WED_WO_STA_REC,
skb->data, skb->len);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_wed_update);
int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
struct ieee80211_ampdu_params *params, struct ieee80211_ampdu_params *params,
int cmd, bool enable, bool tx) int cmd, bool enable, bool tx)
...@@ -1209,6 +1254,10 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, ...@@ -1209,6 +1254,10 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl, mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
wtbl_hdr); wtbl_hdr);
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
if (ret)
return ret;
ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true); ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true);
if (ret) if (ret)
return ret; return ret;
...@@ -1219,6 +1268,10 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, ...@@ -1219,6 +1268,10 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx); mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
if (ret)
return ret;
return mt76_mcu_skb_send_msg(dev, skb, cmd, true); return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
} }
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba); EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
...@@ -1313,44 +1366,13 @@ mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif, ...@@ -1313,44 +1366,13 @@ mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80; he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
} }
int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, int mt76_connac_mcu_uni_set_chctx(struct mt76_phy *phy, struct mt76_vif *mvif,
struct ieee80211_vif *vif, struct ieee80211_chanctx_conf *ctx)
struct mt76_wcid *wcid,
bool enable)
{ {
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &phy->chandef;
struct cfg80211_chan_def *chandef = &phy->chandef;
int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2; int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
enum nl80211_band band = chandef->chan->band; enum nl80211_band band = chandef->chan->band;
struct mt76_dev *mdev = phy->dev; struct mt76_dev *mdev = phy->dev;
struct {
struct {
u8 bss_idx;
u8 pad[3];
} __packed hdr;
struct mt76_connac_bss_basic_tlv basic;
struct mt76_connac_bss_qos_tlv qos;
} basic_req = {
.hdr = {
.bss_idx = mvif->idx,
},
.basic = {
.tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
.len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
.dtim_period = vif->bss_conf.dtim_period,
.omac_idx = mvif->omac_idx,
.band_idx = mvif->band_idx,
.wmm_idx = mvif->wmm_idx,
.active = true, /* keep bss deactivated */
.phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
},
.qos = {
.tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
.len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
.qos = vif->bss_conf.qos,
},
};
struct { struct {
struct { struct {
u8 bss_idx; u8 bss_idx;
...@@ -1388,6 +1410,82 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, ...@@ -1388,6 +1410,82 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
.band = band, .band = band,
}, },
}; };
switch (chandef->width) {
case NL80211_CHAN_WIDTH_40:
rlm_req.rlm.bw = CMD_CBW_40MHZ;
break;
case NL80211_CHAN_WIDTH_80:
rlm_req.rlm.bw = CMD_CBW_80MHZ;
break;
case NL80211_CHAN_WIDTH_80P80:
rlm_req.rlm.bw = CMD_CBW_8080MHZ;
break;
case NL80211_CHAN_WIDTH_160:
rlm_req.rlm.bw = CMD_CBW_160MHZ;
break;
case NL80211_CHAN_WIDTH_5:
rlm_req.rlm.bw = CMD_CBW_5MHZ;
break;
case NL80211_CHAN_WIDTH_10:
rlm_req.rlm.bw = CMD_CBW_10MHZ;
break;
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_20:
default:
rlm_req.rlm.bw = CMD_CBW_20MHZ;
rlm_req.rlm.ht_op_info = 0;
break;
}
if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
rlm_req.rlm.sco = 1; /* SCA */
else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
rlm_req.rlm.sco = 3; /* SCB */
return mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &rlm_req,
sizeof(rlm_req), true);
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_set_chctx);
int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
struct ieee80211_vif *vif,
struct mt76_wcid *wcid,
bool enable,
struct ieee80211_chanctx_conf *ctx)
{
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &phy->chandef;
enum nl80211_band band = chandef->chan->band;
struct mt76_dev *mdev = phy->dev;
struct {
struct {
u8 bss_idx;
u8 pad[3];
} __packed hdr;
struct mt76_connac_bss_basic_tlv basic;
struct mt76_connac_bss_qos_tlv qos;
} basic_req = {
.hdr = {
.bss_idx = mvif->idx,
},
.basic = {
.tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
.len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
.dtim_period = vif->bss_conf.dtim_period,
.omac_idx = mvif->omac_idx,
.band_idx = mvif->band_idx,
.wmm_idx = mvif->wmm_idx,
.active = true, /* keep bss deactivated */
.phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
},
.qos = {
.tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
.len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
.qos = vif->bss_conf.qos,
},
};
int err, conn_type; int err, conn_type;
u8 idx, basic_phy; u8 idx, basic_phy;
...@@ -1474,40 +1572,7 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, ...@@ -1474,40 +1572,7 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
return err; return err;
} }
switch (chandef->width) { return mt76_connac_mcu_uni_set_chctx(phy, mvif, ctx);
case NL80211_CHAN_WIDTH_40:
rlm_req.rlm.bw = CMD_CBW_40MHZ;
break;
case NL80211_CHAN_WIDTH_80:
rlm_req.rlm.bw = CMD_CBW_80MHZ;
break;
case NL80211_CHAN_WIDTH_80P80:
rlm_req.rlm.bw = CMD_CBW_8080MHZ;
break;
case NL80211_CHAN_WIDTH_160:
rlm_req.rlm.bw = CMD_CBW_160MHZ;
break;
case NL80211_CHAN_WIDTH_5:
rlm_req.rlm.bw = CMD_CBW_5MHZ;
break;
case NL80211_CHAN_WIDTH_10:
rlm_req.rlm.bw = CMD_CBW_10MHZ;
break;
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_20:
default:
rlm_req.rlm.bw = CMD_CBW_20MHZ;
rlm_req.rlm.ht_op_info = 0;
break;
}
if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
rlm_req.rlm.sco = 1; /* SCA */
else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
rlm_req.rlm.sco = 3; /* SCB */
return mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &rlm_req,
sizeof(rlm_req), true);
} }
EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss); EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
...@@ -1525,6 +1590,9 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif, ...@@ -1525,6 +1590,9 @@ int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
struct mt76_connac_hw_scan_req *req; struct mt76_connac_hw_scan_req *req;
struct sk_buff *skb; struct sk_buff *skb;
if (test_bit(MT76_HW_SCANNING, &phy->state))
return -EBUSY;
skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req)); skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -2646,6 +2714,10 @@ int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, ...@@ -2646,6 +2714,10 @@ int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
if (ret) if (ret)
return ret; return ret;
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
if (ret)
return ret;
return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true); return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
} }
EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key); EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key);
...@@ -2834,6 +2906,9 @@ mt76_connac_mcu_send_ram_firmware(struct mt76_dev *dev, ...@@ -2834,6 +2906,9 @@ mt76_connac_mcu_send_ram_firmware(struct mt76_dev *dev,
len = le32_to_cpu(region->len); len = le32_to_cpu(region->len);
addr = le32_to_cpu(region->addr); addr = le32_to_cpu(region->addr);
if (region->feature_set & FW_FEATURE_NON_DL)
goto next;
if (region->feature_set & FW_FEATURE_OVERRIDE_ADDR) if (region->feature_set & FW_FEATURE_OVERRIDE_ADDR)
override = addr; override = addr;
...@@ -2850,6 +2925,7 @@ mt76_connac_mcu_send_ram_firmware(struct mt76_dev *dev, ...@@ -2850,6 +2925,7 @@ mt76_connac_mcu_send_ram_firmware(struct mt76_dev *dev,
return err; return err;
} }
next:
offset += len; offset += len;
} }
......
...@@ -63,7 +63,7 @@ struct mt76_connac2_mcu_txd { ...@@ -63,7 +63,7 @@ struct mt76_connac2_mcu_txd {
} __packed __aligned(4); } __packed __aligned(4);
/** /**
* struct mt76_connac2_mcu_uni_txd - mcu command descriptor for firmware v3 * struct mt76_connac2_mcu_uni_txd - mcu command descriptor for connac2 and connac3
* @txd: hardware descriptor * @txd: hardware descriptor
* @len: total length not including txd * @len: total length not including txd
* @cid: command identifier * @cid: command identifier
...@@ -121,11 +121,13 @@ struct mt76_connac2_mcu_rxd { ...@@ -121,11 +121,13 @@ struct mt76_connac2_mcu_rxd {
u8 eid; u8 eid;
u8 seq; u8 seq;
u8 rsv[2]; u8 option;
u8 rsv;
u8 ext_eid; u8 ext_eid;
u8 rsv1[2]; u8 rsv1[2];
u8 s2d_index; u8 s2d_index;
u8 tlv[0];
}; };
struct mt76_connac2_patch_hdr { struct mt76_connac2_patch_hdr {
...@@ -354,6 +356,16 @@ struct sta_rec_he { ...@@ -354,6 +356,16 @@ struct sta_rec_he {
u8 rsv2[2]; u8 rsv2[2];
} __packed; } __packed;
struct sta_rec_he_v2 {
__le16 tag;
__le16 len;
u8 he_mac_cap[6];
u8 he_phy_cap[11];
u8 pkt_ext;
/* 0: BW80, 1: BW160, 2: BW8080 */
__le16 max_nss_mcs[CMD_HE_MCS_BW_NUM];
} __packed;
struct sta_rec_amsdu { struct sta_rec_amsdu {
__le16 tag; __le16 tag;
__le16 len; __le16 len;
...@@ -391,7 +403,8 @@ struct sta_rec_phy { ...@@ -391,7 +403,8 @@ struct sta_rec_phy {
u8 ampdu; u8 ampdu;
u8 rts_policy; u8 rts_policy;
u8 rcpi; u8 rcpi;
u8 rsv[2]; u8 max_ampdu_len; /* connac3 */
u8 rsv[1];
} __packed; } __packed;
struct sta_rec_he_6g_capa { struct sta_rec_he_6g_capa {
...@@ -452,8 +465,8 @@ struct sta_rec_bf { ...@@ -452,8 +465,8 @@ struct sta_rec_bf {
u8 ibf_dbw; u8 ibf_dbw;
u8 ibf_ncol; u8 ibf_ncol;
u8 ibf_nrow; u8 ibf_nrow;
u8 nrow_bw160; u8 nrow_gt_bw80;
u8 ncol_bw160; u8 ncol_gt_bw80;
u8 ru_start_idx; u8 ru_start_idx;
u8 ru_end_idx; u8 ru_end_idx;
...@@ -580,7 +593,7 @@ struct sta_rec_ra_fixed { ...@@ -580,7 +593,7 @@ struct sta_rec_ra_fixed {
struct sta_phy phy; struct sta_phy phy;
u8 spe_en; u8 spe_idx;
u8 short_preamble; u8 short_preamble;
u8 is_5g; u8 is_5g;
u8 mmps_mode; u8 mmps_mode;
...@@ -779,6 +792,9 @@ enum { ...@@ -779,6 +792,9 @@ enum {
STA_REC_BFEE, STA_REC_BFEE,
STA_REC_PHY = 0x15, STA_REC_PHY = 0x15,
STA_REC_HE_6G = 0x17, STA_REC_HE_6G = 0x17,
STA_REC_HE_V2 = 0x19,
STA_REC_HDRT = 0x28,
STA_REC_HDR_TRANS = 0x2B,
STA_REC_MAX_NUM STA_REC_MAX_NUM
}; };
...@@ -946,6 +962,9 @@ enum { ...@@ -946,6 +962,9 @@ enum {
DEV_INFO_MAX_NUM DEV_INFO_MAX_NUM
}; };
#define MCU_UNI_CMD_EVENT BIT(1)
#define MCU_UNI_CMD_UNSOLICITED_EVENT BIT(2)
/* event table */ /* event table */
enum { enum {
MCU_EVENT_TARGET_ADDRESS_LEN = 0x01, MCU_EVENT_TARGET_ADDRESS_LEN = 0x01,
...@@ -981,6 +1000,17 @@ enum { ...@@ -981,6 +1000,17 @@ enum {
MCU_EXT_EVENT_MURU_CTRL = 0x9f, MCU_EXT_EVENT_MURU_CTRL = 0x9f,
}; };
/* unified event table */
enum {
MCU_UNI_EVENT_RESULT = 0x01,
MCU_UNI_EVENT_FW_LOG_2_HOST = 0x04,
MCU_UNI_EVENT_IE_COUNTDOWN = 0x09,
MCU_UNI_EVENT_RDD_REPORT = 0x11,
};
#define MCU_UNI_CMD_EVENT BIT(1)
#define MCU_UNI_CMD_UNSOLICITED_EVENT BIT(2)
enum { enum {
MCU_Q_QUERY, MCU_Q_QUERY,
MCU_Q_SET, MCU_Q_SET,
...@@ -1063,10 +1093,11 @@ enum { ...@@ -1063,10 +1093,11 @@ enum {
#define MCU_CMD_ACK BIT(0) #define MCU_CMD_ACK BIT(0)
#define MCU_CMD_UNI BIT(1) #define MCU_CMD_UNI BIT(1)
#define MCU_CMD_QUERY BIT(2) #define MCU_CMD_SET BIT(2)
#define MCU_CMD_UNI_EXT_ACK (MCU_CMD_ACK | MCU_CMD_UNI | \ #define MCU_CMD_UNI_EXT_ACK (MCU_CMD_ACK | MCU_CMD_UNI | \
MCU_CMD_QUERY) MCU_CMD_SET)
#define MCU_CMD_UNI_QUERY_ACK (MCU_CMD_ACK | MCU_CMD_UNI)
#define __MCU_CMD_FIELD_ID GENMASK(7, 0) #define __MCU_CMD_FIELD_ID GENMASK(7, 0)
#define __MCU_CMD_FIELD_EXT_ID GENMASK(15, 8) #define __MCU_CMD_FIELD_EXT_ID GENMASK(15, 8)
...@@ -1074,6 +1105,7 @@ enum { ...@@ -1074,6 +1105,7 @@ enum {
#define __MCU_CMD_FIELD_UNI BIT(17) #define __MCU_CMD_FIELD_UNI BIT(17)
#define __MCU_CMD_FIELD_CE BIT(18) #define __MCU_CMD_FIELD_CE BIT(18)
#define __MCU_CMD_FIELD_WA BIT(19) #define __MCU_CMD_FIELD_WA BIT(19)
#define __MCU_CMD_FIELD_WM BIT(20)
#define MCU_CMD(_t) FIELD_PREP(__MCU_CMD_FIELD_ID, \ #define MCU_CMD(_t) FIELD_PREP(__MCU_CMD_FIELD_ID, \
MCU_CMD_##_t) MCU_CMD_##_t)
...@@ -1095,6 +1127,16 @@ enum { ...@@ -1095,6 +1127,16 @@ enum {
FIELD_PREP(__MCU_CMD_FIELD_EXT_ID, \ FIELD_PREP(__MCU_CMD_FIELD_EXT_ID, \
MCU_WA_PARAM_CMD_##_t)) MCU_WA_PARAM_CMD_##_t))
#define MCU_WM_UNI_CMD(_t) (MCU_UNI_CMD(_t) | \
__MCU_CMD_FIELD_WM)
#define MCU_WM_UNI_CMD_QUERY(_t) (MCU_UNI_CMD(_t) | \
__MCU_CMD_FIELD_QUERY | \
__MCU_CMD_FIELD_WM)
#define MCU_WA_UNI_CMD(_t) (MCU_UNI_CMD(_t) | \
__MCU_CMD_FIELD_WA)
#define MCU_WMWA_UNI_CMD(_t) (MCU_WM_UNI_CMD(_t) | \
__MCU_CMD_FIELD_WA)
enum { enum {
MCU_EXT_CMD_EFUSE_ACCESS = 0x01, MCU_EXT_CMD_EFUSE_ACCESS = 0x01,
MCU_EXT_CMD_RF_REG_ACCESS = 0x02, MCU_EXT_CMD_RF_REG_ACCESS = 0x02,
...@@ -1148,10 +1190,33 @@ enum { ...@@ -1148,10 +1190,33 @@ enum {
MCU_UNI_CMD_DEV_INFO_UPDATE = 0x01, MCU_UNI_CMD_DEV_INFO_UPDATE = 0x01,
MCU_UNI_CMD_BSS_INFO_UPDATE = 0x02, MCU_UNI_CMD_BSS_INFO_UPDATE = 0x02,
MCU_UNI_CMD_STA_REC_UPDATE = 0x03, MCU_UNI_CMD_STA_REC_UPDATE = 0x03,
MCU_UNI_CMD_EDCA_UPDATE = 0x04,
MCU_UNI_CMD_SUSPEND = 0x05, MCU_UNI_CMD_SUSPEND = 0x05,
MCU_UNI_CMD_OFFLOAD = 0x06, MCU_UNI_CMD_OFFLOAD = 0x06,
MCU_UNI_CMD_HIF_CTRL = 0x07, MCU_UNI_CMD_HIF_CTRL = 0x07,
MCU_UNI_CMD_BAND_CONFIG = 0x08,
MCU_UNI_CMD_REPT_MUAR = 0x09,
MCU_UNI_CMD_WSYS_CONFIG = 0x0b,
MCU_UNI_CMD_REG_ACCESS = 0x0d,
MCU_UNI_CMD_POWER_CREL = 0x0f,
MCU_UNI_CMD_RX_HDR_TRANS = 0x12,
MCU_UNI_CMD_SER = 0x13,
MCU_UNI_CMD_TWT = 0x14,
MCU_UNI_CMD_RDD_CTRL = 0x19,
MCU_UNI_CMD_GET_MIB_INFO = 0x22,
MCU_UNI_CMD_SNIFFER = 0x24, MCU_UNI_CMD_SNIFFER = 0x24,
MCU_UNI_CMD_SR = 0x25,
MCU_UNI_CMD_ROC = 0x27,
MCU_UNI_CMD_TXPOWER = 0x2b,
MCU_UNI_CMD_EFUSE_CTRL = 0x2d,
MCU_UNI_CMD_RA = 0x2f,
MCU_UNI_CMD_MURU = 0x31,
MCU_UNI_CMD_BF = 0x33,
MCU_UNI_CMD_CHANNEL_SWITCH = 0x34,
MCU_UNI_CMD_THERMAL = 0x35,
MCU_UNI_CMD_VOW = 0x37,
MCU_UNI_CMD_RRO = 0x57,
MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58,
}; };
enum { enum {
...@@ -1201,14 +1266,23 @@ enum { ...@@ -1201,14 +1266,23 @@ enum {
enum { enum {
UNI_BSS_INFO_BASIC = 0, UNI_BSS_INFO_BASIC = 0,
UNI_BSS_INFO_RA = 1,
UNI_BSS_INFO_RLM = 2, UNI_BSS_INFO_RLM = 2,
UNI_BSS_INFO_BSS_COLOR = 4, UNI_BSS_INFO_BSS_COLOR = 4,
UNI_BSS_INFO_HE_BASIC = 5, UNI_BSS_INFO_HE_BASIC = 5,
UNI_BSS_INFO_BCN_CONTENT = 7, UNI_BSS_INFO_BCN_CONTENT = 7,
UNI_BSS_INFO_BCN_CSA = 8,
UNI_BSS_INFO_BCN_BCC = 9,
UNI_BSS_INFO_BCN_MBSSID = 10,
UNI_BSS_INFO_RATE = 11,
UNI_BSS_INFO_QBSS = 15, UNI_BSS_INFO_QBSS = 15,
UNI_BSS_INFO_SEC = 16,
UNI_BSS_INFO_TXCMD = 18,
UNI_BSS_INFO_UAPSD = 19, UNI_BSS_INFO_UAPSD = 19,
UNI_BSS_INFO_PS = 21, UNI_BSS_INFO_PS = 21,
UNI_BSS_INFO_BCNFT = 22, UNI_BSS_INFO_BCNFT = 22,
UNI_BSS_INFO_OFFLOAD = 25,
UNI_BSS_INFO_MLD = 26,
}; };
enum { enum {
...@@ -1736,10 +1810,14 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy, ...@@ -1736,10 +1810,14 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
struct ieee80211_ampdu_params *params, struct ieee80211_ampdu_params *params,
int cmd, bool enable, bool tx); int cmd, bool enable, bool tx);
int mt76_connac_mcu_uni_set_chctx(struct mt76_phy *phy,
struct mt76_vif *vif,
struct ieee80211_chanctx_conf *ctx);
int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct mt76_wcid *wcid, struct mt76_wcid *wcid,
bool enable); bool enable,
struct ieee80211_chanctx_conf *ctx);
int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy, int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
struct mt76_sta_cmd_info *info); struct mt76_sta_cmd_info *info);
void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac, void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
...@@ -1813,6 +1891,7 @@ int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter); ...@@ -1813,6 +1891,7 @@ int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter);
int mt76_connac_mcu_restart(struct mt76_dev *dev); int mt76_connac_mcu_restart(struct mt76_dev *dev);
int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index, int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index,
u8 rx_sel, u8 val); u8 rx_sel, u8 val);
int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb);
int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm, int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
const char *fw_wa); const char *fw_wa);
int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name); int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name);
......
...@@ -151,7 +151,7 @@ static s8 mt76x0_get_delta(struct mt76x02_dev *dev) ...@@ -151,7 +151,7 @@ static s8 mt76x0_get_delta(struct mt76x02_dev *dev)
void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev, void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
struct mt76_rate_power *t) struct mt76x02_rate_power *t)
{ {
bool is_2ghz = chan->band == NL80211_BAND_2GHZ; bool is_2ghz = chan->band == NL80211_BAND_2GHZ;
u16 val, addr; u16 val, addr;
...@@ -179,31 +179,19 @@ void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev, ...@@ -179,31 +179,19 @@ void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev,
/* ht-vht mcs 1ss 0, 1, 2, 3 */ /* ht-vht mcs 1ss 0, 1, 2, 3 */
addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 6 : 0x124; addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 6 : 0x124;
val = mt76x02_eeprom_get(dev, addr); val = mt76x02_eeprom_get(dev, addr);
t->ht[0] = t->ht[1] = t->vht[0] = t->vht[1] = s6_to_s8(val); t->ht[0] = t->ht[1] = s6_to_s8(val);
t->ht[2] = t->ht[3] = t->vht[2] = t->vht[3] = s6_to_s8(val >> 8); t->ht[2] = t->ht[3] = s6_to_s8(val >> 8);
/* ht-vht mcs 1ss 4, 5, 6 */ /* ht-vht mcs 1ss 4, 5, 6 */
addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 8 : 0x126; addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 8 : 0x126;
val = mt76x02_eeprom_get(dev, addr); val = mt76x02_eeprom_get(dev, addr);
t->ht[4] = t->ht[5] = t->vht[4] = t->vht[5] = s6_to_s8(val); t->ht[4] = t->ht[5] = s6_to_s8(val);
t->ht[6] = t->ht[7] = t->vht[6] = t->vht[7] = s6_to_s8(val >> 8); t->ht[6] = t->ht[7] = s6_to_s8(val >> 8);
/* ht-vht mcs 1ss 0, 1, 2, 3 stbc */
addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 14 : 0xec;
val = mt76x02_eeprom_get(dev, addr);
t->stbc[0] = t->stbc[1] = s6_to_s8(val);
t->stbc[2] = t->stbc[3] = s6_to_s8(val >> 8);
/* ht-vht mcs 1ss 4, 5, 6 stbc */
addr = is_2ghz ? MT_EE_TX_POWER_BYRATE_BASE + 16 : 0xee;
val = mt76x02_eeprom_get(dev, addr);
t->stbc[4] = t->stbc[5] = s6_to_s8(val);
t->stbc[6] = t->stbc[7] = s6_to_s8(val >> 8);
/* vht mcs 8, 9 5GHz */ /* vht mcs 8, 9 5GHz */
val = mt76x02_eeprom_get(dev, 0x12c); val = mt76x02_eeprom_get(dev, 0x12c);
t->vht[8] = s6_to_s8(val); t->vht[0] = s6_to_s8(val);
t->vht[9] = s6_to_s8(val >> 8); t->vht[1] = s6_to_s8(val >> 8);
delta = mt76x0_tssi_enabled(dev) ? 0 : mt76x0_get_delta(dev); delta = mt76x0_tssi_enabled(dev) ? 0 : mt76x0_get_delta(dev);
mt76x02_add_rate_power_offset(t, delta); mt76x02_add_rate_power_offset(t, delta);
...@@ -235,7 +223,7 @@ void mt76x0_get_power_info(struct mt76x02_dev *dev, ...@@ -235,7 +223,7 @@ void mt76x0_get_power_info(struct mt76x02_dev *dev,
data = mt76x02_eeprom_get(dev, MT_EE_5G_TARGET_POWER); data = mt76x02_eeprom_get(dev, MT_EE_5G_TARGET_POWER);
else else
data = mt76x02_eeprom_get(dev, MT_EE_2G_TARGET_POWER); data = mt76x02_eeprom_get(dev, MT_EE_2G_TARGET_POWER);
target_power = (data & 0xff) - dev->mt76.rate_power.ofdm[7]; target_power = (data & 0xff) - dev->rate_power.ofdm[7];
*tp = target_power + mt76x0_get_delta(dev); *tp = target_power + mt76x0_get_delta(dev);
return; return;
......
...@@ -19,7 +19,7 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev); ...@@ -19,7 +19,7 @@ int mt76x0_eeprom_init(struct mt76x02_dev *dev);
void mt76x0_read_rx_gain(struct mt76x02_dev *dev); void mt76x0_read_rx_gain(struct mt76x02_dev *dev);
void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev, void mt76x0_get_tx_power_per_rate(struct mt76x02_dev *dev,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
struct mt76_rate_power *t); struct mt76x02_rate_power *t);
void mt76x0_get_power_info(struct mt76x02_dev *dev, void mt76x0_get_power_info(struct mt76x02_dev *dev,
struct ieee80211_channel *chan, s8 *tp); struct ieee80211_channel *chan, s8 *tp);
......
...@@ -217,7 +217,7 @@ mt76x0_init_txpower(struct mt76x02_dev *dev, ...@@ -217,7 +217,7 @@ mt76x0_init_txpower(struct mt76x02_dev *dev,
struct ieee80211_supported_band *sband) struct ieee80211_supported_band *sband)
{ {
struct ieee80211_channel *chan; struct ieee80211_channel *chan;
struct mt76_rate_power t; struct mt76x02_rate_power t;
s8 tp; s8 tp;
int i; int i;
......
...@@ -595,10 +595,7 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode, ...@@ -595,10 +595,7 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
case 0: case 0:
/* cck rates */ /* cck rates */
tx_rate = (info[0] & 0x60) >> 5; tx_rate = (info[0] & 0x60) >> 5;
if (tx_rate > 3) *target_power = cur_power + dev->rate_power.cck[tx_rate];
return -EINVAL;
*target_power = cur_power + dev->mt76.rate_power.cck[tx_rate];
*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, tx_rate); *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, tx_rate);
break; break;
case 1: { case 1: {
...@@ -635,7 +632,7 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode, ...@@ -635,7 +632,7 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
return -EINVAL; return -EINVAL;
} }
*target_power = cur_power + dev->mt76.rate_power.ofdm[index]; *target_power = cur_power + dev->rate_power.ofdm[index];
*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, index + 4); *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, index + 4);
break; break;
} }
...@@ -645,7 +642,7 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode, ...@@ -645,7 +642,7 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
if (tx_rate > 9) if (tx_rate > 9)
return -EINVAL; return -EINVAL;
*target_power = cur_power + dev->mt76.rate_power.vht[tx_rate]; *target_power = cur_power + dev->rate_power.vht[tx_rate];
*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate); *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate);
break; break;
default: default:
...@@ -654,7 +651,7 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode, ...@@ -654,7 +651,7 @@ mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
if (tx_rate > 9) if (tx_rate > 9)
return -EINVAL; return -EINVAL;
*target_power = cur_power + dev->mt76.rate_power.ht[tx_rate]; *target_power = cur_power + dev->rate_power.ht[tx_rate];
*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate); *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate);
break; break;
} }
...@@ -841,7 +838,7 @@ static void mt76x0_phy_tssi_calibrate(struct mt76x02_dev *dev) ...@@ -841,7 +838,7 @@ static void mt76x0_phy_tssi_calibrate(struct mt76x02_dev *dev)
void mt76x0_phy_set_txpower(struct mt76x02_dev *dev) void mt76x0_phy_set_txpower(struct mt76x02_dev *dev)
{ {
struct mt76_rate_power *t = &dev->mt76.rate_power; struct mt76x02_rate_power *t = &dev->rate_power;
s8 info; s8 info;
mt76x0_get_tx_power_per_rate(dev, dev->mphy.chandef.chan, t); mt76x0_get_tx_power_per_rate(dev, dev->mphy.chandef.chan, t);
......
...@@ -72,6 +72,18 @@ struct mt76x02_beacon_ops { ...@@ -72,6 +72,18 @@ struct mt76x02_beacon_ops {
#define mt76x02_pre_tbtt_enable(dev, enable) \ #define mt76x02_pre_tbtt_enable(dev, enable) \
(dev)->beacon_ops->pre_tbtt_enable(dev, enable) (dev)->beacon_ops->pre_tbtt_enable(dev, enable)
struct mt76x02_rate_power {
union {
struct {
s8 cck[4];
s8 ofdm[8];
s8 ht[16];
s8 vht[2];
};
s8 all[30];
};
};
struct mt76x02_dev { struct mt76x02_dev {
union { /* must be first */ union { /* must be first */
struct mt76_dev mt76; struct mt76_dev mt76;
...@@ -107,6 +119,8 @@ struct mt76x02_dev { ...@@ -107,6 +119,8 @@ struct mt76x02_dev {
u8 beacon_hang_check; u8 beacon_hang_check;
u8 mcu_timeout; u8 mcu_timeout;
struct mt76x02_rate_power rate_power;
struct mt76x02_calibration cal; struct mt76x02_calibration cal;
int txpower_conf; int txpower_conf;
...@@ -174,7 +188,7 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val); ...@@ -174,7 +188,7 @@ int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val);
void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len); void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len);
bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update); bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update);
void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb); struct sk_buff *skb, u32 *info);
void mt76x02_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q); void mt76x02_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q);
irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance); irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance);
void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
......
...@@ -20,7 +20,7 @@ mt76x02_ampdu_stat_show(struct seq_file *file, void *data) ...@@ -20,7 +20,7 @@ mt76x02_ampdu_stat_show(struct seq_file *file, void *data)
seq_puts(file, "Count: "); seq_puts(file, "Count: ");
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
seq_printf(file, "%8d | ", seq_printf(file, "%8d | ",
dev->mt76.aggr_stats[i * 8 + j]); dev->mphy.aggr_stats[i * 8 + j]);
seq_puts(file, "\n"); seq_puts(file, "\n");
seq_puts(file, "--------"); seq_puts(file, "--------");
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
...@@ -114,6 +114,21 @@ mt76_edcca_get(void *data, u64 *val) ...@@ -114,6 +114,21 @@ mt76_edcca_get(void *data, u64 *val)
DEFINE_DEBUGFS_ATTRIBUTE(fops_edcca, mt76_edcca_get, mt76_edcca_set, DEFINE_DEBUGFS_ATTRIBUTE(fops_edcca, mt76_edcca_get, mt76_edcca_set,
"%lld\n"); "%lld\n");
static int mt76x02_read_rate_txpower(struct seq_file *s, void *data)
{
struct mt76x02_dev *dev = dev_get_drvdata(s->private);
mt76_seq_puts_array(s, "CCK", dev->rate_power.cck,
ARRAY_SIZE(dev->rate_power.cck));
mt76_seq_puts_array(s, "OFDM", dev->rate_power.ofdm,
ARRAY_SIZE(dev->rate_power.ofdm));
mt76_seq_puts_array(s, "HT", dev->rate_power.ht,
ARRAY_SIZE(dev->rate_power.ht));
mt76_seq_puts_array(s, "VHT", dev->rate_power.vht,
ARRAY_SIZE(dev->rate_power.vht));
return 0;
}
void mt76x02_init_debugfs(struct mt76x02_dev *dev) void mt76x02_init_debugfs(struct mt76x02_dev *dev)
{ {
struct dentry *dir; struct dentry *dir;
...@@ -133,6 +148,8 @@ void mt76x02_init_debugfs(struct mt76x02_dev *dev) ...@@ -133,6 +148,8 @@ void mt76x02_init_debugfs(struct mt76x02_dev *dev)
debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir, debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir,
read_txpower); read_txpower);
debugfs_create_devm_seqfile(dev->mt76.dev, "rate_txpower", dir,
mt76x02_read_rate_txpower);
debugfs_create_devm_seqfile(dev->mt76.dev, "agc", dir, read_agc); debugfs_create_devm_seqfile(dev->mt76.dev, "agc", dir, read_agc);
debugfs_create_u32("tx_hang_reset", 0400, dir, &dev->tx_hang_reset); debugfs_create_u32("tx_hang_reset", 0400, dir, &dev->tx_hang_reset);
......
...@@ -62,8 +62,6 @@ enum mt76x02_eeprom_field { ...@@ -62,8 +62,6 @@ enum mt76x02_eeprom_field {
MT_EE_TX_POWER_HT_MCS4 = 0x0a8, MT_EE_TX_POWER_HT_MCS4 = 0x0a8,
MT_EE_TX_POWER_HT_MCS8 = 0x0aa, MT_EE_TX_POWER_HT_MCS8 = 0x0aa,
MT_EE_TX_POWER_HT_MCS12 = 0x0ac, MT_EE_TX_POWER_HT_MCS12 = 0x0ac,
MT_EE_TX_POWER_VHT_MCS0 = 0x0ba,
MT_EE_TX_POWER_VHT_MCS4 = 0x0bc,
MT_EE_TX_POWER_VHT_MCS8 = 0x0be, MT_EE_TX_POWER_VHT_MCS8 = 0x0be,
MT_EE_2G_TARGET_POWER = 0x0d0, MT_EE_2G_TARGET_POWER = 0x0d0,
......
...@@ -25,7 +25,7 @@ void mt76x02_mac_reset_counters(struct mt76x02_dev *dev) ...@@ -25,7 +25,7 @@ void mt76x02_mac_reset_counters(struct mt76x02_dev *dev)
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
mt76_rr(dev, MT_TX_STAT_FIFO); mt76_rr(dev, MT_TX_STAT_FIFO);
memset(dev->mt76.aggr_stats, 0, sizeof(dev->mt76.aggr_stats)); memset(dev->mphy.aggr_stats, 0, sizeof(dev->mphy.aggr_stats));
} }
EXPORT_SYMBOL_GPL(mt76x02_mac_reset_counters); EXPORT_SYMBOL_GPL(mt76x02_mac_reset_counters);
...@@ -1191,8 +1191,8 @@ void mt76x02_mac_work(struct work_struct *work) ...@@ -1191,8 +1191,8 @@ void mt76x02_mac_work(struct work_struct *work)
for (i = 0, idx = 0; i < 16; i++) { for (i = 0, idx = 0; i < 16; i++) {
u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i)); u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
dev->mt76.aggr_stats[idx++] += val & 0xffff; dev->mphy.aggr_stats[idx++] += val & 0xffff;
dev->mt76.aggr_stats[idx++] += val >> 16; dev->mphy.aggr_stats[idx++] += val >> 16;
} }
mt76x02_check_mac_err(dev); mt76x02_check_mac_err(dev);
......
...@@ -59,7 +59,7 @@ mt76x02_tx_power_mask(u8 v1, u8 v2, u8 v3, u8 v4) ...@@ -59,7 +59,7 @@ mt76x02_tx_power_mask(u8 v1, u8 v2, u8 v3, u8 v4)
return val; return val;
} }
int mt76x02_get_max_rate_power(struct mt76_rate_power *r) int mt76x02_get_max_rate_power(struct mt76x02_rate_power *r)
{ {
s8 ret = 0; s8 ret = 0;
int i; int i;
...@@ -71,7 +71,7 @@ int mt76x02_get_max_rate_power(struct mt76_rate_power *r) ...@@ -71,7 +71,7 @@ int mt76x02_get_max_rate_power(struct mt76_rate_power *r)
} }
EXPORT_SYMBOL_GPL(mt76x02_get_max_rate_power); EXPORT_SYMBOL_GPL(mt76x02_get_max_rate_power);
void mt76x02_limit_rate_power(struct mt76_rate_power *r, int limit) void mt76x02_limit_rate_power(struct mt76x02_rate_power *r, int limit)
{ {
int i; int i;
...@@ -81,7 +81,7 @@ void mt76x02_limit_rate_power(struct mt76_rate_power *r, int limit) ...@@ -81,7 +81,7 @@ void mt76x02_limit_rate_power(struct mt76_rate_power *r, int limit)
} }
EXPORT_SYMBOL_GPL(mt76x02_limit_rate_power); EXPORT_SYMBOL_GPL(mt76x02_limit_rate_power);
void mt76x02_add_rate_power_offset(struct mt76_rate_power *r, int offset) void mt76x02_add_rate_power_offset(struct mt76x02_rate_power *r, int offset)
{ {
int i; int i;
...@@ -92,7 +92,7 @@ EXPORT_SYMBOL_GPL(mt76x02_add_rate_power_offset); ...@@ -92,7 +92,7 @@ EXPORT_SYMBOL_GPL(mt76x02_add_rate_power_offset);
void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_1) void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_1)
{ {
struct mt76_rate_power *t = &dev->mt76.rate_power; struct mt76x02_rate_power *t = &dev->rate_power;
mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_0, txp_0); mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_0, txp_0);
mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_1, txp_1); mt76_rmw_field(dev, MT_TX_ALC_CFG_0, MT_TX_ALC_CFG_0_CH_INIT_1, txp_1);
...@@ -107,17 +107,17 @@ void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_1) ...@@ -107,17 +107,17 @@ void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_1)
mt76x02_tx_power_mask(t->ht[4], t->ht[6], t->ht[8], mt76x02_tx_power_mask(t->ht[4], t->ht[6], t->ht[8],
t->ht[10])); t->ht[10]));
mt76_wr(dev, MT_TX_PWR_CFG_3, mt76_wr(dev, MT_TX_PWR_CFG_3,
mt76x02_tx_power_mask(t->ht[12], t->ht[14], t->stbc[0], mt76x02_tx_power_mask(t->ht[12], t->ht[14], t->ht[0],
t->stbc[2])); t->ht[2]));
mt76_wr(dev, MT_TX_PWR_CFG_4, mt76_wr(dev, MT_TX_PWR_CFG_4,
mt76x02_tx_power_mask(t->stbc[4], t->stbc[6], 0, 0)); mt76x02_tx_power_mask(t->ht[4], t->ht[6], 0, 0));
mt76_wr(dev, MT_TX_PWR_CFG_7, mt76_wr(dev, MT_TX_PWR_CFG_7,
mt76x02_tx_power_mask(t->ofdm[7], t->vht[8], t->ht[7], mt76x02_tx_power_mask(t->ofdm[7], t->vht[0], t->ht[7],
t->vht[9])); t->vht[1]));
mt76_wr(dev, MT_TX_PWR_CFG_8, mt76_wr(dev, MT_TX_PWR_CFG_8,
mt76x02_tx_power_mask(t->ht[14], 0, t->vht[8], t->vht[9])); mt76x02_tx_power_mask(t->ht[14], 0, t->vht[0], t->vht[1]));
mt76_wr(dev, MT_TX_PWR_CFG_9, mt76_wr(dev, MT_TX_PWR_CFG_9,
mt76x02_tx_power_mask(t->ht[7], 0, t->stbc[8], t->stbc[9])); mt76x02_tx_power_mask(t->ht[7], 0, t->vht[0], t->vht[1]));
} }
EXPORT_SYMBOL_GPL(mt76x02_phy_set_txpower); EXPORT_SYMBOL_GPL(mt76x02_phy_set_txpower);
......
...@@ -34,10 +34,10 @@ mt76x02_get_low_rssi_gain_thresh(struct mt76x02_dev *dev) ...@@ -34,10 +34,10 @@ mt76x02_get_low_rssi_gain_thresh(struct mt76x02_dev *dev)
} }
} }
void mt76x02_add_rate_power_offset(struct mt76_rate_power *r, int offset); void mt76x02_add_rate_power_offset(struct mt76x02_rate_power *r, int offset);
void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_2); void mt76x02_phy_set_txpower(struct mt76x02_dev *dev, int txp_0, int txp_2);
void mt76x02_limit_rate_power(struct mt76_rate_power *r, int limit); void mt76x02_limit_rate_power(struct mt76x02_rate_power *r, int limit);
int mt76x02_get_max_rate_power(struct mt76_rate_power *r); int mt76x02_get_max_rate_power(struct mt76x02_rate_power *r);
void mt76x02_phy_set_rxpath(struct mt76x02_dev *dev); void mt76x02_phy_set_rxpath(struct mt76x02_dev *dev);
void mt76x02_phy_set_txdac(struct mt76x02_dev *dev); void mt76x02_phy_set_txdac(struct mt76x02_dev *dev);
void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl); void mt76x02_phy_set_bw(struct mt76x02_dev *dev, int width, u8 ctrl);
......
...@@ -33,7 +33,7 @@ void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control, ...@@ -33,7 +33,7 @@ void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
EXPORT_SYMBOL_GPL(mt76x02_tx); EXPORT_SYMBOL_GPL(mt76x02_tx);
void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb) struct sk_buff *skb, u32 *info)
{ {
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76); struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
void *rxwi = skb->data; void *rxwi = skb->data;
...@@ -62,23 +62,23 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev, ...@@ -62,23 +62,23 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev,
u8 mcs = ieee80211_rate_get_vht_mcs(rate); u8 mcs = ieee80211_rate_get_vht_mcs(rate);
if (mcs == 8 || mcs == 9) { if (mcs == 8 || mcs == 9) {
max_txpwr = dev->mt76.rate_power.vht[8]; max_txpwr = dev->rate_power.vht[0];
} else { } else {
u8 nss, idx; u8 nss, idx;
nss = ieee80211_rate_get_vht_nss(rate); nss = ieee80211_rate_get_vht_nss(rate);
idx = ((nss - 1) << 3) + mcs; idx = ((nss - 1) << 3) + mcs;
max_txpwr = dev->mt76.rate_power.ht[idx & 0xf]; max_txpwr = dev->rate_power.ht[idx & 0xf];
} }
} else if (rate->flags & IEEE80211_TX_RC_MCS) { } else if (rate->flags & IEEE80211_TX_RC_MCS) {
max_txpwr = dev->mt76.rate_power.ht[rate->idx & 0xf]; max_txpwr = dev->rate_power.ht[rate->idx & 0xf];
} else { } else {
enum nl80211_band band = dev->mphy.chandef.chan->band; enum nl80211_band band = dev->mphy.chandef.chan->band;
if (band == NL80211_BAND_2GHZ) { if (band == NL80211_BAND_2GHZ) {
const struct ieee80211_rate *r; const struct ieee80211_rate *r;
struct wiphy *wiphy = dev->mt76.hw->wiphy; struct wiphy *wiphy = dev->mt76.hw->wiphy;
struct mt76_rate_power *rp = &dev->mt76.rate_power; struct mt76x02_rate_power *rp = &dev->rate_power;
r = &wiphy->bands[band]->bitrates[rate->idx]; r = &wiphy->bands[band]->bitrates[rate->idx];
if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE) if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE)
...@@ -86,7 +86,7 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev, ...@@ -86,7 +86,7 @@ s8 mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev *dev,
else else
max_txpwr = rp->ofdm[r->hw_value & 0x7]; max_txpwr = rp->ofdm[r->hw_value & 0x7];
} else { } else {
max_txpwr = dev->mt76.rate_power.ofdm[rate->idx & 0x7]; max_txpwr = dev->rate_power.ofdm[rate->idx & 0x7];
} }
} }
...@@ -112,7 +112,7 @@ void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr) ...@@ -112,7 +112,7 @@ void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev *dev, s8 txpwr)
s8 txpwr_adj; s8 txpwr_adj;
txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, txpwr, txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, txpwr,
dev->mt76.rate_power.ofdm[4]); dev->rate_power.ofdm[4]);
mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG, mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj); MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj);
mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG, mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
......
...@@ -280,7 +280,7 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev) ...@@ -280,7 +280,7 @@ void mt76x2_read_rx_gain(struct mt76x02_dev *dev)
} }
EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain);
void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76_rate_power *t, void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76x02_rate_power *t,
struct ieee80211_channel *chan) struct ieee80211_channel *chan)
{ {
bool is_5ghz; bool is_5ghz;
...@@ -324,22 +324,10 @@ void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76_rate_power *t, ...@@ -324,22 +324,10 @@ void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76_rate_power *t,
t->ht[12] = t->ht[13] = mt76x02_rate_power_val(val); t->ht[12] = t->ht[13] = mt76x02_rate_power_val(val);
t->ht[14] = t->ht[15] = mt76x02_rate_power_val(val >> 8); t->ht[14] = t->ht[15] = mt76x02_rate_power_val(val >> 8);
val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS0);
t->vht[0] = t->vht[1] = mt76x02_rate_power_val(val);
t->vht[2] = t->vht[3] = mt76x02_rate_power_val(val >> 8);
val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS4);
t->vht[4] = t->vht[5] = mt76x02_rate_power_val(val);
t->vht[6] = t->vht[7] = mt76x02_rate_power_val(val >> 8);
val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS8); val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS8);
if (!is_5ghz) if (!is_5ghz)
val >>= 8; val >>= 8;
t->vht[8] = t->vht[9] = mt76x02_rate_power_val(val >> 8); t->vht[0] = t->vht[1] = mt76x02_rate_power_val(val >> 8);
memcpy(t->stbc, t->ht, sizeof(t->stbc[0]) * 8);
t->stbc[8] = t->vht[8];
t->stbc[9] = t->vht[9];
} }
EXPORT_SYMBOL_GPL(mt76x2_get_rate_power); EXPORT_SYMBOL_GPL(mt76x2_get_rate_power);
......
...@@ -40,7 +40,7 @@ struct mt76x2_temp_comp { ...@@ -40,7 +40,7 @@ struct mt76x2_temp_comp {
unsigned int low_slope; /* J / dB */ unsigned int low_slope; /* J / dB */
}; };
void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76_rate_power *t, void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76x02_rate_power *t,
struct ieee80211_channel *chan); struct ieee80211_channel *chan);
void mt76x2_get_power_info(struct mt76x02_dev *dev, void mt76x2_get_power_info(struct mt76x02_dev *dev,
struct mt76x2_tx_power_info *t, struct mt76x2_tx_power_info *t,
......
...@@ -182,7 +182,7 @@ void mt76x2_init_txpower(struct mt76x02_dev *dev, ...@@ -182,7 +182,7 @@ void mt76x2_init_txpower(struct mt76x02_dev *dev,
{ {
struct ieee80211_channel *chan; struct ieee80211_channel *chan;
struct mt76x2_tx_power_info txp; struct mt76x2_tx_power_info txp;
struct mt76_rate_power t = {}; struct mt76x02_rate_power t = {};
int i; int i;
for (i = 0; i < sband->n_channels; i++) { for (i = 0; i < sband->n_channels; i++) {
......
...@@ -116,7 +116,7 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev, ...@@ -116,7 +116,7 @@ void mt76x2_phy_set_txpower_regs(struct mt76x02_dev *dev,
EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower_regs); EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower_regs);
static int static int
mt76x2_get_min_rate_power(struct mt76_rate_power *r) mt76x2_get_min_rate_power(struct mt76x02_rate_power *r)
{ {
int i; int i;
s8 ret = 0; s8 ret = 0;
...@@ -140,7 +140,7 @@ void mt76x2_phy_set_txpower(struct mt76x02_dev *dev) ...@@ -140,7 +140,7 @@ void mt76x2_phy_set_txpower(struct mt76x02_dev *dev)
struct ieee80211_channel *chan = dev->mphy.chandef.chan; struct ieee80211_channel *chan = dev->mphy.chandef.chan;
struct mt76x2_tx_power_info txp; struct mt76x2_tx_power_info txp;
int txp_0, txp_1, delta = 0; int txp_0, txp_1, delta = 0;
struct mt76_rate_power t = {}; struct mt76x02_rate_power t = {};
int base_power, gain; int base_power, gain;
mt76x2_get_power_info(dev, &txp, chan); mt76x2_get_power_info(dev, &txp, chan);
...@@ -175,7 +175,7 @@ void mt76x2_phy_set_txpower(struct mt76x02_dev *dev) ...@@ -175,7 +175,7 @@ void mt76x2_phy_set_txpower(struct mt76x02_dev *dev)
dev->target_power = txp.target_power; dev->target_power = txp.target_power;
dev->target_power_delta[0] = txp_0 - txp.chain[0].target_power; dev->target_power_delta[0] = txp_0 - txp.chain[0].target_power;
dev->target_power_delta[1] = txp_1 - txp.chain[0].target_power; dev->target_power_delta[1] = txp_1 - txp.chain[0].target_power;
dev->mt76.rate_power = t; dev->rate_power = t;
mt76x02_phy_set_txpower(dev, txp_0, txp_1); mt76x02_phy_set_txpower(dev, txp_0, txp_1);
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
config MT7915E config MT7915E
tristate "MediaTek MT7915E (PCIe) support" tristate "MediaTek MT7915E (PCIe) support"
select MT76_CONNAC_LIB select MT76_CONNAC_LIB
select WANT_DEV_COREDUMP
depends on MAC80211 depends on MAC80211
depends on PCI depends on PCI
select RELAY select RELAY
......
...@@ -6,4 +6,5 @@ mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \ ...@@ -6,4 +6,5 @@ mt7915e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
debugfs.o mmio.o debugfs.o mmio.o
mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o
mt7915e-$(CONFIG_MT7986_WMAC) += soc.o mt7915e-$(CONFIG_MT7986_WMAC) += soc.o
\ No newline at end of file mt7915e-$(CONFIG_DEV_COREDUMP) += coredump.o
This diff is collapsed.
/* SPDX-License-Identifier: ISC */
/* Copyright (C) 2022 MediaTek Inc. */
#ifndef _COREDUMP_H_
#define _COREDUMP_H_
#include "mt7915.h"
struct trace {
u32 id;
u32 timestamp;
};
struct mt7915_coredump {
char magic[16];
u32 len;
guid_t guid;
/* time-of-day stamp */
u64 tv_sec;
/* time-of-day stamp, nano-seconds */
u64 tv_nsec;
/* kernel version */
char kernel[64];
/* firmware version */
char fw_ver[ETHTOOL_FWVERS_LEN];
u32 device_id;
/* exception state */
char fw_state[12];
u32 last_msg_id;
u32 eint_info_idx;
u32 irq_info_idx;
u32 sched_info_idx;
/* schedule info */
char trace_sched[32];
struct {
struct trace t;
u32 pc;
} sched[60];
/* irq info */
char trace_irq[32];
struct trace irq[60];
/* task queue status */
char task_qid[32];
struct {
u32 read;
u32 write;
} taskq[2];
/* task stack info */
char task_info[32];
struct {
u32 start;
u32 end;
u32 size;
} taski[2];
/* firmware context */
char fw_context[24];
struct {
u32 idx;
u32 handler;
} context;
/* link registers calltrace */
u32 call_stack[16];
/* memory content */
u8 data[];
} __packed;
struct mt7915_coredump_mem {
u32 len;
u8 data[];
} __packed;
struct mt7915_mem_hdr {
u32 start;
u32 len;
u8 data[];
};
struct mt7915_mem_region {
u32 start;
size_t len;
const char *name;
};
#ifdef CONFIG_DEV_COREDUMP
const struct mt7915_mem_region *
mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num);
struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev);
int mt7915_coredump_submit(struct mt7915_dev *dev);
int mt7915_coredump_register(struct mt7915_dev *dev);
void mt7915_coredump_unregister(struct mt7915_dev *dev);
#else /* CONFIG_DEV_COREDUMP */
static inline const struct mt7915_mem_region *
mt7915_coredump_get_mem_layout(struct mt7915_dev *dev, u32 *num)
{
return NULL;
}
static inline int mt7915_coredump_submit(struct mt7915_dev *dev)
{
return 0;
}
static inline struct mt7915_crash_data *mt7915_coredump_new(struct mt7915_dev *dev)
{
return NULL;
}
static inline int mt7915_coredump_register(struct mt7915_dev *dev)
{
return 0;
}
static inline void mt7915_coredump_unregister(struct mt7915_dev *dev)
{
}
#endif /* CONFIG_DEV_COREDUMP */
#endif /* _COREDUMP_H_ */
...@@ -131,9 +131,10 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) ...@@ -131,9 +131,10 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
{ {
struct mt7915_dev *dev = phy->dev; struct mt7915_dev *dev = phy->dev;
u8 *eeprom = dev->mt76.eeprom.data; u8 *eeprom = dev->mt76.eeprom.data;
u8 band = phy->mt76->band_idx;
u32 val; u32 val;
val = eeprom[MT_EE_WIFI_CONF + phy->band_idx]; val = eeprom[MT_EE_WIFI_CONF + band];
val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val); val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
if (!is_mt7915(&dev->mt76)) { if (!is_mt7915(&dev->mt76)) {
...@@ -153,7 +154,7 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) ...@@ -153,7 +154,7 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
return; return;
} }
} else if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) { } else if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support) {
val = phy->band_idx ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ; val = band ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
} }
switch (val) { switch (val) {
...@@ -173,60 +174,51 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy) ...@@ -173,60 +174,51 @@ static void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev, void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev,
struct mt7915_phy *phy) struct mt7915_phy *phy)
{ {
u8 nss, nss_band, nss_band_max, *eeprom = dev->mt76.eeprom.data; u8 path, nss, nss_max = 4, *eeprom = dev->mt76.eeprom.data;
struct mt76_phy *mphy = phy->mt76; struct mt76_phy *mphy = phy->mt76;
bool ext_phy = phy != &dev->phy; u8 band = phy->mt76->band_idx;
mt7915_eeprom_parse_band_config(phy); mt7915_eeprom_parse_band_config(phy);
/* read tx/rx mask from eeprom */ /* read tx/rx path from eeprom */
if (is_mt7915(&dev->mt76)) { if (is_mt7915(&dev->mt76)) {
nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH, path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
eeprom[MT_EE_WIFI_CONF]); eeprom[MT_EE_WIFI_CONF]);
} else { } else {
nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH, path = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH,
eeprom[MT_EE_WIFI_CONF + phy->band_idx]); eeprom[MT_EE_WIFI_CONF + band]);
} }
if (!nss || nss > 4) if (!path || path > 4)
nss = 4; path = 4;
/* read tx/rx stream */ /* read tx/rx stream */
nss_band = nss; nss = path;
if (dev->dbdc_support) { if (dev->dbdc_support) {
if (is_mt7915(&dev->mt76)) { if (is_mt7915(&dev->mt76)) {
nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0, path = min_t(u8, path, 2);
eeprom[MT_EE_WIFI_CONF + 3]); nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
if (phy->band_idx) eeprom[MT_EE_WIFI_CONF + 3]);
nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1, if (band)
eeprom[MT_EE_WIFI_CONF + 3]); nss = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B1,
eeprom[MT_EE_WIFI_CONF + 3]);
} else { } else {
nss_band = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM, nss = FIELD_GET(MT_EE_WIFI_CONF_STREAM_NUM,
eeprom[MT_EE_WIFI_CONF + 2 + phy->band_idx]); eeprom[MT_EE_WIFI_CONF + 2 + band]);
} }
nss_band_max = is_mt7986(&dev->mt76) ? if (!is_mt7986(&dev->mt76))
MT_EE_NSS_MAX_DBDC_MA7986 : MT_EE_NSS_MAX_DBDC_MA7915; nss_max = 2;
} else {
nss_band_max = is_mt7986(&dev->mt76) ?
MT_EE_NSS_MAX_MA7986 : MT_EE_NSS_MAX_MA7915;
} }
if (!nss_band || nss_band > nss_band_max) if (!nss)
nss_band = nss_band_max; nss = nss_max;
nss = min_t(u8, min_t(u8, nss_max, nss), path);
if (nss_band > nss) {
dev_warn(dev->mt76.dev,
"nss mismatch, nss(%d) nss_band(%d) band(%d) ext_phy(%d)\n",
nss, nss_band, phy->band_idx, ext_phy);
nss = nss_band;
}
mphy->chainmask = BIT(nss) - 1; mphy->chainmask = BIT(path) - 1;
if (ext_phy) if (band)
mphy->chainmask <<= dev->chainshift; mphy->chainmask <<= dev->chainshift;
mphy->antenna_mask = BIT(nss_band) - 1; mphy->antenna_mask = BIT(nss) - 1;
dev->chainmask |= mphy->chainmask; dev->chainmask |= mphy->chainmask;
dev->chainshift = hweight8(dev->mphy.chainmask); dev->chainshift = hweight8(dev->mphy.chainmask);
} }
......
...@@ -58,11 +58,6 @@ enum mt7915_eeprom_field { ...@@ -58,11 +58,6 @@ enum mt7915_eeprom_field {
#define MT_EE_RATE_DELTA_SIGN BIT(6) #define MT_EE_RATE_DELTA_SIGN BIT(6)
#define MT_EE_RATE_DELTA_EN BIT(7) #define MT_EE_RATE_DELTA_EN BIT(7)
#define MT_EE_NSS_MAX_MA7915 4
#define MT_EE_NSS_MAX_DBDC_MA7915 2
#define MT_EE_NSS_MAX_MA7986 4
#define MT_EE_NSS_MAX_DBDC_MA7986 4
enum mt7915_adie_sku { enum mt7915_adie_sku {
MT7976_ONE_ADIE_DBDC = 0x7, MT7976_ONE_ADIE_DBDC = 0x7,
MT7975_ONE_ADIE = 0x8, MT7975_ONE_ADIE = 0x8,
......
...@@ -1172,10 +1172,6 @@ static int mt7986_wmac_probe(struct platform_device *pdev) ...@@ -1172,10 +1172,6 @@ static int mt7986_wmac_probe(struct platform_device *pdev)
chip_id = (uintptr_t)of_device_get_match_data(&pdev->dev); chip_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
mem_base = devm_platform_ioremap_resource(pdev, 0); mem_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mem_base)) { if (IS_ERR(mem_base)) {
dev_err(&pdev->dev, "Failed to get memory resource\n"); dev_err(&pdev->dev, "Failed to get memory resource\n");
...@@ -1187,6 +1183,18 @@ static int mt7986_wmac_probe(struct platform_device *pdev) ...@@ -1187,6 +1183,18 @@ static int mt7986_wmac_probe(struct platform_device *pdev)
return PTR_ERR(dev); return PTR_ERR(dev);
mdev = &dev->mt76; mdev = &dev->mt76;
ret = mt7915_mmio_wed_init(dev, pdev, false, &irq);
if (ret < 0)
goto free_device;
if (!ret) {
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
goto free_device;
}
}
ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler, ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler,
IRQF_SHARED, KBUILD_MODNAME, dev); IRQF_SHARED, KBUILD_MODNAME, dev);
if (ret) if (ret)
...@@ -1206,9 +1214,10 @@ static int mt7986_wmac_probe(struct platform_device *pdev) ...@@ -1206,9 +1214,10 @@ static int mt7986_wmac_probe(struct platform_device *pdev)
free_irq: free_irq:
devm_free_irq(mdev->dev, irq, dev); devm_free_irq(mdev->dev, irq, dev);
free_device: free_device:
mt76_free_device(&dev->mt76); if (mtk_wed_device_active(&mdev->mmio.wed))
mtk_wed_device_detach(&mdev->mmio.wed);
mt76_free_device(mdev);
return ret; return ret;
} }
......
...@@ -85,7 +85,7 @@ mt7921_ampdu_stat_read_phy(struct mt7921_phy *phy, ...@@ -85,7 +85,7 @@ mt7921_ampdu_stat_read_phy(struct mt7921_phy *phy,
seq_puts(file, "\nCount: "); seq_puts(file, "\nCount: ");
for (i = 0; i < ARRAY_SIZE(bound); i++) for (i = 0; i < ARRAY_SIZE(bound); i++)
seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i]); seq_printf(file, "%8d | ", phy->mt76->aggr_stats[i]);
seq_puts(file, "\n"); seq_puts(file, "\n");
seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt); seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
......
# SPDX-License-Identifier: ISC
config MT7996E
tristate "MediaTek MT7996 (PCIe) support"
select MT76_CONNAC_LIB
depends on MAC80211
depends on PCI
help
This adds support for MT7996-based wireless PCIe devices,
which support concurrent tri-band operation at 6GHz, 5GHz,
and 2.4GHz IEEE 802.11be 4x4:4SS 4096-QAM, 320MHz channels.
To compile this driver as a module, choose M here.
# SPDX-License-Identifier: ISC
obj-$(CONFIG_MT7996E) += mt7996e.o
mt7996e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
debugfs.o mmio.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -395,7 +395,7 @@ mt76s_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) ...@@ -395,7 +395,7 @@ mt76s_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q)
if (!e || !e->skb) if (!e || !e->skb)
break; break;
dev->drv->rx_skb(dev, MT_RXQ_MAIN, e->skb); dev->drv->rx_skb(dev, MT_RXQ_MAIN, e->skb, NULL);
e->skb = NULL; e->skb = NULL;
nframes++; nframes++;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -29,12 +29,6 @@ enum { ...@@ -29,12 +29,6 @@ enum {
int mt76_wcid_alloc(u32 *mask, int size); int mt76_wcid_alloc(u32 *mask, int size);
static inline bool
mt76_wcid_mask_test(u32 *mask, int idx)
{
return mask[idx / 32] & BIT(idx % 32);
}
static inline void static inline void
mt76_wcid_mask_set(u32 *mask, int idx) mt76_wcid_mask_set(u32 *mask, int idx)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment