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 15 int 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->mt76.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 } 44 EXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel); 45 46 int 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 } 71 EXPORT_SYMBOL_GPL(mt76x2_mcu_load_cr); 72 73 int 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 } 90 EXPORT_SYMBOL_GPL(mt76x2_mcu_init_gain); 91 92 int 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 } 106 EXPORT_SYMBOL_GPL(mt76x2_mcu_tssi_comp); 107