1 | #include <machine/rtems-bsd-kernel-space.h> |
---|
2 | |
---|
3 | /* $OpenBSD: if_urtwn.c,v 1.16 2011/02/10 17:26:40 jakemsr Exp $ */ |
---|
4 | |
---|
5 | /*- |
---|
6 | * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr> |
---|
7 | * Copyright (c) 2014 Kevin Lo <kevlo@FreeBSD.org> |
---|
8 | * Copyright (c) 2015-2016 Andriy Voskoboinyk <avos@FreeBSD.org> |
---|
9 | * |
---|
10 | * Permission to use, copy, modify, and distribute this software for any |
---|
11 | * purpose with or without fee is hereby granted, provided that the above |
---|
12 | * copyright notice and this permission notice appear in all copies. |
---|
13 | * |
---|
14 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
---|
15 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
---|
16 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
---|
17 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
---|
18 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
---|
19 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
---|
20 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
---|
21 | */ |
---|
22 | |
---|
23 | #include <sys/cdefs.h> |
---|
24 | __FBSDID("$FreeBSD$"); |
---|
25 | |
---|
26 | #include <rtems/bsd/local/opt_wlan.h> |
---|
27 | |
---|
28 | #include <rtems/bsd/sys/param.h> |
---|
29 | #include <rtems/bsd/sys/lock.h> |
---|
30 | #include <sys/mutex.h> |
---|
31 | #include <sys/mbuf.h> |
---|
32 | #include <sys/kernel.h> |
---|
33 | #include <sys/socket.h> |
---|
34 | #include <sys/systm.h> |
---|
35 | #include <sys/malloc.h> |
---|
36 | #include <sys/queue.h> |
---|
37 | #include <sys/taskqueue.h> |
---|
38 | #include <sys/bus.h> |
---|
39 | #include <sys/endian.h> |
---|
40 | #include <sys/linker.h> |
---|
41 | |
---|
42 | #include <net/if.h> |
---|
43 | #include <net/ethernet.h> |
---|
44 | #include <net/if_media.h> |
---|
45 | |
---|
46 | #include <net80211/ieee80211_var.h> |
---|
47 | #include <net80211/ieee80211_radiotap.h> |
---|
48 | |
---|
49 | #include <dev/rtwn/if_rtwnreg.h> |
---|
50 | #include <dev/rtwn/if_rtwnvar.h> |
---|
51 | |
---|
52 | #include <dev/rtwn/rtl8192c/r92c.h> |
---|
53 | #include <dev/rtwn/rtl8192c/r92c_var.h> |
---|
54 | |
---|
55 | #include <dev/rtwn/rtl8188e/usb/r88eu.h> |
---|
56 | #include <dev/rtwn/rtl8188e/usb/r88eu_reg.h> |
---|
57 | |
---|
58 | |
---|
59 | void |
---|
60 | r88eu_power_off(struct rtwn_softc *sc) |
---|
61 | { |
---|
62 | uint8_t reg; |
---|
63 | int error, ntries; |
---|
64 | |
---|
65 | /* Disable any kind of TX reports. */ |
---|
66 | error = rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, |
---|
67 | R88E_TX_RPT1_ENA | R88E_TX_RPT2_ENA, 0); |
---|
68 | if (error == ENXIO) /* hardware gone */ |
---|
69 | return; |
---|
70 | |
---|
71 | /* Stop Rx. */ |
---|
72 | rtwn_write_1(sc, R92C_CR, 0); |
---|
73 | |
---|
74 | /* Move card to Low Power State. */ |
---|
75 | /* Block all Tx queues. */ |
---|
76 | rtwn_write_1(sc, R92C_TXPAUSE, R92C_TX_QUEUE_ALL); |
---|
77 | |
---|
78 | for (ntries = 0; ntries < 10; ntries++) { |
---|
79 | /* Should be zero if no packet is transmitting. */ |
---|
80 | if (rtwn_read_4(sc, R88E_SCH_TXCMD) == 0) |
---|
81 | break; |
---|
82 | |
---|
83 | rtwn_delay(sc, 5000); |
---|
84 | } |
---|
85 | if (ntries == 10) { |
---|
86 | device_printf(sc->sc_dev, "%s: failed to block Tx queues\n", |
---|
87 | __func__); |
---|
88 | return; |
---|
89 | } |
---|
90 | |
---|
91 | /* CCK and OFDM are disabled, and clock are gated. */ |
---|
92 | rtwn_setbits_1(sc, R92C_SYS_FUNC_EN, R92C_SYS_FUNC_EN_BBRSTB, 0); |
---|
93 | |
---|
94 | rtwn_delay(sc, 1); |
---|
95 | |
---|
96 | /* Reset MAC TRX */ |
---|
97 | rtwn_write_1(sc, R92C_CR, |
---|
98 | R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN | |
---|
99 | R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | |
---|
100 | R92C_CR_PROTOCOL_EN | R92C_CR_SCHEDULE_EN); |
---|
101 | |
---|
102 | /* check if removed later */ |
---|
103 | rtwn_setbits_1_shift(sc, R92C_CR, R92C_CR_ENSEC, 0, 1); |
---|
104 | |
---|
105 | /* Respond TxOK to scheduler */ |
---|
106 | rtwn_setbits_1(sc, R92C_DUAL_TSF_RST, 0, 0x20); |
---|
107 | |
---|
108 | /* If firmware in ram code, do reset. */ |
---|
109 | #ifndef RTWN_WITHOUT_UCODE |
---|
110 | if (rtwn_read_1(sc, R92C_MCUFWDL) & R92C_MCUFWDL_RDY) |
---|
111 | r88e_fw_reset(sc, RTWN_FW_RESET_SHUTDOWN); |
---|
112 | #endif |
---|
113 | |
---|
114 | /* Reset MCU ready status. */ |
---|
115 | rtwn_write_1(sc, R92C_MCUFWDL, 0); |
---|
116 | |
---|
117 | /* Disable 32k. */ |
---|
118 | rtwn_setbits_1(sc, R88E_32K_CTRL, 0x01, 0); |
---|
119 | |
---|
120 | /* Move card to Disabled state. */ |
---|
121 | /* Turn off RF. */ |
---|
122 | rtwn_write_1(sc, R92C_RF_CTRL, 0); |
---|
123 | |
---|
124 | /* LDO Sleep mode. */ |
---|
125 | rtwn_setbits_1(sc, R92C_LPLDO_CTRL, 0, R92C_LPLDO_CTRL_SLEEP); |
---|
126 | |
---|
127 | /* Turn off MAC by HW state machine */ |
---|
128 | rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, 0, |
---|
129 | R92C_APS_FSMCO_APFM_OFF, 1); |
---|
130 | |
---|
131 | for (ntries = 0; ntries < 10; ntries++) { |
---|
132 | /* Wait until it will be disabled. */ |
---|
133 | if ((rtwn_read_2(sc, R92C_APS_FSMCO) & |
---|
134 | R92C_APS_FSMCO_APFM_OFF) == 0) |
---|
135 | break; |
---|
136 | |
---|
137 | rtwn_delay(sc, 5000); |
---|
138 | } |
---|
139 | if (ntries == 10) { |
---|
140 | device_printf(sc->sc_dev, "%s: could not turn off MAC\n", |
---|
141 | __func__); |
---|
142 | return; |
---|
143 | } |
---|
144 | |
---|
145 | /* schmit trigger */ |
---|
146 | rtwn_setbits_1(sc, R92C_AFE_XTAL_CTRL + 2, 0, 0x80); |
---|
147 | |
---|
148 | /* Enable WL suspend. */ |
---|
149 | rtwn_setbits_1_shift(sc, R92C_APS_FSMCO, |
---|
150 | R92C_APS_FSMCO_AFSM_PCIE, R92C_APS_FSMCO_AFSM_HSUS, 1); |
---|
151 | |
---|
152 | /* Enable bandgap mbias in suspend. */ |
---|
153 | rtwn_write_1(sc, R92C_APS_FSMCO + 3, 0); |
---|
154 | |
---|
155 | /* Clear SIC_EN register. */ |
---|
156 | rtwn_setbits_1(sc, R92C_GPIO_MUXCFG + 1, 0x10, 0); |
---|
157 | |
---|
158 | /* Set USB suspend enable local register */ |
---|
159 | rtwn_setbits_1(sc, R92C_USB_SUSPEND, 0, 0x10); |
---|
160 | |
---|
161 | /* Reset MCU IO Wrapper. */ |
---|
162 | reg = rtwn_read_1(sc, R92C_RSV_CTRL + 1); |
---|
163 | rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg & ~0x08); |
---|
164 | rtwn_write_1(sc, R92C_RSV_CTRL + 1, reg | 0x08); |
---|
165 | |
---|
166 | /* marked as 'For Power Consumption' code. */ |
---|
167 | rtwn_write_1(sc, R92C_GPIO_OUT, rtwn_read_1(sc, R92C_GPIO_IN)); |
---|
168 | rtwn_write_1(sc, R92C_GPIO_IOSEL, 0xff); |
---|
169 | |
---|
170 | rtwn_write_1(sc, R92C_GPIO_IO_SEL, |
---|
171 | rtwn_read_1(sc, R92C_GPIO_IO_SEL) << 4); |
---|
172 | rtwn_setbits_1(sc, R92C_GPIO_MOD, 0, 0x0f); |
---|
173 | |
---|
174 | /* Set LNA, TRSW, EX_PA Pin to output mode. */ |
---|
175 | rtwn_write_4(sc, R88E_BB_PAD_CTRL, 0x00080808); |
---|
176 | } |
---|
177 | |
---|
178 | void |
---|
179 | r88eu_init_intr(struct rtwn_softc *sc) |
---|
180 | { |
---|
181 | /* TODO: adjust */ |
---|
182 | rtwn_write_4(sc, R88E_HISR, 0xffffffff); |
---|
183 | rtwn_write_4(sc, R88E_HIMR, R88E_HIMR_CPWM | R88E_HIMR_CPWM2 | |
---|
184 | R88E_HIMR_TBDER | R88E_HIMR_PSTIMEOUT); |
---|
185 | rtwn_write_4(sc, R88E_HIMRE, R88E_HIMRE_RXFOVW | |
---|
186 | R88E_HIMRE_TXFOVW | R88E_HIMRE_RXERR | R88E_HIMRE_TXERR); |
---|
187 | rtwn_setbits_1(sc, R92C_USB_SPECIAL_OPTION, 0, |
---|
188 | R92C_USB_SPECIAL_OPTION_INT_BULK_SEL); |
---|
189 | } |
---|
190 | |
---|
191 | void |
---|
192 | r88eu_init_rx_agg(struct rtwn_softc *sc) |
---|
193 | { |
---|
194 | /* XXX merge? */ |
---|
195 | rtwn_setbits_1(sc, R92C_TRXDMA_CTRL, 0, |
---|
196 | R92C_TRXDMA_CTRL_RXDMA_AGG_EN); |
---|
197 | /* XXX dehardcode */ |
---|
198 | rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48); |
---|
199 | rtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH + 1, 4); |
---|
200 | } |
---|
201 | |
---|
202 | void |
---|
203 | r88eu_post_init(struct rtwn_softc *sc) |
---|
204 | { |
---|
205 | |
---|
206 | /* Enable per-packet TX report. */ |
---|
207 | rtwn_setbits_1(sc, R88E_TX_RPT_CTRL, 0, R88E_TX_RPT1_ENA); |
---|
208 | |
---|
209 | /* Disable Tx if MACID is not associated. */ |
---|
210 | rtwn_write_4(sc, R88E_MACID_NO_LINK, 0xffffffff); |
---|
211 | rtwn_write_4(sc, R88E_MACID_NO_LINK + 4, 0xffffffff); |
---|
212 | r88e_macid_enable_link(sc, RTWN_MACID_BC, 1); |
---|
213 | |
---|
214 | /* Perform LO and IQ calibrations. */ |
---|
215 | r88e_iq_calib(sc); |
---|
216 | /* Perform LC calibration. */ |
---|
217 | r92c_lc_calib(sc); |
---|
218 | |
---|
219 | rtwn_write_1(sc, R92C_USB_HRPWM, 0); |
---|
220 | |
---|
221 | if (sc->sc_ratectl_sysctl == RTWN_RATECTL_FW) { |
---|
222 | /* No support (yet?) for f/w rate adaptation. */ |
---|
223 | sc->sc_ratectl = RTWN_RATECTL_NET80211; |
---|
224 | } else |
---|
225 | sc->sc_ratectl = sc->sc_ratectl_sysctl; |
---|
226 | } |
---|