Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7615/pci_init.c
48525 views
// SPDX-License-Identifier: ISC1/* Copyright (C) 2019 MediaTek Inc.2*3* Author: Roy Luo <[email protected]>4* Ryder Lee <[email protected]>5* Felix Fietkau <[email protected]>6* Lorenzo Bianconi <[email protected]>7*/89#include <linux/etherdevice.h>10#if defined(__FreeBSD__)11#include <linux/delay.h>12#endif13#include "mt7615.h"14#include "mac.h"15#include "eeprom.h"1617static void mt7615_pci_init_work(struct work_struct *work)18{19struct mt7615_dev *dev = container_of(work, struct mt7615_dev,20mcu_work);21int i, ret;2223ret = mt7615_mcu_init(dev);24for (i = 0; (ret == -EAGAIN) && (i < 10); i++) {25msleep(200);26ret = mt7615_mcu_init(dev);27}2829if (ret)30return;3132mt7615_init_work(dev);33}3435static int mt7615_init_hardware(struct mt7615_dev *dev)36{37u32 addr = mt7615_reg_map(dev, MT_EFUSE_BASE);38int ret, idx;3940mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);4142INIT_WORK(&dev->mcu_work, mt7615_pci_init_work);43ret = mt7615_eeprom_init(dev, addr);44if (ret < 0)45return ret;4647if (is_mt7663(&dev->mt76)) {48/* Reset RGU */49mt76_clear(dev, MT_MCU_CIRQ_IRQ_SEL(4), BIT(1));50mt76_set(dev, MT_MCU_CIRQ_IRQ_SEL(4), BIT(1));51}5253ret = mt7615_dma_init(dev);54if (ret)55return ret;5657set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);5859/* Beacon and mgmt frames should occupy wcid 0 */60idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);61if (idx)62return -ENOSPC;6364dev->mt76.global_wcid.idx = idx;65dev->mt76.global_wcid.hw_key_idx = -1;66rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);6768return 0;69}7071int mt7615_register_device(struct mt7615_dev *dev)72{73int ret;7475mt7615_init_device(dev);76INIT_WORK(&dev->reset_work, mt7615_mac_reset_work);7778/* init led callbacks */79if (IS_ENABLED(CONFIG_MT76_LEDS)) {80dev->mphy.leds.cdev.brightness_set = mt7615_led_set_brightness;81dev->mphy.leds.cdev.blink_set = mt7615_led_set_blink;82}8384ret = mt7622_wmac_init(dev);85if (ret)86return ret;8788ret = mt7615_init_hardware(dev);89if (ret)90return ret;9192ret = mt76_register_device(&dev->mt76, true, mt76_rates,93ARRAY_SIZE(mt76_rates));94if (ret)95return ret;9697#if defined(__linux__)98ret = mt7615_thermal_init(dev);99if (ret)100return ret;101#endif102103ieee80211_queue_work(mt76_hw(dev), &dev->mcu_work);104mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);105mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);106107if (dev->dbdc_support) {108ret = mt7615_register_ext_phy(dev);109if (ret)110return ret;111}112113#if defined(CONFIG_MT7615_DEBUGFS)114return mt7615_init_debugfs(dev);115#else116return 0;117#endif118}119120void mt7615_unregister_device(struct mt7615_dev *dev)121{122bool mcu_running;123124mcu_running = mt7615_wait_for_mcu_init(dev);125126mt7615_unregister_ext_phy(dev);127mt76_unregister_device(&dev->mt76);128if (mcu_running)129mt7615_mcu_exit(dev);130131mt7615_tx_token_put(dev);132mt7615_dma_cleanup(dev);133tasklet_disable(&dev->mt76.irq_tasklet);134135mt76_free_device(&dev->mt76);136}137138139