1 /* 2 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* 7 * Copyright (c) 2008 Atheros Communications Inc. 8 * 9 * Permission to use, copy, modify, and/or distribute this software for any 10 * purpose with or without fee is hereby granted, provided that the above 11 * copyright notice and this permission notice appear in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 */ 21 22 #include <sys/byteorder.h> 23 24 #include "arn_core.h" 25 26 /* 27 * Setup and link descriptors. 28 * 29 * 11N: we can no longer afford to self link the last descriptor. 30 * MAC acknowledges BA status as long as it copies frames to host 31 * buffer (or rx fifo). This can incorrectly acknowledge packets 32 * to a sender if last desc is self-linked. 33 */ 34 void 35 arn_rx_buf_link(struct arn_softc *sc, struct ath_buf *bf) 36 { 37 struct ath_desc *ds; 38 39 ds = bf->bf_desc; 40 ds->ds_link = 0; 41 ds->ds_data = bf->bf_dma.cookie.dmac_address; 42 43 /* virtual addr of the beginning of the buffer. */ 44 ds->ds_vdata = bf->bf_dma.mem_va; 45 46 /* 47 * setup rx descriptors. The bf_dma.alength here tells the H/W 48 * how much data it can DMA to us and that we are prepared 49 * to process 50 */ 51 (void) ath9k_hw_setuprxdesc(sc->sc_ah, ds, 52 bf->bf_dma.alength, /* buffer size */ 53 0); 54 55 if (sc->sc_rxlink == NULL) 56 ath9k_hw_putrxbuf(sc->sc_ah, bf->bf_daddr); 57 else 58 *sc->sc_rxlink = bf->bf_daddr; 59 60 sc->sc_rxlink = &ds->ds_link; 61 ath9k_hw_rxena(sc->sc_ah); 62 } 63 64 void 65 arn_setdefantenna(struct arn_softc *sc, uint32_t antenna) 66 { 67 /* XXX block beacon interrupts */ 68 ath9k_hw_setantenna(sc->sc_ah, antenna); 69 sc->sc_defant = (uint8_t)antenna; /* LINT */ 70 sc->sc_rxotherant = 0; 71 } 72 73 /* 74 * Extend 15-bit time stamp from rx descriptor to 75 * a full 64-bit TSF using the current h/w TSF. 76 */ 77 78 static uint64_t 79 arn_extend_tsf(struct arn_softc *sc, uint32_t rstamp) 80 { 81 uint64_t tsf; 82 83 tsf = ath9k_hw_gettsf64(sc->sc_ah); 84 if ((tsf & 0x7fff) < rstamp) 85 tsf -= 0x8000; 86 return ((tsf & ~0x7fff) | rstamp); 87 } 88 89 static int 90 arn_rx_prepare(struct ath_desc *ds, struct arn_softc *sc) 91 { 92 uint8_t phyerr; 93 94 if (ds->ds_rxstat.rs_more) { 95 /* 96 * Frame spans multiple descriptors; this cannot happen yet 97 * as we don't support jumbograms. If not in monitor mode, 98 * discard the frame. Enable this if you want to see 99 * error frames in Monitor mode. 100 */ 101 if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR) 102 goto rx_next; 103 } else if (ds->ds_rxstat.rs_status != 0) { 104 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) { 105 sc->sc_stats.ast_rx_crcerr++; 106 goto rx_next; /* should ignore? */ 107 } 108 109 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_FIFO) { 110 sc->sc_stats.ast_rx_fifoerr++; 111 } 112 113 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) { 114 sc->sc_stats.ast_rx_phyerr++; 115 phyerr = ds->ds_rxstat.rs_phyerr & 0x1f; 116 sc->sc_stats.ast_rx_phy[phyerr]++; 117 goto rx_next; 118 } 119 120 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) { 121 sc->sc_stats.ast_rx_badcrypt++; 122 } 123 124 /* 125 * Reject error frames with the exception of 126 * decryption and MIC failures. For monitor mode, 127 * we also ignore the CRC error. 128 */ 129 if (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR) { 130 if (ds->ds_rxstat.rs_status & 131 ~(ATH9K_RXERR_DECRYPT | 132 ATH9K_RXERR_MIC | 133 ATH9K_RXERR_CRC)) 134 goto rx_next; 135 } else { 136 if (ds->ds_rxstat.rs_status & 137 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { 138 goto rx_next; 139 } 140 } 141 } 142 143 return (1); 144 rx_next: 145 return (0); 146 } 147 148 149 static void 150 arn_opmode_init(struct arn_softc *sc) 151 { 152 struct ath_hal *ah = sc->sc_ah; 153 uint32_t rfilt; 154 uint32_t mfilt[2]; 155 ieee80211com_t *ic = (ieee80211com_t *)sc; 156 157 /* configure rx filter */ 158 rfilt = arn_calcrxfilter(sc); 159 ath9k_hw_setrxfilter(ah, rfilt); 160 161 /* configure bssid mask */ 162 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) 163 (void) ath9k_hw_setbssidmask(ah, sc->sc_bssidmask); 164 165 /* configure operational mode */ 166 ath9k_hw_setopmode(ah); 167 168 /* Handle any link-level address change. */ 169 (void) ath9k_hw_setmac(ah, sc->sc_myaddr); 170 171 /* calculate and install multicast filter */ 172 mfilt[0] = ~((uint32_t)0); /* LINT */ 173 mfilt[1] = ~((uint32_t)0); /* LINT */ 174 175 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); 176 177 ARN_DBG((ARN_DBG_RECV, "arn: arn_opmode_init(): " 178 "mode = %d RX filter 0x%x, MC filter %08x:%08x\n", 179 ic->ic_opmode, rfilt, mfilt[0], mfilt[1])); 180 } 181 182 /* 183 * Calculate the receive filter according to the 184 * operating mode and state: 185 * 186 * o always accept unicast, broadcast, and multicast traffic 187 * o maintain current state of phy error reception (the hal 188 * may enable phy error frames for noise immunity work) 189 * o probe request frames are accepted only when operating in 190 * hostap, adhoc, or monitor modes 191 * o enable promiscuous mode according to the interface state 192 * o accept beacons: 193 * - when operating in adhoc mode so the 802.11 layer creates 194 * node table entries for peers, 195 * - when operating in station mode for collecting rssi data when 196 * the station is otherwise quiet, or 197 * - when operating as a repeater so we see repeater-sta beacons 198 * - when scanning 199 */ 200 201 uint32_t 202 arn_calcrxfilter(struct arn_softc *sc) 203 { 204 #define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | \ 205 ATH9K_RX_FILTER_PHYRADAR) 206 207 uint32_t rfilt; 208 209 rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE) | 210 ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | 211 ATH9K_RX_FILTER_MCAST; 212 213 /* If not a STA, enable processing of Probe Requests */ 214 if (sc->sc_ah->ah_opmode != ATH9K_M_STA) 215 rfilt |= ATH9K_RX_FILTER_PROBEREQ; 216 217 /* Can't set HOSTAP into promiscous mode */ 218 if (((sc->sc_ah->ah_opmode != ATH9K_M_HOSTAP) && 219 (sc->sc_promisc)) || 220 (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR)) { 221 rfilt |= ATH9K_RX_FILTER_PROM; 222 /* ??? To prevent from sending ACK */ 223 rfilt &= ~ATH9K_RX_FILTER_UCAST; 224 } 225 226 if (sc->sc_ah->ah_opmode == ATH9K_M_STA || 227 sc->sc_ah->ah_opmode == ATH9K_M_IBSS) 228 rfilt |= ATH9K_RX_FILTER_BEACON; 229 230 /* 231 * If in HOSTAP mode, want to enable reception of PSPOLL 232 * frames & beacon frames 233 */ 234 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) 235 rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); 236 237 return (rfilt); 238 239 #undef RX_FILTER_PRESERVE 240 } 241 242 /* 243 * When block ACK agreement has been set up between station and AP, 244 * Net80211 module will call this function to inform hardware about 245 * informations of this BA agreement. 246 * When AP wants to delete BA agreement that was originated by it, 247 * Net80211 modele will call this function to clean up relevant 248 * information in hardware. 249 */ 250 251 void 252 arn_ampdu_recv_action(struct ieee80211_node *in, 253 const uint8_t *frm, 254 const uint8_t *efrm) 255 { 256 struct ieee80211com *ic; 257 struct arn_softc *sc; 258 259 if ((in == NULL) || (frm == NULL) || (ic = in->in_ic) == NULL) { 260 ARN_DBG((ARN_DBG_FATAL, 261 "Unknown AMPDU action or NULL node index\n")); 262 return; 263 } 264 265 sc = (struct arn_softc *)ic; 266 267 if (!(sc->sc_flags & SC_OP_RXAGGR)) 268 return; 269 else 270 sc->sc_recv_action(in, frm, efrm); 271 } 272 273 int 274 arn_startrecv(struct arn_softc *sc) 275 { 276 struct ath_hal *ah = sc->sc_ah; 277 struct ath_buf *bf; 278 279 /* rx descriptor link set up */ 280 mutex_enter(&sc->sc_rxbuflock); 281 if (list_empty(&sc->sc_rxbuf_list)) 282 goto start_recv; 283 284 /* clean up rx link firstly */ 285 sc->sc_rxlink = NULL; 286 287 bf = list_head(&sc->sc_rxbuf_list); 288 while (bf != NULL) { 289 arn_rx_buf_link(sc, bf); 290 bf = list_next(&sc->sc_rxbuf_list, bf); 291 } 292 293 294 /* We could have deleted elements so the list may be empty now */ 295 if (list_empty(&sc->sc_rxbuf_list)) 296 goto start_recv; 297 298 bf = list_head(&sc->sc_rxbuf_list); 299 300 ath9k_hw_putrxbuf(ah, bf->bf_daddr); 301 ath9k_hw_rxena(ah); 302 303 start_recv: 304 mutex_exit(&sc->sc_rxbuflock); 305 arn_opmode_init(sc); 306 ath9k_hw_startpcureceive(ah); 307 308 return (0); 309 } 310 311 boolean_t 312 arn_stoprecv(struct arn_softc *sc) 313 { 314 struct ath_hal *ah = sc->sc_ah; 315 boolean_t stopped; 316 317 ath9k_hw_stoppcurecv(ah); 318 ath9k_hw_setrxfilter(ah, 0); 319 stopped = ath9k_hw_stopdmarecv(ah); 320 321 /* 3ms is long enough for 1 frame ??? */ 322 drv_usecwait(3000); 323 324 sc->sc_rxlink = NULL; 325 326 return (stopped); 327 } 328 329 /* 330 * Intercept management frames to collect beacon rssi data 331 * and to do ibss merges. 332 */ 333 334 void 335 arn_recv_mgmt(struct ieee80211com *ic, mblk_t *mp, struct ieee80211_node *in, 336 int subtype, int rssi, uint32_t rstamp) 337 { 338 struct arn_softc *sc = (struct arn_softc *)ic; 339 340 /* 341 * Call up first so subsequent work can use information 342 * potentially stored in the node (e.g. for ibss merge). 343 */ 344 sc->sc_recv_mgmt(ic, mp, in, subtype, rssi, rstamp); 345 346 ARN_LOCK(sc); 347 switch (subtype) { 348 case IEEE80211_FC0_SUBTYPE_BEACON: 349 /* update rssi statistics */ 350 if (sc->sc_bsync && in == ic->ic_bss && 351 ic->ic_state == IEEE80211_S_RUN) { 352 /* 353 * Resync beacon timers using the tsf of the beacon 354 * frame we just received. 355 */ 356 arn_beacon_config(sc); 357 } 358 /* FALLTHRU */ 359 case IEEE80211_FC0_SUBTYPE_PROBE_RESP: 360 if (ic->ic_opmode == IEEE80211_M_IBSS && 361 ic->ic_state == IEEE80211_S_RUN && 362 (in->in_capinfo & IEEE80211_CAPINFO_IBSS)) { 363 uint64_t tsf = arn_extend_tsf(sc, rstamp); 364 /* 365 * Handle ibss merge as needed; check the tsf on the 366 * frame before attempting the merge. The 802.11 spec 367 * says the station should change it's bssid to match 368 * the oldest station with the same ssid, where oldest 369 * is determined by the tsf. Note that hardware 370 * reconfiguration happens through callback to 371 * ath_newstate as the state machine will go from 372 * RUN -> RUN when this happens. 373 */ 374 if (LE_64(in->in_tstamp.tsf) >= tsf) { 375 ARN_DBG((ARN_DBG_BEACON, "arn: arn_recv_mgmt:" 376 "ibss merge, rstamp %u tsf %lu " 377 "tstamp %lu\n", rstamp, tsf, 378 in->in_tstamp.tsf)); 379 ARN_UNLOCK(sc); 380 ARN_DBG((ARN_DBG_BEACON, "arn_recv_mgmt():" 381 "ibss_merge: rstamp=%d in_tstamp=%02x %02x" 382 " %02x %02x %02x %02x %02x %02x\n", 383 rstamp, in->in_tstamp.data[0], 384 in->in_tstamp.data[1], 385 in->in_tstamp.data[2], 386 in->in_tstamp.data[3], 387 in->in_tstamp.data[4], 388 in->in_tstamp.data[5], 389 in->in_tstamp.data[6], 390 in->in_tstamp.data[7])); 391 (void) ieee80211_ibss_merge(in); 392 return; 393 } 394 } 395 break; 396 } 397 ARN_UNLOCK(sc); 398 } 399 400 static void 401 arn_printrxbuf(struct ath_buf *bf, int32_t done) 402 { 403 struct ath_desc *ds = bf->bf_desc; 404 const struct ath_rx_status *rs = &ds->ds_rxstat; 405 406 ARN_DBG((ARN_DBG_RECV, "arn: R (%p %p) %08x %08x %08x " 407 "%08x %08x %08x %c\n", 408 ds, bf->bf_daddr, 409 ds->ds_link, ds->ds_data, 410 ds->ds_ctl0, ds->ds_ctl1, 411 ds->ds_hw[0], ds->ds_hw[1], 412 !done ? ' ' : (rs->rs_status == 0) ? '*' : '!')); 413 } 414 415 static void 416 arn_rx_handler(struct arn_softc *sc) 417 { 418 #define PA2DESC(_sc, _pa) \ 419 ((struct ath_desc *)((caddr_t)(_sc)->sc_desc + \ 420 ((_pa) - (_sc)->sc_desc_dma.cookie.dmac_address))) 421 422 ieee80211com_t *ic = (ieee80211com_t *)sc; 423 struct ath_buf *bf; 424 struct ath_hal *ah = sc->sc_ah; 425 struct ath_desc *ds; 426 struct ath_rx_status *rs; 427 mblk_t *rx_mp; 428 struct ieee80211_frame *wh; 429 int32_t len, ngood = 0, loop = 1; 430 uint32_t subtype; 431 int status; 432 int last_rssi = ATH_RSSI_DUMMY_MARKER; 433 struct ath_node *an; 434 struct ieee80211_node *in; 435 uint32_t cur_signal; 436 #ifdef ARN_DBG_AMSDU 437 uint8_t qos; 438 #endif 439 440 do { 441 mutex_enter(&sc->sc_rxbuflock); 442 bf = list_head(&sc->sc_rxbuf_list); 443 if (bf == NULL) { 444 ARN_DBG((ARN_DBG_RECV, "arn: arn_rx_handler(): " 445 "no buffer\n")); 446 sc->sc_rxlink = NULL; 447 mutex_exit(&sc->sc_rxbuflock); 448 break; 449 } 450 ASSERT(bf->bf_dma.cookie.dmac_address != 0); 451 ds = bf->bf_desc; 452 453 /* 454 * Must provide the virtual address of the current 455 * descriptor, the physical address, and the virtual 456 * address of the next descriptor in the h/w chain. 457 * This allows the HAL to look ahead to see if the 458 * hardware is done with a descriptor by checking the 459 * done bit in the following descriptor and the address 460 * of the current descriptor the DMA engine is working 461 * on. All this is necessary because of our use of 462 * a self-linked list to avoid rx overruns. 463 */ 464 status = ath9k_hw_rxprocdesc(ah, ds, 465 bf->bf_daddr, 466 PA2DESC(sc, ds->ds_link), 0); 467 if (status == EINPROGRESS) { 468 struct ath_buf *tbf; 469 struct ath_desc *tds; 470 471 if (list_is_last(&bf->bf_node, &sc->sc_rxbuf_list)) { 472 ARN_DBG((ARN_DBG_RECV, "arn: arn_rx_handler(): " 473 "List is in last! \n")); 474 sc->sc_rxlink = NULL; 475 break; 476 } 477 478 tbf = list_object(&sc->sc_rxbuf_list, 479 bf->bf_node.list_next); 480 481 /* 482 * On some hardware the descriptor status words could 483 * get corrupted, including the done bit. Because of 484 * this, check if the next descriptor's done bit is 485 * set or not. 486 * 487 * If the next descriptor's done bit is set, the current 488 * descriptor has been corrupted. Force s/w to discard 489 * this descriptor and continue... 490 */ 491 492 tds = tbf->bf_desc; 493 status = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr, 494 PA2DESC(sc, tds->ds_link), 0); 495 if (status == EINPROGRESS) { 496 mutex_exit(&sc->sc_rxbuflock); 497 break; 498 } 499 } 500 list_remove(&sc->sc_rxbuf_list, bf); 501 mutex_exit(&sc->sc_rxbuflock); 502 503 rs = &ds->ds_rxstat; 504 len = rs->rs_datalen; 505 506 /* less than sizeof(struct ieee80211_frame) */ 507 if (len < 20) { 508 sc->sc_stats.ast_rx_tooshort++; 509 goto requeue; 510 } 511 512 /* The status portion of the descriptor could get corrupted. */ 513 if (sc->rx_dmabuf_size < rs->rs_datalen) { 514 arn_problem("Requeued because of wrong rs_datalen\n"); 515 goto requeue; 516 } 517 518 if (!arn_rx_prepare(ds, sc)) 519 goto requeue; 520 521 if ((rx_mp = allocb(sc->rx_dmabuf_size, BPRI_MED)) == NULL) { 522 arn_problem("arn: arn_rx_handler(): " 523 "allocing mblk buffer failed.\n"); 524 return; 525 } 526 527 ARN_DMA_SYNC(bf->bf_dma, DDI_DMA_SYNC_FORCPU); 528 bcopy(bf->bf_dma.mem_va, rx_mp->b_rptr, len); 529 530 rx_mp->b_wptr += len; 531 wh = (struct ieee80211_frame *)rx_mp->b_rptr; 532 533 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 534 IEEE80211_FC0_TYPE_CTL) { 535 /* 536 * Ignore control frame received in promisc mode. 537 */ 538 freemsg(rx_mp); 539 goto requeue; 540 } 541 /* Remove the CRC at the end of IEEE80211 frame */ 542 rx_mp->b_wptr -= IEEE80211_CRC_LEN; 543 544 #ifdef DEBUG 545 arn_printrxbuf(bf, status == 0); 546 #endif 547 548 #ifdef ARN_DBG_AMSDU 549 if (IEEE80211_IS_DATA_QOS(wh)) { 550 if ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == 551 IEEE80211_FC1_DIR_DSTODS) 552 qos = ((struct ieee80211_qosframe_addr4 *) 553 wh)->i_qos[0]; 554 else 555 qos = 556 ((struct ieee80211_qosframe *)wh)->i_qos[0]; 557 558 if (qos & IEEE80211_QOS_AMSDU) 559 arn_dump_pkg((unsigned char *)bf->bf_dma.mem_va, 560 len, 1, 1); 561 } 562 #endif /* ARN_DBG_AMSDU */ 563 564 /* 565 * Locate the node for sender, track state, and then 566 * pass the (referenced) node up to the 802.11 layer 567 * for its use. 568 */ 569 in = ieee80211_find_rxnode(ic, wh); 570 an = ATH_NODE(in); 571 572 /* 573 * Theory for reporting quality: 574 * 575 * At a hardware RSSI of 45 you will be able to use 576 * MCS 7 reliably. 577 * At a hardware RSSI of 45 you will be able to use 578 * MCS 15 reliably. 579 * At a hardware RSSI of 35 you should be able use 580 * 54 Mbps reliably. 581 * 582 * MCS 7 is the highets MCS index usable by a 1-stream device. 583 * MCS 15 is the highest MCS index usable by a 2-stream device. 584 * 585 * All ath9k devices are either 1-stream or 2-stream. 586 * 587 * How many bars you see is derived from the qual reporting. 588 * 589 * A more elaborate scheme can be used here but it requires 590 * tables of SNR/throughput for each possible mode used. For 591 * the MCS table you can refer to the wireless wiki: 592 * 593 * http://wireless.kernel.org/en/developers/Documentation/ 594 * ieee80211/802.11n 595 */ 596 if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD && 597 !ds->ds_rxstat.rs_moreaggr) { 598 /* LINTED: E_CONSTANT_CONDITION */ 599 ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi); 600 } 601 last_rssi = an->last_rssi; 602 603 if (last_rssi != ATH_RSSI_DUMMY_MARKER) 604 ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi, 605 ATH_RSSI_EP_MULTIPLIER); 606 607 if (ds->ds_rxstat.rs_rssi < 0) 608 ds->ds_rxstat.rs_rssi = 0; 609 610 if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 611 IEEE80211_FC0_TYPE_MGT) { 612 subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 613 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) 614 sc->sc_halstats.ns_avgbrssi = 615 ds->ds_rxstat.rs_rssi; 616 } 617 618 /* 619 * signal (13-15) DLADM_WLAN_STRENGTH_EXCELLENT 620 * signal (10-12) DLADM_WLAN_STRENGTH_VERY_GOOD 621 * signal (6-9) DLADM_WLAN_STRENGTH_GOOD 622 * signal (3-5) DLADM_WLAN_STRENGTH_WEAK 623 * signal (0-2) DLADM_WLAN_STRENGTH_VERY_WEAK 624 */ 625 if (rs->rs_rssi == 0) 626 cur_signal = 0; 627 else if (rs->rs_rssi >= 45) 628 cur_signal = MAX_RSSI; 629 else 630 cur_signal = rs->rs_rssi * MAX_RSSI / 45 + 1; 631 632 /* 633 * Send the frame to net80211 for processing 634 */ 635 if (cur_signal <= 2 && ic->ic_state == IEEE80211_S_RUN) { 636 (void) ieee80211_input(ic, rx_mp, in, 637 (rs->rs_rssi + 10), rs->rs_tstamp); 638 } 639 else 640 (void) ieee80211_input(ic, rx_mp, in, rs->rs_rssi, 641 rs->rs_tstamp); 642 643 /* release node */ 644 ieee80211_free_node(in); 645 646 /* 647 * Arrange to update the last rx timestamp only for 648 * frames from our ap when operating in station mode. 649 * This assumes the rx key is always setup when associated. 650 */ 651 if (ic->ic_opmode == IEEE80211_M_STA && 652 rs->rs_keyix != ATH9K_RXKEYIX_INVALID) { 653 ngood++; 654 } 655 656 /* 657 * change the default rx antenna if rx diversity chooses the 658 * other antenna 3 times in a row. 659 */ 660 if (sc->sc_defant != ds->ds_rxstat.rs_antenna) { 661 if (++sc->sc_rxotherant >= 3) { 662 ath9k_hw_setantenna(sc->sc_ah, 663 ds->ds_rxstat.rs_antenna); 664 sc->sc_defant = ds->ds_rxstat.rs_antenna; 665 sc->sc_rxotherant = 0; 666 } 667 } else { 668 sc->sc_rxotherant = 0; 669 } 670 671 requeue: 672 mutex_enter(&sc->sc_rxbuflock); 673 list_insert_tail(&sc->sc_rxbuf_list, bf); 674 mutex_exit(&sc->sc_rxbuflock); 675 arn_rx_buf_link(sc, bf); 676 } while (loop); 677 678 if (ngood) 679 sc->sc_lastrx = ath9k_hw_gettsf64(ah); 680 681 #undef PA2DESC 682 } 683 684 uint_t 685 arn_softint_handler(caddr_t data) 686 { 687 struct arn_softc *sc = (struct arn_softc *)data; 688 689 ARN_LOCK(sc); 690 691 if (sc->sc_rx_pend) { 692 /* Soft interrupt for this driver */ 693 sc->sc_rx_pend = 0; 694 ARN_UNLOCK(sc); 695 arn_rx_handler(sc); 696 return (DDI_INTR_CLAIMED); 697 } 698 699 ARN_UNLOCK(sc); 700 701 return (DDI_INTR_UNCLAIMED); 702 } 703