1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2020 MediaTek Inc. */
11 TM_CHANGED_FREQ_OFFSET
,
17 static const u8 tm_change_map
[] = {
18 [TM_CHANGED_TXPOWER
] = MT76_TM_ATTR_TX_POWER
,
19 [TM_CHANGED_FREQ_OFFSET
] = MT76_TM_ATTR_FREQ_OFFSET
,
26 #define REG_BAND(_reg) \
27 { .band[0] = MT_##_reg(0), .band[1] = MT_##_reg(1) }
28 #define REG_BAND_IDX(_reg, _idx) \
29 { .band[0] = MT_##_reg(0, _idx), .band[1] = MT_##_reg(1, _idx) }
31 static const struct reg_band reg_backup_list
[] = {
32 REG_BAND_IDX(AGG_PCR0
, 0),
33 REG_BAND_IDX(AGG_PCR0
, 1),
34 REG_BAND_IDX(AGG_AWSCR0
, 0),
35 REG_BAND_IDX(AGG_AWSCR0
, 1),
36 REG_BAND_IDX(AGG_AWSCR0
, 2),
37 REG_BAND_IDX(AGG_AWSCR0
, 3),
45 REG_BAND_IDX(ARB_DRNGR0
, 0),
46 REG_BAND_IDX(ARB_DRNGR0
, 1),
52 mt7915_tm_set_tx_power(struct mt7915_phy
*phy
)
54 struct mt7915_dev
*dev
= phy
->dev
;
55 struct mt76_phy
*mphy
= phy
->mt76
;
56 struct cfg80211_chan_def
*chandef
= &mphy
->chandef
;
57 int freq
= chandef
->center_freq1
;
63 u8 ant_idx
; /* Only 0 is valid */
68 .dbdc_idx
= phy
!= &dev
->phy
,
69 .center_chan
= ieee80211_frequency_to_channel(freq
),
73 if (dev
->mt76
.test
.state
!= MT76_TM_STATE_OFF
)
74 tx_power
= dev
->mt76
.test
.tx_power
;
76 /* Tx power of the other antennas are the same as antenna 0 */
77 if (tx_power
&& tx_power
[0])
78 req
.tx_power
= tx_power
[0];
80 ret
= mt76_mcu_send_msg(&dev
->mt76
,
81 MCU_EXT_CMD_TX_POWER_FEATURE_CTRL
,
82 &req
, sizeof(req
), false);
88 mt7915_tm_set_freq_offset(struct mt7915_dev
*dev
, bool en
, u32 val
)
90 struct mt7915_tm_cmd req
= {
92 .param_idx
= MCU_ATE_SET_FREQ_OFFSET
,
93 .param
.freq
.freq_offset
= cpu_to_le32(val
),
96 return mt76_mcu_send_msg(&dev
->mt76
, MCU_EXT_CMD_ATE_CTRL
, &req
,
101 mt7915_tm_mode_ctrl(struct mt7915_dev
*dev
, bool enable
)
112 return mt76_mcu_send_msg(&dev
->mt76
,
113 MCU_EXT_CMD_TX_POWER_FEATURE_CTRL
,
114 &req
, sizeof(req
), false);
118 mt7915_tm_set_trx(struct mt7915_dev
*dev
, struct mt7915_phy
*phy
,
121 struct mt7915_tm_cmd req
= {
123 .param_idx
= MCU_ATE_SET_TRX
,
124 .param
.trx
.type
= type
,
125 .param
.trx
.enable
= en
,
126 .param
.trx
.band
= phy
!= &dev
->phy
,
129 return mt76_mcu_send_msg(&dev
->mt76
, MCU_EXT_CMD_ATE_CTRL
, &req
,
134 mt7915_tm_reg_backup_restore(struct mt7915_dev
*dev
, struct mt7915_phy
*phy
)
136 int n_regs
= ARRAY_SIZE(reg_backup_list
);
137 bool ext_phy
= phy
!= &dev
->phy
;
138 u32
*b
= dev
->test
.reg_backup
;
141 if (dev
->mt76
.test
.state
== MT76_TM_STATE_OFF
) {
142 for (i
= 0; i
< n_regs
; i
++)
143 mt76_wr(dev
, reg_backup_list
[i
].band
[ext_phy
], b
[i
]);
150 b
= devm_kzalloc(dev
->mt76
.dev
, 4 * n_regs
, GFP_KERNEL
);
154 dev
->test
.reg_backup
= b
;
155 for (i
= 0; i
< n_regs
; i
++)
156 b
[i
] = mt76_rr(dev
, reg_backup_list
[i
].band
[ext_phy
]);
158 mt76_clear(dev
, MT_AGG_PCR0(ext_phy
, 0), MT_AGG_PCR0_MM_PROT
|
159 MT_AGG_PCR0_GF_PROT
| MT_AGG_PCR0_ERP_PROT
|
160 MT_AGG_PCR0_VHT_PROT
| MT_AGG_PCR0_BW20_PROT
|
161 MT_AGG_PCR0_BW40_PROT
| MT_AGG_PCR0_BW80_PROT
);
162 mt76_set(dev
, MT_AGG_PCR0(ext_phy
, 0), MT_AGG_PCR0_PTA_WIN_DIS
);
164 mt76_wr(dev
, MT_AGG_PCR0(ext_phy
, 1), MT_AGG_PCR1_RTS0_NUM_THRES
|
165 MT_AGG_PCR1_RTS0_LEN_THRES
);
167 mt76_clear(dev
, MT_AGG_MRCR(ext_phy
), MT_AGG_MRCR_BAR_CNT_LIMIT
|
168 MT_AGG_MRCR_LAST_RTS_CTS_RN
| MT_AGG_MRCR_RTS_FAIL_LIMIT
|
169 MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT
);
171 mt76_rmw(dev
, MT_AGG_MRCR(ext_phy
), MT_AGG_MRCR_RTS_FAIL_LIMIT
|
172 MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT
,
173 FIELD_PREP(MT_AGG_MRCR_RTS_FAIL_LIMIT
, 1) |
174 FIELD_PREP(MT_AGG_MRCR_TXCMD_RTS_FAIL_LIMIT
, 1));
176 mt76_wr(dev
, MT_TMAC_TFCR0(ext_phy
), 0);
177 mt76_clear(dev
, MT_TMAC_TCR0(ext_phy
), MT_TMAC_TCR0_TBTT_STOP_CTRL
);
179 /* config rx filter for testmode rx */
180 mt76_wr(dev
, MT_WF_RFCR(ext_phy
), 0xcf70a);
181 mt76_wr(dev
, MT_WF_RFCR1(ext_phy
), 0);
185 mt7915_tm_init(struct mt7915_dev
*dev
)
187 bool en
= !(dev
->mt76
.test
.state
== MT76_TM_STATE_OFF
);
189 if (!test_bit(MT76_STATE_RUNNING
, &dev
->phy
.mt76
->state
))
192 mt7915_tm_mode_ctrl(dev
, en
);
193 mt7915_tm_reg_backup_restore(dev
, &dev
->phy
);
194 mt7915_tm_set_trx(dev
, &dev
->phy
, TM_MAC_TXRX
, !en
);
198 mt7915_tm_set_tx_frames(struct mt7915_dev
*dev
, bool en
)
200 static const u8 spe_idx_map
[] = {0, 0, 1, 0, 3, 2, 4, 0,
201 9, 8, 6, 10, 16, 12, 18, 0};
202 struct sk_buff
*skb
= dev
->mt76
.test
.tx_skb
;
203 struct ieee80211_tx_info
*info
;
205 mt7915_tm_set_trx(dev
, &dev
->phy
, TM_MAC_RX_RXV
, false);
208 u8 tx_ant
= dev
->mt76
.test
.tx_antenna_mask
;
210 mutex_unlock(&dev
->mt76
.mutex
);
211 mt7915_set_channel(&dev
->phy
);
212 mutex_lock(&dev
->mt76
.mutex
);
214 mt7915_mcu_set_chan_info(&dev
->phy
, MCU_EXT_CMD_SET_RX_PATH
);
215 dev
->test
.spe_idx
= spe_idx_map
[tx_ant
];
218 mt7915_tm_set_trx(dev
, &dev
->phy
, TM_MAC_TX
, en
);
223 info
= IEEE80211_SKB_CB(skb
);
224 info
->control
.vif
= dev
->phy
.monitor_vif
;
228 mt7915_tm_set_rx_frames(struct mt7915_dev
*dev
, bool en
)
231 mutex_unlock(&dev
->mt76
.mutex
);
232 mt7915_set_channel(&dev
->phy
);
233 mutex_lock(&dev
->mt76
.mutex
);
235 mt7915_mcu_set_chan_info(&dev
->phy
, MCU_EXT_CMD_SET_RX_PATH
);
238 mt7915_tm_set_trx(dev
, &dev
->phy
, TM_MAC_RX_RXV
, en
);
242 mt7915_tm_update_params(struct mt7915_dev
*dev
, u32 changed
)
244 struct mt76_testmode_data
*td
= &dev
->mt76
.test
;
245 bool en
= dev
->mt76
.test
.state
!= MT76_TM_STATE_OFF
;
247 if (changed
& BIT(TM_CHANGED_FREQ_OFFSET
))
248 mt7915_tm_set_freq_offset(dev
, en
, en
? td
->freq_offset
: 0);
249 if (changed
& BIT(TM_CHANGED_TXPOWER
))
250 mt7915_tm_set_tx_power(&dev
->phy
);
254 mt7915_tm_set_state(struct mt76_dev
*mdev
, enum mt76_testmode_state state
)
256 struct mt7915_dev
*dev
= container_of(mdev
, struct mt7915_dev
, mt76
);
257 struct mt76_testmode_data
*td
= &mdev
->test
;
258 enum mt76_testmode_state prev_state
= td
->state
;
260 mdev
->test
.state
= state
;
262 if (prev_state
== MT76_TM_STATE_TX_FRAMES
)
263 mt7915_tm_set_tx_frames(dev
, false);
264 else if (state
== MT76_TM_STATE_TX_FRAMES
)
265 mt7915_tm_set_tx_frames(dev
, true);
266 else if (prev_state
== MT76_TM_STATE_RX_FRAMES
)
267 mt7915_tm_set_rx_frames(dev
, false);
268 else if (state
== MT76_TM_STATE_RX_FRAMES
)
269 mt7915_tm_set_rx_frames(dev
, true);
270 else if (prev_state
== MT76_TM_STATE_OFF
|| state
== MT76_TM_STATE_OFF
)
273 if ((state
== MT76_TM_STATE_IDLE
&&
274 prev_state
== MT76_TM_STATE_OFF
) ||
275 (state
== MT76_TM_STATE_OFF
&&
276 prev_state
== MT76_TM_STATE_IDLE
)) {
280 for (i
= 0; i
< ARRAY_SIZE(tm_change_map
); i
++) {
281 u16 cur
= tm_change_map
[i
];
283 if (td
->param_set
[cur
/ 32] & BIT(cur
% 32))
287 mt7915_tm_update_params(dev
, changed
);
294 mt7915_tm_set_params(struct mt76_dev
*mdev
, struct nlattr
**tb
,
295 enum mt76_testmode_state new_state
)
297 struct mt7915_dev
*dev
= container_of(mdev
, struct mt7915_dev
, mt76
);
298 struct mt76_testmode_data
*td
= &dev
->mt76
.test
;
302 BUILD_BUG_ON(NUM_TM_CHANGED
>= 32);
304 if (new_state
== MT76_TM_STATE_OFF
||
305 td
->state
== MT76_TM_STATE_OFF
)
308 if (td
->tx_antenna_mask
& ~dev
->phy
.chainmask
)
311 for (i
= 0; i
< ARRAY_SIZE(tm_change_map
); i
++) {
312 if (tb
[tm_change_map
[i
]])
316 mt7915_tm_update_params(dev
, changed
);
322 mt7915_tm_dump_stats(struct mt76_dev
*mdev
, struct sk_buff
*msg
)
324 struct mt7915_dev
*dev
= container_of(mdev
, struct mt7915_dev
, mt76
);
328 rx
= nla_nest_start(msg
, MT76_TM_STATS_ATTR_LAST_RX
);
332 if (nla_put_s32(msg
, MT76_TM_RX_ATTR_FREQ_OFFSET
, dev
->test
.last_freq_offset
))
335 rssi
= nla_nest_start(msg
, MT76_TM_RX_ATTR_RCPI
);
339 for (i
= 0; i
< ARRAY_SIZE(dev
->test
.last_rcpi
); i
++)
340 if (nla_put_u8(msg
, i
, dev
->test
.last_rcpi
[i
]))
343 nla_nest_end(msg
, rssi
);
345 rssi
= nla_nest_start(msg
, MT76_TM_RX_ATTR_IB_RSSI
);
349 for (i
= 0; i
< ARRAY_SIZE(dev
->test
.last_ib_rssi
); i
++)
350 if (nla_put_s8(msg
, i
, dev
->test
.last_ib_rssi
[i
]))
353 nla_nest_end(msg
, rssi
);
355 rssi
= nla_nest_start(msg
, MT76_TM_RX_ATTR_WB_RSSI
);
359 for (i
= 0; i
< ARRAY_SIZE(dev
->test
.last_wb_rssi
); i
++)
360 if (nla_put_s8(msg
, i
, dev
->test
.last_wb_rssi
[i
]))
363 nla_nest_end(msg
, rssi
);
365 if (nla_put_u8(msg
, MT76_TM_RX_ATTR_SNR
, dev
->test
.last_snr
))
368 nla_nest_end(msg
, rx
);
373 const struct mt76_testmode_ops mt7915_testmode_ops
= {
374 .set_state
= mt7915_tm_set_state
,
375 .set_params
= mt7915_tm_set_params
,
376 .dump_stats
= mt7915_tm_dump_stats
,