int mt76_mcu_load_cr(struct mt76_dev *dev, u8 type, u8 temp_level, u8 channel) { struct sk_buff *skb; 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 |= (mt76_eeprom_get(dev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff; val |= (mt76_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 */ skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); return mt76_mcu_msg_send(dev, skb, CMD_LOAD_CR); }
int mt76_mcu_function_select(struct mt76_dev *dev, enum mcu_function func, u32 val) { struct sk_buff *skb; struct { __le32 id; __le32 value; } __packed __aligned(4) msg = { .id = cpu_to_le32(func), .value = cpu_to_le32(val), }; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); return mt76_mcu_msg_send(dev, skb, CMD_FUN_SET_OP); }
int mt76_mcu_set_channel(struct mt76_dev *dev, u8 channel, u8 bw, u8 bw_index, bool scan) { struct sk_buff *skb; 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->chainmask), }; /* first set the channel without the extension channel info */ skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); mt76_mcu_msg_send(dev, skb, CMD_SWITCH_CHANNEL_OP); msleep(5); msg.ext_chan = 0xe0 + bw_index; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); return mt76_mcu_msg_send(dev, skb, CMD_SWITCH_CHANNEL_OP); } int mt76_mcu_set_radio_state(struct mt76_dev *dev, bool on) { struct sk_buff *skb; struct { __le32 mode; __le32 level; } __packed __aligned(4) msg = { .mode = cpu_to_le32(on ? RADIO_ON : RADIO_OFF), .level = cpu_to_le32(0), }; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); return mt76_mcu_msg_send(dev, skb, CMD_POWER_SAVING_OP); } int mt76_mcu_calibrate(struct mt76_dev *dev, enum mcu_calibration type, u32 param) { struct sk_buff *skb; struct { __le32 id; __le32 value; } __packed __aligned(4) msg = { .id = cpu_to_le32(type), .value = cpu_to_le32(param), }; int ret; mt76_clear(dev, MT_MCU_COM_REG0, BIT(31)); skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); ret = mt76_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP); if (ret) return ret; if (WARN_ON(!mt76_poll_msec(dev, MT_MCU_COM_REG0, BIT(31), BIT(31), 100))) return -ETIMEDOUT; return 0; } int mt76_mcu_tssi_comp(struct mt76_dev *dev, struct mt76_tssi_comp *tssi_data) { struct sk_buff *skb; struct { __le32 id; struct mt76_tssi_comp data; } __packed __aligned(4) msg = { .id = cpu_to_le32(MCU_CAL_TSSI_COMP), .data = *tssi_data, }; skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); return mt76_mcu_msg_send(dev, skb, CMD_CALIBRATION_OP); } int mt76_mcu_init_gain(struct mt76_dev *dev, u8 channel, u32 gain, bool force) { struct sk_buff *skb; 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)); skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg)); return mt76_mcu_msg_send(dev, skb, CMD_INIT_GAIN_OP); } int mt76_mcu_init(struct mt76_dev *dev) { int ret; mutex_init(&dev->mcu.mutex); ret = mt76pci_load_rom_patch(dev); if (ret) return ret; ret = mt76pci_load_firmware(dev); if (ret) return ret; mt76_mcu_function_select(dev, Q_SELECT, 1); return 0; } int mt76_mcu_cleanup(struct mt76_dev *dev) { mt76_wr(dev, MT_MCU_INT_LEVEL, 1); msleep(20); return 0; }