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

sdio_mac.c (3484B)


      1// SPDX-License-Identifier: ISC
      2/* Copyright (C) 2021 MediaTek Inc. */
      3
      4#include <linux/iopoll.h>
      5#include <linux/mmc/sdio_func.h>
      6#include "mt7921.h"
      7#include "mac.h"
      8#include "../sdio.h"
      9
     10static void mt7921s_enable_irq(struct mt76_dev *dev)
     11{
     12	struct mt76_sdio *sdio = &dev->sdio;
     13
     14	sdio_claim_host(sdio->func);
     15	sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
     16	sdio_release_host(sdio->func);
     17}
     18
     19static void mt7921s_disable_irq(struct mt76_dev *dev)
     20{
     21	struct mt76_sdio *sdio = &dev->sdio;
     22
     23	sdio_claim_host(sdio->func);
     24	sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
     25	sdio_release_host(sdio->func);
     26}
     27
     28static u32 mt7921s_read_whcr(struct mt76_dev *dev)
     29{
     30	return sdio_readl(dev->sdio.func, MCR_WHCR, NULL);
     31}
     32
     33int mt7921s_wfsys_reset(struct mt7921_dev *dev)
     34{
     35	struct mt76_sdio *sdio = &dev->mt76.sdio;
     36	u32 val, status;
     37
     38	mt7921s_mcu_drv_pmctrl(dev);
     39
     40	sdio_claim_host(sdio->func);
     41
     42	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
     43	val &= ~WF_WHOLE_PATH_RSTB;
     44	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
     45
     46	msleep(50);
     47
     48	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
     49	val &= ~WF_SDIO_WF_PATH_RSTB;
     50	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
     51
     52	usleep_range(1000, 2000);
     53
     54	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
     55	val |= WF_WHOLE_PATH_RSTB;
     56	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
     57
     58	readx_poll_timeout(mt7921s_read_whcr, &dev->mt76, status,
     59			   status & WF_RST_DONE, 50000, 2000000);
     60
     61	sdio_release_host(sdio->func);
     62
     63	clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
     64
     65	/* activate mt7921s again */
     66	mt7921s_mcu_drv_pmctrl(dev);
     67	mt76_clear(dev, MT_CONN_STATUS, MT_WIFI_PATCH_DL_STATE);
     68	mt7921s_mcu_fw_pmctrl(dev);
     69	mt7921s_mcu_drv_pmctrl(dev);
     70
     71	return 0;
     72}
     73
     74int mt7921s_init_reset(struct mt7921_dev *dev)
     75{
     76	set_bit(MT76_MCU_RESET, &dev->mphy.state);
     77
     78	wake_up(&dev->mt76.mcu.wait);
     79	skb_queue_purge(&dev->mt76.mcu.res_q);
     80	wait_event_timeout(dev->mt76.sdio.wait,
     81			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);
     82	mt76_worker_disable(&dev->mt76.sdio.txrx_worker);
     83
     84	mt7921s_disable_irq(&dev->mt76);
     85	mt7921s_wfsys_reset(dev);
     86
     87	mt76_worker_enable(&dev->mt76.sdio.txrx_worker);
     88	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
     89	mt7921s_enable_irq(&dev->mt76);
     90
     91	return 0;
     92}
     93
     94int mt7921s_mac_reset(struct mt7921_dev *dev)
     95{
     96	int err;
     97
     98	mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
     99	mt76_txq_schedule_all(&dev->mphy);
    100	mt76_worker_disable(&dev->mt76.tx_worker);
    101	set_bit(MT76_RESET, &dev->mphy.state);
    102	set_bit(MT76_MCU_RESET, &dev->mphy.state);
    103	wake_up(&dev->mt76.mcu.wait);
    104	skb_queue_purge(&dev->mt76.mcu.res_q);
    105	wait_event_timeout(dev->mt76.sdio.wait,
    106			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);
    107	mt76_worker_disable(&dev->mt76.sdio.txrx_worker);
    108	mt76_worker_disable(&dev->mt76.sdio.status_worker);
    109	mt76_worker_disable(&dev->mt76.sdio.net_worker);
    110	cancel_work_sync(&dev->mt76.sdio.stat_work);
    111
    112	mt7921s_disable_irq(&dev->mt76);
    113	mt7921s_wfsys_reset(dev);
    114
    115	mt76_worker_enable(&dev->mt76.sdio.txrx_worker);
    116	mt76_worker_enable(&dev->mt76.sdio.status_worker);
    117	mt76_worker_enable(&dev->mt76.sdio.net_worker);
    118
    119	dev->fw_assert = false;
    120	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
    121	mt7921s_enable_irq(&dev->mt76);
    122
    123	err = mt7921_run_firmware(dev);
    124	if (err)
    125		goto out;
    126
    127	err = mt7921_mcu_set_eeprom(dev);
    128	if (err)
    129		goto out;
    130
    131	err = mt7921_mac_init(dev);
    132	if (err)
    133		goto out;
    134
    135	err = __mt7921_start(&dev->phy);
    136out:
    137	clear_bit(MT76_RESET, &dev->mphy.state);
    138
    139	mt76_worker_enable(&dev->mt76.tx_worker);
    140
    141	return err;
    142}