cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pci_init.c (4250B)


      1// SPDX-License-Identifier: ISC
      2/* Copyright (C) 2019 MediaTek Inc.
      3 *
      4 * Author: Roy Luo <royluo@google.com>
      5 *         Ryder Lee <ryder.lee@mediatek.com>
      6 *         Felix Fietkau <nbd@nbd.name>
      7 *         Lorenzo Bianconi <lorenzo@kernel.org>
      8 */
      9
     10#include <linux/etherdevice.h>
     11#include "mt7615.h"
     12#include "mac.h"
     13#include "eeprom.h"
     14
     15static void mt7615_pci_init_work(struct work_struct *work)
     16{
     17	struct mt7615_dev *dev = container_of(work, struct mt7615_dev,
     18					      mcu_work);
     19	int i, ret;
     20
     21	ret = mt7615_mcu_init(dev);
     22	for (i = 0; (ret == -EAGAIN) && (i < 10); i++) {
     23		msleep(200);
     24		ret = mt7615_mcu_init(dev);
     25	}
     26
     27	if (ret)
     28		return;
     29
     30	mt7615_init_work(dev);
     31}
     32
     33static int mt7615_init_hardware(struct mt7615_dev *dev)
     34{
     35	u32 addr = mt7615_reg_map(dev, MT_EFUSE_BASE);
     36	int ret, idx;
     37
     38	mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
     39
     40	INIT_WORK(&dev->mcu_work, mt7615_pci_init_work);
     41	ret = mt7615_eeprom_init(dev, addr);
     42	if (ret < 0)
     43		return ret;
     44
     45	if (is_mt7663(&dev->mt76)) {
     46		/* Reset RGU */
     47		mt76_clear(dev, MT_MCU_CIRQ_IRQ_SEL(4), BIT(1));
     48		mt76_set(dev, MT_MCU_CIRQ_IRQ_SEL(4), BIT(1));
     49	}
     50
     51	ret = mt7615_dma_init(dev);
     52	if (ret)
     53		return ret;
     54
     55	set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
     56
     57	/* Beacon and mgmt frames should occupy wcid 0 */
     58	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1);
     59	if (idx)
     60		return -ENOSPC;
     61
     62	dev->mt76.global_wcid.idx = idx;
     63	dev->mt76.global_wcid.hw_key_idx = -1;
     64	rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
     65
     66	return 0;
     67}
     68
     69static void
     70mt7615_led_set_config(struct led_classdev *led_cdev,
     71		      u8 delay_on, u8 delay_off)
     72{
     73	struct mt7615_dev *dev;
     74	struct mt76_dev *mt76;
     75	u32 val, addr;
     76
     77	mt76 = container_of(led_cdev, struct mt76_dev, led_cdev);
     78	dev = container_of(mt76, struct mt7615_dev, mt76);
     79
     80	if (!mt76_connac_pm_ref(&dev->mphy, &dev->pm))
     81		return;
     82
     83	val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
     84	      FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
     85	      FIELD_PREP(MT_LED_STATUS_ON, delay_on);
     86
     87	addr = mt7615_reg_map(dev, MT_LED_STATUS_0(mt76->led_pin));
     88	mt76_wr(dev, addr, val);
     89	addr = mt7615_reg_map(dev, MT_LED_STATUS_1(mt76->led_pin));
     90	mt76_wr(dev, addr, val);
     91
     92	val = MT_LED_CTRL_REPLAY(mt76->led_pin) |
     93	      MT_LED_CTRL_KICK(mt76->led_pin);
     94	if (mt76->led_al)
     95		val |= MT_LED_CTRL_POLARITY(mt76->led_pin);
     96	addr = mt7615_reg_map(dev, MT_LED_CTRL);
     97	mt76_wr(dev, addr, val);
     98
     99	mt76_connac_pm_unref(&dev->mphy, &dev->pm);
    100}
    101
    102static int
    103mt7615_led_set_blink(struct led_classdev *led_cdev,
    104		     unsigned long *delay_on,
    105		     unsigned long *delay_off)
    106{
    107	u8 delta_on, delta_off;
    108
    109	delta_off = max_t(u8, *delay_off / 10, 1);
    110	delta_on = max_t(u8, *delay_on / 10, 1);
    111
    112	mt7615_led_set_config(led_cdev, delta_on, delta_off);
    113
    114	return 0;
    115}
    116
    117static void
    118mt7615_led_set_brightness(struct led_classdev *led_cdev,
    119			  enum led_brightness brightness)
    120{
    121	if (!brightness)
    122		mt7615_led_set_config(led_cdev, 0, 0xff);
    123	else
    124		mt7615_led_set_config(led_cdev, 0xff, 0);
    125}
    126
    127int mt7615_register_device(struct mt7615_dev *dev)
    128{
    129	int ret;
    130
    131	mt7615_init_device(dev);
    132	INIT_WORK(&dev->reset_work, mt7615_mac_reset_work);
    133
    134	/* init led callbacks */
    135	if (IS_ENABLED(CONFIG_MT76_LEDS)) {
    136		dev->mt76.led_cdev.brightness_set = mt7615_led_set_brightness;
    137		dev->mt76.led_cdev.blink_set = mt7615_led_set_blink;
    138	}
    139
    140	ret = mt7622_wmac_init(dev);
    141	if (ret)
    142		return ret;
    143
    144	ret = mt7615_init_hardware(dev);
    145	if (ret)
    146		return ret;
    147
    148	ret = mt76_register_device(&dev->mt76, true, mt76_rates,
    149				   ARRAY_SIZE(mt76_rates));
    150	if (ret)
    151		return ret;
    152
    153	ret = mt7615_thermal_init(dev);
    154	if (ret)
    155		return ret;
    156
    157	ieee80211_queue_work(mt76_hw(dev), &dev->mcu_work);
    158	mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);
    159	mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);
    160
    161	if (dev->dbdc_support) {
    162		ret = mt7615_register_ext_phy(dev);
    163		if (ret)
    164			return ret;
    165	}
    166
    167	return mt7615_init_debugfs(dev);
    168}
    169
    170void mt7615_unregister_device(struct mt7615_dev *dev)
    171{
    172	bool mcu_running;
    173
    174	mcu_running = mt7615_wait_for_mcu_init(dev);
    175
    176	mt7615_unregister_ext_phy(dev);
    177	mt76_unregister_device(&dev->mt76);
    178	if (mcu_running)
    179		mt7615_mcu_exit(dev);
    180
    181	mt7615_tx_token_put(dev);
    182	mt7615_dma_cleanup(dev);
    183	tasklet_disable(&dev->irq_tasklet);
    184
    185	mt76_free_device(&dev->mt76);
    186}