Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /* Copyright (C) 2022 MediaTek Inc.
0003  *
0004  * Author: Lorenzo Bianconi <lorenzo@kernel.org>
0005  */
0006 
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/usb.h>
0010 
0011 #include "mt7921.h"
0012 #include "mcu.h"
0013 #include "mac.h"
0014 
0015 static u32 mt7921u_uhw_rr(struct mt76_dev *dev, u32 addr)
0016 {
0017     u32 ret;
0018 
0019     mutex_lock(&dev->usb.usb_ctrl_mtx);
0020     ret = ___mt76u_rr(dev, MT_VEND_DEV_MODE,
0021               USB_DIR_IN | MT_USB_TYPE_UHW_VENDOR, addr);
0022     mutex_unlock(&dev->usb.usb_ctrl_mtx);
0023 
0024     return ret;
0025 }
0026 
0027 static void mt7921u_uhw_wr(struct mt76_dev *dev, u32 addr, u32 val)
0028 {
0029     mutex_lock(&dev->usb.usb_ctrl_mtx);
0030     ___mt76u_wr(dev, MT_VEND_WRITE,
0031             USB_DIR_OUT | MT_USB_TYPE_UHW_VENDOR, addr, val);
0032     mutex_unlock(&dev->usb.usb_ctrl_mtx);
0033 }
0034 
0035 static void mt7921u_dma_prefetch(struct mt7921_dev *dev)
0036 {
0037     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(0),
0038          MT_WPDMA0_MAX_CNT_MASK, 4);
0039     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(0),
0040          MT_WPDMA0_BASE_PTR_MASK, 0x80);
0041 
0042     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(1),
0043          MT_WPDMA0_MAX_CNT_MASK, 4);
0044     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(1),
0045          MT_WPDMA0_BASE_PTR_MASK, 0xc0);
0046 
0047     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(2),
0048          MT_WPDMA0_MAX_CNT_MASK, 4);
0049     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(2),
0050          MT_WPDMA0_BASE_PTR_MASK, 0x100);
0051 
0052     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(3),
0053          MT_WPDMA0_MAX_CNT_MASK, 4);
0054     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(3),
0055          MT_WPDMA0_BASE_PTR_MASK, 0x140);
0056 
0057     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(4),
0058          MT_WPDMA0_MAX_CNT_MASK, 4);
0059     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(4),
0060          MT_WPDMA0_BASE_PTR_MASK, 0x180);
0061 
0062     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(16),
0063          MT_WPDMA0_MAX_CNT_MASK, 4);
0064     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(16),
0065          MT_WPDMA0_BASE_PTR_MASK, 0x280);
0066 
0067     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(17),
0068          MT_WPDMA0_MAX_CNT_MASK, 4);
0069     mt76_rmw(dev, MT_UWFDMA0_TX_RING_EXT_CTRL(17),
0070          MT_WPDMA0_BASE_PTR_MASK,  0x2c0);
0071 }
0072 
0073 static void mt7921u_wfdma_init(struct mt7921_dev *dev)
0074 {
0075     mt7921u_dma_prefetch(dev);
0076 
0077     mt76_clear(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_OMIT_RX_INFO);
0078     mt76_set(dev, MT_UWFDMA0_GLO_CFG,
0079          MT_WFDMA0_GLO_CFG_OMIT_TX_INFO |
0080          MT_WFDMA0_GLO_CFG_OMIT_RX_INFO_PFET2 |
0081          MT_WFDMA0_GLO_CFG_FW_DWLD_BYPASS_DMASHDL |
0082          MT_WFDMA0_GLO_CFG_TX_DMA_EN |
0083          MT_WFDMA0_GLO_CFG_RX_DMA_EN);
0084 
0085     /* disable dmashdl */
0086     mt76_clear(dev, MT_UWFDMA0_GLO_CFG_EXT0,
0087            MT_WFDMA0_CSR_TX_DMASHDL_ENABLE);
0088     mt76_set(dev, MT_DMASHDL_SW_CONTROL, MT_DMASHDL_DMASHDL_BYPASS);
0089 
0090     mt76_set(dev, MT_WFDMA_DUMMY_CR, MT_WFDMA_NEED_REINIT);
0091 }
0092 
0093 static int mt7921u_dma_rx_evt_ep4(struct mt7921_dev *dev)
0094 {
0095     if (!mt76_poll(dev, MT_UWFDMA0_GLO_CFG,
0096                MT_WFDMA0_GLO_CFG_RX_DMA_BUSY, 0, 1000))
0097         return -ETIMEDOUT;
0098 
0099     mt76_clear(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_RX_DMA_EN);
0100     mt76_set(dev, MT_WFDMA_HOST_CONFIG,
0101          MT_WFDMA_HOST_CONFIG_USB_RXEVT_EP4_EN);
0102     mt76_set(dev, MT_UWFDMA0_GLO_CFG, MT_WFDMA0_GLO_CFG_RX_DMA_EN);
0103 
0104     return 0;
0105 }
0106 
0107 static void mt7921u_epctl_rst_opt(struct mt7921_dev *dev, bool reset)
0108 {
0109     u32 val;
0110 
0111     /* usb endpoint reset opt
0112      * bits[4,9]: out blk ep 4-9
0113      * bits[20,21]: in blk ep 4-5
0114      * bits[22]: in int ep 6
0115      */
0116     val = mt7921u_uhw_rr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT);
0117     if (reset)
0118         val |= GENMASK(9, 4) | GENMASK(22, 20);
0119     else
0120         val &= ~(GENMASK(9, 4) | GENMASK(22, 20));
0121     mt7921u_uhw_wr(&dev->mt76, MT_SSUSB_EPCTL_CSR_EP_RST_OPT, val);
0122 }
0123 
0124 int mt7921u_dma_init(struct mt7921_dev *dev, bool resume)
0125 {
0126     int err;
0127 
0128     mt7921u_wfdma_init(dev);
0129 
0130     mt76_clear(dev, MT_UDMA_WLCFG_0, MT_WL_RX_FLUSH);
0131 
0132     mt76_set(dev, MT_UDMA_WLCFG_0,
0133          MT_WL_RX_EN | MT_WL_TX_EN |
0134          MT_WL_RX_MPSZ_PAD0 | MT_TICK_1US_EN);
0135     mt76_clear(dev, MT_UDMA_WLCFG_0,
0136            MT_WL_RX_AGG_TO | MT_WL_RX_AGG_LMT);
0137     mt76_clear(dev, MT_UDMA_WLCFG_1, MT_WL_RX_AGG_PKT_LMT);
0138 
0139     if (resume)
0140         return 0;
0141 
0142     err = mt7921u_dma_rx_evt_ep4(dev);
0143     if (err)
0144         return err;
0145 
0146     mt7921u_epctl_rst_opt(dev, false);
0147 
0148     return 0;
0149 }
0150 
0151 int mt7921u_wfsys_reset(struct mt7921_dev *dev)
0152 {
0153     u32 val;
0154     int i;
0155 
0156     mt7921u_epctl_rst_opt(dev, false);
0157 
0158     val = mt7921u_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST);
0159     val |= MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH;
0160     mt7921u_uhw_wr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST, val);
0161 
0162     usleep_range(10, 20);
0163 
0164     val = mt7921u_uhw_rr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST);
0165     val &= ~MT_CBTOP_RGU_WF_SUBSYS_RST_WF_WHOLE_PATH;
0166     mt7921u_uhw_wr(&dev->mt76, MT_CBTOP_RGU_WF_SUBSYS_RST, val);
0167 
0168     mt7921u_uhw_wr(&dev->mt76, MT_UDMA_CONN_INFRA_STATUS_SEL, 0);
0169     for (i = 0; i < MT7921_WFSYS_INIT_RETRY_COUNT; i++) {
0170         val = mt7921u_uhw_rr(&dev->mt76, MT_UDMA_CONN_INFRA_STATUS);
0171         if (val & MT_UDMA_CONN_WFSYS_INIT_DONE)
0172             break;
0173 
0174         msleep(100);
0175     }
0176 
0177     if (i == MT7921_WFSYS_INIT_RETRY_COUNT)
0178         return -ETIMEDOUT;
0179 
0180     return 0;
0181 }
0182 
0183 int mt7921u_init_reset(struct mt7921_dev *dev)
0184 {
0185     set_bit(MT76_RESET, &dev->mphy.state);
0186 
0187     wake_up(&dev->mt76.mcu.wait);
0188     skb_queue_purge(&dev->mt76.mcu.res_q);
0189 
0190     mt76u_stop_rx(&dev->mt76);
0191     mt76u_stop_tx(&dev->mt76);
0192 
0193     mt7921u_wfsys_reset(dev);
0194 
0195     clear_bit(MT76_RESET, &dev->mphy.state);
0196 
0197     return mt76u_resume_rx(&dev->mt76);
0198 }
0199 
0200 int mt7921u_mac_reset(struct mt7921_dev *dev)
0201 {
0202     int err;
0203 
0204     mt76_txq_schedule_all(&dev->mphy);
0205     mt76_worker_disable(&dev->mt76.tx_worker);
0206 
0207     set_bit(MT76_RESET, &dev->mphy.state);
0208     set_bit(MT76_MCU_RESET, &dev->mphy.state);
0209 
0210     wake_up(&dev->mt76.mcu.wait);
0211     skb_queue_purge(&dev->mt76.mcu.res_q);
0212 
0213     mt76u_stop_rx(&dev->mt76);
0214     mt76u_stop_tx(&dev->mt76);
0215 
0216     mt7921u_wfsys_reset(dev);
0217 
0218     clear_bit(MT76_MCU_RESET, &dev->mphy.state);
0219     err = mt76u_resume_rx(&dev->mt76);
0220     if (err)
0221         goto out;
0222 
0223     err = mt7921u_mcu_power_on(dev);
0224     if (err)
0225         goto out;
0226 
0227     err = mt7921u_dma_init(dev, false);
0228     if (err)
0229         goto out;
0230 
0231     mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
0232     mt76_set(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
0233 
0234     err = mt7921_run_firmware(dev);
0235     if (err)
0236         goto out;
0237 
0238     mt76_clear(dev, MT_UDMA_TX_QSEL, MT_FW_DL_EN);
0239 
0240     err = mt7921_mcu_set_eeprom(dev);
0241     if (err)
0242         goto out;
0243 
0244     err = mt7921_mac_init(dev);
0245     if (err)
0246         goto out;
0247 
0248     err = __mt7921_start(&dev->phy);
0249 out:
0250     clear_bit(MT76_RESET, &dev->mphy.state);
0251 
0252     mt76_worker_enable(&dev->mt76.tx_worker);
0253 
0254     return err;
0255 }