This source file includes following definitions.
- rtw_continuous_tx_enable
- rtw_access_string
- rtw_set_access1
- rtw_set_access
- rtw_config0123_enable
- rtw_anaparm_enable
- rtw_txdac_enable
- rtw_chip_reset1
- rtw_chip_reset
- rtw_recall_eeprom
- rtw_reset
- rtw_txdesc_dmamaps_create
- rtw_rxdesc_dmamaps_create
- rtw_rxdesc_dmamaps_destroy
- rtw_txdesc_dmamaps_destroy
- rtw_srom_parse
- rtw_srom_read
- rtw_set_rfprog
- rtw_init_channels
- rtw_identify_country
- rtw_identify_sta
- rtw_chan2txpower
- rtw_txdesc_blk_init_all
- rtw_txsoft_blk_init
- rtw_txsoft_blk_init_all
- rtw_rxdescs_sync
- rtw_txdescs_sync
- rtw_rxbufs_release
- rtw_rxsoft_alloc
- rtw_rxsoft_init_all
- rtw_rxdesc_init
- rtw_rxdesc_init_all
- rtw_io_enable
- rtw_intr_rx
- rtw_txsoft_release
- rtw_txsofts_release
- rtw_collect_txpkt
- rtw_reset_oactive
- rtw_collect_txring
- rtw_intr_tx
- rtw_intr_beacon
- rtw_intr_atim
- rtw_dump_rings
- rtw_hwring_setup
- rtw_swring_setup
- rtw_txdesc_blk_init
- rtw_txring_next
- rtw_txring_fixup
- rtw_rxring_fixup
- rtw_txdescs_reset
- rtw_intr_ioerror
- rtw_suspend_ticks
- rtw_resume_ticks
- rtw_intr_timeout
- rtw_intr
- rtw_stop
- rtw_pwrstate_string
- rtw_maxim_pwrstate
- rtw_rfmd_pwrstate
- rtw_philips_pwrstate
- rtw_rtl_pwrstate
- rtw_pwrstate0
- rtw_pwrstate
- rtw_tune
- rtw_disable
- rtw_enable
- rtw_transmit_config
- rtw_enable_interrupts
- rtw_set_nettype
- rtw_pktfilt_load
- rtw_init
- rtw_led_init
- rtw_led_newstate
- rtw_led_set
- rtw_led_fastblink
- rtw_led_slowblink
- rtw_led_attach
- rtw_ioctl
- rtw_txring_choose
- rtw_80211_dequeue
- rtw_dequeue
- rtw_seg_too_short
- rtw_dmamap_load_txbuf
- rtw_compute_duration1
- rtw_compute_duration
- rtw_print_txdesc
- rtw_start
- rtw_idle
- rtw_watchdog
- rtw_next_scan
- rtw_join_bss
- rtw_newstate
- rtw_tsf_extend
- rtw_ibss_merge
- rtw_recv_mgmt
- rtw_node_alloc
- rtw_node_free
- rtw_media_change
- rtw_media_status
- rtw_power
- rtw_shutdown
- rtw_establish_hooks
- rtw_disestablish_hooks
- rtw_txsoft_blk_setup
- rtw_txsoft_blk_cleanup_all
- rtw_txsoft_blk_setup_all
- rtw_txdesc_blk_setup
- rtw_txdesc_blk_setup_all
- rtw_rf_attach
- rtw_check_phydelay
- rtw_attach
- rtw_detach
- rtw_bbp_preinit
- rtw_bbp_init
- rtw_sa2400_txpower
- rtw_verify_syna
- rtw_sa2400_tune
- rtw_sa2400_pwrstate
- rtw_sa2400_vcocal_start
- rtw_sa2400_vco_calibration
- rtw_sa2400_filter_calibration
- rtw_sa2400_dc_calibration
- rtw_sa2400_calibrate
- rtw_sa2400_init
- rtw_max2820_tune
- rtw_max2820_init
- rtw_max2820_txpower
- rtw_max2820_pwrstate
- rtw_grf5101_init
- rtw_grf5101_tune
- rtw_grf5101_txpower
- rtw_grf5101_pwrstate
- rtw_rtl8225_pwrstate
- rtw_rtl8225_init
- rtw_rtl8225_txpower
- rtw_rtl8225_tune
- rtw_rtl8255_pwrstate
- rtw_rtl8255_init
- rtw_rtl8255_txpower
- rtw_rtl8255_tune
- rtw_phy_init
- rtw_bbp_write
- rtw_rf_hostbangbits
- rtw_rf_rtl8225_hostbangbits
- rtw_rf_macbangbits
- rtw_grf5101_host_crypt
- rtw_grf5101_mac_crypt
- rtw_rf_hostwrite
- rtw_maxim_swizzle
- rtw_rf_macwrite
- rtw_read8
- rtw_read16
- rtw_read32
- rtw_write8
- rtw_write16
- rtw_write32
- rtw_barrier
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 #include <sys/cdefs.h>
39 #include "bpfilter.h"
40
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/mbuf.h>
44 #include <sys/malloc.h>
45 #include <sys/kernel.h>
46 #include <sys/ioctl.h>
47 #include <sys/socket.h>
48 #include <sys/time.h>
49 #include <sys/types.h>
50
51 #include <machine/endian.h>
52 #include <machine/bus.h>
53 #include <machine/intr.h>
54
55 #include <uvm/uvm_extern.h>
56
57 #include <net/if.h>
58 #include <net/if_media.h>
59
60 #if NBPFILTER > 0
61 #include <net/bpf.h>
62 #endif
63
64 #ifdef INET
65 #include <netinet/in.h>
66 #include <netinet/if_ether.h>
67 #endif
68
69 #include <net80211/ieee80211_var.h>
70 #include <net80211/ieee80211_radiotap.h>
71
72 #include <dev/ic/rtwreg.h>
73 #include <dev/ic/rtwvar.h>
74 #include <dev/ic/max2820reg.h>
75 #include <dev/ic/sa2400reg.h>
76 #include <dev/ic/si4136reg.h>
77 #include <dev/ic/rtl8225reg.h>
78 #include <dev/ic/smc93cx6var.h>
79
80 int rtw_rfprog_fallback = 0;
81 int rtw_do_chip_reset = 0;
82 int rtw_dwelltime = 200;
83 int rtw_macbangbits_timeout = 100;
84
85 #ifdef RTW_DEBUG
86 int rtw_debug = 0;
87 int rtw_rxbufs_limit = RTW_RXQLEN;
88 #endif
89
90 void rtw_start(struct ifnet *);
91 void rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *);
92 void rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *);
93 void rtw_txdesc_blk_init(struct rtw_txdesc_blk *);
94 void rtw_txdescs_sync(struct rtw_txdesc_blk *, u_int, u_int, int);
95 u_int rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *);
96 void rtw_txring_fixup(struct rtw_softc *);
97 void rtw_rxbufs_release(bus_dma_tag_t, struct rtw_rxsoft *);
98 void rtw_rxdesc_init(struct rtw_rxdesc_blk *, struct rtw_rxsoft *, int, int);
99 void rtw_rxring_fixup(struct rtw_softc *);
100 void rtw_io_enable(struct rtw_regs *, u_int8_t, int);
101 void rtw_intr_rx(struct rtw_softc *, u_int16_t);
102 void rtw_intr_beacon(struct rtw_softc *, u_int16_t);
103 void rtw_intr_atim(struct rtw_softc *);
104 void rtw_transmit_config(struct rtw_softc *);
105 void rtw_pktfilt_load(struct rtw_softc *);
106 void rtw_start(struct ifnet *);
107 void rtw_watchdog(struct ifnet *);
108 void rtw_next_scan(void *);
109 void rtw_recv_mgmt(struct ieee80211com *, struct mbuf *,
110 struct ieee80211_node *, int, int, u_int32_t);
111 struct ieee80211_node *rtw_node_alloc(struct ieee80211com *);
112 void rtw_node_free(struct ieee80211com *, struct ieee80211_node *);
113 void rtw_media_status(struct ifnet *, struct ifmediareq *);
114 void rtw_txsoft_blk_cleanup_all(struct rtw_softc *);
115 void rtw_txdesc_blk_setup(struct rtw_txdesc_blk *, struct rtw_txdesc *,
116 u_int, bus_addr_t, bus_addr_t);
117 void rtw_txdesc_blk_setup_all(struct rtw_softc *);
118 void rtw_intr_tx(struct rtw_softc *, u_int16_t);
119 void rtw_intr_ioerror(struct rtw_softc *, u_int16_t);
120 void rtw_intr_timeout(struct rtw_softc *);
121 void rtw_stop(struct ifnet *, int);
122 void rtw_maxim_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int);
123 void rtw_philips_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int);
124 void rtw_rtl_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int);
125 void rtw_pwrstate0(struct rtw_softc *, enum rtw_pwrstate, int, int);
126 void rtw_join_bss(struct rtw_softc *, u_int8_t *, u_int16_t);
127 void rtw_set_access1(struct rtw_regs *, enum rtw_access);
128 int rtw_srom_parse(struct rtw_softc *);
129 int rtw_srom_read(struct rtw_regs *, u_int32_t, struct rtw_srom *,
130 const char *);
131 void rtw_set_rfprog(struct rtw_regs *, int, const char *);
132 u_int8_t rtw_chan2txpower(struct rtw_srom *, struct ieee80211com *,
133 struct ieee80211_channel *);
134 int rtw_txsoft_blk_init(struct rtw_txsoft_blk *);
135 int rtw_rxsoft_init_all(bus_dma_tag_t, struct rtw_rxsoft *,
136 int *, const char *);
137 void rtw_txsoft_release(bus_dma_tag_t, struct ieee80211com *,
138 struct rtw_txsoft *);
139 void rtw_txsofts_release(bus_dma_tag_t, struct ieee80211com *,
140 struct rtw_txsoft_blk *);
141 void rtw_hwring_setup(struct rtw_softc *);
142 int rtw_swring_setup(struct rtw_softc *);
143 void rtw_txdescs_reset(struct rtw_softc *);
144 void rtw_rfmd_pwrstate(struct rtw_regs *, enum rtw_pwrstate, int, int);
145 int rtw_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
146 int rtw_tune(struct rtw_softc *);
147 void rtw_set_nettype(struct rtw_softc *, enum ieee80211_opmode);
148 int rtw_compute_duration1(int, int, uint32_t, int, struct rtw_duration *);
149 int rtw_compute_duration(struct ieee80211_frame *, int, uint32_t, int,
150 int, struct rtw_duration *, struct rtw_duration *, int *, int);
151 int rtw_init(struct ifnet *);
152 int rtw_ioctl(struct ifnet *, u_long, caddr_t);
153 int rtw_seg_too_short(bus_dmamap_t);
154 struct mbuf *rtw_dmamap_load_txbuf(bus_dma_tag_t, bus_dmamap_t, struct mbuf *,
155 u_int, short *, const char *);
156 int rtw_newstate(struct ieee80211com *, enum ieee80211_state, int);
157 int rtw_media_change(struct ifnet *);
158 int rtw_txsoft_blk_setup_all(struct rtw_softc *);
159 int rtw_rf_attach(struct rtw_softc *, int);
160 u_int8_t rtw_check_phydelay(struct rtw_regs *, u_int32_t);
161 int rtw_chip_reset1(struct rtw_regs *, const char *);
162 int rtw_chip_reset(struct rtw_regs *, const char *);
163 int rtw_recall_eeprom(struct rtw_regs *, const char *);
164 int rtw_reset(struct rtw_softc *);
165 void rtw_reset_oactive(struct rtw_softc *);
166 int rtw_txdesc_dmamaps_create(bus_dma_tag_t, struct rtw_txsoft *, u_int);
167 int rtw_rxdesc_dmamaps_create(bus_dma_tag_t, struct rtw_rxsoft *, u_int);
168 void rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t, struct rtw_rxsoft *, u_int);
169 void rtw_txdesc_dmamaps_destroy(bus_dma_tag_t, struct rtw_txsoft *, u_int);
170 void rtw_init_channels(enum rtw_locale, struct ieee80211_channel (*)[],
171 const char*);
172 void rtw_identify_country(struct rtw_regs *, enum rtw_locale *);
173 int rtw_identify_sta(struct rtw_regs *, u_int8_t (*)[], const char *);
174 void rtw_rxdescs_sync(struct rtw_rxdesc_blk *, int, int, int);
175 int rtw_rxsoft_alloc(bus_dma_tag_t, struct rtw_rxsoft *);
176 void rtw_collect_txpkt(struct rtw_softc *, struct rtw_txdesc_blk *,
177 struct rtw_txsoft *, int);
178 void rtw_collect_txring(struct rtw_softc *, struct rtw_txsoft_blk *,
179 struct rtw_txdesc_blk *, int);
180 void rtw_suspend_ticks(struct rtw_softc *);
181 void rtw_resume_ticks(struct rtw_softc *);
182 void rtw_enable_interrupts(struct rtw_softc *);
183 int rtw_dequeue(struct ifnet *, struct rtw_txsoft_blk **,
184 struct rtw_txdesc_blk **, struct mbuf **,
185 struct ieee80211_node **);
186 void rtw_establish_hooks(struct rtw_hooks *, const char *, void *);
187 void rtw_disestablish_hooks(struct rtw_hooks *, const char *, void *);
188 int rtw_txsoft_blk_setup(struct rtw_txsoft_blk *, u_int);
189 void rtw_rxdesc_init_all(struct rtw_rxdesc_blk *, struct rtw_rxsoft *,
190 int);
191 int rtw_txring_choose(struct rtw_softc *, struct rtw_txsoft_blk **,
192 struct rtw_txdesc_blk **, int);
193 u_int rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *);
194 struct mbuf *rtw_80211_dequeue(struct rtw_softc *, struct ifqueue *, int,
195 struct rtw_txsoft_blk **, struct rtw_txdesc_blk **,
196 struct ieee80211_node **, short *);
197 uint64_t rtw_tsf_extend(struct rtw_regs *, u_int32_t);
198 void rtw_ibss_merge(struct rtw_softc *, struct ieee80211_node *,
199 u_int32_t);
200 void rtw_idle(struct rtw_regs *);
201 void rtw_led_attach(struct rtw_led_state *, void *);
202 void rtw_led_init(struct rtw_regs *);
203 void rtw_led_slowblink(void *);
204 void rtw_led_fastblink(void *);
205 void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, u_int);
206 void rtw_led_newstate(struct rtw_softc *, enum ieee80211_state);
207
208 int rtw_phy_init(struct rtw_softc *);
209 int rtw_bbp_preinit(struct rtw_regs *, u_int, int, u_int);
210 int rtw_bbp_init(struct rtw_regs *, struct rtw_bbpset *, int,
211 int, u_int8_t, u_int);
212 void rtw_verify_syna(u_int, u_int32_t);
213 int rtw_sa2400_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
214 int rtw_sa2400_txpower(struct rtw_softc *, u_int8_t);
215 int rtw_sa2400_tune(struct rtw_softc *, u_int);
216 int rtw_sa2400_vcocal_start(struct rtw_softc *, int);
217 int rtw_sa2400_vco_calibration(struct rtw_softc *);
218 int rtw_sa2400_filter_calibration(struct rtw_softc *);
219 int rtw_sa2400_dc_calibration(struct rtw_softc *);
220 int rtw_sa2400_calibrate(struct rtw_softc *, u_int);
221 int rtw_sa2400_init(struct rtw_softc *, u_int, u_int8_t,
222 enum rtw_pwrstate);
223 int rtw_max2820_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
224 int rtw_max2820_init(struct rtw_softc *, u_int, u_int8_t,
225 enum rtw_pwrstate);
226 int rtw_max2820_txpower(struct rtw_softc *, u_int8_t);
227 int rtw_max2820_tune(struct rtw_softc *, u_int);
228 int rtw_rtl8225_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
229 int rtw_rtl8225_init(struct rtw_softc *, u_int, u_int8_t,
230 enum rtw_pwrstate);
231 int rtw_rtl8225_txpower(struct rtw_softc *, u_int8_t);
232 int rtw_rtl8225_tune(struct rtw_softc *, u_int);
233 int rtw_rtl8255_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
234 int rtw_rtl8255_init(struct rtw_softc *, u_int, u_int8_t,
235 enum rtw_pwrstate);
236 int rtw_rtl8255_txpower(struct rtw_softc *, u_int8_t);
237 int rtw_rtl8255_tune(struct rtw_softc *, u_int);
238 int rtw_grf5101_pwrstate(struct rtw_softc *, enum rtw_pwrstate);
239 int rtw_grf5101_init(struct rtw_softc *, u_int, u_int8_t,
240 enum rtw_pwrstate);
241 int rtw_grf5101_txpower(struct rtw_softc *, u_int8_t);
242 int rtw_grf5101_tune(struct rtw_softc *, u_int);
243 int rtw_rf_hostwrite(struct rtw_softc *, u_int, u_int32_t);
244 int rtw_rf_macwrite(struct rtw_softc *, u_int, u_int32_t);
245 int rtw_bbp_write(struct rtw_regs *, u_int, u_int);
246 u_int32_t rtw_grf5101_host_crypt(u_int, u_int32_t);
247 u_int32_t rtw_maxim_swizzle(u_int, uint32_t);
248 u_int32_t rtw_grf5101_mac_crypt(u_int, u_int32_t);
249 void rtw_rf_hostbangbits(struct rtw_regs *, u_int32_t, int, u_int);
250 void rtw_rf_rtl8225_hostbangbits(struct rtw_regs *, u_int32_t, int, u_int);
251 int rtw_rf_macbangbits(struct rtw_regs *, u_int32_t);
252
253 u_int8_t rtw_read8(void *, u_int32_t);
254 u_int16_t rtw_read16(void *, u_int32_t);
255 u_int32_t rtw_read32(void *, u_int32_t);
256 void rtw_write8(void *, u_int32_t, u_int8_t);
257 void rtw_write16(void *, u_int32_t, u_int16_t);
258 void rtw_write32(void *, u_int32_t, u_int32_t);
259 void rtw_barrier(void *, u_int32_t, u_int32_t, int);
260
261 #ifdef RTW_DEBUG
262 void rtw_print_txdesc(struct rtw_softc *, const char *,
263 struct rtw_txsoft *, struct rtw_txdesc_blk *, int);
264 const char *rtw_access_string(enum rtw_access);
265 void rtw_dump_rings(struct rtw_softc *);
266 void rtw_print_txdesc(struct rtw_softc *, const char *,
267 struct rtw_txsoft *, struct rtw_txdesc_blk *, int);
268 #endif
269
270 struct cfdriver rtw_cd = {
271 NULL, "rtw", DV_IFNET
272 };
273
274 void
275 rtw_continuous_tx_enable(struct rtw_softc *sc, int enable)
276 {
277 struct rtw_regs *regs = &sc->sc_regs;
278
279 u_int32_t tcr;
280 tcr = RTW_READ(regs, RTW_TCR);
281 tcr &= ~RTW_TCR_LBK_MASK;
282 if (enable)
283 tcr |= RTW_TCR_LBK_CONT;
284 else
285 tcr |= RTW_TCR_LBK_NORMAL;
286 RTW_WRITE(regs, RTW_TCR, tcr);
287 RTW_SYNC(regs, RTW_TCR, RTW_TCR);
288 rtw_set_access(regs, RTW_ACCESS_ANAPARM);
289 rtw_txdac_enable(sc, !enable);
290 rtw_set_access(regs, RTW_ACCESS_ANAPARM);
291 rtw_set_access(regs, RTW_ACCESS_NONE);
292 }
293
294 #ifdef RTW_DEBUG
295 const char *
296 rtw_access_string(enum rtw_access access)
297 {
298 switch (access) {
299 case RTW_ACCESS_NONE:
300 return "none";
301 case RTW_ACCESS_CONFIG:
302 return "config";
303 case RTW_ACCESS_ANAPARM:
304 return "anaparm";
305 default:
306 return "unknown";
307 }
308 }
309 #endif
310
311 void
312 rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess)
313 {
314 KASSERT(naccess >= RTW_ACCESS_NONE && naccess <= RTW_ACCESS_ANAPARM);
315 KASSERT(regs->r_access >= RTW_ACCESS_NONE &&
316 regs->r_access <= RTW_ACCESS_ANAPARM);
317
318 if (naccess == regs->r_access)
319 return;
320
321 switch (naccess) {
322 case RTW_ACCESS_NONE:
323 switch (regs->r_access) {
324 case RTW_ACCESS_ANAPARM:
325 rtw_anaparm_enable(regs, 0);
326
327 case RTW_ACCESS_CONFIG:
328 rtw_config0123_enable(regs, 0);
329
330 case RTW_ACCESS_NONE:
331 break;
332 }
333 break;
334 case RTW_ACCESS_CONFIG:
335 switch (regs->r_access) {
336 case RTW_ACCESS_NONE:
337 rtw_config0123_enable(regs, 1);
338
339 case RTW_ACCESS_CONFIG:
340 break;
341 case RTW_ACCESS_ANAPARM:
342 rtw_anaparm_enable(regs, 0);
343 break;
344 }
345 break;
346 case RTW_ACCESS_ANAPARM:
347 switch (regs->r_access) {
348 case RTW_ACCESS_NONE:
349 rtw_config0123_enable(regs, 1);
350
351 case RTW_ACCESS_CONFIG:
352 rtw_anaparm_enable(regs, 1);
353
354 case RTW_ACCESS_ANAPARM:
355 break;
356 }
357 break;
358 }
359 }
360
361 void
362 rtw_set_access(struct rtw_regs *regs, enum rtw_access access)
363 {
364 rtw_set_access1(regs, access);
365 RTW_DPRINTF(RTW_DEBUG_ACCESS,
366 ("%s: access %s -> %s\n",__func__,
367 rtw_access_string(regs->r_access),
368 rtw_access_string(access)));
369 regs->r_access = access;
370 }
371
372
373
374
375 void
376 rtw_config0123_enable(struct rtw_regs *regs, int enable)
377 {
378 u_int8_t ecr;
379 ecr = RTW_READ8(regs, RTW_9346CR);
380 ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK);
381 if (enable)
382 ecr |= RTW_9346CR_EEM_CONFIG;
383 else {
384 RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3));
385 ecr |= RTW_9346CR_EEM_NORMAL;
386 }
387 RTW_WRITE8(regs, RTW_9346CR, ecr);
388 RTW_SYNC(regs, RTW_9346CR, RTW_9346CR);
389 }
390
391
392 void
393 rtw_anaparm_enable(struct rtw_regs *regs, int enable)
394 {
395 u_int8_t cfg3;
396
397 cfg3 = RTW_READ8(regs, RTW_CONFIG3);
398 cfg3 |= RTW_CONFIG3_CLKRUNEN;
399 if (enable)
400 cfg3 |= RTW_CONFIG3_PARMEN;
401 else
402 cfg3 &= ~RTW_CONFIG3_PARMEN;
403 RTW_WRITE8(regs, RTW_CONFIG3, cfg3);
404 RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3);
405 }
406
407
408 void
409 rtw_txdac_enable(struct rtw_softc *sc, int enable)
410 {
411 u_int32_t anaparm;
412 struct rtw_regs *regs = &sc->sc_regs;
413
414 anaparm = RTW_READ(regs, RTW_ANAPARM_0);
415 if (enable)
416 anaparm &= ~RTW_ANAPARM_TXDACOFF;
417 else
418 anaparm |= RTW_ANAPARM_TXDACOFF;
419 RTW_WRITE(regs, RTW_ANAPARM_0, anaparm);
420 RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0);
421 }
422
423 int
424 rtw_chip_reset1(struct rtw_regs *regs, const char *dvname)
425 {
426 u_int8_t cr;
427 int i;
428
429 RTW_WRITE8(regs, RTW_CR, RTW_CR_RST);
430
431 RTW_WBR(regs, RTW_CR, RTW_CR);
432
433 for (i = 0; i < 1000; i++) {
434 if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) {
435 RTW_DPRINTF(RTW_DEBUG_RESET,
436 ("%s: reset in %dus\n", dvname, i));
437 return 0;
438 }
439 RTW_RBR(regs, RTW_CR, RTW_CR);
440 DELAY(10);
441 }
442
443 printf("\n%s: reset failed\n", dvname);
444 return ETIMEDOUT;
445 }
446
447 int
448 rtw_chip_reset(struct rtw_regs *regs, const char *dvname)
449 {
450 uint32_t tcr;
451
452
453 tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 |
454 LSHIFT(7, RTW_TCR_SRL_MASK) | LSHIFT(7, RTW_TCR_LRL_MASK);
455
456 RTW_WRITE(regs, RTW_TCR, tcr);
457
458 RTW_WBW(regs, RTW_CR, RTW_TCR);
459
460 return rtw_chip_reset1(regs, dvname);
461 }
462
463 int
464 rtw_recall_eeprom(struct rtw_regs *regs, const char *dvname)
465 {
466 int i;
467 u_int8_t ecr;
468
469 ecr = RTW_READ8(regs, RTW_9346CR);
470 ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD;
471 RTW_WRITE8(regs, RTW_9346CR, ecr);
472
473 RTW_WBR(regs, RTW_9346CR, RTW_9346CR);
474
475
476 for (i = 0; i < 50; i++) {
477 ecr = RTW_READ8(regs, RTW_9346CR);
478 if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) {
479 RTW_DPRINTF(RTW_DEBUG_RESET,
480 ("%s: recall EEPROM in %dus\n", dvname, i * 200));
481 return (0);
482 }
483 RTW_RBR(regs, RTW_9346CR, RTW_9346CR);
484 DELAY(200);
485 }
486
487 printf("\n%s: could not recall EEPROM in %dus\n", dvname, i * 200);
488
489 return (ETIMEDOUT);
490 }
491
492 int
493 rtw_reset(struct rtw_softc *sc)
494 {
495 int rc;
496 uint8_t config1;
497
498 if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
499 return rc;
500
501 if ((rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev.dv_xname)) != 0)
502 ;
503
504 config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1);
505 RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN);
506
507
508 return 0;
509 }
510
511 int
512 rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
513 u_int ndescs)
514 {
515 int i, rc = 0;
516 for (i = 0; i < ndescs; i++) {
517 rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES,
518 0, 0, &descs[i].ts_dmamap);
519 if (rc != 0)
520 break;
521 }
522 return rc;
523 }
524
525 int
526 rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
527 u_int ndescs)
528 {
529 int i, rc = 0;
530 for (i = 0; i < ndescs; i++) {
531 rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
532 &descs[i].rs_dmamap);
533 if (rc != 0)
534 break;
535 }
536 return rc;
537 }
538
539 void
540 rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
541 u_int ndescs)
542 {
543 int i;
544 for (i = 0; i < ndescs; i++) {
545 if (descs[i].rs_dmamap != NULL)
546 bus_dmamap_destroy(dmat, descs[i].rs_dmamap);
547 }
548 }
549
550 void
551 rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
552 u_int ndescs)
553 {
554 int i;
555 for (i = 0; i < ndescs; i++) {
556 if (descs[i].ts_dmamap != NULL)
557 bus_dmamap_destroy(dmat, descs[i].ts_dmamap);
558 }
559 }
560
561 int
562 rtw_srom_parse(struct rtw_softc *sc)
563 {
564 int i;
565 struct rtw_srom *sr = &sc->sc_srom;
566 u_int32_t *flags = &sc->sc_flags;
567 u_int8_t *cs_threshold = &sc->sc_csthr;
568 int *rfchipid = &sc->sc_rfchipid;
569 u_int32_t *rcr = &sc->sc_rcr;
570 enum rtw_locale *locale = &sc->sc_locale;
571 u_int16_t version;
572 u_int8_t mac[IEEE80211_ADDR_LEN];
573
574 *flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV);
575 *rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2);
576
577 version = RTW_SR_GET16(sr, RTW_SR_VERSION);
578 RTW_DPRINTF(RTW_DEBUG_ATTACH,
579 ("%s: SROM %d.%d\n", sc->sc_dev.dv_xname, version >> 8,
580 version & 0xff));
581
582 if (version <= 0x0101) {
583 printf(" is not understood, limping along with defaults ");
584 *flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV);
585 *cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT;
586 *rcr |= RTW_RCR_ENCS1;
587 *rfchipid = RTW_RFCHIPID_PHILIPS;
588 return 0;
589 }
590
591 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
592 mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i);
593
594 RTW_DPRINTF(RTW_DEBUG_ATTACH,
595 ("%s: EEPROM MAC %s\n", sc->sc_dev.dv_xname, ether_sprintf(mac)));
596
597 *cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR);
598
599 if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW8180_CONFIG2_ANT) != 0)
600 *flags |= RTW_F_ANTDIV;
601
602
603
604
605 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0)
606 *flags |= RTW_F_DIGPHY;
607 if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0)
608 *flags |= RTW_F_DFLANTB;
609
610 *rcr |= LSHIFT(MASK_AND_RSHIFT(RTW_SR_GET(sr, RTW_SR_RFPARM),
611 RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1);
612
613 *rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID);
614
615 if (sc->sc_flags & RTW_F_RTL8185) {
616 *locale = RTW_LOCALE_UNKNOWN;
617 return (0);
618 }
619
620 switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW8180_CONFIG0_GL_MASK) {
621 case RTW8180_CONFIG0_GL_USA:
622 *locale = RTW_LOCALE_USA;
623 break;
624 case RTW8180_CONFIG0_GL_EUROPE:
625 *locale = RTW_LOCALE_EUROPE;
626 break;
627 case RTW8180_CONFIG0_GL_JAPAN:
628 case RTW8180_CONFIG0_GL_JAPAN2:
629 *locale = RTW_LOCALE_JAPAN;
630 break;
631 default:
632 *locale = RTW_LOCALE_UNKNOWN;
633 break;
634 }
635 return 0;
636 }
637
638
639 int
640 rtw_srom_read(struct rtw_regs *regs, u_int32_t flags, struct rtw_srom *sr,
641 const char *dvname)
642 {
643 int rc;
644 struct seeprom_descriptor sd;
645 u_int8_t ecr;
646
647 bzero(&sd, sizeof(sd));
648
649 ecr = RTW_READ8(regs, RTW_9346CR);
650
651 if ((flags & RTW_F_9356SROM) != 0) {
652 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n", dvname));
653 sr->sr_size = 256;
654 sd.sd_chip = C56_66;
655 } else {
656 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n", dvname));
657 sr->sr_size = 128;
658 sd.sd_chip = C46;
659 }
660
661 ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK |
662 RTW_9346CR_EEM_MASK | RTW_9346CR_EECS);
663 ecr |= RTW_9346CR_EEM_PROGRAM;
664
665 RTW_WRITE8(regs, RTW_9346CR, ecr);
666
667 sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT);
668
669 if (sr->sr_content == NULL) {
670 printf("%s: unable to allocate SROM buffer\n", dvname);
671 return ENOMEM;
672 }
673
674 bzero(sr->sr_content, sr->sr_size);
675
676
677
678
679
680 sd.sd_tag = regs->r_bt;
681 sd.sd_bsh = regs->r_bh;
682 sd.sd_regsize = 1;
683 sd.sd_control_offset = RTW_9346CR;
684 sd.sd_status_offset = RTW_9346CR;
685 sd.sd_dataout_offset = RTW_9346CR;
686 sd.sd_CK = RTW_9346CR_EESK;
687 sd.sd_CS = RTW_9346CR_EECS;
688 sd.sd_DI = RTW_9346CR_EEDO;
689 sd.sd_DO = RTW_9346CR_EEDI;
690
691 sd.sd_MS = ecr;
692 sd.sd_RDY = 0;
693
694
695 if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) {
696 printf("\n%s: could not read SROM\n", dvname);
697 free(sr->sr_content, M_DEVBUF);
698 sr->sr_content = NULL;
699 return -1;
700 }
701
702
703 RTW_WRITE8(regs, RTW_9346CR,
704 (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL);
705 RTW_WBRW(regs, RTW_9346CR, RTW_9346CR);
706
707 if ((rc = rtw_recall_eeprom(regs, dvname)) != 0)
708 return rc;
709
710 #ifdef RTW_DEBUG
711 {
712 int i;
713 RTW_DPRINTF(RTW_DEBUG_ATTACH,
714 ("\n%s: serial ROM:\n\t", dvname));
715 for (i = 0; i < sr->sr_size/2; i++) {
716 if (((i % 8) == 0) && (i != 0))
717 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t"));
718 RTW_DPRINTF(RTW_DEBUG_ATTACH,
719 (" %04x", sr->sr_content[i]));
720 }
721 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n"));
722 }
723 #endif
724 return 0;
725 }
726
727 void
728 rtw_set_rfprog(struct rtw_regs *regs, int rfchipid,
729 const char *dvname)
730 {
731 u_int8_t cfg4;
732 const char *method;
733
734 cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK;
735
736 switch (rfchipid) {
737 default:
738 cfg4 |= LSHIFT(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK);
739 method = "fallback";
740 break;
741 case RTW_RFCHIPID_INTERSIL:
742 cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL;
743 method = "Intersil";
744 break;
745 case RTW_RFCHIPID_PHILIPS:
746 cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS;
747 method = "Philips";
748 break;
749 case RTW_RFCHIPID_RFMD2948:
750 cfg4 |= RTW_CONFIG4_RFTYPE_RFMD;
751 method = "RFMD";
752 break;
753 }
754
755 RTW_WRITE8(regs, RTW_CONFIG4, cfg4);
756
757 RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4);
758
759 RTW_DPRINTF(RTW_DEBUG_INIT,
760 ("%s: %s RF programming method, %#02x\n", dvname, method,
761 RTW_READ8(regs, RTW_CONFIG4)));
762 }
763
764 void
765 rtw_init_channels(enum rtw_locale locale,
766 struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1],
767 const char *dvname)
768 {
769 int i;
770 const char *name = NULL;
771 #define ADD_CHANNEL(_chans, _chan) do { \
772 (*_chans)[_chan].ic_flags = IEEE80211_CHAN_B; \
773 (*_chans)[_chan].ic_freq = \
774 ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\
775 } while (0)
776
777 switch (locale) {
778 case RTW_LOCALE_USA:
779 name = "USA";
780 for (i = 1; i <= 11; i++)
781 ADD_CHANNEL(chans, i);
782 break;
783 case RTW_LOCALE_JAPAN:
784 name = "Japan";
785 ADD_CHANNEL(chans, 14);
786 for (i = 1; i <= 14; i++)
787 ADD_CHANNEL(chans, i);
788 break;
789 case RTW_LOCALE_EUROPE:
790 name = "Europe";
791 for (i = 1; i <= 13; i++)
792 ADD_CHANNEL(chans, i);
793 break;
794 default:
795 name = "<unknown>";
796 for (i = 10; i <= 11; i++)
797 ADD_CHANNEL(chans, i);
798 break;
799 }
800 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: Geographic Location %s\n",
801 dvname, name));
802 #undef ADD_CHANNEL
803 }
804
805 void
806 rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale)
807 {
808 u_int8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0);
809
810 switch (cfg0 & RTW8180_CONFIG0_GL_MASK) {
811 case RTW8180_CONFIG0_GL_USA:
812 *locale = RTW_LOCALE_USA;
813 break;
814 case RTW8180_CONFIG0_GL_JAPAN:
815 case RTW8180_CONFIG0_GL_JAPAN2:
816 *locale = RTW_LOCALE_JAPAN;
817 break;
818 case RTW8180_CONFIG0_GL_EUROPE:
819 *locale = RTW_LOCALE_EUROPE;
820 break;
821 default:
822 *locale = RTW_LOCALE_UNKNOWN;
823 break;
824 }
825 }
826
827 int
828 rtw_identify_sta(struct rtw_regs *regs, u_int8_t (*addr)[IEEE80211_ADDR_LEN],
829 const char *dvname)
830 {
831 static const u_int8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
833 };
834 u_int32_t idr0 = RTW_READ(regs, RTW_IDR0),
835 idr1 = RTW_READ(regs, RTW_IDR1);
836
837 (*addr)[0] = MASK_AND_RSHIFT(idr0, BITS(0, 7));
838 (*addr)[1] = MASK_AND_RSHIFT(idr0, BITS(8, 15));
839 (*addr)[2] = MASK_AND_RSHIFT(idr0, BITS(16, 23));
840 (*addr)[3] = MASK_AND_RSHIFT(idr0, BITS(24 ,31));
841
842 (*addr)[4] = MASK_AND_RSHIFT(idr1, BITS(0, 7));
843 (*addr)[5] = MASK_AND_RSHIFT(idr1, BITS(8, 15));
844
845 if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) {
846 printf("\n%s: could not get mac address, attach failed\n",
847 dvname);
848 return ENXIO;
849 }
850
851 printf("address %s\n", ether_sprintf(*addr));
852
853 return 0;
854 }
855
856 u_int8_t
857 rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic,
858 struct ieee80211_channel *chan)
859 {
860 u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1;
861 KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14,
862 ("%s: channel %d out of range", __func__,
863 idx - RTW_SR_TXPOWER1 + 1));
864 return RTW_SR_GET(sr, idx);
865 }
866
867 void
868 rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb)
869 {
870 int pri;
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891 u_int nfree[RTW_NTXPRI] =
892 {RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI,
893 RTW_NTXDESCBCN - 1};
894
895 for (pri = 0; pri < RTW_NTXPRI; pri++) {
896 tdb[pri].tdb_nfree = nfree[pri];
897 tdb[pri].tdb_next = 0;
898 }
899 }
900
901 int
902 rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb)
903 {
904 int i;
905 struct rtw_txsoft *ts;
906
907 SIMPLEQ_INIT(&tsb->tsb_dirtyq);
908 SIMPLEQ_INIT(&tsb->tsb_freeq);
909 for (i = 0; i < tsb->tsb_ndesc; i++) {
910 ts = &tsb->tsb_desc[i];
911 ts->ts_mbuf = NULL;
912 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
913 }
914 tsb->tsb_tx_timer = 0;
915 return 0;
916 }
917
918 void
919 rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb)
920 {
921 int pri;
922 for (pri = 0; pri < RTW_NTXPRI; pri++)
923 rtw_txsoft_blk_init(&tsb[pri]);
924 }
925
926 void
927 rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops)
928 {
929 KASSERT(nsync <= rdb->rdb_ndesc);
930
931 if (desc0 + nsync > rdb->rdb_ndesc) {
932 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
933 offsetof(struct rtw_descs, hd_rx[desc0]),
934 sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops);
935 nsync -= (rdb->rdb_ndesc - desc0);
936 desc0 = 0;
937 }
938
939 KASSERT(desc0 < rdb->rdb_ndesc);
940 KASSERT(nsync <= rdb->rdb_ndesc);
941 KASSERT(desc0 + nsync <= rdb->rdb_ndesc);
942
943
944 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
945 offsetof(struct rtw_descs, hd_rx[desc0]),
946 sizeof(struct rtw_rxdesc) * nsync, ops);
947 }
948
949 void
950 rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops)
951 {
952
953 if (desc0 + nsync > tdb->tdb_ndesc) {
954 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
955 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
956 sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0),
957 ops);
958 nsync -= (tdb->tdb_ndesc - desc0);
959 desc0 = 0;
960 }
961
962
963 bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
964 tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
965 sizeof(struct rtw_txdesc) * nsync, ops);
966 }
967
968 void
969 rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc)
970 {
971 int i;
972 struct rtw_rxsoft *rs;
973
974 for (i = 0; i < RTW_RXQLEN; i++) {
975 rs = &desc[i];
976 if (rs->rs_mbuf == NULL)
977 continue;
978 bus_dmamap_sync(dmat, rs->rs_dmamap, 0,
979 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
980 bus_dmamap_unload(dmat, rs->rs_dmamap);
981 m_freem(rs->rs_mbuf);
982 rs->rs_mbuf = NULL;
983 }
984 }
985
986 int
987 rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs)
988 {
989 int rc;
990 struct mbuf *m;
991
992 MGETHDR(m, M_DONTWAIT, MT_DATA);
993 if (m == NULL)
994 return ENOBUFS;
995
996 MCLGET(m, M_DONTWAIT);
997 if ((m->m_flags & M_EXT) == 0) {
998 m_freem(m);
999 return ENOBUFS;
1000 }
1001
1002 m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
1003
1004 if (rs->rs_mbuf != NULL)
1005 bus_dmamap_unload(dmat, rs->rs_dmamap);
1006
1007 rs->rs_mbuf = NULL;
1008
1009 rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT);
1010 if (rc != 0) {
1011 m_freem(m);
1012 return -1;
1013 }
1014
1015 rs->rs_mbuf = m;
1016
1017 return 0;
1018 }
1019
1020 int
1021 rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc,
1022 int *ndesc, const char *dvname)
1023 {
1024 int i, rc = 0;
1025 struct rtw_rxsoft *rs;
1026
1027 for (i = 0; i < RTW_RXQLEN; i++) {
1028 rs = &desc[i];
1029
1030 KASSERT(rs->rs_mbuf == NULL);
1031 #ifdef RTW_DEBUG
1032 if (i == rtw_rxbufs_limit) {
1033 printf("%s: TEST hit %d-buffer limit\n", dvname, i);
1034 rc = ENOBUFS;
1035 break;
1036 }
1037 #endif
1038 if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) {
1039 printf("%s: rtw_rxsoft_alloc failed, %d buffers, "
1040 "rc %d\n", dvname, i, rc);
1041 break;
1042 }
1043 }
1044 *ndesc = i;
1045 return rc;
1046 }
1047
1048 void
1049 rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs,
1050 int idx, int kick)
1051 {
1052 int is_last = (idx == rdb->rdb_ndesc - 1);
1053 uint32_t ctl, octl, obuf;
1054 struct rtw_rxdesc *rd = &rdb->rdb_desc[idx];
1055
1056 obuf = rd->rd_buf;
1057 rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr);
1058
1059 ctl = LSHIFT(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) |
1060 RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS;
1061
1062 if (is_last)
1063 ctl |= RTW_RXCTL_EOR;
1064
1065 octl = rd->rd_ctl;
1066 rd->rd_ctl = htole32(ctl);
1067
1068 RTW_DPRINTF(kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK)
1069 : RTW_DEBUG_RECV_DESC,
1070 ("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd,
1071 letoh32(obuf), letoh32(rd->rd_buf), letoh32(octl),
1072 letoh32(rd->rd_ctl)));
1073
1074
1075 bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0,
1076 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
1077
1078
1079 bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
1080 RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc),
1081 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1082 }
1083
1084 void
1085 rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl,
1086 int kick)
1087 {
1088 int i;
1089 struct rtw_rxdesc *rd;
1090 struct rtw_rxsoft *rs;
1091
1092 for (i = 0; i < rdb->rdb_ndesc; i++) {
1093 rd = &rdb->rdb_desc[i];
1094 rs = &ctl[i];
1095 rtw_rxdesc_init(rdb, rs, i, kick);
1096 }
1097 }
1098
1099 void
1100 rtw_io_enable(struct rtw_regs *regs, u_int8_t flags, int enable)
1101 {
1102 u_int8_t cr;
1103
1104 RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__,
1105 enable ? "enable" : "disable", flags));
1106
1107 cr = RTW_READ8(regs, RTW_CR);
1108
1109
1110 #if 0
1111
1112 cr |= RTW_CR_MULRW;
1113 #endif
1114
1115 RTW_RBW(regs, RTW_CR, RTW_CR);
1116 if (enable)
1117 cr |= flags;
1118 else
1119 cr &= ~flags;
1120 RTW_WRITE8(regs, RTW_CR, cr);
1121 RTW_SYNC(regs, RTW_CR, RTW_CR);
1122 }
1123
1124 void
1125 rtw_intr_rx(struct rtw_softc *sc, u_int16_t isr)
1126 {
1127 #define IS_BEACON(__fc0) \
1128 ((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\
1129 (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON))
1130
1131 static const int ratetbl[4] = {2, 4, 11, 22};
1132
1133
1134 u_int next, nproc = 0;
1135 int hwrate, len, rate, rssi, sq;
1136 u_int32_t hrssi, hstat, htsfth, htsftl;
1137 struct rtw_rxdesc *rd;
1138 struct rtw_rxsoft *rs;
1139 struct rtw_rxdesc_blk *rdb;
1140 struct mbuf *m;
1141
1142 struct ieee80211_node *ni;
1143 struct ieee80211_frame *wh;
1144
1145 rdb = &sc->sc_rxdesc_blk;
1146
1147 KASSERT(rdb->rdb_next < rdb->rdb_ndesc);
1148
1149 for (next = rdb->rdb_next; ; next = (next + 1) % rdb->rdb_ndesc) {
1150 rtw_rxdescs_sync(rdb, next, 1,
1151 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1152 rd = &rdb->rdb_desc[next];
1153 rs = &sc->sc_rxsoft[next];
1154
1155 hstat = letoh32(rd->rd_stat);
1156 hrssi = letoh32(rd->rd_rssi);
1157 htsfth = letoh32(rd->rd_tsfth);
1158 htsftl = letoh32(rd->rd_tsftl);
1159
1160 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1161 ("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n",
1162 __func__, next, hstat, hrssi, htsfth, htsftl));
1163
1164 ++nproc;
1165
1166
1167 if ((hstat & RTW_RXSTAT_OWN) != 0) {
1168 if (nproc > 1)
1169 break;
1170
1171
1172 rtw_rxdescs_sync(rdb, 0, 1,
1173 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1174 rd = &rdb->rdb_desc[0];
1175 if ((rd->rd_stat & htole32(RTW_RXSTAT_OWN)) != 0)
1176 break;
1177 RTW_DPRINTF(RTW_DEBUG_BUGS,
1178 ("%s: NIC skipped from rxdesc[%u] to rxdesc[0]\n",
1179 sc->sc_dev.dv_xname, next));
1180 next = rdb->rdb_ndesc - 1;
1181 continue;
1182 }
1183
1184 #ifdef RTW_DEBUG
1185 #define PRINTSTAT(flag) do { \
1186 if ((hstat & flag) != 0) { \
1187 printf("%s" #flag, delim); \
1188 delim = ","; \
1189 } \
1190 } while (0)
1191 if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) {
1192 const char *delim = "<";
1193 printf("%s: ", sc->sc_dev.dv_xname);
1194 if ((hstat & RTW_RXSTAT_DEBUG) != 0) {
1195 printf("status %08x", hstat);
1196 PRINTSTAT(RTW_RXSTAT_SPLCP);
1197 PRINTSTAT(RTW_RXSTAT_MAR);
1198 PRINTSTAT(RTW_RXSTAT_PAR);
1199 PRINTSTAT(RTW_RXSTAT_BAR);
1200 PRINTSTAT(RTW_RXSTAT_PWRMGT);
1201 PRINTSTAT(RTW_RXSTAT_CRC32);
1202 PRINTSTAT(RTW_RXSTAT_ICV);
1203 printf(">, ");
1204 }
1205 }
1206 #undef PRINTSTAT
1207 #endif
1208
1209 if ((hstat & RTW_RXSTAT_IOERROR) != 0) {
1210 printf("%s: DMA error/FIFO overflow %08x, "
1211 "rx descriptor %d\n", sc->sc_dev.dv_xname,
1212 hstat & RTW_RXSTAT_IOERROR, next);
1213 sc->sc_if.if_ierrors++;
1214 goto next;
1215 }
1216
1217 len = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_LENGTH_MASK);
1218 if (len < IEEE80211_MIN_LEN) {
1219 sc->sc_ic.ic_stats.is_rx_tooshort++;
1220 goto next;
1221 }
1222
1223
1224 len -= IEEE80211_CRC_LEN;
1225
1226 hwrate = MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK);
1227 if (hwrate >= sizeof(ratetbl) / sizeof(ratetbl[0])) {
1228 printf("%s: unknown rate #%d\n", sc->sc_dev.dv_xname,
1229 MASK_AND_RSHIFT(hstat, RTW_RXSTAT_RATE_MASK));
1230 sc->sc_if.if_ierrors++;
1231 goto next;
1232 }
1233 rate = ratetbl[hwrate];
1234
1235 #ifdef RTW_DEBUG
1236 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1237 ("rate %d.%d Mb/s, time %08x%08x\n", (rate * 5) / 10,
1238 (rate * 5) % 10, htsfth, htsftl));
1239 #endif
1240
1241 if ((hstat & RTW_RXSTAT_RES) != 0 &&
1242 sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR)
1243 goto next;
1244
1245
1246 if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
1247 printf("%s: too many rx segments\n",
1248 sc->sc_dev.dv_xname);
1249 goto next;
1250 }
1251
1252 bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0,
1253 rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
1254
1255 m = rs->rs_mbuf;
1256
1257
1258 switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) {
1259 case 0:
1260 break;
1261 case ENOBUFS:
1262 printf("%s: rtw_rxsoft_alloc(, %d) failed, "
1263 "dropping this packet\n", sc->sc_dev.dv_xname,
1264 next);
1265 goto next;
1266 default:
1267
1268 panic("%s: could not load DMA map",
1269 sc->sc_dev.dv_xname);
1270 }
1271
1272 if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
1273 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_RSSI);
1274 else {
1275 rssi = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_IMR_RSSI);
1276
1277
1278
1279 if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
1280 rssi |= 0x80;
1281 }
1282
1283 sq = MASK_AND_RSHIFT(hrssi, RTW_RXRSSI_SQ);
1284
1285
1286
1287
1288
1289 m->m_pkthdr.rcvif = &sc->sc_if;
1290 m->m_pkthdr.len = m->m_len = len;
1291
1292 wh = mtod(m, struct ieee80211_frame *);
1293
1294 if (!IS_BEACON(wh->i_fc[0]))
1295 sc->sc_led_state.ls_event |= RTW_LED_S_RX;
1296
1297 ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
1298
1299 sc->sc_tsfth = htsfth;
1300
1301 #ifdef RTW_DEBUG
1302 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
1303 (IFF_DEBUG|IFF_LINK2)) {
1304 ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len,
1305 rate, rssi);
1306 }
1307 #endif
1308
1309 #if NBPFILTER > 0
1310 if (sc->sc_radiobpf != NULL) {
1311 struct mbuf mb;
1312 struct ieee80211com *ic = &sc->sc_ic;
1313 struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap;
1314
1315 rr->rr_tsft =
1316 htole64(((uint64_t)htsfth << 32) | htsftl);
1317
1318 if ((hstat & RTW_RXSTAT_SPLCP) != 0)
1319 rr->rr_flags = IEEE80211_RADIOTAP_F_SHORTPRE;
1320
1321 rr->rr_flags = 0;
1322 rr->rr_rate = rate;
1323 rr->rr_chan_freq =
1324 htole16(ic->ic_bss->ni_chan->ic_freq);
1325 rr->rr_chan_flags =
1326 htole16(ic->ic_bss->ni_chan->ic_flags);
1327 rr->rr_antsignal = rssi;
1328 rr->rr_barker_lock = htole16(sq);
1329
1330 mb.m_data = (caddr_t)rr;
1331 mb.m_len = sizeof(sc->sc_rxtapu);
1332 mb.m_next = m;
1333 mb.m_nextpkt = NULL;
1334 mb.m_type = 0;
1335 mb.m_flags = 0;
1336 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_IN);
1337 }
1338 #endif
1339
1340 ieee80211_input(&sc->sc_if, m, ni, rssi, htsftl);
1341 ieee80211_release_node(&sc->sc_ic, ni);
1342 next:
1343 rtw_rxdesc_init(rdb, rs, next, 0);
1344 }
1345 rdb->rdb_next = next;
1346
1347 KASSERT(rdb->rdb_next < rdb->rdb_ndesc);
1348
1349
1350
1351
1352
1353 if (!IFQ_IS_EMPTY(&sc->sc_if.if_snd) &&
1354 !(sc->sc_if.if_flags & IFF_OACTIVE))
1355 (*sc->sc_if.if_start)(&sc->sc_if);
1356
1357 return;
1358 #undef IS_BEACON
1359 }
1360
1361 void
1362 rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
1363 struct rtw_txsoft *ts)
1364 {
1365 struct mbuf *m;
1366 struct ieee80211_node *ni;
1367
1368 m = ts->ts_mbuf;
1369 ni = ts->ts_ni;
1370 KASSERT(m != NULL);
1371 KASSERT(ni != NULL);
1372 ts->ts_mbuf = NULL;
1373 ts->ts_ni = NULL;
1374
1375 bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize,
1376 BUS_DMASYNC_POSTWRITE);
1377 bus_dmamap_unload(dmat, ts->ts_dmamap);
1378 m_freem(m);
1379 ieee80211_release_node(ic, ni);
1380 }
1381
1382 void
1383 rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
1384 struct rtw_txsoft_blk *tsb)
1385 {
1386 struct rtw_txsoft *ts;
1387
1388 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
1389 rtw_txsoft_release(dmat, ic, ts);
1390 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
1391 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
1392 }
1393 tsb->tsb_tx_timer = 0;
1394 }
1395
1396 void
1397 rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb,
1398 struct rtw_txsoft *ts, int ndesc)
1399 {
1400 uint32_t hstat;
1401 int data_retry, rts_retry;
1402 struct rtw_txdesc *tdn;
1403 const char *condstring;
1404
1405 rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts);
1406
1407 tdb->tdb_nfree += ndesc;
1408
1409 tdn = &tdb->tdb_desc[ts->ts_last];
1410
1411 hstat = letoh32(tdn->td_stat);
1412 rts_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_RTSRETRY_MASK);
1413 data_retry = MASK_AND_RSHIFT(hstat, RTW_TXSTAT_DRC_MASK);
1414
1415 sc->sc_if.if_collisions += rts_retry + data_retry;
1416
1417 if ((hstat & RTW_TXSTAT_TOK) != 0)
1418 condstring = "ok";
1419 else {
1420 sc->sc_if.if_oerrors++;
1421 condstring = "error";
1422 }
1423
1424 DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
1425 ("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n",
1426 sc->sc_dev.dv_xname, ts, ts->ts_first, ts->ts_last,
1427 condstring, rts_retry, data_retry));
1428 }
1429
1430 void
1431 rtw_reset_oactive(struct rtw_softc *sc)
1432 {
1433 short oflags;
1434 int pri;
1435 struct rtw_txsoft_blk *tsb;
1436 struct rtw_txdesc_blk *tdb;
1437 oflags = sc->sc_if.if_flags;
1438 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1439 tsb = &sc->sc_txsoft_blk[pri];
1440 tdb = &sc->sc_txdesc_blk[pri];
1441 if (!SIMPLEQ_EMPTY(&tsb->tsb_freeq) && tdb->tdb_nfree > 0)
1442 sc->sc_if.if_flags &= ~IFF_OACTIVE;
1443 }
1444 if (oflags != sc->sc_if.if_flags) {
1445 DPRINTF(sc, RTW_DEBUG_OACTIVE,
1446 ("%s: reset OACTIVE\n", __func__));
1447 }
1448 }
1449
1450
1451 void
1452 rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb,
1453 struct rtw_txdesc_blk *tdb, int force)
1454 {
1455 int ndesc;
1456 struct rtw_txsoft *ts;
1457
1458 while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
1459 ndesc = 1 + ts->ts_last - ts->ts_first;
1460 if (ts->ts_last < ts->ts_first)
1461 ndesc += tdb->tdb_ndesc;
1462
1463 KASSERT(ndesc > 0);
1464
1465 rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
1466 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1467
1468 if (force) {
1469 int i;
1470 for (i = ts->ts_first; ; i = RTW_NEXT_IDX(tdb, i)) {
1471 tdb->tdb_desc[i].td_stat &=
1472 ~htole32(RTW_TXSTAT_OWN);
1473 if (i == ts->ts_last)
1474 break;
1475 }
1476 rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
1477 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1478 } else if ((tdb->tdb_desc[ts->ts_last].td_stat &
1479 htole32(RTW_TXSTAT_OWN)) != 0)
1480 break;
1481
1482 rtw_collect_txpkt(sc, tdb, ts, ndesc);
1483 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
1484 SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
1485 }
1486
1487 if (ts == NULL)
1488 tsb->tsb_tx_timer = 0;
1489 rtw_reset_oactive(sc);
1490 }
1491
1492 void
1493 rtw_intr_tx(struct rtw_softc *sc, u_int16_t isr)
1494 {
1495 int pri;
1496 struct rtw_txsoft_blk *tsb;
1497 struct rtw_txdesc_blk *tdb;
1498
1499 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1500 tsb = &sc->sc_txsoft_blk[pri];
1501 tdb = &sc->sc_txdesc_blk[pri];
1502
1503 rtw_collect_txring(sc, tsb, tdb, 0);
1504
1505 }
1506
1507 if ((isr & RTW_INTR_TX) != 0)
1508 rtw_start(&sc->sc_if);
1509 }
1510
1511 void
1512 rtw_intr_beacon(struct rtw_softc *sc, u_int16_t isr)
1513 {
1514 u_int next;
1515 uint32_t tsfth, tsftl;
1516 struct ieee80211com *ic;
1517 struct rtw_txdesc_blk *tdb = &sc->sc_txdesc_blk[RTW_TXPRIBCN];
1518 struct rtw_txsoft_blk *tsb = &sc->sc_txsoft_blk[RTW_TXPRIBCN];
1519 struct mbuf *m;
1520
1521 tsfth = RTW_READ(&sc->sc_regs, RTW_TSFTRH);
1522 tsftl = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
1523
1524 if ((isr & (RTW_INTR_TBDOK|RTW_INTR_TBDER)) != 0) {
1525 next = rtw_txring_next(&sc->sc_regs, tdb);
1526 RTW_DPRINTF(RTW_DEBUG_BEACON,
1527 ("%s: beacon ring %sprocessed, isr = %#04hx"
1528 ", next %u expected %u, %llu\n", __func__,
1529 (next == tdb->tdb_next) ? "" : "un", isr, next,
1530 tdb->tdb_next, (uint64_t)tsfth << 32 | tsftl));
1531 if ((RTW_READ8(&sc->sc_regs, RTW_TPPOLL) & RTW_TPPOLL_BQ) == 0){
1532 rtw_collect_txring(sc, tsb, tdb, 1);
1533 tdb->tdb_next = 0;
1534 }
1535 }
1536
1537
1538 if ((isr & RTW_INTR_BCNINT) != 0 &&
1539 sc->sc_ic.ic_state == IEEE80211_S_RUN &&
1540 SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) {
1541 RTW_DPRINTF(RTW_DEBUG_BEACON,
1542 ("%s: beacon prep. time, isr = %#04hx"
1543 ", %16llu\n", __func__, isr,
1544 (uint64_t)tsfth << 32 | tsftl));
1545 ic = &sc->sc_ic;
1546 if ((m = ieee80211_beacon_alloc(ic, ic->ic_bss)) != NULL) {
1547 RTW_DPRINTF(RTW_DEBUG_BEACON,
1548 ("%s: m %p len %u\n", __func__, m, m->m_len));
1549 }
1550
1551 if (m == NULL) {
1552 printf("%s: could not allocate beacon\n",
1553 sc->sc_dev.dv_xname);
1554 return;
1555 }
1556 m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ic->ic_bss);
1557 IF_ENQUEUE(&sc->sc_beaconq, m);
1558 rtw_start(&sc->sc_if);
1559 }
1560 }
1561
1562 void
1563 rtw_intr_atim(struct rtw_softc *sc)
1564 {
1565
1566 return;
1567 }
1568
1569 #ifdef RTW_DEBUG
1570 void
1571 rtw_dump_rings(struct rtw_softc *sc)
1572 {
1573 struct rtw_txdesc_blk *tdb;
1574 struct rtw_rxdesc *rd;
1575 struct rtw_rxdesc_blk *rdb;
1576 int desc, pri;
1577
1578 if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0)
1579 return;
1580
1581 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1582 tdb = &sc->sc_txdesc_blk[pri];
1583 printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri,
1584 tdb->tdb_ndesc, tdb->tdb_nfree);
1585 for (desc = 0; desc < tdb->tdb_ndesc; desc++)
1586 rtw_print_txdesc(sc, ".", NULL, tdb, desc);
1587 }
1588
1589 rdb = &sc->sc_rxdesc_blk;
1590
1591 for (desc = 0; desc < RTW_RXQLEN; desc++) {
1592 rd = &rdb->rdb_desc[desc];
1593 printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x "
1594 "rsvd1/tsfth %08x\n", __func__,
1595 (desc >= rdb->rdb_ndesc) ? "UNUSED " : "",
1596 letoh32(rd->rd_ctl), letoh32(rd->rd_rssi),
1597 letoh32(rd->rd_buf), letoh32(rd->rd_tsfth));
1598 }
1599 }
1600 #endif
1601
1602 void
1603 rtw_hwring_setup(struct rtw_softc *sc)
1604 {
1605 int pri;
1606 struct rtw_regs *regs = &sc->sc_regs;
1607 struct rtw_txdesc_blk *tdb;
1608
1609 sc->sc_txdesc_blk[RTW_TXPRILO].tdb_basereg = RTW_TLPDA;
1610 sc->sc_txdesc_blk[RTW_TXPRILO].tdb_base = RTW_RING_BASE(sc, hd_txlo);
1611 sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_basereg = RTW_TNPDA;
1612 sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_base = RTW_RING_BASE(sc, hd_txmd);
1613 sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_basereg = RTW_THPDA;
1614 sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_base = RTW_RING_BASE(sc, hd_txhi);
1615 sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_basereg = RTW_TBDA;
1616 sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_base = RTW_RING_BASE(sc, hd_bcn);
1617
1618 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1619 tdb = &sc->sc_txdesc_blk[pri];
1620 RTW_WRITE(regs, tdb->tdb_basereg, tdb->tdb_base);
1621 RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
1622 ("%s: reg[tdb->tdb_basereg] <- %lx\n", __func__,
1623 (u_int *)tdb->tdb_base));
1624 }
1625
1626 RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx));
1627
1628 RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
1629 ("%s: reg[RDSAR] <- %lx\n", __func__,
1630 (u_int *)RTW_RING_BASE(sc, hd_rx)));
1631
1632 RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR);
1633 }
1634
1635 int
1636 rtw_swring_setup(struct rtw_softc *sc)
1637 {
1638 int rc, pri;
1639 struct rtw_rxdesc_blk *rdb;
1640 struct rtw_txdesc_blk *tdb;
1641
1642 rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]);
1643
1644 rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]);
1645
1646 rdb = &sc->sc_rxdesc_blk;
1647 if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft,
1648 &rdb->rdb_ndesc, sc->sc_dev.dv_xname)) != 0 &&
1649 rdb->rdb_ndesc == 0) {
1650 printf("%s: could not allocate rx buffers\n",
1651 sc->sc_dev.dv_xname);
1652 return rc;
1653 }
1654
1655 rdb = &sc->sc_rxdesc_blk;
1656 rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc,
1657 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1658 rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1);
1659 rdb->rdb_next = 0;
1660
1661 tdb = &sc->sc_txdesc_blk[0];
1662 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1663 rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc,
1664 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1665 }
1666 return 0;
1667 }
1668
1669 void
1670 rtw_txdesc_blk_init(struct rtw_txdesc_blk *tdb)
1671 {
1672 int i;
1673
1674 bzero(tdb->tdb_desc, sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
1675 for (i = 0; i < tdb->tdb_ndesc; i++)
1676 tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i));
1677 }
1678
1679 u_int
1680 rtw_txring_next(struct rtw_regs *regs, struct rtw_txdesc_blk *tdb)
1681 {
1682 return (letoh32(RTW_READ(regs, tdb->tdb_basereg)) - tdb->tdb_base) /
1683 sizeof(struct rtw_txdesc);
1684 }
1685
1686 void
1687 rtw_txring_fixup(struct rtw_softc *sc)
1688 {
1689 int pri;
1690 u_int next;
1691 struct rtw_txdesc_blk *tdb;
1692 struct rtw_regs *regs = &sc->sc_regs;
1693
1694 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1695 tdb = &sc->sc_txdesc_blk[pri];
1696 next = rtw_txring_next(regs, tdb);
1697 if (tdb->tdb_next == next)
1698 continue;
1699 RTW_DPRINTF(RTW_DEBUG_BUGS,
1700 ("%s: tx-ring %d expected next %u, read %u\n", __func__,
1701 pri, tdb->tdb_next, next));
1702 tdb->tdb_next = MIN(next, tdb->tdb_ndesc - 1);
1703 }
1704 }
1705
1706 void
1707 rtw_rxring_fixup(struct rtw_softc *sc)
1708 {
1709 u_int next;
1710 uint32_t rdsar;
1711 struct rtw_rxdesc_blk *rdb;
1712
1713 rdsar = letoh32(RTW_READ(&sc->sc_regs, RTW_RDSAR));
1714 next = (rdsar - RTW_RING_BASE(sc, hd_rx)) / sizeof(struct rtw_rxdesc);
1715
1716 rdb = &sc->sc_rxdesc_blk;
1717 if (rdb->rdb_next != next) {
1718 RTW_DPRINTF(RTW_DEBUG_BUGS,
1719 ("%s: rx-ring expected next %u, read %u\n", __func__,
1720 rdb->rdb_next, next));
1721 rdb->rdb_next = MIN(next, rdb->rdb_ndesc - 1);
1722 }
1723 }
1724
1725 void
1726 rtw_txdescs_reset(struct rtw_softc *sc)
1727 {
1728 int pri;
1729
1730 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1731 rtw_collect_txring(sc, &sc->sc_txsoft_blk[pri],
1732 &sc->sc_txdesc_blk[pri], 1);
1733 }
1734 }
1735
1736 void
1737 rtw_intr_ioerror(struct rtw_softc *sc, u_int16_t isr)
1738 {
1739 uint8_t cr = 0;
1740 int xmtr = 0, rcvr = 0;
1741 struct rtw_regs *regs = &sc->sc_regs;
1742
1743 if ((isr & RTW_INTR_TXFOVW) != 0) {
1744 RTW_DPRINTF(RTW_DEBUG_BUGS,
1745 ("%s: tx fifo underflow\n", sc->sc_dev.dv_xname));
1746 rcvr = xmtr = 1;
1747 cr |= RTW_CR_TE | RTW_CR_RE;
1748 }
1749
1750 if ((isr & (RTW_INTR_RDU|RTW_INTR_RXFOVW)) != 0) {
1751 cr |= RTW_CR_RE;
1752 rcvr = 1;
1753 }
1754
1755 RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: restarting xmit/recv, isr %hx"
1756 "\n", sc->sc_dev.dv_xname, isr));
1757
1758 #ifdef RTW_DEBUG
1759 rtw_dump_rings(sc);
1760 #endif
1761
1762 rtw_io_enable(regs, cr, 0);
1763
1764
1765 if (rcvr)
1766 rtw_intr_rx(sc, 0);
1767
1768
1769
1770 if (xmtr)
1771 rtw_txdescs_reset(sc);
1772
1773 RTW_WRITE16(regs, RTW_IMR, 0);
1774 RTW_SYNC(regs, RTW_IMR, RTW_IMR);
1775
1776 if (rtw_do_chip_reset) {
1777 rtw_chip_reset1(regs, sc->sc_dev.dv_xname);
1778 }
1779
1780 rtw_rxdesc_init_all(&sc->sc_rxdesc_blk, &sc->sc_rxsoft[0], 1);
1781
1782 #ifdef RTW_DEBUG
1783 rtw_dump_rings(sc);
1784 #endif
1785
1786 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
1787 RTW_SYNC(regs, RTW_IMR, RTW_IMR);
1788 if (rcvr)
1789 rtw_rxring_fixup(sc);
1790 rtw_io_enable(regs, cr, 1);
1791 if (xmtr)
1792 rtw_txring_fixup(sc);
1793 }
1794
1795 void
1796 rtw_suspend_ticks(struct rtw_softc *sc)
1797 {
1798 RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
1799 ("%s: suspending ticks\n", sc->sc_dev.dv_xname));
1800 sc->sc_do_tick = 0;
1801 }
1802
1803 void
1804 rtw_resume_ticks(struct rtw_softc *sc)
1805 {
1806 u_int32_t tsftrl0, tsftrl1, next_tick;
1807
1808 tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
1809
1810 tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
1811 next_tick = tsftrl1 + 1000000;
1812 RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tick);
1813
1814 sc->sc_do_tick = 1;
1815
1816 RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
1817 ("%s: resume ticks delta %#08x now %#08x next %#08x\n",
1818 sc->sc_dev.dv_xname, tsftrl1 - tsftrl0, tsftrl1, next_tick));
1819 }
1820
1821 void
1822 rtw_intr_timeout(struct rtw_softc *sc)
1823 {
1824 RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", sc->sc_dev.dv_xname));
1825 if (sc->sc_do_tick)
1826 rtw_resume_ticks(sc);
1827 return;
1828 }
1829
1830 int
1831 rtw_intr(void *arg)
1832 {
1833 int i;
1834 struct rtw_softc *sc = arg;
1835 struct rtw_regs *regs = &sc->sc_regs;
1836 u_int16_t isr;
1837
1838
1839
1840
1841
1842 if ((sc->sc_flags & RTW_F_ENABLED) == 0 ||
1843 (sc->sc_if.if_flags & IFF_RUNNING) == 0 ||
1844 (sc->sc_dev.dv_flags & DVF_ACTIVE) == 0) {
1845 RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n",
1846 sc->sc_dev.dv_xname));
1847 return (0);
1848 }
1849
1850 for (i = 0; i < 10; i++) {
1851 isr = RTW_READ16(regs, RTW_ISR);
1852
1853 RTW_WRITE16(regs, RTW_ISR, isr);
1854 RTW_WBR(regs, RTW_ISR, RTW_ISR);
1855
1856 if (sc->sc_intr_ack != NULL)
1857 (*sc->sc_intr_ack)(regs);
1858
1859 if (isr == 0)
1860 break;
1861
1862 #ifdef RTW_DEBUG
1863 #define PRINTINTR(flag) do { \
1864 if ((isr & flag) != 0) { \
1865 printf("%s" #flag, delim); \
1866 delim = ","; \
1867 } \
1868 } while (0)
1869
1870 if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) {
1871 const char *delim = "<";
1872
1873 printf("%s: reg[ISR] = %x", sc->sc_dev.dv_xname, isr);
1874
1875 PRINTINTR(RTW_INTR_TXFOVW);
1876 PRINTINTR(RTW_INTR_TIMEOUT);
1877 PRINTINTR(RTW_INTR_BCNINT);
1878 PRINTINTR(RTW_INTR_ATIMINT);
1879 PRINTINTR(RTW_INTR_TBDER);
1880 PRINTINTR(RTW_INTR_TBDOK);
1881 PRINTINTR(RTW_INTR_THPDER);
1882 PRINTINTR(RTW_INTR_THPDOK);
1883 PRINTINTR(RTW_INTR_TNPDER);
1884 PRINTINTR(RTW_INTR_TNPDOK);
1885 PRINTINTR(RTW_INTR_RXFOVW);
1886 PRINTINTR(RTW_INTR_RDU);
1887 PRINTINTR(RTW_INTR_TLPDER);
1888 PRINTINTR(RTW_INTR_TLPDOK);
1889 PRINTINTR(RTW_INTR_RER);
1890 PRINTINTR(RTW_INTR_ROK);
1891
1892 printf(">\n");
1893 }
1894 #undef PRINTINTR
1895 #endif
1896
1897 if ((isr & RTW_INTR_RX) != 0)
1898 rtw_intr_rx(sc, isr & RTW_INTR_RX);
1899 if ((isr & RTW_INTR_TX) != 0)
1900 rtw_intr_tx(sc, isr & RTW_INTR_TX);
1901 if ((isr & RTW_INTR_BEACON) != 0)
1902 rtw_intr_beacon(sc, isr & RTW_INTR_BEACON);
1903 if ((isr & RTW_INTR_ATIMINT) != 0)
1904 rtw_intr_atim(sc);
1905 if ((isr & RTW_INTR_IOERROR) != 0)
1906 rtw_intr_ioerror(sc, isr & RTW_INTR_IOERROR);
1907 if ((isr & RTW_INTR_TIMEOUT) != 0)
1908 rtw_intr_timeout(sc);
1909 }
1910
1911 return 1;
1912 }
1913
1914
1915 void
1916 rtw_stop(struct ifnet *ifp, int disable)
1917 {
1918 int pri;
1919 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
1920 struct ieee80211com *ic = &sc->sc_ic;
1921 struct rtw_regs *regs = &sc->sc_regs;
1922
1923 if ((sc->sc_flags & RTW_F_ENABLED) == 0)
1924 return;
1925
1926 rtw_suspend_ticks(sc);
1927
1928 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
1929
1930 if ((sc->sc_flags & RTW_F_INVALID) == 0) {
1931
1932 RTW_WRITE16(regs, RTW_IMR, 0);
1933
1934 RTW_WBW(regs, RTW_TPPOLL, RTW_IMR);
1935
1936
1937
1938
1939 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
1940
1941 RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR);
1942
1943 rtw_io_enable(&sc->sc_regs, RTW_CR_RE|RTW_CR_TE, 0);
1944 }
1945
1946 for (pri = 0; pri < RTW_NTXPRI; pri++) {
1947 rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic,
1948 &sc->sc_txsoft_blk[pri]);
1949 }
1950
1951 rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]);
1952
1953 if (disable)
1954 rtw_disable(sc);
1955
1956
1957 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
1958 ifp->if_timer = 0;
1959
1960 return;
1961 }
1962
1963 #ifdef RTW_DEBUG
1964 const char *
1965 rtw_pwrstate_string(enum rtw_pwrstate power)
1966 {
1967 switch (power) {
1968 case RTW_ON:
1969 return "on";
1970 case RTW_SLEEP:
1971 return "sleep";
1972 case RTW_OFF:
1973 return "off";
1974 default:
1975 return "unknown";
1976 }
1977 }
1978 #endif
1979
1980
1981
1982
1983
1984 void
1985 rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
1986 int before_rf, int digphy)
1987 {
1988 u_int32_t anaparm;
1989
1990 anaparm = RTW_READ(regs, RTW_ANAPARM_0);
1991 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
1992
1993 switch (power) {
1994 case RTW_OFF:
1995 if (before_rf)
1996 return;
1997 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF;
1998 anaparm |= RTW_ANAPARM_TXDACOFF;
1999 break;
2000 case RTW_SLEEP:
2001 if (!before_rf)
2002 return;
2003 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP;
2004 anaparm |= RTW_ANAPARM_TXDACOFF;
2005 break;
2006 case RTW_ON:
2007 if (!before_rf)
2008 return;
2009 anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON;
2010 break;
2011 }
2012 RTW_DPRINTF(RTW_DEBUG_PWR,
2013 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2014 __func__, rtw_pwrstate_string(power),
2015 (before_rf) ? "before" : "after", anaparm));
2016
2017 RTW_WRITE(regs, RTW_ANAPARM_0, anaparm);
2018 RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0);
2019 }
2020
2021
2022
2023
2024 void
2025 rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
2026 int before_rf, int digphy)
2027 {
2028 u_int32_t anaparm;
2029
2030 anaparm = RTW_READ(regs, RTW_ANAPARM_0);
2031 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
2032
2033 switch (power) {
2034 case RTW_OFF:
2035 if (before_rf)
2036 return;
2037 anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF;
2038 anaparm |= RTW_ANAPARM_TXDACOFF;
2039 break;
2040 case RTW_SLEEP:
2041 if (!before_rf)
2042 return;
2043 anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP;
2044 anaparm |= RTW_ANAPARM_TXDACOFF;
2045 break;
2046 case RTW_ON:
2047 if (!before_rf)
2048 return;
2049 anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON;
2050 break;
2051 }
2052 RTW_DPRINTF(RTW_DEBUG_PWR,
2053 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2054 __func__, rtw_pwrstate_string(power),
2055 (before_rf) ? "before" : "after", anaparm));
2056
2057 RTW_WRITE(regs, RTW_ANAPARM_0, anaparm);
2058 RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0);
2059 }
2060
2061 void
2062 rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
2063 int before_rf, int digphy)
2064 {
2065 u_int32_t anaparm;
2066
2067 anaparm = RTW_READ(regs, RTW_ANAPARM_0);
2068 anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
2069
2070 switch (power) {
2071 case RTW_OFF:
2072 if (before_rf)
2073 return;
2074 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF;
2075 anaparm |= RTW_ANAPARM_TXDACOFF;
2076 break;
2077 case RTW_SLEEP:
2078 if (!before_rf)
2079 return;
2080 anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP;
2081 anaparm |= RTW_ANAPARM_TXDACOFF;
2082 break;
2083 case RTW_ON:
2084 if (!before_rf)
2085 return;
2086 if (digphy) {
2087 anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON;
2088
2089 anaparm |= RTW_ANAPARM_TXDACOFF;
2090 } else
2091 anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON;
2092 break;
2093 }
2094 RTW_DPRINTF(RTW_DEBUG_PWR,
2095 ("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
2096 __func__, rtw_pwrstate_string(power),
2097 (before_rf) ? "before" : "after", anaparm));
2098
2099 RTW_WRITE(regs, RTW_ANAPARM_0, anaparm);
2100 RTW_SYNC(regs, RTW_ANAPARM_0, RTW_ANAPARM_0);
2101 }
2102
2103 void
2104 rtw_rtl_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
2105 int before_rf, int digphy)
2106 {
2107
2108 }
2109
2110 void
2111 rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf,
2112 int digphy)
2113 {
2114 struct rtw_regs *regs = &sc->sc_regs;
2115
2116 rtw_set_access(regs, RTW_ACCESS_ANAPARM);
2117
2118 (*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy);
2119
2120 rtw_set_access(regs, RTW_ACCESS_NONE);
2121
2122 return;
2123 }
2124
2125 int
2126 rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
2127 {
2128 int rc;
2129
2130 RTW_DPRINTF(RTW_DEBUG_PWR,
2131 ("%s: %s->%s\n", __func__,
2132 rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power)));
2133
2134 if (sc->sc_pwrstate == power)
2135 return 0;
2136
2137 rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY);
2138 rc = (*sc->sc_rf_pwrstate)(sc, power);
2139 rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY);
2140
2141 switch (power) {
2142 case RTW_ON:
2143
2144 break;
2145 case RTW_SLEEP:
2146
2147 break;
2148 case RTW_OFF:
2149
2150 break;
2151 }
2152 if (rc == 0)
2153 sc->sc_pwrstate = power;
2154 else
2155 sc->sc_pwrstate = RTW_OFF;
2156 return rc;
2157 }
2158
2159 int
2160 rtw_tune(struct rtw_softc *sc)
2161 {
2162 struct ieee80211com *ic = &sc->sc_ic;
2163 u_int chan, idx;
2164 u_int8_t txpower;
2165 int rc;
2166
2167 KASSERT(ic->ic_bss->ni_chan != NULL);
2168
2169 chan = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
2170 if (chan == 0 || chan == IEEE80211_CHAN_ANY)
2171 return 0;
2172
2173 if (chan == sc->sc_cur_chan) {
2174 RTW_DPRINTF(RTW_DEBUG_TUNE,
2175 ("%s: already tuned chan #%d\n", __func__, chan));
2176 return 0;
2177 }
2178
2179 rtw_suspend_ticks(sc);
2180
2181 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 0);
2182
2183
2184
2185 KASSERT((sc->sc_flags & RTW_F_ENABLED) != 0);
2186
2187 idx = RTW_SR_TXPOWER1 +
2188 ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan) - 1;
2189 KASSERT2(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14,
2190 ("%s: channel %d out of range", __func__,
2191 idx - RTW_SR_TXPOWER1 + 1));
2192 txpower = RTW_SR_GET(&sc->sc_srom, idx);
2193
2194 if ((rc = rtw_phy_init(sc)) != 0) {
2195
2196 printf("%s: phy init failed\n", sc->sc_dev.dv_xname);
2197 }
2198
2199 sc->sc_cur_chan = chan;
2200
2201 rtw_io_enable(&sc->sc_regs, RTW_CR_RE | RTW_CR_TE, 1);
2202
2203 rtw_resume_ticks(sc);
2204
2205 return rc;
2206 }
2207
2208 void
2209 rtw_disable(struct rtw_softc *sc)
2210 {
2211 int rc;
2212
2213 if ((sc->sc_flags & RTW_F_ENABLED) == 0)
2214 return;
2215
2216
2217 if ((sc->sc_flags & RTW_F_INVALID) == 0 &&
2218 (rc = rtw_pwrstate(sc, RTW_OFF)) != 0) {
2219 printf("%s: failed to turn off PHY (%d)\n",
2220 sc->sc_dev.dv_xname, rc);
2221 }
2222
2223 if (sc->sc_disable != NULL)
2224 (*sc->sc_disable)(sc);
2225
2226 sc->sc_flags &= ~RTW_F_ENABLED;
2227 }
2228
2229 int
2230 rtw_enable(struct rtw_softc *sc)
2231 {
2232 if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
2233 if (sc->sc_enable != NULL && (*sc->sc_enable)(sc) != 0) {
2234 printf("%s: device enable failed\n",
2235 sc->sc_dev.dv_xname);
2236 return (EIO);
2237 }
2238 sc->sc_flags |= RTW_F_ENABLED;
2239 }
2240 return (0);
2241 }
2242
2243 void
2244 rtw_transmit_config(struct rtw_softc *sc)
2245 {
2246 struct rtw_regs *regs = &sc->sc_regs;
2247 u_int32_t tcr;
2248
2249 tcr = RTW_READ(regs, RTW_TCR);
2250
2251 tcr |= RTW_TCR_CWMIN;
2252 tcr &= ~RTW_TCR_MXDMA_MASK;
2253 tcr |= RTW_TCR_MXDMA_256;
2254 if ((sc->sc_flags & RTW_F_RTL8185) == 0)
2255 tcr |= RTW8180_TCR_SAT;
2256 tcr &= ~RTW_TCR_LBK_MASK;
2257 tcr |= RTW_TCR_LBK_NORMAL;
2258
2259
2260 tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
2261 tcr |= LSHIFT(4, RTW_TCR_SRL_MASK) | LSHIFT(4, RTW_TCR_LRL_MASK);
2262
2263 tcr &= ~RTW_TCR_CRC;
2264
2265 RTW_WRITE(regs, RTW_TCR, tcr);
2266 RTW_SYNC(regs, RTW_TCR, RTW_TCR);
2267 }
2268
2269 void
2270 rtw_enable_interrupts(struct rtw_softc *sc)
2271 {
2272 struct rtw_regs *regs = &sc->sc_regs;
2273
2274 sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT;
2275 sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT;
2276
2277 RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
2278 RTW_WBW(regs, RTW_IMR, RTW_ISR);
2279 RTW_WRITE16(regs, RTW_ISR, 0xffff);
2280 RTW_SYNC(regs, RTW_IMR, RTW_ISR);
2281
2282
2283 if (sc->sc_intr_ack != NULL)
2284 (*sc->sc_intr_ack)(regs);
2285 }
2286
2287 void
2288 rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode)
2289 {
2290 uint8_t msr;
2291
2292
2293 rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG);
2294
2295 msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK;
2296
2297 switch (opmode) {
2298 case IEEE80211_M_AHDEMO:
2299 case IEEE80211_M_IBSS:
2300 msr |= RTW_MSR_NETYPE_ADHOC_OK;
2301 break;
2302 case IEEE80211_M_HOSTAP:
2303 msr |= RTW_MSR_NETYPE_AP_OK;
2304 break;
2305 case IEEE80211_M_MONITOR:
2306
2307 msr |= RTW_MSR_NETYPE_NOLINK;
2308 break;
2309 case IEEE80211_M_STA:
2310 msr |= RTW_MSR_NETYPE_INFRA_OK;
2311 break;
2312 }
2313 RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr);
2314
2315 rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE);
2316 }
2317
2318 void
2319 rtw_pktfilt_load(struct rtw_softc *sc)
2320 {
2321 struct rtw_regs *regs = &sc->sc_regs;
2322 struct ieee80211com *ic = &sc->sc_ic;
2323 struct arpcom *ec = &ic->ic_ac;
2324 struct ifnet *ifp = &sc->sc_ic.ic_if;
2325 int hash;
2326 u_int32_t hashes[2] = { 0, 0 };
2327 struct ether_multi *enm;
2328 struct ether_multistep step;
2329
2330
2331
2332 sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK;
2333 sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW8180_RCR_RXFTH_MASK);
2334
2335 sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT;
2336
2337 sc->sc_rcr |= RTW_RCR_ENMARP;
2338
2339 sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW8180_RCR_RXFTH_WHOLE;
2340
2341 switch (ic->ic_opmode) {
2342 case IEEE80211_M_MONITOR:
2343 sc->sc_rcr |= RTW_RCR_MONITOR;
2344 break;
2345 case IEEE80211_M_AHDEMO:
2346 case IEEE80211_M_IBSS:
2347
2348 sc->sc_rcr |= RTW_RCR_ADD3;
2349 break;
2350 default:
2351 break;
2352 }
2353
2354 ifp->if_flags &= ~IFF_ALLMULTI;
2355
2356
2357 if ((ifp->if_flags & IFF_BROADCAST) != 0)
2358 sc->sc_rcr |= RTW_RCR_AB;
2359
2360 if (ifp->if_flags & IFF_PROMISC) {
2361 sc->sc_rcr |= RTW_RCR_AB;
2362 allmulti:
2363 ifp->if_flags |= IFF_ALLMULTI;
2364 goto setit;
2365 }
2366
2367
2368
2369
2370 ETHER_FIRST_MULTI(step, ec, enm);
2371 while (enm != NULL) {
2372
2373 if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
2374 ETHER_ADDR_LEN) != 0)
2375 goto allmulti;
2376
2377 hash = ether_crc32_be((enm->enm_addrlo),
2378 IEEE80211_ADDR_LEN) >> 26;
2379 hashes[hash >> 5] |= (1 << (hash & 0x1f));
2380 sc->sc_rcr |= RTW_RCR_AM;
2381 ETHER_NEXT_MULTI(step, enm);
2382 }
2383
2384
2385 if (~(hashes[0] & hashes[1]) == 0)
2386 goto allmulti;
2387
2388 setit:
2389 if (ifp->if_flags & IFF_ALLMULTI) {
2390 sc->sc_rcr |= RTW_RCR_AM;
2391 hashes[0] = hashes[1] = 0xffffffff;
2392 }
2393
2394 RTW_WRITE(regs, RTW_MAR0, hashes[0]);
2395 RTW_WRITE(regs, RTW_MAR1, hashes[1]);
2396 RTW_WRITE(regs, RTW_RCR, sc->sc_rcr);
2397 RTW_SYNC(regs, RTW_MAR0, RTW_RCR);
2398
2399 DPRINTF(sc, RTW_DEBUG_PKTFILT,
2400 ("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
2401 sc->sc_dev.dv_xname, RTW_READ(regs, RTW_MAR0),
2402 RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)));
2403
2404 return;
2405 }
2406
2407
2408 int
2409 rtw_init(struct ifnet *ifp)
2410 {
2411 struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
2412 struct ieee80211com *ic = &sc->sc_ic;
2413 struct rtw_regs *regs = &sc->sc_regs;
2414 int rc = 0;
2415
2416 if ((rc = rtw_enable(sc)) != 0)
2417 goto out;
2418
2419
2420 rtw_stop(ifp, 0);
2421
2422 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
2423 DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n",
2424 __func__, ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan),
2425 ic->ic_bss->ni_chan->ic_freq, ic->ic_bss->ni_chan->ic_flags));
2426
2427 if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
2428 goto out;
2429
2430 if ((rc = rtw_swring_setup(sc)) != 0)
2431 goto out;
2432
2433 rtw_transmit_config(sc);
2434
2435 rtw_set_access(regs, RTW_ACCESS_CONFIG);
2436
2437 RTW_WRITE8(regs, RTW_MSR, 0x0);
2438 RTW_WBW(regs, RTW_MSR, RTW_BRSR);
2439
2440
2441 if (sc->sc_flags & RTW_F_RTL8185)
2442 RTW_WRITE16(regs, RTW_BRSR, RTW8185_BRSR_MBR_2MBPS);
2443 else
2444 RTW_WRITE16(regs, RTW_BRSR, RTW8180_BRSR_MBR_2MBPS);
2445 RTW_SYNC(regs, RTW_BRSR, RTW_BRSR);
2446
2447 rtw_set_access(regs, RTW_ACCESS_ANAPARM);
2448 rtw_set_access(regs, RTW_ACCESS_NONE);
2449
2450
2451 RTW_WRITE(regs, RTW_FEMR, 0xffff);
2452 RTW_SYNC(regs, RTW_FEMR, RTW_FEMR);
2453
2454 rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev.dv_xname);
2455
2456 RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay);
2457
2458 RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
2459
2460 RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT);
2461
2462 rtw_enable_interrupts(sc);
2463
2464 rtw_pktfilt_load(sc);
2465
2466 rtw_hwring_setup(sc);
2467
2468 rtw_io_enable(regs, RTW_CR_RE|RTW_CR_TE, 1);
2469
2470 ifp->if_flags |= IFF_RUNNING;
2471 ic->ic_state = IEEE80211_S_INIT;
2472
2473 RTW_WRITE16(regs, RTW_BSSID16, 0x0);
2474 RTW_WRITE(regs, RTW_BSSID32, 0x0);
2475
2476 rtw_resume_ticks(sc);
2477
2478 rtw_set_nettype(sc, IEEE80211_M_MONITOR);
2479
2480 if (ic->ic_opmode == IEEE80211_M_MONITOR)
2481 return ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
2482 else
2483 return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2484
2485 out:
2486 printf("%s: interface not running\n", sc->sc_dev.dv_xname);
2487 return rc;
2488 }
2489
2490 void
2491 rtw_led_init(struct rtw_regs *regs)
2492 {
2493 u_int8_t cfg0, cfg1;
2494
2495 rtw_set_access(regs, RTW_ACCESS_CONFIG);
2496
2497 cfg0 = RTW_READ8(regs, RTW_CONFIG0);
2498 cfg0 |= RTW8180_CONFIG0_LEDGPOEN;
2499 RTW_WRITE8(regs, RTW_CONFIG0, cfg0);
2500
2501 cfg1 = RTW_READ8(regs, RTW_CONFIG1);
2502 RTW_DPRINTF(RTW_DEBUG_LED,
2503 ("%s: read % from reg[CONFIG1]\n", __func__, cfg1));
2504
2505 cfg1 &= ~RTW_CONFIG1_LEDS_MASK;
2506 cfg1 |= RTW_CONFIG1_LEDS_TX_RX;
2507 RTW_WRITE8(regs, RTW_CONFIG1, cfg1);
2508
2509 rtw_set_access(regs, RTW_ACCESS_NONE);
2510 }
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521 void
2522 rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate)
2523 {
2524 struct rtw_led_state *ls;
2525
2526 ls = &sc->sc_led_state;
2527
2528 switch (nstate) {
2529 case IEEE80211_S_INIT:
2530 rtw_led_init(&sc->sc_regs);
2531 timeout_del(&ls->ls_slow_ch);
2532 timeout_del(&ls->ls_fast_ch);
2533 ls->ls_slowblink = 0;
2534 ls->ls_actblink = 0;
2535 ls->ls_default = 0;
2536 break;
2537 case IEEE80211_S_SCAN:
2538 timeout_add(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
2539 timeout_add(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
2540
2541 case IEEE80211_S_AUTH:
2542 case IEEE80211_S_ASSOC:
2543 ls->ls_default = RTW_LED1;
2544 ls->ls_actblink = RTW_LED1;
2545 ls->ls_slowblink = RTW_LED1;
2546 break;
2547 case IEEE80211_S_RUN:
2548 ls->ls_slowblink = 0;
2549 break;
2550 }
2551 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
2552 }
2553
2554 void
2555 rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, u_int hwverid)
2556 {
2557 u_int8_t led_condition;
2558 bus_size_t ofs;
2559 u_int8_t mask, newval, val;
2560
2561 led_condition = ls->ls_default;
2562
2563 if (ls->ls_state & RTW_LED_S_SLOW)
2564 led_condition ^= ls->ls_slowblink;
2565 if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX))
2566 led_condition ^= ls->ls_actblink;
2567
2568 RTW_DPRINTF(RTW_DEBUG_LED,
2569 ("%s: LED condition %\n", __func__, led_condition));
2570
2571 switch (hwverid) {
2572 default:
2573 case RTW_TCR_HWVERID_RTL8180F:
2574 ofs = RTW_PSR;
2575 newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1;
2576 if (led_condition & RTW_LED0)
2577 newval &= ~RTW_PSR_LEDGPO0;
2578 if (led_condition & RTW_LED1)
2579 newval &= ~RTW_PSR_LEDGPO1;
2580 break;
2581 case RTW_TCR_HWVERID_RTL8180D:
2582 ofs = RTW_9346CR;
2583 mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS;
2584 newval = RTW_9346CR_EEM_PROGRAM;
2585 if (led_condition & RTW_LED0)
2586 newval |= RTW_9346CR_EEDI;
2587 if (led_condition & RTW_LED1)
2588 newval |= RTW_9346CR_EECS;
2589 break;
2590 }
2591 val = RTW_READ8(regs, ofs);
2592 RTW_DPRINTF(RTW_DEBUG_LED,
2593 ("%s: read % from reg[%#02]\n", __func__, val,
2594 (u_int *)ofs));
2595 val &= ~mask;
2596 val |= newval;
2597 RTW_WRITE8(regs, ofs, val);
2598 RTW_DPRINTF(RTW_DEBUG_LED,
2599 ("%s: wrote % to reg[%#02]\n", __func__, val,
2600 (u_int *)ofs));
2601 RTW_SYNC(regs, ofs, ofs);
2602 }
2603
2604 void
2605 rtw_led_fastblink(void *arg)
2606 {
2607 int ostate, s;
2608 struct rtw_softc *sc = (struct rtw_softc *)arg;
2609 struct rtw_led_state *ls = &sc->sc_led_state;
2610
2611 s = splnet();
2612 ostate = ls->ls_state;
2613 ls->ls_state ^= ls->ls_event;
2614
2615 if ((ls->ls_event & RTW_LED_S_TX) == 0)
2616 ls->ls_state &= ~RTW_LED_S_TX;
2617
2618 if ((ls->ls_event & RTW_LED_S_RX) == 0)
2619 ls->ls_state &= ~RTW_LED_S_RX;
2620
2621 ls->ls_event = 0;
2622
2623 if (ostate != ls->ls_state)
2624 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
2625 splx(s);
2626
2627 timeout_add(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
2628 }
2629
2630 void
2631 rtw_led_slowblink(void *arg)
2632 {
2633 int s;
2634 struct rtw_softc *sc = (struct rtw_softc *)arg;
2635 struct rtw_led_state *ls = &sc->sc_led_state;
2636
2637 s = splnet();
2638 ls->ls_state ^= RTW_LED_S_SLOW;
2639 rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
2640 splx(s);
2641 timeout_add(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
2642 }
2643
2644 void
2645 rtw_led_attach(struct rtw_led_state *ls, void *arg)
2646 {
2647 timeout_set(&ls->ls_fast_ch, rtw_led_fastblink, arg);
2648 timeout_set(&ls->ls_slow_ch, rtw_led_slowblink, arg);
2649 }
2650
2651 int
2652 rtw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2653 {
2654 int rc = 0, s;
2655 struct rtw_softc *sc = ifp->if_softc;
2656 struct ieee80211com *ic = &sc->sc_ic;
2657 struct ifreq *ifr = (struct ifreq *)data;
2658 struct ifaddr *ifa = (struct ifaddr *)data;
2659
2660 s = splnet();
2661 switch (cmd) {
2662 case SIOCSIFMTU:
2663 if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
2664 rc = EINVAL;
2665 } else if (ifp->if_mtu != ifr->ifr_mtu) {
2666 ifp->if_mtu = ifr->ifr_mtu;
2667 }
2668 break;
2669 case SIOCSIFADDR:
2670 ifp->if_flags |= IFF_UP;
2671 #ifdef INET
2672 if (ifa->ifa_addr->sa_family == AF_INET) {
2673 arp_ifinit(&ic->ic_ac, ifa);
2674 }
2675 #endif
2676
2677
2678 case SIOCSIFFLAGS:
2679 if ((ifp->if_flags & IFF_UP) != 0) {
2680 if ((sc->sc_flags & RTW_F_ENABLED) != 0) {
2681 rtw_pktfilt_load(sc);
2682 } else
2683 rc = rtw_init(ifp);
2684 } else if ((sc->sc_flags & RTW_F_ENABLED) != 0)
2685 rtw_stop(ifp, 1);
2686 break;
2687 case SIOCADDMULTI:
2688 case SIOCDELMULTI:
2689 if (cmd == SIOCADDMULTI)
2690 rc = ether_addmulti(ifr, &sc->sc_ic.ic_ac);
2691 else
2692 rc = ether_delmulti(ifr, &sc->sc_ic.ic_ac);
2693 if (rc != ENETRESET)
2694 break;
2695 if (ifp->if_flags & IFF_RUNNING)
2696 rtw_pktfilt_load(sc);
2697 rc = 0;
2698 break;
2699 default:
2700 if ((rc = ieee80211_ioctl(ifp, cmd, data)) == ENETRESET) {
2701 if ((sc->sc_flags & RTW_F_ENABLED) != 0)
2702 rc = rtw_init(ifp);
2703 else
2704 rc = 0;
2705 }
2706 break;
2707 }
2708 splx(s);
2709 return rc;
2710 }
2711
2712
2713
2714
2715 int
2716 rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp,
2717 struct rtw_txdesc_blk **tdbp, int pri)
2718 {
2719 struct rtw_txsoft_blk *tsb;
2720 struct rtw_txdesc_blk *tdb;
2721
2722 KASSERT(pri >= 0 && pri < RTW_NTXPRI);
2723
2724 tsb = &sc->sc_txsoft_blk[pri];
2725 tdb = &sc->sc_txdesc_blk[pri];
2726
2727 if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) {
2728 if (tsb->tsb_tx_timer == 0)
2729 tsb->tsb_tx_timer = 5;
2730 *tsbp = NULL;
2731 *tdbp = NULL;
2732 return -1;
2733 }
2734 *tsbp = tsb;
2735 *tdbp = tdb;
2736 return 0;
2737 }
2738
2739 struct mbuf *
2740 rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri,
2741 struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp,
2742 struct ieee80211_node **nip, short *if_flagsp)
2743 {
2744 struct mbuf *m;
2745
2746 if (IF_IS_EMPTY(ifq))
2747 return NULL;
2748 if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) {
2749 DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n",
2750 __func__, pri));
2751 *if_flagsp |= IFF_OACTIVE;
2752 sc->sc_if.if_timer = 1;
2753 return NULL;
2754 }
2755 IF_DEQUEUE(ifq, m);
2756 *nip = (struct ieee80211_node *)m->m_pkthdr.rcvif;
2757 m->m_pkthdr.rcvif = NULL;
2758 return m;
2759 }
2760
2761
2762
2763
2764 int
2765 rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp,
2766 struct rtw_txdesc_blk **tdbp, struct mbuf **mp,
2767 struct ieee80211_node **nip)
2768 {
2769 struct mbuf *m0;
2770 struct rtw_softc *sc;
2771 short *if_flagsp;
2772
2773 sc = (struct rtw_softc *)ifp->if_softc;
2774
2775 DPRINTF(sc, RTW_DEBUG_XMIT,
2776 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
2777
2778 if_flagsp = &ifp->if_flags;
2779
2780 if (sc->sc_ic.ic_state == IEEE80211_S_RUN &&
2781 (*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp,
2782 tdbp, nip, if_flagsp)) != NULL) {
2783 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n",
2784 __func__));
2785 return 0;
2786 }
2787
2788 if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_mgtq, RTW_TXPRIMD, tsbp,
2789 tdbp, nip, if_flagsp)) != NULL) {
2790 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n",
2791 __func__));
2792 return 0;
2793 }
2794
2795 if (sc->sc_ic.ic_state != IEEE80211_S_RUN) {
2796 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
2797 return 0;
2798 }
2799
2800 if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_pwrsaveq, RTW_TXPRIHI,
2801 tsbp, tdbp, nip, if_flagsp)) != NULL) {
2802 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue pwrsave frame\n",
2803 __func__));
2804 return 0;
2805 }
2806
2807 if (sc->sc_ic.ic_state != IEEE80211_S_RUN) {
2808 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
2809 return 0;
2810 }
2811
2812 *mp = NULL;
2813
2814 IFQ_POLL(&ifp->if_snd, m0);
2815 if (m0 == NULL) {
2816 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n",
2817 __func__));
2818 return 0;
2819 }
2820
2821 if (rtw_txring_choose(sc, tsbp, tdbp, RTW_TXPRIMD) == -1) {
2822 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no descriptor\n", __func__));
2823 *if_flagsp |= IFF_OACTIVE;
2824 sc->sc_if.if_timer = 1;
2825 return 0;
2826 }
2827
2828 IFQ_DEQUEUE(&ifp->if_snd, m0);
2829 if (m0 == NULL) {
2830 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame/ring ready\n",
2831 __func__));
2832 return 0;
2833 }
2834 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__));
2835 ifp->if_opackets++;
2836 #if NBPFILTER > 0
2837 if (ifp->if_bpf)
2838 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
2839 #endif
2840 if ((m0 = ieee80211_encap(ifp, m0, nip)) == NULL) {
2841 DPRINTF(sc, RTW_DEBUG_XMIT,
2842 ("%s: encap error\n", __func__));
2843 ifp->if_oerrors++;
2844 return -1;
2845 }
2846
2847
2848 if (sc->sc_ic.ic_flags & IEEE80211_F_WEPON) {
2849 if ((m0 = ieee80211_wep_crypt(ifp, m0, 1)) == NULL)
2850 return -1;
2851 }
2852
2853 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
2854 *mp = m0;
2855 return 0;
2856 }
2857
2858 int
2859 rtw_seg_too_short(bus_dmamap_t dmamap)
2860 {
2861 int i;
2862 for (i = 0; i < dmamap->dm_nsegs; i++) {
2863 if (dmamap->dm_segs[i].ds_len < 4) {
2864 printf("%s: segment too short\n", __func__);
2865 return 1;
2866 }
2867 }
2868 return 0;
2869 }
2870
2871
2872 struct mbuf *
2873 rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain,
2874 u_int ndescfree, short *ifflagsp, const char *dvname)
2875 {
2876 int first, rc;
2877 struct mbuf *m, *m0;
2878
2879 m0 = chain;
2880
2881
2882
2883
2884
2885 for (first = 1;
2886 ((rc = bus_dmamap_load_mbuf(dmat, dmam, m0,
2887 BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
2888 dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first;
2889 first = 0) {
2890 if (rc == 0)
2891 bus_dmamap_unload(dmat, dmam);
2892 MGETHDR(m, M_DONTWAIT, MT_DATA);
2893 if (m == NULL) {
2894 printf("%s: unable to allocate Tx mbuf\n",
2895 dvname);
2896 break;
2897 }
2898 if (m0->m_pkthdr.len > MHLEN) {
2899 MCLGET(m, M_DONTWAIT);
2900 if ((m->m_flags & M_EXT) == 0) {
2901 printf("%s: cannot allocate Tx cluster\n",
2902 dvname);
2903 m_freem(m);
2904 break;
2905 }
2906 }
2907 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, caddr_t));
2908 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
2909 m_freem(m0);
2910 m0 = m;
2911 m = NULL;
2912 }
2913 if (rc != 0) {
2914 printf("%s: cannot load Tx buffer, rc = %d\n", dvname, rc);
2915 m_freem(m0);
2916 return NULL;
2917 } else if (rtw_seg_too_short(dmam)) {
2918 printf("%s: cannot load Tx buffer, segment too short\n",
2919 dvname);
2920 bus_dmamap_unload(dmat, dmam);
2921 m_freem(m0);
2922 return NULL;
2923 } else if (dmam->dm_nsegs > ndescfree) {
2924 printf("%s: too many tx segments\n", dvname);
2925 bus_dmamap_unload(dmat, dmam);
2926 m_freem(m0);
2927 return NULL;
2928 }
2929 return m0;
2930 }
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952 int
2953 rtw_compute_duration1(int len, int use_ack, uint32_t flags, int rate,
2954 struct rtw_duration *d)
2955 {
2956 int pre, ctsrate;
2957 int ack, bitlen, data_dur, remainder;
2958
2959
2960
2961
2962
2963
2964
2965 bitlen = len * 8;
2966
2967 pre = IEEE80211_DUR_DS_SIFS;
2968 if ((flags & IEEE80211_F_SHPREAMBLE) != 0)
2969 pre += IEEE80211_DUR_DS_SHORT_PREAMBLE +
2970 IEEE80211_DUR_DS_FAST_PLCPHDR;
2971 else
2972 pre += IEEE80211_DUR_DS_LONG_PREAMBLE +
2973 IEEE80211_DUR_DS_SLOW_PLCPHDR;
2974
2975 d->d_residue = 0;
2976 data_dur = (bitlen * 2) / rate;
2977 remainder = (bitlen * 2) % rate;
2978 if (remainder != 0) {
2979 d->d_residue = (rate - remainder) / 16;
2980 data_dur++;
2981 }
2982
2983 switch (rate) {
2984 case 2:
2985 case 4:
2986
2987 ctsrate = 2;
2988 break;
2989 case 11:
2990 case 22:
2991 case 44:
2992
2993 ctsrate = 4;
2994 break;
2995 default:
2996
2997 return -1;
2998 }
2999
3000 d->d_plcp_len = data_dur;
3001
3002 ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0;
3003
3004 d->d_rts_dur =
3005 pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate +
3006 pre + data_dur +
3007 ack;
3008
3009 d->d_data_dur = ack;
3010
3011 return 0;
3012 }
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038 int
3039 rtw_compute_duration(struct ieee80211_frame *wh, int len, uint32_t flags,
3040 int fraglen, int rate, struct rtw_duration *d0, struct rtw_duration *dn,
3041 int *npktp, int debug)
3042 {
3043 int ack, rc;
3044 int firstlen, hdrlen, lastlen, lastlen0, npkt, overlen, paylen;
3045
3046 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS)
3047 hdrlen = sizeof(struct ieee80211_frame_addr4);
3048 else
3049 hdrlen = sizeof(struct ieee80211_frame);
3050
3051 paylen = len - hdrlen;
3052
3053 if ((flags & IEEE80211_F_WEPON) != 0)
3054 overlen = IEEE80211_WEP_TOTLEN + IEEE80211_CRC_LEN;
3055 else
3056 overlen = IEEE80211_CRC_LEN;
3057
3058 npkt = paylen / fraglen;
3059 lastlen0 = paylen % fraglen;
3060
3061 if (npkt == 0)
3062 lastlen = paylen + overlen;
3063 else if (lastlen0 != 0) {
3064 lastlen = lastlen0 + overlen;
3065 npkt++;
3066 } else
3067 lastlen = fraglen + overlen;
3068
3069 if (npktp != NULL)
3070 *npktp = npkt;
3071
3072 if (npkt > 1)
3073 firstlen = fraglen + overlen;
3074 else
3075 firstlen = paylen + overlen;
3076
3077 if (debug) {
3078 printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d "
3079 "fraglen %d overlen %d len %d rate %d flags %08x\n",
3080 __func__, npkt, firstlen, lastlen0, lastlen, fraglen,
3081 overlen, len, rate, flags);
3082 }
3083
3084 ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
3085 (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL;
3086
3087 rc = rtw_compute_duration1(firstlen + hdrlen, ack, flags, rate, d0);
3088 if (rc == -1)
3089 return rc;
3090
3091 if (npkt <= 1) {
3092 *dn = *d0;
3093 return 0;
3094 }
3095 return rtw_compute_duration1(lastlen + hdrlen, ack, flags, rate, dn);
3096 }
3097
3098 #ifdef RTW_DEBUG
3099 void
3100 rtw_print_txdesc(struct rtw_softc *sc, const char *action,
3101 struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc)
3102 {
3103 struct rtw_txdesc *td = &tdb->tdb_desc[desc];
3104 DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] next %#08x "
3105 "buf %#08x ctl0 %#08x ctl1 %#08x len %#08x\n",
3106 sc->sc_dev.dv_xname, ts, action, desc,
3107 letoh32(td->td_buf), letoh32(td->td_next),
3108 letoh32(td->td_ctl0), letoh32(td->td_ctl1),
3109 letoh32(td->td_len)));
3110 }
3111 #endif
3112
3113 void
3114 rtw_start(struct ifnet *ifp)
3115 {
3116 uint8_t tppoll;
3117 int desc, i, lastdesc, npkt, rate;
3118 uint32_t proto_ctl0, ctl0, ctl1;
3119 bus_dmamap_t dmamap;
3120 struct ieee80211com *ic;
3121 struct ieee80211_frame *wh;
3122 struct ieee80211_node *ni;
3123 struct mbuf *m0;
3124 struct rtw_softc *sc;
3125 struct rtw_duration *d0;
3126 struct rtw_txsoft_blk *tsb;
3127 struct rtw_txdesc_blk *tdb;
3128 struct rtw_txsoft *ts;
3129 struct rtw_txdesc *td;
3130
3131 sc = (struct rtw_softc *)ifp->if_softc;
3132 ic = &sc->sc_ic;
3133
3134 DPRINTF(sc, RTW_DEBUG_XMIT,
3135 ("%s: enter %s\n", sc->sc_dev.dv_xname, __func__));
3136
3137 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
3138 goto out;
3139
3140
3141 proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
3142
3143 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0)
3144 proto_ctl0 |= RTW_TXCTL0_SPLCP;
3145
3146 for (;;) {
3147 if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1)
3148 continue;
3149 if (m0 == NULL)
3150 break;
3151 ts = SIMPLEQ_FIRST(&tsb->tsb_freeq);
3152
3153 dmamap = ts->ts_dmamap;
3154
3155 m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0,
3156 tdb->tdb_nfree, &ifp->if_flags, sc->sc_dev.dv_xname);
3157
3158 if (m0 == NULL || dmamap->dm_nsegs == 0) {
3159 DPRINTF(sc, RTW_DEBUG_XMIT,
3160 ("%s: fail dmamap load\n", __func__));
3161 goto post_dequeue_err;
3162 }
3163
3164 wh = mtod(m0, struct ieee80211_frame *);
3165
3166
3167 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
3168 IEEE80211_FC0_TYPE_MGT)
3169 rate = 2;
3170 else
3171 rate = MAX(2, ieee80211_get_rate(ic));
3172
3173 #ifdef RTW_DEBUG
3174 if ((sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
3175 (IFF_DEBUG|IFF_LINK2)) {
3176 ieee80211_dump_pkt(mtod(m0, uint8_t *),
3177 (dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len
3178 : sizeof(wh), rate, 0);
3179 }
3180 #endif
3181 ctl0 = proto_ctl0 |
3182 LSHIFT(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK);
3183
3184 switch (rate) {
3185 default:
3186 case 2:
3187 ctl0 |= RTW_TXCTL0_RATE_1MBPS;
3188 break;
3189 case 4:
3190 ctl0 |= RTW_TXCTL0_RATE_2MBPS;
3191 break;
3192 case 11:
3193 ctl0 |= RTW_TXCTL0_RATE_5MBPS;
3194 break;
3195 case 22:
3196 ctl0 |= RTW_TXCTL0_RATE_11MBPS;
3197 break;
3198 }
3199
3200
3201 if (m0->m_pkthdr.len > ic->ic_rtsthreshold)
3202 ctl0 |= RTW_TXCTL0_RTSEN;
3203
3204 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
3205 IEEE80211_FC0_TYPE_MGT) {
3206 ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN);
3207 if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
3208 IEEE80211_FC0_SUBTYPE_BEACON)
3209 ctl0 |= RTW_TXCTL0_BEACON;
3210 }
3211
3212 if (rtw_compute_duration(wh, m0->m_pkthdr.len,
3213 ic->ic_flags & ~IEEE80211_F_WEPON, ic->ic_fragthreshold,
3214 rate, &ts->ts_d0, &ts->ts_dn, &npkt,
3215 (sc->sc_if.if_flags & (IFF_DEBUG|IFF_LINK2)) ==
3216 (IFF_DEBUG|IFF_LINK2)) == -1) {
3217 DPRINTF(sc, RTW_DEBUG_XMIT,
3218 ("%s: fail compute duration\n", __func__));
3219 goto post_load_err;
3220 }
3221
3222 d0 = &ts->ts_d0;
3223
3224 *(uint16_t*)wh->i_dur = htole16(d0->d_data_dur);
3225
3226 ctl1 = LSHIFT(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
3227 LSHIFT(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
3228
3229 if (d0->d_residue)
3230 ctl1 |= RTW_TXCTL1_LENGEXT;
3231
3232
3233
3234 ts->ts_first = tdb->tdb_next;
3235
3236 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
3237 BUS_DMASYNC_PREWRITE);
3238
3239 KASSERT(ts->ts_first < tdb->tdb_ndesc);
3240
3241 #if NBPFILTER > 0
3242 if (ic->ic_rawbpf != NULL)
3243 bpf_mtap((caddr_t)ic->ic_rawbpf, m0,
3244 BPF_DIRECTION_OUT);
3245
3246 if (sc->sc_radiobpf != NULL) {
3247 struct mbuf mb;
3248 struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
3249
3250 rt->rt_flags = 0;
3251 rt->rt_rate = rate;
3252 rt->rt_chan_freq =
3253 htole16(ic->ic_bss->ni_chan->ic_freq);
3254 rt->rt_chan_flags =
3255 htole16(ic->ic_bss->ni_chan->ic_flags);
3256
3257 mb.m_data = (caddr_t)rt;
3258 mb.m_len = sizeof(sc->sc_txtapu);
3259 mb.m_next = m0;
3260 mb.m_nextpkt = NULL;
3261 mb.m_type = 0;
3262 mb.m_flags = 0;
3263 bpf_mtap(sc->sc_radiobpf, &mb, BPF_DIRECTION_OUT);
3264
3265 }
3266 #endif
3267
3268 for (i = 0, lastdesc = desc = ts->ts_first;
3269 i < dmamap->dm_nsegs;
3270 i++, desc = RTW_NEXT_IDX(tdb, desc)) {
3271 if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) {
3272 DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
3273 ("%s: seg too long\n", __func__));
3274 goto post_load_err;
3275 }
3276 td = &tdb->tdb_desc[desc];
3277 td->td_ctl0 = htole32(ctl0);
3278 if (i != 0)
3279 td->td_ctl0 |= htole32(RTW_TXCTL0_OWN);
3280 td->td_ctl1 = htole32(ctl1);
3281 td->td_buf = htole32(dmamap->dm_segs[i].ds_addr);
3282 td->td_len = htole32(dmamap->dm_segs[i].ds_len);
3283 lastdesc = desc;
3284 #ifdef RTW_DEBUG
3285 rtw_print_txdesc(sc, "load", ts, tdb, desc);
3286 #endif
3287 }
3288
3289 KASSERT(desc < tdb->tdb_ndesc);
3290
3291 ts->ts_ni = ni;
3292 ts->ts_mbuf = m0;
3293 ts->ts_last = lastdesc;
3294 tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS);
3295 tdb->tdb_desc[ts->ts_first].td_ctl0 |=
3296 htole32(RTW_TXCTL0_FS);
3297
3298 #ifdef RTW_DEBUG
3299 rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first);
3300 rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last);
3301 #endif
3302
3303 tdb->tdb_nfree -= dmamap->dm_nsegs;
3304 tdb->tdb_next = desc;
3305
3306 rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
3307 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3308
3309 tdb->tdb_desc[ts->ts_first].td_ctl0 |=
3310 htole32(RTW_TXCTL0_OWN);
3311
3312 #ifdef RTW_DEBUG
3313 rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first);
3314 #endif
3315
3316 rtw_txdescs_sync(tdb, ts->ts_first, 1,
3317 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
3318
3319 SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q);
3320 SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q);
3321
3322 if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN])
3323 sc->sc_led_state.ls_event |= RTW_LED_S_TX;
3324 tsb->tsb_tx_timer = 5;
3325 ifp->if_timer = 1;
3326 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL);
3327 tppoll &= ~RTW_TPPOLL_SALL;
3328 tppoll |= tsb->tsb_poll & RTW_TPPOLL_ALL;
3329 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll);
3330 RTW_SYNC(&sc->sc_regs, RTW_TPPOLL, RTW_TPPOLL);
3331 }
3332 out:
3333 DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
3334 return;
3335 post_load_err:
3336 bus_dmamap_unload(sc->sc_dmat, dmamap);
3337 m_freem(m0);
3338 post_dequeue_err:
3339 ieee80211_release_node(&sc->sc_ic, ni);
3340 return;
3341 }
3342
3343 void
3344 rtw_idle(struct rtw_regs *regs)
3345 {
3346 int active;
3347
3348
3349
3350 RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
3351 RTW_WBR(regs, RTW_TPPOLL, RTW_TPPOLL);
3352
3353 for (active = 0; active < 300 &&
3354 (RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ACTIVE) != 0; active++)
3355 DELAY(10);
3356 RTW_DPRINTF(RTW_DEBUG_BUGS,
3357 ("%s: transmit DMA idle in %dus\n", __func__, active * 10));
3358 }
3359
3360 void
3361 rtw_watchdog(struct ifnet *ifp)
3362 {
3363 int pri, tx_timeouts = 0;
3364 struct rtw_softc *sc;
3365 struct rtw_txsoft_blk *tsb;
3366
3367 sc = ifp->if_softc;
3368
3369 ifp->if_timer = 0;
3370
3371 if ((sc->sc_flags & RTW_F_ENABLED) == 0)
3372 return;
3373
3374 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3375 tsb = &sc->sc_txsoft_blk[pri];
3376
3377 if (tsb->tsb_tx_timer == 0)
3378 continue;
3379 else if (--tsb->tsb_tx_timer == 0) {
3380 if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq))
3381 continue;
3382 RTW_DPRINTF(RTW_DEBUG_BUGS,
3383 ("%s: transmit timeout, priority %d\n",
3384 ifp->if_xname, pri));
3385 ifp->if_oerrors++;
3386 tx_timeouts++;
3387 } else
3388 ifp->if_timer = 1;
3389 }
3390
3391 if (tx_timeouts > 0) {
3392
3393
3394
3395
3396
3397 rtw_idle(&sc->sc_regs);
3398 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 0);
3399 rtw_txdescs_reset(sc);
3400 rtw_io_enable(&sc->sc_regs, RTW_CR_TE, 1);
3401 rtw_txring_fixup(sc);
3402 rtw_start(ifp);
3403 }
3404 ieee80211_watchdog(ifp);
3405 }
3406
3407 void
3408 rtw_next_scan(void *arg)
3409 {
3410 struct rtw_softc *sc = arg;
3411 struct ieee80211com *ic = &sc->sc_ic;
3412 struct ifnet *ifp = &ic->ic_if;
3413 int s;
3414
3415
3416 s = splnet();
3417 if (ic->ic_state == IEEE80211_S_SCAN)
3418 ieee80211_next_scan(ifp);
3419 splx(s);
3420 }
3421
3422 void
3423 rtw_join_bss(struct rtw_softc *sc, u_int8_t *bssid, u_int16_t intval0)
3424 {
3425 uint16_t bcnitv, bintritv, intval;
3426 int i;
3427 struct rtw_regs *regs = &sc->sc_regs;
3428
3429 for (i = 0; i < IEEE80211_ADDR_LEN; i++)
3430 RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]);
3431
3432 RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32);
3433
3434 rtw_set_access(regs, RTW_ACCESS_CONFIG);
3435
3436 intval = MIN(intval0, PRESHIFT(RTW_BCNITV_BCNITV_MASK));
3437
3438 bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK;
3439 bcnitv |= LSHIFT(intval, RTW_BCNITV_BCNITV_MASK);
3440 RTW_WRITE16(regs, RTW_BCNITV, bcnitv);
3441
3442 bintritv = RTW_READ16(regs, RTW_BINTRITV) & ~RTW_BINTRITV_BINTRITV;
3443 bintritv |= LSHIFT(1000, RTW_BINTRITV_BINTRITV);
3444 RTW_WRITE16(regs, RTW_BINTRITV, bintritv);
3445
3446 RTW_WRITE16(regs, RTW_ATIMWND, LSHIFT(1, RTW_ATIMWND_ATIMWND));
3447 RTW_WRITE16(regs, RTW_ATIMTRITV, LSHIFT(2, RTW_ATIMTRITV_ATIMTRITV));
3448 rtw_set_access(regs, RTW_ACCESS_NONE);
3449
3450
3451 RTW_WRITE8(regs, RTW8180_SCR, 0);
3452
3453 rtw_io_enable(regs, RTW_CR_RE | RTW_CR_TE, 1);
3454 }
3455
3456
3457 int
3458 rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
3459 {
3460 struct ifnet *ifp = &ic->ic_if;
3461 struct rtw_softc *sc = ifp->if_softc;
3462 enum ieee80211_state ostate;
3463 int error;
3464
3465 ostate = ic->ic_state;
3466
3467 rtw_led_newstate(sc, nstate);
3468
3469 if (nstate == IEEE80211_S_INIT) {
3470 timeout_del(&sc->sc_scan_to);
3471 sc->sc_cur_chan = IEEE80211_CHAN_ANY;
3472 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
3473 }
3474
3475 if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
3476 rtw_pwrstate(sc, RTW_ON);
3477
3478 if ((error = rtw_tune(sc)) != 0)
3479 return error;
3480
3481 switch (nstate) {
3482 case IEEE80211_S_INIT:
3483 panic("%s: unexpected state IEEE80211_S_INIT", __func__);
3484 break;
3485 case IEEE80211_S_SCAN:
3486 if (ostate != IEEE80211_S_SCAN) {
3487 bzero(ic->ic_bss->ni_bssid, IEEE80211_ADDR_LEN);
3488 rtw_set_nettype(sc, IEEE80211_M_MONITOR);
3489 }
3490
3491 timeout_add(&sc->sc_scan_to, rtw_dwelltime * hz / 1000);
3492
3493 break;
3494 case IEEE80211_S_RUN:
3495 switch (ic->ic_opmode) {
3496 case IEEE80211_M_HOSTAP:
3497 case IEEE80211_M_IBSS:
3498 rtw_set_nettype(sc, IEEE80211_M_MONITOR);
3499
3500 case IEEE80211_M_AHDEMO:
3501 case IEEE80211_M_STA:
3502 rtw_join_bss(sc, ic->ic_bss->ni_bssid,
3503 ic->ic_bss->ni_intval);
3504 break;
3505 case IEEE80211_M_MONITOR:
3506 break;
3507 }
3508 rtw_set_nettype(sc, ic->ic_opmode);
3509 break;
3510 case IEEE80211_S_ASSOC:
3511 case IEEE80211_S_AUTH:
3512 break;
3513 }
3514
3515 if (nstate != IEEE80211_S_SCAN)
3516 timeout_del(&sc->sc_scan_to);
3517
3518 return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
3519 }
3520
3521
3522 uint64_t
3523 rtw_tsf_extend(struct rtw_regs *regs, u_int32_t rstamp)
3524 {
3525 u_int32_t tsftl, tsfth;
3526
3527 tsfth = RTW_READ(regs, RTW_TSFTRH);
3528 tsftl = RTW_READ(regs, RTW_TSFTRL);
3529 if (tsftl < rstamp)
3530 tsfth--;
3531 return ((u_int64_t)tsfth << 32) | rstamp;
3532 }
3533
3534 void
3535 rtw_ibss_merge(struct rtw_softc *sc, struct ieee80211_node *ni,
3536 u_int32_t rstamp)
3537 {
3538 u_int8_t tppoll;
3539 struct ieee80211com *ic = &sc->sc_ic;
3540
3541 if (ieee80211_ibss_merge(ic, ni,
3542 rtw_tsf_extend(&sc->sc_regs, rstamp)) == ENETRESET) {
3543
3544
3545
3546 tppoll = RTW_READ8(&sc->sc_regs, RTW_TPPOLL);
3547 tppoll |= RTW_TPPOLL_SBQ;
3548 RTW_WRITE8(&sc->sc_regs, RTW_TPPOLL, tppoll);
3549 (void)ieee80211_new_state(&sc->sc_ic, IEEE80211_S_RUN, -1);
3550 }
3551 return;
3552 }
3553
3554 void
3555 rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
3556 struct ieee80211_node *ni, int subtype, int rssi, u_int32_t rstamp)
3557 {
3558 struct rtw_softc *sc = (struct rtw_softc*)ic->ic_softc;
3559
3560 (*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
3561
3562 switch (subtype) {
3563 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
3564 case IEEE80211_FC0_SUBTYPE_BEACON:
3565 if (ic->ic_opmode != IEEE80211_M_IBSS ||
3566 ic->ic_state != IEEE80211_S_RUN)
3567 return;
3568 rtw_ibss_merge(sc, ni, rstamp);
3569 break;
3570 default:
3571 break;
3572 }
3573 return;
3574 }
3575
3576 struct ieee80211_node *
3577 rtw_node_alloc(struct ieee80211com *ic)
3578 {
3579 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
3580 struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(ic);
3581
3582 DPRINTF(sc, RTW_DEBUG_NODE,
3583 ("%s: alloc node %p\n", sc->sc_dev.dv_xname, ni));
3584 return ni;
3585 }
3586
3587 void
3588 rtw_node_free(struct ieee80211com *ic, struct ieee80211_node *ni)
3589 {
3590 struct rtw_softc *sc = (struct rtw_softc *)ic->ic_if.if_softc;
3591
3592 DPRINTF(sc, RTW_DEBUG_NODE,
3593 ("%s: freeing node %p %s\n", sc->sc_dev.dv_xname, ni,
3594 ether_sprintf(ni->ni_bssid)));
3595 (*sc->sc_mtbl.mt_node_free)(ic, ni);
3596 }
3597
3598 int
3599 rtw_media_change(struct ifnet *ifp)
3600 {
3601 int error;
3602
3603 error = ieee80211_media_change(ifp);
3604 if (error == ENETRESET) {
3605 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
3606 (IFF_RUNNING|IFF_UP))
3607 rtw_init(ifp);
3608 error = 0;
3609 }
3610 return error;
3611 }
3612
3613 void
3614 rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
3615 {
3616 struct rtw_softc *sc = ifp->if_softc;
3617
3618 if ((sc->sc_flags & RTW_F_ENABLED) == 0) {
3619 imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
3620 imr->ifm_status = 0;
3621 return;
3622 }
3623 ieee80211_media_status(ifp, imr);
3624 }
3625
3626 void
3627 rtw_power(int why, void *arg)
3628 {
3629 struct rtw_softc *sc = arg;
3630 struct ifnet *ifp = &sc->sc_ic.ic_if;
3631 int s;
3632
3633 DPRINTF(sc, RTW_DEBUG_PWR,
3634 ("%s: rtw_power(%d,)\n", sc->sc_dev.dv_xname, why));
3635
3636 s = splnet();
3637 switch (why) {
3638 case PWR_STANDBY:
3639
3640 break;
3641 case PWR_SUSPEND:
3642 rtw_stop(ifp, 1);
3643 if (sc->sc_power != NULL)
3644 (*sc->sc_power)(sc, why);
3645 break;
3646 case PWR_RESUME:
3647 if (ifp->if_flags & IFF_UP) {
3648 if (sc->sc_power != NULL)
3649 (*sc->sc_power)(sc, why);
3650 rtw_init(ifp);
3651 }
3652 break;
3653 }
3654 splx(s);
3655 }
3656
3657
3658 void
3659 rtw_shutdown(void *arg)
3660 {
3661 struct rtw_softc *sc = arg;
3662
3663 rtw_stop(&sc->sc_ic.ic_if, 1);
3664 }
3665
3666 void
3667 rtw_establish_hooks(struct rtw_hooks *hooks, const char *dvname,
3668 void *arg)
3669 {
3670
3671
3672
3673 hooks->rh_shutdown = shutdownhook_establish(rtw_shutdown, arg);
3674 if (hooks->rh_shutdown == NULL)
3675 printf("%s: WARNING: unable to establish shutdown hook\n",
3676 dvname);
3677
3678
3679
3680
3681
3682 hooks->rh_power = powerhook_establish(rtw_power, arg);
3683 if (hooks->rh_power == NULL)
3684 printf("%s: WARNING: unable to establish power hook\n",
3685 dvname);
3686 }
3687
3688 void
3689 rtw_disestablish_hooks(struct rtw_hooks *hooks, const char *dvname,
3690 void *arg)
3691 {
3692 if (hooks->rh_shutdown != NULL)
3693 shutdownhook_disestablish(hooks->rh_shutdown);
3694
3695 if (hooks->rh_power != NULL)
3696 powerhook_disestablish(hooks->rh_power);
3697 }
3698
3699 int
3700 rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen)
3701 {
3702 SIMPLEQ_INIT(&tsb->tsb_dirtyq);
3703 SIMPLEQ_INIT(&tsb->tsb_freeq);
3704 tsb->tsb_ndesc = qlen;
3705 tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF,
3706 M_NOWAIT);
3707 if (tsb->tsb_desc == NULL)
3708 return ENOMEM;
3709 return 0;
3710 }
3711
3712 void
3713 rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc)
3714 {
3715 int pri;
3716 struct rtw_txsoft_blk *tsb;
3717
3718 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3719 tsb = &sc->sc_txsoft_blk[pri];
3720 free(tsb->tsb_desc, M_DEVBUF);
3721 tsb->tsb_desc = NULL;
3722 }
3723 }
3724
3725 int
3726 rtw_txsoft_blk_setup_all(struct rtw_softc *sc)
3727 {
3728 int pri, rc = 0;
3729 int qlen[RTW_NTXPRI] =
3730 {RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
3731 struct rtw_txsoft_blk *tsbs;
3732
3733 tsbs = sc->sc_txsoft_blk;
3734
3735 for (pri = 0; pri < RTW_NTXPRI; pri++) {
3736 rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]);
3737 if (rc != 0)
3738 break;
3739 }
3740 tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ;
3741 tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ;
3742 tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ;
3743 tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ;
3744 return rc;
3745 }
3746
3747 void
3748 rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc,
3749 u_int ndesc, bus_addr_t ofs, bus_addr_t physbase)
3750 {
3751 tdb->tdb_ndesc = ndesc;
3752 tdb->tdb_desc = desc;
3753 tdb->tdb_physbase = physbase;
3754 tdb->tdb_ofs = ofs;
3755
3756 bzero(tdb->tdb_desc, sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
3757
3758 rtw_txdesc_blk_init(tdb);
3759 tdb->tdb_next = 0;
3760 }
3761
3762 void
3763 rtw_txdesc_blk_setup_all(struct rtw_softc *sc)
3764 {
3765 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO],
3766 &sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO,
3767 RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo));
3768
3769 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD],
3770 &sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD,
3771 RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd));
3772
3773 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI],
3774 &sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI,
3775 RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi));
3776
3777 rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN],
3778 &sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN,
3779 RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn));
3780 }
3781
3782 int
3783 rtw_rf_attach(struct rtw_softc *sc, int rfchipid)
3784 {
3785 struct rtw_bbpset *bb = &sc->sc_bbpset;
3786 int notsup = 0;
3787 const char *rfname, *paname = NULL;
3788 char scratch[sizeof("unknown 0xXX")];
3789
3790 switch (rfchipid) {
3791 case RTW_RFCHIPID_RTL8225:
3792 rfname = "RTL8225";
3793 sc->sc_pwrstate_cb = rtw_rtl_pwrstate;
3794 sc->sc_rf_init = rtw_rtl8255_init;
3795 sc->sc_rf_pwrstate = rtw_rtl8225_pwrstate;
3796 sc->sc_rf_tune = rtw_rtl8225_tune;
3797 sc->sc_rf_txpower = rtw_rtl8225_txpower;
3798 break;
3799 case RTW_RFCHIPID_RTL8255:
3800 rfname = "RTL8255";
3801 sc->sc_pwrstate_cb = rtw_rtl_pwrstate;
3802 sc->sc_rf_init = rtw_rtl8255_init;
3803 sc->sc_rf_pwrstate = rtw_rtl8255_pwrstate;
3804 sc->sc_rf_tune = rtw_rtl8255_tune;
3805 sc->sc_rf_txpower = rtw_rtl8255_txpower;
3806 break;
3807 case RTW_RFCHIPID_MAXIM2820:
3808 rfname = "MAX2820";
3809 paname = "MAX2422";
3810
3811 bb->bb_antatten = RTW_BBP_ANTATTEN_MAXIM_MAGIC;
3812 bb->bb_chestlim = 0x00;
3813 bb->bb_chsqlim = 0x9f;
3814 bb->bb_ifagcdet = 0x64;
3815 bb->bb_ifagcini = 0x90;
3816 bb->bb_ifagclimit = 0x1a;
3817 bb->bb_lnadet = 0xf8;
3818 bb->bb_sys1 = 0x88;
3819 bb->bb_sys2 = 0x47;
3820 bb->bb_sys3 = 0x9b;
3821 bb->bb_trl = 0x88;
3822 bb->bb_txagc = 0x08;
3823 sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
3824 sc->sc_rf_init = rtw_max2820_init;
3825 sc->sc_rf_pwrstate = rtw_max2820_pwrstate;
3826 sc->sc_rf_tune = rtw_max2820_tune;
3827 sc->sc_rf_txpower = rtw_max2820_txpower;
3828 break;
3829 case RTW_RFCHIPID_PHILIPS:
3830 rfname = "SA2400A";
3831 paname = "SA2411";
3832
3833 bb->bb_antatten = RTW_BBP_ANTATTEN_PHILIPS_MAGIC;
3834 bb->bb_chestlim = 0x00;
3835 bb->bb_chsqlim = 0xa0;
3836 bb->bb_ifagcdet = 0x64;
3837 bb->bb_ifagcini = 0x90;
3838 bb->bb_ifagclimit = 0x1a;
3839 bb->bb_lnadet = 0xe0;
3840 bb->bb_sys1 = 0x98;
3841 bb->bb_sys2 = 0x47;
3842 bb->bb_sys3 = 0x90;
3843 bb->bb_trl = 0x88;
3844 bb->bb_txagc = 0x38;
3845 sc->sc_pwrstate_cb = rtw_philips_pwrstate;
3846 sc->sc_rf_init = rtw_sa2400_init;
3847 sc->sc_rf_pwrstate = rtw_sa2400_pwrstate;
3848 sc->sc_rf_tune = rtw_sa2400_tune;
3849 sc->sc_rf_txpower = rtw_sa2400_txpower;
3850 break;
3851 case RTW_RFCHIPID_RFMD2948:
3852
3853 rfname = "RFMD RF2948B, "
3854 "LNA: RFMD RF2494, "
3855 "SYN: Silicon Labs Si4126";
3856
3857
3858 paname = "RF2189";
3859
3860 sc->sc_pwrstate_cb = rtw_rfmd_pwrstate;
3861 notsup = 1;
3862 break;
3863 case RTW_RFCHIPID_GCT:
3864 rfname = "GRF5101";
3865 paname = "WS9901";
3866
3867 bb->bb_antatten = RTW_BBP_ANTATTEN_GCT_MAGIC;
3868 bb->bb_chestlim = 0x00;
3869 bb->bb_chsqlim = 0xa0;
3870 bb->bb_ifagcdet = 0x64;
3871 bb->bb_ifagcini = 0x90;
3872 bb->bb_ifagclimit = 0x1e;
3873 bb->bb_lnadet = 0xc0;
3874 bb->bb_sys1 = 0xa8;
3875 bb->bb_sys2 = 0x47;
3876 bb->bb_sys3 = 0x9b;
3877 bb->bb_trl = 0x88;
3878 bb->bb_txagc = 0x08;
3879 sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
3880 sc->sc_rf_init = rtw_grf5101_init;
3881 sc->sc_rf_pwrstate = rtw_grf5101_pwrstate;
3882 sc->sc_rf_tune = rtw_grf5101_tune;
3883 sc->sc_rf_txpower = rtw_grf5101_txpower;
3884 break;
3885 case RTW_RFCHIPID_INTERSIL:
3886 rfname = "HFA3873";
3887 paname = "Intersil <unknown>";
3888 notsup = 1;
3889 break;
3890 default:
3891 snprintf(scratch, sizeof(scratch), "unknown 0x%02x", rfchipid);
3892 rfname = scratch;
3893 notsup = 1;
3894 }
3895
3896 printf("radio %s, ", rfname);
3897 if (paname != NULL)
3898 printf("amp %s, ", paname);
3899
3900 return (notsup);
3901 }
3902
3903
3904
3905
3906 u_int8_t
3907 rtw_check_phydelay(struct rtw_regs *regs, u_int32_t rcr0)
3908 {
3909 #define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
3910 #define REVC (REVAB | RTW8180_RCR_RXFTH_WHOLE)
3911
3912 u_int8_t phydelay = LSHIFT(0x6, RTW_PHYDELAY_PHYDELAY);
3913
3914 RTW_WRITE(regs, RTW_RCR, REVAB);
3915 RTW_WBW(regs, RTW_RCR, RTW_RCR);
3916 RTW_WRITE(regs, RTW_RCR, REVC);
3917
3918 RTW_WBR(regs, RTW_RCR, RTW_RCR);
3919 if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
3920 phydelay |= RTW_PHYDELAY_REVC_MAGIC;
3921
3922 RTW_WRITE(regs, RTW_RCR, rcr0);
3923 RTW_SYNC(regs, RTW_RCR, RTW_RCR);
3924
3925 return phydelay;
3926 #undef REVC
3927 }
3928
3929 void
3930 rtw_attach(struct rtw_softc *sc)
3931 {
3932 struct ieee80211com *ic = &sc->sc_ic;
3933 struct rtw_txsoft_blk *tsb;
3934 struct rtw_mtbl *mtbl;
3935 struct rtw_srom *sr;
3936 const char *vername;
3937 struct ifnet *ifp;
3938 char scratch[sizeof("unknown 0xXXXXXXXX")];
3939 int pri, rc;
3940
3941
3942
3943 if (sc->sc_regs.r_read8 == NULL) {
3944 sc->sc_regs.r_read8 = rtw_read8;
3945 sc->sc_regs.r_read16 = rtw_read16;
3946 sc->sc_regs.r_read32 = rtw_read32;
3947 sc->sc_regs.r_write8 = rtw_write8;
3948 sc->sc_regs.r_write16 = rtw_write16;
3949 sc->sc_regs.r_write32 = rtw_write32;
3950 sc->sc_regs.r_barrier = rtw_barrier;
3951 }
3952
3953 sc->sc_hwverid = RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK;
3954 switch (sc->sc_hwverid) {
3955 case RTW_TCR_HWVERID_RTL8185:
3956 vername = "RTL8185";
3957 sc->sc_flags |= RTW_F_RTL8185;
3958 break;
3959 case RTW_TCR_HWVERID_RTL8180F:
3960 vername = "RTL8180F";
3961 break;
3962 case RTW_TCR_HWVERID_RTL8180D:
3963 vername = "RTL8180D";
3964 break;
3965 default:
3966 snprintf(scratch, sizeof(scratch), "unknown 0x%08x",
3967 sc->sc_hwverid);
3968 vername = scratch;
3969 break;
3970 }
3971
3972 printf("%s: ver %s, ", sc->sc_dev.dv_xname, vername);
3973
3974 rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs),
3975 RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs,
3976 0);
3977
3978 if (rc != 0) {
3979 printf("\n%s: could not allocate hw descriptors, error %d\n",
3980 sc->sc_dev.dv_xname, rc);
3981 goto fail0;
3982 }
3983
3984 rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs,
3985 sc->sc_desc_nsegs, sizeof(struct rtw_descs),
3986 (caddr_t*)&sc->sc_descs, BUS_DMA_COHERENT);
3987
3988 if (rc != 0) {
3989 printf("\n%s: could not map hw descriptors, error %d\n",
3990 sc->sc_dev.dv_xname, rc);
3991 goto fail1;
3992 }
3993
3994 rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1,
3995 sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap);
3996
3997 if (rc != 0) {
3998 printf("\n%s: could not create DMA map for hw descriptors, "
3999 "error %d\n", sc->sc_dev.dv_xname, rc);
4000 goto fail2;
4001 }
4002
4003 sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat;
4004 sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap;
4005
4006 for (pri = 0; pri < RTW_NTXPRI; pri++) {
4007 sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat;
4008 sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap;
4009 }
4010
4011 rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs,
4012 sizeof(struct rtw_descs), NULL, 0);
4013
4014 if (rc != 0) {
4015 printf("\n%s: could not load DMA map for hw descriptors, "
4016 "error %d\n", sc->sc_dev.dv_xname, rc);
4017 goto fail3;
4018 }
4019
4020 if (rtw_txsoft_blk_setup_all(sc) != 0)
4021 goto fail4;
4022
4023 rtw_txdesc_blk_setup_all(sc);
4024
4025 sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0];
4026
4027 for (pri = 0; pri < RTW_NTXPRI; pri++) {
4028 tsb = &sc->sc_txsoft_blk[pri];
4029
4030 if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat,
4031 &tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) {
4032 printf("\n%s: could not load DMA map for "
4033 "hw tx descriptors, error %d\n",
4034 sc->sc_dev.dv_xname, rc);
4035 goto fail5;
4036 }
4037 }
4038
4039 if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0],
4040 RTW_RXQLEN)) != 0) {
4041 printf("\n%s: could not load DMA map for hw rx descriptors, "
4042 "error %d\n", sc->sc_dev.dv_xname, rc);
4043 goto fail6;
4044 }
4045
4046
4047 if (rtw_reset(sc) != 0)
4048 goto fail7;
4049
4050 sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR);
4051
4052 if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0)
4053 sc->sc_flags |= RTW_F_9356SROM;
4054
4055 if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom,
4056 sc->sc_dev.dv_xname) != 0)
4057 goto fail7;
4058
4059 if (rtw_srom_parse(sc) != 0) {
4060 printf("\n%s: attach failed, malformed serial ROM\n",
4061 sc->sc_dev.dv_xname);
4062 goto fail8;
4063 }
4064
4065 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: %s PHY\n", sc->sc_dev.dv_xname,
4066 ((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog"));
4067
4068 RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: CS threshold %u\n",
4069 sc->sc_dev.dv_xname, sc->sc_csthr));
4070
4071 if ((rtw_rf_attach(sc, sc->sc_rfchipid)) != 0) {
4072 printf("\n%s: attach failed, could not attach RF\n",
4073 sc->sc_dev.dv_xname);
4074 goto fail8;
4075 }
4076
4077 sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr);
4078
4079 RTW_DPRINTF(RTW_DEBUG_ATTACH,
4080 ("%s: PHY delay %d\n", sc->sc_dev.dv_xname, sc->sc_phydelay));
4081
4082 if (sc->sc_locale == RTW_LOCALE_UNKNOWN)
4083 rtw_identify_country(&sc->sc_regs, &sc->sc_locale);
4084
4085 rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels,
4086 sc->sc_dev.dv_xname);
4087
4088 if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr,
4089 sc->sc_dev.dv_xname) != 0)
4090 goto fail8;
4091
4092 ifp = &sc->sc_if;
4093 (void)memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
4094 ifp->if_softc = sc;
4095 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
4096 IFF_NOTRAILERS;
4097 ifp->if_ioctl = rtw_ioctl;
4098 ifp->if_start = rtw_start;
4099 ifp->if_watchdog = rtw_watchdog;
4100
4101 IFQ_SET_READY(&sc->sc_if.if_snd);
4102
4103 ic->ic_phytype = IEEE80211_T_DS;
4104 ic->ic_opmode = IEEE80211_M_STA;
4105 ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
4106 IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
4107
4108 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
4109
4110 rtw_led_attach(&sc->sc_led_state, (void *)sc);
4111
4112
4113
4114
4115 if_attach(&sc->sc_if);
4116 ieee80211_ifattach(&sc->sc_if);
4117
4118 mtbl = &sc->sc_mtbl;
4119 mtbl->mt_newstate = ic->ic_newstate;
4120 ic->ic_newstate = rtw_newstate;
4121
4122 mtbl->mt_recv_mgmt = ic->ic_recv_mgmt;
4123 ic->ic_recv_mgmt = rtw_recv_mgmt;
4124
4125 mtbl->mt_node_free = ic->ic_node_free;
4126 ic->ic_node_free = rtw_node_free;
4127
4128 mtbl->mt_node_alloc = ic->ic_node_alloc;
4129 ic->ic_node_alloc = rtw_node_alloc;
4130
4131
4132
4133
4134
4135
4136
4137 ieee80211_media_init(&sc->sc_if, rtw_media_change, rtw_media_status);
4138 timeout_set(&sc->sc_scan_to, rtw_next_scan, sc);
4139
4140 #if NBPFILTER > 0
4141 bzero(&sc->sc_rxtapu, sizeof(sc->sc_rxtapu));
4142 sc->sc_rxtap.rr_ihdr.it_len = sizeof(sc->sc_rxtapu);
4143 sc->sc_rxtap.rr_ihdr.it_present = RTW_RX_RADIOTAP_PRESENT;
4144
4145 bzero(&sc->sc_txtapu, sizeof(sc->sc_txtapu));
4146 sc->sc_txtap.rt_ihdr.it_len = sizeof(sc->sc_txtapu);
4147 sc->sc_txtap.rt_ihdr.it_present = RTW_TX_RADIOTAP_PRESENT;
4148
4149 bpfattach(&sc->sc_radiobpf, &sc->sc_ic.ic_if, DLT_IEEE802_11_RADIO,
4150 sizeof(struct ieee80211_frame) + 64);
4151 #endif
4152
4153 rtw_establish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname, (void*)sc);
4154
4155 return;
4156
4157 fail8:
4158 sr = &sc->sc_srom;
4159 sr->sr_size = 0;
4160 if (sr->sr_content != NULL) {
4161 free(sr->sr_content, M_DEVBUF);
4162 sr->sr_content = NULL;
4163 }
4164
4165 fail7:
4166 rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0],
4167 RTW_RXQLEN);
4168
4169 fail6:
4170 for (pri = 0; pri < RTW_NTXPRI; pri++) {
4171 rtw_txdesc_dmamaps_destroy(sc->sc_dmat,
4172 sc->sc_txsoft_blk[pri].tsb_desc,
4173 sc->sc_txsoft_blk[pri].tsb_ndesc);
4174 }
4175
4176 fail5:
4177 rtw_txsoft_blk_cleanup_all(sc);
4178
4179 fail4:
4180 bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap);
4181 fail3:
4182 bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap);
4183 fail2:
4184 bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_descs,
4185 sizeof(struct rtw_descs));
4186 fail1:
4187 bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs,
4188 sc->sc_desc_nsegs);
4189 fail0:
4190 return;
4191 }
4192
4193 int
4194 rtw_detach(struct rtw_softc *sc)
4195 {
4196 sc->sc_flags |= RTW_F_INVALID;
4197
4198 rtw_stop(&sc->sc_if, 1);
4199
4200 rtw_disestablish_hooks(&sc->sc_hooks, sc->sc_dev.dv_xname,
4201 (void*)sc);
4202 timeout_del(&sc->sc_scan_to);
4203 ieee80211_ifdetach(&sc->sc_if);
4204 if_detach(&sc->sc_if);
4205
4206 return 0;
4207 }
4208
4209
4210
4211
4212
4213 int
4214 rtw_bbp_preinit(struct rtw_regs *regs, u_int antatten0, int dflantb,
4215 u_int freq)
4216 {
4217 u_int antatten = antatten0;
4218 if (dflantb)
4219 antatten |= RTW_BBP_ANTATTEN_DFLANTB;
4220 if (freq == 2484)
4221 antatten |= RTW_BBP_ANTATTEN_CHAN14;
4222 return rtw_bbp_write(regs, RTW_BBP_ANTATTEN, antatten);
4223 }
4224
4225 int
4226 rtw_bbp_init(struct rtw_regs *regs, struct rtw_bbpset *bb, int antdiv,
4227 int dflantb, u_int8_t cs_threshold, u_int freq)
4228 {
4229 int rc;
4230 u_int32_t sys2, sys3;
4231
4232 sys2 = bb->bb_sys2;
4233 if (antdiv)
4234 sys2 |= RTW_BBP_SYS2_ANTDIV;
4235 sys3 = bb->bb_sys3 |
4236 LSHIFT(cs_threshold, RTW_BBP_SYS3_CSTHRESH_MASK);
4237
4238 #define RTW_BBP_WRITE_OR_RETURN(reg, val) \
4239 if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \
4240 return rc;
4241
4242 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1, bb->bb_sys1);
4243 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC, bb->bb_txagc);
4244 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET, bb->bb_lnadet);
4245 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI, bb->bb_ifagcini);
4246 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT, bb->bb_ifagclimit);
4247 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET, bb->bb_ifagcdet);
4248
4249 if ((rc = rtw_bbp_preinit(regs, bb->bb_antatten, dflantb, freq)) != 0)
4250 return rc;
4251
4252 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL, bb->bb_trl);
4253 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2, sys2);
4254 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3, sys3);
4255 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM, bb->bb_chestlim);
4256 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM, bb->bb_chsqlim);
4257 return 0;
4258 }
4259
4260 int
4261 rtw_sa2400_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
4262 {
4263 return rtw_rf_macwrite(sc, SA2400_TX, opaque_txpower);
4264 }
4265
4266
4267 void
4268 rtw_verify_syna(u_int freq, u_int32_t val)
4269 {
4270 u_int32_t expected_val = ~val;
4271
4272 switch (freq) {
4273 case 2412:
4274 expected_val = 0x0000096c;
4275 break;
4276 case 2417:
4277 expected_val = 0x00080970;
4278 break;
4279 case 2422:
4280 expected_val = 0x00100974;
4281 break;
4282 case 2427:
4283 expected_val = 0x00180978;
4284 break;
4285 case 2432:
4286 expected_val = 0x00000980;
4287 break;
4288 case 2437:
4289 expected_val = 0x00080984;
4290 break;
4291 case 2442:
4292 expected_val = 0x00100988;
4293 break;
4294 case 2447:
4295 expected_val = 0x0018098c;
4296 break;
4297 case 2452:
4298 expected_val = 0x00000994;
4299 break;
4300 case 2457:
4301 expected_val = 0x00080998;
4302 break;
4303 case 2462:
4304 expected_val = 0x0010099c;
4305 break;
4306 case 2467:
4307 expected_val = 0x001809a0;
4308 break;
4309 case 2472:
4310 expected_val = 0x000009a8;
4311 break;
4312 case 2484:
4313 expected_val = 0x000009b4;
4314 break;
4315 }
4316 KASSERT(val == expected_val);
4317 }
4318
4319
4320 int
4321 rtw_sa2400_tune(struct rtw_softc *sc, u_int freq)
4322 {
4323 int rc;
4324 u_int32_t syna, synb, sync;
4325
4326
4327
4328
4329
4330
4331 int n = freq / 4, nf = (freq % 4) * 2;
4332
4333 syna = LSHIFT(nf, SA2400_SYNA_NF_MASK) | LSHIFT(n, SA2400_SYNA_N_MASK);
4334 rtw_verify_syna(freq, syna);
4335
4336
4337
4338
4339
4340 synb = LSHIFT(11, SA2400_SYNB_R_MASK) | SA2400_SYNB_L_NORMAL |
4341 SA2400_SYNB_ON | SA2400_SYNB_ONE |
4342 LSHIFT(80, SA2400_SYNB_FC_MASK);
4343
4344 sync = SA2400_SYNC_CP_NORMAL;
4345
4346 if ((rc = rtw_rf_macwrite(sc, SA2400_SYNA, syna)) != 0)
4347 return rc;
4348 if ((rc = rtw_rf_macwrite(sc, SA2400_SYNB, synb)) != 0)
4349 return rc;
4350 if ((rc = rtw_rf_macwrite(sc, SA2400_SYNC, sync)) != 0)
4351 return rc;
4352 return rtw_rf_macwrite(sc, SA2400_SYND, 0x0);
4353 }
4354
4355 int
4356 rtw_sa2400_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
4357 {
4358 u_int32_t opmode;
4359 opmode = SA2400_OPMODE_DEFAULTS;
4360 switch (power) {
4361 case RTW_ON:
4362 opmode |= SA2400_OPMODE_MODE_TXRX;
4363 break;
4364 case RTW_SLEEP:
4365 opmode |= SA2400_OPMODE_MODE_WAIT;
4366 break;
4367 case RTW_OFF:
4368 opmode |= SA2400_OPMODE_MODE_SLEEP;
4369 break;
4370 }
4371
4372 if (sc->sc_flags & RTW_F_DIGPHY)
4373 opmode |= SA2400_OPMODE_DIGIN;
4374
4375 return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode);
4376 }
4377
4378 int
4379 rtw_sa2400_vcocal_start(struct rtw_softc *sc, int start)
4380 {
4381 u_int32_t opmode;
4382
4383 opmode = SA2400_OPMODE_DEFAULTS;
4384 if (start)
4385 opmode |= SA2400_OPMODE_MODE_VCOCALIB;
4386 else
4387 opmode |= SA2400_OPMODE_MODE_SLEEP;
4388
4389 if (sc->sc_flags & RTW_F_DIGPHY)
4390 opmode |= SA2400_OPMODE_DIGIN;
4391
4392 return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode);
4393 }
4394
4395 int
4396 rtw_sa2400_vco_calibration(struct rtw_softc *sc)
4397 {
4398 int rc;
4399
4400 if ((rc = rtw_sa2400_vcocal_start(sc, 1)) != 0)
4401 return rc;
4402 DELAY(2200);
4403
4404 return rtw_sa2400_vcocal_start(sc, 0);
4405 }
4406
4407 int
4408 rtw_sa2400_filter_calibration(struct rtw_softc *sc)
4409 {
4410 u_int32_t opmode;
4411
4412 opmode = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_FCALIB;
4413 if (sc->sc_flags & RTW_F_DIGPHY)
4414 opmode |= SA2400_OPMODE_DIGIN;
4415
4416 return rtw_rf_macwrite(sc, SA2400_OPMODE, opmode);
4417 }
4418
4419 int
4420 rtw_sa2400_dc_calibration(struct rtw_softc *sc)
4421 {
4422 int rc;
4423 u_int32_t dccal;
4424
4425 rtw_continuous_tx_enable(sc, 1);
4426
4427 dccal = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_TXRX;
4428
4429 rc = rtw_rf_macwrite(sc, SA2400_OPMODE, dccal);
4430
4431 if (rc != 0)
4432 return rc;
4433
4434 DELAY(5);
4435
4436
4437
4438 dccal &= ~SA2400_OPMODE_MODE_MASK;
4439 dccal |= SA2400_OPMODE_MODE_DCALIB;
4440
4441 rc = rtw_rf_macwrite(sc, SA2400_OPMODE, dccal);
4442 if (rc != 0)
4443 return rc;
4444
4445 DELAY(20);
4446
4447 rtw_continuous_tx_enable(sc, 0);
4448
4449 return 0;
4450 }
4451
4452 int
4453 rtw_sa2400_calibrate(struct rtw_softc *sc, u_int freq)
4454 {
4455 int i, rc;
4456
4457
4458 for (i = 0; i < 2; i++) {
4459 if ((rc = rtw_sa2400_vco_calibration(sc)) != 0)
4460 return rc;
4461 }
4462
4463 if ((rc = rtw_sa2400_tune(sc, freq)) != 0)
4464 return rc;
4465 if ((rc = rtw_sa2400_filter_calibration(sc)) != 0)
4466 return rc;
4467
4468 if (!(sc->sc_flags & RTW_F_DIGPHY))
4469 return rtw_sa2400_dc_calibration(sc);
4470 return 0;
4471 }
4472
4473 int
4474 rtw_sa2400_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
4475 enum rtw_pwrstate power)
4476 {
4477 int rc;
4478 u_int32_t agc, manrx;
4479
4480 if ((rc = rtw_sa2400_txpower(sc, opaque_txpower)) != 0)
4481 return rc;
4482
4483
4484 if (power == RTW_SLEEP || power == RTW_OFF)
4485 return rtw_sa2400_pwrstate(sc, power);
4486
4487
4488 if ((rc = rtw_sa2400_pwrstate(sc, RTW_SLEEP)) != 0)
4489 return rc;
4490
4491 if ((rc = rtw_sa2400_tune(sc, freq)) != 0)
4492 return rc;
4493
4494 agc = LSHIFT(25, SA2400_AGC_MAXGAIN_MASK);
4495 agc |= LSHIFT(7, SA2400_AGC_BBPDELAY_MASK);
4496 agc |= LSHIFT(15, SA2400_AGC_LNADELAY_MASK);
4497 agc |= LSHIFT(27, SA2400_AGC_RXONDELAY_MASK);
4498
4499 if ((rc = rtw_rf_macwrite(sc, SA2400_AGC, agc)) != 0)
4500 return rc;
4501
4502
4503 manrx = SA2400_MANRX_AHSN;
4504 manrx |= SA2400_MANRX_TEN;
4505 manrx |= LSHIFT(1023, SA2400_MANRX_RXGAIN_MASK);
4506
4507 if ((rc = rtw_rf_macwrite(sc, SA2400_MANRX, manrx)) != 0)
4508 return rc;
4509
4510 if ((rc = rtw_sa2400_calibrate(sc, freq)) != 0)
4511 return rc;
4512
4513
4514 return rtw_sa2400_pwrstate(sc, power);
4515 }
4516
4517
4518 int
4519 rtw_max2820_tune(struct rtw_softc *sc, u_int freq)
4520 {
4521 if (freq < 2400 || freq > 2499)
4522 return -1;
4523
4524 return rtw_rf_hostwrite(sc, MAX2820_CHANNEL,
4525 LSHIFT(freq - 2400, MAX2820_CHANNEL_CF_MASK));
4526 }
4527
4528 int
4529 rtw_max2820_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
4530 enum rtw_pwrstate power)
4531 {
4532 int rc;
4533
4534 if ((rc = rtw_rf_hostwrite(sc, MAX2820_TEST,
4535 MAX2820_TEST_DEFAULT)) != 0)
4536 return rc;
4537
4538 if ((rc = rtw_rf_hostwrite(sc, MAX2820_ENABLE,
4539 MAX2820_ENABLE_DEFAULT)) != 0)
4540 return rc;
4541
4542
4543 if ((rc = rtw_max2820_pwrstate(sc, power)) != 0)
4544 return rc;
4545 else if (power == RTW_OFF || power == RTW_SLEEP)
4546 return 0;
4547
4548 if ((rc = rtw_rf_hostwrite(sc, MAX2820_SYNTH,
4549 MAX2820_SYNTH_R_44MHZ)) != 0)
4550 return rc;
4551
4552 if ((rc = rtw_max2820_tune(sc, freq)) != 0)
4553 return rc;
4554
4555
4556
4557
4558
4559 if ((rc = rtw_rf_hostwrite(sc, MAX2820_RECEIVE,
4560 MAX2820_RECEIVE_DL_DEFAULT |
4561 LSHIFT(4, MAX2820A_RECEIVE_1C_MASK) |
4562 LSHIFT(1, MAX2820A_RECEIVE_2C_MASK))) != 0)
4563 return rc;
4564
4565 return rtw_rf_hostwrite(sc, MAX2820_TRANSMIT,
4566 MAX2820_TRANSMIT_PA_DEFAULT);
4567 }
4568
4569 int
4570 rtw_max2820_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
4571 {
4572
4573 return 0;
4574 }
4575
4576 int
4577 rtw_max2820_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
4578 {
4579 uint32_t enable;
4580
4581 switch (power) {
4582 case RTW_OFF:
4583 case RTW_SLEEP:
4584 default:
4585 enable = 0x0;
4586 break;
4587 case RTW_ON:
4588 enable = MAX2820_ENABLE_DEFAULT;
4589 break;
4590 }
4591 return rtw_rf_hostwrite(sc, MAX2820_ENABLE, enable);
4592 }
4593
4594 int
4595 rtw_grf5101_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
4596 enum rtw_pwrstate power)
4597 {
4598 int rc;
4599
4600
4601
4602
4603
4604
4605
4606 rtw_rf_macwrite(sc, 0x01, 0x1a23);
4607 rtw_rf_macwrite(sc, 0x02, 0x4971);
4608 rtw_rf_macwrite(sc, 0x03, 0x41de);
4609 rtw_rf_macwrite(sc, 0x04, 0x2d80);
4610
4611 rtw_rf_macwrite(sc, 0x05, 0x61ff);
4612
4613 rtw_rf_macwrite(sc, 0x06, 0x0);
4614
4615 rtw_rf_macwrite(sc, 0x08, 0x7533);
4616 rtw_rf_macwrite(sc, 0x09, 0xc401);
4617 rtw_rf_macwrite(sc, 0x0a, 0x0);
4618 rtw_rf_macwrite(sc, 0x0c, 0x1c7);
4619 rtw_rf_macwrite(sc, 0x0d, 0x29d3);
4620 rtw_rf_macwrite(sc, 0x0e, 0x2e8);
4621 rtw_rf_macwrite(sc, 0x10, 0x192);
4622 rtw_rf_macwrite(sc, 0x11, 0x248);
4623 rtw_rf_macwrite(sc, 0x12, 0x0);
4624 rtw_rf_macwrite(sc, 0x13, 0x20c4);
4625 rtw_rf_macwrite(sc, 0x14, 0xf4fc);
4626 rtw_rf_macwrite(sc, 0x15, 0x0);
4627 rtw_rf_macwrite(sc, 0x16, 0x1500);
4628
4629 if ((rc = rtw_grf5101_txpower(sc, opaque_txpower)) != 0)
4630 return rc;
4631
4632 if ((rc = rtw_grf5101_tune(sc, freq)) != 0)
4633 return rc;
4634
4635 return (0);
4636 }
4637
4638 int
4639 rtw_grf5101_tune(struct rtw_softc *sc, u_int freq)
4640 {
4641 struct ieee80211com *ic = &sc->sc_ic;
4642 u_int channel = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
4643
4644
4645 rtw_rf_macwrite(sc, 0x07, 0);
4646 rtw_rf_macwrite(sc, 0x0b, channel - 1);
4647 rtw_rf_macwrite(sc, 0x07, 0x1000);
4648
4649 return (0);
4650 }
4651
4652 int
4653 rtw_grf5101_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
4654 {
4655 rtw_rf_macwrite(sc, 0x15, 0);
4656 rtw_rf_macwrite(sc, 0x06, opaque_txpower);
4657 rtw_rf_macwrite(sc, 0x15, 0x10);
4658 rtw_rf_macwrite(sc, 0x15, 0x00);
4659
4660 return (0);
4661 }
4662
4663 int
4664 rtw_grf5101_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
4665 {
4666 switch (power) {
4667 case RTW_OFF:
4668 case RTW_SLEEP:
4669 rtw_rf_macwrite(sc, 0x07, 0x0000);
4670 rtw_rf_macwrite(sc, 0x1f, 0x0045);
4671 rtw_rf_macwrite(sc, 0x1f, 0x0005);
4672 rtw_rf_macwrite(sc, 0x00, 0x08e4);
4673 default:
4674 break;
4675 case RTW_ON:
4676 rtw_rf_macwrite(sc, 0x1f, 0x0001);
4677 DELAY(10);
4678 rtw_rf_macwrite(sc, 0x1f, 0x0001);
4679 DELAY(10);
4680 rtw_rf_macwrite(sc, 0x1f, 0x0041);
4681 DELAY(10);
4682 rtw_rf_macwrite(sc, 0x1f, 0x0061);
4683 DELAY(10);
4684 rtw_rf_macwrite(sc, 0x00, 0x0ae4);
4685 DELAY(10);
4686 rtw_rf_macwrite(sc, 0x07, 0x1000);
4687 DELAY(100);
4688 break;
4689 }
4690
4691 return 0;
4692 }
4693
4694 int
4695 rtw_rtl8225_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
4696 {
4697 return (0);
4698 }
4699
4700 int
4701 rtw_rtl8225_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
4702 enum rtw_pwrstate power)
4703 {
4704 return (0);
4705 }
4706
4707 int
4708 rtw_rtl8225_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
4709 {
4710 return (0);
4711 }
4712
4713 int
4714 rtw_rtl8225_tune(struct rtw_softc *sc, u_int freq)
4715 {
4716 return (0);
4717 }
4718
4719 int
4720 rtw_rtl8255_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
4721 {
4722 return (0);
4723 }
4724
4725 int
4726 rtw_rtl8255_init(struct rtw_softc *sc, u_int freq, u_int8_t opaque_txpower,
4727 enum rtw_pwrstate power)
4728 {
4729 return (0);
4730 }
4731
4732 int
4733 rtw_rtl8255_txpower(struct rtw_softc *sc, u_int8_t opaque_txpower)
4734 {
4735 return (0);
4736 }
4737
4738 int
4739 rtw_rtl8255_tune(struct rtw_softc *sc, u_int freq)
4740 {
4741 return (0);
4742 }
4743
4744 int
4745 rtw_phy_init(struct rtw_softc *sc)
4746 {
4747 int rc;
4748 struct ieee80211com *ic = &sc->sc_ic;
4749 struct rtw_regs *regs = &sc->sc_regs;
4750 int antdiv = sc->sc_flags & RTW_F_ANTDIV;
4751 int dflantb = sc->sc_flags & RTW_F_DFLANTB;
4752 u_int freq = ic->ic_bss->ni_chan->ic_freq;
4753 u_int8_t opaque_txpower = rtw_chan2txpower(&sc->sc_srom, ic,
4754 ic->ic_bss->ni_chan);
4755 u_int8_t cs_threshold = sc->sc_csthr;
4756 enum rtw_pwrstate power = RTW_ON;
4757
4758 RTW_DPRINTF(RTW_DEBUG_PHY,
4759 ("%s: txpower %u csthresh %u freq %u antdiv %u dflantb %u "
4760 "pwrstate %s\n", __func__, opaque_txpower, cs_threshold, freq,
4761 antdiv, dflantb, rtw_pwrstate_string(power)));
4762
4763
4764 if ((rc = (*sc->sc_rf_txpower)(sc, opaque_txpower)) != 0)
4765 return rc;
4766 if ((rc = rtw_bbp_preinit(regs, sc->sc_bbpset.bb_antatten, dflantb,
4767 freq)) != 0)
4768 return rc;
4769 if ((rc = (*sc->sc_rf_tune)(sc, freq)) != 0)
4770 return rc;
4771
4772 if ((rc = (*sc->sc_rf_init)(sc, freq, opaque_txpower, power)) != 0)
4773 return rc;
4774 #if 0
4775 if ((rc = (*sc->sc_rf_txpower)(sc, opaque_txpower)) != 0)
4776 return rc;
4777 #endif
4778 return rtw_bbp_init(regs, &sc->sc_bbpset, antdiv, dflantb,
4779 cs_threshold, freq);
4780 }
4781
4782
4783
4784
4785
4786 int
4787 rtw_bbp_write(struct rtw_regs *regs, u_int addr, u_int val)
4788 {
4789 #define BBP_WRITE_ITERS 50
4790 #define BBP_WRITE_DELAY 1
4791 int i;
4792 u_int32_t wrbbp, rdbbp;
4793
4794 RTW_DPRINTF(RTW_DEBUG_PHYIO,
4795 ("%s: bbp[%u] <- %u\n", __func__, addr, val));
4796
4797 KASSERT((addr & ~PRESHIFT(RTW_BB_ADDR_MASK)) == 0);
4798 KASSERT((val & ~PRESHIFT(RTW_BB_WR_MASK)) == 0);
4799
4800 wrbbp = LSHIFT(addr, RTW_BB_ADDR_MASK) | RTW_BB_WREN |
4801 LSHIFT(val, RTW_BB_WR_MASK) | RTW_BB_RD_MASK,
4802
4803 rdbbp = LSHIFT(addr, RTW_BB_ADDR_MASK) |
4804 RTW_BB_WR_MASK | RTW_BB_RD_MASK;
4805
4806 RTW_DPRINTF(RTW_DEBUG_PHYIO,
4807 ("%s: rdbbp = %#08x, wrbbp = %#08x\n", __func__, rdbbp, wrbbp));
4808
4809 for (i = BBP_WRITE_ITERS; --i >= 0; ) {
4810 RTW_RBW(regs, RTW_BB, RTW_BB);
4811 RTW_WRITE(regs, RTW_BB, wrbbp);
4812 RTW_SYNC(regs, RTW_BB, RTW_BB);
4813 RTW_WRITE(regs, RTW_BB, rdbbp);
4814 RTW_SYNC(regs, RTW_BB, RTW_BB);
4815 delay(BBP_WRITE_DELAY);
4816 if (MASK_AND_RSHIFT(RTW_READ(regs, RTW_BB),
4817 RTW_BB_RD_MASK) == val) {
4818 RTW_DPRINTF(RTW_DEBUG_PHYIO,
4819 ("%s: finished in %dus\n", __func__,
4820 BBP_WRITE_DELAY * (BBP_WRITE_ITERS - i)));
4821 return 0;
4822 }
4823 delay(BBP_WRITE_DELAY);
4824 }
4825 printf("%s: timeout\n", __func__);
4826 return -1;
4827 }
4828
4829
4830 void
4831 rtw_rf_hostbangbits(struct rtw_regs *regs, u_int32_t bits, int lo_to_hi,
4832 u_int nbits)
4833 {
4834 int i;
4835 u_int32_t mask, reg;
4836
4837 KASSERT(nbits <= 32);
4838
4839 RTW_DPRINTF(RTW_DEBUG_PHYIO,
4840 ("%s: %u bits, %#08x, %s\n", __func__, nbits, bits,
4841 (lo_to_hi) ? "lo to hi" : "hi to lo"));
4842
4843 reg = RTW8180_PHYCFG_HST;
4844 RTW_WRITE(regs, RTW8180_PHYCFG, reg);
4845 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
4846
4847 if (lo_to_hi)
4848 mask = 0x1;
4849 else
4850 mask = 1 << (nbits - 1);
4851
4852 for (i = 0; i < nbits; i++) {
4853 RTW_DPRINTF(RTW_DEBUG_PHYBITIO,
4854 ("%s: bits %#08x mask %#08x -> bit %#08x\n",
4855 __func__, bits, mask, bits & mask));
4856
4857 if ((bits & mask) != 0)
4858 reg |= RTW8180_PHYCFG_HST_DATA;
4859 else
4860 reg &= ~RTW8180_PHYCFG_HST_DATA;
4861
4862 reg |= RTW8180_PHYCFG_HST_CLK;
4863 RTW_WRITE(regs, RTW8180_PHYCFG, reg);
4864 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
4865
4866 DELAY(2);
4867
4868 reg &= ~RTW8180_PHYCFG_HST_CLK;
4869 RTW_WRITE(regs, RTW8180_PHYCFG, reg);
4870 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
4871
4872 if (lo_to_hi)
4873 mask <<= 1;
4874 else
4875 mask >>= 1;
4876 }
4877
4878 reg |= RTW8180_PHYCFG_HST_EN;
4879 KASSERT((reg & RTW8180_PHYCFG_HST_CLK) == 0);
4880 RTW_WRITE(regs, RTW8180_PHYCFG, reg);
4881 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
4882 }
4883
4884 #if 0
4885 void
4886 rtw_rf_rtl8225_hostbangbits(struct rtw_regs *regs, u_int32_t bits, int lo_to_hi,
4887 u_int nbits)
4888 {
4889 int i;
4890 u_int8_t page;
4891 u_int16_t reg0, reg1, reg2;
4892 u_int32_t mask;
4893
4894
4895 page = RTW_READ8(regs, RTW_PSR);
4896 RTW_WRITE8(regs, RTW_PSR, page & ~RTW_PSR_PSEN);
4897
4898
4899 reg0 = RTW_READ16(regs, RTW8185_RFPINSOUTPUT) &
4900 RTW8185_RFPINSOUTPUT_MASK;
4901 reg1 = RTW_READ16(regs, RTW8185_RFPINSENABLE);
4902 RTW_WRITE16(regs, RTW8185_RFPINSENABLE,
4903 RTW8185_RFPINSENABLE_ENABLE | reg0);
4904 reg2 = RTW_READ16(regs, RTW8185_RFPINSSELECT);
4905 RTW_WRITE16(regs, RTW8185_RFPINSSELECT,
4906 RTW8185_RFPINSSELECT_ENABLE | reg1 );
4907 DELAY(10);
4908
4909 RTW_WRITE16(regs, RTW8185_RFPINSOUTPUT, reg0);
4910 DELAY(10);
4911
4912 if (lo_to_hi)
4913 mask = 0x1;
4914 else
4915 mask = 1 << (nbits - 1);
4916
4917 for (i = 0; i < nbits; i++) {
4918 RTW_DPRINTF(RTW_DEBUG_PHYBITIO,
4919 ("%s: bits %#08x mask %#08x -> bit %#08x\n",
4920 __func__, bits, mask, bits & mask));
4921
4922 if ((bits & mask) != 0)
4923 reg |= RTW8180_PHYCFG_HST_DATA;
4924 else
4925 reg &= ~RTW8180_PHYCFG_HST_DATA;
4926
4927 reg |= RTW8180_PHYCFG_HST_CLK;
4928 RTW_WRITE(regs, RTW8180_PHYCFG, reg);
4929 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
4930
4931 DELAY(2);
4932
4933 reg &= ~RTW8180_PHYCFG_HST_CLK;
4934 RTW_WRITE(regs, RTW8180_PHYCFG, reg);
4935 RTW_SYNC(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
4936
4937 if (lo_to_hi)
4938 mask <<= 1;
4939 else
4940 mask >>= 1;
4941 }
4942
4943
4944 RTW_WRITE8(regs, RTW_PSR, page);
4945 }
4946 #endif
4947
4948
4949
4950
4951 int
4952 rtw_rf_macbangbits(struct rtw_regs *regs, u_int32_t reg)
4953 {
4954 int i;
4955
4956 RTW_DPRINTF(RTW_DEBUG_PHY, ("%s: %#08x\n", __func__, reg));
4957
4958 RTW_WRITE(regs, RTW8180_PHYCFG, RTW8180_PHYCFG_MAC_POLL | reg);
4959
4960 RTW_WBR(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
4961
4962 for (i = rtw_macbangbits_timeout; --i >= 0; delay(1)) {
4963 if ((RTW_READ(regs, RTW8180_PHYCFG) &
4964 RTW8180_PHYCFG_MAC_POLL) == 0) {
4965 RTW_DPRINTF(RTW_DEBUG_PHY,
4966 ("%s: finished in %dus\n", __func__,
4967 rtw_macbangbits_timeout - i));
4968 return 0;
4969 }
4970 RTW_RBR(regs, RTW8180_PHYCFG, RTW8180_PHYCFG);
4971 }
4972
4973 printf("%s: RTW8180_PHYCFG_MAC_POLL still set.\n", __func__);
4974 return -1;
4975 }
4976
4977 u_int32_t
4978 rtw_grf5101_host_crypt(u_int addr, u_int32_t val)
4979 {
4980
4981 return 0;
4982 }
4983
4984 u_int32_t
4985 rtw_grf5101_mac_crypt(u_int addr, u_int32_t val)
4986 {
4987 u_int32_t data_and_addr;
4988 #define EXTRACT_NIBBLE(d, which) (((d) >> (4 * (which))) & 0xf)
4989 static u_int8_t caesar[16] = {
4990 0x0, 0x8, 0x4, 0xc,
4991 0x2, 0xa, 0x6, 0xe,
4992 0x1, 0x9, 0x5, 0xd,
4993 0x3, 0xb, 0x7, 0xf
4994 };
4995 data_and_addr =
4996 caesar[EXTRACT_NIBBLE(val, 2)] |
4997 (caesar[EXTRACT_NIBBLE(val, 1)] << 4) |
4998 (caesar[EXTRACT_NIBBLE(val, 0)] << 8) |
4999 (caesar[(addr >> 1) & 0xf] << 12) |
5000 ((addr & 0x1) << 16) |
5001 (caesar[EXTRACT_NIBBLE(val, 3)] << 24);
5002 return LSHIFT(data_and_addr, RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK |
5003 RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK);
5004 #undef EXTRACT_NIBBLE
5005 }
5006
5007
5008 int
5009 rtw_rf_hostwrite(struct rtw_softc *sc, u_int addr, u_int32_t val)
5010 {
5011 u_int nbits;
5012 int lo_to_hi;
5013 u_int32_t bits;
5014 void(*rf_bangbits)(struct rtw_regs *, u_int32_t, int, u_int) =
5015 rtw_rf_hostbangbits;
5016
5017 RTW_DPRINTF(RTW_DEBUG_PHYIO, ("%s: [%u] <- %#08x\n", __func__,
5018 addr, val));
5019
5020 switch (sc->sc_rfchipid) {
5021 case RTW_RFCHIPID_MAXIM2820:
5022 nbits = 16;
5023 lo_to_hi = 0;
5024 bits = LSHIFT(val, MAX2820_TWI_DATA_MASK) |
5025 LSHIFT(addr, MAX2820_TWI_ADDR_MASK);
5026 break;
5027 case RTW_RFCHIPID_PHILIPS:
5028 KASSERT((addr & ~PRESHIFT(SA2400_TWI_ADDR_MASK)) == 0);
5029 KASSERT((val & ~PRESHIFT(SA2400_TWI_DATA_MASK)) == 0);
5030 bits = LSHIFT(val, SA2400_TWI_DATA_MASK) |
5031 LSHIFT(addr, SA2400_TWI_ADDR_MASK) | SA2400_TWI_WREN;
5032 nbits = 32;
5033 lo_to_hi = 1;
5034 break;
5035 case RTW_RFCHIPID_GCT:
5036 KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
5037 KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
5038 bits = rtw_grf5101_host_crypt(addr, val);
5039 nbits = 21;
5040 lo_to_hi = 1;
5041 break;
5042 case RTW_RFCHIPID_RFMD2948:
5043 KASSERT((addr & ~PRESHIFT(SI4126_TWI_ADDR_MASK)) == 0);
5044 KASSERT((val & ~PRESHIFT(SI4126_TWI_DATA_MASK)) == 0);
5045 bits = LSHIFT(val, SI4126_TWI_DATA_MASK) |
5046 LSHIFT(addr, SI4126_TWI_ADDR_MASK);
5047 nbits = 22;
5048 lo_to_hi = 0;
5049 break;
5050 case RTW_RFCHIPID_RTL8225:
5051 case RTW_RFCHIPID_RTL8255:
5052 nbits = 16;
5053 lo_to_hi = 0;
5054 bits = LSHIFT(val, RTL8225_TWI_DATA_MASK) |
5055 LSHIFT(addr, RTL8225_TWI_ADDR_MASK);
5056
5057
5058 rf_bangbits = rtw_rf_hostbangbits;
5059 break;
5060 case RTW_RFCHIPID_INTERSIL:
5061 default:
5062 printf("%s: unknown rfchipid %d\n", __func__, sc->sc_rfchipid);
5063 return -1;
5064 }
5065
5066 (*rf_bangbits)(&sc->sc_regs, bits, lo_to_hi, nbits);
5067
5068 return 0;
5069 }
5070
5071 u_int32_t
5072 rtw_maxim_swizzle(u_int addr, u_int32_t val)
5073 {
5074 u_int32_t hidata, lodata;
5075
5076 KASSERT((val & ~(RTW_MAXIM_LODATA_MASK|RTW_MAXIM_HIDATA_MASK)) == 0);
5077 lodata = MASK_AND_RSHIFT(val, RTW_MAXIM_LODATA_MASK);
5078 hidata = MASK_AND_RSHIFT(val, RTW_MAXIM_HIDATA_MASK);
5079 return LSHIFT(lodata, RTW8180_PHYCFG_MAC_MAXIM_LODATA_MASK) |
5080 LSHIFT(hidata, RTW8180_PHYCFG_MAC_MAXIM_HIDATA_MASK) |
5081 LSHIFT(addr, RTW8180_PHYCFG_MAC_MAXIM_ADDR_MASK);
5082 }
5083
5084
5085 int
5086 rtw_rf_macwrite(struct rtw_softc *sc, u_int addr, u_int32_t val)
5087 {
5088 u_int32_t reg;
5089
5090 RTW_DPRINTF(RTW_DEBUG_PHYIO, ("%s: %s[%u] <- %#08x\n", __func__,
5091 addr, val));
5092
5093 switch (sc->sc_rfchipid) {
5094 case RTW_RFCHIPID_GCT:
5095 reg = rtw_grf5101_mac_crypt(addr, val);
5096 break;
5097 case RTW_RFCHIPID_MAXIM2820:
5098 reg = rtw_maxim_swizzle(addr, val);
5099 break;
5100 default:
5101 case RTW_RFCHIPID_PHILIPS:
5102 KASSERT((addr &
5103 ~PRESHIFT(RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK)) == 0);
5104 KASSERT((val &
5105 ~PRESHIFT(RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK)) == 0);
5106
5107 reg = LSHIFT(addr, RTW8180_PHYCFG_MAC_PHILIPS_ADDR_MASK) |
5108 LSHIFT(val, RTW8180_PHYCFG_MAC_PHILIPS_DATA_MASK);
5109 }
5110
5111 switch (sc->sc_rfchipid) {
5112 case RTW_RFCHIPID_GCT:
5113 case RTW_RFCHIPID_MAXIM2820:
5114 case RTW_RFCHIPID_RFMD2948:
5115 reg |= RTW8180_PHYCFG_MAC_RFTYPE_RFMD;
5116 break;
5117 case RTW_RFCHIPID_INTERSIL:
5118 reg |= RTW8180_PHYCFG_MAC_RFTYPE_INTERSIL;
5119 break;
5120 case RTW_RFCHIPID_PHILIPS:
5121 reg |= RTW8180_PHYCFG_MAC_RFTYPE_PHILIPS;
5122 break;
5123 default:
5124 printf("%s: unknown rfchipid %d\n", __func__, sc->sc_rfchipid);
5125 return -1;
5126 }
5127
5128 return rtw_rf_macbangbits(&sc->sc_regs, reg);
5129 }
5130
5131
5132 u_int8_t
5133 rtw_read8(void *arg, u_int32_t off)
5134 {
5135 struct rtw_regs *regs = (struct rtw_regs *)arg;
5136 return (bus_space_read_1(regs->r_bt, regs->r_bh, off));
5137 }
5138
5139 u_int16_t
5140 rtw_read16(void *arg, u_int32_t off)
5141 {
5142 struct rtw_regs *regs = (struct rtw_regs *)arg;
5143 return (bus_space_read_2(regs->r_bt, regs->r_bh, off));
5144 }
5145
5146 u_int32_t
5147 rtw_read32(void *arg, u_int32_t off)
5148 {
5149 struct rtw_regs *regs = (struct rtw_regs *)arg;
5150 return (bus_space_read_4(regs->r_bt, regs->r_bh, off));
5151 }
5152
5153 void
5154 rtw_write8(void *arg, u_int32_t off, u_int8_t val)
5155 {
5156 struct rtw_regs *regs = (struct rtw_regs *)arg;
5157 bus_space_write_1(regs->r_bt, regs->r_bh, off, val);
5158 }
5159
5160 void
5161 rtw_write16(void *arg, u_int32_t off, u_int16_t val)
5162 {
5163 struct rtw_regs *regs = (struct rtw_regs *)arg;
5164 bus_space_write_2(regs->r_bt, regs->r_bh, off, val);
5165 }
5166
5167 void
5168 rtw_write32(void *arg, u_int32_t off, u_int32_t val)
5169 {
5170 struct rtw_regs *regs = (struct rtw_regs *)arg;
5171 bus_space_write_4(regs->r_bt, regs->r_bh, off, val);
5172 }
5173
5174 void
5175 rtw_barrier(void *arg, u_int32_t reg0, u_int32_t reg1, int flags)
5176 {
5177 struct rtw_regs *regs = (struct rtw_regs *)arg;
5178 bus_space_barrier(regs->r_bt, regs->r_bh, MIN(reg0, reg1),
5179 MAX(reg0, reg1) - MIN(reg0, reg1) + 4, flags);
5180 }