source: trunk/package/mac80211/patches/561-ath9k_fix_staggered_beacons.patch @ 26248

Last change on this file since 26248 was 26248, checked in by nbd, 5 years ago

ath9k: improve precision of beacon timer calculations

File size: 10.7 KB
  • drivers/net/wireless/ath/ath9k/beacon.c

    a b int ath_beaconq_config(struct ath_softc  
    5757 
    5858/* 
    5959 *  Associates the beacon frame buffer with a transmit descriptor.  Will set 
    60  *  up all required antenna switch parameters, rate codes, and channel flags. 
    61  *  Beacons are always sent out at the lowest rate, and are not retried. 
     60 *  up rate codes, and channel flags. Beacons are always sent out at the 
     61 *  lowest rate, and are not retried. 
    6262*/ 
    6363static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, 
    6464                             struct ath_buf *bf, int rateidx) 
    static void ath_beacon_setup(struct ath_ 
    6868        struct ath_common *common = ath9k_hw_common(ah); 
    6969        struct ath_desc *ds; 
    7070        struct ath9k_11n_rate_series series[4]; 
    71         int flags, antenna, ctsrate = 0, ctsduration = 0; 
     71        int flags, ctsrate = 0, ctsduration = 0; 
    7272        struct ieee80211_supported_band *sband; 
    7373        u8 rate = 0; 
    7474 
    static void ath_beacon_setup(struct ath_ 
    7676        flags = ATH9K_TXDESC_NOACK; 
    7777 
    7878        ds->ds_link = 0; 
    79         /* 
    80          * Switch antenna every beacon. 
    81          * Should only switch every beacon period, not for every SWBA 
    82          * XXX assumes two antennae 
    83          */ 
    84         antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); 
    8579 
    8680        sband = &sc->sbands[common->hw->conf.channel->band]; 
    8781        rate = sband->bitrates[rateidx].hw_value; 
    int ath_beacon_alloc(struct ath_softc *s 
    278272                return -ENOMEM; 
    279273 
    280274        tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; 
    281         sc->beacon.bc_tstamp = le64_to_cpu(tstamp); 
     275        sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp); 
    282276        /* Calculate a TSF adjustment factor required for staggered beacons. */ 
    283277        if (avp->av_bslot > 0) { 
    284278                u64 tsfadjust; 
    int ath_beacon_alloc(struct ath_softc *s 
    294288                 * adjustment. Other slots are adjusted to get the timestamp 
    295289                 * close to the TBTT for the BSS. 
    296290                 */ 
    297                 tsfadjust = intval * avp->av_bslot / ATH_BCBUF; 
    298                 avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); 
     291                tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF; 
     292                avp->tsf_adjust = cpu_to_le64(tsfadjust); 
    299293 
    300294                ath_dbg(common, ATH_DBG_BEACON, 
    301295                        "stagger beacons, bslot %d intval %u tsfadjust %llu\n", 
    void ath_beacon_tasklet(unsigned long da 
    401395        intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; 
    402396 
    403397        tsf = ath9k_hw_gettsf64(ah); 
    404         tsftu = TSF_TO_TU(tsf>>32, tsf); 
    405         slot = ((tsftu % intval) * ATH_BCBUF) / intval; 
     398        tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); 
     399        tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); 
     400        slot = (tsftu % (intval * ATH_BCBUF)) / intval; 
    406401        /* 
    407402         * Reverse the slot order to get slot 0 on the TBTT offset that does 
    408403         * not require TSF adjustment and other slots adding 
    void ath_beacon_tasklet(unsigned long da 
    415410 
    416411        ath_dbg(common, ATH_DBG_BEACON, 
    417412                "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", 
    418                 slot, tsf, tsftu, intval, vif); 
     413                slot, tsf, tsftu / ATH_BCBUF, intval, vif); 
    419414 
    420415        bfaddr = 0; 
    421416        if (vif) { 
    static void ath9k_beacon_init(struct ath 
    463458                              u32 next_beacon, 
    464459                              u32 beacon_period) 
    465460{ 
    466         if (beacon_period & ATH9K_BEACON_RESET_TSF) 
     461        if (sc->sc_flags & SC_OP_TSF_RESET) { 
    467462                ath9k_ps_wakeup(sc); 
     463                ath9k_hw_reset_tsf(sc->sc_ah); 
     464        } 
    468465 
    469466        ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); 
    470467 
    471         if (beacon_period & ATH9K_BEACON_RESET_TSF) 
     468        if (sc->sc_flags & SC_OP_TSF_RESET) { 
    472469                ath9k_ps_restore(sc); 
     470                sc->sc_flags &= ~SC_OP_TSF_RESET; 
     471        } 
    473472} 
    474473 
    475474/* 
    static void ath_beacon_config_ap(struct  
    484483        u32 nexttbtt, intval; 
    485484 
    486485        /* NB: the beacon interval is kept internally in TU's */ 
    487         intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 
     486        intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); 
    488487        intval /= ATH_BCBUF;    /* for staggered beacons */ 
    489488        nexttbtt = intval; 
    490489 
    491         if (sc->sc_flags & SC_OP_TSF_RESET) 
    492                 intval |= ATH9K_BEACON_RESET_TSF; 
    493  
    494490        /* 
    495491         * In AP mode we enable the beacon timers and SWBA interrupts to 
    496492         * prepare beacon frames. 
    497493         */ 
    498         intval |= ATH9K_BEACON_ENA; 
    499494        ah->imask |= ATH9K_INT_SWBA; 
    500495        ath_beaconq_config(sc); 
    501496 
    static void ath_beacon_config_ap(struct  
    505500        ath9k_beacon_init(sc, nexttbtt, intval); 
    506501        sc->beacon.bmisscnt = 0; 
    507502        ath9k_hw_set_interrupts(ah, ah->imask); 
    508  
    509         /* Clear the reset TSF flag, so that subsequent beacon updation 
    510            will not reset the HW TSF. */ 
    511  
    512         sc->sc_flags &= ~SC_OP_TSF_RESET; 
    513503} 
    514504 
    515505/* 
    static void ath_beacon_config_adhoc(stru 
    643633{ 
    644634        struct ath_hw *ah = sc->sc_ah; 
    645635        struct ath_common *common = ath9k_hw_common(ah); 
    646         u64 tsf; 
    647         u32 tsftu, intval, nexttbtt; 
    648  
    649         intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 
    650  
     636        u32 tsf, delta, intval, nexttbtt; 
    651637 
    652         /* Pull nexttbtt forward to reflect the current TSF */ 
     638        tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); 
     639        intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); 
    653640 
    654         nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); 
    655         if (nexttbtt == 0) 
    656                 nexttbtt = intval; 
    657         else if (intval) 
    658                 nexttbtt = roundup(nexttbtt, intval); 
    659  
    660         tsf = ath9k_hw_gettsf64(ah); 
    661         tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE; 
    662         do { 
    663                 nexttbtt += intval; 
    664         } while (nexttbtt < tsftu); 
     641        if (!sc->beacon.bc_tstamp) 
     642                nexttbtt = tsf + intval; 
     643        else { 
     644                if (tsf > sc->beacon.bc_tstamp) 
     645                        delta = (tsf - sc->beacon.bc_tstamp); 
     646                else 
     647                        delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); 
     648                nexttbtt = tsf + roundup(delta, intval); 
     649        } 
    665650 
    666651        ath_dbg(common, ATH_DBG_BEACON, 
    667652                "IBSS nexttbtt %u intval %u (%u)\n", 
    static void ath_beacon_config_adhoc(stru 
    672657         * if we need to manually prepare beacon frames.  Otherwise we use a 
    673658         * self-linked tx descriptor and let the hardware deal with things. 
    674659         */ 
    675         intval |= ATH9K_BEACON_ENA; 
    676660        ah->imask |= ATH9K_INT_SWBA; 
    677661 
    678662        ath_beaconq_config(sc); 
  • drivers/net/wireless/ath/ath9k/hw.c

    a b void ath9k_hw_beaconinit(struct ath_hw * 
    17061706        case NL80211_IFTYPE_MESH_POINT: 
    17071707                REG_SET_BIT(ah, AR_TXCFG, 
    17081708                            AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY); 
    1709                 REG_WRITE(ah, AR_NEXT_NDP_TIMER, 
    1710                           TU_TO_USEC(next_beacon + 
    1711                                      (ah->atim_window ? ah-> 
    1712                                       atim_window : 1))); 
     1709                REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon + 
     1710                          TU_TO_USEC(ah->atim_window ? ah->atim_window : 1)); 
    17131711                flags |= AR_NDP_TIMER_EN; 
    17141712        case NL80211_IFTYPE_AP: 
    1715                 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon)); 
    1716                 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 
    1717                           TU_TO_USEC(next_beacon - 
    1718                                      ah->config. 
    1719                                      dma_beacon_response_time)); 
    1720                 REG_WRITE(ah, AR_NEXT_SWBA, 
    1721                           TU_TO_USEC(next_beacon - 
    1722                                      ah->config. 
    1723                                      sw_beacon_response_time)); 
     1713                REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon); 
     1714                REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon - 
     1715                          TU_TO_USEC(ah->config.dma_beacon_response_time)); 
     1716                REG_WRITE(ah, AR_NEXT_SWBA, next_beacon - 
     1717                          TU_TO_USEC(ah->config.sw_beacon_response_time)); 
    17241718                flags |= 
    17251719                        AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN; 
    17261720                break; 
    void ath9k_hw_beaconinit(struct ath_hw * 
    17321726                break; 
    17331727        } 
    17341728 
    1735         REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period)); 
    1736         REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period)); 
    1737         REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period)); 
    1738         REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); 
     1729        REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period); 
     1730        REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period); 
     1731        REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period); 
     1732        REG_WRITE(ah, AR_NDP_PERIOD, beacon_period); 
    17391733 
    17401734        REGWRITE_BUFFER_FLUSH(ah); 
    17411735 
    1742         beacon_period &= ~ATH9K_BEACON_ENA; 
    1743         if (beacon_period & ATH9K_BEACON_RESET_TSF) { 
    1744                 ath9k_hw_reset_tsf(ah); 
    1745         } 
    1746  
    17471736        REG_SET_BIT(ah, AR_TIMER_MODE, flags); 
    17481737} 
    17491738EXPORT_SYMBOL(ath9k_hw_beaconinit); 
    static u32 rightmost_index(struct ath_ge 
    24042393        return timer_table->gen_timer_index[b]; 
    24052394} 
    24062395 
    2407 static u32 ath9k_hw_gettsf32(struct ath_hw *ah) 
     2396u32 ath9k_hw_gettsf32(struct ath_hw *ah) 
    24082397{ 
    24092398        return REG_READ(ah, AR_TSF_L32); 
    24102399} 
     2400EXPORT_SYMBOL(ath9k_hw_gettsf32); 
    24112401 
    24122402struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 
    24132403                                          void (*trigger)(void *), 
  • drivers/net/wireless/ath/ath9k/ath9k.h

    a b struct ath_beacon { 
    392392        u32 beaconq; 
    393393        u32 bmisscnt; 
    394394        u32 ast_be_xmit; 
    395         u64 bc_tstamp; 
     395        u32 bc_tstamp; 
    396396        struct ieee80211_vif *bslot[ATH_BCBUF]; 
    397397        int slottime; 
    398398        int slotupdate; 
  • drivers/net/wireless/ath/ath9k/hw.h

    a b struct ath9k_beacon_state { 
    412412        u32 bs_nextdtim; 
    413413        u32 bs_intval; 
    414414#define ATH9K_BEACON_PERIOD       0x0000ffff 
    415 #define ATH9K_BEACON_ENA          0x00800000 
    416 #define ATH9K_BEACON_RESET_TSF    0x01000000 
    417415#define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */ 
    418416        u32 bs_dtimperiod; 
    419417        u16 bs_cfpperiod; 
    void ath9k_hw_setopmode(struct ath_hw *a 
    927925void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); 
    928926void ath9k_hw_setbssidmask(struct ath_hw *ah); 
    929927void ath9k_hw_write_associd(struct ath_hw *ah); 
     928u32 ath9k_hw_gettsf32(struct ath_hw *ah); 
    930929u64 ath9k_hw_gettsf64(struct ath_hw *ah); 
    931930void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); 
    932931void ath9k_hw_reset_tsf(struct ath_hw *ah); 
  • drivers/net/wireless/ath/ath9k/htc_drv_beacon.c

    a b static void ath9k_htc_beacon_config_ap(s 
    155155        nexttbtt = intval; 
    156156 
    157157        if (priv->op_flags & OP_TSF_RESET) { 
    158                 intval |= ATH9K_BEACON_RESET_TSF; 
     158                ath9k_hw_reset_tsf(priv->ah); 
    159159                priv->op_flags &= ~OP_TSF_RESET; 
    160160        } else { 
    161161                /* 
    static void ath9k_htc_beacon_config_ap(s 
    168168                } while (nexttbtt < tsftu); 
    169169        } 
    170170 
    171         intval |= ATH9K_BEACON_ENA; 
    172  
    173171        if (priv->op_flags & OP_ENABLE_BEACON) 
    174172                imask |= ATH9K_INT_SWBA; 
    175173 
    static void ath9k_htc_beacon_config_ap(s 
    178176                bss_conf->beacon_interval, nexttbtt, imask); 
    179177 
    180178        WMI_CMD(WMI_DISABLE_INTR_CMDID); 
    181         ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); 
     179        ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); 
    182180        priv->bmiss_cnt = 0; 
    183181        htc_imask = cpu_to_be32(imask); 
    184182        WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); 
    static void ath9k_htc_beacon_config_adho 
    207205                nexttbtt += intval; 
    208206        } while (nexttbtt < tsftu); 
    209207 
    210         intval |= ATH9K_BEACON_ENA; 
    211208        if (priv->op_flags & OP_ENABLE_BEACON) 
    212209                imask |= ATH9K_INT_SWBA; 
    213210 
    static void ath9k_htc_beacon_config_adho 
    216213                bss_conf->beacon_interval, nexttbtt, imask); 
    217214 
    218215        WMI_CMD(WMI_DISABLE_INTR_CMDID); 
    219         ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); 
     216        ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval)); 
    220217        priv->bmiss_cnt = 0; 
    221218        htc_imask = cpu_to_be32(imask); 
    222219        WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); 
Note: See TracBrowser for help on using the repository browser.