485 err = arn_buflist_setup(devinfo, sc, &sc->sc_txbuf_list, &bf, &ds,
486 ATH_TXBUF, DDI_DMA_STREAMING, sc->tx_dmabuf_size);
487 if (err != DDI_SUCCESS) {
488 arn_desc_free(sc);
489 return (err);
490 }
491
492 /* create beacon buffer list */
493 #ifdef ARN_IBSS
494 err = arn_buflist_setup(devinfo, sc, &sc->sc_bcbuf_list, &bf, &ds,
495 ATH_BCBUF, DDI_DMA_STREAMING);
496 if (err != DDI_SUCCESS) {
497 arn_desc_free(sc);
498 return (err);
499 }
500 #endif
501
502 return (DDI_SUCCESS);
503 }
504
505 static struct ath_rate_table *
506 /* LINTED E_STATIC_UNUSED */
507 arn_get_ratetable(struct arn_softc *sc, uint32_t mode)
508 {
509 struct ath_rate_table *rate_table = NULL;
510
511 switch (mode) {
512 case IEEE80211_MODE_11A:
513 rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
514 break;
515 case IEEE80211_MODE_11B:
516 rate_table = sc->hw_rate_table[ATH9K_MODE_11B];
517 break;
518 case IEEE80211_MODE_11G:
519 rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
520 break;
521 #ifdef ARB_11N
522 case IEEE80211_MODE_11NA_HT20:
523 rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
524 break;
525 case IEEE80211_MODE_11NG_HT20:
526 rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
527 break;
528 case IEEE80211_MODE_11NA_HT40PLUS:
529 rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
530 break;
531 case IEEE80211_MODE_11NA_HT40MINUS:
532 rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
533 break;
534 case IEEE80211_MODE_11NG_HT40PLUS:
535 rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
536 break;
537 case IEEE80211_MODE_11NG_HT40MINUS:
538 rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
539 break;
540 #endif
541 default:
542 ARN_DBG((ARN_DBG_FATAL, "arn: arn_get_ratetable(): "
543 "invalid mode %u\n", mode));
544 return (NULL);
545 }
546
547 return (rate_table);
548
549 }
550
551 static void
552 arn_setcurmode(struct arn_softc *sc, enum wireless_mode mode)
553 {
554 struct ath_rate_table *rt;
555 int i;
556
557 for (i = 0; i < sizeof (sc->asc_rixmap); i++)
558 sc->asc_rixmap[i] = 0xff;
559
560 rt = sc->hw_rate_table[mode];
561 ASSERT(rt != NULL);
562
563 for (i = 0; i < rt->rate_cnt; i++)
564 sc->asc_rixmap[rt->info[i].dot11rate &
565 IEEE80211_RATE_VAL] = (uint8_t)i; /* LINT */
566
567 sc->sc_currates = rt;
568 sc->sc_curmode = mode;
569
570 /*
959 if (curmode != sc->sc_curmode)
960 arn_setcurmode(sc, arn_chan2mode(hchan));
961
962 arn_update_txpow(sc);
963
964 (void) ath9k_hw_set_interrupts(ah, sc->sc_imask);
965 }
966
967 return (0);
968 }
969
970 /*
971 * This routine performs the periodic noise floor calibration function
972 * that is used to adjust and optimize the chip performance. This
973 * takes environmental changes (location, temperature) into account.
974 * When the task is complete, it reschedules itself depending on the
975 * appropriate interval that was calculated.
976 */
977 static void
978 arn_ani_calibrate(void *arg)
979
980 {
981 ieee80211com_t *ic = (ieee80211com_t *)arg;
982 struct arn_softc *sc = (struct arn_softc *)ic;
983 struct ath_hal *ah = sc->sc_ah;
984 boolean_t longcal = B_FALSE;
985 boolean_t shortcal = B_FALSE;
986 boolean_t aniflag = B_FALSE;
987 unsigned int timestamp = drv_hztousec(ddi_get_lbolt())/1000;
988 uint32_t cal_interval;
989
990 /*
991 * don't calibrate when we're scanning.
992 * we are most likely not on our home channel.
993 */
994 if (ic->ic_state != IEEE80211_S_RUN)
995 goto settimer;
996
997 /* Long calibration runs independently of short calibration. */
998 if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) {
999 longcal = B_TRUE;
2611 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
2612 ATH9K_CIPHER_AES_OCB, NULL))
2613 ic->ic_caps |= IEEE80211_C_AES;
2614 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
2615 ATH9K_CIPHER_TKIP, NULL))
2616 ic->ic_caps |= IEEE80211_C_TKIP;
2617 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
2618 ATH9K_CIPHER_WEP, NULL))
2619 ic->ic_caps |= IEEE80211_C_WEP;
2620 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
2621 ATH9K_CIPHER_MIC, NULL))
2622 ic->ic_caps |= IEEE80211_C_TKIPMIC;
2623 }
2624
2625 static void
2626 arn_setup_ht_cap(struct arn_softc *sc)
2627 {
2628 #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
2629 #define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
2630
2631 /* LINTED E_FUNC_SET_NOT_USED */
2632 uint8_t tx_streams;
2633 uint8_t rx_streams;
2634
2635 arn_ht_conf *ht_info = &sc->sc_ht_conf;
2636
2637 ht_info->ht_supported = B_TRUE;
2638
2639 /* Todo: IEEE80211_HTCAP_SMPS */
2640 ht_info->cap = IEEE80211_HTCAP_CHWIDTH40|
2641 IEEE80211_HTCAP_SHORTGI40 |
2642 IEEE80211_HTCAP_DSSSCCK40;
2643
2644 ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
2645 ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
2646
2647 /* set up supported mcs set */
2648 (void) memset(&ht_info->rx_mcs_mask, 0, sizeof (ht_info->rx_mcs_mask));
2649 tx_streams = ISP2(sc->sc_ah->ah_caps.tx_chainmask) ? 1 : 2;
2650 rx_streams = ISP2(sc->sc_ah->ah_caps.rx_chainmask) ? 1 : 2;
2651
2652 ht_info->rx_mcs_mask[0] = 0xff;
2653 if (rx_streams >= 2)
2654 ht_info->rx_mcs_mask[1] = 0xff;
2655 }
2656
2657 /* xxx should be used for ht rate set negotiating ? */
2658 static void
2659 arn_overwrite_11n_rateset(struct arn_softc *sc)
2660 {
2661 uint8_t *ht_rs = sc->sc_ht_conf.rx_mcs_mask;
2662 int mcs_idx, mcs_count = 0;
2663 int i, j;
2664
2665 (void) memset(&ieee80211_rateset_11n, 0,
2666 sizeof (ieee80211_rateset_11n));
2667 for (i = 0; i < 10; i++) {
2668 for (j = 0; j < 8; j++) {
2669 if (ht_rs[i] & (1 << j)) {
3484 * Disable RX HW
3485 */
3486 ath9k_hw_stoppcurecv(ah);
3487 ath9k_hw_setrxfilter(ah, 0);
3488 (void) ath9k_hw_stopdmarecv(ah);
3489 drv_usecwait(3000);
3490
3491 /*
3492 * Power down HW
3493 */
3494 (void) ath9k_hw_phy_disable(ah);
3495
3496 return (DDI_SUCCESS);
3497 }
3498
3499 DDI_DEFINE_STREAM_OPS(arn_dev_ops, nulldev, nulldev, arn_attach, arn_detach,
3500 nodev, NULL, D_MP, NULL, arn_quiesce);
3501
3502 static struct modldrv arn_modldrv = {
3503 &mod_driverops, /* Type of module. This one is a driver */
3504 "arn-Atheros 9000 series driver:2.0", /* short description */
3505 &arn_dev_ops /* driver specific ops */
3506 };
3507
3508 static struct modlinkage modlinkage = {
3509 MODREV_1, (void *)&arn_modldrv, NULL
3510 };
3511
3512 int
3513 _info(struct modinfo *modinfop)
3514 {
3515 return (mod_info(&modlinkage, modinfop));
3516 }
3517
3518 int
3519 _init(void)
3520 {
3521 int status;
3522
3523 status = ddi_soft_state_init
3524 (&arn_soft_state_p, sizeof (struct arn_softc), 1);
|
485 err = arn_buflist_setup(devinfo, sc, &sc->sc_txbuf_list, &bf, &ds,
486 ATH_TXBUF, DDI_DMA_STREAMING, sc->tx_dmabuf_size);
487 if (err != DDI_SUCCESS) {
488 arn_desc_free(sc);
489 return (err);
490 }
491
492 /* create beacon buffer list */
493 #ifdef ARN_IBSS
494 err = arn_buflist_setup(devinfo, sc, &sc->sc_bcbuf_list, &bf, &ds,
495 ATH_BCBUF, DDI_DMA_STREAMING);
496 if (err != DDI_SUCCESS) {
497 arn_desc_free(sc);
498 return (err);
499 }
500 #endif
501
502 return (DDI_SUCCESS);
503 }
504
505 static void
506 arn_setcurmode(struct arn_softc *sc, enum wireless_mode mode)
507 {
508 struct ath_rate_table *rt;
509 int i;
510
511 for (i = 0; i < sizeof (sc->asc_rixmap); i++)
512 sc->asc_rixmap[i] = 0xff;
513
514 rt = sc->hw_rate_table[mode];
515 ASSERT(rt != NULL);
516
517 for (i = 0; i < rt->rate_cnt; i++)
518 sc->asc_rixmap[rt->info[i].dot11rate &
519 IEEE80211_RATE_VAL] = (uint8_t)i; /* LINT */
520
521 sc->sc_currates = rt;
522 sc->sc_curmode = mode;
523
524 /*
913 if (curmode != sc->sc_curmode)
914 arn_setcurmode(sc, arn_chan2mode(hchan));
915
916 arn_update_txpow(sc);
917
918 (void) ath9k_hw_set_interrupts(ah, sc->sc_imask);
919 }
920
921 return (0);
922 }
923
924 /*
925 * This routine performs the periodic noise floor calibration function
926 * that is used to adjust and optimize the chip performance. This
927 * takes environmental changes (location, temperature) into account.
928 * When the task is complete, it reschedules itself depending on the
929 * appropriate interval that was calculated.
930 */
931 static void
932 arn_ani_calibrate(void *arg)
933 {
934 ieee80211com_t *ic = (ieee80211com_t *)arg;
935 struct arn_softc *sc = (struct arn_softc *)ic;
936 struct ath_hal *ah = sc->sc_ah;
937 boolean_t longcal = B_FALSE;
938 boolean_t shortcal = B_FALSE;
939 boolean_t aniflag = B_FALSE;
940 unsigned int timestamp = drv_hztousec(ddi_get_lbolt())/1000;
941 uint32_t cal_interval;
942
943 /*
944 * don't calibrate when we're scanning.
945 * we are most likely not on our home channel.
946 */
947 if (ic->ic_state != IEEE80211_S_RUN)
948 goto settimer;
949
950 /* Long calibration runs independently of short calibration. */
951 if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) {
952 longcal = B_TRUE;
2564 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
2565 ATH9K_CIPHER_AES_OCB, NULL))
2566 ic->ic_caps |= IEEE80211_C_AES;
2567 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
2568 ATH9K_CIPHER_TKIP, NULL))
2569 ic->ic_caps |= IEEE80211_C_TKIP;
2570 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
2571 ATH9K_CIPHER_WEP, NULL))
2572 ic->ic_caps |= IEEE80211_C_WEP;
2573 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
2574 ATH9K_CIPHER_MIC, NULL))
2575 ic->ic_caps |= IEEE80211_C_TKIPMIC;
2576 }
2577
2578 static void
2579 arn_setup_ht_cap(struct arn_softc *sc)
2580 {
2581 #define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
2582 #define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
2583
2584 uint8_t rx_streams;
2585
2586 arn_ht_conf *ht_info = &sc->sc_ht_conf;
2587
2588 ht_info->ht_supported = B_TRUE;
2589
2590 /* Todo: IEEE80211_HTCAP_SMPS */
2591 ht_info->cap = IEEE80211_HTCAP_CHWIDTH40|
2592 IEEE80211_HTCAP_SHORTGI40 |
2593 IEEE80211_HTCAP_DSSSCCK40;
2594
2595 ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
2596 ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
2597
2598 /* set up supported mcs set */
2599 (void) memset(&ht_info->rx_mcs_mask, 0, sizeof (ht_info->rx_mcs_mask));
2600 rx_streams = ISP2(sc->sc_ah->ah_caps.rx_chainmask) ? 1 : 2;
2601
2602 ht_info->rx_mcs_mask[0] = 0xff;
2603 if (rx_streams >= 2)
2604 ht_info->rx_mcs_mask[1] = 0xff;
2605 }
2606
2607 /* xxx should be used for ht rate set negotiating ? */
2608 static void
2609 arn_overwrite_11n_rateset(struct arn_softc *sc)
2610 {
2611 uint8_t *ht_rs = sc->sc_ht_conf.rx_mcs_mask;
2612 int mcs_idx, mcs_count = 0;
2613 int i, j;
2614
2615 (void) memset(&ieee80211_rateset_11n, 0,
2616 sizeof (ieee80211_rateset_11n));
2617 for (i = 0; i < 10; i++) {
2618 for (j = 0; j < 8; j++) {
2619 if (ht_rs[i] & (1 << j)) {
3434 * Disable RX HW
3435 */
3436 ath9k_hw_stoppcurecv(ah);
3437 ath9k_hw_setrxfilter(ah, 0);
3438 (void) ath9k_hw_stopdmarecv(ah);
3439 drv_usecwait(3000);
3440
3441 /*
3442 * Power down HW
3443 */
3444 (void) ath9k_hw_phy_disable(ah);
3445
3446 return (DDI_SUCCESS);
3447 }
3448
3449 DDI_DEFINE_STREAM_OPS(arn_dev_ops, nulldev, nulldev, arn_attach, arn_detach,
3450 nodev, NULL, D_MP, NULL, arn_quiesce);
3451
3452 static struct modldrv arn_modldrv = {
3453 &mod_driverops, /* Type of module. This one is a driver */
3454 "Atheros 9000 series driver", /* short description */
3455 &arn_dev_ops /* driver specific ops */
3456 };
3457
3458 static struct modlinkage modlinkage = {
3459 MODREV_1, (void *)&arn_modldrv, NULL
3460 };
3461
3462 int
3463 _info(struct modinfo *modinfop)
3464 {
3465 return (mod_info(&modlinkage, modinfop));
3466 }
3467
3468 int
3469 _init(void)
3470 {
3471 int status;
3472
3473 status = ddi_soft_state_init
3474 (&arn_soft_state_p, sizeof (struct arn_softc), 1);
|