109 lines
2.4 KiB
C
109 lines
2.4 KiB
C
|
// SPDX-License-Identifier: ISC
|
||
|
/*
|
||
|
* Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
|
||
|
* Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
|
||
|
*/
|
||
|
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/firmware.h>
|
||
|
#include <linux/delay.h>
|
||
|
|
||
|
#include "mt76x2.h"
|
||
|
#include "mcu.h"
|
||
|
#include "eeprom.h"
|
||
|
|
||
|
int mt76x2_mcu_set_channel(struct mt76x02_dev *dev, u8 channel, u8 bw,
|
||
|
u8 bw_index, bool scan)
|
||
|
{
|
||
|
struct {
|
||
|
u8 idx;
|
||
|
u8 scan;
|
||
|
u8 bw;
|
||
|
u8 _pad0;
|
||
|
|
||
|
__le16 chainmask;
|
||
|
u8 ext_chan;
|
||
|
u8 _pad1;
|
||
|
|
||
|
} __packed __aligned(4) msg = {
|
||
|
.idx = channel,
|
||
|
.scan = scan,
|
||
|
.bw = bw,
|
||
|
.chainmask = cpu_to_le16(dev->mphy.chainmask),
|
||
|
};
|
||
|
|
||
|
/* first set the channel without the extension channel info */
|
||
|
mt76_mcu_send_msg(&dev->mt76, CMD_SWITCH_CHANNEL_OP, &msg,
|
||
|
sizeof(msg), true);
|
||
|
|
||
|
usleep_range(5000, 10000);
|
||
|
|
||
|
msg.ext_chan = 0xe0 + bw_index;
|
||
|
return mt76_mcu_send_msg(&dev->mt76, CMD_SWITCH_CHANNEL_OP, &msg,
|
||
|
sizeof(msg), true);
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel);
|
||
|
|
||
|
int mt76x2_mcu_load_cr(struct mt76x02_dev *dev, u8 type, u8 temp_level,
|
||
|
u8 channel)
|
||
|
{
|
||
|
struct {
|
||
|
u8 cr_mode;
|
||
|
u8 temp;
|
||
|
u8 ch;
|
||
|
u8 _pad0;
|
||
|
|
||
|
__le32 cfg;
|
||
|
} __packed __aligned(4) msg = {
|
||
|
.cr_mode = type,
|
||
|
.temp = temp_level,
|
||
|
.ch = channel,
|
||
|
};
|
||
|
u32 val;
|
||
|
|
||
|
val = BIT(31);
|
||
|
val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff;
|
||
|
val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00;
|
||
|
msg.cfg = cpu_to_le32(val);
|
||
|
|
||
|
/* first set the channel without the extension channel info */
|
||
|
return mt76_mcu_send_msg(&dev->mt76, CMD_LOAD_CR, &msg, sizeof(msg),
|
||
|
true);
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(mt76x2_mcu_load_cr);
|
||
|
|
||
|
int mt76x2_mcu_init_gain(struct mt76x02_dev *dev, u8 channel, u32 gain,
|
||
|
bool force)
|
||
|
{
|
||
|
struct {
|
||
|
__le32 channel;
|
||
|
__le32 gain_val;
|
||
|
} __packed __aligned(4) msg = {
|
||
|
.channel = cpu_to_le32(channel),
|
||
|
.gain_val = cpu_to_le32(gain),
|
||
|
};
|
||
|
|
||
|
if (force)
|
||
|
msg.channel |= cpu_to_le32(BIT(31));
|
||
|
|
||
|
return mt76_mcu_send_msg(&dev->mt76, CMD_INIT_GAIN_OP, &msg,
|
||
|
sizeof(msg), true);
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(mt76x2_mcu_init_gain);
|
||
|
|
||
|
int mt76x2_mcu_tssi_comp(struct mt76x02_dev *dev,
|
||
|
struct mt76x2_tssi_comp *tssi_data)
|
||
|
{
|
||
|
struct {
|
||
|
__le32 id;
|
||
|
struct mt76x2_tssi_comp data;
|
||
|
} __packed __aligned(4) msg = {
|
||
|
.id = cpu_to_le32(MCU_CAL_TSSI_COMP),
|
||
|
.data = *tssi_data,
|
||
|
};
|
||
|
|
||
|
return mt76_mcu_send_msg(&dev->mt76, CMD_CALIBRATION_OP, &msg,
|
||
|
sizeof(msg), true);
|
||
|
}
|
||
|
EXPORT_SYMBOL_GPL(mt76x2_mcu_tssi_comp);
|