| @@ -1,39 +1,41 @@ | | | @@ -1,39 +1,41 @@ |
1 | /* $NetBSD: rt2860.c,v 1.17 2016/06/24 16:08:54 christos Exp $ */ | | 1 | /* $NetBSD: rt2860.c,v 1.18 2016/07/07 01:24:16 christos Exp $ */ |
2 | /* $OpenBSD: rt2860.c,v 1.90 2016/04/13 10:49:26 mpi Exp $ */ | | 2 | /* $OpenBSD: rt2860.c,v 1.90 2016/04/13 10:49:26 mpi Exp $ */ |
| | | 3 | /* $FreeBSD: head/sys/dev/ral/rt2860.c 297793 2016-04-10 23:07:00Z pfg $ */ |
3 | | | 4 | |
4 | /*- | | 5 | /*- |
5 | * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> | | 6 | * Copyright (c) 2007-2010 Damien Bergamini <damien.bergamini@free.fr> |
| | | 7 | * Copyright (c) 2012 Bernhard Schmidt <bschmidt@FreeBSD.org> |
6 | * | | 8 | * |
7 | * Permission to use, copy, modify, and distribute this software for any | | 9 | * Permission to use, copy, modify, and distribute this software for any |
8 | * purpose with or without fee is hereby granted, provided that the above | | 10 | * purpose with or without fee is hereby granted, provided that the above |
9 | * copyright notice and this permission notice appear in all copies. | | 11 | * copyright notice and this permission notice appear in all copies. |
10 | * | | 12 | * |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | | 13 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | 14 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | | 15 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 16 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | 17 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | | 18 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 19 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | */ | | 20 | */ |
19 | | | 21 | |
20 | /*- | | 22 | /*- |
21 | * Ralink Technology RT2860/RT3090/RT3390/RT3562 chipset driver | | 23 | * Ralink Technology RT2860/RT3090/RT3390/RT3562/RT5390/RT5392 chipset driver |
22 | * http://www.ralinktech.com/ | | 24 | * http://www.ralinktech.com/ |
23 | */ | | 25 | */ |
24 | | | 26 | |
25 | #include <sys/cdefs.h> | | 27 | #include <sys/cdefs.h> |
26 | __KERNEL_RCSID(0, "$NetBSD: rt2860.c,v 1.17 2016/06/24 16:08:54 christos Exp $"); | | 28 | __KERNEL_RCSID(0, "$NetBSD: rt2860.c,v 1.18 2016/07/07 01:24:16 christos Exp $"); |
27 | | | 29 | |
28 | #include <sys/param.h> | | 30 | #include <sys/param.h> |
29 | #include <sys/sockio.h> | | 31 | #include <sys/sockio.h> |
30 | #include <sys/sysctl.h> | | 32 | #include <sys/sysctl.h> |
31 | #include <sys/mbuf.h> | | 33 | #include <sys/mbuf.h> |
32 | #include <sys/kernel.h> | | 34 | #include <sys/kernel.h> |
33 | #include <sys/socket.h> | | 35 | #include <sys/socket.h> |
34 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
35 | #include <sys/malloc.h> | | 37 | #include <sys/malloc.h> |
36 | #include <sys/queue.h> | | 38 | #include <sys/queue.h> |
37 | #include <sys/callout.h> | | 39 | #include <sys/callout.h> |
38 | #include <sys/module.h> | | 40 | #include <sys/module.h> |
39 | #include <sys/conf.h> | | 41 | #include <sys/conf.h> |
| @@ -51,26 +53,27 @@ __KERNEL_RCSID(0, "$NetBSD: rt2860.c,v 1 | | | @@ -51,26 +53,27 @@ __KERNEL_RCSID(0, "$NetBSD: rt2860.c,v 1 |
51 | #include <net/if_media.h> | | 53 | #include <net/if_media.h> |
52 | | | 54 | |
53 | #include <net80211/ieee80211_var.h> | | 55 | #include <net80211/ieee80211_var.h> |
54 | #include <net80211/ieee80211_amrr.h> | | 56 | #include <net80211/ieee80211_amrr.h> |
55 | #include <net80211/ieee80211_radiotap.h> | | 57 | #include <net80211/ieee80211_radiotap.h> |
56 | | | 58 | |
57 | #include <dev/firmload.h> | | 59 | #include <dev/firmload.h> |
58 | | | 60 | |
59 | #include <dev/ic/rt2860var.h> | | 61 | #include <dev/ic/rt2860var.h> |
60 | #include <dev/ic/rt2860reg.h> | | 62 | #include <dev/ic/rt2860reg.h> |
61 | | | 63 | |
62 | #include <dev/pci/pcidevs.h> | | 64 | #include <dev/pci/pcidevs.h> |
63 | | | 65 | |
| | | 66 | #define RAL_DEBUG |
64 | #ifdef RAL_DEBUG | | 67 | #ifdef RAL_DEBUG |
65 | #define DPRINTF(x) do { if (rt2860_debug > 0) printf x; } while (0) | | 68 | #define DPRINTF(x) do { if (rt2860_debug > 0) printf x; } while (0) |
66 | #define DPRINTFN(n, x) do { if (rt2860_debug >= (n)) printf x; } while (0) | | 69 | #define DPRINTFN(n, x) do { if (rt2860_debug >= (n)) printf x; } while (0) |
67 | int rt2860_debug = 4; | | 70 | int rt2860_debug = 4; |
68 | #else | | 71 | #else |
69 | #define DPRINTF(x) | | 72 | #define DPRINTF(x) |
70 | #define DPRINTFN(n, x) | | 73 | #define DPRINTFN(n, x) |
71 | #endif | | 74 | #endif |
72 | #define MAXQS 6 /* Tx (4 EDCAs + HCCA + Mgt) and Rx rings */ | | 75 | #define MAXQS 6 /* Tx (4 EDCAs + HCCA + Mgt) and Rx rings */ |
73 | | | 76 | |
74 | static void rt2860_attachhook(device_t); | | 77 | static void rt2860_attachhook(device_t); |
75 | static int rt2860_alloc_tx_ring(struct rt2860_softc *, | | 78 | static int rt2860_alloc_tx_ring(struct rt2860_softc *, |
76 | struct rt2860_tx_ring *); | | 79 | struct rt2860_tx_ring *); |
| @@ -115,48 +118,52 @@ static void rt2860_watchdog(struct ifnet | | | @@ -115,48 +118,52 @@ static void rt2860_watchdog(struct ifnet |
115 | static int rt2860_ioctl(struct ifnet *, u_long, void *); | | 118 | static int rt2860_ioctl(struct ifnet *, u_long, void *); |
116 | static void rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t); | | 119 | static void rt2860_mcu_bbp_write(struct rt2860_softc *, uint8_t, uint8_t); |
117 | static uint8_t rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t); | | 120 | static uint8_t rt2860_mcu_bbp_read(struct rt2860_softc *, uint8_t); |
118 | static void rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t); | | 121 | static void rt2860_rf_write(struct rt2860_softc *, uint8_t, uint32_t); |
119 | static uint8_t rt3090_rf_read(struct rt2860_softc *, uint8_t); | | 122 | static uint8_t rt3090_rf_read(struct rt2860_softc *, uint8_t); |
120 | static void rt3090_rf_write(struct rt2860_softc *, uint8_t, uint8_t); | | 123 | static void rt3090_rf_write(struct rt2860_softc *, uint8_t, uint8_t); |
121 | static int rt2860_mcu_cmd(struct rt2860_softc *, uint8_t, uint16_t, int); | | 124 | static int rt2860_mcu_cmd(struct rt2860_softc *, uint8_t, uint16_t, int); |
122 | static void rt2860_enable_mrr(struct rt2860_softc *); | | 125 | static void rt2860_enable_mrr(struct rt2860_softc *); |
123 | static void rt2860_set_txpreamble(struct rt2860_softc *); | | 126 | static void rt2860_set_txpreamble(struct rt2860_softc *); |
124 | static void rt2860_set_basicrates(struct rt2860_softc *); | | 127 | static void rt2860_set_basicrates(struct rt2860_softc *); |
125 | static void rt2860_select_chan_group(struct rt2860_softc *, int); | | 128 | static void rt2860_select_chan_group(struct rt2860_softc *, int); |
126 | static void rt2860_set_chan(struct rt2860_softc *, u_int); | | 129 | static void rt2860_set_chan(struct rt2860_softc *, u_int); |
127 | static void rt3090_set_chan(struct rt2860_softc *, u_int); | | 130 | static void rt3090_set_chan(struct rt2860_softc *, u_int); |
128 | static int rt3090_rf_init(struct rt2860_softc *); | | 131 | static void rt5390_set_chan(struct rt2860_softc *, u_int); |
| | | 132 | static void rt3090_rf_init(struct rt2860_softc *); |
| | | 133 | static void rt5390_rf_init(struct rt2860_softc *); |
129 | static void rt3090_rf_wakeup(struct rt2860_softc *); | | 134 | static void rt3090_rf_wakeup(struct rt2860_softc *); |
| | | 135 | static void rt5390_rf_wakeup(struct rt2860_softc *); |
130 | static int rt3090_filter_calib(struct rt2860_softc *, uint8_t, uint8_t, | | 136 | static int rt3090_filter_calib(struct rt2860_softc *, uint8_t, uint8_t, |
131 | uint8_t *); | | 137 | uint8_t *); |
132 | static void rt3090_rf_setup(struct rt2860_softc *); | | 138 | static void rt3090_rf_setup(struct rt2860_softc *); |
133 | static void rt2860_set_leds(struct rt2860_softc *, uint16_t); | | 139 | static void rt2860_set_leds(struct rt2860_softc *, uint16_t); |
134 | static void rt2860_set_gp_timer(struct rt2860_softc *, int); | | 140 | static void rt2860_set_gp_timer(struct rt2860_softc *, int); |
135 | static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *); | | 141 | static void rt2860_set_bssid(struct rt2860_softc *, const uint8_t *); |
136 | static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *); | | 142 | static void rt2860_set_macaddr(struct rt2860_softc *, const uint8_t *); |
137 | static void rt2860_updateslot(struct ifnet *); | | 143 | static void rt2860_updateslot(struct ifnet *); |
138 | static void rt2860_updateprot(struct ieee80211com *); | | 144 | static void rt2860_updateprot(struct ieee80211com *); |
139 | static int rt2860_updateedca(struct ieee80211com *); | | 145 | static int rt2860_updateedca(struct ieee80211com *); |
140 | #ifdef HW_CRYPTO | | 146 | #ifdef HW_CRYPTO |
141 | static int rt2860_set_key(struct ieee80211com *, | | 147 | static int rt2860_set_key(struct ieee80211com *, |
142 | const struct ieee80211_key *, const uint8_t *); | | 148 | const struct ieee80211_key *, const uint8_t *); |
143 | static int rt2860_delete_key(struct ieee80211com *, | | 149 | static int rt2860_delete_key(struct ieee80211com *, |
144 | const struct ieee80211_key *); | | 150 | const struct ieee80211_key *); |
145 | #endif | | 151 | #endif |
146 | static int8_t rt2860_rssi2dbm(struct rt2860_softc *, uint8_t, uint8_t); | | 152 | static int8_t rt2860_rssi2dbm(struct rt2860_softc *, uint8_t, uint8_t); |
147 | static const char * rt2860_get_rf(uint8_t); | | 153 | static const char * rt2860_get_rf(uint8_t); |
148 | static int rt2860_read_eeprom(struct rt2860_softc *); | | 154 | static int rt2860_read_eeprom(struct rt2860_softc *); |
149 | static int rt2860_bbp_init(struct rt2860_softc *); | | 155 | static int rt2860_bbp_init(struct rt2860_softc *); |
| | | 156 | static int rt5390_bbp_init(struct rt2860_softc *); |
150 | static int rt2860_txrx_enable(struct rt2860_softc *); | | 157 | static int rt2860_txrx_enable(struct rt2860_softc *); |
151 | static int rt2860_init(struct ifnet *); | | 158 | static int rt2860_init(struct ifnet *); |
152 | static void rt2860_stop(struct ifnet *, int); | | 159 | static void rt2860_stop(struct ifnet *, int); |
153 | static int rt2860_load_microcode(struct rt2860_softc *); | | 160 | static int rt2860_load_microcode(struct rt2860_softc *); |
154 | #if 0 | | 161 | #if 0 |
155 | static void rt2860_calib(struct rt2860_softc *); | | 162 | static void rt2860_calib(struct rt2860_softc *); |
156 | #endif | | 163 | #endif |
157 | static void rt3090_set_rx_antenna(struct rt2860_softc *, int); | | 164 | static void rt3090_set_rx_antenna(struct rt2860_softc *, int); |
158 | static void rt2860_switch_chan(struct rt2860_softc *, | | 165 | static void rt2860_switch_chan(struct rt2860_softc *, |
159 | struct ieee80211_channel *); | | 166 | struct ieee80211_channel *); |
160 | #ifndef IEEE80211_STA_ONLY | | 167 | #ifndef IEEE80211_STA_ONLY |
161 | static int rt2860_setup_beacon(struct rt2860_softc *); | | 168 | static int rt2860_setup_beacon(struct rt2860_softc *); |
162 | #endif | | 169 | #endif |
| @@ -164,48 +171,54 @@ static void rt2860_enable_tsf_sync(struc | | | @@ -164,48 +171,54 @@ static void rt2860_enable_tsf_sync(struc |
164 | | | 171 | |
165 | static const struct { | | 172 | static const struct { |
166 | uint32_t reg; | | 173 | uint32_t reg; |
167 | uint32_t val; | | 174 | uint32_t val; |
168 | } rt2860_def_mac[] = { | | 175 | } rt2860_def_mac[] = { |
169 | RT2860_DEF_MAC | | 176 | RT2860_DEF_MAC |
170 | }; | | 177 | }; |
171 | | | 178 | |
172 | static const struct { | | 179 | static const struct { |
173 | uint8_t reg; | | 180 | uint8_t reg; |
174 | uint8_t val; | | 181 | uint8_t val; |
175 | } rt2860_def_bbp[] = { | | 182 | } rt2860_def_bbp[] = { |
176 | RT2860_DEF_BBP | | 183 | RT2860_DEF_BBP |
| | | 184 | }, rt5390_def_bbp[] = { |
| | | 185 | RT5390_DEF_BBP |
177 | }; | | 186 | }; |
178 | | | 187 | |
179 | static const struct rfprog { | | 188 | static const struct rfprog { |
180 | uint8_t chan; | | 189 | uint8_t chan; |
181 | uint32_t r1, r2, r3, r4; | | 190 | uint32_t r1, r2, r3, r4; |
182 | } rt2860_rf2850[] = { | | 191 | } rt2860_rf2850[] = { |
183 | RT2860_RF2850 | | 192 | RT2860_RF2850 |
184 | }; | | 193 | }; |
185 | | | 194 | |
186 | struct { | | 195 | struct { |
187 | uint8_t n, r, k; | | 196 | uint8_t n, r, k; |
188 | } rt3090_freqs[] = { | | 197 | } rt3090_freqs[] = { |
189 | RT3070_RF3052 | | 198 | RT3070_RF3052 |
190 | }; | | 199 | }; |
191 | | | 200 | |
192 | static const struct { | | 201 | static const struct { |
193 | uint8_t reg; | | 202 | uint8_t reg; |
194 | uint8_t val; | | 203 | uint8_t val; |
195 | } rt3090_def_rf[] = { | | 204 | } rt3090_def_rf[] = { |
196 | RT3070_DEF_RF | | 205 | RT3070_DEF_RF |
197 | }, rt3572_def_rf[] = { | | 206 | }, rt3572_def_rf[] = { |
198 | RT3572_DEF_RF | | 207 | RT3572_DEF_RF |
| | | 208 | }, rt5390_def_rf[] = { |
| | | 209 | RT5390_DEF_RF |
| | | 210 | }, rt5392_def_rf[] = { |
| | | 211 | RT5392_DEF_RF |
199 | }; | | 212 | }; |
200 | | | 213 | |
201 | int | | 214 | int |
202 | rt2860_attach(void *xsc, int id) | | 215 | rt2860_attach(void *xsc, int id) |
203 | { | | 216 | { |
204 | struct rt2860_softc *sc = xsc; | | 217 | struct rt2860_softc *sc = xsc; |
205 | struct ieee80211com *ic = &sc->sc_ic; | | 218 | struct ieee80211com *ic = &sc->sc_ic; |
206 | int qid, ntries, error; | | 219 | int qid, ntries, error; |
207 | uint32_t tmp; | | 220 | uint32_t tmp; |
208 | | | 221 | |
209 | sc->amrr.amrr_min_success_threshold = 1; | | 222 | sc->amrr.amrr_min_success_threshold = 1; |
210 | sc->amrr.amrr_max_success_threshold = 15; | | 223 | sc->amrr.amrr_max_success_threshold = 15; |
211 | | | 224 | |
| @@ -965,26 +978,27 @@ rt2860_ampdu_rx_stop(struct ieee80211com | | | @@ -965,26 +978,27 @@ rt2860_ampdu_rx_stop(struct ieee80211com |
965 | RAL_WRITE(sc, RT2860_WCID_ENTRY(wcid) + 4, tmp); | | 978 | RAL_WRITE(sc, RT2860_WCID_ENTRY(wcid) + 4, tmp); |
966 | } | | 979 | } |
967 | #endif | | 980 | #endif |
968 | | | 981 | |
969 | static int | | 982 | static int |
970 | rt2860_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) | | 983 | rt2860_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) |
971 | { | | 984 | { |
972 | struct rt2860_softc *sc = ic->ic_ifp->if_softc; | | 985 | struct rt2860_softc *sc = ic->ic_ifp->if_softc; |
973 | enum ieee80211_state ostate; | | 986 | enum ieee80211_state ostate; |
974 | uint32_t tmp; | | 987 | uint32_t tmp; |
975 | | | 988 | |
976 | ostate = ic->ic_state; | | 989 | ostate = ic->ic_state; |
977 | | | 990 | |
| | | 991 | DPRINTF(("ostate = %d nstate = %d\n", ostate, nstate)); |
978 | if (ostate == IEEE80211_S_RUN) { | | 992 | if (ostate == IEEE80211_S_RUN) { |
979 | /* turn link LED off */ | | 993 | /* turn link LED off */ |
980 | rt2860_set_leds(sc, RT2860_LED_RADIO); | | 994 | rt2860_set_leds(sc, RT2860_LED_RADIO); |
981 | } | | 995 | } |
982 | | | 996 | |
983 | switch (nstate) { | | 997 | switch (nstate) { |
984 | case IEEE80211_S_INIT: | | 998 | case IEEE80211_S_INIT: |
985 | if (ostate == IEEE80211_S_RUN) { | | 999 | if (ostate == IEEE80211_S_RUN) { |
986 | /* abort TSF synchronization */ | | 1000 | /* abort TSF synchronization */ |
987 | tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG); | | 1001 | tmp = RAL_READ(sc, RT2860_BCN_TIME_CFG); |
988 | RAL_WRITE(sc, RT2860_BCN_TIME_CFG, | | 1002 | RAL_WRITE(sc, RT2860_BCN_TIME_CFG, |
989 | tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | | | 1003 | tmp & ~(RT2860_BCN_TX_EN | RT2860_TSF_TIMER_EN | |
990 | RT2860_TBTT_TIMER_EN)); | | 1004 | RT2860_TBTT_TIMER_EN)); |
| @@ -1263,75 +1277,81 @@ rt2860_rx_intr(struct rt2860_softc *sc) | | | @@ -1263,75 +1277,81 @@ rt2860_rx_intr(struct rt2860_softc *sc) |
1263 | { | | 1277 | { |
1264 | struct ieee80211com *ic = &sc->sc_ic; | | 1278 | struct ieee80211com *ic = &sc->sc_ic; |
1265 | struct ifnet *ifp = &sc->sc_if; | | 1279 | struct ifnet *ifp = &sc->sc_if; |
1266 | struct ieee80211_frame *wh; | | 1280 | struct ieee80211_frame *wh; |
1267 | struct ieee80211_node *ni; | | 1281 | struct ieee80211_node *ni; |
1268 | struct mbuf *m, *m1; | | 1282 | struct mbuf *m, *m1; |
1269 | uint32_t hw; | | 1283 | uint32_t hw; |
1270 | uint8_t ant, rssi; | | 1284 | uint8_t ant, rssi; |
1271 | int error; | | 1285 | int error; |
1272 | struct rt2860_rx_radiotap_header *tap; | | 1286 | struct rt2860_rx_radiotap_header *tap; |
1273 | uint16_t phy; | | 1287 | uint16_t phy; |
1274 | | | 1288 | |
1275 | hw = RAL_READ(sc, RT2860_FS_DRX_IDX) & 0xfff; | | 1289 | hw = RAL_READ(sc, RT2860_FS_DRX_IDX) & 0xfff; |
| | | 1290 | DPRINTF(("rx mbuf %#x\n", hw)); |
1276 | while (sc->rxq.cur != hw) { | | 1291 | while (sc->rxq.cur != hw) { |
1277 | struct rt2860_rx_data *data = &sc->rxq.data[sc->rxq.cur]; | | 1292 | struct rt2860_rx_data *data = &sc->rxq.data[sc->rxq.cur]; |
1278 | struct rt2860_rxd *rxd = &sc->rxq.rxd[sc->rxq.cur]; | | 1293 | struct rt2860_rxd *rxd = &sc->rxq.rxd[sc->rxq.cur]; |
1279 | struct rt2860_rxwi *rxwi; | | 1294 | struct rt2860_rxwi *rxwi; |
1280 | | | 1295 | |
1281 | bus_dmamap_sync(sc->sc_dmat, sc->rxq.map, | | 1296 | bus_dmamap_sync(sc->sc_dmat, sc->rxq.map, |
1282 | sc->rxq.cur * sizeof (struct rt2860_rxd), | | 1297 | sc->rxq.cur * sizeof (struct rt2860_rxd), |
1283 | sizeof (struct rt2860_rxd), BUS_DMASYNC_POSTREAD); | | 1298 | sizeof (struct rt2860_rxd), BUS_DMASYNC_POSTREAD); |
1284 | | | 1299 | |
1285 | if (__predict_false(!(rxd->sdl0 & htole16(RT2860_RX_DDONE)))) { | | 1300 | if (__predict_false(!(rxd->sdl0 & htole16(RT2860_RX_DDONE)))) { |
1286 | DPRINTF(("RXD DDONE bit not set!\n")); | | 1301 | DPRINTF(("RXD DDONE bit not set!\n")); |
1287 | break; /* should not happen */ | | 1302 | break; /* should not happen */ |
1288 | } | | 1303 | } |
1289 | | | 1304 | |
1290 | if (__predict_false(rxd->flags & | | 1305 | if (__predict_false(rxd->flags & |
1291 | htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { | | 1306 | htole32(RT2860_RX_CRCERR | RT2860_RX_ICVERR))) { |
| | | 1307 | DPRINTF(("error %#x\n", rxd->flags)); |
1292 | ifp->if_ierrors++; | | 1308 | ifp->if_ierrors++; |
1293 | goto skip; | | 1309 | goto skip; |
1294 | } | | 1310 | } |
1295 | | | 1311 | |
1296 | #ifdef HW_CRYPTO | | 1312 | #ifdef HW_CRYPTO |
1297 | if (__predict_false(rxd->flags & htole32(RT2860_RX_MICERR))) { | | 1313 | if (__predict_false(rxd->flags & htole32(RT2860_RX_MICERR))) { |
1298 | /* report MIC failures to net80211 for TKIP */ | | 1314 | /* report MIC failures to net80211 for TKIP */ |
1299 | ieee80211_notify_michael_failure(ic, wh, 0/* XXX */); | | 1315 | ieee80211_notify_michael_failure(ic, wh, 0/* XXX */); |
| | | 1316 | DPRINTF(("error2 %#x\n", rxd->flags)); |
1300 | ifp->if_ierrors++; | | 1317 | ifp->if_ierrors++; |
1301 | goto skip; | | 1318 | goto skip; |
1302 | } | | 1319 | } |
1303 | #endif | | 1320 | #endif |
1304 | | | 1321 | |
1305 | MGETHDR(m1, M_DONTWAIT, MT_DATA); | | 1322 | MGETHDR(m1, M_DONTWAIT, MT_DATA); |
1306 | if (__predict_false(m1 == NULL)) { | | 1323 | if (__predict_false(m1 == NULL)) { |
| | | 1324 | DPRINTF(("error2 %#x\n", rxd->flags)); |
1307 | ifp->if_ierrors++; | | 1325 | ifp->if_ierrors++; |
1308 | goto skip; | | 1326 | goto skip; |
1309 | } | | 1327 | } |
1310 | MCLGET(m1, M_DONTWAIT); | | 1328 | MCLGET(m1, M_DONTWAIT); |
1311 | if (__predict_false((m1->m_flags & M_EXT) == 0)) { | | 1329 | if (__predict_false((m1->m_flags & M_EXT) == 0)) { |
| | | 1330 | DPRINTF(("no mbuf\n")); |
1312 | m_freem(m1); | | 1331 | m_freem(m1); |
1313 | ifp->if_ierrors++; | | 1332 | ifp->if_ierrors++; |
1314 | goto skip; | | 1333 | goto skip; |
1315 | } | | 1334 | } |
1316 | | | 1335 | |
1317 | bus_dmamap_sync(sc->sc_dmat, data->map, 0, | | 1336 | bus_dmamap_sync(sc->sc_dmat, data->map, 0, |
1318 | data->map->dm_mapsize, BUS_DMASYNC_POSTREAD); | | 1337 | data->map->dm_mapsize, BUS_DMASYNC_POSTREAD); |
1319 | bus_dmamap_unload(sc->sc_dmat, data->map); | | 1338 | bus_dmamap_unload(sc->sc_dmat, data->map); |
1320 | | | 1339 | |
1321 | error = bus_dmamap_load(sc->sc_dmat, data->map, | | 1340 | error = bus_dmamap_load(sc->sc_dmat, data->map, |
1322 | mtod(m1, void *), MCLBYTES, NULL, | | 1341 | mtod(m1, void *), MCLBYTES, NULL, |
1323 | BUS_DMA_READ | BUS_DMA_NOWAIT); | | 1342 | BUS_DMA_READ | BUS_DMA_NOWAIT); |
1324 | if (__predict_false(error != 0)) { | | 1343 | if (__predict_false(error != 0)) { |
| | | 1344 | DPRINTF(("dma error %d\n", error)); |
1325 | m_freem(m1); | | 1345 | m_freem(m1); |
1326 | | | 1346 | |
1327 | /* try to reload the old mbuf */ | | 1347 | /* try to reload the old mbuf */ |
1328 | error = bus_dmamap_load(sc->sc_dmat, data->map, | | 1348 | error = bus_dmamap_load(sc->sc_dmat, data->map, |
1329 | mtod(data->m, void *), MCLBYTES, NULL, | | 1349 | mtod(data->m, void *), MCLBYTES, NULL, |
1330 | BUS_DMA_READ | BUS_DMA_NOWAIT); | | 1350 | BUS_DMA_READ | BUS_DMA_NOWAIT); |
1331 | if (__predict_false(error != 0)) { | | 1351 | if (__predict_false(error != 0)) { |
1332 | panic("%s: could not load old rx mbuf", | | 1352 | panic("%s: could not load old rx mbuf", |
1333 | device_xname(sc->sc_dev)); | | 1353 | device_xname(sc->sc_dev)); |
1334 | } | | 1354 | } |
1335 | /* physical address may have changed */ | | 1355 | /* physical address may have changed */ |
1336 | rxd->sdp0 = htole32(data->map->dm_segs[0].ds_addr); | | 1356 | rxd->sdp0 = htole32(data->map->dm_segs[0].ds_addr); |
1337 | ifp->if_ierrors++; | | 1357 | ifp->if_ierrors++; |
| @@ -1475,26 +1495,27 @@ rt2860_gp_intr(struct rt2860_softc *sc) | | | @@ -1475,26 +1495,27 @@ rt2860_gp_intr(struct rt2860_softc *sc) |
1475 | if (ic->ic_state == IEEE80211_S_SCAN) | | 1495 | if (ic->ic_state == IEEE80211_S_SCAN) |
1476 | ieee80211_next_scan(ic); | | 1496 | ieee80211_next_scan(ic); |
1477 | else if (ic->ic_state == IEEE80211_S_RUN) | | 1497 | else if (ic->ic_state == IEEE80211_S_RUN) |
1478 | rt2860_updatestats(sc); | | 1498 | rt2860_updatestats(sc); |
1479 | } | | 1499 | } |
1480 | | | 1500 | |
1481 | int | | 1501 | int |
1482 | rt2860_intr(void *arg) | | 1502 | rt2860_intr(void *arg) |
1483 | { | | 1503 | { |
1484 | struct rt2860_softc *sc = arg; | | 1504 | struct rt2860_softc *sc = arg; |
1485 | uint32_t r; | | 1505 | uint32_t r; |
1486 | | | 1506 | |
1487 | r = RAL_READ(sc, RT2860_INT_STATUS); | | 1507 | r = RAL_READ(sc, RT2860_INT_STATUS); |
| | | 1508 | DPRINTF(("intr %#x\n", r)); |
1488 | if (__predict_false(r == 0xffffffff)) | | 1509 | if (__predict_false(r == 0xffffffff)) |
1489 | return 0; /* device likely went away */ | | 1510 | return 0; /* device likely went away */ |
1490 | if (r == 0) | | 1511 | if (r == 0) |
1491 | return 0; /* not for us */ | | 1512 | return 0; /* not for us */ |
1492 | | | 1513 | |
1493 | /* acknowledge interrupts */ | | 1514 | /* acknowledge interrupts */ |
1494 | RAL_WRITE(sc, RT2860_INT_STATUS, r); | | 1515 | RAL_WRITE(sc, RT2860_INT_STATUS, r); |
1495 | | | 1516 | |
1496 | if (r & RT2860_TX_RX_COHERENT) | | 1517 | if (r & RT2860_TX_RX_COHERENT) |
1497 | rt2860_intr_coherent(sc); | | 1518 | rt2860_intr_coherent(sc); |
1498 | | | 1519 | |
1499 | if (r & RT2860_MAC_INT_2) /* TX status */ | | 1520 | if (r & RT2860_MAC_INT_2) /* TX status */ |
1500 | rt2860_drain_stats_fifo(sc); | | 1521 | rt2860_drain_stats_fifo(sc); |
| @@ -2343,27 +2364,128 @@ rt3090_set_chan(struct rt2860_softc *sc, | | | @@ -2343,27 +2364,128 @@ rt3090_set_chan(struct rt2860_softc *sc, |
2343 | /* program RF filter */ | | 2364 | /* program RF filter */ |
2344 | rf = rt3090_rf_read(sc, 24); /* Tx */ | | 2365 | rf = rt3090_rf_read(sc, 24); /* Tx */ |
2345 | rf = (rf & ~0x3f) | sc->rf24_20mhz; | | 2366 | rf = (rf & ~0x3f) | sc->rf24_20mhz; |
2346 | rt3090_rf_write(sc, 24, rf); | | 2367 | rt3090_rf_write(sc, 24, rf); |
2347 | rf = rt3090_rf_read(sc, 31); /* Rx */ | | 2368 | rf = rt3090_rf_read(sc, 31); /* Rx */ |
2348 | rf = (rf & ~0x3f) | sc->rf24_20mhz; | | 2369 | rf = (rf & ~0x3f) | sc->rf24_20mhz; |
2349 | rt3090_rf_write(sc, 31, rf); | | 2370 | rt3090_rf_write(sc, 31, rf); |
2350 | | | 2371 | |
2351 | /* enable RF tuning */ | | 2372 | /* enable RF tuning */ |
2352 | rf = rt3090_rf_read(sc, 7); | | 2373 | rf = rt3090_rf_read(sc, 7); |
2353 | rt3090_rf_write(sc, 7, rf | RT3070_TUNE); | | 2374 | rt3090_rf_write(sc, 7, rf | RT3070_TUNE); |
2354 | } | | 2375 | } |
2355 | | | 2376 | |
2356 | static int | | 2377 | static void |
| | | 2378 | rt5390_set_chan(struct rt2860_softc *sc, u_int chan) |
| | | 2379 | { |
| | | 2380 | uint8_t h20mhz, rf, tmp; |
| | | 2381 | int8_t txpow1, txpow2; |
| | | 2382 | int i; |
| | | 2383 | |
| | | 2384 | /* RT5390 is 2GHz only */ |
| | | 2385 | KASSERT(chan >= 1 && chan <= 14); |
| | | 2386 | |
| | | 2387 | /* find the settings for this channel (we know it exists) */ |
| | | 2388 | for (i = 0; rt2860_rf2850[i].chan != chan; i++); |
| | | 2389 | |
| | | 2390 | /* use Tx power values from EEPROM */ |
| | | 2391 | txpow1 = sc->txpow1[i]; |
| | | 2392 | txpow2 = sc->txpow2[i]; |
| | | 2393 | |
| | | 2394 | rt3090_rf_write(sc, 8, rt3090_freqs[i].n); |
| | | 2395 | rt3090_rf_write(sc, 9, rt3090_freqs[i].k & 0x0f); |
| | | 2396 | rf = rt3090_rf_read(sc, 11); |
| | | 2397 | rf = (rf & ~0x03) | (rt3090_freqs[i].r & 0x03); |
| | | 2398 | rt3090_rf_write(sc, 11, rf); |
| | | 2399 | |
| | | 2400 | rf = rt3090_rf_read(sc, 49); |
| | | 2401 | rf = (rf & ~0x3f) | (txpow1 & 0x3f); |
| | | 2402 | /* the valid range of the RF R49 is 0x00~0x27 */ |
| | | 2403 | if ((rf & 0x3f) > 0x27) |
| | | 2404 | rf = (rf & ~0x3f) | 0x27; |
| | | 2405 | rt3090_rf_write(sc, 49, rf); |
| | | 2406 | if (sc->mac_ver == 0x5392) { |
| | | 2407 | rf = rt3090_rf_read(sc, 50); |
| | | 2408 | rf = (rf & ~0x3f) | (txpow2 & 0x3f); |
| | | 2409 | /* the valid range of the RF R50 is 0x00~0x27 */ |
| | | 2410 | if ((rf & 0x3f) > 0x27) |
| | | 2411 | rf = (rf & ~0x3f) | 0x27; |
| | | 2412 | rt3090_rf_write(sc, 50, rf); |
| | | 2413 | } |
| | | 2414 | |
| | | 2415 | rf = rt3090_rf_read(sc, 1); |
| | | 2416 | rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | RT3070_TX0_PD; |
| | | 2417 | if (sc->mac_ver == 0x5392) |
| | | 2418 | rf |= RT3070_RX1_PD | RT3070_TX1_PD; |
| | | 2419 | rt3090_rf_write(sc, 1, rf); |
| | | 2420 | |
| | | 2421 | rf = rt3090_rf_read(sc, 2); |
| | | 2422 | rt3090_rf_write(sc, 2, rf | RT3593_RESCAL); |
| | | 2423 | DELAY(1000); |
| | | 2424 | rt3090_rf_write(sc, 2, rf & ~RT3593_RESCAL); |
| | | 2425 | |
| | | 2426 | rf = rt3090_rf_read(sc, 17); |
| | | 2427 | tmp = rf; |
| | | 2428 | rf = (rf & ~0x7f) | (sc->freq & 0x7f); |
| | | 2429 | rf = MIN(rf, 0x5f); |
| | | 2430 | if (tmp != rf) |
| | | 2431 | rt2860_mcu_cmd(sc, 0x74, (tmp << 8 ) | rf, 0); |
| | | 2432 | |
| | | 2433 | if (sc->mac_ver == 0x5390) { |
| | | 2434 | if (chan <= 4) |
| | | 2435 | rf = 0x73; |
| | | 2436 | else if (chan >= 5 && chan <= 6) |
| | | 2437 | rf = 0x63; |
| | | 2438 | else if (chan >= 7 && chan <= 10) |
| | | 2439 | rf = 0x53; |
| | | 2440 | else |
| | | 2441 | rf = 43; |
| | | 2442 | rt3090_rf_write(sc, 55, rf); |
| | | 2443 | |
| | | 2444 | if (chan == 1) |
| | | 2445 | rf = 0x0c; |
| | | 2446 | else if (chan == 2) |
| | | 2447 | rf = 0x0b; |
| | | 2448 | else if (chan == 3) |
| | | 2449 | rf = 0x0a; |
| | | 2450 | else if (chan >= 4 && chan <= 6) |
| | | 2451 | rf = 0x09; |
| | | 2452 | else if (chan >= 7 && chan <= 12) |
| | | 2453 | rf = 0x08; |
| | | 2454 | else if (chan == 13) |
| | | 2455 | rf = 0x07; |
| | | 2456 | else |
| | | 2457 | rf = 0x06; |
| | | 2458 | rt3090_rf_write(sc, 59, rf); |
| | | 2459 | } |
| | | 2460 | |
| | | 2461 | /* Tx/Rx h20M */ |
| | | 2462 | h20mhz = (sc->rf24_20mhz & 0x20) >> 5; |
| | | 2463 | rf = rt3090_rf_read(sc, 30); |
| | | 2464 | rf = (rf & ~0x06) | (h20mhz << 1) | (h20mhz << 2); |
| | | 2465 | rt3090_rf_write(sc, 30, rf); |
| | | 2466 | |
| | | 2467 | /* Rx BB filter VCM */ |
| | | 2468 | rf = rt3090_rf_read(sc, 30); |
| | | 2469 | rf = (rf & ~0x18) | 0x10; |
| | | 2470 | rt3090_rf_write(sc, 30, rf); |
| | | 2471 | |
| | | 2472 | /* Initiate VCO calibration. */ |
| | | 2473 | rf = rt3090_rf_read(sc, 3); |
| | | 2474 | rf |= RT3593_VCOCAL; |
| | | 2475 | rt3090_rf_write(sc, 3, rf); |
| | | 2476 | } |
| | | 2477 | |
| | | 2478 | static void |
2357 | rt3090_rf_init(struct rt2860_softc *sc) | | 2479 | rt3090_rf_init(struct rt2860_softc *sc) |
2358 | { | | 2480 | { |
2359 | uint32_t tmp; | | 2481 | uint32_t tmp; |
2360 | uint8_t rf, bbp; | | 2482 | uint8_t rf, bbp; |
2361 | int i; | | 2483 | int i; |
2362 | | | 2484 | |
2363 | rf = rt3090_rf_read(sc, 30); | | 2485 | rf = rt3090_rf_read(sc, 30); |
2364 | /* toggle RF R30 bit 7 */ | | 2486 | /* toggle RF R30 bit 7 */ |
2365 | rt3090_rf_write(sc, 30, rf | 0x80); | | 2487 | rt3090_rf_write(sc, 30, rf | 0x80); |
2366 | DELAY(1000); | | 2488 | DELAY(1000); |
2367 | rt3090_rf_write(sc, 30, rf & ~0x80); | | 2489 | rt3090_rf_write(sc, 30, rf & ~0x80); |
2368 | | | 2490 | |
2369 | tmp = RAL_READ(sc, RT3070_LDO_CFG0); | | 2491 | tmp = RAL_READ(sc, RT3070_LDO_CFG0); |
| @@ -2454,28 +2576,95 @@ rt3090_rf_init(struct rt2860_softc *sc) | | | @@ -2454,28 +2576,95 @@ rt3090_rf_init(struct rt2860_softc *sc) |
2454 | rf = rt3090_rf_read(sc, 17); | | 2576 | rf = rt3090_rf_read(sc, 17); |
2455 | rf &= ~RT3070_TX_LO1; | | 2577 | rf &= ~RT3070_TX_LO1; |
2456 | if (sc->mac_rev >= 0x0211 && !sc->ext_2ghz_lna) | | 2578 | if (sc->mac_rev >= 0x0211 && !sc->ext_2ghz_lna) |
2457 | rf |= 0x20; /* fix for long range Rx issue */ | | 2579 | rf |= 0x20; /* fix for long range Rx issue */ |
2458 | if (sc->txmixgain_2ghz >= 2) | | 2580 | if (sc->txmixgain_2ghz >= 2) |
2459 | rf = (rf & ~0x7) | sc->txmixgain_2ghz; | | 2581 | rf = (rf & ~0x7) | sc->txmixgain_2ghz; |
2460 | rt3090_rf_write(sc, 17, rf); | | 2582 | rt3090_rf_write(sc, 17, rf); |
2461 | | | 2583 | |
2462 | rf = rt3090_rf_read(sc, 20); | | 2584 | rf = rt3090_rf_read(sc, 20); |
2463 | rt3090_rf_write(sc, 20, rf & ~RT3070_RX_LO1); | | 2585 | rt3090_rf_write(sc, 20, rf & ~RT3070_RX_LO1); |
2464 | | | 2586 | |
2465 | rf = rt3090_rf_read(sc, 21); | | 2587 | rf = rt3090_rf_read(sc, 21); |
2466 | rt3090_rf_write(sc, 21, rf & ~RT3070_RX_LO2); | | 2588 | rt3090_rf_write(sc, 21, rf & ~RT3070_RX_LO2); |
| | | 2589 | } |
2467 | | | 2590 | |
2468 | return 0; | | 2591 | static void |
| | | 2592 | rt5390_rf_init(struct rt2860_softc *sc) |
| | | 2593 | { |
| | | 2594 | uint8_t rf, bbp; |
| | | 2595 | int i; |
| | | 2596 | |
| | | 2597 | rf = rt3090_rf_read(sc, 2); |
| | | 2598 | /* Toggle RF R2 bit 7. */ |
| | | 2599 | rt3090_rf_write(sc, 2, rf | RT3593_RESCAL); |
| | | 2600 | DELAY(1000); |
| | | 2601 | rt3090_rf_write(sc, 2, rf & ~RT3593_RESCAL); |
| | | 2602 | |
| | | 2603 | /* Initialize RF registers to default value. */ |
| | | 2604 | if (sc->mac_ver == 0x5392) { |
| | | 2605 | for (i = 0; i < __arraycount(rt5392_def_rf); i++) { |
| | | 2606 | rt3090_rf_write(sc, rt5392_def_rf[i].reg, |
| | | 2607 | rt5392_def_rf[i].val); |
| | | 2608 | } |
| | | 2609 | } else { |
| | | 2610 | for (i = 0; i < __arraycount(rt5390_def_rf); i++) { |
| | | 2611 | rt3090_rf_write(sc, rt5390_def_rf[i].reg, |
| | | 2612 | rt5390_def_rf[i].val); |
| | | 2613 | } |
| | | 2614 | } |
| | | 2615 | |
| | | 2616 | sc->rf24_20mhz = 0x1f; |
| | | 2617 | sc->rf24_40mhz = 0x2f; |
| | | 2618 | |
| | | 2619 | if (sc->mac_rev < 0x0211) |
| | | 2620 | rt3090_rf_write(sc, 27, 0x03); |
| | | 2621 | |
| | | 2622 | /* Set led open drain enable. */ |
| | | 2623 | RAL_WRITE(sc, RT3070_OPT_14, RAL_READ(sc, RT3070_OPT_14) | 1); |
| | | 2624 | |
| | | 2625 | RAL_WRITE(sc, RT2860_TX_SW_CFG1, 0); |
| | | 2626 | RAL_WRITE(sc, RT2860_TX_SW_CFG2, 0); |
| | | 2627 | |
| | | 2628 | if (sc->mac_ver == 0x5390) |
| | | 2629 | rt3090_set_rx_antenna(sc, 0); |
| | | 2630 | |
| | | 2631 | /* Patch RSSI inaccurate issue. */ |
| | | 2632 | rt2860_mcu_bbp_write(sc, 79, 0x13); |
| | | 2633 | rt2860_mcu_bbp_write(sc, 80, 0x05); |
| | | 2634 | rt2860_mcu_bbp_write(sc, 81, 0x33); |
| | | 2635 | |
| | | 2636 | /* Enable DC filter. */ |
| | | 2637 | if (sc->mac_rev >= 0x0211) |
| | | 2638 | rt2860_mcu_bbp_write(sc, 103, 0xc0); |
| | | 2639 | |
| | | 2640 | bbp = rt2860_mcu_bbp_read(sc, 138); |
| | | 2641 | if (sc->ntxchains == 1) |
| | | 2642 | bbp |= 0x20; /* Turn off DAC1. */ |
| | | 2643 | if (sc->nrxchains == 1) |
| | | 2644 | bbp &= ~0x02; /* Turn off ADC1. */ |
| | | 2645 | rt2860_mcu_bbp_write(sc, 138, bbp); |
| | | 2646 | |
| | | 2647 | /* Enable RX LO1 and LO2. */ |
| | | 2648 | rt3090_rf_write(sc, 38, rt3090_rf_read(sc, 38) & ~RT5390_RX_LO1); |
| | | 2649 | rt3090_rf_write(sc, 39, rt3090_rf_read(sc, 39) & ~RT5390_RX_LO2); |
| | | 2650 | |
| | | 2651 | /* Avoid data lost and CRC error. */ |
| | | 2652 | rt2860_mcu_bbp_write(sc, 4, |
| | | 2653 | rt2860_mcu_bbp_read(sc, 4) | RT5390_MAC_IF_CTRL); |
| | | 2654 | |
| | | 2655 | rf = rt3090_rf_read(sc, 30); |
| | | 2656 | rf = (rf & ~0x18) | 0x10; |
| | | 2657 | rt3090_rf_write(sc, 30, rf); |
2469 | } | | 2658 | } |
2470 | | | 2659 | |
2471 | static void | | 2660 | static void |
2472 | rt3090_rf_wakeup(struct rt2860_softc *sc) | | 2661 | rt3090_rf_wakeup(struct rt2860_softc *sc) |
2473 | { | | 2662 | { |
2474 | uint32_t tmp; | | 2663 | uint32_t tmp; |
2475 | uint8_t rf; | | 2664 | uint8_t rf; |
2476 | | | 2665 | |
2477 | if (sc->mac_ver == 0x3593) { | | 2666 | if (sc->mac_ver == 0x3593) { |
2478 | /* enable VCO */ | | 2667 | /* enable VCO */ |
2479 | rf = rt3090_rf_read(sc, 1); | | 2668 | rf = rt3090_rf_read(sc, 1); |
2480 | rt3090_rf_write(sc, 1, rf | RT3593_VCO); | | 2669 | rt3090_rf_write(sc, 1, rf | RT3593_VCO); |
2481 | | | 2670 | |
| @@ -2524,26 +2713,62 @@ rt3090_rf_wakeup(struct rt2860_softc *sc | | | @@ -2524,26 +2713,62 @@ rt3090_rf_wakeup(struct rt2860_softc *sc |
2524 | rf = rt3090_rf_read(sc, 27); | | 2713 | rf = rt3090_rf_read(sc, 27); |
2525 | rf &= ~0x77; | | 2714 | rf &= ~0x77; |
2526 | if (sc->mac_rev < 0x0211) | | 2715 | if (sc->mac_rev < 0x0211) |
2527 | rf |= 0x03; | | 2716 | rf |= 0x03; |
2528 | rt3090_rf_write(sc, 27, rf); | | 2717 | rt3090_rf_write(sc, 27, rf); |
2529 | } | | 2718 | } |
2530 | if (sc->patch_dac && sc->mac_rev < 0x0211) { | | 2719 | if (sc->patch_dac && sc->mac_rev < 0x0211) { |
2531 | tmp = RAL_READ(sc, RT3070_LDO_CFG0); | | 2720 | tmp = RAL_READ(sc, RT3070_LDO_CFG0); |
2532 | tmp = (tmp & ~0x1f000000) | 0x0d000000; | | 2721 | tmp = (tmp & ~0x1f000000) | 0x0d000000; |
2533 | RAL_WRITE(sc, RT3070_LDO_CFG0, tmp); | | 2722 | RAL_WRITE(sc, RT3070_LDO_CFG0, tmp); |
2534 | } | | 2723 | } |
2535 | } | | 2724 | } |
2536 | | | 2725 | |
| | | 2726 | static void |
| | | 2727 | rt5390_rf_wakeup(struct rt2860_softc *sc) |
| | | 2728 | { |
| | | 2729 | uint32_t tmp; |
| | | 2730 | uint8_t rf; |
| | | 2731 | |
| | | 2732 | rf = rt3090_rf_read(sc, 1); |
| | | 2733 | rf |= RT3070_RF_BLOCK | RT3070_PLL_PD | RT3070_RX0_PD | |
| | | 2734 | RT3070_TX0_PD; |
| | | 2735 | if (sc->mac_ver == 0x5392) |
| | | 2736 | rf |= RT3070_RX1_PD | RT3070_TX1_PD; |
| | | 2737 | rt3090_rf_write(sc, 1, rf); |
| | | 2738 | |
| | | 2739 | rf = rt3090_rf_read(sc, 6); |
| | | 2740 | rf |= RT3593_VCO_IC | RT3593_VCOCAL; |
| | | 2741 | if (sc->mac_ver == 0x5390) |
| | | 2742 | rf &= ~RT3593_VCO_IC; |
| | | 2743 | rt3090_rf_write(sc, 6, rf); |
| | | 2744 | |
| | | 2745 | rt3090_rf_write(sc, 2, rt3090_rf_read(sc, 2) | RT3593_RESCAL); |
| | | 2746 | |
| | | 2747 | rf = rt3090_rf_read(sc, 22); |
| | | 2748 | rf = (rf & ~0xe0) | 0x20; |
| | | 2749 | rt3090_rf_write(sc, 22, rf); |
| | | 2750 | |
| | | 2751 | rt3090_rf_write(sc, 42, rt3090_rf_read(sc, 42) | RT5390_RX_CTB); |
| | | 2752 | rt3090_rf_write(sc, 20, rt3090_rf_read(sc, 20) & ~0x77); |
| | | 2753 | rt3090_rf_write(sc, 3, rt3090_rf_read(sc, 3) | RT3593_VCOCAL); |
| | | 2754 | |
| | | 2755 | if (sc->patch_dac && sc->mac_rev < 0x0211) { |
| | | 2756 | tmp = RAL_READ(sc, RT3070_LDO_CFG0); |
| | | 2757 | tmp = (tmp & ~0x1f000000) | 0x0d000000; |
| | | 2758 | RAL_WRITE(sc, RT3070_LDO_CFG0, tmp); |
| | | 2759 | } |
| | | 2760 | } |
| | | 2761 | |
2537 | static int | | 2762 | static int |
2538 | rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target, | | 2763 | rt3090_filter_calib(struct rt2860_softc *sc, uint8_t init, uint8_t target, |
2539 | uint8_t *val) | | 2764 | uint8_t *val) |
2540 | { | | 2765 | { |
2541 | uint8_t rf22, rf24; | | 2766 | uint8_t rf22, rf24; |
2542 | uint8_t bbp55_pb, bbp55_sb, delta; | | 2767 | uint8_t bbp55_pb, bbp55_sb, delta; |
2543 | int ntries; | | 2768 | int ntries; |
2544 | | | 2769 | |
2545 | /* program filter */ | | 2770 | /* program filter */ |
2546 | rf24 = rt3090_rf_read(sc, 24); | | 2771 | rf24 = rt3090_rf_read(sc, 24); |
2547 | rf24 = (rf24 & 0xc0) | init; /* initial filter value */ | | 2772 | rf24 = (rf24 & 0xc0) | init; /* initial filter value */ |
2548 | rt3090_rf_write(sc, 24, rf24); | | 2773 | rt3090_rf_write(sc, 24, rf24); |
2549 | | | 2774 | |
| @@ -2938,26 +3163,27 @@ rt2860_get_rf(uint8_t rev) | | | @@ -2938,26 +3163,27 @@ rt2860_get_rf(uint8_t rev) |
2938 | { | | 3163 | { |
2939 | switch (rev) { | | 3164 | switch (rev) { |
2940 | case RT2860_RF_2820: return "RT2820"; | | 3165 | case RT2860_RF_2820: return "RT2820"; |
2941 | case RT2860_RF_2850: return "RT2850"; | | 3166 | case RT2860_RF_2850: return "RT2850"; |
2942 | case RT2860_RF_2720: return "RT2720"; | | 3167 | case RT2860_RF_2720: return "RT2720"; |
2943 | case RT2860_RF_2750: return "RT2750"; | | 3168 | case RT2860_RF_2750: return "RT2750"; |
2944 | case RT3070_RF_3020: return "RT3020"; | | 3169 | case RT3070_RF_3020: return "RT3020"; |
2945 | case RT3070_RF_2020: return "RT2020"; | | 3170 | case RT3070_RF_2020: return "RT2020"; |
2946 | case RT3070_RF_3021: return "RT3021"; | | 3171 | case RT3070_RF_3021: return "RT3021"; |
2947 | case RT3070_RF_3022: return "RT3022"; | | 3172 | case RT3070_RF_3022: return "RT3022"; |
2948 | case RT3070_RF_3052: return "RT3052"; | | 3173 | case RT3070_RF_3052: return "RT3052"; |
2949 | case RT3070_RF_3320: return "RT3320"; | | 3174 | case RT3070_RF_3320: return "RT3320"; |
2950 | case RT3070_RF_3053: return "RT3053"; | | 3175 | case RT3070_RF_3053: return "RT3053"; |
| | | 3176 | case RT5390_RF_5390: return "RT5390"; |
2951 | default: return "unknown"; | | 3177 | default: return "unknown"; |
2952 | } | | 3178 | } |
2953 | } | | 3179 | } |
2954 | | | 3180 | |
2955 | static int | | 3181 | static int |
2956 | rt2860_read_eeprom(struct rt2860_softc *sc) | | 3182 | rt2860_read_eeprom(struct rt2860_softc *sc) |
2957 | { | | 3183 | { |
2958 | struct ieee80211com *ic = &sc->sc_ic; | | 3184 | struct ieee80211com *ic = &sc->sc_ic; |
2959 | int8_t delta_2ghz, delta_5ghz; | | 3185 | int8_t delta_2ghz, delta_5ghz; |
2960 | uint32_t tmp; | | 3186 | uint32_t tmp; |
2961 | uint16_t val; | | 3187 | uint16_t val; |
2962 | int ridx, ant, i; | | 3188 | int ridx, ant, i; |
2963 | | | 3189 | |
| @@ -3039,28 +3265,33 @@ rt2860_read_eeprom(struct rt2860_softc * | | | @@ -3039,28 +3265,33 @@ rt2860_read_eeprom(struct rt2860_softc * |
3039 | } else if (sc->mac_ver >= 0x3071) { | | 3265 | } else if (sc->mac_ver >= 0x3071) { |
3040 | /* default to RF3020 1T1R */ | | 3266 | /* default to RF3020 1T1R */ |
3041 | sc->rf_rev = RT3070_RF_3020; | | 3267 | sc->rf_rev = RT3070_RF_3020; |
3042 | sc->ntxchains = 1; | | 3268 | sc->ntxchains = 1; |
3043 | sc->nrxchains = 1; | | 3269 | sc->nrxchains = 1; |
3044 | } else { | | 3270 | } else { |
3045 | /* default to RF2820 1T2R */ | | 3271 | /* default to RF2820 1T2R */ |
3046 | sc->rf_rev = RT2860_RF_2820; | | 3272 | sc->rf_rev = RT2860_RF_2820; |
3047 | sc->ntxchains = 1; | | 3273 | sc->ntxchains = 1; |
3048 | sc->nrxchains = 2; | | 3274 | sc->nrxchains = 2; |
3049 | } | | 3275 | } |
3050 | } else { | | 3276 | } else { |
3051 | sc->rf_rev = (val >> 8) & 0xf; | | 3277 | sc->rf_rev = (val >> 8) & 0xf; |
3052 | sc->ntxchains = (val >> 4) & 0xf; | | 3278 | if (sc->mac_ver >= 0x5390) { |
3053 | sc->nrxchains = val & 0xf; | | 3279 | sc->ntxchains = (sc->mac_ver == 0x5392) ? 2 : 1; |
| | | 3280 | sc->nrxchains = (sc->mac_ver == 0x5392) ? 2 : 1; |
| | | 3281 | } else { |
| | | 3282 | sc->ntxchains = (val >> 4) & 0xf; |
| | | 3283 | sc->nrxchains = val & 0xf; |
| | | 3284 | } |
3054 | } | | 3285 | } |
3055 | DPRINTF(("EEPROM RF rev=0x%02x chains=%dT%dR\n", | | 3286 | DPRINTF(("EEPROM RF rev=0x%02x chains=%dT%dR\n", |
3056 | sc->rf_rev, sc->ntxchains, sc->nrxchains)); | | 3287 | sc->rf_rev, sc->ntxchains, sc->nrxchains)); |
3057 | | | 3288 | |
3058 | /* check if RF supports automatic Tx access gain control */ | | 3289 | /* check if RF supports automatic Tx access gain control */ |
3059 | val = rt2860_srom_read(sc, RT2860_EEPROM_CONFIG); | | 3290 | val = rt2860_srom_read(sc, RT2860_EEPROM_CONFIG); |
3060 | DPRINTF(("EEPROM CFG 0x%04x\n", val)); | | 3291 | DPRINTF(("EEPROM CFG 0x%04x\n", val)); |
3061 | /* check if driver should patch the DAC issue */ | | 3292 | /* check if driver should patch the DAC issue */ |
3062 | if ((val >> 8) != 0xff) | | 3293 | if ((val >> 8) != 0xff) |
3063 | sc->patch_dac = (val >> 15) & 1; | | 3294 | sc->patch_dac = (val >> 15) & 1; |
3064 | if ((val & 0xff) != 0xff) { | | 3295 | if ((val & 0xff) != 0xff) { |
3065 | sc->ext_5ghz_lna = (val >> 3) & 1; | | 3296 | sc->ext_5ghz_lna = (val >> 3) & 1; |
3066 | sc->ext_2ghz_lna = (val >> 2) & 1; | | 3297 | sc->ext_2ghz_lna = (val >> 2) & 1; |
| @@ -3078,37 +3309,43 @@ rt2860_read_eeprom(struct rt2860_softc * | | | @@ -3078,37 +3309,43 @@ rt2860_read_eeprom(struct rt2860_softc * |
3078 | if ((val & 0xff80) != 0x9280) | | 3309 | if ((val & 0xff80) != 0x9280) |
3079 | sc->pslevel = MIN(sc->pslevel, 1); | | 3310 | sc->pslevel = MIN(sc->pslevel, 1); |
3080 | DPRINTF(("EEPROM PCIe PS Level=%d\n", sc->pslevel)); | | 3311 | DPRINTF(("EEPROM PCIe PS Level=%d\n", sc->pslevel)); |
3081 | } | | 3312 | } |
3082 | } | | 3313 | } |
3083 | | | 3314 | |
3084 | /* read power settings for 2GHz channels */ | | 3315 | /* read power settings for 2GHz channels */ |
3085 | for (i = 0; i < 14; i += 2) { | | 3316 | for (i = 0; i < 14; i += 2) { |
3086 | val = rt2860_srom_read(sc, | | 3317 | val = rt2860_srom_read(sc, |
3087 | RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2); | | 3318 | RT2860_EEPROM_PWR2GHZ_BASE1 + i / 2); |
3088 | sc->txpow1[i + 0] = (int8_t)(val & 0xff); | | 3319 | sc->txpow1[i + 0] = (int8_t)(val & 0xff); |
3089 | sc->txpow1[i + 1] = (int8_t)(val >> 8); | | 3320 | sc->txpow1[i + 1] = (int8_t)(val >> 8); |
3090 | | | 3321 | |
3091 | val = rt2860_srom_read(sc, | | 3322 | if (sc->mac_ver != 0x5390) { |
3092 | RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2); | | 3323 | val = rt2860_srom_read(sc, |
3093 | sc->txpow2[i + 0] = (int8_t)(val & 0xff); | | 3324 | RT2860_EEPROM_PWR2GHZ_BASE2 + i / 2); |
3094 | sc->txpow2[i + 1] = (int8_t)(val >> 8); | | 3325 | sc->txpow2[i + 0] = (int8_t)(val & 0xff); |
3095 | } | | 3326 | sc->txpow2[i + 1] = (int8_t)(val >> 8); |
| | | 3327 | } |
| | | 3328 | } |
3096 | /* fix broken Tx power entries */ | | 3329 | /* fix broken Tx power entries */ |
3097 | for (i = 0; i < 14; i++) { | | 3330 | for (i = 0; i < 14; i++) { |
3098 | if (sc->txpow1[i] < 0 || sc->txpow1[i] > 31) | | 3331 | if (sc->txpow1[i] < 0 || |
| | | 3332 | sc->txpow1[i] > ((sc->mac_ver >= 0x5390) ? 39 : 31)) |
3099 | sc->txpow1[i] = 5; | | 3333 | sc->txpow1[i] = 5; |
3100 | if (sc->txpow2[i] < 0 || sc->txpow2[i] > 31) | | 3334 | if (sc->mac_ver != 0x5390) { |
3101 | sc->txpow2[i] = 5; | | 3335 | if (sc->txpow2[i] < 0 || |
| | | 3336 | sc->txpow2[i] > ((sc->mac_ver >= 0x5390) ? 39 : 31)) |
| | | 3337 | sc->txpow2[i] = 5; |
| | | 3338 | } |
3102 | DPRINTF(("chan %d: power1=%d, power2=%d\n", | | 3339 | DPRINTF(("chan %d: power1=%d, power2=%d\n", |
3103 | rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i])); | | 3340 | rt2860_rf2850[i].chan, sc->txpow1[i], sc->txpow2[i])); |
3104 | } | | 3341 | } |
3105 | /* read power settings for 5GHz channels */ | | 3342 | /* read power settings for 5GHz channels */ |
3106 | for (i = 0; i < 40; i += 2) { | | 3343 | for (i = 0; i < 40; i += 2) { |
3107 | val = rt2860_srom_read(sc, | | 3344 | val = rt2860_srom_read(sc, |
3108 | RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2); | | 3345 | RT2860_EEPROM_PWR5GHZ_BASE1 + i / 2); |
3109 | sc->txpow1[i + 14] = (int8_t)(val & 0xff); | | 3346 | sc->txpow1[i + 14] = (int8_t)(val & 0xff); |
3110 | sc->txpow1[i + 15] = (int8_t)(val >> 8); | | 3347 | sc->txpow1[i + 15] = (int8_t)(val >> 8); |
3111 | | | 3348 | |
3112 | val = rt2860_srom_read(sc, | | 3349 | val = rt2860_srom_read(sc, |
3113 | RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2); | | 3350 | RT2860_EEPROM_PWR5GHZ_BASE2 + i / 2); |
3114 | sc->txpow2[i + 14] = (int8_t)(val & 0xff); | | 3351 | sc->txpow2[i + 14] = (int8_t)(val & 0xff); |
| @@ -3274,48 +3511,92 @@ rt2860_bbp_init(struct rt2860_softc *sc) | | | @@ -3274,48 +3511,92 @@ rt2860_bbp_init(struct rt2860_softc *sc) |
3274 | /* wait for BBP to wake up */ | | 3511 | /* wait for BBP to wake up */ |
3275 | for (ntries = 0; ntries < 20; ntries++) { | | 3512 | for (ntries = 0; ntries < 20; ntries++) { |
3276 | uint8_t bbp0 = rt2860_mcu_bbp_read(sc, 0); | | 3513 | uint8_t bbp0 = rt2860_mcu_bbp_read(sc, 0); |
3277 | if (bbp0 != 0 && bbp0 != 0xff) | | 3514 | if (bbp0 != 0 && bbp0 != 0xff) |
3278 | break; | | 3515 | break; |
3279 | } | | 3516 | } |
3280 | if (ntries == 20) { | | 3517 | if (ntries == 20) { |
3281 | aprint_error_dev(sc->sc_dev, | | 3518 | aprint_error_dev(sc->sc_dev, |
3282 | "timeout waiting for BBP to wake up\n"); | | 3519 | "timeout waiting for BBP to wake up\n"); |
3283 | return ETIMEDOUT; | | 3520 | return ETIMEDOUT; |
3284 | } | | 3521 | } |
3285 | | | 3522 | |
3286 | /* initialize BBP registers to default values */ | | 3523 | /* initialize BBP registers to default values */ |
3287 | for (i = 0; i < (int)__arraycount(rt2860_def_bbp); i++) { | | 3524 | if (sc->mac_ver >= 0x5390) |
3288 | rt2860_mcu_bbp_write(sc, rt2860_def_bbp[i].reg, | | 3525 | rt5390_bbp_init(sc); |
3289 | rt2860_def_bbp[i].val); | | 3526 | else { |
| | | 3527 | for (i = 0; i < (int)__arraycount(rt2860_def_bbp); i++) { |
| | | 3528 | rt2860_mcu_bbp_write(sc, rt2860_def_bbp[i].reg, |
| | | 3529 | rt2860_def_bbp[i].val); |
| | | 3530 | } |
3290 | } | | 3531 | } |
3291 | | | 3532 | |
3292 | /* fix BBP84 for RT2860E */ | | 3533 | /* fix BBP84 for RT2860E */ |
3293 | if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101) | | 3534 | if (sc->mac_ver == 0x2860 && sc->mac_rev != 0x0101) |
3294 | rt2860_mcu_bbp_write(sc, 84, 0x19); | | 3535 | rt2860_mcu_bbp_write(sc, 84, 0x19); |
3295 | | | 3536 | |
3296 | if (sc->mac_ver >= 0x3071) { | | 3537 | if (sc->mac_ver >= 0x3071) { |
3297 | rt2860_mcu_bbp_write(sc, 79, 0x13); | | 3538 | rt2860_mcu_bbp_write(sc, 79, 0x13); |
3298 | rt2860_mcu_bbp_write(sc, 80, 0x05); | | 3539 | rt2860_mcu_bbp_write(sc, 80, 0x05); |
3299 | rt2860_mcu_bbp_write(sc, 81, 0x33); | | 3540 | rt2860_mcu_bbp_write(sc, 81, 0x33); |
3300 | } else if (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) { | | 3541 | } else if (sc->mac_ver == 0x2860 && sc->mac_rev == 0x0100) { |
3301 | rt2860_mcu_bbp_write(sc, 69, 0x16); | | 3542 | rt2860_mcu_bbp_write(sc, 69, 0x16); |
3302 | rt2860_mcu_bbp_write(sc, 73, 0x12); | | 3543 | rt2860_mcu_bbp_write(sc, 73, 0x12); |
3303 | } | | 3544 | } |
3304 | | | 3545 | |
3305 | return 0; | | 3546 | return 0; |
3306 | } | | 3547 | } |
3307 | | | 3548 | |
3308 | static int | | 3549 | static int |
| | | 3550 | rt5390_bbp_init(struct rt2860_softc *sc) |
| | | 3551 | { |
| | | 3552 | uint8_t bbp; |
| | | 3553 | int i; |
| | | 3554 | |
| | | 3555 | /* Apply maximum likelihood detection for 2 stream case. */ |
| | | 3556 | if (sc->nrxchains > 1) { |
| | | 3557 | bbp = rt2860_mcu_bbp_read(sc, 105); |
| | | 3558 | rt2860_mcu_bbp_write(sc, 105, bbp | RT5390_MLD); |
| | | 3559 | } |
| | | 3560 | |
| | | 3561 | /* Avoid data lost and CRC error. */ |
| | | 3562 | bbp = rt2860_mcu_bbp_read(sc, 4); |
| | | 3563 | rt2860_mcu_bbp_write(sc, 4, bbp | RT5390_MAC_IF_CTRL); |
| | | 3564 | |
| | | 3565 | for (i = 0; i < __arraycount(rt5390_def_bbp); i++) { |
| | | 3566 | rt2860_mcu_bbp_write(sc, rt5390_def_bbp[i].reg, |
| | | 3567 | rt5390_def_bbp[i].val); |
| | | 3568 | } |
| | | 3569 | |
| | | 3570 | if (sc->mac_ver == 0x5392) { |
| | | 3571 | rt2860_mcu_bbp_write(sc, 84, 0x9a); |
| | | 3572 | rt2860_mcu_bbp_write(sc, 95, 0x9a); |
| | | 3573 | rt2860_mcu_bbp_write(sc, 98, 0x12); |
| | | 3574 | rt2860_mcu_bbp_write(sc, 106, 0x05); |
| | | 3575 | rt2860_mcu_bbp_write(sc, 134, 0xd0); |
| | | 3576 | rt2860_mcu_bbp_write(sc, 135, 0xf6); |
| | | 3577 | } |
| | | 3578 | |
| | | 3579 | bbp = rt2860_mcu_bbp_read(sc, 152); |
| | | 3580 | rt2860_mcu_bbp_write(sc, 152, bbp | 0x80); |
| | | 3581 | |
| | | 3582 | /* Disable hardware antenna diversity. */ |
| | | 3583 | if (sc->mac_ver == 0x5390) |
| | | 3584 | rt2860_mcu_bbp_write(sc, 154, 0); |
| | | 3585 | |
| | | 3586 | return 0; |
| | | 3587 | } |
| | | 3588 | |
| | | 3589 | static int |
3309 | rt2860_txrx_enable(struct rt2860_softc *sc) | | 3590 | rt2860_txrx_enable(struct rt2860_softc *sc) |
3310 | { | | 3591 | { |
3311 | uint32_t tmp; | | 3592 | uint32_t tmp; |
3312 | int ntries; | | 3593 | int ntries; |
3313 | | | 3594 | |
3314 | /* enable Tx/Rx DMA engine */ | | 3595 | /* enable Tx/Rx DMA engine */ |
3315 | RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_TX_EN); | | 3596 | RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_TX_EN); |
3316 | RAL_BARRIER_READ_WRITE(sc); | | 3597 | RAL_BARRIER_READ_WRITE(sc); |
3317 | for (ntries = 0; ntries < 200; ntries++) { | | 3598 | for (ntries = 0; ntries < 200; ntries++) { |
3318 | tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); | | 3599 | tmp = RAL_READ(sc, RT2860_WPDMA_GLO_CFG); |
3319 | if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) | | 3600 | if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) |
3320 | break; | | 3601 | break; |
3321 | DELAY(1000); | | 3602 | DELAY(1000); |
| @@ -3430,27 +3711,29 @@ rt2860_init(struct ifnet *ifp) | | | @@ -3430,27 +3711,29 @@ rt2860_init(struct ifnet *ifp) |
3430 | /* PBF hardware reset */ | | 3711 | /* PBF hardware reset */ |
3431 | RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe1f); | | 3712 | RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe1f); |
3432 | RAL_BARRIER_WRITE(sc); | | 3713 | RAL_BARRIER_WRITE(sc); |
3433 | RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe00); | | 3714 | RAL_WRITE(sc, RT2860_SYS_CTRL, 0xe00); |
3434 | | | 3715 | |
3435 | RAL_WRITE(sc, RT2860_PWR_PIN_CFG, RT2860_IO_RA_PE | RT2860_IO_RF_PE); | | 3716 | RAL_WRITE(sc, RT2860_PWR_PIN_CFG, RT2860_IO_RA_PE | RT2860_IO_RF_PE); |
3436 | | | 3717 | |
3437 | RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_BBP_HRST | RT2860_MAC_SRST); | | 3718 | RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, RT2860_BBP_HRST | RT2860_MAC_SRST); |
3438 | RAL_BARRIER_WRITE(sc); | | 3719 | RAL_BARRIER_WRITE(sc); |
3439 | RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, 0); | | 3720 | RAL_WRITE(sc, RT2860_MAC_SYS_CTRL, 0); |
3440 | | | 3721 | |
3441 | for (i = 0; i < (int)__arraycount(rt2860_def_mac); i++) | | 3722 | for (i = 0; i < (int)__arraycount(rt2860_def_mac); i++) |
3442 | RAL_WRITE(sc, rt2860_def_mac[i].reg, rt2860_def_mac[i].val); | | 3723 | RAL_WRITE(sc, rt2860_def_mac[i].reg, rt2860_def_mac[i].val); |
3443 | if (sc->mac_ver >= 0x3071) { | | 3724 | if (sc->mac_ver >= 0x5390) |
| | | 3725 | RAL_WRITE(sc, RT2860_TX_SW_CFG0, 0x00000404); |
| | | 3726 | else if (sc->mac_ver >= 0x3071) { |
3444 | /* set delay of PA_PE assertion to 1us (unit of 0.25us) */ | | 3727 | /* set delay of PA_PE assertion to 1us (unit of 0.25us) */ |
3445 | RAL_WRITE(sc, RT2860_TX_SW_CFG0, | | 3728 | RAL_WRITE(sc, RT2860_TX_SW_CFG0, |
3446 | 4 << RT2860_DLY_PAPE_EN_SHIFT); | | 3729 | 4 << RT2860_DLY_PAPE_EN_SHIFT); |
3447 | } | | 3730 | } |
3448 | | | 3731 | |
3449 | if (!(RAL_READ(sc, RT2860_PCI_CFG) & RT2860_PCI_CFG_PCI)) { | | 3732 | if (!(RAL_READ(sc, RT2860_PCI_CFG) & RT2860_PCI_CFG_PCI)) { |
3450 | sc->sc_flags |= RT2860_PCIE; | | 3733 | sc->sc_flags |= RT2860_PCIE; |
3451 | /* PCIe has different clock cycle count than PCI */ | | 3734 | /* PCIe has different clock cycle count than PCI */ |
3452 | tmp = RAL_READ(sc, RT2860_US_CYC_CNT); | | 3735 | tmp = RAL_READ(sc, RT2860_US_CYC_CNT); |
3453 | tmp = (tmp & ~0xff) | 0x7d; | | 3736 | tmp = (tmp & ~0xff) | 0x7d; |
3454 | RAL_WRITE(sc, RT2860_US_CYC_CNT, tmp); | | 3737 | RAL_WRITE(sc, RT2860_US_CYC_CNT, tmp); |
3455 | } | | 3738 | } |
3456 | | | 3739 | |
| @@ -3534,33 +3817,37 @@ rt2860_init(struct ifnet *ifp) | | | @@ -3534,33 +3817,37 @@ rt2860_init(struct ifnet *ifp) |
3534 | } | | 3817 | } |
3535 | | | 3818 | |
3536 | /* select Main antenna for 1T1R devices */ | | 3819 | /* select Main antenna for 1T1R devices */ |
3537 | if (sc->rf_rev == RT3070_RF_2020 || | | 3820 | if (sc->rf_rev == RT3070_RF_2020 || |
3538 | sc->rf_rev == RT3070_RF_3020 || | | 3821 | sc->rf_rev == RT3070_RF_3020 || |
3539 | sc->rf_rev == RT3070_RF_3320) | | 3822 | sc->rf_rev == RT3070_RF_3320) |
3540 | rt3090_set_rx_antenna(sc, 0); | | 3823 | rt3090_set_rx_antenna(sc, 0); |
3541 | | | 3824 | |
3542 | /* send LEDs operating mode to microcontroller */ | | 3825 | /* send LEDs operating mode to microcontroller */ |
3543 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED1, sc->led[0], 0); | | 3826 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED1, sc->led[0], 0); |
3544 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1], 0); | | 3827 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED2, sc->led[1], 0); |
3545 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2], 0); | | 3828 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_LED3, sc->led[2], 0); |
3546 | | | 3829 | |
3547 | if (sc->mac_ver >= 0x3071) | | 3830 | if (sc->mac_ver >= 0x5390) |
| | | 3831 | rt5390_rf_init(sc); |
| | | 3832 | else if (sc->mac_ver >= 0x3071) |
3548 | rt3090_rf_init(sc); | | 3833 | rt3090_rf_init(sc); |
3549 | | | 3834 | |
3550 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_SLEEP, 0x02ff, 1); | | 3835 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_SLEEP, 0x02ff, 1); |
3551 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_WAKEUP, 0, 1); | | 3836 | rt2860_mcu_cmd(sc, RT2860_MCU_CMD_WAKEUP, 0, 1); |
3552 | | | 3837 | |
3553 | if (sc->mac_ver >= 0x3071) | | 3838 | if (sc->mac_ver >= 0x5390) |
| | | 3839 | rt5390_rf_wakeup(sc); |
| | | 3840 | else if (sc->mac_ver >= 0x3071) |
3554 | rt3090_rf_wakeup(sc); | | 3841 | rt3090_rf_wakeup(sc); |
3555 | | | 3842 | |
3556 | /* disable non-existing Rx chains */ | | 3843 | /* disable non-existing Rx chains */ |
3557 | bbp3 = rt2860_mcu_bbp_read(sc, 3); | | 3844 | bbp3 = rt2860_mcu_bbp_read(sc, 3); |
3558 | bbp3 &= ~(1 << 3 | 1 << 4); | | 3845 | bbp3 &= ~(1 << 3 | 1 << 4); |
3559 | if (sc->nrxchains == 2) | | 3846 | if (sc->nrxchains == 2) |
3560 | bbp3 |= 1 << 3; | | 3847 | bbp3 |= 1 << 3; |
3561 | else if (sc->nrxchains == 3) | | 3848 | else if (sc->nrxchains == 3) |
3562 | bbp3 |= 1 << 4; | | 3849 | bbp3 |= 1 << 4; |
3563 | rt2860_mcu_bbp_write(sc, 3, bbp3); | | 3850 | rt2860_mcu_bbp_write(sc, 3, bbp3); |
3564 | | | 3851 | |
3565 | /* disable non-existing Tx chains */ | | 3852 | /* disable non-existing Tx chains */ |
3566 | bbp1 = rt2860_mcu_bbp_read(sc, 1); | | 3853 | bbp1 = rt2860_mcu_bbp_read(sc, 1); |
| @@ -3767,43 +4054,46 @@ rt3090_set_rx_antenna(struct rt2860_soft | | | @@ -3767,43 +4054,46 @@ rt3090_set_rx_antenna(struct rt2860_soft |
3767 | } | | 4054 | } |
3768 | } | | 4055 | } |
3769 | | | 4056 | |
3770 | static void | | 4057 | static void |
3771 | rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c) | | 4058 | rt2860_switch_chan(struct rt2860_softc *sc, struct ieee80211_channel *c) |
3772 | { | | 4059 | { |
3773 | struct ieee80211com *ic = &sc->sc_ic; | | 4060 | struct ieee80211com *ic = &sc->sc_ic; |
3774 | u_int chan, group; | | 4061 | u_int chan, group; |
3775 | | | 4062 | |
3776 | chan = ieee80211_chan2ieee(ic, c); | | 4063 | chan = ieee80211_chan2ieee(ic, c); |
3777 | if (chan == 0 || chan == IEEE80211_CHAN_ANY) | | 4064 | if (chan == 0 || chan == IEEE80211_CHAN_ANY) |
3778 | return; | | 4065 | return; |
3779 | | | 4066 | |
3780 | if (sc->mac_ver >= 0x3071) | | 4067 | if (sc->mac_ver >= 0x5390) |
| | | 4068 | rt5390_set_chan(sc, chan); |
| | | 4069 | else if (sc->mac_ver >= 0x3071) |
3781 | rt3090_set_chan(sc, chan); | | 4070 | rt3090_set_chan(sc, chan); |
3782 | else | | 4071 | else |
3783 | rt2860_set_chan(sc, chan); | | 4072 | rt2860_set_chan(sc, chan); |
3784 | | | 4073 | |
3785 | /* determine channel group */ | | 4074 | /* determine channel group */ |
3786 | if (chan <= 14) | | 4075 | if (chan <= 14) |
3787 | group = 0; | | 4076 | group = 0; |
3788 | else if (chan <= 64) | | 4077 | else if (chan <= 64) |
3789 | group = 1; | | 4078 | group = 1; |
3790 | else if (chan <= 128) | | 4079 | else if (chan <= 128) |
3791 | group = 2; | | 4080 | group = 2; |
3792 | else | | 4081 | else |
3793 | group = 3; | | 4082 | group = 3; |
3794 | | | 4083 | |
3795 | /* XXX necessary only when group has changed! */ | | 4084 | /* XXX necessary only when group has changed! */ |
3796 | rt2860_select_chan_group(sc, group); | | 4085 | if (sc->mac_ver < 0x5390) |
| | | 4086 | rt2860_select_chan_group(sc, group); |
3797 | | | 4087 | |
3798 | DELAY(1000); | | 4088 | DELAY(1000); |
3799 | } | | 4089 | } |
3800 | | | 4090 | |
3801 | #ifndef IEEE80211_STA_ONLY | | 4091 | #ifndef IEEE80211_STA_ONLY |
3802 | static int | | 4092 | static int |
3803 | rt2860_setup_beacon(struct rt2860_softc *sc) | | 4093 | rt2860_setup_beacon(struct rt2860_softc *sc) |
3804 | { | | 4094 | { |
3805 | struct ieee80211com *ic = &sc->sc_ic; | | 4095 | struct ieee80211com *ic = &sc->sc_ic; |
3806 | struct rt2860_txwi txwi; | | 4096 | struct rt2860_txwi txwi; |
3807 | struct mbuf *m; | | 4097 | struct mbuf *m; |
3808 | int ridx; | | 4098 | int ridx; |
3809 | | | 4099 | |