mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	mt76: mt7915: add support for continuous tx in testmode
Implement continuous tx state for MT7915 NIC testmode. Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
		
							parent
							
								
									39e48823e1
								
							
						
					
					
						commit
						3f0caa3cbf
					
				| @ -3208,7 +3208,8 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) | |||||||
| #ifdef CONFIG_NL80211_TESTMODE | #ifdef CONFIG_NL80211_TESTMODE | ||||||
| 	if (phy->mt76->test.tx_antenna_mask && | 	if (phy->mt76->test.tx_antenna_mask && | ||||||
| 	    (phy->mt76->test.state == MT76_TM_STATE_TX_FRAMES || | 	    (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.tx_streams_num = fls(phy->mt76->test.tx_antenna_mask); | ||||||
| 		req.rx_streams = phy->mt76->test.tx_antenna_mask; | 		req.rx_streams = phy->mt76->test.tx_antenna_mask; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -240,6 +240,7 @@ enum { | |||||||
| 
 | 
 | ||||||
| enum { | enum { | ||||||
| 	MCU_EXT_CMD_EFUSE_ACCESS = 0x01, | 	MCU_EXT_CMD_EFUSE_ACCESS = 0x01, | ||||||
|  | 	MCU_EXT_CMD_RF_TEST = 0x04, | ||||||
| 	MCU_EXT_CMD_PM_STATE_CTRL = 0x07, | 	MCU_EXT_CMD_PM_STATE_CTRL = 0x07, | ||||||
| 	MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, | 	MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, | ||||||
| 	MCU_EXT_CMD_FW_LOG_2_HOST = 0x13, | 	MCU_EXT_CMD_FW_LOG_2_HOST = 0x13, | ||||||
|  | |||||||
| @ -409,6 +409,16 @@ mt7915_tm_init(struct mt7915_phy *phy, bool en) | |||||||
| 	mt7915_mcu_add_bss_info(phy, phy->monitor_vif, 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 | static void | ||||||
| mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en) | 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); | 	mt7915_tm_clean_hwq(phy, dev->mt76.global_wcid.idx); | ||||||
| 
 | 
 | ||||||
| 	if (en) { | 	if (en) { | ||||||
| 		mutex_unlock(&dev->mt76.mutex); | 		mt7915_tm_update_channel(phy); | ||||||
| 		mt7915_set_channel(phy); |  | ||||||
| 		mutex_lock(&dev->mt76.mutex); |  | ||||||
| 
 |  | ||||||
| 		mt7915_mcu_set_chan_info(phy, MCU_EXT_CMD_SET_RX_PATH); |  | ||||||
| 
 | 
 | ||||||
| 		if (td->tx_spe_idx) { | 		if (td->tx_spe_idx) { | ||||||
| 			phy->test.spe_idx = td->tx_spe_idx; | 			phy->test.spe_idx = td->tx_spe_idx; | ||||||
| @ -468,18 +474,146 @@ mt7915_tm_set_tx_frames(struct mt7915_phy *phy, bool en) | |||||||
| static void | static void | ||||||
| mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en) | mt7915_tm_set_rx_frames(struct mt7915_phy *phy, bool en) | ||||||
| { | { | ||||||
| 	struct mt7915_dev *dev = phy->dev; | 	if (en) | ||||||
| 	if (en) { | 		mt7915_tm_update_channel(phy); | ||||||
| 		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_set_trx(phy, TM_MAC_RX_RXV, en); | 	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; | ||||||
|  | 	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 | static void | ||||||
| mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed) | mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed) | ||||||
| { | { | ||||||
| @ -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 || | 	else if (prev_state == MT76_TM_STATE_RX_FRAMES || | ||||||
| 		 state == MT76_TM_STATE_RX_FRAMES) | 		 state == MT76_TM_STATE_RX_FRAMES) | ||||||
| 		mt7915_tm_set_rx_frames(phy, 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 || | 	else if (prev_state == MT76_TM_STATE_OFF || | ||||||
| 		 state == MT76_TM_STATE_OFF) | 		 state == MT76_TM_STATE_OFF) | ||||||
| 		mt7915_tm_init(phy, !(state == MT76_TM_STATE_OFF)); | 		mt7915_tm_init(phy, !(state == MT76_TM_STATE_OFF)); | ||||||
|  | |||||||
| @ -56,4 +56,44 @@ enum { | |||||||
| 	TM_MAC_RX_RXV, | 	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 | #endif | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Shayne Chen
						Shayne Chen