brintos

brintos / linux-shallow public Read only

0
0
Text · 3.4 KiB · 1f77cf7 Raw
142 lines · c
1// SPDX-License-Identifier: ISC2/* Copyright (C) 2021 MediaTek Inc. */3 4#include <linux/iopoll.h>5#include <linux/mmc/sdio_func.h>6#include "mt7921.h"7#include "../mt76_connac2_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 mt792x_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 mt792x_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 mt792x_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_MCU_RESET, &dev->mphy.state);102	wake_up(&dev->mt76.mcu.wait);103	skb_queue_purge(&dev->mt76.mcu.res_q);104	wait_event_timeout(dev->mt76.sdio.wait,105			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);106	mt76_worker_disable(&dev->mt76.sdio.txrx_worker);107	mt76_worker_disable(&dev->mt76.sdio.status_worker);108	mt76_worker_disable(&dev->mt76.sdio.net_worker);109	mt76_worker_disable(&dev->mt76.sdio.stat_worker);110 111	mt7921s_disable_irq(&dev->mt76);112	mt7921s_wfsys_reset(dev);113 114	mt76_worker_enable(&dev->mt76.sdio.txrx_worker);115	mt76_worker_enable(&dev->mt76.sdio.status_worker);116	mt76_worker_enable(&dev->mt76.sdio.net_worker);117	mt76_worker_enable(&dev->mt76.sdio.stat_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 138	mt76_worker_enable(&dev->mt76.tx_worker);139 140	return err;141}142