Ticket #8023: openbsd_if_urtwn.c

File openbsd_if_urtwn.c, 87.0 KB (added by andrewbachmann, 12 years ago)

openbsd's if_urtwn.c

Line 
1/* $OpenBSD: if_urtwn.c,v 1.22 2012/04/08 12:17:20 jsg Exp $ */
2
3/*-
4 * Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
20 * Driver for Realtek RTL8188CE-VAU/RTL8188CUS/RTL8188RU/RTL8192CU.
21 */
22
23#include "bpfilter.h"
24
25#include <sys/param.h>
26#include <sys/sockio.h>
27#include <sys/mbuf.h>
28#include <sys/kernel.h>
29#include <sys/socket.h>
30#include <sys/systm.h>
31#include <sys/timeout.h>
32#include <sys/conf.h>
33#include <sys/device.h>
34
35#include <machine/bus.h>
36#include <machine/endian.h>
37#include <machine/intr.h>
38
39#if NBPFILTER > 0
40#include <net/bpf.h>
41#endif
42#include <net/if.h>
43#include <net/if_arp.h>
44#include <net/if_dl.h>
45#include <net/if_media.h>
46#include <net/if_types.h>
47
48#include <netinet/in.h>
49#include <netinet/in_systm.h>
50#include <netinet/in_var.h>
51#include <netinet/if_ether.h>
52#include <netinet/ip.h>
53
54#include <net80211/ieee80211_var.h>
55#include <net80211/ieee80211_radiotap.h>
56
57#include <dev/usb/usb.h>
58#include <dev/usb/usbdi.h>
59#include <dev/usb/usbdi_util.h>
60#include <dev/usb/usbdevs.h>
61
62#include <dev/usb/if_urtwnreg.h>
63
64#ifdef USB_DEBUG
65#define URTWN_DEBUG
66#endif
67
68#ifdef URTWN_DEBUG
69#define DPRINTF(x) do { if (urtwn_debug) printf x; } while (0)
70#define DPRINTFN(n, x) do { if (urtwn_debug >= (n)) printf x; } while (0)
71int urtwn_debug = 4;
72#else
73#define DPRINTF(x)
74#define DPRINTFN(n, x)
75#endif
76
77static const struct usb_devno urtwn_devs[] = {
78 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_1 },
79 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8188CU_2 },
80 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_RTL8192CU },
81 { USB_VENDOR_ASUS, USB_PRODUCT_ASUS_RTL8192CU },
82 { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_1 },
83 { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CE_2 },
84 { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8188CU },
85 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F7D2102 },
86 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8188CU },
87 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192CU },
88 { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_1 },
89 { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_2 },
90 { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_3 },
91 { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_4 },
92 { USB_VENDOR_CHICONY, USB_PRODUCT_CHICONY_RTL8188CUS_5 },
93 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_RTL8192CU },
94 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8188CU },
95 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_1 },
96 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_2 },
97 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_RTL8192CU_3 },
98 { USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8188CU },
99 { USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192CU },
100 { USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8188CU },
101 { USB_VENDOR_FEIXUN, USB_PRODUCT_FEIXUN_RTL8192CU },
102 { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUP150 },
103 { USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192CU },
104 { USB_VENDOR_HP3, USB_PRODUCT_HP3_RTL8188CU },
105 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_WNA1000M },
106 { USB_VENDOR_NETGEAR, USB_PRODUCT_NETGEAR_RTL8192CU },
107 { USB_VENDOR_NETGEAR4, USB_PRODUCT_NETGEAR4_RTL8188CU },
108 { USB_VENDOR_NOVATECH, USB_PRODUCT_NOVATECH_RTL8188CU },
109 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_1 },
110 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_2 },
111 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_3 },
112 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CU_4 },
113 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8188CUS },
114 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_RTL8192CU },
115 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_0 },
116 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CE_1 },
117 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CTV },
118 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_0 },
119 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_1 },
120 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_2 },
121 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CU_COMBO },
122 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188CUS },
123 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU },
124 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8188RU_2 },
125 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8191CU },
126 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CE },
127 { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192CU },
128 { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU },
129 { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188CU_2 },
130 { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8192CU },
131 { USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8188CU },
132 { USB_VENDOR_TRENDNET, USB_PRODUCT_TRENDNET_RTL8192CU },
133 { USB_VENDOR_ZYXEL, USB_PRODUCT_ZYXEL_RTL8192CU }
134};
135
136int urtwn_match(struct device *, void *, void *);
137void urtwn_attach(struct device *, struct device *, void *);
138int urtwn_detach(struct device *, int);
139int urtwn_activate(struct device *, int);
140int urtwn_open_pipes(struct urtwn_softc *);
141void urtwn_close_pipes(struct urtwn_softc *);
142int urtwn_alloc_rx_list(struct urtwn_softc *);
143void urtwn_free_rx_list(struct urtwn_softc *);
144int urtwn_alloc_tx_list(struct urtwn_softc *);
145void urtwn_free_tx_list(struct urtwn_softc *);
146void urtwn_task(void *);
147void urtwn_do_async(struct urtwn_softc *,
148 void (*)(struct urtwn_softc *, void *), void *, int);
149void urtwn_wait_async(struct urtwn_softc *);
150int urtwn_write_region_1(struct urtwn_softc *, uint16_t, uint8_t *,
151 int);
152void urtwn_write_1(struct urtwn_softc *, uint16_t, uint8_t);
153void urtwn_write_2(struct urtwn_softc *, uint16_t, uint16_t);
154void urtwn_write_4(struct urtwn_softc *, uint16_t, uint32_t);
155int urtwn_read_region_1(struct urtwn_softc *, uint16_t, uint8_t *,
156 int);
157uint8_t urtwn_read_1(struct urtwn_softc *, uint16_t);
158uint16_t urtwn_read_2(struct urtwn_softc *, uint16_t);
159uint32_t urtwn_read_4(struct urtwn_softc *, uint16_t);
160int urtwn_fw_cmd(struct urtwn_softc *, uint8_t, const void *, int);
161void urtwn_rf_write(struct urtwn_softc *, int, uint8_t, uint32_t);
162uint32_t urtwn_rf_read(struct urtwn_softc *, int, uint8_t);
163void urtwn_cam_write(struct urtwn_softc *, uint32_t, uint32_t);
164int urtwn_llt_write(struct urtwn_softc *, uint32_t, uint32_t);
165uint8_t urtwn_efuse_read_1(struct urtwn_softc *, uint16_t);
166void urtwn_efuse_read(struct urtwn_softc *);
167int urtwn_read_chipid(struct urtwn_softc *);
168void urtwn_read_rom(struct urtwn_softc *);
169int urtwn_media_change(struct ifnet *);
170int urtwn_ra_init(struct urtwn_softc *);
171void urtwn_tsf_sync_enable(struct urtwn_softc *);
172void urtwn_set_led(struct urtwn_softc *, int, int);
173void urtwn_calib_to(void *);
174void urtwn_calib_cb(struct urtwn_softc *, void *);
175void urtwn_next_scan(void *);
176int urtwn_newstate(struct ieee80211com *, enum ieee80211_state,
177 int);
178void urtwn_newstate_cb(struct urtwn_softc *, void *);
179void urtwn_updateedca(struct ieee80211com *);
180void urtwn_updateedca_cb(struct urtwn_softc *, void *);
181int urtwn_set_key(struct ieee80211com *, struct ieee80211_node *,
182 struct ieee80211_key *);
183void urtwn_set_key_cb(struct urtwn_softc *, void *);
184void urtwn_delete_key(struct ieee80211com *,
185 struct ieee80211_node *, struct ieee80211_key *);
186void urtwn_delete_key_cb(struct urtwn_softc *, void *);
187void urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t);
188int8_t urtwn_get_rssi(struct urtwn_softc *, int, void *);
189void urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int);
190void urtwn_rxeof(usbd_xfer_handle, usbd_private_handle,
191 usbd_status);
192void urtwn_txeof(usbd_xfer_handle, usbd_private_handle,
193 usbd_status);
194int urtwn_tx(struct urtwn_softc *, struct mbuf *,
195 struct ieee80211_node *);
196void urtwn_start(struct ifnet *);
197void urtwn_watchdog(struct ifnet *);
198int urtwn_ioctl(struct ifnet *, u_long, caddr_t);
199int urtwn_power_on(struct urtwn_softc *);
200int urtwn_llt_init(struct urtwn_softc *);
201void urtwn_fw_reset(struct urtwn_softc *);
202int urtwn_fw_loadpage(struct urtwn_softc *, int, uint8_t *, int);
203int urtwn_load_firmware(struct urtwn_softc *);
204int urtwn_dma_init(struct urtwn_softc *);
205void urtwn_mac_init(struct urtwn_softc *);
206void urtwn_bb_init(struct urtwn_softc *);
207void urtwn_rf_init(struct urtwn_softc *);
208void urtwn_cam_init(struct urtwn_softc *);
209void urtwn_pa_bias_init(struct urtwn_softc *);
210void urtwn_rxfilter_init(struct urtwn_softc *);
211void urtwn_edca_init(struct urtwn_softc *);
212void urtwn_write_txpower(struct urtwn_softc *, int, uint16_t[]);
213void urtwn_get_txpower(struct urtwn_softc *, int,
214 struct ieee80211_channel *, struct ieee80211_channel *,
215 uint16_t[]);
216void urtwn_set_txpower(struct urtwn_softc *,
217 struct ieee80211_channel *, struct ieee80211_channel *);
218void urtwn_set_chan(struct urtwn_softc *,
219 struct ieee80211_channel *, struct ieee80211_channel *);
220int urtwn_iq_calib_chain(struct urtwn_softc *, int, uint16_t[],
221 uint16_t[]);
222void urtwn_iq_calib(struct urtwn_softc *);
223void urtwn_lc_calib(struct urtwn_softc *);
224void urtwn_temp_calib(struct urtwn_softc *);
225int urtwn_init(struct ifnet *);
226void urtwn_stop(struct ifnet *);
227
228/* Aliases. */
229#define urtwn_bb_write urtwn_write_4
230#define urtwn_bb_read urtwn_read_4
231
232struct cfdriver urtwn_cd = {
233 NULL, "urtwn", DV_IFNET
234};
235
236const struct cfattach urtwn_ca = {
237 sizeof(struct urtwn_softc),
238 urtwn_match,
239 urtwn_attach,
240 urtwn_detach,
241 urtwn_activate
242};
243
244int
245urtwn_match(struct device *parent, void *match, void *aux)
246{
247 struct usb_attach_arg *uaa = aux;
248
249 if (uaa->iface != NULL)
250 return (UMATCH_NONE);
251
252 return ((usb_lookup(urtwn_devs, uaa->vendor, uaa->product) != NULL) ?
253 UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
254}
255
256void
257urtwn_attach(struct device *parent, struct device *self, void *aux)
258{
259 struct urtwn_softc *sc = (struct urtwn_softc *)self;
260 struct usb_attach_arg *uaa = aux;
261 struct ieee80211com *ic = &sc->sc_ic;
262 struct ifnet *ifp = &ic->ic_if;
263 int i, error;
264
265 sc->sc_udev = uaa->device;
266
267 usb_init_task(&sc->sc_task, urtwn_task, sc, USB_TASK_TYPE_GENERIC);
268 timeout_set(&sc->scan_to, urtwn_next_scan, sc);
269 timeout_set(&sc->calib_to, urtwn_calib_to, sc);
270
271 if (usbd_set_config_no(sc->sc_udev, 1, 0) != 0) {
272 printf("%s: could not set configuration no\n",
273 sc->sc_dev.dv_xname);
274 return;
275 }
276
277 /* Get the first interface handle. */
278 error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
279 if (error != 0) {
280 printf("%s: could not get interface handle\n",
281 sc->sc_dev.dv_xname);
282 return;
283 }
284
285 error = urtwn_read_chipid(sc);
286 if (error != 0) {
287 printf("%s: unsupported test chip\n", sc->sc_dev.dv_xname);
288 return;
289 }
290
291 /* Determine number of Tx/Rx chains. */
292 if (sc->chip & URTWN_CHIP_92C) {
293 sc->ntxchains = (sc->chip & URTWN_CHIP_92C_1T2R) ? 1 : 2;
294 sc->nrxchains = 2;
295 } else {
296 sc->ntxchains = 1;
297 sc->nrxchains = 1;
298 }
299 urtwn_read_rom(sc);
300
301 printf("%s: MAC/BB RTL%s, RF 6052 %dT%dR, address %s\n",
302 sc->sc_dev.dv_xname,
303 (sc->chip & URTWN_CHIP_92C) ? "8192CU" :
304 (sc->board_type == R92C_BOARD_TYPE_HIGHPA) ? "8188RU" :
305 (sc->board_type == R92C_BOARD_TYPE_MINICARD) ? "8188CE-VAU" :
306 "8188CUS", sc->ntxchains, sc->nrxchains,
307 ether_sprintf(ic->ic_myaddr));
308
309 if (urtwn_open_pipes(sc) != 0)
310 return;
311
312 ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */
313 ic->ic_opmode = IEEE80211_M_STA; /* Default to BSS mode. */
314 ic->ic_state = IEEE80211_S_INIT;
315
316 /* Set device capabilities. */
317 ic->ic_caps =
318 IEEE80211_C_MONITOR | /* Monitor mode supported. */
319 IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */
320 IEEE80211_C_SHSLOT | /* Short slot time supported. */
321 IEEE80211_C_WEP | /* WEP. */
322 IEEE80211_C_RSN; /* WPA/RSN. */
323
324#ifndef IEEE80211_NO_HT
325 /* Set HT capabilities. */
326 ic->ic_htcaps =
327 IEEE80211_HTCAP_CBW20_40 |
328 IEEE80211_HTCAP_DSSSCCK40;
329 /* Set supported HT rates. */
330 for (i = 0; i < sc->nrxchains; i++)
331 ic->ic_sup_mcs[i] = 0xff;
332#endif
333
334 /* Set supported .11b and .11g rates. */
335 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
336 ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
337
338 /* Set supported .11b and .11g channels (1 through 14). */
339 for (i = 1; i <= 14; i++) {
340 ic->ic_channels[i].ic_freq =
341 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
342 ic->ic_channels[i].ic_flags =
343 IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
344 IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
345 }
346 /*
347 * The number of STAs that we can support is limited by the number
348 * of CAM entries used for hardware crypto.
349 */
350 ic->ic_max_nnodes = R92C_CAM_ENTRY_COUNT - 4;
351 if (ic->ic_max_nnodes > IEEE80211_CACHE_SIZE)
352 ic->ic_max_nnodes = IEEE80211_CACHE_SIZE;
353
354 ifp->if_softc = sc;
355 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
356 ifp->if_ioctl = urtwn_ioctl;
357 ifp->if_start = urtwn_start;
358 ifp->if_watchdog = urtwn_watchdog;
359 IFQ_SET_READY(&ifp->if_snd);
360 memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ);
361
362 if_attach(ifp);
363 ieee80211_ifattach(ifp);
364 ic->ic_updateedca = urtwn_updateedca;
365#ifdef notyet
366 ic->ic_set_key = urtwn_set_key;
367 ic->ic_delete_key = urtwn_delete_key;
368#endif
369 /* Override state transition machine. */
370 sc->sc_newstate = ic->ic_newstate;
371 ic->ic_newstate = urtwn_newstate;
372 ieee80211_media_init(ifp, urtwn_media_change, ieee80211_media_status);
373
374#if NBPFILTER > 0
375 bpfattach(&sc->sc_drvbpf, ifp, DLT_IEEE802_11_RADIO,
376 sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN);
377
378 sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
379 sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
380 sc->sc_rxtap.wr_ihdr.it_present = htole32(URTWN_RX_RADIOTAP_PRESENT);
381
382 sc->sc_txtap_len = sizeof(sc->sc_txtapu);
383 sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
384 sc->sc_txtap.wt_ihdr.it_present = htole32(URTWN_TX_RADIOTAP_PRESENT);
385#endif
386}
387
388int
389urtwn_detach(struct device *self, int flags)
390{
391 struct urtwn_softc *sc = (struct urtwn_softc *)self;
392 struct ifnet *ifp = &sc->sc_ic.ic_if;
393 int s;
394
395 s = splusb();
396
397 if (timeout_initialized(&sc->scan_to))
398 timeout_del(&sc->scan_to);
399 if (timeout_initialized(&sc->calib_to))
400 timeout_del(&sc->calib_to);
401
402 /* Wait for all async commands to complete. */
403 usb_rem_wait_task(sc->sc_udev, &sc->sc_task);
404
405 usbd_ref_wait(sc->sc_udev);
406
407 if (ifp->if_softc != NULL) {
408 ieee80211_ifdetach(ifp);
409 if_detach(ifp);
410 }
411
412 /* Abort and close Tx/Rx pipes. */
413 urtwn_close_pipes(sc);
414
415 /* Free Tx/Rx buffers. */
416 urtwn_free_tx_list(sc);
417 urtwn_free_rx_list(sc);
418 splx(s);
419
420 return (0);
421}
422
423int
424urtwn_activate(struct device *self, int act)
425{
426 struct urtwn_softc *sc = (struct urtwn_softc *)self;
427
428 switch (act) {
429 case DVACT_DEACTIVATE:
430 usbd_deactivate(sc->sc_udev);
431 break;
432 }
433 return (0);
434}
435
436int
437urtwn_open_pipes(struct urtwn_softc *sc)
438{
439 /* Bulk-out endpoints addresses (from highest to lowest prio). */
440 const uint8_t epaddr[] = { 0x02, 0x03, 0x05 };
441 usb_interface_descriptor_t *id;
442 usb_endpoint_descriptor_t *ed;
443 int i, ntx = 0, error;
444
445 /* Determine the number of bulk-out pipes. */
446 id = usbd_get_interface_descriptor(sc->sc_iface);
447 for (i = 0; i < id->bNumEndpoints; i++) {
448 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
449 if (ed != NULL &&
450 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK &&
451 UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT)
452 ntx++;
453 }
454 DPRINTF(("found %d bulk-out pipes\n", ntx));
455 if (ntx == 0 || ntx > R92C_MAX_EPOUT) {
456 printf("%s: %d: invalid number of Tx bulk pipes\n",
457 sc->sc_dev.dv_xname, ntx);
458 return (EIO);
459 }
460
461 /* Open bulk-in pipe at address 0x81. */
462 error = usbd_open_pipe(sc->sc_iface, 0x81, 0, &sc->rx_pipe);
463 if (error != 0) {
464 printf("%s: could not open Rx bulk pipe\n",
465 sc->sc_dev.dv_xname);
466 goto fail;
467 }
468
469 /* Open bulk-out pipes (up to 3). */
470 for (i = 0; i < ntx; i++) {
471 error = usbd_open_pipe(sc->sc_iface, epaddr[i], 0,
472 &sc->tx_pipe[i]);
473 if (error != 0) {
474 printf("%s: could not open Tx bulk pipe 0x%02x\n",
475 sc->sc_dev.dv_xname, epaddr[i]);
476 goto fail;
477 }
478 }
479
480 /* Map 802.11 access categories to USB pipes. */
481 sc->ac2idx[EDCA_AC_BK] =
482 sc->ac2idx[EDCA_AC_BE] = (ntx == 3) ? 2 : ((ntx == 2) ? 1 : 0);
483 sc->ac2idx[EDCA_AC_VI] = (ntx == 3) ? 1 : 0;
484 sc->ac2idx[EDCA_AC_VO] = 0; /* Always use highest prio. */
485
486 if (error != 0)
487 fail: urtwn_close_pipes(sc);
488 return (error);
489}
490
491void
492urtwn_close_pipes(struct urtwn_softc *sc)
493{
494 int i;
495
496 /* Close Rx pipe. */
497 if (sc->rx_pipe != NULL) {
498 usbd_abort_pipe(sc->rx_pipe);
499 usbd_close_pipe(sc->rx_pipe);
500 }
501 /* Close Tx pipes. */
502 for (i = 0; i < R92C_MAX_EPOUT; i++) {
503 if (sc->tx_pipe[i] == NULL)
504 continue;
505 usbd_abort_pipe(sc->tx_pipe[i]);
506 usbd_close_pipe(sc->tx_pipe[i]);
507 }
508}
509
510int
511urtwn_alloc_rx_list(struct urtwn_softc *sc)
512{
513 struct urtwn_rx_data *data;
514 int i, error = 0;
515
516 for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
517 data = &sc->rx_data[i];
518
519 data->sc = sc; /* Backpointer for callbacks. */
520
521 data->xfer = usbd_alloc_xfer(sc->sc_udev);
522 if (data->xfer == NULL) {
523 printf("%s: could not allocate xfer\n",
524 sc->sc_dev.dv_xname);
525 error = ENOMEM;
526 break;
527 }
528 data->buf = usbd_alloc_buffer(data->xfer, URTWN_RXBUFSZ);
529 if (data->buf == NULL) {
530 printf("%s: could not allocate xfer buffer\n",
531 sc->sc_dev.dv_xname);
532 error = ENOMEM;
533 break;
534 }
535 }
536 if (error != 0)
537 urtwn_free_rx_list(sc);
538 return (error);
539}
540
541void
542urtwn_free_rx_list(struct urtwn_softc *sc)
543{
544 int i;
545
546 /* NB: Caller must abort pipe first. */
547 for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
548 if (sc->rx_data[i].xfer != NULL)
549 usbd_free_xfer(sc->rx_data[i].xfer);
550 sc->rx_data[i].xfer = NULL;
551 }
552}
553
554int
555urtwn_alloc_tx_list(struct urtwn_softc *sc)
556{
557 struct urtwn_tx_data *data;
558 int i, error = 0;
559
560 TAILQ_INIT(&sc->tx_free_list);
561 for (i = 0; i < URTWN_TX_LIST_COUNT; i++) {
562 data = &sc->tx_data[i];
563
564 data->sc = sc; /* Backpointer for callbacks. */
565
566 data->xfer = usbd_alloc_xfer(sc->sc_udev);
567 if (data->xfer == NULL) {
568 printf("%s: could not allocate xfer\n",
569 sc->sc_dev.dv_xname);
570 error = ENOMEM;
571 break;
572 }
573 data->buf = usbd_alloc_buffer(data->xfer, URTWN_TXBUFSZ);
574 if (data->buf == NULL) {
575 printf("%s: could not allocate xfer buffer\n",
576 sc->sc_dev.dv_xname);
577 error = ENOMEM;
578 break;
579 }
580 /* Append this Tx buffer to our free list. */
581 TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next);
582 }
583 if (error != 0)
584 urtwn_free_tx_list(sc);
585 return (error);
586}
587
588void
589urtwn_free_tx_list(struct urtwn_softc *sc)
590{
591 int i;
592
593 /* NB: Caller must abort pipe first. */
594 for (i = 0; i < URTWN_TX_LIST_COUNT; i++) {
595 if (sc->tx_data[i].xfer != NULL)
596 usbd_free_xfer(sc->tx_data[i].xfer);
597 sc->tx_data[i].xfer = NULL;
598 }
599}
600
601void
602urtwn_task(void *arg)
603{
604 struct urtwn_softc *sc = arg;
605 struct urtwn_host_cmd_ring *ring = &sc->cmdq;
606 struct urtwn_host_cmd *cmd;
607 int s;
608
609 /* Process host commands. */
610 s = splusb();
611 while (ring->next != ring->cur) {
612 cmd = &ring->cmd[ring->next];
613 splx(s);
614 /* Invoke callback. */
615 cmd->cb(sc, cmd->data);
616 s = splusb();
617 ring->queued--;
618 ring->next = (ring->next + 1) % URTWN_HOST_CMD_RING_COUNT;
619 }
620 splx(s);
621}
622
623void
624urtwn_do_async(struct urtwn_softc *sc,
625 void (*cb)(struct urtwn_softc *, void *), void *arg, int len)
626{
627 struct urtwn_host_cmd_ring *ring = &sc->cmdq;
628 struct urtwn_host_cmd *cmd;
629 int s;
630
631 s = splusb();
632 cmd = &ring->cmd[ring->cur];
633 cmd->cb = cb;
634 KASSERT(len <= sizeof(cmd->data));
635 memcpy(cmd->data, arg, len);
636 ring->cur = (ring->cur + 1) % URTWN_HOST_CMD_RING_COUNT;
637
638 /* If there is no pending command already, schedule a task. */
639 if (++ring->queued == 1)
640 usb_add_task(sc->sc_udev, &sc->sc_task);
641 splx(s);
642}
643
644void
645urtwn_wait_async(struct urtwn_softc *sc)
646{
647 /* Wait for all queued asynchronous commands to complete. */
648 usb_wait_task(sc->sc_udev, &sc->sc_task);
649}
650
651int
652urtwn_write_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
653 int len)
654{
655 usb_device_request_t req;
656
657 req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
658 req.bRequest = R92C_REQ_REGS;
659 USETW(req.wValue, addr);
660 USETW(req.wIndex, 0);
661 USETW(req.wLength, len);
662 return (usbd_do_request(sc->sc_udev, &req, buf));
663}
664
665void
666urtwn_write_1(struct urtwn_softc *sc, uint16_t addr, uint8_t val)
667{
668 urtwn_write_region_1(sc, addr, &val, 1);
669}
670
671void
672urtwn_write_2(struct urtwn_softc *sc, uint16_t addr, uint16_t val)
673{
674 val = htole16(val);
675 urtwn_write_region_1(sc, addr, (uint8_t *)&val, 2);
676}
677
678void
679urtwn_write_4(struct urtwn_softc *sc, uint16_t addr, uint32_t val)
680{
681 val = htole32(val);
682 urtwn_write_region_1(sc, addr, (uint8_t *)&val, 4);
683}
684
685int
686urtwn_read_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf,
687 int len)
688{
689 usb_device_request_t req;
690
691 req.bmRequestType = UT_READ_VENDOR_DEVICE;
692 req.bRequest = R92C_REQ_REGS;
693 USETW(req.wValue, addr);
694 USETW(req.wIndex, 0);
695 USETW(req.wLength, len);
696 return (usbd_do_request(sc->sc_udev, &req, buf));
697}
698
699uint8_t
700urtwn_read_1(struct urtwn_softc *sc, uint16_t addr)
701{
702 uint8_t val;
703
704 if (urtwn_read_region_1(sc, addr, &val, 1) != 0)
705 return (0xff);
706 return (val);
707}
708
709uint16_t
710urtwn_read_2(struct urtwn_softc *sc, uint16_t addr)
711{
712 uint16_t val;
713
714 if (urtwn_read_region_1(sc, addr, (uint8_t *)&val, 2) != 0)
715 return (0xffff);
716 return (letoh16(val));
717}
718
719uint32_t
720urtwn_read_4(struct urtwn_softc *sc, uint16_t addr)
721{
722 uint32_t val;
723
724 if (urtwn_read_region_1(sc, addr, (uint8_t *)&val, 4) != 0)
725 return (0xffffffff);
726 return (letoh32(val));
727}
728
729int
730urtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len)
731{
732 struct r92c_fw_cmd cmd;
733 int ntries;
734
735 /* Wait for current FW box to be empty. */
736 for (ntries = 0; ntries < 100; ntries++) {
737 if (!(urtwn_read_1(sc, R92C_HMETFR) & (1 << sc->fwcur)))
738 break;
739 DELAY(1);
740 }
741 if (ntries == 100) {
742 printf("%s: could not send firmware command %d\n",
743 sc->sc_dev.dv_xname, id);
744 return (ETIMEDOUT);
745 }
746 memset(&cmd, 0, sizeof(cmd));
747 cmd.id = id;
748 if (len > 3)
749 cmd.id |= R92C_CMD_FLAG_EXT;
750 KASSERT(len <= sizeof(cmd.msg));
751 memcpy(cmd.msg, buf, len);
752
753 /* Write the first word last since that will trigger the FW. */
754 urtwn_write_region_1(sc, R92C_HMEBOX_EXT(sc->fwcur),
755 (uint8_t *)&cmd + 4, 2);
756 urtwn_write_region_1(sc, R92C_HMEBOX(sc->fwcur),
757 (uint8_t *)&cmd + 0, 4);
758
759 sc->fwcur = (sc->fwcur + 1) % R92C_H2C_NBOX;
760 return (0);
761}
762
763void
764urtwn_rf_write(struct urtwn_softc *sc, int chain, uint8_t addr, uint32_t val)
765{
766 urtwn_bb_write(sc, R92C_LSSI_PARAM(chain),
767 SM(R92C_LSSI_PARAM_ADDR, addr) |
768 SM(R92C_LSSI_PARAM_DATA, val));
769}
770
771uint32_t
772urtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr)
773{
774 uint32_t reg[R92C_MAX_CHAINS], val;
775
776 reg[0] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(0));
777 if (chain != 0)
778 reg[chain] = urtwn_bb_read(sc, R92C_HSSI_PARAM2(chain));
779
780 urtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
781 reg[0] & ~R92C_HSSI_PARAM2_READ_EDGE);
782 DELAY(1000);
783
784 urtwn_bb_write(sc, R92C_HSSI_PARAM2(chain),
785 RW(reg[chain], R92C_HSSI_PARAM2_READ_ADDR, addr) |
786 R92C_HSSI_PARAM2_READ_EDGE);
787 DELAY(1000);
788
789 urtwn_bb_write(sc, R92C_HSSI_PARAM2(0),
790 reg[0] | R92C_HSSI_PARAM2_READ_EDGE);
791 DELAY(1000);
792
793 if (urtwn_bb_read(sc, R92C_HSSI_PARAM1(chain)) & R92C_HSSI_PARAM1_PI)
794 val = urtwn_bb_read(sc, R92C_HSPI_READBACK(chain));
795 else
796 val = urtwn_bb_read(sc, R92C_LSSI_READBACK(chain));
797 return (MS(val, R92C_LSSI_READBACK_DATA));
798}
799
800void
801urtwn_cam_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data)
802{
803 urtwn_write_4(sc, R92C_CAMWRITE, data);
804 urtwn_write_4(sc, R92C_CAMCMD,
805 R92C_CAMCMD_POLLING | R92C_CAMCMD_WRITE |
806 SM(R92C_CAMCMD_ADDR, addr));
807}
808
809int
810urtwn_llt_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data)
811{
812 int ntries;
813
814 urtwn_write_4(sc, R92C_LLT_INIT,
815 SM(R92C_LLT_INIT_OP, R92C_LLT_INIT_OP_WRITE) |
816 SM(R92C_LLT_INIT_ADDR, addr) |
817 SM(R92C_LLT_INIT_DATA, data));
818 /* Wait for write operation to complete. */
819 for (ntries = 0; ntries < 20; ntries++) {
820 if (MS(urtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) ==
821 R92C_LLT_INIT_OP_NO_ACTIVE)
822 return (0);
823 DELAY(5);
824 }
825 return (ETIMEDOUT);
826}
827
828uint8_t
829urtwn_efuse_read_1(struct urtwn_softc *sc, uint16_t addr)
830{
831 uint32_t reg;
832 int ntries;
833
834 reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
835 reg = RW(reg, R92C_EFUSE_CTRL_ADDR, addr);
836 reg &= ~R92C_EFUSE_CTRL_VALID;
837 urtwn_write_4(sc, R92C_EFUSE_CTRL, reg);
838 /* Wait for read operation to complete. */
839 for (ntries = 0; ntries < 100; ntries++) {
840 reg = urtwn_read_4(sc, R92C_EFUSE_CTRL);
841 if (reg & R92C_EFUSE_CTRL_VALID)
842 return (MS(reg, R92C_EFUSE_CTRL_DATA));
843 DELAY(5);
844 }
845 printf("%s: could not read efuse byte at address 0x%x\n",
846 sc->sc_dev.dv_xname, addr);
847 return (0xff);
848}
849
850void
851urtwn_efuse_read(struct urtwn_softc *sc)
852{
853 uint8_t *rom = (uint8_t *)&sc->rom;
854 uint16_t addr = 0;
855 uint32_t reg;
856 uint8_t off, msk;
857 int i;
858
859 reg = urtwn_read_2(sc, R92C_SYS_ISO_CTRL);
860 if (!(reg & R92C_SYS_ISO_CTRL_PWC_EV12V)) {
861 urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
862 reg | R92C_SYS_ISO_CTRL_PWC_EV12V);
863 }
864 reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
865 if (!(reg & R92C_SYS_FUNC_EN_ELDR)) {
866 urtwn_write_2(sc, R92C_SYS_FUNC_EN,
867 reg | R92C_SYS_FUNC_EN_ELDR);
868 }
869 reg = urtwn_read_2(sc, R92C_SYS_CLKR);
870 if ((reg & (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) !=
871 (R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M)) {
872 urtwn_write_2(sc, R92C_SYS_CLKR,
873 reg | R92C_SYS_CLKR_LOADER_EN | R92C_SYS_CLKR_ANA8M);
874 }
875 memset(&sc->rom, 0xff, sizeof(sc->rom));
876 while (addr < 512) {
877 reg = urtwn_efuse_read_1(sc, addr);
878 if (reg == 0xff)
879 break;
880 addr++;
881 off = reg >> 4;
882 msk = reg & 0xf;
883 for (i = 0; i < 4; i++) {
884 if (msk & (1 << i))
885 continue;
886 rom[off * 8 + i * 2 + 0] =
887 urtwn_efuse_read_1(sc, addr);
888 addr++;
889 rom[off * 8 + i * 2 + 1] =
890 urtwn_efuse_read_1(sc, addr);
891 addr++;
892 }
893 }
894#ifdef URTWN_DEBUG
895 if (urtwn_debug >= 2) {
896 /* Dump ROM content. */
897 printf("\n");
898 for (i = 0; i < sizeof(sc->rom); i++)
899 printf("%02x:", rom[i]);
900 printf("\n");
901 }
902#endif
903}
904
905int
906urtwn_read_chipid(struct urtwn_softc *sc)
907{
908 uint32_t reg;
909
910 reg = urtwn_read_4(sc, R92C_SYS_CFG);
911 if (reg & R92C_SYS_CFG_TRP_VAUX_EN)
912 return (EIO);
913
914 if (reg & R92C_SYS_CFG_TYPE_92C) {
915 sc->chip |= URTWN_CHIP_92C;
916 /* Check if it is a castrated 8192C. */
917 if (MS(urtwn_read_4(sc, R92C_HPON_FSM),
918 R92C_HPON_FSM_CHIP_BONDING_ID) ==
919 R92C_HPON_FSM_CHIP_BONDING_ID_92C_1T2R)
920 sc->chip |= URTWN_CHIP_92C_1T2R;
921 }
922 if (reg & R92C_SYS_CFG_VENDOR_UMC) {
923 sc->chip |= URTWN_CHIP_UMC;
924 if (MS(reg, R92C_SYS_CFG_CHIP_VER_RTL) == 0)
925 sc->chip |= URTWN_CHIP_UMC_A_CUT;
926 }
927 return (0);
928}
929
930void
931urtwn_read_rom(struct urtwn_softc *sc)
932{
933 struct ieee80211com *ic = &sc->sc_ic;
934 struct r92c_rom *rom = &sc->rom;
935
936 /* Read full ROM image. */
937 urtwn_efuse_read(sc);
938
939 /* XXX Weird but this is what the vendor driver does. */
940 sc->pa_setting = urtwn_efuse_read_1(sc, 0x1fa);
941 DPRINTF(("PA setting=0x%x\n", sc->pa_setting));
942
943 sc->board_type = MS(rom->rf_opt1, R92C_ROM_RF1_BOARD_TYPE);
944
945 sc->regulatory = MS(rom->rf_opt1, R92C_ROM_RF1_REGULATORY);
946 DPRINTF(("regulatory type=%d\n", sc->regulatory));
947
948 IEEE80211_ADDR_COPY(ic->ic_myaddr, rom->macaddr);
949}
950
951int
952urtwn_media_change(struct ifnet *ifp)
953{
954 int error;
955
956 error = ieee80211_media_change(ifp);
957 if (error != ENETRESET)
958 return (error);
959
960 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
961 (IFF_UP | IFF_RUNNING)) {
962 urtwn_stop(ifp);
963 urtwn_init(ifp);
964 }
965 return (0);
966}
967
968/*
969 * Initialize rate adaptation in firmware.
970 */
971int
972urtwn_ra_init(struct urtwn_softc *sc)
973{
974 static const uint8_t map[] =
975 { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
976 struct ieee80211com *ic = &sc->sc_ic;
977 struct ieee80211_node *ni = ic->ic_bss;
978 struct ieee80211_rateset *rs = &ni->ni_rates;
979 struct r92c_fw_cmd_macid_cfg cmd;
980 uint32_t rates, basicrates;
981 uint8_t mode;
982 int maxrate, maxbasicrate, error, i, j;
983
984 /* Get normal and basic rates mask. */
985 rates = basicrates = 0;
986 maxrate = maxbasicrate = 0;
987 for (i = 0; i < rs->rs_nrates; i++) {
988 /* Convert 802.11 rate to HW rate index. */
989 for (j = 0; j < nitems(map); j++)
990 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == map[j])
991 break;
992 if (j == nitems(map)) /* Unknown rate, skip. */
993 continue;
994 rates |= 1 << j;
995 if (j > maxrate)
996 maxrate = j;
997 if (rs->rs_rates[i] & IEEE80211_RATE_BASIC) {
998 basicrates |= 1 << j;
999 if (j > maxbasicrate)
1000 maxbasicrate = j;
1001 }
1002 }
1003 if (ic->ic_curmode == IEEE80211_MODE_11B)
1004 mode = R92C_RAID_11B;
1005 else
1006 mode = R92C_RAID_11BG;
1007 DPRINTF(("mode=0x%x rates=0x%08x, basicrates=0x%08x\n",
1008 mode, rates, basicrates));
1009
1010 /* Set rates mask for group addressed frames. */
1011 cmd.macid = URTWN_MACID_BC | URTWN_MACID_VALID;
1012 cmd.mask = htole32(mode << 28 | basicrates);
1013 error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
1014 if (error != 0) {
1015 printf("%s: could not add broadcast station\n",
1016 sc->sc_dev.dv_xname);
1017 return (error);
1018 }
1019 /* Set initial MRR rate. */
1020 DPRINTF(("maxbasicrate=%d\n", maxbasicrate));
1021 urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BC),
1022 maxbasicrate);
1023
1024 /* Set rates mask for unicast frames. */
1025 cmd.macid = URTWN_MACID_BSS | URTWN_MACID_VALID;
1026 cmd.mask = htole32(mode << 28 | rates);
1027 error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd));
1028 if (error != 0) {
1029 printf("%s: could not add BSS station\n",
1030 sc->sc_dev.dv_xname);
1031 return (error);
1032 }
1033 /* Set initial MRR rate. */
1034 DPRINTF(("maxrate=%d\n", maxrate));
1035 urtwn_write_1(sc, R92C_INIDATA_RATE_SEL(URTWN_MACID_BSS),
1036 maxrate);
1037
1038 /* Indicate highest supported rate. */
1039 ni->ni_txrate = rs->rs_nrates - 1;
1040 return (0);
1041}
1042
1043void
1044urtwn_tsf_sync_enable(struct urtwn_softc *sc)
1045{
1046 struct ieee80211_node *ni = sc->sc_ic.ic_bss;
1047 uint64_t tsf;
1048
1049 /* Enable TSF synchronization. */
1050 urtwn_write_1(sc, R92C_BCN_CTRL,
1051 urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_DIS_TSF_UDT0);
1052
1053 urtwn_write_1(sc, R92C_BCN_CTRL,
1054 urtwn_read_1(sc, R92C_BCN_CTRL) & ~R92C_BCN_CTRL_EN_BCN);
1055
1056 /* Set initial TSF. */
1057 memcpy(&tsf, ni->ni_tstamp, 8);
1058 tsf = letoh64(tsf);
1059 tsf = tsf - (tsf % (ni->ni_intval * IEEE80211_DUR_TU));
1060 tsf -= IEEE80211_DUR_TU;
1061 urtwn_write_4(sc, R92C_TSFTR + 0, tsf);
1062 urtwn_write_4(sc, R92C_TSFTR + 4, tsf >> 32);
1063
1064 urtwn_write_1(sc, R92C_BCN_CTRL,
1065 urtwn_read_1(sc, R92C_BCN_CTRL) | R92C_BCN_CTRL_EN_BCN);
1066}
1067
1068void
1069urtwn_set_led(struct urtwn_softc *sc, int led, int on)
1070{
1071 uint8_t reg;
1072
1073 if (led == URTWN_LED_LINK) {
1074 reg = urtwn_read_1(sc, R92C_LEDCFG0) & 0x70;
1075 if (!on)
1076 reg |= R92C_LEDCFG0_DIS;
1077 urtwn_write_1(sc, R92C_LEDCFG0, reg);
1078 sc->ledlink = on; /* Save LED state. */
1079 }
1080}
1081
1082void
1083urtwn_calib_to(void *arg)
1084{
1085 struct urtwn_softc *sc = arg;
1086
1087 if (usbd_is_dying(sc->sc_udev))
1088 return;
1089
1090 usbd_ref_incr(sc->sc_udev);
1091
1092 /* Do it in a process context. */
1093 urtwn_do_async(sc, urtwn_calib_cb, NULL, 0);
1094
1095 usbd_ref_decr(sc->sc_udev);
1096}
1097
1098/* ARGSUSED */
1099void
1100urtwn_calib_cb(struct urtwn_softc *sc, void *arg)
1101{
1102 struct r92c_fw_cmd_rssi cmd;
1103
1104 if (sc->avg_pwdb != -1) {
1105 /* Indicate Rx signal strength to FW for rate adaptation. */
1106 memset(&cmd, 0, sizeof(cmd));
1107 cmd.macid = 0; /* BSS. */
1108 cmd.pwdb = sc->avg_pwdb;
1109 DPRINTFN(3, ("sending RSSI command avg=%d\n", sc->avg_pwdb));
1110 urtwn_fw_cmd(sc, R92C_CMD_RSSI_SETTING, &cmd, sizeof(cmd));
1111 }
1112
1113 /* Do temperature compensation. */
1114 urtwn_temp_calib(sc);
1115
1116 if (!usbd_is_dying(sc->sc_udev))
1117 timeout_add_sec(&sc->calib_to, 2);
1118}
1119
1120void
1121urtwn_next_scan(void *arg)
1122{
1123 struct urtwn_softc *sc = arg;
1124 struct ieee80211com *ic = &sc->sc_ic;
1125 int s;
1126
1127 if (usbd_is_dying(sc->sc_udev))
1128 return;
1129
1130 usbd_ref_incr(sc->sc_udev);
1131
1132 s = splnet();
1133 if (ic->ic_state == IEEE80211_S_SCAN)
1134 ieee80211_next_scan(&ic->ic_if);
1135 splx(s);
1136
1137 usbd_ref_decr(sc->sc_udev);
1138}
1139
1140int
1141urtwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
1142{
1143 struct urtwn_softc *sc = ic->ic_softc;
1144 struct urtwn_cmd_newstate cmd;
1145
1146 /* Do it in a process context. */
1147 cmd.state = nstate;
1148 cmd.arg = arg;
1149 urtwn_do_async(sc, urtwn_newstate_cb, &cmd, sizeof(cmd));
1150 return (0);
1151}
1152
1153void
1154urtwn_newstate_cb(struct urtwn_softc *sc, void *arg)
1155{
1156 struct urtwn_cmd_newstate *cmd = arg;
1157 struct ieee80211com *ic = &sc->sc_ic;
1158 struct ieee80211_node *ni;
1159 enum ieee80211_state ostate;
1160 uint32_t reg;
1161 int s;
1162
1163 s = splnet();
1164 ostate = ic->ic_state;
1165 DPRINTF(("newstate %d -> %d\n", ostate, cmd->state));
1166
1167 if (ostate == IEEE80211_S_RUN) {
1168 /* Stop calibration. */
1169 timeout_del(&sc->calib_to);
1170
1171 /* Turn link LED off. */
1172 urtwn_set_led(sc, URTWN_LED_LINK, 0);
1173
1174 /* Set media status to 'No Link'. */
1175 reg = urtwn_read_4(sc, R92C_CR);
1176 reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_NOLINK);
1177 urtwn_write_4(sc, R92C_CR, reg);
1178
1179 /* Stop Rx of data frames. */
1180 urtwn_write_2(sc, R92C_RXFLTMAP2, 0);
1181
1182 /* Rest TSF. */
1183 urtwn_write_1(sc, R92C_DUAL_TSF_RST, 0x03);
1184
1185 /* Disable TSF synchronization. */
1186 urtwn_write_1(sc, R92C_BCN_CTRL,
1187 urtwn_read_1(sc, R92C_BCN_CTRL) |
1188 R92C_BCN_CTRL_DIS_TSF_UDT0);
1189
1190 /* Reset EDCA parameters. */
1191 urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002f3217);
1192 urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005e4317);
1193 urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x00105320);
1194 urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a444);
1195 }
1196 switch (cmd->state) {
1197 case IEEE80211_S_INIT:
1198 /* Turn link LED off. */
1199 urtwn_set_led(sc, URTWN_LED_LINK, 0);
1200 break;
1201 case IEEE80211_S_SCAN:
1202 if (ostate != IEEE80211_S_SCAN) {
1203 /* Allow Rx from any BSSID. */
1204 urtwn_write_4(sc, R92C_RCR,
1205 urtwn_read_4(sc, R92C_RCR) &
1206 ~(R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN));
1207
1208 /* Set gain for scanning. */
1209 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
1210 reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
1211 urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
1212
1213 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
1214 reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x20);
1215 urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
1216 }
1217
1218 /* Make link LED blink during scan. */
1219 urtwn_set_led(sc, URTWN_LED_LINK, !sc->ledlink);
1220
1221 /* Pause AC Tx queues. */
1222 urtwn_write_1(sc, R92C_TXPAUSE,
1223 urtwn_read_1(sc, R92C_TXPAUSE) | 0x0f);
1224
1225 urtwn_set_chan(sc, ic->ic_bss->ni_chan, NULL);
1226 if (!usbd_is_dying(sc->sc_udev))
1227 timeout_add_msec(&sc->scan_to, 200);
1228 break;
1229
1230 case IEEE80211_S_AUTH:
1231 /* Set initial gain under link. */
1232 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(0));
1233 reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
1234 urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(0), reg);
1235
1236 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCCORE1(1));
1237 reg = RW(reg, R92C_OFDM0_AGCCORE1_GAIN, 0x32);
1238 urtwn_bb_write(sc, R92C_OFDM0_AGCCORE1(1), reg);
1239
1240 urtwn_set_chan(sc, ic->ic_bss->ni_chan, NULL);
1241 break;
1242 case IEEE80211_S_ASSOC:
1243 break;
1244 case IEEE80211_S_RUN:
1245 if (ic->ic_opmode == IEEE80211_M_MONITOR) {
1246 urtwn_set_chan(sc, ic->ic_ibss_chan, NULL);
1247
1248 /* Enable Rx of data frames. */
1249 urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
1250
1251 /* Turn link LED on. */
1252 urtwn_set_led(sc, URTWN_LED_LINK, 1);
1253 break;
1254 }
1255 ni = ic->ic_bss;
1256
1257 /* Set media status to 'Associated'. */
1258 reg = urtwn_read_4(sc, R92C_CR);
1259 reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA);
1260 urtwn_write_4(sc, R92C_CR, reg);
1261
1262 /* Set BSSID. */
1263 urtwn_write_4(sc, R92C_BSSID + 0, LE_READ_4(&ni->ni_bssid[0]));
1264 urtwn_write_4(sc, R92C_BSSID + 4, LE_READ_2(&ni->ni_bssid[4]));
1265
1266 if (ic->ic_curmode == IEEE80211_MODE_11B)
1267 urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 0);
1268 else /* 802.11b/g */
1269 urtwn_write_1(sc, R92C_INIRTS_RATE_SEL, 3);
1270
1271 /* Enable Rx of data frames. */
1272 urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
1273
1274 /* Flush all AC queues. */
1275 urtwn_write_1(sc, R92C_TXPAUSE, 0);
1276
1277 /* Set beacon interval. */
1278 urtwn_write_2(sc, R92C_BCN_INTERVAL, ni->ni_intval);
1279
1280 /* Allow Rx from our BSSID only. */
1281 urtwn_write_4(sc, R92C_RCR,
1282 urtwn_read_4(sc, R92C_RCR) |
1283 R92C_RCR_CBSSID_DATA | R92C_RCR_CBSSID_BCN);
1284
1285 /* Enable TSF synchronization. */
1286 urtwn_tsf_sync_enable(sc);
1287
1288 urtwn_write_1(sc, R92C_SIFS_CCK + 1, 10);
1289 urtwn_write_1(sc, R92C_SIFS_OFDM + 1, 10);
1290 urtwn_write_1(sc, R92C_SPEC_SIFS + 1, 10);
1291 urtwn_write_1(sc, R92C_MAC_SPEC_SIFS + 1, 10);
1292 urtwn_write_1(sc, R92C_R2T_SIFS + 1, 10);
1293 urtwn_write_1(sc, R92C_T2T_SIFS + 1, 10);
1294
1295 /* Intialize rate adaptation. */
1296 urtwn_ra_init(sc);
1297 /* Turn link LED on. */
1298 urtwn_set_led(sc, URTWN_LED_LINK, 1);
1299
1300 sc->avg_pwdb = -1; /* Reset average RSSI. */
1301 /* Reset temperature calibration state machine. */
1302 sc->thcal_state = 0;
1303 sc->thcal_lctemp = 0;
1304 /* Start periodic calibration. */
1305 if (!usbd_is_dying(sc->sc_udev))
1306 timeout_add_sec(&sc->calib_to, 2);
1307 break;
1308 }
1309 (void)sc->sc_newstate(ic, cmd->state, cmd->arg);
1310 splx(s);
1311}
1312
1313void
1314urtwn_updateedca(struct ieee80211com *ic)
1315{
1316 /* Do it in a process context. */
1317 urtwn_do_async(ic->ic_softc, urtwn_updateedca_cb, NULL, 0);
1318}
1319
1320/* ARGSUSED */
1321void
1322urtwn_updateedca_cb(struct urtwn_softc *sc, void *arg)
1323{
1324 const uint16_t aci2reg[EDCA_NUM_AC] = {
1325 R92C_EDCA_BE_PARAM,
1326 R92C_EDCA_BK_PARAM,
1327 R92C_EDCA_VI_PARAM,
1328 R92C_EDCA_VO_PARAM
1329 };
1330 struct ieee80211com *ic = &sc->sc_ic;
1331 struct ieee80211_edca_ac_params *ac;
1332 int s, aci, aifs, slottime;
1333
1334 s = splnet();
1335 slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
1336 for (aci = 0; aci < EDCA_NUM_AC; aci++) {
1337 ac = &ic->ic_edca_ac[aci];
1338 /* AIFS[AC] = AIFSN[AC] * aSlotTime + aSIFSTime. */
1339 aifs = ac->ac_aifsn * slottime + 10;
1340 urtwn_write_4(sc, aci2reg[aci],
1341 SM(R92C_EDCA_PARAM_TXOP, ac->ac_txoplimit) |
1342 SM(R92C_EDCA_PARAM_ECWMIN, ac->ac_ecwmin) |
1343 SM(R92C_EDCA_PARAM_ECWMAX, ac->ac_ecwmax) |
1344 SM(R92C_EDCA_PARAM_AIFS, aifs));
1345 }
1346 splx(s);
1347}
1348
1349int
1350urtwn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
1351 struct ieee80211_key *k)
1352{
1353 struct urtwn_softc *sc = ic->ic_softc;
1354 struct urtwn_cmd_key cmd;
1355
1356 /* Defer setting of WEP keys until interface is brought up. */
1357 if ((ic->ic_if.if_flags & (IFF_UP | IFF_RUNNING)) !=
1358 (IFF_UP | IFF_RUNNING))
1359 return (0);
1360
1361 /* Do it in a process context. */
1362 cmd.key = *k;
1363 cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
1364 urtwn_do_async(sc, urtwn_set_key_cb, &cmd, sizeof(cmd));
1365 return (0);
1366}
1367
1368void
1369urtwn_set_key_cb(struct urtwn_softc *sc, void *arg)
1370{
1371 static const uint8_t etherzeroaddr[6] = { 0 };
1372 struct ieee80211com *ic = &sc->sc_ic;
1373 struct urtwn_cmd_key *cmd = arg;
1374 struct ieee80211_key *k = &cmd->key;
1375 const uint8_t *macaddr;
1376 uint8_t keybuf[16], algo;
1377 int i, entry;
1378
1379 /* Map net80211 cipher to HW crypto algorithm. */
1380 switch (k->k_cipher) {
1381 case IEEE80211_CIPHER_WEP40:
1382 algo = R92C_CAM_ALGO_WEP40;
1383 break;
1384 case IEEE80211_CIPHER_WEP104:
1385 algo = R92C_CAM_ALGO_WEP104;
1386 break;
1387 case IEEE80211_CIPHER_TKIP:
1388 algo = R92C_CAM_ALGO_TKIP;
1389 break;
1390 case IEEE80211_CIPHER_CCMP:
1391 algo = R92C_CAM_ALGO_AES;
1392 break;
1393 default:
1394 return;
1395 }
1396 if (k->k_flags & IEEE80211_KEY_GROUP) {
1397 macaddr = etherzeroaddr;
1398 entry = k->k_id;
1399 } else {
1400 macaddr = ic->ic_bss->ni_macaddr;
1401 entry = 4;
1402 }
1403 /* Write key. */
1404 memset(keybuf, 0, sizeof(keybuf));
1405 memcpy(keybuf, k->k_key, MIN(k->k_len, sizeof(keybuf)));
1406 for (i = 0; i < 4; i++) {
1407 urtwn_cam_write(sc, R92C_CAM_KEY(entry, i),
1408 LE_READ_4(&keybuf[i * 4]));
1409 }
1410 /* Write CTL0 last since that will validate the CAM entry. */
1411 urtwn_cam_write(sc, R92C_CAM_CTL1(entry),
1412 LE_READ_4(&macaddr[2]));
1413 urtwn_cam_write(sc, R92C_CAM_CTL0(entry),
1414 SM(R92C_CAM_ALGO, algo) |
1415 SM(R92C_CAM_KEYID, k->k_id) |
1416 SM(R92C_CAM_MACLO, LE_READ_2(&macaddr[0])) |
1417 R92C_CAM_VALID);
1418}
1419
1420void
1421urtwn_delete_key(struct ieee80211com *ic, struct ieee80211_node *ni,
1422 struct ieee80211_key *k)
1423{
1424 struct urtwn_softc *sc = ic->ic_softc;
1425 struct urtwn_cmd_key cmd;
1426
1427 if (!(ic->ic_if.if_flags & IFF_RUNNING) ||
1428 ic->ic_state != IEEE80211_S_RUN)
1429 return; /* Nothing to do. */
1430
1431 /* Do it in a process context. */
1432 cmd.key = *k;
1433 cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
1434 urtwn_do_async(sc, urtwn_delete_key_cb, &cmd, sizeof(cmd));
1435}
1436
1437void
1438urtwn_delete_key_cb(struct urtwn_softc *sc, void *arg)
1439{
1440 struct urtwn_cmd_key *cmd = arg;
1441 struct ieee80211_key *k = &cmd->key;
1442 int i, entry;
1443
1444 if (k->k_flags & IEEE80211_KEY_GROUP)
1445 entry = k->k_id;
1446 else
1447 entry = 4;
1448 urtwn_cam_write(sc, R92C_CAM_CTL0(entry), 0);
1449 urtwn_cam_write(sc, R92C_CAM_CTL1(entry), 0);
1450 /* Clear key. */
1451 for (i = 0; i < 4; i++)
1452 urtwn_cam_write(sc, R92C_CAM_KEY(entry, i), 0);
1453}
1454
1455void
1456urtwn_update_avgrssi(struct urtwn_softc *sc, int rate, int8_t rssi)
1457{
1458 int pwdb;
1459
1460 /* Convert antenna signal to percentage. */
1461 if (rssi <= -100 || rssi >= 20)
1462 pwdb = 0;
1463 else if (rssi >= 0)
1464 pwdb = 100;
1465 else
1466 pwdb = 100 + rssi;
1467 if (rate <= 3) {
1468 /* CCK gain is smaller than OFDM/MCS gain. */
1469 pwdb += 6;
1470 if (pwdb > 100)
1471 pwdb = 100;
1472 if (pwdb <= 14)
1473 pwdb -= 4;
1474 else if (pwdb <= 26)
1475 pwdb -= 8;
1476 else if (pwdb <= 34)
1477 pwdb -= 6;
1478 else if (pwdb <= 42)
1479 pwdb -= 2;
1480 }
1481 if (sc->avg_pwdb == -1) /* Init. */
1482 sc->avg_pwdb = pwdb;
1483 else if (sc->avg_pwdb < pwdb)
1484 sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20) + 1;
1485 else
1486 sc->avg_pwdb = ((sc->avg_pwdb * 19 + pwdb) / 20);
1487 DPRINTFN(4, ("PWDB=%d EMA=%d\n", pwdb, sc->avg_pwdb));
1488}
1489
1490int8_t
1491urtwn_get_rssi(struct urtwn_softc *sc, int rate, void *physt)
1492{
1493 static const int8_t cckoff[] = { 16, -12, -26, -46 };
1494 struct r92c_rx_phystat *phy;
1495 struct r92c_rx_cck *cck;
1496 uint8_t rpt;
1497 int8_t rssi;
1498
1499 if (rate <= 3) {
1500 cck = (struct r92c_rx_cck *)physt;
1501 if (sc->sc_flags & URTWN_FLAG_CCK_HIPWR) {
1502 rpt = (cck->agc_rpt >> 5) & 0x3;
1503 rssi = (cck->agc_rpt & 0x1f) << 1;
1504 } else {
1505 rpt = (cck->agc_rpt >> 6) & 0x3;
1506 rssi = cck->agc_rpt & 0x3e;
1507 }
1508 rssi = cckoff[rpt] - rssi;
1509 } else { /* OFDM/HT. */
1510 phy = (struct r92c_rx_phystat *)physt;
1511 rssi = ((letoh32(phy->phydw1) >> 1) & 0x7f) - 110;
1512 }
1513 return (rssi);
1514}
1515
1516void
1517urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen)
1518{
1519 struct ieee80211com *ic = &sc->sc_ic;
1520 struct ifnet *ifp = &ic->ic_if;
1521 struct ieee80211_rxinfo rxi;
1522 struct ieee80211_frame *wh;
1523 struct ieee80211_node *ni;
1524 struct r92c_rx_stat *stat;
1525 uint32_t rxdw0, rxdw3;
1526 struct mbuf *m;
1527 uint8_t rate;
1528 int8_t rssi = 0;
1529 int s, infosz;
1530
1531 stat = (struct r92c_rx_stat *)buf;
1532 rxdw0 = letoh32(stat->rxdw0);
1533 rxdw3 = letoh32(stat->rxdw3);
1534
1535 if (__predict_false(rxdw0 & (R92C_RXDW0_CRCERR | R92C_RXDW0_ICVERR))) {
1536 /*
1537 * This should not happen since we setup our Rx filter
1538 * to not receive these frames.
1539 */
1540 ifp->if_ierrors++;
1541 return;
1542 }
1543 if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) {
1544 ifp->if_ierrors++;
1545 return;
1546 }
1547
1548 rate = MS(rxdw3, R92C_RXDW3_RATE);
1549 infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
1550
1551 /* Get RSSI from PHY status descriptor if present. */
1552 if (infosz != 0 && (rxdw0 & R92C_RXDW0_PHYST)) {
1553 rssi = urtwn_get_rssi(sc, rate, &stat[1]);
1554 /* Update our average RSSI. */
1555 urtwn_update_avgrssi(sc, rate, rssi);
1556 }
1557
1558 DPRINTFN(5, ("Rx frame len=%d rate=%d infosz=%d rssi=%d\n",
1559 pktlen, rate, infosz, rssi));
1560
1561 MGETHDR(m, M_DONTWAIT, MT_DATA);
1562 if (__predict_false(m == NULL)) {
1563 ifp->if_ierrors++;
1564 return;
1565 }
1566 if (pktlen > MHLEN) {
1567 MCLGET(m, M_DONTWAIT);
1568 if (__predict_false(!(m->m_flags & M_EXT))) {
1569 ifp->if_ierrors++;
1570 m_freem(m);
1571 return;
1572 }
1573 }
1574 /* Finalize mbuf. */
1575 m->m_pkthdr.rcvif = ifp;
1576 wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz);
1577 memcpy(mtod(m, uint8_t *), wh, pktlen);
1578 m->m_pkthdr.len = m->m_len = pktlen;
1579
1580 s = splnet();
1581#if NBPFILTER > 0
1582 if (__predict_false(sc->sc_drvbpf != NULL)) {
1583 struct urtwn_rx_radiotap_header *tap = &sc->sc_rxtap;
1584 struct mbuf mb;
1585
1586 tap->wr_flags = 0;
1587 /* Map HW rate index to 802.11 rate. */
1588 tap->wr_flags = 2;
1589 if (!(rxdw3 & R92C_RXDW3_HT)) {
1590 switch (rate) {
1591 /* CCK. */
1592 case 0: tap->wr_rate = 2; break;
1593 case 1: tap->wr_rate = 4; break;
1594 case 2: tap->wr_rate = 11; break;
1595 case 3: tap->wr_rate = 22; break;
1596 /* OFDM. */
1597 case 4: tap->wr_rate = 12; break;
1598 case 5: tap->wr_rate = 18; break;
1599 case 6: tap->wr_rate = 24; break;
1600 case 7: tap->wr_rate = 36; break;
1601 case 8: tap->wr_rate = 48; break;
1602 case 9: tap->wr_rate = 72; break;
1603 case 10: tap->wr_rate = 96; break;
1604 case 11: tap->wr_rate = 108; break;
1605 }
1606 } else if (rate >= 12) { /* MCS0~15. */
1607 /* Bit 7 set means HT MCS instead of rate. */
1608 tap->wr_rate = 0x80 | (rate - 12);
1609 }
1610 tap->wr_dbm_antsignal = rssi;
1611 tap->wr_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
1612 tap->wr_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
1613
1614 mb.m_data = (caddr_t)tap;
1615 mb.m_len = sc->sc_rxtap_len;
1616 mb.m_next = m;
1617 mb.m_nextpkt = NULL;
1618 mb.m_type = 0;
1619 mb.m_flags = 0;
1620 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_IN);
1621 }
1622#endif
1623
1624 ni = ieee80211_find_rxnode(ic, wh);
1625 rxi.rxi_flags = 0;
1626 rxi.rxi_rssi = rssi;
1627 rxi.rxi_tstamp = 0; /* Unused. */
1628 ieee80211_input(ifp, m, ni, &rxi);
1629 /* Node is no longer needed. */
1630 ieee80211_release_node(ic, ni);
1631 splx(s);
1632}
1633
1634void
1635urtwn_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv,
1636 usbd_status status)
1637{
1638 struct urtwn_rx_data *data = priv;
1639 struct urtwn_softc *sc = data->sc;
1640 struct r92c_rx_stat *stat;
1641 uint32_t rxdw0;
1642 uint8_t *buf;
1643 int len, totlen, pktlen, infosz, npkts;
1644
1645 if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
1646 DPRINTF(("RX status=%d\n", status));
1647 if (status == USBD_STALLED)
1648 usbd_clear_endpoint_stall_async(sc->rx_pipe);
1649 if (status != USBD_CANCELLED)
1650 goto resubmit;
1651 return;
1652 }
1653 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1654
1655 if (__predict_false(len < sizeof(*stat))) {
1656 DPRINTF(("xfer too short %d\n", len));
1657 goto resubmit;
1658 }
1659 buf = data->buf;
1660
1661 /* Get the number of encapsulated frames. */
1662 stat = (struct r92c_rx_stat *)buf;
1663 npkts = MS(letoh32(stat->rxdw2), R92C_RXDW2_PKTCNT);
1664 DPRINTFN(6, ("Rx %d frames in one chunk\n", npkts));
1665
1666 /* Process all of them. */
1667 while (npkts-- > 0) {
1668 if (__predict_false(len < sizeof(*stat)))
1669 break;
1670 stat = (struct r92c_rx_stat *)buf;
1671 rxdw0 = letoh32(stat->rxdw0);
1672
1673 pktlen = MS(rxdw0, R92C_RXDW0_PKTLEN);
1674 if (__predict_false(pktlen == 0))
1675 break;
1676
1677 infosz = MS(rxdw0, R92C_RXDW0_INFOSZ) * 8;
1678
1679 /* Make sure everything fits in xfer. */
1680 totlen = sizeof(*stat) + infosz + pktlen;
1681 if (__predict_false(totlen > len))
1682 break;
1683
1684 /* Process 802.11 frame. */
1685 urtwn_rx_frame(sc, buf, pktlen);
1686
1687 /* Next chunk is 128-byte aligned. */
1688 totlen = (totlen + 127) & ~127;
1689 buf += totlen;
1690 len -= totlen;
1691 }
1692
1693 resubmit:
1694 /* Setup a new transfer. */
1695 usbd_setup_xfer(xfer, sc->rx_pipe, data, data->buf, URTWN_RXBUFSZ,
1696 USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, urtwn_rxeof);
1697 (void)usbd_transfer(xfer);
1698}
1699
1700void
1701urtwn_txeof(usbd_xfer_handle xfer, usbd_private_handle priv,
1702 usbd_status status)
1703{
1704 struct urtwn_tx_data *data = priv;
1705 struct urtwn_softc *sc = data->sc;
1706 struct ifnet *ifp = &sc->sc_ic.ic_if;
1707 int s;
1708
1709 s = splnet();
1710 /* Put this Tx buffer back to our free list. */
1711 TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next);
1712
1713 if (__predict_false(status != USBD_NORMAL_COMPLETION)) {
1714 DPRINTF(("TX status=%d\n", status));
1715 if (status == USBD_STALLED)
1716 usbd_clear_endpoint_stall_async(data->pipe);
1717 ifp->if_oerrors++;
1718 splx(s);
1719 return;
1720 }
1721 sc->sc_tx_timer = 0;
1722 ifp->if_opackets++;
1723
1724 /* We just released a Tx buffer, notify Tx. */
1725 if (ifp->if_flags & IFF_OACTIVE) {
1726 ifp->if_flags &= ~IFF_OACTIVE;
1727 urtwn_start(ifp);
1728 }
1729 splx(s);
1730}
1731
1732int
1733urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
1734{
1735 struct ieee80211com *ic = &sc->sc_ic;
1736 struct ieee80211_frame *wh;
1737 struct ieee80211_key *k = NULL;
1738 struct urtwn_tx_data *data;
1739 struct r92c_tx_desc *txd;
1740 usbd_pipe_handle pipe;
1741 uint16_t qos, sum;
1742 uint8_t raid, type, tid, qid;
1743 int i, hasqos, xferlen, error;
1744
1745 wh = mtod(m, struct ieee80211_frame *);
1746 type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
1747
1748 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
1749 k = ieee80211_get_txkey(ic, wh, ni);
1750 if ((m = ieee80211_encrypt(ic, m, k)) == NULL)
1751 return (ENOBUFS);
1752 wh = mtod(m, struct ieee80211_frame *);
1753 }
1754
1755 if ((hasqos = ieee80211_has_qos(wh))) {
1756 qos = ieee80211_get_qos(wh);
1757 tid = qos & IEEE80211_QOS_TID;
1758 qid = ieee80211_up_to_ac(ic, tid);
1759 } else if (type != IEEE80211_FC0_TYPE_DATA) {
1760 /* Use AC VO for management frames. */
1761 qid = EDCA_AC_VO;
1762 } else
1763 qid = EDCA_AC_BE;
1764
1765 /* Get the USB pipe to use for this AC. */
1766 pipe = sc->tx_pipe[sc->ac2idx[qid]];
1767
1768 /* Grab a Tx buffer from our free list. */
1769 data = TAILQ_FIRST(&sc->tx_free_list);
1770 TAILQ_REMOVE(&sc->tx_free_list, data, next);
1771
1772 /* Fill Tx descriptor. */
1773 txd = (struct r92c_tx_desc *)data->buf;
1774 memset(txd, 0, sizeof(*txd));
1775
1776 txd->txdw0 |= htole32(
1777 SM(R92C_TXDW0_PKTLEN, m->m_pkthdr.len) |
1778 SM(R92C_TXDW0_OFFSET, sizeof(*txd)) |
1779 R92C_TXDW0_OWN | R92C_TXDW0_FSG | R92C_TXDW0_LSG);
1780 if (IEEE80211_IS_MULTICAST(wh->i_addr1))
1781 txd->txdw0 |= htole32(R92C_TXDW0_BMCAST);
1782
1783#ifdef notyet
1784 if (k != NULL) {
1785 switch (k->k_cipher) {
1786 case IEEE80211_CIPHER_WEP40:
1787 case IEEE80211_CIPHER_WEP104:
1788 case IEEE80211_CIPHER_TKIP:
1789 cipher = R92C_TXDW1_CIPHER_RC4;
1790 break;
1791 case IEEE80211_CIPHER_CCMP:
1792 cipher = R92C_TXDW1_CIPHER_AES;
1793 break;
1794 default:
1795 cipher = R92C_TXDW1_CIPHER_NONE;
1796 }
1797 txd->txdw1 |= htole32(SM(R92C_TXDW1_CIPHER, cipher));
1798 }
1799#endif
1800 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
1801 type == IEEE80211_FC0_TYPE_DATA) {
1802 if (ic->ic_curmode == IEEE80211_MODE_11B)
1803 raid = R92C_RAID_11B;
1804 else
1805 raid = R92C_RAID_11BG;
1806 txd->txdw1 |= htole32(
1807 SM(R92C_TXDW1_MACID, URTWN_MACID_BSS) |
1808 SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_BE) |
1809 SM(R92C_TXDW1_RAID, raid) |
1810 R92C_TXDW1_AGGBK);
1811
1812 if (ic->ic_flags & IEEE80211_F_USEPROT) {
1813 if (ic->ic_protmode == IEEE80211_PROT_CTSONLY) {
1814 txd->txdw4 |= htole32(R92C_TXDW4_CTS2SELF |
1815 R92C_TXDW4_HWRTSEN);
1816 } else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS) {
1817 txd->txdw4 |= htole32(R92C_TXDW4_RTSEN |
1818 R92C_TXDW4_HWRTSEN);
1819 }
1820 }
1821 /* Send RTS at OFDM24. */
1822 txd->txdw4 |= htole32(SM(R92C_TXDW4_RTSRATE, 8));
1823 txd->txdw5 |= htole32(0x0001ff00);
1824 /* Send data at OFDM54. */
1825 txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 11));
1826
1827 } else {
1828 txd->txdw1 |= htole32(
1829 SM(R92C_TXDW1_MACID, 0) |
1830 SM(R92C_TXDW1_QSEL, R92C_TXDW1_QSEL_MGNT) |
1831 SM(R92C_TXDW1_RAID, R92C_RAID_11B));
1832
1833 /* Force CCK1. */
1834 txd->txdw4 |= htole32(R92C_TXDW4_DRVRATE);
1835 txd->txdw5 |= htole32(SM(R92C_TXDW5_DATARATE, 0));
1836 }
1837 /* Set sequence number (already little endian). */
1838 txd->txdseq |= *(uint16_t *)wh->i_seq;
1839
1840 if (!hasqos) {
1841 /* Use HW sequence numbering for non-QoS frames. */
1842 txd->txdw4 |= htole32(R92C_TXDW4_HWSEQ);
1843 txd->txdseq |= htole16(0x8000); /* WTF? */
1844 } else
1845 txd->txdw4 |= htole32(R92C_TXDW4_QOS);
1846
1847 /* Compute Tx descriptor checksum. */
1848 sum = 0;
1849 for (i = 0; i < sizeof(*txd) / 2; i++)
1850 sum ^= ((uint16_t *)txd)[i];
1851 txd->txdsum = sum; /* NB: already little endian. */
1852
1853#if NBPFILTER > 0
1854 if (__predict_false(sc->sc_drvbpf != NULL)) {
1855 struct urtwn_tx_radiotap_header *tap = &sc->sc_txtap;
1856 struct mbuf mb;
1857
1858 tap->wt_flags = 0;
1859 tap->wt_chan_freq = htole16(ic->ic_bss->ni_chan->ic_freq);
1860 tap->wt_chan_flags = htole16(ic->ic_bss->ni_chan->ic_flags);
1861
1862 mb.m_data = (caddr_t)tap;
1863 mb.m_len = sc->sc_txtap_len;
1864 mb.m_next = m;
1865 mb.m_nextpkt = NULL;
1866 mb.m_type = 0;
1867 mb.m_flags = 0;
1868 bpf_mtap(sc->sc_drvbpf, &mb, BPF_DIRECTION_OUT);
1869 }
1870#endif
1871
1872 xferlen = sizeof(*txd) + m->m_pkthdr.len;
1873 m_copydata(m, 0, m->m_pkthdr.len, (caddr_t)&txd[1]);
1874 m_freem(m);
1875
1876 data->pipe = pipe;
1877 usbd_setup_xfer(data->xfer, pipe, data, data->buf, xferlen,
1878 USBD_FORCE_SHORT_XFER | USBD_NO_COPY, URTWN_TX_TIMEOUT,
1879 urtwn_txeof);
1880 error = usbd_transfer(data->xfer);
1881 if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) {
1882 /* Put this Tx buffer back to our free list. */
1883 TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next);
1884 return (error);
1885 }
1886 ieee80211_release_node(ic, ni);
1887 return (0);
1888}
1889
1890void
1891urtwn_start(struct ifnet *ifp)
1892{
1893 struct urtwn_softc *sc = ifp->if_softc;
1894 struct ieee80211com *ic = &sc->sc_ic;
1895 struct ieee80211_node *ni;
1896 struct mbuf *m;
1897
1898 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
1899 return;
1900
1901 for (;;) {
1902 if (TAILQ_EMPTY(&sc->tx_free_list)) {
1903 ifp->if_flags |= IFF_OACTIVE;
1904 break;
1905 }
1906 /* Send pending management frames first. */
1907 IF_DEQUEUE(&ic->ic_mgtq, m);
1908 if (m != NULL) {
1909 ni = (void *)m->m_pkthdr.rcvif;
1910 goto sendit;
1911 }
1912 if (ic->ic_state != IEEE80211_S_RUN)
1913 break;
1914
1915 /* Encapsulate and send data frames. */
1916 IFQ_DEQUEUE(&ifp->if_snd, m);
1917 if (m == NULL)
1918 break;
1919#if NBPFILTER > 0
1920 if (ifp->if_bpf != NULL)
1921 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1922#endif
1923 if ((m = ieee80211_encap(ifp, m, &ni)) == NULL)
1924 continue;
1925sendit:
1926#if NBPFILTER > 0
1927 if (ic->ic_rawbpf != NULL)
1928 bpf_mtap(ic->ic_rawbpf, m, BPF_DIRECTION_OUT);
1929#endif
1930 if (urtwn_tx(sc, m, ni) != 0) {
1931 ieee80211_release_node(ic, ni);
1932 ifp->if_oerrors++;
1933 continue;
1934 }
1935
1936 sc->sc_tx_timer = 5;
1937 ifp->if_timer = 1;
1938 }
1939}
1940
1941void
1942urtwn_watchdog(struct ifnet *ifp)
1943{
1944 struct urtwn_softc *sc = ifp->if_softc;
1945
1946 ifp->if_timer = 0;
1947
1948 if (sc->sc_tx_timer > 0) {
1949 if (--sc->sc_tx_timer == 0) {
1950 printf("%s: device timeout\n", sc->sc_dev.dv_xname);
1951 /* urtwn_init(ifp); XXX needs a process context! */
1952 ifp->if_oerrors++;
1953 return;
1954 }
1955 ifp->if_timer = 1;
1956 }
1957 ieee80211_watchdog(ifp);
1958}
1959
1960int
1961urtwn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
1962{
1963 struct urtwn_softc *sc = ifp->if_softc;
1964 struct ieee80211com *ic = &sc->sc_ic;
1965 struct ifaddr *ifa;
1966 struct ifreq *ifr;
1967 int s, error = 0;
1968
1969 if (usbd_is_dying(sc->sc_udev))
1970 return ENXIO;
1971
1972 usbd_ref_incr(sc->sc_udev);
1973
1974 s = splnet();
1975
1976 switch (cmd) {
1977 case SIOCSIFADDR:
1978 ifa = (struct ifaddr *)data;
1979 ifp->if_flags |= IFF_UP;
1980#ifdef INET
1981 if (ifa->ifa_addr->sa_family == AF_INET)
1982 arp_ifinit(&ic->ic_ac, ifa);
1983#endif
1984 /* FALLTHROUGH */
1985 case SIOCSIFFLAGS:
1986 if (ifp->if_flags & IFF_UP) {
1987 if (!(ifp->if_flags & IFF_RUNNING))
1988 urtwn_init(ifp);
1989 } else {
1990 if (ifp->if_flags & IFF_RUNNING)
1991 urtwn_stop(ifp);
1992 }
1993 break;
1994 case SIOCADDMULTI:
1995 case SIOCDELMULTI:
1996 ifr = (struct ifreq *)data;
1997 error = (cmd == SIOCADDMULTI) ?
1998 ether_addmulti(ifr, &ic->ic_ac) :
1999 ether_delmulti(ifr, &ic->ic_ac);
2000 if (error == ENETRESET)
2001 error = 0;
2002 break;
2003 case SIOCS80211CHANNEL:
2004 error = ieee80211_ioctl(ifp, cmd, data);
2005 if (error == ENETRESET &&
2006 ic->ic_opmode == IEEE80211_M_MONITOR) {
2007 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
2008 (IFF_UP | IFF_RUNNING))
2009 urtwn_set_chan(sc, ic->ic_ibss_chan, NULL);
2010 error = 0;
2011 }
2012 break;
2013 default:
2014 error = ieee80211_ioctl(ifp, cmd, data);
2015 }
2016
2017 if (error == ENETRESET) {
2018 if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
2019 (IFF_UP | IFF_RUNNING)) {
2020 urtwn_stop(ifp);
2021 urtwn_init(ifp);
2022 }
2023 error = 0;
2024 }
2025 splx(s);
2026
2027 usbd_ref_decr(sc->sc_udev);
2028
2029 return (error);
2030}
2031
2032int
2033urtwn_power_on(struct urtwn_softc *sc)
2034{
2035 uint32_t reg;
2036 int ntries;
2037
2038 /* Wait for autoload done bit. */
2039 for (ntries = 0; ntries < 1000; ntries++) {
2040 if (urtwn_read_1(sc, R92C_APS_FSMCO) & R92C_APS_FSMCO_PFM_ALDN)
2041 break;
2042 DELAY(5);
2043 }
2044 if (ntries == 1000) {
2045 printf("%s: timeout waiting for chip autoload\n",
2046 sc->sc_dev.dv_xname);
2047 return (ETIMEDOUT);
2048 }
2049
2050 /* Unlock ISO/CLK/Power control register. */
2051 urtwn_write_1(sc, R92C_RSV_CTRL, 0);
2052 /* Move SPS into PWM mode. */
2053 urtwn_write_1(sc, R92C_SPS0_CTRL, 0x2b);
2054 DELAY(100);
2055
2056 reg = urtwn_read_1(sc, R92C_LDOV12D_CTRL);
2057 if (!(reg & R92C_LDOV12D_CTRL_LDV12_EN)) {
2058 urtwn_write_1(sc, R92C_LDOV12D_CTRL,
2059 reg | R92C_LDOV12D_CTRL_LDV12_EN);
2060 DELAY(100);
2061 urtwn_write_1(sc, R92C_SYS_ISO_CTRL,
2062 urtwn_read_1(sc, R92C_SYS_ISO_CTRL) &
2063 ~R92C_SYS_ISO_CTRL_MD2PP);
2064 }
2065
2066 /* Auto enable WLAN. */
2067 urtwn_write_2(sc, R92C_APS_FSMCO,
2068 urtwn_read_2(sc, R92C_APS_FSMCO) | R92C_APS_FSMCO_APFM_ONMAC);
2069 for (ntries = 0; ntries < 1000; ntries++) {
2070 if (urtwn_read_2(sc, R92C_APS_FSMCO) &
2071 R92C_APS_FSMCO_APFM_ONMAC)
2072 break;
2073 DELAY(5);
2074 }
2075 if (ntries == 1000) {
2076 printf("%s: timeout waiting for MAC auto ON\n",
2077 sc->sc_dev.dv_xname);
2078 return (ETIMEDOUT);
2079 }
2080
2081 /* Enable radio, GPIO and LED functions. */
2082 urtwn_write_2(sc, R92C_APS_FSMCO,
2083 R92C_APS_FSMCO_AFSM_HSUS |
2084 R92C_APS_FSMCO_PDN_EN |
2085 R92C_APS_FSMCO_PFM_ALDN);
2086 /* Release RF digital isolation. */
2087 urtwn_write_2(sc, R92C_SYS_ISO_CTRL,
2088 urtwn_read_2(sc, R92C_SYS_ISO_CTRL) & ~R92C_SYS_ISO_CTRL_DIOR);
2089
2090 /* Initialize MAC. */
2091 urtwn_write_1(sc, R92C_APSD_CTRL,
2092 urtwn_read_1(sc, R92C_APSD_CTRL) & ~R92C_APSD_CTRL_OFF);
2093 for (ntries = 0; ntries < 200; ntries++) {
2094 if (!(urtwn_read_1(sc, R92C_APSD_CTRL) &
2095 R92C_APSD_CTRL_OFF_STATUS))
2096 break;
2097 DELAY(5);
2098 }
2099 if (ntries == 200) {
2100 printf("%s: timeout waiting for MAC initialization\n",
2101 sc->sc_dev.dv_xname);
2102 return (ETIMEDOUT);
2103 }
2104
2105 /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */
2106 reg = urtwn_read_2(sc, R92C_CR);
2107 reg |= R92C_CR_HCI_TXDMA_EN | R92C_CR_HCI_RXDMA_EN |
2108 R92C_CR_TXDMA_EN | R92C_CR_RXDMA_EN | R92C_CR_PROTOCOL_EN |
2109 R92C_CR_SCHEDULE_EN | R92C_CR_MACTXEN | R92C_CR_MACRXEN |
2110 R92C_CR_ENSEC;
2111 urtwn_write_2(sc, R92C_CR, reg);
2112
2113 urtwn_write_1(sc, 0xfe10, 0x19);
2114 return (0);
2115}
2116
2117int
2118urtwn_llt_init(struct urtwn_softc *sc)
2119{
2120 int i, error;
2121
2122 /* Reserve pages [0; R92C_TX_PAGE_COUNT]. */
2123 for (i = 0; i < R92C_TX_PAGE_COUNT; i++) {
2124 if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
2125 return (error);
2126 }
2127 /* NB: 0xff indicates end-of-list. */
2128 if ((error = urtwn_llt_write(sc, i, 0xff)) != 0)
2129 return (error);
2130 /*
2131 * Use pages [R92C_TX_PAGE_COUNT + 1; R92C_TXPKTBUF_COUNT - 1]
2132 * as ring buffer.
2133 */
2134 for (++i; i < R92C_TXPKTBUF_COUNT - 1; i++) {
2135 if ((error = urtwn_llt_write(sc, i, i + 1)) != 0)
2136 return (error);
2137 }
2138 /* Make the last page point to the beginning of the ring buffer. */
2139 error = urtwn_llt_write(sc, i, R92C_TX_PAGE_COUNT + 1);
2140 return (error);
2141}
2142
2143void
2144urtwn_fw_reset(struct urtwn_softc *sc)
2145{
2146 uint16_t reg;
2147 int ntries;
2148
2149 /* Tell 8051 to reset itself. */
2150 urtwn_write_1(sc, R92C_HMETFR + 3, 0x20);
2151
2152 /* Wait until 8051 resets by itself. */
2153 for (ntries = 0; ntries < 100; ntries++) {
2154 reg = urtwn_read_2(sc, R92C_SYS_FUNC_EN);
2155 if (!(reg & R92C_SYS_FUNC_EN_CPUEN))
2156 return;
2157 DELAY(50);
2158 }
2159 /* Force 8051 reset. */
2160 urtwn_write_2(sc, R92C_SYS_FUNC_EN, reg & ~R92C_SYS_FUNC_EN_CPUEN);
2161}
2162
2163int
2164urtwn_fw_loadpage(struct urtwn_softc *sc, int page, uint8_t *buf, int len)
2165{
2166 uint32_t reg;
2167 int off, mlen, error = 0;
2168
2169 reg = urtwn_read_4(sc, R92C_MCUFWDL);
2170 reg = RW(reg, R92C_MCUFWDL_PAGE, page);
2171 urtwn_write_4(sc, R92C_MCUFWDL, reg);
2172
2173 off = R92C_FW_START_ADDR;
2174 while (len > 0) {
2175 if (len > 196)
2176 mlen = 196;
2177 else if (len > 4)
2178 mlen = 4;
2179 else
2180 mlen = 1;
2181 error = urtwn_write_region_1(sc, off, buf, mlen);
2182 if (error != 0)
2183 break;
2184 off += mlen;
2185 buf += mlen;
2186 len -= mlen;
2187 }
2188 return (error);
2189}
2190
2191int
2192urtwn_load_firmware(struct urtwn_softc *sc)
2193{
2194 const struct r92c_fw_hdr *hdr;
2195 const char *name;
2196 u_char *fw, *ptr;
2197 size_t len;
2198 uint32_t reg;
2199 int mlen, ntries, page, error;
2200
2201 /* Read firmware image from the filesystem. */
2202 if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
2203 URTWN_CHIP_UMC_A_CUT)
2204 name = "urtwn-rtl8192cfwU";
2205 else
2206 name = "urtwn-rtl8192cfwT";
2207 if ((error = loadfirmware(name, &fw, &len)) != 0) {
2208 printf("%s: failed loadfirmware of file %s (error %d)\n",
2209 sc->sc_dev.dv_xname, name, error);
2210 return (error);
2211 }
2212 if (len < sizeof(*hdr)) {
2213 printf("%s: firmware too short\n", sc->sc_dev.dv_xname);
2214 error = EINVAL;
2215 goto fail;
2216 }
2217 ptr = fw;
2218 hdr = (const struct r92c_fw_hdr *)ptr;
2219 /* Check if there is a valid FW header and skip it. */
2220 if ((letoh16(hdr->signature) >> 4) == 0x88c ||
2221 (letoh16(hdr->signature) >> 4) == 0x92c) {
2222 DPRINTF(("FW V%d.%d %02d-%02d %02d:%02d\n",
2223 letoh16(hdr->version), letoh16(hdr->subversion),
2224 hdr->month, hdr->date, hdr->hour, hdr->minute));
2225 ptr += sizeof(*hdr);
2226 len -= sizeof(*hdr);
2227 }
2228
2229 if (urtwn_read_1(sc, R92C_MCUFWDL) & 0x80) {
2230 urtwn_fw_reset(sc);
2231 urtwn_write_1(sc, R92C_MCUFWDL, 0);
2232 }
2233 urtwn_write_2(sc, R92C_SYS_FUNC_EN,
2234 urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
2235 R92C_SYS_FUNC_EN_CPUEN);
2236 urtwn_write_1(sc, R92C_MCUFWDL,
2237 urtwn_read_1(sc, R92C_MCUFWDL) | R92C_MCUFWDL_EN);
2238 urtwn_write_1(sc, R92C_MCUFWDL + 2,
2239 urtwn_read_1(sc, R92C_MCUFWDL + 2) & ~0x08);
2240
2241 for (page = 0; len > 0; page++) {
2242 mlen = MIN(len, R92C_FW_PAGE_SIZE);
2243 error = urtwn_fw_loadpage(sc, page, ptr, mlen);
2244 if (error != 0) {
2245 printf("%s: could not load firmware page %d\n",
2246 sc->sc_dev.dv_xname, page);
2247 goto fail;
2248 }
2249 ptr += mlen;
2250 len -= mlen;
2251 }
2252 urtwn_write_1(sc, R92C_MCUFWDL,
2253 urtwn_read_1(sc, R92C_MCUFWDL) & ~R92C_MCUFWDL_EN);
2254 urtwn_write_1(sc, R92C_MCUFWDL + 1, 0);
2255
2256 /* Wait for checksum report. */
2257 for (ntries = 0; ntries < 1000; ntries++) {
2258 if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_CHKSUM_RPT)
2259 break;
2260 DELAY(5);
2261 }
2262 if (ntries == 1000) {
2263 printf("%s: timeout waiting for checksum report\n",
2264 sc->sc_dev.dv_xname);
2265 error = ETIMEDOUT;
2266 goto fail;
2267 }
2268
2269 reg = urtwn_read_4(sc, R92C_MCUFWDL);
2270 reg = (reg & ~R92C_MCUFWDL_WINTINI_RDY) | R92C_MCUFWDL_RDY;
2271 urtwn_write_4(sc, R92C_MCUFWDL, reg);
2272 /* Wait for firmware readiness. */
2273 for (ntries = 0; ntries < 1000; ntries++) {
2274 if (urtwn_read_4(sc, R92C_MCUFWDL) & R92C_MCUFWDL_WINTINI_RDY)
2275 break;
2276 DELAY(5);
2277 }
2278 if (ntries == 1000) {
2279 printf("%s: timeout waiting for firmware readiness\n",
2280 sc->sc_dev.dv_xname);
2281 error = ETIMEDOUT;
2282 goto fail;
2283 }
2284 fail:
2285 free(fw, M_DEVBUF);
2286 return (error);
2287}
2288
2289int
2290urtwn_dma_init(struct urtwn_softc *sc)
2291{
2292 int hashq, hasnq, haslq, nqueues, nqpages, nrempages;
2293 uint32_t reg;
2294 int error;
2295
2296 /* Initialize LLT table. */
2297 error = urtwn_llt_init(sc);
2298 if (error != 0)
2299 return (error);
2300
2301 /* Get Tx queues to USB endpoints mapping. */
2302 hashq = hasnq = haslq = 0;
2303 reg = urtwn_read_2(sc, R92C_USB_EP + 1);
2304 DPRINTFN(2, ("USB endpoints mapping 0x%x\n", reg));
2305 if (MS(reg, R92C_USB_EP_HQ) != 0)
2306 hashq = 1;
2307 if (MS(reg, R92C_USB_EP_NQ) != 0)
2308 hasnq = 1;
2309 if (MS(reg, R92C_USB_EP_LQ) != 0)
2310 haslq = 1;
2311 nqueues = hashq + hasnq + haslq;
2312 if (nqueues == 0)
2313 return (EIO);
2314 /* Get the number of pages for each queue. */
2315 nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues;
2316 /* The remaining pages are assigned to the high priority queue. */
2317 nrempages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) % nqueues;
2318
2319 /* Set number of pages for normal priority queue. */
2320 urtwn_write_1(sc, R92C_RQPN_NPQ, hasnq ? nqpages : 0);
2321 urtwn_write_4(sc, R92C_RQPN,
2322 /* Set number of pages for public queue. */
2323 SM(R92C_RQPN_PUBQ, R92C_PUBQ_NPAGES) |
2324 /* Set number of pages for high priority queue. */
2325 SM(R92C_RQPN_HPQ, hashq ? nqpages + nrempages : 0) |
2326 /* Set number of pages for low priority queue. */
2327 SM(R92C_RQPN_LPQ, haslq ? nqpages : 0) |
2328 /* Load values. */
2329 R92C_RQPN_LD);
2330
2331 urtwn_write_1(sc, R92C_TXPKTBUF_BCNQ_BDNY, R92C_TX_PAGE_BOUNDARY);
2332 urtwn_write_1(sc, R92C_TXPKTBUF_MGQ_BDNY, R92C_TX_PAGE_BOUNDARY);
2333 urtwn_write_1(sc, R92C_TXPKTBUF_WMAC_LBK_BF_HD, R92C_TX_PAGE_BOUNDARY);
2334 urtwn_write_1(sc, R92C_TRXFF_BNDY, R92C_TX_PAGE_BOUNDARY);
2335 urtwn_write_1(sc, R92C_TDECTRL + 1, R92C_TX_PAGE_BOUNDARY);
2336
2337 /* Set queue to USB pipe mapping. */
2338 reg = urtwn_read_2(sc, R92C_TRXDMA_CTRL);
2339 reg &= ~R92C_TRXDMA_CTRL_QMAP_M;
2340 if (nqueues == 1) {
2341 if (hashq)
2342 reg |= R92C_TRXDMA_CTRL_QMAP_HQ;
2343 else if (hasnq)
2344 reg |= R92C_TRXDMA_CTRL_QMAP_NQ;
2345 else
2346 reg |= R92C_TRXDMA_CTRL_QMAP_LQ;
2347 } else if (nqueues == 2) {
2348 /* All 2-endpoints configs have a high priority queue. */
2349 if (!hashq)
2350 return (EIO);
2351 if (hasnq)
2352 reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ;
2353 else
2354 reg |= R92C_TRXDMA_CTRL_QMAP_HQ_LQ;
2355 } else
2356 reg |= R92C_TRXDMA_CTRL_QMAP_3EP;
2357 urtwn_write_2(sc, R92C_TRXDMA_CTRL, reg);
2358
2359 /* Set Tx/Rx transfer page boundary. */
2360 urtwn_write_2(sc, R92C_TRXFF_BNDY + 2, 0x27ff);
2361
2362 /* Set Tx/Rx transfer page size. */
2363 urtwn_write_1(sc, R92C_PBP,
2364 SM(R92C_PBP_PSRX, R92C_PBP_128) |
2365 SM(R92C_PBP_PSTX, R92C_PBP_128));
2366 return (0);
2367}
2368
2369void
2370urtwn_mac_init(struct urtwn_softc *sc)
2371{
2372 int i;
2373
2374 /* Write MAC initialization values. */
2375 for (i = 0; i < nitems(rtl8192cu_mac); i++)
2376 urtwn_write_1(sc, rtl8192cu_mac[i].reg, rtl8192cu_mac[i].val);
2377}
2378
2379void
2380urtwn_bb_init(struct urtwn_softc *sc)
2381{
2382 const struct urtwn_bb_prog *prog;
2383 uint32_t reg;
2384 int i;
2385
2386 /* Enable BB and RF. */
2387 urtwn_write_2(sc, R92C_SYS_FUNC_EN,
2388 urtwn_read_2(sc, R92C_SYS_FUNC_EN) |
2389 R92C_SYS_FUNC_EN_BBRSTB | R92C_SYS_FUNC_EN_BB_GLB_RST |
2390 R92C_SYS_FUNC_EN_DIO_RF);
2391
2392 urtwn_write_2(sc, R92C_AFE_PLL_CTRL, 0xdb83);
2393
2394 urtwn_write_1(sc, R92C_RF_CTRL,
2395 R92C_RF_CTRL_EN | R92C_RF_CTRL_RSTB | R92C_RF_CTRL_SDMRSTB);
2396 urtwn_write_1(sc, R92C_SYS_FUNC_EN,
2397 R92C_SYS_FUNC_EN_USBA | R92C_SYS_FUNC_EN_USBD |
2398 R92C_SYS_FUNC_EN_BB_GLB_RST | R92C_SYS_FUNC_EN_BBRSTB);
2399
2400 urtwn_write_1(sc, R92C_LDOHCI12_CTRL, 0x0f);
2401 urtwn_write_1(sc, 0x15, 0xe9);
2402 urtwn_write_1(sc, R92C_AFE_XTAL_CTRL + 1, 0x80);
2403
2404 /* Select BB programming based on board type. */
2405 if (!(sc->chip & URTWN_CHIP_92C)) {
2406 if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
2407 prog = &rtl8188ce_bb_prog;
2408 else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
2409 prog = &rtl8188ru_bb_prog;
2410 else
2411 prog = &rtl8188cu_bb_prog;
2412 } else {
2413 if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
2414 prog = &rtl8192ce_bb_prog;
2415 else
2416 prog = &rtl8192cu_bb_prog;
2417 }
2418 /* Write BB initialization values. */
2419 for (i = 0; i < prog->count; i++) {
2420 urtwn_bb_write(sc, prog->regs[i], prog->vals[i]);
2421 DELAY(1);
2422 }
2423
2424 if (sc->chip & URTWN_CHIP_92C_1T2R) {
2425 /* 8192C 1T only configuration. */
2426 reg = urtwn_bb_read(sc, R92C_FPGA0_TXINFO);
2427 reg = (reg & ~0x00000003) | 0x2;
2428 urtwn_bb_write(sc, R92C_FPGA0_TXINFO, reg);
2429
2430 reg = urtwn_bb_read(sc, R92C_FPGA1_TXINFO);
2431 reg = (reg & ~0x00300033) | 0x00200022;
2432 urtwn_bb_write(sc, R92C_FPGA1_TXINFO, reg);
2433
2434 reg = urtwn_bb_read(sc, R92C_CCK0_AFESETTING);
2435 reg = (reg & ~0xff000000) | 0x45 << 24;
2436 urtwn_bb_write(sc, R92C_CCK0_AFESETTING, reg);
2437
2438 reg = urtwn_bb_read(sc, R92C_OFDM0_TRXPATHENA);
2439 reg = (reg & ~0x000000ff) | 0x23;
2440 urtwn_bb_write(sc, R92C_OFDM0_TRXPATHENA, reg);
2441
2442 reg = urtwn_bb_read(sc, R92C_OFDM0_AGCPARAM1);
2443 reg = (reg & ~0x00000030) | 1 << 4;
2444 urtwn_bb_write(sc, R92C_OFDM0_AGCPARAM1, reg);
2445
2446 reg = urtwn_bb_read(sc, 0xe74);
2447 reg = (reg & ~0x0c000000) | 2 << 26;
2448 urtwn_bb_write(sc, 0xe74, reg);
2449 reg = urtwn_bb_read(sc, 0xe78);
2450 reg = (reg & ~0x0c000000) | 2 << 26;
2451 urtwn_bb_write(sc, 0xe78, reg);
2452 reg = urtwn_bb_read(sc, 0xe7c);
2453 reg = (reg & ~0x0c000000) | 2 << 26;
2454 urtwn_bb_write(sc, 0xe7c, reg);
2455 reg = urtwn_bb_read(sc, 0xe80);
2456 reg = (reg & ~0x0c000000) | 2 << 26;
2457 urtwn_bb_write(sc, 0xe80, reg);
2458 reg = urtwn_bb_read(sc, 0xe88);
2459 reg = (reg & ~0x0c000000) | 2 << 26;
2460 urtwn_bb_write(sc, 0xe88, reg);
2461 }
2462
2463 /* Write AGC values. */
2464 for (i = 0; i < prog->agccount; i++) {
2465 urtwn_bb_write(sc, R92C_OFDM0_AGCRSSITABLE,
2466 prog->agcvals[i]);
2467 DELAY(1);
2468 }
2469
2470 if (urtwn_bb_read(sc, R92C_HSSI_PARAM2(0)) &
2471 R92C_HSSI_PARAM2_CCK_HIPWR)
2472 sc->sc_flags |= URTWN_FLAG_CCK_HIPWR;
2473}
2474
2475void
2476urtwn_rf_init(struct urtwn_softc *sc)
2477{
2478 const struct urtwn_rf_prog *prog;
2479 uint32_t reg, type;
2480 int i, j, idx, off;
2481
2482 /* Select RF programming based on board type. */
2483 if (!(sc->chip & URTWN_CHIP_92C)) {
2484 if (sc->board_type == R92C_BOARD_TYPE_MINICARD)
2485 prog = rtl8188ce_rf_prog;
2486 else if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
2487 prog = rtl8188ru_rf_prog;
2488 else
2489 prog = rtl8188cu_rf_prog;
2490 } else
2491 prog = rtl8192ce_rf_prog;
2492
2493 for (i = 0; i < sc->nrxchains; i++) {
2494 /* Save RF_ENV control type. */
2495 idx = i / 2;
2496 off = (i % 2) * 16;
2497 reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
2498 type = (reg >> off) & 0x10;
2499
2500 /* Set RF_ENV enable. */
2501 reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
2502 reg |= 0x100000;
2503 urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
2504 DELAY(1);
2505 /* Set RF_ENV output high. */
2506 reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACEOE(i));
2507 reg |= 0x10;
2508 urtwn_bb_write(sc, R92C_FPGA0_RFIFACEOE(i), reg);
2509 DELAY(1);
2510 /* Set address and data lengths of RF registers. */
2511 reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
2512 reg &= ~R92C_HSSI_PARAM2_ADDR_LENGTH;
2513 urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
2514 DELAY(1);
2515 reg = urtwn_bb_read(sc, R92C_HSSI_PARAM2(i));
2516 reg &= ~R92C_HSSI_PARAM2_DATA_LENGTH;
2517 urtwn_bb_write(sc, R92C_HSSI_PARAM2(i), reg);
2518 DELAY(1);
2519
2520 /* Write RF initialization values for this chain. */
2521 for (j = 0; j < prog[i].count; j++) {
2522 if (prog[i].regs[j] >= 0xf9 &&
2523 prog[i].regs[j] <= 0xfe) {
2524 /*
2525 * These are fake RF registers offsets that
2526 * indicate a delay is required.
2527 */
2528 usbd_delay_ms(sc->sc_udev, 50);
2529 continue;
2530 }
2531 urtwn_rf_write(sc, i, prog[i].regs[j],
2532 prog[i].vals[j]);
2533 DELAY(1);
2534 }
2535
2536 /* Restore RF_ENV control type. */
2537 reg = urtwn_bb_read(sc, R92C_FPGA0_RFIFACESW(idx));
2538 reg &= ~(0x10 << off) | (type << off);
2539 urtwn_bb_write(sc, R92C_FPGA0_RFIFACESW(idx), reg);
2540
2541 /* Cache RF register CHNLBW. */
2542 sc->rf_chnlbw[i] = urtwn_rf_read(sc, i, R92C_RF_CHNLBW);
2543 }
2544
2545 if ((sc->chip & (URTWN_CHIP_UMC_A_CUT | URTWN_CHIP_92C)) ==
2546 URTWN_CHIP_UMC_A_CUT) {
2547 urtwn_rf_write(sc, 0, R92C_RF_RX_G1, 0x30255);
2548 urtwn_rf_write(sc, 0, R92C_RF_RX_G2, 0x50a00);
2549 }
2550}
2551
2552void
2553urtwn_cam_init(struct urtwn_softc *sc)
2554{
2555 /* Invalidate all CAM entries. */
2556 urtwn_write_4(sc, R92C_CAMCMD,
2557 R92C_CAMCMD_POLLING | R92C_CAMCMD_CLR);
2558}
2559
2560void
2561urtwn_pa_bias_init(struct urtwn_softc *sc)
2562{
2563 uint8_t reg;
2564 int i;
2565
2566 for (i = 0; i < sc->nrxchains; i++) {
2567 if (sc->pa_setting & (1 << i))
2568 continue;
2569 urtwn_rf_write(sc, i, R92C_RF_IPA, 0x0f406);
2570 urtwn_rf_write(sc, i, R92C_RF_IPA, 0x4f406);
2571 urtwn_rf_write(sc, i, R92C_RF_IPA, 0x8f406);
2572 urtwn_rf_write(sc, i, R92C_RF_IPA, 0xcf406);
2573 }
2574 if (!(sc->pa_setting & 0x10)) {
2575 reg = urtwn_read_1(sc, 0x16);
2576 reg = (reg & ~0xf0) | 0x90;
2577 urtwn_write_1(sc, 0x16, reg);
2578 }
2579}
2580
2581void
2582urtwn_rxfilter_init(struct urtwn_softc *sc)
2583{
2584 /* Initialize Rx filter. */
2585 /* TODO: use better filter for monitor mode. */
2586 urtwn_write_4(sc, R92C_RCR,
2587 R92C_RCR_AAP | R92C_RCR_APM | R92C_RCR_AM | R92C_RCR_AB |
2588 R92C_RCR_APP_ICV | R92C_RCR_AMF | R92C_RCR_HTC_LOC_CTRL |
2589 R92C_RCR_APP_MIC | R92C_RCR_APP_PHYSTS);
2590 /* Accept all multicast frames. */
2591 urtwn_write_4(sc, R92C_MAR + 0, 0xffffffff);
2592 urtwn_write_4(sc, R92C_MAR + 4, 0xffffffff);
2593 /* Accept all management frames. */
2594 urtwn_write_2(sc, R92C_RXFLTMAP0, 0xffff);
2595 /* Reject all control frames. */
2596 urtwn_write_2(sc, R92C_RXFLTMAP1, 0x0000);
2597 /* Accept all data frames. */
2598 urtwn_write_2(sc, R92C_RXFLTMAP2, 0xffff);
2599}
2600
2601void
2602urtwn_edca_init(struct urtwn_softc *sc)
2603{
2604 urtwn_write_2(sc, R92C_SPEC_SIFS, 0x100a);
2605 urtwn_write_2(sc, R92C_MAC_SPEC_SIFS, 0x100a);
2606 urtwn_write_2(sc, R92C_SIFS_CCK, 0x100a);
2607 urtwn_write_2(sc, R92C_SIFS_OFDM, 0x100a);
2608 urtwn_write_4(sc, R92C_EDCA_BE_PARAM, 0x005ea42b);
2609 urtwn_write_4(sc, R92C_EDCA_BK_PARAM, 0x0000a44f);
2610 urtwn_write_4(sc, R92C_EDCA_VI_PARAM, 0x005ea324);
2611 urtwn_write_4(sc, R92C_EDCA_VO_PARAM, 0x002fa226);
2612}
2613
2614void
2615urtwn_write_txpower(struct urtwn_softc *sc, int chain,
2616 uint16_t power[URTWN_RIDX_COUNT])
2617{
2618 uint32_t reg;
2619
2620 /* Write per-CCK rate Tx power. */
2621 if (chain == 0) {
2622 reg = urtwn_bb_read(sc, R92C_TXAGC_A_CCK1_MCS32);
2623 reg = RW(reg, R92C_TXAGC_A_CCK1, power[0]);
2624 urtwn_bb_write(sc, R92C_TXAGC_A_CCK1_MCS32, reg);
2625 reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
2626 reg = RW(reg, R92C_TXAGC_A_CCK2, power[1]);
2627 reg = RW(reg, R92C_TXAGC_A_CCK55, power[2]);
2628 reg = RW(reg, R92C_TXAGC_A_CCK11, power[3]);
2629 urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
2630 } else {
2631 reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK1_55_MCS32);
2632 reg = RW(reg, R92C_TXAGC_B_CCK1, power[0]);
2633 reg = RW(reg, R92C_TXAGC_B_CCK2, power[1]);
2634 reg = RW(reg, R92C_TXAGC_B_CCK55, power[2]);
2635 urtwn_bb_write(sc, R92C_TXAGC_B_CCK1_55_MCS32, reg);
2636 reg = urtwn_bb_read(sc, R92C_TXAGC_B_CCK11_A_CCK2_11);
2637 reg = RW(reg, R92C_TXAGC_B_CCK11, power[3]);
2638 urtwn_bb_write(sc, R92C_TXAGC_B_CCK11_A_CCK2_11, reg);
2639 }
2640 /* Write per-OFDM rate Tx power. */
2641 urtwn_bb_write(sc, R92C_TXAGC_RATE18_06(chain),
2642 SM(R92C_TXAGC_RATE06, power[ 4]) |
2643 SM(R92C_TXAGC_RATE09, power[ 5]) |
2644 SM(R92C_TXAGC_RATE12, power[ 6]) |
2645 SM(R92C_TXAGC_RATE18, power[ 7]));
2646 urtwn_bb_write(sc, R92C_TXAGC_RATE54_24(chain),
2647 SM(R92C_TXAGC_RATE24, power[ 8]) |
2648 SM(R92C_TXAGC_RATE36, power[ 9]) |
2649 SM(R92C_TXAGC_RATE48, power[10]) |
2650 SM(R92C_TXAGC_RATE54, power[11]));
2651 /* Write per-MCS Tx power. */
2652 urtwn_bb_write(sc, R92C_TXAGC_MCS03_MCS00(chain),
2653 SM(R92C_TXAGC_MCS00, power[12]) |
2654 SM(R92C_TXAGC_MCS01, power[13]) |
2655 SM(R92C_TXAGC_MCS02, power[14]) |
2656 SM(R92C_TXAGC_MCS03, power[15]));
2657 urtwn_bb_write(sc, R92C_TXAGC_MCS07_MCS04(chain),
2658 SM(R92C_TXAGC_MCS04, power[16]) |
2659 SM(R92C_TXAGC_MCS05, power[17]) |
2660 SM(R92C_TXAGC_MCS06, power[18]) |
2661 SM(R92C_TXAGC_MCS07, power[19]));
2662 urtwn_bb_write(sc, R92C_TXAGC_MCS11_MCS08(chain),
2663 SM(R92C_TXAGC_MCS08, power[20]) |
2664 SM(R92C_TXAGC_MCS08, power[21]) |
2665 SM(R92C_TXAGC_MCS10, power[22]) |
2666 SM(R92C_TXAGC_MCS11, power[23]));
2667 urtwn_bb_write(sc, R92C_TXAGC_MCS15_MCS12(chain),
2668 SM(R92C_TXAGC_MCS12, power[24]) |
2669 SM(R92C_TXAGC_MCS13, power[25]) |
2670 SM(R92C_TXAGC_MCS14, power[26]) |
2671 SM(R92C_TXAGC_MCS15, power[27]));
2672}
2673
2674void
2675urtwn_get_txpower(struct urtwn_softc *sc, int chain,
2676 struct ieee80211_channel *c, struct ieee80211_channel *extc,
2677 uint16_t power[URTWN_RIDX_COUNT])
2678{
2679 struct ieee80211com *ic = &sc->sc_ic;
2680 struct r92c_rom *rom = &sc->rom;
2681 uint16_t cckpow, ofdmpow, htpow, diff, max;
2682 const struct urtwn_txpwr *base;
2683 int ridx, chan, group;
2684
2685 /* Determine channel group. */
2686 chan = ieee80211_chan2ieee(ic, c); /* XXX center freq! */
2687 if (chan <= 3)
2688 group = 0;
2689 else if (chan <= 9)
2690 group = 1;
2691 else
2692 group = 2;
2693
2694 /* Get original Tx power based on board type and RF chain. */
2695 if (!(sc->chip & URTWN_CHIP_92C)) {
2696 if (sc->board_type == R92C_BOARD_TYPE_HIGHPA)
2697 base = &rtl8188ru_txagc[chain];
2698 else
2699 base = &rtl8192cu_txagc[chain];
2700 } else
2701 base = &rtl8192cu_txagc[chain];
2702
2703 memset(power, 0, URTWN_RIDX_COUNT * sizeof(power[0]));
2704 if (sc->regulatory == 0) {
2705 for (ridx = 0; ridx <= 3; ridx++)
2706 power[ridx] = base->pwr[0][ridx];
2707 }
2708 for (ridx = 4; ridx < URTWN_RIDX_COUNT; ridx++) {
2709 if (sc->regulatory == 3) {
2710 power[ridx] = base->pwr[0][ridx];
2711 /* Apply vendor limits. */
2712 if (extc != NULL)
2713 max = rom->ht40_max_pwr[group];
2714 else
2715 max = rom->ht20_max_pwr[group];
2716 max = (max >> (chain * 4)) & 0xf;
2717 if (power[ridx] > max)
2718 power[ridx] = max;
2719 } else if (sc->regulatory == 1) {
2720 if (extc == NULL)
2721 power[ridx] = base->pwr[group][ridx];
2722 } else if (sc->regulatory != 2)
2723 power[ridx] = base->pwr[0][ridx];
2724 }
2725
2726 /* Compute per-CCK rate Tx power. */
2727 cckpow = rom->cck_tx_pwr[chain][group];
2728 for (ridx = 0; ridx <= 3; ridx++) {
2729 power[ridx] += cckpow;
2730 if (power[ridx] > R92C_MAX_TX_PWR)
2731 power[ridx] = R92C_MAX_TX_PWR;
2732 }
2733
2734 htpow = rom->ht40_1s_tx_pwr[chain][group];
2735 if (sc->ntxchains > 1) {
2736 /* Apply reduction for 2 spatial streams. */
2737 diff = rom->ht40_2s_tx_pwr_diff[group];
2738 diff = (diff >> (chain * 4)) & 0xf;
2739 htpow = (htpow > diff) ? htpow - diff : 0;
2740 }
2741
2742 /* Compute per-OFDM rate Tx power. */
2743 diff = rom->ofdm_tx_pwr_diff[group];
2744 diff = (diff >> (chain * 4)) & 0xf;
2745 ofdmpow = htpow + diff; /* HT->OFDM correction. */
2746 for (ridx = 4; ridx <= 11; ridx++) {
2747 power[ridx] += ofdmpow;
2748 if (power[ridx] > R92C_MAX_TX_PWR)
2749 power[ridx] = R92C_MAX_TX_PWR;
2750 }
2751
2752 /* Compute per-MCS Tx power. */
2753 if (extc == NULL) {
2754 diff = rom->ht20_tx_pwr_diff[group];
2755 diff = (diff >> (chain * 4)) & 0xf;
2756 htpow += diff; /* HT40->HT20 correction. */
2757 }
2758 for (ridx = 12; ridx <= 27; ridx++) {
2759 power[ridx] += htpow;
2760 if (power[ridx] > R92C_MAX_TX_PWR)
2761 power[ridx] = R92C_MAX_TX_PWR;
2762 }
2763#ifdef URTWN_DEBUG
2764 if (urtwn_debug >= 4) {
2765 /* Dump per-rate Tx power values. */
2766 printf("Tx power for chain %d:\n", chain);
2767 for (ridx = 0; ridx < URTWN_RIDX_COUNT; ridx++)
2768 printf("Rate %d = %u\n", ridx, power[ridx]);
2769 }
2770#endif
2771}
2772
2773void
2774urtwn_set_txpower(struct urtwn_softc *sc, struct ieee80211_channel *c,
2775 struct ieee80211_channel *extc)
2776{
2777 uint16_t power[URTWN_RIDX_COUNT];
2778 int i;
2779
2780 for (i = 0; i < sc->ntxchains; i++) {
2781 /* Compute per-rate Tx power values. */
2782 urtwn_get_txpower(sc, i, c, extc, power);
2783 /* Write per-rate Tx power values to hardware. */
2784 urtwn_write_txpower(sc, i, power);
2785 }
2786}
2787
2788void
2789urtwn_set_chan(struct urtwn_softc *sc, struct ieee80211_channel *c,
2790 struct ieee80211_channel *extc)
2791{
2792 struct ieee80211com *ic = &sc->sc_ic;
2793 uint32_t reg;
2794 u_int chan;
2795 int i;
2796
2797 chan = ieee80211_chan2ieee(ic, c); /* XXX center freq! */
2798
2799 /* Set Tx power for this new channel. */
2800 urtwn_set_txpower(sc, c, extc);
2801
2802 for (i = 0; i < sc->nrxchains; i++) {
2803 urtwn_rf_write(sc, i, R92C_RF_CHNLBW,
2804 RW(sc->rf_chnlbw[i], R92C_RF_CHNLBW_CHNL, chan));
2805 }
2806#ifndef IEEE80211_NO_HT
2807 if (extc != NULL) {
2808 /* Is secondary channel below or above primary? */
2809 int prichlo = c->ic_freq < extc->ic_freq;
2810
2811 urtwn_write_1(sc, R92C_BWOPMODE,
2812 urtwn_read_1(sc, R92C_BWOPMODE) & ~R92C_BWOPMODE_20MHZ);
2813
2814 reg = urtwn_read_1(sc, R92C_RRSR + 2);
2815 reg = (reg & ~0x6f) | (prichlo ? 1 : 2) << 5;
2816 urtwn_write_1(sc, R92C_RRSR + 2, reg);
2817
2818 urtwn_bb_write(sc, R92C_FPGA0_RFMOD,
2819 urtwn_bb_read(sc, R92C_FPGA0_RFMOD) | R92C_RFMOD_40MHZ);
2820 urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
2821 urtwn_bb_read(sc, R92C_FPGA1_RFMOD) | R92C_RFMOD_40MHZ);
2822
2823 /* Set CCK side band. */
2824 reg = urtwn_bb_read(sc, R92C_CCK0_SYSTEM);
2825 reg = (reg & ~0x00000010) | (prichlo ? 0 : 1) << 4;
2826 urtwn_bb_write(sc, R92C_CCK0_SYSTEM, reg);
2827
2828 reg = urtwn_bb_read(sc, R92C_OFDM1_LSTF);
2829 reg = (reg & ~0x00000c00) | (prichlo ? 1 : 2) << 10;
2830 urtwn_bb_write(sc, R92C_OFDM1_LSTF, reg);
2831
2832 urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
2833 urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) &
2834 ~R92C_FPGA0_ANAPARAM2_CBW20);
2835
2836 reg = urtwn_bb_read(sc, 0x818);
2837 reg = (reg & ~0x0c000000) | (prichlo ? 2 : 1) << 26;
2838 urtwn_bb_write(sc, 0x818, reg);
2839
2840 /* Select 40MHz bandwidth. */
2841 urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
2842 (sc->rf_chnlbw[0] & ~0xfff) | chan);
2843 } else
2844#endif
2845 {
2846 urtwn_write_1(sc, R92C_BWOPMODE,
2847 urtwn_read_1(sc, R92C_BWOPMODE) | R92C_BWOPMODE_20MHZ);
2848
2849 urtwn_bb_write(sc, R92C_FPGA0_RFMOD,
2850 urtwn_bb_read(sc, R92C_FPGA0_RFMOD) & ~R92C_RFMOD_40MHZ);
2851 urtwn_bb_write(sc, R92C_FPGA1_RFMOD,
2852 urtwn_bb_read(sc, R92C_FPGA1_RFMOD) & ~R92C_RFMOD_40MHZ);
2853
2854 urtwn_bb_write(sc, R92C_FPGA0_ANAPARAM2,
2855 urtwn_bb_read(sc, R92C_FPGA0_ANAPARAM2) |
2856 R92C_FPGA0_ANAPARAM2_CBW20);
2857
2858 /* Select 20MHz bandwidth. */
2859 urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
2860 (sc->rf_chnlbw[0] & ~0xfff) | R92C_RF_CHNLBW_BW20 | chan);
2861 }
2862}
2863
2864int
2865urtwn_iq_calib_chain(struct urtwn_softc *sc, int chain, uint16_t tx[2],
2866 uint16_t rx[2])
2867{
2868 uint32_t status;
2869 int offset = chain * 0x20;
2870
2871 if (chain == 0) { /* IQ calibration for chain 0. */
2872 /* IQ calibration settings for chain 0. */
2873 urtwn_bb_write(sc, 0xe30, 0x10008c1f);
2874 urtwn_bb_write(sc, 0xe34, 0x10008c1f);
2875 urtwn_bb_write(sc, 0xe38, 0x82140102);
2876
2877 if (sc->ntxchains > 1) {
2878 urtwn_bb_write(sc, 0xe3c, 0x28160202); /* 2T */
2879 /* IQ calibration settings for chain 1. */
2880 urtwn_bb_write(sc, 0xe50, 0x10008c22);
2881 urtwn_bb_write(sc, 0xe54, 0x10008c22);
2882 urtwn_bb_write(sc, 0xe58, 0x82140102);
2883 urtwn_bb_write(sc, 0xe5c, 0x28160202);
2884 } else
2885 urtwn_bb_write(sc, 0xe3c, 0x28160502); /* 1T */
2886
2887 /* LO calibration settings. */
2888 urtwn_bb_write(sc, 0xe4c, 0x001028d1);
2889 /* We're doing LO and IQ calibration in one shot. */
2890 urtwn_bb_write(sc, 0xe48, 0xf9000000);
2891 urtwn_bb_write(sc, 0xe48, 0xf8000000);
2892
2893 } else { /* IQ calibration for chain 1. */
2894 /* We're doing LO and IQ calibration in one shot. */
2895 urtwn_bb_write(sc, 0xe60, 0x00000002);
2896 urtwn_bb_write(sc, 0xe60, 0x00000000);
2897 }
2898
2899 /* Give LO and IQ calibrations the time to complete. */
2900 usbd_delay_ms(sc->sc_udev, 1);
2901
2902 /* Read IQ calibration status. */
2903 status = urtwn_bb_read(sc, 0xeac);
2904
2905 if (status & (1 << (28 + chain * 3)))
2906 return (0); /* Tx failed. */
2907 /* Read Tx IQ calibration results. */
2908 tx[0] = (urtwn_bb_read(sc, 0xe94 + offset) >> 16) & 0x3ff;
2909 tx[1] = (urtwn_bb_read(sc, 0xe9c + offset) >> 16) & 0x3ff;
2910 if (tx[0] == 0x142 || tx[1] == 0x042)
2911 return (0); /* Tx failed. */
2912
2913 if (status & (1 << (27 + chain * 3)))
2914 return (1); /* Rx failed. */
2915 /* Read Rx IQ calibration results. */
2916 rx[0] = (urtwn_bb_read(sc, 0xea4 + offset) >> 16) & 0x3ff;
2917 rx[1] = (urtwn_bb_read(sc, 0xeac + offset) >> 16) & 0x3ff;
2918 if (rx[0] == 0x132 || rx[1] == 0x036)
2919 return (1); /* Rx failed. */
2920
2921 return (3); /* Both Tx and Rx succeeded. */
2922}
2923
2924void
2925urtwn_iq_calib(struct urtwn_softc *sc)
2926{
2927 /* TODO */
2928}
2929
2930void
2931urtwn_lc_calib(struct urtwn_softc *sc)
2932{
2933 uint32_t rf_ac[2];
2934 uint8_t txmode;
2935 int i;
2936
2937 txmode = urtwn_read_1(sc, R92C_OFDM1_LSTF + 3);
2938 if ((txmode & 0x70) != 0) {
2939 /* Disable all continuous Tx. */
2940 urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode & ~0x70);
2941
2942 /* Set RF mode to standby mode. */
2943 for (i = 0; i < sc->nrxchains; i++) {
2944 rf_ac[i] = urtwn_rf_read(sc, i, R92C_RF_AC);
2945 urtwn_rf_write(sc, i, R92C_RF_AC,
2946 RW(rf_ac[i], R92C_RF_AC_MODE,
2947 R92C_RF_AC_MODE_STANDBY));
2948 }
2949 } else {
2950 /* Block all Tx queues. */
2951 urtwn_write_1(sc, R92C_TXPAUSE, 0xff);
2952 }
2953 /* Start calibration. */
2954 urtwn_rf_write(sc, 0, R92C_RF_CHNLBW,
2955 urtwn_rf_read(sc, 0, R92C_RF_CHNLBW) | R92C_RF_CHNLBW_LCSTART);
2956
2957 /* Give calibration the time to complete. */
2958 usbd_delay_ms(sc->sc_udev, 100);
2959
2960 /* Restore configuration. */
2961 if ((txmode & 0x70) != 0) {
2962 /* Restore Tx mode. */
2963 urtwn_write_1(sc, R92C_OFDM1_LSTF + 3, txmode);
2964 /* Restore RF mode. */
2965 for (i = 0; i < sc->nrxchains; i++)
2966 urtwn_rf_write(sc, i, R92C_RF_AC, rf_ac[i]);
2967 } else {
2968 /* Unblock all Tx queues. */
2969 urtwn_write_1(sc, R92C_TXPAUSE, 0x00);
2970 }
2971}
2972
2973void
2974urtwn_temp_calib(struct urtwn_softc *sc)
2975{
2976 int temp;
2977
2978 if (sc->thcal_state == 0) {
2979 /* Start measuring temperature. */
2980 urtwn_rf_write(sc, 0, R92C_RF_T_METER, 0x60);
2981 sc->thcal_state = 1;
2982 return;
2983 }
2984 sc->thcal_state = 0;
2985
2986 /* Read measured temperature. */
2987 temp = urtwn_rf_read(sc, 0, R92C_RF_T_METER) & 0x1f;
2988 if (temp == 0) /* Read failed, skip. */
2989 return;
2990 DPRINTFN(2, ("temperature=%d\n", temp));
2991
2992 /*
2993 * Redo LC calibration if temperature changed significantly since
2994 * last calibration.
2995 */
2996 if (sc->thcal_lctemp == 0) {
2997 /* First LC calibration is performed in urtwn_init(). */
2998 sc->thcal_lctemp = temp;
2999 } else if (abs(temp - sc->thcal_lctemp) > 1) {
3000 DPRINTF(("LC calib triggered by temp: %d -> %d\n",
3001 sc->thcal_lctemp, temp));
3002 urtwn_lc_calib(sc);
3003 /* Record temperature of last LC calibration. */
3004 sc->thcal_lctemp = temp;
3005 }
3006}
3007
3008int
3009urtwn_init(struct ifnet *ifp)
3010{
3011 struct urtwn_softc *sc = ifp->if_softc;
3012 struct ieee80211com *ic = &sc->sc_ic;
3013 struct urtwn_rx_data *data;
3014 uint32_t reg;
3015 int i, error;
3016
3017 /* Init host async commands ring. */
3018 sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0;
3019 /* Init firmware commands ring. */
3020 sc->fwcur = 0;
3021
3022 /* Allocate Tx/Rx buffers. */
3023 error = urtwn_alloc_rx_list(sc);
3024 if (error != 0) {
3025 printf("%s: could not allocate Rx buffers\n",
3026 sc->sc_dev.dv_xname);
3027 goto fail;
3028 }
3029 error = urtwn_alloc_tx_list(sc);
3030 if (error != 0) {
3031 printf("%s: could not allocate Tx buffers\n",
3032 sc->sc_dev.dv_xname);
3033 goto fail;
3034 }
3035 /* Power on adapter. */
3036 error = urtwn_power_on(sc);
3037 if (error != 0)
3038 goto fail;
3039
3040 /* Initialize DMA. */
3041 error = urtwn_dma_init(sc);
3042 if (error != 0)
3043 goto fail;
3044
3045 /* Set info size in Rx descriptors (in 64-bit words). */
3046 urtwn_write_1(sc, R92C_RX_DRVINFO_SZ, 4);
3047
3048 /* Init interrupts. */
3049 urtwn_write_4(sc, R92C_HISR, 0xffffffff);
3050 urtwn_write_4(sc, R92C_HIMR, 0xffffffff);
3051
3052 /* Set MAC address. */
3053 IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(ifp->if_sadl));
3054 urtwn_write_region_1(sc, R92C_MACID, ic->ic_myaddr,
3055 IEEE80211_ADDR_LEN);
3056
3057 /* Set initial network type. */
3058 reg = urtwn_read_4(sc, R92C_CR);
3059 reg = RW(reg, R92C_CR_NETTYPE, R92C_CR_NETTYPE_INFRA);
3060 urtwn_write_4(sc, R92C_CR, reg);
3061
3062 urtwn_rxfilter_init(sc);
3063
3064 reg = urtwn_read_4(sc, R92C_RRSR);
3065 reg = RW(reg, R92C_RRSR_RATE_BITMAP, R92C_RRSR_RATE_CCK_ONLY_1M);
3066 urtwn_write_4(sc, R92C_RRSR, reg);
3067
3068 /* Set short/long retry limits. */
3069 urtwn_write_2(sc, R92C_RL,
3070 SM(R92C_RL_SRL, 0x30) | SM(R92C_RL_LRL, 0x30));
3071
3072 /* Initialize EDCA parameters. */
3073 urtwn_edca_init(sc);
3074
3075 /* Setup rate fallback. */
3076 urtwn_write_4(sc, R92C_DARFRC + 0, 0x00000000);
3077 urtwn_write_4(sc, R92C_DARFRC + 4, 0x10080404);
3078 urtwn_write_4(sc, R92C_RARFRC + 0, 0x04030201);
3079 urtwn_write_4(sc, R92C_RARFRC + 4, 0x08070605);
3080
3081 urtwn_write_1(sc, R92C_FWHW_TXQ_CTRL,
3082 urtwn_read_1(sc, R92C_FWHW_TXQ_CTRL) |
3083 R92C_FWHW_TXQ_CTRL_AMPDU_RTY_NEW);
3084 /* Set ACK timeout. */
3085 urtwn_write_1(sc, R92C_ACKTO, 0x40);
3086
3087 /* Setup USB aggregation. */
3088 reg = urtwn_read_4(sc, R92C_TDECTRL);
3089 reg = RW(reg, R92C_TDECTRL_BLK_DESC_NUM, 6);
3090 urtwn_write_4(sc, R92C_TDECTRL, reg);
3091 urtwn_write_1(sc, R92C_TRXDMA_CTRL,
3092 urtwn_read_1(sc, R92C_TRXDMA_CTRL) |
3093 R92C_TRXDMA_CTRL_RXDMA_AGG_EN);
3094 urtwn_write_1(sc, R92C_USB_SPECIAL_OPTION,
3095 urtwn_read_1(sc, R92C_USB_SPECIAL_OPTION) |
3096 R92C_USB_SPECIAL_OPTION_AGG_EN);
3097 urtwn_write_1(sc, R92C_RXDMA_AGG_PG_TH, 48);
3098 urtwn_write_1(sc, R92C_USB_DMA_AGG_TO, 4);
3099 urtwn_write_1(sc, R92C_USB_AGG_TH, 8);
3100 urtwn_write_1(sc, R92C_USB_AGG_TO, 6);
3101
3102 /* Initialize beacon parameters. */
3103 urtwn_write_2(sc, R92C_TBTT_PROHIBIT, 0x6404);
3104 urtwn_write_1(sc, R92C_DRVERLYINT, 0x05);
3105 urtwn_write_1(sc, R92C_BCNDMATIM, 0x02);
3106 urtwn_write_2(sc, R92C_BCNTCFG, 0x660f);
3107
3108 /* Setup AMPDU aggregation. */
3109 urtwn_write_4(sc, R92C_AGGLEN_LMT, 0x99997631); /* MCS7~0 */
3110 urtwn_write_1(sc, R92C_AGGR_BREAK_TIME, 0x16);
3111 urtwn_write_2(sc, 0x4ca, 0x0708);
3112
3113 urtwn_write_1(sc, R92C_BCN_MAX_ERR, 0xff);
3114 urtwn_write_1(sc, R92C_BCN_CTRL, R92C_BCN_CTRL_DIS_TSF_UDT0);
3115
3116 /* Load 8051 microcode. */
3117 error = urtwn_load_firmware(sc);
3118 if (error != 0)
3119 goto fail;
3120
3121 /* Initialize MAC/BB/RF blocks. */
3122 urtwn_mac_init(sc);
3123 urtwn_bb_init(sc);
3124 urtwn_rf_init(sc);
3125
3126 /* Turn CCK and OFDM blocks on. */
3127 reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
3128 reg |= R92C_RFMOD_CCK_EN;
3129 urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
3130 reg = urtwn_bb_read(sc, R92C_FPGA0_RFMOD);
3131 reg |= R92C_RFMOD_OFDM_EN;
3132 urtwn_bb_write(sc, R92C_FPGA0_RFMOD, reg);
3133
3134 /* Clear per-station keys table. */
3135 urtwn_cam_init(sc);
3136
3137 /* Enable hardware sequence numbering. */
3138 urtwn_write_1(sc, R92C_HWSEQ_CTRL, 0xff);
3139
3140 /* Perform LO and IQ calibrations. */
3141 urtwn_iq_calib(sc);
3142 /* Perform LC calibration. */
3143 urtwn_lc_calib(sc);
3144
3145 /* Fix USB interference issue. */
3146 urtwn_write_1(sc, 0xfe40, 0xe0);
3147 urtwn_write_1(sc, 0xfe41, 0x8d);
3148 urtwn_write_1(sc, 0xfe42, 0x80);
3149
3150 urtwn_pa_bias_init(sc);
3151
3152 /* Initialize GPIO setting. */
3153 urtwn_write_1(sc, R92C_GPIO_MUXCFG,
3154 urtwn_read_1(sc, R92C_GPIO_MUXCFG) & ~R92C_GPIO_MUXCFG_ENBT);
3155
3156 /* Fix for lower temperature. */
3157 urtwn_write_1(sc, 0x15, 0xe9);
3158
3159 /* Set default channel. */
3160 ic->ic_bss->ni_chan = ic->ic_ibss_chan;
3161 urtwn_set_chan(sc, ic->ic_ibss_chan, NULL);
3162
3163 /* Queue Rx xfers. */
3164 for (i = 0; i < URTWN_RX_LIST_COUNT; i++) {
3165 data = &sc->rx_data[i];
3166
3167 usbd_setup_xfer(data->xfer, sc->rx_pipe, data, data->buf,
3168 URTWN_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY,
3169 USBD_NO_TIMEOUT, urtwn_rxeof);
3170 error = usbd_transfer(data->xfer);
3171 if (error != 0 && error != USBD_IN_PROGRESS)
3172 goto fail;
3173 }
3174
3175 /* We're ready to go. */
3176 ifp->if_flags &= ~IFF_OACTIVE;
3177 ifp->if_flags |= IFF_RUNNING;
3178
3179#ifdef notyet
3180 if (ic->ic_flags & IEEE80211_F_WEPON) {
3181 /* Install WEP keys. */
3182 for (i = 0; i < IEEE80211_WEP_NKID; i++)
3183 urtwn_set_key(ic, NULL, &ic->ic_nw_keys[i]);
3184 urtwn_wait_async(sc);
3185 }
3186#endif
3187 if (ic->ic_opmode == IEEE80211_M_MONITOR)
3188 ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
3189 else
3190 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
3191 return (0);
3192 fail:
3193 urtwn_stop(ifp);
3194 return (error);
3195}
3196
3197void
3198urtwn_stop(struct ifnet *ifp)
3199{
3200 struct urtwn_softc *sc = ifp->if_softc;
3201 struct ieee80211com *ic = &sc->sc_ic;
3202 int i, s;
3203
3204 sc->sc_tx_timer = 0;
3205 ifp->if_timer = 0;
3206 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
3207
3208 s = splusb();
3209 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
3210 /* Wait for all async commands to complete. */
3211 urtwn_wait_async(sc);
3212 splx(s);
3213
3214 timeout_del(&sc->scan_to);
3215 timeout_del(&sc->calib_to);
3216
3217 /* Abort Tx. */
3218 for (i = 0; i < R92C_MAX_EPOUT; i++) {
3219 if (sc->tx_pipe[i] != NULL)
3220 usbd_abort_pipe(sc->tx_pipe[i]);
3221 }
3222 /* Stop Rx pipe. */
3223 usbd_abort_pipe(sc->rx_pipe);
3224 /* Free Tx/Rx buffers. */
3225 urtwn_free_tx_list(sc);
3226 urtwn_free_rx_list(sc);
3227}