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

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
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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->phy.test.mtd_name = devm_kstrdup(dev->dev, part, GFP_KERNEL);
	dev->phy.test.mtd_offset = offset;
#endif

out_put_node:
+3 −3
Original line number Diff line number Diff line
@@ -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);
+31 −12
Original line number Diff line number Diff line
@@ -515,10 +515,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 {
@@ -582,6 +582,10 @@ struct mt76_phy {

	int txpower_cur;
	u8 antenna_mask;

#ifdef CONFIG_NL80211_TESTMODE
	struct mt76_testmode_data test;
#endif
};

struct mt76_dev {
@@ -661,9 +665,7 @@ struct mt76_dev {

#ifdef CONFIG_NL80211_TESTMODE
	const struct mt76_testmode_ops *test_ops;
	struct mt76_testmode_data test;
#endif

	struct workqueue_struct *wq;

	union {
@@ -931,10 +933,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 +1035,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 +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,
			   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);

+9 −9
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ static void mt7615_stop(struct ieee80211_hw *hw)

	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);
@@ -181,7 +181,7 @@ 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))
@@ -252,7 +252,7 @@ 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;

@@ -321,7 +321,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, !mt76_testmode_enabled(phy->mt76));

	mt7615_mac_reset_counters(dev);
	phy->noise = 0;
@@ -334,7 +334,7 @@ int mt7615_set_channel(struct mt7615_phy *phy)

	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,
					     MT7615_WATCHDOG_TIME);

@@ -411,9 +411,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 +425,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;
@@ -480,7 +480,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)

Loading