2 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include <linux/delay.h>
21 #include "../mt76x02_phy.h"
22 #include "../mt76x02_usb.h"
24 static void mt76x2u_init_dma(struct mt76x02_dev
*dev
)
26 u32 val
= mt76_rr(dev
, MT_VEND_ADDR(CFG
, MT_USB_U3DMA_CFG
));
28 val
|= MT_USB_DMA_CFG_RX_DROP_OR_PAD
|
29 MT_USB_DMA_CFG_RX_BULK_EN
|
30 MT_USB_DMA_CFG_TX_BULK_EN
;
32 /* disable AGGR_BULK_RX in order to receive one
33 * frame in each rx urb and avoid copies
35 val
&= ~MT_USB_DMA_CFG_RX_BULK_AGG_EN
;
36 mt76_wr(dev
, MT_VEND_ADDR(CFG
, MT_USB_U3DMA_CFG
), val
);
39 static void mt76x2u_power_on_rf_patch(struct mt76x02_dev
*dev
)
41 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x130), BIT(0) | BIT(16));
44 mt76_clear(dev
, MT_VEND_ADDR(CFG
, 0x1c), 0xff);
45 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x1c), 0x30);
47 mt76_wr(dev
, MT_VEND_ADDR(CFG
, 0x14), 0x484f);
50 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x130), BIT(17));
51 usleep_range(150, 200);
53 mt76_clear(dev
, MT_VEND_ADDR(CFG
, 0x130), BIT(16));
54 usleep_range(50, 100);
56 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x14c), BIT(19) | BIT(20));
59 static void mt76x2u_power_on_rf(struct mt76x02_dev
*dev
, int unit
)
61 int shift
= unit
? 8 : 0;
62 u32 val
= (BIT(1) | BIT(3) | BIT(4) | BIT(5)) << shift
;
65 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x130), BIT(0) << shift
);
68 /* Enable RFDIG LDO/AFE/ABB/ADDA */
69 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x130), val
);
72 /* Switch RFDIG power to internal LDO */
73 mt76_clear(dev
, MT_VEND_ADDR(CFG
, 0x130), BIT(2) << shift
);
76 mt76x2u_power_on_rf_patch(dev
);
78 mt76_set(dev
, 0x530, 0xf);
81 static void mt76x2u_power_on(struct mt76x02_dev
*dev
)
85 /* Turn on WL MTCMOS */
86 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x148),
87 MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP
);
89 val
= MT_WLAN_MTC_CTRL_STATE_UP
|
90 MT_WLAN_MTC_CTRL_PWR_ACK
|
91 MT_WLAN_MTC_CTRL_PWR_ACK_S
;
93 mt76_poll(dev
, MT_VEND_ADDR(CFG
, 0x148), val
, val
, 1000);
95 mt76_clear(dev
, MT_VEND_ADDR(CFG
, 0x148), 0x7f << 16);
98 mt76_clear(dev
, MT_VEND_ADDR(CFG
, 0x148), 0xf << 24);
101 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x148), 0xf << 24);
102 mt76_clear(dev
, MT_VEND_ADDR(CFG
, 0x148), 0xfff);
104 /* Turn on AD/DA power down */
105 mt76_clear(dev
, MT_VEND_ADDR(CFG
, 0x1204), BIT(3));
107 /* WLAN function enable */
108 mt76_set(dev
, MT_VEND_ADDR(CFG
, 0x80), BIT(0));
110 /* Release BBP software reset */
111 mt76_clear(dev
, MT_VEND_ADDR(CFG
, 0x64), BIT(18));
113 mt76x2u_power_on_rf(dev
, 0);
114 mt76x2u_power_on_rf(dev
, 1);
117 static int mt76x2u_init_eeprom(struct mt76x02_dev
*dev
)
121 dev
->mt76
.eeprom
.data
= devm_kzalloc(dev
->mt76
.dev
,
124 dev
->mt76
.eeprom
.size
= MT7612U_EEPROM_SIZE
;
125 if (!dev
->mt76
.eeprom
.data
)
128 for (i
= 0; i
+ 4 <= MT7612U_EEPROM_SIZE
; i
+= 4) {
129 val
= mt76_rr(dev
, MT_VEND_ADDR(EEPROM
, i
));
130 put_unaligned_le32(val
, dev
->mt76
.eeprom
.data
+ i
);
133 mt76x02_eeprom_parse_hw_cap(dev
);
137 int mt76x2u_init_hardware(struct mt76x02_dev
*dev
)
141 mt76x2_reset_wlan(dev
, true);
142 mt76x2u_power_on(dev
);
144 if (!mt76x02_wait_for_mac(&dev
->mt76
))
147 err
= mt76x2u_mcu_fw_init(dev
);
151 if (!mt76_poll_msec(dev
, MT_WPDMA_GLO_CFG
,
152 MT_WPDMA_GLO_CFG_TX_DMA_BUSY
|
153 MT_WPDMA_GLO_CFG_RX_DMA_BUSY
, 0, 100))
156 /* wait for asic ready after fw load. */
157 if (!mt76x02_wait_for_mac(&dev
->mt76
))
160 mt76x2u_init_dma(dev
);
162 err
= mt76x2u_mcu_init(dev
);
166 err
= mt76x2u_mac_reset(dev
);
170 mt76x02_mac_setaddr(dev
, dev
->mt76
.eeprom
.data
+ MT_EE_MAC_ADDR
);
171 dev
->mt76
.rxfilter
= mt76_rr(dev
, MT_RX_FILTR_CFG
);
173 if (!mt76x02_wait_for_txrx_idle(&dev
->mt76
))
176 /* reset wcid table */
177 for (i
= 0; i
< 256; i
++)
178 mt76x02_mac_wcid_setup(dev
, i
, 0, NULL
);
180 /* reset shared key table and pairwise key table */
181 for (i
= 0; i
< 16; i
++) {
182 for (k
= 0; k
< 4; k
++)
183 mt76x02_mac_shared_key_setup(dev
, i
, k
, NULL
);
186 mt76x02u_init_beacon_config(dev
);
188 mt76_rmw(dev
, MT_US_CYC_CFG
, MT_US_CYC_CNT
, 0x1e);
189 mt76_wr(dev
, MT_TXOP_CTRL_CFG
, 0x583f);
191 err
= mt76x2_mcu_load_cr(dev
, MT_RF_BBP_CR
, 0, 0);
195 mt76x02_phy_set_rxpath(dev
);
196 mt76x02_phy_set_txdac(dev
);
198 return mt76x2u_mac_stop(dev
);
201 int mt76x2u_register_device(struct mt76x02_dev
*dev
)
203 struct ieee80211_hw
*hw
= mt76_hw(dev
);
206 INIT_DELAYED_WORK(&dev
->cal_work
, mt76x2u_phy_calibrate
);
207 mt76x02_init_device(dev
);
209 err
= mt76x2u_init_eeprom(dev
);
213 err
= mt76u_alloc_queues(&dev
->mt76
);
217 err
= mt76x2u_init_hardware(dev
);
221 err
= mt76_register_device(&dev
->mt76
, true, mt76x02_rates
,
222 ARRAY_SIZE(mt76x02_rates
));
226 /* check hw sg support in order to enable AMSDU */
227 if (dev
->mt76
.usb
.sg_en
)
228 hw
->max_tx_fragments
= MT_SG_MAX_SIZE
;
230 hw
->max_tx_fragments
= 1;
232 set_bit(MT76_STATE_INITIALIZED
, &dev
->mt76
.state
);
234 mt76x02_init_debugfs(dev
);
235 mt76x2_init_txpower(dev
, &dev
->mt76
.sband_2g
.sband
);
236 mt76x2_init_txpower(dev
, &dev
->mt76
.sband_5g
.sband
);
241 mt76x2u_cleanup(dev
);
245 void mt76x2u_stop_hw(struct mt76x02_dev
*dev
)
247 cancel_delayed_work_sync(&dev
->cal_work
);
248 cancel_delayed_work_sync(&dev
->mt76
.mac_work
);
249 mt76x2u_mac_stop(dev
);
252 void mt76x2u_cleanup(struct mt76x02_dev
*dev
)
254 mt76x02_mcu_set_radio_state(dev
, false);
255 mt76x2u_stop_hw(dev
);
256 mt76u_queues_deinit(&dev
->mt76
);