18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: ISC 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 48c2ecf20Sopenharmony_ci * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/kernel.h> 88c2ecf20Sopenharmony_ci#include <linux/firmware.h> 98c2ecf20Sopenharmony_ci#include <linux/delay.h> 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "mt76x2.h" 128c2ecf20Sopenharmony_ci#include "mcu.h" 138c2ecf20Sopenharmony_ci#include "eeprom.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ciint mt76x2_mcu_set_channel(struct mt76x02_dev *dev, u8 channel, u8 bw, 168c2ecf20Sopenharmony_ci u8 bw_index, bool scan) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci struct { 198c2ecf20Sopenharmony_ci u8 idx; 208c2ecf20Sopenharmony_ci u8 scan; 218c2ecf20Sopenharmony_ci u8 bw; 228c2ecf20Sopenharmony_ci u8 _pad0; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci __le16 chainmask; 258c2ecf20Sopenharmony_ci u8 ext_chan; 268c2ecf20Sopenharmony_ci u8 _pad1; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci } __packed __aligned(4) msg = { 298c2ecf20Sopenharmony_ci .idx = channel, 308c2ecf20Sopenharmony_ci .scan = scan, 318c2ecf20Sopenharmony_ci .bw = bw, 328c2ecf20Sopenharmony_ci .chainmask = cpu_to_le16(dev->chainmask), 338c2ecf20Sopenharmony_ci }; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci /* first set the channel without the extension channel info */ 368c2ecf20Sopenharmony_ci mt76_mcu_send_msg(dev, CMD_SWITCH_CHANNEL_OP, &msg, sizeof(msg), true); 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci usleep_range(5000, 10000); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci msg.ext_chan = 0xe0 + bw_index; 418c2ecf20Sopenharmony_ci return mt76_mcu_send_msg(dev, CMD_SWITCH_CHANNEL_OP, &msg, sizeof(msg), 428c2ecf20Sopenharmony_ci true); 438c2ecf20Sopenharmony_ci} 448c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ciint mt76x2_mcu_load_cr(struct mt76x02_dev *dev, u8 type, u8 temp_level, 478c2ecf20Sopenharmony_ci u8 channel) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci struct { 508c2ecf20Sopenharmony_ci u8 cr_mode; 518c2ecf20Sopenharmony_ci u8 temp; 528c2ecf20Sopenharmony_ci u8 ch; 538c2ecf20Sopenharmony_ci u8 _pad0; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci __le32 cfg; 568c2ecf20Sopenharmony_ci } __packed __aligned(4) msg = { 578c2ecf20Sopenharmony_ci .cr_mode = type, 588c2ecf20Sopenharmony_ci .temp = temp_level, 598c2ecf20Sopenharmony_ci .ch = channel, 608c2ecf20Sopenharmony_ci }; 618c2ecf20Sopenharmony_ci u32 val; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci val = BIT(31); 648c2ecf20Sopenharmony_ci val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff; 658c2ecf20Sopenharmony_ci val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00; 668c2ecf20Sopenharmony_ci msg.cfg = cpu_to_le32(val); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci /* first set the channel without the extension channel info */ 698c2ecf20Sopenharmony_ci return mt76_mcu_send_msg(dev, CMD_LOAD_CR, &msg, sizeof(msg), true); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76x2_mcu_load_cr); 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ciint mt76x2_mcu_init_gain(struct mt76x02_dev *dev, u8 channel, u32 gain, 748c2ecf20Sopenharmony_ci bool force) 758c2ecf20Sopenharmony_ci{ 768c2ecf20Sopenharmony_ci struct { 778c2ecf20Sopenharmony_ci __le32 channel; 788c2ecf20Sopenharmony_ci __le32 gain_val; 798c2ecf20Sopenharmony_ci } __packed __aligned(4) msg = { 808c2ecf20Sopenharmony_ci .channel = cpu_to_le32(channel), 818c2ecf20Sopenharmony_ci .gain_val = cpu_to_le32(gain), 828c2ecf20Sopenharmony_ci }; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci if (force) 858c2ecf20Sopenharmony_ci msg.channel |= cpu_to_le32(BIT(31)); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci return mt76_mcu_send_msg(dev, CMD_INIT_GAIN_OP, &msg, sizeof(msg), 888c2ecf20Sopenharmony_ci true); 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76x2_mcu_init_gain); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ciint mt76x2_mcu_tssi_comp(struct mt76x02_dev *dev, 938c2ecf20Sopenharmony_ci struct mt76x2_tssi_comp *tssi_data) 948c2ecf20Sopenharmony_ci{ 958c2ecf20Sopenharmony_ci struct { 968c2ecf20Sopenharmony_ci __le32 id; 978c2ecf20Sopenharmony_ci struct mt76x2_tssi_comp data; 988c2ecf20Sopenharmony_ci } __packed __aligned(4) msg = { 998c2ecf20Sopenharmony_ci .id = cpu_to_le32(MCU_CAL_TSSI_COMP), 1008c2ecf20Sopenharmony_ci .data = *tssi_data, 1018c2ecf20Sopenharmony_ci }; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci return mt76_mcu_send_msg(dev, CMD_CALIBRATION_OP, &msg, sizeof(msg), 1048c2ecf20Sopenharmony_ci true); 1058c2ecf20Sopenharmony_ci} 1068c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76x2_mcu_tssi_comp); 107