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

mt76: mt7915: add support for continuous tx in testmode



Implement continuous tx state for MT7915 NIC testmode.

Signed-off-by: default avatarShayne Chen <shayne.chen@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 39e48823
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3208,7 +3208,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
#ifdef CONFIG_NL80211_TESTMODE
	if (phy->mt76->test.tx_antenna_mask &&
	    (phy->mt76->test.state == MT76_TM_STATE_TX_FRAMES ||
	     phy->mt76->test.state == MT76_TM_STATE_RX_FRAMES)) {
	     phy->mt76->test.state == MT76_TM_STATE_RX_FRAMES ||
	     phy->mt76->test.state == MT76_TM_STATE_TX_CONT)) {
		req.tx_streams_num = fls(phy->mt76->test.tx_antenna_mask);
		req.rx_streams = phy->mt76->test.tx_antenna_mask;

+1 −0
Original line number Diff line number Diff line
@@ -240,6 +240,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,
+148 −11
Original line number Diff line number Diff line
@@ -409,6 +409,16 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en)
	mt7915_mcu_add_bss_info(phy, phy->monitor_vif, en);
}

static void
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)
{
@@ -425,11 +435,7 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
	mt7915_tm_clean_hwq(phy, dev->mt76.global_wcid.idx);

	if (en) {
		mutex_unlock(&dev->mt76.mutex);
		mt7915_set_channel(phy);
		mutex_lock(&dev->mt76.mutex);

		mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
		mt7915_tm_update_channel(phy);

		if (td->tx_spe_idx) {
			phy->test.spe_idx = td->tx_spe_idx;
@@ -468,16 +474,144 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en)
static void
mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en)
{
	if (en)
		mt7915_tm_update_channel(phy);

	mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
}

static int
mt7915_tm_rf_switch_mode(struct mt7915_dev *dev, u32 oper)
{
	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;
	if (en) {
		mutex_unlock(&dev->mt76.mutex);
		mt7915_set_channel(phy);
		mutex_lock(&dev->mt76.mutex);
	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;

		mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH);
	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;
	}

	mt7915_tm_set_trx(phy, TM_MAC_RX_RXV, en);
	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
@@ -507,6 +641,9 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state)
	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));
+40 −0
Original line number Diff line number Diff line
@@ -56,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