1 1.1 nia /* $NetBSD: if_rsu.c,v 1.1 2026/10/18 20:17:42 nia Exp $ */ 2 1.1 nia /* $OpenBSD: if_rsu.c,v 1.53 2024/05/23 03:21:08 jsg Exp $ */ 3 1.1 nia 4 1.1 nia /*- 5 1.1 nia * Copyright (c) 2010 Damien Bergamini <damien.bergamini (at) free.fr> 6 1.1 nia * 7 1.1 nia * Permission to use, copy, modify, and distribute this software for any 8 1.1 nia * purpose with or without fee is hereby granted, provided that the above 9 1.1 nia * copyright notice and this permission notice appear in all copies. 10 1.1 nia * 11 1.1 nia * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 1.1 nia * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 1.1 nia * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 1.1 nia * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 1.1 nia * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 1.1 nia * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 1.1 nia * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 1.1 nia */ 19 1.1 nia 20 1.1 nia /* 21 1.1 nia * Driver for Realtek RTL8188SU/RTL8191SU/RTL8192SU. 22 1.1 nia */ 23 1.1 nia 24 1.1 nia /* 25 1.1 nia * XXX: This driver is unfinished. It attaches but is not yet usable. 26 1.1 nia */ 27 1.1 nia 28 1.1 nia #include <sys/param.h> 29 1.1 nia #include <sys/sockio.h> 30 1.1 nia #include <sys/mbuf.h> 31 1.1 nia #include <sys/systm.h> 32 1.1 nia #include <sys/callout.h> 33 1.1 nia #include <sys/module.h> 34 1.1 nia #include <sys/device.h> 35 1.1 nia #include <sys/endian.h> 36 1.1 nia 37 1.1 nia #include <machine/intr.h> 38 1.1 nia 39 1.1 nia #include <net/if.h> 40 1.1 nia #include <net/if_dl.h> 41 1.1 nia #include <net/if_ether.h> 42 1.1 nia #include <net/if_media.h> 43 1.1 nia 44 1.1 nia #include <netinet/in.h> 45 1.1 nia 46 1.1 nia #include <net80211/ieee80211_var.h> 47 1.1 nia #include <net80211/ieee80211_radiotap.h> 48 1.1 nia 49 1.1 nia #include <dev/firmload.h> 50 1.1 nia 51 1.1 nia #include <dev/usb/usb.h> 52 1.1 nia #include <dev/usb/usbdi.h> 53 1.1 nia #include <dev/usb/usbdivar.h> 54 1.1 nia #include <dev/usb/usbdi_util.h> 55 1.1 nia #include <dev/usb/usbdevs.h> 56 1.1 nia 57 1.1 nia #include <dev/usb/if_rsureg.h> 58 1.1 nia 59 1.1 nia #ifdef RSU_DEBUG 60 1.1 nia #define DPRINTF(x) do { if (rsu_debug) printf x; } while (0) 61 1.1 nia #define DPRINTFN(n, x) do { if (rsu_debug >= (n)) printf x; } while (0) 62 1.1 nia int rsu_debug = 4; 63 1.1 nia #else 64 1.1 nia #define DPRINTF(x) 65 1.1 nia #define DPRINTFN(n, x) 66 1.1 nia #endif 67 1.1 nia 68 1.1 nia /* 69 1.1 nia * NB: When updating this list of devices, beware to also update the list 70 1.1 nia * of devices that have HT support disabled below, if applicable. 71 1.1 nia */ 72 1.1 nia static const struct usb_devno rsu_devs[] = { 73 1.1 nia { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_RTL8192SU }, 74 1.1 nia { USB_VENDOR_ASUSTEK, USB_PRODUCT_ASUSTEK_USBN10 }, 75 1.1 nia { USB_VENDOR_ASUSTEK, USB_PRODUCT_ASUSTEK_RTL8192SU_1 }, 76 1.1 nia { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_1 }, 77 1.1 nia { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_2 }, 78 1.1 nia { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_3 }, 79 1.1 nia { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_4 }, 80 1.1 nia { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_5 }, 81 1.1 nia { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_1 }, 82 1.1 nia { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_2 }, 83 1.1 nia { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_RTL8192SU_3 }, 84 1.1 nia { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_RTL8192SU_1 }, 85 1.1 nia { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_RTL8192SU_2 }, 86 1.1 nia { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_RTL8192SU_3 }, 87 1.1 nia { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_CGWLUSB300GNM }, 88 1.1 nia { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_DWA131A1 }, 89 1.1 nia { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_1 }, 90 1.1 nia { USB_VENDOR_DLINK2, USB_PRODUCT_DLINK2_RTL8192SU_2 }, 91 1.1 nia { USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_1 }, 92 1.1 nia { USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_2 }, 93 1.1 nia { USB_VENDOR_EDIMAX, USB_PRODUCT_EDIMAX_RTL8192SU_3 }, 94 1.1 nia { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUN54 }, 95 1.1 nia { USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWNUM300 }, 96 1.1 nia { USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_1 }, 97 1.1 nia { USB_VENDOR_HAWKING, USB_PRODUCT_HAWKING_RTL8192SU_2 }, 98 1.1 nia { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GWUSNANO }, 99 1.1 nia { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8171 }, 100 1.1 nia { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8172 }, 101 1.1 nia { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8173 }, 102 1.1 nia { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8174 }, 103 1.1 nia { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8192SU }, 104 1.1 nia { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8712 }, 105 1.1 nia { USB_VENDOR_REALTEK, USB_PRODUCT_REALTEK_RTL8713 }, 106 1.1 nia { USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_1 }, 107 1.1 nia { USB_VENDOR_SENAO, USB_PRODUCT_SENAO_RTL8192SU_2 }, 108 1.1 nia { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL349V1 }, 109 1.1 nia { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_WL353 }, 110 1.1 nia { USB_VENDOR_SITECOMEU, USB_PRODUCT_SITECOMEU_RTL8188S }, 111 1.1 nia { USB_VENDOR_SWEEX2, USB_PRODUCT_SWEEX2_LW154 } 112 1.1 nia }; 113 1.1 nia 114 1.1 nia #ifdef notyet 115 1.1 nia /* List of devices that have HT support disabled. */ 116 1.1 nia static const struct usb_devno rsu_devs_noht[] = { 117 1.1 nia { USB_VENDOR_ASUSTEK, USB_PRODUCT_ASUS_RTL8192SU_1 }, 118 1.1 nia { USB_VENDOR_AZUREWAVE, USB_PRODUCT_AZUREWAVE_RTL8192SU_4 } 119 1.1 nia }; 120 1.1 nia #endif 121 1.1 nia 122 1.1 nia static int rsu_match(device_t, cfdata_t, void *); 123 1.1 nia static void rsu_attach(device_t, device_t, void *); 124 1.1 nia static int rsu_detach(device_t, int); 125 1.1 nia static int rsu_activate(device_t, enum devact); 126 1.1 nia 127 1.1 nia int rsu_open_pipes(struct rsu_softc *); 128 1.1 nia void rsu_close_pipes(struct rsu_softc *); 129 1.1 nia int rsu_alloc_rx_list(struct rsu_softc *); 130 1.1 nia void rsu_free_rx_list(struct rsu_softc *); 131 1.1 nia int rsu_alloc_tx_list(struct rsu_softc *); 132 1.1 nia void rsu_free_tx_list(struct rsu_softc *); 133 1.1 nia void rsu_task(void *); 134 1.1 nia void rsu_do_async(struct rsu_softc *, 135 1.1 nia void (*)(struct rsu_softc *, void *), void *, int); 136 1.1 nia void rsu_wait_async(struct rsu_softc *); 137 1.1 nia int rsu_write_region_1(struct rsu_softc *, uint16_t, uint8_t *, 138 1.1 nia int); 139 1.1 nia void rsu_write_1(struct rsu_softc *, uint16_t, uint8_t); 140 1.1 nia void rsu_write_2(struct rsu_softc *, uint16_t, uint16_t); 141 1.1 nia void rsu_write_4(struct rsu_softc *, uint16_t, uint32_t); 142 1.1 nia int rsu_read_region_1(struct rsu_softc *, uint16_t, uint8_t *, 143 1.1 nia int); 144 1.1 nia uint8_t rsu_read_1(struct rsu_softc *, uint16_t); 145 1.1 nia uint16_t rsu_read_2(struct rsu_softc *, uint16_t); 146 1.1 nia uint32_t rsu_read_4(struct rsu_softc *, uint16_t); 147 1.1 nia int rsu_fw_iocmd(struct rsu_softc *, uint32_t); 148 1.1 nia uint8_t rsu_efuse_read_1(struct rsu_softc *, uint16_t); 149 1.1 nia int rsu_read_rom(struct rsu_softc *); 150 1.1 nia int rsu_fw_cmd(struct rsu_softc *, uint8_t, void *, int); 151 1.1 nia int rsu_media_change(struct ifnet *); 152 1.1 nia void rsu_calib_to(void *); 153 1.1 nia void rsu_calib_cb(struct rsu_softc *, void *); 154 1.1 nia int rsu_newstate(struct ieee80211com *, enum ieee80211_state, int); 155 1.1 nia void rsu_newstate_cb(struct rsu_softc *, void *); 156 1.1 nia int rsu_site_survey(struct rsu_softc *); 157 1.1 nia int rsu_join_bss(struct rsu_softc *, struct ieee80211_node *); 158 1.1 nia int rsu_disconnect(struct rsu_softc *); 159 1.1 nia void rsu_event_survey(struct rsu_softc *, uint8_t *, int); 160 1.1 nia void rsu_event_join_bss(struct rsu_softc *, uint8_t *, int); 161 1.1 nia void rsu_rx_event(struct rsu_softc *, uint8_t, uint8_t *, int); 162 1.1 nia void rsu_rx_multi_event(struct rsu_softc *, uint8_t *, int); 163 1.1 nia int8_t rsu_get_rssi(struct rsu_softc *, int, void *); 164 1.1 nia void rsu_rx_frame(struct rsu_softc *, uint8_t *, int); 165 1.1 nia void rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int); 166 1.1 nia void rsu_rxeof(struct usbd_xfer *, void *, usbd_status); 167 1.1 nia void rsu_txeof(struct usbd_xfer *, void *, usbd_status); 168 1.1 nia int rsu_tx(struct rsu_softc *, struct mbuf *, 169 1.1 nia struct ieee80211_node *); 170 1.1 nia int rsu_send_mgmt(struct ieee80211com *, struct ieee80211_node *, 171 1.1 nia int, int); 172 1.1 nia void rsu_start(struct ifnet *); 173 1.1 nia void rsu_watchdog(struct ifnet *); 174 1.1 nia int rsu_ioctl(struct ifnet *, u_long, void *); 175 1.1 nia void rsu_power_on_acut(struct rsu_softc *); 176 1.1 nia void rsu_power_on_bcut(struct rsu_softc *); 177 1.1 nia void rsu_power_off(struct rsu_softc *); 178 1.1 nia int rsu_fw_loadsection(struct rsu_softc *, uint8_t *, int); 179 1.1 nia int rsu_load_firmware(struct rsu_softc *); 180 1.1 nia int rsu_init(struct ifnet *); 181 1.1 nia void rsu_stop(struct ifnet *); 182 1.1 nia 183 1.1 nia CFATTACH_DECL_NEW(rsu, sizeof(struct rsu_softc), rsu_match, 184 1.1 nia rsu_attach, rsu_detach, rsu_activate); 185 1.1 nia 186 1.1 nia static int 187 1.1 nia rsu_activate(device_t self, enum devact act) 188 1.1 nia { 189 1.1 nia struct rsu_softc *sc = device_private(self); 190 1.1 nia switch (act) { 191 1.1 nia case DVACT_DEACTIVATE: 192 1.1 nia if_deactivate(sc->sc_ic.ic_ifp); 193 1.1 nia return 0; 194 1.1 nia default: 195 1.1 nia return EOPNOTSUPP; 196 1.1 nia } 197 1.1 nia } 198 1.1 nia 199 1.1 nia static int 200 1.1 nia rsu_match(device_t parent, cfdata_t match, void *aux) 201 1.1 nia { 202 1.1 nia struct usb_attach_arg *uaa = aux; 203 1.1 nia 204 1.1 nia return ((usb_lookup(rsu_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ? 205 1.1 nia UMATCH_VENDOR_PRODUCT_CONF_IFACE : UMATCH_NONE); 206 1.1 nia } 207 1.1 nia 208 1.1 nia static void 209 1.1 nia rsu_attach(device_t parent, device_t self, void *aux) 210 1.1 nia { 211 1.1 nia struct rsu_softc *sc = device_private(self); 212 1.1 nia struct usb_attach_arg *uaa = aux; 213 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 214 1.1 nia struct ifnet *ifp = &sc->sc_ec.ec_if; 215 1.1 nia int i, error; 216 1.1 nia 217 1.1 nia sc->sc_dev = self; 218 1.1 nia sc->sc_udev = uaa->uaa_device; 219 1.1 nia 220 1.1 nia cv_init(&sc->sc_task_cv, "rsutsk"); 221 1.1 nia mutex_init(&sc->sc_task_mtx, MUTEX_DEFAULT, IPL_NET); 222 1.1 nia mutex_init(&sc->sc_tx_mtx, MUTEX_DEFAULT, IPL_NONE); 223 1.1 nia 224 1.1 nia usb_init_task(&sc->sc_task, rsu_task, sc, 0); 225 1.1 nia 226 1.1 nia callout_init(&sc->calib_to, 0); 227 1.1 nia callout_setfunc(&sc->calib_to, rsu_calib_to, sc); 228 1.1 nia 229 1.1 nia /* Read chip revision. */ 230 1.1 nia sc->cut = MS(rsu_read_4(sc, R92S_PMC_FSM), R92S_PMC_FSM_CUT); 231 1.1 nia if (sc->cut != 3) 232 1.1 nia sc->cut = (sc->cut >> 1) + 1; 233 1.1 nia 234 1.1 nia KASSERT(sc->sc_dev != NULL); 235 1.1 nia 236 1.1 nia error = usbd_set_config_no(sc->sc_udev, 1, 0); 237 1.1 nia if (error != 0) { 238 1.1 nia aprint_error_dev(self, "failed to set configuration" 239 1.1 nia ", err=%s\n", usbd_errstr(error)); 240 1.1 nia return; 241 1.1 nia } 242 1.1 nia 243 1.1 nia /* Get the first interface handle. */ 244 1.1 nia error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface); 245 1.1 nia if (error != 0) { 246 1.1 nia aprint_error_dev(self, "could not get interface handle\n"); 247 1.1 nia return; 248 1.1 nia } 249 1.1 nia 250 1.1 nia error = rsu_read_rom(sc); 251 1.1 nia if (error != 0) { 252 1.1 nia printf("%s: could not read ROM\n", device_xname(sc->sc_dev)); 253 1.1 nia return; 254 1.1 nia } 255 1.1 nia IEEE80211_ADDR_COPY(ic->ic_myaddr, &sc->rom[0x12]); 256 1.1 nia 257 1.1 nia printf("%s: MAC/BB RTL8712 cut %d, address %s\n", 258 1.1 nia device_xname(sc->sc_dev), sc->cut, ether_sprintf(ic->ic_myaddr)); 259 1.1 nia 260 1.1 nia if (rsu_open_pipes(sc) != 0) 261 1.1 nia return; 262 1.1 nia 263 1.1 nia KASSERT(ifp != NULL); 264 1.1 nia 265 1.1 nia ic->ic_ifp = ifp; 266 1.1 nia ic->ic_phytype = IEEE80211_T_OFDM; /* Not only, but not used. */ 267 1.1 nia ic->ic_opmode = IEEE80211_M_STA; /* Default to BSS mode. */ 268 1.1 nia ic->ic_state = IEEE80211_S_INIT; 269 1.1 nia 270 1.1 nia /* Set device capabilities. */ 271 1.1 nia ic->ic_caps = 272 1.1 nia IEEE80211_C_MONITOR | /* Monitor mode. */ 273 1.1 nia IEEE80211_C_SHPREAMBLE | /* Short preamble supported. */ 274 1.1 nia IEEE80211_C_SHSLOT | /* Short slot time supported. */ 275 1.1 nia IEEE80211_C_WPA; /* WPA/RSN. */ 276 1.1 nia 277 1.1 nia #ifdef notyet 278 1.1 nia ic->ic_caps += 279 1.1 nia IEEE80211_C_WEP; /* WEP. */ 280 1.1 nia #endif 281 1.1 nia 282 1.1 nia #ifdef notyet 283 1.1 nia /* Check if HT support is present. */ 284 1.1 nia if (usb_lookup(rsu_devs_noht, uaa->uaa_vendor, uaa->uaa_product) == NULL) { 285 1.1 nia /* Set HT capabilities. */ 286 1.1 nia ic->ic_htcaps = 287 1.1 nia IEEE80211_HTCAP_CBW20_40 | 288 1.1 nia IEEE80211_HTCAP_DSSSCCK40; 289 1.1 nia /* Set supported HT rates. */ 290 1.1 nia for (i = 0; i < 2; i++) 291 1.1 nia ic->ic_sup_mcs[i] = 0xff; 292 1.1 nia } 293 1.1 nia #endif 294 1.1 nia 295 1.1 nia /* Set supported .11b and .11g rates. */ 296 1.1 nia ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 297 1.1 nia ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g; 298 1.1 nia 299 1.1 nia /* Set supported .11b and .11g channels (1 through 14). */ 300 1.1 nia for (i = 1; i <= 14; i++) { 301 1.1 nia ic->ic_channels[i].ic_freq = 302 1.1 nia ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 303 1.1 nia ic->ic_channels[i].ic_flags = 304 1.1 nia IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM | 305 1.1 nia IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ; 306 1.1 nia } 307 1.1 nia 308 1.1 nia ifp->if_softc = sc; 309 1.1 nia ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 310 1.1 nia ifp->if_init = rsu_init; 311 1.1 nia ifp->if_ioctl = rsu_ioctl; 312 1.1 nia ifp->if_start = rsu_start; 313 1.1 nia ifp->if_watchdog = rsu_watchdog; 314 1.1 nia memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 315 1.1 nia 316 1.1 nia if_initialize(ifp); 317 1.1 nia ieee80211_ifattach(ic); 318 1.1 nia 319 1.1 nia /* Override state transition machine. */ 320 1.1 nia sc->sc_newstate = ic->ic_newstate; 321 1.1 nia ic->ic_newstate = rsu_newstate; 322 1.1 nia 323 1.1 nia /* XXX media locking needs revisiting */ 324 1.1 nia mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB); 325 1.1 nia ieee80211_media_init_with_lock(ic, 326 1.1 nia rsu_media_change, ieee80211_media_status, &sc->sc_media_mtx); 327 1.1 nia 328 1.1 nia if_register(ifp); 329 1.1 nia 330 1.1 nia ieee80211_announce(ic); 331 1.1 nia 332 1.1 nia usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 333 1.1 nia } 334 1.1 nia 335 1.1 nia static int 336 1.1 nia rsu_detach(device_t self, int flags) 337 1.1 nia { 338 1.1 nia struct rsu_softc *sc = device_private(self); 339 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 340 1.1 nia struct ifnet *ifp = sc->sc_ic.ic_ifp; 341 1.1 nia int s; 342 1.1 nia 343 1.1 nia s = splusb(); 344 1.1 nia 345 1.1 nia if (ifp->if_flags & IFF_RUNNING) { 346 1.1 nia rsu_stop(ifp); 347 1.1 nia callout_halt(&sc->calib_to, NULL); 348 1.1 nia usb_rem_task_wait(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER, 349 1.1 nia NULL); 350 1.1 nia } 351 1.1 nia 352 1.1 nia ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 353 1.1 nia ieee80211_ifdetach(ic); 354 1.1 nia if_detach(ifp); 355 1.1 nia 356 1.1 nia mutex_destroy(&sc->sc_media_mtx); 357 1.1 nia 358 1.1 nia /* Abort and close Tx/Rx pipes. */ 359 1.1 nia rsu_close_pipes(sc); 360 1.1 nia 361 1.1 nia /* Free Tx/Rx buffers. */ 362 1.1 nia rsu_free_tx_list(sc); 363 1.1 nia rsu_free_rx_list(sc); 364 1.1 nia splx(s); 365 1.1 nia 366 1.1 nia usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 367 1.1 nia 368 1.1 nia callout_destroy(&sc->calib_to); 369 1.1 nia 370 1.1 nia mutex_destroy(&sc->sc_task_mtx); 371 1.1 nia mutex_destroy(&sc->sc_tx_mtx); 372 1.1 nia 373 1.1 nia return (0); 374 1.1 nia } 375 1.1 nia 376 1.1 nia int 377 1.1 nia rsu_open_pipes(struct rsu_softc *sc) 378 1.1 nia { 379 1.1 nia usb_interface_descriptor_t *id; 380 1.1 nia int i, error; 381 1.1 nia 382 1.1 nia /* 383 1.1 nia * Determine the number of Tx/Rx endpoints (there are chips with 384 1.1 nia * 4, 6 or 11 endpoints). 385 1.1 nia */ 386 1.1 nia id = usbd_get_interface_descriptor(sc->sc_iface); 387 1.1 nia sc->npipes = id->bNumEndpoints; 388 1.1 nia if (sc->npipes == 4) 389 1.1 nia sc->qid2idx = rsu_qid2idx_4ep; 390 1.1 nia else if (sc->npipes == 6) 391 1.1 nia sc->qid2idx = rsu_qid2idx_6ep; 392 1.1 nia else /* Assume npipes==11; will fail below otherwise. */ 393 1.1 nia sc->qid2idx = rsu_qid2idx_11ep; 394 1.1 nia DPRINTF(("%d endpoints configuration\n", sc->npipes)); 395 1.1 nia 396 1.1 nia /* Open all pipes. */ 397 1.1 nia for (i = 0; i < MIN(sc->npipes, (int)__arraycount(r92s_epaddr)); i++) { 398 1.1 nia error = usbd_open_pipe(sc->sc_iface, r92s_epaddr[i], 0, 399 1.1 nia &sc->pipe[i]); 400 1.1 nia if (error != 0) { 401 1.1 nia printf("%s: could not open bulk pipe 0x%02x\n", 402 1.1 nia device_xname(sc->sc_dev), r92s_epaddr[i]); 403 1.1 nia break; 404 1.1 nia } 405 1.1 nia } 406 1.1 nia if (error != 0) 407 1.1 nia rsu_close_pipes(sc); 408 1.1 nia return (error); 409 1.1 nia } 410 1.1 nia 411 1.1 nia void 412 1.1 nia rsu_close_pipes(struct rsu_softc *sc) 413 1.1 nia { 414 1.1 nia struct usbd_pipe *pipe; 415 1.1 nia int i; 416 1.1 nia 417 1.1 nia /* Close all pipes. */ 418 1.1 nia for (i = 0; i < sc->npipes; i++) { 419 1.1 nia pipe = atomic_swap_ptr(&sc->pipe[i], NULL); 420 1.1 nia if (pipe != NULL) { 421 1.1 nia usbd_close_pipe(pipe); 422 1.1 nia } 423 1.1 nia } 424 1.1 nia } 425 1.1 nia 426 1.1 nia int 427 1.1 nia rsu_alloc_rx_list(struct rsu_softc *sc) 428 1.1 nia { 429 1.1 nia struct rsu_rx_data *data; 430 1.1 nia int i, error = 0; 431 1.1 nia 432 1.1 nia for (i = 0; i < RSU_RX_LIST_COUNT; i++) { 433 1.1 nia data = &sc->rx_data[i]; 434 1.1 nia 435 1.1 nia data->sc = sc; /* Backpointer for callbacks. */ 436 1.1 nia 437 1.1 nia error = usbd_create_xfer(data->pipe, RSU_RXBUFSZ, 438 1.1 nia 0, 0, &data->xfer); 439 1.1 nia if (error) { 440 1.1 nia printf("%s: could not allocate xfer\n", 441 1.1 nia device_xname(sc->sc_dev)); 442 1.1 nia error = ENOMEM; 443 1.1 nia break; 444 1.1 nia } 445 1.1 nia data->buf = usbd_get_buffer(data->xfer); 446 1.1 nia } 447 1.1 nia if (error != 0) 448 1.1 nia rsu_free_rx_list(sc); 449 1.1 nia return (error); 450 1.1 nia } 451 1.1 nia 452 1.1 nia void 453 1.1 nia rsu_free_rx_list(struct rsu_softc *sc) 454 1.1 nia { 455 1.1 nia int i; 456 1.1 nia 457 1.1 nia /* NB: Caller must abort pipe first. */ 458 1.1 nia for (i = 0; i < RSU_RX_LIST_COUNT; i++) { 459 1.1 nia if (sc->rx_data[i].xfer != NULL) 460 1.1 nia usbd_destroy_xfer(sc->rx_data[i].xfer); 461 1.1 nia sc->rx_data[i].xfer = NULL; 462 1.1 nia } 463 1.1 nia } 464 1.1 nia 465 1.1 nia int 466 1.1 nia rsu_alloc_tx_list(struct rsu_softc *sc) 467 1.1 nia { 468 1.1 nia struct rsu_tx_data *data; 469 1.1 nia int i, error = 0; 470 1.1 nia 471 1.1 nia mutex_enter(&sc->sc_tx_mtx); 472 1.1 nia TAILQ_INIT(&sc->tx_free_list); 473 1.1 nia for (i = 0; i < RSU_TX_LIST_COUNT; i++) { 474 1.1 nia data = &sc->tx_data[i]; 475 1.1 nia 476 1.1 nia data->sc = sc; /* Backpointer for callbacks. */ 477 1.1 nia 478 1.1 nia error = usbd_create_xfer(data->pipe, 479 1.1 nia RSU_TXBUFSZ, USBD_FORCE_SHORT_XFER, 0, 480 1.1 nia &data->xfer); 481 1.1 nia if (error) { 482 1.1 nia printf("%s: could not allocate xfer\n", 483 1.1 nia device_xname(sc->sc_dev)); 484 1.1 nia error = ENOMEM; 485 1.1 nia break; 486 1.1 nia } 487 1.1 nia data->buf = usbd_get_buffer(data->xfer); 488 1.1 nia 489 1.1 nia /* Append this Tx buffer to our free list. */ 490 1.1 nia TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next); 491 1.1 nia } 492 1.1 nia if (error != 0) 493 1.1 nia rsu_free_tx_list(sc); 494 1.1 nia 495 1.1 nia mutex_exit(&sc->sc_tx_mtx); 496 1.1 nia return (error); 497 1.1 nia } 498 1.1 nia 499 1.1 nia void 500 1.1 nia rsu_free_tx_list(struct rsu_softc *sc) 501 1.1 nia { 502 1.1 nia struct usbd_xfer *xfer; 503 1.1 nia int i; 504 1.1 nia 505 1.1 nia /* NB: Caller must abort pipe first. */ 506 1.1 nia for (i = 0; i < RSU_TX_LIST_COUNT; i++) { 507 1.1 nia xfer = atomic_swap_ptr(&sc->tx_data[i].xfer, NULL); 508 1.1 nia if (xfer != NULL) 509 1.1 nia usbd_destroy_xfer(xfer); 510 1.1 nia } 511 1.1 nia } 512 1.1 nia 513 1.1 nia void 514 1.1 nia rsu_task(void *arg) 515 1.1 nia { 516 1.1 nia struct rsu_softc *sc = arg; 517 1.1 nia struct rsu_host_cmd_ring *ring = &sc->cmdq; 518 1.1 nia struct rsu_host_cmd *cmd; 519 1.1 nia int s; 520 1.1 nia 521 1.1 nia /* Process host commands. */ 522 1.1 nia s = splusb(); 523 1.1 nia mutex_spin_enter(&sc->sc_task_mtx); 524 1.1 nia 525 1.1 nia while (ring->next != ring->cur) { 526 1.1 nia cmd = &ring->cmd[ring->next]; 527 1.1 nia splx(s); 528 1.1 nia membar_consumer(); 529 1.1 nia /* Invoke callback. */ 530 1.1 nia cmd->cb(sc, cmd->data); 531 1.1 nia s = splusb(); 532 1.1 nia atomic_dec_uint(&ring->queued); 533 1.1 nia ring->next = (ring->next + 1) % RSU_HOST_CMD_RING_COUNT; 534 1.1 nia } 535 1.1 nia 536 1.1 nia mutex_spin_exit(&sc->sc_task_mtx); 537 1.1 nia splx(s); 538 1.1 nia } 539 1.1 nia 540 1.1 nia void 541 1.1 nia rsu_do_async(struct rsu_softc *sc, 542 1.1 nia void (*cb)(struct rsu_softc *, void *), void *arg, int len) 543 1.1 nia { 544 1.1 nia struct rsu_host_cmd_ring *ring = &sc->cmdq; 545 1.1 nia struct rsu_host_cmd *cmd; 546 1.1 nia bool schedtask = false; 547 1.1 nia int s; 548 1.1 nia 549 1.1 nia s = splusb(); 550 1.1 nia mutex_spin_enter(&sc->sc_task_mtx); 551 1.1 nia 552 1.1 nia cmd = &ring->cmd[ring->cur]; 553 1.1 nia cmd->cb = cb; 554 1.1 nia KASSERT(len <= sizeof(cmd->data)); 555 1.1 nia memcpy(cmd->data, arg, len); 556 1.1 nia ring->cur = (ring->cur + 1) % RSU_HOST_CMD_RING_COUNT; 557 1.1 nia 558 1.1 nia /* If there is no pending command already, schedule a task. */ 559 1.1 nia if (atomic_inc_uint_nv(&ring->queued) == 1) 560 1.1 nia schedtask = true; 561 1.1 nia 562 1.1 nia mutex_spin_exit(&sc->sc_task_mtx); 563 1.1 nia splx(s); 564 1.1 nia 565 1.1 nia if (schedtask) 566 1.1 nia usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); 567 1.1 nia } 568 1.1 nia 569 1.1 nia void 570 1.1 nia rsu_wait_async(struct rsu_softc *sc) 571 1.1 nia { 572 1.1 nia /* Wait for all queued asynchronous commands to complete. */ 573 1.1 nia mutex_spin_enter(&sc->sc_task_mtx); 574 1.1 nia while (sc->cmdq.queued > 0) 575 1.1 nia cv_wait(&sc->sc_task_cv, &sc->sc_task_mtx); 576 1.1 nia mutex_spin_exit(&sc->sc_task_mtx); 577 1.1 nia } 578 1.1 nia 579 1.1 nia int 580 1.1 nia rsu_write_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf, 581 1.1 nia int len) 582 1.1 nia { 583 1.1 nia usb_device_request_t req; 584 1.1 nia 585 1.1 nia req.bmRequestType = UT_WRITE_VENDOR_DEVICE; 586 1.1 nia req.bRequest = R92S_REQ_REGS; 587 1.1 nia USETW(req.wValue, addr); 588 1.1 nia USETW(req.wIndex, 0); 589 1.1 nia USETW(req.wLength, len); 590 1.1 nia return (usbd_do_request(sc->sc_udev, &req, buf)); 591 1.1 nia } 592 1.1 nia 593 1.1 nia void 594 1.1 nia rsu_write_1(struct rsu_softc *sc, uint16_t addr, uint8_t val) 595 1.1 nia { 596 1.1 nia rsu_write_region_1(sc, addr, &val, 1); 597 1.1 nia } 598 1.1 nia 599 1.1 nia void 600 1.1 nia rsu_write_2(struct rsu_softc *sc, uint16_t addr, uint16_t val) 601 1.1 nia { 602 1.1 nia val = htole16(val); 603 1.1 nia rsu_write_region_1(sc, addr, (uint8_t *)&val, 2); 604 1.1 nia } 605 1.1 nia 606 1.1 nia void 607 1.1 nia rsu_write_4(struct rsu_softc *sc, uint16_t addr, uint32_t val) 608 1.1 nia { 609 1.1 nia val = htole32(val); 610 1.1 nia rsu_write_region_1(sc, addr, (uint8_t *)&val, 4); 611 1.1 nia } 612 1.1 nia 613 1.1 nia int 614 1.1 nia rsu_read_region_1(struct rsu_softc *sc, uint16_t addr, uint8_t *buf, 615 1.1 nia int len) 616 1.1 nia { 617 1.1 nia usb_device_request_t req; 618 1.1 nia 619 1.1 nia req.bmRequestType = UT_READ_VENDOR_DEVICE; 620 1.1 nia req.bRequest = R92S_REQ_REGS; 621 1.1 nia USETW(req.wValue, addr); 622 1.1 nia USETW(req.wIndex, 0); 623 1.1 nia USETW(req.wLength, len); 624 1.1 nia return (usbd_do_request(sc->sc_udev, &req, buf)); 625 1.1 nia } 626 1.1 nia 627 1.1 nia uint8_t 628 1.1 nia rsu_read_1(struct rsu_softc *sc, uint16_t addr) 629 1.1 nia { 630 1.1 nia uint8_t val; 631 1.1 nia 632 1.1 nia if (rsu_read_region_1(sc, addr, &val, 1) != 0) 633 1.1 nia return (0xff); 634 1.1 nia return (val); 635 1.1 nia } 636 1.1 nia 637 1.1 nia uint16_t 638 1.1 nia rsu_read_2(struct rsu_softc *sc, uint16_t addr) 639 1.1 nia { 640 1.1 nia uint16_t val; 641 1.1 nia 642 1.1 nia if (rsu_read_region_1(sc, addr, (uint8_t *)&val, 2) != 0) 643 1.1 nia return (0xffff); 644 1.1 nia return (le16toh(val)); 645 1.1 nia } 646 1.1 nia 647 1.1 nia uint32_t 648 1.1 nia rsu_read_4(struct rsu_softc *sc, uint16_t addr) 649 1.1 nia { 650 1.1 nia uint32_t val; 651 1.1 nia 652 1.1 nia if (rsu_read_region_1(sc, addr, (uint8_t *)&val, 4) != 0) 653 1.1 nia return (0xffffffff); 654 1.1 nia return (le32toh(val)); 655 1.1 nia } 656 1.1 nia 657 1.1 nia int 658 1.1 nia rsu_fw_iocmd(struct rsu_softc *sc, uint32_t iocmd) 659 1.1 nia { 660 1.1 nia int ntries; 661 1.1 nia 662 1.1 nia rsu_write_4(sc, R92S_IOCMD_CTRL, iocmd); 663 1.1 nia DELAY(100); 664 1.1 nia for (ntries = 0; ntries < 50; ntries++) { 665 1.1 nia if (rsu_read_4(sc, R92S_IOCMD_CTRL) == 0) 666 1.1 nia return (0); 667 1.1 nia DELAY(10); 668 1.1 nia } 669 1.1 nia return (ETIMEDOUT); 670 1.1 nia } 671 1.1 nia 672 1.1 nia uint8_t 673 1.1 nia rsu_efuse_read_1(struct rsu_softc *sc, uint16_t addr) 674 1.1 nia { 675 1.1 nia uint32_t reg; 676 1.1 nia int ntries; 677 1.1 nia 678 1.1 nia reg = rsu_read_4(sc, R92S_EFUSE_CTRL); 679 1.1 nia reg = RW(reg, R92S_EFUSE_CTRL_ADDR, addr); 680 1.1 nia reg &= ~R92S_EFUSE_CTRL_VALID; 681 1.1 nia rsu_write_4(sc, R92S_EFUSE_CTRL, reg); 682 1.1 nia /* Wait for read operation to complete. */ 683 1.1 nia for (ntries = 0; ntries < 100; ntries++) { 684 1.1 nia reg = rsu_read_4(sc, R92S_EFUSE_CTRL); 685 1.1 nia if (reg & R92S_EFUSE_CTRL_VALID) 686 1.1 nia return (MS(reg, R92S_EFUSE_CTRL_DATA)); 687 1.1 nia DELAY(5); 688 1.1 nia } 689 1.1 nia printf("%s: could not read efuse byte at address 0x%x\n", 690 1.1 nia device_xname(sc->sc_dev), addr); 691 1.1 nia return (0xff); 692 1.1 nia } 693 1.1 nia 694 1.1 nia int 695 1.1 nia rsu_read_rom(struct rsu_softc *sc) 696 1.1 nia { 697 1.1 nia uint8_t *rom = sc->rom; 698 1.1 nia uint16_t addr = 0; 699 1.1 nia uint32_t reg; 700 1.1 nia uint8_t off, msk; 701 1.1 nia int i; 702 1.1 nia 703 1.1 nia /* Make sure that ROM type is eFuse and that autoload succeeded. */ 704 1.1 nia reg = rsu_read_1(sc, R92S_EE_9346CR); 705 1.1 nia if ((reg & (R92S_9356SEL | R92S_EEPROM_EN)) != R92S_EEPROM_EN) 706 1.1 nia return (EIO); 707 1.1 nia 708 1.1 nia /* Turn on 2.5V to prevent eFuse leakage. */ 709 1.1 nia reg = rsu_read_1(sc, R92S_EFUSE_TEST + 3); 710 1.1 nia rsu_write_1(sc, R92S_EFUSE_TEST + 3, reg | 0x80); 711 1.1 nia usbd_delay_ms(sc->sc_udev, 10); 712 1.1 nia rsu_write_1(sc, R92S_EFUSE_TEST + 3, reg & ~0x80); 713 1.1 nia 714 1.1 nia /* Read full ROM image. */ 715 1.1 nia memset(&sc->rom, 0xff, sizeof(sc->rom)); 716 1.1 nia while (addr < 512) { 717 1.1 nia reg = rsu_efuse_read_1(sc, addr); 718 1.1 nia if (reg == 0xff) 719 1.1 nia break; 720 1.1 nia addr++; 721 1.1 nia off = reg >> 4; 722 1.1 nia msk = reg & 0xf; 723 1.1 nia for (i = 0; i < 4; i++) { 724 1.1 nia if (msk & (1 << i)) 725 1.1 nia continue; 726 1.1 nia rom[off * 8 + i * 2 + 0] = 727 1.1 nia rsu_efuse_read_1(sc, addr); 728 1.1 nia addr++; 729 1.1 nia rom[off * 8 + i * 2 + 1] = 730 1.1 nia rsu_efuse_read_1(sc, addr); 731 1.1 nia addr++; 732 1.1 nia } 733 1.1 nia } 734 1.1 nia 735 1.1 nia #ifdef RSU_DEBUG 736 1.1 nia if (rsu_debug >= 5) { 737 1.1 nia /* Dump ROM content. */ 738 1.1 nia printf("\n"); 739 1.1 nia for (i = 0; i < sizeof(sc->rom); i++) 740 1.1 nia printf("%02x:", rom[i]); 741 1.1 nia printf("\n"); 742 1.1 nia } 743 1.1 nia #endif 744 1.1 nia return (0); 745 1.1 nia } 746 1.1 nia 747 1.1 nia int 748 1.1 nia rsu_fw_cmd(struct rsu_softc *sc, uint8_t code, void *buf, int len) 749 1.1 nia { 750 1.1 nia struct rsu_tx_data *data; 751 1.1 nia struct r92s_tx_desc *txd; 752 1.1 nia struct r92s_fw_cmd_hdr *cmd; 753 1.1 nia int cmdsz, xferlen; 754 1.1 nia 755 1.1 nia data = sc->fwcmd_data; 756 1.1 nia 757 1.1 nia /* Round-up command length to a multiple of 8 bytes. */ 758 1.1 nia cmdsz = (len + 7) & ~7; 759 1.1 nia 760 1.1 nia xferlen = sizeof(*txd) + sizeof(*cmd) + cmdsz; 761 1.1 nia KASSERT(xferlen <= RSU_TXBUFSZ); 762 1.1 nia memset(data->buf, 0, xferlen); 763 1.1 nia 764 1.1 nia /* Setup Tx descriptor. */ 765 1.1 nia txd = (struct r92s_tx_desc *)data->buf; 766 1.1 nia txd->txdw0 = htole32( 767 1.1 nia SM(R92S_TXDW0_OFFSET, sizeof(*txd)) | 768 1.1 nia SM(R92S_TXDW0_PKTLEN, sizeof(*cmd) + cmdsz) | 769 1.1 nia R92S_TXDW0_OWN | R92S_TXDW0_FSG | R92S_TXDW0_LSG); 770 1.1 nia txd->txdw1 = htole32(SM(R92S_TXDW1_QSEL, R92S_TXDW1_QSEL_H2C)); 771 1.1 nia 772 1.1 nia /* Setup command header. */ 773 1.1 nia cmd = (struct r92s_fw_cmd_hdr *)&txd[1]; 774 1.1 nia cmd->len = htole16(cmdsz); 775 1.1 nia cmd->code = code; 776 1.1 nia cmd->seq = sc->cmd_seq; 777 1.1 nia sc->cmd_seq = (sc->cmd_seq + 1) & 0x7f; 778 1.1 nia 779 1.1 nia /* Copy command payload. */ 780 1.1 nia memcpy(&cmd[1], buf, len); 781 1.1 nia 782 1.1 nia DPRINTFN(2, ("Tx cmd code=%d len=%d\n", code, cmdsz)); 783 1.1 nia /*pipe = sc->pipe[sc->qid2idx[RSU_QID_H2C]];*/ 784 1.1 nia usbd_setup_xfer(data->xfer, data, data->buf, xferlen, 785 1.1 nia USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS, 786 1.1 nia RSU_CMD_TIMEOUT, NULL); 787 1.1 nia return (usbd_transfer(data->xfer)); 788 1.1 nia } 789 1.1 nia 790 1.1 nia int 791 1.1 nia rsu_media_change(struct ifnet *ifp) 792 1.1 nia { 793 1.1 nia int error; 794 1.1 nia 795 1.1 nia error = ieee80211_media_change(ifp); 796 1.1 nia if (error != ENETRESET) 797 1.1 nia return (error); 798 1.1 nia 799 1.1 nia if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 800 1.1 nia (IFF_UP | IFF_RUNNING)) { 801 1.1 nia rsu_stop(ifp); 802 1.1 nia error = rsu_init(ifp); 803 1.1 nia } 804 1.1 nia return (error); 805 1.1 nia } 806 1.1 nia 807 1.1 nia void 808 1.1 nia rsu_calib_to(void *arg) 809 1.1 nia { 810 1.1 nia struct rsu_softc *sc = arg; 811 1.1 nia 812 1.1 nia /* Do it in a process context. */ 813 1.1 nia rsu_do_async(sc, rsu_calib_cb, NULL, 0); 814 1.1 nia } 815 1.1 nia 816 1.1 nia void 817 1.1 nia rsu_calib_cb(struct rsu_softc *sc, void *arg) 818 1.1 nia { 819 1.1 nia uint32_t reg; 820 1.1 nia 821 1.1 nia #ifdef notyet 822 1.1 nia /* Read WPS PBC status. */ 823 1.1 nia rsu_write_1(sc, R92S_MAC_PINMUX_CTRL, 824 1.1 nia R92S_GPIOMUX_EN | SM(R92S_GPIOSEL_GPIO, R92S_GPIOSEL_GPIO_JTAG)); 825 1.1 nia rsu_write_1(sc, R92S_GPIO_IO_SEL, 826 1.1 nia rsu_read_1(sc, R92S_GPIO_IO_SEL) & ~R92S_GPIO_WPS); 827 1.1 nia reg = rsu_read_1(sc, R92S_GPIO_CTRL); 828 1.1 nia if (reg != 0xff && (reg & R92S_GPIO_WPS)) 829 1.1 nia DPRINTF(("WPS PBC is pushed\n")); 830 1.1 nia #endif 831 1.1 nia 832 1.1 nia /* Read current signal level. */ 833 1.1 nia if (rsu_fw_iocmd(sc, 0xf4000001) == 0) { 834 1.1 nia reg = rsu_read_4(sc, R92S_IOCMD_DATA); 835 1.1 nia DPRINTFN(8, ("RSSI=%d%%\n", reg >> 4)); 836 1.1 nia } 837 1.1 nia (void)reg; 838 1.1 nia 839 1.1 nia callout_schedule(&sc->calib_to, hz); 840 1.1 nia } 841 1.1 nia 842 1.1 nia int 843 1.1 nia rsu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 844 1.1 nia { 845 1.1 nia struct rsu_softc *sc = ic->ic_ifp->if_softc; 846 1.1 nia struct rsu_cmd_newstate cmd; 847 1.1 nia 848 1.1 nia callout_stop(&sc->calib_to); 849 1.1 nia 850 1.1 nia /* Do it in a process context. */ 851 1.1 nia cmd.state = nstate; 852 1.1 nia cmd.arg = arg; 853 1.1 nia rsu_do_async(sc, rsu_newstate_cb, &cmd, sizeof(cmd)); 854 1.1 nia return (0); 855 1.1 nia } 856 1.1 nia 857 1.1 nia void 858 1.1 nia rsu_newstate_cb(struct rsu_softc *sc, void *arg) 859 1.1 nia { 860 1.1 nia struct rsu_cmd_newstate *cmd = arg; 861 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 862 1.1 nia struct ifnet *ifp = sc->sc_ic.ic_ifp; 863 1.1 nia enum ieee80211_state ostate; 864 1.1 nia int error, s; 865 1.1 nia 866 1.1 nia s = splnet(); 867 1.1 nia ostate = ic->ic_state; 868 1.1 nia 869 1.1 nia if (ostate == IEEE80211_S_RUN) { 870 1.1 nia /* Stop calibration. */ 871 1.1 nia callout_halt(&sc->calib_to, NULL); 872 1.1 nia /* Disassociate from our current BSS. */ 873 1.1 nia (void)rsu_disconnect(sc); 874 1.1 nia } 875 1.1 nia switch (cmd->state) { 876 1.1 nia case IEEE80211_S_INIT: 877 1.1 nia break; 878 1.1 nia case IEEE80211_S_SCAN: 879 1.1 nia error = rsu_site_survey(sc); 880 1.1 nia if (error != 0) { 881 1.1 nia printf("%s: could not send site survey command\n", 882 1.1 nia device_xname(sc->sc_dev)); 883 1.1 nia } 884 1.1 nia if (ifp->if_flags & IFF_DEBUG) 885 1.1 nia printf("%s: %s -> %s\n", ifp->if_xname, 886 1.1 nia ieee80211_state_name[ic->ic_state], 887 1.1 nia ieee80211_state_name[cmd->state]); 888 1.1 nia ic->ic_state = cmd->state; 889 1.1 nia splx(s); 890 1.1 nia return; 891 1.1 nia case IEEE80211_S_AUTH: 892 1.1 nia ic->ic_state = cmd->state; 893 1.1 nia splx(s); 894 1.1 nia return; 895 1.1 nia case IEEE80211_S_ASSOC: 896 1.1 nia /* No-op for this driver. See rsu_event_join_bss(). */ 897 1.1 nia if (ifp->if_flags & IFF_DEBUG) 898 1.1 nia printf("%s: %s -> %s\n", ifp->if_xname, 899 1.1 nia ieee80211_state_name[ic->ic_state], 900 1.1 nia ieee80211_state_name[cmd->state]); 901 1.1 nia ic->ic_state = cmd->state; 902 1.1 nia splx(s); 903 1.1 nia return; 904 1.1 nia case IEEE80211_S_RUN: 905 1.1 nia /* Indicate highest supported rate. */ 906 1.1 nia ic->ic_bss->ni_txrate = ic->ic_bss->ni_rates.rs_nrates - 1; 907 1.1 nia 908 1.1 nia /* Start periodic calibration. */ 909 1.1 nia callout_schedule(&sc->calib_to, hz); 910 1.1 nia break; 911 1.1 nia } 912 1.1 nia (void)sc->sc_newstate(ic, cmd->state, cmd->arg); 913 1.1 nia splx(s); 914 1.1 nia } 915 1.1 nia 916 1.1 nia int 917 1.1 nia rsu_site_survey(struct rsu_softc *sc) 918 1.1 nia { 919 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 920 1.1 nia struct r92s_fw_cmd_sitesurvey cmd; 921 1.1 nia 922 1.1 nia memset(&cmd, 0, sizeof(cmd)); 923 1.1 nia if ((ic->ic_flags & IEEE80211_F_ASCAN) || sc->scan_pass == 1) 924 1.1 nia cmd.active = htole32(1); 925 1.1 nia cmd.limit = htole32(48); 926 1.1 nia if (sc->scan_pass == 1) { 927 1.1 nia /* Do a directed scan for second pass. */ 928 1.1 nia cmd.ssidlen = htole32(ic->ic_des_esslen); 929 1.1 nia memcpy(cmd.ssid, ic->ic_des_essid, ic->ic_des_esslen); 930 1.1 nia } 931 1.1 nia DPRINTF(("sending site survey command, pass=%d\n", sc->scan_pass)); 932 1.1 nia return (rsu_fw_cmd(sc, R92S_CMD_SITE_SURVEY, &cmd, sizeof(cmd))); 933 1.1 nia } 934 1.1 nia 935 1.1 nia int 936 1.1 nia rsu_join_bss(struct rsu_softc *sc, struct ieee80211_node *ni) 937 1.1 nia { 938 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 939 1.1 nia struct ndis_wlan_bssid_ex *bss; 940 1.1 nia struct ndis_802_11_fixed_ies *fixed; 941 1.1 nia struct r92s_fw_cmd_auth auth; 942 1.1 nia uint8_t buf[sizeof(*bss) + 128], *frm; 943 1.1 nia uint8_t opmode; 944 1.1 nia int error; 945 1.1 nia 946 1.1 nia /* Let the FW decide the opmode based on the capinfo field. */ 947 1.1 nia opmode = NDIS802_11AUTOUNKNOWN; 948 1.1 nia DPRINTF(("setting operating mode to %d\n", opmode)); 949 1.1 nia error = rsu_fw_cmd(sc, R92S_CMD_SET_OPMODE, &opmode, sizeof(opmode)); 950 1.1 nia if (error != 0) 951 1.1 nia return (error); 952 1.1 nia 953 1.1 nia memset(&auth, 0, sizeof(auth)); 954 1.1 nia auth.mode = R92S_AUTHMODE_OPEN; 955 1.1 nia DPRINTF(("setting auth mode to %d\n", auth.mode)); 956 1.1 nia error = rsu_fw_cmd(sc, R92S_CMD_SET_AUTH, &auth, sizeof(auth)); 957 1.1 nia if (error != 0) 958 1.1 nia return (error); 959 1.1 nia 960 1.1 nia memset(buf, 0, sizeof(buf)); 961 1.1 nia bss = (struct ndis_wlan_bssid_ex *)buf; 962 1.1 nia IEEE80211_ADDR_COPY(bss->macaddr, ni->ni_bssid); 963 1.1 nia bss->ssid.ssidlen = htole32(ni->ni_esslen); 964 1.1 nia memcpy(bss->ssid.ssid, ni->ni_essid, ni->ni_esslen); 965 1.1 nia bss->rssi = htole32(ni->ni_rssi); 966 1.1 nia if (ic->ic_curmode == IEEE80211_MODE_11B) 967 1.1 nia bss->networktype = htole32(NDIS802_11DS); 968 1.1 nia else 969 1.1 nia bss->networktype = htole32(NDIS802_11OFDM24); 970 1.1 nia bss->config.len = htole32(sizeof(bss->config)); 971 1.1 nia bss->config.bintval = htole32(ni->ni_intval); 972 1.1 nia bss->config.dsconfig = htole32(ieee80211_chan2ieee(ic, ni->ni_chan)); 973 1.1 nia bss->inframode = htole32(NDIS802_11INFRASTRUCTURE); 974 1.1 nia memcpy(bss->supprates, ni->ni_rates.rs_rates, 975 1.1 nia ni->ni_rates.rs_nrates); 976 1.1 nia /* Write the fixed fields of the beacon frame. */ 977 1.1 nia fixed = (struct ndis_802_11_fixed_ies *)&bss[1]; 978 1.1 nia memcpy(&fixed->tstamp, ni->ni_tstamp.data, 8); 979 1.1 nia fixed->bintval = htole16(ni->ni_intval); 980 1.1 nia fixed->capabilities = htole16(ni->ni_capinfo); 981 1.1 nia /* Write IEs to be included in the association request. */ 982 1.1 nia frm = (uint8_t *)&fixed[1]; 983 1.1 nia bss->ieslen = htole32(frm - (uint8_t *)fixed); 984 1.1 nia bss->len = htole32(((frm - buf) + 3) & ~3); 985 1.1 nia DPRINTF(("sending join bss command to %s chan %d\n", 986 1.1 nia ether_sprintf(bss->macaddr), le32toh(bss->config.dsconfig))); 987 1.1 nia return (rsu_fw_cmd(sc, R92S_CMD_JOIN_BSS, buf, sizeof(buf))); 988 1.1 nia } 989 1.1 nia 990 1.1 nia int 991 1.1 nia rsu_disconnect(struct rsu_softc *sc) 992 1.1 nia { 993 1.1 nia uint32_t zero = 0; /* :-) */ 994 1.1 nia 995 1.1 nia /* Disassociate from our current BSS. */ 996 1.1 nia DPRINTF(("sending disconnect command\n")); 997 1.1 nia return (rsu_fw_cmd(sc, R92S_CMD_DISCONNECT, &zero, sizeof(zero))); 998 1.1 nia } 999 1.1 nia 1000 1.1 nia void 1001 1.1 nia rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) 1002 1.1 nia { 1003 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 1004 1.1 nia struct ieee80211_node *ni; 1005 1.1 nia struct ieee80211_frame *wh; 1006 1.1 nia struct ndis_wlan_bssid_ex *bss; 1007 1.1 nia struct mbuf *m; 1008 1.1 nia uint32_t pktlen, ieslen; 1009 1.1 nia 1010 1.1 nia if (__predict_false(len < sizeof(*bss))) 1011 1.1 nia return; 1012 1.1 nia bss = (struct ndis_wlan_bssid_ex *)buf; 1013 1.1 nia ieslen = le32toh(bss->ieslen); 1014 1.1 nia if (ieslen > len - sizeof(*bss)) 1015 1.1 nia return; 1016 1.1 nia 1017 1.1 nia DPRINTFN(2, ("found BSS %s: len=%d chan=%d inframode=%d " 1018 1.1 nia "networktype=%d privacy=%d\n", 1019 1.1 nia ether_sprintf(bss->macaddr), le32toh(bss->len), 1020 1.1 nia le32toh(bss->config.dsconfig), le32toh(bss->inframode), 1021 1.1 nia le32toh(bss->networktype), le32toh(bss->privacy))); 1022 1.1 nia 1023 1.1 nia /* Build a fake beacon frame to let net80211 do all the parsing. */ 1024 1.1 nia pktlen = sizeof(*wh) + ieslen; 1025 1.1 nia if (__predict_false(pktlen > MCLBYTES)) 1026 1.1 nia return; 1027 1.1 nia MGETHDR(m, M_DONTWAIT, MT_DATA); 1028 1.1 nia if (__predict_false(m == NULL)) 1029 1.1 nia return; 1030 1.1 nia if (pktlen > MHLEN) { 1031 1.1 nia MCLGET(m, M_DONTWAIT); 1032 1.1 nia if (!(m->m_flags & M_EXT)) { 1033 1.1 nia m_free(m); 1034 1.1 nia return; 1035 1.1 nia } 1036 1.1 nia } 1037 1.1 nia wh = mtod(m, struct ieee80211_frame *); 1038 1.1 nia wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | 1039 1.1 nia IEEE80211_FC0_SUBTYPE_BEACON; 1040 1.1 nia wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 1041 1.1 nia *(uint16_t *)wh->i_dur = 0; 1042 1.1 nia IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr); 1043 1.1 nia IEEE80211_ADDR_COPY(wh->i_addr2, bss->macaddr); 1044 1.1 nia IEEE80211_ADDR_COPY(wh->i_addr3, bss->macaddr); 1045 1.1 nia *(uint16_t *)wh->i_seq = 0; 1046 1.1 nia memcpy(&wh[1], (uint8_t *)&bss[1], ieslen); 1047 1.1 nia 1048 1.1 nia /* Finalize mbuf. */ 1049 1.1 nia m->m_pkthdr.len = m->m_len = pktlen; 1050 1.1 nia 1051 1.1 nia ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 1052 1.1 nia ieee80211_input(ic, m, ni, le32toh(bss->rssi), 0); 1053 1.1 nia /* Node is no longer needed. */ 1054 1.1 nia ieee80211_free_node(ni); 1055 1.1 nia } 1056 1.1 nia 1057 1.1 nia void 1058 1.1 nia rsu_event_join_bss(struct rsu_softc *sc, uint8_t *buf, int len) 1059 1.1 nia { 1060 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 1061 1.1 nia struct ieee80211_node *ni = ic->ic_bss; 1062 1.1 nia struct r92s_event_join_bss *rsp; 1063 1.1 nia int res; 1064 1.1 nia 1065 1.1 nia if (__predict_false(len < sizeof(*rsp))) 1066 1.1 nia return; 1067 1.1 nia rsp = (struct r92s_event_join_bss *)buf; 1068 1.1 nia res = (int)le32toh(rsp->join_res); 1069 1.1 nia 1070 1.1 nia DPRINTF(("Rx join BSS event len=%d res=%d\n", len, res)); 1071 1.1 nia if (res <= 0) { 1072 1.1 nia ic->ic_stats.is_rx_auth_fail++; 1073 1.1 nia ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 1074 1.1 nia return; 1075 1.1 nia } 1076 1.1 nia DPRINTF(("associated with %s associd=%d\n", 1077 1.1 nia ether_sprintf(rsp->bss.macaddr), le32toh(rsp->associd))); 1078 1.1 nia 1079 1.1 nia ni->ni_associd = le32toh(rsp->associd) | 0xc000; 1080 1.1 nia 1081 1.1 nia /* Force an ASSOC->RUN transition. AUTH->RUN is invalid. */ 1082 1.1 nia ic->ic_state = IEEE80211_S_ASSOC; 1083 1.1 nia ieee80211_new_state(ic, IEEE80211_S_RUN, 1084 1.1 nia IEEE80211_FC0_SUBTYPE_ASSOC_RESP); 1085 1.1 nia } 1086 1.1 nia 1087 1.1 nia void 1088 1.1 nia rsu_rx_event(struct rsu_softc *sc, uint8_t code, uint8_t *buf, int len) 1089 1.1 nia { 1090 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 1091 1.1 nia struct ifnet *ifp = sc->sc_ic.ic_ifp; 1092 1.1 nia 1093 1.1 nia DPRINTFN(4, ("Rx event code=%d len=%d\n", code, len)); 1094 1.1 nia switch (code) { 1095 1.1 nia case R92S_EVT_SURVEY: 1096 1.1 nia if (ic->ic_state == IEEE80211_S_SCAN) 1097 1.1 nia rsu_event_survey(sc, buf, len); 1098 1.1 nia break; 1099 1.1 nia case R92S_EVT_SURVEY_DONE: 1100 1.1 nia DPRINTF(("site survey pass %d done, found %d BSS\n", 1101 1.1 nia sc->scan_pass, le32toh(*(uint32_t *)buf))); 1102 1.1 nia if (ic->ic_state != IEEE80211_S_SCAN) 1103 1.1 nia break; /* Ignore if not scanning. */ 1104 1.1 nia if (sc->scan_pass == 0 && ic->ic_des_esslen != 0) { 1105 1.1 nia /* Schedule a directed scan for hidden APs. */ 1106 1.1 nia sc->scan_pass = 1; 1107 1.1 nia ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 1108 1.1 nia break; 1109 1.1 nia } 1110 1.1 nia sc->scan_pass = 0; 1111 1.1 nia break; 1112 1.1 nia case R92S_EVT_JOIN_BSS: 1113 1.1 nia if (ic->ic_state == IEEE80211_S_AUTH) 1114 1.1 nia rsu_event_join_bss(sc, buf, len); 1115 1.1 nia break; 1116 1.1 nia case R92S_EVT_DEL_STA: 1117 1.1 nia DPRINTF(("disassociated from %s\n", ether_sprintf(buf))); 1118 1.1 nia if (ic->ic_state == IEEE80211_S_RUN && 1119 1.1 nia IEEE80211_ADDR_EQ(ic->ic_bss->ni_bssid, buf)) 1120 1.1 nia ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 1121 1.1 nia break; 1122 1.1 nia case R92S_EVT_WPS_PBC: 1123 1.1 nia DPRINTF(("WPS PBC pushed.\n")); 1124 1.1 nia break; 1125 1.1 nia case R92S_EVT_FWDBG: 1126 1.1 nia if (ifp->if_flags & IFF_DEBUG) { 1127 1.1 nia buf[60] = '\0'; 1128 1.1 nia printf("FWDBG: %s\n", (char *)buf); 1129 1.1 nia } 1130 1.1 nia break; 1131 1.1 nia } 1132 1.1 nia } 1133 1.1 nia 1134 1.1 nia void 1135 1.1 nia rsu_rx_multi_event(struct rsu_softc *sc, uint8_t *buf, int len) 1136 1.1 nia { 1137 1.1 nia struct r92s_fw_cmd_hdr *cmd; 1138 1.1 nia int cmdsz; 1139 1.1 nia 1140 1.1 nia DPRINTFN(6, ("Rx events len=%d\n", len)); 1141 1.1 nia 1142 1.1 nia /* Skip Rx status. */ 1143 1.1 nia buf += sizeof(struct r92s_rx_stat); 1144 1.1 nia len -= sizeof(struct r92s_rx_stat); 1145 1.1 nia 1146 1.1 nia /* Process all events. */ 1147 1.1 nia for (;;) { 1148 1.1 nia /* Check that command header fits. */ 1149 1.1 nia if (__predict_false(len < sizeof(*cmd))) 1150 1.1 nia break; 1151 1.1 nia cmd = (struct r92s_fw_cmd_hdr *)buf; 1152 1.1 nia /* Check that command payload fits. */ 1153 1.1 nia cmdsz = le16toh(cmd->len); 1154 1.1 nia if (__predict_false(len < sizeof(*cmd) + cmdsz)) 1155 1.1 nia break; 1156 1.1 nia if (cmdsz > len) 1157 1.1 nia break; 1158 1.1 nia 1159 1.1 nia /* Process firmware event. */ 1160 1.1 nia rsu_rx_event(sc, cmd->code, (uint8_t *)&cmd[1], cmdsz); 1161 1.1 nia 1162 1.1 nia if (!(cmd->seq & R92S_FW_CMD_MORE)) 1163 1.1 nia break; 1164 1.1 nia buf += sizeof(*cmd) + cmdsz; 1165 1.1 nia len -= sizeof(*cmd) + cmdsz; 1166 1.1 nia } 1167 1.1 nia } 1168 1.1 nia 1169 1.1 nia int8_t 1170 1.1 nia rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt) 1171 1.1 nia { 1172 1.1 nia static const int8_t cckoff[] = { 14, -2, -20, -40 }; 1173 1.1 nia struct r92s_rx_phystat *phy; 1174 1.1 nia struct r92s_rx_cck *cck; 1175 1.1 nia uint8_t rpt; 1176 1.1 nia int8_t rssi; 1177 1.1 nia 1178 1.1 nia if (rate <= 3) { 1179 1.1 nia cck = (struct r92s_rx_cck *)physt; 1180 1.1 nia rpt = (cck->agc_rpt >> 6) & 0x3; 1181 1.1 nia rssi = cck->agc_rpt & 0x3e; 1182 1.1 nia rssi = cckoff[rpt] - rssi; 1183 1.1 nia } else { /* OFDM/HT. */ 1184 1.1 nia phy = (struct r92s_rx_phystat *)physt; 1185 1.1 nia rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 106; 1186 1.1 nia } 1187 1.1 nia return (rssi); 1188 1.1 nia } 1189 1.1 nia 1190 1.1 nia void 1191 1.1 nia rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen) 1192 1.1 nia { 1193 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 1194 1.1 nia struct ifnet *ifp = sc->sc_ic.ic_ifp; 1195 1.1 nia struct ieee80211_frame *wh; 1196 1.1 nia struct ieee80211_node *ni; 1197 1.1 nia struct r92s_rx_stat *stat; 1198 1.1 nia uint32_t rxdw0, rxdw3; 1199 1.1 nia struct mbuf *m; 1200 1.1 nia uint8_t rate; 1201 1.1 nia int8_t rssi = 0; 1202 1.1 nia int s, infosz; 1203 1.1 nia 1204 1.1 nia stat = (struct r92s_rx_stat *)buf; 1205 1.1 nia rxdw0 = le32toh(stat->rxdw0); 1206 1.1 nia rxdw3 = le32toh(stat->rxdw3); 1207 1.1 nia 1208 1.1 nia if (__predict_false(rxdw0 & R92S_RXDW0_CRCERR)) { 1209 1.1 nia if_statinc(ifp, if_ierrors); 1210 1.1 nia return; 1211 1.1 nia } 1212 1.1 nia if (__predict_false(pktlen < sizeof(*wh) || pktlen > MCLBYTES)) { 1213 1.1 nia if_statinc(ifp, if_ierrors); 1214 1.1 nia return; 1215 1.1 nia } 1216 1.1 nia 1217 1.1 nia rate = MS(rxdw3, R92S_RXDW3_RATE); 1218 1.1 nia infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8; 1219 1.1 nia 1220 1.1 nia /* Get RSSI from PHY status descriptor if present. */ 1221 1.1 nia if (infosz != 0) 1222 1.1 nia rssi = rsu_get_rssi(sc, rate, &stat[1]); 1223 1.1 nia 1224 1.1 nia DPRINTFN(5, ("Rx frame len=%d rate=%d infosz=%d rssi=%d\n", 1225 1.1 nia pktlen, rate, infosz, rssi)); 1226 1.1 nia 1227 1.1 nia MGETHDR(m, M_DONTWAIT, MT_DATA); 1228 1.1 nia if (__predict_false(m == NULL)) { 1229 1.1 nia if_statinc(ifp, if_ierrors); 1230 1.1 nia return; 1231 1.1 nia } 1232 1.1 nia if (pktlen > MHLEN) { 1233 1.1 nia MCLGET(m, M_DONTWAIT); 1234 1.1 nia if (__predict_false(!(m->m_flags & M_EXT))) { 1235 1.1 nia if_statinc(ifp, if_ierrors); 1236 1.1 nia m_freem(m); 1237 1.1 nia return; 1238 1.1 nia } 1239 1.1 nia } 1240 1.1 nia /* Finalize mbuf. */ 1241 1.1 nia m_set_rcvif(m, ifp); 1242 1.1 nia 1243 1.1 nia /* Hardware does Rx TCP checksum offload. */ 1244 1.1 nia if (rxdw3 & R92S_RXDW3_TCPCHKVALID) { 1245 1.1 nia if (__predict_true(rxdw3 & R92S_RXDW3_TCPCHKRPT)) 1246 1.1 nia m->m_pkthdr.csum_flags |= M_CSUM_TCPv4; 1247 1.1 nia else 1248 1.1 nia m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD; 1249 1.1 nia } 1250 1.1 nia wh = (struct ieee80211_frame *)((uint8_t *)&stat[1] + infosz); 1251 1.1 nia memcpy(mtod(m, uint8_t *), wh, pktlen); 1252 1.1 nia m->m_pkthdr.len = m->m_len = pktlen; 1253 1.1 nia 1254 1.1 nia s = splnet(); 1255 1.1 nia 1256 1.1 nia ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); 1257 1.1 nia ieee80211_input(ic, m, ni, rssi, 0); 1258 1.1 nia /* Node is no longer needed. */ 1259 1.1 nia ieee80211_free_node(ni); 1260 1.1 nia splx(s); 1261 1.1 nia } 1262 1.1 nia 1263 1.1 nia void 1264 1.1 nia rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len) 1265 1.1 nia { 1266 1.1 nia struct r92s_rx_stat *stat; 1267 1.1 nia uint32_t rxdw0; 1268 1.1 nia int totlen, pktlen, infosz, npkts; 1269 1.1 nia 1270 1.1 nia /* Get the number of encapsulated frames. */ 1271 1.1 nia stat = (struct r92s_rx_stat *)buf; 1272 1.1 nia npkts = MS(le32toh(stat->rxdw2), R92S_RXDW2_PKTCNT); 1273 1.1 nia DPRINTFN(6, ("Rx %d frames in one chunk\n", npkts)); 1274 1.1 nia 1275 1.1 nia /* Process all of them. */ 1276 1.1 nia while (npkts-- > 0) { 1277 1.1 nia if (__predict_false(len < sizeof(*stat))) 1278 1.1 nia break; 1279 1.1 nia stat = (struct r92s_rx_stat *)buf; 1280 1.1 nia rxdw0 = le32toh(stat->rxdw0); 1281 1.1 nia 1282 1.1 nia pktlen = MS(rxdw0, R92S_RXDW0_PKTLEN); 1283 1.1 nia if (__predict_false(pktlen == 0)) 1284 1.1 nia break; 1285 1.1 nia 1286 1.1 nia infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8; 1287 1.1 nia 1288 1.1 nia /* Make sure everything fits in xfer. */ 1289 1.1 nia totlen = sizeof(*stat) + infosz + pktlen; 1290 1.1 nia if (__predict_false(totlen > len)) 1291 1.1 nia break; 1292 1.1 nia 1293 1.1 nia /* Process 802.11 frame. */ 1294 1.1 nia rsu_rx_frame(sc, buf, pktlen); 1295 1.1 nia 1296 1.1 nia /* Next chunk is 128-byte aligned. */ 1297 1.1 nia totlen = (totlen + 127) & ~127; 1298 1.1 nia buf += totlen; 1299 1.1 nia len -= totlen; 1300 1.1 nia } 1301 1.1 nia } 1302 1.1 nia 1303 1.1 nia void 1304 1.1 nia rsu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1305 1.1 nia { 1306 1.1 nia struct rsu_rx_data *data = priv; 1307 1.1 nia struct rsu_softc *sc = data->sc; 1308 1.1 nia struct r92s_rx_stat *stat; 1309 1.1 nia struct ifnet *ifp = sc->sc_ic.ic_ifp; 1310 1.1 nia int len; 1311 1.1 nia 1312 1.1 nia if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1313 1.1 nia DPRINTF(("RX status=%d\n", status)); 1314 1.1 nia if (status == USBD_STALLED) 1315 1.1 nia usbd_clear_endpoint_stall_async(data->pipe); 1316 1.1 nia if (status != USBD_CANCELLED) 1317 1.1 nia goto resubmit; 1318 1.1 nia return; 1319 1.1 nia } 1320 1.1 nia usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1321 1.1 nia 1322 1.1 nia if (__predict_false(len < sizeof(*stat))) { 1323 1.1 nia DPRINTF(("xfer too short %d\n", len)); 1324 1.1 nia if_statinc(ifp, if_ierrors); 1325 1.1 nia goto resubmit; 1326 1.1 nia } 1327 1.1 nia if (len > RSU_RXBUFSZ) { 1328 1.1 nia DPRINTF(("xfer too large %d\n", len)); 1329 1.1 nia if_statinc(ifp, if_ierrors); 1330 1.1 nia goto resubmit; 1331 1.1 nia } 1332 1.1 nia 1333 1.1 nia /* Determine if it is a firmware C2H event or an 802.11 frame. */ 1334 1.1 nia stat = (struct r92s_rx_stat *)data->buf; 1335 1.1 nia if ((le32toh(stat->rxdw1) & 0x1ff) == 0x1ff) 1336 1.1 nia rsu_rx_multi_event(sc, data->buf, len); 1337 1.1 nia else 1338 1.1 nia rsu_rx_multi_frame(sc, data->buf, len); 1339 1.1 nia 1340 1.1 nia resubmit: 1341 1.1 nia /* Setup a new transfer. */ 1342 1.1 nia usbd_setup_xfer(xfer, data, data->buf, RSU_RXBUFSZ, 1343 1.1 nia USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rsu_rxeof); 1344 1.1 nia (void)usbd_transfer(xfer); 1345 1.1 nia } 1346 1.1 nia 1347 1.1 nia void 1348 1.1 nia rsu_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1349 1.1 nia { 1350 1.1 nia struct rsu_tx_data *data = priv; 1351 1.1 nia struct rsu_softc *sc = data->sc; 1352 1.1 nia struct ifnet *ifp = sc->sc_ic.ic_ifp; 1353 1.1 nia int s; 1354 1.1 nia 1355 1.1 nia s = splnet(); 1356 1.1 nia 1357 1.1 nia /* Put this Tx buffer back to our free list. */ 1358 1.1 nia mutex_enter(&sc->sc_tx_mtx); 1359 1.1 nia TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next); 1360 1.1 nia mutex_exit(&sc->sc_tx_mtx); 1361 1.1 nia 1362 1.1 nia if (__predict_false(status != USBD_NORMAL_COMPLETION)) { 1363 1.1 nia if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1364 1.1 nia return; 1365 1.1 nia 1366 1.1 nia DPRINTF(("TX status=%d\n", status)); 1367 1.1 nia if (status == USBD_STALLED) 1368 1.1 nia usbd_clear_endpoint_stall_async(data->pipe); 1369 1.1 nia if_statinc(ifp, if_oerrors); 1370 1.1 nia splx(s); 1371 1.1 nia return; 1372 1.1 nia } 1373 1.1 nia sc->sc_tx_timer = 0; 1374 1.1 nia 1375 1.1 nia /* We just released a Tx buffer, notify Tx. */ 1376 1.1 nia if (ifp->if_flags & IFF_OACTIVE) { 1377 1.1 nia ifp->if_flags &= ~IFF_OACTIVE; 1378 1.1 nia rsu_start(ifp); 1379 1.1 nia } 1380 1.1 nia splx(s); 1381 1.1 nia } 1382 1.1 nia 1383 1.1 nia int 1384 1.1 nia rsu_tx(struct rsu_softc *sc, struct mbuf *m, struct ieee80211_node *ni) 1385 1.1 nia { 1386 1.1 nia struct ieee80211_frame *wh; 1387 1.1 nia struct rsu_tx_data *data; 1388 1.1 nia struct r92s_tx_desc *txd; 1389 1.1 nia struct usbd_pipe *pipe; 1390 1.1 nia uint16_t qos; 1391 1.1 nia uint8_t qid, tid = 0; 1392 1.1 nia int hasqos, xferlen, error; 1393 1.1 nia 1394 1.1 nia wh = mtod(m, struct ieee80211_frame *); 1395 1.1 nia 1396 1.1 nia #ifdef notyet 1397 1.1 nia if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) { 1398 1.1 nia k = ieee80211_get_txkey(ic, wh, ni); 1399 1.1 nia if ((m = ieee80211_encrypt(ic, m, k)) == NULL) 1400 1.1 nia return (ENOBUFS); 1401 1.1 nia wh = mtod(m, struct ieee80211_frame *); 1402 1.1 nia } 1403 1.1 nia #endif 1404 1.1 nia 1405 1.1 nia if ((hasqos = ieee80211_has_qos(wh))) { 1406 1.1 nia qos = ieee80211_get_qos(wh); 1407 1.1 nia tid = qos & IEEE80211_QOS_TID; 1408 1.1 nia qid = rsu_ac2qid[TID_TO_WME_AC(tid)]; 1409 1.1 nia } else 1410 1.1 nia qid = RSU_QID_BE; 1411 1.1 nia 1412 1.1 nia /* Get the USB pipe to use for this queue id. */ 1413 1.1 nia pipe = sc->pipe[sc->qid2idx[qid]]; 1414 1.1 nia 1415 1.1 nia /* Grab a Tx buffer from our free list. */ 1416 1.1 nia mutex_enter(&sc->sc_tx_mtx); 1417 1.1 nia data = TAILQ_FIRST(&sc->tx_free_list); 1418 1.1 nia TAILQ_REMOVE(&sc->tx_free_list, data, next); 1419 1.1 nia mutex_exit(&sc->sc_tx_mtx); 1420 1.1 nia 1421 1.1 nia /* Fill Tx descriptor. */ 1422 1.1 nia txd = (struct r92s_tx_desc *)data->buf; 1423 1.1 nia memset(txd, 0, sizeof(*txd)); 1424 1.1 nia 1425 1.1 nia txd->txdw0 |= htole32( 1426 1.1 nia SM(R92S_TXDW0_PKTLEN, m->m_pkthdr.len) | 1427 1.1 nia SM(R92S_TXDW0_OFFSET, sizeof(*txd)) | 1428 1.1 nia R92S_TXDW0_OWN | R92S_TXDW0_FSG | R92S_TXDW0_LSG); 1429 1.1 nia 1430 1.1 nia txd->txdw1 |= htole32( 1431 1.1 nia SM(R92S_TXDW1_MACID, R92S_MACID_BSS) | 1432 1.1 nia SM(R92S_TXDW1_QSEL, R92S_TXDW1_QSEL_BE)); 1433 1.1 nia if (!hasqos) 1434 1.1 nia txd->txdw1 |= htole32(R92S_TXDW1_NONQOS); 1435 1.1 nia #ifdef notyet 1436 1.1 nia if (k != NULL) { 1437 1.1 nia switch (k->k_cipher) { 1438 1.1 nia case IEEE80211_CIPHER_WEP: 1439 1.1 nia k->wk_flags |= IEEE80211_KEY_GROUP; /* XXX */ 1440 1.1 nia if (k->wk_keylen == 5) 1441 1.1 nia mode = RT2860_MODE_WEP40; 1442 1.1 nia else 1443 1.1 nia mode = RT2860_MODE_WEP104; 1444 1.1 nia break; 1445 1.1 nia case IEEE80211_CIPHER_TKIP: 1446 1.1 nia cipher = R92S_TXDW1_CIPHER_TKIP; 1447 1.1 nia break; 1448 1.1 nia case IEEE80211_CIPHER_AES_CCM: 1449 1.1 nia cipher = R92S_TXDW1_CIPHER_AES; 1450 1.1 nia break; 1451 1.1 nia default: 1452 1.1 nia cipher = R92S_TXDW1_CIPHER_NONE; 1453 1.1 nia } 1454 1.1 nia txd->txdw1 |= htole32( 1455 1.1 nia SM(R92S_TXDW1_CIPHER, cipher) | 1456 1.1 nia SM(R92S_TXDW1_KEYIDX, k->k_id)); 1457 1.1 nia } 1458 1.1 nia #endif 1459 1.1 nia txd->txdw2 |= htole32(R92S_TXDW2_BK); 1460 1.1 nia if (IEEE80211_IS_MULTICAST(wh->i_addr1)) 1461 1.1 nia txd->txdw2 |= htole32(R92S_TXDW2_BMCAST); 1462 1.1 nia /* 1463 1.1 nia * Firmware will use and increment the sequence number for the 1464 1.1 nia * specified TID. 1465 1.1 nia */ 1466 1.1 nia txd->txdw3 |= htole32(SM(R92S_TXDW3_SEQ, tid)); 1467 1.1 nia 1468 1.1 nia xferlen = sizeof(*txd) + m->m_pkthdr.len; 1469 1.1 nia m_copydata(m, 0, m->m_pkthdr.len, &txd[1]); 1470 1.1 nia m_freem(m); 1471 1.1 nia 1472 1.1 nia data->pipe = pipe; 1473 1.1 nia usbd_setup_xfer(data->xfer, data, data->buf, xferlen, 1474 1.1 nia USBD_FORCE_SHORT_XFER, RSU_TX_TIMEOUT, 1475 1.1 nia rsu_txeof); 1476 1.1 nia error = usbd_transfer(data->xfer); 1477 1.1 nia if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) { 1478 1.1 nia /* Put this Tx buffer back to our free list. */ 1479 1.1 nia mutex_enter(&sc->sc_tx_mtx); 1480 1.1 nia TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next); 1481 1.1 nia mutex_exit(&sc->sc_tx_mtx); 1482 1.1 nia return (error); 1483 1.1 nia } 1484 1.1 nia ieee80211_free_node(ni); 1485 1.1 nia return (0); 1486 1.1 nia } 1487 1.1 nia 1488 1.1 nia void 1489 1.1 nia rsu_start(struct ifnet *ifp) 1490 1.1 nia { 1491 1.1 nia struct rsu_softc *sc = ifp->if_softc; 1492 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 1493 1.1 nia struct ether_header *eh; 1494 1.1 nia struct ieee80211_node *ni; 1495 1.1 nia struct mbuf *m; 1496 1.1 nia 1497 1.1 nia if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 1498 1.1 nia return; 1499 1.1 nia 1500 1.1 nia for (;;) { 1501 1.1 nia if (TAILQ_EMPTY(&sc->tx_free_list)) { 1502 1.1 nia ifp->if_flags |= IFF_OACTIVE; 1503 1.1 nia break; 1504 1.1 nia } 1505 1.1 nia if (ic->ic_state != IEEE80211_S_RUN) 1506 1.1 nia break; 1507 1.1 nia 1508 1.1 nia /* Encapsulate and send data frames. */ 1509 1.1 nia IFQ_DEQUEUE(&ifp->if_snd, m); 1510 1.1 nia if (m == NULL) 1511 1.1 nia break; 1512 1.1 nia 1513 1.1 nia eh = mtod(m, struct ether_header *); 1514 1.1 nia ni = ieee80211_find_txnode(ic, eh->ether_dhost); 1515 1.1 nia if (ni == NULL) { 1516 1.1 nia m_freem(m); 1517 1.1 nia if_statinc(ifp, if_oerrors); 1518 1.1 nia continue; 1519 1.1 nia } 1520 1.1 nia 1521 1.1 nia if ((m = ieee80211_encap(ic, m, ni)) == NULL) { 1522 1.1 nia ieee80211_free_node(ni); 1523 1.1 nia if_statinc(ifp, if_oerrors); 1524 1.1 nia continue; 1525 1.1 nia } 1526 1.1 nia 1527 1.1 nia if (rsu_tx(sc, m, ni) != 0) { 1528 1.1 nia ieee80211_free_node(ni); 1529 1.1 nia if_statinc(ifp, if_oerrors); 1530 1.1 nia continue; 1531 1.1 nia } 1532 1.1 nia 1533 1.1 nia sc->sc_tx_timer = 5; 1534 1.1 nia ifp->if_timer = 1; 1535 1.1 nia } 1536 1.1 nia } 1537 1.1 nia 1538 1.1 nia void 1539 1.1 nia rsu_watchdog(struct ifnet *ifp) 1540 1.1 nia { 1541 1.1 nia struct rsu_softc *sc = ifp->if_softc; 1542 1.1 nia 1543 1.1 nia ifp->if_timer = 0; 1544 1.1 nia 1545 1.1 nia if (sc->sc_tx_timer > 0) { 1546 1.1 nia if (--sc->sc_tx_timer == 0) { 1547 1.1 nia printf("%s: device timeout\n", 1548 1.1 nia device_xname(sc->sc_dev)); 1549 1.1 nia /* rsu_init(ifp); XXX needs a process context! */ 1550 1.1 nia if_statinc(ifp, if_oerrors); 1551 1.1 nia return; 1552 1.1 nia } 1553 1.1 nia ifp->if_timer = 1; 1554 1.1 nia } 1555 1.1 nia ieee80211_watchdog(&sc->sc_ic); 1556 1.1 nia } 1557 1.1 nia 1558 1.1 nia int 1559 1.1 nia rsu_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1560 1.1 nia { 1561 1.1 nia struct rsu_softc *sc = ifp->if_softc; 1562 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 1563 1.1 nia int s, error = 0; 1564 1.1 nia 1565 1.1 nia s = splnet(); 1566 1.1 nia 1567 1.1 nia switch (cmd) { 1568 1.1 nia case SIOCSIFADDR: 1569 1.1 nia ifp->if_flags |= IFF_UP; 1570 1.1 nia /* FALLTHROUGH */ 1571 1.1 nia case SIOCSIFFLAGS: 1572 1.1 nia switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 1573 1.1 nia case IFF_UP|IFF_RUNNING: 1574 1.1 nia break; 1575 1.1 nia case IFF_UP: 1576 1.1 nia rsu_init(ifp); 1577 1.1 nia break; 1578 1.1 nia case IFF_RUNNING: 1579 1.1 nia rsu_stop(ifp); 1580 1.1 nia break; 1581 1.1 nia case 0: 1582 1.1 nia break; 1583 1.1 nia } 1584 1.1 nia break; 1585 1.1 nia default: 1586 1.1 nia error = ieee80211_ioctl(ic, cmd, data); 1587 1.1 nia } 1588 1.1 nia 1589 1.1 nia if (error == ENETRESET) { 1590 1.1 nia if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == 1591 1.1 nia (IFF_UP | IFF_RUNNING)) { 1592 1.1 nia rsu_stop(ifp); 1593 1.1 nia rsu_init(ifp); 1594 1.1 nia } 1595 1.1 nia error = 0; 1596 1.1 nia } 1597 1.1 nia splx(s); 1598 1.1 nia 1599 1.1 nia return (error); 1600 1.1 nia } 1601 1.1 nia 1602 1.1 nia /* 1603 1.1 nia * Power on sequence for A-cut adapters. 1604 1.1 nia */ 1605 1.1 nia void 1606 1.1 nia rsu_power_on_acut(struct rsu_softc *sc) 1607 1.1 nia { 1608 1.1 nia uint32_t reg; 1609 1.1 nia 1610 1.1 nia rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x53); 1611 1.1 nia rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x57); 1612 1.1 nia 1613 1.1 nia /* Enable AFE macro block's bandgap and Mbias. */ 1614 1.1 nia rsu_write_1(sc, R92S_AFE_MISC, 1615 1.1 nia rsu_read_1(sc, R92S_AFE_MISC) | 1616 1.1 nia R92S_AFE_MISC_BGEN | R92S_AFE_MISC_MBEN); 1617 1.1 nia /* Enable LDOA15 block. */ 1618 1.1 nia rsu_write_1(sc, R92S_LDOA15_CTRL, 1619 1.1 nia rsu_read_1(sc, R92S_LDOA15_CTRL) | R92S_LDA15_EN); 1620 1.1 nia 1621 1.1 nia rsu_write_1(sc, R92S_SPS1_CTRL, 1622 1.1 nia rsu_read_1(sc, R92S_SPS1_CTRL) | R92S_SPS1_LDEN); 1623 1.1 nia usbd_delay_ms(sc->sc_udev, 2); 1624 1.1 nia /* Enable switch regulator block. */ 1625 1.1 nia rsu_write_1(sc, R92S_SPS1_CTRL, 1626 1.1 nia rsu_read_1(sc, R92S_SPS1_CTRL) | R92S_SPS1_SWEN); 1627 1.1 nia 1628 1.1 nia rsu_write_4(sc, R92S_SPS1_CTRL, 0x00a7b267); 1629 1.1 nia 1630 1.1 nia rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1, 1631 1.1 nia rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) | 0x08); 1632 1.1 nia 1633 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 1634 1.1 nia rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x20); 1635 1.1 nia 1636 1.1 nia rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1, 1637 1.1 nia rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) & ~0x90); 1638 1.1 nia 1639 1.1 nia /* Enable AFE clock. */ 1640 1.1 nia rsu_write_1(sc, R92S_AFE_XTAL_CTRL + 1, 1641 1.1 nia rsu_read_1(sc, R92S_AFE_XTAL_CTRL + 1) & ~0x04); 1642 1.1 nia /* Enable AFE PLL macro block. */ 1643 1.1 nia rsu_write_1(sc, R92S_AFE_PLL_CTRL, 1644 1.1 nia rsu_read_1(sc, R92S_AFE_PLL_CTRL) | 0x11); 1645 1.1 nia /* Attach AFE PLL to MACTOP/BB. */ 1646 1.1 nia rsu_write_1(sc, R92S_SYS_ISO_CTRL, 1647 1.1 nia rsu_read_1(sc, R92S_SYS_ISO_CTRL) & ~0x11); 1648 1.1 nia 1649 1.1 nia /* Switch to 40MHz clock instead of 80MHz. */ 1650 1.1 nia rsu_write_2(sc, R92S_SYS_CLKR, 1651 1.1 nia rsu_read_2(sc, R92S_SYS_CLKR) & ~R92S_SYS_CLKSEL); 1652 1.1 nia 1653 1.1 nia /* Enable MAC clock. */ 1654 1.1 nia rsu_write_2(sc, R92S_SYS_CLKR, 1655 1.1 nia rsu_read_2(sc, R92S_SYS_CLKR) | 1656 1.1 nia R92S_MAC_CLK_EN | R92S_SYS_CLK_EN); 1657 1.1 nia 1658 1.1 nia rsu_write_1(sc, R92S_PMC_FSM, 0x02); 1659 1.1 nia 1660 1.1 nia /* Enable digital core and IOREG R/W. */ 1661 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 1662 1.1 nia rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x08); 1663 1.1 nia 1664 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 1665 1.1 nia rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x80); 1666 1.1 nia 1667 1.1 nia /* Switch the control path to firmware. */ 1668 1.1 nia reg = rsu_read_2(sc, R92S_SYS_CLKR); 1669 1.1 nia reg = (reg & ~R92S_SWHW_SEL) | R92S_FWHW_SEL; 1670 1.1 nia rsu_write_2(sc, R92S_SYS_CLKR, reg); 1671 1.1 nia 1672 1.1 nia rsu_write_2(sc, R92S_CR, 0x37fc); 1673 1.1 nia 1674 1.1 nia /* Fix USB RX FIFO issue. */ 1675 1.1 nia rsu_write_1(sc, 0xfe5c, 1676 1.1 nia rsu_read_1(sc, 0xfe5c) | 0x80); 1677 1.1 nia rsu_write_1(sc, 0x00ab, 1678 1.1 nia rsu_read_1(sc, 0x00ab) | 0xc0); 1679 1.1 nia 1680 1.1 nia rsu_write_1(sc, R92S_SYS_CLKR, 1681 1.1 nia rsu_read_1(sc, R92S_SYS_CLKR) & ~R92S_SYS_CPU_CLKSEL); 1682 1.1 nia } 1683 1.1 nia 1684 1.1 nia /* 1685 1.1 nia * Power on sequence for B-cut and C-cut adapters. 1686 1.1 nia */ 1687 1.1 nia void 1688 1.1 nia rsu_power_on_bcut(struct rsu_softc *sc) 1689 1.1 nia { 1690 1.1 nia uint32_t reg; 1691 1.1 nia int ntries; 1692 1.1 nia 1693 1.1 nia /* Prevent eFuse leakage. */ 1694 1.1 nia rsu_write_1(sc, 0x37, 0xb0); 1695 1.1 nia usbd_delay_ms(sc->sc_udev, 10); 1696 1.1 nia rsu_write_1(sc, 0x37, 0x30); 1697 1.1 nia 1698 1.1 nia /* Switch the control path to hardware. */ 1699 1.1 nia reg = rsu_read_2(sc, R92S_SYS_CLKR); 1700 1.1 nia if (reg & R92S_FWHW_SEL) { 1701 1.1 nia rsu_write_2(sc, R92S_SYS_CLKR, 1702 1.1 nia reg & ~(R92S_SWHW_SEL | R92S_FWHW_SEL)); 1703 1.1 nia } 1704 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 1705 1.1 nia rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) & ~0x8c); 1706 1.1 nia usbd_delay_ms(sc->sc_udev, 10); 1707 1.1 nia 1708 1.1 nia rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x53); 1709 1.1 nia rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x57); 1710 1.1 nia 1711 1.1 nia reg = rsu_read_1(sc, R92S_AFE_MISC); 1712 1.1 nia rsu_write_1(sc, R92S_AFE_MISC, reg | R92S_AFE_MISC_BGEN); 1713 1.1 nia rsu_write_1(sc, R92S_AFE_MISC, reg | R92S_AFE_MISC_BGEN | 1714 1.1 nia R92S_AFE_MISC_MBEN | R92S_AFE_MISC_I32_EN); 1715 1.1 nia 1716 1.1 nia /* Enable PLL. */ 1717 1.1 nia rsu_write_1(sc, R92S_LDOA15_CTRL, 1718 1.1 nia rsu_read_1(sc, R92S_LDOA15_CTRL) | R92S_LDA15_EN); 1719 1.1 nia 1720 1.1 nia rsu_write_1(sc, R92S_LDOV12D_CTRL, 1721 1.1 nia rsu_read_1(sc, R92S_LDOV12D_CTRL) | R92S_LDV12_EN); 1722 1.1 nia 1723 1.1 nia rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1, 1724 1.1 nia rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) | 0x08); 1725 1.1 nia 1726 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 1727 1.1 nia rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x20); 1728 1.1 nia 1729 1.1 nia /* Support 64KB IMEM. */ 1730 1.1 nia rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1, 1731 1.1 nia rsu_read_1(sc, R92S_SYS_ISO_CTRL + 1) & ~0x97); 1732 1.1 nia 1733 1.1 nia /* Enable AFE clock. */ 1734 1.1 nia rsu_write_1(sc, R92S_AFE_XTAL_CTRL + 1, 1735 1.1 nia rsu_read_1(sc, R92S_AFE_XTAL_CTRL + 1) & ~0x04); 1736 1.1 nia /* Enable AFE PLL macro block. */ 1737 1.1 nia reg = rsu_read_1(sc, R92S_AFE_PLL_CTRL); 1738 1.1 nia rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x11); 1739 1.1 nia usbd_delay_ms(sc->sc_udev, 5); 1740 1.1 nia rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x51); 1741 1.1 nia usbd_delay_ms(sc->sc_udev, 5); 1742 1.1 nia rsu_write_1(sc, R92S_AFE_PLL_CTRL, reg | 0x11); 1743 1.1 nia usbd_delay_ms(sc->sc_udev, 5); 1744 1.1 nia 1745 1.1 nia /* Attach AFE PLL to MACTOP/BB. */ 1746 1.1 nia rsu_write_1(sc, R92S_SYS_ISO_CTRL, 1747 1.1 nia rsu_read_1(sc, R92S_SYS_ISO_CTRL) & ~0x11); 1748 1.1 nia 1749 1.1 nia /* Switch to 40MHz clock. */ 1750 1.1 nia rsu_write_1(sc, R92S_SYS_CLKR, 0x00); 1751 1.1 nia /* Disable CPU clock and 80MHz SSC. */ 1752 1.1 nia rsu_write_1(sc, R92S_SYS_CLKR, 1753 1.1 nia rsu_read_1(sc, R92S_SYS_CLKR) | 0xa0); 1754 1.1 nia /* Enable MAC clock. */ 1755 1.1 nia rsu_write_2(sc, R92S_SYS_CLKR, 1756 1.1 nia rsu_read_2(sc, R92S_SYS_CLKR) | 1757 1.1 nia R92S_MAC_CLK_EN | R92S_SYS_CLK_EN); 1758 1.1 nia 1759 1.1 nia rsu_write_1(sc, R92S_PMC_FSM, 0x02); 1760 1.1 nia 1761 1.1 nia /* Enable digital core and IOREG R/W. */ 1762 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 1763 1.1 nia rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x08); 1764 1.1 nia 1765 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 1766 1.1 nia rsu_read_1(sc, R92S_SYS_FUNC_EN + 1) | 0x80); 1767 1.1 nia 1768 1.1 nia /* Switch the control path to firmware. */ 1769 1.1 nia reg = rsu_read_2(sc, R92S_SYS_CLKR); 1770 1.1 nia reg = (reg & ~R92S_SWHW_SEL) | R92S_FWHW_SEL; 1771 1.1 nia rsu_write_2(sc, R92S_SYS_CLKR, reg); 1772 1.1 nia 1773 1.1 nia rsu_write_2(sc, R92S_CR, 0x37fc); 1774 1.1 nia 1775 1.1 nia /* Fix USB RX FIFO issue. */ 1776 1.1 nia rsu_write_1(sc, 0xfe5c, 1777 1.1 nia rsu_read_1(sc, 0xfe5c) | 0x80); 1778 1.1 nia 1779 1.1 nia rsu_write_1(sc, R92S_SYS_CLKR, 1780 1.1 nia rsu_read_1(sc, R92S_SYS_CLKR) & ~R92S_SYS_CPU_CLKSEL); 1781 1.1 nia 1782 1.1 nia rsu_write_1(sc, 0xfe1c, 0x80); 1783 1.1 nia 1784 1.1 nia /* Make sure TxDMA is ready to download firmware. */ 1785 1.1 nia for (ntries = 0; ntries < 20; ntries++) { 1786 1.1 nia reg = rsu_read_1(sc, R92S_TCR); 1787 1.1 nia if ((reg & (R92S_TCR_IMEM_CHK_RPT | R92S_TCR_EMEM_CHK_RPT)) == 1788 1.1 nia (R92S_TCR_IMEM_CHK_RPT | R92S_TCR_EMEM_CHK_RPT)) 1789 1.1 nia break; 1790 1.1 nia DELAY(5); 1791 1.1 nia } 1792 1.1 nia if (ntries == 20) { 1793 1.1 nia /* Reset TxDMA. */ 1794 1.1 nia reg = rsu_read_1(sc, R92S_CR); 1795 1.1 nia rsu_write_1(sc, R92S_CR, reg & ~R92S_CR_TXDMA_EN); 1796 1.1 nia DELAY(2); 1797 1.1 nia rsu_write_1(sc, R92S_CR, reg | R92S_CR_TXDMA_EN); 1798 1.1 nia } 1799 1.1 nia } 1800 1.1 nia 1801 1.1 nia void 1802 1.1 nia rsu_power_off(struct rsu_softc *sc) 1803 1.1 nia { 1804 1.1 nia /* Turn RF off. */ 1805 1.1 nia rsu_write_1(sc, R92S_RF_CTRL, 0x00); 1806 1.1 nia usbd_delay_ms(sc->sc_udev, 5); 1807 1.1 nia 1808 1.1 nia /* Turn MAC off. */ 1809 1.1 nia /* Switch control path. */ 1810 1.1 nia rsu_write_1(sc, R92S_SYS_CLKR + 1, 0x38); 1811 1.1 nia /* Reset MACTOP. */ 1812 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 0x70); 1813 1.1 nia rsu_write_1(sc, R92S_PMC_FSM, 0x06); 1814 1.1 nia rsu_write_1(sc, R92S_SYS_ISO_CTRL + 0, 0xf9); 1815 1.1 nia rsu_write_1(sc, R92S_SYS_ISO_CTRL + 1, 0xe8); 1816 1.1 nia 1817 1.1 nia /* Disable AFE PLL. */ 1818 1.1 nia rsu_write_1(sc, R92S_AFE_PLL_CTRL, 0x00); 1819 1.1 nia /* Disable A15V. */ 1820 1.1 nia rsu_write_1(sc, R92S_LDOA15_CTRL, 0x54); 1821 1.1 nia /* Disable eFuse 1.2V. */ 1822 1.1 nia rsu_write_1(sc, R92S_SYS_FUNC_EN + 1, 0x50); 1823 1.1 nia rsu_write_1(sc, R92S_LDOV12D_CTRL, 0x24); 1824 1.1 nia /* Enable AFE macro block's bandgap and Mbias. */ 1825 1.1 nia rsu_write_1(sc, R92S_AFE_MISC, 0x30); 1826 1.1 nia /* Disable 1.6V LDO. */ 1827 1.1 nia rsu_write_1(sc, R92S_SPS0_CTRL + 0, 0x56); 1828 1.1 nia rsu_write_1(sc, R92S_SPS0_CTRL + 1, 0x43); 1829 1.1 nia } 1830 1.1 nia 1831 1.1 nia int 1832 1.1 nia rsu_fw_loadsection(struct rsu_softc *sc, uint8_t *buf, int len) 1833 1.1 nia { 1834 1.1 nia struct rsu_tx_data *data; 1835 1.1 nia struct r92s_tx_desc *txd; 1836 1.1 nia /*struct usbd_pipe *pipe;*/ 1837 1.1 nia int mlen, error; 1838 1.1 nia 1839 1.1 nia data = sc->fwcmd_data; 1840 1.1 nia /*pipe = sc->pipe[sc->qid2idx[RSU_QID_VO]];*/ 1841 1.1 nia txd = (struct r92s_tx_desc *)data->buf; 1842 1.1 nia while (len > 0) { 1843 1.1 nia memset(txd, 0, sizeof(*txd)); 1844 1.1 nia if (len <= RSU_TXBUFSZ - sizeof(*txd)) { 1845 1.1 nia /* Last chunk. */ 1846 1.1 nia txd->txdw0 |= htole32(R92S_TXDW0_LINIP); 1847 1.1 nia mlen = len; 1848 1.1 nia } else 1849 1.1 nia mlen = RSU_TXBUFSZ - sizeof(*txd); 1850 1.1 nia txd->txdw0 |= htole32(SM(R92S_TXDW0_PKTLEN, mlen)); 1851 1.1 nia memcpy(&txd[1], buf, mlen); 1852 1.1 nia 1853 1.1 nia usbd_setup_xfer(data->xfer, data, data->buf, 1854 1.1 nia sizeof(*txd) + mlen, 1855 1.1 nia USBD_SHORT_XFER_OK | USBD_SYNCHRONOUS, 1856 1.1 nia RSU_TX_TIMEOUT, NULL); 1857 1.1 nia error = usbd_transfer(data->xfer); 1858 1.1 nia if (error != 0) 1859 1.1 nia return (error); 1860 1.1 nia buf += mlen; 1861 1.1 nia len -= mlen; 1862 1.1 nia } 1863 1.1 nia return (0); 1864 1.1 nia } 1865 1.1 nia 1866 1.1 nia int 1867 1.1 nia rsu_load_firmware(struct rsu_softc *sc) 1868 1.1 nia { 1869 1.1 nia struct r92s_fw_hdr *hdr; 1870 1.1 nia struct r92s_fw_priv *dmem; 1871 1.1 nia uint8_t *imem, *emem; 1872 1.1 nia int imemsz, ememsz; 1873 1.1 nia u_char *fw; 1874 1.1 nia size_t size; 1875 1.1 nia uint32_t reg; 1876 1.1 nia int ntries, error; 1877 1.1 nia firmware_handle_t fh; 1878 1.1 nia 1879 1.1 nia if ((error = firmware_open("rsu", "rsu-rtl8712", &fh)) != 0) { 1880 1.1 nia printf("%s: failed firmware_open of file %s (error %d)\n", 1881 1.1 nia device_xname(sc->sc_dev), "rsu-rtl8712", error); 1882 1.1 nia return error; 1883 1.1 nia } 1884 1.1 nia 1885 1.1 nia size = firmware_get_size(fh); 1886 1.1 nia if ((fw = firmware_malloc(size)) == NULL) { 1887 1.1 nia firmware_close(fh); 1888 1.1 nia return ENOMEM; 1889 1.1 nia } 1890 1.1 nia 1891 1.1 nia if ((error = firmware_read(fh, 0, fw, size)) != 0) { 1892 1.1 nia firmware_close(fh); 1893 1.1 nia goto fail; 1894 1.1 nia } 1895 1.1 nia 1896 1.1 nia firmware_close(fh); 1897 1.1 nia 1898 1.1 nia if (size < sizeof(*hdr)) { 1899 1.1 nia printf("%s: firmware too short\n", device_xname(sc->sc_dev)); 1900 1.1 nia error = EINVAL; 1901 1.1 nia goto fail; 1902 1.1 nia } 1903 1.1 nia 1904 1.1 nia hdr = (struct r92s_fw_hdr *)fw; 1905 1.1 nia if (hdr->signature != htole16(0x8712) && 1906 1.1 nia hdr->signature != htole16(0x8192)) { 1907 1.1 nia printf("%s: invalid firmware signature 0x%x\n", 1908 1.1 nia device_xname(sc->sc_dev), le16toh(hdr->signature)); 1909 1.1 nia error = EINVAL; 1910 1.1 nia goto fail; 1911 1.1 nia } 1912 1.1 nia DPRINTF(("FW V%d %02x-%02x %02x:%02x\n", le16toh(hdr->version), 1913 1.1 nia hdr->month, hdr->day, hdr->hour, hdr->minute)); 1914 1.1 nia 1915 1.1 nia /* Make sure that driver and firmware are in sync. */ 1916 1.1 nia if (hdr->privsz != htole32(sizeof(*dmem))) { 1917 1.1 nia printf("%s: unsupported firmware image\n", 1918 1.1 nia device_xname(sc->sc_dev)); 1919 1.1 nia error = EINVAL; 1920 1.1 nia goto fail; 1921 1.1 nia } 1922 1.1 nia /* Get FW sections sizes. */ 1923 1.1 nia imemsz = le32toh(hdr->imemsz); 1924 1.1 nia ememsz = le32toh(hdr->sramsz); 1925 1.1 nia /* Check that all FW sections fit in image. */ 1926 1.1 nia if (size < sizeof(*hdr) + imemsz + ememsz) { 1927 1.1 nia printf("%s: firmware too short\n", device_xname(sc->sc_dev)); 1928 1.1 nia error = EINVAL; 1929 1.1 nia goto fail; 1930 1.1 nia } 1931 1.1 nia imem = (uint8_t *)&hdr[1]; 1932 1.1 nia emem = imem + imemsz; 1933 1.1 nia 1934 1.1 nia /* Load IMEM section. */ 1935 1.1 nia error = rsu_fw_loadsection(sc, imem, imemsz); 1936 1.1 nia if (error != 0) { 1937 1.1 nia printf("%s: could not load firmware section %s\n", 1938 1.1 nia device_xname(sc->sc_dev), "IMEM"); 1939 1.1 nia goto fail; 1940 1.1 nia } 1941 1.1 nia /* Wait for load to complete. */ 1942 1.1 nia for (ntries = 0; ntries < 10; ntries++) { 1943 1.1 nia reg = rsu_read_2(sc, R92S_TCR); 1944 1.1 nia if (reg & R92S_TCR_IMEM_CODE_DONE) 1945 1.1 nia break; 1946 1.1 nia DELAY(10); 1947 1.1 nia } 1948 1.1 nia if (ntries == 10 || !(reg & R92S_TCR_IMEM_CHK_RPT)) { 1949 1.1 nia printf("%s: timeout waiting for %s transfer\n", 1950 1.1 nia device_xname(sc->sc_dev), "IMEM"); 1951 1.1 nia error = ETIMEDOUT; 1952 1.1 nia goto fail; 1953 1.1 nia } 1954 1.1 nia 1955 1.1 nia /* Load EMEM section. */ 1956 1.1 nia error = rsu_fw_loadsection(sc, emem, ememsz); 1957 1.1 nia if (error != 0) { 1958 1.1 nia printf("%s: could not load firmware section %s\n", 1959 1.1 nia device_xname(sc->sc_dev), "EMEM"); 1960 1.1 nia goto fail; 1961 1.1 nia } 1962 1.1 nia /* Wait for load to complete. */ 1963 1.1 nia for (ntries = 0; ntries < 10; ntries++) { 1964 1.1 nia reg = rsu_read_2(sc, R92S_TCR); 1965 1.1 nia if (reg & R92S_TCR_EMEM_CODE_DONE) 1966 1.1 nia break; 1967 1.1 nia DELAY(10); 1968 1.1 nia } 1969 1.1 nia if (ntries == 10 || !(reg & R92S_TCR_EMEM_CHK_RPT)) { 1970 1.1 nia printf("%s: timeout waiting for %s transfer\n", 1971 1.1 nia device_xname(sc->sc_dev), "EMEM"); 1972 1.1 nia error = ETIMEDOUT; 1973 1.1 nia goto fail; 1974 1.1 nia } 1975 1.1 nia 1976 1.1 nia /* Enable CPU. */ 1977 1.1 nia rsu_write_1(sc, R92S_SYS_CLKR, 1978 1.1 nia rsu_read_1(sc, R92S_SYS_CLKR) | R92S_SYS_CPU_CLKSEL); 1979 1.1 nia if (!(rsu_read_1(sc, R92S_SYS_CLKR) & R92S_SYS_CPU_CLKSEL)) { 1980 1.1 nia printf("%s: could not enable system clock\n", 1981 1.1 nia device_xname(sc->sc_dev)); 1982 1.1 nia error = EIO; 1983 1.1 nia goto fail; 1984 1.1 nia } 1985 1.1 nia rsu_write_2(sc, R92S_SYS_FUNC_EN, 1986 1.1 nia rsu_read_2(sc, R92S_SYS_FUNC_EN) | R92S_FEN_CPUEN); 1987 1.1 nia if (!(rsu_read_2(sc, R92S_SYS_FUNC_EN) & R92S_FEN_CPUEN)) { 1988 1.1 nia printf("%s: could not enable microcontroller\n", 1989 1.1 nia device_xname(sc->sc_dev)); 1990 1.1 nia error = EIO; 1991 1.1 nia goto fail; 1992 1.1 nia } 1993 1.1 nia 1994 1.1 nia /* Wait for CPU to initialize. */ 1995 1.1 nia for (ntries = 0; ntries < 100; ntries++) { 1996 1.1 nia if (rsu_read_2(sc, R92S_TCR) & R92S_TCR_IMEM_RDY) 1997 1.1 nia break; 1998 1.1 nia usbd_delay_ms(sc->sc_udev, 10); 1999 1.1 nia } 2000 1.1 nia if (ntries == 100) { 2001 1.1 nia printf("%s: timeout waiting for microcontroller\n", 2002 1.1 nia device_xname(sc->sc_dev)); 2003 1.1 nia error = ETIMEDOUT; 2004 1.1 nia goto fail; 2005 1.1 nia } 2006 1.1 nia 2007 1.1 nia /* Update DMEM section before loading. */ 2008 1.1 nia dmem = &hdr->priv; 2009 1.1 nia memset(dmem, 0, sizeof(*dmem)); 2010 1.1 nia dmem->hci_sel = R92S_HCI_SEL_USB | R92S_HCI_SEL_8172; 2011 1.1 nia dmem->nendpoints = sc->npipes; 2012 1.1 nia dmem->rf_config = 0x12; /* 1T2R */ 2013 1.1 nia dmem->vcs_type = R92S_VCS_TYPE_AUTO; 2014 1.1 nia dmem->vcs_mode = R92S_VCS_MODE_RTS_CTS; 2015 1.1 nia #ifdef notyet 2016 1.1 nia dmem->bw40_en = (ic->ic_htcaps & IEEE80211_HTCAP_CBW20_40) != 0; 2017 1.1 nia #else 2018 1.1 nia dmem->bw40_en = 0; 2019 1.1 nia #endif 2020 1.1 nia dmem->turbo_mode = 1; 2021 1.1 nia /* Load DMEM section. */ 2022 1.1 nia error = rsu_fw_loadsection(sc, (uint8_t *)dmem, sizeof(*dmem)); 2023 1.1 nia if (error != 0) { 2024 1.1 nia printf("%s: could not load firmware section %s\n", 2025 1.1 nia device_xname(sc->sc_dev), "DMEM"); 2026 1.1 nia goto fail; 2027 1.1 nia } 2028 1.1 nia /* Wait for load to complete. */ 2029 1.1 nia for (ntries = 0; ntries < 100; ntries++) { 2030 1.1 nia if (rsu_read_2(sc, R92S_TCR) & R92S_TCR_DMEM_CODE_DONE) 2031 1.1 nia break; 2032 1.1 nia DELAY(1000); 2033 1.1 nia } 2034 1.1 nia if (ntries == 100) { 2035 1.1 nia printf("%s: timeout waiting for %s transfer\n", 2036 1.1 nia device_xname(sc->sc_dev), "DMEM"); 2037 1.1 nia error = ETIMEDOUT; 2038 1.1 nia goto fail; 2039 1.1 nia } 2040 1.1 nia /* Wait for firmware readiness. */ 2041 1.1 nia for (ntries = 0; ntries < 60; ntries++) { 2042 1.1 nia if (!(rsu_read_2(sc, R92S_TCR) & R92S_TCR_FWRDY)) 2043 1.1 nia break; 2044 1.1 nia usbd_delay_ms(sc->sc_udev, 10); 2045 1.1 nia } 2046 1.1 nia if (ntries == 60) { 2047 1.1 nia printf("%s: timeout waiting for firmware readiness\n", 2048 1.1 nia device_xname(sc->sc_dev)); 2049 1.1 nia error = ETIMEDOUT; 2050 1.1 nia goto fail; 2051 1.1 nia } 2052 1.1 nia fail: 2053 1.1 nia firmware_free(fw, size); 2054 1.1 nia return (error); 2055 1.1 nia } 2056 1.1 nia 2057 1.1 nia int 2058 1.1 nia rsu_init(struct ifnet *ifp) 2059 1.1 nia { 2060 1.1 nia struct rsu_softc *sc = ifp->if_softc; 2061 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 2062 1.1 nia struct r92s_set_pwr_mode cmd; 2063 1.1 nia struct rsu_rx_data *data; 2064 1.1 nia int i, error; 2065 1.1 nia 2066 1.1 nia /* Init host async commands ring. */ 2067 1.1 nia 2068 1.1 nia mutex_enter(&sc->sc_task_mtx); 2069 1.1 nia sc->cmdq.cur = sc->cmdq.next = sc->cmdq.queued = 0; 2070 1.1 nia mutex_exit(&sc->sc_task_mtx); 2071 1.1 nia 2072 1.1 nia /* Allocate Tx/Rx buffers. */ 2073 1.1 nia error = rsu_alloc_rx_list(sc); 2074 1.1 nia if (error != 0) { 2075 1.1 nia printf("%s: could not allocate Rx buffers\n", 2076 1.1 nia device_xname(sc->sc_dev)); 2077 1.1 nia goto fail; 2078 1.1 nia } 2079 1.1 nia error = rsu_alloc_tx_list(sc); 2080 1.1 nia if (error != 0) { 2081 1.1 nia printf("%s: could not allocate Tx buffers\n", 2082 1.1 nia device_xname(sc->sc_dev)); 2083 1.1 nia goto fail; 2084 1.1 nia } 2085 1.1 nia 2086 1.1 nia /* Reserve one Tx buffer for firmware commands. */ 2087 1.1 nia mutex_enter(&sc->sc_tx_mtx); 2088 1.1 nia sc->fwcmd_data = TAILQ_FIRST(&sc->tx_free_list); 2089 1.1 nia TAILQ_REMOVE(&sc->tx_free_list, sc->fwcmd_data, next); 2090 1.1 nia mutex_exit(&sc->sc_tx_mtx); 2091 1.1 nia 2092 1.1 nia /* Power on adapter. */ 2093 1.1 nia if (sc->cut == 1) 2094 1.1 nia rsu_power_on_acut(sc); 2095 1.1 nia else 2096 1.1 nia rsu_power_on_bcut(sc); 2097 1.1 nia /* Load firmware. */ 2098 1.1 nia error = rsu_load_firmware(sc); 2099 1.1 nia if (error != 0) 2100 1.1 nia goto fail; 2101 1.1 nia 2102 1.1 nia /* Enable Rx TCP checksum offload. */ 2103 1.1 nia rsu_write_4(sc, R92S_RCR, 2104 1.1 nia rsu_read_4(sc, R92S_RCR) | 0x04000000); 2105 1.1 nia /* Append PHY status. */ 2106 1.1 nia rsu_write_4(sc, R92S_RCR, 2107 1.1 nia rsu_read_4(sc, R92S_RCR) | 0x02000000); 2108 1.1 nia 2109 1.1 nia rsu_write_4(sc, R92S_CR, 2110 1.1 nia rsu_read_4(sc, R92S_CR) & ~0xff000000); 2111 1.1 nia 2112 1.1 nia /* Use 128 bytes pages. */ 2113 1.1 nia rsu_write_1(sc, 0x00b5, 2114 1.1 nia rsu_read_1(sc, 0x00b5) | 0x01); 2115 1.1 nia /* Enable USB Rx aggregation. */ 2116 1.1 nia rsu_write_1(sc, 0x00bd, 2117 1.1 nia rsu_read_1(sc, 0x00bd) | 0x80); 2118 1.1 nia /* Set USB Rx aggregation threshold. */ 2119 1.1 nia rsu_write_1(sc, 0x00d9, 0x01); 2120 1.1 nia /* Set USB Rx aggregation timeout (1.7ms/4). */ 2121 1.1 nia rsu_write_1(sc, 0xfe5b, 0x04); 2122 1.1 nia /* Fix USB Rx FIFO issue. */ 2123 1.1 nia rsu_write_1(sc, 0xfe5c, 2124 1.1 nia rsu_read_1(sc, 0xfe5c) | 0x80); 2125 1.1 nia 2126 1.1 nia /* Set MAC address. */ 2127 1.1 nia IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 2128 1.1 nia rsu_write_region_1(sc, R92S_MACID, ic->ic_myaddr, IEEE80211_ADDR_LEN); 2129 1.1 nia 2130 1.1 nia /* Queue Rx xfers (XXX C2H pipe for 11-pipe configurations?) */ 2131 1.1 nia for (i = 0; i < RSU_RX_LIST_COUNT; i++) { 2132 1.1 nia data = &sc->rx_data[i]; 2133 1.1 nia 2134 1.1 nia data->pipe = sc->pipe[sc->qid2idx[RSU_QID_RXOFF]]; 2135 1.1 nia usbd_setup_xfer(data->xfer, data, data->buf, 2136 1.1 nia RSU_RXBUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, 2137 1.1 nia rsu_rxeof); 2138 1.1 nia error = usbd_transfer(data->xfer); 2139 1.1 nia if (error != 0 && error != USBD_IN_PROGRESS) 2140 1.1 nia goto fail; 2141 1.1 nia } 2142 1.1 nia 2143 1.1 nia /* NB: it really takes that long for firmware to boot. */ 2144 1.1 nia usbd_delay_ms(sc->sc_udev, 1500); 2145 1.1 nia 2146 1.1 nia DPRINTF(("setting MAC address to %s\n", ether_sprintf(ic->ic_myaddr))); 2147 1.1 nia error = rsu_fw_cmd(sc, R92S_CMD_SET_MAC_ADDRESS, ic->ic_myaddr, 2148 1.1 nia IEEE80211_ADDR_LEN); 2149 1.1 nia if (error != 0) { 2150 1.1 nia printf("%s: could not set MAC address\n", 2151 1.1 nia device_xname(sc->sc_dev)); 2152 1.1 nia goto fail; 2153 1.1 nia } 2154 1.1 nia 2155 1.1 nia rsu_write_1(sc, R92S_USB_HRPWM, 2156 1.1 nia R92S_USB_HRPWM_PS_ST_ACTIVE | R92S_USB_HRPWM_PS_ALL_ON); 2157 1.1 nia 2158 1.1 nia memset(&cmd, 0, sizeof(cmd)); 2159 1.1 nia cmd.mode = R92S_PS_MODE_ACTIVE; 2160 1.1 nia DPRINTF(("setting ps mode to %d\n", cmd.mode)); 2161 1.1 nia error = rsu_fw_cmd(sc, R92S_CMD_SET_PWR_MODE, &cmd, sizeof(cmd)); 2162 1.1 nia if (error != 0) { 2163 1.1 nia printf("%s: could not set PS mode\n", 2164 1.1 nia device_xname(sc->sc_dev)); 2165 1.1 nia goto fail; 2166 1.1 nia } 2167 1.1 nia 2168 1.1 nia #ifdef notyet 2169 1.1 nia if (ic->ic_htcaps & IEEE80211_HTCAP_CBW20_40) { 2170 1.1 nia /* Enable 40MHz mode. */ 2171 1.1 nia error = rsu_fw_iocmd(sc, 2172 1.1 nia SM(R92S_IOCMD_CLASS, 0xf4) | 2173 1.1 nia SM(R92S_IOCMD_INDEX, 0x00) | 2174 1.1 nia SM(R92S_IOCMD_VALUE, 0x0007)); 2175 1.1 nia if (error != 0) { 2176 1.1 nia printf("%s: could not enable 40MHz mode\n", 2177 1.1 nia device_xname(sc->sc_dev)); 2178 1.1 nia goto fail; 2179 1.1 nia } 2180 1.1 nia } 2181 1.1 nia #endif 2182 1.1 nia 2183 1.1 nia /* Set default channel. */ 2184 1.1 nia ic->ic_bss->ni_chan = ic->ic_ibss_chan; 2185 1.1 nia 2186 1.1 nia /* We're ready to go. */ 2187 1.1 nia ifp->if_flags &= ~IFF_OACTIVE; 2188 1.1 nia ifp->if_flags |= IFF_RUNNING; 2189 1.1 nia 2190 1.1 nia sc->scan_pass = 0; 2191 1.1 nia if (ic->ic_opmode == IEEE80211_M_MONITOR) 2192 1.1 nia ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 2193 1.1 nia else 2194 1.1 nia ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2195 1.1 nia return (0); 2196 1.1 nia fail: 2197 1.1 nia rsu_stop(ifp); 2198 1.1 nia return (error); 2199 1.1 nia } 2200 1.1 nia 2201 1.1 nia void 2202 1.1 nia rsu_stop(struct ifnet *ifp) 2203 1.1 nia { 2204 1.1 nia struct rsu_softc *sc = ifp->if_softc; 2205 1.1 nia struct ieee80211com *ic = &sc->sc_ic; 2206 1.1 nia int i, s; 2207 1.1 nia 2208 1.1 nia sc->sc_tx_timer = 0; 2209 1.1 nia ifp->if_timer = 0; 2210 1.1 nia ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2211 1.1 nia 2212 1.1 nia s = splusb(); 2213 1.1 nia ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2214 1.1 nia /* Wait for all async commands to complete. */ 2215 1.1 nia rsu_wait_async(sc); 2216 1.1 nia splx(s); 2217 1.1 nia 2218 1.1 nia callout_destroy(&sc->calib_to); 2219 1.1 nia 2220 1.1 nia /* Power off adapter. */ 2221 1.1 nia rsu_power_off(sc); 2222 1.1 nia 2223 1.1 nia /* Abort Tx/Rx. */ 2224 1.1 nia for (i = 0; i < sc->npipes; i++) 2225 1.1 nia usbd_abort_pipe(sc->pipe[i]); 2226 1.1 nia 2227 1.1 nia /* Free Tx/Rx buffers. */ 2228 1.1 nia rsu_free_tx_list(sc); 2229 1.1 nia rsu_free_rx_list(sc); 2230 1.1 nia } 2231 1.1 nia 2232 1.1 nia MODULE(MODULE_CLASS_DRIVER, if_rsu, NULL); 2233 1.1 nia 2234 1.1 nia #ifdef _MODULE 2235 1.1 nia #include "ioconf.c" 2236 1.1 nia #endif 2237 1.1 nia 2238 1.1 nia static int 2239 1.1 nia if_rsu_modcmd(modcmd_t cmd, void *arg) 2240 1.1 nia { 2241 1.1 nia int error = 0; 2242 1.1 nia 2243 1.1 nia switch (cmd) { 2244 1.1 nia case MODULE_CMD_INIT: 2245 1.1 nia #ifdef _MODULE 2246 1.1 nia error = config_init_component(cfdriver_ioconf_rsu, 2247 1.1 nia cfattach_ioconf_rsu, cfdata_ioconf_rsu); 2248 1.1 nia #endif 2249 1.1 nia return error; 2250 1.1 nia case MODULE_CMD_FINI: 2251 1.1 nia #ifdef _MODULE 2252 1.1 nia error = config_fini_component(cfdriver_ioconf_rsu, 2253 1.1 nia cfattach_ioconf_rsu, cfdata_ioconf_rsu); 2254 1.1 nia #endif 2255 1.1 nia return error; 2256 1.1 nia default: 2257 1.1 nia return ENOTTY; 2258 1.1 nia } 2259 1.1 nia } 2260