int mt76x2_mcu_init(struct mt76x02_dev *dev) { static const struct mt76_mcu_ops mt76x2_mcu_ops = { .mcu_send_msg = mt76x02_mcu_msg_send, }; int ret; dev->mt76.mcu_ops = &mt76x2_mcu_ops; ret = mt76pci_load_rom_patch(dev); if (ret) return ret; ret = mt76pci_load_firmware(dev); if (ret) return ret; mt76x02_mcu_function_select(dev, Q_SELECT, 1); return 0; }
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; }