root/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mt76x2u_mac_reset_counters
  2. mt76x2u_mac_fixup_xtal
  3. mt76x2u_mac_reset
  4. mt76x2u_mac_start
  5. mt76x2u_mac_stop

   1 // SPDX-License-Identifier: ISC
   2 /*
   3  * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
   4  */
   5 
   6 #include "mt76x2u.h"
   7 #include "eeprom.h"
   8 
   9 static void mt76x2u_mac_reset_counters(struct mt76x02_dev *dev)
  10 {
  11         mt76_rr(dev, MT_RX_STAT_0);
  12         mt76_rr(dev, MT_RX_STAT_1);
  13         mt76_rr(dev, MT_RX_STAT_2);
  14         mt76_rr(dev, MT_TX_STA_0);
  15         mt76_rr(dev, MT_TX_STA_1);
  16         mt76_rr(dev, MT_TX_STA_2);
  17 }
  18 
  19 static void mt76x2u_mac_fixup_xtal(struct mt76x02_dev *dev)
  20 {
  21         s8 offset = 0;
  22         u16 eep_val;
  23 
  24         eep_val = mt76x02_eeprom_get(dev, MT_EE_XTAL_TRIM_2);
  25 
  26         offset = eep_val & 0x7f;
  27         if ((eep_val & 0xff) == 0xff)
  28                 offset = 0;
  29         else if (eep_val & 0x80)
  30                 offset = 0 - offset;
  31 
  32         eep_val >>= 8;
  33         if (eep_val == 0x00 || eep_val == 0xff) {
  34                 eep_val = mt76x02_eeprom_get(dev, MT_EE_XTAL_TRIM_1);
  35                 eep_val &= 0xff;
  36 
  37                 if (eep_val == 0x00 || eep_val == 0xff)
  38                         eep_val = 0x14;
  39         }
  40 
  41         eep_val &= 0x7f;
  42         mt76_rmw_field(dev, MT_VEND_ADDR(CFG, MT_XO_CTRL5),
  43                        MT_XO_CTRL5_C2_VAL, eep_val + offset);
  44         mt76_set(dev, MT_VEND_ADDR(CFG, MT_XO_CTRL6), MT_XO_CTRL6_C2_CTRL);
  45 
  46         mt76_wr(dev, 0x504, 0x06000000);
  47         mt76_wr(dev, 0x50c, 0x08800000);
  48         mdelay(5);
  49         mt76_wr(dev, 0x504, 0x0);
  50 
  51         /* decrease SIFS from 16us to 13us */
  52         mt76_rmw_field(dev, MT_XIFS_TIME_CFG,
  53                        MT_XIFS_TIME_CFG_OFDM_SIFS, 0xd);
  54         mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG, MT_BKOFF_SLOT_CFG_CC_DELAY, 1);
  55 
  56         /* init fce */
  57         mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
  58 
  59         eep_val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2);
  60         switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) {
  61         case 0:
  62                 mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80);
  63                 break;
  64         case 1:
  65                 mt76_wr(dev, MT_XO_CTRL7, 0x5c1feed0);
  66                 break;
  67         default:
  68                 break;
  69         }
  70 }
  71 
  72 int mt76x2u_mac_reset(struct mt76x02_dev *dev)
  73 {
  74         mt76_wr(dev, MT_WPDMA_GLO_CFG, BIT(4) | BIT(5));
  75 
  76         /* init pbf regs */
  77         mt76_wr(dev, MT_PBF_TX_MAX_PCNT, 0xefef3f1f);
  78         mt76_wr(dev, MT_PBF_RX_MAX_PCNT, 0xfebf);
  79 
  80         mt76_write_mac_initvals(dev);
  81 
  82         mt76_wr(dev, MT_TX_LINK_CFG, 0x1020);
  83         mt76_wr(dev, MT_AUTO_RSP_CFG, 0x13);
  84         mt76_wr(dev, MT_MAX_LEN_CFG, 0x2f00);
  85 
  86         mt76_wr(dev, MT_WMM_AIFSN, 0x2273);
  87         mt76_wr(dev, MT_WMM_CWMIN, 0x2344);
  88         mt76_wr(dev, MT_WMM_CWMAX, 0x34aa);
  89 
  90         mt76_clear(dev, MT_MAC_SYS_CTRL,
  91                    MT_MAC_SYS_CTRL_RESET_CSR |
  92                    MT_MAC_SYS_CTRL_RESET_BBP);
  93 
  94         if (is_mt7612(dev))
  95                 mt76_clear(dev, MT_COEXCFG0, MT_COEXCFG0_COEX_EN);
  96 
  97         mt76_set(dev, MT_EXT_CCA_CFG, 0xf000);
  98         mt76_clear(dev, MT_TX_ALC_CFG_4, BIT(31));
  99 
 100         mt76x2u_mac_fixup_xtal(dev);
 101 
 102         return 0;
 103 }
 104 
 105 int mt76x2u_mac_start(struct mt76x02_dev *dev)
 106 {
 107         mt76x2u_mac_reset_counters(dev);
 108 
 109         mt76_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX);
 110         mt76x02_wait_for_wpdma(&dev->mt76, 1000);
 111         usleep_range(50, 100);
 112 
 113         mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
 114 
 115         mt76_wr(dev, MT_MAC_SYS_CTRL,
 116                 MT_MAC_SYS_CTRL_ENABLE_TX |
 117                 MT_MAC_SYS_CTRL_ENABLE_RX);
 118 
 119         return 0;
 120 }
 121 
 122 int mt76x2u_mac_stop(struct mt76x02_dev *dev)
 123 {
 124         int i, count = 0, val;
 125         bool stopped = false;
 126         u32 rts_cfg;
 127 
 128         if (test_bit(MT76_REMOVED, &dev->mt76.state))
 129                 return -EIO;
 130 
 131         rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
 132         mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT);
 133 
 134         mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
 135         mt76_clear(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN);
 136 
 137         /* wait tx dma to stop */
 138         for (i = 0; i < 2000; i++) {
 139                 val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));
 140                 if (!(val & MT_USB_DMA_CFG_TX_BUSY) && i > 10)
 141                         break;
 142                 usleep_range(50, 100);
 143         }
 144 
 145         /* page count on TxQ */
 146         for (i = 0; i < 200; i++) {
 147                 if (!(mt76_rr(dev, 0x0438) & 0xffffffff) &&
 148                     !(mt76_rr(dev, 0x0a30) & 0x000000ff) &&
 149                     !(mt76_rr(dev, 0x0a34) & 0xff00ff00))
 150                         break;
 151                 usleep_range(10, 20);
 152         }
 153 
 154         /* disable tx-rx */
 155         mt76_clear(dev, MT_MAC_SYS_CTRL,
 156                    MT_MAC_SYS_CTRL_ENABLE_RX |
 157                    MT_MAC_SYS_CTRL_ENABLE_TX);
 158 
 159         /* Wait for MAC to become idle */
 160         for (i = 0; i < 1000; i++) {
 161                 if (!(mt76_rr(dev, MT_MAC_STATUS) & MT_MAC_STATUS_TX) &&
 162                     !mt76_rr(dev, MT_BBP(IBI, 12))) {
 163                         stopped = true;
 164                         break;
 165                 }
 166                 usleep_range(10, 20);
 167         }
 168 
 169         if (!stopped) {
 170                 mt76_set(dev, MT_BBP(CORE, 4), BIT(1));
 171                 mt76_clear(dev, MT_BBP(CORE, 4), BIT(1));
 172 
 173                 mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
 174                 mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
 175         }
 176 
 177         /* page count on RxQ */
 178         for (i = 0; i < 200; i++) {
 179                 if (!(mt76_rr(dev, 0x0430) & 0x00ff0000) &&
 180                     !(mt76_rr(dev, 0x0a30) & 0xffffffff) &&
 181                     !(mt76_rr(dev, 0x0a34) & 0xffffffff) &&
 182                     ++count > 10)
 183                         break;
 184                 msleep(50);
 185         }
 186 
 187         if (!mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_RX, 0, 2000))
 188                 dev_warn(dev->mt76.dev, "MAC RX failed to stop\n");
 189 
 190         /* wait rx dma to stop */
 191         for (i = 0; i < 2000; i++) {
 192                 val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));
 193                 if (!(val & MT_USB_DMA_CFG_RX_BUSY) && i > 10)
 194                         break;
 195                 usleep_range(50, 100);
 196         }
 197 
 198         mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg);
 199 
 200         return 0;
 201 }

/* [<][>][^][v][top][bottom][index][help] */