Print this page
7154 arn(7D) walks out of bounds when byteswapping the 4K eeprom
7152 weird condition in arn(7D) needs clarification
7153 delete unused code in arn(7D)
7155 arn(7D) should include the mac fields in the eeprom enumeration


 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);