1 /* 2 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer, 15 * without modification. 16 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 17 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 18 * redistribution must be conditioned upon including a substantially 19 * similar Disclaimer requirement for further binary redistribution. 20 * 3. Neither the names of the above-listed copyright holders nor the names 21 * of any contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. 23 * 24 * NO WARRANTY 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 28 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 29 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 30 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 33 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 35 * THE POSSIBILITY OF SUCH DAMAGES. 36 */ 37 38 #pragma ident "%Z%%M% %I% %E% SMI" 39 40 #include <sys/param.h> 41 #include <sys/types.h> 42 #include <sys/signal.h> 43 #include <sys/stream.h> 44 #include <sys/termio.h> 45 #include <sys/errno.h> 46 #include <sys/file.h> 47 #include <sys/cmn_err.h> 48 #include <sys/stropts.h> 49 #include <sys/strsubr.h> 50 #include <sys/strtty.h> 51 #include <sys/kbio.h> 52 #include <sys/cred.h> 53 #include <sys/stat.h> 54 #include <sys/consdev.h> 55 #include <sys/kmem.h> 56 #include <sys/modctl.h> 57 #include <sys/ddi.h> 58 #include <sys/sunddi.h> 59 #include <sys/pci.h> 60 #include <sys/errno.h> 61 #include <sys/gld.h> 62 #include <sys/dlpi.h> 63 #include <sys/ethernet.h> 64 #include <sys/list.h> 65 #include <sys/byteorder.h> 66 #include <sys/strsun.h> 67 #include <inet/common.h> 68 #include <inet/nd.h> 69 #include <inet/mi.h> 70 #include <inet/wifi_ioctl.h> 71 #include "ath_hal.h" 72 #include "ath_impl.h" 73 74 static const char *acnames[] = { 75 "WME_AC_BE", 76 "WME_AC_BK", 77 "WME_AC_VI", 78 "WME_AC_VO", 79 "WME_UPSD" 80 }; 81 82 extern void ath_setup_desc(ath_t *asc, struct ath_buf *bf); 83 84 uint32_t 85 ath_calcrxfilter(ath_t *asc) 86 { 87 ieee80211com_t *ic = (ieee80211com_t *)asc; 88 struct ath_hal *ah = asc->asc_ah; 89 uint32_t rfilt; 90 91 rfilt = (ATH_HAL_GETRXFILTER(ah) & HAL_RX_FILTER_PHYERR) 92 | HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST; 93 if (ic->ic_opmode != IEEE80211_M_STA) 94 rfilt |= HAL_RX_FILTER_PROBEREQ; 95 if (ic->ic_opmode != IEEE80211_M_HOSTAP && 96 (asc->asc_promisc & GLD_MAC_PROMISC_PHYS)) /* promiscuous */ 97 rfilt |= HAL_RX_FILTER_PROM; 98 if (ic->ic_opmode == IEEE80211_M_STA || 99 ic->ic_opmode == IEEE80211_M_IBSS || 100 ic->ic_state == IEEE80211_S_SCAN) 101 rfilt |= HAL_RX_FILTER_BEACON; 102 return (rfilt); 103 } 104 105 static int 106 ath_set_data_queue(ath_t *asc, int ac, int haltype) 107 { 108 HAL_TXQ_INFO qi; 109 int qnum; 110 struct ath_hal *ah = asc->asc_ah; 111 struct ath_txq *txq; 112 113 if (ac >= ATH_N(asc->asc_ac2q)) { 114 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_set_data_queue(): " 115 "ac %u out of range, max %u!\n", 116 ac, ATH_N(asc->asc_ac2q))); 117 return (1); 118 } 119 (void) memset(&qi, 0, sizeof (qi)); 120 qi.tqi_subtype = haltype; 121 /* 122 * Enable interrupts only for EOL and DESC conditions. 123 * We mark tx descriptors to receive a DESC interrupt 124 * when a tx queue gets deep; otherwise waiting for the 125 * EOL to reap descriptors. Note that this is done to 126 * reduce interrupt load and this only defers reaping 127 * descriptors, never transmitting frames. Aside from 128 * reducing interrupts this also permits more concurrency. 129 * The only potential downside is if the tx queue backs 130 * up in which case the top half of the kernel may backup 131 * due to a lack of tx descriptors. 132 */ 133 qi.tqi_qflags = HAL_TXQ_TXEOLINT_ENABLE | HAL_TXQ_TXDESCINT_ENABLE; 134 qnum = ATH_HAL_SETUPTXQUEUE(ah, HAL_TX_QUEUE_DATA, &qi); 135 if (qnum == -1) { 136 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_set_data_queue(): " 137 "Unable to setup hardware queue for %s traffic!\n", 138 acnames[ac])); 139 return (1); 140 } 141 if (qnum >= ATH_N(asc->asc_txq)) { 142 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_set_data_queue(): " 143 "hal qnum %u out of range, max %u!\n", 144 qnum, ATH_N(asc->asc_txq))); 145 return (1); 146 } 147 if (!ATH_TXQ_SETUP(asc, qnum)) { 148 txq = &asc->asc_txq[qnum]; 149 txq->axq_qnum = qnum; 150 txq->axq_depth = 0; 151 txq->axq_intrcnt = 0; 152 txq->axq_link = NULL; 153 list_create(&txq->axq_list, sizeof (struct ath_buf), 154 offsetof(struct ath_buf, bf_node)); 155 mutex_init(&txq->axq_lock, NULL, MUTEX_DRIVER, NULL); 156 asc->asc_txqsetup |= 1<<qnum; 157 } 158 asc->asc_ac2q[ac] = &asc->asc_txq[qnum]; 159 return (0); 160 } 161 162 int 163 ath_txq_setup(ath_t *asc) 164 { 165 if (ath_set_data_queue(asc, WME_AC_BE, HAL_WME_AC_BK) || 166 ath_set_data_queue(asc, WME_AC_BK, HAL_WME_AC_BE) || 167 ath_set_data_queue(asc, WME_AC_VI, HAL_WME_AC_VI) || 168 ath_set_data_queue(asc, WME_AC_VO, HAL_WME_AC_VO)) { 169 return (1); 170 } 171 172 return (0); 173 } 174 175 void 176 ath_txq_cleanup(ath_t *asc) 177 { 178 int i; 179 180 mutex_destroy(&asc->asc_txbuflock); 181 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { 182 if (ATH_TXQ_SETUP(asc, i)) { 183 struct ath_txq *txq = &asc->asc_txq[i]; 184 185 ATH_HAL_RELEASETXQUEUE(asc->asc_ah, txq->axq_qnum); 186 mutex_destroy(&txq->axq_lock); 187 asc->asc_txqsetup &= ~(1 << txq->axq_qnum); 188 } 189 } 190 } 191 192 void 193 ath_setcurmode(ath_t *asc, enum ieee80211_phymode mode) 194 { 195 const HAL_RATE_TABLE *rt; 196 int i; 197 198 for (i = 0; i < sizeof (asc->asc_rixmap); i++) 199 asc->asc_rixmap[i] = 0xff; 200 201 rt = asc->asc_rates[mode]; 202 ASSERT(rt != NULL); 203 204 for (i = 0; i < rt->rateCount; i++) 205 asc->asc_rixmap[rt->info[i].dot11Rate & IEEE80211_RATE_VAL] = i; 206 207 asc->asc_currates = rt; 208 asc->asc_curmode = mode; 209 } 210 211 /* Set correct parameters for a certain mode */ 212 void 213 ath_mode_init(ath_t *asc) 214 { 215 ieee80211com_t *ic = (ieee80211com_t *)asc; 216 struct ath_hal *ah = asc->asc_ah; 217 uint32_t rfilt; 218 219 /* configure rx filter */ 220 rfilt = ath_calcrxfilter(asc); 221 ATH_HAL_SETRXFILTER(ah, rfilt); 222 ATH_HAL_SETOPMODE(ah); 223 ATH_HAL_SETMCASTFILTER(ah, asc->asc_mfilt[0], asc->asc_mfilt[1]); 224 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_mode_init(): " 225 "mode =%d RX filter 0x%x, MC filter %08x:%08x\n", 226 ic->ic_opmode, rfilt, 227 asc->asc_mfilt[0], asc->asc_mfilt[1])); 228 } 229 230 231 /* 232 * Disable the receive h/w in preparation for a reset. 233 */ 234 void 235 ath_stoprecv(ath_t *asc) 236 { 237 ATH_HAL_STOPPCURECV(asc->asc_ah); /* disable PCU */ 238 ATH_HAL_SETRXFILTER(asc->asc_ah, 0); /* clear recv filter */ 239 ATH_HAL_STOPDMARECV(asc->asc_ah); /* disable DMA engine */ 240 drv_usecwait(3000); 241 242 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_stoprecv(): rx queue %p, link %p\n", 243 ATH_HAL_GETRXBUF(asc->asc_ah), asc->asc_rxlink)); 244 asc->asc_rxlink = NULL; 245 } 246 247 uint32_t 248 ath_chan2flags(ieee80211com_t *isc, struct ieee80211_channel *chan) 249 { 250 static const uint32_t modeflags[] = { 251 0, /* IEEE80211_MODE_AUTO */ 252 CHANNEL_A, /* IEEE80211_MODE_11A */ 253 CHANNEL_B, /* IEEE80211_MODE_11B */ 254 CHANNEL_PUREG, /* IEEE80211_MODE_11G */ 255 0, /* IEEE80211_MODE_FH */ 256 CHANNEL_108A, /* IEEE80211_MODE_TURBO_A */ 257 CHANNEL_108G /* IEEE80211_MODE_TURBO_G */ 258 }; 259 return (modeflags[ieee80211_chan2mode(isc, chan)]); 260 } 261 262 263 int 264 ath_getchannels(ath_t *asc, uint32_t cc, HAL_BOOL outdoor, HAL_BOOL xchanmode) 265 { 266 ieee80211com_t *ic = (ieee80211com_t *)asc; 267 struct ath_hal *ah = asc->asc_ah; 268 HAL_CHANNEL *chans; 269 int i, ix; 270 uint32_t nchan; 271 272 chans = (HAL_CHANNEL *) 273 kmem_zalloc(IEEE80211_CHAN_MAX * sizeof (HAL_CHANNEL), KM_SLEEP); 274 275 if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan, 276 NULL, 0, NULL, cc, HAL_MODE_ALL, outdoor, xchanmode)) { 277 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_getchannels(): " 278 "unable to get channel list\n"); 279 kmem_free(chans, IEEE80211_CHAN_MAX * sizeof (HAL_CHANNEL))); 280 return (EINVAL); 281 } 282 283 /* 284 * Convert HAL channels to ieee80211 ones and insert 285 * them in the table according to their channel number. 286 */ 287 for (i = 0; i < nchan; i++) { 288 HAL_CHANNEL *c = &chans[i]; 289 uint16_t flags; 290 ix = ath_hal_mhz2ieee(ah, c->channel, c->channelFlags); 291 if (ix > IEEE80211_CHAN_MAX) { 292 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_getchannels(): " 293 "bad hal channel %d (%u/%x) ignored\n", 294 ix, c->channel, c->channelFlags)); 295 continue; 296 } 297 /* NB: flags are known to be compatible */ 298 if (ix < 0) { 299 /* 300 * can't handle frequency <2400MHz (negative 301 * channels) right now 302 */ 303 ATH_DEBUG((ATH_DBG_AUX, "ath:ath_getchannels(): " 304 "hal channel %d (%u/%x) " 305 "cannot be handled, ignored\n", 306 ix, c->channel, c->channelFlags)); 307 continue; 308 } 309 /* 310 * Calculate net80211 flags; most are compatible 311 * but some need massaging. Note the static turbo 312 * conversion can be removed once net80211 is updated 313 * to understand static vs. dynamic turbo. 314 */ 315 flags = c->channelFlags & CHANNEL_COMPAT; 316 if (c->channelFlags & CHANNEL_STURBO) 317 flags |= IEEE80211_CHAN_TURBO; 318 if (ic->ic_sup_channels[ix].ich_freq == 0) { 319 ic->ic_sup_channels[ix].ich_freq = c->channel; 320 ic->ic_sup_channels[ix].ich_flags = flags; 321 } else { 322 /* channels overlap; e.g. 11g and 11b */ 323 ic->ic_sup_channels[ix].ich_flags |= flags; 324 } 325 if ((c->channelFlags & CHANNEL_G) == CHANNEL_G) 326 asc->asc_have11g = 1; 327 } 328 kmem_free(chans, IEEE80211_CHAN_MAX * sizeof (HAL_CHANNEL)); 329 return (0); 330 } 331 332 static void 333 ath_drainq(ath_t *asc, struct ath_txq *txq) 334 { 335 struct ath_buf *bf; 336 337 /* 338 * This assumes output has been stopped. 339 */ 340 for (;;) { 341 mutex_enter(&txq->axq_lock); 342 bf = list_head(&txq->axq_list); 343 if (bf == NULL) { 344 txq->axq_link = NULL; 345 mutex_exit(&txq->axq_lock); 346 break; 347 } 348 list_remove(&txq->axq_list, bf); 349 mutex_exit(&txq->axq_lock); 350 bf->bf_in = NULL; 351 mutex_enter(&asc->asc_txbuflock); 352 list_insert_tail(&asc->asc_txbuf_list, bf); 353 mutex_exit(&asc->asc_txbuflock); 354 } 355 } 356 357 358 /* 359 * Drain the transmit queues and reclaim resources. 360 */ 361 void 362 ath_draintxq(ath_t *asc) 363 { 364 struct ath_hal *ah = asc->asc_ah; 365 struct ath_txq *txq; 366 int i; 367 368 if (!asc->asc_invalid) { 369 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { 370 if (ATH_TXQ_SETUP(asc, i)) { 371 txq = &asc->asc_txq[i]; 372 (void) ATH_HAL_STOPTXDMA(ah, txq->axq_qnum); 373 } 374 } 375 } 376 for (i = 0; i < HAL_NUM_TX_QUEUES; i++) { 377 if (ATH_TXQ_SETUP(asc, i)) { 378 ath_drainq(asc, &asc->asc_txq[i]); 379 } 380 } 381 } 382 383 384 /* Enable the receive h/w following a reset */ 385 int 386 ath_startrecv(ath_t *asc) 387 { 388 struct ath_buf *bf; 389 390 asc->asc_rxlink = NULL; 391 392 bf = list_head(&asc->asc_rxbuf_list); 393 while (bf != NULL) { 394 ath_setup_desc(asc, bf); 395 bf = list_next(&asc->asc_rxbuf_list, bf); 396 } 397 398 bf = list_head(&asc->asc_rxbuf_list); 399 ATH_HAL_PUTRXBUF(asc->asc_ah, bf->bf_daddr); 400 ATH_HAL_RXENA(asc->asc_ah); /* enable recv descriptors */ 401 ath_mode_init(asc); /* set filters, etc. */ 402 ATH_HAL_STARTPCURECV(asc->asc_ah); /* re-enable PCU/DMA engine */ 403 return (0); 404 } 405 406 /* 407 * Update internal state after a channel change. 408 */ 409 void 410 ath_chan_change(ath_t *asc, struct ieee80211_channel *chan) 411 { 412 struct ieee80211com *ic = &asc->asc_isc; 413 enum ieee80211_phymode mode; 414 415 /* 416 * Change channels and update the h/w rate map 417 * if we're switching; e.g. 11a to 11b/g. 418 */ 419 mode = ieee80211_chan2mode(ic, chan); 420 if (mode != asc->asc_curmode) 421 ath_setcurmode(asc, mode); 422 } 423 424 /* 425 * Set/change channels. If the channel is really being changed, 426 * it's done by resetting the chip. To accomplish this we must 427 * first cleanup any pending DMA. 428 */ 429 int 430 ath_chan_set(ath_t *asc, struct ieee80211_channel *chan) 431 { 432 struct ath_hal *ah = asc->asc_ah; 433 ieee80211com_t *ic = &asc->asc_isc; 434 435 if (chan != ic->ic_ibss_chan) { 436 HAL_STATUS status; 437 HAL_CHANNEL hchan; 438 439 /* 440 * To switch channels clear any pending DMA operations; 441 * wait long enough for the RX fifo to drain, reset the 442 * hardware at the new frequency, and then re-enable 443 * the relevant bits of the h/w. 444 */ 445 ATH_HAL_INTRSET(ah, 0); /* disable interrupts */ 446 ath_draintxq(asc); /* clear pending tx frames */ 447 ath_stoprecv(asc); /* turn off frame recv */ 448 /* 449 * Convert to a HAL channel description with 450 * the flags constrained to reflect the current 451 * operating mode. 452 */ 453 hchan.channel = chan->ich_freq; 454 hchan.channelFlags = ath_chan2flags(ic, chan); 455 if (!ATH_HAL_RESET(ah, (HAL_OPMODE)ic->ic_opmode, 456 &hchan, AH_TRUE, &status)) { 457 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_chan_set():" 458 "unable to reset channel %u (%uMhz)\n", 459 ieee80211_chan2ieee(ic, chan), chan->ich_freq)); 460 return (EIO); 461 } 462 asc->asc_curchan = hchan; 463 464 /* 465 * Re-enable rx framework. 466 */ 467 if (ath_startrecv(asc) != 0) { 468 ath_problem("ath: ath_chan_set(): " 469 "restarting receiving logic failed\n"); 470 return (EIO); 471 } 472 473 /* 474 * Change channels and update the h/w rate map 475 * if we're switching; e.g. 11a to 11b/g. 476 */ 477 ic->ic_ibss_chan = chan; 478 ath_chan_change(asc, chan); 479 /* 480 * Re-enable interrupts. 481 */ 482 ATH_HAL_INTRSET(ah, asc->asc_imask); 483 } 484 return (0); 485 } 486 487 488 /* 489 * Configure the beacon and sleep timers. 490 * 491 * When operating as an AP this resets the TSF and sets 492 * up the hardware to notify us when we need to issue beacons. 493 * 494 * When operating in station mode this sets up the beacon 495 * timers according to the timestamp of the last received 496 * beacon and the current TSF, configures PCF and DTIM 497 * handling, programs the sleep registers so the hardware 498 * will wakeup in time to receive beacons, and configures 499 * the beacon miss handling so we'll receive a BMISS 500 * interrupt when we stop seeing beacons from the AP 501 * we've associated with. 502 */ 503 void 504 ath_beacon_config(ath_t *asc) 505 { 506 struct ath_hal *ah = asc->asc_ah; 507 ieee80211com_t *ic = (ieee80211com_t *)asc; 508 struct ieee80211_node *in = ic->ic_bss; 509 uint32_t nexttbtt; 510 511 nexttbtt = (ATH_LE_READ_4(in->in_tstamp.data + 4) << 22) | 512 (ATH_LE_READ_4(in->in_tstamp.data) >> 10); 513 nexttbtt += in->in_intval; 514 if (ic->ic_opmode != IEEE80211_M_HOSTAP) { 515 HAL_BEACON_STATE bs; 516 517 /* NB: no PCF support right now */ 518 bzero(&bs, sizeof (bs)); 519 bs.bs_intval = in->in_intval; 520 bs.bs_nexttbtt = nexttbtt; 521 bs.bs_dtimperiod = bs.bs_intval; 522 bs.bs_nextdtim = nexttbtt; 523 524 /* 525 * Setup the number of consecutive beacons to miss 526 * before taking a BMISS interrupt. 527 * Note that we clamp the result to at most 10 beacons. 528 */ 529 bs.bs_bmissthreshold = ic->ic_bmissthreshold; 530 if (bs.bs_bmissthreshold > 10) 531 bs.bs_bmissthreshold = 10; 532 else if (bs.bs_bmissthreshold <= 0) 533 bs.bs_bmissthreshold = 1; 534 /* 535 * Calculate sleep duration. The configuration is 536 * given in ms. We insure a multiple of the beacon 537 * period is used. Also, if the sleep duration is 538 * greater than the DTIM period then it makes senses 539 * to make it a multiple of that. 540 */ 541 bs.bs_sleepduration = 542 roundup((100 * 1000) / 1024, bs.bs_intval); 543 if (bs.bs_sleepduration > bs.bs_dtimperiod) 544 bs.bs_sleepduration = 545 roundup(bs.bs_sleepduration, bs.bs_dtimperiod); 546 547 548 ATH_DEBUG((ATH_DBG_AUX, "ath: ath_beacon_config(): " 549 "intval %u nexttbtt %u dtim %u" 550 " nextdtim %u bmiss %u sleep %u\n", 551 bs.bs_intval, 552 bs.bs_nexttbtt, 553 bs.bs_dtimperiod, 554 bs.bs_nextdtim, 555 bs.bs_bmissthreshold, 556 bs.bs_sleepduration)); 557 ATH_HAL_INTRSET(ah, 0); 558 /* 559 * Reset our tsf so the hardware will update the 560 * tsf register to reflect timestamps found in 561 * received beacons. 562 */ 563 ATH_HAL_RESETTSF(ah); 564 ATH_HAL_BEACONTIMERS(ah, &bs); 565 asc->asc_imask |= HAL_INT_BMISS; 566 ATH_HAL_INTRSET(ah, asc->asc_imask); 567 } else { 568 ATH_HAL_INTRSET(ah, 0); 569 ATH_HAL_BEACONINIT(ah, nexttbtt, in->in_intval); 570 asc->asc_imask |= HAL_INT_SWBA; /* beacon prepare */ 571 ATH_HAL_INTRSET(ah, asc->asc_imask); 572 } 573 } 574 575 /* 576 * Allocate tx/rx key slots for TKIP. We allocate two slots for 577 * each key, one for decrypt/encrypt and the other for the MIC. 578 */ 579 static int 580 key_alloc_2pair(ath_t *asc, ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix) 581 { 582 uint16_t i, keyix; 583 584 ASSERT(asc->asc_splitmic); 585 for (i = 0; i < ATH_N(asc->asc_keymap)/4; i++) { 586 uint8_t b = asc->asc_keymap[i]; 587 if (b != 0xff) { 588 /* 589 * One or more slots in this byte are free. 590 */ 591 keyix = i*NBBY; 592 while (b & 1) { 593 again: 594 keyix++; 595 b >>= 1; 596 } 597 /* XXX IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV */ 598 if (isset(asc->asc_keymap, keyix+32) || 599 isset(asc->asc_keymap, keyix+64) || 600 isset(asc->asc_keymap, keyix+32+64)) { 601 /* full pair unavailable */ 602 if (keyix == (i+1)*NBBY) { 603 /* no slots were appropriate, advance */ 604 continue; 605 } 606 goto again; 607 } 608 setbit(asc->asc_keymap, keyix); 609 setbit(asc->asc_keymap, keyix+64); 610 setbit(asc->asc_keymap, keyix+32); 611 setbit(asc->asc_keymap, keyix+32+64); 612 ATH_DEBUG((ATH_DBG_AUX, 613 "key_alloc_2pair: key pair %u,%u %u,%u\n", 614 keyix, keyix+64, 615 keyix+32, keyix+32+64)); 616 *txkeyix = *rxkeyix = keyix; 617 return (1); 618 } 619 } 620 ATH_DEBUG((ATH_DBG_AUX, "key_alloc_2pair:" 621 " out of pair space\n")); 622 return (0); 623 } 624 /* 625 * Allocate a single key cache slot. 626 */ 627 static int 628 key_alloc_single(ath_t *asc, ieee80211_keyix *txkeyix, ieee80211_keyix *rxkeyix) 629 { 630 uint16_t i, keyix; 631 632 /* try i,i+32,i+64,i+32+64 to minimize key pair conflicts */ 633 for (i = 0; i < ATH_N(asc->asc_keymap); i++) { 634 uint8_t b = asc->asc_keymap[i]; 635 636 if (b != 0xff) { 637 /* 638 * One or more slots are free. 639 */ 640 keyix = i*NBBY; 641 while (b & 1) 642 keyix++, b >>= 1; 643 setbit(asc->asc_keymap, keyix); 644 ATH_DEBUG((ATH_DBG_AUX, "key_alloc_single:" 645 " key %u\n", keyix)); 646 *txkeyix = *rxkeyix = keyix; 647 return (1); 648 } 649 } 650 return (0); 651 } 652 653 /* 654 * Allocate one or more key cache slots for a unicast key. The 655 * key itself is needed only to identify the cipher. For hardware 656 * TKIP with split cipher+MIC keys we allocate two key cache slot 657 * pairs so that we can setup separate TX and RX MIC keys. Note 658 * that the MIC key for a TKIP key at slot i is assumed by the 659 * hardware to be at slot i+64. This limits TKIP keys to the first 660 * 64 entries. 661 */ 662 /* ARGSUSED */ 663 int 664 ath_key_alloc(ieee80211com_t *ic, const struct ieee80211_key *k, 665 ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) 666 { 667 ath_t *asc = (ath_t *)ic; 668 669 /* 670 * We allocate two pair for TKIP when using the h/w to do 671 * the MIC. For everything else, including software crypto, 672 * we allocate a single entry. Note that s/w crypto requires 673 * a pass-through slot on the 5211 and 5212. The 5210 does 674 * not support pass-through cache entries and we map all 675 * those requests to slot 0. 676 */ 677 if (k->wk_flags & IEEE80211_KEY_SWCRYPT) { 678 return (key_alloc_single(asc, keyix, rxkeyix)); 679 } else if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP && 680 (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && asc->asc_splitmic) { 681 return (key_alloc_2pair(asc, keyix, rxkeyix)); 682 } else { 683 return (key_alloc_single(asc, keyix, rxkeyix)); 684 } 685 } 686 687 /* 688 * Delete an entry in the key cache allocated by ath_key_alloc. 689 */ 690 int 691 ath_key_delete(ieee80211com_t *ic, const struct ieee80211_key *k) 692 { 693 ath_t *asc = (ath_t *)ic; 694 struct ath_hal *ah = asc->asc_ah; 695 const struct ieee80211_cipher *cip = k->wk_cipher; 696 ieee80211_keyix keyix = k->wk_keyix; 697 698 ATH_DEBUG((ATH_DBG_AUX, "ath_key_delete:" 699 " delete key %u ic_cipher=0x%x\n", keyix, cip->ic_cipher)); 700 701 ATH_HAL_KEYRESET(ah, keyix); 702 /* 703 * Handle split tx/rx keying required for TKIP with h/w MIC. 704 */ 705 if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && 706 (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && asc->asc_splitmic) 707 ATH_HAL_KEYRESET(ah, keyix+32); /* RX key */ 708 709 if (keyix >= IEEE80211_WEP_NKID) { 710 /* 711 * Don't touch keymap entries for global keys so 712 * they are never considered for dynamic allocation. 713 */ 714 clrbit(asc->asc_keymap, keyix); 715 if (cip->ic_cipher == IEEE80211_CIPHER_TKIP && 716 (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && 717 asc->asc_splitmic) { 718 clrbit(asc->asc_keymap, keyix+64); /* TX key MIC */ 719 clrbit(asc->asc_keymap, keyix+32); /* RX key */ 720 clrbit(asc->asc_keymap, keyix+32+64); /* RX key MIC */ 721 } 722 } 723 return (1); 724 } 725 726 static void 727 ath_keyprint(const char *tag, uint_t ix, 728 const HAL_KEYVAL *hk, const uint8_t mac[IEEE80211_ADDR_LEN]) 729 { 730 static const char *ciphers[] = { 731 "WEP", 732 "AES-OCB", 733 "AES-CCM", 734 "CKIP", 735 "TKIP", 736 "CLR", 737 }; 738 int i, n; 739 char buf[MAX_IEEE80211STR], buft[32]; 740 741 (void) snprintf(buf, sizeof (buf), "%s: [%02u] %s ", 742 tag, ix, ciphers[hk->kv_type]); 743 for (i = 0, n = hk->kv_len; i < n; i++) { 744 (void) snprintf(buft, sizeof (buft), "%02x", hk->kv_val[i]); 745 (void) strlcat(buf, buft, sizeof (buf)); 746 } 747 (void) snprintf(buft, sizeof (buft), " mac %s", 748 ieee80211_macaddr_sprintf(mac)); 749 (void) strlcat(buf, buft, sizeof (buf)); 750 if (hk->kv_type == HAL_CIPHER_TKIP) { 751 (void) snprintf(buft, sizeof (buft), " mic "); 752 (void) strlcat(buf, buft, sizeof (buf)); 753 for (i = 0; i < sizeof (hk->kv_mic); i++) { 754 (void) snprintf(buft, sizeof (buft), "%02x", 755 hk->kv_mic[i]); 756 (void) strlcat(buf, buft, sizeof (buf)); 757 } 758 } 759 ATH_DEBUG((ATH_DBG_AUX, "%s", buf)); 760 } 761 762 /* 763 * Set a TKIP key into the hardware. This handles the 764 * potential distribution of key state to multiple key 765 * cache slots for TKIP. 766 */ 767 static int 768 ath_keyset_tkip(ath_t *asc, const struct ieee80211_key *k, 769 HAL_KEYVAL *hk, const uint8_t mac[IEEE80211_ADDR_LEN]) 770 { 771 #define IEEE80211_KEY_XR (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV) 772 static const uint8_t zerobssid[IEEE80211_ADDR_LEN] = {0, 0, 0, 0, 0, 0}; 773 struct ath_hal *ah = asc->asc_ah; 774 775 ASSERT(k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP); 776 if ((k->wk_flags & IEEE80211_KEY_XR) == IEEE80211_KEY_XR) { 777 /* 778 * TX key goes at first index, RX key at +32. 779 * The hal handles the MIC keys at index+64. 780 */ 781 (void) memcpy(hk->kv_mic, k->wk_txmic, sizeof (hk->kv_mic)); 782 ath_keyprint("ath_keyset_tkip:", k->wk_keyix, hk, zerobssid); 783 if (!ATH_HAL_KEYSET(ah, k->wk_keyix, hk, zerobssid)) 784 return (0); 785 786 (void) memcpy(hk->kv_mic, k->wk_rxmic, sizeof (hk->kv_mic)); 787 ath_keyprint("ath_keyset_tkip:", k->wk_keyix+32, hk, mac); 788 return (ATH_HAL_KEYSET(ah, k->wk_keyix+32, hk, mac)); 789 } else if (k->wk_flags & IEEE80211_KEY_XR) { 790 /* 791 * TX/RX key goes at first index. 792 * The hal handles the MIC keys are index+64. 793 */ 794 (void) memcpy(hk->kv_mic, k->wk_flags & IEEE80211_KEY_XMIT ? 795 k->wk_txmic : k->wk_rxmic, sizeof (hk->kv_mic)); 796 ath_keyprint("ath_keyset_tkip:", k->wk_keyix, hk, zerobssid); 797 return (ATH_HAL_KEYSET(ah, k->wk_keyix, hk, zerobssid)); 798 } 799 return (0); 800 #undef IEEE80211_KEY_XR 801 } 802 803 /* 804 * Set the key cache contents for the specified key. Key cache 805 * slot(s) must already have been allocated by ath_key_alloc. 806 */ 807 int 808 ath_key_set(ieee80211com_t *ic, const struct ieee80211_key *k, 809 const uint8_t mac[IEEE80211_ADDR_LEN]) 810 { 811 static const uint8_t ciphermap[] = { 812 HAL_CIPHER_WEP, /* IEEE80211_CIPHER_WEP */ 813 HAL_CIPHER_TKIP, /* IEEE80211_CIPHER_TKIP */ 814 HAL_CIPHER_AES_OCB, /* IEEE80211_CIPHER_AES_OCB */ 815 HAL_CIPHER_AES_CCM, /* IEEE80211_CIPHER_AES_CCM */ 816 HAL_CIPHER_CKIP, /* IEEE80211_CIPHER_CKIP */ 817 HAL_CIPHER_CLR, /* IEEE80211_CIPHER_NONE */ 818 }; 819 ath_t *asc = (ath_t *)ic; 820 struct ath_hal *ah = asc->asc_ah; 821 const struct ieee80211_cipher *cip = k->wk_cipher; 822 HAL_KEYVAL hk; 823 824 bzero(&hk, sizeof (hk)); 825 /* 826 * Software crypto uses a "clear key" so non-crypto 827 * state kept in the key cache are maintainedd so that 828 * rx frames have an entry to match. 829 */ 830 if ((k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) { 831 ASSERT(cip->ic_cipher < ATH_N(ciphermap)); 832 hk.kv_type = ciphermap[cip->ic_cipher]; 833 hk.kv_len = k->wk_keylen; 834 bcopy(k->wk_key, hk.kv_val, k->wk_keylen); 835 } else { 836 hk.kv_type = HAL_CIPHER_CLR; 837 } 838 839 if (hk.kv_type == HAL_CIPHER_TKIP && 840 (k->wk_flags & IEEE80211_KEY_SWMIC) == 0 && 841 asc->asc_splitmic) { 842 return (ath_keyset_tkip(asc, k, &hk, mac)); 843 } else { 844 ath_keyprint("ath_keyset:", k->wk_keyix, &hk, mac); 845 return (ATH_HAL_KEYSET(ah, k->wk_keyix, &hk, mac)); 846 } 847 } 848 849 /* 850 * Enable/Disable short slot timing 851 */ 852 void 853 ath_set_shortslot(ieee80211com_t *ic, int onoff) 854 { 855 struct ath_hal *ah = ((ath_t *)ic)->asc_ah; 856 857 if (onoff) 858 ATH_HAL_SETSLOTTIME(ah, HAL_SLOT_TIME_9); 859 else 860 ATH_HAL_SETSLOTTIME(ah, HAL_SLOT_TIME_20); 861 } 862 863 int 864 ath_reset(ieee80211com_t *ic) 865 { 866 ath_t *asc = (ath_t *)ic; 867 struct ath_hal *ah = asc->asc_ah; 868 struct ieee80211_channel *ch; 869 HAL_STATUS status; 870 HAL_CHANNEL hchan; 871 872 /* 873 * Convert to a HAL channel description with the flags 874 * constrained to reflect the current operating mode. 875 */ 876 ch = ic->ic_curchan; 877 asc->asc_curchan.channel = ch->ich_freq; 878 asc->asc_curchan.channelFlags = ath_chan2flags(ic, ch); 879 880 ATH_HAL_INTRSET(ah, 0); /* disable interrupts */ 881 ath_draintxq(asc); /* stop xmit side */ 882 if (ATH_IS_RUNNING(asc)) { 883 ath_stoprecv(asc); /* stop recv side */ 884 /* indicate channel change so we do a full reset */ 885 if (!ATH_HAL_RESET(ah, (HAL_OPMODE)ic->ic_opmode, &hchan, 886 AH_TRUE, &status)) { 887 ath_problem("ath: ath_reset(): " 888 "resetting hardware failed, HAL status %u\n", 889 status); 890 } 891 ath_chan_change(asc, ch); 892 } 893 if (ATH_IS_RUNNING(asc)) { 894 if (ath_startrecv(asc) != 0) /* restart recv */ 895 ath_problem("ath: ath_reset(): " 896 "starting receiving logic failed\n"); 897 if (ic->ic_state == IEEE80211_S_RUN) { 898 ath_beacon_config(asc); /* restart beacons */ 899 } 900 ATH_HAL_INTRSET(ah, asc->asc_imask); 901 } 902 return (0); 903 } 904