1// SPDX-License-Identifier: ISC
2/*
3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
5 */
6
7#include <linux/kernel.h>
8#include <linux/firmware.h>
9#include <linux/delay.h>
10
11#include "mt76x2.h"
12#include "mcu.h"
13#include "eeprom.h"
14
15int mt76x2_mcu_set_channel(struct mt76x02_dev *dev, u8 channel, u8 bw,
16			   u8 bw_index, bool scan)
17{
18	struct {
19		u8 idx;
20		u8 scan;
21		u8 bw;
22		u8 _pad0;
23
24		__le16 chainmask;
25		u8 ext_chan;
26		u8 _pad1;
27
28	} __packed __aligned(4) msg = {
29		.idx = channel,
30		.scan = scan,
31		.bw = bw,
32		.chainmask = cpu_to_le16(dev->chainmask),
33	};
34
35	/* first set the channel without the extension channel info */
36	mt76_mcu_send_msg(dev, CMD_SWITCH_CHANNEL_OP, &msg, sizeof(msg), true);
37
38	usleep_range(5000, 10000);
39
40	msg.ext_chan = 0xe0 + bw_index;
41	return mt76_mcu_send_msg(dev, CMD_SWITCH_CHANNEL_OP, &msg, sizeof(msg),
42				 true);
43}
44EXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel);
45
46int mt76x2_mcu_load_cr(struct mt76x02_dev *dev, u8 type, u8 temp_level,
47		       u8 channel)
48{
49	struct {
50		u8 cr_mode;
51		u8 temp;
52		u8 ch;
53		u8 _pad0;
54
55		__le32 cfg;
56	} __packed __aligned(4) msg = {
57		.cr_mode = type,
58		.temp = temp_level,
59		.ch = channel,
60	};
61	u32 val;
62
63	val = BIT(31);
64	val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff;
65	val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00;
66	msg.cfg = cpu_to_le32(val);
67
68	/* first set the channel without the extension channel info */
69	return mt76_mcu_send_msg(dev, CMD_LOAD_CR, &msg, sizeof(msg), true);
70}
71EXPORT_SYMBOL_GPL(mt76x2_mcu_load_cr);
72
73int mt76x2_mcu_init_gain(struct mt76x02_dev *dev, u8 channel, u32 gain,
74			 bool force)
75{
76	struct {
77		__le32 channel;
78		__le32 gain_val;
79	} __packed __aligned(4) msg = {
80		.channel = cpu_to_le32(channel),
81		.gain_val = cpu_to_le32(gain),
82	};
83
84	if (force)
85		msg.channel |= cpu_to_le32(BIT(31));
86
87	return mt76_mcu_send_msg(dev, CMD_INIT_GAIN_OP, &msg, sizeof(msg),
88				 true);
89}
90EXPORT_SYMBOL_GPL(mt76x2_mcu_init_gain);
91
92int mt76x2_mcu_tssi_comp(struct mt76x02_dev *dev,
93			 struct mt76x2_tssi_comp *tssi_data)
94{
95	struct {
96		__le32 id;
97		struct mt76x2_tssi_comp data;
98	} __packed __aligned(4) msg = {
99		.id = cpu_to_le32(MCU_CAL_TSSI_COMP),
100		.data = *tssi_data,
101	};
102
103	return mt76_mcu_send_msg(dev, CMD_CALIBRATION_OP, &msg, sizeof(msg),
104				 true);
105}
106EXPORT_SYMBOL_GPL(mt76x2_mcu_tssi_comp);
107