1 /* $NetBSD: awi.c,v 1.85 2009/11/12 19:32:14 dyoung Exp $ */ 2 3 /*- 4 * Copyright (c) 1999,2000,2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Bill Sommerfeld 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /* 32 * Driver for AMD 802.11 firmware. 33 * Uses am79c930 chip driver to talk to firmware running on the am79c930. 34 * 35 * More-or-less a generic ethernet-like if driver, with 802.11 gorp added. 36 */ 37 38 /* 39 * todo: 40 * - flush tx queue on resynch. 41 * - clear oactive on "down". 42 * - rewrite copy-into-mbuf code 43 * - mgmt state machine gets stuck retransmitting assoc requests. 44 * - multicast filter. 45 * - fix device reset so it's more likely to work 46 * - show status goo through ifmedia. 47 * 48 * more todo: 49 * - deal with more 802.11 frames. 50 * - send reassoc request 51 * - deal with reassoc response 52 * - send/deal with disassociation 53 * - deal with "full" access points (no room for me). 54 * - power save mode 55 * 56 * later: 57 * - SSID preferences 58 * - need ioctls for poking at the MIBs 59 * - implement ad-hoc mode (including bss creation). 60 * - decide when to do "ad hoc" vs. infrastructure mode (IFF_LINK flags?) 61 * (focus on inf. mode since that will be needed for ietf) 62 * - deal with DH vs. FH versions of the card 63 * - deal with faster cards (2mb/s) 64 * - ?WEP goo (mmm, rc4) (it looks not particularly useful). 65 * - ifmedia revision. 66 * - common 802.11 mibish things. 67 * - common 802.11 media layer. 68 */ 69 70 /* 71 * Driver for AMD 802.11 PCnetMobile firmware. 72 * Uses am79c930 chip driver to talk to firmware running on the am79c930. 73 * 74 * The initial version of the driver was written by 75 * Bill Sommerfeld <sommerfeld@NetBSD.org>. 76 * Then the driver module completely rewritten to support cards with DS phy 77 * and to support adhoc mode by Atsushi Onoe <onoe@NetBSD.org> 78 */ 79 80 #include <sys/cdefs.h> 81 __KERNEL_RCSID(0, "$NetBSD: awi.c,v 1.85 2009/11/12 19:32:14 dyoung Exp $"); 82 83 #include "opt_inet.h" 84 #include "bpfilter.h" 85 86 #include <sys/param.h> 87 #include <sys/systm.h> 88 #include <sys/kernel.h> 89 #include <sys/mbuf.h> 90 #include <sys/malloc.h> 91 #include <sys/proc.h> 92 #include <sys/socket.h> 93 #include <sys/sockio.h> 94 #include <sys/errno.h> 95 #include <sys/endian.h> 96 #include <sys/device.h> 97 98 #include <net/if.h> 99 #include <net/if_dl.h> 100 #include <net/if_ether.h> 101 #include <net/if_media.h> 102 #include <net/if_llc.h> 103 104 #include <net80211/ieee80211_netbsd.h> 105 #include <net80211/ieee80211_var.h> 106 107 #if NBPFILTER > 0 108 #include <net/bpf.h> 109 #endif 110 111 #include <sys/cpu.h> 112 #include <sys/bus.h> 113 114 #include <dev/ic/am79c930reg.h> 115 #include <dev/ic/am79c930var.h> 116 #include <dev/ic/awireg.h> 117 #include <dev/ic/awivar.h> 118 119 static int awi_init(struct ifnet *); 120 static void awi_stop(struct ifnet *, int); 121 static void awi_start(struct ifnet *); 122 static void awi_watchdog(struct ifnet *); 123 static int awi_ioctl(struct ifnet *, u_long, void *); 124 static int awi_media_change(struct ifnet *); 125 static void awi_media_status(struct ifnet *, struct ifmediareq *); 126 static int awi_mode_init(struct awi_softc *); 127 static void awi_rx_int(struct awi_softc *); 128 static void awi_tx_int(struct awi_softc *); 129 static struct mbuf *awi_devget(struct awi_softc *, u_int32_t, u_int16_t); 130 static int awi_hw_init(struct awi_softc *); 131 static int awi_init_mibs(struct awi_softc *); 132 static int awi_mib(struct awi_softc *, u_int8_t, u_int8_t, int); 133 static int awi_cmd(struct awi_softc *, u_int8_t, int); 134 static int awi_cmd_wait(struct awi_softc *); 135 static void awi_cmd_done(struct awi_softc *); 136 static int awi_next_txd(struct awi_softc *, int, u_int32_t *, u_int32_t *); 137 static int awi_lock(struct awi_softc *); 138 static void awi_unlock(struct awi_softc *); 139 static int awi_intr_lock(struct awi_softc *); 140 static void awi_intr_unlock(struct awi_softc *); 141 static int awi_newstate(struct ieee80211com *, enum ieee80211_state, int); 142 static void awi_recv_mgmt(struct ieee80211com *, struct mbuf *, 143 struct ieee80211_node *, int, int, u_int32_t); 144 static int awi_send_mgmt(struct ieee80211com *, struct ieee80211_node *, int, 145 int); 146 static struct mbuf *awi_ether_encap(struct awi_softc *, struct mbuf *); 147 static struct mbuf *awi_ether_modcap(struct awi_softc *, struct mbuf *); 148 149 /* unaligned little endian access */ 150 #define LE_READ_2(p) \ 151 ((((u_int8_t *)(p))[0] ) | (((u_int8_t *)(p))[1] << 8)) 152 #define LE_READ_4(p) \ 153 ((((u_int8_t *)(p))[0] ) | (((u_int8_t *)(p))[1] << 8) | \ 154 (((u_int8_t *)(p))[2] << 16) | (((u_int8_t *)(p))[3] << 24)) 155 #define LE_WRITE_2(p, v) \ 156 ((((u_int8_t *)(p))[0] = (((u_int32_t)(v) ) & 0xff)), \ 157 (((u_int8_t *)(p))[1] = (((u_int32_t)(v) >> 8) & 0xff))) 158 #define LE_WRITE_4(p, v) \ 159 ((((u_int8_t *)(p))[0] = (((u_int32_t)(v) ) & 0xff)), \ 160 (((u_int8_t *)(p))[1] = (((u_int32_t)(v) >> 8) & 0xff)), \ 161 (((u_int8_t *)(p))[2] = (((u_int32_t)(v) >> 16) & 0xff)), \ 162 (((u_int8_t *)(p))[3] = (((u_int32_t)(v) >> 24) & 0xff))) 163 164 struct awi_chanset awi_chanset[] = { 165 /* PHY type domain min max def */ 166 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_JP, 6, 17, 6 }, 167 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_ES, 0, 26, 1 }, 168 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_FR, 0, 32, 1 }, 169 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_US, 0, 77, 1 }, 170 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_CA, 0, 77, 1 }, 171 { AWI_PHY_TYPE_FH, AWI_REG_DOMAIN_EU, 0, 77, 1 }, 172 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_JP, 14, 14, 14 }, 173 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_ES, 10, 11, 10 }, 174 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_FR, 10, 13, 10 }, 175 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_US, 1, 11, 3 }, 176 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_CA, 1, 11, 3 }, 177 { AWI_PHY_TYPE_DS, AWI_REG_DOMAIN_EU, 1, 13, 3 }, 178 { 0, 0, 0, 0, 0 } 179 }; 180 181 #ifdef AWI_DEBUG 182 int awi_debug = 0; 183 184 #define DPRINTF(X) if (awi_debug) printf X 185 #define DPRINTF2(X) if (awi_debug > 1) printf X 186 #else 187 #define DPRINTF(X) 188 #define DPRINTF2(X) 189 #endif 190 191 int 192 awi_attach(struct awi_softc *sc) 193 { 194 struct ieee80211com *ic = &sc->sc_ic; 195 struct ifnet *ifp = &sc->sc_if; 196 int s, i, error, nrate; 197 int mword; 198 enum ieee80211_phymode mode; 199 200 s = splnet(); 201 sc->sc_busy = 1; 202 sc->sc_attached = 0; 203 sc->sc_substate = AWI_ST_NONE; 204 if ((error = awi_hw_init(sc)) != 0) { 205 config_deactivate(&sc->sc_dev); 206 splx(s); 207 return error; 208 } 209 error = awi_init_mibs(sc); 210 if (error != 0) { 211 config_deactivate(&sc->sc_dev); 212 splx(s); 213 return error; 214 } 215 ifp->if_softc = sc; 216 ifp->if_flags = 217 #ifdef IFF_NOTRAILERS 218 IFF_NOTRAILERS | 219 #endif 220 IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 221 ifp->if_ioctl = awi_ioctl; 222 ifp->if_start = awi_start; 223 ifp->if_watchdog = awi_watchdog; 224 ifp->if_init = awi_init; 225 ifp->if_stop = awi_stop; 226 IFQ_SET_READY(&ifp->if_snd); 227 memcpy(ifp->if_xname, device_xname(&sc->sc_dev), IFNAMSIZ); 228 229 ic->ic_ifp = ifp; 230 ic->ic_caps = IEEE80211_C_WEP | IEEE80211_C_IBSS | IEEE80211_C_HOSTAP; 231 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { 232 ic->ic_phytype = IEEE80211_T_FH; 233 mode = IEEE80211_MODE_FH; 234 } else { 235 ic->ic_phytype = IEEE80211_T_DS; 236 ic->ic_caps |= IEEE80211_C_AHDEMO; 237 mode = IEEE80211_MODE_11B; 238 } 239 ic->ic_opmode = IEEE80211_M_STA; 240 nrate = sc->sc_mib_phy.aSuprt_Data_Rates[1]; 241 memcpy(ic->ic_sup_rates[mode].rs_rates, 242 sc->sc_mib_phy.aSuprt_Data_Rates + 2, nrate); 243 ic->ic_sup_rates[mode].rs_nrates = nrate; 244 IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_mib_addr.aMAC_Address); 245 246 printf("%s: IEEE802.11 %s (firmware %s)\n", ifp->if_xname, 247 (ic->ic_phytype == IEEE80211_T_FH) ? "FH" : "DS", sc->sc_banner); 248 printf("%s: 802.11 address: %s\n", ifp->if_xname, 249 ether_sprintf(ic->ic_myaddr)); 250 251 if_attach(ifp); 252 ieee80211_ifattach(ic); 253 254 sc->sc_newstate = ic->ic_newstate; 255 ic->ic_newstate = awi_newstate; 256 257 sc->sc_recv_mgmt = ic->ic_recv_mgmt; 258 ic->ic_recv_mgmt = awi_recv_mgmt; 259 260 sc->sc_send_mgmt = ic->ic_send_mgmt; 261 ic->ic_send_mgmt = awi_send_mgmt; 262 263 ieee80211_media_init(ic, awi_media_change, awi_media_status); 264 265 /* Melco compatibility mode. */ 266 #define ADD(s, o) ifmedia_add(&ic->ic_media, \ 267 IFM_MAKEWORD(IFM_IEEE80211, (s), (o), 0), 0, NULL) 268 ADD(IFM_AUTO, IFM_FLAG0); 269 270 for (i = 0; i < nrate; i++) { 271 mword = ieee80211_rate2media(ic, 272 ic->ic_sup_rates[mode].rs_rates[i], mode); 273 if (mword == 0) 274 continue; 275 ADD(mword, IFM_FLAG0); 276 } 277 #undef ADD 278 279 if ((sc->sc_sdhook = shutdownhook_establish(awi_shutdown, sc)) == NULL) 280 printf("%s: WARNING: unable to establish shutdown hook\n", 281 ifp->if_xname); 282 if ((sc->sc_powerhook = 283 powerhook_establish(ifp->if_xname, awi_power, sc)) == NULL) 284 printf("%s: WARNING: unable to establish power hook\n", 285 ifp->if_xname); 286 sc->sc_attached = 1; 287 splx(s); 288 289 /* ready to accept ioctl */ 290 awi_unlock(sc); 291 292 return 0; 293 } 294 295 int 296 awi_detach(struct awi_softc *sc) 297 { 298 struct ieee80211com *ic = &sc->sc_ic; 299 struct ifnet *ifp = &sc->sc_if; 300 int s; 301 302 if (!sc->sc_attached) 303 return 0; 304 305 s = splnet(); 306 awi_stop(ifp, 1); 307 308 while (sc->sc_sleep_cnt > 0) { 309 wakeup(sc); 310 (void)tsleep(sc, PWAIT, "awidet", 1); 311 } 312 sc->sc_attached = 0; 313 ieee80211_ifdetach(ic); 314 if_detach(ifp); 315 shutdownhook_disestablish(sc->sc_sdhook); 316 powerhook_disestablish(sc->sc_powerhook); 317 splx(s); 318 return 0; 319 } 320 321 int 322 awi_activate(device_t self, enum devact act) 323 { 324 struct awi_softc *sc = device_private(self); 325 326 switch (act) { 327 case DVACT_DEACTIVATE: 328 if_deactivate(&sc->sc_if); 329 return 0; 330 default: 331 return EOPNOTSUPP; 332 } 333 } 334 335 void 336 awi_power(int why, void *arg) 337 { 338 struct awi_softc *sc = arg; 339 struct ifnet *ifp = &sc->sc_if; 340 int s; 341 int ocansleep; 342 343 DPRINTF(("awi_power: %d\n", why)); 344 s = splnet(); 345 ocansleep = sc->sc_cansleep; 346 sc->sc_cansleep = 0; 347 switch (why) { 348 case PWR_SUSPEND: 349 case PWR_STANDBY: 350 awi_stop(ifp, 1); 351 break; 352 case PWR_RESUME: 353 if (ifp->if_flags & IFF_UP) { 354 awi_init(ifp); 355 (void)awi_intr(sc); /* make sure */ 356 } 357 break; 358 case PWR_SOFTSUSPEND: 359 case PWR_SOFTSTANDBY: 360 case PWR_SOFTRESUME: 361 break; 362 } 363 sc->sc_cansleep = ocansleep; 364 splx(s); 365 } 366 367 void 368 awi_shutdown(void *arg) 369 { 370 struct awi_softc *sc = arg; 371 struct ifnet *ifp = &sc->sc_if; 372 373 if (sc->sc_attached) 374 awi_stop(ifp, 1); 375 } 376 377 int 378 awi_intr(void *arg) 379 { 380 struct awi_softc *sc = arg; 381 u_int16_t status; 382 int handled = 0, ocansleep; 383 #ifdef AWI_DEBUG 384 static const char *intname[] = { 385 "CMD", "RX", "TX", "SCAN_CMPLT", 386 "CFP_START", "DTIM", "CFP_ENDING", "GROGGY", 387 "TXDATA", "TXBCAST", "TXPS", "TXCF", 388 "TXMGT", "#13", "RXDATA", "RXMGT" 389 }; 390 #endif 391 392 if (!sc->sc_enabled || !sc->sc_enab_intr || 393 !device_is_active(&sc->sc_dev)) { 394 DPRINTF(("awi_intr: stray interrupt: " 395 "enabled %d enab_intr %d invalid %d\n", 396 sc->sc_enabled, sc->sc_enab_intr, 397 !device_is_active(&sc->sc_dev))); 398 return 0; 399 } 400 401 am79c930_gcr_setbits(&sc->sc_chip, 402 AM79C930_GCR_DISPWDN | AM79C930_GCR_ECINT); 403 awi_write_1(sc, AWI_DIS_PWRDN, 1); 404 ocansleep = sc->sc_cansleep; 405 sc->sc_cansleep = 0; 406 407 for (;;) { 408 if (awi_intr_lock(sc) != 0) 409 break; 410 status = awi_read_1(sc, AWI_INTSTAT); 411 awi_write_1(sc, AWI_INTSTAT, 0); 412 awi_write_1(sc, AWI_INTSTAT, 0); 413 status |= awi_read_1(sc, AWI_INTSTAT2) << 8; 414 awi_write_1(sc, AWI_INTSTAT2, 0); 415 DELAY(10); 416 awi_intr_unlock(sc); 417 if (!sc->sc_cmd_inprog) 418 status &= ~AWI_INT_CMD; /* make sure */ 419 if (status == 0) 420 break; 421 #ifdef AWI_DEBUG 422 if (awi_debug > 1) { 423 int i; 424 425 printf("awi_intr: status 0x%04x", status); 426 for (i = 0; i < sizeof(intname)/sizeof(intname[0]); 427 i++) { 428 if (status & (1 << i)) 429 printf(" %s", intname[i]); 430 } 431 printf("\n"); 432 } 433 #endif 434 handled = 1; 435 if (status & AWI_INT_RX) 436 awi_rx_int(sc); 437 if (status & AWI_INT_TX) 438 awi_tx_int(sc); 439 if (status & AWI_INT_CMD) 440 awi_cmd_done(sc); 441 if (status & AWI_INT_SCAN_CMPLT) { 442 if (sc->sc_ic.ic_state == IEEE80211_S_SCAN && 443 sc->sc_substate == AWI_ST_NONE) 444 ieee80211_next_scan(&sc->sc_ic); 445 } 446 } 447 sc->sc_cansleep = ocansleep; 448 am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_DISPWDN); 449 awi_write_1(sc, AWI_DIS_PWRDN, 0); 450 return handled; 451 } 452 453 454 static int 455 awi_init(struct ifnet *ifp) 456 { 457 struct awi_softc *sc = ifp->if_softc; 458 struct ieee80211com *ic = &sc->sc_ic; 459 struct ieee80211_node *ni = ic->ic_bss; 460 struct ieee80211_rateset *rs; 461 int error, rate, i; 462 463 DPRINTF(("awi_init: enabled=%d\n", sc->sc_enabled)); 464 if (sc->sc_enabled) { 465 awi_stop(ifp, 0); 466 } else { 467 if (sc->sc_enable) 468 (*sc->sc_enable)(sc); 469 sc->sc_enabled = 1; 470 if ((error = awi_hw_init(sc)) != 0) { 471 if (sc->sc_disable) 472 (*sc->sc_disable)(sc); 473 sc->sc_enabled = 0; 474 return error; 475 } 476 } 477 ic->ic_state = IEEE80211_S_INIT; 478 479 ic->ic_flags &= ~IEEE80211_F_IBSSON; 480 switch (ic->ic_opmode) { 481 case IEEE80211_M_STA: 482 sc->sc_mib_local.Network_Mode = 1; 483 sc->sc_mib_local.Acting_as_AP = 0; 484 break; 485 case IEEE80211_M_IBSS: 486 ic->ic_flags |= IEEE80211_F_IBSSON; 487 /* FALLTHRU */ 488 case IEEE80211_M_AHDEMO: 489 sc->sc_mib_local.Network_Mode = 0; 490 sc->sc_mib_local.Acting_as_AP = 0; 491 break; 492 case IEEE80211_M_HOSTAP: 493 sc->sc_mib_local.Network_Mode = 1; 494 sc->sc_mib_local.Acting_as_AP = 1; 495 break; 496 case IEEE80211_M_MONITOR: 497 return ENODEV; 498 } 499 #if 0 500 IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); 501 #endif 502 memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE); 503 sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID; 504 sc->sc_mib_mac.aDesired_ESS_ID[1] = ic->ic_des_esslen; 505 memcpy(&sc->sc_mib_mac.aDesired_ESS_ID[2], ic->ic_des_essid, 506 ic->ic_des_esslen); 507 508 /* configure basic rate */ 509 if (ic->ic_phytype == IEEE80211_T_FH) 510 rs = &ic->ic_sup_rates[IEEE80211_MODE_FH]; 511 else 512 rs = &ic->ic_sup_rates[IEEE80211_MODE_11B]; 513 if (ic->ic_fixed_rate != -1) { 514 rate = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 515 } else { 516 rate = 0; 517 for (i = 0; i < rs->rs_nrates; i++) { 518 if ((rs->rs_rates[i] & IEEE80211_RATE_BASIC) && 519 rate < (rs->rs_rates[i] & IEEE80211_RATE_VAL)) 520 rate = rs->rs_rates[i] & IEEE80211_RATE_VAL; 521 } 522 } 523 rate *= 5; 524 LE_WRITE_2(&sc->sc_mib_mac.aStation_Basic_Rate, rate); 525 526 if ((error = awi_mode_init(sc)) != 0) { 527 DPRINTF(("awi_init: awi_mode_init failed %d\n", error)); 528 awi_stop(ifp, 1); 529 return error; 530 } 531 532 /* start transmitter */ 533 sc->sc_txdone = sc->sc_txnext = sc->sc_txbase; 534 awi_write_4(sc, sc->sc_txbase + AWI_TXD_START, 0); 535 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NEXT, 0); 536 awi_write_4(sc, sc->sc_txbase + AWI_TXD_LENGTH, 0); 537 awi_write_1(sc, sc->sc_txbase + AWI_TXD_RATE, 0); 538 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NDA, 0); 539 awi_write_4(sc, sc->sc_txbase + AWI_TXD_NRA, 0); 540 awi_write_1(sc, sc->sc_txbase + AWI_TXD_STATE, 0); 541 awi_write_4(sc, AWI_CA_TX_DATA, sc->sc_txbase); 542 awi_write_4(sc, AWI_CA_TX_MGT, 0); 543 awi_write_4(sc, AWI_CA_TX_BCAST, 0); 544 awi_write_4(sc, AWI_CA_TX_PS, 0); 545 awi_write_4(sc, AWI_CA_TX_CF, 0); 546 if ((error = awi_cmd(sc, AWI_CMD_INIT_TX, AWI_WAIT)) != 0) { 547 DPRINTF(("awi_init: failed to start transmitter: %d\n", error)); 548 awi_stop(ifp, 1); 549 return error; 550 } 551 552 /* start receiver */ 553 if ((error = awi_cmd(sc, AWI_CMD_INIT_RX, AWI_WAIT)) != 0) { 554 DPRINTF(("awi_init: failed to start receiver: %d\n", error)); 555 awi_stop(ifp, 1); 556 return error; 557 } 558 sc->sc_rxdoff = awi_read_4(sc, AWI_CA_IRX_DATA_DESC); 559 sc->sc_rxmoff = awi_read_4(sc, AWI_CA_IRX_PS_DESC); 560 561 ifp->if_flags |= IFF_RUNNING; 562 ifp->if_flags &= ~IFF_OACTIVE; 563 ic->ic_state = IEEE80211_S_INIT; 564 565 if (ic->ic_opmode == IEEE80211_M_AHDEMO || 566 ic->ic_opmode == IEEE80211_M_HOSTAP) { 567 ni->ni_chan = ic->ic_ibss_chan; 568 ni->ni_intval = ic->ic_lintval; 569 ni->ni_rssi = 0; 570 ni->ni_rstamp = 0; 571 memset(&ni->ni_tstamp, 0, sizeof(ni->ni_tstamp)); 572 ni->ni_rates = 573 ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)]; 574 IEEE80211_ADDR_COPY(ni->ni_macaddr, ic->ic_myaddr); 575 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 576 IEEE80211_ADDR_COPY(ni->ni_bssid, ic->ic_myaddr); 577 ni->ni_esslen = ic->ic_des_esslen; 578 memcpy(ni->ni_essid, ic->ic_des_essid, ni->ni_esslen); 579 ni->ni_capinfo = IEEE80211_CAPINFO_ESS; 580 if (ic->ic_phytype == IEEE80211_T_FH) { 581 ni->ni_fhdwell = 200; /* XXX */ 582 ni->ni_fhindex = 1; 583 } 584 } else { 585 ni->ni_capinfo = IEEE80211_CAPINFO_IBSS; 586 memset(ni->ni_bssid, 0, IEEE80211_ADDR_LEN); 587 ni->ni_esslen = 0; 588 } 589 if (ic->ic_flags & IEEE80211_F_PRIVACY) 590 ni->ni_capinfo |= IEEE80211_CAPINFO_PRIVACY; 591 if (ic->ic_opmode != IEEE80211_M_AHDEMO) 592 ic->ic_flags |= IEEE80211_F_SIBSS; 593 ic->ic_state = IEEE80211_S_SCAN; /*XXX*/ 594 sc->sc_substate = AWI_ST_NONE; 595 ieee80211_new_state(ic, IEEE80211_S_RUN, -1); 596 } else { 597 /* XXX check sc->sc_cur_chan */ 598 ni->ni_chan = &ic->ic_channels[sc->sc_cur_chan]; 599 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 600 } 601 return 0; 602 } 603 604 static void 605 awi_stop(struct ifnet *ifp, int disable) 606 { 607 struct awi_softc *sc = ifp->if_softc; 608 609 if (!sc->sc_enabled) 610 return; 611 612 DPRINTF(("awi_stop(%d)\n", disable)); 613 614 ieee80211_new_state(&sc->sc_ic, IEEE80211_S_INIT, -1); 615 616 if (device_is_active(&sc->sc_dev)) { 617 if (sc->sc_cmd_inprog) 618 (void)awi_cmd_wait(sc); 619 (void)awi_cmd(sc, AWI_CMD_KILL_RX, AWI_WAIT); 620 sc->sc_cmd_inprog = AWI_CMD_FLUSH_TX; 621 awi_write_1(sc, AWI_CA_FTX_DATA, 1); 622 awi_write_1(sc, AWI_CA_FTX_MGT, 0); 623 awi_write_1(sc, AWI_CA_FTX_BCAST, 0); 624 awi_write_1(sc, AWI_CA_FTX_PS, 0); 625 awi_write_1(sc, AWI_CA_FTX_CF, 0); 626 (void)awi_cmd(sc, AWI_CMD_FLUSH_TX, AWI_WAIT); 627 } 628 ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE); 629 ifp->if_timer = 0; 630 sc->sc_tx_timer = sc->sc_rx_timer = 0; 631 if (sc->sc_rxpend != NULL) { 632 m_freem(sc->sc_rxpend); 633 sc->sc_rxpend = NULL; 634 } 635 IFQ_PURGE(&ifp->if_snd); 636 637 if (disable) { 638 if (device_is_active(&sc->sc_dev)) 639 am79c930_gcr_setbits(&sc->sc_chip, 640 AM79C930_GCR_CORESET); 641 if (sc->sc_disable) 642 (*sc->sc_disable)(sc); 643 sc->sc_enabled = 0; 644 } 645 } 646 647 static void 648 awi_start(struct ifnet *ifp) 649 { 650 struct awi_softc *sc = ifp->if_softc; 651 struct ieee80211com *ic = &sc->sc_ic; 652 struct ether_header *eh; 653 struct ieee80211_node *ni; 654 struct ieee80211_frame *wh; 655 struct mbuf *m, *m0; 656 int len, dowep; 657 u_int32_t txd, frame, ntxd; 658 u_int8_t rate; 659 660 if (!sc->sc_enabled || !device_is_active(&sc->sc_dev)) 661 return; 662 663 for (;;) { 664 txd = sc->sc_txnext; 665 IF_POLL(&ic->ic_mgtq, m0); 666 dowep = 0; 667 if (m0 != NULL) { 668 len = m0->m_pkthdr.len; 669 if (awi_next_txd(sc, len, &frame, &ntxd)) { 670 ifp->if_flags |= IFF_OACTIVE; 671 break; 672 } 673 IF_DEQUEUE(&ic->ic_mgtq, m0); 674 ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; 675 } else { 676 if (ic->ic_state != IEEE80211_S_RUN) 677 break; 678 IFQ_POLL(&ifp->if_snd, m0); 679 if (m0 == NULL) 680 break; 681 /* 682 * Need to calculate the real length to determine 683 * if the transmit buffer has a room for the packet. 684 */ 685 len = m0->m_pkthdr.len + sizeof(struct ieee80211_frame); 686 if (!(ifp->if_flags & IFF_LINK0) && !sc->sc_adhoc_ap) 687 len += sizeof(struct llc) - 688 sizeof(struct ether_header); 689 if (ic->ic_flags & IEEE80211_F_PRIVACY) { 690 dowep = 1; 691 len += IEEE80211_WEP_IVLEN + 692 IEEE80211_WEP_KIDLEN + IEEE80211_WEP_CRCLEN; 693 } 694 if (awi_next_txd(sc, len, &frame, &ntxd)) { 695 ifp->if_flags |= IFF_OACTIVE; 696 break; 697 } 698 IFQ_DEQUEUE(&ifp->if_snd, m0); 699 ifp->if_opackets++; 700 #if NBPFILTER > 0 701 if (ifp->if_bpf) 702 bpf_mtap(ifp->if_bpf, m0); 703 #endif 704 eh = mtod(m0, struct ether_header *); 705 ni = ieee80211_find_txnode(ic, eh->ether_dhost); 706 if (ni == NULL) { 707 ifp->if_oerrors++; 708 continue; 709 } 710 if ((ifp->if_flags & IFF_LINK0) || sc->sc_adhoc_ap) 711 m0 = awi_ether_encap(sc, m0); 712 else { 713 m0 = ieee80211_encap(ic, m0, ni); 714 } 715 if (m0 == NULL) { 716 ieee80211_free_node(ni); 717 ifp->if_oerrors++; 718 continue; 719 } 720 wh = mtod(m0, struct ieee80211_frame *); 721 if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && 722 (ic->ic_opmode == IEEE80211_M_HOSTAP || 723 ic->ic_opmode == IEEE80211_M_IBSS) && 724 sc->sc_adhoc_ap == 0 && 725 (ifp->if_flags & IFF_LINK0) == 0 && 726 (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 727 IEEE80211_FC0_TYPE_DATA) { 728 m_freem(m0); 729 ieee80211_free_node(ni); 730 ifp->if_oerrors++; 731 continue; 732 } 733 } 734 #if NBPFILTER > 0 735 if (ic->ic_rawbpf) 736 bpf_mtap(ic->ic_rawbpf, m0); 737 #endif 738 if (dowep) { 739 if ((ieee80211_crypto_encap(ic, ni, m0)) == NULL) { 740 m_freem(m0); 741 ieee80211_free_node(ni); 742 ifp->if_oerrors++; 743 continue; 744 } 745 } 746 ieee80211_free_node(ni); 747 #ifdef DIAGNOSTIC 748 if (m0->m_pkthdr.len != len) { 749 printf("%s: length %d should be %d\n", 750 sc->sc_if.if_xname, m0->m_pkthdr.len, len); 751 m_freem(m0); 752 ifp->if_oerrors++; 753 continue; 754 } 755 #endif 756 757 if ((ifp->if_flags & IFF_DEBUG) && (ifp->if_flags & IFF_LINK2)) 758 ieee80211_dump_pkt(m0->m_data, m0->m_len, 759 ic->ic_bss->ni_rates. 760 rs_rates[ic->ic_bss->ni_txrate] & 761 IEEE80211_RATE_VAL, -1); 762 763 for (m = m0, len = 0; m != NULL; m = m->m_next) { 764 awi_write_bytes(sc, frame + len, mtod(m, u_int8_t *), 765 m->m_len); 766 len += m->m_len; 767 } 768 m_freem(m0); 769 rate = (ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] & 770 IEEE80211_RATE_VAL) * 5; 771 awi_write_1(sc, ntxd + AWI_TXD_STATE, 0); 772 awi_write_4(sc, txd + AWI_TXD_START, frame); 773 awi_write_4(sc, txd + AWI_TXD_NEXT, ntxd); 774 awi_write_4(sc, txd + AWI_TXD_LENGTH, len); 775 awi_write_1(sc, txd + AWI_TXD_RATE, rate); 776 awi_write_4(sc, txd + AWI_TXD_NDA, 0); 777 awi_write_4(sc, txd + AWI_TXD_NRA, 0); 778 awi_write_1(sc, txd + AWI_TXD_STATE, AWI_TXD_ST_OWN); 779 sc->sc_txnext = ntxd; 780 781 sc->sc_tx_timer = 5; 782 ifp->if_timer = 1; 783 } 784 } 785 786 static void 787 awi_watchdog(struct ifnet *ifp) 788 { 789 struct awi_softc *sc = ifp->if_softc; 790 u_int32_t prevdone; 791 int ocansleep; 792 793 ifp->if_timer = 0; 794 if (!sc->sc_enabled || !device_is_active(&sc->sc_dev)) 795 return; 796 797 ocansleep = sc->sc_cansleep; 798 sc->sc_cansleep = 0; 799 if (sc->sc_tx_timer) { 800 if (--sc->sc_tx_timer == 0) { 801 printf("%s: device timeout\n", ifp->if_xname); 802 prevdone = sc->sc_txdone; 803 awi_tx_int(sc); 804 if (sc->sc_txdone == prevdone) { 805 ifp->if_oerrors++; 806 awi_init(ifp); 807 goto out; 808 } 809 } 810 ifp->if_timer = 1; 811 } 812 if (sc->sc_rx_timer) { 813 if (--sc->sc_rx_timer == 0) { 814 if (sc->sc_ic.ic_state == IEEE80211_S_RUN) { 815 ieee80211_new_state(&sc->sc_ic, 816 IEEE80211_S_SCAN, -1); 817 goto out; 818 } 819 } else 820 ifp->if_timer = 1; 821 } 822 /* TODO: rate control */ 823 ieee80211_watchdog(&sc->sc_ic); 824 out: 825 sc->sc_cansleep = ocansleep; 826 } 827 828 static int 829 awi_ioctl(struct ifnet *ifp, u_long cmd, void *data) 830 { 831 struct awi_softc *sc = ifp->if_softc; 832 struct ifreq *ifr = (struct ifreq *)data; 833 int s, error; 834 835 s = splnet(); 836 /* serialize ioctl, since we may sleep */ 837 if ((error = awi_lock(sc)) != 0) 838 goto cantlock; 839 840 switch (cmd) { 841 case SIOCSIFFLAGS: 842 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 843 break; 844 if (ifp->if_flags & IFF_UP) { 845 if (sc->sc_enabled) { 846 /* 847 * To avoid rescanning another access point, 848 * do not call awi_init() here. Instead, 849 * only reflect promisc mode settings. 850 */ 851 error = awi_mode_init(sc); 852 } else 853 error = awi_init(ifp); 854 } else if (sc->sc_enabled) 855 awi_stop(ifp, 1); 856 break; 857 case SIOCSIFMEDIA: 858 case SIOCGIFMEDIA: 859 error = ifmedia_ioctl(ifp, ifr, &sc->sc_ic.ic_media, cmd); 860 break; 861 case SIOCADDMULTI: 862 case SIOCDELMULTI: 863 error = ether_ioctl(ifp, cmd, data); 864 if (error == ENETRESET) { 865 /* do not rescan */ 866 if (ifp->if_flags & IFF_RUNNING) 867 error = awi_mode_init(sc); 868 else 869 error = 0; 870 } 871 break; 872 default: 873 error = ieee80211_ioctl(&sc->sc_ic, cmd, data); 874 if (error == ENETRESET) { 875 if (sc->sc_enabled) 876 error = awi_init(ifp); 877 else 878 error = 0; 879 } 880 break; 881 } 882 awi_unlock(sc); 883 cantlock: 884 splx(s); 885 return error; 886 } 887 888 /* 889 * Called from ifmedia_ioctl via awi_ioctl with lock obtained. 890 * 891 * TBD factor with ieee80211_media_change 892 */ 893 static int 894 awi_media_change(struct ifnet *ifp) 895 { 896 struct awi_softc *sc = ifp->if_softc; 897 struct ieee80211com *ic = &sc->sc_ic; 898 struct ifmedia_entry *ime; 899 enum ieee80211_opmode newmode; 900 int i, rate, newadhoc_ap, error = 0; 901 902 ime = ic->ic_media.ifm_cur; 903 if (IFM_SUBTYPE(ime->ifm_media) == IFM_AUTO) { 904 i = -1; 905 } else { 906 struct ieee80211_rateset *rs = 907 &ic->ic_sup_rates[(ic->ic_phytype == IEEE80211_T_FH) 908 ? IEEE80211_MODE_FH : IEEE80211_MODE_11B]; 909 rate = ieee80211_media2rate(ime->ifm_media); 910 if (rate == 0) 911 return EINVAL; 912 for (i = 0; i < rs->rs_nrates; i++) { 913 if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) == rate) 914 break; 915 } 916 if (i == rs->rs_nrates) 917 return EINVAL; 918 } 919 if (ic->ic_fixed_rate != i) { 920 ic->ic_fixed_rate = i; 921 error = ENETRESET; 922 } 923 924 /* 925 * combination of mediaopt 926 * 927 * hostap adhoc flag0 opmode adhoc_ap comment 928 * + - - HOSTAP 0 HostAP 929 * - + - IBSS 0 IBSS 930 * - + + AHDEMO 0 WaveLAN adhoc 931 * - - + IBSS 1 Melco old Sta 932 * also LINK0 933 * - - - STA 0 Infra Station 934 */ 935 newadhoc_ap = 0; 936 if (ime->ifm_media & IFM_IEEE80211_HOSTAP) 937 newmode = IEEE80211_M_HOSTAP; 938 else if (ime->ifm_media & IFM_IEEE80211_ADHOC) { 939 if (ic->ic_phytype == IEEE80211_T_DS && 940 (ime->ifm_media & IFM_FLAG0)) 941 newmode = IEEE80211_M_AHDEMO; 942 else 943 newmode = IEEE80211_M_IBSS; 944 } else if (ime->ifm_media & IFM_FLAG0) { 945 newmode = IEEE80211_M_IBSS; 946 newadhoc_ap = 1; 947 } else 948 newmode = IEEE80211_M_STA; 949 if (ic->ic_opmode != newmode || sc->sc_adhoc_ap != newadhoc_ap) { 950 ic->ic_opmode = newmode; 951 sc->sc_adhoc_ap = newadhoc_ap; 952 error = ENETRESET; 953 } 954 955 if (error == ENETRESET) { 956 if (sc->sc_enabled) 957 error = awi_init(ifp); 958 else 959 error = 0; 960 } 961 return error; 962 } 963 964 static void 965 awi_media_status(struct ifnet *ifp, struct ifmediareq *imr) 966 { 967 struct awi_softc *sc = ifp->if_softc; 968 struct ieee80211com *ic = &sc->sc_ic; 969 int rate; 970 enum ieee80211_phymode mode; 971 972 imr->ifm_status = IFM_AVALID; 973 if (ic->ic_state == IEEE80211_S_RUN) 974 imr->ifm_status |= IFM_ACTIVE; 975 imr->ifm_active = IFM_IEEE80211; 976 if (ic->ic_phytype == IEEE80211_T_FH) 977 mode = IEEE80211_MODE_FH; 978 else 979 mode = IEEE80211_MODE_11B; 980 if (ic->ic_state == IEEE80211_S_RUN) { 981 rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_bss->ni_txrate] & 982 IEEE80211_RATE_VAL; 983 } else { 984 if (ic->ic_fixed_rate == -1) 985 rate = 0; 986 else 987 rate = ic->ic_sup_rates[mode]. 988 rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; 989 } 990 imr->ifm_active |= ieee80211_rate2media(ic, rate, mode); 991 switch (ic->ic_opmode) { 992 case IEEE80211_M_MONITOR: /* we should never reach here */ 993 break; 994 case IEEE80211_M_STA: 995 break; 996 case IEEE80211_M_IBSS: 997 if (sc->sc_adhoc_ap) 998 imr->ifm_active |= IFM_FLAG0; 999 else 1000 imr->ifm_active |= IFM_IEEE80211_ADHOC; 1001 break; 1002 case IEEE80211_M_AHDEMO: 1003 imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0; 1004 break; 1005 case IEEE80211_M_HOSTAP: 1006 imr->ifm_active |= IFM_IEEE80211_HOSTAP; 1007 break; 1008 } 1009 } 1010 1011 static int 1012 awi_mode_init(struct awi_softc *sc) 1013 { 1014 struct ifnet *ifp = &sc->sc_if; 1015 int n, error; 1016 struct ether_multi *enm; 1017 struct ether_multistep step; 1018 1019 /* reinitialize muticast filter */ 1020 n = 0; 1021 sc->sc_mib_local.Accept_All_Multicast_Dis = 0; 1022 if (sc->sc_ic.ic_opmode != IEEE80211_M_HOSTAP && 1023 (ifp->if_flags & IFF_PROMISC)) { 1024 sc->sc_mib_mac.aPromiscuous_Enable = 1; 1025 goto set_mib; 1026 } 1027 sc->sc_mib_mac.aPromiscuous_Enable = 0; 1028 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm); 1029 while (enm != NULL) { 1030 if (n == AWI_GROUP_ADDR_SIZE || 1031 !IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi)) 1032 goto set_mib; 1033 IEEE80211_ADDR_COPY(sc->sc_mib_addr.aGroup_Addresses[n], 1034 enm->enm_addrlo); 1035 n++; 1036 ETHER_NEXT_MULTI(step, enm); 1037 } 1038 for (; n < AWI_GROUP_ADDR_SIZE; n++) 1039 memset(sc->sc_mib_addr.aGroup_Addresses[n], 0, 1040 IEEE80211_ADDR_LEN); 1041 sc->sc_mib_local.Accept_All_Multicast_Dis = 1; 1042 1043 set_mib: 1044 if (sc->sc_mib_local.Accept_All_Multicast_Dis) 1045 ifp->if_flags &= ~IFF_ALLMULTI; 1046 else 1047 ifp->if_flags |= IFF_ALLMULTI; 1048 sc->sc_mib_mgt.Wep_Required = 1049 (sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) ? AWI_WEP_ON : AWI_WEP_OFF; 1050 1051 if ((error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_LOCAL, AWI_WAIT)) || 1052 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_ADDR, AWI_WAIT)) || 1053 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MAC, AWI_WAIT)) || 1054 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT, AWI_WAIT)) || 1055 (error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_PHY, AWI_WAIT))) { 1056 DPRINTF(("awi_mode_init: MIB set failed: %d\n", error)); 1057 return error; 1058 } 1059 return 0; 1060 } 1061 1062 static void 1063 awi_rx_int(struct awi_softc *sc) 1064 { 1065 struct ieee80211com *ic = &sc->sc_ic; 1066 struct ifnet *ifp = &sc->sc_if; 1067 struct ieee80211_frame_min *wh; 1068 struct ieee80211_node *ni; 1069 u_int8_t state, rate, rssi; 1070 u_int16_t len; 1071 u_int32_t frame, next, rstamp, rxoff; 1072 struct mbuf *m; 1073 1074 rxoff = sc->sc_rxdoff; 1075 for (;;) { 1076 state = awi_read_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE); 1077 if (state & AWI_RXD_ST_OWN) 1078 break; 1079 if (!(state & AWI_RXD_ST_CONSUMED)) { 1080 if (sc->sc_substate != AWI_ST_NONE) 1081 goto rx_next; 1082 if (state & AWI_RXD_ST_RXERROR) { 1083 ifp->if_ierrors++; 1084 goto rx_next; 1085 } 1086 len = awi_read_2(sc, rxoff + AWI_RXD_LEN); 1087 rate = awi_read_1(sc, rxoff + AWI_RXD_RATE); 1088 rssi = awi_read_1(sc, rxoff + AWI_RXD_RSSI); 1089 frame = awi_read_4(sc, rxoff + AWI_RXD_START_FRAME) & 1090 0x7fff; 1091 rstamp = awi_read_4(sc, rxoff + AWI_RXD_LOCALTIME); 1092 m = awi_devget(sc, frame, len); 1093 if (m == NULL) { 1094 ifp->if_ierrors++; 1095 goto rx_next; 1096 } 1097 if (state & AWI_RXD_ST_LF) { 1098 /* TODO check my bss */ 1099 if (!(sc->sc_ic.ic_flags & IEEE80211_F_SIBSS) && 1100 sc->sc_ic.ic_state == IEEE80211_S_RUN) { 1101 sc->sc_rx_timer = 10; 1102 ifp->if_timer = 1; 1103 } 1104 if ((ifp->if_flags & IFF_DEBUG) && 1105 (ifp->if_flags & IFF_LINK2)) 1106 ieee80211_dump_pkt(m->m_data, m->m_len, 1107 rate / 5, rssi); 1108 if ((ifp->if_flags & IFF_LINK0) || 1109 sc->sc_adhoc_ap) 1110 m = awi_ether_modcap(sc, m); 1111 else 1112 m = m_pullup(m, sizeof(*wh)); 1113 if (m == NULL) { 1114 ifp->if_ierrors++; 1115 goto rx_next; 1116 } 1117 wh = mtod(m, struct ieee80211_frame_min *); 1118 ni = ieee80211_find_rxnode(ic, wh); 1119 ieee80211_input(ic, m, ni, rssi, rstamp); 1120 /* 1121 * The frame may have caused the 1122 * node to be marked for reclamation 1123 * (e.g. in response to a DEAUTH 1124 * message) so use release_node here 1125 * instead of unref_node. 1126 */ 1127 ieee80211_free_node(ni); 1128 } else 1129 sc->sc_rxpend = m; 1130 rx_next: 1131 state |= AWI_RXD_ST_CONSUMED; 1132 awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state); 1133 } 1134 next = awi_read_4(sc, rxoff + AWI_RXD_NEXT); 1135 if (next & AWI_RXD_NEXT_LAST) 1136 break; 1137 /* make sure the next pointer is correct */ 1138 if (next != awi_read_4(sc, rxoff + AWI_RXD_NEXT)) 1139 break; 1140 state |= AWI_RXD_ST_OWN; 1141 awi_write_1(sc, rxoff + AWI_RXD_HOST_DESC_STATE, state); 1142 rxoff = next & 0x7fff; 1143 } 1144 sc->sc_rxdoff = rxoff; 1145 } 1146 1147 static void 1148 awi_tx_int(struct awi_softc *sc) 1149 { 1150 struct ifnet *ifp = &sc->sc_if; 1151 u_int8_t flags; 1152 1153 while (sc->sc_txdone != sc->sc_txnext) { 1154 flags = awi_read_1(sc, sc->sc_txdone + AWI_TXD_STATE); 1155 if ((flags & AWI_TXD_ST_OWN) || !(flags & AWI_TXD_ST_DONE)) 1156 break; 1157 if (flags & AWI_TXD_ST_ERROR) 1158 ifp->if_oerrors++; 1159 sc->sc_txdone = awi_read_4(sc, sc->sc_txdone + AWI_TXD_NEXT) & 1160 0x7fff; 1161 } 1162 DPRINTF2(("awi_txint: txdone %d txnext %d txbase %d txend %d\n", 1163 sc->sc_txdone, sc->sc_txnext, sc->sc_txbase, sc->sc_txend)); 1164 sc->sc_tx_timer = 0; 1165 ifp->if_flags &= ~IFF_OACTIVE; 1166 awi_start(ifp); 1167 } 1168 1169 static struct mbuf * 1170 awi_devget(struct awi_softc *sc, u_int32_t off, u_int16_t len) 1171 { 1172 struct ifnet *ifp = &sc->sc_if; 1173 struct mbuf *m; 1174 struct mbuf *top, **mp; 1175 u_int tlen; 1176 1177 top = sc->sc_rxpend; 1178 mp = ⊤ 1179 if (top != NULL) { 1180 sc->sc_rxpend = NULL; 1181 top->m_pkthdr.len += len; 1182 m = top; 1183 while (*mp != NULL) { 1184 m = *mp; 1185 mp = &m->m_next; 1186 } 1187 if (m->m_flags & M_EXT) 1188 tlen = m->m_ext.ext_size; 1189 else if (m->m_flags & M_PKTHDR) 1190 tlen = MHLEN; 1191 else 1192 tlen = MLEN; 1193 tlen -= m->m_len; 1194 if (tlen > len) 1195 tlen = len; 1196 awi_read_bytes(sc, off, mtod(m, u_int8_t *) + m->m_len, tlen); 1197 off += tlen; 1198 len -= tlen; 1199 } 1200 1201 while (len > 0) { 1202 if (top == NULL) { 1203 MGETHDR(m, M_DONTWAIT, MT_DATA); 1204 if (m == NULL) 1205 return NULL; 1206 m->m_pkthdr.rcvif = ifp; 1207 m->m_pkthdr.len = len; 1208 m->m_len = MHLEN; 1209 m->m_flags |= M_HASFCS; 1210 } else { 1211 MGET(m, M_DONTWAIT, MT_DATA); 1212 if (m == NULL) { 1213 m_freem(top); 1214 return NULL; 1215 } 1216 m->m_len = MLEN; 1217 } 1218 if (len >= MINCLSIZE) { 1219 MCLGET(m, M_DONTWAIT); 1220 if (m->m_flags & M_EXT) 1221 m->m_len = m->m_ext.ext_size; 1222 } 1223 if (top == NULL) { 1224 int hdrlen = sizeof(struct ieee80211_frame) + 1225 sizeof(struct llc); 1226 char *newdata = (char *) 1227 ALIGN(m->m_data + hdrlen) - hdrlen; 1228 m->m_len -= newdata - m->m_data; 1229 m->m_data = newdata; 1230 } 1231 if (m->m_len > len) 1232 m->m_len = len; 1233 awi_read_bytes(sc, off, mtod(m, u_int8_t *), m->m_len); 1234 off += m->m_len; 1235 len -= m->m_len; 1236 *mp = m; 1237 mp = &m->m_next; 1238 } 1239 return top; 1240 } 1241 1242 /* 1243 * Initialize hardware and start firmware to accept commands. 1244 * Called everytime after power on firmware. 1245 */ 1246 1247 static int 1248 awi_hw_init(struct awi_softc *sc) 1249 { 1250 u_int8_t status; 1251 u_int16_t intmask; 1252 int i, error; 1253 1254 sc->sc_enab_intr = 0; 1255 awi_drvstate(sc, AWI_DRV_RESET); 1256 1257 /* reset firmware */ 1258 am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_CORESET); 1259 DELAY(100); 1260 awi_write_1(sc, AWI_SELFTEST, 0); 1261 awi_write_1(sc, AWI_CMD, 0); 1262 awi_write_1(sc, AWI_BANNER, 0); 1263 am79c930_gcr_clearbits(&sc->sc_chip, AM79C930_GCR_CORESET); 1264 DELAY(100); 1265 1266 /* wait for selftest completion */ 1267 for (i = 0; ; i++) { 1268 if (!device_is_active(&sc->sc_dev)) 1269 return ENXIO; 1270 if (i >= AWI_SELFTEST_TIMEOUT*hz/1000) { 1271 printf("%s: failed to complete selftest (timeout)\n", 1272 sc->sc_if.if_xname); 1273 return ENXIO; 1274 } 1275 status = awi_read_1(sc, AWI_SELFTEST); 1276 if ((status & 0xf0) == 0xf0) 1277 break; 1278 if (sc->sc_cansleep) { 1279 sc->sc_sleep_cnt++; 1280 (void)tsleep(sc, PWAIT, "awitst", 1); 1281 sc->sc_sleep_cnt--; 1282 } else { 1283 DELAY(1000*1000/hz); 1284 } 1285 } 1286 if (status != AWI_SELFTEST_PASSED) { 1287 printf("%s: failed to complete selftest (code %x)\n", 1288 sc->sc_if.if_xname, status); 1289 return ENXIO; 1290 } 1291 1292 /* check banner to confirm firmware write it */ 1293 awi_read_bytes(sc, AWI_BANNER, sc->sc_banner, AWI_BANNER_LEN); 1294 if (memcmp(sc->sc_banner, "PCnetMobile:", 12) != 0) { 1295 printf("%s: failed to complete selftest (bad banner)\n", 1296 sc->sc_if.if_xname); 1297 for (i = 0; i < AWI_BANNER_LEN; i++) 1298 printf("%s%02x", i ? ":" : "\t", sc->sc_banner[i]); 1299 printf("\n"); 1300 return ENXIO; 1301 } 1302 1303 /* initializing interrupt */ 1304 sc->sc_enab_intr = 1; 1305 error = awi_intr_lock(sc); 1306 if (error) 1307 return error; 1308 intmask = AWI_INT_GROGGY | AWI_INT_SCAN_CMPLT | 1309 AWI_INT_TX | AWI_INT_RX | AWI_INT_CMD; 1310 awi_write_1(sc, AWI_INTMASK, ~intmask & 0xff); 1311 awi_write_1(sc, AWI_INTMASK2, 0); 1312 awi_write_1(sc, AWI_INTSTAT, 0); 1313 awi_write_1(sc, AWI_INTSTAT2, 0); 1314 awi_intr_unlock(sc); 1315 am79c930_gcr_setbits(&sc->sc_chip, AM79C930_GCR_ENECINT); 1316 1317 /* issuing interface test command */ 1318 error = awi_cmd(sc, AWI_CMD_NOP, AWI_WAIT); 1319 if (error) { 1320 printf("%s: failed to complete selftest", 1321 sc->sc_if.if_xname); 1322 if (error == ENXIO) 1323 printf(" (no hardware)\n"); 1324 else if (error != EWOULDBLOCK) 1325 printf(" (error %d)\n", error); 1326 else if (sc->sc_cansleep) 1327 printf(" (lost interrupt)\n"); 1328 else 1329 printf(" (command timeout)\n"); 1330 return error; 1331 } 1332 1333 /* Initialize VBM */ 1334 awi_write_1(sc, AWI_VBM_OFFSET, 0); 1335 awi_write_1(sc, AWI_VBM_LENGTH, 1); 1336 awi_write_1(sc, AWI_VBM_BITMAP, 0); 1337 return 0; 1338 } 1339 1340 /* 1341 * Extract the factory default MIB value from firmware and assign the driver 1342 * default value. 1343 * Called once at attaching the interface. 1344 */ 1345 1346 static int 1347 awi_init_mibs(struct awi_softc *sc) 1348 { 1349 int chan, i, error; 1350 struct ieee80211com *ic = &sc->sc_ic; 1351 struct awi_chanset *cs; 1352 1353 if ((error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_LOCAL, AWI_WAIT)) || 1354 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_ADDR, AWI_WAIT)) || 1355 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MAC, AWI_WAIT)) || 1356 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_MGT, AWI_WAIT)) || 1357 (error = awi_mib(sc, AWI_CMD_GET_MIB, AWI_MIB_PHY, AWI_WAIT))) { 1358 printf("%s: failed to get default mib value (error %d)\n", 1359 sc->sc_if.if_xname, error); 1360 return error; 1361 } 1362 1363 memset(&sc->sc_ic.ic_chan_avail, 0, sizeof(sc->sc_ic.ic_chan_avail)); 1364 for (cs = awi_chanset; ; cs++) { 1365 if (cs->cs_type == 0) { 1366 printf("%s: failed to set available channel\n", 1367 sc->sc_if.if_xname); 1368 return ENXIO; 1369 } 1370 if (cs->cs_type == sc->sc_mib_phy.IEEE_PHY_Type && 1371 cs->cs_region == sc->sc_mib_phy.aCurrent_Reg_Domain) 1372 break; 1373 } 1374 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { 1375 for (i = cs->cs_min; i <= cs->cs_max; i++) { 1376 chan = IEEE80211_FH_CHAN(i % 3 + 1, i); 1377 setbit(sc->sc_ic.ic_chan_avail, chan); 1378 /* XXX for FHSS, does frequency matter? */ 1379 ic->ic_channels[chan].ic_freq = 0; 1380 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_FHSS; 1381 /* 1382 * According to the IEEE 802.11 specification, 1383 * hop pattern parameter for FH phy should be 1384 * incremented by 3 for given hop chanset, i.e., 1385 * the chanset parameter is calculated for given 1386 * hop patter. However, BayStack 650 Access Points 1387 * apparently use fixed hop chanset parameter value 1388 * 1 for any hop pattern. So we also try this 1389 * combination of hop chanset and pattern. 1390 */ 1391 chan = IEEE80211_FH_CHAN(1, i); 1392 setbit(sc->sc_ic.ic_chan_avail, chan); 1393 ic->ic_channels[chan].ic_freq = 0; /* XXX */ 1394 ic->ic_channels[chan].ic_flags = IEEE80211_CHAN_FHSS; 1395 } 1396 } else { 1397 for (i = cs->cs_min; i <= cs->cs_max; i++) { 1398 setbit(sc->sc_ic.ic_chan_avail, i); 1399 ic->ic_channels[i].ic_freq = 1400 ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ); 1401 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B; 1402 } 1403 } 1404 sc->sc_cur_chan = cs->cs_def; 1405 ic->ic_ibss_chan = &ic->ic_channels[cs->cs_def]; 1406 1407 sc->sc_mib_local.Fragmentation_Dis = 1; 1408 sc->sc_mib_local.Add_PLCP_Dis = 0; 1409 sc->sc_mib_local.MAC_Hdr_Prsv = 0; 1410 sc->sc_mib_local.Rx_Mgmt_Que_En = 0; 1411 sc->sc_mib_local.Re_Assembly_Dis = 1; 1412 sc->sc_mib_local.Strip_PLCP_Dis = 0; 1413 sc->sc_mib_local.Power_Saving_Mode_Dis = 1; 1414 sc->sc_mib_local.Accept_All_Multicast_Dis = 1; 1415 sc->sc_mib_local.Check_Seq_Cntl_Dis = 0; 1416 sc->sc_mib_local.Flush_CFP_Queue_On_CF_End = 0; 1417 sc->sc_mib_local.Network_Mode = 1; 1418 sc->sc_mib_local.PWD_Lvl = 0; 1419 sc->sc_mib_local.CFP_Mode = 0; 1420 1421 /* allocate buffers */ 1422 sc->sc_txbase = AWI_BUFFERS; 1423 sc->sc_txend = sc->sc_txbase + 1424 (AWI_TXD_SIZE + sizeof(struct ieee80211_frame) + 1425 sizeof(struct ether_header) + ETHERMTU) * AWI_NTXBUFS; 1426 LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Offset, sc->sc_txbase); 1427 LE_WRITE_4(&sc->sc_mib_local.Tx_Buffer_Size, 1428 sc->sc_txend - sc->sc_txbase); 1429 LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Offset, sc->sc_txend); 1430 LE_WRITE_4(&sc->sc_mib_local.Rx_Buffer_Size, 1431 AWI_BUFFERS_END - sc->sc_txend); 1432 sc->sc_mib_local.Acting_as_AP = 0; 1433 sc->sc_mib_local.Fill_CFP = 0; 1434 1435 memset(&sc->sc_mib_mac.aDesired_ESS_ID, 0, AWI_ESS_ID_SIZE); 1436 sc->sc_mib_mac.aDesired_ESS_ID[0] = IEEE80211_ELEMID_SSID; 1437 1438 sc->sc_mib_mgt.aPower_Mgt_Mode = 0; 1439 sc->sc_mib_mgt.aDTIM_Period = 1; 1440 LE_WRITE_2(&sc->sc_mib_mgt.aATIM_Window, 0); 1441 return 0; 1442 } 1443 1444 static int 1445 awi_mib(struct awi_softc *sc, u_int8_t cmd, u_int8_t mib, int wflag) 1446 { 1447 int error; 1448 u_int8_t size, *ptr; 1449 1450 switch (mib) { 1451 case AWI_MIB_LOCAL: 1452 ptr = (u_int8_t *)&sc->sc_mib_local; 1453 size = sizeof(sc->sc_mib_local); 1454 break; 1455 case AWI_MIB_ADDR: 1456 ptr = (u_int8_t *)&sc->sc_mib_addr; 1457 size = sizeof(sc->sc_mib_addr); 1458 break; 1459 case AWI_MIB_MAC: 1460 ptr = (u_int8_t *)&sc->sc_mib_mac; 1461 size = sizeof(sc->sc_mib_mac); 1462 break; 1463 case AWI_MIB_STAT: 1464 ptr = (u_int8_t *)&sc->sc_mib_stat; 1465 size = sizeof(sc->sc_mib_stat); 1466 break; 1467 case AWI_MIB_MGT: 1468 ptr = (u_int8_t *)&sc->sc_mib_mgt; 1469 size = sizeof(sc->sc_mib_mgt); 1470 break; 1471 case AWI_MIB_PHY: 1472 ptr = (u_int8_t *)&sc->sc_mib_phy; 1473 size = sizeof(sc->sc_mib_phy); 1474 break; 1475 default: 1476 return EINVAL; 1477 } 1478 if (sc->sc_cmd_inprog) { 1479 if ((error = awi_cmd_wait(sc)) != 0) { 1480 if (error == EWOULDBLOCK) { 1481 DPRINTF(("awi_mib: cmd %d inprog", 1482 sc->sc_cmd_inprog)); 1483 } 1484 return error; 1485 } 1486 } 1487 sc->sc_cmd_inprog = cmd; 1488 if (cmd == AWI_CMD_SET_MIB) 1489 awi_write_bytes(sc, AWI_CA_MIB_DATA, ptr, size); 1490 awi_write_1(sc, AWI_CA_MIB_TYPE, mib); 1491 awi_write_1(sc, AWI_CA_MIB_SIZE, size); 1492 awi_write_1(sc, AWI_CA_MIB_INDEX, 0); 1493 if ((error = awi_cmd(sc, cmd, wflag)) != 0) 1494 return error; 1495 if (cmd == AWI_CMD_GET_MIB) { 1496 awi_read_bytes(sc, AWI_CA_MIB_DATA, ptr, size); 1497 #ifdef AWI_DEBUG 1498 if (awi_debug) { 1499 int i; 1500 1501 printf("awi_mib: #%d:", mib); 1502 for (i = 0; i < size; i++) 1503 printf(" %02x", ptr[i]); 1504 printf("\n"); 1505 } 1506 #endif 1507 } 1508 return 0; 1509 } 1510 1511 static int 1512 awi_cmd(struct awi_softc *sc, u_int8_t cmd, int wflag) 1513 { 1514 u_int8_t status; 1515 int error = 0; 1516 #ifdef AWI_DEBUG 1517 static const char *cmdname[] = { 1518 "IDLE", "NOP", "SET_MIB", "INIT_TX", "FLUSH_TX", "INIT_RX", 1519 "KILL_RX", "SLEEP", "WAKE", "GET_MIB", "SCAN", "SYNC", "RESUME" 1520 }; 1521 #endif 1522 1523 #ifdef AWI_DEBUG 1524 if (awi_debug > 1) { 1525 if (cmd >= sizeof(cmdname)/sizeof(cmdname[0])) 1526 printf("awi_cmd: #%d", cmd); 1527 else 1528 printf("awi_cmd: %s", cmdname[cmd]); 1529 printf(" %s\n", wflag == AWI_NOWAIT ? "nowait" : "wait"); 1530 } 1531 #endif 1532 sc->sc_cmd_inprog = cmd; 1533 awi_write_1(sc, AWI_CMD_STATUS, AWI_STAT_IDLE); 1534 awi_write_1(sc, AWI_CMD, cmd); 1535 if (wflag == AWI_NOWAIT) 1536 return EINPROGRESS; 1537 if ((error = awi_cmd_wait(sc)) != 0) 1538 return error; 1539 status = awi_read_1(sc, AWI_CMD_STATUS); 1540 awi_write_1(sc, AWI_CMD, 0); 1541 switch (status) { 1542 case AWI_STAT_OK: 1543 break; 1544 case AWI_STAT_BADPARM: 1545 return EINVAL; 1546 default: 1547 printf("%s: command %d failed %x\n", 1548 sc->sc_if.if_xname, cmd, status); 1549 return ENXIO; 1550 } 1551 return 0; 1552 } 1553 1554 static int 1555 awi_cmd_wait(struct awi_softc *sc) 1556 { 1557 int i, error = 0; 1558 1559 i = 0; 1560 while (sc->sc_cmd_inprog) { 1561 if (!device_is_active(&sc->sc_dev)) 1562 return ENXIO; 1563 if (awi_read_1(sc, AWI_CMD) != sc->sc_cmd_inprog) { 1564 printf("%s: failed to access hardware\n", 1565 sc->sc_if.if_xname); 1566 config_deactivate(&sc->sc_dev); 1567 return ENXIO; 1568 } 1569 if (sc->sc_cansleep) { 1570 sc->sc_sleep_cnt++; 1571 error = tsleep(sc, PWAIT, "awicmd", 1572 AWI_CMD_TIMEOUT*hz/1000); 1573 sc->sc_sleep_cnt--; 1574 } else { 1575 if (awi_read_1(sc, AWI_CMD_STATUS) != AWI_STAT_IDLE) { 1576 awi_cmd_done(sc); 1577 break; 1578 } 1579 if (i++ >= AWI_CMD_TIMEOUT*1000/10) 1580 error = EWOULDBLOCK; 1581 else 1582 DELAY(10); 1583 } 1584 if (error) 1585 break; 1586 } 1587 if (error) { 1588 DPRINTF(("awi_cmd_wait: cmd 0x%x, error %d\n", 1589 sc->sc_cmd_inprog, error)); 1590 } 1591 return error; 1592 } 1593 1594 static void 1595 awi_cmd_done(struct awi_softc *sc) 1596 { 1597 u_int8_t cmd, status; 1598 1599 status = awi_read_1(sc, AWI_CMD_STATUS); 1600 if (status == AWI_STAT_IDLE) 1601 return; /* stray interrupt */ 1602 1603 cmd = sc->sc_cmd_inprog; 1604 sc->sc_cmd_inprog = 0; 1605 wakeup(sc); 1606 awi_write_1(sc, AWI_CMD, 0); 1607 1608 if (status != AWI_STAT_OK) { 1609 printf("%s: command %d failed %x\n", 1610 sc->sc_if.if_xname, cmd, status); 1611 sc->sc_substate = AWI_ST_NONE; 1612 return; 1613 } 1614 if (sc->sc_substate != AWI_ST_NONE) 1615 (void)ieee80211_new_state(&sc->sc_ic, sc->sc_nstate, -1); 1616 } 1617 1618 static int 1619 awi_next_txd(struct awi_softc *sc, int len, u_int32_t *framep, u_int32_t *ntxdp) 1620 { 1621 u_int32_t txd, ntxd, frame; 1622 1623 txd = sc->sc_txnext; 1624 frame = txd + AWI_TXD_SIZE; 1625 if (frame + len > sc->sc_txend) 1626 frame = sc->sc_txbase; 1627 ntxd = frame + len; 1628 if (ntxd + AWI_TXD_SIZE > sc->sc_txend) 1629 ntxd = sc->sc_txbase; 1630 *framep = frame; 1631 *ntxdp = ntxd; 1632 /* 1633 * Determine if there are any room in ring buffer. 1634 * --- send wait, === new data, +++ conflict (ENOBUFS) 1635 * base........................end 1636 * done----txd=====ntxd OK 1637 * --txd=====done++++ntxd-- full 1638 * --txd=====ntxd done-- OK 1639 * ==ntxd done----txd=== OK 1640 * ==done++++ntxd----txd=== full 1641 * ++ntxd txd=====done++ full 1642 */ 1643 if (txd < ntxd) { 1644 if (txd < sc->sc_txdone && ntxd + AWI_TXD_SIZE > sc->sc_txdone) 1645 return ENOBUFS; 1646 } else { 1647 if (txd < sc->sc_txdone || ntxd + AWI_TXD_SIZE > sc->sc_txdone) 1648 return ENOBUFS; 1649 } 1650 return 0; 1651 } 1652 1653 static int 1654 awi_lock(struct awi_softc *sc) 1655 { 1656 int error = 0; 1657 1658 if (curlwp == NULL) 1659 { 1660 /* 1661 * XXX 1662 * Though driver ioctl should be called with context, 1663 * KAME ipv6 stack calls ioctl in interrupt for now. 1664 * We simply abort the request if there are other 1665 * ioctl requests in progress. 1666 */ 1667 if (sc->sc_busy) { 1668 if (!device_is_active(&sc->sc_dev)) 1669 return ENXIO; 1670 return EWOULDBLOCK; 1671 } 1672 sc->sc_busy = 1; 1673 sc->sc_cansleep = 0; 1674 return 0; 1675 } 1676 while (sc->sc_busy) { 1677 if (!device_is_active(&sc->sc_dev)) 1678 return ENXIO; 1679 sc->sc_sleep_cnt++; 1680 error = tsleep(sc, PWAIT | PCATCH, "awilck", 0); 1681 sc->sc_sleep_cnt--; 1682 if (error) 1683 return error; 1684 } 1685 sc->sc_busy = 1; 1686 sc->sc_cansleep = 1; 1687 return 0; 1688 } 1689 1690 static void 1691 awi_unlock(struct awi_softc *sc) 1692 { 1693 sc->sc_busy = 0; 1694 sc->sc_cansleep = 0; 1695 if (sc->sc_sleep_cnt) 1696 wakeup(sc); 1697 } 1698 1699 static int 1700 awi_intr_lock(struct awi_softc *sc) 1701 { 1702 u_int8_t status; 1703 int i, retry; 1704 1705 status = 1; 1706 for (retry = 0; retry < 10; retry++) { 1707 for (i = 0; i < AWI_LOCKOUT_TIMEOUT*1000/5; i++) { 1708 if ((status = awi_read_1(sc, AWI_LOCKOUT_HOST)) == 0) 1709 break; 1710 DELAY(5); 1711 } 1712 if (status != 0) 1713 break; 1714 awi_write_1(sc, AWI_LOCKOUT_MAC, 1); 1715 if ((status = awi_read_1(sc, AWI_LOCKOUT_HOST)) == 0) 1716 break; 1717 awi_write_1(sc, AWI_LOCKOUT_MAC, 0); 1718 } 1719 if (status != 0) { 1720 printf("%s: failed to lock interrupt\n", 1721 sc->sc_if.if_xname); 1722 return ENXIO; 1723 } 1724 return 0; 1725 } 1726 1727 static void 1728 awi_intr_unlock(struct awi_softc *sc) 1729 { 1730 1731 awi_write_1(sc, AWI_LOCKOUT_MAC, 0); 1732 } 1733 1734 static int 1735 awi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) 1736 { 1737 struct ifnet *ifp = ic->ic_ifp; 1738 struct awi_softc *sc = ifp->if_softc; 1739 struct ieee80211_node *ni; 1740 int error; 1741 u_int8_t newmode; 1742 enum ieee80211_state ostate; 1743 #ifdef AWI_DEBUG 1744 static const char *stname[] = 1745 { "INIT", "SCAN", "AUTH", "ASSOC", "RUN" }; 1746 static const char *substname[] = 1747 { "NONE", "SCAN_INIT", "SCAN_SETMIB", "SCAN_SCCMD", 1748 "SUB_INIT", "SUB_SETSS", "SUB_SYNC" }; 1749 #endif /* AWI_DEBUG */ 1750 1751 ostate = ic->ic_state; 1752 DPRINTF(("awi_newstate: %s (%s/%s) -> %s\n", stname[ostate], 1753 stname[sc->sc_nstate], substname[sc->sc_substate], stname[nstate])); 1754 1755 /* set LED */ 1756 switch (nstate) { 1757 case IEEE80211_S_INIT: 1758 awi_drvstate(sc, AWI_DRV_RESET); 1759 break; 1760 case IEEE80211_S_SCAN: 1761 if (ic->ic_opmode == IEEE80211_M_IBSS || 1762 ic->ic_opmode == IEEE80211_M_AHDEMO) 1763 awi_drvstate(sc, AWI_DRV_ADHSC); 1764 else 1765 awi_drvstate(sc, AWI_DRV_INFSY); 1766 break; 1767 case IEEE80211_S_AUTH: 1768 awi_drvstate(sc, AWI_DRV_INFSY); 1769 break; 1770 case IEEE80211_S_ASSOC: 1771 awi_drvstate(sc, AWI_DRV_INFAUTH); 1772 break; 1773 case IEEE80211_S_RUN: 1774 if (ic->ic_opmode == IEEE80211_M_IBSS || 1775 ic->ic_opmode == IEEE80211_M_AHDEMO) 1776 awi_drvstate(sc, AWI_DRV_ADHSY); 1777 else 1778 awi_drvstate(sc, AWI_DRV_INFASSOC); 1779 break; 1780 } 1781 1782 if (nstate == IEEE80211_S_INIT) { 1783 sc->sc_substate = AWI_ST_NONE; 1784 ic->ic_flags &= ~IEEE80211_F_SIBSS; 1785 return (*sc->sc_newstate)(ic, nstate, arg); 1786 } 1787 1788 /* state transition */ 1789 if (nstate == IEEE80211_S_SCAN) { 1790 /* SCAN substate */ 1791 if (sc->sc_substate == AWI_ST_NONE) { 1792 sc->sc_nstate = nstate; /* next state in transition */ 1793 sc->sc_substate = AWI_ST_SCAN_INIT; 1794 } 1795 switch (sc->sc_substate) { 1796 case AWI_ST_SCAN_INIT: 1797 sc->sc_substate = AWI_ST_SCAN_SETMIB; 1798 switch (ostate) { 1799 case IEEE80211_S_RUN: 1800 /* beacon miss */ 1801 if (ifp->if_flags & IFF_DEBUG) 1802 printf("%s: no recent beacons from %s;" 1803 " rescanning\n", 1804 ifp->if_xname, 1805 ether_sprintf(ic->ic_bss->ni_bssid)); 1806 /* FALLTHRU */ 1807 case IEEE80211_S_AUTH: 1808 case IEEE80211_S_ASSOC: 1809 case IEEE80211_S_INIT: 1810 ieee80211_begin_scan(ic, 1); 1811 /* FALLTHRU */ 1812 case IEEE80211_S_SCAN: 1813 /* scan next */ 1814 break; 1815 } 1816 if (ic->ic_flags & IEEE80211_F_ASCAN) 1817 newmode = AWI_SCAN_ACTIVE; 1818 else 1819 newmode = AWI_SCAN_PASSIVE; 1820 if (sc->sc_mib_mgt.aScan_Mode != newmode) { 1821 sc->sc_mib_mgt.aScan_Mode = newmode; 1822 if ((error = awi_mib(sc, AWI_CMD_SET_MIB, 1823 AWI_MIB_MGT, AWI_NOWAIT)) != 0) 1824 break; 1825 } 1826 /* FALLTHRU */ 1827 case AWI_ST_SCAN_SETMIB: 1828 sc->sc_substate = AWI_ST_SCAN_SCCMD; 1829 if (sc->sc_cmd_inprog) { 1830 if ((error = awi_cmd_wait(sc)) != 0) 1831 break; 1832 } 1833 sc->sc_cmd_inprog = AWI_CMD_SCAN; 1834 ni = ic->ic_bss; 1835 awi_write_2(sc, AWI_CA_SCAN_DURATION, 1836 (ic->ic_flags & IEEE80211_F_ASCAN) ? 1837 AWI_ASCAN_DURATION : AWI_PSCAN_DURATION); 1838 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { 1839 awi_write_1(sc, AWI_CA_SCAN_SET, 1840 IEEE80211_FH_CHANSET( 1841 ieee80211_chan2ieee(ic, ni->ni_chan))); 1842 awi_write_1(sc, AWI_CA_SCAN_PATTERN, 1843 IEEE80211_FH_CHANPAT( 1844 ieee80211_chan2ieee(ic, ni->ni_chan))); 1845 awi_write_1(sc, AWI_CA_SCAN_IDX, 1); 1846 } else { 1847 awi_write_1(sc, AWI_CA_SCAN_SET, 1848 ieee80211_chan2ieee(ic, ni->ni_chan)); 1849 awi_write_1(sc, AWI_CA_SCAN_PATTERN, 0); 1850 awi_write_1(sc, AWI_CA_SCAN_IDX, 0); 1851 } 1852 awi_write_1(sc, AWI_CA_SCAN_SUSP, 0); 1853 sc->sc_cur_chan = ieee80211_chan2ieee(ic, ni->ni_chan); 1854 if ((error = awi_cmd(sc, AWI_CMD_SCAN, AWI_NOWAIT)) 1855 != 0) 1856 break; 1857 /* FALLTHRU */ 1858 case AWI_ST_SCAN_SCCMD: 1859 ic->ic_state = nstate; 1860 sc->sc_substate = AWI_ST_NONE; 1861 error = EINPROGRESS; 1862 break; 1863 default: 1864 DPRINTF(("awi_newstate: unexpected state %s/%s\n", 1865 stname[nstate], substname[sc->sc_substate])); 1866 sc->sc_substate = AWI_ST_NONE; 1867 error = EIO; 1868 break; 1869 } 1870 goto out; 1871 } 1872 1873 if (ostate == IEEE80211_S_SCAN) { 1874 /* set SSID and channel */ 1875 /* substate */ 1876 if (sc->sc_substate == AWI_ST_NONE) { 1877 sc->sc_nstate = nstate; /* next state in transition */ 1878 sc->sc_substate = AWI_ST_SUB_INIT; 1879 } 1880 ni = ic->ic_bss; 1881 switch (sc->sc_substate) { 1882 case AWI_ST_SUB_INIT: 1883 sc->sc_substate = AWI_ST_SUB_SETSS; 1884 IEEE80211_ADDR_COPY(&sc->sc_mib_mgt.aCurrent_BSS_ID, 1885 ni->ni_bssid); 1886 memset(&sc->sc_mib_mgt.aCurrent_ESS_ID, 0, 1887 AWI_ESS_ID_SIZE); 1888 sc->sc_mib_mgt.aCurrent_ESS_ID[0] = 1889 IEEE80211_ELEMID_SSID; 1890 sc->sc_mib_mgt.aCurrent_ESS_ID[1] = ni->ni_esslen; 1891 memcpy(&sc->sc_mib_mgt.aCurrent_ESS_ID[2], 1892 ni->ni_essid, ni->ni_esslen); 1893 LE_WRITE_2(&sc->sc_mib_mgt.aBeacon_Period, 1894 ni->ni_intval); 1895 if ((error = awi_mib(sc, AWI_CMD_SET_MIB, AWI_MIB_MGT, 1896 AWI_NOWAIT)) != 0) 1897 break; 1898 /* FALLTHRU */ 1899 case AWI_ST_SUB_SETSS: 1900 sc->sc_substate = AWI_ST_SUB_SYNC; 1901 if (sc->sc_cmd_inprog) { 1902 if ((error = awi_cmd_wait(sc)) != 0) 1903 break; 1904 } 1905 sc->sc_cmd_inprog = AWI_CMD_SYNC; 1906 if (sc->sc_mib_phy.IEEE_PHY_Type == AWI_PHY_TYPE_FH) { 1907 awi_write_1(sc, AWI_CA_SYNC_SET, 1908 IEEE80211_FH_CHANSET( 1909 ieee80211_chan2ieee(ic, ni->ni_chan))); 1910 awi_write_1(sc, AWI_CA_SYNC_PATTERN, 1911 IEEE80211_FH_CHANPAT( 1912 ieee80211_chan2ieee(ic, ni->ni_chan))); 1913 awi_write_1(sc, AWI_CA_SYNC_IDX, 1914 ni->ni_fhindex); 1915 awi_write_2(sc, AWI_CA_SYNC_DWELL, 1916 ni->ni_fhdwell); 1917 } else { 1918 awi_write_1(sc, AWI_CA_SYNC_SET, 1919 ieee80211_chan2ieee(ic, ni->ni_chan)); 1920 awi_write_1(sc, AWI_CA_SYNC_PATTERN, 0); 1921 awi_write_1(sc, AWI_CA_SYNC_IDX, 0); 1922 awi_write_2(sc, AWI_CA_SYNC_DWELL, 0); 1923 } 1924 if (ic->ic_flags & IEEE80211_F_SIBSS) { 1925 memset(&ni->ni_tstamp, 0, 1926 sizeof(ni->ni_tstamp)); 1927 ni->ni_rstamp = 0; 1928 awi_write_1(sc, AWI_CA_SYNC_STARTBSS, 1); 1929 } else 1930 awi_write_1(sc, AWI_CA_SYNC_STARTBSS, 0); 1931 awi_write_2(sc, AWI_CA_SYNC_MBZ, 0); 1932 awi_write_bytes(sc, AWI_CA_SYNC_TIMESTAMP, 1933 ni->ni_tstamp.data, sizeof(ni->ni_tstamp.data)); 1934 awi_write_4(sc, AWI_CA_SYNC_REFTIME, ni->ni_rstamp); 1935 sc->sc_cur_chan = ieee80211_chan2ieee(ic, ni->ni_chan); 1936 if ((error = awi_cmd(sc, AWI_CMD_SYNC, AWI_NOWAIT)) 1937 != 0) 1938 break; 1939 /* FALLTHRU */ 1940 case AWI_ST_SUB_SYNC: 1941 sc->sc_substate = AWI_ST_NONE; 1942 if (ic->ic_flags & IEEE80211_F_SIBSS) { 1943 if ((error = awi_mib(sc, AWI_CMD_GET_MIB, 1944 AWI_MIB_MGT, AWI_WAIT)) != 0) 1945 break; 1946 IEEE80211_ADDR_COPY(ni->ni_bssid, 1947 &sc->sc_mib_mgt.aCurrent_BSS_ID); 1948 } else { 1949 if (nstate == IEEE80211_S_RUN) { 1950 sc->sc_rx_timer = 10; 1951 ifp->if_timer = 1; 1952 } 1953 } 1954 error = 0; 1955 break; 1956 default: 1957 DPRINTF(("awi_newstate: unexpected state %s/%s\n", 1958 stname[nstate], substname[sc->sc_substate])); 1959 sc->sc_substate = AWI_ST_NONE; 1960 error = EIO; 1961 break; 1962 } 1963 goto out; 1964 } 1965 1966 sc->sc_substate = AWI_ST_NONE; 1967 1968 return (*sc->sc_newstate)(ic, nstate, arg); 1969 out: 1970 if (error != 0) { 1971 if (error == EINPROGRESS) 1972 error = 0; 1973 return error; 1974 } 1975 return (*sc->sc_newstate)(ic, nstate, arg); 1976 } 1977 1978 static void 1979 awi_recv_mgmt(struct ieee80211com *ic, struct mbuf *m0, 1980 struct ieee80211_node *ni, 1981 int subtype, int rssi, u_int32_t rstamp) 1982 { 1983 struct awi_softc *sc = ic->ic_ifp->if_softc; 1984 1985 /* probe request is handled by hardware */ 1986 if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_REQ) 1987 return; 1988 (*sc->sc_recv_mgmt)(ic, m0, ni, subtype, rssi, rstamp); 1989 } 1990 1991 static int 1992 awi_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni, 1993 int type, int arg) 1994 { 1995 struct awi_softc *sc = ic->ic_ifp->if_softc; 1996 1997 /* probe request is handled by hardware */ 1998 if (type == IEEE80211_FC0_SUBTYPE_PROBE_REQ) 1999 return 0; 2000 return (*sc->sc_send_mgmt)(ic, ni, type, arg); 2001 } 2002 2003 static struct mbuf * 2004 awi_ether_encap(struct awi_softc *sc, struct mbuf *m) 2005 { 2006 struct ieee80211com *ic = &sc->sc_ic; 2007 struct ieee80211_node *ni = ic->ic_bss; 2008 struct ether_header *eh; 2009 struct ieee80211_frame *wh; 2010 2011 if (m->m_len < sizeof(struct ether_header)) { 2012 m = m_pullup(m, sizeof(struct ether_header)); 2013 if (m == NULL) 2014 return NULL; 2015 } 2016 eh = mtod(m, struct ether_header *); 2017 M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT); 2018 if (m == NULL) 2019 return NULL; 2020 wh = mtod(m, struct ieee80211_frame *); 2021 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA; 2022 *(u_int16_t *)wh->i_dur = 0; 2023 *(u_int16_t *)wh->i_seq = 2024 htole16(ni->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT); 2025 ni->ni_txseqs[0]++; 2026 if (ic->ic_opmode == IEEE80211_M_IBSS || 2027 ic->ic_opmode == IEEE80211_M_AHDEMO) { 2028 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 2029 if (sc->sc_adhoc_ap) 2030 IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr); 2031 else 2032 IEEE80211_ADDR_COPY(wh->i_addr1, eh->ether_dhost); 2033 IEEE80211_ADDR_COPY(wh->i_addr2, eh->ether_shost); 2034 IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid); 2035 } else { 2036 wh->i_fc[1] = IEEE80211_FC1_DIR_TODS; 2037 IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid); 2038 IEEE80211_ADDR_COPY(wh->i_addr2, eh->ether_shost); 2039 IEEE80211_ADDR_COPY(wh->i_addr3, eh->ether_dhost); 2040 } 2041 return m; 2042 } 2043 2044 static struct mbuf * 2045 awi_ether_modcap(struct awi_softc *sc, struct mbuf *m) 2046 { 2047 struct ieee80211com *ic = &sc->sc_ic; 2048 struct ether_header eh; 2049 struct ieee80211_frame wh; 2050 struct llc *llc; 2051 2052 if (m->m_len < sizeof(wh) + sizeof(eh)) { 2053 m = m_pullup(m, sizeof(wh) + sizeof(eh)); 2054 if (m == NULL) 2055 return NULL; 2056 } 2057 memcpy(&wh, mtod(m, void *), sizeof(wh)); 2058 if (wh.i_fc[0] != (IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA)) 2059 return m; 2060 memcpy(&eh, mtod(m, char *) + sizeof(wh), sizeof(eh)); 2061 m_adj(m, sizeof(eh) - sizeof(*llc)); 2062 if (ic->ic_opmode == IEEE80211_M_IBSS || 2063 ic->ic_opmode == IEEE80211_M_AHDEMO) 2064 IEEE80211_ADDR_COPY(wh.i_addr2, eh.ether_shost); 2065 memcpy(mtod(m, void *), &wh, sizeof(wh)); 2066 llc = (struct llc *)(mtod(m, char *) + sizeof(wh)); 2067 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 2068 llc->llc_control = LLC_UI; 2069 llc->llc_snap.org_code[0] = 0; 2070 llc->llc_snap.org_code[1] = 0; 2071 llc->llc_snap.org_code[2] = 0; 2072 llc->llc_snap.ether_type = eh.ether_type; 2073 return m; 2074 } 2075