Commit c918c74d authored by Shayne Chen's avatar Shayne Chen Committed by Felix Fietkau

mt76: testmode: introduce dbdc support

Add testmode support for DBDC NICs (both MT7615D and MT7915D work).
Testmode data and parameters are moved from per-dev to per-phy
for maintaining the value of each band.
Signed-off-by: default avatarShayne Chen <shayne.chen@mediatek.com>
Acked-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent dae0dc2b
...@@ -411,8 +411,12 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q, ...@@ -411,8 +411,12 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
free: free:
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
/* fix tx_done accounting on queue overflow */ /* fix tx_done accounting on queue overflow */
if (tx_info.skb == dev->test.tx_skb) if (mt76_is_testmode_skb(dev, skb, &hw)) {
dev->test.tx_done--; struct mt76_phy *phy = hw->priv;
if (tx_info.skb == phy->test.tx_skb)
phy->test.tx_done--;
}
#endif #endif
e.skb = tx_info.skb; e.skb = tx_info.skb;
......
...@@ -75,8 +75,8 @@ mt76_get_of_eeprom(struct mt76_dev *dev, int len) ...@@ -75,8 +75,8 @@ mt76_get_of_eeprom(struct mt76_dev *dev, int len)
} }
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
dev->test.mtd_name = devm_kstrdup(dev->dev, part, GFP_KERNEL); dev->phy.test.mtd_name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
dev->test.mtd_offset = offset; dev->phy.test.mtd_offset = offset;
#endif #endif
out_put_node: out_put_node:
......
...@@ -519,10 +519,10 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) ...@@ -519,10 +519,10 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb)
} }
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
if (dev->test.state == MT76_TM_STATE_RX_FRAMES) { if (phy->test.state == MT76_TM_STATE_RX_FRAMES) {
dev->test.rx_stats.packets[q]++; phy->test.rx_stats.packets[q]++;
if (status->flag & RX_FLAG_FAILED_FCS_CRC) if (status->flag & RX_FLAG_FAILED_FCS_CRC)
dev->test.rx_stats.fcs_error[q]++; phy->test.rx_stats.fcs_error[q]++;
} }
#endif #endif
__skb_queue_tail(&dev->rx_skb[q], skb); __skb_queue_tail(&dev->rx_skb[q], skb);
......
...@@ -515,10 +515,10 @@ struct mt76_rx_status { ...@@ -515,10 +515,10 @@ struct mt76_rx_status {
}; };
struct mt76_testmode_ops { struct mt76_testmode_ops {
int (*set_state)(struct mt76_dev *dev, enum mt76_testmode_state state); int (*set_state)(struct mt76_phy *phy, enum mt76_testmode_state state);
int (*set_params)(struct mt76_dev *dev, struct nlattr **tb, int (*set_params)(struct mt76_phy *phy, struct nlattr **tb,
enum mt76_testmode_state new_state); 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 { struct mt76_testmode_data {
...@@ -582,6 +582,10 @@ struct mt76_phy { ...@@ -582,6 +582,10 @@ struct mt76_phy {
int txpower_cur; int txpower_cur;
u8 antenna_mask; u8 antenna_mask;
#ifdef CONFIG_NL80211_TESTMODE
struct mt76_testmode_data test;
#endif
}; };
struct mt76_dev { struct mt76_dev {
...@@ -661,9 +665,7 @@ struct mt76_dev { ...@@ -661,9 +665,7 @@ struct mt76_dev {
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
const struct mt76_testmode_ops *test_ops; const struct mt76_testmode_ops *test_ops;
struct mt76_testmode_data test;
#endif #endif
struct workqueue_struct *wq; struct workqueue_struct *wq;
union { union {
...@@ -931,10 +933,27 @@ static inline u8 mt76_tx_power_nss_delta(u8 nss) ...@@ -931,10 +933,27 @@ static inline u8 mt76_tx_power_nss_delta(u8 nss)
return nss_delta[nss - 1]; 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 #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 #else
return false; return false;
#endif #endif
...@@ -1016,17 +1035,17 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -1016,17 +1035,17 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
void *data, int len); void *data, int len);
int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
struct netlink_callback *cb, void *data, int len); 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 #ifdef CONFIG_NL80211_TESTMODE
enum mt76_testmode_state state = MT76_TM_STATE_IDLE; 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; state = MT76_TM_STATE_OFF;
mt76_testmode_set_state(dev, state); mt76_testmode_set_state(phy, state);
#endif #endif
} }
...@@ -1052,7 +1071,7 @@ void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, ...@@ -1052,7 +1071,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, void mt76_rx_poll_complete(struct mt76_dev *dev, enum mt76_rxq_id q,
struct napi_struct *napi); struct napi_struct *napi);
void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); 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, void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q,
struct mt76_queue_entry *e); struct mt76_queue_entry *e);
......
...@@ -97,7 +97,7 @@ static void mt7615_stop(struct ieee80211_hw *hw) ...@@ -97,7 +97,7 @@ static void mt7615_stop(struct ieee80211_hw *hw)
mt7615_mutex_acquire(dev); mt7615_mutex_acquire(dev);
mt76_testmode_reset(&dev->mt76, true); mt76_testmode_reset(phy->mt76, true);
clear_bit(MT76_STATE_RUNNING, &phy->mt76->state); clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
cancel_delayed_work_sync(&phy->scan_work); cancel_delayed_work_sync(&phy->scan_work);
...@@ -181,7 +181,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw, ...@@ -181,7 +181,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
mt7615_mutex_acquire(dev); mt7615_mutex_acquire(dev);
mt76_testmode_reset(&dev->mt76, true); mt76_testmode_reset(phy->mt76, true);
if (vif->type == NL80211_IFTYPE_MONITOR && if (vif->type == NL80211_IFTYPE_MONITOR &&
is_zero_ether_addr(vif->addr)) is_zero_ether_addr(vif->addr))
...@@ -252,7 +252,7 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw, ...@@ -252,7 +252,7 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,
mt7615_mutex_acquire(dev); mt7615_mutex_acquire(dev);
mt76_testmode_reset(&dev->mt76, true); mt76_testmode_reset(phy->mt76, true);
if (vif == phy->monitor_vif) if (vif == phy->monitor_vif)
phy->monitor_vif = NULL; phy->monitor_vif = NULL;
...@@ -321,7 +321,7 @@ int mt7615_set_channel(struct mt7615_phy *phy) ...@@ -321,7 +321,7 @@ int mt7615_set_channel(struct mt7615_phy *phy)
mt7615_mac_set_timing(phy); mt7615_mac_set_timing(phy);
ret = mt7615_dfs_init_radar_detector(phy); ret = mt7615_dfs_init_radar_detector(phy);
mt7615_mac_cca_stats_reset(phy); mt7615_mac_cca_stats_reset(phy);
mt7615_mcu_set_sku_en(phy, !mt76_testmode_enabled(&dev->mt76)); mt7615_mcu_set_sku_en(phy, !mt76_testmode_enabled(phy->mt76));
mt7615_mac_reset_counters(dev); mt7615_mac_reset_counters(dev);
phy->noise = 0; phy->noise = 0;
...@@ -334,7 +334,7 @@ int mt7615_set_channel(struct mt7615_phy *phy) ...@@ -334,7 +334,7 @@ int mt7615_set_channel(struct mt7615_phy *phy)
mt76_txq_schedule_all(phy->mt76); mt76_txq_schedule_all(phy->mt76);
if (!mt76_testmode_enabled(&dev->mt76)) if (!mt76_testmode_enabled(phy->mt76))
ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work, ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
MT7615_WATCHDOG_TIME); MT7615_WATCHDOG_TIME);
...@@ -411,9 +411,9 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed) ...@@ -411,9 +411,9 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
if (changed & (IEEE80211_CONF_CHANGE_CHANNEL | if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
IEEE80211_CONF_CHANGE_POWER)) { IEEE80211_CONF_CHANGE_POWER)) {
#ifdef CONFIG_NL80211_TESTMODE #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); mt7615_mutex_acquire(dev);
mt76_testmode_reset(&dev->mt76, false); mt76_testmode_reset(phy->mt76, false);
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
} }
#endif #endif
...@@ -425,7 +425,7 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed) ...@@ -425,7 +425,7 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed)
mt7615_mutex_acquire(dev); mt7615_mutex_acquire(dev);
if (changed & IEEE80211_CONF_CHANGE_MONITOR) { 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)) if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC; phy->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
...@@ -480,7 +480,7 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw, ...@@ -480,7 +480,7 @@ static void mt7615_configure_filter(struct ieee80211_hw *hw,
#define MT76_FILTER(_flag, _hw) do { \ #define MT76_FILTER(_flag, _hw) do { \
flags |= *total_flags & FIF_##_flag; \ flags |= *total_flags & FIF_##_flag; \
phy->rxfilter &= ~(_hw); \ phy->rxfilter &= ~(_hw); \
if (!mt76_testmode_enabled(&dev->mt76)) \ if (!mt76_testmode_enabled(phy->mt76)) \
phy->rxfilter |= !(flags & FIF_##_flag) * (_hw);\ phy->rxfilter |= !(flags & FIF_##_flag) * (_hw);\
} while (0) } while (0)
......
...@@ -2895,7 +2895,7 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd) ...@@ -2895,7 +2895,7 @@ int mt7615_mcu_set_chan_info(struct mt7615_phy *phy, int cmd)
req.band_idx = phy != &dev->phy; req.band_idx = phy != &dev->phy;
req.bw = mt7615_mcu_chan_bw(chandef); req.bw = mt7615_mcu_chan_bw(chandef);
if (mt76_testmode_enabled(&dev->mt76)) if (mt76_testmode_enabled(phy->mt76))
memset(req.txpower_sku, 0x3f, 49); memset(req.txpower_sku, 0x3f, 49);
else else
mt7615_mcu_set_txpower_sku(phy, req.txpower_sku); mt7615_mcu_set_txpower_sku(phy, req.txpower_sku);
......
...@@ -67,8 +67,8 @@ mt7615_tm_set_tx_power(struct mt7615_phy *phy) ...@@ -67,8 +67,8 @@ mt7615_tm_set_tx_power(struct mt7615_phy *phy)
}; };
u8 *tx_power = NULL; u8 *tx_power = NULL;
if (dev->mt76.test.state != MT76_TM_STATE_OFF) if (mphy->test.state != MT76_TM_STATE_OFF)
tx_power = dev->mt76.test.tx_power; tx_power = mphy->test.tx_power;
len = MT7615_EE_MAX - MT_EE_NIC_CONF_0; len = MT7615_EE_MAX - MT_EE_NIC_CONF_0;
skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, sizeof(req_hdr) + len); 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) ...@@ -95,14 +95,15 @@ mt7615_tm_set_tx_power(struct mt7615_phy *phy)
} }
static void static void
mt7615_tm_reg_backup_restore(struct mt7615_dev *dev) mt7615_tm_reg_backup_restore(struct mt7615_phy *phy)
{ {
struct mt7615_dev *dev = phy->dev;
u32 *b = dev->test.reg_backup; u32 *b = dev->test.reg_backup;
int n_regs = ARRAY_SIZE(reg_backup_list); int n_regs = ARRAY_SIZE(reg_backup_list);
int n_rf_regs = ARRAY_SIZE(rf_backup_list); int n_rf_regs = ARRAY_SIZE(rf_backup_list);
int i; int i;
if (dev->mt76.test.state == MT76_TM_STATE_OFF) { if (dev->mphy.test.state == MT76_TM_STATE_OFF) {
for (i = 0; i < n_regs; i++) for (i = 0; i < n_regs; i++)
mt76_wr(dev, reg_backup_list[i], b[i]); mt76_wr(dev, reg_backup_list[i], b[i]);
...@@ -128,10 +129,10 @@ mt7615_tm_reg_backup_restore(struct mt7615_dev *dev) ...@@ -128,10 +129,10 @@ mt7615_tm_reg_backup_restore(struct mt7615_dev *dev)
rf_backup_list[i].reg); rf_backup_list[i].reg);
} }
static void 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; unsigned int total_flags = ~0;
if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state))
...@@ -142,16 +143,7 @@ mt7615_tm_init_phy(struct mt7615_dev *dev, struct mt7615_phy *phy) ...@@ -142,16 +143,7 @@ mt7615_tm_init_phy(struct mt7615_dev *dev, struct mt7615_phy *phy)
mt7615_ops.configure_filter(phy->mt76->hw, 0, &total_flags, 0); mt7615_ops.configure_filter(phy->mt76->hw, 0, &total_flags, 0);
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
mt7615_tm_reg_backup_restore(dev); mt7615_tm_reg_backup_restore(phy);
}
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);
} }
static void static void
...@@ -175,9 +167,10 @@ mt7615_tm_set_rx_enable(struct mt7615_dev *dev, bool en) ...@@ -175,9 +167,10 @@ mt7615_tm_set_rx_enable(struct mt7615_dev *dev, bool en)
} }
static void 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; u8 mask = td->tx_antenna_mask;
int i; int i;
...@@ -185,7 +178,7 @@ mt7615_tm_set_tx_antenna(struct mt7615_dev *dev, bool en) ...@@ -185,7 +178,7 @@ mt7615_tm_set_tx_antenna(struct mt7615_dev *dev, bool en)
return; return;
if (!en) if (!en)
mask = dev->phy.chainmask; mask = phy->chainmask;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
mt76_rmw_field(dev, MT_WF_PHY_RFINTF3_0(i), mt76_rmw_field(dev, MT_WF_PHY_RFINTF3_0(i),
...@@ -228,26 +221,28 @@ mt7615_tm_set_tx_antenna(struct mt7615_dev *dev, bool en) ...@@ -228,26 +221,28 @@ mt7615_tm_set_tx_antenna(struct mt7615_dev *dev, bool en)
} }
static void 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 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_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
mt7615_tm_set_tx_antenna(dev, en); mt7615_tm_set_tx_antenna(phy, en);
mt7615_tm_set_rx_enable(dev, !en); mt7615_tm_set_rx_enable(dev, !en);
if (!en || !skb) if (!en || !skb)
return; return;
info = IEEE80211_SKB_CB(skb); info = IEEE80211_SKB_CB(skb);
info->control.vif = dev->phy.monitor_vif; info->control.vif = phy->monitor_vif;
} }
static void 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; struct mt7615_dev *dev = phy->dev;
bool en = dev->mt76.test.state != MT76_TM_STATE_OFF; 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)) if (changed & BIT(TM_CHANGED_TXPOWER_CTRL))
mt7615_mcu_set_test_param(dev, MCU_ATE_SET_TX_POWER_CONTROL, mt7615_mcu_set_test_param(dev, MCU_ATE_SET_TX_POWER_CONTROL,
...@@ -256,25 +251,25 @@ mt7615_tm_update_params(struct mt7615_dev *dev, u32 changed) ...@@ -256,25 +251,25 @@ mt7615_tm_update_params(struct mt7615_dev *dev, u32 changed)
mt7615_mcu_set_test_param(dev, MCU_ATE_SET_FREQ_OFFSET, mt7615_mcu_set_test_param(dev, MCU_ATE_SET_FREQ_OFFSET,
en, en ? td->freq_offset : 0); en, en ? td->freq_offset : 0);
if (changed & BIT(TM_CHANGED_TXPOWER)) if (changed & BIT(TM_CHANGED_TXPOWER))
mt7615_tm_set_tx_power(&dev->phy); mt7615_tm_set_tx_power(phy);
} }
static int 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 mt7615_phy *phy = mphy->priv;
struct mt76_testmode_data *td = &mdev->test; struct mt76_testmode_data *td = &mphy->test;
enum mt76_testmode_state prev_state = td->state; enum mt76_testmode_state prev_state = td->state;
mdev->test.state = state; mphy->test.state = state;
if (prev_state == MT76_TM_STATE_TX_FRAMES) 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) 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) if (state <= MT76_TM_STATE_IDLE)
mt7615_tm_init(dev); mt7615_tm_init(phy);
if ((state == MT76_TM_STATE_IDLE && if ((state == MT76_TM_STATE_IDLE &&
prev_state == MT76_TM_STATE_OFF) || prev_state == MT76_TM_STATE_OFF) ||
...@@ -290,18 +285,18 @@ mt7615_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state) ...@@ -290,18 +285,18 @@ mt7615_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
changed |= BIT(i); changed |= BIT(i);
} }
mt7615_tm_update_params(dev, changed); mt7615_tm_update_params(phy, changed);
} }
return 0; return 0;
} }
static int 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) enum mt76_testmode_state new_state)
{ {
struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); struct mt76_testmode_data *td = &mphy->test;
struct mt76_testmode_data *td = &dev->mt76.test; struct mt7615_phy *phy = mphy->priv;
u32 changed = 0; u32 changed = 0;
int i; int i;
...@@ -311,7 +306,7 @@ mt7615_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb, ...@@ -311,7 +306,7 @@ mt7615_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
td->state == MT76_TM_STATE_OFF) td->state == MT76_TM_STATE_OFF)
return 0; return 0;
if (td->tx_antenna_mask & ~dev->phy.chainmask) if (td->tx_antenna_mask & ~phy->chainmask)
return -EINVAL; return -EINVAL;
for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) { for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
...@@ -319,15 +314,16 @@ mt7615_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb, ...@@ -319,15 +314,16 @@ mt7615_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
changed |= BIT(i); changed |= BIT(i);
} }
mt7615_tm_update_params(dev, changed); mt7615_tm_update_params(phy, changed);
return 0; return 0;
} }
static int 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;
struct mt7615_dev *dev = phy->dev;
void *rx, *rssi; void *rx, *rssi;
int i; int i;
......
...@@ -601,18 +601,19 @@ void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb) ...@@ -601,18 +601,19 @@ void mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb)
#endif #endif
static void static void
mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy, mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi,
__le32 *txwi, struct sk_buff *skb) struct sk_buff *skb)
{ {
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
struct mt76_testmode_data *td = &dev->mt76.test; struct mt76_testmode_data *td = &phy->mt76->test;
struct mt7915_dev *dev = phy->dev;
u8 rate_idx = td->tx_rate_idx; u8 rate_idx = td->tx_rate_idx;
u8 nss = td->tx_rate_nss; u8 nss = td->tx_rate_nss;
u8 bw, mode; u8 bw, mode;
u16 rateval = 0; u16 rateval = 0;
u32 val; u32 val;
if (skb != dev->mt76.test.tx_skb) if (skb != phy->mt76->test.tx_skb)
return; return;
switch (td->tx_rate_mode) { switch (td->tx_rate_mode) {
...@@ -644,7 +645,7 @@ mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy, ...@@ -644,7 +645,7 @@ mt7915_mac_write_txwi_tm(struct mt7915_dev *dev, struct mt76_phy *mphy,
break; break;
} }
switch (mphy->chandef.width) { switch (phy->mt76->chandef.width) {
case NL80211_CHAN_WIDTH_40: case NL80211_CHAN_WIDTH_40:
bw = 1; bw = 1;
break; break;
...@@ -902,8 +903,8 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, ...@@ -902,8 +903,8 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE); txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
} }
if (mt76_testmode_enabled(&dev->mt76)) if (mt76_testmode_enabled(mphy))
mt7915_mac_write_txwi_tm(dev, mphy, txwi, skb); mt7915_mac_write_txwi_tm(mphy->priv, txwi, skb);
} }
static void static void
...@@ -1051,20 +1052,19 @@ mt7915_tx_complete_status(struct mt76_dev *mdev, struct sk_buff *skb, ...@@ -1051,20 +1052,19 @@ mt7915_tx_complete_status(struct mt76_dev *mdev, struct sk_buff *skb,
status.rate = &msta->stats.tx_rate; status.rate = &msta->stats.tx_rate;
} }
hw = mt76_tx_status_get_hw(mdev, skb);
#ifdef CONFIG_NL80211_TESTMODE #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 mt7915_phy *phy = mt7915_hw_phy(hw);
struct ieee80211_vif *vif = phy->monitor_vif; struct ieee80211_vif *vif = phy->monitor_vif;
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
mt76_tx_complete_skb(mdev, mvif->sta.wcid.idx, skb); mt76_tx_complete_skb(mdev, mvif->sta.wcid.idx, skb);
return; return;
} }
#endif #endif
hw = mt76_tx_status_get_hw(mdev, skb);
if (info->flags & IEEE80211_TX_CTL_AMPDU) if (info->flags & IEEE80211_TX_CTL_AMPDU)
info->flags |= IEEE80211_TX_STAT_AMPDU; info->flags |= IEEE80211_TX_STAT_AMPDU;
......
...@@ -44,12 +44,12 @@ static int mt7915_start(struct ieee80211_hw *hw) ...@@ -44,12 +44,12 @@ static int mt7915_start(struct ieee80211_hw *hw)
mt7915_mac_enable_nf(dev, 1); mt7915_mac_enable_nf(dev, 1);
} }
mt7915_mcu_set_sku_en(phy, !mt76_testmode_enabled(&dev->mt76)); mt7915_mcu_set_sku_en(phy, !mt76_testmode_enabled(phy->mt76));
mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH); mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
set_bit(MT76_STATE_RUNNING, &phy->mt76->state); set_bit(MT76_STATE_RUNNING, &phy->mt76->state);
if (!mt76_testmode_enabled(&dev->mt76)) if (!mt76_testmode_enabled(phy->mt76))
ieee80211_queue_delayed_work(hw, &phy->mac_work, ieee80211_queue_delayed_work(hw, &phy->mac_work,
MT7915_WATCHDOG_TIME); MT7915_WATCHDOG_TIME);
...@@ -70,7 +70,7 @@ static void mt7915_stop(struct ieee80211_hw *hw) ...@@ -70,7 +70,7 @@ static void mt7915_stop(struct ieee80211_hw *hw)
mutex_lock(&dev->mt76.mutex); 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); clear_bit(MT76_STATE_RUNNING, &phy->mt76->state);
...@@ -153,7 +153,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, ...@@ -153,7 +153,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw,
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
mt76_testmode_reset(&dev->mt76, true); mt76_testmode_reset(phy->mt76, true);
if (vif->type == NL80211_IFTYPE_MONITOR && if (vif->type == NL80211_IFTYPE_MONITOR &&
is_zero_ether_addr(vif->addr)) is_zero_ether_addr(vif->addr))
...@@ -228,7 +228,7 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw, ...@@ -228,7 +228,7 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,
/* TODO: disable beacon for the bss */ /* TODO: disable beacon for the bss */
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
mt76_testmode_reset(&dev->mt76, true); mt76_testmode_reset(phy->mt76, true);
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
if (vif == phy->monitor_vif) if (vif == phy->monitor_vif)
...@@ -298,7 +298,7 @@ int mt7915_set_channel(struct mt7915_phy *phy) ...@@ -298,7 +298,7 @@ int mt7915_set_channel(struct mt7915_phy *phy)
mt76_txq_schedule_all(phy->mt76); mt76_txq_schedule_all(phy->mt76);
if (!mt76_testmode_enabled(&dev->mt76)) if (!mt76_testmode_enabled(phy->mt76))
ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work, ieee80211_queue_delayed_work(phy->mt76->hw, &phy->mac_work,
MT7915_WATCHDOG_TIME); MT7915_WATCHDOG_TIME);
...@@ -365,9 +365,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) ...@@ -365,9 +365,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
#ifdef CONFIG_NL80211_TESTMODE #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); mutex_lock(&dev->mt76.mutex);
mt76_testmode_reset(&dev->mt76, false); mt76_testmode_reset(phy->mt76, false);
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
} }
#endif #endif
...@@ -396,7 +396,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) ...@@ -396,7 +396,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, mt76_rmw_field(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN,
enabled); enabled);
mt76_testmode_reset(&dev->mt76, true); mt76_testmode_reset(phy->mt76, true);
mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter); mt76_wr(dev, MT_WF_RFCR(band), phy->rxfilter);
} }
......
...@@ -3186,6 +3186,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) ...@@ -3186,6 +3186,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
struct mt7915_dev *dev = phy->dev; struct mt7915_dev *dev = phy->dev;
struct cfg80211_chan_def *chandef = &phy->mt76->chandef; struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
int freq1 = chandef->center_freq1; int freq1 = chandef->center_freq1;
bool ext_phy = phy != &dev->phy;
struct { struct {
u8 control_ch; u8 control_ch;
u8 center_ch; u8 center_ch;
...@@ -3209,16 +3210,21 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) ...@@ -3209,16 +3210,21 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
.bw = mt7915_mcu_chan_bw(chandef), .bw = mt7915_mcu_chan_bw(chandef),
.tx_streams_num = hweight8(phy->mt76->antenna_mask), .tx_streams_num = hweight8(phy->mt76->antenna_mask),
.rx_streams = phy->mt76->antenna_mask, .rx_streams = phy->mt76->antenna_mask,
.band_idx = phy != &dev->phy, .band_idx = ext_phy,
.channel_band = chandef->chan->band, .channel_band = chandef->chan->band,
}; };
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
if (dev->mt76.test.tx_antenna_mask && if (phy->mt76->test.tx_antenna_mask &&
(dev->mt76.test.state == MT76_TM_STATE_TX_FRAMES || (phy->mt76->test.state == MT76_TM_STATE_TX_FRAMES ||
dev->mt76.test.state == MT76_TM_STATE_RX_FRAMES)) { phy->mt76->test.state == MT76_TM_STATE_RX_FRAMES)) {
req.tx_streams_num = fls(dev->mt76.test.tx_antenna_mask); req.tx_streams_num = fls(phy->mt76->test.tx_antenna_mask);
req.rx_streams = dev->mt76.test.tx_antenna_mask; req.rx_streams = phy->mt76->test.tx_antenna_mask;
if (ext_phy) {
req.tx_streams_num = 2;
req.rx_streams >>= 2;
}
} }
#endif #endif
......
...@@ -70,8 +70,8 @@ mt7915_tm_set_tx_power(struct mt7915_phy *phy) ...@@ -70,8 +70,8 @@ mt7915_tm_set_tx_power(struct mt7915_phy *phy)
}; };
u8 *tx_power = NULL; u8 *tx_power = NULL;
if (dev->mt76.test.state != MT76_TM_STATE_OFF) if (phy->mt76->test.state != MT76_TM_STATE_OFF)
tx_power = dev->mt76.test.tx_power; tx_power = phy->mt76->test.tx_power;
/* Tx power of the other antennas are the same as antenna 0 */ /* Tx power of the other antennas are the same as antenna 0 */
if (tx_power && tx_power[0]) if (tx_power && tx_power[0])
...@@ -85,11 +85,13 @@ mt7915_tm_set_tx_power(struct mt7915_phy *phy) ...@@ -85,11 +85,13 @@ mt7915_tm_set_tx_power(struct mt7915_phy *phy)
} }
static int 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 = { struct mt7915_tm_cmd req = {
.testmode_en = en, .testmode_en = en,
.param_idx = MCU_ATE_SET_FREQ_OFFSET, .param_idx = MCU_ATE_SET_FREQ_OFFSET,
.param.freq.band = phy != &dev->phy,
.param.freq.freq_offset = cpu_to_le32(val), .param.freq.freq_offset = cpu_to_le32(val),
}; };
...@@ -115,9 +117,9 @@ mt7915_tm_mode_ctrl(struct mt7915_dev *dev, bool enable) ...@@ -115,9 +117,9 @@ mt7915_tm_mode_ctrl(struct mt7915_dev *dev, bool enable)
} }
static int static int
mt7915_tm_set_trx(struct mt7915_dev *dev, struct mt7915_phy *phy, mt7915_tm_set_trx(struct mt7915_phy *phy, int type, bool en)
int type, bool en)
{ {
struct mt7915_dev *dev = phy->dev;
struct mt7915_tm_cmd req = { struct mt7915_tm_cmd req = {
.testmode_en = 1, .testmode_en = 1,
.param_idx = MCU_ATE_SET_TRX, .param_idx = MCU_ATE_SET_TRX,
...@@ -131,14 +133,15 @@ mt7915_tm_set_trx(struct mt7915_dev *dev, struct mt7915_phy *phy, ...@@ -131,14 +133,15 @@ mt7915_tm_set_trx(struct mt7915_dev *dev, struct mt7915_phy *phy,
} }
static void 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); int n_regs = ARRAY_SIZE(reg_backup_list);
struct mt7915_dev *dev = phy->dev;
bool ext_phy = phy != &dev->phy; bool ext_phy = phy != &dev->phy;
u32 *b = dev->test.reg_backup; u32 *b = dev->test.reg_backup;
int i; int i;
if (dev->mt76.test.state == MT76_TM_STATE_OFF) { if (dev->mphy.test.state == MT76_TM_STATE_OFF) {
for (i = 0; i < n_regs; i++) for (i = 0; i < n_regs; i++)
mt76_wr(dev, reg_backup_list[i].band[ext_phy], b[i]); mt76_wr(dev, reg_backup_list[i].band[ext_phy], b[i]);
return; return;
...@@ -182,95 +185,101 @@ mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy) ...@@ -182,95 +185,101 @@ mt7915_tm_reg_backup_restore(struct mt7915_dev *dev, struct mt7915_phy *phy)
} }
static void static void
mt7915_tm_init(struct mt7915_dev *dev) mt7915_tm_init(struct mt7915_phy *phy)
{ {
bool en = !(dev->mt76.test.state == MT76_TM_STATE_OFF); bool en = !(phy->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; return;
mt7915_tm_mode_ctrl(dev, en); mt7915_tm_mode_ctrl(dev, en);
mt7915_tm_reg_backup_restore(dev, &dev->phy); mt7915_tm_reg_backup_restore(phy);
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TXRX, !en); mt7915_tm_set_trx(phy, TM_MAC_TXRX, !en);
mt7915_mcu_add_bss_info(&dev->phy, dev->phy.monitor_vif, en); mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en);
} }
static void static void
mt7915_tm_set_tx_frames(struct mt7915_dev *dev, bool en) 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, static const u8 spe_idx_map[] = {0, 0, 1, 0, 3, 2, 4, 0,
9, 8, 6, 10, 16, 12, 18, 0}; 9, 8, 6, 10, 16, 12, 18, 0};
struct sk_buff *skb = dev->mt76.test.tx_skb; struct sk_buff *skb = phy->mt76->test.tx_skb;
struct mt7915_dev *dev = phy->dev;
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_RX_RXV, false); mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, false);
if (en) { if (en) {
u8 tx_ant = dev->mt76.test.tx_antenna_mask; u8 tx_ant = phy->mt76->test.tx_antenna_mask;
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
mt7915_set_channel(&dev->phy); mt7915_set_channel(phy);
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
mt7915_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH); mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
if (phy != &dev->phy)
tx_ant >>= 2;
dev->test.spe_idx = spe_idx_map[tx_ant]; dev->test.spe_idx = spe_idx_map[tx_ant];
} }
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_TX, en); mt7915_tm_set_trx(phy, TM_MAC_TX, en);
if (!en || !skb) if (!en || !skb)
return; return;
info = IEEE80211_SKB_CB(skb); info = IEEE80211_SKB_CB(skb);
info->control.vif = dev->phy.monitor_vif; info->control.vif = phy->monitor_vif;
} }
static void static void
mt7915_tm_set_rx_frames(struct mt7915_dev *dev, bool en) mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
{ {
struct mt7915_dev *dev = phy->dev;
if (en) { if (en) {
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
mt7915_set_channel(&dev->phy); mt7915_set_channel(phy);
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
mt7915_mcu_set_chan_info(&dev->phy, MCU_EXT_CMD_SET_RX_PATH); mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
} }
mt7915_tm_set_trx(dev, &dev->phy, TM_MAC_RX_RXV, en); mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
} }
static void static void
mt7915_tm_update_params(struct mt7915_dev *dev, u32 changed) mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed)
{ {
struct mt76_testmode_data *td = &dev->mt76.test; struct mt76_testmode_data *td = &phy->mt76->test;
bool en = dev->mt76.test.state != MT76_TM_STATE_OFF; bool en = phy->mt76->test.state != MT76_TM_STATE_OFF;
if (changed & BIT(TM_CHANGED_FREQ_OFFSET)) if (changed & BIT(TM_CHANGED_FREQ_OFFSET))
mt7915_tm_set_freq_offset(dev, en, en ? td->freq_offset : 0); mt7915_tm_set_freq_offset(phy, en, en ? td->freq_offset : 0);
if (changed & BIT(TM_CHANGED_TXPOWER)) if (changed & BIT(TM_CHANGED_TXPOWER))
mt7915_tm_set_tx_power(&dev->phy); mt7915_tm_set_tx_power(phy);
} }
static int static int
mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state) mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
{ {
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); struct mt76_testmode_data *td = &mphy->test;
struct mt76_testmode_data *td = &mdev->test; struct mt7915_phy *phy = mphy->priv;
enum mt76_testmode_state prev_state = td->state; enum mt76_testmode_state prev_state = td->state;
mdev->test.state = state; mphy->test.state = state;
if (prev_state == MT76_TM_STATE_TX_FRAMES) if (prev_state == MT76_TM_STATE_TX_FRAMES)
mt7915_tm_set_tx_frames(dev, false); mt7915_tm_set_tx_frames(phy, false);
else if (state == MT76_TM_STATE_TX_FRAMES) else if (state == MT76_TM_STATE_TX_FRAMES)
mt7915_tm_set_tx_frames(dev, true); mt7915_tm_set_tx_frames(phy, true);
else if (prev_state == MT76_TM_STATE_RX_FRAMES) else if (prev_state == MT76_TM_STATE_RX_FRAMES)
mt7915_tm_set_rx_frames(dev, false); mt7915_tm_set_rx_frames(phy, false);
else if (state == MT76_TM_STATE_RX_FRAMES) else if (state == MT76_TM_STATE_RX_FRAMES)
mt7915_tm_set_rx_frames(dev, true); mt7915_tm_set_rx_frames(phy, true);
else if (prev_state == MT76_TM_STATE_OFF || state == MT76_TM_STATE_OFF) else if (prev_state == MT76_TM_STATE_OFF || state == MT76_TM_STATE_OFF)
mt7915_tm_init(dev); mt7915_tm_init(phy);
if ((state == MT76_TM_STATE_IDLE && if ((state == MT76_TM_STATE_IDLE &&
prev_state == MT76_TM_STATE_OFF) || prev_state == MT76_TM_STATE_OFF) ||
...@@ -286,18 +295,18 @@ mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state) ...@@ -286,18 +295,18 @@ mt7915_tm_set_state(struct mt76_dev *mdev, enum mt76_testmode_state state)
changed |= BIT(i); changed |= BIT(i);
} }
mt7915_tm_update_params(dev, changed); mt7915_tm_update_params(phy, changed);
} }
return 0; return 0;
} }
static int 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) enum mt76_testmode_state new_state)
{ {
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); struct mt76_testmode_data *td = &mphy->test;
struct mt76_testmode_data *td = &dev->mt76.test; struct mt7915_phy *phy = mphy->priv;
u32 changed = 0; u32 changed = 0;
int i; int i;
...@@ -307,7 +316,7 @@ mt7915_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb, ...@@ -307,7 +316,7 @@ mt7915_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
td->state == MT76_TM_STATE_OFF) td->state == MT76_TM_STATE_OFF)
return 0; return 0;
if (td->tx_antenna_mask & ~dev->phy.chainmask) if (td->tx_antenna_mask & ~phy->chainmask)
return -EINVAL; return -EINVAL;
for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) { for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) {
...@@ -315,15 +324,16 @@ mt7915_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb, ...@@ -315,15 +324,16 @@ mt7915_tm_set_params(struct mt76_dev *mdev, struct nlattr **tb,
changed |= BIT(i); changed |= BIT(i);
} }
mt7915_tm_update_params(dev, changed); mt7915_tm_update_params(phy, changed);
return 0; return 0;
} }
static int 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;
struct mt7915_dev *dev = phy->dev;
void *rx, *rssi; void *rx, *rssi;
int i; int i;
......
...@@ -19,11 +19,11 @@ static const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = { ...@@ -19,11 +19,11 @@ static const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
[MT76_TM_ATTR_FREQ_OFFSET] = { .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_wcid *wcid = &dev->global_wcid;
struct mt76_phy *phy = &dev->phy;
struct sk_buff *skb = td->tx_skb; struct sk_buff *skb = td->tx_skb;
struct mt76_queue *q; struct mt76_queue *q;
int qid; int qid;
...@@ -56,10 +56,9 @@ void mt76_testmode_tx_pending(struct mt76_dev *dev) ...@@ -56,10 +56,9 @@ void mt76_testmode_tx_pending(struct mt76_dev *dev)
static int 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_testmode_data *td = &phy->test;
struct mt76_phy *phy = &dev->phy;
struct ieee80211_tx_info *info; struct ieee80211_tx_info *info;
struct ieee80211_hdr *hdr; struct ieee80211_hdr *hdr;
struct sk_buff *skb; struct sk_buff *skb;
...@@ -67,6 +66,7 @@ mt76_testmode_tx_init(struct mt76_dev *dev) ...@@ -67,6 +66,7 @@ mt76_testmode_tx_init(struct mt76_dev *dev)
IEEE80211_FCTL_FROMDS; IEEE80211_FCTL_FROMDS;
struct ieee80211_tx_rate *rate; struct ieee80211_tx_rate *rate;
u8 max_nss = hweight8(phy->antenna_mask); u8 max_nss = hweight8(phy->antenna_mask);
bool ext_phy = phy != &phy->dev->phy;
if (td->tx_antenna_mask) if (td->tx_antenna_mask)
max_nss = min_t(u8, max_nss, hweight8(td->tx_antenna_mask)); max_nss = min_t(u8, max_nss, hweight8(td->tx_antenna_mask));
...@@ -88,6 +88,9 @@ mt76_testmode_tx_init(struct mt76_dev *dev) ...@@ -88,6 +88,9 @@ mt76_testmode_tx_init(struct mt76_dev *dev)
IEEE80211_TX_CTL_NO_ACK | IEEE80211_TX_CTL_NO_ACK |
IEEE80211_TX_CTL_NO_PS_BUFFER; 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) if (td->tx_rate_mode > MT76_TM_TX_MODE_VHT)
goto out; goto out;
...@@ -166,9 +169,10 @@ mt76_testmode_tx_init(struct mt76_dev *dev) ...@@ -166,9 +169,10 @@ mt76_testmode_tx_init(struct mt76_dev *dev)
} }
static void 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_queued = 0;
td->tx_done = 0; td->tx_done = 0;
...@@ -177,9 +181,10 @@ mt76_testmode_tx_start(struct mt76_dev *dev) ...@@ -177,9 +181,10 @@ mt76_testmode_tx_start(struct mt76_dev *dev)
} }
static void 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); mt76_worker_disable(&dev->tx_worker);
...@@ -206,9 +211,9 @@ mt76_testmode_param_present(struct mt76_testmode_data *td, u16 idx) ...@@ -206,9 +211,9 @@ mt76_testmode_param_present(struct mt76_testmode_data *td, u16 idx)
} }
static void 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) if (td->tx_msdu_len > 0)
return; return;
...@@ -220,49 +225,50 @@ mt76_testmode_init_defaults(struct mt76_dev *dev) ...@@ -220,49 +225,50 @@ mt76_testmode_init_defaults(struct mt76_dev *dev)
} }
static int 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; int err;
if (prev_state == MT76_TM_STATE_TX_FRAMES) 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) { if (state == MT76_TM_STATE_TX_FRAMES) {
err = mt76_testmode_tx_init(dev); err = mt76_testmode_tx_init(phy);
if (err) if (err)
return err; return err;
} }
err = dev->test_ops->set_state(dev, state); err = dev->test_ops->set_state(phy, state);
if (err) { if (err) {
if (state == MT76_TM_STATE_TX_FRAMES) if (state == MT76_TM_STATE_TX_FRAMES)
mt76_testmode_tx_stop(dev); mt76_testmode_tx_stop(phy);
return err; return err;
} }
if (state == MT76_TM_STATE_TX_FRAMES) 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) { 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; 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 mt76_testmode_data *td = &phy->test;
struct ieee80211_hw *hw = dev->phy.hw; struct ieee80211_hw *hw = phy->hw;
if (state == td->state && state == MT76_TM_STATE_OFF) if (state == td->state && state == MT76_TM_STATE_OFF)
return 0; return 0;
if (state > MT76_TM_STATE_OFF && 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))) !(hw->conf.flags & IEEE80211_CONF_MONITOR)))
return -ENOTCONN; return -ENOTCONN;
...@@ -270,12 +276,12 @@ int mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state ...@@ -270,12 +276,12 @@ int mt76_testmode_set_state(struct mt76_dev *dev, enum mt76_testmode_state state
td->state != MT76_TM_STATE_IDLE) { td->state != MT76_TM_STATE_IDLE) {
int ret; int ret;
ret = __mt76_testmode_set_state(dev, MT76_TM_STATE_IDLE); ret = __mt76_testmode_set_state(phy, MT76_TM_STATE_IDLE);
if (ret) if (ret)
return ret; return ret;
} }
return __mt76_testmode_set_state(dev, state); return __mt76_testmode_set_state(phy, state);
} }
EXPORT_SYMBOL(mt76_testmode_set_state); EXPORT_SYMBOL(mt76_testmode_set_state);
...@@ -301,8 +307,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -301,8 +307,9 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{ {
struct mt76_phy *phy = hw->priv; struct mt76_phy *phy = hw->priv;
struct mt76_dev *dev = phy->dev; 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]; struct nlattr *tb[NUM_MT76_TM_ATTRS];
bool ext_phy = phy != &dev->phy;
u32 state; u32 state;
int err; int err;
int i; int i;
...@@ -320,11 +327,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -320,11 +327,11 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
mutex_lock(&dev->mutex); mutex_lock(&dev->mutex);
if (tb[MT76_TM_ATTR_RESET]) { 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)); memset(td, 0, sizeof(*td));
} }
mt76_testmode_init_defaults(dev); mt76_testmode_init_defaults(phy);
if (tb[MT76_TM_ATTR_TX_COUNT]) if (tb[MT76_TM_ATTR_TX_COUNT])
td->tx_count = nla_get_u32(tb[MT76_TM_ATTR_TX_COUNT]); td->tx_count = nla_get_u32(tb[MT76_TM_ATTR_TX_COUNT]);
...@@ -350,8 +357,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -350,8 +357,8 @@ 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_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_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_LTF], &td->tx_ltf, 0, 2) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA], &td->tx_antenna_mask, 1, mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_ANTENNA], &td->tx_antenna_mask,
phy->antenna_mask) || 1 << (ext_phy * 2), phy->antenna_mask << (ext_phy * 2)) ||
mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL], mt76_tm_get_u8(tb[MT76_TM_ATTR_TX_POWER_CONTROL],
&td->tx_power_control, 0, 1)) &td->tx_power_control, 0, 1))
goto out; goto out;
...@@ -382,7 +389,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -382,7 +389,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
} }
if (dev->test_ops->set_params) { 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) if (err)
goto out; goto out;
} }
...@@ -393,7 +400,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -393,7 +400,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
err = 0; err = 0;
if (tb[MT76_TM_ATTR_STATE]) if (tb[MT76_TM_ATTR_STATE])
err = mt76_testmode_set_state(dev, state); err = mt76_testmode_set_state(phy, state);
out: out:
mutex_unlock(&dev->mutex); mutex_unlock(&dev->mutex);
...@@ -403,9 +410,10 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, ...@@ -403,9 +410,10 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
EXPORT_SYMBOL(mt76_testmode_cmd); EXPORT_SYMBOL(mt76_testmode_cmd);
static int 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_packets = 0;
u64 rx_fcs_error = 0; u64 rx_fcs_error = 0;
int i; int i;
...@@ -425,7 +433,7 @@ mt76_testmode_dump_stats(struct mt76_dev *dev, struct sk_buff *msg) ...@@ -425,7 +433,7 @@ mt76_testmode_dump_stats(struct mt76_dev *dev, struct sk_buff *msg)
return -EMSGSIZE; return -EMSGSIZE;
if (dev->test_ops->dump_stats) if (dev->test_ops->dump_stats)
return dev->test_ops->dump_stats(dev, msg); return dev->test_ops->dump_stats(phy, msg);
return 0; return 0;
} }
...@@ -435,7 +443,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, ...@@ -435,7 +443,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
{ {
struct mt76_phy *phy = hw->priv; struct mt76_phy *phy = hw->priv;
struct mt76_dev *dev = phy->dev; 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] = {}; struct nlattr *tb[NUM_MT76_TM_ATTRS] = {};
int err = 0; int err = 0;
void *a; void *a;
...@@ -461,14 +469,14 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, ...@@ -461,14 +469,14 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg,
a = nla_nest_start(msg, MT76_TM_ATTR_STATS); a = nla_nest_start(msg, MT76_TM_ATTR_STATS);
if (a) { if (a) {
err = mt76_testmode_dump_stats(dev, msg); err = mt76_testmode_dump_stats(phy, msg);
nla_nest_end(msg, a); nla_nest_end(msg, a);
} }
goto out; goto out;
} }
mt76_testmode_init_defaults(dev); mt76_testmode_init_defaults(phy);
err = -EMSGSIZE; err = -EMSGSIZE;
if (nla_put_u32(msg, MT76_TM_ATTR_STATE, td->state)) if (nla_put_u32(msg, MT76_TM_ATTR_STATE, td->state))
......
...@@ -202,16 +202,22 @@ void mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff *sk ...@@ -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 ieee80211_hw *hw;
struct sk_buff_head list; struct sk_buff_head list;
mt76_tx_check_non_aql(dev, wcid_idx, skb);
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
if (skb == dev->test.tx_skb) { if (mt76_is_testmode_skb(dev, skb, &hw)) {
dev->test.tx_done++; struct mt76_phy *phy = hw->priv;
if (dev->test.tx_queued == dev->test.tx_done)
if (skb == phy->test.tx_skb)
phy->test.tx_done++;
if (phy->test.tx_queued == phy->test.tx_done)
wake_up(&dev->tx_wait); wake_up(&dev->tx_wait);
ieee80211_free_txskb(hw, skb);
return;
} }
#endif #endif
mt76_tx_check_non_aql(dev, wcid_idx, skb);
if (!skb->prev) { if (!skb->prev) {
hw = mt76_tx_status_get_hw(dev, skb); hw = mt76_tx_status_get_hw(dev, skb);
ieee80211_free_txskb(hw, skb); ieee80211_free_txskb(hw, skb);
...@@ -261,7 +267,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, ...@@ -261,7 +267,7 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta,
int qid = skb_get_queue_mapping(skb); int qid = skb_get_queue_mapping(skb);
bool ext_phy = phy != &dev->phy; bool ext_phy = phy != &dev->phy;
if (mt76_testmode_enabled(dev)) { if (mt76_testmode_enabled(phy)) {
ieee80211_free_txskb(phy->hw, skb); ieee80211_free_txskb(phy->hw, skb);
return; return;
} }
...@@ -539,8 +545,10 @@ void mt76_tx_worker(struct mt76_worker *w) ...@@ -539,8 +545,10 @@ void mt76_tx_worker(struct mt76_worker *w)
mt76_txq_schedule_all(dev->phy2); mt76_txq_schedule_all(dev->phy2);
#ifdef CONFIG_NL80211_TESTMODE #ifdef CONFIG_NL80211_TESTMODE
if (dev->test.tx_pending) if (dev->phy.test.tx_pending)
mt76_testmode_tx_pending(dev); mt76_testmode_tx_pending(&dev->phy);
if (dev->phy2 && dev->phy2->test.tx_pending)
mt76_testmode_tx_pending(dev->phy2);
#endif #endif
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment