Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
0004  * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
0005  */
0006 
0007 #include <linux/kernel.h>
0008 #include <linux/firmware.h>
0009 #include <linux/delay.h>
0010 
0011 #include "mt76x2.h"
0012 #include "mcu.h"
0013 #include "eeprom.h"
0014 
0015 int mt76x2_mcu_set_channel(struct mt76x02_dev *dev, u8 channel, u8 bw,
0016                u8 bw_index, bool scan)
0017 {
0018     struct {
0019         u8 idx;
0020         u8 scan;
0021         u8 bw;
0022         u8 _pad0;
0023 
0024         __le16 chainmask;
0025         u8 ext_chan;
0026         u8 _pad1;
0027 
0028     } __packed __aligned(4) msg = {
0029         .idx = channel,
0030         .scan = scan,
0031         .bw = bw,
0032         .chainmask = cpu_to_le16(dev->mphy.chainmask),
0033     };
0034 
0035     /* first set the channel without the extension channel info */
0036     mt76_mcu_send_msg(&dev->mt76, CMD_SWITCH_CHANNEL_OP, &msg,
0037               sizeof(msg), true);
0038 
0039     usleep_range(5000, 10000);
0040 
0041     msg.ext_chan = 0xe0 + bw_index;
0042     return mt76_mcu_send_msg(&dev->mt76, CMD_SWITCH_CHANNEL_OP, &msg,
0043                  sizeof(msg), true);
0044 }
0045 EXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel);
0046 
0047 int mt76x2_mcu_load_cr(struct mt76x02_dev *dev, u8 type, u8 temp_level,
0048                u8 channel)
0049 {
0050     struct {
0051         u8 cr_mode;
0052         u8 temp;
0053         u8 ch;
0054         u8 _pad0;
0055 
0056         __le32 cfg;
0057     } __packed __aligned(4) msg = {
0058         .cr_mode = type,
0059         .temp = temp_level,
0060         .ch = channel,
0061     };
0062     u32 val;
0063 
0064     val = BIT(31);
0065     val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff;
0066     val |= (mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1) << 8) & 0xff00;
0067     msg.cfg = cpu_to_le32(val);
0068 
0069     /* first set the channel without the extension channel info */
0070     return mt76_mcu_send_msg(&dev->mt76, CMD_LOAD_CR, &msg, sizeof(msg),
0071                  true);
0072 }
0073 EXPORT_SYMBOL_GPL(mt76x2_mcu_load_cr);
0074 
0075 int mt76x2_mcu_init_gain(struct mt76x02_dev *dev, u8 channel, u32 gain,
0076              bool force)
0077 {
0078     struct {
0079         __le32 channel;
0080         __le32 gain_val;
0081     } __packed __aligned(4) msg = {
0082         .channel = cpu_to_le32(channel),
0083         .gain_val = cpu_to_le32(gain),
0084     };
0085 
0086     if (force)
0087         msg.channel |= cpu_to_le32(BIT(31));
0088 
0089     return mt76_mcu_send_msg(&dev->mt76, CMD_INIT_GAIN_OP, &msg,
0090                  sizeof(msg), true);
0091 }
0092 EXPORT_SYMBOL_GPL(mt76x2_mcu_init_gain);
0093 
0094 int mt76x2_mcu_tssi_comp(struct mt76x02_dev *dev,
0095              struct mt76x2_tssi_comp *tssi_data)
0096 {
0097     struct {
0098         __le32 id;
0099         struct mt76x2_tssi_comp data;
0100     } __packed __aligned(4) msg = {
0101         .id = cpu_to_le32(MCU_CAL_TSSI_COMP),
0102         .data = *tssi_data,
0103     };
0104 
0105     return mt76_mcu_send_msg(&dev->mt76, CMD_CALIBRATION_OP, &msg,
0106                  sizeof(msg), true);
0107 }
0108 EXPORT_SYMBOL_GPL(mt76x2_mcu_tssi_comp);