mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
mt76 patches for 5.12
* add new mt7921e driver * factor out common code shared between 7615/7663 and 7921 * performance optimizations * 7915 dbdc fixes * 802.11 encap offload support * support for multiple pcie gen1 host interfaces on 7915 * 7915 testmode support * bugfixes * testmode support enhancements * endian fixes * 7915 txbf support -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iEYEABECAAYFAmAURZcACgkQ130UHQKnbvX3xACePCxN0DX5vTv+4Z79sTpnc4ZY acwAn2iE9ObgXOWlSx3+QTz8fM4f5vGd =JCVv -----END PGP SIGNATURE----- Merge tag 'mt76-for-kvalo-2021-01-29' of https://github.com/nbd168/wireless mt76 patches for 5.12 * add new mt7921e driver * factor out common code shared between 7615/7663 and 7921 * performance optimizations * 7915 dbdc fixes * 802.11 encap offload support * support for multiple pcie gen1 host interfaces on 7915 * 7915 testmode support * bugfixes * testmode support enhancements * endian fixes * 7915 txbf support
This commit is contained in:
commit
1299616023
|
|
@ -24,8 +24,13 @@ config MT76x02_USB
|
|||
tristate
|
||||
select MT76_USB
|
||||
|
||||
config MT76_CONNAC_LIB
|
||||
tristate
|
||||
select MT76_CORE
|
||||
|
||||
source "drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig"
|
||||
source "drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig"
|
||||
source "drivers/net/wireless/mediatek/mt76/mt7603/Kconfig"
|
||||
source "drivers/net/wireless/mediatek/mt76/mt7615/Kconfig"
|
||||
source "drivers/net/wireless/mediatek/mt76/mt7915/Kconfig"
|
||||
source "drivers/net/wireless/mediatek/mt76/mt7921/Kconfig"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ obj-$(CONFIG_MT76_USB) += mt76-usb.o
|
|||
obj-$(CONFIG_MT76_SDIO) += mt76-sdio.o
|
||||
obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o
|
||||
obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o
|
||||
obj-$(CONFIG_MT76_CONNAC_LIB) += mt76-connac-lib.o
|
||||
|
||||
mt76-y := \
|
||||
mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \
|
||||
|
|
@ -26,8 +27,11 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
|
|||
|
||||
mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
|
||||
|
||||
mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o
|
||||
|
||||
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
|
||||
obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
|
||||
obj-$(CONFIG_MT7603E) += mt7603/
|
||||
obj-$(CONFIG_MT7615_COMMON) += mt7615/
|
||||
obj-$(CONFIG_MT7915E) += mt7915/
|
||||
obj-$(CONFIG_MT7921E) += mt7921/
|
||||
|
|
|
|||
|
|
@ -411,8 +411,12 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
|
|||
free:
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
/* fix tx_done accounting on queue overflow */
|
||||
if (tx_info.skb == dev->test.tx_skb)
|
||||
dev->test.tx_done--;
|
||||
if (mt76_is_testmode_skb(dev, skb, &hw)) {
|
||||
struct mt76_phy *phy = hw->priv;
|
||||
|
||||
if (tx_info.skb == phy->test.tx_skb)
|
||||
phy->test.tx_done--;
|
||||
}
|
||||
#endif
|
||||
|
||||
e.skb = tx_info.skb;
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ mt76_get_of_eeprom(struct mt76_dev *dev, int len)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
dev->test.mtd_name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
|
||||
dev->test.mtd_offset = offset;
|
||||
dev->test_mtd.name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
|
||||
dev->test_mtd.offset = offset;
|
||||
#endif
|
||||
|
||||
out_put_node:
|
||||
|
|
|
|||
|
|
@ -387,9 +387,9 @@ void mt76_unregister_phy(struct mt76_phy *phy)
|
|||
{
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
|
||||
dev->phy2 = NULL;
|
||||
mt76_tx_status_check(dev, NULL, true);
|
||||
ieee80211_unregister_hw(phy->hw);
|
||||
dev->phy2 = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_unregister_phy);
|
||||
|
||||
|
|
@ -519,10 +519,10 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
if (dev->test.state == MT76_TM_STATE_RX_FRAMES) {
|
||||
dev->test.rx_stats.packets[q]++;
|
||||
if (phy->test.state == MT76_TM_STATE_RX_FRAMES) {
|
||||
phy->test.rx_stats.packets[q]++;
|
||||
if (status->flag & RX_FLAG_FAILED_FCS_CRC)
|
||||
dev->test.rx_stats.fcs_error[q]++;
|
||||
phy->test.rx_stats.fcs_error[q]++;
|
||||
}
|
||||
#endif
|
||||
__skb_queue_tail(&dev->rx_skb[q], skb);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ enum mt76_rxq_id {
|
|||
MT_RXQ_MCU,
|
||||
MT_RXQ_MCU_WA,
|
||||
MT_RXQ_EXT,
|
||||
MT_RXQ_EXT_WA,
|
||||
__MT_RXQ_MAX
|
||||
};
|
||||
|
||||
|
|
@ -515,10 +516,10 @@ struct mt76_rx_status {
|
|||
};
|
||||
|
||||
struct mt76_testmode_ops {
|
||||
int (*set_state)(struct mt76_dev *dev, enum mt76_testmode_state state);
|
||||
int (*set_params)(struct mt76_dev *dev, struct nlattr **tb,
|
||||
int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state);
|
||||
int (*set_params)(struct mt76_phy *phy, struct nlattr **tb,
|
||||
enum mt76_testmode_state new_state);
|
||||
int (*dump_stats)(struct mt76_dev *dev, struct sk_buff *msg);
|
||||
int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg);
|
||||
};
|
||||
|
||||
struct mt76_testmode_data {
|
||||
|
|
@ -539,17 +540,20 @@ struct mt76_testmode_data {
|
|||
u8 tx_ltf;
|
||||
|
||||
u8 tx_antenna_mask;
|
||||
u8 tx_spe_idx;
|
||||
|
||||
u8 tx_duty_cycle;
|
||||
u32 tx_time;
|
||||
u32 tx_ipg;
|
||||
|
||||
u32 freq_offset;
|
||||
|
||||
u8 tx_power[4];
|
||||
u8 tx_power_control;
|
||||
|
||||
const char *mtd_name;
|
||||
u32 mtd_offset;
|
||||
|
||||
u32 tx_pending;
|
||||
u32 tx_queued;
|
||||
u16 tx_queued_limit;
|
||||
u32 tx_done;
|
||||
struct {
|
||||
u64 packets[__MT_RXQ_MAX];
|
||||
|
|
@ -557,6 +561,14 @@ struct mt76_testmode_data {
|
|||
} rx_stats;
|
||||
};
|
||||
|
||||
struct mt76_vif {
|
||||
u8 idx;
|
||||
u8 omac_idx;
|
||||
u8 band_idx;
|
||||
u8 wmm_idx;
|
||||
u8 scan_seq_num;
|
||||
};
|
||||
|
||||
struct mt76_phy {
|
||||
struct ieee80211_hw *hw;
|
||||
struct mt76_dev *dev;
|
||||
|
|
@ -578,10 +590,16 @@ struct mt76_phy {
|
|||
|
||||
u8 macaddr[ETH_ALEN];
|
||||
|
||||
u32 vif_mask;
|
||||
|
||||
int txpower_cur;
|
||||
u8 antenna_mask;
|
||||
u16 chainmask;
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
struct mt76_testmode_data test;
|
||||
#endif
|
||||
|
||||
struct delayed_work mac_work;
|
||||
u8 mac_work_count;
|
||||
};
|
||||
|
||||
struct mt76_dev {
|
||||
|
|
@ -622,7 +640,6 @@ struct mt76_dev {
|
|||
|
||||
struct mt76_worker tx_worker;
|
||||
struct napi_struct tx_napi;
|
||||
struct delayed_work mac_work;
|
||||
|
||||
wait_queue_head_t tx_wait;
|
||||
struct sk_buff_head status_list;
|
||||
|
|
@ -630,6 +647,8 @@ struct mt76_dev {
|
|||
u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)];
|
||||
u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)];
|
||||
|
||||
u32 vif_mask;
|
||||
|
||||
struct mt76_wcid global_wcid;
|
||||
struct mt76_wcid __rcu *wcid[MT76_N_WCIDS];
|
||||
|
||||
|
|
@ -646,6 +665,7 @@ struct mt76_dev {
|
|||
|
||||
struct mt76_rate_power rate_power;
|
||||
|
||||
char alpha2[3];
|
||||
enum nl80211_dfs_regions region;
|
||||
|
||||
u32 debugfs_reg;
|
||||
|
|
@ -661,9 +681,11 @@ struct mt76_dev {
|
|||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
const struct mt76_testmode_ops *test_ops;
|
||||
struct mt76_testmode_data test;
|
||||
struct {
|
||||
const char *name;
|
||||
u32 offset;
|
||||
} test_mtd;
|
||||
#endif
|
||||
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
union {
|
||||
|
|
@ -931,10 +953,27 @@ static inline u8 mt76_tx_power_nss_delta(u8 nss)
|
|||
return nss_delta[nss - 1];
|
||||
}
|
||||
|
||||
static inline bool mt76_testmode_enabled(struct mt76_dev *dev)
|
||||
static inline bool mt76_testmode_enabled(struct mt76_phy *phy)
|
||||
{
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
return dev->test.state != MT76_TM_STATE_OFF;
|
||||
return phy->test.state != MT76_TM_STATE_OFF;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool mt76_is_testmode_skb(struct mt76_dev *dev,
|
||||
struct sk_buff *skb,
|
||||
struct ieee80211_hw **hw)
|
||||
{
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
if (skb == dev->phy.test.tx_skb)
|
||||
*hw = dev->phy.hw;
|
||||
else if (dev->phy2 && skb == dev->phy2->test.tx_skb)
|
||||
*hw = dev->phy2->hw;
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
|
@ -1016,17 +1055,17 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
void *data, int len);
|
||||
int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
struct netlink_callback *cb, void *data, int len);
|
||||
int mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state);
|
||||
int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state);
|
||||
|
||||
static inline void mt76_testmode_reset(struct mt76_dev *dev, bool disable)
|
||||
static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable)
|
||||
{
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
enum mt76_testmode_state state = MT76_TM_STATE_IDLE;
|
||||
|
||||
if (disable || dev->test.state == MT76_TM_STATE_OFF)
|
||||
if (disable || phy->test.state == MT76_TM_STATE_OFF)
|
||||
state = MT76_TM_STATE_OFF;
|
||||
|
||||
mt76_testmode_set_state(dev, state);
|
||||
mt76_testmode_set_state(phy, state);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1052,7 +1091,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames,
|
|||
void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
|
||||
struct napi_struct *napi);
|
||||
void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames);
|
||||
void mt76_testmode_tx_pending(struct mt76_dev *dev);
|
||||
void mt76_testmode_tx_pending(struct mt76_phy *phy);
|
||||
void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q,
|
||||
struct mt76_queue_entry *e);
|
||||
|
||||
|
|
|
|||
|
|
@ -532,7 +532,7 @@ int mt7603_register_device(struct mt7603_dev *dev)
|
|||
spin_lock_init(&dev->sta_poll_lock);
|
||||
spin_lock_init(&dev->ps_lock);
|
||||
|
||||
INIT_DELAYED_WORK(&dev->mt76.mac_work, mt7603_mac_work);
|
||||
INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7603_mac_work);
|
||||
tasklet_setup(&dev->mt76.pre_tbtt_tasklet, mt7603_pre_tbtt_tasklet);
|
||||
|
||||
dev->slottime = 9;
|
||||
|
|
|
|||
|
|
@ -1631,9 +1631,13 @@ mt7603_edcca_check(struct mt7603_dev *dev)
|
|||
if (rssi0 > 128)
|
||||
rssi0 -= 256;
|
||||
|
||||
rssi1 = FIELD_GET(MT_AGC_41_RSSI_1, val);
|
||||
if (rssi1 > 128)
|
||||
rssi1 -= 256;
|
||||
if (dev->mphy.antenna_mask & BIT(1)) {
|
||||
rssi1 = FIELD_GET(MT_AGC_41_RSSI_1, val);
|
||||
if (rssi1 > 128)
|
||||
rssi1 -= 256;
|
||||
} else {
|
||||
rssi1 = rssi0;
|
||||
}
|
||||
|
||||
if (max(rssi0, rssi1) >= -40 &&
|
||||
dev->ed_strong_signal < MT7603_EDCCA_BLOCK_TH)
|
||||
|
|
@ -1788,7 +1792,7 @@ mt7603_false_cca_check(struct mt7603_dev *dev)
|
|||
void mt7603_mac_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7603_dev *dev = container_of(work, struct mt7603_dev,
|
||||
mt76.mac_work.work);
|
||||
mphy.mac_work.work);
|
||||
bool reset = false;
|
||||
int i, idx;
|
||||
|
||||
|
|
@ -1796,7 +1800,7 @@ void mt7603_mac_work(struct work_struct *work)
|
|||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
dev->mac_work_count++;
|
||||
dev->mphy.mac_work_count++;
|
||||
mt76_update_survey(&dev->mt76);
|
||||
mt7603_edcca_check(dev);
|
||||
|
||||
|
|
@ -1807,7 +1811,7 @@ void mt7603_mac_work(struct work_struct *work)
|
|||
dev->mt76.aggr_stats[idx++] += val >> 16;
|
||||
}
|
||||
|
||||
if (dev->mac_work_count == 10)
|
||||
if (dev->mphy.mac_work_count == 10)
|
||||
mt7603_false_cca_check(dev);
|
||||
|
||||
if (mt7603_watchdog_check(dev, &dev->rx_pse_check,
|
||||
|
|
@ -1838,17 +1842,17 @@ void mt7603_mac_work(struct work_struct *work)
|
|||
dev->rx_dma_idx = ~0;
|
||||
memset(dev->tx_dma_idx, 0xff, sizeof(dev->tx_dma_idx));
|
||||
reset = true;
|
||||
dev->mac_work_count = 0;
|
||||
dev->mphy.mac_work_count = 0;
|
||||
}
|
||||
|
||||
if (dev->mac_work_count >= 10)
|
||||
dev->mac_work_count = 0;
|
||||
if (dev->mphy.mac_work_count >= 10)
|
||||
dev->mphy.mac_work_count = 0;
|
||||
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
|
||||
if (reset)
|
||||
mt7603_mac_watchdog_reset(dev);
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
|
||||
msecs_to_jiffies(MT7603_WATCHDOG_TIME));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ mt7603_start(struct ieee80211_hw *hw)
|
|||
mt7603_mac_start(dev);
|
||||
dev->mphy.survey_time = ktime_get_boottime();
|
||||
set_bit(MT76_STATE_RUNNING, &dev->mphy.state);
|
||||
mt7603_mac_work(&dev->mt76.mac_work.work);
|
||||
mt7603_mac_work(&dev->mphy.mac_work.work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ mt7603_stop(struct ieee80211_hw *hw)
|
|||
struct mt7603_dev *dev = hw->priv;
|
||||
|
||||
clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
|
||||
cancel_delayed_work_sync(&dev->mt76.mac_work);
|
||||
cancel_delayed_work_sync(&dev->mphy.mac_work);
|
||||
mt7603_mac_stop(dev);
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
mvif->idx = ffs(~dev->mphy.vif_mask) - 1;
|
||||
mvif->idx = ffs(~dev->mt76.vif_mask) - 1;
|
||||
if (mvif->idx >= MT7603_MAX_INTERFACES) {
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
|
|
@ -65,7 +65,7 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|||
}
|
||||
|
||||
idx = MT7603_WTBL_RESERVED - 1 - mvif->idx;
|
||||
dev->mphy.vif_mask |= BIT(mvif->idx);
|
||||
dev->mt76.vif_mask |= BIT(mvif->idx);
|
||||
INIT_LIST_HEAD(&mvif->sta.poll_list);
|
||||
mvif->sta.wcid.idx = idx;
|
||||
mvif->sta.wcid.hw_key_idx = -1;
|
||||
|
|
@ -105,7 +105,7 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|||
spin_unlock_bh(&dev->sta_poll_lock);
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
dev->mphy.vif_mask &= ~BIT(mvif->idx);
|
||||
dev->mt76.vif_mask &= ~BIT(mvif->idx);
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
}
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
|
|||
u8 bw = MT_BW_20;
|
||||
bool failed = false;
|
||||
|
||||
cancel_delayed_work_sync(&dev->mt76.mac_work);
|
||||
cancel_delayed_work_sync(&dev->mphy.mac_work);
|
||||
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
|
@ -178,7 +178,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
|
|||
|
||||
mt76_txq_schedule_all(&dev->mphy);
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
|
||||
msecs_to_jiffies(MT7603_WATCHDOG_TIME));
|
||||
|
||||
/* reset channel stats */
|
||||
|
|
@ -200,7 +200,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
|
|||
tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
|
||||
|
||||
if (failed)
|
||||
mt7603_mac_work(&dev->mt76.mac_work.work);
|
||||
mt7603_mac_work(&dev->mphy.mac_work.work);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -132,8 +132,6 @@ struct mt7603_dev {
|
|||
|
||||
spinlock_t ps_lock;
|
||||
|
||||
u8 mac_work_count;
|
||||
|
||||
u8 mcu_running;
|
||||
|
||||
u8 ed_monitor_enabled;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
config MT7615_COMMON
|
||||
tristate
|
||||
select MT76_CORE
|
||||
select WANT_DEV_COREDUMP
|
||||
select MT76_CONNAC_LIB
|
||||
|
||||
config MT7615E
|
||||
tristate "MediaTek MT7615E and MT7663E (PCIe) support"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,20 @@ mt7615_radar_pattern_set(void *data, u64 val)
|
|||
DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
|
||||
mt7615_radar_pattern_set, "%lld\n");
|
||||
|
||||
static int mt7615_config(void *data, u64 val)
|
||||
{
|
||||
struct mt7615_dev *dev = data;
|
||||
int ret;
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
ret = mt76_connac_mcu_chip_config(&dev->mt76);
|
||||
mt7615_mutex_release(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_config, NULL, mt7615_config, "%lld\n");
|
||||
|
||||
static int
|
||||
mt7615_scs_set(void *data, u64 val)
|
||||
{
|
||||
|
|
@ -525,6 +539,9 @@ int mt7615_init_debugfs(struct mt7615_dev *dev)
|
|||
debugfs_create_u32("rf_regidx", 0600, dir, &dev->debugfs_rf_reg);
|
||||
debugfs_create_file_unsafe("rf_regval", 0600, dir, dev,
|
||||
&fops_rf_reg);
|
||||
if (is_mt7663(&dev->mt76))
|
||||
debugfs_create_file("chip_config", 0600, dir, dev,
|
||||
&fops_config);
|
||||
if (mt76_is_sdio(&dev->mt76))
|
||||
debugfs_create_devm_seqfile(dev->mt76.dev, "sched-quota", dir,
|
||||
mt7663s_sched_quota_read);
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
|
|||
|
||||
dev->chainmask = BIT(tx_mask) - 1;
|
||||
dev->mphy.antenna_mask = dev->chainmask;
|
||||
dev->phy.chainmask = dev->chainmask;
|
||||
dev->mphy.chainmask = dev->chainmask;
|
||||
}
|
||||
|
||||
static int mt7663_eeprom_get_target_power_index(struct mt7615_dev *dev,
|
||||
|
|
|
|||
|
|
@ -10,15 +10,16 @@
|
|||
#include <linux/etherdevice.h>
|
||||
#include "mt7615.h"
|
||||
#include "mac.h"
|
||||
#include "mcu.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
void mt7615_phy_init(struct mt7615_dev *dev)
|
||||
static void
|
||||
mt7615_phy_init(struct mt7615_dev *dev)
|
||||
{
|
||||
/* disable rf low power beacon mode */
|
||||
mt76_set(dev, MT_WF_PHY_WF2_RFCTRL0(0), MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN);
|
||||
mt76_set(dev, MT_WF_PHY_WF2_RFCTRL0(1), MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_phy_init);
|
||||
|
||||
static void
|
||||
mt7615_init_mac_chain(struct mt7615_dev *dev, int chain)
|
||||
|
|
@ -79,7 +80,8 @@ mt7615_init_mac_chain(struct mt7615_dev *dev, int chain)
|
|||
}
|
||||
}
|
||||
|
||||
void mt7615_mac_init(struct mt7615_dev *dev)
|
||||
static void
|
||||
mt7615_mac_init(struct mt7615_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -95,7 +97,7 @@ void mt7615_mac_init(struct mt7615_dev *dev)
|
|||
MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
|
||||
MT_TMAC_CTCR0_INS_DDLMT_EN);
|
||||
|
||||
mt7615_mcu_set_rts_thresh(&dev->phy, 0x92b);
|
||||
mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b, 0);
|
||||
mt7615_mac_set_scs(&dev->phy, true);
|
||||
|
||||
mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS,
|
||||
|
|
@ -128,9 +130,9 @@ void mt7615_mac_init(struct mt7615_dev *dev)
|
|||
mt7615_init_mac_chain(dev, 1);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_mac_init);
|
||||
|
||||
void mt7615_check_offload_capability(struct mt7615_dev *dev)
|
||||
static void
|
||||
mt7615_check_offload_capability(struct mt7615_dev *dev)
|
||||
{
|
||||
struct ieee80211_hw *hw = mt76_hw(dev);
|
||||
struct wiphy *wiphy = hw->wiphy;
|
||||
|
|
@ -162,7 +164,6 @@ void mt7615_check_offload_capability(struct mt7615_dev *dev)
|
|||
wiphy->max_sched_scan_reqs = 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_check_offload_capability);
|
||||
|
||||
bool mt7615_wait_for_mcu_init(struct mt7615_dev *dev)
|
||||
{
|
||||
|
|
@ -286,6 +287,16 @@ void mt7615_init_txpower(struct mt7615_dev *dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_init_txpower);
|
||||
|
||||
void mt7615_init_work(struct mt7615_dev *dev)
|
||||
{
|
||||
mt7615_mcu_set_eeprom(dev);
|
||||
mt7615_mac_init(dev);
|
||||
mt7615_phy_init(dev);
|
||||
mt7615_mcu_del_wtbl_all(dev);
|
||||
mt7615_check_offload_capability(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_init_work);
|
||||
|
||||
static void
|
||||
mt7615_regd_notifier(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
|
|
@ -296,13 +307,16 @@ mt7615_regd_notifier(struct wiphy *wiphy,
|
|||
struct mt7615_phy *phy = mphy->priv;
|
||||
struct cfg80211_chan_def *chandef = &mphy->chandef;
|
||||
|
||||
memcpy(dev->mt76.alpha2, request->alpha2, sizeof(dev->mt76.alpha2));
|
||||
dev->mt76.region = request->dfs_region;
|
||||
|
||||
if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR))
|
||||
return;
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
mt7615_dfs_init_radar_detector(phy);
|
||||
|
||||
if (chandef->chan->flags & IEEE80211_CHAN_RADAR)
|
||||
mt7615_dfs_init_radar_detector(phy);
|
||||
if (mt7615_firmware_offload(phy->dev))
|
||||
mt76_connac_mcu_set_channel_domain(mphy);
|
||||
|
||||
mt7615_mutex_release(dev);
|
||||
}
|
||||
|
||||
|
|
@ -331,11 +345,12 @@ mt7615_init_wiphy(struct ieee80211_hw *hw)
|
|||
}
|
||||
wiphy->reg_notifier = mt7615_regd_notifier;
|
||||
|
||||
wiphy->max_sched_scan_plan_interval = MT7615_MAX_SCHED_SCAN_INTERVAL;
|
||||
wiphy->max_sched_scan_plan_interval =
|
||||
MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL;
|
||||
wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
|
||||
wiphy->max_scan_ie_len = MT7615_SCAN_IE_LEN;
|
||||
wiphy->max_sched_scan_ssids = MT7615_MAX_SCHED_SCAN_SSID;
|
||||
wiphy->max_match_sets = MT7615_MAX_SCAN_MATCH;
|
||||
wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
|
||||
wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
|
||||
wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
|
||||
wiphy->max_sched_scan_reqs = 1;
|
||||
wiphy->max_scan_ssids = 4;
|
||||
|
||||
|
|
@ -362,9 +377,9 @@ mt7615_cap_dbdc_enable(struct mt7615_dev *dev)
|
|||
dev->mphy.antenna_mask = dev->chainmask >> 2;
|
||||
else
|
||||
dev->mphy.antenna_mask = dev->chainmask >> 1;
|
||||
dev->phy.chainmask = dev->mphy.antenna_mask;
|
||||
dev->mphy.hw->wiphy->available_antennas_rx = dev->phy.chainmask;
|
||||
dev->mphy.hw->wiphy->available_antennas_tx = dev->phy.chainmask;
|
||||
dev->mphy.chainmask = dev->mphy.antenna_mask;
|
||||
dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;
|
||||
dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;
|
||||
mt76_set_stream_caps(&dev->mphy, true);
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +390,7 @@ mt7615_cap_dbdc_disable(struct mt7615_dev *dev)
|
|||
IEEE80211_VHT_CAP_SHORT_GI_160 |
|
||||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
|
||||
dev->mphy.antenna_mask = dev->chainmask;
|
||||
dev->phy.chainmask = dev->chainmask;
|
||||
dev->mphy.chainmask = dev->chainmask;
|
||||
dev->mphy.hw->wiphy->available_antennas_rx = dev->chainmask;
|
||||
dev->mphy.hw->wiphy->available_antennas_tx = dev->chainmask;
|
||||
mt76_set_stream_caps(&dev->mphy, true);
|
||||
|
|
@ -404,11 +419,11 @@ int mt7615_register_ext_phy(struct mt7615_dev *dev)
|
|||
phy = mphy->priv;
|
||||
phy->dev = dev;
|
||||
phy->mt76 = mphy;
|
||||
phy->chainmask = dev->chainmask & ~dev->phy.chainmask;
|
||||
mphy->antenna_mask = BIT(hweight8(phy->chainmask)) - 1;
|
||||
mphy->chainmask = dev->chainmask & ~dev->mphy.chainmask;
|
||||
mphy->antenna_mask = BIT(hweight8(mphy->chainmask)) - 1;
|
||||
mt7615_init_wiphy(mphy->hw);
|
||||
|
||||
INIT_DELAYED_WORK(&phy->mac_work, mt7615_mac_work);
|
||||
INIT_DELAYED_WORK(&mphy->mac_work, mt7615_mac_work);
|
||||
INIT_DELAYED_WORK(&phy->scan_work, mt7615_scan_work);
|
||||
skb_queue_head_init(&phy->scan_event_list);
|
||||
|
||||
|
|
@ -471,9 +486,11 @@ void mt7615_init_device(struct mt7615_dev *dev)
|
|||
init_completion(&dev->pm.wake_cmpl);
|
||||
spin_lock_init(&dev->pm.txq_lock);
|
||||
set_bit(MT76_STATE_PM, &dev->mphy.state);
|
||||
INIT_DELAYED_WORK(&dev->phy.mac_work, mt7615_mac_work);
|
||||
INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7615_mac_work);
|
||||
INIT_DELAYED_WORK(&dev->phy.scan_work, mt7615_scan_work);
|
||||
INIT_DELAYED_WORK(&dev->coredump.work, mt7615_coredump_work);
|
||||
skb_queue_head_init(&dev->phy.scan_event_list);
|
||||
skb_queue_head_init(&dev->coredump.msg_list);
|
||||
INIT_LIST_HEAD(&dev->sta_poll_list);
|
||||
spin_lock_init(&dev->sta_poll_lock);
|
||||
init_waitqueue_head(&dev->reset_wait);
|
||||
|
|
@ -488,7 +505,6 @@ void mt7615_init_device(struct mt7615_dev *dev)
|
|||
dev->mphy.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
|
||||
dev->mphy.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
|
||||
dev->mphy.sband_5g.sband.vht_cap.cap |=
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
|
||||
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
|
||||
mt7615_cap_dbdc_disable(dev);
|
||||
dev->phy.dfs_state = -1;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
* Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
*/
|
||||
|
||||
#include <linux/devcoredump.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include "mt7615.h"
|
||||
|
|
@ -14,6 +15,7 @@
|
|||
#include "../dma.h"
|
||||
#include "mt7615_trace.h"
|
||||
#include "mac.h"
|
||||
#include "mcu.h"
|
||||
|
||||
#define to_rssi(field, rxv) ((FIELD_GET(field, rxv) - 220) / 2)
|
||||
|
||||
|
|
@ -186,7 +188,7 @@ mt7615_get_status_freq_info(struct mt7615_dev *dev, struct mt76_phy *mphy,
|
|||
status->freq = ieee80211_channel_to_frequency(chfreq, status->band);
|
||||
}
|
||||
|
||||
static void mt7615_mac_fill_tm_rx(struct mt7615_dev *dev, __le32 *rxv)
|
||||
static void mt7615_mac_fill_tm_rx(struct mt7615_phy *phy, __le32 *rxv)
|
||||
{
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
u32 rxv1 = le32_to_cpu(rxv[0]);
|
||||
|
|
@ -210,13 +212,13 @@ static void mt7615_mac_fill_tm_rx(struct mt7615_dev *dev, __le32 *rxv)
|
|||
foe = (foe * foe_const) >> 15;
|
||||
}
|
||||
|
||||
dev->test.last_freq_offset = foe;
|
||||
dev->test.last_rcpi[0] = FIELD_GET(MT_RXV4_RCPI0, rxv4);
|
||||
dev->test.last_rcpi[1] = FIELD_GET(MT_RXV4_RCPI1, rxv4);
|
||||
dev->test.last_rcpi[2] = FIELD_GET(MT_RXV4_RCPI2, rxv4);
|
||||
dev->test.last_rcpi[3] = FIELD_GET(MT_RXV4_RCPI3, rxv4);
|
||||
dev->test.last_ib_rssi[0] = FIELD_GET(MT_RXV3_IB_RSSI, rxv3);
|
||||
dev->test.last_wb_rssi[0] = FIELD_GET(MT_RXV3_WB_RSSI, rxv3);
|
||||
phy->test.last_freq_offset = foe;
|
||||
phy->test.last_rcpi[0] = FIELD_GET(MT_RXV4_RCPI0, rxv4);
|
||||
phy->test.last_rcpi[1] = FIELD_GET(MT_RXV4_RCPI1, rxv4);
|
||||
phy->test.last_rcpi[2] = FIELD_GET(MT_RXV4_RCPI2, rxv4);
|
||||
phy->test.last_rcpi[3] = FIELD_GET(MT_RXV4_RCPI3, rxv4);
|
||||
phy->test.last_ib_rssi[0] = FIELD_GET(MT_RXV3_IB_RSSI, rxv3);
|
||||
phy->test.last_wb_rssi[0] = FIELD_GET(MT_RXV3_WB_RSSI, rxv3);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -326,7 +328,7 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
|
|||
* that PHY.
|
||||
*/
|
||||
if (phy_idx < 0) {
|
||||
int first_chain = ffs(phy2->chainmask) - 1;
|
||||
int first_chain = ffs(phy2->mt76->chainmask) - 1;
|
||||
|
||||
phy_idx = ((rxdg5 >> (first_chain * 8)) & 0xff) == 0;
|
||||
}
|
||||
|
|
@ -435,7 +437,7 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
|
|||
status->chain_signal[i]);
|
||||
}
|
||||
|
||||
mt7615_mac_fill_tm_rx(dev, rxd);
|
||||
mt7615_mac_fill_tm_rx(mphy->priv, rxd);
|
||||
|
||||
rxd += 6;
|
||||
if ((u8 *)rxd - skb->data >= skb->len)
|
||||
|
|
@ -544,7 +546,7 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
|
|||
u16 seqno = 0;
|
||||
|
||||
if (vif) {
|
||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
|
||||
|
||||
omac_idx = mvif->omac_idx;
|
||||
wmm_idx = mvif->wmm_idx;
|
||||
|
|
@ -1465,7 +1467,7 @@ static void mt7615_mac_tx_free(struct mt7615_dev *dev, struct sk_buff *skb)
|
|||
mt7615_mac_sta_poll(dev);
|
||||
rcu_read_unlock();
|
||||
|
||||
mt7615_pm_power_save_sched(dev);
|
||||
mt76_connac_power_save_sched(&dev->mphy, &dev->pm);
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
}
|
||||
|
||||
|
|
@ -1789,11 +1791,11 @@ void mt7615_update_channel(struct mt76_dev *mdev)
|
|||
{
|
||||
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||
|
||||
if (mt7615_pm_wake(dev))
|
||||
if (mt76_connac_pm_wake(&dev->mphy, &dev->pm))
|
||||
return;
|
||||
|
||||
__mt7615_update_channel(dev);
|
||||
mt7615_pm_power_save_sched(dev);
|
||||
mt76_connac_power_save_sched(&dev->mphy, &dev->pm);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_update_channel);
|
||||
|
||||
|
|
@ -1862,97 +1864,20 @@ void mt7615_pm_wake_work(struct work_struct *work)
|
|||
{
|
||||
struct mt7615_dev *dev;
|
||||
struct mt76_phy *mphy;
|
||||
int i;
|
||||
|
||||
dev = (struct mt7615_dev *)container_of(work, struct mt7615_dev,
|
||||
pm.wake_work);
|
||||
mphy = dev->phy.mt76;
|
||||
|
||||
if (mt7615_mcu_set_drv_ctrl(dev)) {
|
||||
if (!mt7615_mcu_set_drv_ctrl(dev))
|
||||
mt76_connac_pm_dequeue_skbs(mphy, &dev->pm);
|
||||
else
|
||||
dev_err(mphy->dev->dev, "failed to wake device\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_bh(&dev->pm.txq_lock);
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||
struct mt7615_sta *msta = dev->pm.tx_q[i].msta;
|
||||
struct ieee80211_sta *sta = NULL;
|
||||
struct mt76_wcid *wcid;
|
||||
|
||||
if (!dev->pm.tx_q[i].skb)
|
||||
continue;
|
||||
|
||||
wcid = msta ? &msta->wcid : &dev->mt76.global_wcid;
|
||||
if (msta && wcid->sta)
|
||||
sta = container_of((void *)msta, struct ieee80211_sta,
|
||||
drv_priv);
|
||||
|
||||
mt76_tx(mphy, sta, wcid, dev->pm.tx_q[i].skb);
|
||||
dev->pm.tx_q[i].skb = NULL;
|
||||
}
|
||||
spin_unlock_bh(&dev->pm.txq_lock);
|
||||
|
||||
mt76_worker_schedule(&dev->mt76.tx_worker);
|
||||
|
||||
out:
|
||||
ieee80211_wake_queues(mphy->hw);
|
||||
complete_all(&dev->pm.wake_cmpl);
|
||||
}
|
||||
|
||||
int mt7615_pm_wake(struct mt7615_dev *dev)
|
||||
{
|
||||
struct mt76_phy *mphy = dev->phy.mt76;
|
||||
|
||||
if (!mt7615_firmware_offload(dev))
|
||||
return 0;
|
||||
|
||||
if (!mt76_is_mmio(mphy->dev))
|
||||
return 0;
|
||||
|
||||
if (!test_bit(MT76_STATE_PM, &mphy->state))
|
||||
return 0;
|
||||
|
||||
if (test_bit(MT76_HW_SCANNING, &mphy->state) ||
|
||||
test_bit(MT76_HW_SCHED_SCANNING, &mphy->state))
|
||||
return 0;
|
||||
|
||||
if (queue_work(dev->mt76.wq, &dev->pm.wake_work))
|
||||
reinit_completion(&dev->pm.wake_cmpl);
|
||||
|
||||
if (!wait_for_completion_timeout(&dev->pm.wake_cmpl, 3 * HZ)) {
|
||||
ieee80211_wake_queues(mphy->hw);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_pm_wake);
|
||||
|
||||
void mt7615_pm_power_save_sched(struct mt7615_dev *dev)
|
||||
{
|
||||
struct mt76_phy *mphy = dev->phy.mt76;
|
||||
|
||||
if (!mt7615_firmware_offload(dev))
|
||||
return;
|
||||
|
||||
if (!mt76_is_mmio(mphy->dev))
|
||||
return;
|
||||
|
||||
if (!dev->pm.enable || !test_bit(MT76_STATE_RUNNING, &mphy->state))
|
||||
return;
|
||||
|
||||
dev->pm.last_activity = jiffies;
|
||||
|
||||
if (test_bit(MT76_HW_SCANNING, &mphy->state) ||
|
||||
test_bit(MT76_HW_SCHED_SCANNING, &mphy->state))
|
||||
return;
|
||||
|
||||
if (!test_bit(MT76_STATE_PM, &mphy->state))
|
||||
queue_delayed_work(dev->mt76.wq, &dev->pm.ps_work,
|
||||
dev->pm.idle_timeout);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_pm_power_save_sched);
|
||||
|
||||
void mt7615_pm_power_save_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7615_dev *dev;
|
||||
|
|
@ -1976,17 +1901,17 @@ void mt7615_pm_power_save_work(struct work_struct *work)
|
|||
void mt7615_mac_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7615_phy *phy;
|
||||
struct mt76_dev *mdev;
|
||||
struct mt76_phy *mphy;
|
||||
|
||||
phy = (struct mt7615_phy *)container_of(work, struct mt7615_phy,
|
||||
mac_work.work);
|
||||
mdev = &phy->dev->mt76;
|
||||
mphy = (struct mt76_phy *)container_of(work, struct mt76_phy,
|
||||
mac_work.work);
|
||||
phy = mphy->priv;
|
||||
|
||||
mt7615_mutex_acquire(phy->dev);
|
||||
|
||||
mt7615_update_survey(phy->dev);
|
||||
if (++phy->mac_work_count == 5) {
|
||||
phy->mac_work_count = 0;
|
||||
if (++mphy->mac_work_count == 5) {
|
||||
mphy->mac_work_count = 0;
|
||||
|
||||
mt7615_mac_update_mib_stats(phy);
|
||||
mt7615_mac_scs_check(phy);
|
||||
|
|
@ -1994,8 +1919,8 @@ void mt7615_mac_work(struct work_struct *work)
|
|||
|
||||
mt7615_mutex_release(phy->dev);
|
||||
|
||||
mt76_tx_status_check(mdev, NULL, false);
|
||||
ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
|
||||
mt76_tx_status_check(mphy->dev, NULL, false);
|
||||
ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
|
||||
MT7615_WATCHDOG_TIME);
|
||||
}
|
||||
|
||||
|
|
@ -2017,7 +1942,16 @@ mt7615_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
|||
struct ieee80211_hw *hw = priv;
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
|
||||
mt7615_mcu_add_beacon(dev, hw, vif, vif->bss_conf.enable_beacon);
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_AP:
|
||||
mt7615_mcu_add_beacon(dev, hw, vif,
|
||||
vif->bss_conf.enable_beacon);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2058,6 +1992,23 @@ void mt7615_dma_reset(struct mt7615_dev *dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_dma_reset);
|
||||
|
||||
void mt7615_tx_token_put(struct mt7615_dev *dev)
|
||||
{
|
||||
struct mt76_txwi_cache *txwi;
|
||||
int id;
|
||||
|
||||
spin_lock_bh(&dev->token_lock);
|
||||
idr_for_each_entry(&dev->token, txwi, id) {
|
||||
mt7615_txp_skb_unmap(&dev->mt76, txwi);
|
||||
if (txwi->skb)
|
||||
dev_kfree_skb_any(txwi->skb);
|
||||
mt76_put_txwi(&dev->mt76, txwi);
|
||||
}
|
||||
spin_unlock_bh(&dev->token_lock);
|
||||
idr_destroy(&dev->token);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_tx_token_put);
|
||||
|
||||
void mt7615_mac_reset_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7615_phy *phy2;
|
||||
|
|
@ -2078,11 +2029,11 @@ void mt7615_mac_reset_work(struct work_struct *work)
|
|||
set_bit(MT76_RESET, &dev->mphy.state);
|
||||
set_bit(MT76_MCU_RESET, &dev->mphy.state);
|
||||
wake_up(&dev->mt76.mcu.wait);
|
||||
cancel_delayed_work_sync(&dev->phy.mac_work);
|
||||
cancel_delayed_work_sync(&dev->mphy.mac_work);
|
||||
del_timer_sync(&dev->phy.roc_timer);
|
||||
cancel_work_sync(&dev->phy.roc_work);
|
||||
if (phy2) {
|
||||
cancel_delayed_work_sync(&phy2->mac_work);
|
||||
cancel_delayed_work_sync(&phy2->mt76->mac_work);
|
||||
del_timer_sync(&phy2->roc_timer);
|
||||
cancel_work_sync(&phy2->roc_work);
|
||||
}
|
||||
|
|
@ -2101,6 +2052,9 @@ void mt7615_mac_reset_work(struct work_struct *work)
|
|||
|
||||
mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_PDMA_STOPPED);
|
||||
|
||||
mt7615_tx_token_put(dev);
|
||||
idr_init(&dev->token);
|
||||
|
||||
if (mt7615_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) {
|
||||
mt7615_dma_reset(dev);
|
||||
|
||||
|
|
@ -2134,10 +2088,11 @@ void mt7615_mac_reset_work(struct work_struct *work)
|
|||
|
||||
mt7615_mutex_release(dev);
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->phy.mac_work,
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
|
||||
MT7615_WATCHDOG_TIME);
|
||||
if (phy2)
|
||||
ieee80211_queue_delayed_work(ext_phy->hw, &phy2->mac_work,
|
||||
ieee80211_queue_delayed_work(ext_phy->hw,
|
||||
&phy2->mt76->mac_work,
|
||||
MT7615_WATCHDOG_TIME);
|
||||
|
||||
}
|
||||
|
|
@ -2319,3 +2274,44 @@ int mt7615_mac_set_beacon_filter(struct mt7615_phy *phy,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt7615_coredump_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7615_dev *dev;
|
||||
char *dump, *data;
|
||||
|
||||
dev = (struct mt7615_dev *)container_of(work, struct mt7615_dev,
|
||||
coredump.work.work);
|
||||
|
||||
if (time_is_after_jiffies(dev->coredump.last_activity +
|
||||
4 * MT76_CONNAC_COREDUMP_TIMEOUT)) {
|
||||
queue_delayed_work(dev->mt76.wq, &dev->coredump.work,
|
||||
MT76_CONNAC_COREDUMP_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
dump = vzalloc(MT76_CONNAC_COREDUMP_SZ);
|
||||
data = dump;
|
||||
|
||||
while (true) {
|
||||
struct sk_buff *skb;
|
||||
|
||||
spin_lock_bh(&dev->mt76.lock);
|
||||
skb = __skb_dequeue(&dev->coredump.msg_list);
|
||||
spin_unlock_bh(&dev->mt76.lock);
|
||||
|
||||
if (!skb)
|
||||
break;
|
||||
|
||||
skb_pull(skb, sizeof(struct mt7615_mcu_rxd));
|
||||
if (data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ)
|
||||
break;
|
||||
|
||||
memcpy(data, skb->data, skb->len);
|
||||
data += skb->len;
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
dev_coredumpv(dev->mt76.dev, dump, MT76_CONNAC_COREDUMP_SZ,
|
||||
GFP_KERNEL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,22 +24,6 @@ static bool mt7615_dev_running(struct mt7615_dev *dev)
|
|||
return phy && test_bit(MT76_STATE_RUNNING, &phy->mt76->state);
|
||||
}
|
||||
|
||||
static void mt7615_free_pending_tx_skbs(struct mt7615_dev *dev,
|
||||
struct mt7615_sta *msta)
|
||||
{
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&dev->pm.txq_lock);
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||
if (msta && dev->pm.tx_q[i].msta != msta)
|
||||
continue;
|
||||
|
||||
dev_kfree_skb(dev->pm.tx_q[i].skb);
|
||||
dev->pm.tx_q[i].skb = NULL;
|
||||
}
|
||||
spin_unlock_bh(&dev->pm.txq_lock);
|
||||
}
|
||||
|
||||
static int mt7615_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
|
|
@ -55,22 +39,24 @@ static int mt7615_start(struct ieee80211_hw *hw)
|
|||
|
||||
if (!running) {
|
||||
mt7615_mcu_set_pm(dev, 0, 0);
|
||||
mt7615_mcu_set_mac_enable(dev, 0, true);
|
||||
mt76_connac_mcu_set_mac_enable(&dev->mt76, 0, true, false);
|
||||
mt7615_mac_enable_nf(dev, 0);
|
||||
}
|
||||
|
||||
if (phy != &dev->phy) {
|
||||
mt7615_mcu_set_pm(dev, 1, 0);
|
||||
mt7615_mcu_set_mac_enable(dev, 1, true);
|
||||
mt76_connac_mcu_set_mac_enable(&dev->mt76, 1, true, false);
|
||||
mt7615_mac_enable_nf(dev, 1);
|
||||
}
|
||||
|
||||
mt7615_mcu_set_channel_domain(phy);
|
||||
if (mt7615_firmware_offload(dev))
|
||||
mt76_connac_mcu_set_channel_domain(phy->mt76);
|
||||
|
||||
mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
|
||||
|
||||
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
|
||||
|
||||
ieee80211_queue_delayed_work(hw, &phy->mac_work,
|
||||
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
|
||||
MT7615_WATCHDOG_TIME);
|
||||
|
||||
if (!running)
|
||||
|
|
@ -86,30 +72,30 @@ static void mt7615_stop(struct ieee80211_hw *hw)
|
|||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
struct mt7615_phy *phy = mt7615_hw_phy(hw);
|
||||
|
||||
cancel_delayed_work_sync(&phy->mac_work);
|
||||
cancel_delayed_work_sync(&phy->mt76->mac_work);
|
||||
del_timer_sync(&phy->roc_timer);
|
||||
cancel_work_sync(&phy->roc_work);
|
||||
|
||||
cancel_delayed_work_sync(&dev->pm.ps_work);
|
||||
cancel_work_sync(&dev->pm.wake_work);
|
||||
|
||||
mt7615_free_pending_tx_skbs(dev, NULL);
|
||||
mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
|
||||
mt76_testmode_reset(&dev->mt76, true);
|
||||
mt76_testmode_reset(phy->mt76, true);
|
||||
|
||||
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
|
||||
cancel_delayed_work_sync(&phy->scan_work);
|
||||
|
||||
if (phy != &dev->phy) {
|
||||
mt7615_mcu_set_pm(dev, 1, 1);
|
||||
mt7615_mcu_set_mac_enable(dev, 1, false);
|
||||
mt76_connac_mcu_set_mac_enable(&dev->mt76, 1, false, false);
|
||||
}
|
||||
|
||||
if (!mt7615_dev_running(dev)) {
|
||||
mt7615_mcu_set_pm(dev, 0, 1);
|
||||
mt7615_mcu_set_mac_enable(dev, 0, false);
|
||||
mt76_connac_mcu_set_mac_enable(&dev->mt76, 0, false, false);
|
||||
}
|
||||
|
||||
mt7615_mutex_release(dev);
|
||||
|
|
@ -181,14 +167,14 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
|
|||
|
||||
mt7615_mutex_acquire(dev);
|
||||
|
||||
mt76_testmode_reset(&dev->mt76, true);
|
||||
mt76_testmode_reset(phy->mt76, true);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR &&
|
||||
is_zero_ether_addr(vif->addr))
|
||||
phy->monitor_vif = vif;
|
||||
|
||||
mvif->idx = ffs(~dev->mphy.vif_mask) - 1;
|
||||
if (mvif->idx >= MT7615_MAX_INTERFACES) {
|
||||
mvif->mt76.idx = ffs(~dev->mt76.vif_mask) - 1;
|
||||
if (mvif->mt76.idx >= MT7615_MAX_INTERFACES) {
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -198,26 +184,26 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
|
|||
ret = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
mvif->omac_idx = idx;
|
||||
mvif->mt76.omac_idx = idx;
|
||||
|
||||
mvif->band_idx = ext_phy;
|
||||
mvif->mt76.band_idx = ext_phy;
|
||||
if (mt7615_ext_phy(dev))
|
||||
mvif->wmm_idx = ext_phy * (MT7615_MAX_WMM_SETS / 2) +
|
||||
mvif->idx % (MT7615_MAX_WMM_SETS / 2);
|
||||
mvif->mt76.wmm_idx = ext_phy * (MT7615_MAX_WMM_SETS / 2) +
|
||||
mvif->mt76.idx % (MT7615_MAX_WMM_SETS / 2);
|
||||
else
|
||||
mvif->wmm_idx = mvif->idx % MT7615_MAX_WMM_SETS;
|
||||
mvif->mt76.wmm_idx = mvif->mt76.idx % MT7615_MAX_WMM_SETS;
|
||||
|
||||
dev->mphy.vif_mask |= BIT(mvif->idx);
|
||||
dev->omac_mask |= BIT_ULL(mvif->omac_idx);
|
||||
phy->omac_mask |= BIT_ULL(mvif->omac_idx);
|
||||
dev->mt76.vif_mask |= BIT(mvif->mt76.idx);
|
||||
dev->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
|
||||
phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
|
||||
|
||||
mt7615_mcu_set_dbdc(dev);
|
||||
|
||||
idx = MT7615_WTBL_RESERVED - mvif->idx;
|
||||
idx = MT7615_WTBL_RESERVED - mvif->mt76.idx;
|
||||
|
||||
INIT_LIST_HEAD(&mvif->sta.poll_list);
|
||||
mvif->sta.wcid.idx = idx;
|
||||
mvif->sta.wcid.ext_phy = mvif->band_idx;
|
||||
mvif->sta.wcid.ext_phy = mvif->mt76.band_idx;
|
||||
mvif->sta.wcid.hw_key_idx = -1;
|
||||
mt7615_mac_wtbl_update(dev, idx,
|
||||
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
|
||||
|
|
@ -228,7 +214,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
|
|||
mtxq->wcid = &mvif->sta.wcid;
|
||||
}
|
||||
|
||||
ret = mt7615_mcu_add_dev_info(dev, vif, true);
|
||||
ret = mt7615_mcu_add_dev_info(phy, vif, true);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
|
@ -252,20 +238,20 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,
|
|||
|
||||
mt7615_mutex_acquire(dev);
|
||||
|
||||
mt76_testmode_reset(&dev->mt76, true);
|
||||
mt76_testmode_reset(phy->mt76, true);
|
||||
if (vif == phy->monitor_vif)
|
||||
phy->monitor_vif = NULL;
|
||||
|
||||
mt7615_free_pending_tx_skbs(dev, msta);
|
||||
mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->wcid);
|
||||
|
||||
mt7615_mac_set_beacon_filter(phy, vif, false);
|
||||
mt7615_mcu_add_dev_info(dev, vif, false);
|
||||
mt7615_mcu_add_dev_info(phy, vif, false);
|
||||
|
||||
rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
|
||||
|
||||
dev->mphy.vif_mask &= ~BIT(mvif->idx);
|
||||
dev->omac_mask &= ~BIT_ULL(mvif->omac_idx);
|
||||
phy->omac_mask &= ~BIT_ULL(mvif->omac_idx);
|
||||
dev->mt76.vif_mask &= ~BIT(mvif->mt76.idx);
|
||||
dev->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
|
||||
phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx);
|
||||
|
||||
mt7615_mutex_release(dev);
|
||||
|
||||
|
|
@ -300,7 +286,7 @@ int mt7615_set_channel(struct mt7615_phy *phy)
|
|||
bool ext_phy = phy != &dev->phy;
|
||||
int ret;
|
||||
|
||||
cancel_delayed_work_sync(&phy->mac_work);
|
||||
cancel_delayed_work_sync(&phy->mt76->mac_work);
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
|
||||
|
|
@ -321,7 +307,7 @@ int mt7615_set_channel(struct mt7615_phy *phy)
|
|||
mt7615_mac_set_timing(phy);
|
||||
ret = mt7615_dfs_init_radar_detector(phy);
|
||||
mt7615_mac_cca_stats_reset(phy);
|
||||
mt7615_mcu_set_sku_en(phy, !mt76_testmode_enabled(&dev->mt76));
|
||||
mt7615_mcu_set_sku_en(phy, true);
|
||||
|
||||
mt7615_mac_reset_counters(dev);
|
||||
phy->noise = 0;
|
||||
|
|
@ -334,8 +320,9 @@ int mt7615_set_channel(struct mt7615_phy *phy)
|
|||
|
||||
mt76_txq_schedule_all(phy->mt76);
|
||||
|
||||
if (!mt76_testmode_enabled(&dev->mt76))
|
||||
ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
|
||||
if (!mt76_testmode_enabled(phy->mt76))
|
||||
ieee80211_queue_delayed_work(phy->mt76->hw,
|
||||
&phy->mt76->mac_work,
|
||||
MT7615_WATCHDOG_TIME);
|
||||
|
||||
return ret;
|
||||
|
|
@ -411,9 +398,9 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
|
|||
if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
|
||||
IEEE80211_CONF_CHANGE_POWER)) {
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
if (dev->mt76.test.state != MT76_TM_STATE_OFF) {
|
||||
if (phy->mt76->test.state != MT76_TM_STATE_OFF) {
|
||||
mt7615_mutex_acquire(dev);
|
||||
mt76_testmode_reset(&dev->mt76, false);
|
||||
mt76_testmode_reset(phy->mt76, false);
|
||||
mt7615_mutex_release(dev);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -425,7 +412,7 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
|
|||
mt7615_mutex_acquire(dev);
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
|
||||
mt76_testmode_reset(&dev->mt76, true);
|
||||
mt76_testmode_reset(phy->mt76, true);
|
||||
|
||||
if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
|
||||
phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
|
||||
|
|
@ -444,7 +431,7 @@ static int
|
|||
mt7615_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
int err;
|
||||
|
||||
|
|
@ -480,7 +467,7 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
|
|||
#define MT76_FILTER(_flag, _hw) do { \
|
||||
flags |= *total_flags & FIF_##_flag; \
|
||||
phy->rxfilter &= ~(_hw); \
|
||||
if (!mt76_testmode_enabled(&dev->mt76)) \
|
||||
if (!mt76_testmode_enabled(phy->mt76)) \
|
||||
phy->rxfilter |= !(flags & FIF_##_flag) * (_hw);\
|
||||
} while (0)
|
||||
|
||||
|
|
@ -541,7 +528,7 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
|
|||
|
||||
if (changed & BSS_CHANGED_BEACON_ENABLED) {
|
||||
mt7615_mcu_add_bss_info(phy, vif, NULL, info->enable_beacon);
|
||||
mt7615_mcu_sta_add(dev, vif, NULL, info->enable_beacon);
|
||||
mt7615_mcu_sta_add(phy, vif, NULL, info->enable_beacon);
|
||||
|
||||
if (vif->p2p && info->enable_beacon)
|
||||
mt7615_mcu_set_p2p_oppps(hw, vif);
|
||||
|
|
@ -552,7 +539,7 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
|
|||
mt7615_mcu_add_beacon(dev, hw, vif, info->enable_beacon);
|
||||
|
||||
if (changed & BSS_CHANGED_PS)
|
||||
mt7615_mcu_set_vif_ps(dev, vif);
|
||||
mt76_connac_mcu_set_vif_ps(&dev->mt76, vif);
|
||||
|
||||
if (changed & BSS_CHANGED_ARP_FILTER)
|
||||
mt7615_mcu_update_arp_filter(hw, vif, info);
|
||||
|
|
@ -578,6 +565,7 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
|
|||
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
|
||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||
struct mt7615_phy *phy;
|
||||
int idx, err;
|
||||
|
||||
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
|
||||
|
|
@ -588,23 +576,20 @@ int mt7615_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->band_idx;
|
||||
msta->wcid.ext_phy = mvif->mt76.band_idx;
|
||||
|
||||
err = mt7615_pm_wake(dev);
|
||||
phy = mvif->mt76.band_idx ? mt7615_ext_phy(dev) : &dev->phy;
|
||||
err = mt76_connac_pm_wake(phy->mt76, &dev->pm);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
|
||||
struct mt7615_phy *phy;
|
||||
|
||||
phy = mvif->band_idx ? mt7615_ext_phy(dev) : &dev->phy;
|
||||
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
|
||||
mt7615_mcu_add_bss_info(phy, vif, sta, true);
|
||||
}
|
||||
mt7615_mac_wtbl_update(dev, idx,
|
||||
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
|
||||
mt7615_mcu_sta_add(dev, vif, sta, true);
|
||||
mt7615_mcu_sta_add(&dev->phy, vif, sta, true);
|
||||
|
||||
mt7615_pm_power_save_sched(dev);
|
||||
mt76_connac_power_save_sched(phy->mt76, &dev->pm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -615,27 +600,26 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
|
|||
{
|
||||
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||
struct mt7615_sta *msta = (struct mt7615_sta *)sta->drv_priv;
|
||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||
struct mt7615_phy *phy;
|
||||
|
||||
mt7615_free_pending_tx_skbs(dev, msta);
|
||||
mt7615_pm_wake(dev);
|
||||
mt76_connac_free_pending_tx_skbs(&dev->pm, &msta->wcid);
|
||||
|
||||
mt7615_mcu_sta_add(dev, vif, sta, false);
|
||||
phy = mvif->mt76.band_idx ? mt7615_ext_phy(dev) : &dev->phy;
|
||||
mt76_connac_pm_wake(phy->mt76, &dev->pm);
|
||||
|
||||
mt7615_mcu_sta_add(&dev->phy, vif, sta, false);
|
||||
mt7615_mac_wtbl_update(dev, msta->wcid.idx,
|
||||
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
|
||||
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
|
||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||
struct mt7615_phy *phy;
|
||||
|
||||
phy = mvif->band_idx ? mt7615_ext_phy(dev) : &dev->phy;
|
||||
if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
|
||||
mt7615_mcu_add_bss_info(phy, vif, sta, false);
|
||||
}
|
||||
|
||||
spin_lock_bh(&dev->sta_poll_lock);
|
||||
if (!list_empty(&msta->poll_list))
|
||||
list_del_init(&msta->poll_list);
|
||||
spin_unlock_bh(&dev->sta_poll_lock);
|
||||
|
||||
mt7615_pm_power_save_sched(dev);
|
||||
mt76_connac_power_save_sched(phy->mt76, &dev->pm);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt7615_mac_sta_remove);
|
||||
|
||||
|
|
@ -720,25 +704,17 @@ static void mt7615_tx(struct ieee80211_hw *hw,
|
|||
skb_set_queue_mapping(skb, qid);
|
||||
}
|
||||
|
||||
spin_lock_bh(&dev->pm.txq_lock);
|
||||
if (!dev->pm.tx_q[qid].skb) {
|
||||
ieee80211_stop_queues(hw);
|
||||
dev->pm.tx_q[qid].msta = msta;
|
||||
dev->pm.tx_q[qid].skb = skb;
|
||||
queue_work(dev->mt76.wq, &dev->pm.wake_work);
|
||||
} else {
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
spin_unlock_bh(&dev->pm.txq_lock);
|
||||
mt76_connac_pm_queue_skb(hw, &dev->pm, wcid, skb);
|
||||
}
|
||||
|
||||
static int mt7615_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
|
||||
{
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
struct mt7615_phy *phy = mt7615_hw_phy(hw);
|
||||
int band = phy != &dev->phy;
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
mt7615_mcu_set_rts_thresh(phy, val);
|
||||
mt76_connac_mcu_set_rts_thresh(&dev->mt76, val, band);
|
||||
mt7615_mutex_release(dev);
|
||||
|
||||
return 0;
|
||||
|
|
@ -910,7 +886,7 @@ mt7615_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
|||
else
|
||||
tx_ant <<= 1;
|
||||
}
|
||||
phy->chainmask = tx_ant;
|
||||
phy->mt76->chainmask = tx_ant;
|
||||
|
||||
mt76_set_stream_caps(phy->mt76, true);
|
||||
|
||||
|
|
@ -993,8 +969,12 @@ mt7615_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
struct mt76_phy *mphy = hw->priv;
|
||||
int err;
|
||||
|
||||
/* fall-back to sw-scan */
|
||||
if (!mt7615_firmware_offload(dev))
|
||||
return 1;
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
err = mt7615_mcu_hw_scan(mphy->priv, vif, req);
|
||||
err = mt76_connac_mcu_hw_scan(mphy, vif, req);
|
||||
mt7615_mutex_release(dev);
|
||||
|
||||
return err;
|
||||
|
|
@ -1007,7 +987,7 @@ mt7615_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|||
struct mt76_phy *mphy = hw->priv;
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
mt7615_mcu_cancel_hw_scan(mphy->priv, vif);
|
||||
mt76_connac_mcu_cancel_hw_scan(mphy, vif);
|
||||
mt7615_mutex_release(dev);
|
||||
}
|
||||
|
||||
|
|
@ -1020,13 +1000,16 @@ mt7615_start_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
struct mt76_phy *mphy = hw->priv;
|
||||
int err;
|
||||
|
||||
if (!mt7615_firmware_offload(dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
|
||||
err = mt7615_mcu_sched_scan_req(mphy->priv, vif, req);
|
||||
err = mt76_connac_mcu_sched_scan_req(mphy, vif, req);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
err = mt7615_mcu_sched_scan_enable(mphy->priv, vif, true);
|
||||
err = mt76_connac_mcu_sched_scan_enable(mphy, vif, true);
|
||||
out:
|
||||
mt7615_mutex_release(dev);
|
||||
|
||||
|
|
@ -1040,8 +1023,11 @@ mt7615_stop_sched_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|||
struct mt76_phy *mphy = hw->priv;
|
||||
int err;
|
||||
|
||||
if (!mt7615_firmware_offload(dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
err = mt7615_mcu_sched_scan_enable(mphy->priv, vif, false);
|
||||
err = mt76_connac_mcu_sched_scan_enable(mphy, vif, false);
|
||||
mt7615_mutex_release(dev);
|
||||
|
||||
return err;
|
||||
|
|
@ -1101,26 +1087,27 @@ static int mt7615_cancel_remain_on_channel(struct ieee80211_hw *hw,
|
|||
static int mt7615_suspend(struct ieee80211_hw *hw,
|
||||
struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
struct mt7615_phy *phy = mt7615_hw_phy(hw);
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
int err = 0;
|
||||
|
||||
cancel_delayed_work_sync(&dev->pm.ps_work);
|
||||
mt7615_free_pending_tx_skbs(dev, NULL);
|
||||
mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
|
||||
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
|
||||
cancel_delayed_work_sync(&phy->scan_work);
|
||||
cancel_delayed_work_sync(&phy->mac_work);
|
||||
cancel_delayed_work_sync(&phy->mt76->mac_work);
|
||||
|
||||
set_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
|
||||
ieee80211_iterate_active_interfaces(hw,
|
||||
IEEE80211_IFACE_ITER_RESUME_ALL,
|
||||
mt7615_mcu_set_suspend_iter, phy);
|
||||
mt76_connac_mcu_set_suspend_iter,
|
||||
phy->mt76);
|
||||
|
||||
if (!mt7615_dev_running(dev))
|
||||
err = mt7615_mcu_set_hif_suspend(dev, true);
|
||||
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
|
||||
|
||||
mt7615_mutex_release(dev);
|
||||
|
||||
|
|
@ -1129,8 +1116,8 @@ static int mt7615_suspend(struct ieee80211_hw *hw,
|
|||
|
||||
static int mt7615_resume(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
struct mt7615_phy *phy = mt7615_hw_phy(hw);
|
||||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
bool running;
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
|
|
@ -1141,7 +1128,7 @@ static int mt7615_resume(struct ieee80211_hw *hw)
|
|||
if (!running) {
|
||||
int err;
|
||||
|
||||
err = mt7615_mcu_set_hif_suspend(dev, false);
|
||||
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
|
||||
if (err < 0) {
|
||||
mt7615_mutex_release(dev);
|
||||
return err;
|
||||
|
|
@ -1151,9 +1138,10 @@ static int mt7615_resume(struct ieee80211_hw *hw)
|
|||
clear_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
|
||||
ieee80211_iterate_active_interfaces(hw,
|
||||
IEEE80211_IFACE_ITER_RESUME_ALL,
|
||||
mt7615_mcu_set_suspend_iter, phy);
|
||||
mt76_connac_mcu_set_suspend_iter,
|
||||
phy->mt76);
|
||||
|
||||
ieee80211_queue_delayed_work(hw, &phy->mac_work,
|
||||
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
|
||||
MT7615_WATCHDOG_TIME);
|
||||
|
||||
mt7615_mutex_release(dev);
|
||||
|
|
@ -1176,7 +1164,7 @@ static void mt7615_set_rekey_data(struct ieee80211_hw *hw,
|
|||
struct mt7615_dev *dev = mt7615_hw_dev(hw);
|
||||
|
||||
mt7615_mutex_acquire(dev);
|
||||
mt7615_mcu_update_gtk_rekey(hw, vif, data);
|
||||
mt76_connac_mcu_update_gtk_rekey(hw, vif, data);
|
||||
mt7615_mutex_release(dev);
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -4,6 +4,8 @@
|
|||
#ifndef __MT7615_MCU_H
|
||||
#define __MT7615_MCU_H
|
||||
|
||||
#include "../mt76_connac_mcu.h"
|
||||
|
||||
struct mt7615_mcu_txd {
|
||||
__le32 txd[8];
|
||||
|
||||
|
|
@ -90,6 +92,7 @@ enum {
|
|||
MCU_EVENT_SCHED_SCAN_DONE = 0x23,
|
||||
MCU_EVENT_EXT = 0xed,
|
||||
MCU_EVENT_RESTART_DL = 0xef,
|
||||
MCU_EVENT_COREDUMP = 0xf0,
|
||||
};
|
||||
|
||||
/* ext event table */
|
||||
|
|
@ -236,64 +239,6 @@ enum {
|
|||
MCU_S2D_H2CN
|
||||
};
|
||||
|
||||
#define MCU_FW_PREFIX BIT(31)
|
||||
#define MCU_UNI_PREFIX BIT(30)
|
||||
#define MCU_CE_PREFIX BIT(29)
|
||||
#define MCU_QUERY_PREFIX BIT(28)
|
||||
#define MCU_CMD_MASK ~(MCU_FW_PREFIX | MCU_UNI_PREFIX | \
|
||||
MCU_CE_PREFIX | MCU_QUERY_PREFIX)
|
||||
|
||||
#define MCU_QUERY_MASK BIT(16)
|
||||
|
||||
enum {
|
||||
MCU_CMD_TARGET_ADDRESS_LEN_REQ = MCU_FW_PREFIX | 0x01,
|
||||
MCU_CMD_FW_START_REQ = MCU_FW_PREFIX | 0x02,
|
||||
MCU_CMD_INIT_ACCESS_REG = 0x3,
|
||||
MCU_CMD_PATCH_START_REQ = 0x05,
|
||||
MCU_CMD_PATCH_FINISH_REQ = MCU_FW_PREFIX | 0x07,
|
||||
MCU_CMD_PATCH_SEM_CONTROL = MCU_FW_PREFIX | 0x10,
|
||||
MCU_CMD_EXT_CID = 0xED,
|
||||
MCU_CMD_FW_SCATTER = MCU_FW_PREFIX | 0xEE,
|
||||
MCU_CMD_RESTART_DL_REQ = MCU_FW_PREFIX | 0xEF,
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_EXT_CMD_RF_REG_ACCESS = 0x02,
|
||||
MCU_EXT_CMD_PM_STATE_CTRL = 0x07,
|
||||
MCU_EXT_CMD_CHANNEL_SWITCH = 0x08,
|
||||
MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11,
|
||||
MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
|
||||
MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
|
||||
MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
|
||||
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
|
||||
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
|
||||
MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
|
||||
MCU_EXT_CMD_GET_TEMP = 0x2c,
|
||||
MCU_EXT_CMD_WTBL_UPDATE = 0x32,
|
||||
MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
|
||||
MCU_EXT_CMD_ATE_CTRL = 0x3d,
|
||||
MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
|
||||
MCU_EXT_CMD_DBDC_CTRL = 0x45,
|
||||
MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
|
||||
MCU_EXT_CMD_MUAR_UPDATE = 0x48,
|
||||
MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
|
||||
MCU_EXT_CMD_SET_RX_PATH = 0x4e,
|
||||
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
|
||||
MCU_EXT_CMD_RXDCOC_CAL = 0x59,
|
||||
MCU_EXT_CMD_TXDPD_CAL = 0x60,
|
||||
MCU_EXT_CMD_SET_RDD_TH = 0x7c,
|
||||
MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_UNI_CMD_DEV_INFO_UPDATE = MCU_UNI_PREFIX | 0x01,
|
||||
MCU_UNI_CMD_BSS_INFO_UPDATE = MCU_UNI_PREFIX | 0x02,
|
||||
MCU_UNI_CMD_STA_REC_UPDATE = MCU_UNI_PREFIX | 0x03,
|
||||
MCU_UNI_CMD_SUSPEND = MCU_UNI_PREFIX | 0x05,
|
||||
MCU_UNI_CMD_OFFLOAD = MCU_UNI_PREFIX | 0x06,
|
||||
MCU_UNI_CMD_HIF_CTRL = MCU_UNI_PREFIX | 0x07,
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_ATE_SET_FREQ_OFFSET = 0xa,
|
||||
MCU_ATE_SET_TX_POWER_CONTROL = 0x15,
|
||||
|
|
@ -305,269 +250,11 @@ struct mt7615_mcu_uni_event {
|
|||
__le32 status; /* 0: success, others: fail */
|
||||
} __packed;
|
||||
|
||||
struct mt7615_beacon_loss_event {
|
||||
u8 bss_idx;
|
||||
u8 reason;
|
||||
u8 pad[2];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_mcu_scan_ssid {
|
||||
__le32 ssid_len;
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_mcu_scan_channel {
|
||||
u8 band; /* 1: 2.4GHz
|
||||
* 2: 5.0GHz
|
||||
* Others: Reserved
|
||||
*/
|
||||
u8 channel_num;
|
||||
} __packed;
|
||||
|
||||
struct mt7615_mcu_scan_match {
|
||||
__le32 rssi_th;
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
u8 ssid_len;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_hw_scan_req {
|
||||
u8 seq_num;
|
||||
u8 bss_idx;
|
||||
u8 scan_type; /* 0: PASSIVE SCAN
|
||||
* 1: ACTIVE SCAN
|
||||
*/
|
||||
u8 ssid_type; /* BIT(0) wildcard SSID
|
||||
* BIT(1) P2P wildcard SSID
|
||||
* BIT(2) specified SSID + wildcard SSID
|
||||
* BIT(2) + ssid_type_ext BIT(0) specified SSID only
|
||||
*/
|
||||
u8 ssids_num;
|
||||
u8 probe_req_num; /* Number of probe request for each SSID */
|
||||
u8 scan_func; /* BIT(0) Enable random MAC scan
|
||||
* BIT(1) Disable DBDC scan type 1~3.
|
||||
* BIT(2) Use DBDC scan type 3 (dedicated one RF to scan).
|
||||
*/
|
||||
u8 version; /* 0: Not support fields after ies.
|
||||
* 1: Support fields after ies.
|
||||
*/
|
||||
struct mt7615_mcu_scan_ssid ssids[4];
|
||||
__le16 probe_delay_time;
|
||||
__le16 channel_dwell_time; /* channel Dwell interval */
|
||||
__le16 timeout_value;
|
||||
u8 channel_type; /* 0: Full channels
|
||||
* 1: Only 2.4GHz channels
|
||||
* 2: Only 5GHz channels
|
||||
* 3: P2P social channel only (channel #1, #6 and #11)
|
||||
* 4: Specified channels
|
||||
* Others: Reserved
|
||||
*/
|
||||
u8 channels_num; /* valid when channel_type is 4 */
|
||||
/* valid when channels_num is set */
|
||||
struct mt7615_mcu_scan_channel channels[32];
|
||||
__le16 ies_len;
|
||||
u8 ies[MT7615_SCAN_IE_LEN];
|
||||
/* following fields are valid if version > 0 */
|
||||
u8 ext_channels_num;
|
||||
u8 ext_ssids_num;
|
||||
__le16 channel_min_dwell_time;
|
||||
struct mt7615_mcu_scan_channel ext_channels[32];
|
||||
struct mt7615_mcu_scan_ssid ext_ssids[6];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 random_mac[ETH_ALEN]; /* valid when BIT(1) in scan_func is set. */
|
||||
u8 pad[63];
|
||||
u8 ssid_type_ext;
|
||||
} __packed;
|
||||
|
||||
#define SCAN_DONE_EVENT_MAX_CHANNEL_NUM 64
|
||||
struct mt7615_hw_scan_done {
|
||||
u8 seq_num;
|
||||
u8 sparse_channel_num;
|
||||
struct mt7615_mcu_scan_channel sparse_channel;
|
||||
u8 complete_channel_num;
|
||||
u8 current_state;
|
||||
u8 version;
|
||||
u8 pad;
|
||||
__le32 beacon_scan_num;
|
||||
u8 pno_enabled;
|
||||
u8 pad2[3];
|
||||
u8 sparse_channel_valid_num;
|
||||
u8 pad3[3];
|
||||
u8 channel_num[SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
|
||||
/* idle format for channel_idle_time
|
||||
* 0: first bytes: idle time(ms) 2nd byte: dwell time(ms)
|
||||
* 1: first bytes: idle time(8ms) 2nd byte: dwell time(8ms)
|
||||
* 2: dwell time (16us)
|
||||
*/
|
||||
__le16 channel_idle_time[SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
|
||||
/* beacon and probe response count */
|
||||
u8 beacon_probe_num[SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
|
||||
u8 mdrdy_count[SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
|
||||
__le32 beacon_2g_num;
|
||||
__le32 beacon_5g_num;
|
||||
} __packed;
|
||||
|
||||
struct mt7615_sched_scan_req {
|
||||
u8 version;
|
||||
u8 seq_num;
|
||||
u8 stop_on_match;
|
||||
u8 ssids_num;
|
||||
u8 match_num;
|
||||
u8 pad;
|
||||
__le16 ie_len;
|
||||
struct mt7615_mcu_scan_ssid ssids[MT7615_MAX_SCHED_SCAN_SSID];
|
||||
struct mt7615_mcu_scan_match match[MT7615_MAX_SCAN_MATCH];
|
||||
u8 channel_type;
|
||||
u8 channels_num;
|
||||
u8 intervals_num;
|
||||
u8 scan_func; /* BIT(0) eable random mac address */
|
||||
struct mt7615_mcu_scan_channel channels[64];
|
||||
__le16 intervals[MT7615_MAX_SCHED_SCAN_INTERVAL];
|
||||
u8 random_mac[ETH_ALEN]; /* valid when BIT(0) in scan_func is set */
|
||||
u8 pad2[58];
|
||||
} __packed;
|
||||
|
||||
struct nt7615_sched_scan_done {
|
||||
u8 seq_num;
|
||||
u8 status; /* 0: ssid found */
|
||||
__le16 pad;
|
||||
} __packed;
|
||||
|
||||
struct mt7615_mcu_reg_event {
|
||||
__le32 reg;
|
||||
__le32 val;
|
||||
} __packed;
|
||||
|
||||
struct mt7615_mcu_bss_event {
|
||||
u8 bss_idx;
|
||||
u8 is_absent;
|
||||
u8 free_quota;
|
||||
u8 pad;
|
||||
} __packed;
|
||||
|
||||
struct mt7615_bss_basic_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 active;
|
||||
u8 omac_idx;
|
||||
u8 hw_bss_idx;
|
||||
u8 band_idx;
|
||||
__le32 conn_type;
|
||||
u8 conn_state;
|
||||
u8 wmm_idx;
|
||||
u8 bssid[ETH_ALEN];
|
||||
__le16 bmc_tx_wlan_idx;
|
||||
__le16 bcn_interval;
|
||||
u8 dtim_period;
|
||||
u8 phymode; /* bit(0): A
|
||||
* bit(1): B
|
||||
* bit(2): G
|
||||
* bit(3): GN
|
||||
* bit(4): AN
|
||||
* bit(5): AC
|
||||
*/
|
||||
__le16 sta_idx;
|
||||
u8 nonht_basic_phy;
|
||||
u8 pad[3];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_bss_qos_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 qos;
|
||||
u8 pad[3];
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
WOW_USB = 1,
|
||||
WOW_PCIE = 2,
|
||||
WOW_GPIO = 3,
|
||||
};
|
||||
|
||||
struct mt7615_wow_ctrl_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 cmd; /* 0x1: PM_WOWLAN_REQ_START
|
||||
* 0x2: PM_WOWLAN_REQ_STOP
|
||||
* 0x3: PM_WOWLAN_PARAM_CLEAR
|
||||
*/
|
||||
u8 trigger; /* 0: NONE
|
||||
* BIT(0): NL80211_WOWLAN_TRIG_MAGIC_PKT
|
||||
* BIT(1): NL80211_WOWLAN_TRIG_ANY
|
||||
* BIT(2): NL80211_WOWLAN_TRIG_DISCONNECT
|
||||
* BIT(3): NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE
|
||||
* BIT(4): BEACON_LOST
|
||||
* BIT(5): NL80211_WOWLAN_TRIG_NET_DETECT
|
||||
*/
|
||||
u8 wakeup_hif; /* 0x0: HIF_SDIO
|
||||
* 0x1: HIF_USB
|
||||
* 0x2: HIF_PCIE
|
||||
* 0x3: HIF_GPIO
|
||||
*/
|
||||
u8 pad;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_wow_gpio_param_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 gpio_pin;
|
||||
u8 trigger_lvl;
|
||||
u8 pad[2];
|
||||
__le32 gpio_interval;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
#define MT7615_WOW_MASK_MAX_LEN 16
|
||||
#define MT7615_WOW_PATTEN_MAX_LEN 128
|
||||
struct mt7615_wow_pattern_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 index; /* pattern index */
|
||||
u8 enable; /* 0: disable
|
||||
* 1: enable
|
||||
*/
|
||||
u8 data_len; /* pattern length */
|
||||
u8 pad;
|
||||
u8 mask[MT7615_WOW_MASK_MAX_LEN];
|
||||
u8 pattern[MT7615_WOW_PATTEN_MAX_LEN];
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_suspend_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 enable; /* 0: suspend mode disabled
|
||||
* 1: suspend mode enabled
|
||||
*/
|
||||
u8 mdtim; /* LP parameter */
|
||||
u8 wow_suspend; /* 0: update by origin policy
|
||||
* 1: update by wow dtim
|
||||
*/
|
||||
u8 pad[5];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_gtk_rekey_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 kek[NL80211_KEK_LEN];
|
||||
u8 kck[NL80211_KCK_LEN];
|
||||
u8 replay_ctr[NL80211_REPLAY_CTR_LEN];
|
||||
u8 rekey_mode; /* 0: rekey offload enable
|
||||
* 1: rekey offload disable
|
||||
* 2: rekey update
|
||||
*/
|
||||
u8 keyid;
|
||||
u8 pad[2];
|
||||
__le32 proto; /* WPA-RSN-WAPI-OPSN */
|
||||
__le32 pairwise_cipher;
|
||||
__le32 group_cipher;
|
||||
__le32 key_mgmt; /* NONE-PSK-IEEE802.1X */
|
||||
__le32 mgmt_group_cipher;
|
||||
u8 option; /* 1: rekey data update without enabling offload */
|
||||
u8 reserverd[3];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_roc_tlv {
|
||||
u8 bss_idx;
|
||||
u8 token;
|
||||
|
|
@ -585,65 +272,6 @@ struct mt7615_roc_tlv {
|
|||
u8 rsv1[8];
|
||||
} __packed;
|
||||
|
||||
struct mt7615_arpns_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 mode;
|
||||
u8 ips_num;
|
||||
u8 option;
|
||||
u8 pad[1];
|
||||
} __packed;
|
||||
|
||||
/* offload mcu commands */
|
||||
enum {
|
||||
MCU_CMD_START_HW_SCAN = MCU_CE_PREFIX | 0x03,
|
||||
MCU_CMD_SET_PS_PROFILE = MCU_CE_PREFIX | 0x05,
|
||||
MCU_CMD_SET_CHAN_DOMAIN = MCU_CE_PREFIX | 0x0f,
|
||||
MCU_CMD_SET_BSS_CONNECTED = MCU_CE_PREFIX | 0x16,
|
||||
MCU_CMD_SET_BSS_ABORT = MCU_CE_PREFIX | 0x17,
|
||||
MCU_CMD_CANCEL_HW_SCAN = MCU_CE_PREFIX | 0x1b,
|
||||
MCU_CMD_SET_ROC = MCU_CE_PREFIX | 0x1c,
|
||||
MCU_CMD_SET_P2P_OPPPS = MCU_CE_PREFIX | 0x33,
|
||||
MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61,
|
||||
MCU_CMD_SCHED_SCAN_REQ = MCU_CE_PREFIX | 0x62,
|
||||
MCU_CMD_REG_WRITE = MCU_CE_PREFIX | 0xc0,
|
||||
MCU_CMD_REG_READ = MCU_CE_PREFIX | MCU_QUERY_MASK | 0xc0,
|
||||
};
|
||||
|
||||
#define MCU_CMD_ACK BIT(0)
|
||||
#define MCU_CMD_UNI BIT(1)
|
||||
#define MCU_CMD_QUERY BIT(2)
|
||||
|
||||
#define MCU_CMD_UNI_EXT_ACK (MCU_CMD_ACK | MCU_CMD_UNI | MCU_CMD_QUERY)
|
||||
|
||||
enum {
|
||||
UNI_BSS_INFO_BASIC = 0,
|
||||
UNI_BSS_INFO_RLM = 2,
|
||||
UNI_BSS_INFO_BCN_CONTENT = 7,
|
||||
UNI_BSS_INFO_QBSS = 15,
|
||||
UNI_BSS_INFO_UAPSD = 19,
|
||||
};
|
||||
|
||||
enum {
|
||||
UNI_SUSPEND_MODE_SETTING,
|
||||
UNI_SUSPEND_WOW_CTRL,
|
||||
UNI_SUSPEND_WOW_GPIO_PARAM,
|
||||
UNI_SUSPEND_WOW_WAKEUP_PORT,
|
||||
UNI_SUSPEND_WOW_PATTERN,
|
||||
};
|
||||
|
||||
enum {
|
||||
UNI_OFFLOAD_OFFLOAD_ARP,
|
||||
UNI_OFFLOAD_OFFLOAD_ND,
|
||||
UNI_OFFLOAD_OFFLOAD_GTK_REKEY,
|
||||
UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
|
||||
};
|
||||
|
||||
enum {
|
||||
PATCH_SEM_RELEASE = 0x0,
|
||||
PATCH_SEM_GET = 0x1
|
||||
};
|
||||
|
||||
enum {
|
||||
PATCH_NOT_DL_SEM_FAIL = 0x0,
|
||||
PATCH_IS_DL = 0x1,
|
||||
|
|
@ -664,34 +292,6 @@ enum {
|
|||
FW_STATE_N9_RDY = 2,
|
||||
};
|
||||
|
||||
#define STA_TYPE_STA BIT(0)
|
||||
#define STA_TYPE_AP BIT(1)
|
||||
#define STA_TYPE_ADHOC BIT(2)
|
||||
#define STA_TYPE_WDS BIT(4)
|
||||
#define STA_TYPE_BC BIT(5)
|
||||
|
||||
#define NETWORK_INFRA BIT(16)
|
||||
#define NETWORK_P2P BIT(17)
|
||||
#define NETWORK_IBSS BIT(18)
|
||||
#define NETWORK_WDS BIT(21)
|
||||
|
||||
#define CONNECTION_INFRA_STA (STA_TYPE_STA | NETWORK_INFRA)
|
||||
#define CONNECTION_INFRA_AP (STA_TYPE_AP | NETWORK_INFRA)
|
||||
#define CONNECTION_P2P_GC (STA_TYPE_STA | NETWORK_P2P)
|
||||
#define CONNECTION_P2P_GO (STA_TYPE_AP | NETWORK_P2P)
|
||||
#define CONNECTION_IBSS_ADHOC (STA_TYPE_ADHOC | NETWORK_IBSS)
|
||||
#define CONNECTION_WDS (STA_TYPE_WDS | NETWORK_WDS)
|
||||
#define CONNECTION_INFRA_BC (STA_TYPE_BC | NETWORK_INFRA)
|
||||
|
||||
#define CONN_STATE_DISCONNECT 0
|
||||
#define CONN_STATE_CONNECT 1
|
||||
#define CONN_STATE_PORT_SECURE 2
|
||||
|
||||
enum {
|
||||
DEV_INFO_ACTIVE,
|
||||
DEV_INFO_MAX_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
DBDC_TYPE_WMM,
|
||||
DBDC_TYPE_MGMT,
|
||||
|
|
@ -704,11 +304,6 @@ enum {
|
|||
__DBDC_TYPE_MAX,
|
||||
};
|
||||
|
||||
struct tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
} __packed;
|
||||
|
||||
struct bss_info_omac {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
|
|
@ -767,157 +362,6 @@ enum {
|
|||
BSS_INFO_MAX_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
WTBL_RESET_AND_SET = 1,
|
||||
WTBL_SET,
|
||||
WTBL_QUERY,
|
||||
WTBL_RESET_ALL
|
||||
};
|
||||
|
||||
struct wtbl_req_hdr {
|
||||
u8 wlan_idx;
|
||||
u8 operation;
|
||||
__le16 tlv_num;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_generic {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
u8 muar_idx;
|
||||
u8 skip_tx;
|
||||
u8 cf_ack;
|
||||
u8 qos;
|
||||
u8 mesh;
|
||||
u8 adm;
|
||||
__le16 partial_aid;
|
||||
u8 baf_en;
|
||||
u8 aad_om;
|
||||
} __packed;
|
||||
|
||||
struct wtbl_rx {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 rcid;
|
||||
u8 rca1;
|
||||
u8 rca2;
|
||||
u8 rv;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_ht {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 ht;
|
||||
u8 ldpc;
|
||||
u8 af;
|
||||
u8 mm;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_vht {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 ldpc;
|
||||
u8 dyn_bw;
|
||||
u8 vht;
|
||||
u8 txop_ps;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_tx_ps {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 txps;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_hdr_trans {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 to_ds;
|
||||
u8 from_ds;
|
||||
u8 disable_rx_trans;
|
||||
u8 rsv;
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
MT_BA_TYPE_INVALID,
|
||||
MT_BA_TYPE_ORIGINATOR,
|
||||
MT_BA_TYPE_RECIPIENT
|
||||
};
|
||||
|
||||
enum {
|
||||
RST_BA_MAC_TID_MATCH,
|
||||
RST_BA_MAC_MATCH,
|
||||
RST_BA_NO_MATCH
|
||||
};
|
||||
|
||||
struct wtbl_ba {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
/* common */
|
||||
u8 tid;
|
||||
u8 ba_type;
|
||||
u8 rsv0[2];
|
||||
/* originator only */
|
||||
__le16 sn;
|
||||
u8 ba_en;
|
||||
u8 ba_winsize_idx;
|
||||
__le16 ba_winsize;
|
||||
/* recipient only */
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
u8 rst_ba_tid;
|
||||
u8 rst_ba_sel;
|
||||
u8 rst_ba_sb;
|
||||
u8 band_idx;
|
||||
u8 rsv1[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_bf {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 ibf;
|
||||
u8 ebf;
|
||||
u8 ibf_vht;
|
||||
u8 ebf_vht;
|
||||
u8 gid;
|
||||
u8 pfmu_idx;
|
||||
u8 rsv[2];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_smps {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 smps;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_pn {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 pn[6];
|
||||
u8 rsv[2];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_spe {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 spe_idx;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_raw {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 wtbl_idx;
|
||||
u8 dw;
|
||||
u8 rsv[2];
|
||||
__le32 msk;
|
||||
__le32 val;
|
||||
} __packed;
|
||||
|
||||
#define MT7615_WTBL_UPDATE_MAX_SIZE (sizeof(struct wtbl_req_hdr) + \
|
||||
sizeof(struct wtbl_generic) + \
|
||||
sizeof(struct wtbl_rx) + \
|
||||
|
|
@ -942,127 +386,6 @@ struct wtbl_raw {
|
|||
#define MT7615_WTBL_UPDATE_BA_SIZE (sizeof(struct wtbl_req_hdr) + \
|
||||
sizeof(struct wtbl_ba))
|
||||
|
||||
enum {
|
||||
WTBL_GENERIC,
|
||||
WTBL_RX,
|
||||
WTBL_HT,
|
||||
WTBL_VHT,
|
||||
WTBL_PEER_PS, /* not used */
|
||||
WTBL_TX_PS,
|
||||
WTBL_HDR_TRANS,
|
||||
WTBL_SEC_KEY,
|
||||
WTBL_BA,
|
||||
WTBL_RDG, /* obsoleted */
|
||||
WTBL_PROTECT, /* not used */
|
||||
WTBL_CLEAR, /* not used */
|
||||
WTBL_BF,
|
||||
WTBL_SMPS,
|
||||
WTBL_RAW_DATA, /* debug only */
|
||||
WTBL_PN,
|
||||
WTBL_SPE,
|
||||
WTBL_MAX_NUM
|
||||
};
|
||||
|
||||
struct sta_ntlv_hdr {
|
||||
u8 rsv[2];
|
||||
__le16 tlv_num;
|
||||
} __packed;
|
||||
|
||||
struct sta_req_hdr {
|
||||
u8 bss_idx;
|
||||
u8 wlan_idx;
|
||||
__le16 tlv_num;
|
||||
u8 is_tlv_append;
|
||||
u8 muar_idx;
|
||||
u8 rsv[2];
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_state {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 state;
|
||||
__le32 flags;
|
||||
u8 vhtop;
|
||||
u8 pad[2];
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_basic {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le32 conn_type;
|
||||
u8 conn_state;
|
||||
u8 qos;
|
||||
__le16 aid;
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
#define EXTRA_INFO_VER BIT(0)
|
||||
#define EXTRA_INFO_NEW BIT(1)
|
||||
__le16 extra_info;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_ht {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le16 ht_cap;
|
||||
u16 rsv;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_vht {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le32 vht_cap;
|
||||
__le16 vht_rx_mcs_map;
|
||||
__le16 vht_tx_mcs_map;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_ba {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 tid;
|
||||
u8 ba_type;
|
||||
u8 amsdu;
|
||||
u8 ba_en;
|
||||
__le16 ssn;
|
||||
__le16 winsize;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_uapsd {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 dac_map;
|
||||
u8 tac_map;
|
||||
u8 max_sp;
|
||||
u8 rsv0;
|
||||
__le16 listen_interval;
|
||||
u8 rsv1[2];
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
STA_REC_BASIC,
|
||||
STA_REC_RA,
|
||||
STA_REC_RA_CMM_INFO,
|
||||
STA_REC_RA_UPDATE,
|
||||
STA_REC_BF,
|
||||
STA_REC_AMSDU, /* for CR4 */
|
||||
STA_REC_BA,
|
||||
STA_REC_STATE,
|
||||
STA_REC_TX_PROC, /* for hdr trans and CSO in CR4 */
|
||||
STA_REC_HT,
|
||||
STA_REC_VHT,
|
||||
STA_REC_APPS,
|
||||
STA_REC_WTBL = 13,
|
||||
STA_REC_MAX_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
CMD_CBW_20MHZ,
|
||||
CMD_CBW_40MHZ,
|
||||
CMD_CBW_80MHZ,
|
||||
CMD_CBW_160MHZ,
|
||||
CMD_CBW_10MHZ,
|
||||
CMD_CBW_5MHZ,
|
||||
CMD_CBW_8080MHZ
|
||||
};
|
||||
|
||||
enum {
|
||||
CH_SWITCH_NORMAL = 0,
|
||||
CH_SWITCH_SCAN = 3,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "../mt76.h"
|
||||
#include "../mt76_connac_mcu.h"
|
||||
#include "regs.h"
|
||||
|
||||
#define MT7615_MAX_INTERFACES 16
|
||||
|
|
@ -65,11 +65,6 @@
|
|||
#define MT7615_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
|
||||
#define MT7615_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
|
||||
|
||||
#define MT7615_SCAN_IE_LEN 600
|
||||
#define MT7615_MAX_SCHED_SCAN_INTERVAL 10
|
||||
#define MT7615_MAX_SCHED_SCAN_SSID 10
|
||||
#define MT7615_MAX_SCAN_MATCH 16
|
||||
|
||||
struct mt7615_vif;
|
||||
struct mt7615_sta;
|
||||
struct mt7615_dfs_pulse;
|
||||
|
|
@ -133,12 +128,7 @@ struct mt7615_sta {
|
|||
};
|
||||
|
||||
struct mt7615_vif {
|
||||
u8 idx;
|
||||
u8 omac_idx;
|
||||
u8 band_idx;
|
||||
u8 wmm_idx;
|
||||
u8 scan_seq_num;
|
||||
|
||||
struct mt76_vif mt76; /* must be first */
|
||||
struct mt7615_sta sta;
|
||||
};
|
||||
|
||||
|
|
@ -171,8 +161,6 @@ struct mt7615_phy {
|
|||
s8 ofdm_sensitivity;
|
||||
s8 cck_sensitivity;
|
||||
|
||||
u16 chainmask;
|
||||
|
||||
s16 coverage_class;
|
||||
u8 slottime;
|
||||
|
||||
|
|
@ -185,9 +173,6 @@ struct mt7615_phy {
|
|||
|
||||
struct mib_stats mib;
|
||||
|
||||
struct delayed_work mac_work;
|
||||
u8 mac_work_count;
|
||||
|
||||
struct sk_buff_head scan_event_list;
|
||||
struct delayed_work scan_work;
|
||||
|
||||
|
|
@ -195,13 +180,24 @@ struct mt7615_phy {
|
|||
struct timer_list roc_timer;
|
||||
wait_queue_head_t roc_wait;
|
||||
bool roc_grant;
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
struct {
|
||||
u32 *reg_backup;
|
||||
|
||||
s16 last_freq_offset;
|
||||
u8 last_rcpi[4];
|
||||
s8 last_ib_rssi[4];
|
||||
s8 last_wb_rssi[4];
|
||||
} test;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define mt7615_mcu_add_tx_ba(dev, ...) (dev)->mcu_ops->add_tx_ba((dev), __VA_ARGS__)
|
||||
#define mt7615_mcu_add_rx_ba(dev, ...) (dev)->mcu_ops->add_rx_ba((dev), __VA_ARGS__)
|
||||
#define mt7615_mcu_sta_add(dev, ...) (dev)->mcu_ops->sta_add((dev), __VA_ARGS__)
|
||||
#define mt7615_mcu_add_dev_info(dev, ...) (dev)->mcu_ops->add_dev_info((dev), __VA_ARGS__)
|
||||
#define mt7615_mcu_add_bss_info(phy, ...) (phy->dev)->mcu_ops->add_bss_info((phy), __VA_ARGS__)
|
||||
#define mt7615_mcu_sta_add(phy, ...) ((phy)->dev)->mcu_ops->sta_add((phy), __VA_ARGS__)
|
||||
#define mt7615_mcu_add_dev_info(phy, ...) ((phy)->dev)->mcu_ops->add_dev_info((phy), __VA_ARGS__)
|
||||
#define mt7615_mcu_add_bss_info(phy, ...) ((phy)->dev)->mcu_ops->add_bss_info((phy), __VA_ARGS__)
|
||||
#define mt7615_mcu_add_beacon(dev, ...) (dev)->mcu_ops->add_beacon_offload((dev), __VA_ARGS__)
|
||||
#define mt7615_mcu_set_pm(dev, ...) (dev)->mcu_ops->set_pm_state((dev), __VA_ARGS__)
|
||||
#define mt7615_mcu_set_drv_ctrl(dev) (dev)->mcu_ops->set_drv_ctrl((dev))
|
||||
|
|
@ -213,11 +209,10 @@ struct mt7615_mcu_ops {
|
|||
int (*add_rx_ba)(struct mt7615_dev *dev,
|
||||
struct ieee80211_ampdu_params *params,
|
||||
bool enable);
|
||||
int (*sta_add)(struct mt7615_dev *dev,
|
||||
struct ieee80211_vif *vif,
|
||||
int (*sta_add)(struct mt7615_phy *phy, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enable);
|
||||
int (*add_dev_info)(struct mt7615_dev *dev,
|
||||
struct ieee80211_vif *vif, bool enable);
|
||||
int (*add_dev_info)(struct mt7615_phy *phy, struct ieee80211_vif *vif,
|
||||
bool enable);
|
||||
int (*add_bss_info)(struct mt7615_phy *phy, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enable);
|
||||
int (*add_beacon_offload)(struct mt7615_dev *dev,
|
||||
|
|
@ -281,33 +276,8 @@ struct mt7615_dev {
|
|||
|
||||
u32 muar_mask;
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
struct {
|
||||
u32 *reg_backup;
|
||||
|
||||
s16 last_freq_offset;
|
||||
u8 last_rcpi[4];
|
||||
s8 last_ib_rssi[4];
|
||||
s8 last_wb_rssi[4];
|
||||
} test;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
bool enable;
|
||||
|
||||
spinlock_t txq_lock;
|
||||
struct {
|
||||
struct mt7615_sta *msta;
|
||||
struct sk_buff *skb;
|
||||
} tx_q[IEEE80211_NUM_ACS];
|
||||
|
||||
struct work_struct wake_work;
|
||||
struct completion wake_cmpl;
|
||||
|
||||
struct delayed_work ps_work;
|
||||
unsigned long last_activity;
|
||||
unsigned long idle_timeout;
|
||||
} pm;
|
||||
struct mt76_connac_pm pm;
|
||||
struct mt76_connac_coredump coredump;
|
||||
};
|
||||
|
||||
enum tx_pkt_queue_idx {
|
||||
|
|
@ -325,20 +295,6 @@ enum tx_pkt_queue_idx {
|
|||
MT_LMAC_PSMP1,
|
||||
};
|
||||
|
||||
enum {
|
||||
HW_BSSID_0 = 0x0,
|
||||
HW_BSSID_1,
|
||||
HW_BSSID_2,
|
||||
HW_BSSID_3,
|
||||
HW_BSSID_MAX = HW_BSSID_3,
|
||||
EXT_BSSID_START = 0x10,
|
||||
EXT_BSSID_1,
|
||||
EXT_BSSID_15 = 0x1f,
|
||||
EXT_BSSID_MAX = EXT_BSSID_15,
|
||||
REPEATER_BSSID_START = 0x20,
|
||||
REPEATER_BSSID_MAX = 0x3f,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT_RX_SEL0,
|
||||
MT_RX_SEL1,
|
||||
|
|
@ -407,7 +363,6 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
|
|||
int irq, const u32 *map);
|
||||
u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr);
|
||||
|
||||
void mt7615_check_offload_capability(struct mt7615_dev *dev);
|
||||
void mt7615_init_device(struct mt7615_dev *dev);
|
||||
int mt7615_register_device(struct mt7615_dev *dev);
|
||||
void mt7615_unregister_device(struct mt7615_dev *dev);
|
||||
|
|
@ -428,8 +383,6 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
|
|||
struct ieee80211_tx_rate *probe_rate,
|
||||
struct ieee80211_tx_rate *rates);
|
||||
void mt7615_pm_wake_work(struct work_struct *work);
|
||||
int mt7615_pm_wake(struct mt7615_dev *dev);
|
||||
void mt7615_pm_power_save_sched(struct mt7615_dev *dev);
|
||||
void mt7615_pm_power_save_work(struct work_struct *work);
|
||||
int mt7615_mcu_del_wtbl_all(struct mt7615_dev *dev);
|
||||
int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd);
|
||||
|
|
@ -485,19 +438,10 @@ static inline u16 mt7615_wtbl_size(struct mt7615_dev *dev)
|
|||
return MT7615_WTBL_SIZE;
|
||||
}
|
||||
|
||||
static inline void mt7615_mutex_acquire(struct mt7615_dev *dev)
|
||||
__acquires(&dev->mt76.mutex)
|
||||
{
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
mt7615_pm_wake(dev);
|
||||
}
|
||||
|
||||
static inline void mt7615_mutex_release(struct mt7615_dev *dev)
|
||||
__releases(&dev->mt76.mutex)
|
||||
{
|
||||
mt7615_pm_power_save_sched(dev);
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
}
|
||||
#define mt7615_mutex_acquire(dev) \
|
||||
mt76_connac_mutex_acquire(&(dev)->mt76, &(dev)->pm)
|
||||
#define mt7615_mutex_release(dev) \
|
||||
mt76_connac_mutex_release(&(dev)->mt76, &(dev)->pm)
|
||||
|
||||
static inline u8 mt7615_lmac_mapping(struct mt7615_dev *dev, u8 ac)
|
||||
{
|
||||
|
|
@ -525,9 +469,8 @@ void mt7615_roc_work(struct work_struct *work);
|
|||
void mt7615_roc_timer(struct timer_list *timer);
|
||||
void mt7615_init_txpower(struct mt7615_dev *dev,
|
||||
struct ieee80211_supported_band *sband);
|
||||
void mt7615_phy_init(struct mt7615_dev *dev);
|
||||
void mt7615_mac_init(struct mt7615_dev *dev);
|
||||
int mt7615_set_channel(struct mt7615_phy *phy);
|
||||
void mt7615_init_work(struct mt7615_dev *dev);
|
||||
|
||||
int mt7615_mcu_restart(struct mt76_dev *dev);
|
||||
void mt7615_update_channel(struct mt76_dev *mdev);
|
||||
|
|
@ -558,24 +501,11 @@ u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg);
|
|||
int mt7615_rf_wr(struct mt7615_dev *dev, u32 wf, u32 reg, u32 val);
|
||||
int mt7615_mcu_set_dbdc(struct mt7615_dev *dev);
|
||||
int mt7615_mcu_set_eeprom(struct mt7615_dev *dev);
|
||||
int mt7615_mcu_set_mac_enable(struct mt7615_dev *dev, int band, bool enable);
|
||||
int mt7615_mcu_set_rts_thresh(struct mt7615_phy *phy, u32 val);
|
||||
int mt7615_mcu_get_temperature(struct mt7615_dev *dev, int index);
|
||||
int mt7615_mcu_set_tx_power(struct mt7615_phy *phy);
|
||||
void mt7615_mcu_exit(struct mt7615_dev *dev);
|
||||
void mt7615_mcu_fill_msg(struct mt7615_dev *dev, struct sk_buff *skb,
|
||||
int cmd, int *wait_seq);
|
||||
int mt7615_mcu_set_channel_domain(struct mt7615_phy *phy);
|
||||
int mt7615_mcu_hw_scan(struct mt7615_phy *phy, struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *scan_req);
|
||||
int mt7615_mcu_cancel_hw_scan(struct mt7615_phy *phy,
|
||||
struct ieee80211_vif *vif);
|
||||
int mt7615_mcu_sched_scan_req(struct mt7615_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_sched_scan_request *sreq);
|
||||
int mt7615_mcu_sched_scan_enable(struct mt7615_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
bool enable);
|
||||
|
||||
int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
enum mt76_txq_id qid, struct mt76_wcid *wcid,
|
||||
|
|
@ -583,7 +513,7 @@ int mt7615_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||
struct mt76_tx_info *tx_info);
|
||||
|
||||
void mt7615_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
|
||||
|
||||
void mt7615_tx_token_put(struct mt7615_dev *dev);
|
||||
void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
|
||||
struct sk_buff *skb);
|
||||
void mt7615_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps);
|
||||
|
|
@ -604,7 +534,6 @@ int mt7615_mcu_set_test_param(struct mt7615_dev *dev, u8 param, bool test_mode,
|
|||
int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable);
|
||||
int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy);
|
||||
int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy);
|
||||
int mt7615_mcu_set_vif_ps(struct mt7615_dev *dev, struct ieee80211_vif *vif);
|
||||
int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy);
|
||||
|
||||
int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
|
||||
|
|
@ -620,18 +549,13 @@ int mt7615_mac_set_beacon_filter(struct mt7615_phy *phy,
|
|||
bool enable);
|
||||
int mt7615_mcu_set_bss_pm(struct mt7615_dev *dev, struct ieee80211_vif *vif,
|
||||
bool enable);
|
||||
int mt7615_mcu_set_hif_suspend(struct mt7615_dev *dev, bool suspend);
|
||||
void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
|
||||
struct ieee80211_vif *vif);
|
||||
int mt7615_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_gtk_rekey_data *key);
|
||||
int mt7615_mcu_update_arp_filter(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *info);
|
||||
int __mt7663_load_firmware(struct mt7615_dev *dev);
|
||||
u32 mt7615_mcu_reg_rr(struct mt76_dev *dev, u32 offset);
|
||||
void mt7615_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val);
|
||||
void mt7615_coredump_work(struct work_struct *work);
|
||||
|
||||
/* usb */
|
||||
int mt7663_usb_sdio_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <linux/pci.h>
|
||||
|
||||
#include "mt7615.h"
|
||||
#include "mcu.h"
|
||||
|
||||
static const struct pci_device_id mt7615_pci_device_table[] = {
|
||||
{ PCI_DEVICE(0x14c3, 0x7615) },
|
||||
|
|
@ -75,14 +76,14 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
bool hif_suspend;
|
||||
int i, err;
|
||||
|
||||
err = mt7615_pm_wake(dev);
|
||||
err = mt76_connac_pm_wake(&dev->mphy, &dev->pm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
|
||||
mt7615_firmware_offload(dev);
|
||||
if (hif_suspend) {
|
||||
err = mt7615_mcu_set_hif_suspend(dev, true);
|
||||
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
|
@ -130,7 +131,7 @@ static int mt7615_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
|||
}
|
||||
napi_enable(&mdev->tx_napi);
|
||||
if (hif_suspend)
|
||||
mt7615_mcu_set_hif_suspend(dev, false);
|
||||
mt76_connac_mcu_set_hif_suspend(mdev, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -172,7 +173,7 @@ static int mt7615_pci_resume(struct pci_dev *pdev)
|
|||
|
||||
if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
|
||||
mt7615_firmware_offload(dev))
|
||||
err = mt7615_mcu_set_hif_suspend(dev, false);
|
||||
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "mac.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
static void mt7615_init_work(struct work_struct *work)
|
||||
static void mt7615_pci_init_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7615_dev *dev = container_of(work, struct mt7615_dev,
|
||||
mcu_work);
|
||||
|
|
@ -27,12 +27,7 @@ static void mt7615_init_work(struct work_struct *work)
|
|||
if (ret)
|
||||
return;
|
||||
|
||||
mt7615_mcu_set_eeprom(dev);
|
||||
mt7615_mac_init(dev);
|
||||
mt7615_phy_init(dev);
|
||||
mt7615_mcu_del_wtbl_all(dev);
|
||||
mt7615_check_offload_capability(dev);
|
||||
|
||||
mt7615_init_work(dev);
|
||||
if (dev->dbdc_support)
|
||||
mt7615_register_ext_phy(dev);
|
||||
}
|
||||
|
|
@ -44,7 +39,7 @@ static int mt7615_init_hardware(struct mt7615_dev *dev)
|
|||
|
||||
mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
|
||||
|
||||
INIT_WORK(&dev->mcu_work, mt7615_init_work);
|
||||
INIT_WORK(&dev->mcu_work, mt7615_pci_init_work);
|
||||
spin_lock_init(&dev->token_lock);
|
||||
idr_init(&dev->token);
|
||||
|
||||
|
|
@ -160,9 +155,7 @@ int mt7615_register_device(struct mt7615_dev *dev)
|
|||
|
||||
void mt7615_unregister_device(struct mt7615_dev *dev)
|
||||
{
|
||||
struct mt76_txwi_cache *txwi;
|
||||
bool mcu_running;
|
||||
int id;
|
||||
|
||||
mcu_running = mt7615_wait_for_mcu_init(dev);
|
||||
|
||||
|
|
@ -172,15 +165,7 @@ void mt7615_unregister_device(struct mt7615_dev *dev)
|
|||
mt7615_mcu_exit(dev);
|
||||
mt7615_dma_cleanup(dev);
|
||||
|
||||
spin_lock_bh(&dev->token_lock);
|
||||
idr_for_each_entry(&dev->token, txwi, id) {
|
||||
mt7615_txp_skb_unmap(&dev->mt76, txwi);
|
||||
if (txwi->skb)
|
||||
dev_kfree_skb_any(txwi->skb);
|
||||
mt76_put_txwi(&dev->mt76, txwi);
|
||||
}
|
||||
spin_unlock_bh(&dev->token_lock);
|
||||
idr_destroy(&dev->token);
|
||||
mt7615_tx_token_put(dev);
|
||||
|
||||
tasklet_disable(&dev->irq_tasklet);
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ mt7615_write_fw_txp(struct mt7615_dev *dev, struct mt76_tx_info *tx_info,
|
|||
txp->flags |= cpu_to_le16(MT_CT_INFO_MGMT_FRAME);
|
||||
|
||||
if (vif) {
|
||||
struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
|
||||
struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
|
||||
|
||||
txp->bss_idx = mvif->idx;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "mt7615.h"
|
||||
#include "sdio.h"
|
||||
#include "mac.h"
|
||||
#include "mcu.h"
|
||||
|
||||
static const struct sdio_device_id mt7663s_table[] = {
|
||||
{ SDIO_DEVICE(SDIO_VENDOR_ID_MEDIATEK, 0x7603) },
|
||||
|
|
@ -227,11 +228,7 @@ static void mt7663s_init_work(struct work_struct *work)
|
|||
if (mt7663s_mcu_init(dev))
|
||||
return;
|
||||
|
||||
mt7615_mcu_set_eeprom(dev);
|
||||
mt7615_mac_init(dev);
|
||||
mt7615_phy_init(dev);
|
||||
mt7615_mcu_del_wtbl_all(dev);
|
||||
mt7615_check_offload_capability(dev);
|
||||
mt7615_init_work(dev);
|
||||
}
|
||||
|
||||
static int mt7663s_hw_init(struct mt7615_dev *dev, struct sdio_func *func)
|
||||
|
|
@ -417,7 +414,7 @@ static int mt7663s_suspend(struct device *dev)
|
|||
mt7615_firmware_offload(mdev)) {
|
||||
int err;
|
||||
|
||||
err = mt7615_mcu_set_hif_suspend(mdev, true);
|
||||
err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, true);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
|
@ -456,7 +453,7 @@ static int mt7663s_resume(struct device *dev)
|
|||
|
||||
if (!test_bit(MT76_STATE_SUSPEND, &mdev->mphy.state) &&
|
||||
mt7615_firmware_offload(mdev))
|
||||
err = mt7615_mcu_set_hif_suspend(mdev, false);
|
||||
err = mt76_connac_mcu_set_hif_suspend(&mdev->mt76, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ mt7615_tm_set_tx_power(struct mt7615_phy *phy)
|
|||
};
|
||||
u8 *tx_power = NULL;
|
||||
|
||||
if (dev->mt76.test.state != MT76_TM_STATE_OFF)
|
||||
tx_power = dev->mt76.test.tx_power;
|
||||
if (mphy->test.state != MT76_TM_STATE_OFF)
|
||||
tx_power = mphy->test.tx_power;
|
||||
|
||||
len = MT7615_EE_MAX - MT_EE_NIC_CONF_0;
|
||||
skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req_hdr) + len);
|
||||
|
|
@ -95,14 +95,15 @@ mt7615_tm_set_tx_power(struct mt7615_phy *phy)
|
|||
}
|
||||
|
||||
static void
|
||||
mt7615_tm_reg_backup_restore(struct mt7615_dev *dev)
|
||||
mt7615_tm_reg_backup_restore(struct mt7615_phy *phy)
|
||||
{
|
||||
u32 *b = dev->test.reg_backup;
|
||||
struct mt7615_dev *dev = phy->dev;
|
||||
u32 *b = phy->test.reg_backup;
|
||||
int n_regs = ARRAY_SIZE(reg_backup_list);
|
||||
int n_rf_regs = ARRAY_SIZE(rf_backup_list);
|
||||
int i;
|
||||
|
||||
if (dev->mt76.test.state == MT76_TM_STATE_OFF) {
|
||||
if (phy->mt76->test.state == MT76_TM_STATE_OFF) {
|
||||
for (i = 0; i < n_regs; i++)
|
||||
mt76_wr(dev, reg_backup_list[i], b[i]);
|
||||
|
||||
|
|
@ -120,7 +121,7 @@ mt7615_tm_reg_backup_restore(struct mt7615_dev *dev)
|
|||
if (!b)
|
||||
return;
|
||||
|
||||
dev->test.reg_backup = b;
|
||||
phy->test.reg_backup = b;
|
||||
for (i = 0; i < n_regs; i++)
|
||||
b[i] = mt76_rr(dev, reg_backup_list[i]);
|
||||
for (i = 0; i < n_rf_regs; i++)
|
||||
|
|
@ -128,30 +129,23 @@ mt7615_tm_reg_backup_restore(struct mt7615_dev *dev)
|
|||
rf_backup_list[i].reg);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mt7615_tm_init_phy(struct mt7615_dev *dev, struct mt7615_phy *phy)
|
||||
mt7615_tm_init(struct mt7615_phy *phy)
|
||||
{
|
||||
struct mt7615_dev *dev = phy->dev;
|
||||
unsigned int total_flags = ~0;
|
||||
|
||||
if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
|
||||
return;
|
||||
|
||||
mt7615_mcu_set_sku_en(phy, phy->mt76->test.state == MT76_TM_STATE_OFF);
|
||||
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
mt7615_set_channel(phy);
|
||||
mt7615_ops.configure_filter(phy->mt76->hw, 0, &total_flags, 0);
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
mt7615_tm_reg_backup_restore(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7615_tm_init(struct mt7615_dev *dev)
|
||||
{
|
||||
mt7615_tm_init_phy(dev, &dev->phy);
|
||||
|
||||
if (dev->mt76.phy2)
|
||||
mt7615_tm_init_phy(dev, dev->mt76.phy2->priv);
|
||||
mt7615_tm_reg_backup_restore(phy);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -175,9 +169,10 @@ mt7615_tm_set_rx_enable(struct mt7615_dev *dev, bool en)
|
|||
}
|
||||
|
||||
static void
|
||||
mt7615_tm_set_tx_antenna(struct mt7615_dev *dev, bool en)
|
||||
mt7615_tm_set_tx_antenna(struct mt7615_phy *phy, bool en)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->mt76.test;
|
||||
struct mt7615_dev *dev = phy->dev;
|
||||
struct mt76_testmode_data *td = &phy->mt76->test;
|
||||
u8 mask = td->tx_antenna_mask;
|
||||
int i;
|
||||
|
||||
|
|
@ -185,7 +180,7 @@ mt7615_tm_set_tx_antenna(struct mt7615_dev *dev, bool en)
|
|||
return;
|
||||
|
||||
if (!en)
|
||||
mask = dev->phy.chainmask;
|
||||
mask = phy->mt76->chainmask;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
mt76_rmw_field(dev, MT_WF_PHY_RFINTF3_0(i),
|
||||
|
|
@ -228,26 +223,28 @@ mt7615_tm_set_tx_antenna(struct mt7615_dev *dev, bool en)
|
|||
}
|
||||
|
||||
static void
|
||||
mt7615_tm_set_tx_frames(struct mt7615_dev *dev, bool en)
|
||||
mt7615_tm_set_tx_frames(struct mt7615_phy *phy, bool en)
|
||||
{
|
||||
struct mt7615_dev *dev = phy->dev;
|
||||
struct ieee80211_tx_info *info;
|
||||
struct sk_buff *skb = dev->mt76.test.tx_skb;
|
||||
struct sk_buff *skb = phy->mt76->test.tx_skb;
|
||||
|
||||
mt7615_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH);
|
||||
mt7615_tm_set_tx_antenna(dev, en);
|
||||
mt7615_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
|
||||
mt7615_tm_set_tx_antenna(phy, en);
|
||||
mt7615_tm_set_rx_enable(dev, !en);
|
||||
if (!en || !skb)
|
||||
return;
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
info->control.vif = dev->phy.monitor_vif;
|
||||
info->control.vif = phy->monitor_vif;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7615_tm_update_params(struct mt7615_dev *dev, u32 changed)
|
||||
mt7615_tm_update_params(struct mt7615_phy *phy, u32 changed)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->mt76.test;
|
||||
bool en = dev->mt76.test.state != MT76_TM_STATE_OFF;
|
||||
struct mt7615_dev *dev = phy->dev;
|
||||
struct mt76_testmode_data *td = &phy->mt76->test;
|
||||
bool en = phy->mt76->test.state != MT76_TM_STATE_OFF;
|
||||
|
||||
if (changed & BIT(TM_CHANGED_TXPOWER_CTRL))
|
||||
mt7615_mcu_set_test_param(dev, MCU_ATE_SET_TX_POWER_CONTROL,
|
||||
|
|
@ -256,25 +253,25 @@ mt7615_tm_update_params(struct mt7615_dev *dev, u32 changed)
|
|||
mt7615_mcu_set_test_param(dev, MCU_ATE_SET_FREQ_OFFSET,
|
||||
en, en ? td->freq_offset : 0);
|
||||
if (changed & BIT(TM_CHANGED_TXPOWER))
|
||||
mt7615_tm_set_tx_power(&dev->phy);
|
||||
mt7615_tm_set_tx_power(phy);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7615_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
|
||||
mt7615_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
|
||||
{
|
||||
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||
struct mt76_testmode_data *td = &mdev->test;
|
||||
struct mt7615_phy *phy = mphy->priv;
|
||||
struct mt76_testmode_data *td = &mphy->test;
|
||||
enum mt76_testmode_state prev_state = td->state;
|
||||
|
||||
mdev->test.state = state;
|
||||
mphy->test.state = state;
|
||||
|
||||
if (prev_state == MT76_TM_STATE_TX_FRAMES)
|
||||
mt7615_tm_set_tx_frames(dev, false);
|
||||
mt7615_tm_set_tx_frames(phy, false);
|
||||
else if (state == MT76_TM_STATE_TX_FRAMES)
|
||||
mt7615_tm_set_tx_frames(dev, true);
|
||||
mt7615_tm_set_tx_frames(phy, true);
|
||||
|
||||
if (state <= MT76_TM_STATE_IDLE)
|
||||
mt7615_tm_init(dev);
|
||||
mt7615_tm_init(phy);
|
||||
|
||||
if ((state == MT76_TM_STATE_IDLE &&
|
||||
prev_state == MT76_TM_STATE_OFF) ||
|
||||
|
|
@ -290,18 +287,18 @@ mt7615_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
|
|||
changed |= BIT(i);
|
||||
}
|
||||
|
||||
mt7615_tm_update_params(dev, changed);
|
||||
mt7615_tm_update_params(phy, changed);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7615_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
|
||||
mt7615_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
|
||||
enum mt76_testmode_state new_state)
|
||||
{
|
||||
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||
struct mt76_testmode_data *td = &dev->mt76.test;
|
||||
struct mt76_testmode_data *td = &mphy->test;
|
||||
struct mt7615_phy *phy = mphy->priv;
|
||||
u32 changed = 0;
|
||||
int i;
|
||||
|
||||
|
|
@ -311,7 +308,7 @@ mt7615_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
|
|||
td->state == MT76_TM_STATE_OFF)
|
||||
return 0;
|
||||
|
||||
if (td->tx_antenna_mask & ~dev->phy.chainmask)
|
||||
if (td->tx_antenna_mask & ~mphy->chainmask)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
|
||||
|
|
@ -319,15 +316,15 @@ mt7615_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
|
|||
changed |= BIT(i);
|
||||
}
|
||||
|
||||
mt7615_tm_update_params(dev, changed);
|
||||
mt7615_tm_update_params(phy, changed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7615_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
|
||||
mt7615_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
|
||||
{
|
||||
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76);
|
||||
struct mt7615_phy *phy = mphy->priv;
|
||||
void *rx, *rssi;
|
||||
int i;
|
||||
|
||||
|
|
@ -335,15 +332,15 @@ mt7615_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
|
|||
if (!rx)
|
||||
return -ENOMEM;
|
||||
|
||||
if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, dev->test.last_freq_offset))
|
||||
if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, phy->test.last_freq_offset))
|
||||
return -ENOMEM;
|
||||
|
||||
rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RCPI);
|
||||
if (!rssi)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->test.last_rcpi); i++)
|
||||
if (nla_put_u8(msg, i, dev->test.last_rcpi[i]))
|
||||
for (i = 0; i < ARRAY_SIZE(phy->test.last_rcpi); i++)
|
||||
if (nla_put_u8(msg, i, phy->test.last_rcpi[i]))
|
||||
return -ENOMEM;
|
||||
|
||||
nla_nest_end(msg, rssi);
|
||||
|
|
@ -352,8 +349,8 @@ mt7615_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
|
|||
if (!rssi)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->test.last_ib_rssi); i++)
|
||||
if (nla_put_s8(msg, i, dev->test.last_ib_rssi[i]))
|
||||
for (i = 0; i < ARRAY_SIZE(phy->test.last_ib_rssi); i++)
|
||||
if (nla_put_s8(msg, i, phy->test.last_ib_rssi[i]))
|
||||
return -ENOMEM;
|
||||
|
||||
nla_nest_end(msg, rssi);
|
||||
|
|
@ -362,8 +359,8 @@ mt7615_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
|
|||
if (!rssi)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->test.last_wb_rssi); i++)
|
||||
if (nla_put_s8(msg, i, dev->test.last_wb_rssi[i]))
|
||||
for (i = 0; i < ARRAY_SIZE(phy->test.last_wb_rssi); i++)
|
||||
if (nla_put_s8(msg, i, phy->test.last_wb_rssi[i]))
|
||||
return -ENOMEM;
|
||||
|
||||
nla_nest_end(msg, rssi);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ static void mt7663u_stop(struct ieee80211_hw *hw)
|
|||
del_timer_sync(&phy->roc_timer);
|
||||
cancel_work_sync(&phy->roc_work);
|
||||
cancel_delayed_work_sync(&phy->scan_work);
|
||||
cancel_delayed_work_sync(&phy->mac_work);
|
||||
cancel_delayed_work_sync(&phy->mt76->mac_work);
|
||||
mt76u_stop_tx(&dev->mt76);
|
||||
}
|
||||
|
||||
|
|
@ -47,11 +47,7 @@ static void mt7663u_init_work(struct work_struct *work)
|
|||
if (mt7663u_mcu_init(dev))
|
||||
return;
|
||||
|
||||
mt7615_mcu_set_eeprom(dev);
|
||||
mt7615_mac_init(dev);
|
||||
mt7615_phy_init(dev);
|
||||
mt7615_mcu_del_wtbl_all(dev);
|
||||
mt7615_check_offload_capability(dev);
|
||||
mt7615_init_work(dev);
|
||||
}
|
||||
|
||||
static int mt7663u_probe(struct usb_interface *usb_intf,
|
||||
|
|
@ -173,7 +169,7 @@ static int mt7663u_suspend(struct usb_interface *intf, pm_message_t state)
|
|||
mt7615_firmware_offload(dev)) {
|
||||
int err;
|
||||
|
||||
err = mt7615_mcu_set_hif_suspend(dev, true);
|
||||
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, true);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
|
@ -201,7 +197,7 @@ static int mt7663u_resume(struct usb_interface *intf)
|
|||
|
||||
if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
|
||||
mt7615_firmware_offload(dev))
|
||||
err = mt7615_mcu_set_hif_suspend(dev, false);
|
||||
err = mt76_connac_mcu_set_hif_suspend(&dev->mt76, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
105
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Normal file
105
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#ifndef __MT76_CONNAC_H
|
||||
#define __MT76_CONNAC_H
|
||||
|
||||
#include "mt76.h"
|
||||
|
||||
#define MT76_CONNAC_SCAN_IE_LEN 600
|
||||
#define MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL 10
|
||||
#define MT76_CONNAC_MAX_SCHED_SCAN_SSID 10
|
||||
#define MT76_CONNAC_MAX_SCAN_MATCH 16
|
||||
|
||||
#define MT76_CONNAC_COREDUMP_TIMEOUT (HZ / 20)
|
||||
#define MT76_CONNAC_COREDUMP_SZ (128 * 1024)
|
||||
|
||||
enum {
|
||||
CMD_CBW_20MHZ = IEEE80211_STA_RX_BW_20,
|
||||
CMD_CBW_40MHZ = IEEE80211_STA_RX_BW_40,
|
||||
CMD_CBW_80MHZ = IEEE80211_STA_RX_BW_80,
|
||||
CMD_CBW_160MHZ = IEEE80211_STA_RX_BW_160,
|
||||
CMD_CBW_10MHZ,
|
||||
CMD_CBW_5MHZ,
|
||||
CMD_CBW_8080MHZ,
|
||||
|
||||
CMD_HE_MCS_BW80 = 0,
|
||||
CMD_HE_MCS_BW160,
|
||||
CMD_HE_MCS_BW8080,
|
||||
CMD_HE_MCS_BW_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
HW_BSSID_0 = 0x0,
|
||||
HW_BSSID_1,
|
||||
HW_BSSID_2,
|
||||
HW_BSSID_3,
|
||||
HW_BSSID_MAX = HW_BSSID_3,
|
||||
EXT_BSSID_START = 0x10,
|
||||
EXT_BSSID_1,
|
||||
EXT_BSSID_15 = 0x1f,
|
||||
EXT_BSSID_MAX = EXT_BSSID_15,
|
||||
REPEATER_BSSID_START = 0x20,
|
||||
REPEATER_BSSID_MAX = 0x3f,
|
||||
};
|
||||
|
||||
struct mt76_connac_pm {
|
||||
bool enable;
|
||||
|
||||
spinlock_t txq_lock;
|
||||
struct {
|
||||
struct mt76_wcid *wcid;
|
||||
struct sk_buff *skb;
|
||||
} tx_q[IEEE80211_NUM_ACS];
|
||||
|
||||
struct work_struct wake_work;
|
||||
struct completion wake_cmpl;
|
||||
|
||||
struct delayed_work ps_work;
|
||||
unsigned long last_activity;
|
||||
unsigned long idle_timeout;
|
||||
};
|
||||
|
||||
struct mt76_connac_coredump {
|
||||
struct sk_buff_head msg_list;
|
||||
struct delayed_work work;
|
||||
unsigned long last_activity;
|
||||
};
|
||||
|
||||
extern const struct wiphy_wowlan_support mt76_connac_wowlan_support;
|
||||
|
||||
static inline bool is_mt7921(struct mt76_dev *dev)
|
||||
{
|
||||
return mt76_chip(dev) == 0x7961;
|
||||
}
|
||||
|
||||
int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm);
|
||||
void mt76_connac_power_save_sched(struct mt76_phy *phy,
|
||||
struct mt76_connac_pm *pm);
|
||||
void mt76_connac_free_pending_tx_skbs(struct mt76_connac_pm *pm,
|
||||
struct mt76_wcid *wcid);
|
||||
|
||||
static inline void
|
||||
mt76_connac_mutex_acquire(struct mt76_dev *dev, struct mt76_connac_pm *pm)
|
||||
__acquires(&dev->mutex)
|
||||
{
|
||||
mutex_lock(&dev->mutex);
|
||||
mt76_connac_pm_wake(&dev->phy, pm);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mt76_connac_mutex_release(struct mt76_dev *dev, struct mt76_connac_pm *pm)
|
||||
__releases(&dev->mutex)
|
||||
{
|
||||
mt76_connac_power_save_sched(&dev->phy, pm);
|
||||
mutex_unlock(&dev->mutex);
|
||||
}
|
||||
|
||||
void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw,
|
||||
struct mt76_connac_pm *pm,
|
||||
struct mt76_wcid *wcid,
|
||||
struct sk_buff *skb);
|
||||
void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,
|
||||
struct mt76_connac_pm *pm);
|
||||
|
||||
#endif /* __MT76_CONNAC_H */
|
||||
119
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
Normal file
119
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#include "mt76_connac.h"
|
||||
|
||||
int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)
|
||||
{
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
|
||||
if (!pm->enable)
|
||||
return 0;
|
||||
|
||||
if (!mt76_is_mmio(dev))
|
||||
return 0;
|
||||
|
||||
if (!test_bit(MT76_STATE_PM, &phy->state))
|
||||
return 0;
|
||||
|
||||
if (test_bit(MT76_HW_SCANNING, &phy->state) ||
|
||||
test_bit(MT76_HW_SCHED_SCANNING, &phy->state))
|
||||
return 0;
|
||||
|
||||
if (queue_work(dev->wq, &pm->wake_work))
|
||||
reinit_completion(&pm->wake_cmpl);
|
||||
|
||||
if (!wait_for_completion_timeout(&pm->wake_cmpl, 3 * HZ)) {
|
||||
ieee80211_wake_queues(phy->hw);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_pm_wake);
|
||||
|
||||
void mt76_connac_power_save_sched(struct mt76_phy *phy,
|
||||
struct mt76_connac_pm *pm)
|
||||
{
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
|
||||
if (!mt76_is_mmio(dev))
|
||||
return;
|
||||
|
||||
if (!pm->enable || !test_bit(MT76_STATE_RUNNING, &phy->state))
|
||||
return;
|
||||
|
||||
pm->last_activity = jiffies;
|
||||
|
||||
if (test_bit(MT76_HW_SCANNING, &phy->state) ||
|
||||
test_bit(MT76_HW_SCHED_SCANNING, &phy->state))
|
||||
return;
|
||||
|
||||
if (!test_bit(MT76_STATE_PM, &phy->state))
|
||||
queue_delayed_work(dev->wq, &pm->ps_work, pm->idle_timeout);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_power_save_sched);
|
||||
|
||||
void mt76_connac_free_pending_tx_skbs(struct mt76_connac_pm *pm,
|
||||
struct mt76_wcid *wcid)
|
||||
{
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&pm->txq_lock);
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||
if (wcid && pm->tx_q[i].wcid != wcid)
|
||||
continue;
|
||||
|
||||
dev_kfree_skb(pm->tx_q[i].skb);
|
||||
pm->tx_q[i].skb = NULL;
|
||||
}
|
||||
spin_unlock_bh(&pm->txq_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_free_pending_tx_skbs);
|
||||
|
||||
void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw,
|
||||
struct mt76_connac_pm *pm,
|
||||
struct mt76_wcid *wcid,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
int qid = skb_get_queue_mapping(skb);
|
||||
struct mt76_phy *phy = hw->priv;
|
||||
|
||||
spin_lock_bh(&pm->txq_lock);
|
||||
if (!pm->tx_q[qid].skb) {
|
||||
ieee80211_stop_queues(hw);
|
||||
pm->tx_q[qid].wcid = wcid;
|
||||
pm->tx_q[qid].skb = skb;
|
||||
queue_work(phy->dev->wq, &pm->wake_work);
|
||||
} else {
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
spin_unlock_bh(&pm->txq_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_pm_queue_skb);
|
||||
|
||||
void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,
|
||||
struct mt76_connac_pm *pm)
|
||||
{
|
||||
int i;
|
||||
|
||||
spin_lock_bh(&pm->txq_lock);
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||
struct mt76_wcid *wcid = pm->tx_q[i].wcid;
|
||||
struct ieee80211_sta *sta = NULL;
|
||||
|
||||
if (!pm->tx_q[i].skb)
|
||||
continue;
|
||||
|
||||
if (wcid && wcid->sta)
|
||||
sta = container_of((void *)wcid, struct ieee80211_sta,
|
||||
drv_priv);
|
||||
|
||||
mt76_tx(phy, sta, wcid, pm->tx_q[i].skb);
|
||||
pm->tx_q[i].skb = NULL;
|
||||
}
|
||||
spin_unlock_bh(&pm->txq_lock);
|
||||
|
||||
mt76_worker_schedule(&phy->dev->tx_worker);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76_connac_pm_dequeue_skbs);
|
||||
1842
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
Normal file
1842
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
Normal file
File diff suppressed because it is too large
Load Diff
979
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
Normal file
979
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
Normal file
|
|
@ -0,0 +1,979 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#ifndef __MT76_CONNAC_MCU_H
|
||||
#define __MT76_CONNAC_MCU_H
|
||||
|
||||
#include "mt76_connac.h"
|
||||
|
||||
struct tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
} __packed;
|
||||
|
||||
/* sta_rec */
|
||||
|
||||
struct sta_ntlv_hdr {
|
||||
u8 rsv[2];
|
||||
__le16 tlv_num;
|
||||
} __packed;
|
||||
|
||||
struct sta_req_hdr {
|
||||
u8 bss_idx;
|
||||
u8 wlan_idx_lo;
|
||||
__le16 tlv_num;
|
||||
u8 is_tlv_append;
|
||||
u8 muar_idx;
|
||||
u8 wlan_idx_hi;
|
||||
u8 rsv;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_basic {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le32 conn_type;
|
||||
u8 conn_state;
|
||||
u8 qos;
|
||||
__le16 aid;
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
#define EXTRA_INFO_VER BIT(0)
|
||||
#define EXTRA_INFO_NEW BIT(1)
|
||||
__le16 extra_info;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_ht {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le16 ht_cap;
|
||||
u16 rsv;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_vht {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le32 vht_cap;
|
||||
__le16 vht_rx_mcs_map;
|
||||
__le16 vht_tx_mcs_map;
|
||||
/* mt7921 */
|
||||
u8 rts_bw_sig;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_uapsd {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 dac_map;
|
||||
u8 tac_map;
|
||||
u8 max_sp;
|
||||
u8 rsv0;
|
||||
__le16 listen_interval;
|
||||
u8 rsv1[2];
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_ba {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 tid;
|
||||
u8 ba_type;
|
||||
u8 amsdu;
|
||||
u8 ba_en;
|
||||
__le16 ssn;
|
||||
__le16 winsize;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_he {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
|
||||
__le32 he_cap;
|
||||
|
||||
u8 t_frame_dur;
|
||||
u8 max_ampdu_exp;
|
||||
u8 bw_set;
|
||||
u8 device_class;
|
||||
u8 dcm_tx_mode;
|
||||
u8 dcm_tx_max_nss;
|
||||
u8 dcm_rx_mode;
|
||||
u8 dcm_rx_max_nss;
|
||||
u8 dcm_max_ru;
|
||||
u8 punc_pream_rx;
|
||||
u8 pkt_ext;
|
||||
u8 rsv1;
|
||||
|
||||
__le16 max_nss_mcs[CMD_HE_MCS_BW_NUM];
|
||||
|
||||
u8 rsv2[2];
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_amsdu {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 max_amsdu_num;
|
||||
u8 max_mpdu_size;
|
||||
u8 amsdu_en;
|
||||
u8 rsv;
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_state {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le32 flags;
|
||||
u8 state;
|
||||
u8 vht_opmode;
|
||||
u8 action;
|
||||
u8 rsv[1];
|
||||
} __packed;
|
||||
|
||||
#define HT_MCS_MASK_NUM 10
|
||||
struct sta_rec_ra_info {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le16 legacy;
|
||||
u8 rx_mcs_bitmask[HT_MCS_MASK_NUM];
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_phy {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le16 basic_rate;
|
||||
u8 phy_type;
|
||||
u8 ampdu;
|
||||
u8 rts_policy;
|
||||
u8 rcpi;
|
||||
u8 rsv[2];
|
||||
} __packed;
|
||||
|
||||
/* wtbl_rec */
|
||||
|
||||
struct wtbl_req_hdr {
|
||||
u8 wlan_idx_lo;
|
||||
u8 operation;
|
||||
__le16 tlv_num;
|
||||
u8 wlan_idx_hi;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_generic {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
u8 muar_idx;
|
||||
u8 skip_tx;
|
||||
u8 cf_ack;
|
||||
u8 qos;
|
||||
u8 mesh;
|
||||
u8 adm;
|
||||
__le16 partial_aid;
|
||||
u8 baf_en;
|
||||
u8 aad_om;
|
||||
} __packed;
|
||||
|
||||
struct wtbl_rx {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 rcid;
|
||||
u8 rca1;
|
||||
u8 rca2;
|
||||
u8 rv;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_ht {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 ht;
|
||||
u8 ldpc;
|
||||
u8 af;
|
||||
u8 mm;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_vht {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 ldpc;
|
||||
u8 dyn_bw;
|
||||
u8 vht;
|
||||
u8 txop_ps;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_tx_ps {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 txps;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_hdr_trans {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 to_ds;
|
||||
u8 from_ds;
|
||||
u8 disable_rx_trans;
|
||||
u8 rsv;
|
||||
} __packed;
|
||||
|
||||
struct wtbl_ba {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
/* common */
|
||||
u8 tid;
|
||||
u8 ba_type;
|
||||
u8 rsv0[2];
|
||||
/* originator only */
|
||||
__le16 sn;
|
||||
u8 ba_en;
|
||||
u8 ba_winsize_idx;
|
||||
__le16 ba_winsize;
|
||||
/* recipient only */
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
u8 rst_ba_tid;
|
||||
u8 rst_ba_sel;
|
||||
u8 rst_ba_sb;
|
||||
u8 band_idx;
|
||||
u8 rsv1[4];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_smps {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 smps;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
/* mt7615 only */
|
||||
|
||||
struct wtbl_bf {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 ibf;
|
||||
u8 ebf;
|
||||
u8 ibf_vht;
|
||||
u8 ebf_vht;
|
||||
u8 gid;
|
||||
u8 pfmu_idx;
|
||||
u8 rsv[2];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_pn {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 pn[6];
|
||||
u8 rsv[2];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_spe {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 spe_idx;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct wtbl_raw {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 wtbl_idx;
|
||||
u8 dw;
|
||||
u8 rsv[2];
|
||||
__le32 msk;
|
||||
__le32 val;
|
||||
} __packed;
|
||||
|
||||
#define MT76_CONNAC_WTBL_UPDATE_MAX_SIZE (sizeof(struct wtbl_req_hdr) + \
|
||||
sizeof(struct wtbl_generic) + \
|
||||
sizeof(struct wtbl_rx) + \
|
||||
sizeof(struct wtbl_ht) + \
|
||||
sizeof(struct wtbl_vht) + \
|
||||
sizeof(struct wtbl_tx_ps) + \
|
||||
sizeof(struct wtbl_hdr_trans) +\
|
||||
sizeof(struct wtbl_ba) + \
|
||||
sizeof(struct wtbl_bf) + \
|
||||
sizeof(struct wtbl_smps) + \
|
||||
sizeof(struct wtbl_pn) + \
|
||||
sizeof(struct wtbl_spe))
|
||||
|
||||
#define MT76_CONNAC_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
|
||||
sizeof(struct sta_rec_basic) + \
|
||||
sizeof(struct sta_rec_ht) + \
|
||||
sizeof(struct sta_rec_he) + \
|
||||
sizeof(struct sta_rec_ba) + \
|
||||
sizeof(struct sta_rec_vht) + \
|
||||
sizeof(struct sta_rec_uapsd) + \
|
||||
sizeof(struct sta_rec_amsdu) + \
|
||||
sizeof(struct tlv) + \
|
||||
MT76_CONNAC_WTBL_UPDATE_MAX_SIZE)
|
||||
|
||||
#define MT76_CONNAC_WTBL_UPDATE_BA_SIZE (sizeof(struct wtbl_req_hdr) + \
|
||||
sizeof(struct wtbl_ba))
|
||||
|
||||
enum {
|
||||
STA_REC_BASIC,
|
||||
STA_REC_RA,
|
||||
STA_REC_RA_CMM_INFO,
|
||||
STA_REC_RA_UPDATE,
|
||||
STA_REC_BF,
|
||||
STA_REC_AMSDU,
|
||||
STA_REC_BA,
|
||||
STA_REC_STATE,
|
||||
STA_REC_TX_PROC, /* for hdr trans and CSO in CR4 */
|
||||
STA_REC_HT,
|
||||
STA_REC_VHT,
|
||||
STA_REC_APPS,
|
||||
STA_REC_KEY,
|
||||
STA_REC_WTBL,
|
||||
STA_REC_HE,
|
||||
STA_REC_HW_AMSDU,
|
||||
STA_REC_WTBL_AADOM,
|
||||
STA_REC_KEY_V2,
|
||||
STA_REC_MURU,
|
||||
STA_REC_MUEDCA,
|
||||
STA_REC_BFEE,
|
||||
STA_REC_PHY = 0x15,
|
||||
STA_REC_MAX_NUM
|
||||
};
|
||||
|
||||
enum {
|
||||
WTBL_GENERIC,
|
||||
WTBL_RX,
|
||||
WTBL_HT,
|
||||
WTBL_VHT,
|
||||
WTBL_PEER_PS, /* not used */
|
||||
WTBL_TX_PS,
|
||||
WTBL_HDR_TRANS,
|
||||
WTBL_SEC_KEY,
|
||||
WTBL_BA,
|
||||
WTBL_RDG, /* obsoleted */
|
||||
WTBL_PROTECT, /* not used */
|
||||
WTBL_CLEAR, /* not used */
|
||||
WTBL_BF,
|
||||
WTBL_SMPS,
|
||||
WTBL_RAW_DATA, /* debug only */
|
||||
WTBL_PN,
|
||||
WTBL_SPE,
|
||||
WTBL_MAX_NUM
|
||||
};
|
||||
|
||||
#define STA_TYPE_STA BIT(0)
|
||||
#define STA_TYPE_AP BIT(1)
|
||||
#define STA_TYPE_ADHOC BIT(2)
|
||||
#define STA_TYPE_WDS BIT(4)
|
||||
#define STA_TYPE_BC BIT(5)
|
||||
|
||||
#define NETWORK_INFRA BIT(16)
|
||||
#define NETWORK_P2P BIT(17)
|
||||
#define NETWORK_IBSS BIT(18)
|
||||
#define NETWORK_WDS BIT(21)
|
||||
|
||||
#define CONNECTION_INFRA_STA (STA_TYPE_STA | NETWORK_INFRA)
|
||||
#define CONNECTION_INFRA_AP (STA_TYPE_AP | NETWORK_INFRA)
|
||||
#define CONNECTION_P2P_GC (STA_TYPE_STA | NETWORK_P2P)
|
||||
#define CONNECTION_P2P_GO (STA_TYPE_AP | NETWORK_P2P)
|
||||
#define CONNECTION_IBSS_ADHOC (STA_TYPE_ADHOC | NETWORK_IBSS)
|
||||
#define CONNECTION_WDS (STA_TYPE_WDS | NETWORK_WDS)
|
||||
#define CONNECTION_INFRA_BC (STA_TYPE_BC | NETWORK_INFRA)
|
||||
|
||||
#define CONN_STATE_DISCONNECT 0
|
||||
#define CONN_STATE_CONNECT 1
|
||||
#define CONN_STATE_PORT_SECURE 2
|
||||
|
||||
/* HE MAC */
|
||||
#define STA_REC_HE_CAP_HTC BIT(0)
|
||||
#define STA_REC_HE_CAP_BQR BIT(1)
|
||||
#define STA_REC_HE_CAP_BSR BIT(2)
|
||||
#define STA_REC_HE_CAP_OM BIT(3)
|
||||
#define STA_REC_HE_CAP_AMSDU_IN_AMPDU BIT(4)
|
||||
/* HE PHY */
|
||||
#define STA_REC_HE_CAP_DUAL_BAND BIT(5)
|
||||
#define STA_REC_HE_CAP_LDPC BIT(6)
|
||||
#define STA_REC_HE_CAP_TRIG_CQI_FK BIT(7)
|
||||
#define STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE BIT(8)
|
||||
/* STBC */
|
||||
#define STA_REC_HE_CAP_LE_EQ_80M_TX_STBC BIT(9)
|
||||
#define STA_REC_HE_CAP_LE_EQ_80M_RX_STBC BIT(10)
|
||||
#define STA_REC_HE_CAP_GT_80M_TX_STBC BIT(11)
|
||||
#define STA_REC_HE_CAP_GT_80M_RX_STBC BIT(12)
|
||||
/* GI */
|
||||
#define STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI BIT(13)
|
||||
#define STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI BIT(14)
|
||||
#define STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI BIT(15)
|
||||
#define STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI BIT(16)
|
||||
#define STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI BIT(17)
|
||||
/* 242 TONE */
|
||||
#define STA_REC_HE_CAP_BW20_RU242_SUPPORT BIT(18)
|
||||
#define STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242 BIT(19)
|
||||
#define STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242 BIT(20)
|
||||
|
||||
#define PHY_MODE_A BIT(0)
|
||||
#define PHY_MODE_B BIT(1)
|
||||
#define PHY_MODE_G BIT(2)
|
||||
#define PHY_MODE_GN BIT(3)
|
||||
#define PHY_MODE_AN BIT(4)
|
||||
#define PHY_MODE_AC BIT(5)
|
||||
#define PHY_MODE_AX_24G BIT(6)
|
||||
#define PHY_MODE_AX_5G BIT(7)
|
||||
#define PHY_MODE_AX_6G BIT(8)
|
||||
|
||||
#define MODE_CCK BIT(0)
|
||||
#define MODE_OFDM BIT(1)
|
||||
#define MODE_HT BIT(2)
|
||||
#define MODE_VHT BIT(3)
|
||||
#define MODE_HE BIT(4)
|
||||
|
||||
enum {
|
||||
PHY_TYPE_HR_DSSS_INDEX = 0,
|
||||
PHY_TYPE_ERP_INDEX,
|
||||
PHY_TYPE_ERP_P2P_INDEX,
|
||||
PHY_TYPE_OFDM_INDEX,
|
||||
PHY_TYPE_HT_INDEX,
|
||||
PHY_TYPE_VHT_INDEX,
|
||||
PHY_TYPE_HE_INDEX,
|
||||
PHY_TYPE_INDEX_NUM
|
||||
};
|
||||
|
||||
#define PHY_TYPE_BIT_HR_DSSS BIT(PHY_TYPE_HR_DSSS_INDEX)
|
||||
#define PHY_TYPE_BIT_ERP BIT(PHY_TYPE_ERP_INDEX)
|
||||
#define PHY_TYPE_BIT_OFDM BIT(PHY_TYPE_OFDM_INDEX)
|
||||
#define PHY_TYPE_BIT_HT BIT(PHY_TYPE_HT_INDEX)
|
||||
#define PHY_TYPE_BIT_VHT BIT(PHY_TYPE_VHT_INDEX)
|
||||
#define PHY_TYPE_BIT_HE BIT(PHY_TYPE_HE_INDEX)
|
||||
|
||||
#define MT_WTBL_RATE_TX_MODE GENMASK(9, 6)
|
||||
#define MT_WTBL_RATE_MCS GENMASK(5, 0)
|
||||
#define MT_WTBL_RATE_NSS GENMASK(12, 10)
|
||||
#define MT_WTBL_RATE_HE_GI GENMASK(7, 4)
|
||||
#define MT_WTBL_RATE_GI GENMASK(3, 0)
|
||||
|
||||
#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_40 BIT(9)
|
||||
#define MT_WTBL_W5_SHORT_GI_80 BIT(10)
|
||||
#define MT_WTBL_W5_SHORT_GI_160 BIT(11)
|
||||
#define MT_WTBL_W5_BW_CAP GENMASK(13, 12)
|
||||
#define MT_WTBL_W5_MPDU_FAIL_COUNT GENMASK(25, 23)
|
||||
#define MT_WTBL_W5_MPDU_OK_COUNT GENMASK(28, 26)
|
||||
#define MT_WTBL_W5_RATE_IDX GENMASK(31, 29)
|
||||
|
||||
enum {
|
||||
WTBL_RESET_AND_SET = 1,
|
||||
WTBL_SET,
|
||||
WTBL_QUERY,
|
||||
WTBL_RESET_ALL
|
||||
};
|
||||
|
||||
enum {
|
||||
MT_BA_TYPE_INVALID,
|
||||
MT_BA_TYPE_ORIGINATOR,
|
||||
MT_BA_TYPE_RECIPIENT
|
||||
};
|
||||
|
||||
enum {
|
||||
RST_BA_MAC_TID_MATCH,
|
||||
RST_BA_MAC_MATCH,
|
||||
RST_BA_NO_MATCH
|
||||
};
|
||||
|
||||
enum {
|
||||
DEV_INFO_ACTIVE,
|
||||
DEV_INFO_MAX_NUM
|
||||
};
|
||||
|
||||
#define MCU_CMD_ACK BIT(0)
|
||||
#define MCU_CMD_UNI BIT(1)
|
||||
#define MCU_CMD_QUERY BIT(2)
|
||||
|
||||
#define MCU_CMD_UNI_EXT_ACK (MCU_CMD_ACK | MCU_CMD_UNI | \
|
||||
MCU_CMD_QUERY)
|
||||
|
||||
#define MCU_FW_PREFIX BIT(31)
|
||||
#define MCU_UNI_PREFIX BIT(30)
|
||||
#define MCU_CE_PREFIX BIT(29)
|
||||
#define MCU_QUERY_PREFIX BIT(28)
|
||||
#define MCU_CMD_MASK ~(MCU_FW_PREFIX | MCU_UNI_PREFIX | \
|
||||
MCU_CE_PREFIX | MCU_QUERY_PREFIX)
|
||||
|
||||
#define MCU_QUERY_MASK BIT(16)
|
||||
|
||||
enum {
|
||||
MCU_EXT_CMD_EFUSE_ACCESS = 0x01,
|
||||
MCU_EXT_CMD_RF_REG_ACCESS = 0x02,
|
||||
MCU_EXT_CMD_PM_STATE_CTRL = 0x07,
|
||||
MCU_EXT_CMD_CHANNEL_SWITCH = 0x08,
|
||||
MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11,
|
||||
MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
|
||||
MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21,
|
||||
MCU_EXT_CMD_STA_REC_UPDATE = 0x25,
|
||||
MCU_EXT_CMD_BSS_INFO_UPDATE = 0x26,
|
||||
MCU_EXT_CMD_EDCA_UPDATE = 0x27,
|
||||
MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
|
||||
MCU_EXT_CMD_GET_TEMP = 0x2c,
|
||||
MCU_EXT_CMD_WTBL_UPDATE = 0x32,
|
||||
MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
|
||||
MCU_EXT_CMD_ATE_CTRL = 0x3d,
|
||||
MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
|
||||
MCU_EXT_CMD_DBDC_CTRL = 0x45,
|
||||
MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
|
||||
MCU_EXT_CMD_RX_HDR_TRANS = 0x47,
|
||||
MCU_EXT_CMD_MUAR_UPDATE = 0x48,
|
||||
MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
|
||||
MCU_EXT_CMD_SET_RX_PATH = 0x4e,
|
||||
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
|
||||
MCU_EXT_CMD_RXDCOC_CAL = 0x59,
|
||||
MCU_EXT_CMD_TXDPD_CAL = 0x60,
|
||||
MCU_EXT_CMD_SET_RDD_TH = 0x7c,
|
||||
MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_UNI_CMD_DEV_INFO_UPDATE = MCU_UNI_PREFIX | 0x01,
|
||||
MCU_UNI_CMD_BSS_INFO_UPDATE = MCU_UNI_PREFIX | 0x02,
|
||||
MCU_UNI_CMD_STA_REC_UPDATE = MCU_UNI_PREFIX | 0x03,
|
||||
MCU_UNI_CMD_SUSPEND = MCU_UNI_PREFIX | 0x05,
|
||||
MCU_UNI_CMD_OFFLOAD = MCU_UNI_PREFIX | 0x06,
|
||||
MCU_UNI_CMD_HIF_CTRL = MCU_UNI_PREFIX | 0x07,
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_CMD_TARGET_ADDRESS_LEN_REQ = MCU_FW_PREFIX | 0x01,
|
||||
MCU_CMD_FW_START_REQ = MCU_FW_PREFIX | 0x02,
|
||||
MCU_CMD_INIT_ACCESS_REG = 0x3,
|
||||
MCU_CMD_NIC_POWER_CTRL = MCU_FW_PREFIX | 0x4,
|
||||
MCU_CMD_PATCH_START_REQ = MCU_FW_PREFIX | 0x05,
|
||||
MCU_CMD_PATCH_FINISH_REQ = MCU_FW_PREFIX | 0x07,
|
||||
MCU_CMD_PATCH_SEM_CONTROL = MCU_FW_PREFIX | 0x10,
|
||||
MCU_CMD_EXT_CID = 0xed,
|
||||
MCU_CMD_FW_SCATTER = MCU_FW_PREFIX | 0xee,
|
||||
MCU_CMD_RESTART_DL_REQ = MCU_FW_PREFIX | 0xef,
|
||||
};
|
||||
|
||||
/* offload mcu commands */
|
||||
enum {
|
||||
MCU_CMD_START_HW_SCAN = MCU_CE_PREFIX | 0x03,
|
||||
MCU_CMD_SET_PS_PROFILE = MCU_CE_PREFIX | 0x05,
|
||||
MCU_CMD_SET_CHAN_DOMAIN = MCU_CE_PREFIX | 0x0f,
|
||||
MCU_CMD_SET_BSS_CONNECTED = MCU_CE_PREFIX | 0x16,
|
||||
MCU_CMD_SET_BSS_ABORT = MCU_CE_PREFIX | 0x17,
|
||||
MCU_CMD_CANCEL_HW_SCAN = MCU_CE_PREFIX | 0x1b,
|
||||
MCU_CMD_SET_ROC = MCU_CE_PREFIX | 0x1d,
|
||||
MCU_CMD_SET_P2P_OPPPS = MCU_CE_PREFIX | 0x33,
|
||||
MCU_CMD_SET_RATE_TX_POWER = MCU_CE_PREFIX | 0x5d,
|
||||
MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61,
|
||||
MCU_CMD_SCHED_SCAN_REQ = MCU_CE_PREFIX | 0x62,
|
||||
MCU_CMD_REG_WRITE = MCU_CE_PREFIX | 0xc0,
|
||||
MCU_CMD_REG_READ = MCU_CE_PREFIX | MCU_QUERY_MASK | 0xc0,
|
||||
MCU_CMD_CHIP_CONFIG = MCU_CE_PREFIX | 0xca,
|
||||
MCU_CMD_FWLOG_2_HOST = MCU_CE_PREFIX | 0xc5,
|
||||
MCU_CMD_GET_WTBL = MCU_CE_PREFIX | 0xcd,
|
||||
};
|
||||
|
||||
enum {
|
||||
PATCH_SEM_RELEASE,
|
||||
PATCH_SEM_GET
|
||||
};
|
||||
|
||||
enum {
|
||||
UNI_BSS_INFO_BASIC = 0,
|
||||
UNI_BSS_INFO_RLM = 2,
|
||||
UNI_BSS_INFO_HE_BASIC = 5,
|
||||
UNI_BSS_INFO_BCN_CONTENT = 7,
|
||||
UNI_BSS_INFO_QBSS = 15,
|
||||
UNI_BSS_INFO_UAPSD = 19,
|
||||
UNI_BSS_INFO_PS = 21,
|
||||
UNI_BSS_INFO_BCNFT = 22,
|
||||
};
|
||||
|
||||
enum {
|
||||
UNI_OFFLOAD_OFFLOAD_ARP,
|
||||
UNI_OFFLOAD_OFFLOAD_ND,
|
||||
UNI_OFFLOAD_OFFLOAD_GTK_REKEY,
|
||||
UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
|
||||
};
|
||||
|
||||
enum {
|
||||
UNI_SUSPEND_MODE_SETTING,
|
||||
UNI_SUSPEND_WOW_CTRL,
|
||||
UNI_SUSPEND_WOW_GPIO_PARAM,
|
||||
UNI_SUSPEND_WOW_WAKEUP_PORT,
|
||||
UNI_SUSPEND_WOW_PATTERN,
|
||||
};
|
||||
|
||||
enum {
|
||||
WOW_USB = 1,
|
||||
WOW_PCIE = 2,
|
||||
WOW_GPIO = 3,
|
||||
};
|
||||
|
||||
struct mt76_connac_bss_basic_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 active;
|
||||
u8 omac_idx;
|
||||
u8 hw_bss_idx;
|
||||
u8 band_idx;
|
||||
__le32 conn_type;
|
||||
u8 conn_state;
|
||||
u8 wmm_idx;
|
||||
u8 bssid[ETH_ALEN];
|
||||
__le16 bmc_tx_wlan_idx;
|
||||
__le16 bcn_interval;
|
||||
u8 dtim_period;
|
||||
u8 phymode; /* bit(0): A
|
||||
* bit(1): B
|
||||
* bit(2): G
|
||||
* bit(3): GN
|
||||
* bit(4): AN
|
||||
* bit(5): AC
|
||||
*/
|
||||
__le16 sta_idx;
|
||||
u8 nonht_basic_phy;
|
||||
u8 pad[3];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_bss_qos_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 qos;
|
||||
u8 pad[3];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_beacon_loss_event {
|
||||
u8 bss_idx;
|
||||
u8 reason;
|
||||
u8 pad[2];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_mcu_bss_event {
|
||||
u8 bss_idx;
|
||||
u8 is_absent;
|
||||
u8 free_quota;
|
||||
u8 pad;
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_mcu_scan_ssid {
|
||||
__le32 ssid_len;
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_mcu_scan_channel {
|
||||
u8 band; /* 1: 2.4GHz
|
||||
* 2: 5.0GHz
|
||||
* Others: Reserved
|
||||
*/
|
||||
u8 channel_num;
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_mcu_scan_match {
|
||||
__le32 rssi_th;
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
u8 ssid_len;
|
||||
u8 rsv[3];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_hw_scan_req {
|
||||
u8 seq_num;
|
||||
u8 bss_idx;
|
||||
u8 scan_type; /* 0: PASSIVE SCAN
|
||||
* 1: ACTIVE SCAN
|
||||
*/
|
||||
u8 ssid_type; /* BIT(0) wildcard SSID
|
||||
* BIT(1) P2P wildcard SSID
|
||||
* BIT(2) specified SSID + wildcard SSID
|
||||
* BIT(2) + ssid_type_ext BIT(0) specified SSID only
|
||||
*/
|
||||
u8 ssids_num;
|
||||
u8 probe_req_num; /* Number of probe request for each SSID */
|
||||
u8 scan_func; /* BIT(0) Enable random MAC scan
|
||||
* BIT(1) Disable DBDC scan type 1~3.
|
||||
* BIT(2) Use DBDC scan type 3 (dedicated one RF to scan).
|
||||
*/
|
||||
u8 version; /* 0: Not support fields after ies.
|
||||
* 1: Support fields after ies.
|
||||
*/
|
||||
struct mt76_connac_mcu_scan_ssid ssids[4];
|
||||
__le16 probe_delay_time;
|
||||
__le16 channel_dwell_time; /* channel Dwell interval */
|
||||
__le16 timeout_value;
|
||||
u8 channel_type; /* 0: Full channels
|
||||
* 1: Only 2.4GHz channels
|
||||
* 2: Only 5GHz channels
|
||||
* 3: P2P social channel only (channel #1, #6 and #11)
|
||||
* 4: Specified channels
|
||||
* Others: Reserved
|
||||
*/
|
||||
u8 channels_num; /* valid when channel_type is 4 */
|
||||
/* valid when channels_num is set */
|
||||
struct mt76_connac_mcu_scan_channel channels[32];
|
||||
__le16 ies_len;
|
||||
u8 ies[MT76_CONNAC_SCAN_IE_LEN];
|
||||
/* following fields are valid if version > 0 */
|
||||
u8 ext_channels_num;
|
||||
u8 ext_ssids_num;
|
||||
__le16 channel_min_dwell_time;
|
||||
struct mt76_connac_mcu_scan_channel ext_channels[32];
|
||||
struct mt76_connac_mcu_scan_ssid ext_ssids[6];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 random_mac[ETH_ALEN]; /* valid when BIT(1) in scan_func is set. */
|
||||
u8 pad[63];
|
||||
u8 ssid_type_ext;
|
||||
} __packed;
|
||||
|
||||
#define MT76_CONNAC_SCAN_DONE_EVENT_MAX_CHANNEL_NUM 64
|
||||
|
||||
struct mt76_connac_hw_scan_done {
|
||||
u8 seq_num;
|
||||
u8 sparse_channel_num;
|
||||
struct mt76_connac_mcu_scan_channel sparse_channel;
|
||||
u8 complete_channel_num;
|
||||
u8 current_state;
|
||||
u8 version;
|
||||
u8 pad;
|
||||
__le32 beacon_scan_num;
|
||||
u8 pno_enabled;
|
||||
u8 pad2[3];
|
||||
u8 sparse_channel_valid_num;
|
||||
u8 pad3[3];
|
||||
u8 channel_num[MT76_CONNAC_SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
|
||||
/* idle format for channel_idle_time
|
||||
* 0: first bytes: idle time(ms) 2nd byte: dwell time(ms)
|
||||
* 1: first bytes: idle time(8ms) 2nd byte: dwell time(8ms)
|
||||
* 2: dwell time (16us)
|
||||
*/
|
||||
__le16 channel_idle_time[MT76_CONNAC_SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
|
||||
/* beacon and probe response count */
|
||||
u8 beacon_probe_num[MT76_CONNAC_SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
|
||||
u8 mdrdy_count[MT76_CONNAC_SCAN_DONE_EVENT_MAX_CHANNEL_NUM];
|
||||
__le32 beacon_2g_num;
|
||||
__le32 beacon_5g_num;
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_sched_scan_req {
|
||||
u8 version;
|
||||
u8 seq_num;
|
||||
u8 stop_on_match;
|
||||
u8 ssids_num;
|
||||
u8 match_num;
|
||||
u8 pad;
|
||||
__le16 ie_len;
|
||||
struct mt76_connac_mcu_scan_ssid ssids[MT76_CONNAC_MAX_SCHED_SCAN_SSID];
|
||||
struct mt76_connac_mcu_scan_match match[MT76_CONNAC_MAX_SCAN_MATCH];
|
||||
u8 channel_type;
|
||||
u8 channels_num;
|
||||
u8 intervals_num;
|
||||
u8 scan_func; /* BIT(0) eable random mac address */
|
||||
struct mt76_connac_mcu_scan_channel channels[64];
|
||||
__le16 intervals[MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL];
|
||||
u8 random_mac[ETH_ALEN]; /* valid when BIT(0) in scan_func is set */
|
||||
u8 pad2[58];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_sched_scan_done {
|
||||
u8 seq_num;
|
||||
u8 status; /* 0: ssid found */
|
||||
__le16 pad;
|
||||
} __packed;
|
||||
|
||||
struct bss_info_uni_he {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
__le16 he_rts_thres;
|
||||
u8 he_pe_duration;
|
||||
u8 su_disable;
|
||||
__le16 max_nss_mcs[CMD_HE_MCS_BW_NUM];
|
||||
u8 rsv[2];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_gtk_rekey_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 kek[NL80211_KEK_LEN];
|
||||
u8 kck[NL80211_KCK_LEN];
|
||||
u8 replay_ctr[NL80211_REPLAY_CTR_LEN];
|
||||
u8 rekey_mode; /* 0: rekey offload enable
|
||||
* 1: rekey offload disable
|
||||
* 2: rekey update
|
||||
*/
|
||||
u8 keyid;
|
||||
u8 pad[2];
|
||||
__le32 proto; /* WPA-RSN-WAPI-OPSN */
|
||||
__le32 pairwise_cipher;
|
||||
__le32 group_cipher;
|
||||
__le32 key_mgmt; /* NONE-PSK-IEEE802.1X */
|
||||
__le32 mgmt_group_cipher;
|
||||
u8 option; /* 1: rekey data update without enabling offload */
|
||||
u8 reserverd[3];
|
||||
} __packed;
|
||||
|
||||
#define MT76_CONNAC_WOW_MASK_MAX_LEN 16
|
||||
#define MT76_CONNAC_WOW_PATTEN_MAX_LEN 128
|
||||
|
||||
struct mt76_connac_wow_pattern_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 index; /* pattern index */
|
||||
u8 enable; /* 0: disable
|
||||
* 1: enable
|
||||
*/
|
||||
u8 data_len; /* pattern length */
|
||||
u8 pad;
|
||||
u8 mask[MT76_CONNAC_WOW_MASK_MAX_LEN];
|
||||
u8 pattern[MT76_CONNAC_WOW_PATTEN_MAX_LEN];
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_wow_ctrl_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 cmd; /* 0x1: PM_WOWLAN_REQ_START
|
||||
* 0x2: PM_WOWLAN_REQ_STOP
|
||||
* 0x3: PM_WOWLAN_PARAM_CLEAR
|
||||
*/
|
||||
u8 trigger; /* 0: NONE
|
||||
* BIT(0): NL80211_WOWLAN_TRIG_MAGIC_PKT
|
||||
* BIT(1): NL80211_WOWLAN_TRIG_ANY
|
||||
* BIT(2): NL80211_WOWLAN_TRIG_DISCONNECT
|
||||
* BIT(3): NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE
|
||||
* BIT(4): BEACON_LOST
|
||||
* BIT(5): NL80211_WOWLAN_TRIG_NET_DETECT
|
||||
*/
|
||||
u8 wakeup_hif; /* 0x0: HIF_SDIO
|
||||
* 0x1: HIF_USB
|
||||
* 0x2: HIF_PCIE
|
||||
* 0x3: HIF_GPIO
|
||||
*/
|
||||
u8 pad;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_wow_gpio_param_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 gpio_pin;
|
||||
u8 trigger_lvl;
|
||||
u8 pad[2];
|
||||
__le32 gpio_interval;
|
||||
u8 rsv[4];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_arpns_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 mode;
|
||||
u8 ips_num;
|
||||
u8 option;
|
||||
u8 pad[1];
|
||||
} __packed;
|
||||
|
||||
struct mt76_connac_suspend_tlv {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 enable; /* 0: suspend mode disabled
|
||||
* 1: suspend mode enabled
|
||||
*/
|
||||
u8 mdtim; /* LP parameter */
|
||||
u8 wow_suspend; /* 0: update by origin policy
|
||||
* 1: update by wow dtim
|
||||
*/
|
||||
u8 pad[5];
|
||||
} __packed;
|
||||
|
||||
#define to_wcid_lo(id) FIELD_GET(GENMASK(7, 0), (u16)id)
|
||||
#define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id)
|
||||
|
||||
static inline void
|
||||
mt76_connac_mcu_get_wlan_idx(struct mt76_dev *dev, struct mt76_wcid *wcid,
|
||||
u8 *wlan_idx_lo, u8 *wlan_idx_hi)
|
||||
{
|
||||
*wlan_idx_hi = 0;
|
||||
|
||||
if (is_mt7921(dev)) {
|
||||
*wlan_idx_lo = wcid ? to_wcid_lo(wcid->idx) : 0;
|
||||
*wlan_idx_hi = wcid ? to_wcid_hi(wcid->idx) : 0;
|
||||
} else {
|
||||
*wlan_idx_lo = wcid ? wcid->idx : 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct sk_buff *
|
||||
mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
|
||||
struct mt76_wcid *wcid);
|
||||
struct wtbl_req_hdr *
|
||||
mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev *dev, struct mt76_wcid *wcid,
|
||||
int cmd, void *sta_wtbl, struct sk_buff **skb);
|
||||
struct tlv *mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag,
|
||||
int len, void *sta_ntlv,
|
||||
void *sta_wtbl);
|
||||
static inline struct tlv *
|
||||
mt76_connac_mcu_add_tlv(struct sk_buff *skb, int tag, int len)
|
||||
{
|
||||
return mt76_connac_mcu_add_nested_tlv(skb, tag, len, skb->data, NULL);
|
||||
}
|
||||
|
||||
int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy);
|
||||
int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif);
|
||||
void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enable);
|
||||
void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, void *sta_wtbl,
|
||||
void *wtbl_tlv);
|
||||
void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_vif *vif);
|
||||
void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
struct ieee80211_sta *sta, void *sta_wtbl,
|
||||
void *wtbl_tlv);
|
||||
void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
struct ieee80211_ampdu_params *params,
|
||||
bool enable, bool tx, void *sta_wtbl,
|
||||
void *wtbl_tlv);
|
||||
void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
|
||||
struct ieee80211_ampdu_params *params,
|
||||
bool enable, bool tx);
|
||||
int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
struct mt76_wcid *wcid,
|
||||
bool enable);
|
||||
int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
|
||||
struct ieee80211_ampdu_params *params,
|
||||
bool enable, bool tx);
|
||||
int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
struct mt76_wcid *wcid,
|
||||
bool enable);
|
||||
int mt76_connac_mcu_add_sta_cmd(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct mt76_wcid *wcid,
|
||||
bool enable, int cmd);
|
||||
void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
|
||||
struct ieee80211_vif *vif);
|
||||
int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band);
|
||||
int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable,
|
||||
bool hdr_trans);
|
||||
int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
|
||||
u32 mode);
|
||||
int mt76_connac_mcu_start_patch(struct mt76_dev *dev);
|
||||
int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get);
|
||||
int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option);
|
||||
|
||||
int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
|
||||
struct ieee80211_scan_request *scan_req);
|
||||
int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif);
|
||||
int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_sched_scan_request *sreq);
|
||||
int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
bool enable);
|
||||
int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_gtk_rekey_data *key);
|
||||
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend);
|
||||
void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
|
||||
struct ieee80211_vif *vif);
|
||||
int mt76_connac_mcu_chip_config(struct mt76_dev *dev);
|
||||
void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
struct mt76_connac_coredump *coredump);
|
||||
#endif /* __MT76_CONNAC_MCU_H */
|
||||
|
|
@ -16,7 +16,7 @@ static int mt76x0e_start(struct ieee80211_hw *hw)
|
|||
|
||||
mt76x02_mac_start(dev);
|
||||
mt76x0_phy_calibrate(dev, true);
|
||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mt76.mac_work,
|
||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mphy.mac_work,
|
||||
MT_MAC_WORK_INTERVAL);
|
||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
|
||||
MT_CALIBRATE_INTERVAL);
|
||||
|
|
@ -28,7 +28,7 @@ static int mt76x0e_start(struct ieee80211_hw *hw)
|
|||
static void mt76x0e_stop_hw(struct mt76x02_dev *dev)
|
||||
{
|
||||
cancel_delayed_work_sync(&dev->cal_work);
|
||||
cancel_delayed_work_sync(&dev->mt76.mac_work);
|
||||
cancel_delayed_work_sync(&dev->mphy.mac_work);
|
||||
clear_bit(MT76_RESTART, &dev->mphy.state);
|
||||
|
||||
if (!mt76_poll(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_BUSY,
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ static void mt76x0u_stop(struct ieee80211_hw *hw)
|
|||
|
||||
clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
|
||||
cancel_delayed_work_sync(&dev->cal_work);
|
||||
cancel_delayed_work_sync(&dev->mt76.mac_work);
|
||||
cancel_delayed_work_sync(&dev->mphy.mac_work);
|
||||
mt76u_stop_tx(&dev->mt76);
|
||||
mt76x02u_exit_beacon_config(dev);
|
||||
|
||||
|
|
@ -108,7 +108,7 @@ static int mt76x0u_start(struct ieee80211_hw *hw)
|
|||
return ret;
|
||||
|
||||
mt76x0_phy_calibrate(dev, true);
|
||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mt76.mac_work,
|
||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mphy.mac_work,
|
||||
MT_MAC_WORK_INTERVAL);
|
||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
|
||||
MT_CALIBRATE_INTERVAL);
|
||||
|
|
|
|||
|
|
@ -82,8 +82,6 @@ struct mt76x02_dev {
|
|||
|
||||
struct mutex phy_mutex;
|
||||
|
||||
u16 chainmask;
|
||||
|
||||
u8 txdone_seq;
|
||||
DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
|
||||
spinlock_t txstatus_fifo_lock;
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
|
|||
u16 txwi_flags = 0;
|
||||
u8 nss;
|
||||
s8 txpwr_adj, max_txpwr_adj;
|
||||
u8 ccmp_pn[8], nstreams = dev->chainmask & 0xf;
|
||||
u8 ccmp_pn[8], nstreams = dev->mphy.chainmask & 0xf;
|
||||
|
||||
memset(txwi, 0, sizeof(*txwi));
|
||||
|
||||
|
|
@ -685,7 +685,7 @@ mt76x02_mac_process_rate(struct mt76x02_dev *dev,
|
|||
status->rate_idx = idx;
|
||||
break;
|
||||
case MT_PHY_TYPE_VHT: {
|
||||
u8 n_rxstream = dev->chainmask & 0xf;
|
||||
u8 n_rxstream = dev->mphy.chainmask & 0xf;
|
||||
|
||||
status->encoding = RX_ENC_VHT;
|
||||
status->rate_idx = FIELD_GET(MT_RATE_INDEX_VHT_IDX, idx);
|
||||
|
|
@ -777,7 +777,7 @@ int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
|
|||
u16 rate = le16_to_cpu(rxwi->rate);
|
||||
u16 tid_sn = le16_to_cpu(rxwi->tid_sn);
|
||||
bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST);
|
||||
int pad_len = 0, nstreams = dev->chainmask & 0xf;
|
||||
int pad_len = 0, nstreams = dev->mphy.chainmask & 0xf;
|
||||
s8 signal;
|
||||
u8 pn_len;
|
||||
u8 wcid;
|
||||
|
|
@ -1162,7 +1162,7 @@ static void mt76x02_edcca_check(struct mt76x02_dev *dev)
|
|||
void mt76x02_mac_work(struct work_struct *work)
|
||||
{
|
||||
struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev,
|
||||
mt76.mac_work.work);
|
||||
mphy.mac_work.work);
|
||||
int i, idx;
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
|
@ -1185,7 +1185,7 @@ void mt76x02_mac_work(struct work_struct *work)
|
|||
|
||||
mt76_tx_status_check(&dev->mt76, NULL, false);
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
|
||||
MT_MAC_WORK_INTERVAL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ static void mt76x02_reset_state(struct mt76x02_dev *dev)
|
|||
memset(msta, 0, sizeof(*msta));
|
||||
}
|
||||
|
||||
dev->mphy.vif_mask = 0;
|
||||
dev->mt76.vif_mask = 0;
|
||||
dev->mt76.beacon_mask = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ void mt76x02_phy_set_rxpath(struct mt76x02_dev *dev)
|
|||
val = mt76_rr(dev, MT_BBP(AGC, 0));
|
||||
val &= ~BIT(4);
|
||||
|
||||
switch (dev->chainmask & 0xf) {
|
||||
switch (dev->mphy.chainmask & 0xf) {
|
||||
case 2:
|
||||
val |= BIT(3);
|
||||
break;
|
||||
|
|
@ -35,7 +35,7 @@ void mt76x02_phy_set_txdac(struct mt76x02_dev *dev)
|
|||
{
|
||||
int txpath;
|
||||
|
||||
txpath = (dev->chainmask >> 8) & 0xf;
|
||||
txpath = (dev->mphy.chainmask >> 8) & 0xf;
|
||||
switch (txpath) {
|
||||
case 2:
|
||||
mt76_set(dev, MT_BBP(TXBE, 5), 0x3);
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
|
|||
struct ieee80211_hw *hw = mt76_hw(dev);
|
||||
struct wiphy *wiphy = hw->wiphy;
|
||||
|
||||
INIT_DELAYED_WORK(&dev->mt76.mac_work, mt76x02_mac_work);
|
||||
INIT_DELAYED_WORK(&dev->mphy.mac_work, mt76x02_mac_work);
|
||||
|
||||
hw->queues = 4;
|
||||
hw->max_rates = 1;
|
||||
|
|
@ -197,10 +197,10 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
|
|||
IEEE80211_HT_CAP_LDPC_CODING;
|
||||
dev->mphy.sband_5g.sband.ht_cap.cap |=
|
||||
IEEE80211_HT_CAP_LDPC_CODING;
|
||||
dev->chainmask = 0x202;
|
||||
dev->mphy.chainmask = 0x202;
|
||||
dev->mphy.antenna_mask = 3;
|
||||
} else {
|
||||
dev->chainmask = 0x101;
|
||||
dev->mphy.chainmask = 0x101;
|
||||
dev->mphy.antenna_mask = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -304,7 +304,7 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|||
unsigned int idx = 0;
|
||||
|
||||
/* Allow to change address in HW if we create first interface. */
|
||||
if (!dev->mphy.vif_mask &&
|
||||
if (!dev->mt76.vif_mask &&
|
||||
(((vif->addr[0] ^ dev->mphy.macaddr[0]) & ~GENMASK(4, 1)) ||
|
||||
memcmp(vif->addr + 1, dev->mphy.macaddr + 1, ETH_ALEN - 1)))
|
||||
mt76x02_mac_setaddr(dev, vif->addr);
|
||||
|
|
@ -329,11 +329,11 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
|||
idx += 8;
|
||||
|
||||
/* vif is already set or idx is 8 for AP/Mesh/... */
|
||||
if (dev->mphy.vif_mask & BIT(idx) ||
|
||||
if (dev->mt76.vif_mask & BIT(idx) ||
|
||||
(vif->type != NL80211_IFTYPE_STATION && idx > 7))
|
||||
return -EBUSY;
|
||||
|
||||
dev->mphy.vif_mask |= BIT(idx);
|
||||
dev->mt76.vif_mask |= BIT(idx);
|
||||
|
||||
mt76x02_vif_init(dev, vif, idx);
|
||||
return 0;
|
||||
|
|
@ -346,7 +346,7 @@ void mt76x02_remove_interface(struct ieee80211_hw *hw,
|
|||
struct mt76x02_dev *dev = hw->priv;
|
||||
struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
|
||||
|
||||
dev->mphy.vif_mask &= ~BIT(mvif->idx);
|
||||
dev->mt76.vif_mask &= ~BIT(mvif->idx);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mt76x02_remove_interface);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ int mt76x2_mcu_set_channel(struct mt76x02_dev *dev, u8 channel, u8 bw,
|
|||
.idx = channel,
|
||||
.scan = scan,
|
||||
.bw = bw,
|
||||
.chainmask = cpu_to_le16(dev->chainmask),
|
||||
.chainmask = cpu_to_le16(dev->mphy.chainmask),
|
||||
};
|
||||
|
||||
/* first set the channel without the extension channel info */
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ static int mt76x2_init_hardware(struct mt76x02_dev *dev)
|
|||
void mt76x2_stop_hardware(struct mt76x02_dev *dev)
|
||||
{
|
||||
cancel_delayed_work_sync(&dev->cal_work);
|
||||
cancel_delayed_work_sync(&dev->mt76.mac_work);
|
||||
cancel_delayed_work_sync(&dev->mphy.mac_work);
|
||||
cancel_delayed_work_sync(&dev->wdt_work);
|
||||
clear_bit(MT76_RESTART, &dev->mphy.state);
|
||||
mt76x02_mcu_set_radio_state(dev, false);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ mt76x2_start(struct ieee80211_hw *hw)
|
|||
mt76x02_mac_start(dev);
|
||||
mt76x2_phy_start(dev);
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
|
||||
MT_MAC_WORK_INTERVAL);
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->wdt_work,
|
||||
MT_WATCHDOG_TIME);
|
||||
|
|
@ -116,7 +116,7 @@ static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant,
|
|||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
dev->chainmask = (tx_ant == 3) ? 0x202 : 0x101;
|
||||
dev->mphy.chainmask = (tx_ant == 3) ? 0x202 : 0x101;
|
||||
dev->mphy.antenna_mask = tx_ant;
|
||||
|
||||
mt76_set_stream_caps(&dev->mphy, true);
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ int mt76x2u_register_device(struct mt76x02_dev *dev)
|
|||
void mt76x2u_stop_hw(struct mt76x02_dev *dev)
|
||||
{
|
||||
cancel_delayed_work_sync(&dev->cal_work);
|
||||
cancel_delayed_work_sync(&dev->mt76.mac_work);
|
||||
cancel_delayed_work_sync(&dev->mphy.mac_work);
|
||||
mt76x2u_mac_stop(dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ static int mt76x2u_start(struct ieee80211_hw *hw)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
|
||||
MT_MAC_WORK_INTERVAL);
|
||||
set_bit(MT76_STATE_RUNNING, &dev->mphy.state);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,32 @@
|
|||
|
||||
/** global debugfs **/
|
||||
|
||||
static int
|
||||
mt7915_implicit_txbf_set(void *data, u64 val)
|
||||
{
|
||||
struct mt7915_dev *dev = data;
|
||||
|
||||
if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
|
||||
return -EBUSY;
|
||||
|
||||
dev->ibf = !!val;
|
||||
|
||||
return mt7915_mcu_set_txbf_type(dev);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_implicit_txbf_get(void *data, u64 *val)
|
||||
{
|
||||
struct mt7915_dev *dev = data;
|
||||
|
||||
*val = dev->ibf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_implicit_txbf, mt7915_implicit_txbf_get,
|
||||
mt7915_implicit_txbf_set, "%lld\n");
|
||||
|
||||
/* test knob of system layer 1/2 error recovery */
|
||||
static int mt7915_ser_trigger_set(void *data, u64 val)
|
||||
{
|
||||
|
|
@ -355,6 +381,8 @@ int mt7915_init_debugfs(struct mt7915_dev *dev)
|
|||
mt7915_queues_acq);
|
||||
debugfs_create_file("tx_stats", 0400, dir, dev, &fops_tx_stats);
|
||||
debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
|
||||
debugfs_create_file("implicit_txbf", 0600, dir, dev,
|
||||
&fops_implicit_txbf);
|
||||
debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
|
||||
/* test knobs */
|
||||
debugfs_create_file("radar_trigger", 0200, dir, dev,
|
||||
|
|
|
|||
|
|
@ -73,34 +73,41 @@ static int mt7915_poll_tx(struct napi_struct *napi, int budget)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void mt7915_dma_prefetch(struct mt7915_dev *dev)
|
||||
static void __mt7915_dma_prefetch(struct mt7915_dev *dev, u32 ofs)
|
||||
{
|
||||
#define PREFETCH(base, depth) ((base) << 16 | (depth))
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL, PREFETCH(0x0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING1_EXT_CTRL, PREFETCH(0x40, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL, PREFETCH(0x80, 0x0));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL + ofs, PREFETCH(0x0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING1_EXT_CTRL + ofs, PREFETCH(0x40, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL + ofs, PREFETCH(0x80, 0x0));
|
||||
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING0_EXT_CTRL, PREFETCH(0x80, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING1_EXT_CTRL, PREFETCH(0xc0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING2_EXT_CTRL, PREFETCH(0x100, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING3_EXT_CTRL, PREFETCH(0x140, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING4_EXT_CTRL, PREFETCH(0x180, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING5_EXT_CTRL, PREFETCH(0x1c0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING6_EXT_CTRL, PREFETCH(0x200, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING7_EXT_CTRL, PREFETCH(0x240, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING0_EXT_CTRL + ofs, PREFETCH(0x80, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING1_EXT_CTRL + ofs, PREFETCH(0xc0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING2_EXT_CTRL + ofs, PREFETCH(0x100, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING3_EXT_CTRL + ofs, PREFETCH(0x140, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING4_EXT_CTRL + ofs, PREFETCH(0x180, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING5_EXT_CTRL + ofs, PREFETCH(0x1c0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING6_EXT_CTRL + ofs, PREFETCH(0x200, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING7_EXT_CTRL + ofs, PREFETCH(0x240, 0x4));
|
||||
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING16_EXT_CTRL, PREFETCH(0x280, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING17_EXT_CTRL, PREFETCH(0x2c0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING18_EXT_CTRL, PREFETCH(0x300, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING19_EXT_CTRL, PREFETCH(0x340, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING20_EXT_CTRL, PREFETCH(0x380, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING21_EXT_CTRL, PREFETCH(0x3c0, 0x0));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING16_EXT_CTRL + ofs, PREFETCH(0x280, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING17_EXT_CTRL + ofs, PREFETCH(0x2c0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING18_EXT_CTRL + ofs, PREFETCH(0x300, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING19_EXT_CTRL + ofs, PREFETCH(0x340, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING20_EXT_CTRL + ofs, PREFETCH(0x380, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_TX_RING21_EXT_CTRL + ofs, PREFETCH(0x3c0, 0x0));
|
||||
|
||||
mt76_wr(dev, MT_WFDMA1_RX_RING0_EXT_CTRL, PREFETCH(0x3c0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_RX_RING1_EXT_CTRL, PREFETCH(0x400, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_RX_RING2_EXT_CTRL, PREFETCH(0x440, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_RX_RING3_EXT_CTRL, PREFETCH(0x480, 0x0));
|
||||
mt76_wr(dev, MT_WFDMA1_RX_RING0_EXT_CTRL + ofs, PREFETCH(0x3c0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_RX_RING1_EXT_CTRL + ofs, PREFETCH(0x400, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_RX_RING2_EXT_CTRL + ofs, PREFETCH(0x440, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA1_RX_RING3_EXT_CTRL + ofs, PREFETCH(0x480, 0x0));
|
||||
}
|
||||
|
||||
void mt7915_dma_prefetch(struct mt7915_dev *dev)
|
||||
{
|
||||
__mt7915_dma_prefetch(dev, 0);
|
||||
if (dev->hif2)
|
||||
__mt7915_dma_prefetch(dev, MT_WFDMA1_PCIE1_BASE - MT_WFDMA1_BASE);
|
||||
}
|
||||
|
||||
static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr)
|
||||
|
|
@ -204,6 +211,7 @@ int mt7915_dma_init(struct mt7915_dev *dev)
|
|||
/* Increase buffer size to receive large VHT/HE MPDUs */
|
||||
struct mt76_bus_ops *bus_ops;
|
||||
int rx_buf_size = MT_RX_BUF_SIZE * 2;
|
||||
u32 hif1_ofs = 0;
|
||||
int ret;
|
||||
|
||||
dev->bus_ops = dev->mt76.bus;
|
||||
|
|
@ -219,14 +227,14 @@ int mt7915_dma_init(struct mt7915_dev *dev)
|
|||
|
||||
mt76_dma_attach(&dev->mt76);
|
||||
|
||||
if (dev->hif2)
|
||||
hif1_ofs = MT_WFDMA1_PCIE1_BASE - MT_WFDMA1_BASE;
|
||||
|
||||
/* configure global setting */
|
||||
mt76_set(dev, MT_WFDMA1_GLO_CFG,
|
||||
MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
|
||||
MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
|
||||
|
||||
/* configure perfetch settings */
|
||||
mt7915_dma_prefetch(dev);
|
||||
|
||||
/* reset dma idx */
|
||||
mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
|
||||
mt76_wr(dev, MT_WFDMA1_RST_DTX_PTR, ~0);
|
||||
|
|
@ -235,6 +243,21 @@ int mt7915_dma_init(struct mt7915_dev *dev)
|
|||
mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
|
||||
mt76_wr(dev, MT_WFDMA1_PRI_DLY_INT_CFG0, 0);
|
||||
|
||||
if (dev->hif2) {
|
||||
mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
|
||||
MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
|
||||
MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR + hif1_ofs, ~0);
|
||||
mt76_wr(dev, MT_WFDMA1_RST_DTX_PTR + hif1_ofs, ~0);
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0 + hif1_ofs, 0);
|
||||
mt76_wr(dev, MT_WFDMA1_PRI_DLY_INT_CFG0 + hif1_ofs, 0);
|
||||
}
|
||||
|
||||
/* configure perfetch settings */
|
||||
mt7915_dma_prefetch(dev);
|
||||
|
||||
/* init tx queue */
|
||||
ret = mt7915_init_tx_queues(&dev->phy, MT7915_TXQ_BAND0,
|
||||
MT7915_TX_RING_SIZE);
|
||||
|
|
@ -283,7 +306,17 @@ int mt7915_dma_init(struct mt7915_dev *dev)
|
|||
if (dev->dbdc_support) {
|
||||
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT],
|
||||
MT7915_RXQ_BAND1, MT7915_RX_RING_SIZE,
|
||||
rx_buf_size, MT_RX_DATA_RING_BASE);
|
||||
rx_buf_size,
|
||||
MT_RX_DATA_RING_BASE + hif1_ofs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* event from WA */
|
||||
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_EXT_WA],
|
||||
MT7915_RXQ_MCU_WA_EXT,
|
||||
MT7915_RX_MCU_RING_SIZE,
|
||||
rx_buf_size,
|
||||
MT_RX_EVENT_RING_BASE + hif1_ofs);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -326,6 +359,17 @@ int mt7915_dma_init(struct mt7915_dev *dev)
|
|||
mt76_set(dev, MT_WFDMA1_GLO_CFG,
|
||||
MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN);
|
||||
|
||||
if (dev->hif2) {
|
||||
mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
|
||||
(MT_WFDMA0_GLO_CFG_TX_DMA_EN |
|
||||
MT_WFDMA0_GLO_CFG_RX_DMA_EN));
|
||||
mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
|
||||
(MT_WFDMA1_GLO_CFG_TX_DMA_EN |
|
||||
MT_WFDMA1_GLO_CFG_RX_DMA_EN));
|
||||
mt76_set(dev, MT_WFDMA_HOST_CONFIG,
|
||||
MT_WFDMA_HOST_CONFIG_PDMA_BAND);
|
||||
}
|
||||
|
||||
/* enable interrupts for TX/RX rings */
|
||||
mt7915_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_MCU |
|
||||
MT_INT_MCU_CMD);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,10 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memset(dev->mt76.eeprom.data, -1, MT7915_EEPROM_SIZE);
|
||||
if (ret)
|
||||
dev->flash_mode = true;
|
||||
else
|
||||
memset(dev->mt76.eeprom.data, -1, MT7915_EEPROM_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -50,12 +53,15 @@ void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
|
|||
u32 val;
|
||||
|
||||
val = mt7915_eeprom_read(dev, MT_EE_WIFI_CONF + ext_phy);
|
||||
val = FIELD_GET(MT_EE_WIFI_CONF_BAND_SEL, val);
|
||||
val = FIELD_GET(MT_EE_WIFI_CONF0_BAND_SEL, val);
|
||||
if (val == MT_EE_BAND_SEL_DEFAULT && dev->dbdc_support)
|
||||
val = ext_phy ? MT_EE_BAND_SEL_5GHZ : MT_EE_BAND_SEL_2GHZ;
|
||||
|
||||
switch (val) {
|
||||
case MT_EE_5GHZ:
|
||||
case MT_EE_BAND_SEL_5GHZ:
|
||||
phy->mt76->cap.has_5ghz = true;
|
||||
break;
|
||||
case MT_EE_2GHZ:
|
||||
case MT_EE_BAND_SEL_2GHZ:
|
||||
phy->mt76->cap.has_2ghz = true;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -67,26 +73,30 @@ void mt7915_eeprom_parse_band_config(struct mt7915_phy *phy)
|
|||
|
||||
static void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev)
|
||||
{
|
||||
u8 nss, tx_mask[2] = {}, *eeprom = dev->mt76.eeprom.data;
|
||||
u8 nss, nss_band, *eeprom = dev->mt76.eeprom.data;
|
||||
|
||||
mt7915_eeprom_parse_band_config(&dev->phy);
|
||||
|
||||
/* read tx mask from eeprom */
|
||||
tx_mask[0] = FIELD_GET(MT_EE_WIFI_CONF_TX_MASK,
|
||||
eeprom[MT_EE_WIFI_CONF]);
|
||||
if (dev->dbdc_support)
|
||||
tx_mask[1] = FIELD_GET(MT_EE_WIFI_CONF_TX_MASK,
|
||||
eeprom[MT_EE_WIFI_CONF + 1]);
|
||||
|
||||
nss = tx_mask[0] + tx_mask[1];
|
||||
if (!nss || nss > 4) {
|
||||
tx_mask[0] = 4;
|
||||
nss = FIELD_GET(MT_EE_WIFI_CONF0_TX_PATH, eeprom[MT_EE_WIFI_CONF]);
|
||||
if (!nss || nss > 4)
|
||||
nss = 4;
|
||||
|
||||
nss_band = nss;
|
||||
|
||||
if (dev->dbdc_support) {
|
||||
nss_band = FIELD_GET(MT_EE_WIFI_CONF3_TX_PATH_B0,
|
||||
eeprom[MT_EE_WIFI_CONF + 3]);
|
||||
if (!nss_band || nss_band > 2)
|
||||
nss_band = 2;
|
||||
|
||||
if (nss_band >= nss)
|
||||
nss = 4;
|
||||
}
|
||||
|
||||
dev->chainmask = BIT(nss) - 1;
|
||||
dev->mphy.antenna_mask = BIT(tx_mask[0]) - 1;
|
||||
dev->phy.chainmask = dev->mphy.antenna_mask;
|
||||
dev->mphy.antenna_mask = BIT(nss_band) - 1;
|
||||
dev->mphy.chainmask = dev->mphy.antenna_mask;
|
||||
}
|
||||
|
||||
int mt7915_eeprom_init(struct mt7915_dev *dev)
|
||||
|
|
|
|||
|
|
@ -25,17 +25,20 @@ enum mt7915_eeprom_field {
|
|||
__MT_EE_MAX = 0xe00
|
||||
};
|
||||
|
||||
#define MT_EE_WIFI_CONF_TX_MASK GENMASK(2, 0)
|
||||
#define MT_EE_WIFI_CONF_BAND_SEL GENMASK(7, 6)
|
||||
#define MT_EE_WIFI_CONF_TSSI0_2G BIT(0)
|
||||
#define MT_EE_WIFI_CONF_TSSI0_5G BIT(2)
|
||||
#define MT_EE_WIFI_CONF_TSSI1_5G BIT(4)
|
||||
#define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0)
|
||||
#define MT_EE_WIFI_CONF0_BAND_SEL GENMASK(7, 6)
|
||||
#define MT_EE_WIFI_CONF1_BAND_SEL GENMASK(7, 6)
|
||||
#define MT_EE_WIFI_CONF3_TX_PATH_B0 GENMASK(1, 0)
|
||||
#define MT_EE_WIFI_CONF3_TX_PATH_B1 GENMASK(5, 4)
|
||||
#define MT_EE_WIFI_CONF7_TSSI0_2G BIT(0)
|
||||
#define MT_EE_WIFI_CONF7_TSSI0_5G BIT(2)
|
||||
#define MT_EE_WIFI_CONF7_TSSI1_5G BIT(4)
|
||||
|
||||
enum mt7915_eeprom_band {
|
||||
MT_EE_DUAL_BAND,
|
||||
MT_EE_5GHZ,
|
||||
MT_EE_2GHZ,
|
||||
MT_EE_DBDC,
|
||||
MT_EE_BAND_SEL_DEFAULT,
|
||||
MT_EE_BAND_SEL_5GHZ,
|
||||
MT_EE_BAND_SEL_2GHZ,
|
||||
MT_EE_BAND_SEL_DUAL,
|
||||
};
|
||||
|
||||
#define SKU_DELTA_VAL GENMASK(5, 0)
|
||||
|
|
@ -116,9 +119,9 @@ mt7915_tssi_enabled(struct mt7915_dev *dev, enum nl80211_band band)
|
|||
|
||||
/* TODO: DBDC */
|
||||
if (band == NL80211_BAND_5GHZ)
|
||||
return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF_TSSI0_5G;
|
||||
return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF7_TSSI0_5G;
|
||||
else
|
||||
return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF_TSSI0_2G;
|
||||
return eep[MT_EE_WIFI_CONF + 7] & MT_EE_WIFI_CONF7_TSSI0_2G;
|
||||
}
|
||||
|
||||
extern const struct sku_group mt7915_sku_groups[];
|
||||
|
|
|
|||
|
|
@ -169,18 +169,19 @@ static int mt7915_txbf_init(struct mt7915_dev *dev)
|
|||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* TODO: DBDC & check whether iBF phase calibration data has
|
||||
* been stored in eeprom offset 0x651~0x7b8, then write down
|
||||
* 0x1111 into 0x651 and 0x651 to trigger iBF.
|
||||
*/
|
||||
|
||||
if (dev->dbdc_support) {
|
||||
ret = mt7915_mcu_set_txbf_module(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* trigger sounding packets */
|
||||
ret = mt7915_mcu_set_txbf_sounding(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* enable iBF & eBF */
|
||||
/* enable eBF */
|
||||
return mt7915_mcu_set_txbf_type(dev);
|
||||
}
|
||||
|
||||
|
|
@ -235,12 +236,12 @@ static int mt7915_register_ext_phy(struct mt7915_dev *dev)
|
|||
phy = mphy->priv;
|
||||
phy->dev = dev;
|
||||
phy->mt76 = mphy;
|
||||
phy->chainmask = dev->chainmask & ~dev->phy.chainmask;
|
||||
mphy->antenna_mask = BIT(hweight8(phy->chainmask)) - 1;
|
||||
mphy->chainmask = dev->chainmask & ~dev->mphy.chainmask;
|
||||
mphy->antenna_mask = BIT(hweight8(mphy->chainmask)) - 1;
|
||||
mt7915_init_wiphy(mphy->hw);
|
||||
|
||||
INIT_LIST_HEAD(&phy->stats_list);
|
||||
INIT_DELAYED_WORK(&phy->mac_work, mt7915_mac_work);
|
||||
INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work);
|
||||
|
||||
mt7915_eeprom_parse_band_config(phy);
|
||||
mt7915_set_stream_vht_txbf_caps(phy);
|
||||
|
|
@ -329,7 +330,7 @@ static int mt7915_init_hardware(struct mt7915_dev *dev)
|
|||
|
||||
void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy)
|
||||
{
|
||||
int nss = hweight8(phy->chainmask);
|
||||
int nss = hweight8(phy->mt76->chainmask);
|
||||
u32 *cap = &phy->mt76->sband_5g.sband.vht_cap.cap;
|
||||
|
||||
*cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
|
||||
|
|
@ -440,8 +441,7 @@ static int
|
|||
mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
|
||||
struct ieee80211_sband_iftype_data *data)
|
||||
{
|
||||
int i, idx = 0;
|
||||
int nss = hweight8(phy->chainmask);
|
||||
int i, idx = 0, nss = hweight8(phy->mt76->chainmask);
|
||||
u16 mcs_map = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
|
@ -622,7 +622,7 @@ int mt7915_register_device(struct mt7915_dev *dev)
|
|||
dev->mt76.phy.priv = &dev->phy;
|
||||
INIT_LIST_HEAD(&dev->phy.stats_list);
|
||||
INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work);
|
||||
INIT_DELAYED_WORK(&dev->phy.mac_work, mt7915_mac_work);
|
||||
INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work);
|
||||
INIT_LIST_HEAD(&dev->sta_rc_list);
|
||||
INIT_LIST_HEAD(&dev->sta_poll_list);
|
||||
spin_lock_init(&dev->sta_poll_lock);
|
||||
|
|
@ -648,8 +648,8 @@ int mt7915_register_device(struct mt7915_dev *dev)
|
|||
dev->mphy.sband_5g.sband.vht_cap.cap |=
|
||||
IEEE80211_VHT_CAP_SHORT_GI_160 |
|
||||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
|
||||
dev->mphy.hw->wiphy->available_antennas_rx = dev->phy.chainmask;
|
||||
dev->mphy.hw->wiphy->available_antennas_tx = dev->phy.chainmask;
|
||||
dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;
|
||||
dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;
|
||||
|
||||
mt76_set_stream_caps(&dev->mphy, true);
|
||||
mt7915_set_stream_vht_txbf_caps(&dev->phy);
|
||||
|
|
@ -672,28 +672,12 @@ int mt7915_register_device(struct mt7915_dev *dev)
|
|||
|
||||
void mt7915_unregister_device(struct mt7915_dev *dev)
|
||||
{
|
||||
struct mt76_txwi_cache *txwi;
|
||||
int id;
|
||||
|
||||
mt7915_unregister_ext_phy(dev);
|
||||
mt76_unregister_device(&dev->mt76);
|
||||
mt7915_mcu_exit(dev);
|
||||
mt7915_dma_cleanup(dev);
|
||||
|
||||
spin_lock_bh(&dev->token_lock);
|
||||
idr_for_each_entry(&dev->token, txwi, id) {
|
||||
mt7915_txp_skb_unmap(&dev->mt76, txwi);
|
||||
if (txwi->skb) {
|
||||
struct ieee80211_hw *hw;
|
||||
|
||||
hw = mt76_tx_status_get_hw(&dev->mt76, txwi->skb);
|
||||
ieee80211_free_txskb(hw, txwi->skb);
|
||||
}
|
||||
mt76_put_txwi(&dev->mt76, txwi);
|
||||
dev->token_count--;
|
||||
}
|
||||
spin_unlock_bh(&dev->token_lock);
|
||||
idr_destroy(&dev->token);
|
||||
mt7915_tx_token_put(dev);
|
||||
|
||||
mt76_free_device(&dev->mt76);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -565,13 +565,20 @@ int mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
|
|||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
|
||||
{
|
||||
struct mt7915_phy *phy = &dev->phy;
|
||||
__le32 *rxd = (__le32 *)skb->data;
|
||||
__le32 *rxv_hdr = rxd + 2;
|
||||
__le32 *rxv = rxd + 4;
|
||||
u32 rcpi, ib_rssi, wb_rssi, v20, v21;
|
||||
bool ext_phy;
|
||||
s32 foe;
|
||||
u8 snr;
|
||||
int i;
|
||||
|
||||
ext_phy = FIELD_GET(MT_RXV_HDR_BAND_IDX, le32_to_cpu(rxv_hdr[1]));
|
||||
if (ext_phy)
|
||||
phy = mt7915_ext_phy(dev);
|
||||
|
||||
rcpi = le32_to_cpu(rxv[6]);
|
||||
ib_rssi = le32_to_cpu(rxv[7]);
|
||||
wb_rssi = le32_to_cpu(rxv[8]) >> 5;
|
||||
|
|
@ -580,9 +587,9 @@ void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
|
|||
if (i == 3)
|
||||
wb_rssi = le32_to_cpu(rxv[9]);
|
||||
|
||||
dev->test.last_rcpi[i] = rcpi & 0xff;
|
||||
dev->test.last_ib_rssi[i] = ib_rssi & 0xff;
|
||||
dev->test.last_wb_rssi[i] = wb_rssi & 0xff;
|
||||
phy->test.last_rcpi[i] = rcpi & 0xff;
|
||||
phy->test.last_ib_rssi[i] = ib_rssi & 0xff;
|
||||
phy->test.last_wb_rssi[i] = wb_rssi & 0xff;
|
||||
}
|
||||
|
||||
v20 = le32_to_cpu(rxv[20]);
|
||||
|
|
@ -593,26 +600,26 @@ void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
|
|||
|
||||
snr = FIELD_GET(MT_CRXV_SNR, v20) - 16;
|
||||
|
||||
dev->test.last_freq_offset = foe;
|
||||
dev->test.last_snr = snr;
|
||||
phy->test.last_freq_offset = foe;
|
||||
phy->test.last_snr = snr;
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy,
|
||||
__le32 *txwi, struct sk_buff *skb)
|
||||
mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
struct mt76_testmode_data *td = &dev->mt76.test;
|
||||
struct mt76_testmode_data *td = &phy->mt76->test;
|
||||
u8 rate_idx = td->tx_rate_idx;
|
||||
u8 nss = td->tx_rate_nss;
|
||||
u8 bw, mode;
|
||||
u16 rateval = 0;
|
||||
u32 val;
|
||||
|
||||
if (skb != dev->mt76.test.tx_skb)
|
||||
if (skb != phy->mt76->test.tx_skb)
|
||||
return;
|
||||
|
||||
switch (td->tx_rate_mode) {
|
||||
|
|
@ -644,7 +651,7 @@ mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy,
|
|||
break;
|
||||
}
|
||||
|
||||
switch (mphy->chandef.width) {
|
||||
switch (phy->mt76->chandef.width) {
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
bw = 1;
|
||||
break;
|
||||
|
|
@ -693,12 +700,12 @@ mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy,
|
|||
if (mode >= MT_PHY_TYPE_HE_SU)
|
||||
val |= FIELD_PREP(MT_TXD6_HELTF, td->tx_ltf);
|
||||
|
||||
if (td->tx_rate_ldpc)
|
||||
if (td->tx_rate_ldpc || bw > 0)
|
||||
val |= MT_TXD6_LDPC;
|
||||
|
||||
txwi[6] |= cpu_to_le32(val);
|
||||
txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
|
||||
dev->test.spe_idx));
|
||||
phy->test.spe_idx));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -902,8 +909,8 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
|
|||
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
|
||||
}
|
||||
|
||||
if (mt76_testmode_enabled(&dev->mt76))
|
||||
mt7915_mac_write_txwi_tm(dev, mphy, txwi, skb);
|
||||
if (mt76_testmode_enabled(mphy))
|
||||
mt7915_mac_write_txwi_tm(mphy->priv, txwi, skb);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -942,6 +949,9 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||
int id, i, nbuf = tx_info->nbuf - 1;
|
||||
u8 *txwi = (u8 *)txwi_ptr;
|
||||
|
||||
if (unlikely(tx_info->skb->len <= ETH_HLEN))
|
||||
return -EINVAL;
|
||||
|
||||
if (!wcid)
|
||||
wcid = &dev->mt76.global_wcid;
|
||||
|
||||
|
|
@ -1048,20 +1058,19 @@ mt7915_tx_complete_status(struct mt76_dev *mdev, struct sk_buff *skb,
|
|||
status.rate = &msta->stats.tx_rate;
|
||||
}
|
||||
|
||||
hw = mt76_tx_status_get_hw(mdev, skb);
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
if (skb == mdev->test.tx_skb) {
|
||||
if (mt76_is_testmode_skb(mdev, skb, &hw)) {
|
||||
struct mt7915_phy *phy = mt7915_hw_phy(hw);
|
||||
struct ieee80211_vif *vif = phy->monitor_vif;
|
||||
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
|
||||
|
||||
mt76_tx_complete_skb(mdev, mvif->sta.wcid.idx, skb);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
hw = mt76_tx_status_get_hw(mdev, skb);
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_AMPDU)
|
||||
info->flags |= IEEE80211_TX_STAT_AMPDU;
|
||||
|
||||
|
|
@ -1353,7 +1362,7 @@ mt7915_phy_get_nf(struct mt7915_phy *phy, int idx)
|
|||
u32 val, sum = 0, n = 0;
|
||||
int nss, i;
|
||||
|
||||
for (nss = 0; nss < hweight8(phy->chainmask); nss++) {
|
||||
for (nss = 0; nss < hweight8(phy->mt76->chainmask); nss++) {
|
||||
u32 reg = MT_WF_IRPI(nss + (idx << dev->dbdc_support));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(nf_power); i++, reg += 4) {
|
||||
|
|
@ -1434,7 +1443,15 @@ mt7915_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
|||
{
|
||||
struct ieee80211_hw *hw = priv;
|
||||
|
||||
mt7915_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon);
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_AP:
|
||||
mt7915_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1457,12 +1474,21 @@ mt7915_dma_reset(struct mt7915_phy *phy)
|
|||
{
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
struct mt76_phy *mphy_ext = dev->mt76.phy2;
|
||||
u32 hif1_ofs = MT_WFDMA1_PCIE1_BASE - MT_WFDMA1_BASE;
|
||||
int i;
|
||||
|
||||
mt76_clear(dev, MT_WFDMA0_GLO_CFG,
|
||||
MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
|
||||
mt76_clear(dev, MT_WFDMA1_GLO_CFG,
|
||||
MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN);
|
||||
if (dev->hif2) {
|
||||
mt76_clear(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
|
||||
(MT_WFDMA0_GLO_CFG_TX_DMA_EN |
|
||||
MT_WFDMA0_GLO_CFG_RX_DMA_EN));
|
||||
mt76_clear(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
|
||||
(MT_WFDMA1_GLO_CFG_TX_DMA_EN |
|
||||
MT_WFDMA1_GLO_CFG_RX_DMA_EN));
|
||||
}
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WA], true);
|
||||
|
|
@ -1483,6 +1509,35 @@ mt7915_dma_reset(struct mt7915_phy *phy)
|
|||
MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
|
||||
mt76_set(dev, MT_WFDMA1_GLO_CFG,
|
||||
MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN);
|
||||
if (dev->hif2) {
|
||||
mt76_set(dev, MT_WFDMA0_GLO_CFG + hif1_ofs,
|
||||
(MT_WFDMA0_GLO_CFG_TX_DMA_EN |
|
||||
MT_WFDMA0_GLO_CFG_RX_DMA_EN));
|
||||
mt76_set(dev, MT_WFDMA1_GLO_CFG + hif1_ofs,
|
||||
(MT_WFDMA1_GLO_CFG_TX_DMA_EN |
|
||||
MT_WFDMA1_GLO_CFG_RX_DMA_EN));
|
||||
}
|
||||
}
|
||||
|
||||
void mt7915_tx_token_put(struct mt7915_dev *dev)
|
||||
{
|
||||
struct mt76_txwi_cache *txwi;
|
||||
int id;
|
||||
|
||||
spin_lock_bh(&dev->token_lock);
|
||||
idr_for_each_entry(&dev->token, txwi, id) {
|
||||
mt7915_txp_skb_unmap(&dev->mt76, txwi);
|
||||
if (txwi->skb) {
|
||||
struct ieee80211_hw *hw;
|
||||
|
||||
hw = mt76_tx_status_get_hw(&dev->mt76, txwi->skb);
|
||||
ieee80211_free_txskb(hw, txwi->skb);
|
||||
}
|
||||
mt76_put_txwi(&dev->mt76, txwi);
|
||||
dev->token_count--;
|
||||
}
|
||||
spin_unlock_bh(&dev->token_lock);
|
||||
idr_destroy(&dev->token);
|
||||
}
|
||||
|
||||
/* system error recovery */
|
||||
|
|
@ -1506,9 +1561,9 @@ void mt7915_mac_reset_work(struct work_struct *work)
|
|||
set_bit(MT76_RESET, &dev->mphy.state);
|
||||
set_bit(MT76_MCU_RESET, &dev->mphy.state);
|
||||
wake_up(&dev->mt76.mcu.wait);
|
||||
cancel_delayed_work_sync(&dev->phy.mac_work);
|
||||
cancel_delayed_work_sync(&dev->mphy.mac_work);
|
||||
if (phy2)
|
||||
cancel_delayed_work_sync(&phy2->mac_work);
|
||||
cancel_delayed_work_sync(&phy2->mt76->mac_work);
|
||||
|
||||
/* lock/unlock all queues to ensure that no tx is pending */
|
||||
mt76_txq_schedule_all(&dev->mphy);
|
||||
|
|
@ -1525,6 +1580,9 @@ void mt7915_mac_reset_work(struct work_struct *work)
|
|||
|
||||
mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_DMA_STOPPED);
|
||||
|
||||
mt7915_tx_token_put(dev);
|
||||
idr_init(&dev->token);
|
||||
|
||||
if (mt7915_wait_reset_state(dev, MT_MCU_CMD_RESET_DONE)) {
|
||||
mt7915_dma_reset(&dev->phy);
|
||||
|
||||
|
|
@ -1559,10 +1617,11 @@ void mt7915_mac_reset_work(struct work_struct *work)
|
|||
|
||||
mt7915_update_beacons(dev);
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->phy.mac_work,
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
|
||||
MT7915_WATCHDOG_TIME);
|
||||
if (phy2)
|
||||
ieee80211_queue_delayed_work(ext_phy->hw, &phy2->mac_work,
|
||||
ieee80211_queue_delayed_work(ext_phy->hw,
|
||||
&phy2->mt76->mac_work,
|
||||
MT7915_WATCHDOG_TIME);
|
||||
}
|
||||
|
||||
|
|
@ -1673,17 +1732,17 @@ void mt7915_mac_sta_rc_work(struct work_struct *work)
|
|||
void mt7915_mac_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7915_phy *phy;
|
||||
struct mt76_dev *mdev;
|
||||
struct mt76_phy *mphy;
|
||||
|
||||
phy = (struct mt7915_phy *)container_of(work, struct mt7915_phy,
|
||||
mac_work.work);
|
||||
mdev = &phy->dev->mt76;
|
||||
mphy = (struct mt76_phy *)container_of(work, struct mt76_phy,
|
||||
mac_work.work);
|
||||
phy = mphy->priv;
|
||||
|
||||
mutex_lock(&mdev->mutex);
|
||||
mutex_lock(&mphy->dev->mutex);
|
||||
|
||||
mt76_update_survey(mdev);
|
||||
if (++phy->mac_work_count == 5) {
|
||||
phy->mac_work_count = 0;
|
||||
mt76_update_survey(mphy->dev);
|
||||
if (++mphy->mac_work_count == 5) {
|
||||
mphy->mac_work_count = 0;
|
||||
|
||||
mt7915_mac_update_mib_stats(phy);
|
||||
}
|
||||
|
|
@ -1691,11 +1750,11 @@ void mt7915_mac_work(struct work_struct *work)
|
|||
if (++phy->sta_work_count == 10) {
|
||||
phy->sta_work_count = 0;
|
||||
mt7915_mac_sta_stats_work(phy);
|
||||
};
|
||||
}
|
||||
|
||||
mutex_unlock(&mdev->mutex);
|
||||
mutex_unlock(&mphy->dev->mutex);
|
||||
|
||||
ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
|
||||
ieee80211_queue_delayed_work(mphy->hw, &mphy->mac_work,
|
||||
MT7915_WATCHDOG_TIME);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ enum rx_pkt_type {
|
|||
#define MT_RXD3_NORMAL_PF_MODE BIT(29)
|
||||
#define MT_RXD3_NORMAL_PF_STS GENMASK(31, 30)
|
||||
|
||||
#define MT_RXV_HDR_BAND_IDX BIT(24)
|
||||
|
||||
/* P-RXV */
|
||||
#define MT_PRXV_TX_RATE GENMASK(6, 0)
|
||||
#define MT_PRXV_TX_DCM BIT(4)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ static int mt7915_start(struct ieee80211_hw *hw)
|
|||
struct mt7915_phy *phy = mt7915_hw_phy(hw);
|
||||
bool running;
|
||||
|
||||
flush_work(&dev->init_work);
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
running = mt7915_dev_running(dev);
|
||||
|
|
@ -44,13 +46,13 @@ static int mt7915_start(struct ieee80211_hw *hw)
|
|||
mt7915_mac_enable_nf(dev, 1);
|
||||
}
|
||||
|
||||
mt7915_mcu_set_sku_en(phy, !mt76_testmode_enabled(&dev->mt76));
|
||||
mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
|
||||
mt7915_mcu_set_sku_en(phy, true);
|
||||
mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
|
||||
|
||||
set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
|
||||
|
||||
if (!mt76_testmode_enabled(&dev->mt76))
|
||||
ieee80211_queue_delayed_work(hw, &phy->mac_work,
|
||||
if (!mt76_testmode_enabled(phy->mt76))
|
||||
ieee80211_queue_delayed_work(hw, &phy->mt76->mac_work,
|
||||
MT7915_WATCHDOG_TIME);
|
||||
|
||||
if (!running)
|
||||
|
|
@ -66,11 +68,11 @@ static void mt7915_stop(struct ieee80211_hw *hw)
|
|||
struct mt7915_dev *dev = mt7915_hw_dev(hw);
|
||||
struct mt7915_phy *phy = mt7915_hw_phy(hw);
|
||||
|
||||
cancel_delayed_work_sync(&phy->mac_work);
|
||||
cancel_delayed_work_sync(&phy->mt76->mac_work);
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
mt76_testmode_reset(&dev->mt76, true);
|
||||
mt76_testmode_reset(phy->mt76, true);
|
||||
|
||||
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
|
||||
|
||||
|
|
@ -153,13 +155,13 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
|
|||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
mt76_testmode_reset(&dev->mt76, true);
|
||||
mt76_testmode_reset(phy->mt76, true);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR &&
|
||||
is_zero_ether_addr(vif->addr))
|
||||
phy->monitor_vif = vif;
|
||||
|
||||
mvif->idx = ffs(~phy->mt76->vif_mask) - 1;
|
||||
mvif->idx = ffs(~dev->mt76.vif_mask) - 1;
|
||||
if (mvif->idx >= MT7915_MAX_INTERFACES) {
|
||||
ret = -ENOSPC;
|
||||
goto out;
|
||||
|
|
@ -184,7 +186,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
phy->mt76->vif_mask |= BIT(mvif->idx);
|
||||
dev->mt76.vif_mask |= BIT(mvif->idx);
|
||||
phy->omac_mask |= BIT_ULL(mvif->omac_idx);
|
||||
|
||||
idx = MT7915_WTBL_RESERVED - mvif->idx;
|
||||
|
|
@ -228,7 +230,7 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
|
|||
/* TODO: disable beacon for the bss */
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
mt76_testmode_reset(&dev->mt76, true);
|
||||
mt76_testmode_reset(phy->mt76, true);
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
|
||||
if (vif == phy->monitor_vif)
|
||||
|
|
@ -239,7 +241,7 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
|
|||
rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
phy->mt76->vif_mask &= ~BIT(mvif->idx);
|
||||
dev->mt76.vif_mask &= ~BIT(mvif->idx);
|
||||
phy->omac_mask &= ~BIT_ULL(mvif->omac_idx);
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
|
||||
|
|
@ -273,7 +275,7 @@ int mt7915_set_channel(struct mt7915_phy *phy)
|
|||
struct mt7915_dev *dev = phy->dev;
|
||||
int ret;
|
||||
|
||||
cancel_delayed_work_sync(&phy->mac_work);
|
||||
cancel_delayed_work_sync(&phy->mt76->mac_work);
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
set_bit(MT76_RESET, &phy->mt76->state);
|
||||
|
|
@ -281,7 +283,7 @@ int mt7915_set_channel(struct mt7915_phy *phy)
|
|||
mt7915_init_dfs_state(phy);
|
||||
mt76_set_channel(phy->mt76);
|
||||
|
||||
ret = mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_CHANNEL_SWITCH);
|
||||
ret = mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(CHANNEL_SWITCH));
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
|
@ -298,8 +300,9 @@ int mt7915_set_channel(struct mt7915_phy *phy)
|
|||
|
||||
mt76_txq_schedule_all(phy->mt76);
|
||||
|
||||
if (!mt76_testmode_enabled(&dev->mt76))
|
||||
ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
|
||||
if (!mt76_testmode_enabled(phy->mt76))
|
||||
ieee80211_queue_delayed_work(phy->mt76->hw,
|
||||
&phy->mt76->mac_work,
|
||||
MT7915_WATCHDOG_TIME);
|
||||
|
||||
return ret;
|
||||
|
|
@ -365,9 +368,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
|
|||
|
||||
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
if (dev->mt76.test.state != MT76_TM_STATE_OFF) {
|
||||
if (phy->mt76->test.state != MT76_TM_STATE_OFF) {
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
mt76_testmode_reset(&dev->mt76, false);
|
||||
mt76_testmode_reset(phy->mt76, false);
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -396,7 +399,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
|
|||
|
||||
mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN,
|
||||
enabled);
|
||||
mt76_testmode_reset(&dev->mt76, true);
|
||||
mt76_testmode_reset(phy->mt76, true);
|
||||
mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
|
||||
}
|
||||
|
||||
|
|
@ -427,7 +430,6 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
|
|||
struct mt7915_dev *dev = mt7915_hw_dev(hw);
|
||||
struct mt7915_phy *phy = mt7915_hw_phy(hw);
|
||||
bool band = phy != &dev->phy;
|
||||
|
||||
u32 ctl_flags = MT_WF_RFCR1_DROP_ACK |
|
||||
MT_WF_RFCR1_DROP_BF_POLL |
|
||||
MT_WF_RFCR1_DROP_BA |
|
||||
|
|
@ -441,6 +443,8 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
|
|||
phy->rxfilter |= !(flags & FIF_##_flag) * (_hw); \
|
||||
} while (0)
|
||||
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
|
||||
phy->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
|
||||
MT_WF_RFCR_DROP_OTHER_BEACON |
|
||||
MT_WF_RFCR_DROP_FRAME_REPORT |
|
||||
|
|
@ -471,6 +475,8 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,
|
|||
mt76_clear(dev, MT_WF_RFCR1(band), ctl_flags);
|
||||
else
|
||||
mt76_set(dev, MT_WF_RFCR1(band), ctl_flags);
|
||||
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
}
|
||||
|
||||
static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
|
||||
|
|
@ -808,7 +814,7 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
|||
else
|
||||
tx_ant <<= 1;
|
||||
}
|
||||
phy->chainmask = tx_ant;
|
||||
phy->mt76->chainmask = tx_ant;
|
||||
|
||||
mt76_set_stream_caps(phy->mt76, true);
|
||||
mt7915_set_stream_vht_txbf_caps(phy);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -49,6 +49,8 @@ enum {
|
|||
enum {
|
||||
MCU_ATE_SET_TRX = 0x1,
|
||||
MCU_ATE_SET_FREQ_OFFSET = 0xa,
|
||||
MCU_ATE_SET_SLOT_TIME = 0x13,
|
||||
MCU_ATE_CLEAN_TXQUEUE = 0x1c,
|
||||
};
|
||||
|
||||
struct mt7915_mcu_rxd {
|
||||
|
|
@ -118,6 +120,12 @@ struct mt7915_mcu_rdd_report {
|
|||
} hw_pulse[32];
|
||||
} __packed;
|
||||
|
||||
struct mt7915_mcu_eeprom {
|
||||
u8 buffer_mode;
|
||||
u8 format;
|
||||
__le16 len;
|
||||
} __packed;
|
||||
|
||||
struct mt7915_mcu_eeprom_info {
|
||||
__le32 addr;
|
||||
__le32 valid;
|
||||
|
|
@ -176,6 +184,30 @@ struct mt7915_mcu_phy_rx_info {
|
|||
#define MT_RA_RATE_DCM_EN BIT(4)
|
||||
#define MT_RA_RATE_BW GENMASK(14, 13)
|
||||
|
||||
struct edca {
|
||||
u8 queue;
|
||||
u8 set;
|
||||
u8 aifs;
|
||||
u8 cw_min;
|
||||
__le16 cw_max;
|
||||
__le16 txop;
|
||||
};
|
||||
|
||||
struct mt7915_mcu_tx {
|
||||
u8 total;
|
||||
u8 action;
|
||||
u8 valid;
|
||||
u8 mode;
|
||||
|
||||
struct edca edca[IEEE80211_NUM_ACS];
|
||||
} __packed;
|
||||
|
||||
#define WMM_AIFS_SET BIT(0)
|
||||
#define WMM_CW_MIN_SET BIT(1)
|
||||
#define WMM_CW_MAX_SET BIT(2)
|
||||
#define WMM_TXOP_SET BIT(3)
|
||||
#define WMM_PARAM_SET GENMASK(3, 0)
|
||||
|
||||
#define MCU_PQ_ID(p, q) (((p) << 15) | ((q) << 10))
|
||||
#define MCU_PKT_ID 0xa0
|
||||
|
||||
|
|
@ -193,6 +225,12 @@ enum {
|
|||
MCU_S2D_H2CN
|
||||
};
|
||||
|
||||
|
||||
#define __MCU_CMD_FIELD_ID GENMASK(7, 0)
|
||||
#define __MCU_CMD_FIELD_EXT_ID GENMASK(15, 8)
|
||||
#define __MCU_CMD_FIELD_QUERY BIT(16)
|
||||
#define __MCU_CMD_FIELD_WA BIT(17)
|
||||
|
||||
enum {
|
||||
MCU_CMD_TARGET_ADDRESS_LEN_REQ = 0x01,
|
||||
MCU_CMD_FW_START_REQ = 0x02,
|
||||
|
|
@ -201,6 +239,7 @@ enum {
|
|||
MCU_CMD_PATCH_START_REQ = 0x05,
|
||||
MCU_CMD_PATCH_FINISH_REQ = 0x07,
|
||||
MCU_CMD_PATCH_SEM_CONTROL = 0x10,
|
||||
MCU_CMD_WA_PARAM = 0xC4,
|
||||
MCU_CMD_EXT_CID = 0xED,
|
||||
MCU_CMD_FW_SCATTER = 0xEE,
|
||||
MCU_CMD_RESTART_DL_REQ = 0xEF,
|
||||
|
|
@ -208,6 +247,7 @@ enum {
|
|||
|
||||
enum {
|
||||
MCU_EXT_CMD_EFUSE_ACCESS = 0x01,
|
||||
MCU_EXT_CMD_RF_TEST = 0x04,
|
||||
MCU_EXT_CMD_PM_STATE_CTRL = 0x07,
|
||||
MCU_EXT_CMD_CHANNEL_SWITCH = 0x08,
|
||||
MCU_EXT_CMD_FW_LOG_2_HOST = 0x13,
|
||||
|
|
@ -238,6 +278,29 @@ enum {
|
|||
MCU_EXT_CMD_PHY_STAT_INFO = 0xad,
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_WA_PARAM_CMD_QUERY,
|
||||
MCU_WA_PARAM_CMD_SET,
|
||||
MCU_WA_PARAM_CMD_CAPABILITY,
|
||||
MCU_WA_PARAM_CMD_DEBUG,
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_WA_PARAM_RED = 0x0e,
|
||||
};
|
||||
|
||||
#define MCU_CMD(_t) FIELD_PREP(__MCU_CMD_FIELD_ID, MCU_CMD_##_t)
|
||||
#define MCU_EXT_CMD(_t) (MCU_CMD(EXT_CID) | \
|
||||
FIELD_PREP(__MCU_CMD_FIELD_EXT_ID, \
|
||||
MCU_EXT_CMD_##_t))
|
||||
#define MCU_EXT_QUERY(_t) (MCU_EXT_CMD(_t) | __MCU_CMD_FIELD_QUERY)
|
||||
|
||||
#define MCU_WA_CMD(_t) (MCU_CMD(_t) | __MCU_CMD_FIELD_WA)
|
||||
#define MCU_WA_EXT_CMD(_t) (MCU_EXT_CMD(_t) | __MCU_CMD_FIELD_WA)
|
||||
#define MCU_WA_PARAM_CMD(_t) (MCU_WA_CMD(WA_PARAM) | \
|
||||
FIELD_PREP(__MCU_CMD_FIELD_EXT_ID, \
|
||||
MCU_WA_PARAM_CMD_##_t))
|
||||
|
||||
enum {
|
||||
PATCH_SEM_RELEASE,
|
||||
PATCH_SEM_GET
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ enum mt7915_rxq_id {
|
|||
MT7915_RXQ_BAND1,
|
||||
MT7915_RXQ_MCU_WM = 0,
|
||||
MT7915_RXQ_MCU_WA,
|
||||
MT7915_RXQ_MCU_WA_EXT,
|
||||
};
|
||||
|
||||
struct mt7915_sta_stats {
|
||||
|
|
@ -72,6 +73,11 @@ struct mt7915_sta_stats {
|
|||
unsigned long jiffies;
|
||||
};
|
||||
|
||||
struct mt7915_sta_key_conf {
|
||||
s8 keyidx;
|
||||
u8 key[16];
|
||||
};
|
||||
|
||||
struct mt7915_sta {
|
||||
struct mt76_wcid wcid; /* must be first */
|
||||
|
||||
|
|
@ -85,6 +91,8 @@ struct mt7915_sta {
|
|||
struct mt7915_sta_stats stats;
|
||||
|
||||
unsigned long ampdu_state;
|
||||
|
||||
struct mt7915_sta_key_conf bip;
|
||||
};
|
||||
|
||||
struct mt7915_vif {
|
||||
|
|
@ -107,6 +115,14 @@ struct mib_stats {
|
|||
u16 ba_miss_cnt;
|
||||
};
|
||||
|
||||
struct mt7915_hif {
|
||||
struct list_head list;
|
||||
|
||||
struct device *dev;
|
||||
void __iomem *regs;
|
||||
int irq;
|
||||
};
|
||||
|
||||
struct mt7915_phy {
|
||||
struct mt76_phy *mt76;
|
||||
struct mt7915_dev *dev;
|
||||
|
|
@ -119,7 +135,6 @@ struct mt7915_phy {
|
|||
u64 omac_mask;
|
||||
|
||||
u16 noise;
|
||||
u16 chainmask;
|
||||
|
||||
s16 coverage_class;
|
||||
u8 slottime;
|
||||
|
|
@ -133,9 +148,21 @@ struct mt7915_phy {
|
|||
struct mib_stats mib;
|
||||
struct list_head stats_list;
|
||||
|
||||
struct delayed_work mac_work;
|
||||
u8 mac_work_count;
|
||||
u8 sta_work_count;
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
struct {
|
||||
u32 *reg_backup;
|
||||
|
||||
s32 last_freq_offset;
|
||||
u8 last_rcpi[4];
|
||||
s8 last_ib_rssi[4];
|
||||
s8 last_wb_rssi[4];
|
||||
u8 last_snr;
|
||||
|
||||
u8 spe_idx;
|
||||
} test;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct mt7915_dev {
|
||||
|
|
@ -144,10 +171,13 @@ struct mt7915_dev {
|
|||
struct mt76_phy mphy;
|
||||
};
|
||||
|
||||
struct mt7915_hif *hif2;
|
||||
|
||||
const struct mt76_bus_ops *bus_ops;
|
||||
struct mt7915_phy phy;
|
||||
|
||||
u16 chainmask;
|
||||
u32 hif_idx;
|
||||
|
||||
struct work_struct init_work;
|
||||
struct work_struct rc_work;
|
||||
|
|
@ -168,21 +198,9 @@ struct mt7915_dev {
|
|||
s8 **rate_power; /* TODO: use mt76_rate_power */
|
||||
|
||||
bool dbdc_support;
|
||||
bool flash_mode;
|
||||
bool fw_debug;
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
struct {
|
||||
u32 *reg_backup;
|
||||
|
||||
s32 last_freq_offset;
|
||||
u8 last_rcpi[4];
|
||||
s8 last_ib_rssi[4];
|
||||
s8 last_wb_rssi[4];
|
||||
u8 last_snr;
|
||||
|
||||
u8 spe_idx;
|
||||
} test;
|
||||
#endif
|
||||
bool ibf;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -271,7 +289,6 @@ static inline u8 mt7915_lmac_mapping(struct mt7915_dev *dev, u8 ac)
|
|||
}
|
||||
|
||||
extern const struct ieee80211_ops mt7915_ops;
|
||||
extern struct pci_driver mt7915_pci_driver;
|
||||
extern const struct mt76_testmode_ops mt7915_testmode_ops;
|
||||
|
||||
u32 mt7915_reg_map(struct mt7915_dev *dev, u32 addr);
|
||||
|
|
@ -319,6 +336,7 @@ int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
|
|||
int mt7915_set_channel(struct mt7915_phy *phy);
|
||||
int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd);
|
||||
int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif);
|
||||
int mt7915_mcu_update_edca(struct mt7915_dev *dev, void *req);
|
||||
int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
|
||||
struct ieee80211_sta *sta, u32 rate);
|
||||
int mt7915_mcu_set_eeprom(struct mt7915_dev *dev);
|
||||
|
|
@ -334,6 +352,7 @@ int mt7915_mcu_set_pm(struct mt7915_dev *dev, int band, int enter);
|
|||
int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable);
|
||||
int mt7915_mcu_set_sku(struct mt7915_phy *phy);
|
||||
int mt7915_mcu_set_txbf_type(struct mt7915_dev *dev);
|
||||
int mt7915_mcu_set_txbf_module(struct mt7915_dev *dev);
|
||||
int mt7915_mcu_set_txbf_sounding(struct mt7915_dev *dev);
|
||||
int mt7915_mcu_set_fcc5_lpn(struct mt7915_dev *dev, int val);
|
||||
int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev,
|
||||
|
|
@ -356,14 +375,23 @@ static inline bool is_mt7915(struct mt76_dev *dev)
|
|||
return mt76_chip(dev) == 0x7915;
|
||||
}
|
||||
|
||||
void mt7915_dual_hif_set_irq_mask(struct mt7915_dev *dev, bool write_reg,
|
||||
u32 clear, u32 set);
|
||||
|
||||
static inline void mt7915_irq_enable(struct mt7915_dev *dev, u32 mask)
|
||||
{
|
||||
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, 0, mask);
|
||||
if (dev->hif2)
|
||||
mt7915_dual_hif_set_irq_mask(dev, true, 0, mask);
|
||||
else
|
||||
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, 0, mask);
|
||||
}
|
||||
|
||||
static inline void mt7915_irq_disable(struct mt7915_dev *dev, u32 mask)
|
||||
{
|
||||
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
|
||||
if (dev->hif2)
|
||||
mt7915_dual_hif_set_irq_mask(dev, true, mask, 0);
|
||||
else
|
||||
mt76_set_irq_mask(&dev->mt76, MT_INT_MASK_CSR, mask, 0);
|
||||
}
|
||||
|
||||
static inline u32
|
||||
|
|
@ -463,6 +491,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
|||
struct ieee80211_sta *sta,
|
||||
struct mt76_tx_info *tx_info);
|
||||
void mt7915_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
|
||||
void mt7915_tx_token_put(struct mt7915_dev *dev);
|
||||
int mt7915_init_tx_queues(struct mt7915_phy *phy, int idx, int n_desc);
|
||||
void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
|
||||
struct sk_buff *skb);
|
||||
|
|
|
|||
|
|
@ -12,11 +12,72 @@
|
|||
#include "mac.h"
|
||||
#include "../trace.h"
|
||||
|
||||
static LIST_HEAD(hif_list);
|
||||
static DEFINE_SPINLOCK(hif_lock);
|
||||
static u32 hif_idx;
|
||||
|
||||
static const struct pci_device_id mt7915_pci_device_table[] = {
|
||||
{ PCI_DEVICE(0x14c3, 0x7915) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7915) },
|
||||
{ },
|
||||
};
|
||||
|
||||
static const struct pci_device_id mt7915_hif_device_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7916) },
|
||||
{ },
|
||||
};
|
||||
|
||||
void mt7915_dual_hif_set_irq_mask(struct mt7915_dev *dev, bool write_reg,
|
||||
u32 clear, u32 set)
|
||||
{
|
||||
struct mt76_dev *mdev = &dev->mt76;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&mdev->mmio.irq_lock, flags);
|
||||
|
||||
mdev->mmio.irqmask &= ~clear;
|
||||
mdev->mmio.irqmask |= set;
|
||||
|
||||
if (write_reg) {
|
||||
mt76_wr(dev, MT_INT_MASK_CSR, mdev->mmio.irqmask);
|
||||
mt76_wr(dev, MT_INT1_MASK_CSR, mdev->mmio.irqmask);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&mdev->mmio.irq_lock, flags);
|
||||
}
|
||||
|
||||
static struct mt7915_hif *
|
||||
mt7915_pci_get_hif2(struct mt7915_dev *dev)
|
||||
{
|
||||
struct mt7915_hif *hif;
|
||||
u32 val;
|
||||
|
||||
spin_lock_bh(&hif_lock);
|
||||
|
||||
list_for_each_entry(hif, &hif_list, list) {
|
||||
val = readl(hif->regs + MT_PCIE_RECOG_ID);
|
||||
val &= MT_PCIE_RECOG_ID_MASK;
|
||||
if (val != dev->hif_idx)
|
||||
continue;
|
||||
|
||||
get_device(hif->dev);
|
||||
goto out;
|
||||
}
|
||||
hif = NULL;
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&hif_lock);
|
||||
|
||||
return hif;
|
||||
}
|
||||
|
||||
static void mt7915_put_hif2(struct mt7915_hif *hif)
|
||||
{
|
||||
if (!hif)
|
||||
return;
|
||||
|
||||
put_device(hif->dev);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
|
||||
{
|
||||
|
|
@ -26,6 +87,7 @@ mt7915_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
|
|||
[MT_RXQ_EXT] = MT_INT_RX_DONE_DATA1,
|
||||
[MT_RXQ_MCU] = MT_INT_RX_DONE_WM,
|
||||
[MT_RXQ_MCU_WA] = MT_INT_RX_DONE_WA,
|
||||
[MT_RXQ_EXT_WA] = MT_INT_RX_DONE_WA_EXT,
|
||||
};
|
||||
|
||||
mt7915_irq_enable(dev, rx_irq_mask[q]);
|
||||
|
|
@ -35,12 +97,20 @@ mt7915_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
|
|||
static irqreturn_t mt7915_irq_handler(int irq, void *dev_instance)
|
||||
{
|
||||
struct mt7915_dev *dev = dev_instance;
|
||||
u32 intr, mask;
|
||||
u32 intr, intr1, mask;
|
||||
|
||||
intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
|
||||
intr &= dev->mt76.mmio.irqmask;
|
||||
mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
|
||||
|
||||
if (dev->hif2) {
|
||||
intr1 = mt76_rr(dev, MT_INT1_SOURCE_CSR);
|
||||
intr1 &= dev->mt76.mmio.irqmask;
|
||||
mt76_wr(dev, MT_INT1_SOURCE_CSR, intr1);
|
||||
|
||||
intr |= intr1;
|
||||
}
|
||||
|
||||
if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
|
||||
return IRQ_NONE;
|
||||
|
||||
|
|
@ -67,6 +137,9 @@ static irqreturn_t mt7915_irq_handler(int irq, void *dev_instance)
|
|||
if (intr & MT_INT_RX_DONE_WA)
|
||||
napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]);
|
||||
|
||||
if (intr & MT_INT_RX_DONE_WA_EXT)
|
||||
napi_schedule(&dev->mt76.napi[MT_RXQ_EXT_WA]);
|
||||
|
||||
if (intr & MT_INT_MCU_CMD) {
|
||||
u32 val = mt76_rr(dev, MT_MCU_CMD);
|
||||
|
||||
|
|
@ -103,6 +176,53 @@ mt7915_alloc_device(struct pci_dev *pdev, struct mt7915_dev *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void mt7915_pci_init_hif2(struct mt7915_dev *dev)
|
||||
{
|
||||
struct mt7915_hif *hif;
|
||||
|
||||
dev->hif_idx = ++hif_idx;
|
||||
if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7916, NULL))
|
||||
return;
|
||||
|
||||
mt76_wr(dev, MT_PCIE_RECOG_ID, dev->hif_idx | MT_PCIE_RECOG_ID_SEM);
|
||||
|
||||
hif = mt7915_pci_get_hif2(dev);
|
||||
if (!hif)
|
||||
return;
|
||||
|
||||
dev->hif2 = hif;
|
||||
|
||||
mt76_wr(dev, MT_INT1_MASK_CSR, 0);
|
||||
|
||||
if (devm_request_irq(dev->mt76.dev, hif->irq, mt7915_irq_handler,
|
||||
IRQF_SHARED, KBUILD_MODNAME "-hif", dev)) {
|
||||
mt7915_put_hif2(hif);
|
||||
hif = NULL;
|
||||
}
|
||||
|
||||
/* master switch of PCIe tnterrupt enable */
|
||||
mt7915_l1_wr(dev, MT_PCIE1_MAC_INT_ENABLE, 0xff);
|
||||
}
|
||||
|
||||
static int mt7915_pci_hif2_probe(struct pci_dev *pdev)
|
||||
{
|
||||
struct mt7915_hif *hif;
|
||||
|
||||
hif = devm_kzalloc(&pdev->dev, sizeof(*hif), GFP_KERNEL);
|
||||
if (!hif)
|
||||
return -ENOMEM;
|
||||
|
||||
hif->dev = &pdev->dev;
|
||||
hif->regs = pcim_iomap_table(pdev)[0];
|
||||
hif->irq = pdev->irq;
|
||||
spin_lock_bh(&hif_lock);
|
||||
list_add(&hif->list, &hif_list);
|
||||
spin_unlock_bh(&hif_lock);
|
||||
pci_set_drvdata(pdev, hif);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7915_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
|
|
@ -141,6 +261,9 @@ static int mt7915_pci_probe(struct pci_dev *pdev,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (id->device == 0x7916)
|
||||
return mt7915_pci_hif2_probe(pdev);
|
||||
|
||||
mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7915_ops,
|
||||
&drv_ops);
|
||||
if (!mdev)
|
||||
|
|
@ -166,6 +289,8 @@ static int mt7915_pci_probe(struct pci_dev *pdev,
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
mt7915_pci_init_hif2(dev);
|
||||
|
||||
ret = mt7915_register_device(dev);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -177,24 +302,64 @@ static int mt7915_pci_probe(struct pci_dev *pdev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void mt7915_hif_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct mt7915_hif *hif = pci_get_drvdata(pdev);
|
||||
|
||||
list_del(&hif->list);
|
||||
}
|
||||
|
||||
static void mt7915_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct mt76_dev *mdev = pci_get_drvdata(pdev);
|
||||
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
|
||||
struct mt76_dev *mdev;
|
||||
struct mt7915_dev *dev;
|
||||
|
||||
mdev = pci_get_drvdata(pdev);
|
||||
dev = container_of(mdev, struct mt7915_dev, mt76);
|
||||
mt7915_put_hif2(dev->hif2);
|
||||
mt7915_unregister_device(dev);
|
||||
}
|
||||
|
||||
struct pci_driver mt7915_pci_driver = {
|
||||
static struct pci_driver mt7915_hif_driver = {
|
||||
.name = KBUILD_MODNAME "_hif",
|
||||
.id_table = mt7915_hif_device_table,
|
||||
.probe = mt7915_pci_probe,
|
||||
.remove = mt7915_hif_remove,
|
||||
};
|
||||
|
||||
static struct pci_driver mt7915_pci_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = mt7915_pci_device_table,
|
||||
.probe = mt7915_pci_probe,
|
||||
.remove = mt7915_pci_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(mt7915_pci_driver);
|
||||
static int __init mt7915_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = pci_register_driver(&mt7915_hif_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pci_register_driver(&mt7915_pci_driver);
|
||||
if (ret)
|
||||
pci_unregister_driver(&mt7915_hif_driver);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit mt7915_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&mt7915_pci_driver);
|
||||
pci_unregister_driver(&mt7915_hif_driver);
|
||||
}
|
||||
|
||||
module_init(mt7915_init);
|
||||
module_exit(mt7915_exit);
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, mt7915_pci_device_table);
|
||||
MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table);
|
||||
MODULE_FIRMWARE(MT7915_FIRMWARE_WA);
|
||||
MODULE_FIRMWARE(MT7915_FIRMWARE_WM);
|
||||
MODULE_FIRMWARE(MT7915_ROM_PATCH);
|
||||
|
|
|
|||
|
|
@ -59,6 +59,13 @@
|
|||
#define MT_TIMEOUT_VAL_PLCP GENMASK(15, 0)
|
||||
#define MT_TIMEOUT_VAL_CCA GENMASK(31, 16)
|
||||
|
||||
#define MT_TMAC_ATCR(_band) MT_WF_TMAC(_band, 0x098)
|
||||
#define MT_TMAC_ATCR_TXV_TOUT GENMASK(7, 0)
|
||||
|
||||
#define MT_TMAC_TRCR0(_band) MT_WF_TMAC(_band, 0x09c)
|
||||
#define MT_TMAC_TRCR0_TR2T_CHK GENMASK(8, 0)
|
||||
#define MT_TMAC_TRCR0_I2T_CHK GENMASK(24, 16)
|
||||
|
||||
#define MT_TMAC_ICR0(_band) MT_WF_TMAC(_band, 0x0a4)
|
||||
#define MT_IFS_EIFS GENMASK(8, 0)
|
||||
#define MT_IFS_RIFS GENMASK(14, 10)
|
||||
|
|
@ -70,7 +77,6 @@
|
|||
#define MT_TMAC_CTCR0_INS_DDLMT_EN BIT(17)
|
||||
#define MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN BIT(18)
|
||||
|
||||
#define MT_TMAC_TRCR0(_band) MT_WF_TMAC(_band, 0x09c)
|
||||
#define MT_TMAC_TFCR0(_band) MT_WF_TMAC(_band, 0x1e0)
|
||||
|
||||
#define MT_WF_DMA_BASE(_band) ((_band) ? 0xa1e00 : 0x21e00)
|
||||
|
|
@ -342,21 +348,36 @@
|
|||
#define MT_INT_RX_DONE_DATA1 BIT(17)
|
||||
#define MT_INT_RX_DONE_WM BIT(0)
|
||||
#define MT_INT_RX_DONE_WA BIT(1)
|
||||
#define MT_INT_RX_DONE_ALL (BIT(0) | BIT(1) | GENMASK(17, 16))
|
||||
#define MT_INT_RX_DONE_WA_EXT BIT(2)
|
||||
#define MT_INT_RX_DONE_ALL (GENMASK(2, 0) | GENMASK(17, 16))
|
||||
#define MT_INT_TX_DONE_MCU_WA BIT(15)
|
||||
#define MT_INT_TX_DONE_FWDL BIT(26)
|
||||
#define MT_INT_TX_DONE_MCU_WM BIT(27)
|
||||
#define MT_INT_TX_DONE_BAND0 BIT(30)
|
||||
#define MT_INT_TX_DONE_BAND1 BIT(31)
|
||||
|
||||
#define MT_INT_BAND1_MASK (MT_INT_RX_DONE_WA_EXT | \
|
||||
MT_INT_TX_DONE_BAND1)
|
||||
|
||||
#define MT_INT_MCU_CMD BIT(29)
|
||||
|
||||
#define MT_INT_TX_DONE_MCU (MT_INT_TX_DONE_MCU_WA | \
|
||||
MT_INT_TX_DONE_MCU_WM | \
|
||||
MT_INT_TX_DONE_FWDL)
|
||||
|
||||
#define MT_WFDMA_HOST_CONFIG MT_WFDMA_EXT_CSR(0x30)
|
||||
#define MT_WFDMA_HOST_CONFIG_PDMA_BAND BIT(0)
|
||||
|
||||
#define MT_WFDMA_EXT_CSR_HIF_MISC MT_WFDMA_EXT_CSR(0x44)
|
||||
#define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY BIT(0)
|
||||
|
||||
#define MT_INT1_SOURCE_CSR MT_WFDMA_EXT_CSR(0x88)
|
||||
#define MT_INT1_MASK_CSR MT_WFDMA_EXT_CSR(0x8c)
|
||||
|
||||
#define MT_PCIE_RECOG_ID MT_WFDMA_EXT_CSR(0x90)
|
||||
#define MT_PCIE_RECOG_ID_MASK GENMASK(30, 0)
|
||||
#define MT_PCIE_RECOG_ID_SEM BIT(31)
|
||||
|
||||
/* WFDMA0 PCIE1 */
|
||||
#define MT_WFDMA0_PCIE1_BASE 0xd8000
|
||||
#define MT_WFDMA0_PCIE1(ofs) (MT_WFDMA0_PCIE1_BASE + (ofs))
|
||||
|
|
@ -411,6 +432,10 @@
|
|||
#define MT_HW_CHIPID 0x70010200
|
||||
#define MT_HW_REV 0x70010204
|
||||
|
||||
#define MT_PCIE1_MAC_BASE 0x74020000
|
||||
#define MT_PCIE1_MAC(ofs) (MT_PCIE1_MAC_BASE + (ofs))
|
||||
#define MT_PCIE1_MAC_INT_ENABLE MT_PCIE1_MAC(0x188)
|
||||
|
||||
#define MT_PCIE_MAC_BASE 0x74030000
|
||||
#define MT_PCIE_MAC(ofs) (MT_PCIE_MAC_BASE + (ofs))
|
||||
#define MT_PCIE_MAC_INT_ENABLE MT_PCIE_MAC(0x188)
|
||||
|
|
|
|||
|
|
@ -70,30 +70,32 @@ mt7915_tm_set_tx_power(struct mt7915_phy *phy)
|
|||
};
|
||||
u8 *tx_power = NULL;
|
||||
|
||||
if (dev->mt76.test.state != MT76_TM_STATE_OFF)
|
||||
tx_power = dev->mt76.test.tx_power;
|
||||
if (phy->mt76->test.state != MT76_TM_STATE_OFF)
|
||||
tx_power = phy->mt76->test.tx_power;
|
||||
|
||||
/* Tx power of the other antennas are the same as antenna 0 */
|
||||
if (tx_power && tx_power[0])
|
||||
req.tx_power = tx_power[0];
|
||||
|
||||
ret = mt76_mcu_send_msg(&dev->mt76,
|
||||
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL,
|
||||
MCU_EXT_CMD(TX_POWER_FEATURE_CTRL),
|
||||
&req, sizeof(req), false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_freq_offset(struct mt7915_dev *dev, bool en, u32 val)
|
||||
mt7915_tm_set_freq_offset(struct mt7915_phy *phy, bool en, u32 val)
|
||||
{
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
struct mt7915_tm_cmd req = {
|
||||
.testmode_en = en,
|
||||
.param_idx = MCU_ATE_SET_FREQ_OFFSET,
|
||||
.param.freq.band = phy != &dev->phy,
|
||||
.param.freq.freq_offset = cpu_to_le32(val),
|
||||
};
|
||||
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req,
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
|
||||
sizeof(req), false);
|
||||
}
|
||||
|
||||
|
|
@ -110,14 +112,14 @@ mt7915_tm_mode_ctrl(struct mt7915_dev *dev, bool enable)
|
|||
};
|
||||
|
||||
return mt76_mcu_send_msg(&dev->mt76,
|
||||
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL,
|
||||
MCU_EXT_CMD(TX_POWER_FEATURE_CTRL),
|
||||
&req, sizeof(req), false);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_trx(struct mt7915_dev *dev, struct mt7915_phy *phy,
|
||||
int type, bool en)
|
||||
mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en)
|
||||
{
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
struct mt7915_tm_cmd req = {
|
||||
.testmode_en = 1,
|
||||
.param_idx = MCU_ATE_SET_TRX,
|
||||
|
|
@ -126,19 +128,230 @@ mt7915_tm_set_trx(struct mt7915_dev *dev, struct mt7915_phy *phy,
|
|||
.param.trx.band = phy != &dev->phy,
|
||||
};
|
||||
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req,
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
|
||||
sizeof(req), false);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_clean_hwq(struct mt7915_phy *phy, u8 wcid)
|
||||
{
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
struct mt7915_tm_cmd req = {
|
||||
.testmode_en = 1,
|
||||
.param_idx = MCU_ATE_CLEAN_TXQUEUE,
|
||||
.param.clean.wcid = wcid,
|
||||
.param.clean.band = phy != &dev->phy,
|
||||
};
|
||||
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
|
||||
sizeof(req), false);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_slot_time(struct mt7915_phy *phy, u8 slot_time, u8 sifs)
|
||||
{
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
struct mt7915_tm_cmd req = {
|
||||
.testmode_en = !(phy->mt76->test.state == MT76_TM_STATE_OFF),
|
||||
.param_idx = MCU_ATE_SET_SLOT_TIME,
|
||||
.param.slot.slot_time = slot_time,
|
||||
.param.slot.sifs = sifs,
|
||||
.param.slot.rifs = 2,
|
||||
.param.slot.eifs = cpu_to_le16(60),
|
||||
.param.slot.band = phy != &dev->phy,
|
||||
};
|
||||
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
|
||||
sizeof(req), false);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_wmm_qid(struct mt7915_dev *dev, u8 qid, u8 aifs, u8 cw_min,
|
||||
u16 cw_max, u16 txop)
|
||||
{
|
||||
struct mt7915_mcu_tx req = { .total = 1 };
|
||||
struct edca *e = &req.edca[0];
|
||||
|
||||
e->queue = qid;
|
||||
e->set = WMM_PARAM_SET;
|
||||
|
||||
e->aifs = aifs;
|
||||
e->cw_min = cw_min;
|
||||
e->cw_max = cpu_to_le16(cw_max);
|
||||
e->txop = cpu_to_le16(txop);
|
||||
|
||||
return mt7915_mcu_update_edca(dev, &req);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_ipg_params(struct mt7915_phy *phy, u32 ipg, u8 mode)
|
||||
{
|
||||
#define TM_DEFAULT_SIFS 10
|
||||
#define TM_MAX_SIFS 127
|
||||
#define TM_MAX_AIFSN 0xf
|
||||
#define TM_MIN_AIFSN 0x1
|
||||
#define BBP_PROC_TIME 1500
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
u8 sig_ext = (mode == MT76_TM_TX_MODE_CCK) ? 0 : 6;
|
||||
u8 slot_time = 9, sifs = TM_DEFAULT_SIFS;
|
||||
u8 aifsn = TM_MIN_AIFSN;
|
||||
u32 i2t_time, tr2t_time, txv_time;
|
||||
bool ext_phy = phy != &dev->phy;
|
||||
u16 cw = 0;
|
||||
|
||||
if (ipg < sig_ext + slot_time + sifs)
|
||||
ipg = 0;
|
||||
|
||||
if (!ipg)
|
||||
goto done;
|
||||
|
||||
ipg -= sig_ext;
|
||||
|
||||
if (ipg <= (TM_MAX_SIFS + slot_time)) {
|
||||
sifs = ipg - slot_time;
|
||||
} else {
|
||||
u32 val = (ipg + slot_time) / slot_time;
|
||||
|
||||
while (val >>= 1)
|
||||
cw++;
|
||||
|
||||
if (cw > 16)
|
||||
cw = 16;
|
||||
|
||||
ipg -= ((1 << cw) - 1) * slot_time;
|
||||
|
||||
aifsn = ipg / slot_time;
|
||||
if (aifsn > TM_MAX_AIFSN)
|
||||
aifsn = TM_MAX_AIFSN;
|
||||
|
||||
ipg -= aifsn * slot_time;
|
||||
|
||||
if (ipg > TM_DEFAULT_SIFS) {
|
||||
if (ipg < TM_MAX_SIFS)
|
||||
sifs = ipg;
|
||||
else
|
||||
sifs = TM_MAX_SIFS;
|
||||
}
|
||||
}
|
||||
done:
|
||||
txv_time = mt76_get_field(dev, MT_TMAC_ATCR(ext_phy),
|
||||
MT_TMAC_ATCR_TXV_TOUT);
|
||||
txv_time *= 50; /* normal clock time */
|
||||
|
||||
i2t_time = (slot_time * 1000 - txv_time - BBP_PROC_TIME) / 50;
|
||||
tr2t_time = (sifs * 1000 - txv_time - BBP_PROC_TIME) / 50;
|
||||
|
||||
mt76_set(dev, MT_TMAC_TRCR0(ext_phy),
|
||||
FIELD_PREP(MT_TMAC_TRCR0_TR2T_CHK, tr2t_time) |
|
||||
FIELD_PREP(MT_TMAC_TRCR0_I2T_CHK, i2t_time));
|
||||
|
||||
mt7915_tm_set_slot_time(phy, slot_time, sifs);
|
||||
|
||||
return mt7915_tm_set_wmm_qid(dev,
|
||||
mt7915_lmac_mapping(dev, IEEE80211_AC_BE),
|
||||
aifsn, cw, cw, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time)
|
||||
{
|
||||
struct mt76_phy *mphy = phy->mt76;
|
||||
struct mt76_testmode_data *td = &mphy->test;
|
||||
struct sk_buff *old = td->tx_skb, *new;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct rate_info rate = {};
|
||||
u16 flags = 0, tx_len;
|
||||
u32 bitrate;
|
||||
|
||||
if (!tx_time || !old)
|
||||
return 0;
|
||||
|
||||
rate.mcs = td->tx_rate_idx;
|
||||
rate.nss = td->tx_rate_nss;
|
||||
|
||||
switch (td->tx_rate_mode) {
|
||||
case MT76_TM_TX_MODE_CCK:
|
||||
case MT76_TM_TX_MODE_OFDM:
|
||||
if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
|
||||
sband = &mphy->sband_5g.sband;
|
||||
else
|
||||
sband = &mphy->sband_2g.sband;
|
||||
|
||||
rate.legacy = sband->bitrates[rate.mcs].bitrate;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_HT:
|
||||
rate.mcs += rate.nss * 8;
|
||||
flags |= RATE_INFO_FLAGS_MCS;
|
||||
|
||||
if (td->tx_rate_sgi)
|
||||
flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_VHT:
|
||||
flags |= RATE_INFO_FLAGS_VHT_MCS;
|
||||
|
||||
if (td->tx_rate_sgi)
|
||||
flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_HE_SU:
|
||||
case MT76_TM_TX_MODE_HE_EXT_SU:
|
||||
case MT76_TM_TX_MODE_HE_TB:
|
||||
case MT76_TM_TX_MODE_HE_MU:
|
||||
rate.he_gi = td->tx_rate_sgi;
|
||||
flags |= RATE_INFO_FLAGS_HE_MCS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rate.flags = flags;
|
||||
|
||||
switch (mphy->chandef.width) {
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
rate.bw = RATE_INFO_BW_160;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
rate.bw = RATE_INFO_BW_80;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
rate.bw = RATE_INFO_BW_40;
|
||||
break;
|
||||
default:
|
||||
rate.bw = RATE_INFO_BW_20;
|
||||
break;
|
||||
}
|
||||
|
||||
bitrate = cfg80211_calculate_bitrate(&rate);
|
||||
tx_len = bitrate * tx_time / 10 / 8;
|
||||
|
||||
if (tx_len < sizeof(struct ieee80211_hdr))
|
||||
tx_len = sizeof(struct ieee80211_hdr);
|
||||
else if (tx_len > IEEE80211_MAX_FRAME_LEN)
|
||||
tx_len = IEEE80211_MAX_FRAME_LEN;
|
||||
|
||||
new = alloc_skb(tx_len, GFP_KERNEL);
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_copy_header(new, old);
|
||||
__skb_put_zero(new, tx_len);
|
||||
memcpy(new->data, old->data, sizeof(struct ieee80211_hdr));
|
||||
|
||||
dev_kfree_skb(old);
|
||||
td->tx_skb = new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy)
|
||||
mt7915_tm_reg_backup_restore(struct mt7915_phy *phy)
|
||||
{
|
||||
int n_regs = ARRAY_SIZE(reg_backup_list);
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
bool ext_phy = phy != &dev->phy;
|
||||
u32 *b = dev->test.reg_backup;
|
||||
u32 *b = phy->test.reg_backup;
|
||||
int i;
|
||||
|
||||
if (dev->mt76.test.state == MT76_TM_STATE_OFF) {
|
||||
if (phy->mt76->test.state == MT76_TM_STATE_OFF) {
|
||||
for (i = 0; i < n_regs; i++)
|
||||
mt76_wr(dev, reg_backup_list[i].band[ext_phy], b[i]);
|
||||
return;
|
||||
|
|
@ -151,7 +364,7 @@ mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy)
|
|||
if (!b)
|
||||
return;
|
||||
|
||||
dev->test.reg_backup = b;
|
||||
phy->test.reg_backup = b;
|
||||
for (i = 0; i < n_regs; i++)
|
||||
b[i] = mt76_rr(dev, reg_backup_list[i].band[ext_phy]);
|
||||
|
||||
|
|
@ -182,93 +395,260 @@ mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy)
|
|||
}
|
||||
|
||||
static void
|
||||
mt7915_tm_init(struct mt7915_dev *dev)
|
||||
mt7915_tm_init(struct mt7915_phy *phy, bool en)
|
||||
{
|
||||
bool en = !(dev->mt76.test.state == MT76_TM_STATE_OFF);
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
|
||||
if (!test_bit(MT76_STATE_RUNNING, &dev->phy.mt76->state))
|
||||
if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
|
||||
return;
|
||||
|
||||
mt7915_mcu_set_sku_en(phy, !en);
|
||||
|
||||
mt7915_tm_mode_ctrl(dev, en);
|
||||
mt7915_tm_reg_backup_restore(dev, &dev->phy);
|
||||
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TXRX, !en);
|
||||
mt7915_tm_reg_backup_restore(phy);
|
||||
mt7915_tm_set_trx(phy, TM_MAC_TXRX, !en);
|
||||
|
||||
mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_tm_set_tx_frames(struct mt7915_dev *dev, bool en)
|
||||
mt7915_tm_update_channel(struct mt7915_phy *phy)
|
||||
{
|
||||
mutex_unlock(&phy->dev->mt76.mutex);
|
||||
mt7915_set_channel(phy);
|
||||
mutex_lock(&phy->dev->mt76.mutex);
|
||||
|
||||
mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD(SET_RX_PATH));
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
|
||||
{
|
||||
static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0,
|
||||
9, 8, 6, 10, 16, 12, 18, 0};
|
||||
struct sk_buff *skb = dev->mt76.test.tx_skb;
|
||||
struct mt76_testmode_data *td = &phy->mt76->test;
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
struct ieee80211_tx_info *info;
|
||||
u8 duty_cycle = td->tx_duty_cycle;
|
||||
u32 tx_time = td->tx_time;
|
||||
u32 ipg = td->tx_ipg;
|
||||
|
||||
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_RX_RXV, false);
|
||||
mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
|
||||
mt7915_tm_clean_hwq(phy, dev->mt76.global_wcid.idx);
|
||||
|
||||
if (en) {
|
||||
u8 tx_ant = dev->mt76.test.tx_antenna_mask;
|
||||
mt7915_tm_update_channel(phy);
|
||||
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
mt7915_set_channel(&dev->phy);
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
if (td->tx_spe_idx) {
|
||||
phy->test.spe_idx = td->tx_spe_idx;
|
||||
} else {
|
||||
u8 tx_ant = td->tx_antenna_mask;
|
||||
|
||||
mt7915_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH);
|
||||
dev->test.spe_idx = spe_idx_map[tx_ant];
|
||||
if (phy != &dev->phy)
|
||||
tx_ant >>= 2;
|
||||
phy->test.spe_idx = spe_idx_map[tx_ant];
|
||||
}
|
||||
}
|
||||
|
||||
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TX, en);
|
||||
/* if all three params are set, duty_cycle will be ignored */
|
||||
if (duty_cycle && tx_time && !ipg) {
|
||||
ipg = tx_time * 100 / duty_cycle - tx_time;
|
||||
} else if (duty_cycle && !tx_time && ipg) {
|
||||
if (duty_cycle < 100)
|
||||
tx_time = duty_cycle * ipg / (100 - duty_cycle);
|
||||
}
|
||||
|
||||
if (!en || !skb)
|
||||
mt7915_tm_set_ipg_params(phy, ipg, td->tx_rate_mode);
|
||||
mt7915_tm_set_tx_len(phy, tx_time);
|
||||
|
||||
if (ipg)
|
||||
td->tx_queued_limit = MT76_TM_TIMEOUT * 1000000 / ipg / 2;
|
||||
|
||||
if (!en || !td->tx_skb)
|
||||
return;
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
info->control.vif = dev->phy.monitor_vif;
|
||||
info = IEEE80211_SKB_CB(td->tx_skb);
|
||||
info->control.vif = phy->monitor_vif;
|
||||
|
||||
mt7915_tm_set_trx(phy, TM_MAC_TX, en);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_tm_set_rx_frames(struct mt7915_dev *dev, bool en)
|
||||
mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
|
||||
{
|
||||
if (en) {
|
||||
mutex_unlock(&dev->mt76.mutex);
|
||||
mt7915_set_channel(&dev->phy);
|
||||
mutex_lock(&dev->mt76.mutex);
|
||||
if (en)
|
||||
mt7915_tm_update_channel(phy);
|
||||
|
||||
mt7915_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH);
|
||||
}
|
||||
|
||||
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_RX_RXV, en);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_tm_update_params(struct mt7915_dev *dev, u32 changed)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->mt76.test;
|
||||
bool en = dev->mt76.test.state != MT76_TM_STATE_OFF;
|
||||
|
||||
if (changed & BIT(TM_CHANGED_FREQ_OFFSET))
|
||||
mt7915_tm_set_freq_offset(dev, en, en ? td->freq_offset : 0);
|
||||
if (changed & BIT(TM_CHANGED_TXPOWER))
|
||||
mt7915_tm_set_tx_power(&dev->phy);
|
||||
mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
|
||||
mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper)
|
||||
{
|
||||
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
|
||||
struct mt76_testmode_data *td = &mdev->test;
|
||||
struct mt7915_tm_rf_test req = {
|
||||
.op.op_mode = cpu_to_le32(oper),
|
||||
};
|
||||
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_TEST), &req,
|
||||
sizeof(req), true);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en)
|
||||
{
|
||||
#define TX_CONT_START 0x05
|
||||
#define TX_CONT_STOP 0x06
|
||||
struct mt7915_dev *dev = phy->dev;
|
||||
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
|
||||
int freq1 = ieee80211_frequency_to_channel(chandef->center_freq1);
|
||||
struct mt76_testmode_data *td = &phy->mt76->test;
|
||||
u32 func_idx = en ? TX_CONT_START : TX_CONT_STOP;
|
||||
u8 rate_idx = td->tx_rate_idx, mode;
|
||||
u16 rateval;
|
||||
struct mt7915_tm_rf_test req = {
|
||||
.action = 1,
|
||||
.icap_len = 120,
|
||||
.op.rf.func_idx = cpu_to_le32(func_idx),
|
||||
};
|
||||
struct tm_tx_cont *tx_cont = &req.op.rf.param.tx_cont;
|
||||
|
||||
tx_cont->control_ch = chandef->chan->hw_value;
|
||||
tx_cont->center_ch = freq1;
|
||||
tx_cont->tx_ant = td->tx_antenna_mask;
|
||||
tx_cont->band = phy != &dev->phy;
|
||||
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
tx_cont->bw = CMD_CBW_40MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
tx_cont->bw = CMD_CBW_80MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
tx_cont->bw = CMD_CBW_8080MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
tx_cont->bw = CMD_CBW_160MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
tx_cont->bw = CMD_CBW_5MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_10:
|
||||
tx_cont->bw = CMD_CBW_10MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
tx_cont->bw = CMD_CBW_20MHZ;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
tx_cont->bw = CMD_CBW_20MHZ;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!en) {
|
||||
req.op.rf.param.func_data = cpu_to_le32(phy != &dev->phy);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (td->tx_rate_mode <= MT76_TM_TX_MODE_OFDM) {
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 idx = rate_idx;
|
||||
|
||||
if (chandef->chan->band == NL80211_BAND_5GHZ)
|
||||
sband = &phy->mt76->sband_5g.sband;
|
||||
else
|
||||
sband = &phy->mt76->sband_2g.sband;
|
||||
|
||||
if (td->tx_rate_mode == MT76_TM_TX_MODE_OFDM)
|
||||
idx += 4;
|
||||
rate_idx = sband->bitrates[idx].hw_value & 0xff;
|
||||
}
|
||||
|
||||
switch (td->tx_rate_mode) {
|
||||
case MT76_TM_TX_MODE_CCK:
|
||||
mode = MT_PHY_TYPE_CCK;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_OFDM:
|
||||
mode = MT_PHY_TYPE_OFDM;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_HT:
|
||||
mode = MT_PHY_TYPE_HT;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_VHT:
|
||||
mode = MT_PHY_TYPE_VHT;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_HE_SU:
|
||||
mode = MT_PHY_TYPE_HE_SU;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_HE_EXT_SU:
|
||||
mode = MT_PHY_TYPE_HE_EXT_SU;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_HE_TB:
|
||||
mode = MT_PHY_TYPE_HE_TB;
|
||||
break;
|
||||
case MT76_TM_TX_MODE_HE_MU:
|
||||
mode = MT_PHY_TYPE_HE_MU;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rateval = mode << 6 | rate_idx;
|
||||
tx_cont->rateval = cpu_to_le16(rateval);
|
||||
|
||||
out:
|
||||
if (!en) {
|
||||
int ret;
|
||||
|
||||
ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_TEST), &req,
|
||||
sizeof(req), true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return mt7915_tm_rf_switch_mode(dev, RF_OPER_NORMAL);
|
||||
}
|
||||
|
||||
mt7915_tm_rf_switch_mode(dev, RF_OPER_RF_TEST);
|
||||
mt7915_tm_update_channel(phy);
|
||||
|
||||
return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RF_TEST), &req,
|
||||
sizeof(req), true);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
|
||||
{
|
||||
struct mt76_testmode_data *td = &phy->mt76->test;
|
||||
bool en = phy->mt76->test.state != MT76_TM_STATE_OFF;
|
||||
|
||||
if (changed & BIT(TM_CHANGED_FREQ_OFFSET))
|
||||
mt7915_tm_set_freq_offset(phy, en, en ? td->freq_offset : 0);
|
||||
if (changed & BIT(TM_CHANGED_TXPOWER))
|
||||
mt7915_tm_set_tx_power(phy);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
|
||||
{
|
||||
struct mt76_testmode_data *td = &mphy->test;
|
||||
struct mt7915_phy *phy = mphy->priv;
|
||||
enum mt76_testmode_state prev_state = td->state;
|
||||
|
||||
mdev->test.state = state;
|
||||
mphy->test.state = state;
|
||||
|
||||
if (prev_state == MT76_TM_STATE_TX_FRAMES)
|
||||
mt7915_tm_set_tx_frames(dev, false);
|
||||
else if (state == MT76_TM_STATE_TX_FRAMES)
|
||||
mt7915_tm_set_tx_frames(dev, true);
|
||||
else if (prev_state == MT76_TM_STATE_RX_FRAMES)
|
||||
mt7915_tm_set_rx_frames(dev, false);
|
||||
else if (state == MT76_TM_STATE_RX_FRAMES)
|
||||
mt7915_tm_set_rx_frames(dev, true);
|
||||
else if (prev_state == MT76_TM_STATE_OFF || state == MT76_TM_STATE_OFF)
|
||||
mt7915_tm_init(dev);
|
||||
if (prev_state == MT76_TM_STATE_TX_FRAMES ||
|
||||
state == MT76_TM_STATE_TX_FRAMES)
|
||||
mt7915_tm_set_tx_frames(phy, state == MT76_TM_STATE_TX_FRAMES);
|
||||
else if (prev_state == MT76_TM_STATE_RX_FRAMES ||
|
||||
state == MT76_TM_STATE_RX_FRAMES)
|
||||
mt7915_tm_set_rx_frames(phy, state == MT76_TM_STATE_RX_FRAMES);
|
||||
else if (prev_state == MT76_TM_STATE_TX_CONT ||
|
||||
state == MT76_TM_STATE_TX_CONT)
|
||||
mt7915_tm_set_tx_cont(phy, state == MT76_TM_STATE_TX_CONT);
|
||||
else if (prev_state == MT76_TM_STATE_OFF ||
|
||||
state == MT76_TM_STATE_OFF)
|
||||
mt7915_tm_init(phy, !(state == MT76_TM_STATE_OFF));
|
||||
|
||||
if ((state == MT76_TM_STATE_IDLE &&
|
||||
prev_state == MT76_TM_STATE_OFF) ||
|
||||
|
|
@ -284,18 +664,18 @@ mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
|
|||
changed |= BIT(i);
|
||||
}
|
||||
|
||||
mt7915_tm_update_params(dev, changed);
|
||||
mt7915_tm_update_params(phy, changed);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
|
||||
mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb,
|
||||
enum mt76_testmode_state new_state)
|
||||
{
|
||||
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
|
||||
struct mt76_testmode_data *td = &dev->mt76.test;
|
||||
struct mt76_testmode_data *td = &mphy->test;
|
||||
struct mt7915_phy *phy = mphy->priv;
|
||||
u32 changed = 0;
|
||||
int i;
|
||||
|
||||
|
|
@ -305,7 +685,7 @@ mt7915_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
|
|||
td->state == MT76_TM_STATE_OFF)
|
||||
return 0;
|
||||
|
||||
if (td->tx_antenna_mask & ~dev->phy.chainmask)
|
||||
if (td->tx_antenna_mask & ~mphy->chainmask)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
|
||||
|
|
@ -313,15 +693,15 @@ mt7915_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
|
|||
changed |= BIT(i);
|
||||
}
|
||||
|
||||
mt7915_tm_update_params(dev, changed);
|
||||
mt7915_tm_update_params(phy, changed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7915_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
|
||||
mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
|
||||
{
|
||||
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
|
||||
struct mt7915_phy *phy = mphy->priv;
|
||||
void *rx, *rssi;
|
||||
int i;
|
||||
|
||||
|
|
@ -329,15 +709,15 @@ mt7915_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
|
|||
if (!rx)
|
||||
return -ENOMEM;
|
||||
|
||||
if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, dev->test.last_freq_offset))
|
||||
if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, phy->test.last_freq_offset))
|
||||
return -ENOMEM;
|
||||
|
||||
rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RCPI);
|
||||
if (!rssi)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->test.last_rcpi); i++)
|
||||
if (nla_put_u8(msg, i, dev->test.last_rcpi[i]))
|
||||
for (i = 0; i < ARRAY_SIZE(phy->test.last_rcpi); i++)
|
||||
if (nla_put_u8(msg, i, phy->test.last_rcpi[i]))
|
||||
return -ENOMEM;
|
||||
|
||||
nla_nest_end(msg, rssi);
|
||||
|
|
@ -346,8 +726,8 @@ mt7915_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
|
|||
if (!rssi)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->test.last_ib_rssi); i++)
|
||||
if (nla_put_s8(msg, i, dev->test.last_ib_rssi[i]))
|
||||
for (i = 0; i < ARRAY_SIZE(phy->test.last_ib_rssi); i++)
|
||||
if (nla_put_s8(msg, i, phy->test.last_ib_rssi[i]))
|
||||
return -ENOMEM;
|
||||
|
||||
nla_nest_end(msg, rssi);
|
||||
|
|
@ -356,13 +736,13 @@ mt7915_tm_dump_stats(struct mt76_dev *mdev, struct sk_buff *msg)
|
|||
if (!rssi)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(dev->test.last_wb_rssi); i++)
|
||||
if (nla_put_s8(msg, i, dev->test.last_wb_rssi[i]))
|
||||
for (i = 0; i < ARRAY_SIZE(phy->test.last_wb_rssi); i++)
|
||||
if (nla_put_s8(msg, i, phy->test.last_wb_rssi[i]))
|
||||
return -ENOMEM;
|
||||
|
||||
nla_nest_end(msg, rssi);
|
||||
|
||||
if (nla_put_u8(msg, MT76_TM_RX_ATTR_SNR, dev->test.last_snr))
|
||||
if (nla_put_u8(msg, MT76_TM_RX_ATTR_SNR, phy->test.last_snr))
|
||||
return -ENOMEM;
|
||||
|
||||
nla_nest_end(msg, rx);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,23 @@ struct mt7915_tm_freq_offset {
|
|||
__le32 freq_offset;
|
||||
};
|
||||
|
||||
struct mt7915_tm_slot_time {
|
||||
u8 slot_time;
|
||||
u8 sifs;
|
||||
u8 rifs;
|
||||
u8 _rsv;
|
||||
__le16 eifs;
|
||||
u8 band;
|
||||
u8 _rsv1[5];
|
||||
};
|
||||
|
||||
struct mt7915_tm_clean_txq {
|
||||
bool sta_pause;
|
||||
u8 wcid; /* 256 sta */
|
||||
u8 band;
|
||||
u8 rsv;
|
||||
};
|
||||
|
||||
struct mt7915_tm_cmd {
|
||||
u8 testmode_en;
|
||||
u8 param_idx;
|
||||
|
|
@ -24,6 +41,8 @@ struct mt7915_tm_cmd {
|
|||
__le32 data;
|
||||
struct mt7915_tm_trx trx;
|
||||
struct mt7915_tm_freq_offset freq;
|
||||
struct mt7915_tm_slot_time slot;
|
||||
struct mt7915_tm_clean_txq clean;
|
||||
u8 test[72];
|
||||
} param;
|
||||
} __packed;
|
||||
|
|
@ -37,4 +56,44 @@ enum {
|
|||
TM_MAC_RX_RXV,
|
||||
};
|
||||
|
||||
struct tm_tx_cont {
|
||||
u8 control_ch;
|
||||
u8 center_ch;
|
||||
u8 bw;
|
||||
u8 tx_ant;
|
||||
__le16 rateval;
|
||||
u8 band;
|
||||
u8 txfd_mode;
|
||||
};
|
||||
|
||||
struct mt7915_tm_rf_test {
|
||||
u8 action;
|
||||
u8 icap_len;
|
||||
u8 _rsv[2];
|
||||
union {
|
||||
__le32 op_mode;
|
||||
__le32 freq;
|
||||
|
||||
struct {
|
||||
__le32 func_idx;
|
||||
union {
|
||||
__le32 func_data;
|
||||
__le32 cal_dump;
|
||||
|
||||
struct tm_tx_cont tx_cont;
|
||||
|
||||
u8 _pad[80];
|
||||
} param;
|
||||
} rf;
|
||||
} op;
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
RF_OPER_NORMAL,
|
||||
RF_OPER_RF_TEST,
|
||||
RF_OPER_ICAP,
|
||||
RF_OPER_ICAP_OVERLAP,
|
||||
RF_OPER_WIFI_SPECTRUM,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
11
drivers/net/wireless/mediatek/mt76/mt7921/Kconfig
Normal file
11
drivers/net/wireless/mediatek/mt76/mt7921/Kconfig
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# SPDX-License-Identifier: ISC
|
||||
config MT7921E
|
||||
tristate "MediaTek MT7921E (PCIe) support"
|
||||
select MT76_CONNAC_LIB
|
||||
select WANT_DEV_COREDUMP
|
||||
depends on MAC80211
|
||||
depends on PCI
|
||||
help
|
||||
This adds support for MT7921E 802.11ax 2x2:2SS wireless devices.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
5
drivers/net/wireless/mediatek/mt76/mt7921/Makefile
Normal file
5
drivers/net/wireless/mediatek/mt76/mt7921/Makefile
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#SPDX-License-Identifier: ISC
|
||||
|
||||
obj-$(CONFIG_MT7921E) += mt7921e.o
|
||||
|
||||
mt7921e-y := pci.o mac.o mcu.o dma.o eeprom.o main.o init.o debugfs.o
|
||||
250
drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
Normal file
250
drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#include "mt7921.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
static int
|
||||
mt7921_fw_debug_set(void *data, u64 val)
|
||||
{
|
||||
struct mt7921_dev *dev = data;
|
||||
|
||||
dev->fw_debug = (u8)val;
|
||||
|
||||
mt7921_mcu_fw_log_2_host(dev, dev->fw_debug);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7921_fw_debug_get(void *data, u64 *val)
|
||||
{
|
||||
struct mt7921_dev *dev = data;
|
||||
|
||||
*val = dev->fw_debug;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_fw_debug, mt7921_fw_debug_get,
|
||||
mt7921_fw_debug_set, "%lld\n");
|
||||
|
||||
static void
|
||||
mt7921_ampdu_stat_read_phy(struct mt7921_phy *phy,
|
||||
struct seq_file *file)
|
||||
{
|
||||
struct mt7921_dev *dev = file->private;
|
||||
int bound[15], range[4], i;
|
||||
|
||||
if (!phy)
|
||||
return;
|
||||
|
||||
/* Tx ampdu stat */
|
||||
for (i = 0; i < ARRAY_SIZE(range); i++)
|
||||
range[i] = mt76_rr(dev, MT_MIB_ARNG(0, i));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bound); i++)
|
||||
bound[i] = MT_MIB_ARNCR_RANGE(range[i / 4], i) + 1;
|
||||
|
||||
seq_printf(file, "\nPhy0\n");
|
||||
|
||||
seq_printf(file, "Length: %8d | ", bound[0]);
|
||||
for (i = 0; i < ARRAY_SIZE(bound) - 1; i++)
|
||||
seq_printf(file, "%3d -%3d | ",
|
||||
bound[i] + 1, bound[i + 1]);
|
||||
|
||||
seq_puts(file, "\nCount: ");
|
||||
for (i = 0; i < ARRAY_SIZE(bound); i++)
|
||||
seq_printf(file, "%8d | ", dev->mt76.aggr_stats[i]);
|
||||
seq_puts(file, "\n");
|
||||
|
||||
seq_printf(file, "BA miss count: %d\n", phy->mib.ba_miss_cnt);
|
||||
}
|
||||
|
||||
static int
|
||||
mt7921_tx_stats_read(struct seq_file *file, void *data)
|
||||
{
|
||||
struct mt7921_dev *dev = file->private;
|
||||
int stat[8], i, n;
|
||||
|
||||
mt7921_ampdu_stat_read_phy(&dev->phy, file);
|
||||
|
||||
/* Tx amsdu info */
|
||||
seq_puts(file, "Tx MSDU stat:\n");
|
||||
for (i = 0, n = 0; i < ARRAY_SIZE(stat); i++) {
|
||||
stat[i] = mt76_rr(dev, MT_PLE_AMSDU_PACK_MSDU_CNT(i));
|
||||
n += stat[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(stat); i++) {
|
||||
seq_printf(file, "AMSDU pack count of %d MSDU in TXD: 0x%x ",
|
||||
i + 1, stat[i]);
|
||||
if (n != 0)
|
||||
seq_printf(file, "(%d%%)\n", stat[i] * 100 / n);
|
||||
else
|
||||
seq_puts(file, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7921_tx_stats_open(struct inode *inode, struct file *f)
|
||||
{
|
||||
return single_open(f, mt7921_tx_stats_read, inode->i_private);
|
||||
}
|
||||
|
||||
static const struct file_operations fops_tx_stats = {
|
||||
.open = mt7921_tx_stats_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int
|
||||
mt7921_queues_acq(struct seq_file *s, void *data)
|
||||
{
|
||||
struct mt7921_dev *dev = dev_get_drvdata(s->private);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
int j, acs = i / 4, index = i % 4;
|
||||
u32 ctrl, val, qlen = 0;
|
||||
|
||||
val = mt76_rr(dev, MT_PLE_AC_QEMPTY(acs, index));
|
||||
ctrl = BIT(31) | BIT(15) | (acs << 8);
|
||||
|
||||
for (j = 0; j < 32; j++) {
|
||||
if (val & BIT(j))
|
||||
continue;
|
||||
|
||||
mt76_wr(dev, MT_PLE_FL_Q0_CTRL,
|
||||
ctrl | (j + (index << 5)));
|
||||
qlen += mt76_get_field(dev, MT_PLE_FL_Q3_CTRL,
|
||||
GENMASK(11, 0));
|
||||
}
|
||||
seq_printf(s, "AC%d%d: queued=%d\n", acs, index, qlen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7921_queues_read(struct seq_file *s, void *data)
|
||||
{
|
||||
struct mt7921_dev *dev = dev_get_drvdata(s->private);
|
||||
struct {
|
||||
struct mt76_queue *q;
|
||||
char *queue;
|
||||
} queue_map[] = {
|
||||
{ dev->mphy.q_tx[MT_TXQ_BE], "WFDMA0" },
|
||||
{ dev->mt76.q_mcu[MT_MCUQ_WM], "MCUWM" },
|
||||
{ dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" },
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
|
||||
struct mt76_queue *q = queue_map[i].q;
|
||||
|
||||
if (!q)
|
||||
continue;
|
||||
|
||||
seq_printf(s,
|
||||
"%s: queued=%d head=%d tail=%d\n",
|
||||
queue_map[i].queue, q->queued, q->head,
|
||||
q->tail);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7921_pm_set(void *data, u64 val)
|
||||
{
|
||||
struct mt7921_dev *dev = data;
|
||||
struct mt76_phy *mphy = dev->phy.mt76;
|
||||
int ret = 0;
|
||||
|
||||
mt7921_mutex_acquire(dev);
|
||||
|
||||
dev->pm.enable = val;
|
||||
|
||||
ieee80211_iterate_active_interfaces(mphy->hw,
|
||||
IEEE80211_IFACE_ITER_RESUME_ALL,
|
||||
mt7921_pm_interface_iter, mphy->priv);
|
||||
mt7921_mutex_release(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7921_pm_get(void *data, u64 *val)
|
||||
{
|
||||
struct mt7921_dev *dev = data;
|
||||
|
||||
*val = dev->pm.enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7921_pm_get, mt7921_pm_set, "%lld\n");
|
||||
|
||||
static int
|
||||
mt7921_pm_idle_timeout_set(void *data, u64 val)
|
||||
{
|
||||
struct mt7921_dev *dev = data;
|
||||
|
||||
dev->pm.idle_timeout = msecs_to_jiffies(val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mt7921_pm_idle_timeout_get(void *data, u64 *val)
|
||||
{
|
||||
struct mt7921_dev *dev = data;
|
||||
|
||||
*val = jiffies_to_msecs(dev->pm.idle_timeout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_pm_idle_timeout, mt7921_pm_idle_timeout_get,
|
||||
mt7921_pm_idle_timeout_set, "%lld\n");
|
||||
|
||||
static int mt7921_config(void *data, u64 val)
|
||||
{
|
||||
struct mt7921_dev *dev = data;
|
||||
int ret;
|
||||
|
||||
mt7921_mutex_acquire(dev);
|
||||
ret = mt76_connac_mcu_chip_config(&dev->mt76);
|
||||
mt7921_mutex_release(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_DEBUGFS_ATTRIBUTE(fops_config, NULL, mt7921_config, "%lld\n");
|
||||
|
||||
int mt7921_init_debugfs(struct mt7921_dev *dev)
|
||||
{
|
||||
struct dentry *dir;
|
||||
|
||||
dir = mt76_register_debugfs(&dev->mt76);
|
||||
if (!dir)
|
||||
return -ENOMEM;
|
||||
|
||||
debugfs_create_devm_seqfile(dev->mt76.dev, "queues", dir,
|
||||
mt7921_queues_read);
|
||||
debugfs_create_devm_seqfile(dev->mt76.dev, "acq", dir,
|
||||
mt7921_queues_acq);
|
||||
debugfs_create_file("tx_stats", 0400, dir, dev, &fops_tx_stats);
|
||||
debugfs_create_file("fw_debug", 0600, dir, dev, &fops_fw_debug);
|
||||
debugfs_create_file("runtime-pm", 0600, dir, dev, &fops_pm);
|
||||
debugfs_create_file("idle-timeout", 0600, dir, dev,
|
||||
&fops_pm_idle_timeout);
|
||||
debugfs_create_file("chip_config", 0600, dir, dev, &fops_config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
356
drivers/net/wireless/mediatek/mt76/mt7921/dma.c
Normal file
356
drivers/net/wireless/mediatek/mt76/mt7921/dma.c
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#include "mt7921.h"
|
||||
#include "../dma.h"
|
||||
#include "mac.h"
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
void mt7921_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
__le32 *rxd = (__le32 *)skb->data;
|
||||
enum rx_pkt_type type;
|
||||
u16 flag;
|
||||
|
||||
type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0]));
|
||||
flag = FIELD_GET(MT_RXD0_PKT_FLAG, le32_to_cpu(rxd[0]));
|
||||
|
||||
if (type == PKT_TYPE_RX_EVENT && flag == 0x1)
|
||||
type = PKT_TYPE_NORMAL_MCU;
|
||||
|
||||
switch (type) {
|
||||
case PKT_TYPE_TXRX_NOTIFY:
|
||||
mt7921_mac_tx_free(dev, skb);
|
||||
break;
|
||||
case PKT_TYPE_RX_EVENT:
|
||||
mt7921_mcu_rx_event(dev, skb);
|
||||
break;
|
||||
case PKT_TYPE_NORMAL_MCU:
|
||||
case PKT_TYPE_NORMAL:
|
||||
if (!mt7921_mac_fill_rx(dev, skb)) {
|
||||
mt76_rx(&dev->mt76, q, skb);
|
||||
return;
|
||||
}
|
||||
fallthrough;
|
||||
default:
|
||||
dev_kfree_skb(skb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mt7921_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 int mt7921_poll_tx(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct mt7921_dev *dev;
|
||||
|
||||
dev = container_of(napi, struct mt7921_dev, mt76.tx_napi);
|
||||
|
||||
mt7921_tx_cleanup(dev);
|
||||
|
||||
if (napi_complete_done(napi, 0))
|
||||
mt7921_irq_enable(dev, MT_INT_TX_DONE_ALL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt7921_dma_prefetch(struct mt7921_dev *dev)
|
||||
{
|
||||
#define PREFETCH(base, depth) ((base) << 16 | (depth))
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL, PREFETCH(0x0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL, PREFETCH(0x40, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING3_EXT_CTRL, PREFETCH(0x80, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING4_EXT_CTRL, PREFETCH(0xc0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_RX_RING5_EXT_CTRL, PREFETCH(0x100, 0x4));
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, PREFETCH(0x140, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING1_EXT_CTRL, PREFETCH(0x180, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING2_EXT_CTRL, PREFETCH(0x1c0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING3_EXT_CTRL, PREFETCH(0x200, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING4_EXT_CTRL, PREFETCH(0x240, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING5_EXT_CTRL, PREFETCH(0x280, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING6_EXT_CTRL, PREFETCH(0x2c0, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING16_EXT_CTRL, PREFETCH(0x340, 0x4));
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING17_EXT_CTRL, PREFETCH(0x380, 0x4));
|
||||
}
|
||||
|
||||
static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr)
|
||||
{
|
||||
static const struct {
|
||||
u32 phys;
|
||||
u32 mapped;
|
||||
u32 size;
|
||||
} fixed_map[] = {
|
||||
{ 0x00400000, 0x80000, 0x10000}, /* WF_MCU_SYSRAM */
|
||||
{ 0x00410000, 0x90000, 0x10000}, /* WF_MCU_SYSRAM (configure register) */
|
||||
{ 0x40000000, 0x70000, 0x10000}, /* WF_UMAC_SYSRAM */
|
||||
{ 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */
|
||||
{ 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */
|
||||
{ 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */
|
||||
{ 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */
|
||||
{ 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */
|
||||
{ 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */
|
||||
{ 0x7c060000, 0xe0000, 0x10000}, /* CONN_INFRA, conn_host_csr_top */
|
||||
{ 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */
|
||||
{ 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */
|
||||
{ 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */
|
||||
{ 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */
|
||||
{ 0x820cc000, 0x0e000, 0x2000 }, /* WF_UMAC_TOP (PP) */
|
||||
{ 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */
|
||||
{ 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */
|
||||
{ 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */
|
||||
{ 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */
|
||||
{ 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */
|
||||
{ 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */
|
||||
{ 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */
|
||||
{ 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */
|
||||
{ 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */
|
||||
{ 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */
|
||||
{ 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */
|
||||
{ 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */
|
||||
{ 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */
|
||||
{ 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */
|
||||
{ 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */
|
||||
{ 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */
|
||||
{ 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */
|
||||
{ 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */
|
||||
{ 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */
|
||||
{ 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */
|
||||
{ 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */
|
||||
{ 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */
|
||||
{ 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */
|
||||
{ 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */
|
||||
{ 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */
|
||||
{ 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */
|
||||
{ 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */
|
||||
};
|
||||
int i;
|
||||
|
||||
if (addr < 0x100000)
|
||||
return addr;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fixed_map); i++) {
|
||||
u32 ofs;
|
||||
|
||||
if (addr < fixed_map[i].phys)
|
||||
continue;
|
||||
|
||||
ofs = addr - fixed_map[i].phys;
|
||||
if (ofs > fixed_map[i].size)
|
||||
continue;
|
||||
|
||||
return fixed_map[i].mapped + ofs;
|
||||
}
|
||||
|
||||
if ((addr >= 0x18000000 && addr < 0x18c00000) ||
|
||||
(addr >= 0x70000000 && addr < 0x78000000) ||
|
||||
(addr >= 0x7c000000 && addr < 0x7c400000))
|
||||
return mt7921_reg_map_l1(dev, addr);
|
||||
|
||||
dev_err(dev->mt76.dev, "Access currently unsupported address %08x\n",
|
||||
addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset)
|
||||
{
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
u32 addr = __mt7921_reg_addr(dev, offset);
|
||||
|
||||
return dev->bus_ops->rr(mdev, addr);
|
||||
}
|
||||
|
||||
static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val)
|
||||
{
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
u32 addr = __mt7921_reg_addr(dev, offset);
|
||||
|
||||
dev->bus_ops->wr(mdev, addr, val);
|
||||
}
|
||||
|
||||
static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
|
||||
{
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
u32 addr = __mt7921_reg_addr(dev, offset);
|
||||
|
||||
return dev->bus_ops->rmw(mdev, addr, mask, val);
|
||||
}
|
||||
|
||||
static int mt7921_dmashdl_disabled(struct mt7921_dev *dev)
|
||||
{
|
||||
mt76_clear(dev, MT_WFDMA0_GLO_CFG_EXT0, MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
|
||||
mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt7921_dma_init(struct mt7921_dev *dev)
|
||||
{
|
||||
/* Increase buffer size to receive large VHT/HE MPDUs */
|
||||
struct mt76_bus_ops *bus_ops;
|
||||
int rx_buf_size = MT_RX_BUF_SIZE * 2;
|
||||
int ret;
|
||||
|
||||
dev->bus_ops = dev->mt76.bus;
|
||||
bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),
|
||||
GFP_KERNEL);
|
||||
if (!bus_ops)
|
||||
return -ENOMEM;
|
||||
|
||||
bus_ops->rr = mt7921_rr;
|
||||
bus_ops->wr = mt7921_wr;
|
||||
bus_ops->rmw = mt7921_rmw;
|
||||
dev->mt76.bus = bus_ops;
|
||||
|
||||
mt76_dma_attach(&dev->mt76);
|
||||
|
||||
/* reset */
|
||||
mt76_clear(dev, MT_WFDMA0_RST,
|
||||
MT_WFDMA0_RST_DMASHDL_ALL_RST |
|
||||
MT_WFDMA0_RST_LOGIC_RST);
|
||||
|
||||
mt76_set(dev, MT_WFDMA0_RST,
|
||||
MT_WFDMA0_RST_DMASHDL_ALL_RST |
|
||||
MT_WFDMA0_RST_LOGIC_RST);
|
||||
|
||||
ret = mt7921_dmashdl_disabled(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* disable WFDMA0 */
|
||||
mt76_clear(dev, MT_WFDMA0_GLO_CFG,
|
||||
MT_WFDMA0_GLO_CFG_TX_DMA_EN |
|
||||
MT_WFDMA0_GLO_CFG_RX_DMA_EN |
|
||||
MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
|
||||
MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
|
||||
MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
|
||||
MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
|
||||
|
||||
mt76_poll(dev, MT_WFDMA0_GLO_CFG,
|
||||
MT_WFDMA0_GLO_CFG_TX_DMA_BUSY |
|
||||
MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000);
|
||||
|
||||
/* init tx queue */
|
||||
ret = mt7921_init_tx_queues(&dev->phy, MT7921_TXQ_BAND0,
|
||||
MT7921_TX_RING_SIZE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_TX_RING0_EXT_CTRL, 0x4);
|
||||
|
||||
/* command to WM */
|
||||
ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7921_TXQ_MCU_WM,
|
||||
MT7921_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* firmware download */
|
||||
ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7921_TXQ_FWDL,
|
||||
MT7921_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* event from WM before firmware download */
|
||||
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
|
||||
MT7921_RXQ_MCU_WM,
|
||||
MT7921_RX_MCU_RING_SIZE,
|
||||
rx_buf_size, MT_RX_EVENT_RING_BASE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Change mcu queue after firmware download */
|
||||
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
|
||||
MT7921_RXQ_MCU_WM,
|
||||
MT7921_RX_MCU_RING_SIZE,
|
||||
rx_buf_size, MT_WFDMA0(0x540));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* rx data */
|
||||
ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN],
|
||||
MT7921_RXQ_BAND0, MT7921_RX_RING_SIZE,
|
||||
rx_buf_size, MT_RX_DATA_RING_BASE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mt76_init_queues(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
netif_tx_napi_add(&dev->mt76.napi_dev, &dev->mt76.tx_napi,
|
||||
mt7921_poll_tx, NAPI_POLL_WEIGHT);
|
||||
napi_enable(&dev->mt76.tx_napi);
|
||||
|
||||
/* configure perfetch settings */
|
||||
mt7921_dma_prefetch(dev);
|
||||
|
||||
/* reset dma idx */
|
||||
mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
|
||||
|
||||
/* configure delay interrupt */
|
||||
mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
|
||||
|
||||
mt76_set(dev, MT_WFDMA0_GLO_CFG,
|
||||
MT_WFDMA0_GLO_CFG_TX_WB_DDONE |
|
||||
MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN |
|
||||
MT_WFDMA0_GLO_CFG_CLK_GAT_DIS |
|
||||
MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
|
||||
MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
|
||||
MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
|
||||
|
||||
mt76_set(dev, MT_WFDMA0_GLO_CFG,
|
||||
MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
|
||||
|
||||
mt76_set(dev, 0x54000120, BIT(1));
|
||||
|
||||
/* enable interrupts for TX/RX rings */
|
||||
mt7921_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
|
||||
MT_INT_MCU_CMD);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt7921_dma_cleanup(struct mt7921_dev *dev)
|
||||
{
|
||||
/* disable */
|
||||
mt76_clear(dev, MT_WFDMA0_GLO_CFG,
|
||||
MT_WFDMA0_GLO_CFG_TX_DMA_EN |
|
||||
MT_WFDMA0_GLO_CFG_RX_DMA_EN |
|
||||
MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN |
|
||||
MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
|
||||
MT_WFDMA0_GLO_CFG_OMIT_RX_INFO |
|
||||
MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2);
|
||||
|
||||
/* reset */
|
||||
mt76_clear(dev, MT_WFDMA0_RST,
|
||||
MT_WFDMA0_RST_DMASHDL_ALL_RST |
|
||||
MT_WFDMA0_RST_LOGIC_RST);
|
||||
|
||||
mt76_set(dev, MT_WFDMA0_RST,
|
||||
MT_WFDMA0_RST_DMASHDL_ALL_RST |
|
||||
MT_WFDMA0_RST_LOGIC_RST);
|
||||
|
||||
mt76_dma_cleanup(&dev->mt76);
|
||||
}
|
||||
100
drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c
Normal file
100
drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#include "mt7921.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
static u32 mt7921_eeprom_read(struct mt7921_dev *dev, u32 offset)
|
||||
{
|
||||
u8 *data = dev->mt76.eeprom.data;
|
||||
|
||||
if (data[offset] == 0xff)
|
||||
mt7921_mcu_get_eeprom(dev, offset);
|
||||
|
||||
return data[offset];
|
||||
}
|
||||
|
||||
static int mt7921_eeprom_load(struct mt7921_dev *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mt76_eeprom_init(&dev->mt76, MT7921_EEPROM_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
memset(dev->mt76.eeprom.data, -1, MT7921_EEPROM_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt7921_check_eeprom(struct mt7921_dev *dev)
|
||||
{
|
||||
u8 *eeprom = dev->mt76.eeprom.data;
|
||||
u16 val;
|
||||
|
||||
mt7921_eeprom_read(dev, MT_EE_CHIP_ID);
|
||||
val = get_unaligned_le16(eeprom);
|
||||
|
||||
switch (val) {
|
||||
case 0x7961:
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void mt7921_eeprom_parse_band_config(struct mt7921_phy *phy)
|
||||
{
|
||||
struct mt7921_dev *dev = phy->dev;
|
||||
u32 val;
|
||||
|
||||
val = mt7921_eeprom_read(dev, MT_EE_WIFI_CONF);
|
||||
val = FIELD_GET(MT_EE_WIFI_CONF_BAND_SEL, val);
|
||||
|
||||
switch (val) {
|
||||
case MT_EE_5GHZ:
|
||||
phy->mt76->cap.has_5ghz = true;
|
||||
break;
|
||||
case MT_EE_2GHZ:
|
||||
phy->mt76->cap.has_2ghz = true;
|
||||
break;
|
||||
default:
|
||||
phy->mt76->cap.has_2ghz = true;
|
||||
phy->mt76->cap.has_5ghz = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mt7921_eeprom_parse_hw_cap(struct mt7921_dev *dev)
|
||||
{
|
||||
u8 tx_mask;
|
||||
|
||||
mt7921_eeprom_parse_band_config(&dev->phy);
|
||||
|
||||
/* TODO: read NSS with MCU_CMD_NIC_CAPV2 */
|
||||
tx_mask = 2;
|
||||
dev->chainmask = BIT(tx_mask) - 1;
|
||||
dev->mphy.antenna_mask = dev->chainmask;
|
||||
dev->mphy.chainmask = dev->mphy.antenna_mask;
|
||||
}
|
||||
|
||||
int mt7921_eeprom_init(struct mt7921_dev *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = mt7921_eeprom_load(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mt7921_check_eeprom(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt7921_eeprom_parse_hw_cap(dev);
|
||||
memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR,
|
||||
ETH_ALEN);
|
||||
|
||||
mt76_eeprom_override(&dev->mphy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
27
drivers/net/wireless/mediatek/mt76/mt7921/eeprom.h
Normal file
27
drivers/net/wireless/mediatek/mt76/mt7921/eeprom.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#ifndef __MT7921_EEPROM_H
|
||||
#define __MT7921_EEPROM_H
|
||||
|
||||
#include "mt7921.h"
|
||||
|
||||
enum mt7921_eeprom_field {
|
||||
MT_EE_CHIP_ID = 0x000,
|
||||
MT_EE_VERSION = 0x002,
|
||||
MT_EE_MAC_ADDR = 0x004,
|
||||
MT_EE_WIFI_CONF = 0x07c,
|
||||
__MT_EE_MAX = 0x3bf
|
||||
};
|
||||
|
||||
#define MT_EE_WIFI_CONF_TX_MASK BIT(0)
|
||||
#define MT_EE_WIFI_CONF_BAND_SEL GENMASK(3, 2)
|
||||
|
||||
enum mt7921_eeprom_band {
|
||||
MT_EE_NA,
|
||||
MT_EE_5GHZ,
|
||||
MT_EE_2GHZ,
|
||||
MT_EE_DUAL_BAND,
|
||||
};
|
||||
|
||||
#endif
|
||||
282
drivers/net/wireless/mediatek/mt76/mt7921/init.c
Normal file
282
drivers/net/wireless/mediatek/mt76/mt7921/init.c
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
#include "mt7921.h"
|
||||
#include "mac.h"
|
||||
#include "mcu.h"
|
||||
#include "eeprom.h"
|
||||
|
||||
#define CCK_RATE(_idx, _rate) { \
|
||||
.bitrate = _rate, \
|
||||
.flags = IEEE80211_RATE_SHORT_PREAMBLE, \
|
||||
.hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \
|
||||
.hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + (_idx)), \
|
||||
}
|
||||
|
||||
#define OFDM_RATE(_idx, _rate) { \
|
||||
.bitrate = _rate, \
|
||||
.hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
|
||||
.hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \
|
||||
}
|
||||
|
||||
static struct ieee80211_rate mt7921_rates[] = {
|
||||
CCK_RATE(0, 10),
|
||||
CCK_RATE(1, 20),
|
||||
CCK_RATE(2, 55),
|
||||
CCK_RATE(3, 110),
|
||||
OFDM_RATE(11, 60),
|
||||
OFDM_RATE(15, 90),
|
||||
OFDM_RATE(10, 120),
|
||||
OFDM_RATE(14, 180),
|
||||
OFDM_RATE(9, 240),
|
||||
OFDM_RATE(13, 360),
|
||||
OFDM_RATE(8, 480),
|
||||
OFDM_RATE(12, 540),
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_limit if_limits[] = {
|
||||
{
|
||||
.max = MT7921_MAX_INTERFACES,
|
||||
.types = BIT(NL80211_IFTYPE_STATION)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination if_comb[] = {
|
||||
{
|
||||
.limits = if_limits,
|
||||
.n_limits = ARRAY_SIZE(if_limits),
|
||||
.max_interfaces = MT7921_MAX_INTERFACES,
|
||||
.num_different_channels = 1,
|
||||
.beacon_int_infra_match = true,
|
||||
}
|
||||
};
|
||||
|
||||
static void
|
||||
mt7921_regd_notifier(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct mt7921_dev *dev = mt7921_hw_dev(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);
|
||||
mt7921_mutex_release(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7921_init_wiphy(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct mt7921_phy *phy = mt7921_hw_phy(hw);
|
||||
struct wiphy *wiphy = hw->wiphy;
|
||||
|
||||
hw->queues = 4;
|
||||
hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
|
||||
hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
|
||||
|
||||
phy->slottime = 9;
|
||||
|
||||
hw->sta_data_size = sizeof(struct mt7921_sta);
|
||||
hw->vif_data_size = sizeof(struct mt7921_vif);
|
||||
|
||||
wiphy->iface_combinations = if_comb;
|
||||
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
|
||||
wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN;
|
||||
wiphy->max_scan_ssids = 4;
|
||||
wiphy->max_sched_scan_plan_interval =
|
||||
MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL;
|
||||
wiphy->max_sched_scan_ie_len = IEEE80211_MAX_DATA_LEN;
|
||||
wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID;
|
||||
wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH;
|
||||
wiphy->max_sched_scan_reqs = 1;
|
||||
wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
||||
wiphy->reg_notifier = mt7921_regd_notifier;
|
||||
|
||||
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL);
|
||||
|
||||
ieee80211_hw_set(hw, SINGLE_SCAN_ON_ALL_BANDS);
|
||||
ieee80211_hw_set(hw, HAS_RATE_CONTROL);
|
||||
ieee80211_hw_set(hw, SUPPORTS_TX_ENCAP_OFFLOAD);
|
||||
ieee80211_hw_set(hw, WANT_MONITOR_VIF);
|
||||
ieee80211_hw_set(hw, SUPPORTS_PS);
|
||||
ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
|
||||
|
||||
hw->max_tx_fragments = 4;
|
||||
}
|
||||
|
||||
static void
|
||||
mt7921_mac_init_band(struct mt7921_dev *dev, u8 band)
|
||||
{
|
||||
u32 mask, set;
|
||||
|
||||
mt76_rmw_field(dev, MT_TMAC_CTCR0(band),
|
||||
MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);
|
||||
mt76_set(dev, MT_TMAC_CTCR0(band),
|
||||
MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
|
||||
MT_TMAC_CTCR0_INS_DDLMT_EN);
|
||||
|
||||
mask = MT_MDP_RCFR0_MCU_RX_MGMT |
|
||||
MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR |
|
||||
MT_MDP_RCFR0_MCU_RX_CTL_BAR;
|
||||
set = FIELD_PREP(MT_MDP_RCFR0_MCU_RX_MGMT, MT_MDP_TO_HIF) |
|
||||
FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR, MT_MDP_TO_HIF) |
|
||||
FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_BAR, MT_MDP_TO_HIF);
|
||||
mt76_rmw(dev, MT_MDP_BNRCFR0(band), mask, set);
|
||||
|
||||
mask = MT_MDP_RCFR1_MCU_RX_BYPASS |
|
||||
MT_MDP_RCFR1_RX_DROPPED_UCAST |
|
||||
MT_MDP_RCFR1_RX_DROPPED_MCAST;
|
||||
set = FIELD_PREP(MT_MDP_RCFR1_MCU_RX_BYPASS, MT_MDP_TO_HIF) |
|
||||
FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_TO_HIF) |
|
||||
FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF);
|
||||
mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set);
|
||||
|
||||
mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
|
||||
mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
|
||||
|
||||
mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_MAX_RX_LEN, 1536);
|
||||
/* disable rx rate report by default due to hw issues */
|
||||
mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN);
|
||||
}
|
||||
|
||||
static void mt7921_mac_init(struct mt7921_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, 1536);
|
||||
/* disable hardware de-agg */
|
||||
mt76_clear(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);
|
||||
mt76_clear(dev, MT_MDP_DCR0, MT_MDP_DCR0_RX_HDR_TRANS_EN);
|
||||
|
||||
for (i = 0; i < MT7921_WTBL_SIZE; i++)
|
||||
mt7921_mac_wtbl_update(dev, i,
|
||||
MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
|
||||
for (i = 0; i < 2; i++)
|
||||
mt7921_mac_init_band(dev, i);
|
||||
|
||||
mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b, 0);
|
||||
}
|
||||
|
||||
static void mt7921_init_work(struct work_struct *work)
|
||||
{
|
||||
struct mt7921_dev *dev = container_of(work, struct mt7921_dev,
|
||||
init_work);
|
||||
|
||||
mt7921_mcu_set_eeprom(dev);
|
||||
mt7921_mac_init(dev);
|
||||
}
|
||||
|
||||
static int mt7921_init_hardware(struct mt7921_dev *dev)
|
||||
{
|
||||
int ret, idx;
|
||||
|
||||
INIT_WORK(&dev->init_work, mt7921_init_work);
|
||||
spin_lock_init(&dev->token_lock);
|
||||
idr_init(&dev->token);
|
||||
|
||||
ret = mt7921_dma_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
|
||||
|
||||
/* force firmware operation mode into normal state,
|
||||
* which should be set before firmware download stage.
|
||||
*/
|
||||
mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
|
||||
|
||||
ret = mt7921_mcu_init(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = mt7921_eeprom_init(dev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Beacon and mgmt frames should occupy wcid 0 */
|
||||
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7921_WTBL_STA - 1);
|
||||
if (idx)
|
||||
return -ENOSPC;
|
||||
|
||||
dev->mt76.global_wcid.idx = idx;
|
||||
dev->mt76.global_wcid.hw_key_idx = -1;
|
||||
dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;
|
||||
rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt7921_register_device(struct mt7921_dev *dev)
|
||||
{
|
||||
struct ieee80211_hw *hw = mt76_hw(dev);
|
||||
int ret;
|
||||
|
||||
dev->phy.dev = dev;
|
||||
dev->phy.mt76 = &dev->mt76.phy;
|
||||
dev->mt76.phy.priv = &dev->phy;
|
||||
|
||||
INIT_DELAYED_WORK(&dev->pm.ps_work, mt7921_pm_power_save_work);
|
||||
INIT_WORK(&dev->pm.wake_work, mt7921_pm_wake_work);
|
||||
init_completion(&dev->pm.wake_cmpl);
|
||||
spin_lock_init(&dev->pm.txq_lock);
|
||||
set_bit(MT76_STATE_PM, &dev->mphy.state);
|
||||
INIT_LIST_HEAD(&dev->phy.stats_list);
|
||||
INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7921_mac_work);
|
||||
INIT_DELAYED_WORK(&dev->phy.scan_work, mt7921_scan_work);
|
||||
INIT_DELAYED_WORK(&dev->coredump.work, mt7921_coredump_work);
|
||||
skb_queue_head_init(&dev->phy.scan_event_list);
|
||||
skb_queue_head_init(&dev->coredump.msg_list);
|
||||
INIT_LIST_HEAD(&dev->sta_poll_list);
|
||||
spin_lock_init(&dev->sta_poll_lock);
|
||||
|
||||
init_waitqueue_head(&dev->reset_wait);
|
||||
INIT_WORK(&dev->reset_work, mt7921_mac_reset_work);
|
||||
|
||||
ret = mt7921_init_hardware(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mt7921_init_wiphy(hw);
|
||||
dev->pm.idle_timeout = MT7921_PM_TIMEOUT;
|
||||
dev->mphy.sband_2g.sband.ht_cap.cap |=
|
||||
IEEE80211_HT_CAP_LDPC_CODING |
|
||||
IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
dev->mphy.sband_5g.sband.ht_cap.cap |=
|
||||
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_A_MPDU_LENGTH_EXPONENT_MASK;
|
||||
dev->mphy.sband_5g.sband.vht_cap.cap |=
|
||||
IEEE80211_VHT_CAP_SHORT_GI_160 |
|
||||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
|
||||
dev->mphy.hw->wiphy->available_antennas_rx = dev->mphy.chainmask;
|
||||
dev->mphy.hw->wiphy->available_antennas_tx = dev->mphy.chainmask;
|
||||
|
||||
mt76_set_stream_caps(&dev->mphy, true);
|
||||
mt7921_set_stream_he_caps(&dev->phy);
|
||||
|
||||
ret = mt76_register_device(&dev->mt76, true, mt7921_rates,
|
||||
ARRAY_SIZE(mt7921_rates));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
|
||||
|
||||
return mt7921_init_debugfs(dev);
|
||||
}
|
||||
|
||||
void mt7921_unregister_device(struct mt7921_dev *dev)
|
||||
{
|
||||
mt76_unregister_device(&dev->mt76);
|
||||
mt7921_mcu_exit(dev);
|
||||
mt7921_dma_cleanup(dev);
|
||||
|
||||
mt7921_tx_token_put(dev);
|
||||
|
||||
tasklet_disable(&dev->irq_tasklet);
|
||||
mt76_free_device(&dev->mt76);
|
||||
}
|
||||
1516
drivers/net/wireless/mediatek/mt76/mt7921/mac.c
Normal file
1516
drivers/net/wireless/mediatek/mt76/mt7921/mac.c
Normal file
File diff suppressed because it is too large
Load Diff
333
drivers/net/wireless/mediatek/mt76/mt7921/mac.h
Normal file
333
drivers/net/wireless/mediatek/mt76/mt7921/mac.h
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#ifndef __MT7921_MAC_H
|
||||
#define __MT7921_MAC_H
|
||||
|
||||
#define MT_CT_PARSE_LEN 72
|
||||
#define MT_CT_DMA_BUF_NUM 2
|
||||
|
||||
#define MT_RXD0_LENGTH GENMASK(15, 0)
|
||||
#define MT_RXD0_PKT_FLAG GENMASK(19, 16)
|
||||
#define MT_RXD0_PKT_TYPE GENMASK(31, 27)
|
||||
|
||||
#define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16)
|
||||
#define MT_RXD0_NORMAL_IP_SUM BIT(23)
|
||||
#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24)
|
||||
|
||||
enum rx_pkt_type {
|
||||
PKT_TYPE_TXS,
|
||||
PKT_TYPE_TXRXV,
|
||||
PKT_TYPE_NORMAL,
|
||||
PKT_TYPE_RX_DUP_RFB,
|
||||
PKT_TYPE_RX_TMR,
|
||||
PKT_TYPE_RETRIEVE,
|
||||
PKT_TYPE_TXRX_NOTIFY,
|
||||
PKT_TYPE_RX_EVENT,
|
||||
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_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)
|
||||
|
||||
/* P-RXV */
|
||||
#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_HT_AD_CODE BIT(11)
|
||||
#define MT_PRXV_HE_RU_ALLOC_L GENMASK(31, 28)
|
||||
#define MT_PRXV_HE_RU_ALLOC_H GENMASK(3, 0)
|
||||
#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)
|
||||
|
||||
/* 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_UPLINK BIT(31)
|
||||
|
||||
#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_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_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)
|
||||
/* 0: success, others: dropped */
|
||||
#define MT_TX_FREE_STATUS GENMASK(14, 13)
|
||||
#define MT_TX_FREE_MSDU_ID GENMASK(30, 16)
|
||||
#define MT_TX_FREE_PAIR BIT(31)
|
||||
/* will support this field in further revision */
|
||||
#define MT_TX_FREE_RATE GENMASK(13, 0)
|
||||
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
1161
drivers/net/wireless/mediatek/mt76/mt7921/main.c
Normal file
1161
drivers/net/wireless/mediatek/mt76/mt7921/main.c
Normal file
File diff suppressed because it is too large
Load Diff
1308
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
Normal file
1308
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
Normal file
File diff suppressed because it is too large
Load Diff
434
drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
Normal file
434
drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
Normal file
|
|
@ -0,0 +1,434 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#ifndef __MT7921_MCU_H
|
||||
#define __MT7921_MCU_H
|
||||
|
||||
#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);
|
||||
|
||||
/* event table */
|
||||
enum {
|
||||
MCU_EVENT_REG_ACCESS = 0x05,
|
||||
MCU_EVENT_SCAN_DONE = 0x0d,
|
||||
MCU_EVENT_BSS_ABSENCE = 0x11,
|
||||
MCU_EVENT_BSS_BEACON_LOSS = 0x13,
|
||||
MCU_EVENT_CH_PRIVILEGE = 0x18,
|
||||
MCU_EVENT_SCHED_SCAN_DONE = 0x23,
|
||||
MCU_EVENT_DBG_MSG = 0x27,
|
||||
MCU_EVENT_COREDUMP = 0xf0,
|
||||
};
|
||||
|
||||
/* ext event table */
|
||||
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;
|
||||
u8 data[16];
|
||||
} __packed;
|
||||
|
||||
#define MT_RA_RATE_NSS GENMASK(8, 6)
|
||||
#define MT_RA_RATE_MCS GENMASK(3, 0)
|
||||
#define MT_RA_RATE_TX_MODE GENMASK(12, 9)
|
||||
#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
|
||||
|
||||
enum {
|
||||
MCU_Q_QUERY,
|
||||
MCU_Q_SET,
|
||||
MCU_Q_RESERVED,
|
||||
MCU_Q_NA
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_S2D_H2N,
|
||||
MCU_S2D_C2N,
|
||||
MCU_S2D_H2C,
|
||||
MCU_S2D_H2CN
|
||||
};
|
||||
|
||||
struct mt7921_mcu_uni_event {
|
||||
u8 cid;
|
||||
u8 pad[3];
|
||||
__le32 status; /* 0: success, others: fail */
|
||||
} __packed;
|
||||
|
||||
enum {
|
||||
PATCH_NOT_DL_SEM_FAIL,
|
||||
PATCH_IS_DL,
|
||||
PATCH_NOT_DL_SEM_SUCCESS,
|
||||
PATCH_REL_SEM_SUCCESS
|
||||
};
|
||||
|
||||
enum {
|
||||
FW_STATE_INITIAL,
|
||||
FW_STATE_FW_DOWNLOAD,
|
||||
FW_STATE_NORMAL_OPERATION,
|
||||
FW_STATE_NORMAL_TRX,
|
||||
FW_STATE_WACPU_RDY = 7
|
||||
};
|
||||
|
||||
enum {
|
||||
EE_MODE_EFUSE,
|
||||
EE_MODE_BUFFER,
|
||||
};
|
||||
|
||||
enum {
|
||||
EE_FORMAT_BIN,
|
||||
EE_FORMAT_WHOLE,
|
||||
EE_FORMAT_MULTIPLE,
|
||||
};
|
||||
|
||||
enum {
|
||||
MCU_PHY_STATE_TX_RATE,
|
||||
MCU_PHY_STATE_RX_RATE,
|
||||
MCU_PHY_STATE_RSSI,
|
||||
MCU_PHY_STATE_CONTENTION_RX_RATE,
|
||||
MCU_PHY_STATE_OFDMLQ_CNINFO,
|
||||
};
|
||||
|
||||
#define STA_TYPE_STA BIT(0)
|
||||
#define STA_TYPE_AP BIT(1)
|
||||
#define STA_TYPE_ADHOC BIT(2)
|
||||
#define STA_TYPE_WDS BIT(4)
|
||||
#define STA_TYPE_BC BIT(5)
|
||||
|
||||
#define NETWORK_INFRA BIT(16)
|
||||
#define NETWORK_P2P BIT(17)
|
||||
#define NETWORK_IBSS BIT(18)
|
||||
#define NETWORK_WDS BIT(21)
|
||||
|
||||
#define CONNECTION_INFRA_STA (STA_TYPE_STA | NETWORK_INFRA)
|
||||
#define CONNECTION_INFRA_AP (STA_TYPE_AP | NETWORK_INFRA)
|
||||
#define CONNECTION_P2P_GC (STA_TYPE_STA | NETWORK_P2P)
|
||||
#define CONNECTION_P2P_GO (STA_TYPE_AP | NETWORK_P2P)
|
||||
#define CONNECTION_IBSS_ADHOC (STA_TYPE_ADHOC | NETWORK_IBSS)
|
||||
#define CONNECTION_WDS (STA_TYPE_WDS | NETWORK_WDS)
|
||||
#define CONNECTION_INFRA_BC (STA_TYPE_BC | NETWORK_INFRA)
|
||||
|
||||
struct sec_key {
|
||||
u8 cipher_id;
|
||||
u8 cipher_len;
|
||||
u8 key_id;
|
||||
u8 key_len;
|
||||
u8 key[32];
|
||||
} __packed;
|
||||
|
||||
struct sta_rec_sec {
|
||||
__le16 tag;
|
||||
__le16 len;
|
||||
u8 add;
|
||||
u8 n_cipher;
|
||||
u8 rsv[2];
|
||||
|
||||
struct sec_key key[2];
|
||||
} __packed;
|
||||
|
||||
enum mt7921_cipher_type {
|
||||
MT_CIPHER_NONE,
|
||||
MT_CIPHER_WEP40,
|
||||
MT_CIPHER_WEP104,
|
||||
MT_CIPHER_WEP128,
|
||||
MT_CIPHER_TKIP,
|
||||
MT_CIPHER_AES_CCMP,
|
||||
MT_CIPHER_CCMP_256,
|
||||
MT_CIPHER_GCMP,
|
||||
MT_CIPHER_GCMP_256,
|
||||
MT_CIPHER_WAPI,
|
||||
MT_CIPHER_BIP_CMAC_128,
|
||||
};
|
||||
|
||||
enum {
|
||||
CH_SWITCH_NORMAL = 0,
|
||||
CH_SWITCH_SCAN = 3,
|
||||
CH_SWITCH_MCC = 4,
|
||||
CH_SWITCH_DFS = 5,
|
||||
CH_SWITCH_BACKGROUND_SCAN_START = 6,
|
||||
CH_SWITCH_BACKGROUND_SCAN_RUNNING = 7,
|
||||
CH_SWITCH_BACKGROUND_SCAN_STOP = 8,
|
||||
CH_SWITCH_SCAN_BYPASS_DPD = 9
|
||||
};
|
||||
|
||||
enum {
|
||||
THERMAL_SENSOR_TEMP_QUERY,
|
||||
THERMAL_SENSOR_MANUAL_CTRL,
|
||||
THERMAL_SENSOR_INFO_QUERY,
|
||||
THERMAL_SENSOR_TASK_CTRL,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT_EBF = BIT(0), /* explicit beamforming */
|
||||
MT_IBF = BIT(1) /* implicit beamforming */
|
||||
};
|
||||
|
||||
#define MT7921_WTBL_UPDATE_MAX_SIZE (sizeof(struct wtbl_req_hdr) + \
|
||||
sizeof(struct wtbl_generic) + \
|
||||
sizeof(struct wtbl_rx) + \
|
||||
sizeof(struct wtbl_ht) + \
|
||||
sizeof(struct wtbl_vht) + \
|
||||
sizeof(struct wtbl_hdr_trans) +\
|
||||
sizeof(struct wtbl_ba) + \
|
||||
sizeof(struct wtbl_smps))
|
||||
|
||||
#define MT7921_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \
|
||||
sizeof(struct sta_rec_basic) + \
|
||||
sizeof(struct sta_rec_ht) + \
|
||||
sizeof(struct sta_rec_he) + \
|
||||
sizeof(struct sta_rec_ba) + \
|
||||
sizeof(struct sta_rec_vht) + \
|
||||
sizeof(struct sta_rec_uapsd) + \
|
||||
sizeof(struct sta_rec_amsdu) + \
|
||||
sizeof(struct tlv) + \
|
||||
MT7921_WTBL_UPDATE_MAX_SIZE)
|
||||
|
||||
#define MT7921_WTBL_UPDATE_BA_SIZE (sizeof(struct wtbl_req_hdr) + \
|
||||
sizeof(struct wtbl_ba))
|
||||
|
||||
#define STA_CAP_WMM BIT(0)
|
||||
#define STA_CAP_SGI_20 BIT(4)
|
||||
#define STA_CAP_SGI_40 BIT(5)
|
||||
#define STA_CAP_TX_STBC BIT(6)
|
||||
#define STA_CAP_RX_STBC BIT(7)
|
||||
#define STA_CAP_VHT_SGI_80 BIT(16)
|
||||
#define STA_CAP_VHT_SGI_160 BIT(17)
|
||||
#define STA_CAP_VHT_TX_STBC BIT(18)
|
||||
#define STA_CAP_VHT_RX_STBC BIT(19)
|
||||
#define STA_CAP_VHT_LDPC BIT(23)
|
||||
#define STA_CAP_LDPC BIT(24)
|
||||
#define STA_CAP_HT BIT(26)
|
||||
#define STA_CAP_VHT BIT(27)
|
||||
#define STA_CAP_HE BIT(28)
|
||||
|
||||
struct mt7921_mcu_reg_event {
|
||||
__le32 reg;
|
||||
__le32 val;
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_tx_config {
|
||||
u8 peer_addr[ETH_ALEN];
|
||||
u8 sw;
|
||||
u8 dis_rx_hdr_tran;
|
||||
|
||||
u8 aad_om;
|
||||
u8 pfmu_idx;
|
||||
__le16 partial_aid;
|
||||
|
||||
u8 ibf;
|
||||
u8 ebf;
|
||||
u8 is_ht;
|
||||
u8 is_vht;
|
||||
|
||||
u8 mesh;
|
||||
u8 baf_en;
|
||||
u8 cf_ack;
|
||||
u8 rdg_ba;
|
||||
|
||||
u8 rdg;
|
||||
u8 pm;
|
||||
u8 rts;
|
||||
u8 smps;
|
||||
|
||||
u8 txop_ps;
|
||||
u8 not_update_ipsm;
|
||||
u8 skip_tx;
|
||||
u8 ldpc;
|
||||
|
||||
u8 qos;
|
||||
u8 from_ds;
|
||||
u8 to_ds;
|
||||
u8 dyn_bw;
|
||||
|
||||
u8 amdsu_cross_lg;
|
||||
u8 check_per;
|
||||
u8 gid_63;
|
||||
u8 he;
|
||||
|
||||
u8 vht_ibf;
|
||||
u8 vht_ebf;
|
||||
u8 vht_ldpc;
|
||||
u8 he_ldpc;
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_sec_config {
|
||||
u8 wpi_flag;
|
||||
u8 rv;
|
||||
u8 ikv;
|
||||
u8 rkv;
|
||||
|
||||
u8 rcid;
|
||||
u8 rca1;
|
||||
u8 rca2;
|
||||
u8 even_pn;
|
||||
|
||||
u8 key_id;
|
||||
u8 muar_idx;
|
||||
u8 cipher_suit;
|
||||
u8 rsv[1];
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_key_config {
|
||||
u8 key[32];
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_rate_info {
|
||||
u8 mpdu_fail;
|
||||
u8 mpdu_tx;
|
||||
u8 rate_idx;
|
||||
u8 rsv[1];
|
||||
__le16 rate[8];
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_ba_config {
|
||||
u8 ba_en;
|
||||
u8 rsv[3];
|
||||
__le32 ba_winsize;
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_ant_id_config {
|
||||
u8 ant_id[4];
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_peer_cap {
|
||||
struct mt7921_mcu_ant_id_config ant_id_config;
|
||||
|
||||
u8 power_offset;
|
||||
u8 bw_selector;
|
||||
u8 change_bw_rate_n;
|
||||
u8 bw;
|
||||
u8 spe_idx;
|
||||
|
||||
u8 g2;
|
||||
u8 g4;
|
||||
u8 g8;
|
||||
u8 g16;
|
||||
|
||||
u8 mmss;
|
||||
u8 ampdu_factor;
|
||||
u8 rsv[1];
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_rx_cnt {
|
||||
u8 rx_rcpi[4];
|
||||
u8 rx_cc[4];
|
||||
u8 rx_cc_sel;
|
||||
u8 ce_rmsd;
|
||||
u8 rsv[2];
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_tx_cnt {
|
||||
__le16 rate1_cnt;
|
||||
__le16 rate1_fail_cnt;
|
||||
__le16 rate2_cnt;
|
||||
__le16 rate3_cnt;
|
||||
__le16 cur_bw_tx_cnt;
|
||||
__le16 cur_bw_tx_fail_cnt;
|
||||
__le16 other_bw_tx_cnt;
|
||||
__le16 other_bw_tx_fail_cnt;
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_wlan_info_event {
|
||||
struct mt7921_mcu_tx_config tx_config;
|
||||
struct mt7921_mcu_sec_config sec_config;
|
||||
struct mt7921_mcu_key_config key_config;
|
||||
struct mt7921_mcu_rate_info rate_info;
|
||||
struct mt7921_mcu_ba_config ba_config;
|
||||
struct mt7921_mcu_peer_cap peer_cap;
|
||||
struct mt7921_mcu_rx_cnt rx_cnt;
|
||||
struct mt7921_mcu_tx_cnt tx_cnt;
|
||||
} __packed;
|
||||
|
||||
struct mt7921_mcu_wlan_info {
|
||||
__le32 wlan_idx;
|
||||
struct mt7921_mcu_wlan_info_event event;
|
||||
} __packed;
|
||||
#endif
|
||||
342
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
Normal file
342
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
Normal file
|
|
@ -0,0 +1,342 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#ifndef __MT7921_H
|
||||
#define __MT7921_H
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ktime.h>
|
||||
#include "../mt76_connac_mcu.h"
|
||||
#include "regs.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 - \
|
||||
MT7921_MAX_INTERFACES)
|
||||
|
||||
#define MT7921_PM_TIMEOUT (HZ / 12)
|
||||
#define MT7921_HW_SCAN_TIMEOUT (HZ / 10)
|
||||
#define MT7921_WATCHDOG_TIME (HZ / 10)
|
||||
#define MT7921_RESET_TIMEOUT (30 * HZ)
|
||||
|
||||
#define MT7921_TX_RING_SIZE 2048
|
||||
#define MT7921_TX_MCU_RING_SIZE 256
|
||||
#define MT7921_TX_FWDL_RING_SIZE 128
|
||||
|
||||
#define MT7921_RX_RING_SIZE 1536
|
||||
#define MT7921_RX_MCU_RING_SIZE 512
|
||||
|
||||
#define MT7921_DRV_OWN_RETRY_COUNT 10
|
||||
|
||||
#define MT7921_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7961_1.bin"
|
||||
#define MT7921_ROM_PATCH "mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin"
|
||||
|
||||
#define MT7921_EEPROM_SIZE 3584
|
||||
#define MT7921_TOKEN_SIZE 8192
|
||||
#define MT7921_TOKEN_FREE_THR 64
|
||||
|
||||
#define MT7921_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */
|
||||
#define MT7921_CFEND_RATE_11B 0x03 /* 11B LP, 11M */
|
||||
#define MT7921_5G_RATE_DEFAULT 0x4b /* OFDM 6M */
|
||||
#define MT7921_2G_RATE_DEFAULT 0x0 /* CCK 1M */
|
||||
|
||||
#define MT7921_SKU_RATE_NUM 161
|
||||
#define MT7921_SKU_MAX_DELTA_IDX MT7921_SKU_RATE_NUM
|
||||
#define MT7921_SKU_TABLE_SIZE (MT7921_SKU_RATE_NUM + 1)
|
||||
|
||||
struct mt7921_vif;
|
||||
struct mt7921_sta;
|
||||
|
||||
enum mt7921_txq_id {
|
||||
MT7921_TXQ_BAND0,
|
||||
MT7921_TXQ_BAND1,
|
||||
MT7921_TXQ_FWDL = 16,
|
||||
MT7921_TXQ_MCU_WM,
|
||||
};
|
||||
|
||||
enum mt7921_rxq_id {
|
||||
MT7921_RXQ_BAND0 = 0,
|
||||
MT7921_RXQ_BAND1,
|
||||
MT7921_RXQ_MCU_WM = 0,
|
||||
};
|
||||
|
||||
struct mt7921_sta_stats {
|
||||
struct rate_info prob_rate;
|
||||
struct rate_info tx_rate;
|
||||
|
||||
unsigned long per;
|
||||
unsigned long changed;
|
||||
unsigned long jiffies;
|
||||
};
|
||||
|
||||
struct mt7921_sta_key_conf {
|
||||
s8 keyidx;
|
||||
u8 key[16];
|
||||
};
|
||||
|
||||
struct mt7921_sta {
|
||||
struct mt76_wcid wcid; /* must be first */
|
||||
|
||||
struct mt7921_vif *vif;
|
||||
|
||||
struct list_head stats_list;
|
||||
struct list_head poll_list;
|
||||
u32 airtime_ac[8];
|
||||
|
||||
struct mt7921_sta_stats stats;
|
||||
|
||||
unsigned long ampdu_state;
|
||||
|
||||
struct mt7921_sta_key_conf bip;
|
||||
};
|
||||
|
||||
struct mt7921_vif {
|
||||
struct mt76_vif mt76; /* must be first */
|
||||
|
||||
struct mt7921_sta sta;
|
||||
struct mt7921_phy *phy;
|
||||
|
||||
struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
|
||||
};
|
||||
|
||||
struct mib_stats {
|
||||
u16 ack_fail_cnt;
|
||||
u16 fcs_err_cnt;
|
||||
u16 rts_cnt;
|
||||
u16 rts_retries_cnt;
|
||||
u16 ba_miss_cnt;
|
||||
};
|
||||
|
||||
struct mt7921_phy {
|
||||
struct mt76_phy *mt76;
|
||||
struct mt7921_dev *dev;
|
||||
|
||||
struct ieee80211_sband_iftype_data iftype[2][NUM_NL80211_IFTYPES];
|
||||
|
||||
struct ieee80211_vif *monitor_vif;
|
||||
|
||||
u32 rxfilter;
|
||||
u64 omac_mask;
|
||||
|
||||
u16 noise;
|
||||
|
||||
s16 coverage_class;
|
||||
u8 slottime;
|
||||
|
||||
__le32 rx_ampdu_ts;
|
||||
u32 ampdu_ref;
|
||||
|
||||
struct mib_stats mib;
|
||||
struct list_head stats_list;
|
||||
|
||||
u8 sta_work_count;
|
||||
|
||||
struct sk_buff_head scan_event_list;
|
||||
struct delayed_work scan_work;
|
||||
};
|
||||
|
||||
struct mt7921_dev {
|
||||
union { /* must be first */
|
||||
struct mt76_dev mt76;
|
||||
struct mt76_phy mphy;
|
||||
};
|
||||
|
||||
const struct mt76_bus_ops *bus_ops;
|
||||
struct mt7921_phy phy;
|
||||
struct tasklet_struct irq_tasklet;
|
||||
|
||||
u16 chainmask;
|
||||
|
||||
struct work_struct init_work;
|
||||
struct work_struct reset_work;
|
||||
wait_queue_head_t reset_wait;
|
||||
u32 reset_state;
|
||||
|
||||
struct list_head sta_poll_list;
|
||||
spinlock_t sta_poll_lock;
|
||||
|
||||
spinlock_t token_lock;
|
||||
int token_count;
|
||||
struct idr token;
|
||||
|
||||
u8 fw_debug;
|
||||
|
||||
struct mt76_connac_pm pm;
|
||||
struct mt76_connac_coredump coredump;
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
struct mt76_phy *phy = hw->priv;
|
||||
|
||||
return phy->priv;
|
||||
}
|
||||
|
||||
static inline struct mt7921_dev *
|
||||
mt7921_hw_dev(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct mt76_phy *phy = hw->priv;
|
||||
|
||||
return container_of(phy->dev, struct mt7921_dev, mt76);
|
||||
}
|
||||
|
||||
#define mt7921_mutex_acquire(dev) \
|
||||
mt76_connac_mutex_acquire(&(dev)->mt76, &(dev)->pm)
|
||||
#define mt7921_mutex_release(dev) \
|
||||
mt76_connac_mutex_release(&(dev)->mt76, &(dev)->pm)
|
||||
|
||||
static inline u8 mt7921_lmac_mapping(struct mt7921_dev *dev, u8 ac)
|
||||
{
|
||||
/* LMAC uses the reverse order of mac80211 AC indexes */
|
||||
return 3 - ac;
|
||||
}
|
||||
|
||||
extern const struct ieee80211_ops mt7921_ops;
|
||||
extern struct pci_driver mt7921_pci_driver;
|
||||
|
||||
u32 mt7921_reg_map(struct mt7921_dev *dev, u32 addr);
|
||||
|
||||
int mt7921_register_device(struct mt7921_dev *dev);
|
||||
void mt7921_unregister_device(struct mt7921_dev *dev);
|
||||
int mt7921_eeprom_init(struct mt7921_dev *dev);
|
||||
void mt7921_eeprom_parse_band_config(struct mt7921_phy *phy);
|
||||
int mt7921_eeprom_get_target_power(struct mt7921_dev *dev,
|
||||
struct ieee80211_channel *chan,
|
||||
u8 chain_idx);
|
||||
void mt7921_eeprom_init_sku(struct mt7921_dev *dev);
|
||||
int mt7921_dma_init(struct mt7921_dev *dev);
|
||||
void mt7921_dma_prefetch(struct mt7921_dev *dev);
|
||||
void mt7921_dma_cleanup(struct mt7921_dev *dev);
|
||||
int mt7921_mcu_init(struct mt7921_dev *dev);
|
||||
int mt7921_mcu_add_bss_info(struct mt7921_phy *phy,
|
||||
struct ieee80211_vif *vif, int enable);
|
||||
int mt7921_mcu_add_key(struct mt7921_dev *dev, struct ieee80211_vif *vif,
|
||||
struct mt7921_sta *msta, struct ieee80211_key_conf *key,
|
||||
enum set_key_cmd cmd);
|
||||
int mt7921_set_channel(struct mt7921_phy *phy);
|
||||
int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd);
|
||||
int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif);
|
||||
int mt7921_mcu_set_eeprom(struct mt7921_dev *dev);
|
||||
int mt7921_mcu_get_eeprom(struct mt7921_dev *dev, u32 offset);
|
||||
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)
|
||||
{
|
||||
mt76_set_irq_mask(&dev->mt76, 0, 0, mask);
|
||||
|
||||
tasklet_schedule(&dev->irq_tasklet);
|
||||
}
|
||||
|
||||
static inline u32
|
||||
mt7921_reg_map_l1(struct mt7921_dev *dev, u32 addr)
|
||||
{
|
||||
u32 offset = FIELD_GET(MT_HIF_REMAP_L1_OFFSET, addr);
|
||||
u32 base = FIELD_GET(MT_HIF_REMAP_L1_BASE, addr);
|
||||
|
||||
mt76_rmw_field(dev, MT_HIF_REMAP_L1, MT_HIF_REMAP_L1_MASK, base);
|
||||
/* use read to push write */
|
||||
mt76_rr(dev, MT_HIF_REMAP_L1);
|
||||
|
||||
return MT_HIF_REMAP_BASE_L1 + offset;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
mt7921_l1_rr(struct mt7921_dev *dev, u32 addr)
|
||||
{
|
||||
return mt76_rr(dev, mt7921_reg_map_l1(dev, addr));
|
||||
}
|
||||
|
||||
static inline void
|
||||
mt7921_l1_wr(struct mt7921_dev *dev, u32 addr, u32 val)
|
||||
{
|
||||
mt76_wr(dev, mt7921_reg_map_l1(dev, addr), val);
|
||||
}
|
||||
|
||||
static inline u32
|
||||
mt7921_l1_rmw(struct mt7921_dev *dev, u32 addr, u32 mask, u32 val)
|
||||
{
|
||||
val |= mt7921_l1_rr(dev, addr) & ~mask;
|
||||
mt7921_l1_wr(dev, addr, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#define mt7921_l1_set(dev, addr, val) mt7921_l1_rmw(dev, addr, 0, val)
|
||||
#define mt7921_l1_clear(dev, addr, val) mt7921_l1_rmw(dev, addr, val, 0)
|
||||
|
||||
bool mt7921_mac_wtbl_update(struct mt7921_dev *dev, int idx, u32 mask);
|
||||
void mt7921_mac_reset_counters(struct mt7921_phy *phy);
|
||||
void mt7921_mac_write_txwi(struct mt7921_dev *dev, __le32 *txwi,
|
||||
struct sk_buff *skb, struct mt76_wcid *wcid,
|
||||
struct ieee80211_key_conf *key, bool beacon);
|
||||
void mt7921_mac_set_timing(struct mt7921_phy *phy);
|
||||
int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb);
|
||||
void mt7921_mac_fill_rx_vector(struct mt7921_dev *dev, struct sk_buff *skb);
|
||||
void mt7921_mac_tx_free(struct mt7921_dev *dev, struct sk_buff *skb);
|
||||
int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
void mt7921_mac_work(struct work_struct *work);
|
||||
void mt7921_mac_reset_work(struct work_struct *work);
|
||||
int mt7921_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
|
||||
enum mt76_txq_id qid, struct mt76_wcid *wcid,
|
||||
struct ieee80211_sta *sta,
|
||||
struct mt76_tx_info *tx_info);
|
||||
void mt7921_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
|
||||
int mt7921_init_tx_queues(struct mt7921_phy *phy, int idx, int n_desc);
|
||||
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);
|
||||
void mt7921_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps);
|
||||
void mt7921_stats_work(struct work_struct *work);
|
||||
void mt7921_txp_skb_unmap(struct mt76_dev *dev,
|
||||
struct mt76_txwi_cache *txwi);
|
||||
void mt7921_set_stream_he_caps(struct mt7921_phy *phy);
|
||||
void mt7921_update_channel(struct mt76_dev *mdev);
|
||||
int mt7921_init_debugfs(struct mt7921_dev *dev);
|
||||
|
||||
int mt7921_mcu_uni_tx_ba(struct mt7921_dev *dev,
|
||||
struct ieee80211_ampdu_params *params,
|
||||
bool enable);
|
||||
int mt7921_mcu_uni_rx_ba(struct mt7921_dev *dev,
|
||||
struct ieee80211_ampdu_params *params,
|
||||
bool enable);
|
||||
void mt7921_scan_work(struct work_struct *work);
|
||||
u32 mt7921_get_wtbl_info(struct mt7921_dev *dev, u32 wlan_idx);
|
||||
int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif);
|
||||
int mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif,
|
||||
bool enable);
|
||||
int mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
|
||||
bool enable);
|
||||
int mt7921_mcu_update_arp_filter(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *info);
|
||||
int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev);
|
||||
int mt7921_mcu_fw_pmctrl(struct mt7921_dev *dev);
|
||||
void mt7921_pm_wake_work(struct work_struct *work);
|
||||
void mt7921_pm_power_save_work(struct work_struct *work);
|
||||
bool mt7921_wait_for_mcu_init(struct mt7921_dev *dev);
|
||||
int mt7921_mac_set_beacon_filter(struct mt7921_phy *phy,
|
||||
struct ieee80211_vif *vif,
|
||||
bool enable);
|
||||
void mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif);
|
||||
void mt7921_coredump_work(struct work_struct *work);
|
||||
#endif
|
||||
292
drivers/net/wireless/mediatek/mt76/mt7921/pci.c
Normal file
292
drivers/net/wireless/mediatek/mt76/mt7921/pci.c
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
// SPDX-License-Identifier: ISC
|
||||
/* Copyright (C) 2020 MediaTek Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "mt7921.h"
|
||||
#include "mac.h"
|
||||
#include "mcu.h"
|
||||
#include "../trace.h"
|
||||
|
||||
static const struct pci_device_id mt7921_pci_device_table[] = {
|
||||
{ PCI_DEVICE(0x14c3, 0x7961) },
|
||||
{ },
|
||||
};
|
||||
|
||||
static void
|
||||
mt7921_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
|
||||
{
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
|
||||
if (q == MT_RXQ_MAIN)
|
||||
mt7921_irq_enable(dev, MT_INT_RX_DONE_DATA);
|
||||
else if (q == MT_RXQ_MCU_WA)
|
||||
mt7921_irq_enable(dev, MT_INT_RX_DONE_WM2);
|
||||
else
|
||||
mt7921_irq_enable(dev, MT_INT_RX_DONE_WM);
|
||||
}
|
||||
|
||||
static irqreturn_t mt7921_irq_handler(int irq, void *dev_instance)
|
||||
{
|
||||
struct mt7921_dev *dev = dev_instance;
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
|
||||
|
||||
if (!test_bit(MT76_STATE_INITIALIZED, &dev->mphy.state))
|
||||
return IRQ_NONE;
|
||||
|
||||
tasklet_schedule(&dev->irq_tasklet);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void mt7921_irq_tasklet(unsigned long data)
|
||||
{
|
||||
struct mt7921_dev *dev = (struct mt7921_dev *)data;
|
||||
u32 intr, mask = 0;
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
|
||||
|
||||
intr = mt76_rr(dev, MT_WFDMA0_HOST_INT_STA);
|
||||
intr &= dev->mt76.mmio.irqmask;
|
||||
mt76_wr(dev, MT_WFDMA0_HOST_INT_STA, intr);
|
||||
|
||||
trace_dev_irq(&dev->mt76, intr, dev->mt76.mmio.irqmask);
|
||||
|
||||
mask |= intr & MT_INT_RX_DONE_ALL;
|
||||
if (intr & MT_INT_TX_DONE_MCU)
|
||||
mask |= MT_INT_TX_DONE_MCU;
|
||||
|
||||
mt76_set_irq_mask(&dev->mt76, MT_WFDMA0_HOST_INT_ENA, mask, 0);
|
||||
|
||||
if (intr & MT_INT_TX_DONE_ALL)
|
||||
napi_schedule(&dev->mt76.tx_napi);
|
||||
|
||||
if (intr & MT_INT_RX_DONE_WM)
|
||||
napi_schedule(&dev->mt76.napi[MT_RXQ_MCU]);
|
||||
|
||||
if (intr & MT_INT_RX_DONE_WM2)
|
||||
napi_schedule(&dev->mt76.napi[MT_RXQ_MCU_WA]);
|
||||
|
||||
if (intr & MT_INT_RX_DONE_DATA)
|
||||
napi_schedule(&dev->mt76.napi[MT_RXQ_MAIN]);
|
||||
}
|
||||
|
||||
static int mt7921_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
static const struct mt76_driver_ops drv_ops = {
|
||||
/* txwi_size = txd size + txp size */
|
||||
.txwi_size = MT_TXD_SIZE + sizeof(struct mt7921_txp_common),
|
||||
.drv_flags = MT_DRV_TXWI_NO_FREE | MT_DRV_HW_MGMT_TXQ |
|
||||
MT_DRV_AMSDU_OFFLOAD,
|
||||
.survey_flags = SURVEY_INFO_TIME_TX |
|
||||
SURVEY_INFO_TIME_RX |
|
||||
SURVEY_INFO_TIME_BSS_RX,
|
||||
.tx_prepare_skb = mt7921_tx_prepare_skb,
|
||||
.tx_complete_skb = mt7921_tx_complete_skb,
|
||||
.rx_skb = mt7921_queue_rx_skb,
|
||||
.rx_poll_complete = mt7921_rx_poll_complete,
|
||||
.sta_ps = mt7921_sta_ps,
|
||||
.sta_add = mt7921_mac_sta_add,
|
||||
.sta_remove = mt7921_mac_sta_remove,
|
||||
.update_survey = mt7921_update_channel,
|
||||
};
|
||||
struct mt7921_dev *dev;
|
||||
struct mt76_dev *mdev;
|
||||
int ret;
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
goto err_free_pci_vec;
|
||||
|
||||
mt76_pci_disable_aspm(pdev);
|
||||
|
||||
mdev = mt76_alloc_device(&pdev->dev, sizeof(*dev), &mt7921_ops,
|
||||
&drv_ops);
|
||||
if (!mdev) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_pci_vec;
|
||||
}
|
||||
|
||||
dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
|
||||
mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
|
||||
tasklet_init(&dev->irq_tasklet, mt7921_irq_tasklet, (unsigned long)dev);
|
||||
mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) |
|
||||
(mt7921_l1_rr(dev, MT_HW_REV) & 0xff);
|
||||
dev_err(mdev->dev, "ASIC revision: %04x\n", mdev->rev);
|
||||
|
||||
mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
|
||||
|
||||
mt7921_l1_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
|
||||
|
||||
ret = devm_request_irq(mdev->dev, pdev->irq, mt7921_irq_handler,
|
||||
IRQF_SHARED, KBUILD_MODNAME, dev);
|
||||
if (ret)
|
||||
goto err_free_dev;
|
||||
|
||||
ret = mt7921_register_device(dev);
|
||||
if (ret)
|
||||
goto err_free_dev;
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_dev:
|
||||
mt76_free_device(&dev->mt76);
|
||||
err_free_pci_vec:
|
||||
pci_free_irq_vectors(pdev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mt7921_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct mt76_dev *mdev = pci_get_drvdata(pdev);
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
|
||||
mt7921_unregister_device(dev);
|
||||
devm_free_irq(&pdev->dev, pdev->irq, dev);
|
||||
pci_free_irq_vectors(pdev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int mt7921_pci_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
{
|
||||
struct mt76_dev *mdev = pci_get_drvdata(pdev);
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
bool hif_suspend;
|
||||
int i, err;
|
||||
|
||||
err = mt76_connac_pm_wake(&dev->mphy, &dev->pm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
hif_suspend = !test_bit(MT76_STATE_SUSPEND, &dev->mphy.state);
|
||||
if (hif_suspend) {
|
||||
err = mt76_connac_mcu_set_hif_suspend(mdev, true);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
napi_disable(&mdev->tx_napi);
|
||||
mt76_worker_disable(&mdev->tx_worker);
|
||||
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_disable(&mdev->napi[i]);
|
||||
}
|
||||
tasklet_kill(&dev->irq_tasklet);
|
||||
|
||||
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 |
|
||||
MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000);
|
||||
|
||||
/* put dma disabled */
|
||||
mt76_clear(dev, MT_WFDMA0_GLO_CFG,
|
||||
MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
|
||||
|
||||
/* disable interrupt */
|
||||
mt76_wr(dev, MT_WFDMA0_HOST_INT_ENA, 0);
|
||||
|
||||
pci_save_state(pdev);
|
||||
err = pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||
if (err)
|
||||
goto restore;
|
||||
|
||||
err = mt7921_mcu_drv_pmctrl(dev);
|
||||
if (err)
|
||||
goto restore;
|
||||
|
||||
return 0;
|
||||
|
||||
restore:
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_enable(&mdev->napi[i]);
|
||||
}
|
||||
napi_enable(&mdev->tx_napi);
|
||||
if (hif_suspend)
|
||||
mt76_connac_mcu_set_hif_suspend(mdev, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mt7921_pci_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct mt76_dev *mdev = pci_get_drvdata(pdev);
|
||||
struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76);
|
||||
int i, err;
|
||||
|
||||
err = mt7921_mcu_fw_pmctrl(dev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = pci_set_power_state(pdev, PCI_D0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
pci_restore_state(pdev);
|
||||
|
||||
/* enable interrupt */
|
||||
mt7921_l1_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0xff);
|
||||
mt7921_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
|
||||
MT_INT_MCU_CMD);
|
||||
|
||||
/* put dma enabled */
|
||||
mt76_set(dev, MT_WFDMA0_GLO_CFG,
|
||||
MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
|
||||
|
||||
mt76_worker_enable(&mdev->tx_worker);
|
||||
mt76_for_each_q_rx(mdev, i) {
|
||||
napi_enable(&mdev->napi[i]);
|
||||
napi_schedule(&mdev->napi[i]);
|
||||
}
|
||||
napi_enable(&mdev->tx_napi);
|
||||
napi_schedule(&mdev->tx_napi);
|
||||
|
||||
if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state))
|
||||
err = mt76_connac_mcu_set_hif_suspend(mdev, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
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 */
|
||||
};
|
||||
|
||||
module_pci_driver(mt7921_pci_driver);
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, mt7921_pci_device_table);
|
||||
MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
|
||||
MODULE_FIRMWARE(MT7921_ROM_PATCH);
|
||||
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
|
||||
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
|
||||
MODULE_LICENSE("Dual BSD/GPL");
|
||||
419
drivers/net/wireless/mediatek/mt76/mt7921/regs.h
Normal file
419
drivers/net/wireless/mediatek/mt76/mt7921/regs.h
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
/* SPDX-License-Identifier: ISC */
|
||||
/* Copyright (C) 2020 MediaTek Inc. */
|
||||
|
||||
#ifndef __MT7921_REGS_H
|
||||
#define __MT7921_REGS_H
|
||||
|
||||
/* MCU WFDMA1 */
|
||||
#define MT_MCU_WFDMA1_BASE 0x3000
|
||||
#define MT_MCU_WFDMA1(ofs) (MT_MCU_WFDMA1_BASE + (ofs))
|
||||
|
||||
#define MT_MCU_INT_EVENT MT_MCU_WFDMA1(0x108)
|
||||
#define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0)
|
||||
#define MT_MCU_INT_EVENT_DMA_INIT BIT(1)
|
||||
#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(2)
|
||||
#define MT_MCU_INT_EVENT_RESET_DONE BIT(3)
|
||||
|
||||
#define MT_PLE_BASE 0x8000
|
||||
#define MT_PLE(ofs) (MT_PLE_BASE + (ofs))
|
||||
|
||||
#define MT_PLE_FL_Q0_CTRL MT_PLE(0x1b0)
|
||||
#define MT_PLE_FL_Q1_CTRL MT_PLE(0x1b4)
|
||||
#define MT_PLE_FL_Q2_CTRL MT_PLE(0x1b8)
|
||||
#define MT_PLE_FL_Q3_CTRL MT_PLE(0x1bc)
|
||||
|
||||
#define MT_PLE_AC_QEMPTY(ac, n) MT_PLE(0x300 + 0x10 * (ac) + \
|
||||
((n) << 2))
|
||||
#define MT_PLE_AMSDU_PACK_MSDU_CNT(n) MT_PLE(0x10e0 + ((n) << 2))
|
||||
|
||||
#define MT_MDP_BASE 0xf000
|
||||
#define MT_MDP(ofs) (MT_MDP_BASE + (ofs))
|
||||
|
||||
#define MT_MDP_DCR0 MT_MDP(0x000)
|
||||
#define MT_MDP_DCR0_DAMSDU_EN BIT(15)
|
||||
#define MT_MDP_DCR0_RX_HDR_TRANS_EN BIT(19)
|
||||
|
||||
#define MT_MDP_DCR1 MT_MDP(0x004)
|
||||
#define MT_MDP_DCR1_MAX_RX_LEN GENMASK(15, 3)
|
||||
|
||||
#define MT_MDP_BNRCFR0(_band) MT_MDP(0x070 + ((_band) << 8))
|
||||
#define MT_MDP_RCFR0_MCU_RX_MGMT GENMASK(5, 4)
|
||||
#define MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR GENMASK(7, 6)
|
||||
#define MT_MDP_RCFR0_MCU_RX_CTL_BAR GENMASK(9, 8)
|
||||
|
||||
#define MT_MDP_BNRCFR1(_band) MT_MDP(0x074 + ((_band) << 8))
|
||||
#define MT_MDP_RCFR1_MCU_RX_BYPASS GENMASK(23, 22)
|
||||
#define MT_MDP_RCFR1_RX_DROPPED_UCAST GENMASK(28, 27)
|
||||
#define MT_MDP_RCFR1_RX_DROPPED_MCAST GENMASK(30, 29)
|
||||
#define MT_MDP_TO_HIF 0
|
||||
#define MT_MDP_TO_WM 1
|
||||
|
||||
/* TMAC: band 0(0x21000), band 1(0xa1000) */
|
||||
#define MT_WF_TMAC_BASE(_band) ((_band) ? 0xa1000 : 0x21000)
|
||||
#define MT_WF_TMAC(_band, ofs) (MT_WF_TMAC_BASE(_band) + (ofs))
|
||||
|
||||
#define MT_TMAC_TCR0(_band) MT_WF_TMAC(_band, 0)
|
||||
#define MT_TMAC_TCR0_TBTT_STOP_CTRL BIT(25)
|
||||
|
||||
#define MT_TMAC_CDTR(_band) MT_WF_TMAC(_band, 0x090)
|
||||
#define MT_TMAC_ODTR(_band) MT_WF_TMAC(_band, 0x094)
|
||||
#define MT_TIMEOUT_VAL_PLCP GENMASK(15, 0)
|
||||
#define MT_TIMEOUT_VAL_CCA GENMASK(31, 16)
|
||||
|
||||
#define MT_TMAC_ICR0(_band) MT_WF_TMAC(_band, 0x0a4)
|
||||
#define MT_IFS_EIFS GENMASK(8, 0)
|
||||
#define MT_IFS_RIFS GENMASK(14, 10)
|
||||
#define MT_IFS_SIFS GENMASK(22, 16)
|
||||
#define MT_IFS_SLOT GENMASK(30, 24)
|
||||
|
||||
#define MT_TMAC_CTCR0(_band) MT_WF_TMAC(_band, 0x0f4)
|
||||
#define MT_TMAC_CTCR0_INS_DDLMT_REFTIME GENMASK(5, 0)
|
||||
#define MT_TMAC_CTCR0_INS_DDLMT_EN BIT(17)
|
||||
#define MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN BIT(18)
|
||||
|
||||
#define MT_TMAC_TRCR0(_band) MT_WF_TMAC(_band, 0x09c)
|
||||
#define MT_TMAC_TFCR0(_band) MT_WF_TMAC(_band, 0x1e0)
|
||||
|
||||
#define MT_WF_DMA_BASE(_band) ((_band) ? 0xa1e00 : 0x21e00)
|
||||
#define MT_WF_DMA(_band, ofs) (MT_WF_DMA_BASE(_band) + (ofs))
|
||||
|
||||
#define MT_DMA_DCR0(_band) MT_WF_DMA(_band, 0x000)
|
||||
#define MT_DMA_DCR0_MAX_RX_LEN GENMASK(15, 3)
|
||||
#define MT_DMA_DCR0_RXD_G5_EN BIT(23)
|
||||
|
||||
/* LPON: band 0(0x24200), band 1(0xa4200) */
|
||||
#define MT_WF_LPON_BASE(_band) ((_band) ? 0xa4200 : 0x24200)
|
||||
#define MT_WF_LPON(_band, ofs) (MT_WF_LPON_BASE(_band) + (ofs))
|
||||
|
||||
#define MT_LPON_UTTR0(_band) MT_WF_LPON(_band, 0x080)
|
||||
#define MT_LPON_UTTR1(_band) MT_WF_LPON(_band, 0x084)
|
||||
|
||||
#define MT_LPON_TCR(_band, n) MT_WF_LPON(_band, 0x0a8 + (n) * 4)
|
||||
#define MT_LPON_TCR_SW_MODE GENMASK(1, 0)
|
||||
#define MT_LPON_TCR_SW_WRITE BIT(0)
|
||||
|
||||
/* MIB: band 0(0x24800), band 1(0xa4800) */
|
||||
#define MT_WF_MIB_BASE(_band) ((_band) ? 0xa4800 : 0x24800)
|
||||
#define MT_WF_MIB(_band, ofs) (MT_WF_MIB_BASE(_band) + (ofs))
|
||||
|
||||
#define MT_MIB_SDR3(_band) MT_WF_MIB(_band, 0x014)
|
||||
#define MT_MIB_SDR3_FCS_ERR_MASK GENMASK(15, 0)
|
||||
|
||||
#define MT_MIB_SDR9(_band) MT_WF_MIB(_band, 0x02c)
|
||||
#define MT_MIB_SDR9_BUSY_MASK GENMASK(23, 0)
|
||||
|
||||
#define MT_MIB_SDR16(_band) MT_WF_MIB(_band, 0x048)
|
||||
#define MT_MIB_SDR16_BUSY_MASK GENMASK(23, 0)
|
||||
|
||||
#define MT_MIB_SDR34(_band) MT_WF_MIB(_band, 0x090)
|
||||
#define MT_MIB_MU_BF_TX_CNT GENMASK(15, 0)
|
||||
|
||||
#define MT_MIB_SDR36(_band) MT_WF_MIB(_band, 0x098)
|
||||
#define MT_MIB_SDR36_TXTIME_MASK GENMASK(23, 0)
|
||||
#define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x09c)
|
||||
#define MT_MIB_SDR37_RXTIME_MASK GENMASK(23, 0)
|
||||
|
||||
#define MT_MIB_DR8(_band) MT_WF_MIB(_band, 0x0c0)
|
||||
#define MT_MIB_DR9(_band) MT_WF_MIB(_band, 0x0c4)
|
||||
#define MT_MIB_DR11(_band) MT_WF_MIB(_band, 0x0cc)
|
||||
|
||||
#define MT_MIB_MB_SDR0(_band, n) MT_WF_MIB(_band, 0x100 + ((n) << 4))
|
||||
#define MT_MIB_RTS_RETRIES_COUNT_MASK GENMASK(31, 16)
|
||||
#define MT_MIB_RTS_COUNT_MASK GENMASK(15, 0)
|
||||
|
||||
#define MT_MIB_MB_SDR1(_band, n) MT_WF_MIB(_band, 0x104 + ((n) << 4))
|
||||
#define MT_MIB_BA_MISS_COUNT_MASK GENMASK(15, 0)
|
||||
#define MT_MIB_ACK_FAIL_COUNT_MASK GENMASK(31, 16)
|
||||
|
||||
#define MT_MIB_MB_SDR2(_band, n) MT_WF_MIB(_band, 0x108 + ((n) << 4))
|
||||
#define MT_MIB_FRAME_RETRIES_COUNT_MASK GENMASK(15, 0)
|
||||
|
||||
#define MT_TX_AGG_CNT(_band, n) MT_WF_MIB(_band, 0x0a8 + ((n) << 2))
|
||||
#define MT_TX_AGG_CNT2(_band, n) MT_WF_MIB(_band, 0x164 + ((n) << 2))
|
||||
#define MT_MIB_ARNG(_band, n) MT_WF_MIB(_band, 0x4b8 + ((n) << 2))
|
||||
#define MT_MIB_ARNCR_RANGE(val, n) (((val) >> ((n) << 3)) & GENMASK(7, 0))
|
||||
|
||||
#define MT_WTBLON_TOP_BASE 0x34000
|
||||
#define MT_WTBLON_TOP(ofs) (MT_WTBLON_TOP_BASE + (ofs))
|
||||
#define MT_WTBLON_TOP_WDUCR MT_WTBLON_TOP(0x0)
|
||||
#define MT_WTBLON_TOP_WDUCR_GROUP GENMASK(2, 0)
|
||||
|
||||
#define MT_WTBL_UPDATE MT_WTBLON_TOP(0x030)
|
||||
#define MT_WTBL_UPDATE_WLAN_IDX GENMASK(9, 0)
|
||||
#define MT_WTBL_UPDATE_ADM_COUNT_CLEAR BIT(12)
|
||||
#define MT_WTBL_UPDATE_BUSY BIT(31)
|
||||
|
||||
#define MT_WTBL_BASE 0x38000
|
||||
#define MT_WTBL_LMAC_ID GENMASK(14, 8)
|
||||
#define MT_WTBL_LMAC_DW GENMASK(7, 2)
|
||||
#define MT_WTBL_LMAC_OFFS(_id, _dw) (MT_WTBL_BASE | \
|
||||
FIELD_PREP(MT_WTBL_LMAC_ID, _id) | \
|
||||
FIELD_PREP(MT_WTBL_LMAC_DW, _dw))
|
||||
|
||||
/* AGG: band 0(0x20800), band 1(0xa0800) */
|
||||
#define MT_WF_AGG_BASE(_band) ((_band) ? 0xa0800 : 0x20800)
|
||||
#define MT_WF_AGG(_band, ofs) (MT_WF_AGG_BASE(_band) + (ofs))
|
||||
|
||||
#define MT_AGG_AWSCR0(_band, _n) MT_WF_AGG(_band, 0x05c + (_n) * 4)
|
||||
#define MT_AGG_PCR0(_band, _n) MT_WF_AGG(_band, 0x06c + (_n) * 4)
|
||||
#define MT_AGG_PCR0_MM_PROT BIT(0)
|
||||
#define MT_AGG_PCR0_GF_PROT BIT(1)
|
||||
#define MT_AGG_PCR0_BW20_PROT BIT(2)
|
||||
#define MT_AGG_PCR0_BW40_PROT BIT(4)
|
||||
#define MT_AGG_PCR0_BW80_PROT BIT(6)
|
||||
#define MT_AGG_PCR0_ERP_PROT GENMASK(12, 8)
|
||||
#define MT_AGG_PCR0_VHT_PROT BIT(13)
|
||||
#define MT_AGG_PCR0_PTA_WIN_DIS BIT(15)
|
||||
|
||||
#define MT_AGG_PCR1_RTS0_NUM_THRES GENMASK(31, 23)
|
||||
#define MT_AGG_PCR1_RTS0_LEN_THRES GENMASK(19, 0)
|
||||
|
||||
#define MT_AGG_ACR0(_band) MT_WF_AGG(_band, 0x084)
|
||||
#define MT_AGG_ACR_CFEND_RATE GENMASK(13, 0)
|
||||
#define MT_AGG_ACR_BAR_RATE GENMASK(29, 16)
|
||||
|
||||
#define MT_AGG_MRCR(_band) MT_WF_AGG(_band, 0x098)
|
||||
#define MT_AGG_MRCR_BAR_CNT_LIMIT GENMASK(15, 12)
|
||||
#define MT_AGG_MRCR_LAST_RTS_CTS_RN BIT(6)
|
||||
#define MT_AGG_MRCR_RTS_FAIL_LIMIT GENMASK(11, 7)
|
||||
#define MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT GENMASK(28, 24)
|
||||
|
||||
#define MT_AGG_ATCR1(_band) MT_WF_AGG(_band, 0x0f0)
|
||||
#define MT_AGG_ATCR3(_band) MT_WF_AGG(_band, 0x0f4)
|
||||
|
||||
/* ARB: band 0(0x20c00), band 1(0xa0c00) */
|
||||
#define MT_WF_ARB_BASE(_band) ((_band) ? 0xa0c00 : 0x20c00)
|
||||
#define MT_WF_ARB(_band, ofs) (MT_WF_ARB_BASE(_band) + (ofs))
|
||||
|
||||
#define MT_ARB_SCR(_band) MT_WF_ARB(_band, 0x080)
|
||||
#define MT_ARB_SCR_TX_DISABLE BIT(8)
|
||||
#define MT_ARB_SCR_RX_DISABLE BIT(9)
|
||||
|
||||
#define MT_ARB_DRNGR0(_band, _n) MT_WF_ARB(_band, 0x194 + (_n) * 4)
|
||||
|
||||
/* RMAC: band 0(0x21400), band 1(0xa1400) */
|
||||
#define MT_WF_RMAC_BASE(_band) ((_band) ? 0xa1400 : 0x21400)
|
||||
#define MT_WF_RMAC(_band, ofs) (MT_WF_RMAC_BASE(_band) + (ofs))
|
||||
|
||||
#define MT_WF_RFCR(_band) MT_WF_RMAC(_band, 0x000)
|
||||
#define MT_WF_RFCR_DROP_STBC_MULTI BIT(0)
|
||||
#define MT_WF_RFCR_DROP_FCSFAIL BIT(1)
|
||||
#define MT_WF_RFCR_DROP_VERSION BIT(3)
|
||||
#define MT_WF_RFCR_DROP_PROBEREQ BIT(4)
|
||||
#define MT_WF_RFCR_DROP_MCAST BIT(5)
|
||||
#define MT_WF_RFCR_DROP_BCAST BIT(6)
|
||||
#define MT_WF_RFCR_DROP_MCAST_FILTERED BIT(7)
|
||||
#define MT_WF_RFCR_DROP_A3_MAC BIT(8)
|
||||
#define MT_WF_RFCR_DROP_A3_BSSID BIT(9)
|
||||
#define MT_WF_RFCR_DROP_A2_BSSID BIT(10)
|
||||
#define MT_WF_RFCR_DROP_OTHER_BEACON BIT(11)
|
||||
#define MT_WF_RFCR_DROP_FRAME_REPORT BIT(12)
|
||||
#define MT_WF_RFCR_DROP_CTL_RSV BIT(13)
|
||||
#define MT_WF_RFCR_DROP_CTS BIT(14)
|
||||
#define MT_WF_RFCR_DROP_RTS BIT(15)
|
||||
#define MT_WF_RFCR_DROP_DUPLICATE BIT(16)
|
||||
#define MT_WF_RFCR_DROP_OTHER_BSS BIT(17)
|
||||
#define MT_WF_RFCR_DROP_OTHER_UC BIT(18)
|
||||
#define MT_WF_RFCR_DROP_OTHER_TIM BIT(19)
|
||||
#define MT_WF_RFCR_DROP_NDPA BIT(20)
|
||||
#define MT_WF_RFCR_DROP_UNWANTED_CTL BIT(21)
|
||||
|
||||
#define MT_WF_RFCR1(_band) MT_WF_RMAC(_band, 0x004)
|
||||
#define MT_WF_RFCR1_DROP_ACK BIT(4)
|
||||
#define MT_WF_RFCR1_DROP_BF_POLL BIT(5)
|
||||
#define MT_WF_RFCR1_DROP_BA BIT(6)
|
||||
#define MT_WF_RFCR1_DROP_CFEND BIT(7)
|
||||
#define MT_WF_RFCR1_DROP_CFACK BIT(8)
|
||||
|
||||
#define MT_WF_RMAC_MIB_TIME0(_band) MT_WF_RMAC(_band, 0x03c4)
|
||||
#define MT_WF_RMAC_MIB_RXTIME_CLR BIT(31)
|
||||
#define MT_WF_RMAC_MIB_RXTIME_EN BIT(30)
|
||||
|
||||
#define MT_WF_RMAC_MIB_AIRTIME14(_band) MT_WF_RMAC(_band, 0x03b8)
|
||||
#define MT_MIB_OBSSTIME_MASK GENMASK(23, 0)
|
||||
#define MT_WF_RMAC_MIB_AIRTIME0(_band) MT_WF_RMAC(_band, 0x0380)
|
||||
|
||||
/* WFDMA0 */
|
||||
#define MT_WFDMA0_BASE 0xd4000
|
||||
#define MT_WFDMA0(ofs) (MT_WFDMA0_BASE + (ofs))
|
||||
|
||||
#define MT_WFDMA0_RST MT_WFDMA0(0x100)
|
||||
#define MT_WFDMA0_RST_LOGIC_RST BIT(4)
|
||||
#define MT_WFDMA0_RST_DMASHDL_ALL_RST BIT(5)
|
||||
|
||||
#define MT_WFDMA0_BUSY_ENA MT_WFDMA0(0x13c)
|
||||
#define MT_WFDMA0_BUSY_ENA_TX_FIFO0 BIT(0)
|
||||
#define MT_WFDMA0_BUSY_ENA_TX_FIFO1 BIT(1)
|
||||
#define MT_WFDMA0_BUSY_ENA_RX_FIFO BIT(2)
|
||||
|
||||
#define MT_MCU_CMD MT_WFDMA0(0x1f0)
|
||||
#define MT_MCU_CMD_STOP_DMA_FW_RELOAD BIT(1)
|
||||
#define MT_MCU_CMD_STOP_DMA BIT(2)
|
||||
#define MT_MCU_CMD_RESET_DONE BIT(3)
|
||||
#define MT_MCU_CMD_RECOVERY_DONE BIT(4)
|
||||
#define MT_MCU_CMD_NORMAL_STATE BIT(5)
|
||||
#define MT_MCU_CMD_ERROR_MASK GENMASK(5, 1)
|
||||
|
||||
#define MT_WFDMA0_HOST_INT_STA MT_WFDMA0(0x200)
|
||||
#define HOST_RX_DONE_INT_STS0 BIT(0) /* Rx mcu */
|
||||
#define HOST_RX_DONE_INT_STS2 BIT(2) /* Rx data */
|
||||
#define HOST_RX_DONE_INT_STS4 BIT(22) /* Rx mcu after fw downloaded */
|
||||
#define HOST_TX_DONE_INT_STS16 BIT(26)
|
||||
#define HOST_TX_DONE_INT_STS17 BIT(27) /* MCU tx done*/
|
||||
|
||||
#define MT_WFDMA0_HOST_INT_ENA MT_WFDMA0(0x204)
|
||||
#define HOST_RX_DONE_INT_ENA0 BIT(0)
|
||||
#define HOST_RX_DONE_INT_ENA1 BIT(1)
|
||||
#define HOST_RX_DONE_INT_ENA2 BIT(2)
|
||||
#define HOST_RX_DONE_INT_ENA3 BIT(3)
|
||||
#define HOST_TX_DONE_INT_ENA0 BIT(4)
|
||||
#define HOST_TX_DONE_INT_ENA1 BIT(5)
|
||||
#define HOST_TX_DONE_INT_ENA2 BIT(6)
|
||||
#define HOST_TX_DONE_INT_ENA3 BIT(7)
|
||||
#define HOST_TX_DONE_INT_ENA4 BIT(8)
|
||||
#define HOST_TX_DONE_INT_ENA5 BIT(9)
|
||||
#define HOST_TX_DONE_INT_ENA6 BIT(10)
|
||||
#define HOST_TX_DONE_INT_ENA7 BIT(11)
|
||||
#define HOST_TX_DONE_INT_ENA8 BIT(12)
|
||||
#define HOST_TX_DONE_INT_ENA9 BIT(13)
|
||||
#define HOST_TX_DONE_INT_ENA10 BIT(14)
|
||||
#define HOST_TX_DONE_INT_ENA11 BIT(15)
|
||||
#define HOST_TX_DONE_INT_ENA12 BIT(16)
|
||||
#define HOST_TX_DONE_INT_ENA13 BIT(17)
|
||||
#define HOST_TX_DONE_INT_ENA14 BIT(18)
|
||||
#define HOST_RX_COHERENT_EN BIT(20)
|
||||
#define HOST_TX_COHERENT_EN BIT(21)
|
||||
#define HOST_RX_DONE_INT_ENA4 BIT(22)
|
||||
#define HOST_RX_DONE_INT_ENA5 BIT(23)
|
||||
#define HOST_TX_DONE_INT_ENA16 BIT(26)
|
||||
#define HOST_TX_DONE_INT_ENA17 BIT(27)
|
||||
#define MCU2HOST_SW_INT_ENA BIT(29)
|
||||
#define HOST_TX_DONE_INT_ENA18 BIT(30)
|
||||
|
||||
/* WFDMA interrupt */
|
||||
#define MT_INT_RX_DONE_DATA HOST_RX_DONE_INT_ENA2
|
||||
#define MT_INT_RX_DONE_WM HOST_RX_DONE_INT_ENA0
|
||||
#define MT_INT_RX_DONE_WM2 HOST_RX_DONE_INT_ENA4
|
||||
#define MT_INT_RX_DONE_ALL (MT_INT_RX_DONE_DATA | \
|
||||
MT_INT_RX_DONE_WM | \
|
||||
MT_INT_RX_DONE_WM2)
|
||||
#define MT_INT_TX_DONE_MCU_WM HOST_TX_DONE_INT_ENA17
|
||||
#define MT_INT_TX_DONE_FWDL HOST_TX_DONE_INT_ENA16
|
||||
#define MT_INT_TX_DONE_BAND0 HOST_TX_DONE_INT_ENA0
|
||||
#define MT_INT_MCU_CMD MCU2HOST_SW_INT_ENA
|
||||
|
||||
#define MT_INT_TX_DONE_MCU (MT_INT_TX_DONE_MCU_WM | \
|
||||
MT_INT_TX_DONE_FWDL)
|
||||
#define MT_INT_TX_DONE_ALL (MT_INT_TX_DONE_MCU_WM | \
|
||||
MT_INT_TX_DONE_BAND0 | \
|
||||
GENMASK(18, 4))
|
||||
|
||||
#define MT_WFDMA0_GLO_CFG MT_WFDMA0(0x208)
|
||||
#define MT_WFDMA0_GLO_CFG_TX_DMA_EN BIT(0)
|
||||
#define MT_WFDMA0_GLO_CFG_TX_DMA_BUSY BIT(1)
|
||||
#define MT_WFDMA0_GLO_CFG_RX_DMA_EN BIT(2)
|
||||
#define MT_WFDMA0_GLO_CFG_RX_DMA_BUSY BIT(3)
|
||||
#define MT_WFDMA0_GLO_CFG_TX_WB_DDONE BIT(6)
|
||||
#define MT_WFDMA0_GLO_CFG_FIFO_LITTLE_ENDIAN BIT(12)
|
||||
#define MT_WFDMA0_GLO_CFG_CSR_DISP_BASE_PTR_CHAIN_EN BIT(15)
|
||||
#define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 BIT(21)
|
||||
#define MT_WFDMA0_GLO_CFG_OMIT_RX_INFO BIT(27)
|
||||
#define MT_WFDMA0_GLO_CFG_OMIT_TX_INFO BIT(28)
|
||||
#define MT_WFDMA0_GLO_CFG_CLK_GAT_DIS BIT(30)
|
||||
|
||||
#define MT_WFDMA0_RST_DTX_PTR MT_WFDMA0(0x20c)
|
||||
#define MT_WFDMA0_GLO_CFG_EXT0 MT_WFDMA0(0x2b0)
|
||||
#define MT_WFDMA0_CSR_TX_DMASHDL_ENABLE BIT(6)
|
||||
#define MT_WFDMA0_PRI_DLY_INT_CFG0 MT_WFDMA0(0x2f0)
|
||||
|
||||
#define MT_RX_DATA_RING_BASE MT_WFDMA0(0x520)
|
||||
|
||||
#define MT_WFDMA0_TX_RING0_EXT_CTRL MT_WFDMA0(0x600)
|
||||
#define MT_WFDMA0_TX_RING1_EXT_CTRL MT_WFDMA0(0x604)
|
||||
#define MT_WFDMA0_TX_RING2_EXT_CTRL MT_WFDMA0(0x608)
|
||||
#define MT_WFDMA0_TX_RING3_EXT_CTRL MT_WFDMA0(0x60c)
|
||||
#define MT_WFDMA0_TX_RING4_EXT_CTRL MT_WFDMA0(0x610)
|
||||
#define MT_WFDMA0_TX_RING5_EXT_CTRL MT_WFDMA0(0x614)
|
||||
#define MT_WFDMA0_TX_RING6_EXT_CTRL MT_WFDMA0(0x618)
|
||||
#define MT_WFDMA0_TX_RING16_EXT_CTRL MT_WFDMA0(0x640)
|
||||
#define MT_WFDMA0_TX_RING17_EXT_CTRL MT_WFDMA0(0x644)
|
||||
|
||||
#define MT_WFDMA0_RX_RING0_EXT_CTRL MT_WFDMA0(0x680)
|
||||
#define MT_WFDMA0_RX_RING1_EXT_CTRL MT_WFDMA0(0x684)
|
||||
#define MT_WFDMA0_RX_RING2_EXT_CTRL MT_WFDMA0(0x688)
|
||||
#define MT_WFDMA0_RX_RING3_EXT_CTRL MT_WFDMA0(0x68c)
|
||||
#define MT_WFDMA0_RX_RING4_EXT_CTRL MT_WFDMA0(0x690)
|
||||
#define MT_WFDMA0_RX_RING5_EXT_CTRL MT_WFDMA0(0x694)
|
||||
|
||||
#define MT_TX_RING_BASE MT_WFDMA0(0x300)
|
||||
#define MT_RX_EVENT_RING_BASE MT_WFDMA0(0x500)
|
||||
|
||||
/* WFDMA CSR */
|
||||
#define MT_WFDMA_EXT_CSR_BASE 0xd7000
|
||||
#define MT_WFDMA_EXT_CSR(ofs) (MT_WFDMA_EXT_CSR_BASE + (ofs))
|
||||
#define MT_WFDMA_EXT_CSR_HIF_MISC MT_WFDMA_EXT_CSR(0x44)
|
||||
#define MT_WFDMA_EXT_CSR_HIF_MISC_BUSY BIT(0)
|
||||
|
||||
#define MT_INFRA_CFG_BASE 0xfe000
|
||||
#define MT_INFRA(ofs) (MT_INFRA_CFG_BASE + (ofs))
|
||||
|
||||
#define MT_HIF_REMAP_L1 MT_INFRA(0x260)
|
||||
#define MT_HIF_REMAP_L1_MASK GENMASK(15, 0)
|
||||
#define MT_HIF_REMAP_L1_OFFSET GENMASK(15, 0)
|
||||
#define MT_HIF_REMAP_L1_BASE GENMASK(31, 16)
|
||||
#define MT_HIF_REMAP_BASE_L1 0xe0000
|
||||
|
||||
#define MT_SWDEF_BASE 0x41f200
|
||||
#define MT_SWDEF(ofs) (MT_SWDEF_BASE + (ofs))
|
||||
#define MT_SWDEF_MODE MT_SWDEF(0x3c)
|
||||
#define MT_SWDEF_NORMAL_MODE 0
|
||||
#define MT_SWDEF_ICAP_MODE 1
|
||||
#define MT_SWDEF_SPECTRUM_MODE 2
|
||||
|
||||
#define MT_TOP_BASE 0x18060000
|
||||
#define MT_TOP(ofs) (MT_TOP_BASE + (ofs))
|
||||
|
||||
#define MT_TOP_LPCR_HOST_BAND0 MT_TOP(0x10)
|
||||
#define MT_TOP_LPCR_HOST_FW_OWN BIT(0)
|
||||
#define MT_TOP_LPCR_HOST_DRV_OWN BIT(1)
|
||||
|
||||
#define MT_TOP_MISC MT_TOP(0xf0)
|
||||
#define MT_TOP_MISC_FW_STATE GENMASK(2, 0)
|
||||
|
||||
#define MT_HW_BOUND 0x70010020
|
||||
#define MT_HW_CHIPID 0x70010200
|
||||
#define MT_HW_REV 0x70010204
|
||||
|
||||
#define MT_PCIE_MAC_BASE 0x74030000
|
||||
#define MT_PCIE_MAC(ofs) (MT_PCIE_MAC_BASE + (ofs))
|
||||
#define MT_PCIE_MAC_INT_ENABLE MT_PCIE_MAC(0x188)
|
||||
|
||||
#define MT_DMA_SHDL(ofs) (0xd6000 + (ofs))
|
||||
#define MT_DMASHDL_SW_CONTROL MT_DMA_SHDL(0x004)
|
||||
#define MT_DMASHDL_DMASHDL_BYPASS BIT(28)
|
||||
#define MT_DMASHDL_OPTIONAL MT_DMA_SHDL(0x008)
|
||||
#define MT_DMASHDL_PAGE MT_DMA_SHDL(0x00c)
|
||||
#define MT_DMASHDL_REFILL MT_DMA_SHDL(0x010)
|
||||
#define MT_DMASHDL_PKT_MAX_SIZE MT_DMA_SHDL(0x01c)
|
||||
#define MT_DMASHDL_PKT_MAX_SIZE_PLE GENMASK(11, 0)
|
||||
#define MT_DMASHDL_PKT_MAX_SIZE_PSE GENMASK(27, 16)
|
||||
|
||||
#define MT_DMASHDL_GROUP_QUOTA(_n) MT_DMA_SHDL(0x020 + ((_n) << 2))
|
||||
#define MT_DMASHDL_GROUP_QUOTA_MIN GENMASK(11, 0)
|
||||
#define MT_DMASHDL_GROUP_QUOTA_MAX GENMASK(27, 16)
|
||||
|
||||
#define MT_DMASHDL_Q_MAP(_n) MT_DMA_SHDL(0x060 + ((_n) << 2))
|
||||
#define MT_DMASHDL_Q_MAP_MASK GENMASK(3, 0)
|
||||
#define MT_DMASHDL_Q_MAP_SHIFT(_n) (4 * ((_n) % 8))
|
||||
|
||||
#define MT_DMASHDL_SCHED_SET(_n) MT_DMA_SHDL(0x070 + ((_n) << 2))
|
||||
|
||||
#define MT_CONN_ON_LPCTL 0x7c060010
|
||||
#define PCIE_LPCR_HOST_OWN_SYNC BIT(2)
|
||||
#define PCIE_LPCR_HOST_CLR_OWN BIT(1)
|
||||
#define PCIE_LPCR_HOST_SET_OWN BIT(0)
|
||||
|
||||
#define MT_CONN_ON_MISC 0x7c0600f0
|
||||
#define MT_TOP_MISC2_FW_N9_RDY GENMASK(1, 0)
|
||||
|
||||
#endif
|
||||
|
|
@ -14,18 +14,23 @@ static const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
|
|||
[MT76_TM_ATTR_TX_RATE_STBC] = { .type = NLA_U8 },
|
||||
[MT76_TM_ATTR_TX_LTF] = { .type = NLA_U8 },
|
||||
[MT76_TM_ATTR_TX_ANTENNA] = { .type = NLA_U8 },
|
||||
[MT76_TM_ATTR_TX_SPE_IDX] = { .type = NLA_U8 },
|
||||
[MT76_TM_ATTR_TX_POWER_CONTROL] = { .type = NLA_U8 },
|
||||
[MT76_TM_ATTR_TX_POWER] = { .type = NLA_NESTED },
|
||||
[MT76_TM_ATTR_TX_DUTY_CYCLE] = { .type = NLA_U8 },
|
||||
[MT76_TM_ATTR_TX_IPG] = { .type = NLA_U32 },
|
||||
[MT76_TM_ATTR_TX_TIME] = { .type = NLA_U32 },
|
||||
[MT76_TM_ATTR_FREQ_OFFSET] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
void mt76_testmode_tx_pending(struct mt76_dev *dev)
|
||||
void mt76_testmode_tx_pending(struct mt76_phy *phy)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
struct mt76_wcid *wcid = &dev->global_wcid;
|
||||
struct mt76_phy *phy = &dev->phy;
|
||||
struct sk_buff *skb = td->tx_skb;
|
||||
struct mt76_queue *q;
|
||||
u16 tx_queued_limit;
|
||||
int qid;
|
||||
|
||||
if (!skb || !td->tx_pending)
|
||||
|
|
@ -34,9 +39,12 @@ void mt76_testmode_tx_pending(struct mt76_dev *dev)
|
|||
qid = skb_get_queue_mapping(skb);
|
||||
q = phy->q_tx[qid];
|
||||
|
||||
tx_queued_limit = td->tx_queued_limit ? td->tx_queued_limit : 1000;
|
||||
|
||||
spin_lock_bh(&q->lock);
|
||||
|
||||
while (td->tx_pending > 0 && td->tx_queued - td->tx_done < 1000 &&
|
||||
while (td->tx_pending > 0 &&
|
||||
td->tx_queued - td->tx_done < tx_queued_limit &&
|
||||
q->queued < q->ndesc / 2) {
|
||||
int ret;
|
||||
|
||||
|
|
@ -56,10 +64,9 @@ void mt76_testmode_tx_pending(struct mt76_dev *dev)
|
|||
|
||||
|
||||
static int
|
||||
mt76_testmode_tx_init(struct mt76_dev *dev)
|
||||
mt76_testmode_tx_init(struct mt76_phy *phy)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct mt76_phy *phy = &dev->phy;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
struct ieee80211_tx_info *info;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct sk_buff *skb;
|
||||
|
|
@ -67,6 +74,7 @@ mt76_testmode_tx_init(struct mt76_dev *dev)
|
|||
IEEE80211_FCTL_FROMDS;
|
||||
struct ieee80211_tx_rate *rate;
|
||||
u8 max_nss = hweight8(phy->antenna_mask);
|
||||
bool ext_phy = phy != &phy->dev->phy;
|
||||
|
||||
if (td->tx_antenna_mask)
|
||||
max_nss = min_t(u8, max_nss, hweight8(td->tx_antenna_mask));
|
||||
|
|
@ -88,6 +96,9 @@ mt76_testmode_tx_init(struct mt76_dev *dev)
|
|||
IEEE80211_TX_CTL_NO_ACK |
|
||||
IEEE80211_TX_CTL_NO_PS_BUFFER;
|
||||
|
||||
if (ext_phy)
|
||||
info->hw_queue |= MT_TX_HW_QUEUE_EXT_PHY;
|
||||
|
||||
if (td->tx_rate_mode > MT76_TM_TX_MODE_VHT)
|
||||
goto out;
|
||||
|
||||
|
|
@ -166,9 +177,10 @@ mt76_testmode_tx_init(struct mt76_dev *dev)
|
|||
}
|
||||
|
||||
static void
|
||||
mt76_testmode_tx_start(struct mt76_dev *dev)
|
||||
mt76_testmode_tx_start(struct mt76_phy *phy)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
|
||||
td->tx_queued = 0;
|
||||
td->tx_done = 0;
|
||||
|
|
@ -177,9 +189,10 @@ mt76_testmode_tx_start(struct mt76_dev *dev)
|
|||
}
|
||||
|
||||
static void
|
||||
mt76_testmode_tx_stop(struct mt76_dev *dev)
|
||||
mt76_testmode_tx_stop(struct mt76_phy *phy)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
|
||||
mt76_worker_disable(&dev->tx_worker);
|
||||
|
||||
|
|
@ -187,7 +200,8 @@ mt76_testmode_tx_stop(struct mt76_dev *dev)
|
|||
|
||||
mt76_worker_enable(&dev->tx_worker);
|
||||
|
||||
wait_event_timeout(dev->tx_wait, td->tx_done == td->tx_queued, 10 * HZ);
|
||||
wait_event_timeout(dev->tx_wait, td->tx_done == td->tx_queued,
|
||||
MT76_TM_TIMEOUT * HZ);
|
||||
|
||||
dev_kfree_skb(td->tx_skb);
|
||||
td->tx_skb = NULL;
|
||||
|
|
@ -206,9 +220,9 @@ mt76_testmode_param_present(struct mt76_testmode_data *td, u16 idx)
|
|||
}
|
||||
|
||||
static void
|
||||
mt76_testmode_init_defaults(struct mt76_dev *dev)
|
||||
mt76_testmode_init_defaults(struct mt76_phy *phy)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
|
||||
if (td->tx_msdu_len > 0)
|
||||
return;
|
||||
|
|
@ -220,49 +234,50 @@ mt76_testmode_init_defaults(struct mt76_dev *dev)
|
|||
}
|
||||
|
||||
static int
|
||||
__mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state)
|
||||
__mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state)
|
||||
{
|
||||
enum mt76_testmode_state prev_state = dev->test.state;
|
||||
enum mt76_testmode_state prev_state = phy->test.state;
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
int err;
|
||||
|
||||
if (prev_state == MT76_TM_STATE_TX_FRAMES)
|
||||
mt76_testmode_tx_stop(dev);
|
||||
mt76_testmode_tx_stop(phy);
|
||||
|
||||
if (state == MT76_TM_STATE_TX_FRAMES) {
|
||||
err = mt76_testmode_tx_init(dev);
|
||||
err = mt76_testmode_tx_init(phy);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = dev->test_ops->set_state(dev, state);
|
||||
err = dev->test_ops->set_state(phy, state);
|
||||
if (err) {
|
||||
if (state == MT76_TM_STATE_TX_FRAMES)
|
||||
mt76_testmode_tx_stop(dev);
|
||||
mt76_testmode_tx_stop(phy);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
if (state == MT76_TM_STATE_TX_FRAMES)
|
||||
mt76_testmode_tx_start(dev);
|
||||
mt76_testmode_tx_start(phy);
|
||||
else if (state == MT76_TM_STATE_RX_FRAMES) {
|
||||
memset(&dev->test.rx_stats, 0, sizeof(dev->test.rx_stats));
|
||||
memset(&phy->test.rx_stats, 0, sizeof(phy->test.rx_stats));
|
||||
}
|
||||
|
||||
dev->test.state = state;
|
||||
phy->test.state = state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state)
|
||||
int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct ieee80211_hw *hw = dev->phy.hw;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
struct ieee80211_hw *hw = phy->hw;
|
||||
|
||||
if (state == td->state && state == MT76_TM_STATE_OFF)
|
||||
return 0;
|
||||
|
||||
if (state > MT76_TM_STATE_OFF &&
|
||||
(!test_bit(MT76_STATE_RUNNING, &dev->phy.state) ||
|
||||
(!test_bit(MT76_STATE_RUNNING, &phy->state) ||
|
||||
!(hw->conf.flags & IEEE80211_CONF_MONITOR)))
|
||||
return -ENOTCONN;
|
||||
|
||||
|
|
@ -270,12 +285,12 @@ int mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state
|
|||
td->state != MT76_TM_STATE_IDLE) {
|
||||
int ret;
|
||||
|
||||
ret = __mt76_testmode_set_state(dev, MT76_TM_STATE_IDLE);
|
||||
ret = __mt76_testmode_set_state(phy, MT76_TM_STATE_IDLE);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return __mt76_testmode_set_state(dev, state);
|
||||
return __mt76_testmode_set_state(phy, state);
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(mt76_testmode_set_state);
|
||||
|
|
@ -301,8 +316,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
{
|
||||
struct mt76_phy *phy = hw->priv;
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
struct nlattr *tb[NUM_MT76_TM_ATTRS];
|
||||
bool ext_phy = phy != &dev->phy;
|
||||
u32 state;
|
||||
int err;
|
||||
int i;
|
||||
|
|
@ -320,11 +336,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
mutex_lock(&dev->mutex);
|
||||
|
||||
if (tb[MT76_TM_ATTR_RESET]) {
|
||||
mt76_testmode_set_state(dev, MT76_TM_STATE_OFF);
|
||||
mt76_testmode_set_state(phy, MT76_TM_STATE_OFF);
|
||||
memset(td, 0, sizeof(*td));
|
||||
}
|
||||
|
||||
mt76_testmode_init_defaults(dev);
|
||||
mt76_testmode_init_defaults(phy);
|
||||
|
||||
if (tb[MT76_TM_ATTR_TX_COUNT])
|
||||
td->tx_count = nla_get_u32(tb[MT76_TM_ATTR_TX_COUNT]);
|
||||
|
|
@ -350,12 +366,21 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_LDPC], &td->tx_rate_ldpc, 0, 1) ||
|
||||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_RATE_STBC], &td->tx_rate_stbc, 0, 1) ||
|
||||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_LTF], &td->tx_ltf, 0, 2) ||
|
||||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA], &td->tx_antenna_mask, 1,
|
||||
phy->antenna_mask) ||
|
||||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA], &td->tx_antenna_mask,
|
||||
1 << (ext_phy * 2), phy->antenna_mask << (ext_phy * 2)) ||
|
||||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_SPE_IDX], &td->tx_spe_idx, 0, 27) ||
|
||||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_DUTY_CYCLE],
|
||||
&td->tx_duty_cycle, 0, 99) ||
|
||||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
|
||||
&td->tx_power_control, 0, 1))
|
||||
goto out;
|
||||
|
||||
if (tb[MT76_TM_ATTR_TX_IPG])
|
||||
td->tx_ipg = nla_get_u32(tb[MT76_TM_ATTR_TX_IPG]);
|
||||
|
||||
if (tb[MT76_TM_ATTR_TX_TIME])
|
||||
td->tx_time = nla_get_u32(tb[MT76_TM_ATTR_TX_TIME]);
|
||||
|
||||
if (tb[MT76_TM_ATTR_FREQ_OFFSET])
|
||||
td->freq_offset = nla_get_u32(tb[MT76_TM_ATTR_FREQ_OFFSET]);
|
||||
|
||||
|
|
@ -382,7 +407,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
}
|
||||
|
||||
if (dev->test_ops->set_params) {
|
||||
err = dev->test_ops->set_params(dev, tb, state);
|
||||
err = dev->test_ops->set_params(phy, tb, state);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -393,7 +418,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
|
||||
err = 0;
|
||||
if (tb[MT76_TM_ATTR_STATE])
|
||||
err = mt76_testmode_set_state(dev, state);
|
||||
err = mt76_testmode_set_state(phy, state);
|
||||
|
||||
out:
|
||||
mutex_unlock(&dev->mutex);
|
||||
|
|
@ -403,9 +428,10 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
EXPORT_SYMBOL(mt76_testmode_cmd);
|
||||
|
||||
static int
|
||||
mt76_testmode_dump_stats(struct mt76_dev *dev, struct sk_buff *msg)
|
||||
mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg)
|
||||
{
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
u64 rx_packets = 0;
|
||||
u64 rx_fcs_error = 0;
|
||||
int i;
|
||||
|
|
@ -425,7 +451,7 @@ mt76_testmode_dump_stats(struct mt76_dev *dev, struct sk_buff *msg)
|
|||
return -EMSGSIZE;
|
||||
|
||||
if (dev->test_ops->dump_stats)
|
||||
return dev->test_ops->dump_stats(dev, msg);
|
||||
return dev->test_ops->dump_stats(phy, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -435,7 +461,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
|
|||
{
|
||||
struct mt76_phy *phy = hw->priv;
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
struct mt76_testmode_data *td = &dev->test;
|
||||
struct mt76_testmode_data *td = &phy->test;
|
||||
struct nlattr *tb[NUM_MT76_TM_ATTRS] = {};
|
||||
int err = 0;
|
||||
void *a;
|
||||
|
|
@ -461,22 +487,22 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
|
|||
|
||||
a = nla_nest_start(msg, MT76_TM_ATTR_STATS);
|
||||
if (a) {
|
||||
err = mt76_testmode_dump_stats(dev, msg);
|
||||
err = mt76_testmode_dump_stats(phy, msg);
|
||||
nla_nest_end(msg, a);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
mt76_testmode_init_defaults(dev);
|
||||
mt76_testmode_init_defaults(phy);
|
||||
|
||||
err = -EMSGSIZE;
|
||||
if (nla_put_u32(msg, MT76_TM_ATTR_STATE, td->state))
|
||||
goto out;
|
||||
|
||||
if (td->mtd_name &&
|
||||
(nla_put_string(msg, MT76_TM_ATTR_MTD_PART, td->mtd_name) ||
|
||||
nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, td->mtd_offset)))
|
||||
if (dev->test_mtd.name &&
|
||||
(nla_put_string(msg, MT76_TM_ATTR_MTD_PART, dev->test_mtd.name) ||
|
||||
nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, dev->test_mtd.offset)))
|
||||
goto out;
|
||||
|
||||
if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) ||
|
||||
|
|
@ -491,6 +517,14 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
|
|||
nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) ||
|
||||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) &&
|
||||
nla_put_u8(msg, MT76_TM_ATTR_TX_ANTENNA, td->tx_antenna_mask)) ||
|
||||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_SPE_IDX) &&
|
||||
nla_put_u8(msg, MT76_TM_ATTR_TX_SPE_IDX, td->tx_spe_idx)) ||
|
||||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_DUTY_CYCLE) &&
|
||||
nla_put_u8(msg, MT76_TM_ATTR_TX_DUTY_CYCLE, td->tx_duty_cycle)) ||
|
||||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_IPG) &&
|
||||
nla_put_u32(msg, MT76_TM_ATTR_TX_IPG, td->tx_ipg)) ||
|
||||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_TIME) &&
|
||||
nla_put_u32(msg, MT76_TM_ATTR_TX_TIME, td->tx_time)) ||
|
||||
(mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER_CONTROL) &&
|
||||
nla_put_u8(msg, MT76_TM_ATTR_TX_POWER_CONTROL, td->tx_power_control)) ||
|
||||
(mt76_testmode_param_present(td, MT76_TM_ATTR_FREQ_OFFSET) &&
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
#ifndef __MT76_TESTMODE_H
|
||||
#define __MT76_TESTMODE_H
|
||||
|
||||
#define MT76_TM_TIMEOUT 10
|
||||
|
||||
/**
|
||||
* enum mt76_testmode_attr - testmode attributes inside NL80211_ATTR_TESTDATA
|
||||
*
|
||||
|
|
@ -35,6 +37,13 @@
|
|||
* @MT76_TM_ATTR_FREQ_OFFSET: RF frequency offset (u32)
|
||||
*
|
||||
* @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr)
|
||||
*
|
||||
* @MT76_TM_ATTR_TX_SPE_IDX: tx spatial extension index (u8)
|
||||
*
|
||||
* @MT76_TM_ATTR_TX_DUTY_CYCLE: packet tx duty cycle (u8)
|
||||
* @MT76_TM_ATTR_TX_IPG: tx inter-packet gap, in unit of us (u32)
|
||||
* @MT76_TM_ATTR_TX_TIME: packet transmission time, in unit of us (u32)
|
||||
*
|
||||
*/
|
||||
enum mt76_testmode_attr {
|
||||
MT76_TM_ATTR_UNSPEC,
|
||||
|
|
@ -63,6 +72,12 @@ enum mt76_testmode_attr {
|
|||
|
||||
MT76_TM_ATTR_STATS,
|
||||
|
||||
MT76_TM_ATTR_TX_SPE_IDX,
|
||||
|
||||
MT76_TM_ATTR_TX_DUTY_CYCLE,
|
||||
MT76_TM_ATTR_TX_IPG,
|
||||
MT76_TM_ATTR_TX_TIME,
|
||||
|
||||
/* keep last */
|
||||
NUM_MT76_TM_ATTRS,
|
||||
MT76_TM_ATTR_MAX = NUM_MT76_TM_ATTRS - 1,
|
||||
|
|
@ -128,12 +143,14 @@ enum mt76_testmode_rx_attr {
|
|||
* @MT76_TM_STATE_IDLE: test mode enabled, but idle
|
||||
* @MT76_TM_STATE_TX_FRAMES: send a fixed number of test frames
|
||||
* @MT76_TM_STATE_RX_FRAMES: receive packets and keep statistics
|
||||
* @MT76_TM_STATE_TX_CONT: waveform tx without time gap
|
||||
*/
|
||||
enum mt76_testmode_state {
|
||||
MT76_TM_STATE_OFF,
|
||||
MT76_TM_STATE_IDLE,
|
||||
MT76_TM_STATE_TX_FRAMES,
|
||||
MT76_TM_STATE_RX_FRAMES,
|
||||
MT76_TM_STATE_TX_CONT,
|
||||
|
||||
/* keep last */
|
||||
NUM_MT76_TM_STATES,
|
||||
|
|
|
|||
|
|
@ -202,16 +202,22 @@ void mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *sk
|
|||
struct ieee80211_hw *hw;
|
||||
struct sk_buff_head list;
|
||||
|
||||
mt76_tx_check_non_aql(dev, wcid_idx, skb);
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
if (skb == dev->test.tx_skb) {
|
||||
dev->test.tx_done++;
|
||||
if (dev->test.tx_queued == dev->test.tx_done)
|
||||
if (mt76_is_testmode_skb(dev, skb, &hw)) {
|
||||
struct mt76_phy *phy = hw->priv;
|
||||
|
||||
if (skb == phy->test.tx_skb)
|
||||
phy->test.tx_done++;
|
||||
if (phy->test.tx_queued == phy->test.tx_done)
|
||||
wake_up(&dev->tx_wait);
|
||||
|
||||
ieee80211_free_txskb(hw, skb);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
mt76_tx_check_non_aql(dev, wcid_idx, skb);
|
||||
|
||||
if (!skb->prev) {
|
||||
hw = mt76_tx_status_get_hw(dev, skb);
|
||||
ieee80211_free_txskb(hw, skb);
|
||||
|
|
@ -261,7 +267,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
|
|||
int qid = skb_get_queue_mapping(skb);
|
||||
bool ext_phy = phy != &dev->phy;
|
||||
|
||||
if (mt76_testmode_enabled(dev)) {
|
||||
if (mt76_testmode_enabled(phy)) {
|
||||
ieee80211_free_txskb(phy->hw, skb);
|
||||
return;
|
||||
}
|
||||
|
|
@ -454,7 +460,6 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
|
|||
struct mt76_wcid *wcid;
|
||||
int ret = 0;
|
||||
|
||||
spin_lock_bh(&q->lock);
|
||||
while (1) {
|
||||
if (test_bit(MT76_STATE_PM, &phy->state) ||
|
||||
test_bit(MT76_RESET, &phy->state)) {
|
||||
|
|
@ -464,14 +469,9 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
|
|||
|
||||
if (dev->queue_ops->tx_cleanup &&
|
||||
q->queued + 2 * MT_TXQ_FREE_THR >= q->ndesc) {
|
||||
spin_unlock_bh(&q->lock);
|
||||
dev->queue_ops->tx_cleanup(dev, q, false);
|
||||
spin_lock_bh(&q->lock);
|
||||
}
|
||||
|
||||
if (mt76_txq_stopped(q))
|
||||
break;
|
||||
|
||||
txq = ieee80211_next_txq(phy->hw, qid);
|
||||
if (!txq)
|
||||
break;
|
||||
|
|
@ -481,6 +481,8 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
|
|||
if (wcid && test_bit(MT_WCID_FLAG_PS, &wcid->flags))
|
||||
continue;
|
||||
|
||||
spin_lock_bh(&q->lock);
|
||||
|
||||
if (mtxq->send_bar && mtxq->aggr) {
|
||||
struct ieee80211_txq *txq = mtxq_to_txq(mtxq);
|
||||
struct ieee80211_sta *sta = txq->sta;
|
||||
|
|
@ -494,10 +496,13 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid)
|
|||
spin_lock_bh(&q->lock);
|
||||
}
|
||||
|
||||
ret += mt76_txq_send_burst(phy, q, mtxq);
|
||||
if (!mt76_txq_stopped(q))
|
||||
ret += mt76_txq_send_burst(phy, q, mtxq);
|
||||
|
||||
spin_unlock_bh(&q->lock);
|
||||
|
||||
ieee80211_return_txq(phy->hw, txq, false);
|
||||
}
|
||||
spin_unlock_bh(&q->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -539,8 +544,10 @@ void mt76_tx_worker(struct mt76_worker *w)
|
|||
mt76_txq_schedule_all(dev->phy2);
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
if (dev->test.tx_pending)
|
||||
mt76_testmode_tx_pending(dev);
|
||||
if (dev->phy.test.tx_pending)
|
||||
mt76_testmode_tx_pending(&dev->phy);
|
||||
if (dev->phy2 && dev->phy2->test.tx_pending)
|
||||
mt76_testmode_tx_pending(dev->phy2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -612,6 +612,7 @@ static void mt76u_complete_rx(struct urb *urb)
|
|||
case -ECONNRESET:
|
||||
case -ESHUTDOWN:
|
||||
case -ENOENT:
|
||||
case -EPROTO:
|
||||
return;
|
||||
default:
|
||||
dev_err_ratelimited(dev->dev, "rx urb failed: %d\n",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user