if_mwl.c revision 195171
1/*- 2 * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 2007-2008 Marvell Semiconductor, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer, 11 * without modification. 12 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 13 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 14 * redistribution must be conditioned upon including a substantially 15 * similar Disclaimer requirement for further binary redistribution. 16 * 17 * NO WARRANTY 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 21 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 22 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 23 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 26 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGES. 29 */ 30 31#include <sys/cdefs.h> 32__FBSDID("$FreeBSD: head/sys/dev/mwl/if_mwl.c 195171 2009-06-29 18:42:54Z sam $"); 33 34/* 35 * Driver for the Marvell 88W8363 Wireless LAN controller. 36 */ 37 38#include "opt_inet.h" 39#include "opt_mwl.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/sysctl.h> 44#include <sys/mbuf.h> 45#include <sys/malloc.h> 46#include <sys/lock.h> 47#include <sys/mutex.h> 48#include <sys/kernel.h> 49#include <sys/socket.h> 50#include <sys/sockio.h> 51#include <sys/errno.h> 52#include <sys/callout.h> 53#include <sys/bus.h> 54#include <sys/endian.h> 55#include <sys/kthread.h> 56#include <sys/taskqueue.h> 57 58#include <machine/bus.h> 59 60#include <net/if.h> 61#include <net/if_dl.h> 62#include <net/if_media.h> 63#include <net/if_types.h> 64#include <net/if_arp.h> 65#include <net/ethernet.h> 66#include <net/if_llc.h> 67 68#include <net/bpf.h> 69 70#include <net80211/ieee80211_var.h> 71#include <net80211/ieee80211_regdomain.h> 72 73#ifdef INET 74#include <netinet/in.h> 75#include <netinet/if_ether.h> 76#endif /* INET */ 77 78#include <dev/mwl/if_mwlvar.h> 79#include <dev/mwl/mwldiag.h> 80 81/* idiomatic shorthands: MS = mask+shift, SM = shift+mask */ 82#define MS(v,x) (((v) & x) >> x##_S) 83#define SM(v,x) (((v) << x##_S) & x) 84 85static struct ieee80211vap *mwl_vap_create(struct ieee80211com *, 86 const char name[IFNAMSIZ], int unit, int opmode, 87 int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], 88 const uint8_t mac[IEEE80211_ADDR_LEN]); 89static void mwl_vap_delete(struct ieee80211vap *); 90static int mwl_setupdma(struct mwl_softc *); 91static int mwl_hal_reset(struct mwl_softc *sc); 92static int mwl_init_locked(struct mwl_softc *); 93static void mwl_init(void *); 94static void mwl_stop_locked(struct ifnet *, int); 95static int mwl_reset(struct ieee80211vap *, u_long); 96static void mwl_stop(struct ifnet *, int); 97static void mwl_start(struct ifnet *); 98static int mwl_raw_xmit(struct ieee80211_node *, struct mbuf *, 99 const struct ieee80211_bpf_params *); 100static int mwl_media_change(struct ifnet *); 101static void mwl_watchdog(struct ifnet *); 102static int mwl_ioctl(struct ifnet *, u_long, caddr_t); 103static void mwl_radar_proc(void *, int); 104static void mwl_chanswitch_proc(void *, int); 105static void mwl_bawatchdog_proc(void *, int); 106static int mwl_key_alloc(struct ieee80211vap *, 107 struct ieee80211_key *, 108 ieee80211_keyix *, ieee80211_keyix *); 109static int mwl_key_delete(struct ieee80211vap *, 110 const struct ieee80211_key *); 111static int mwl_key_set(struct ieee80211vap *, const struct ieee80211_key *, 112 const uint8_t mac[IEEE80211_ADDR_LEN]); 113static int mwl_mode_init(struct mwl_softc *); 114static void mwl_update_mcast(struct ifnet *); 115static void mwl_update_promisc(struct ifnet *); 116static void mwl_updateslot(struct ifnet *); 117static int mwl_beacon_setup(struct ieee80211vap *); 118static void mwl_beacon_update(struct ieee80211vap *, int); 119#ifdef MWL_HOST_PS_SUPPORT 120static void mwl_update_ps(struct ieee80211vap *, int); 121static int mwl_set_tim(struct ieee80211_node *, int); 122#endif 123static int mwl_dma_setup(struct mwl_softc *); 124static void mwl_dma_cleanup(struct mwl_softc *); 125static struct ieee80211_node *mwl_node_alloc(struct ieee80211vap *, 126 const uint8_t [IEEE80211_ADDR_LEN]); 127static void mwl_node_cleanup(struct ieee80211_node *); 128static void mwl_node_drain(struct ieee80211_node *); 129static void mwl_node_getsignal(const struct ieee80211_node *, 130 int8_t *, int8_t *); 131static void mwl_node_getmimoinfo(const struct ieee80211_node *, 132 struct ieee80211_mimo_info *); 133static int mwl_rxbuf_init(struct mwl_softc *, struct mwl_rxbuf *); 134static void mwl_rx_proc(void *, int); 135static void mwl_txq_init(struct mwl_softc *sc, struct mwl_txq *, int); 136static int mwl_tx_setup(struct mwl_softc *, int, int); 137static int mwl_wme_update(struct ieee80211com *); 138static void mwl_tx_cleanupq(struct mwl_softc *, struct mwl_txq *); 139static void mwl_tx_cleanup(struct mwl_softc *); 140static uint16_t mwl_calcformat(uint8_t rate, const struct ieee80211_node *); 141static int mwl_tx_start(struct mwl_softc *, struct ieee80211_node *, 142 struct mwl_txbuf *, struct mbuf *); 143static void mwl_tx_proc(void *, int); 144static int mwl_chan_set(struct mwl_softc *, struct ieee80211_channel *); 145static void mwl_draintxq(struct mwl_softc *); 146static void mwl_cleartxq(struct mwl_softc *, struct ieee80211vap *); 147static void mwl_recv_action(struct ieee80211_node *, 148 const uint8_t *, const uint8_t *); 149static int mwl_addba_request(struct ieee80211_node *, 150 struct ieee80211_tx_ampdu *, int dialogtoken, 151 int baparamset, int batimeout); 152static int mwl_addba_response(struct ieee80211_node *, 153 struct ieee80211_tx_ampdu *, int status, 154 int baparamset, int batimeout); 155static void mwl_addba_stop(struct ieee80211_node *, 156 struct ieee80211_tx_ampdu *); 157static int mwl_startrecv(struct mwl_softc *); 158static MWL_HAL_APMODE mwl_getapmode(const struct ieee80211vap *, 159 struct ieee80211_channel *); 160static int mwl_setapmode(struct ieee80211vap *, struct ieee80211_channel*); 161static void mwl_scan_start(struct ieee80211com *); 162static void mwl_scan_end(struct ieee80211com *); 163static void mwl_set_channel(struct ieee80211com *); 164static int mwl_peerstadb(struct ieee80211_node *, 165 int aid, int staid, MWL_HAL_PEERINFO *pi); 166static int mwl_localstadb(struct ieee80211vap *); 167static int mwl_newstate(struct ieee80211vap *, enum ieee80211_state, int); 168static int allocstaid(struct mwl_softc *sc, int aid); 169static void delstaid(struct mwl_softc *sc, int staid); 170static void mwl_newassoc(struct ieee80211_node *, int); 171static void mwl_agestations(void *); 172static int mwl_setregdomain(struct ieee80211com *, 173 struct ieee80211_regdomain *, int, 174 struct ieee80211_channel []); 175static void mwl_getradiocaps(struct ieee80211com *, int, int *, 176 struct ieee80211_channel []); 177static int mwl_getchannels(struct mwl_softc *); 178 179static void mwl_sysctlattach(struct mwl_softc *); 180static void mwl_announce(struct mwl_softc *); 181 182SYSCTL_NODE(_hw, OID_AUTO, mwl, CTLFLAG_RD, 0, "Marvell driver parameters"); 183 184static int mwl_rxdesc = MWL_RXDESC; /* # rx desc's to allocate */ 185SYSCTL_INT(_hw_mwl, OID_AUTO, rxdesc, CTLFLAG_RW, &mwl_rxdesc, 186 0, "rx descriptors allocated"); 187static int mwl_rxbuf = MWL_RXBUF; /* # rx buffers to allocate */ 188SYSCTL_INT(_hw_mwl, OID_AUTO, rxbuf, CTLFLAG_RW, &mwl_rxbuf, 189 0, "rx buffers allocated"); 190TUNABLE_INT("hw.mwl.rxbuf", &mwl_rxbuf); 191static int mwl_txbuf = MWL_TXBUF; /* # tx buffers to allocate */ 192SYSCTL_INT(_hw_mwl, OID_AUTO, txbuf, CTLFLAG_RW, &mwl_txbuf, 193 0, "tx buffers allocated"); 194TUNABLE_INT("hw.mwl.txbuf", &mwl_txbuf); 195static int mwl_txcoalesce = 8; /* # tx packets to q before poking f/w*/ 196SYSCTL_INT(_hw_mwl, OID_AUTO, txcoalesce, CTLFLAG_RW, &mwl_txcoalesce, 197 0, "tx buffers to send at once"); 198TUNABLE_INT("hw.mwl.txcoalesce", &mwl_txcoalesce); 199static int mwl_rxquota = MWL_RXBUF; /* # max buffers to process */ 200SYSCTL_INT(_hw_mwl, OID_AUTO, rxquota, CTLFLAG_RW, &mwl_rxquota, 201 0, "max rx buffers to process per interrupt"); 202TUNABLE_INT("hw.mwl.rxquota", &mwl_rxquota); 203static int mwl_rxdmalow = 3; /* # min buffers for wakeup */ 204SYSCTL_INT(_hw_mwl, OID_AUTO, rxdmalow, CTLFLAG_RW, &mwl_rxdmalow, 205 0, "min free rx buffers before restarting traffic"); 206TUNABLE_INT("hw.mwl.rxdmalow", &mwl_rxdmalow); 207 208#ifdef MWL_DEBUG 209static int mwl_debug = 0; 210SYSCTL_INT(_hw_mwl, OID_AUTO, debug, CTLFLAG_RW, &mwl_debug, 211 0, "control debugging printfs"); 212TUNABLE_INT("hw.mwl.debug", &mwl_debug); 213enum { 214 MWL_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ 215 MWL_DEBUG_XMIT_DESC = 0x00000002, /* xmit descriptors */ 216 MWL_DEBUG_RECV = 0x00000004, /* basic recv operation */ 217 MWL_DEBUG_RECV_DESC = 0x00000008, /* recv descriptors */ 218 MWL_DEBUG_RESET = 0x00000010, /* reset processing */ 219 MWL_DEBUG_BEACON = 0x00000020, /* beacon handling */ 220 MWL_DEBUG_INTR = 0x00000040, /* ISR */ 221 MWL_DEBUG_TX_PROC = 0x00000080, /* tx ISR proc */ 222 MWL_DEBUG_RX_PROC = 0x00000100, /* rx ISR proc */ 223 MWL_DEBUG_KEYCACHE = 0x00000200, /* key cache management */ 224 MWL_DEBUG_STATE = 0x00000400, /* 802.11 state transitions */ 225 MWL_DEBUG_NODE = 0x00000800, /* node management */ 226 MWL_DEBUG_RECV_ALL = 0x00001000, /* trace all frames (beacons) */ 227 MWL_DEBUG_TSO = 0x00002000, /* TSO processing */ 228 MWL_DEBUG_AMPDU = 0x00004000, /* BA stream handling */ 229 MWL_DEBUG_ANY = 0xffffffff 230}; 231#define IS_BEACON(wh) \ 232 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK|IEEE80211_FC0_SUBTYPE_MASK)) == \ 233 (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON)) 234#define IFF_DUMPPKTS_RECV(sc, wh) \ 235 (((sc->sc_debug & MWL_DEBUG_RECV) && \ 236 ((sc->sc_debug & MWL_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \ 237 (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) 238#define IFF_DUMPPKTS_XMIT(sc) \ 239 ((sc->sc_debug & MWL_DEBUG_XMIT) || \ 240 (sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) 241#define DPRINTF(sc, m, fmt, ...) do { \ 242 if (sc->sc_debug & (m)) \ 243 printf(fmt, __VA_ARGS__); \ 244} while (0) 245#define KEYPRINTF(sc, hk, mac) do { \ 246 if (sc->sc_debug & MWL_DEBUG_KEYCACHE) \ 247 mwl_keyprint(sc, __func__, hk, mac); \ 248} while (0) 249static void mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix); 250static void mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix); 251#else 252#define IFF_DUMPPKTS_RECV(sc, wh) \ 253 ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) 254#define IFF_DUMPPKTS_XMIT(sc) \ 255 ((sc->sc_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) 256#define DPRINTF(sc, m, fmt, ...) do { \ 257 (void) sc; \ 258} while (0) 259#define KEYPRINTF(sc, k, mac) do { \ 260 (void) sc; \ 261} while (0) 262#endif 263 264MALLOC_DEFINE(M_MWLDEV, "mwldev", "mwl driver dma buffers"); 265 266/* 267 * Each packet has fixed front matter: a 2-byte length 268 * of the payload, followed by a 4-address 802.11 header 269 * (regardless of the actual header and always w/o any 270 * QoS header). The payload then follows. 271 */ 272struct mwltxrec { 273 uint16_t fwlen; 274 struct ieee80211_frame_addr4 wh; 275} __packed; 276 277/* 278 * Read/Write shorthands for accesses to BAR 0. Note 279 * that all BAR 1 operations are done in the "hal" and 280 * there should be no reference to them here. 281 */ 282static __inline uint32_t 283RD4(struct mwl_softc *sc, bus_size_t off) 284{ 285 return bus_space_read_4(sc->sc_io0t, sc->sc_io0h, off); 286} 287 288static __inline void 289WR4(struct mwl_softc *sc, bus_size_t off, uint32_t val) 290{ 291 bus_space_write_4(sc->sc_io0t, sc->sc_io0h, off, val); 292} 293 294int 295mwl_attach(uint16_t devid, struct mwl_softc *sc) 296{ 297 struct ifnet *ifp; 298 struct ieee80211com *ic; 299 struct mwl_hal *mh; 300 int error = 0; 301 302 DPRINTF(sc, MWL_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid); 303 304 ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); 305 if (ifp == NULL) { 306 device_printf(sc->sc_dev, "can not if_alloc()\n"); 307 return ENOSPC; 308 } 309 ic = ifp->if_l2com; 310 311 /* set these up early for if_printf use */ 312 if_initname(ifp, device_get_name(sc->sc_dev), 313 device_get_unit(sc->sc_dev)); 314 315 mh = mwl_hal_attach(sc->sc_dev, devid, 316 sc->sc_io1h, sc->sc_io1t, sc->sc_dmat); 317 if (mh == NULL) { 318 if_printf(ifp, "unable to attach HAL\n"); 319 error = EIO; 320 goto bad; 321 } 322 sc->sc_mh = mh; 323 /* 324 * Load firmware so we can get setup. We arbitrarily 325 * pick station firmware; we'll re-load firmware as 326 * needed so setting up the wrong mode isn't a big deal. 327 */ 328 if (mwl_hal_fwload(mh, NULL) != 0) { 329 if_printf(ifp, "unable to setup builtin firmware\n"); 330 error = EIO; 331 goto bad1; 332 } 333 if (mwl_hal_gethwspecs(mh, &sc->sc_hwspecs) != 0) { 334 if_printf(ifp, "unable to fetch h/w specs\n"); 335 error = EIO; 336 goto bad1; 337 } 338 error = mwl_getchannels(sc); 339 if (error != 0) 340 goto bad1; 341 342 sc->sc_txantenna = 0; /* h/w default */ 343 sc->sc_rxantenna = 0; /* h/w default */ 344 sc->sc_invalid = 0; /* ready to go, enable int handling */ 345 sc->sc_ageinterval = MWL_AGEINTERVAL; 346 347 /* 348 * Allocate tx+rx descriptors and populate the lists. 349 * We immediately push the information to the firmware 350 * as otherwise it gets upset. 351 */ 352 error = mwl_dma_setup(sc); 353 if (error != 0) { 354 if_printf(ifp, "failed to setup descriptors: %d\n", error); 355 goto bad1; 356 } 357 error = mwl_setupdma(sc); /* push to firmware */ 358 if (error != 0) /* NB: mwl_setupdma prints msg */ 359 goto bad1; 360 361 callout_init(&sc->sc_timer, CALLOUT_MPSAFE); 362 363 sc->sc_tq = taskqueue_create("mwl_taskq", M_NOWAIT, 364 taskqueue_thread_enqueue, &sc->sc_tq); 365 taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, 366 "%s taskq", ifp->if_xname); 367 368 TASK_INIT(&sc->sc_rxtask, 0, mwl_rx_proc, sc); 369 TASK_INIT(&sc->sc_radartask, 0, mwl_radar_proc, sc); 370 TASK_INIT(&sc->sc_chanswitchtask, 0, mwl_chanswitch_proc, sc); 371 TASK_INIT(&sc->sc_bawatchdogtask, 0, mwl_bawatchdog_proc, sc); 372 373 /* NB: insure BK queue is the lowest priority h/w queue */ 374 if (!mwl_tx_setup(sc, WME_AC_BK, MWL_WME_AC_BK)) { 375 if_printf(ifp, "unable to setup xmit queue for %s traffic!\n", 376 ieee80211_wme_acnames[WME_AC_BK]); 377 error = EIO; 378 goto bad2; 379 } 380 if (!mwl_tx_setup(sc, WME_AC_BE, MWL_WME_AC_BE) || 381 !mwl_tx_setup(sc, WME_AC_VI, MWL_WME_AC_VI) || 382 !mwl_tx_setup(sc, WME_AC_VO, MWL_WME_AC_VO)) { 383 /* 384 * Not enough hardware tx queues to properly do WME; 385 * just punt and assign them all to the same h/w queue. 386 * We could do a better job of this if, for example, 387 * we allocate queues when we switch from station to 388 * AP mode. 389 */ 390 if (sc->sc_ac2q[WME_AC_VI] != NULL) 391 mwl_tx_cleanupq(sc, sc->sc_ac2q[WME_AC_VI]); 392 if (sc->sc_ac2q[WME_AC_BE] != NULL) 393 mwl_tx_cleanupq(sc, sc->sc_ac2q[WME_AC_BE]); 394 sc->sc_ac2q[WME_AC_BE] = sc->sc_ac2q[WME_AC_BK]; 395 sc->sc_ac2q[WME_AC_VI] = sc->sc_ac2q[WME_AC_BK]; 396 sc->sc_ac2q[WME_AC_VO] = sc->sc_ac2q[WME_AC_BK]; 397 } 398 TASK_INIT(&sc->sc_txtask, 0, mwl_tx_proc, sc); 399 400 ifp->if_softc = sc; 401 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 402 ifp->if_start = mwl_start; 403 ifp->if_watchdog = mwl_watchdog; 404 ifp->if_ioctl = mwl_ioctl; 405 ifp->if_init = mwl_init; 406 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 407 ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; 408 IFQ_SET_READY(&ifp->if_snd); 409 410 ic->ic_ifp = ifp; 411 /* XXX not right but it's not used anywhere important */ 412 ic->ic_phytype = IEEE80211_T_OFDM; 413 ic->ic_opmode = IEEE80211_M_STA; 414 ic->ic_caps = 415 IEEE80211_C_STA /* station mode supported */ 416 | IEEE80211_C_HOSTAP /* hostap mode */ 417 | IEEE80211_C_MONITOR /* monitor mode */ 418#if 0 419 | IEEE80211_C_IBSS /* ibss, nee adhoc, mode */ 420 | IEEE80211_C_AHDEMO /* adhoc demo mode */ 421#endif 422 | IEEE80211_C_WDS /* WDS supported */ 423 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 424 | IEEE80211_C_SHSLOT /* short slot time supported */ 425 | IEEE80211_C_WME /* WME/WMM supported */ 426 | IEEE80211_C_BURST /* xmit bursting supported */ 427 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 428 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 429 | IEEE80211_C_TXFRAG /* handle tx frags */ 430 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 431 | IEEE80211_C_DFS /* DFS supported */ 432 ; 433 434 ic->ic_htcaps = 435 IEEE80211_HTCAP_SMPS_ENA /* SM PS mode enabled */ 436 | IEEE80211_HTCAP_CHWIDTH40 /* 40MHz channel width */ 437 | IEEE80211_HTCAP_SHORTGI20 /* short GI in 20MHz */ 438 | IEEE80211_HTCAP_SHORTGI40 /* short GI in 40MHz */ 439 | IEEE80211_HTCAP_RXSTBC_2STREAM/* 1-2 spatial streams */ 440#if MWL_AGGR_SIZE == 7935 441 | IEEE80211_HTCAP_MAXAMSDU_7935 /* max A-MSDU length */ 442#else 443 | IEEE80211_HTCAP_MAXAMSDU_3839 /* max A-MSDU length */ 444#endif 445#if 0 446 | IEEE80211_HTCAP_PSMP /* PSMP supported */ 447 | IEEE80211_HTCAP_40INTOLERANT /* 40MHz intolerant */ 448#endif 449 /* s/w capabilities */ 450 | IEEE80211_HTC_HT /* HT operation */ 451 | IEEE80211_HTC_AMPDU /* tx A-MPDU */ 452 | IEEE80211_HTC_AMSDU /* tx A-MSDU */ 453 | IEEE80211_HTC_SMPS /* SMPS available */ 454 ; 455 456 /* 457 * Mark h/w crypto support. 458 * XXX no way to query h/w support. 459 */ 460 ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP 461 | IEEE80211_CRYPTO_AES_CCM 462 | IEEE80211_CRYPTO_TKIP 463 | IEEE80211_CRYPTO_TKIPMIC 464 ; 465 /* 466 * Transmit requires space in the packet for a special 467 * format transmit record and optional padding between 468 * this record and the payload. Ask the net80211 layer 469 * to arrange this when encapsulating packets so we can 470 * add it efficiently. 471 */ 472 ic->ic_headroom = sizeof(struct mwltxrec) - 473 sizeof(struct ieee80211_frame); 474 475 /* call MI attach routine. */ 476 ieee80211_ifattach(ic, sc->sc_hwspecs.macAddr); 477 ic->ic_setregdomain = mwl_setregdomain; 478 ic->ic_getradiocaps = mwl_getradiocaps; 479 /* override default methods */ 480 ic->ic_raw_xmit = mwl_raw_xmit; 481 ic->ic_newassoc = mwl_newassoc; 482 ic->ic_updateslot = mwl_updateslot; 483 ic->ic_update_mcast = mwl_update_mcast; 484 ic->ic_update_promisc = mwl_update_promisc; 485 ic->ic_wme.wme_update = mwl_wme_update; 486 487 ic->ic_node_alloc = mwl_node_alloc; 488 sc->sc_node_cleanup = ic->ic_node_cleanup; 489 ic->ic_node_cleanup = mwl_node_cleanup; 490 sc->sc_node_drain = ic->ic_node_drain; 491 ic->ic_node_drain = mwl_node_drain; 492 ic->ic_node_getsignal = mwl_node_getsignal; 493 ic->ic_node_getmimoinfo = mwl_node_getmimoinfo; 494 495 ic->ic_scan_start = mwl_scan_start; 496 ic->ic_scan_end = mwl_scan_end; 497 ic->ic_set_channel = mwl_set_channel; 498 499 sc->sc_recv_action = ic->ic_recv_action; 500 ic->ic_recv_action = mwl_recv_action; 501 sc->sc_addba_request = ic->ic_addba_request; 502 ic->ic_addba_request = mwl_addba_request; 503 sc->sc_addba_response = ic->ic_addba_response; 504 ic->ic_addba_response = mwl_addba_response; 505 sc->sc_addba_stop = ic->ic_addba_stop; 506 ic->ic_addba_stop = mwl_addba_stop; 507 508 ic->ic_vap_create = mwl_vap_create; 509 ic->ic_vap_delete = mwl_vap_delete; 510 511 ieee80211_radiotap_attach(ic, 512 &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), 513 MWL_TX_RADIOTAP_PRESENT, 514 &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), 515 MWL_RX_RADIOTAP_PRESENT); 516 /* 517 * Setup dynamic sysctl's now that country code and 518 * regdomain are available from the hal. 519 */ 520 mwl_sysctlattach(sc); 521 522 if (bootverbose) 523 ieee80211_announce(ic); 524 mwl_announce(sc); 525 return 0; 526bad2: 527 mwl_dma_cleanup(sc); 528bad1: 529 mwl_hal_detach(mh); 530bad: 531 if_free(ifp); 532 sc->sc_invalid = 1; 533 return error; 534} 535 536int 537mwl_detach(struct mwl_softc *sc) 538{ 539 struct ifnet *ifp = sc->sc_ifp; 540 struct ieee80211com *ic = ifp->if_l2com; 541 542 DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", 543 __func__, ifp->if_flags); 544 545 mwl_stop(ifp, 1); 546 /* 547 * NB: the order of these is important: 548 * o call the 802.11 layer before detaching the hal to 549 * insure callbacks into the driver to delete global 550 * key cache entries can be handled 551 * o reclaim the tx queue data structures after calling 552 * the 802.11 layer as we'll get called back to reclaim 553 * node state and potentially want to use them 554 * o to cleanup the tx queues the hal is called, so detach 555 * it last 556 * Other than that, it's straightforward... 557 */ 558 ieee80211_ifdetach(ic); 559 mwl_dma_cleanup(sc); 560 mwl_tx_cleanup(sc); 561 mwl_hal_detach(sc->sc_mh); 562 if_free(ifp); 563 564 return 0; 565} 566 567/* 568 * MAC address handling for multiple BSS on the same radio. 569 * The first vap uses the MAC address from the EEPROM. For 570 * subsequent vap's we set the U/L bit (bit 1) in the MAC 571 * address and use the next six bits as an index. 572 */ 573static void 574assign_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN], int clone) 575{ 576 int i; 577 578 if (clone && mwl_hal_ismbsscapable(sc->sc_mh)) { 579 /* NB: we only do this if h/w supports multiple bssid */ 580 for (i = 0; i < 32; i++) 581 if ((sc->sc_bssidmask & (1<<i)) == 0) 582 break; 583 if (i != 0) 584 mac[0] |= (i << 2)|0x2; 585 } else 586 i = 0; 587 sc->sc_bssidmask |= 1<<i; 588 if (i == 0) 589 sc->sc_nbssid0++; 590} 591 592static void 593reclaim_address(struct mwl_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN]) 594{ 595 int i = mac[0] >> 2; 596 if (i != 0 || --sc->sc_nbssid0 == 0) 597 sc->sc_bssidmask &= ~(1<<i); 598} 599 600static struct ieee80211vap * 601mwl_vap_create(struct ieee80211com *ic, 602 const char name[IFNAMSIZ], int unit, int opmode, int flags, 603 const uint8_t bssid[IEEE80211_ADDR_LEN], 604 const uint8_t mac0[IEEE80211_ADDR_LEN]) 605{ 606 struct ifnet *ifp = ic->ic_ifp; 607 struct mwl_softc *sc = ifp->if_softc; 608 struct mwl_hal *mh = sc->sc_mh; 609 struct ieee80211vap *vap, *apvap; 610 struct mwl_hal_vap *hvap; 611 struct mwl_vap *mvp; 612 uint8_t mac[IEEE80211_ADDR_LEN]; 613 614 IEEE80211_ADDR_COPY(mac, mac0); 615 switch (opmode) { 616 case IEEE80211_M_HOSTAP: 617 if ((flags & IEEE80211_CLONE_MACADDR) == 0) 618 assign_address(sc, mac, flags & IEEE80211_CLONE_BSSID); 619 hvap = mwl_hal_newvap(mh, MWL_HAL_AP, mac); 620 if (hvap == NULL) { 621 if ((flags & IEEE80211_CLONE_MACADDR) == 0) 622 reclaim_address(sc, mac); 623 return NULL; 624 } 625 break; 626 case IEEE80211_M_STA: 627 if ((flags & IEEE80211_CLONE_MACADDR) == 0) 628 assign_address(sc, mac, flags & IEEE80211_CLONE_BSSID); 629 hvap = mwl_hal_newvap(mh, MWL_HAL_STA, mac); 630 if (hvap == NULL) { 631 if ((flags & IEEE80211_CLONE_MACADDR) == 0) 632 reclaim_address(sc, mac); 633 return NULL; 634 } 635 /* no h/w beacon miss support; always use s/w */ 636 flags |= IEEE80211_CLONE_NOBEACONS; 637 break; 638 case IEEE80211_M_WDS: 639 hvap = NULL; /* NB: we use associated AP vap */ 640 if (sc->sc_napvaps == 0) 641 return NULL; /* no existing AP vap */ 642 break; 643 case IEEE80211_M_MONITOR: 644 hvap = NULL; 645 break; 646 case IEEE80211_M_IBSS: 647 case IEEE80211_M_AHDEMO: 648 default: 649 return NULL; 650 } 651 652 mvp = (struct mwl_vap *) malloc(sizeof(struct mwl_vap), 653 M_80211_VAP, M_NOWAIT | M_ZERO); 654 if (mvp == NULL) { 655 if (hvap != NULL) { 656 mwl_hal_delvap(hvap); 657 if ((flags & IEEE80211_CLONE_MACADDR) == 0) 658 reclaim_address(sc, mac); 659 } 660 /* XXX msg */ 661 return NULL; 662 } 663 mvp->mv_hvap = hvap; 664 if (opmode == IEEE80211_M_WDS) { 665 /* 666 * WDS vaps must have an associated AP vap; find one. 667 * XXX not right. 668 */ 669 TAILQ_FOREACH(apvap, &ic->ic_vaps, iv_next) 670 if (apvap->iv_opmode == IEEE80211_M_HOSTAP) { 671 mvp->mv_ap_hvap = MWL_VAP(apvap)->mv_hvap; 672 break; 673 } 674 KASSERT(mvp->mv_ap_hvap != NULL, ("no ap vap")); 675 } 676 vap = &mvp->mv_vap; 677 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); 678 if (hvap != NULL) 679 IEEE80211_ADDR_COPY(vap->iv_myaddr, mac); 680 /* override with driver methods */ 681 mvp->mv_newstate = vap->iv_newstate; 682 vap->iv_newstate = mwl_newstate; 683 vap->iv_max_keyix = 0; /* XXX */ 684 vap->iv_key_alloc = mwl_key_alloc; 685 vap->iv_key_delete = mwl_key_delete; 686 vap->iv_key_set = mwl_key_set; 687#ifdef MWL_HOST_PS_SUPPORT 688 if (opmode == IEEE80211_M_HOSTAP) { 689 vap->iv_update_ps = mwl_update_ps; 690 mvp->mv_set_tim = vap->iv_set_tim; 691 vap->iv_set_tim = mwl_set_tim; 692 } 693#endif 694 vap->iv_reset = mwl_reset; 695 vap->iv_update_beacon = mwl_beacon_update; 696 697 /* override max aid so sta's cannot assoc when we're out of sta id's */ 698 vap->iv_max_aid = MWL_MAXSTAID; 699 /* override default A-MPDU rx parameters */ 700 vap->iv_ampdu_rxmax = IEEE80211_HTCAP_MAXRXAMPDU_64K; 701 vap->iv_ampdu_density = IEEE80211_HTCAP_MPDUDENSITY_4; 702 703 /* complete setup */ 704 ieee80211_vap_attach(vap, mwl_media_change, ieee80211_media_status); 705 706 switch (vap->iv_opmode) { 707 case IEEE80211_M_HOSTAP: 708 case IEEE80211_M_STA: 709 /* 710 * Setup sta db entry for local address. 711 */ 712 mwl_localstadb(vap); 713 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 714 sc->sc_napvaps++; 715 else 716 sc->sc_nstavaps++; 717 break; 718 case IEEE80211_M_WDS: 719 sc->sc_nwdsvaps++; 720 break; 721 default: 722 break; 723 } 724 /* 725 * Setup overall operating mode. 726 */ 727 if (sc->sc_napvaps) 728 ic->ic_opmode = IEEE80211_M_HOSTAP; 729 else if (sc->sc_nstavaps) 730 ic->ic_opmode = IEEE80211_M_STA; 731 else 732 ic->ic_opmode = opmode; 733 734 return vap; 735} 736 737static void 738mwl_vap_delete(struct ieee80211vap *vap) 739{ 740 struct mwl_vap *mvp = MWL_VAP(vap); 741 struct ifnet *parent = vap->iv_ic->ic_ifp; 742 struct mwl_softc *sc = parent->if_softc; 743 struct mwl_hal *mh = sc->sc_mh; 744 struct mwl_hal_vap *hvap = mvp->mv_hvap; 745 enum ieee80211_opmode opmode = vap->iv_opmode; 746 747 /* XXX disallow ap vap delete if WDS still present */ 748 if (parent->if_drv_flags & IFF_DRV_RUNNING) { 749 /* quiesce h/w while we remove the vap */ 750 mwl_hal_intrset(mh, 0); /* disable interrupts */ 751 } 752 ieee80211_vap_detach(vap); 753 switch (opmode) { 754 case IEEE80211_M_HOSTAP: 755 case IEEE80211_M_STA: 756 KASSERT(hvap != NULL, ("no hal vap handle")); 757 (void) mwl_hal_delstation(hvap, vap->iv_myaddr); 758 mwl_hal_delvap(hvap); 759 if (opmode == IEEE80211_M_HOSTAP) 760 sc->sc_napvaps--; 761 else 762 sc->sc_nstavaps--; 763 /* XXX don't do it for IEEE80211_CLONE_MACADDR */ 764 reclaim_address(sc, vap->iv_myaddr); 765 break; 766 case IEEE80211_M_WDS: 767 sc->sc_nwdsvaps--; 768 break; 769 default: 770 break; 771 } 772 mwl_cleartxq(sc, vap); 773 free(mvp, M_80211_VAP); 774 if (parent->if_drv_flags & IFF_DRV_RUNNING) 775 mwl_hal_intrset(mh, sc->sc_imask); 776} 777 778void 779mwl_suspend(struct mwl_softc *sc) 780{ 781 struct ifnet *ifp = sc->sc_ifp; 782 783 DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", 784 __func__, ifp->if_flags); 785 786 mwl_stop(ifp, 1); 787} 788 789void 790mwl_resume(struct mwl_softc *sc) 791{ 792 struct ifnet *ifp = sc->sc_ifp; 793 794 DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags %x\n", 795 __func__, ifp->if_flags); 796 797 if (ifp->if_flags & IFF_UP) 798 mwl_init(sc); 799} 800 801void 802mwl_shutdown(void *arg) 803{ 804 struct mwl_softc *sc = arg; 805 806 mwl_stop(sc->sc_ifp, 1); 807} 808 809/* 810 * Interrupt handler. Most of the actual processing is deferred. 811 */ 812void 813mwl_intr(void *arg) 814{ 815 struct mwl_softc *sc = arg; 816 struct mwl_hal *mh = sc->sc_mh; 817 uint32_t status; 818 819 if (sc->sc_invalid) { 820 /* 821 * The hardware is not ready/present, don't touch anything. 822 * Note this can happen early on if the IRQ is shared. 823 */ 824 DPRINTF(sc, MWL_DEBUG_ANY, "%s: invalid; ignored\n", __func__); 825 return; 826 } 827 /* 828 * Figure out the reason(s) for the interrupt. 829 */ 830 mwl_hal_getisr(mh, &status); /* NB: clears ISR too */ 831 if (status == 0) /* must be a shared irq */ 832 return; 833 834 DPRINTF(sc, MWL_DEBUG_INTR, "%s: status 0x%x imask 0x%x\n", 835 __func__, status, sc->sc_imask); 836 if (status & MACREG_A2HRIC_BIT_RX_RDY) 837 taskqueue_enqueue(sc->sc_tq, &sc->sc_rxtask); 838 if (status & MACREG_A2HRIC_BIT_TX_DONE) 839 taskqueue_enqueue(sc->sc_tq, &sc->sc_txtask); 840 if (status & MACREG_A2HRIC_BIT_BA_WATCHDOG) 841 taskqueue_enqueue(sc->sc_tq, &sc->sc_bawatchdogtask); 842 if (status & MACREG_A2HRIC_BIT_OPC_DONE) 843 mwl_hal_cmddone(mh); 844 if (status & MACREG_A2HRIC_BIT_MAC_EVENT) { 845 ; 846 } 847 if (status & MACREG_A2HRIC_BIT_ICV_ERROR) { 848 /* TKIP ICV error */ 849 sc->sc_stats.mst_rx_badtkipicv++; 850 } 851 if (status & MACREG_A2HRIC_BIT_QUEUE_EMPTY) { 852 /* 11n aggregation queue is empty, re-fill */ 853 ; 854 } 855 if (status & MACREG_A2HRIC_BIT_QUEUE_FULL) { 856 ; 857 } 858 if (status & MACREG_A2HRIC_BIT_RADAR_DETECT) { 859 /* radar detected, process event */ 860 taskqueue_enqueue(sc->sc_tq, &sc->sc_radartask); 861 } 862 if (status & MACREG_A2HRIC_BIT_CHAN_SWITCH) { 863 /* DFS channel switch */ 864 taskqueue_enqueue(sc->sc_tq, &sc->sc_chanswitchtask); 865 } 866} 867 868static void 869mwl_radar_proc(void *arg, int pending) 870{ 871 struct mwl_softc *sc = arg; 872 struct ifnet *ifp = sc->sc_ifp; 873 struct ieee80211com *ic = ifp->if_l2com; 874 875 DPRINTF(sc, MWL_DEBUG_ANY, "%s: radar detected, pending %u\n", 876 __func__, pending); 877 878 sc->sc_stats.mst_radardetect++; 879 /* XXX stop h/w BA streams? */ 880 881 IEEE80211_LOCK(ic); 882 ieee80211_dfs_notify_radar(ic, ic->ic_curchan); 883 IEEE80211_UNLOCK(ic); 884} 885 886static void 887mwl_chanswitch_proc(void *arg, int pending) 888{ 889 struct mwl_softc *sc = arg; 890 struct ifnet *ifp = sc->sc_ifp; 891 struct ieee80211com *ic = ifp->if_l2com; 892 893 DPRINTF(sc, MWL_DEBUG_ANY, "%s: channel switch notice, pending %u\n", 894 __func__, pending); 895 896 IEEE80211_LOCK(ic); 897 sc->sc_csapending = 0; 898 ieee80211_csa_completeswitch(ic); 899 IEEE80211_UNLOCK(ic); 900} 901 902static void 903mwl_bawatchdog(const MWL_HAL_BASTREAM *sp) 904{ 905 struct ieee80211_node *ni = sp->data[0]; 906 907 /* send DELBA and drop the stream */ 908 ieee80211_ampdu_stop(ni, sp->data[1], IEEE80211_REASON_UNSPECIFIED); 909} 910 911static void 912mwl_bawatchdog_proc(void *arg, int pending) 913{ 914 struct mwl_softc *sc = arg; 915 struct mwl_hal *mh = sc->sc_mh; 916 const MWL_HAL_BASTREAM *sp; 917 uint8_t bitmap, n; 918 919 sc->sc_stats.mst_bawatchdog++; 920 921 if (mwl_hal_getwatchdogbitmap(mh, &bitmap) != 0) { 922 DPRINTF(sc, MWL_DEBUG_AMPDU, 923 "%s: could not get bitmap\n", __func__); 924 sc->sc_stats.mst_bawatchdog_failed++; 925 return; 926 } 927 DPRINTF(sc, MWL_DEBUG_AMPDU, "%s: bitmap 0x%x\n", __func__, bitmap); 928 if (bitmap == 0xff) { 929 n = 0; 930 /* disable all ba streams */ 931 for (bitmap = 0; bitmap < 8; bitmap++) { 932 sp = mwl_hal_bastream_lookup(mh, bitmap); 933 if (sp != NULL) { 934 mwl_bawatchdog(sp); 935 n++; 936 } 937 } 938 if (n == 0) { 939 DPRINTF(sc, MWL_DEBUG_AMPDU, 940 "%s: no BA streams found\n", __func__); 941 sc->sc_stats.mst_bawatchdog_empty++; 942 } 943 } else if (bitmap != 0xaa) { 944 /* disable a single ba stream */ 945 sp = mwl_hal_bastream_lookup(mh, bitmap); 946 if (sp != NULL) { 947 mwl_bawatchdog(sp); 948 } else { 949 DPRINTF(sc, MWL_DEBUG_AMPDU, 950 "%s: no BA stream %d\n", __func__, bitmap); 951 sc->sc_stats.mst_bawatchdog_notfound++; 952 } 953 } 954} 955 956/* 957 * Convert net80211 channel to a HAL channel. 958 */ 959static void 960mwl_mapchan(MWL_HAL_CHANNEL *hc, const struct ieee80211_channel *chan) 961{ 962 hc->channel = chan->ic_ieee; 963 964 *(uint32_t *)&hc->channelFlags = 0; 965 if (IEEE80211_IS_CHAN_2GHZ(chan)) 966 hc->channelFlags.FreqBand = MWL_FREQ_BAND_2DOT4GHZ; 967 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 968 hc->channelFlags.FreqBand = MWL_FREQ_BAND_5GHZ; 969 if (IEEE80211_IS_CHAN_HT40(chan)) { 970 hc->channelFlags.ChnlWidth = MWL_CH_40_MHz_WIDTH; 971 if (IEEE80211_IS_CHAN_HT40U(chan)) 972 hc->channelFlags.ExtChnlOffset = MWL_EXT_CH_ABOVE_CTRL_CH; 973 else 974 hc->channelFlags.ExtChnlOffset = MWL_EXT_CH_BELOW_CTRL_CH; 975 } else 976 hc->channelFlags.ChnlWidth = MWL_CH_20_MHz_WIDTH; 977 /* XXX 10MHz channels */ 978} 979 980/* 981 * Inform firmware of our tx/rx dma setup. The BAR 0 982 * writes below are for compatibility with older firmware. 983 * For current firmware we send this information with a 984 * cmd block via mwl_hal_sethwdma. 985 */ 986static int 987mwl_setupdma(struct mwl_softc *sc) 988{ 989 int error, i; 990 991 sc->sc_hwdma.rxDescRead = sc->sc_rxdma.dd_desc_paddr; 992 WR4(sc, sc->sc_hwspecs.rxDescRead, sc->sc_hwdma.rxDescRead); 993 WR4(sc, sc->sc_hwspecs.rxDescWrite, sc->sc_hwdma.rxDescRead); 994 995 for (i = 0; i < MWL_NUM_TX_QUEUES-MWL_NUM_ACK_QUEUES; i++) { 996 struct mwl_txq *txq = &sc->sc_txq[i]; 997 sc->sc_hwdma.wcbBase[i] = txq->dma.dd_desc_paddr; 998 WR4(sc, sc->sc_hwspecs.wcbBase[i], sc->sc_hwdma.wcbBase[i]); 999 } 1000 sc->sc_hwdma.maxNumTxWcb = mwl_txbuf; 1001 sc->sc_hwdma.maxNumWCB = MWL_NUM_TX_QUEUES-MWL_NUM_ACK_QUEUES; 1002 1003 error = mwl_hal_sethwdma(sc->sc_mh, &sc->sc_hwdma); 1004 if (error != 0) { 1005 device_printf(sc->sc_dev, 1006 "unable to setup tx/rx dma; hal status %u\n", error); 1007 /* XXX */ 1008 } 1009 return error; 1010} 1011 1012/* 1013 * Inform firmware of tx rate parameters. 1014 * Called after a channel change. 1015 */ 1016static int 1017mwl_setcurchanrates(struct mwl_softc *sc) 1018{ 1019 struct ifnet *ifp = sc->sc_ifp; 1020 struct ieee80211com *ic = ifp->if_l2com; 1021 const struct ieee80211_rateset *rs; 1022 MWL_HAL_TXRATE rates; 1023 1024 memset(&rates, 0, sizeof(rates)); 1025 rs = ieee80211_get_suprates(ic, ic->ic_curchan); 1026 /* rate used to send management frames */ 1027 rates.MgtRate = rs->rs_rates[0] & IEEE80211_RATE_VAL; 1028 /* rate used to send multicast frames */ 1029 rates.McastRate = rates.MgtRate; 1030 1031 return mwl_hal_settxrate_auto(sc->sc_mh, &rates); 1032} 1033 1034/* 1035 * Inform firmware of tx rate parameters. Called whenever 1036 * user-settable params change and after a channel change. 1037 */ 1038static int 1039mwl_setrates(struct ieee80211vap *vap) 1040{ 1041 struct mwl_vap *mvp = MWL_VAP(vap); 1042 struct ieee80211_node *ni = vap->iv_bss; 1043 const struct ieee80211_txparam *tp = ni->ni_txparms; 1044 MWL_HAL_TXRATE rates; 1045 1046 KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state)); 1047 1048 /* 1049 * Update the h/w rate map. 1050 * NB: 0x80 for MCS is passed through unchanged 1051 */ 1052 memset(&rates, 0, sizeof(rates)); 1053 /* rate used to send management frames */ 1054 rates.MgtRate = tp->mgmtrate; 1055 /* rate used to send multicast frames */ 1056 rates.McastRate = tp->mcastrate; 1057 1058 /* while here calculate EAPOL fixed rate cookie */ 1059 mvp->mv_eapolformat = htole16(mwl_calcformat(rates.MgtRate, ni)); 1060 1061 return mwl_hal_settxrate(mvp->mv_hvap, 1062 tp->ucastrate != IEEE80211_FIXED_RATE_NONE ? 1063 RATE_FIXED : RATE_AUTO, &rates); 1064} 1065 1066/* 1067 * Setup a fixed xmit rate cookie for EAPOL frames. 1068 */ 1069static void 1070mwl_seteapolformat(struct ieee80211vap *vap) 1071{ 1072 struct mwl_vap *mvp = MWL_VAP(vap); 1073 struct ieee80211_node *ni = vap->iv_bss; 1074 enum ieee80211_phymode mode; 1075 uint8_t rate; 1076 1077 KASSERT(vap->iv_state == IEEE80211_S_RUN, ("state %d", vap->iv_state)); 1078 1079 mode = ieee80211_chan2mode(ni->ni_chan); 1080 /* 1081 * Use legacy rates when operating a mixed HT+non-HT bss. 1082 * NB: this may violate POLA for sta and wds vap's. 1083 */ 1084 if (mode == IEEE80211_MODE_11NA && 1085 (vap->iv_flags_ht & IEEE80211_FHT_PUREN) == 0) 1086 rate = vap->iv_txparms[IEEE80211_MODE_11A].mgmtrate; 1087 else if (mode == IEEE80211_MODE_11NG && 1088 (vap->iv_flags_ht & IEEE80211_FHT_PUREN) == 0) 1089 rate = vap->iv_txparms[IEEE80211_MODE_11G].mgmtrate; 1090 else 1091 rate = vap->iv_txparms[mode].mgmtrate; 1092 1093 mvp->mv_eapolformat = htole16(mwl_calcformat(rate, ni)); 1094} 1095 1096/* 1097 * Map SKU+country code to region code for radar bin'ing. 1098 */ 1099static int 1100mwl_map2regioncode(const struct ieee80211_regdomain *rd) 1101{ 1102 switch (rd->regdomain) { 1103 case SKU_FCC: 1104 case SKU_FCC3: 1105 return DOMAIN_CODE_FCC; 1106 case SKU_CA: 1107 return DOMAIN_CODE_IC; 1108 case SKU_ETSI: 1109 case SKU_ETSI2: 1110 case SKU_ETSI3: 1111 if (rd->country == CTRY_SPAIN) 1112 return DOMAIN_CODE_SPAIN; 1113 if (rd->country == CTRY_FRANCE || rd->country == CTRY_FRANCE2) 1114 return DOMAIN_CODE_FRANCE; 1115 /* XXX force 1.3.1 radar type */ 1116 return DOMAIN_CODE_ETSI_131; 1117 case SKU_JAPAN: 1118 return DOMAIN_CODE_MKK; 1119 case SKU_ROW: 1120 return DOMAIN_CODE_DGT; /* Taiwan */ 1121 case SKU_APAC: 1122 case SKU_APAC2: 1123 case SKU_APAC3: 1124 return DOMAIN_CODE_AUS; /* Australia */ 1125 } 1126 /* XXX KOREA? */ 1127 return DOMAIN_CODE_FCC; /* XXX? */ 1128} 1129 1130static int 1131mwl_hal_reset(struct mwl_softc *sc) 1132{ 1133 struct ifnet *ifp = sc->sc_ifp; 1134 struct ieee80211com *ic = ifp->if_l2com; 1135 struct mwl_hal *mh = sc->sc_mh; 1136 1137 mwl_hal_setantenna(mh, WL_ANTENNATYPE_RX, sc->sc_rxantenna); 1138 mwl_hal_setantenna(mh, WL_ANTENNATYPE_TX, sc->sc_txantenna); 1139 mwl_hal_setradio(mh, 1, WL_AUTO_PREAMBLE); 1140 mwl_hal_setwmm(sc->sc_mh, (ic->ic_flags & IEEE80211_F_WME) != 0); 1141 mwl_chan_set(sc, ic->ic_curchan); 1142 /* NB: RF/RA performance tuned for indoor mode */ 1143 mwl_hal_setrateadaptmode(mh, 0); 1144 mwl_hal_setoptimizationlevel(mh, 1145 (ic->ic_flags & IEEE80211_F_BURST) != 0); 1146 1147 mwl_hal_setregioncode(mh, mwl_map2regioncode(&ic->ic_regdomain)); 1148 1149 mwl_hal_setaggampduratemode(mh, 1, 80); /* XXX */ 1150 mwl_hal_setcfend(mh, 0); /* XXX */ 1151 1152 return 1; 1153} 1154 1155static int 1156mwl_init_locked(struct mwl_softc *sc) 1157{ 1158 struct ifnet *ifp = sc->sc_ifp; 1159 struct mwl_hal *mh = sc->sc_mh; 1160 int error = 0; 1161 1162 DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n", 1163 __func__, ifp->if_flags); 1164 1165 MWL_LOCK_ASSERT(sc); 1166 1167 /* 1168 * Stop anything previously setup. This is safe 1169 * whether this is the first time through or not. 1170 */ 1171 mwl_stop_locked(ifp, 0); 1172 1173 /* 1174 * Push vap-independent state to the firmware. 1175 */ 1176 if (!mwl_hal_reset(sc)) { 1177 if_printf(ifp, "unable to reset hardware\n"); 1178 return EIO; 1179 } 1180 1181 /* 1182 * Setup recv (once); transmit is already good to go. 1183 */ 1184 error = mwl_startrecv(sc); 1185 if (error != 0) { 1186 if_printf(ifp, "unable to start recv logic\n"); 1187 return error; 1188 } 1189 1190 /* 1191 * Enable interrupts. 1192 */ 1193 sc->sc_imask = MACREG_A2HRIC_BIT_RX_RDY 1194 | MACREG_A2HRIC_BIT_TX_DONE 1195 | MACREG_A2HRIC_BIT_OPC_DONE 1196#if 0 1197 | MACREG_A2HRIC_BIT_MAC_EVENT 1198#endif 1199 | MACREG_A2HRIC_BIT_ICV_ERROR 1200 | MACREG_A2HRIC_BIT_RADAR_DETECT 1201 | MACREG_A2HRIC_BIT_CHAN_SWITCH 1202#if 0 1203 | MACREG_A2HRIC_BIT_QUEUE_EMPTY 1204#endif 1205 | MACREG_A2HRIC_BIT_BA_WATCHDOG 1206 | MACREQ_A2HRIC_BIT_TX_ACK 1207 ; 1208 1209 ifp->if_drv_flags |= IFF_DRV_RUNNING; 1210 mwl_hal_intrset(mh, sc->sc_imask); 1211 1212 return 0; 1213} 1214 1215static void 1216mwl_init(void *arg) 1217{ 1218 struct mwl_softc *sc = arg; 1219 struct ifnet *ifp = sc->sc_ifp; 1220 struct ieee80211com *ic = ifp->if_l2com; 1221 int error = 0; 1222 1223 DPRINTF(sc, MWL_DEBUG_ANY, "%s: if_flags 0x%x\n", 1224 __func__, ifp->if_flags); 1225 1226 MWL_LOCK(sc); 1227 error = mwl_init_locked(sc); 1228 MWL_UNLOCK(sc); 1229 1230 if (error == 0) 1231 ieee80211_start_all(ic); /* start all vap's */ 1232} 1233 1234static void 1235mwl_stop_locked(struct ifnet *ifp, int disable) 1236{ 1237 struct mwl_softc *sc = ifp->if_softc; 1238 1239 DPRINTF(sc, MWL_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", 1240 __func__, sc->sc_invalid, ifp->if_flags); 1241 1242 MWL_LOCK_ASSERT(sc); 1243 if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 1244 /* 1245 * Shutdown the hardware and driver. 1246 */ 1247 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1248 ifp->if_timer = 0; 1249 mwl_draintxq(sc); 1250 } 1251} 1252 1253static void 1254mwl_stop(struct ifnet *ifp, int disable) 1255{ 1256 struct mwl_softc *sc = ifp->if_softc; 1257 1258 MWL_LOCK(sc); 1259 mwl_stop_locked(ifp, disable); 1260 MWL_UNLOCK(sc); 1261} 1262 1263static int 1264mwl_reset_vap(struct ieee80211vap *vap, int state) 1265{ 1266 struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; 1267 struct ieee80211com *ic = vap->iv_ic; 1268 1269 if (state == IEEE80211_S_RUN) 1270 mwl_setrates(vap); 1271 /* XXX off by 1? */ 1272 mwl_hal_setrtsthreshold(hvap, vap->iv_rtsthreshold); 1273 /* XXX auto? 20/40 split? */ 1274 mwl_hal_sethtgi(hvap, (vap->iv_flags_ht & 1275 (IEEE80211_FHT_SHORTGI20|IEEE80211_FHT_SHORTGI40)) ? 1 : 0); 1276 mwl_hal_setnprot(hvap, ic->ic_htprotmode == IEEE80211_PROT_NONE ? 1277 HTPROTECT_NONE : HTPROTECT_AUTO); 1278 /* XXX txpower cap */ 1279 1280 /* re-setup beacons */ 1281 if (state == IEEE80211_S_RUN && 1282 (vap->iv_opmode == IEEE80211_M_HOSTAP || 1283 vap->iv_opmode == IEEE80211_M_IBSS)) { 1284 mwl_setapmode(vap, vap->iv_bss->ni_chan); 1285 mwl_hal_setnprotmode(hvap, 1286 MS(ic->ic_curhtprotmode, IEEE80211_HTINFO_OPMODE)); 1287 return mwl_beacon_setup(vap); 1288 } 1289 return 0; 1290} 1291 1292/* 1293 * Reset the hardware w/o losing operational state. 1294 * Used to to reset or reload hardware state for a vap. 1295 */ 1296static int 1297mwl_reset(struct ieee80211vap *vap, u_long cmd) 1298{ 1299 struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; 1300 int error = 0; 1301 1302 if (hvap != NULL) { /* WDS, MONITOR, etc. */ 1303 struct ieee80211com *ic = vap->iv_ic; 1304 struct ifnet *ifp = ic->ic_ifp; 1305 struct mwl_softc *sc = ifp->if_softc; 1306 struct mwl_hal *mh = sc->sc_mh; 1307 1308 /* XXX handle DWDS sta vap change */ 1309 /* XXX do we need to disable interrupts? */ 1310 mwl_hal_intrset(mh, 0); /* disable interrupts */ 1311 error = mwl_reset_vap(vap, vap->iv_state); 1312 mwl_hal_intrset(mh, sc->sc_imask); 1313 } 1314 return error; 1315} 1316 1317/* 1318 * Allocate a tx buffer for sending a frame. The 1319 * packet is assumed to have the WME AC stored so 1320 * we can use it to select the appropriate h/w queue. 1321 */ 1322static struct mwl_txbuf * 1323mwl_gettxbuf(struct mwl_softc *sc, struct mwl_txq *txq) 1324{ 1325 struct mwl_txbuf *bf; 1326 1327 /* 1328 * Grab a TX buffer and associated resources. 1329 */ 1330 MWL_TXQ_LOCK(txq); 1331 bf = STAILQ_FIRST(&txq->free); 1332 if (bf != NULL) { 1333 STAILQ_REMOVE_HEAD(&txq->free, bf_list); 1334 txq->nfree--; 1335 } 1336 MWL_TXQ_UNLOCK(txq); 1337 if (bf == NULL) 1338 DPRINTF(sc, MWL_DEBUG_XMIT, 1339 "%s: out of xmit buffers on q %d\n", __func__, txq->qnum); 1340 return bf; 1341} 1342 1343/* 1344 * Return a tx buffer to the queue it came from. Note there 1345 * are two cases because we must preserve the order of buffers 1346 * as it reflects the fixed order of descriptors in memory 1347 * (the firmware pre-fetches descriptors so we cannot reorder). 1348 */ 1349static void 1350mwl_puttxbuf_head(struct mwl_txq *txq, struct mwl_txbuf *bf) 1351{ 1352 bf->bf_m = NULL; 1353 bf->bf_node = NULL; 1354 MWL_TXQ_LOCK(txq); 1355 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list); 1356 txq->nfree++; 1357 MWL_TXQ_UNLOCK(txq); 1358} 1359 1360static void 1361mwl_puttxbuf_tail(struct mwl_txq *txq, struct mwl_txbuf *bf) 1362{ 1363 bf->bf_m = NULL; 1364 bf->bf_node = NULL; 1365 MWL_TXQ_LOCK(txq); 1366 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list); 1367 txq->nfree++; 1368 MWL_TXQ_UNLOCK(txq); 1369} 1370 1371static void 1372mwl_start(struct ifnet *ifp) 1373{ 1374 struct mwl_softc *sc = ifp->if_softc; 1375 struct ieee80211_node *ni; 1376 struct mwl_txbuf *bf; 1377 struct mbuf *m; 1378 struct mwl_txq *txq = NULL; /* XXX silence gcc */ 1379 int nqueued; 1380 1381 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) 1382 return; 1383 nqueued = 0; 1384 for (;;) { 1385 bf = NULL; 1386 IFQ_DEQUEUE(&ifp->if_snd, m); 1387 if (m == NULL) 1388 break; 1389 /* 1390 * Grab the node for the destination. 1391 */ 1392 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1393 KASSERT(ni != NULL, ("no node")); 1394 m->m_pkthdr.rcvif = NULL; /* committed, clear ref */ 1395 /* 1396 * Grab a TX buffer and associated resources. 1397 * We honor the classification by the 802.11 layer. 1398 */ 1399 txq = sc->sc_ac2q[M_WME_GETAC(m)]; 1400 bf = mwl_gettxbuf(sc, txq); 1401 if (bf == NULL) { 1402 m_freem(m); 1403 ieee80211_free_node(ni); 1404#ifdef MWL_TX_NODROP 1405 sc->sc_stats.mst_tx_qstop++; 1406 /* XXX blocks other traffic */ 1407 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1408 break; 1409#else 1410 DPRINTF(sc, MWL_DEBUG_XMIT, 1411 "%s: tail drop on q %d\n", __func__, txq->qnum); 1412 sc->sc_stats.mst_tx_qdrop++; 1413 continue; 1414#endif /* MWL_TX_NODROP */ 1415 } 1416 1417 /* 1418 * Pass the frame to the h/w for transmission. 1419 */ 1420 if (mwl_tx_start(sc, ni, bf, m)) { 1421 ifp->if_oerrors++; 1422 mwl_puttxbuf_head(txq, bf); 1423 ieee80211_free_node(ni); 1424 continue; 1425 } 1426 nqueued++; 1427 if (nqueued >= mwl_txcoalesce) { 1428 /* 1429 * Poke the firmware to process queued frames; 1430 * see below about (lack of) locking. 1431 */ 1432 nqueued = 0; 1433 mwl_hal_txstart(sc->sc_mh, 0/*XXX*/); 1434 } 1435 } 1436 if (nqueued) { 1437 /* 1438 * NB: We don't need to lock against tx done because 1439 * this just prods the firmware to check the transmit 1440 * descriptors. The firmware will also start fetching 1441 * descriptors by itself if it notices new ones are 1442 * present when it goes to deliver a tx done interrupt 1443 * to the host. So if we race with tx done processing 1444 * it's ok. Delivering the kick here rather than in 1445 * mwl_tx_start is an optimization to avoid poking the 1446 * firmware for each packet. 1447 * 1448 * NB: the queue id isn't used so 0 is ok. 1449 */ 1450 mwl_hal_txstart(sc->sc_mh, 0/*XXX*/); 1451 } 1452} 1453 1454static int 1455mwl_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 1456 const struct ieee80211_bpf_params *params) 1457{ 1458 struct ieee80211com *ic = ni->ni_ic; 1459 struct ifnet *ifp = ic->ic_ifp; 1460 struct mwl_softc *sc = ifp->if_softc; 1461 struct mwl_txbuf *bf; 1462 struct mwl_txq *txq; 1463 1464 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->sc_invalid) { 1465 ieee80211_free_node(ni); 1466 m_freem(m); 1467 return ENETDOWN; 1468 } 1469 /* 1470 * Grab a TX buffer and associated resources. 1471 * Note that we depend on the classification 1472 * by the 802.11 layer to get to the right h/w 1473 * queue. Management frames must ALWAYS go on 1474 * queue 1 but we cannot just force that here 1475 * because we may receive non-mgt frames. 1476 */ 1477 txq = sc->sc_ac2q[M_WME_GETAC(m)]; 1478 bf = mwl_gettxbuf(sc, txq); 1479 if (bf == NULL) { 1480 sc->sc_stats.mst_tx_qstop++; 1481 /* XXX blocks other traffic */ 1482 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 1483 ieee80211_free_node(ni); 1484 m_freem(m); 1485 return ENOBUFS; 1486 } 1487 /* 1488 * Pass the frame to the h/w for transmission. 1489 */ 1490 if (mwl_tx_start(sc, ni, bf, m)) { 1491 ifp->if_oerrors++; 1492 mwl_puttxbuf_head(txq, bf); 1493 1494 ieee80211_free_node(ni); 1495 return EIO; /* XXX */ 1496 } 1497 /* 1498 * NB: We don't need to lock against tx done because 1499 * this just prods the firmware to check the transmit 1500 * descriptors. The firmware will also start fetching 1501 * descriptors by itself if it notices new ones are 1502 * present when it goes to deliver a tx done interrupt 1503 * to the host. So if we race with tx done processing 1504 * it's ok. Delivering the kick here rather than in 1505 * mwl_tx_start is an optimization to avoid poking the 1506 * firmware for each packet. 1507 * 1508 * NB: the queue id isn't used so 0 is ok. 1509 */ 1510 mwl_hal_txstart(sc->sc_mh, 0/*XXX*/); 1511 return 0; 1512} 1513 1514static int 1515mwl_media_change(struct ifnet *ifp) 1516{ 1517 struct ieee80211vap *vap = ifp->if_softc; 1518 int error; 1519 1520 error = ieee80211_media_change(ifp); 1521 /* NB: only the fixed rate can change and that doesn't need a reset */ 1522 if (error == ENETRESET) { 1523 mwl_setrates(vap); 1524 error = 0; 1525 } 1526 return error; 1527} 1528 1529#ifdef MWL_DEBUG 1530static void 1531mwl_keyprint(struct mwl_softc *sc, const char *tag, 1532 const MWL_HAL_KEYVAL *hk, const uint8_t mac[IEEE80211_ADDR_LEN]) 1533{ 1534 static const char *ciphers[] = { 1535 "WEP", 1536 "TKIP", 1537 "AES-CCM", 1538 }; 1539 int i, n; 1540 1541 printf("%s: [%u] %-7s", tag, hk->keyIndex, ciphers[hk->keyTypeId]); 1542 for (i = 0, n = hk->keyLen; i < n; i++) 1543 printf(" %02x", hk->key.aes[i]); 1544 printf(" mac %s", ether_sprintf(mac)); 1545 if (hk->keyTypeId == KEY_TYPE_ID_TKIP) { 1546 printf(" %s", "rxmic"); 1547 for (i = 0; i < sizeof(hk->key.tkip.rxMic); i++) 1548 printf(" %02x", hk->key.tkip.rxMic[i]); 1549 printf(" txmic"); 1550 for (i = 0; i < sizeof(hk->key.tkip.txMic); i++) 1551 printf(" %02x", hk->key.tkip.txMic[i]); 1552 } 1553 printf(" flags 0x%x\n", hk->keyFlags); 1554} 1555#endif 1556 1557/* 1558 * Allocate a key cache slot for a unicast key. The 1559 * firmware handles key allocation and every station is 1560 * guaranteed key space so we are always successful. 1561 */ 1562static int 1563mwl_key_alloc(struct ieee80211vap *vap, struct ieee80211_key *k, 1564 ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 1565{ 1566 struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; 1567 1568 if (k->wk_keyix != IEEE80211_KEYIX_NONE || 1569 (k->wk_flags & IEEE80211_KEY_GROUP)) { 1570 if (!(&vap->iv_nw_keys[0] <= k && 1571 k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { 1572 /* should not happen */ 1573 DPRINTF(sc, MWL_DEBUG_KEYCACHE, 1574 "%s: bogus group key\n", __func__); 1575 return 0; 1576 } 1577 /* give the caller what they requested */ 1578 *keyix = *rxkeyix = k - vap->iv_nw_keys; 1579 } else { 1580 /* 1581 * Firmware handles key allocation. 1582 */ 1583 *keyix = *rxkeyix = 0; 1584 } 1585 return 1; 1586} 1587 1588/* 1589 * Delete a key entry allocated by mwl_key_alloc. 1590 */ 1591static int 1592mwl_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) 1593{ 1594 struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; 1595 struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; 1596 MWL_HAL_KEYVAL hk; 1597 const uint8_t bcastaddr[IEEE80211_ADDR_LEN] = 1598 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 1599 1600 if (hvap == NULL) { 1601 if (vap->iv_opmode != IEEE80211_M_WDS) { 1602 /* XXX monitor mode? */ 1603 DPRINTF(sc, MWL_DEBUG_KEYCACHE, 1604 "%s: no hvap for opmode %d\n", __func__, 1605 vap->iv_opmode); 1606 return 0; 1607 } 1608 hvap = MWL_VAP(vap)->mv_ap_hvap; 1609 } 1610 1611 DPRINTF(sc, MWL_DEBUG_KEYCACHE, "%s: delete key %u\n", 1612 __func__, k->wk_keyix); 1613 1614 memset(&hk, 0, sizeof(hk)); 1615 hk.keyIndex = k->wk_keyix; 1616 switch (k->wk_cipher->ic_cipher) { 1617 case IEEE80211_CIPHER_WEP: 1618 hk.keyTypeId = KEY_TYPE_ID_WEP; 1619 break; 1620 case IEEE80211_CIPHER_TKIP: 1621 hk.keyTypeId = KEY_TYPE_ID_TKIP; 1622 break; 1623 case IEEE80211_CIPHER_AES_CCM: 1624 hk.keyTypeId = KEY_TYPE_ID_AES; 1625 break; 1626 default: 1627 /* XXX should not happen */ 1628 DPRINTF(sc, MWL_DEBUG_KEYCACHE, "%s: unknown cipher %d\n", 1629 __func__, k->wk_cipher->ic_cipher); 1630 return 0; 1631 } 1632 return (mwl_hal_keyreset(hvap, &hk, bcastaddr) == 0); /*XXX*/ 1633} 1634 1635static __inline int 1636addgroupflags(MWL_HAL_KEYVAL *hk, const struct ieee80211_key *k) 1637{ 1638 if (k->wk_flags & IEEE80211_KEY_GROUP) { 1639 if (k->wk_flags & IEEE80211_KEY_XMIT) 1640 hk->keyFlags |= KEY_FLAG_TXGROUPKEY; 1641 if (k->wk_flags & IEEE80211_KEY_RECV) 1642 hk->keyFlags |= KEY_FLAG_RXGROUPKEY; 1643 return 1; 1644 } else 1645 return 0; 1646} 1647 1648/* 1649 * Set the key cache contents for the specified key. Key cache 1650 * slot(s) must already have been allocated by mwl_key_alloc. 1651 */ 1652static int 1653mwl_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, 1654 const uint8_t mac[IEEE80211_ADDR_LEN]) 1655{ 1656#define GRPXMIT (IEEE80211_KEY_XMIT | IEEE80211_KEY_GROUP) 1657/* NB: static wep keys are marked GROUP+tx/rx; GTK will be tx or rx */ 1658#define IEEE80211_IS_STATICKEY(k) \ 1659 (((k)->wk_flags & (GRPXMIT|IEEE80211_KEY_RECV)) == \ 1660 (GRPXMIT|IEEE80211_KEY_RECV)) 1661 struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; 1662 struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; 1663 const struct ieee80211_cipher *cip = k->wk_cipher; 1664 const uint8_t *macaddr; 1665 MWL_HAL_KEYVAL hk; 1666 1667 KASSERT((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0, 1668 ("s/w crypto set?")); 1669 1670 if (hvap == NULL) { 1671 if (vap->iv_opmode != IEEE80211_M_WDS) { 1672 /* XXX monitor mode? */ 1673 DPRINTF(sc, MWL_DEBUG_KEYCACHE, 1674 "%s: no hvap for opmode %d\n", __func__, 1675 vap->iv_opmode); 1676 return 0; 1677 } 1678 hvap = MWL_VAP(vap)->mv_ap_hvap; 1679 } 1680 memset(&hk, 0, sizeof(hk)); 1681 hk.keyIndex = k->wk_keyix; 1682 switch (cip->ic_cipher) { 1683 case IEEE80211_CIPHER_WEP: 1684 hk.keyTypeId = KEY_TYPE_ID_WEP; 1685 hk.keyLen = k->wk_keylen; 1686 if (k->wk_keyix == vap->iv_def_txkey) 1687 hk.keyFlags = KEY_FLAG_WEP_TXKEY; 1688 if (!IEEE80211_IS_STATICKEY(k)) { 1689 /* NB: WEP is never used for the PTK */ 1690 (void) addgroupflags(&hk, k); 1691 } 1692 break; 1693 case IEEE80211_CIPHER_TKIP: 1694 hk.keyTypeId = KEY_TYPE_ID_TKIP; 1695 hk.key.tkip.tsc.high = (uint32_t)(k->wk_keytsc >> 16); 1696 hk.key.tkip.tsc.low = (uint16_t)k->wk_keytsc; 1697 hk.keyFlags = KEY_FLAG_TSC_VALID | KEY_FLAG_MICKEY_VALID; 1698 hk.keyLen = k->wk_keylen + IEEE80211_MICBUF_SIZE; 1699 if (!addgroupflags(&hk, k)) 1700 hk.keyFlags |= KEY_FLAG_PAIRWISE; 1701 break; 1702 case IEEE80211_CIPHER_AES_CCM: 1703 hk.keyTypeId = KEY_TYPE_ID_AES; 1704 hk.keyLen = k->wk_keylen; 1705 if (!addgroupflags(&hk, k)) 1706 hk.keyFlags |= KEY_FLAG_PAIRWISE; 1707 break; 1708 default: 1709 /* XXX should not happen */ 1710 DPRINTF(sc, MWL_DEBUG_KEYCACHE, "%s: unknown cipher %d\n", 1711 __func__, k->wk_cipher->ic_cipher); 1712 return 0; 1713 } 1714 /* 1715 * NB: tkip mic keys get copied here too; the layout 1716 * just happens to match that in ieee80211_key. 1717 */ 1718 memcpy(hk.key.aes, k->wk_key, hk.keyLen); 1719 1720 /* 1721 * Locate address of sta db entry for writing key; 1722 * the convention unfortunately is somewhat different 1723 * than how net80211, hostapd, and wpa_supplicant think. 1724 */ 1725 if (vap->iv_opmode == IEEE80211_M_STA) { 1726 /* 1727 * NB: keys plumbed before the sta reaches AUTH state 1728 * will be discarded or written to the wrong sta db 1729 * entry because iv_bss is meaningless. This is ok 1730 * (right now) because we handle deferred plumbing of 1731 * WEP keys when the sta reaches AUTH state. 1732 */ 1733 macaddr = vap->iv_bss->ni_bssid; 1734 } else if (vap->iv_opmode == IEEE80211_M_WDS && 1735 vap->iv_state != IEEE80211_S_RUN) { 1736 /* 1737 * Prior to RUN state a WDS vap will not it's BSS node 1738 * setup so we will plumb the key to the wrong mac 1739 * address (it'll be our local address). Workaround 1740 * this for the moment by grabbing the correct address. 1741 */ 1742 macaddr = vap->iv_des_bssid; 1743 } else if ((k->wk_flags & GRPXMIT) == GRPXMIT) 1744 macaddr = vap->iv_myaddr; 1745 else 1746 macaddr = mac; 1747 KEYPRINTF(sc, &hk, macaddr); 1748 return (mwl_hal_keyset(hvap, &hk, macaddr) == 0); 1749#undef IEEE80211_IS_STATICKEY 1750#undef GRPXMIT 1751} 1752 1753/* unaligned little endian access */ 1754#define LE_READ_2(p) \ 1755 ((uint16_t) \ 1756 ((((const uint8_t *)(p))[0] ) | \ 1757 (((const uint8_t *)(p))[1] << 8))) 1758#define LE_READ_4(p) \ 1759 ((uint32_t) \ 1760 ((((const uint8_t *)(p))[0] ) | \ 1761 (((const uint8_t *)(p))[1] << 8) | \ 1762 (((const uint8_t *)(p))[2] << 16) | \ 1763 (((const uint8_t *)(p))[3] << 24))) 1764 1765/* 1766 * Set the multicast filter contents into the hardware. 1767 * XXX f/w has no support; just defer to the os. 1768 */ 1769static void 1770mwl_setmcastfilter(struct mwl_softc *sc) 1771{ 1772 struct ifnet *ifp = sc->sc_ifp; 1773#if 0 1774 struct ether_multi *enm; 1775 struct ether_multistep estep; 1776 uint8_t macs[IEEE80211_ADDR_LEN*MWL_HAL_MCAST_MAX];/* XXX stack use */ 1777 uint8_t *mp; 1778 int nmc; 1779 1780 mp = macs; 1781 nmc = 0; 1782 ETHER_FIRST_MULTI(estep, &sc->sc_ec, enm); 1783 while (enm != NULL) { 1784 /* XXX Punt on ranges. */ 1785 if (nmc == MWL_HAL_MCAST_MAX || 1786 !IEEE80211_ADDR_EQ(enm->enm_addrlo, enm->enm_addrhi)) { 1787 ifp->if_flags |= IFF_ALLMULTI; 1788 return; 1789 } 1790 IEEE80211_ADDR_COPY(mp, enm->enm_addrlo); 1791 mp += IEEE80211_ADDR_LEN, nmc++; 1792 ETHER_NEXT_MULTI(estep, enm); 1793 } 1794 ifp->if_flags &= ~IFF_ALLMULTI; 1795 mwl_hal_setmcast(sc->sc_mh, nmc, macs); 1796#else 1797 /* XXX no mcast filter support; we get everything */ 1798 ifp->if_flags |= IFF_ALLMULTI; 1799#endif 1800} 1801 1802static int 1803mwl_mode_init(struct mwl_softc *sc) 1804{ 1805 struct ifnet *ifp = sc->sc_ifp; 1806 struct ieee80211com *ic = ifp->if_l2com; 1807 struct mwl_hal *mh = sc->sc_mh; 1808 1809 /* 1810 * NB: Ignore promisc in hostap mode; it's set by the 1811 * bridge. This is wrong but we have no way to 1812 * identify internal requests (from the bridge) 1813 * versus external requests such as for tcpdump. 1814 */ 1815 mwl_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) && 1816 ic->ic_opmode != IEEE80211_M_HOSTAP); 1817 mwl_setmcastfilter(sc); 1818 1819 return 0; 1820} 1821 1822/* 1823 * Callback from the 802.11 layer after a multicast state change. 1824 */ 1825static void 1826mwl_update_mcast(struct ifnet *ifp) 1827{ 1828 struct mwl_softc *sc = ifp->if_softc; 1829 1830 mwl_setmcastfilter(sc); 1831} 1832 1833/* 1834 * Callback from the 802.11 layer after a promiscuous mode change. 1835 * Note this interface does not check the operating mode as this 1836 * is an internal callback and we are expected to honor the current 1837 * state (e.g. this is used for setting the interface in promiscuous 1838 * mode when operating in hostap mode to do ACS). 1839 */ 1840static void 1841mwl_update_promisc(struct ifnet *ifp) 1842{ 1843 struct mwl_softc *sc = ifp->if_softc; 1844 1845 mwl_hal_setpromisc(sc->sc_mh, (ifp->if_flags & IFF_PROMISC) != 0); 1846} 1847 1848/* 1849 * Callback from the 802.11 layer to update the slot time 1850 * based on the current setting. We use it to notify the 1851 * firmware of ERP changes and the f/w takes care of things 1852 * like slot time and preamble. 1853 */ 1854static void 1855mwl_updateslot(struct ifnet *ifp) 1856{ 1857 struct mwl_softc *sc = ifp->if_softc; 1858 struct ieee80211com *ic = ifp->if_l2com; 1859 struct mwl_hal *mh = sc->sc_mh; 1860 int prot; 1861 1862 /* NB: can be called early; suppress needless cmds */ 1863 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) 1864 return; 1865 1866 /* 1867 * Calculate the ERP flags. The firwmare will use 1868 * this to carry out the appropriate measures. 1869 */ 1870 prot = 0; 1871 if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) { 1872 if ((ic->ic_flags & IEEE80211_F_SHSLOT) == 0) 1873 prot |= IEEE80211_ERP_NON_ERP_PRESENT; 1874 if (ic->ic_flags & IEEE80211_F_USEPROT) 1875 prot |= IEEE80211_ERP_USE_PROTECTION; 1876 if (ic->ic_flags & IEEE80211_F_USEBARKER) 1877 prot |= IEEE80211_ERP_LONG_PREAMBLE; 1878 } 1879 1880 DPRINTF(sc, MWL_DEBUG_RESET, 1881 "%s: chan %u MHz/flags 0x%x %s slot, (prot 0x%x ic_flags 0x%x)\n", 1882 __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags, 1883 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", prot, 1884 ic->ic_flags); 1885 1886 mwl_hal_setgprot(mh, prot); 1887} 1888 1889/* 1890 * Setup the beacon frame. 1891 */ 1892static int 1893mwl_beacon_setup(struct ieee80211vap *vap) 1894{ 1895 struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; 1896 struct ieee80211_node *ni = vap->iv_bss; 1897 struct ieee80211_beacon_offsets bo; 1898 struct mbuf *m; 1899 1900 m = ieee80211_beacon_alloc(ni, &bo); 1901 if (m == NULL) 1902 return ENOBUFS; 1903 mwl_hal_setbeacon(hvap, mtod(m, const void *), m->m_len); 1904 m_free(m); 1905 1906 return 0; 1907} 1908 1909/* 1910 * Update the beacon frame in response to a change. 1911 */ 1912static void 1913mwl_beacon_update(struct ieee80211vap *vap, int item) 1914{ 1915 struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; 1916 struct ieee80211com *ic = vap->iv_ic; 1917 1918 KASSERT(hvap != NULL, ("no beacon")); 1919 switch (item) { 1920 case IEEE80211_BEACON_ERP: 1921 mwl_updateslot(ic->ic_ifp); 1922 break; 1923 case IEEE80211_BEACON_HTINFO: 1924 mwl_hal_setnprotmode(hvap, 1925 MS(ic->ic_curhtprotmode, IEEE80211_HTINFO_OPMODE)); 1926 break; 1927 case IEEE80211_BEACON_CAPS: 1928 case IEEE80211_BEACON_WME: 1929 case IEEE80211_BEACON_APPIE: 1930 case IEEE80211_BEACON_CSA: 1931 break; 1932 case IEEE80211_BEACON_TIM: 1933 /* NB: firmware always forms TIM */ 1934 return; 1935 } 1936 /* XXX retain beacon frame and update */ 1937 mwl_beacon_setup(vap); 1938} 1939 1940static void 1941mwl_load_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 1942{ 1943 bus_addr_t *paddr = (bus_addr_t*) arg; 1944 KASSERT(error == 0, ("error %u on bus_dma callback", error)); 1945 *paddr = segs->ds_addr; 1946} 1947 1948#ifdef MWL_HOST_PS_SUPPORT 1949/* 1950 * Handle power save station occupancy changes. 1951 */ 1952static void 1953mwl_update_ps(struct ieee80211vap *vap, int nsta) 1954{ 1955 struct mwl_vap *mvp = MWL_VAP(vap); 1956 1957 if (nsta == 0 || mvp->mv_last_ps_sta == 0) 1958 mwl_hal_setpowersave_bss(mvp->mv_hvap, nsta); 1959 mvp->mv_last_ps_sta = nsta; 1960} 1961 1962/* 1963 * Handle associated station power save state changes. 1964 */ 1965static int 1966mwl_set_tim(struct ieee80211_node *ni, int set) 1967{ 1968 struct ieee80211vap *vap = ni->ni_vap; 1969 struct mwl_vap *mvp = MWL_VAP(vap); 1970 1971 if (mvp->mv_set_tim(ni, set)) { /* NB: state change */ 1972 mwl_hal_setpowersave_sta(mvp->mv_hvap, 1973 IEEE80211_AID(ni->ni_associd), set); 1974 return 1; 1975 } else 1976 return 0; 1977} 1978#endif /* MWL_HOST_PS_SUPPORT */ 1979 1980static int 1981mwl_desc_setup(struct mwl_softc *sc, const char *name, 1982 struct mwl_descdma *dd, 1983 int nbuf, size_t bufsize, int ndesc, size_t descsize) 1984{ 1985 struct ifnet *ifp = sc->sc_ifp; 1986 uint8_t *ds; 1987 int error; 1988 1989 DPRINTF(sc, MWL_DEBUG_RESET, 1990 "%s: %s DMA: %u bufs (%ju) %u desc/buf (%ju)\n", 1991 __func__, name, nbuf, (uintmax_t) bufsize, 1992 ndesc, (uintmax_t) descsize); 1993 1994 dd->dd_name = name; 1995 dd->dd_desc_len = nbuf * ndesc * descsize; 1996 1997 /* 1998 * Setup DMA descriptor area. 1999 */ 2000 error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */ 2001 PAGE_SIZE, 0, /* alignment, bounds */ 2002 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 2003 BUS_SPACE_MAXADDR, /* highaddr */ 2004 NULL, NULL, /* filter, filterarg */ 2005 dd->dd_desc_len, /* maxsize */ 2006 1, /* nsegments */ 2007 dd->dd_desc_len, /* maxsegsize */ 2008 BUS_DMA_ALLOCNOW, /* flags */ 2009 NULL, /* lockfunc */ 2010 NULL, /* lockarg */ 2011 &dd->dd_dmat); 2012 if (error != 0) { 2013 if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name); 2014 return error; 2015 } 2016 2017 /* allocate descriptors */ 2018 error = bus_dmamap_create(dd->dd_dmat, BUS_DMA_NOWAIT, &dd->dd_dmamap); 2019 if (error != 0) { 2020 if_printf(ifp, "unable to create dmamap for %s descriptors, " 2021 "error %u\n", dd->dd_name, error); 2022 goto fail0; 2023 } 2024 2025 error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc, 2026 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 2027 &dd->dd_dmamap); 2028 if (error != 0) { 2029 if_printf(ifp, "unable to alloc memory for %u %s descriptors, " 2030 "error %u\n", nbuf * ndesc, dd->dd_name, error); 2031 goto fail1; 2032 } 2033 2034 error = bus_dmamap_load(dd->dd_dmat, dd->dd_dmamap, 2035 dd->dd_desc, dd->dd_desc_len, 2036 mwl_load_cb, &dd->dd_desc_paddr, 2037 BUS_DMA_NOWAIT); 2038 if (error != 0) { 2039 if_printf(ifp, "unable to map %s descriptors, error %u\n", 2040 dd->dd_name, error); 2041 goto fail2; 2042 } 2043 2044 ds = dd->dd_desc; 2045 memset(ds, 0, dd->dd_desc_len); 2046 DPRINTF(sc, MWL_DEBUG_RESET, "%s: %s DMA map: %p (%lu) -> %p (%lu)\n", 2047 __func__, dd->dd_name, ds, (u_long) dd->dd_desc_len, 2048 (caddr_t) dd->dd_desc_paddr, /*XXX*/ (u_long) dd->dd_desc_len); 2049 2050 return 0; 2051fail2: 2052 bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap); 2053fail1: 2054 bus_dmamap_destroy(dd->dd_dmat, dd->dd_dmamap); 2055fail0: 2056 bus_dma_tag_destroy(dd->dd_dmat); 2057 memset(dd, 0, sizeof(*dd)); 2058 return error; 2059#undef DS2PHYS 2060} 2061 2062static void 2063mwl_desc_cleanup(struct mwl_softc *sc, struct mwl_descdma *dd) 2064{ 2065 bus_dmamap_unload(dd->dd_dmat, dd->dd_dmamap); 2066 bus_dmamem_free(dd->dd_dmat, dd->dd_desc, dd->dd_dmamap); 2067 bus_dmamap_destroy(dd->dd_dmat, dd->dd_dmamap); 2068 bus_dma_tag_destroy(dd->dd_dmat); 2069 2070 memset(dd, 0, sizeof(*dd)); 2071} 2072 2073/* 2074 * Construct a tx q's free list. The order of entries on 2075 * the list must reflect the physical layout of tx descriptors 2076 * because the firmware pre-fetches descriptors. 2077 * 2078 * XXX might be better to use indices into the buffer array. 2079 */ 2080static void 2081mwl_txq_reset(struct mwl_softc *sc, struct mwl_txq *txq) 2082{ 2083 struct mwl_txbuf *bf; 2084 int i; 2085 2086 bf = txq->dma.dd_bufptr; 2087 STAILQ_INIT(&txq->free); 2088 for (i = 0; i < mwl_txbuf; i++, bf++) 2089 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list); 2090 txq->nfree = i; 2091} 2092 2093#define DS2PHYS(_dd, _ds) \ 2094 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) 2095 2096static int 2097mwl_txdma_setup(struct mwl_softc *sc, struct mwl_txq *txq) 2098{ 2099 struct ifnet *ifp = sc->sc_ifp; 2100 int error, bsize, i; 2101 struct mwl_txbuf *bf; 2102 struct mwl_txdesc *ds; 2103 2104 error = mwl_desc_setup(sc, "tx", &txq->dma, 2105 mwl_txbuf, sizeof(struct mwl_txbuf), 2106 MWL_TXDESC, sizeof(struct mwl_txdesc)); 2107 if (error != 0) 2108 return error; 2109 2110 /* allocate and setup tx buffers */ 2111 bsize = mwl_txbuf * sizeof(struct mwl_txbuf); 2112 bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO); 2113 if (bf == NULL) { 2114 if_printf(ifp, "malloc of %u tx buffers failed\n", 2115 mwl_txbuf); 2116 return ENOMEM; 2117 } 2118 txq->dma.dd_bufptr = bf; 2119 2120 ds = txq->dma.dd_desc; 2121 for (i = 0; i < mwl_txbuf; i++, bf++, ds += MWL_TXDESC) { 2122 bf->bf_desc = ds; 2123 bf->bf_daddr = DS2PHYS(&txq->dma, ds); 2124 error = bus_dmamap_create(sc->sc_dmat, BUS_DMA_NOWAIT, 2125 &bf->bf_dmamap); 2126 if (error != 0) { 2127 if_printf(ifp, "unable to create dmamap for tx " 2128 "buffer %u, error %u\n", i, error); 2129 return error; 2130 } 2131 } 2132 mwl_txq_reset(sc, txq); 2133 return 0; 2134} 2135 2136static void 2137mwl_txdma_cleanup(struct mwl_softc *sc, struct mwl_txq *txq) 2138{ 2139 struct mwl_txbuf *bf; 2140 int i; 2141 2142 bf = txq->dma.dd_bufptr; 2143 for (i = 0; i < mwl_txbuf; i++, bf++) { 2144 KASSERT(bf->bf_m == NULL, ("mbuf on free list")); 2145 KASSERT(bf->bf_node == NULL, ("node on free list")); 2146 if (bf->bf_dmamap != NULL) 2147 bus_dmamap_destroy(sc->sc_dmat, bf->bf_dmamap); 2148 } 2149 STAILQ_INIT(&txq->free); 2150 txq->nfree = 0; 2151 if (txq->dma.dd_bufptr != NULL) { 2152 free(txq->dma.dd_bufptr, M_MWLDEV); 2153 txq->dma.dd_bufptr = NULL; 2154 } 2155 if (txq->dma.dd_desc_len != 0) 2156 mwl_desc_cleanup(sc, &txq->dma); 2157} 2158 2159static int 2160mwl_rxdma_setup(struct mwl_softc *sc) 2161{ 2162 struct ifnet *ifp = sc->sc_ifp; 2163 int error, jumbosize, bsize, i; 2164 struct mwl_rxbuf *bf; 2165 struct mwl_jumbo *rbuf; 2166 struct mwl_rxdesc *ds; 2167 caddr_t data; 2168 2169 error = mwl_desc_setup(sc, "rx", &sc->sc_rxdma, 2170 mwl_rxdesc, sizeof(struct mwl_rxbuf), 2171 1, sizeof(struct mwl_rxdesc)); 2172 if (error != 0) 2173 return error; 2174 2175 /* 2176 * Receive is done to a private pool of jumbo buffers. 2177 * This allows us to attach to mbuf's and avoid re-mapping 2178 * memory on each rx we post. We allocate a large chunk 2179 * of memory and manage it in the driver. The mbuf free 2180 * callback method is used to reclaim frames after sending 2181 * them up the stack. By default we allocate 2x the number of 2182 * rx descriptors configured so we have some slop to hold 2183 * us while frames are processed. 2184 */ 2185 if (mwl_rxbuf < 2*mwl_rxdesc) { 2186 if_printf(ifp, 2187 "too few rx dma buffers (%d); increasing to %d\n", 2188 mwl_rxbuf, 2*mwl_rxdesc); 2189 mwl_rxbuf = 2*mwl_rxdesc; 2190 } 2191 jumbosize = roundup(MWL_AGGR_SIZE, PAGE_SIZE); 2192 sc->sc_rxmemsize = mwl_rxbuf*jumbosize; 2193 2194 error = bus_dma_tag_create(sc->sc_dmat, /* parent */ 2195 PAGE_SIZE, 0, /* alignment, bounds */ 2196 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ 2197 BUS_SPACE_MAXADDR, /* highaddr */ 2198 NULL, NULL, /* filter, filterarg */ 2199 sc->sc_rxmemsize, /* maxsize */ 2200 1, /* nsegments */ 2201 sc->sc_rxmemsize, /* maxsegsize */ 2202 BUS_DMA_ALLOCNOW, /* flags */ 2203 NULL, /* lockfunc */ 2204 NULL, /* lockarg */ 2205 &sc->sc_rxdmat); 2206 error = bus_dmamap_create(sc->sc_rxdmat, BUS_DMA_NOWAIT, &sc->sc_rxmap); 2207 if (error != 0) { 2208 if_printf(ifp, "could not create rx DMA map\n"); 2209 return error; 2210 } 2211 2212 error = bus_dmamem_alloc(sc->sc_rxdmat, (void**) &sc->sc_rxmem, 2213 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 2214 &sc->sc_rxmap); 2215 if (error != 0) { 2216 if_printf(ifp, "could not alloc %ju bytes of rx DMA memory\n", 2217 (uintmax_t) sc->sc_rxmemsize); 2218 return error; 2219 } 2220 2221 error = bus_dmamap_load(sc->sc_rxdmat, sc->sc_rxmap, 2222 sc->sc_rxmem, sc->sc_rxmemsize, 2223 mwl_load_cb, &sc->sc_rxmem_paddr, 2224 BUS_DMA_NOWAIT); 2225 if (error != 0) { 2226 if_printf(ifp, "could not load rx DMA map\n"); 2227 return error; 2228 } 2229 2230 /* 2231 * Allocate rx buffers and set them up. 2232 */ 2233 bsize = mwl_rxdesc * sizeof(struct mwl_rxbuf); 2234 bf = malloc(bsize, M_MWLDEV, M_NOWAIT | M_ZERO); 2235 if (bf == NULL) { 2236 if_printf(ifp, "malloc of %u rx buffers failed\n", bsize); 2237 return error; 2238 } 2239 sc->sc_rxdma.dd_bufptr = bf; 2240 2241 STAILQ_INIT(&sc->sc_rxbuf); 2242 ds = sc->sc_rxdma.dd_desc; 2243 for (i = 0; i < mwl_rxdesc; i++, bf++, ds++) { 2244 bf->bf_desc = ds; 2245 bf->bf_daddr = DS2PHYS(&sc->sc_rxdma, ds); 2246 /* pre-assign dma buffer */ 2247 bf->bf_data = ((uint8_t *)sc->sc_rxmem) + (i*jumbosize); 2248 /* NB: tail is intentional to preserve descriptor order */ 2249 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); 2250 } 2251 2252 /* 2253 * Place remainder of dma memory buffers on the free list. 2254 */ 2255 SLIST_INIT(&sc->sc_rxfree); 2256 for (; i < mwl_rxbuf; i++) { 2257 data = ((uint8_t *)sc->sc_rxmem) + (i*jumbosize); 2258 rbuf = MWL_JUMBO_DATA2BUF(data); 2259 SLIST_INSERT_HEAD(&sc->sc_rxfree, rbuf, next); 2260 sc->sc_nrxfree++; 2261 } 2262 MWL_RXFREE_INIT(sc); 2263 return 0; 2264} 2265#undef DS2PHYS 2266 2267static void 2268mwl_rxdma_cleanup(struct mwl_softc *sc) 2269{ 2270 if (sc->sc_rxmap != NULL) 2271 bus_dmamap_unload(sc->sc_rxdmat, sc->sc_rxmap); 2272 if (sc->sc_rxmem != NULL) { 2273 bus_dmamem_free(sc->sc_rxdmat, sc->sc_rxmem, sc->sc_rxmap); 2274 sc->sc_rxmem = NULL; 2275 } 2276 if (sc->sc_rxmap != NULL) { 2277 bus_dmamap_destroy(sc->sc_rxdmat, sc->sc_rxmap); 2278 sc->sc_rxmap = NULL; 2279 } 2280 if (sc->sc_rxdma.dd_bufptr != NULL) { 2281 free(sc->sc_rxdma.dd_bufptr, M_MWLDEV); 2282 sc->sc_rxdma.dd_bufptr = NULL; 2283 } 2284 if (sc->sc_rxdma.dd_desc_len != 0) 2285 mwl_desc_cleanup(sc, &sc->sc_rxdma); 2286 MWL_RXFREE_DESTROY(sc); 2287} 2288 2289static int 2290mwl_dma_setup(struct mwl_softc *sc) 2291{ 2292 int error, i; 2293 2294 error = mwl_rxdma_setup(sc); 2295 if (error != 0) 2296 return error; 2297 2298 for (i = 0; i < MWL_NUM_TX_QUEUES; i++) { 2299 error = mwl_txdma_setup(sc, &sc->sc_txq[i]); 2300 if (error != 0) { 2301 mwl_dma_cleanup(sc); 2302 return error; 2303 } 2304 } 2305 return 0; 2306} 2307 2308static void 2309mwl_dma_cleanup(struct mwl_softc *sc) 2310{ 2311 int i; 2312 2313 for (i = 0; i < MWL_NUM_TX_QUEUES; i++) 2314 mwl_txdma_cleanup(sc, &sc->sc_txq[i]); 2315 mwl_rxdma_cleanup(sc); 2316} 2317 2318static struct ieee80211_node * 2319mwl_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 2320{ 2321 struct ieee80211com *ic = vap->iv_ic; 2322 struct mwl_softc *sc = ic->ic_ifp->if_softc; 2323 const size_t space = sizeof(struct mwl_node); 2324 struct mwl_node *mn; 2325 2326 mn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO); 2327 if (mn == NULL) { 2328 /* XXX stat+msg */ 2329 return NULL; 2330 } 2331 DPRINTF(sc, MWL_DEBUG_NODE, "%s: mn %p\n", __func__, mn); 2332 return &mn->mn_node; 2333} 2334 2335static void 2336mwl_node_cleanup(struct ieee80211_node *ni) 2337{ 2338 struct ieee80211com *ic = ni->ni_ic; 2339 struct mwl_softc *sc = ic->ic_ifp->if_softc; 2340 struct mwl_node *mn = MWL_NODE(ni); 2341 2342 DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p ic %p staid %d\n", 2343 __func__, ni, ni->ni_ic, mn->mn_staid); 2344 2345 if (mn->mn_staid != 0) { 2346 struct ieee80211vap *vap = ni->ni_vap; 2347 2348 if (mn->mn_hvap != NULL) { 2349 if (vap->iv_opmode == IEEE80211_M_STA) 2350 mwl_hal_delstation(mn->mn_hvap, vap->iv_myaddr); 2351 else 2352 mwl_hal_delstation(mn->mn_hvap, ni->ni_macaddr); 2353 } 2354 /* 2355 * NB: legacy WDS peer sta db entry is installed using 2356 * the associate ap's hvap; use it again to delete it. 2357 * XXX can vap be NULL? 2358 */ 2359 else if (vap->iv_opmode == IEEE80211_M_WDS && 2360 MWL_VAP(vap)->mv_ap_hvap != NULL) 2361 mwl_hal_delstation(MWL_VAP(vap)->mv_ap_hvap, 2362 ni->ni_macaddr); 2363 delstaid(sc, mn->mn_staid); 2364 mn->mn_staid = 0; 2365 } 2366 sc->sc_node_cleanup(ni); 2367} 2368 2369/* 2370 * Reclaim rx dma buffers from packets sitting on the ampdu 2371 * reorder queue for a station. We replace buffers with a 2372 * system cluster (if available). 2373 */ 2374static void 2375mwl_ampdu_rxdma_reclaim(struct ieee80211_rx_ampdu *rap) 2376{ 2377#if 0 2378 int i, n, off; 2379 struct mbuf *m; 2380 void *cl; 2381 2382 n = rap->rxa_qframes; 2383 for (i = 0; i < rap->rxa_wnd && n > 0; i++) { 2384 m = rap->rxa_m[i]; 2385 if (m == NULL) 2386 continue; 2387 n--; 2388 /* our dma buffers have a well-known free routine */ 2389 if ((m->m_flags & M_EXT) == 0 || 2390 m->m_ext.ext_free != mwl_ext_free) 2391 continue; 2392 /* 2393 * Try to allocate a cluster and move the data. 2394 */ 2395 off = m->m_data - m->m_ext.ext_buf; 2396 if (off + m->m_pkthdr.len > MCLBYTES) { 2397 /* XXX no AMSDU for now */ 2398 continue; 2399 } 2400 cl = pool_cache_get_paddr(&mclpool_cache, 0, 2401 &m->m_ext.ext_paddr); 2402 if (cl != NULL) { 2403 /* 2404 * Copy the existing data to the cluster, remove 2405 * the rx dma buffer, and attach the cluster in 2406 * its place. Note we preserve the offset to the 2407 * data so frames being bridged can still prepend 2408 * their headers without adding another mbuf. 2409 */ 2410 memcpy((caddr_t) cl + off, m->m_data, m->m_pkthdr.len); 2411 MEXTREMOVE(m); 2412 MEXTADD(m, cl, MCLBYTES, 0, NULL, &mclpool_cache); 2413 /* setup mbuf like _MCLGET does */ 2414 m->m_flags |= M_CLUSTER | M_EXT_RW; 2415 _MOWNERREF(m, M_EXT | M_CLUSTER); 2416 /* NB: m_data is clobbered by MEXTADDR, adjust */ 2417 m->m_data += off; 2418 } 2419 } 2420#endif 2421} 2422 2423/* 2424 * Callback to reclaim resources. We first let the 2425 * net80211 layer do it's thing, then if we are still 2426 * blocked by a lack of rx dma buffers we walk the ampdu 2427 * reorder q's to reclaim buffers by copying to a system 2428 * cluster. 2429 */ 2430static void 2431mwl_node_drain(struct ieee80211_node *ni) 2432{ 2433 struct ieee80211com *ic = ni->ni_ic; 2434 struct mwl_softc *sc = ic->ic_ifp->if_softc; 2435 struct mwl_node *mn = MWL_NODE(ni); 2436 2437 DPRINTF(sc, MWL_DEBUG_NODE, "%s: ni %p vap %p staid %d\n", 2438 __func__, ni, ni->ni_vap, mn->mn_staid); 2439 2440 /* NB: call up first to age out ampdu q's */ 2441 sc->sc_node_drain(ni); 2442 2443 /* XXX better to not check low water mark? */ 2444 if (sc->sc_rxblocked && mn->mn_staid != 0 && 2445 (ni->ni_flags & IEEE80211_NODE_HT)) { 2446 uint8_t tid; 2447 /* 2448 * Walk the reorder q and reclaim rx dma buffers by copying 2449 * the packet contents into clusters. 2450 */ 2451 for (tid = 0; tid < WME_NUM_TID; tid++) { 2452 struct ieee80211_rx_ampdu *rap; 2453 2454 rap = &ni->ni_rx_ampdu[tid]; 2455 if ((rap->rxa_flags & IEEE80211_AGGR_XCHGPEND) == 0) 2456 continue; 2457 if (rap->rxa_qframes) 2458 mwl_ampdu_rxdma_reclaim(rap); 2459 } 2460 } 2461} 2462 2463static void 2464mwl_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise) 2465{ 2466 *rssi = ni->ni_ic->ic_node_getrssi(ni); 2467#ifdef MWL_ANT_INFO_SUPPORT 2468#if 0 2469 /* XXX need to smooth data */ 2470 *noise = -MWL_NODE_CONST(ni)->mn_ai.nf; 2471#else 2472 *noise = -95; /* XXX */ 2473#endif 2474#else 2475 *noise = -95; /* XXX */ 2476#endif 2477} 2478 2479/* 2480 * Convert Hardware per-antenna rssi info to common format: 2481 * Let a1, a2, a3 represent the amplitudes per chain 2482 * Let amax represent max[a1, a2, a3] 2483 * Rssi1_dBm = RSSI_dBm + 20*log10(a1/amax) 2484 * Rssi1_dBm = RSSI_dBm + 20*log10(a1) - 20*log10(amax) 2485 * We store a table that is 4*20*log10(idx) - the extra 4 is to store or 2486 * maintain some extra precision. 2487 * 2488 * Values are stored in .5 db format capped at 127. 2489 */ 2490static void 2491mwl_node_getmimoinfo(const struct ieee80211_node *ni, 2492 struct ieee80211_mimo_info *mi) 2493{ 2494#define CVT(_dst, _src) do { \ 2495 (_dst) = rssi + ((logdbtbl[_src] - logdbtbl[rssi_max]) >> 2); \ 2496 (_dst) = (_dst) > 64 ? 127 : ((_dst) << 1); \ 2497} while (0) 2498 static const int8_t logdbtbl[32] = { 2499 0, 0, 24, 38, 48, 56, 62, 68, 2500 72, 76, 80, 83, 86, 89, 92, 94, 2501 96, 98, 100, 102, 104, 106, 107, 109, 2502 110, 112, 113, 115, 116, 117, 118, 119 2503 }; 2504 const struct mwl_node *mn = MWL_NODE_CONST(ni); 2505 uint8_t rssi = mn->mn_ai.rsvd1/2; /* XXX */ 2506 uint32_t rssi_max; 2507 2508 rssi_max = mn->mn_ai.rssi_a; 2509 if (mn->mn_ai.rssi_b > rssi_max) 2510 rssi_max = mn->mn_ai.rssi_b; 2511 if (mn->mn_ai.rssi_c > rssi_max) 2512 rssi_max = mn->mn_ai.rssi_c; 2513 2514 CVT(mi->rssi[0], mn->mn_ai.rssi_a); 2515 CVT(mi->rssi[1], mn->mn_ai.rssi_b); 2516 CVT(mi->rssi[2], mn->mn_ai.rssi_c); 2517 2518 mi->noise[0] = mn->mn_ai.nf_a; 2519 mi->noise[1] = mn->mn_ai.nf_b; 2520 mi->noise[2] = mn->mn_ai.nf_c; 2521#undef CVT 2522} 2523 2524static __inline void * 2525mwl_getrxdma(struct mwl_softc *sc) 2526{ 2527 struct mwl_jumbo *buf; 2528 void *data; 2529 2530 /* 2531 * Allocate from jumbo pool. 2532 */ 2533 MWL_RXFREE_LOCK(sc); 2534 buf = SLIST_FIRST(&sc->sc_rxfree); 2535 if (buf == NULL) { 2536 DPRINTF(sc, MWL_DEBUG_ANY, 2537 "%s: out of rx dma buffers\n", __func__); 2538 sc->sc_stats.mst_rx_nodmabuf++; 2539 data = NULL; 2540 } else { 2541 SLIST_REMOVE_HEAD(&sc->sc_rxfree, next); 2542 sc->sc_nrxfree--; 2543 data = MWL_JUMBO_BUF2DATA(buf); 2544 } 2545 MWL_RXFREE_UNLOCK(sc); 2546 return data; 2547} 2548 2549static __inline void 2550mwl_putrxdma(struct mwl_softc *sc, void *data) 2551{ 2552 struct mwl_jumbo *buf; 2553 2554 /* XXX bounds check data */ 2555 MWL_RXFREE_LOCK(sc); 2556 buf = MWL_JUMBO_DATA2BUF(data); 2557 SLIST_INSERT_HEAD(&sc->sc_rxfree, buf, next); 2558 sc->sc_nrxfree++; 2559 MWL_RXFREE_UNLOCK(sc); 2560} 2561 2562static int 2563mwl_rxbuf_init(struct mwl_softc *sc, struct mwl_rxbuf *bf) 2564{ 2565 struct mwl_rxdesc *ds; 2566 2567 ds = bf->bf_desc; 2568 if (bf->bf_data == NULL) { 2569 bf->bf_data = mwl_getrxdma(sc); 2570 if (bf->bf_data == NULL) { 2571 /* mark descriptor to be skipped */ 2572 ds->RxControl = EAGLE_RXD_CTRL_OS_OWN; 2573 /* NB: don't need PREREAD */ 2574 MWL_RXDESC_SYNC(sc, ds, BUS_DMASYNC_PREWRITE); 2575 sc->sc_stats.mst_rxbuf_failed++; 2576 return ENOMEM; 2577 } 2578 } 2579 /* 2580 * NB: DMA buffer contents is known to be unmodified 2581 * so there's no need to flush the data cache. 2582 */ 2583 2584 /* 2585 * Setup descriptor. 2586 */ 2587 ds->QosCtrl = 0; 2588 ds->RSSI = 0; 2589 ds->Status = EAGLE_RXD_STATUS_IDLE; 2590 ds->Channel = 0; 2591 ds->PktLen = htole16(MWL_AGGR_SIZE); 2592 ds->SQ2 = 0; 2593 ds->pPhysBuffData = htole32(MWL_JUMBO_DMA_ADDR(sc, bf->bf_data)); 2594 /* NB: don't touch pPhysNext, set once */ 2595 ds->RxControl = EAGLE_RXD_CTRL_DRIVER_OWN; 2596 MWL_RXDESC_SYNC(sc, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2597 2598 return 0; 2599} 2600 2601static void 2602mwl_ext_free(void *data, void *arg) 2603{ 2604 struct mwl_softc *sc = arg; 2605 2606 /* XXX bounds check data */ 2607 mwl_putrxdma(sc, data); 2608 /* 2609 * If we were previously blocked by a lack of rx dma buffers 2610 * check if we now have enough to restart rx interrupt handling. 2611 * NB: we know we are called at splvm which is above splnet. 2612 */ 2613 if (sc->sc_rxblocked && sc->sc_nrxfree > mwl_rxdmalow) { 2614 sc->sc_rxblocked = 0; 2615 mwl_hal_intrset(sc->sc_mh, sc->sc_imask); 2616 } 2617} 2618 2619struct mwl_frame_bar { 2620 u_int8_t i_fc[2]; 2621 u_int8_t i_dur[2]; 2622 u_int8_t i_ra[IEEE80211_ADDR_LEN]; 2623 u_int8_t i_ta[IEEE80211_ADDR_LEN]; 2624 /* ctl, seq, FCS */ 2625} __packed; 2626 2627/* 2628 * Like ieee80211_anyhdrsize, but handles BAR frames 2629 * specially so the logic below to piece the 802.11 2630 * header together works. 2631 */ 2632static __inline int 2633mwl_anyhdrsize(const void *data) 2634{ 2635 const struct ieee80211_frame *wh = data; 2636 2637 if ((wh->i_fc[0]&IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) { 2638 switch (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) { 2639 case IEEE80211_FC0_SUBTYPE_CTS: 2640 case IEEE80211_FC0_SUBTYPE_ACK: 2641 return sizeof(struct ieee80211_frame_ack); 2642 case IEEE80211_FC0_SUBTYPE_BAR: 2643 return sizeof(struct mwl_frame_bar); 2644 } 2645 return sizeof(struct ieee80211_frame_min); 2646 } else 2647 return ieee80211_hdrsize(data); 2648} 2649 2650static void 2651mwl_handlemicerror(struct ieee80211com *ic, const uint8_t *data) 2652{ 2653 const struct ieee80211_frame *wh; 2654 struct ieee80211_node *ni; 2655 2656 wh = (const struct ieee80211_frame *)(data + sizeof(uint16_t)); 2657 ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh); 2658 if (ni != NULL) { 2659 ieee80211_notify_michael_failure(ni->ni_vap, wh, 0); 2660 ieee80211_free_node(ni); 2661 } 2662} 2663 2664/* 2665 * Convert hardware signal strength to rssi. The value 2666 * provided by the device has the noise floor added in; 2667 * we need to compensate for this but we don't have that 2668 * so we use a fixed value. 2669 * 2670 * The offset of 8 is good for both 2.4 and 5GHz. The LNA 2671 * offset is already set as part of the initial gain. This 2672 * will give at least +/- 3dB for 2.4GHz and +/- 5dB for 5GHz. 2673 */ 2674static __inline int 2675cvtrssi(uint8_t ssi) 2676{ 2677 int rssi = (int) ssi + 8; 2678 /* XXX hack guess until we have a real noise floor */ 2679 rssi = 2*(87 - rssi); /* NB: .5 dBm units */ 2680 return (rssi < 0 ? 0 : rssi > 127 ? 127 : rssi); 2681} 2682 2683static void 2684mwl_rx_proc(void *arg, int npending) 2685{ 2686#define IEEE80211_DIR_DSTODS(wh) \ 2687 ((((const struct ieee80211_frame *)wh)->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 2688 struct mwl_softc *sc = arg; 2689 struct ifnet *ifp = sc->sc_ifp; 2690 struct ieee80211com *ic = ifp->if_l2com; 2691 struct mwl_rxbuf *bf; 2692 struct mwl_rxdesc *ds; 2693 struct mbuf *m; 2694 struct ieee80211_qosframe *wh; 2695 struct ieee80211_qosframe_addr4 *wh4; 2696 struct ieee80211_node *ni; 2697 struct mwl_node *mn; 2698 int off, len, hdrlen, pktlen, rssi, ntodo; 2699 uint8_t *data, status; 2700 void *newdata; 2701 int16_t nf; 2702 2703 DPRINTF(sc, MWL_DEBUG_RX_PROC, "%s: pending %u rdptr 0x%x wrptr 0x%x\n", 2704 __func__, npending, RD4(sc, sc->sc_hwspecs.rxDescRead), 2705 RD4(sc, sc->sc_hwspecs.rxDescWrite)); 2706 nf = -96; /* XXX */ 2707 bf = sc->sc_rxnext; 2708 for (ntodo = mwl_rxquota; ntodo > 0; ntodo--) { 2709 if (bf == NULL) 2710 bf = STAILQ_FIRST(&sc->sc_rxbuf); 2711 ds = bf->bf_desc; 2712 data = bf->bf_data; 2713 if (data == NULL) { 2714 /* 2715 * If data allocation failed previously there 2716 * will be no buffer; try again to re-populate it. 2717 * Note the firmware will not advance to the next 2718 * descriptor with a dma buffer so we must mimic 2719 * this or we'll get out of sync. 2720 */ 2721 DPRINTF(sc, MWL_DEBUG_ANY, 2722 "%s: rx buf w/o dma memory\n", __func__); 2723 (void) mwl_rxbuf_init(sc, bf); 2724 sc->sc_stats.mst_rx_dmabufmissing++; 2725 break; 2726 } 2727 MWL_RXDESC_SYNC(sc, ds, 2728 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2729 if (ds->RxControl != EAGLE_RXD_CTRL_DMA_OWN) 2730 break; 2731#ifdef MWL_DEBUG 2732 if (sc->sc_debug & MWL_DEBUG_RECV_DESC) 2733 mwl_printrxbuf(bf, 0); 2734#endif 2735 status = ds->Status; 2736 if (status & EAGLE_RXD_STATUS_DECRYPT_ERR_MASK) { 2737 ifp->if_ierrors++; 2738 sc->sc_stats.mst_rx_crypto++; 2739 /* 2740 * NB: Check EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR 2741 * for backwards compatibility. 2742 */ 2743 if (status != EAGLE_RXD_STATUS_GENERAL_DECRYPT_ERR && 2744 (status & EAGLE_RXD_STATUS_TKIP_MIC_DECRYPT_ERR)) { 2745 /* 2746 * MIC error, notify upper layers. 2747 */ 2748 bus_dmamap_sync(sc->sc_rxdmat, sc->sc_rxmap, 2749 BUS_DMASYNC_POSTREAD); 2750 mwl_handlemicerror(ic, data); 2751 sc->sc_stats.mst_rx_tkipmic++; 2752 } 2753 /* XXX too painful to tap packets */ 2754 goto rx_next; 2755 } 2756 /* 2757 * Sync the data buffer. 2758 */ 2759 len = le16toh(ds->PktLen); 2760 bus_dmamap_sync(sc->sc_rxdmat, sc->sc_rxmap, BUS_DMASYNC_POSTREAD); 2761 /* 2762 * The 802.11 header is provided all or in part at the front; 2763 * use it to calculate the true size of the header that we'll 2764 * construct below. We use this to figure out where to copy 2765 * payload prior to constructing the header. 2766 */ 2767 hdrlen = mwl_anyhdrsize(data + sizeof(uint16_t)); 2768 off = sizeof(uint16_t) + sizeof(struct ieee80211_frame_addr4); 2769 2770 /* calculate rssi early so we can re-use for each aggregate */ 2771 rssi = cvtrssi(ds->RSSI); 2772 2773 pktlen = hdrlen + (len - off); 2774 /* 2775 * NB: we know our frame is at least as large as 2776 * IEEE80211_MIN_LEN because there is a 4-address 2777 * frame at the front. Hence there's no need to 2778 * vet the packet length. If the frame in fact 2779 * is too small it should be discarded at the 2780 * net80211 layer. 2781 */ 2782 2783 /* 2784 * Attach dma buffer to an mbuf. We tried 2785 * doing this based on the packet size (i.e. 2786 * copying small packets) but it turns out to 2787 * be a net loss. The tradeoff might be system 2788 * dependent (cache architecture is important). 2789 */ 2790 MGETHDR(m, M_DONTWAIT, MT_DATA); 2791 if (m == NULL) { 2792 DPRINTF(sc, MWL_DEBUG_ANY, 2793 "%s: no rx mbuf\n", __func__); 2794 sc->sc_stats.mst_rx_nombuf++; 2795 goto rx_next; 2796 } 2797 /* 2798 * Acquire the replacement dma buffer before 2799 * processing the frame. If we're out of dma 2800 * buffers we disable rx interrupts and wait 2801 * for the free pool to reach mlw_rxdmalow buffers 2802 * before starting to do work again. If the firmware 2803 * runs out of descriptors then it will toss frames 2804 * which is better than our doing it as that can 2805 * starve our processing. It is also important that 2806 * we always process rx'd frames in case they are 2807 * A-MPDU as otherwise the host's view of the BA 2808 * window may get out of sync with the firmware. 2809 */ 2810 newdata = mwl_getrxdma(sc); 2811 if (newdata == NULL) { 2812 /* NB: stat+msg in mwl_getrxdma */ 2813 m_free(m); 2814 /* disable RX interrupt and mark state */ 2815 mwl_hal_intrset(sc->sc_mh, 2816 sc->sc_imask &~ MACREG_A2HRIC_BIT_RX_RDY); 2817 sc->sc_rxblocked = 1; 2818 ieee80211_drain(ic); 2819 /* XXX check rxblocked and immediately start again? */ 2820 goto rx_stop; 2821 } 2822 bf->bf_data = newdata; 2823 /* 2824 * Attach the dma buffer to the mbuf; 2825 * mwl_rxbuf_init will re-setup the rx 2826 * descriptor using the replacement dma 2827 * buffer we just installed above. 2828 */ 2829 MEXTADD(m, data, MWL_AGGR_SIZE, mwl_ext_free, 2830 data, sc, 0, EXT_NET_DRV); 2831 m->m_data += off - hdrlen; 2832 m->m_pkthdr.len = m->m_len = pktlen; 2833 m->m_pkthdr.rcvif = ifp; 2834 /* NB: dma buffer assumed read-only */ 2835 2836 /* 2837 * Piece 802.11 header together. 2838 */ 2839 wh = mtod(m, struct ieee80211_qosframe *); 2840 /* NB: don't need to do this sometimes but ... */ 2841 /* XXX special case so we can memcpy after m_devget? */ 2842 ovbcopy(data + sizeof(uint16_t), wh, hdrlen); 2843 if (IEEE80211_QOS_HAS_SEQ(wh)) { 2844 if (IEEE80211_DIR_DSTODS(wh)) { 2845 wh4 = mtod(m, 2846 struct ieee80211_qosframe_addr4*); 2847 *(uint16_t *)wh4->i_qos = ds->QosCtrl; 2848 } else { 2849 *(uint16_t *)wh->i_qos = ds->QosCtrl; 2850 } 2851 } 2852 /* 2853 * The f/w strips WEP header but doesn't clear 2854 * the WEP bit; mark the packet with M_WEP so 2855 * net80211 will treat the data as decrypted. 2856 * While here also clear the PWR_MGT bit since 2857 * power save is handled by the firmware and 2858 * passing this up will potentially cause the 2859 * upper layer to put a station in power save 2860 * (except when configured with MWL_HOST_PS_SUPPORT). 2861 */ 2862 if (wh->i_fc[1] & IEEE80211_FC1_WEP) 2863 m->m_flags |= M_WEP; 2864#ifdef MWL_HOST_PS_SUPPORT 2865 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 2866#else 2867 wh->i_fc[1] &= ~(IEEE80211_FC1_WEP | IEEE80211_FC1_PWR_MGT); 2868#endif 2869 2870 if (ieee80211_radiotap_active(ic)) { 2871 struct mwl_rx_radiotap_header *tap = &sc->sc_rx_th; 2872 2873 tap->wr_flags = 0; 2874 tap->wr_rate = ds->Rate; 2875 tap->wr_antsignal = rssi + nf; 2876 tap->wr_antnoise = nf; 2877 } 2878 if (IFF_DUMPPKTS_RECV(sc, wh)) { 2879 ieee80211_dump_pkt(ic, mtod(m, caddr_t), 2880 len, ds->Rate, rssi); 2881 } 2882 ifp->if_ipackets++; 2883 2884 /* dispatch */ 2885 ni = ieee80211_find_rxnode(ic, 2886 (const struct ieee80211_frame_min *) wh); 2887 if (ni != NULL) { 2888 mn = MWL_NODE(ni); 2889#ifdef MWL_ANT_INFO_SUPPORT 2890 mn->mn_ai.rssi_a = ds->ai.rssi_a; 2891 mn->mn_ai.rssi_b = ds->ai.rssi_b; 2892 mn->mn_ai.rssi_c = ds->ai.rssi_c; 2893 mn->mn_ai.rsvd1 = rssi; 2894#endif 2895 /* tag AMPDU aggregates for reorder processing */ 2896 if (ni->ni_flags & IEEE80211_NODE_HT) 2897 m->m_flags |= M_AMPDU; 2898 (void) ieee80211_input(ni, m, rssi, nf); 2899 ieee80211_free_node(ni); 2900 } else 2901 (void) ieee80211_input_all(ic, m, rssi, nf); 2902rx_next: 2903 /* NB: ignore ENOMEM so we process more descriptors */ 2904 (void) mwl_rxbuf_init(sc, bf); 2905 bf = STAILQ_NEXT(bf, bf_list); 2906 } 2907rx_stop: 2908 sc->sc_rxnext = bf; 2909 2910 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && 2911 !IFQ_IS_EMPTY(&ifp->if_snd)) { 2912 /* NB: kick fw; the tx thread may have been preempted */ 2913 mwl_hal_txstart(sc->sc_mh, 0); 2914 mwl_start(ifp); 2915 } 2916#undef IEEE80211_DIR_DSTODS 2917} 2918 2919static void 2920mwl_txq_init(struct mwl_softc *sc, struct mwl_txq *txq, int qnum) 2921{ 2922 struct mwl_txbuf *bf, *bn; 2923 struct mwl_txdesc *ds; 2924 2925 MWL_TXQ_LOCK_INIT(sc, txq); 2926 txq->qnum = qnum; 2927 txq->txpri = 0; /* XXX */ 2928#if 0 2929 /* NB: q setup by mwl_txdma_setup XXX */ 2930 STAILQ_INIT(&txq->free); 2931#endif 2932 STAILQ_FOREACH(bf, &txq->free, bf_list) { 2933 bf->bf_txq = txq; 2934 2935 ds = bf->bf_desc; 2936 bn = STAILQ_NEXT(bf, bf_list); 2937 if (bn == NULL) 2938 bn = STAILQ_FIRST(&txq->free); 2939 ds->pPhysNext = htole32(bn->bf_daddr); 2940 } 2941 STAILQ_INIT(&txq->active); 2942} 2943 2944/* 2945 * Setup a hardware data transmit queue for the specified 2946 * access control. We record the mapping from ac's 2947 * to h/w queues for use by mwl_tx_start. 2948 */ 2949static int 2950mwl_tx_setup(struct mwl_softc *sc, int ac, int mvtype) 2951{ 2952#define N(a) (sizeof(a)/sizeof(a[0])) 2953 struct mwl_txq *txq; 2954 2955 if (ac >= N(sc->sc_ac2q)) { 2956 device_printf(sc->sc_dev, "AC %u out of range, max %zu!\n", 2957 ac, N(sc->sc_ac2q)); 2958 return 0; 2959 } 2960 if (mvtype >= MWL_NUM_TX_QUEUES) { 2961 device_printf(sc->sc_dev, "mvtype %u out of range, max %u!\n", 2962 mvtype, MWL_NUM_TX_QUEUES); 2963 return 0; 2964 } 2965 txq = &sc->sc_txq[mvtype]; 2966 mwl_txq_init(sc, txq, mvtype); 2967 sc->sc_ac2q[ac] = txq; 2968 return 1; 2969#undef N 2970} 2971 2972/* 2973 * Update WME parameters for a transmit queue. 2974 */ 2975static int 2976mwl_txq_update(struct mwl_softc *sc, int ac) 2977{ 2978#define MWL_EXPONENT_TO_VALUE(v) ((1<<v)-1) 2979 struct ifnet *ifp = sc->sc_ifp; 2980 struct ieee80211com *ic = ifp->if_l2com; 2981 struct mwl_txq *txq = sc->sc_ac2q[ac]; 2982 struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; 2983 struct mwl_hal *mh = sc->sc_mh; 2984 int aifs, cwmin, cwmax, txoplim; 2985 2986 aifs = wmep->wmep_aifsn; 2987 /* XXX in sta mode need to pass log values for cwmin/max */ 2988 cwmin = MWL_EXPONENT_TO_VALUE(wmep->wmep_logcwmin); 2989 cwmax = MWL_EXPONENT_TO_VALUE(wmep->wmep_logcwmax); 2990 txoplim = wmep->wmep_txopLimit; /* NB: units of 32us */ 2991 2992 if (mwl_hal_setedcaparams(mh, txq->qnum, cwmin, cwmax, aifs, txoplim)) { 2993 device_printf(sc->sc_dev, "unable to update hardware queue " 2994 "parameters for %s traffic!\n", 2995 ieee80211_wme_acnames[ac]); 2996 return 0; 2997 } 2998 return 1; 2999#undef MWL_EXPONENT_TO_VALUE 3000} 3001 3002/* 3003 * Callback from the 802.11 layer to update WME parameters. 3004 */ 3005static int 3006mwl_wme_update(struct ieee80211com *ic) 3007{ 3008 struct mwl_softc *sc = ic->ic_ifp->if_softc; 3009 3010 return !mwl_txq_update(sc, WME_AC_BE) || 3011 !mwl_txq_update(sc, WME_AC_BK) || 3012 !mwl_txq_update(sc, WME_AC_VI) || 3013 !mwl_txq_update(sc, WME_AC_VO) ? EIO : 0; 3014} 3015 3016/* 3017 * Reclaim resources for a setup queue. 3018 */ 3019static void 3020mwl_tx_cleanupq(struct mwl_softc *sc, struct mwl_txq *txq) 3021{ 3022 /* XXX hal work? */ 3023 MWL_TXQ_LOCK_DESTROY(txq); 3024} 3025 3026/* 3027 * Reclaim all tx queue resources. 3028 */ 3029static void 3030mwl_tx_cleanup(struct mwl_softc *sc) 3031{ 3032 int i; 3033 3034 for (i = 0; i < MWL_NUM_TX_QUEUES; i++) 3035 mwl_tx_cleanupq(sc, &sc->sc_txq[i]); 3036} 3037 3038static int 3039mwl_tx_dmasetup(struct mwl_softc *sc, struct mwl_txbuf *bf, struct mbuf *m0) 3040{ 3041 struct mbuf *m; 3042 int error; 3043 3044 /* 3045 * Load the DMA map so any coalescing is done. This 3046 * also calculates the number of descriptors we need. 3047 */ 3048 error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m0, 3049 bf->bf_segs, &bf->bf_nseg, 3050 BUS_DMA_NOWAIT); 3051 if (error == EFBIG) { 3052 /* XXX packet requires too many descriptors */ 3053 bf->bf_nseg = MWL_TXDESC+1; 3054 } else if (error != 0) { 3055 sc->sc_stats.mst_tx_busdma++; 3056 m_freem(m0); 3057 return error; 3058 } 3059 /* 3060 * Discard null packets and check for packets that 3061 * require too many TX descriptors. We try to convert 3062 * the latter to a cluster. 3063 */ 3064 if (error == EFBIG) { /* too many desc's, linearize */ 3065 sc->sc_stats.mst_tx_linear++; 3066#if MWL_TXDESC > 1 3067 m = m_collapse(m0, M_DONTWAIT, MWL_TXDESC); 3068#else 3069 m = m_defrag(m0, M_DONTWAIT); 3070#endif 3071 if (m == NULL) { 3072 m_freem(m0); 3073 sc->sc_stats.mst_tx_nombuf++; 3074 return ENOMEM; 3075 } 3076 m0 = m; 3077 error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m0, 3078 bf->bf_segs, &bf->bf_nseg, 3079 BUS_DMA_NOWAIT); 3080 if (error != 0) { 3081 sc->sc_stats.mst_tx_busdma++; 3082 m_freem(m0); 3083 return error; 3084 } 3085 KASSERT(bf->bf_nseg <= MWL_TXDESC, 3086 ("too many segments after defrag; nseg %u", bf->bf_nseg)); 3087 } else if (bf->bf_nseg == 0) { /* null packet, discard */ 3088 sc->sc_stats.mst_tx_nodata++; 3089 m_freem(m0); 3090 return EIO; 3091 } 3092 DPRINTF(sc, MWL_DEBUG_XMIT, "%s: m %p len %u\n", 3093 __func__, m0, m0->m_pkthdr.len); 3094 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE); 3095 bf->bf_m = m0; 3096 3097 return 0; 3098} 3099 3100static __inline int 3101mwl_cvtlegacyrate(int rate) 3102{ 3103 switch (rate) { 3104 case 2: return 0; 3105 case 4: return 1; 3106 case 11: return 2; 3107 case 22: return 3; 3108 case 44: return 4; 3109 case 12: return 5; 3110 case 18: return 6; 3111 case 24: return 7; 3112 case 36: return 8; 3113 case 48: return 9; 3114 case 72: return 10; 3115 case 96: return 11; 3116 case 108:return 12; 3117 } 3118 return 0; 3119} 3120 3121/* 3122 * Calculate fixed tx rate information per client state; 3123 * this value is suitable for writing to the Format field 3124 * of a tx descriptor. 3125 */ 3126static uint16_t 3127mwl_calcformat(uint8_t rate, const struct ieee80211_node *ni) 3128{ 3129 uint16_t fmt; 3130 3131 fmt = SM(3, EAGLE_TXD_ANTENNA) 3132 | (IEEE80211_IS_CHAN_HT40D(ni->ni_chan) ? 3133 EAGLE_TXD_EXTCHAN_LO : EAGLE_TXD_EXTCHAN_HI); 3134 if (rate & IEEE80211_RATE_MCS) { /* HT MCS */ 3135 fmt |= EAGLE_TXD_FORMAT_HT 3136 /* NB: 0x80 implicitly stripped from ucastrate */ 3137 | SM(rate, EAGLE_TXD_RATE); 3138 /* XXX short/long GI may be wrong; re-check */ 3139 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) { 3140 fmt |= EAGLE_TXD_CHW_40 3141 | (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40 ? 3142 EAGLE_TXD_GI_SHORT : EAGLE_TXD_GI_LONG); 3143 } else { 3144 fmt |= EAGLE_TXD_CHW_20 3145 | (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20 ? 3146 EAGLE_TXD_GI_SHORT : EAGLE_TXD_GI_LONG); 3147 } 3148 } else { /* legacy rate */ 3149 fmt |= EAGLE_TXD_FORMAT_LEGACY 3150 | SM(mwl_cvtlegacyrate(rate), EAGLE_TXD_RATE) 3151 | EAGLE_TXD_CHW_20 3152 /* XXX iv_flags & IEEE80211_F_SHPREAMBLE? */ 3153 | (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE ? 3154 EAGLE_TXD_PREAMBLE_SHORT : EAGLE_TXD_PREAMBLE_LONG); 3155 } 3156 return fmt; 3157} 3158 3159static int 3160mwl_tx_start(struct mwl_softc *sc, struct ieee80211_node *ni, struct mwl_txbuf *bf, 3161 struct mbuf *m0) 3162{ 3163#define IEEE80211_DIR_DSTODS(wh) \ 3164 ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 3165 struct ifnet *ifp = sc->sc_ifp; 3166 struct ieee80211com *ic = ifp->if_l2com; 3167 struct ieee80211vap *vap = ni->ni_vap; 3168 int error, iswep, ismcast; 3169 int hdrlen, copyhdrlen, pktlen; 3170 struct mwl_txdesc *ds; 3171 struct mwl_txq *txq; 3172 struct ieee80211_frame *wh; 3173 struct mwltxrec *tr; 3174 struct mwl_node *mn; 3175 uint16_t qos; 3176#if MWL_TXDESC > 1 3177 int i; 3178#endif 3179 3180 wh = mtod(m0, struct ieee80211_frame *); 3181 iswep = wh->i_fc[1] & IEEE80211_FC1_WEP; 3182 ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); 3183 hdrlen = ieee80211_anyhdrsize(wh); 3184 copyhdrlen = hdrlen; 3185 pktlen = m0->m_pkthdr.len; 3186 if (IEEE80211_QOS_HAS_SEQ(wh)) { 3187 if (IEEE80211_DIR_DSTODS(wh)) { 3188 qos = *(uint16_t *) 3189 (((struct ieee80211_qosframe_addr4 *) wh)->i_qos); 3190 copyhdrlen -= sizeof(qos); 3191 } else 3192 qos = *(uint16_t *) 3193 (((struct ieee80211_qosframe *) wh)->i_qos); 3194 } else 3195 qos = 0; 3196 3197 if (iswep) { 3198 const struct ieee80211_cipher *cip; 3199 struct ieee80211_key *k; 3200 3201 /* 3202 * Construct the 802.11 header+trailer for an encrypted 3203 * frame. The only reason this can fail is because of an 3204 * unknown or unsupported cipher/key type. 3205 * 3206 * NB: we do this even though the firmware will ignore 3207 * what we've done for WEP and TKIP as we need the 3208 * ExtIV filled in for CCMP and this also adjusts 3209 * the headers which simplifies our work below. 3210 */ 3211 k = ieee80211_crypto_encap(ni, m0); 3212 if (k == NULL) { 3213 /* 3214 * This can happen when the key is yanked after the 3215 * frame was queued. Just discard the frame; the 3216 * 802.11 layer counts failures and provides 3217 * debugging/diagnostics. 3218 */ 3219 m_freem(m0); 3220 return EIO; 3221 } 3222 /* 3223 * Adjust the packet length for the crypto additions 3224 * done during encap and any other bits that the f/w 3225 * will add later on. 3226 */ 3227 cip = k->wk_cipher; 3228 pktlen += cip->ic_header + cip->ic_miclen + cip->ic_trailer; 3229 3230 /* packet header may have moved, reset our local pointer */ 3231 wh = mtod(m0, struct ieee80211_frame *); 3232 } 3233 3234 if (ieee80211_radiotap_active_vap(vap)) { 3235 sc->sc_tx_th.wt_flags = 0; /* XXX */ 3236 if (iswep) 3237 sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; 3238#if 0 3239 sc->sc_tx_th.wt_rate = ds->DataRate; 3240#endif 3241 sc->sc_tx_th.wt_txpower = ni->ni_txpower; 3242 sc->sc_tx_th.wt_antenna = sc->sc_txantenna; 3243 3244 ieee80211_radiotap_tx(vap, m0); 3245 } 3246 /* 3247 * Copy up/down the 802.11 header; the firmware requires 3248 * we present a 2-byte payload length followed by a 3249 * 4-address header (w/o QoS), followed (optionally) by 3250 * any WEP/ExtIV header (but only filled in for CCMP). 3251 * We are assured the mbuf has sufficient headroom to 3252 * prepend in-place by the setup of ic_headroom in 3253 * mwl_attach. 3254 */ 3255 if (hdrlen < sizeof(struct mwltxrec)) { 3256 const int space = sizeof(struct mwltxrec) - hdrlen; 3257 if (M_LEADINGSPACE(m0) < space) { 3258 /* NB: should never happen */ 3259 device_printf(sc->sc_dev, 3260 "not enough headroom, need %d found %zd, " 3261 "m_flags 0x%x m_len %d\n", 3262 space, M_LEADINGSPACE(m0), m0->m_flags, m0->m_len); 3263 ieee80211_dump_pkt(ic, 3264 mtod(m0, const uint8_t *), m0->m_len, 0, -1); 3265 m_freem(m0); 3266 sc->sc_stats.mst_tx_noheadroom++; 3267 return EIO; 3268 } 3269 M_PREPEND(m0, space, M_NOWAIT); 3270 } 3271 tr = mtod(m0, struct mwltxrec *); 3272 if (wh != (struct ieee80211_frame *) &tr->wh) 3273 ovbcopy(wh, &tr->wh, hdrlen); 3274 /* 3275 * Note: the "firmware length" is actually the length 3276 * of the fully formed "802.11 payload". That is, it's 3277 * everything except for the 802.11 header. In particular 3278 * this includes all crypto material including the MIC! 3279 */ 3280 tr->fwlen = htole16(pktlen - hdrlen); 3281 3282 /* 3283 * Load the DMA map so any coalescing is done. This 3284 * also calculates the number of descriptors we need. 3285 */ 3286 error = mwl_tx_dmasetup(sc, bf, m0); 3287 if (error != 0) { 3288 /* NB: stat collected in mwl_tx_dmasetup */ 3289 DPRINTF(sc, MWL_DEBUG_XMIT, 3290 "%s: unable to setup dma\n", __func__); 3291 return error; 3292 } 3293 bf->bf_node = ni; /* NB: held reference */ 3294 m0 = bf->bf_m; /* NB: may have changed */ 3295 tr = mtod(m0, struct mwltxrec *); 3296 wh = (struct ieee80211_frame *)&tr->wh; 3297 3298 /* 3299 * Formulate tx descriptor. 3300 */ 3301 ds = bf->bf_desc; 3302 txq = bf->bf_txq; 3303 3304 ds->QosCtrl = qos; /* NB: already little-endian */ 3305#if MWL_TXDESC == 1 3306 /* 3307 * NB: multiframes should be zero because the descriptors 3308 * are initialized to zero. This should handle the case 3309 * where the driver is built with MWL_TXDESC=1 but we are 3310 * using firmware with multi-segment support. 3311 */ 3312 ds->PktPtr = htole32(bf->bf_segs[0].ds_addr); 3313 ds->PktLen = htole16(bf->bf_segs[0].ds_len); 3314#else 3315 ds->multiframes = htole32(bf->bf_nseg); 3316 ds->PktLen = htole16(m0->m_pkthdr.len); 3317 for (i = 0; i < bf->bf_nseg; i++) { 3318 ds->PktPtrArray[i] = htole32(bf->bf_segs[i].ds_addr); 3319 ds->PktLenArray[i] = htole16(bf->bf_segs[i].ds_len); 3320 } 3321#endif 3322 /* NB: pPhysNext, DataRate, and SapPktInfo setup once, don't touch */ 3323 ds->Format = 0; 3324 ds->pad = 0; 3325 ds->ack_wcb_addr = 0; 3326 3327 mn = MWL_NODE(ni); 3328 /* 3329 * Select transmit rate. 3330 */ 3331 switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) { 3332 case IEEE80211_FC0_TYPE_MGT: 3333 sc->sc_stats.mst_tx_mgmt++; 3334 /* fall thru... */ 3335 case IEEE80211_FC0_TYPE_CTL: 3336 /* NB: assign to BE q to avoid bursting */ 3337 ds->TxPriority = MWL_WME_AC_BE; 3338 break; 3339 case IEEE80211_FC0_TYPE_DATA: 3340 if (!ismcast) { 3341 const struct ieee80211_txparam *tp = ni->ni_txparms; 3342 /* 3343 * EAPOL frames get forced to a fixed rate and w/o 3344 * aggregation; otherwise check for any fixed rate 3345 * for the client (may depend on association state). 3346 */ 3347 if (m0->m_flags & M_EAPOL) { 3348 const struct mwl_vap *mvp = MWL_VAP_CONST(vap); 3349 ds->Format = mvp->mv_eapolformat; 3350 ds->pad = htole16( 3351 EAGLE_TXD_FIXED_RATE | EAGLE_TXD_DONT_AGGR); 3352 } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { 3353 /* XXX pre-calculate per node */ 3354 ds->Format = htole16( 3355 mwl_calcformat(tp->ucastrate, ni)); 3356 ds->pad = htole16(EAGLE_TXD_FIXED_RATE); 3357 } 3358 /* NB: EAPOL frames will never have qos set */ 3359 if (qos == 0) 3360 ds->TxPriority = txq->qnum; 3361#if MWL_MAXBA > 3 3362 else if (mwl_bastream_match(&mn->mn_ba[3], qos)) 3363 ds->TxPriority = mn->mn_ba[3].txq; 3364#endif 3365#if MWL_MAXBA > 2 3366 else if (mwl_bastream_match(&mn->mn_ba[2], qos)) 3367 ds->TxPriority = mn->mn_ba[2].txq; 3368#endif 3369#if MWL_MAXBA > 1 3370 else if (mwl_bastream_match(&mn->mn_ba[1], qos)) 3371 ds->TxPriority = mn->mn_ba[1].txq; 3372#endif 3373#if MWL_MAXBA > 0 3374 else if (mwl_bastream_match(&mn->mn_ba[0], qos)) 3375 ds->TxPriority = mn->mn_ba[0].txq; 3376#endif 3377 else 3378 ds->TxPriority = txq->qnum; 3379 } else 3380 ds->TxPriority = txq->qnum; 3381 break; 3382 default: 3383 if_printf(ifp, "bogus frame type 0x%x (%s)\n", 3384 wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__); 3385 sc->sc_stats.mst_tx_badframetype++; 3386 m_freem(m0); 3387 return EIO; 3388 } 3389 3390 if (IFF_DUMPPKTS_XMIT(sc)) 3391 ieee80211_dump_pkt(ic, 3392 mtod(m0, const uint8_t *)+sizeof(uint16_t), 3393 m0->m_len - sizeof(uint16_t), ds->DataRate, -1); 3394 3395 MWL_TXQ_LOCK(txq); 3396 ds->Status = htole32(EAGLE_TXD_STATUS_FW_OWNED); 3397 STAILQ_INSERT_TAIL(&txq->active, bf, bf_list); 3398 MWL_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3399 3400 ifp->if_opackets++; 3401 ifp->if_timer = 5; 3402 MWL_TXQ_UNLOCK(txq); 3403 3404 return 0; 3405#undef IEEE80211_DIR_DSTODS 3406} 3407 3408static __inline int 3409mwl_cvtlegacyrix(int rix) 3410{ 3411#define N(x) (sizeof(x)/sizeof(x[0])) 3412 static const int ieeerates[] = 3413 { 2, 4, 11, 22, 44, 12, 18, 24, 36, 48, 72, 96, 108 }; 3414 return (rix < N(ieeerates) ? ieeerates[rix] : 0); 3415#undef N 3416} 3417 3418/* 3419 * Process completed xmit descriptors from the specified queue. 3420 */ 3421static int 3422mwl_tx_processq(struct mwl_softc *sc, struct mwl_txq *txq) 3423{ 3424#define EAGLE_TXD_STATUS_MCAST \ 3425 (EAGLE_TXD_STATUS_MULTICAST_TX | EAGLE_TXD_STATUS_BROADCAST_TX) 3426 struct ifnet *ifp = sc->sc_ifp; 3427 struct ieee80211com *ic = ifp->if_l2com; 3428 struct mwl_txbuf *bf; 3429 struct mwl_txdesc *ds; 3430 struct ieee80211_node *ni; 3431 struct mwl_node *an; 3432 int nreaped; 3433 uint32_t status; 3434 3435 DPRINTF(sc, MWL_DEBUG_TX_PROC, "%s: tx queue %u\n", __func__, txq->qnum); 3436 for (nreaped = 0;; nreaped++) { 3437 MWL_TXQ_LOCK(txq); 3438 bf = STAILQ_FIRST(&txq->active); 3439 if (bf == NULL) { 3440 MWL_TXQ_UNLOCK(txq); 3441 break; 3442 } 3443 ds = bf->bf_desc; 3444 MWL_TXDESC_SYNC(txq, ds, 3445 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 3446 if (ds->Status & htole32(EAGLE_TXD_STATUS_FW_OWNED)) { 3447 MWL_TXQ_UNLOCK(txq); 3448 break; 3449 } 3450 STAILQ_REMOVE_HEAD(&txq->active, bf_list); 3451 MWL_TXQ_UNLOCK(txq); 3452 3453#ifdef MWL_DEBUG 3454 if (sc->sc_debug & MWL_DEBUG_XMIT_DESC) 3455 mwl_printtxbuf(bf, txq->qnum, nreaped); 3456#endif 3457 ni = bf->bf_node; 3458 if (ni != NULL) { 3459 an = MWL_NODE(ni); 3460 status = le32toh(ds->Status); 3461 if (status & EAGLE_TXD_STATUS_OK) { 3462 uint16_t Format = le16toh(ds->Format); 3463 uint8_t txant = MS(Format, EAGLE_TXD_ANTENNA); 3464 3465 sc->sc_stats.mst_ant_tx[txant]++; 3466 if (status & EAGLE_TXD_STATUS_OK_RETRY) 3467 sc->sc_stats.mst_tx_retries++; 3468 if (status & EAGLE_TXD_STATUS_OK_MORE_RETRY) 3469 sc->sc_stats.mst_tx_mretries++; 3470 if (txq->qnum >= MWL_WME_AC_VO) 3471 ic->ic_wme.wme_hipri_traffic++; 3472 ni->ni_txrate = MS(Format, EAGLE_TXD_RATE); 3473 if ((Format & EAGLE_TXD_FORMAT_HT) == 0) { 3474 ni->ni_txrate = mwl_cvtlegacyrix( 3475 ni->ni_txrate); 3476 } else 3477 ni->ni_txrate |= IEEE80211_RATE_MCS; 3478 sc->sc_stats.mst_tx_rate = ni->ni_txrate; 3479 } else { 3480 if (status & EAGLE_TXD_STATUS_FAILED_LINK_ERROR) 3481 sc->sc_stats.mst_tx_linkerror++; 3482 if (status & EAGLE_TXD_STATUS_FAILED_XRETRY) 3483 sc->sc_stats.mst_tx_xretries++; 3484 if (status & EAGLE_TXD_STATUS_FAILED_AGING) 3485 sc->sc_stats.mst_tx_aging++; 3486 if (bf->bf_m->m_flags & M_FF) 3487 sc->sc_stats.mst_ff_txerr++; 3488 } 3489 /* 3490 * Do any tx complete callback. Note this must 3491 * be done before releasing the node reference. 3492 * XXX no way to figure out if frame was ACK'd 3493 */ 3494 if (bf->bf_m->m_flags & M_TXCB) { 3495 /* XXX strip fw len in case header inspected */ 3496 m_adj(bf->bf_m, sizeof(uint16_t)); 3497 ieee80211_process_callback(ni, bf->bf_m, 3498 (status & EAGLE_TXD_STATUS_OK) == 0); 3499 } 3500 /* 3501 * Reclaim reference to node. 3502 * 3503 * NB: the node may be reclaimed here if, for example 3504 * this is a DEAUTH message that was sent and the 3505 * node was timed out due to inactivity. 3506 */ 3507 ieee80211_free_node(ni); 3508 } 3509 ds->Status = htole32(EAGLE_TXD_STATUS_IDLE); 3510 3511 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 3512 BUS_DMASYNC_POSTWRITE); 3513 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); 3514 m_freem(bf->bf_m); 3515 3516 mwl_puttxbuf_tail(txq, bf); 3517 } 3518 return nreaped; 3519#undef EAGLE_TXD_STATUS_MCAST 3520} 3521 3522/* 3523 * Deferred processing of transmit interrupt; special-cased 3524 * for four hardware queues, 0-3. 3525 */ 3526static void 3527mwl_tx_proc(void *arg, int npending) 3528{ 3529 struct mwl_softc *sc = arg; 3530 struct ifnet *ifp = sc->sc_ifp; 3531 int nreaped; 3532 3533 /* 3534 * Process each active queue. 3535 */ 3536 nreaped = 0; 3537 if (!STAILQ_EMPTY(&sc->sc_txq[0].active)) 3538 nreaped += mwl_tx_processq(sc, &sc->sc_txq[0]); 3539 if (!STAILQ_EMPTY(&sc->sc_txq[1].active)) 3540 nreaped += mwl_tx_processq(sc, &sc->sc_txq[1]); 3541 if (!STAILQ_EMPTY(&sc->sc_txq[2].active)) 3542 nreaped += mwl_tx_processq(sc, &sc->sc_txq[2]); 3543 if (!STAILQ_EMPTY(&sc->sc_txq[3].active)) 3544 nreaped += mwl_tx_processq(sc, &sc->sc_txq[3]); 3545 3546 if (nreaped != 0) { 3547 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3548 ifp->if_timer = 0; 3549 if (!IFQ_IS_EMPTY(&ifp->if_snd)) { 3550 /* NB: kick fw; the tx thread may have been preempted */ 3551 mwl_hal_txstart(sc->sc_mh, 0); 3552 mwl_start(ifp); 3553 } 3554 } 3555} 3556 3557static void 3558mwl_tx_draintxq(struct mwl_softc *sc, struct mwl_txq *txq) 3559{ 3560 struct ieee80211_node *ni; 3561 struct mwl_txbuf *bf; 3562 u_int ix; 3563 3564 /* 3565 * NB: this assumes output has been stopped and 3566 * we do not need to block mwl_tx_tasklet 3567 */ 3568 for (ix = 0;; ix++) { 3569 MWL_TXQ_LOCK(txq); 3570 bf = STAILQ_FIRST(&txq->active); 3571 if (bf == NULL) { 3572 MWL_TXQ_UNLOCK(txq); 3573 break; 3574 } 3575 STAILQ_REMOVE_HEAD(&txq->active, bf_list); 3576 MWL_TXQ_UNLOCK(txq); 3577#ifdef MWL_DEBUG 3578 if (sc->sc_debug & MWL_DEBUG_RESET) { 3579 struct ifnet *ifp = sc->sc_ifp; 3580 struct ieee80211com *ic = ifp->if_l2com; 3581 const struct mwltxrec *tr = 3582 mtod(bf->bf_m, const struct mwltxrec *); 3583 mwl_printtxbuf(bf, txq->qnum, ix); 3584 ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh, 3585 bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1); 3586 } 3587#endif /* MWL_DEBUG */ 3588 bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); 3589 ni = bf->bf_node; 3590 if (ni != NULL) { 3591 /* 3592 * Reclaim node reference. 3593 */ 3594 ieee80211_free_node(ni); 3595 } 3596 m_freem(bf->bf_m); 3597 3598 mwl_puttxbuf_tail(txq, bf); 3599 } 3600} 3601 3602/* 3603 * Drain the transmit queues and reclaim resources. 3604 */ 3605static void 3606mwl_draintxq(struct mwl_softc *sc) 3607{ 3608 struct ifnet *ifp = sc->sc_ifp; 3609 int i; 3610 3611 for (i = 0; i < MWL_NUM_TX_QUEUES; i++) 3612 mwl_tx_draintxq(sc, &sc->sc_txq[i]); 3613 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 3614 ifp->if_timer = 0; 3615} 3616 3617#ifdef MWL_DIAGAPI 3618/* 3619 * Reset the transmit queues to a pristine state after a fw download. 3620 */ 3621static void 3622mwl_resettxq(struct mwl_softc *sc) 3623{ 3624 int i; 3625 3626 for (i = 0; i < MWL_NUM_TX_QUEUES; i++) 3627 mwl_txq_reset(sc, &sc->sc_txq[i]); 3628} 3629#endif /* MWL_DIAGAPI */ 3630 3631/* 3632 * Clear the transmit queues of any frames submitted for the 3633 * specified vap. This is done when the vap is deleted so we 3634 * don't potentially reference the vap after it is gone. 3635 * Note we cannot remove the frames; we only reclaim the node 3636 * reference. 3637 */ 3638static void 3639mwl_cleartxq(struct mwl_softc *sc, struct ieee80211vap *vap) 3640{ 3641 struct mwl_txq *txq; 3642 struct mwl_txbuf *bf; 3643 int i; 3644 3645 for (i = 0; i < MWL_NUM_TX_QUEUES; i++) { 3646 txq = &sc->sc_txq[i]; 3647 MWL_TXQ_LOCK(txq); 3648 STAILQ_FOREACH(bf, &txq->active, bf_list) { 3649 struct ieee80211_node *ni = bf->bf_node; 3650 if (ni != NULL && ni->ni_vap == vap) { 3651 bf->bf_node = NULL; 3652 ieee80211_free_node(ni); 3653 } 3654 } 3655 MWL_TXQ_UNLOCK(txq); 3656 } 3657} 3658 3659static void 3660mwl_recv_action(struct ieee80211_node *ni, const uint8_t *frm, const uint8_t *efrm) 3661{ 3662 struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; 3663 const struct ieee80211_action *ia; 3664 3665 ia = (const struct ieee80211_action *) frm; 3666 if (ia->ia_category == IEEE80211_ACTION_CAT_HT && 3667 ia->ia_action == IEEE80211_ACTION_HT_MIMOPWRSAVE) { 3668 const struct ieee80211_action_ht_mimopowersave *mps = 3669 (const struct ieee80211_action_ht_mimopowersave *) ia; 3670 3671 mwl_hal_setmimops(sc->sc_mh, ni->ni_macaddr, 3672 mps->am_control & IEEE80211_A_HT_MIMOPWRSAVE_ENA, 3673 MS(mps->am_control, IEEE80211_A_HT_MIMOPWRSAVE_MODE)); 3674 } else 3675 sc->sc_recv_action(ni, frm, efrm); 3676} 3677 3678static int 3679mwl_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, 3680 int dialogtoken, int baparamset, int batimeout) 3681{ 3682 struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; 3683 struct ieee80211vap *vap = ni->ni_vap; 3684 struct mwl_node *mn = MWL_NODE(ni); 3685 struct mwl_bastate *bas; 3686 3687 bas = tap->txa_private; 3688 if (bas == NULL) { 3689 const MWL_HAL_BASTREAM *sp; 3690 /* 3691 * Check for a free BA stream slot. 3692 */ 3693#if MWL_MAXBA > 3 3694 if (mn->mn_ba[3].bastream == NULL) 3695 bas = &mn->mn_ba[3]; 3696 else 3697#endif 3698#if MWL_MAXBA > 2 3699 if (mn->mn_ba[2].bastream == NULL) 3700 bas = &mn->mn_ba[2]; 3701 else 3702#endif 3703#if MWL_MAXBA > 1 3704 if (mn->mn_ba[1].bastream == NULL) 3705 bas = &mn->mn_ba[1]; 3706 else 3707#endif 3708#if MWL_MAXBA > 0 3709 if (mn->mn_ba[0].bastream == NULL) 3710 bas = &mn->mn_ba[0]; 3711 else 3712#endif 3713 { 3714 /* sta already has max BA streams */ 3715 /* XXX assign BA stream to highest priority tid */ 3716 DPRINTF(sc, MWL_DEBUG_AMPDU, 3717 "%s: already has max bastreams\n", __func__); 3718 sc->sc_stats.mst_ampdu_reject++; 3719 return 0; 3720 } 3721 /* NB: no held reference to ni */ 3722 sp = mwl_hal_bastream_alloc(MWL_VAP(vap)->mv_hvap, 3723 (baparamset & IEEE80211_BAPS_POLICY_IMMEDIATE) != 0, 3724 ni->ni_macaddr, WME_AC_TO_TID(tap->txa_ac), ni->ni_htparam, 3725 ni, tap); 3726 if (sp == NULL) { 3727 /* 3728 * No available stream, return 0 so no 3729 * a-mpdu aggregation will be done. 3730 */ 3731 DPRINTF(sc, MWL_DEBUG_AMPDU, 3732 "%s: no bastream available\n", __func__); 3733 sc->sc_stats.mst_ampdu_nostream++; 3734 return 0; 3735 } 3736 DPRINTF(sc, MWL_DEBUG_AMPDU, "%s: alloc bastream %p\n", 3737 __func__, sp); 3738 /* NB: qos is left zero so we won't match in mwl_tx_start */ 3739 bas->bastream = sp; 3740 tap->txa_private = bas; 3741 } 3742 /* fetch current seq# from the firmware; if available */ 3743 if (mwl_hal_bastream_get_seqno(sc->sc_mh, bas->bastream, 3744 vap->iv_opmode == IEEE80211_M_STA ? vap->iv_myaddr : ni->ni_macaddr, 3745 &tap->txa_start) != 0) 3746 tap->txa_start = 0; 3747 return sc->sc_addba_request(ni, tap, dialogtoken, baparamset, batimeout); 3748} 3749 3750static int 3751mwl_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, 3752 int code, int baparamset, int batimeout) 3753{ 3754 struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; 3755 struct mwl_bastate *bas; 3756 3757 bas = tap->txa_private; 3758 if (bas == NULL) { 3759 /* XXX should not happen */ 3760 DPRINTF(sc, MWL_DEBUG_AMPDU, 3761 "%s: no BA stream allocated, AC %d\n", 3762 __func__, tap->txa_ac); 3763 sc->sc_stats.mst_addba_nostream++; 3764 return 0; 3765 } 3766 if (code == IEEE80211_STATUS_SUCCESS) { 3767 struct ieee80211vap *vap = ni->ni_vap; 3768 int bufsiz, error; 3769 3770 /* 3771 * Tell the firmware to setup the BA stream; 3772 * we know resources are available because we 3773 * pre-allocated one before forming the request. 3774 */ 3775 bufsiz = MS(baparamset, IEEE80211_BAPS_BUFSIZ); 3776 if (bufsiz == 0) 3777 bufsiz = IEEE80211_AGGR_BAWMAX; 3778 error = mwl_hal_bastream_create(MWL_VAP(vap)->mv_hvap, 3779 bas->bastream, bufsiz, bufsiz, tap->txa_start); 3780 if (error != 0) { 3781 /* 3782 * Setup failed, return immediately so no a-mpdu 3783 * aggregation will be done. 3784 */ 3785 mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream); 3786 mwl_bastream_free(bas); 3787 tap->txa_private = NULL; 3788 3789 DPRINTF(sc, MWL_DEBUG_AMPDU, 3790 "%s: create failed, error %d, bufsiz %d AC %d " 3791 "htparam 0x%x\n", __func__, error, bufsiz, 3792 tap->txa_ac, ni->ni_htparam); 3793 sc->sc_stats.mst_bacreate_failed++; 3794 return 0; 3795 } 3796 /* NB: cache txq to avoid ptr indirect */ 3797 mwl_bastream_setup(bas, tap->txa_ac, bas->bastream->txq); 3798 DPRINTF(sc, MWL_DEBUG_AMPDU, 3799 "%s: bastream %p assigned to txq %d AC %d bufsiz %d " 3800 "htparam 0x%x\n", __func__, bas->bastream, 3801 bas->txq, tap->txa_ac, bufsiz, ni->ni_htparam); 3802 } else { 3803 /* 3804 * Other side NAK'd us; return the resources. 3805 */ 3806 DPRINTF(sc, MWL_DEBUG_AMPDU, 3807 "%s: request failed with code %d, destroy bastream %p\n", 3808 __func__, code, bas->bastream); 3809 mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream); 3810 mwl_bastream_free(bas); 3811 tap->txa_private = NULL; 3812 } 3813 /* NB: firmware sends BAR so we don't need to */ 3814 return sc->sc_addba_response(ni, tap, code, baparamset, batimeout); 3815} 3816 3817static void 3818mwl_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap) 3819{ 3820 struct mwl_softc *sc = ni->ni_ic->ic_ifp->if_softc; 3821 struct mwl_bastate *bas; 3822 3823 bas = tap->txa_private; 3824 if (bas != NULL) { 3825 DPRINTF(sc, MWL_DEBUG_AMPDU, "%s: destroy bastream %p\n", 3826 __func__, bas->bastream); 3827 mwl_hal_bastream_destroy(sc->sc_mh, bas->bastream); 3828 mwl_bastream_free(bas); 3829 tap->txa_private = NULL; 3830 } 3831 sc->sc_addba_stop(ni, tap); 3832} 3833 3834/* 3835 * Setup the rx data structures. This should only be 3836 * done once or we may get out of sync with the firmware. 3837 */ 3838static int 3839mwl_startrecv(struct mwl_softc *sc) 3840{ 3841 if (!sc->sc_recvsetup) { 3842 struct mwl_rxbuf *bf, *prev; 3843 struct mwl_rxdesc *ds; 3844 3845 prev = NULL; 3846 STAILQ_FOREACH(bf, &sc->sc_rxbuf, bf_list) { 3847 int error = mwl_rxbuf_init(sc, bf); 3848 if (error != 0) { 3849 DPRINTF(sc, MWL_DEBUG_RECV, 3850 "%s: mwl_rxbuf_init failed %d\n", 3851 __func__, error); 3852 return error; 3853 } 3854 if (prev != NULL) { 3855 ds = prev->bf_desc; 3856 ds->pPhysNext = htole32(bf->bf_daddr); 3857 } 3858 prev = bf; 3859 } 3860 if (prev != NULL) { 3861 ds = prev->bf_desc; 3862 ds->pPhysNext = 3863 htole32(STAILQ_FIRST(&sc->sc_rxbuf)->bf_daddr); 3864 } 3865 sc->sc_recvsetup = 1; 3866 } 3867 mwl_mode_init(sc); /* set filters, etc. */ 3868 return 0; 3869} 3870 3871static MWL_HAL_APMODE 3872mwl_getapmode(const struct ieee80211vap *vap, struct ieee80211_channel *chan) 3873{ 3874 MWL_HAL_APMODE mode; 3875 3876 if (IEEE80211_IS_CHAN_HT(chan)) { 3877 if (vap->iv_flags_ht & IEEE80211_FHT_PUREN) 3878 mode = AP_MODE_N_ONLY; 3879 else if (IEEE80211_IS_CHAN_5GHZ(chan)) 3880 mode = AP_MODE_AandN; 3881 else if (vap->iv_flags & IEEE80211_F_PUREG) 3882 mode = AP_MODE_GandN; 3883 else 3884 mode = AP_MODE_BandGandN; 3885 } else if (IEEE80211_IS_CHAN_ANYG(chan)) { 3886 if (vap->iv_flags & IEEE80211_F_PUREG) 3887 mode = AP_MODE_G_ONLY; 3888 else 3889 mode = AP_MODE_MIXED; 3890 } else if (IEEE80211_IS_CHAN_B(chan)) 3891 mode = AP_MODE_B_ONLY; 3892 else if (IEEE80211_IS_CHAN_A(chan)) 3893 mode = AP_MODE_A_ONLY; 3894 else 3895 mode = AP_MODE_MIXED; /* XXX should not happen? */ 3896 return mode; 3897} 3898 3899static int 3900mwl_setapmode(struct ieee80211vap *vap, struct ieee80211_channel *chan) 3901{ 3902 struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; 3903 return mwl_hal_setapmode(hvap, mwl_getapmode(vap, chan)); 3904} 3905 3906/* 3907 * Set/change channels. 3908 */ 3909static int 3910mwl_chan_set(struct mwl_softc *sc, struct ieee80211_channel *chan) 3911{ 3912 struct mwl_hal *mh = sc->sc_mh; 3913 struct ifnet *ifp = sc->sc_ifp; 3914 struct ieee80211com *ic = ifp->if_l2com; 3915 MWL_HAL_CHANNEL hchan; 3916 int maxtxpow; 3917 3918 DPRINTF(sc, MWL_DEBUG_RESET, "%s: chan %u MHz/flags 0x%x\n", 3919 __func__, chan->ic_freq, chan->ic_flags); 3920 3921 /* 3922 * Convert to a HAL channel description with 3923 * the flags constrained to reflect the current 3924 * operating mode. 3925 */ 3926 mwl_mapchan(&hchan, chan); 3927 mwl_hal_intrset(mh, 0); /* disable interrupts */ 3928#if 0 3929 mwl_draintxq(sc); /* clear pending tx frames */ 3930#endif 3931 mwl_hal_setchannel(mh, &hchan); 3932 /* 3933 * Tx power is cap'd by the regulatory setting and 3934 * possibly a user-set limit. We pass the min of 3935 * these to the hal to apply them to the cal data 3936 * for this channel. 3937 * XXX min bound? 3938 */ 3939 maxtxpow = 2*chan->ic_maxregpower; 3940 if (maxtxpow > ic->ic_txpowlimit) 3941 maxtxpow = ic->ic_txpowlimit; 3942 mwl_hal_settxpower(mh, &hchan, maxtxpow / 2); 3943 /* NB: potentially change mcast/mgt rates */ 3944 mwl_setcurchanrates(sc); 3945 3946 /* 3947 * Update internal state. 3948 */ 3949 sc->sc_tx_th.wt_chan_freq = htole16(chan->ic_freq); 3950 sc->sc_rx_th.wr_chan_freq = htole16(chan->ic_freq); 3951 if (IEEE80211_IS_CHAN_A(chan)) { 3952 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_A); 3953 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_A); 3954 } else if (IEEE80211_IS_CHAN_ANYG(chan)) { 3955 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_G); 3956 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_G); 3957 } else { 3958 sc->sc_tx_th.wt_chan_flags = htole16(IEEE80211_CHAN_B); 3959 sc->sc_rx_th.wr_chan_flags = htole16(IEEE80211_CHAN_B); 3960 } 3961 sc->sc_curchan = hchan; 3962 mwl_hal_intrset(mh, sc->sc_imask); 3963 3964 return 0; 3965} 3966 3967static void 3968mwl_scan_start(struct ieee80211com *ic) 3969{ 3970 struct ifnet *ifp = ic->ic_ifp; 3971 struct mwl_softc *sc = ifp->if_softc; 3972 3973 DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__); 3974} 3975 3976static void 3977mwl_scan_end(struct ieee80211com *ic) 3978{ 3979 struct ifnet *ifp = ic->ic_ifp; 3980 struct mwl_softc *sc = ifp->if_softc; 3981 3982 DPRINTF(sc, MWL_DEBUG_STATE, "%s\n", __func__); 3983} 3984 3985static void 3986mwl_set_channel(struct ieee80211com *ic) 3987{ 3988 struct ifnet *ifp = ic->ic_ifp; 3989 struct mwl_softc *sc = ifp->if_softc; 3990 3991 (void) mwl_chan_set(sc, ic->ic_curchan); 3992} 3993 3994/* 3995 * Handle a channel switch request. We inform the firmware 3996 * and mark the global state to suppress various actions. 3997 * NB: we issue only one request to the fw; we may be called 3998 * multiple times if there are multiple vap's. 3999 */ 4000static void 4001mwl_startcsa(struct ieee80211vap *vap) 4002{ 4003 struct ieee80211com *ic = vap->iv_ic; 4004 struct mwl_softc *sc = ic->ic_ifp->if_softc; 4005 MWL_HAL_CHANNEL hchan; 4006 4007 if (sc->sc_csapending) 4008 return; 4009 4010 mwl_mapchan(&hchan, ic->ic_csa_newchan); 4011 /* 1 =>'s quiet channel */ 4012 mwl_hal_setchannelswitchie(sc->sc_mh, &hchan, 1, ic->ic_csa_count); 4013 sc->sc_csapending = 1; 4014} 4015 4016/* 4017 * Plumb any static WEP key for the station. This is 4018 * necessary as we must propagate the key from the 4019 * global key table of the vap to each sta db entry. 4020 */ 4021static void 4022mwl_setanywepkey(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) 4023{ 4024 if ((vap->iv_flags & (IEEE80211_F_PRIVACY|IEEE80211_F_WPA)) == 4025 IEEE80211_F_PRIVACY && 4026 vap->iv_def_txkey != IEEE80211_KEYIX_NONE && 4027 vap->iv_nw_keys[vap->iv_def_txkey].wk_keyix != IEEE80211_KEYIX_NONE) 4028 (void) mwl_key_set(vap, &vap->iv_nw_keys[vap->iv_def_txkey], mac); 4029} 4030 4031static int 4032mwl_peerstadb(struct ieee80211_node *ni, int aid, int staid, MWL_HAL_PEERINFO *pi) 4033{ 4034#define WME(ie) ((const struct ieee80211_wme_info *) ie) 4035 struct ieee80211vap *vap = ni->ni_vap; 4036 struct mwl_hal_vap *hvap; 4037 int error; 4038 4039 if (vap->iv_opmode == IEEE80211_M_WDS) { 4040 /* 4041 * WDS vap's do not have a f/w vap; instead they piggyback 4042 * on an AP vap and we must install the sta db entry and 4043 * crypto state using that AP's handle (the WDS vap has none). 4044 */ 4045 hvap = MWL_VAP(vap)->mv_ap_hvap; 4046 } else 4047 hvap = MWL_VAP(vap)->mv_hvap; 4048 error = mwl_hal_newstation(hvap, ni->ni_macaddr, 4049 aid, staid, pi, 4050 ni->ni_flags & (IEEE80211_NODE_QOS | IEEE80211_NODE_HT), 4051 ni->ni_ies.wme_ie != NULL ? WME(ni->ni_ies.wme_ie)->wme_info : 0); 4052 if (error == 0) { 4053 /* 4054 * Setup security for this station. For sta mode this is 4055 * needed even though do the same thing on transition to 4056 * AUTH state because the call to mwl_hal_newstation 4057 * clobbers the crypto state we setup. 4058 */ 4059 mwl_setanywepkey(vap, ni->ni_macaddr); 4060 } 4061 return error; 4062#undef WME 4063} 4064 4065static void 4066mwl_setglobalkeys(struct ieee80211vap *vap) 4067{ 4068 struct ieee80211_key *wk; 4069 4070 wk = &vap->iv_nw_keys[0]; 4071 for (; wk < &vap->iv_nw_keys[IEEE80211_WEP_NKID]; wk++) 4072 if (wk->wk_keyix != IEEE80211_KEYIX_NONE) 4073 (void) mwl_key_set(vap, wk, vap->iv_myaddr); 4074} 4075 4076/* 4077 * Convert a legacy rate set to a firmware bitmask. 4078 */ 4079static uint32_t 4080get_rate_bitmap(const struct ieee80211_rateset *rs) 4081{ 4082 uint32_t rates; 4083 int i; 4084 4085 rates = 0; 4086 for (i = 0; i < rs->rs_nrates; i++) 4087 switch (rs->rs_rates[i] & IEEE80211_RATE_VAL) { 4088 case 2: rates |= 0x001; break; 4089 case 4: rates |= 0x002; break; 4090 case 11: rates |= 0x004; break; 4091 case 22: rates |= 0x008; break; 4092 case 44: rates |= 0x010; break; 4093 case 12: rates |= 0x020; break; 4094 case 18: rates |= 0x040; break; 4095 case 24: rates |= 0x080; break; 4096 case 36: rates |= 0x100; break; 4097 case 48: rates |= 0x200; break; 4098 case 72: rates |= 0x400; break; 4099 case 96: rates |= 0x800; break; 4100 case 108: rates |= 0x1000; break; 4101 } 4102 return rates; 4103} 4104 4105/* 4106 * Construct an HT firmware bitmask from an HT rate set. 4107 */ 4108static uint32_t 4109get_htrate_bitmap(const struct ieee80211_htrateset *rs) 4110{ 4111 uint32_t rates; 4112 int i; 4113 4114 rates = 0; 4115 for (i = 0; i < rs->rs_nrates; i++) { 4116 if (rs->rs_rates[i] < 16) 4117 rates |= 1<<rs->rs_rates[i]; 4118 } 4119 return rates; 4120} 4121 4122/* 4123 * Craft station database entry for station. 4124 * NB: use host byte order here, the hal handles byte swapping. 4125 */ 4126static MWL_HAL_PEERINFO * 4127mkpeerinfo(MWL_HAL_PEERINFO *pi, const struct ieee80211_node *ni) 4128{ 4129 const struct ieee80211vap *vap = ni->ni_vap; 4130 4131 memset(pi, 0, sizeof(*pi)); 4132 pi->LegacyRateBitMap = get_rate_bitmap(&ni->ni_rates); 4133 pi->CapInfo = ni->ni_capinfo; 4134 if (ni->ni_flags & IEEE80211_NODE_HT) { 4135 /* HT capabilities, etc */ 4136 pi->HTCapabilitiesInfo = ni->ni_htcap; 4137 /* XXX pi.HTCapabilitiesInfo */ 4138 pi->MacHTParamInfo = ni->ni_htparam; 4139 pi->HTRateBitMap = get_htrate_bitmap(&ni->ni_htrates); 4140 pi->AddHtInfo.ControlChan = ni->ni_htctlchan; 4141 pi->AddHtInfo.AddChan = ni->ni_ht2ndchan; 4142 pi->AddHtInfo.OpMode = ni->ni_htopmode; 4143 pi->AddHtInfo.stbc = ni->ni_htstbc; 4144 4145 /* constrain according to local configuration */ 4146 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40) == 0) 4147 pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI40; 4148 if ((vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20) == 0) 4149 pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_SHORTGI20; 4150 if (ni->ni_chw != 40) 4151 pi->HTCapabilitiesInfo &= ~IEEE80211_HTCAP_CHWIDTH40; 4152 } 4153 return pi; 4154} 4155 4156/* 4157 * Re-create the local sta db entry for a vap to ensure 4158 * up to date WME state is pushed to the firmware. Because 4159 * this resets crypto state this must be followed by a 4160 * reload of any keys in the global key table. 4161 */ 4162static int 4163mwl_localstadb(struct ieee80211vap *vap) 4164{ 4165#define WME(ie) ((const struct ieee80211_wme_info *) ie) 4166 struct mwl_hal_vap *hvap = MWL_VAP(vap)->mv_hvap; 4167 struct ieee80211_node *bss; 4168 MWL_HAL_PEERINFO pi; 4169 int error; 4170 4171 switch (vap->iv_opmode) { 4172 case IEEE80211_M_STA: 4173 bss = vap->iv_bss; 4174 error = mwl_hal_newstation(hvap, vap->iv_myaddr, 0, 0, 4175 vap->iv_state == IEEE80211_S_RUN ? 4176 mkpeerinfo(&pi, bss) : NULL, 4177 (bss->ni_flags & (IEEE80211_NODE_QOS | IEEE80211_NODE_HT)), 4178 bss->ni_ies.wme_ie != NULL ? 4179 WME(bss->ni_ies.wme_ie)->wme_info : 0); 4180 if (error == 0) 4181 mwl_setglobalkeys(vap); 4182 break; 4183 case IEEE80211_M_HOSTAP: 4184 error = mwl_hal_newstation(hvap, vap->iv_myaddr, 4185 0, 0, NULL, vap->iv_flags & IEEE80211_F_WME, 0); 4186 if (error == 0) 4187 mwl_setglobalkeys(vap); 4188 break; 4189 default: 4190 error = 0; 4191 break; 4192 } 4193 return error; 4194#undef WME 4195} 4196 4197static int 4198mwl_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 4199{ 4200 struct mwl_vap *mvp = MWL_VAP(vap); 4201 struct mwl_hal_vap *hvap = mvp->mv_hvap; 4202 struct ieee80211com *ic = vap->iv_ic; 4203 struct ieee80211_node *ni = NULL; 4204 struct ifnet *ifp = ic->ic_ifp; 4205 struct mwl_softc *sc = ifp->if_softc; 4206 struct mwl_hal *mh = sc->sc_mh; 4207 enum ieee80211_state ostate = vap->iv_state; 4208 int error; 4209 4210 DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: %s -> %s\n", 4211 vap->iv_ifp->if_xname, __func__, 4212 ieee80211_state_name[ostate], ieee80211_state_name[nstate]); 4213 4214 callout_stop(&sc->sc_timer); 4215 /* 4216 * Clear current radar detection state. 4217 */ 4218 if (ostate == IEEE80211_S_CAC) { 4219 /* stop quiet mode radar detection */ 4220 mwl_hal_setradardetection(mh, DR_CHK_CHANNEL_AVAILABLE_STOP); 4221 } else if (sc->sc_radarena) { 4222 /* stop in-service radar detection */ 4223 mwl_hal_setradardetection(mh, DR_DFS_DISABLE); 4224 sc->sc_radarena = 0; 4225 } 4226 /* 4227 * Carry out per-state actions before doing net80211 work. 4228 */ 4229 if (nstate == IEEE80211_S_INIT) { 4230 /* NB: only ap+sta vap's have a fw entity */ 4231 if (hvap != NULL) 4232 mwl_hal_stop(hvap); 4233 } else if (nstate == IEEE80211_S_SCAN) { 4234 mwl_hal_start(hvap); 4235 /* NB: this disables beacon frames */ 4236 mwl_hal_setinframode(hvap); 4237 } else if (nstate == IEEE80211_S_AUTH) { 4238 /* 4239 * Must create a sta db entry in case a WEP key needs to 4240 * be plumbed. This entry will be overwritten if we 4241 * associate; otherwise it will be reclaimed on node free. 4242 */ 4243 ni = vap->iv_bss; 4244 MWL_NODE(ni)->mn_hvap = hvap; 4245 (void) mwl_peerstadb(ni, 0, 0, NULL); 4246 } else if (nstate == IEEE80211_S_CSA) { 4247 /* XXX move to below? */ 4248 if (vap->iv_opmode == IEEE80211_M_HOSTAP) 4249 mwl_startcsa(vap); 4250 } else if (nstate == IEEE80211_S_CAC) { 4251 /* XXX move to below? */ 4252 /* stop ap xmit and enable quiet mode radar detection */ 4253 mwl_hal_setradardetection(mh, DR_CHK_CHANNEL_AVAILABLE_START); 4254 } 4255 4256 /* 4257 * Invoke the parent method to do net80211 work. 4258 */ 4259 error = mvp->mv_newstate(vap, nstate, arg); 4260 4261 /* 4262 * Carry out work that must be done after net80211 runs; 4263 * this work requires up to date state (e.g. iv_bss). 4264 */ 4265 if (error == 0 && nstate == IEEE80211_S_RUN) { 4266 /* NB: collect bss node again, it may have changed */ 4267 ni = vap->iv_bss; 4268 4269 DPRINTF(sc, MWL_DEBUG_STATE, 4270 "%s: %s(RUN): iv_flags 0x%08x bintvl %d bssid %s " 4271 "capinfo 0x%04x chan %d\n", 4272 vap->iv_ifp->if_xname, __func__, vap->iv_flags, 4273 ni->ni_intval, ether_sprintf(ni->ni_bssid), ni->ni_capinfo, 4274 ieee80211_chan2ieee(ic, ic->ic_curchan)); 4275 4276 /* 4277 * Recreate local sta db entry to update WME/HT state. 4278 */ 4279 mwl_localstadb(vap); 4280 switch (vap->iv_opmode) { 4281 case IEEE80211_M_HOSTAP: 4282 if (ostate == IEEE80211_S_CAC) { 4283 /* enable in-service radar detection */ 4284 mwl_hal_setradardetection(mh, 4285 DR_IN_SERVICE_MONITOR_START); 4286 sc->sc_radarena = 1; 4287 } 4288 /* 4289 * Allocate and setup the beacon frame 4290 * (and related state). 4291 */ 4292 error = mwl_reset_vap(vap, IEEE80211_S_RUN); 4293 if (error != 0) { 4294 DPRINTF(sc, MWL_DEBUG_STATE, 4295 "%s: beacon setup failed, error %d\n", 4296 __func__, error); 4297 goto bad; 4298 } 4299 /* NB: must be after setting up beacon */ 4300 mwl_hal_start(hvap); 4301 break; 4302 case IEEE80211_M_STA: 4303 DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: aid 0x%x\n", 4304 vap->iv_ifp->if_xname, __func__, ni->ni_associd); 4305 /* 4306 * Set state now that we're associated. 4307 */ 4308 mwl_hal_setassocid(hvap, ni->ni_bssid, ni->ni_associd); 4309 mwl_setrates(vap); 4310 mwl_hal_setrtsthreshold(hvap, vap->iv_rtsthreshold); 4311 if ((vap->iv_flags & IEEE80211_F_DWDS) && 4312 sc->sc_ndwdsvaps++ == 0) 4313 mwl_hal_setdwds(mh, 1); 4314 break; 4315 case IEEE80211_M_WDS: 4316 DPRINTF(sc, MWL_DEBUG_STATE, "%s: %s: bssid %s\n", 4317 vap->iv_ifp->if_xname, __func__, 4318 ether_sprintf(ni->ni_bssid)); 4319 mwl_seteapolformat(vap); 4320 break; 4321 default: 4322 break; 4323 } 4324 /* 4325 * Set CS mode according to operating channel; 4326 * this mostly an optimization for 5GHz. 4327 * 4328 * NB: must follow mwl_hal_start which resets csmode 4329 */ 4330 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) 4331 mwl_hal_setcsmode(mh, CSMODE_AGGRESSIVE); 4332 else 4333 mwl_hal_setcsmode(mh, CSMODE_AUTO_ENA); 4334 /* 4335 * Start timer to prod firmware. 4336 */ 4337 if (sc->sc_ageinterval != 0) 4338 callout_reset(&sc->sc_timer, sc->sc_ageinterval*hz, 4339 mwl_agestations, sc); 4340 } else if (nstate == IEEE80211_S_SLEEP) { 4341 /* XXX set chip in power save */ 4342 } else if ((vap->iv_flags & IEEE80211_F_DWDS) && 4343 --sc->sc_ndwdsvaps == 0) 4344 mwl_hal_setdwds(mh, 0); 4345bad: 4346 return error; 4347} 4348 4349/* 4350 * Manage station id's; these are separate from AID's 4351 * as AID's may have values out of the range of possible 4352 * station id's acceptable to the firmware. 4353 */ 4354static int 4355allocstaid(struct mwl_softc *sc, int aid) 4356{ 4357 int staid; 4358 4359 if (!(0 < aid && aid < MWL_MAXSTAID) || isset(sc->sc_staid, aid)) { 4360 /* NB: don't use 0 */ 4361 for (staid = 1; staid < MWL_MAXSTAID; staid++) 4362 if (isclr(sc->sc_staid, staid)) 4363 break; 4364 } else 4365 staid = aid; 4366 setbit(sc->sc_staid, staid); 4367 return staid; 4368} 4369 4370static void 4371delstaid(struct mwl_softc *sc, int staid) 4372{ 4373 clrbit(sc->sc_staid, staid); 4374} 4375 4376/* 4377 * Setup driver-specific state for a newly associated node. 4378 * Note that we're called also on a re-associate, the isnew 4379 * param tells us if this is the first time or not. 4380 */ 4381static void 4382mwl_newassoc(struct ieee80211_node *ni, int isnew) 4383{ 4384 struct ieee80211vap *vap = ni->ni_vap; 4385 struct mwl_softc *sc = vap->iv_ic->ic_ifp->if_softc; 4386 struct mwl_node *mn = MWL_NODE(ni); 4387 MWL_HAL_PEERINFO pi; 4388 uint16_t aid; 4389 int error; 4390 4391 aid = IEEE80211_AID(ni->ni_associd); 4392 if (isnew) { 4393 mn->mn_staid = allocstaid(sc, aid); 4394 mn->mn_hvap = MWL_VAP(vap)->mv_hvap; 4395 } else { 4396 mn = MWL_NODE(ni); 4397 /* XXX reset BA stream? */ 4398 } 4399 DPRINTF(sc, MWL_DEBUG_NODE, "%s: mac %s isnew %d aid %d staid %d\n", 4400 __func__, ether_sprintf(ni->ni_macaddr), isnew, aid, mn->mn_staid); 4401 error = mwl_peerstadb(ni, aid, mn->mn_staid, mkpeerinfo(&pi, ni)); 4402 if (error != 0) { 4403 DPRINTF(sc, MWL_DEBUG_NODE, 4404 "%s: error %d creating sta db entry\n", 4405 __func__, error); 4406 /* XXX how to deal with error? */ 4407 } 4408} 4409 4410/* 4411 * Periodically poke the firmware to age out station state 4412 * (power save queues, pending tx aggregates). 4413 */ 4414static void 4415mwl_agestations(void *arg) 4416{ 4417 struct mwl_softc *sc = arg; 4418 4419 mwl_hal_setkeepalive(sc->sc_mh); 4420 if (sc->sc_ageinterval != 0) /* NB: catch dynamic changes */ 4421 callout_schedule(&sc->sc_timer, sc->sc_ageinterval*hz); 4422} 4423 4424static const struct mwl_hal_channel * 4425findhalchannel(const MWL_HAL_CHANNELINFO *ci, int ieee) 4426{ 4427 int i; 4428 4429 for (i = 0; i < ci->nchannels; i++) { 4430 const struct mwl_hal_channel *hc = &ci->channels[i]; 4431 if (hc->ieee == ieee) 4432 return hc; 4433 } 4434 return NULL; 4435} 4436 4437static int 4438mwl_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, 4439 int nchan, struct ieee80211_channel chans[]) 4440{ 4441 struct mwl_softc *sc = ic->ic_ifp->if_softc; 4442 struct mwl_hal *mh = sc->sc_mh; 4443 const MWL_HAL_CHANNELINFO *ci; 4444 int i; 4445 4446 for (i = 0; i < nchan; i++) { 4447 struct ieee80211_channel *c = &chans[i]; 4448 const struct mwl_hal_channel *hc; 4449 4450 if (IEEE80211_IS_CHAN_2GHZ(c)) { 4451 mwl_hal_getchannelinfo(mh, MWL_FREQ_BAND_2DOT4GHZ, 4452 IEEE80211_IS_CHAN_HT40(c) ? 4453 MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci); 4454 } else if (IEEE80211_IS_CHAN_5GHZ(c)) { 4455 mwl_hal_getchannelinfo(mh, MWL_FREQ_BAND_5GHZ, 4456 IEEE80211_IS_CHAN_HT40(c) ? 4457 MWL_CH_40_MHz_WIDTH : MWL_CH_20_MHz_WIDTH, &ci); 4458 } else { 4459 if_printf(ic->ic_ifp, 4460 "%s: channel %u freq %u/0x%x not 2.4/5GHz\n", 4461 __func__, c->ic_ieee, c->ic_freq, c->ic_flags); 4462 return EINVAL; 4463 } 4464 /* 4465 * Verify channel has cal data and cap tx power. 4466 */ 4467 hc = findhalchannel(ci, c->ic_ieee); 4468 if (hc != NULL) { 4469 if (c->ic_maxpower > 2*hc->maxTxPow) 4470 c->ic_maxpower = 2*hc->maxTxPow; 4471 goto next; 4472 } 4473 if (IEEE80211_IS_CHAN_HT40(c)) { 4474 /* 4475 * Look for the extension channel since the 4476 * hal table only has the primary channel. 4477 */ 4478 hc = findhalchannel(ci, c->ic_extieee); 4479 if (hc != NULL) { 4480 if (c->ic_maxpower > 2*hc->maxTxPow) 4481 c->ic_maxpower = 2*hc->maxTxPow; 4482 goto next; 4483 } 4484 } 4485 if_printf(ic->ic_ifp, 4486 "%s: no cal data for channel %u ext %u freq %u/0x%x\n", 4487 __func__, c->ic_ieee, c->ic_extieee, 4488 c->ic_freq, c->ic_flags); 4489 return EINVAL; 4490 next: 4491 ; 4492 } 4493 return 0; 4494} 4495 4496#define IEEE80211_CHAN_HTG (IEEE80211_CHAN_HT|IEEE80211_CHAN_G) 4497#define IEEE80211_CHAN_HTA (IEEE80211_CHAN_HT|IEEE80211_CHAN_A) 4498 4499static void 4500addchan(struct ieee80211_channel *c, int freq, int flags, int ieee, int txpow) 4501{ 4502 c->ic_freq = freq; 4503 c->ic_flags = flags; 4504 c->ic_ieee = ieee; 4505 c->ic_minpower = 0; 4506 c->ic_maxpower = 2*txpow; 4507 c->ic_maxregpower = txpow; 4508} 4509 4510static const struct ieee80211_channel * 4511findchannel(const struct ieee80211_channel chans[], int nchans, 4512 int freq, int flags) 4513{ 4514 const struct ieee80211_channel *c; 4515 int i; 4516 4517 for (i = 0; i < nchans; i++) { 4518 c = &chans[i]; 4519 if (c->ic_freq == freq && c->ic_flags == flags) 4520 return c; 4521 } 4522 return NULL; 4523} 4524 4525static void 4526addht40channels(struct ieee80211_channel chans[], int maxchans, int *nchans, 4527 const MWL_HAL_CHANNELINFO *ci, int flags) 4528{ 4529 struct ieee80211_channel *c; 4530 const struct ieee80211_channel *extc; 4531 const struct mwl_hal_channel *hc; 4532 int i; 4533 4534 c = &chans[*nchans]; 4535 4536 flags &= ~IEEE80211_CHAN_HT; 4537 for (i = 0; i < ci->nchannels; i++) { 4538 /* 4539 * Each entry defines an HT40 channel pair; find the 4540 * extension channel above and the insert the pair. 4541 */ 4542 hc = &ci->channels[i]; 4543 extc = findchannel(chans, *nchans, hc->freq+20, 4544 flags | IEEE80211_CHAN_HT20); 4545 if (extc != NULL) { 4546 if (*nchans >= maxchans) 4547 break; 4548 addchan(c, hc->freq, flags | IEEE80211_CHAN_HT40U, 4549 hc->ieee, hc->maxTxPow); 4550 c->ic_extieee = extc->ic_ieee; 4551 c++, (*nchans)++; 4552 if (*nchans >= maxchans) 4553 break; 4554 addchan(c, extc->ic_freq, flags | IEEE80211_CHAN_HT40D, 4555 extc->ic_ieee, hc->maxTxPow); 4556 c->ic_extieee = hc->ieee; 4557 c++, (*nchans)++; 4558 } 4559 } 4560} 4561 4562static void 4563addchannels(struct ieee80211_channel chans[], int maxchans, int *nchans, 4564 const MWL_HAL_CHANNELINFO *ci, int flags) 4565{ 4566 struct ieee80211_channel *c; 4567 int i; 4568 4569 c = &chans[*nchans]; 4570 4571 for (i = 0; i < ci->nchannels; i++) { 4572 const struct mwl_hal_channel *hc; 4573 4574 hc = &ci->channels[i]; 4575 if (*nchans >= maxchans) 4576 break; 4577 addchan(c, hc->freq, flags, hc->ieee, hc->maxTxPow); 4578 c++, (*nchans)++; 4579 if (flags == IEEE80211_CHAN_G || flags == IEEE80211_CHAN_HTG) { 4580 /* g channel have a separate b-only entry */ 4581 if (*nchans >= maxchans) 4582 break; 4583 c[0] = c[-1]; 4584 c[-1].ic_flags = IEEE80211_CHAN_B; 4585 c++, (*nchans)++; 4586 } 4587 if (flags == IEEE80211_CHAN_HTG) { 4588 /* HT g channel have a separate g-only entry */ 4589 if (*nchans >= maxchans) 4590 break; 4591 c[-1].ic_flags = IEEE80211_CHAN_G; 4592 c[0] = c[-1]; 4593 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 4594 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 4595 c++, (*nchans)++; 4596 } 4597 if (flags == IEEE80211_CHAN_HTA) { 4598 /* HT a channel have a separate a-only entry */ 4599 if (*nchans >= maxchans) 4600 break; 4601 c[-1].ic_flags = IEEE80211_CHAN_A; 4602 c[0] = c[-1]; 4603 c[0].ic_flags &= ~IEEE80211_CHAN_HT; 4604 c[0].ic_flags |= IEEE80211_CHAN_HT20; /* HT20 */ 4605 c++, (*nchans)++; 4606 } 4607 } 4608} 4609 4610static void 4611getchannels(struct mwl_softc *sc, int maxchans, int *nchans, 4612 struct ieee80211_channel chans[]) 4613{ 4614 const MWL_HAL_CHANNELINFO *ci; 4615 4616 /* 4617 * Use the channel info from the hal to craft the 4618 * channel list. Note that we pass back an unsorted 4619 * list; the caller is required to sort it for us 4620 * (if desired). 4621 */ 4622 *nchans = 0; 4623 if (mwl_hal_getchannelinfo(sc->sc_mh, 4624 MWL_FREQ_BAND_2DOT4GHZ, MWL_CH_20_MHz_WIDTH, &ci) == 0) 4625 addchannels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTG); 4626 if (mwl_hal_getchannelinfo(sc->sc_mh, 4627 MWL_FREQ_BAND_5GHZ, MWL_CH_20_MHz_WIDTH, &ci) == 0) 4628 addchannels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTA); 4629 if (mwl_hal_getchannelinfo(sc->sc_mh, 4630 MWL_FREQ_BAND_2DOT4GHZ, MWL_CH_40_MHz_WIDTH, &ci) == 0) 4631 addht40channels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTG); 4632 if (mwl_hal_getchannelinfo(sc->sc_mh, 4633 MWL_FREQ_BAND_5GHZ, MWL_CH_40_MHz_WIDTH, &ci) == 0) 4634 addht40channels(chans, maxchans, nchans, ci, IEEE80211_CHAN_HTA); 4635} 4636 4637static void 4638mwl_getradiocaps(struct ieee80211com *ic, 4639 int maxchans, int *nchans, struct ieee80211_channel chans[]) 4640{ 4641 struct mwl_softc *sc = ic->ic_ifp->if_softc; 4642 4643 getchannels(sc, maxchans, nchans, chans); 4644} 4645 4646static int 4647mwl_getchannels(struct mwl_softc *sc) 4648{ 4649 struct ifnet *ifp = sc->sc_ifp; 4650 struct ieee80211com *ic = ifp->if_l2com; 4651 4652 /* 4653 * Use the channel info from the hal to craft the 4654 * channel list for net80211. Note that we pass up 4655 * an unsorted list; net80211 will sort it for us. 4656 */ 4657 memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); 4658 ic->ic_nchans = 0; 4659 getchannels(sc, IEEE80211_CHAN_MAX, &ic->ic_nchans, ic->ic_channels); 4660 4661 ic->ic_regdomain.regdomain = SKU_DEBUG; 4662 ic->ic_regdomain.country = CTRY_DEFAULT; 4663 ic->ic_regdomain.location = 'I'; 4664 ic->ic_regdomain.isocc[0] = ' '; /* XXX? */ 4665 ic->ic_regdomain.isocc[1] = ' '; 4666 return (ic->ic_nchans == 0 ? EIO : 0); 4667} 4668#undef IEEE80211_CHAN_HTA 4669#undef IEEE80211_CHAN_HTG 4670 4671#ifdef MWL_DEBUG 4672static void 4673mwl_printrxbuf(const struct mwl_rxbuf *bf, u_int ix) 4674{ 4675 const struct mwl_rxdesc *ds = bf->bf_desc; 4676 uint32_t status = le32toh(ds->Status); 4677 4678 printf("R[%2u] (DS.V:%p DS.P:%p) NEXT:%08x DATA:%08x RC:%02x%s\n" 4679 " STAT:%02x LEN:%04x RSSI:%02x CHAN:%02x RATE:%02x QOS:%04x HT:%04x\n", 4680 ix, ds, (const struct mwl_desc *)bf->bf_daddr, 4681 le32toh(ds->pPhysNext), le32toh(ds->pPhysBuffData), 4682 ds->RxControl, 4683 ds->RxControl != EAGLE_RXD_CTRL_DRIVER_OWN ? 4684 "" : (status & EAGLE_RXD_STATUS_OK) ? " *" : " !", 4685 ds->Status, le16toh(ds->PktLen), ds->RSSI, ds->Channel, 4686 ds->Rate, le16toh(ds->QosCtrl), le16toh(ds->HtSig2)); 4687} 4688 4689static void 4690mwl_printtxbuf(const struct mwl_txbuf *bf, u_int qnum, u_int ix) 4691{ 4692 const struct mwl_txdesc *ds = bf->bf_desc; 4693 uint32_t status = le32toh(ds->Status); 4694 4695 printf("Q%u[%3u]", qnum, ix); 4696 printf(" (DS.V:%p DS.P:%p)\n", 4697 ds, (const struct mwl_txdesc *)bf->bf_daddr); 4698 printf(" NEXT:%08x DATA:%08x LEN:%04x STAT:%08x%s\n", 4699 le32toh(ds->pPhysNext), 4700 le32toh(ds->PktPtr), le16toh(ds->PktLen), status, 4701 status & EAGLE_TXD_STATUS_USED ? 4702 "" : (status & 3) != 0 ? " *" : " !"); 4703 printf(" RATE:%02x PRI:%x QOS:%04x SAP:%08x FORMAT:%04x\n", 4704 ds->DataRate, ds->TxPriority, le16toh(ds->QosCtrl), 4705 le32toh(ds->SapPktInfo), le16toh(ds->Format)); 4706#if MWL_TXDESC > 1 4707 printf(" MULTIFRAMES:%u LEN:%04x %04x %04x %04x %04x %04x\n" 4708 , le32toh(ds->multiframes) 4709 , le16toh(ds->PktLenArray[0]), le16toh(ds->PktLenArray[1]) 4710 , le16toh(ds->PktLenArray[2]), le16toh(ds->PktLenArray[3]) 4711 , le16toh(ds->PktLenArray[4]), le16toh(ds->PktLenArray[5]) 4712 ); 4713 printf(" DATA:%08x %08x %08x %08x %08x %08x\n" 4714 , le32toh(ds->PktPtrArray[0]), le32toh(ds->PktPtrArray[1]) 4715 , le32toh(ds->PktPtrArray[2]), le32toh(ds->PktPtrArray[3]) 4716 , le32toh(ds->PktPtrArray[4]), le32toh(ds->PktPtrArray[5]) 4717 ); 4718#endif 4719#if 0 4720{ const uint8_t *cp = (const uint8_t *) ds; 4721 int i; 4722 for (i = 0; i < sizeof(struct mwl_txdesc); i++) { 4723 printf("%02x ", cp[i]); 4724 if (((i+1) % 16) == 0) 4725 printf("\n"); 4726 } 4727 printf("\n"); 4728} 4729#endif 4730} 4731#endif /* MWL_DEBUG */ 4732 4733#if 0 4734static void 4735mwl_txq_dump(struct mwl_txq *txq) 4736{ 4737 struct mwl_txbuf *bf; 4738 int i = 0; 4739 4740 MWL_TXQ_LOCK(txq); 4741 STAILQ_FOREACH(bf, &txq->active, bf_list) { 4742 struct mwl_txdesc *ds = bf->bf_desc; 4743 MWL_TXDESC_SYNC(txq, ds, 4744 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 4745#ifdef MWL_DEBUG 4746 mwl_printtxbuf(bf, txq->qnum, i); 4747#endif 4748 i++; 4749 } 4750 MWL_TXQ_UNLOCK(txq); 4751} 4752#endif 4753 4754static void 4755mwl_watchdog(struct ifnet *ifp) 4756{ 4757 struct mwl_softc *sc = ifp->if_softc; 4758 4759 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->sc_invalid) { 4760 if (mwl_hal_setkeepalive(sc->sc_mh)) 4761 if_printf(ifp, "transmit timeout (firmware hung?)\n"); 4762 else 4763 if_printf(ifp, "transmit timeout\n"); 4764#if 0 4765 mwl_reset(ifp); 4766mwl_txq_dump(&sc->sc_txq[0]);/*XXX*/ 4767#endif 4768 ifp->if_oerrors++; 4769 sc->sc_stats.mst_watchdog++; 4770 } 4771} 4772 4773#ifdef MWL_DIAGAPI 4774/* 4775 * Diagnostic interface to the HAL. This is used by various 4776 * tools to do things like retrieve register contents for 4777 * debugging. The mechanism is intentionally opaque so that 4778 * it can change frequently w/o concern for compatiblity. 4779 */ 4780static int 4781mwl_ioctl_diag(struct mwl_softc *sc, struct mwl_diag *md) 4782{ 4783 struct mwl_hal *mh = sc->sc_mh; 4784 u_int id = md->md_id & MWL_DIAG_ID; 4785 void *indata = NULL; 4786 void *outdata = NULL; 4787 u_int32_t insize = md->md_in_size; 4788 u_int32_t outsize = md->md_out_size; 4789 int error = 0; 4790 4791 if (md->md_id & MWL_DIAG_IN) { 4792 /* 4793 * Copy in data. 4794 */ 4795 indata = malloc(insize, M_TEMP, M_NOWAIT); 4796 if (indata == NULL) { 4797 error = ENOMEM; 4798 goto bad; 4799 } 4800 error = copyin(md->md_in_data, indata, insize); 4801 if (error) 4802 goto bad; 4803 } 4804 if (md->md_id & MWL_DIAG_DYN) { 4805 /* 4806 * Allocate a buffer for the results (otherwise the HAL 4807 * returns a pointer to a buffer where we can read the 4808 * results). Note that we depend on the HAL leaving this 4809 * pointer for us to use below in reclaiming the buffer; 4810 * may want to be more defensive. 4811 */ 4812 outdata = malloc(outsize, M_TEMP, M_NOWAIT); 4813 if (outdata == NULL) { 4814 error = ENOMEM; 4815 goto bad; 4816 } 4817 } 4818 if (mwl_hal_getdiagstate(mh, id, indata, insize, &outdata, &outsize)) { 4819 if (outsize < md->md_out_size) 4820 md->md_out_size = outsize; 4821 if (outdata != NULL) 4822 error = copyout(outdata, md->md_out_data, 4823 md->md_out_size); 4824 } else { 4825 error = EINVAL; 4826 } 4827bad: 4828 if ((md->md_id & MWL_DIAG_IN) && indata != NULL) 4829 free(indata, M_TEMP); 4830 if ((md->md_id & MWL_DIAG_DYN) && outdata != NULL) 4831 free(outdata, M_TEMP); 4832 return error; 4833} 4834 4835static int 4836mwl_ioctl_reset(struct mwl_softc *sc, struct mwl_diag *md) 4837{ 4838 struct mwl_hal *mh = sc->sc_mh; 4839 int error; 4840 4841 MWL_LOCK_ASSERT(sc); 4842 4843 if (md->md_id == 0 && mwl_hal_fwload(mh, NULL) != 0) { 4844 device_printf(sc->sc_dev, "unable to load firmware\n"); 4845 return EIO; 4846 } 4847 if (mwl_hal_gethwspecs(mh, &sc->sc_hwspecs) != 0) { 4848 device_printf(sc->sc_dev, "unable to fetch h/w specs\n"); 4849 return EIO; 4850 } 4851 error = mwl_setupdma(sc); 4852 if (error != 0) { 4853 /* NB: mwl_setupdma prints a msg */ 4854 return error; 4855 } 4856 /* 4857 * Reset tx/rx data structures; after reload we must 4858 * re-start the driver's notion of the next xmit/recv. 4859 */ 4860 mwl_draintxq(sc); /* clear pending frames */ 4861 mwl_resettxq(sc); /* rebuild tx q lists */ 4862 sc->sc_rxnext = NULL; /* force rx to start at the list head */ 4863 return 0; 4864} 4865#endif /* MWL_DIAGAPI */ 4866 4867static int 4868mwl_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 4869{ 4870#define IS_RUNNING(ifp) \ 4871 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 4872 struct mwl_softc *sc = ifp->if_softc; 4873 struct ieee80211com *ic = ifp->if_l2com; 4874 struct ifreq *ifr = (struct ifreq *)data; 4875 int error = 0, startall; 4876 4877 switch (cmd) { 4878 case SIOCSIFFLAGS: 4879 MWL_LOCK(sc); 4880 startall = 0; 4881 if (IS_RUNNING(ifp)) { 4882 /* 4883 * To avoid rescanning another access point, 4884 * do not call mwl_init() here. Instead, 4885 * only reflect promisc mode settings. 4886 */ 4887 mwl_mode_init(sc); 4888 } else if (ifp->if_flags & IFF_UP) { 4889 /* 4890 * Beware of being called during attach/detach 4891 * to reset promiscuous mode. In that case we 4892 * will still be marked UP but not RUNNING. 4893 * However trying to re-init the interface 4894 * is the wrong thing to do as we've already 4895 * torn down much of our state. There's 4896 * probably a better way to deal with this. 4897 */ 4898 if (!sc->sc_invalid) { 4899 mwl_init_locked(sc); /* XXX lose error */ 4900 startall = 1; 4901 } 4902 } else 4903 mwl_stop_locked(ifp, 1); 4904 MWL_UNLOCK(sc); 4905 if (startall) 4906 ieee80211_start_all(ic); 4907 break; 4908 case SIOCGMVSTATS: 4909 mwl_hal_gethwstats(sc->sc_mh, &sc->sc_stats.hw_stats); 4910 /* NB: embed these numbers to get a consistent view */ 4911 sc->sc_stats.mst_tx_packets = ifp->if_opackets; 4912 sc->sc_stats.mst_rx_packets = ifp->if_ipackets; 4913 /* 4914 * NB: Drop the softc lock in case of a page fault; 4915 * we'll accept any potential inconsisentcy in the 4916 * statistics. The alternative is to copy the data 4917 * to a local structure. 4918 */ 4919 return copyout(&sc->sc_stats, 4920 ifr->ifr_data, sizeof (sc->sc_stats)); 4921#ifdef MWL_DIAGAPI 4922 case SIOCGMVDIAG: 4923 /* XXX check privs */ 4924 return mwl_ioctl_diag(sc, (struct mwl_diag *) ifr); 4925 case SIOCGMVRESET: 4926 /* XXX check privs */ 4927 MWL_LOCK(sc); 4928 error = mwl_ioctl_reset(sc,(struct mwl_diag *) ifr); 4929 MWL_UNLOCK(sc); 4930 break; 4931#endif /* MWL_DIAGAPI */ 4932 case SIOCGIFMEDIA: 4933 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 4934 break; 4935 case SIOCGIFADDR: 4936 error = ether_ioctl(ifp, cmd, data); 4937 break; 4938 default: 4939 error = EINVAL; 4940 break; 4941 } 4942 return error; 4943#undef IS_RUNNING 4944} 4945 4946#ifdef MWL_DEBUG 4947static int 4948mwl_sysctl_debug(SYSCTL_HANDLER_ARGS) 4949{ 4950 struct mwl_softc *sc = arg1; 4951 int debug, error; 4952 4953 debug = sc->sc_debug | (mwl_hal_getdebug(sc->sc_mh) << 24); 4954 error = sysctl_handle_int(oidp, &debug, 0, req); 4955 if (error || !req->newptr) 4956 return error; 4957 mwl_hal_setdebug(sc->sc_mh, debug >> 24); 4958 sc->sc_debug = debug & 0x00ffffff; 4959 return 0; 4960} 4961#endif /* MWL_DEBUG */ 4962 4963static void 4964mwl_sysctlattach(struct mwl_softc *sc) 4965{ 4966#ifdef MWL_DEBUG 4967 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); 4968 struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); 4969 4970 sc->sc_debug = mwl_debug; 4971 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 4972 "debug", CTLTYPE_INT | CTLFLAG_RW, sc, 0, 4973 mwl_sysctl_debug, "I", "control debugging printfs"); 4974#endif 4975} 4976 4977/* 4978 * Announce various information on device/driver attach. 4979 */ 4980static void 4981mwl_announce(struct mwl_softc *sc) 4982{ 4983 struct ifnet *ifp = sc->sc_ifp; 4984 4985 if_printf(ifp, "Rev A%d hardware, v%d.%d.%d.%d firmware (regioncode %d)\n", 4986 sc->sc_hwspecs.hwVersion, 4987 (sc->sc_hwspecs.fwReleaseNumber>>24) & 0xff, 4988 (sc->sc_hwspecs.fwReleaseNumber>>16) & 0xff, 4989 (sc->sc_hwspecs.fwReleaseNumber>>8) & 0xff, 4990 (sc->sc_hwspecs.fwReleaseNumber>>0) & 0xff, 4991 sc->sc_hwspecs.regionCode); 4992 sc->sc_fwrelease = sc->sc_hwspecs.fwReleaseNumber; 4993 4994 if (bootverbose) { 4995 int i; 4996 for (i = 0; i <= WME_AC_VO; i++) { 4997 struct mwl_txq *txq = sc->sc_ac2q[i]; 4998 if_printf(ifp, "Use hw queue %u for %s traffic\n", 4999 txq->qnum, ieee80211_wme_acnames[i]); 5000 } 5001 } 5002 if (bootverbose || mwl_rxdesc != MWL_RXDESC) 5003 if_printf(ifp, "using %u rx descriptors\n", mwl_rxdesc); 5004 if (bootverbose || mwl_rxbuf != MWL_RXBUF) 5005 if_printf(ifp, "using %u rx buffers\n", mwl_rxbuf); 5006 if (bootverbose || mwl_txbuf != MWL_TXBUF) 5007 if_printf(ifp, "using %u tx buffers\n", mwl_txbuf); 5008 if (bootverbose && mwl_hal_ismbsscapable(sc->sc_mh)) 5009 if_printf(ifp, "multi-bss support\n"); 5010#ifdef MWL_TX_NODROP 5011 if (bootverbose) 5012 if_printf(ifp, "no tx drop\n"); 5013#endif 5014} 5015