Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
0003  * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
0004  * Copyright (c) 2007-2008 Matthew W. S. Bell  <mentor@madwifi.org>
0005  * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
0006  * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
0007  * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
0008  *
0009  * Permission to use, copy, modify, and distribute this software for any
0010  * purpose with or without fee is hereby granted, provided that the above
0011  * copyright notice and this permission notice appear in all copies.
0012  *
0013  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0014  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0015  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0016  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0017  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0018  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0019  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0020  *
0021  */
0022 
0023 /*********************************\
0024 * Protocol Control Unit Functions *
0025 \*********************************/
0026 
0027 #include <asm/unaligned.h>
0028 
0029 #include "ath5k.h"
0030 #include "reg.h"
0031 #include "debug.h"
0032 
0033 /**
0034  * DOC: Protocol Control Unit (PCU) functions
0035  *
0036  * Protocol control unit is responsible to maintain various protocol
0037  * properties before a frame is send and after a frame is received to/from
0038  * baseband. To be more specific, PCU handles:
0039  *
0040  * - Buffering of RX and TX frames (after QCU/DCUs)
0041  *
0042  * - Encrypting and decrypting (using the built-in engine)
0043  *
0044  * - Generating ACKs, RTS/CTS frames
0045  *
0046  * - Maintaining TSF
0047  *
0048  * - FCS
0049  *
0050  * - Updating beacon data (with TSF etc)
0051  *
0052  * - Generating virtual CCA
0053  *
0054  * - RX/Multicast filtering
0055  *
0056  * - BSSID filtering
0057  *
0058  * - Various statistics
0059  *
0060  * -Different operating modes: AP, STA, IBSS
0061  *
0062  * Note: Most of these functions can be tweaked/bypassed so you can do
0063  * them on sw above for debugging or research. For more infos check out PCU
0064  * registers on reg.h.
0065  */
0066 
0067 /**
0068  * DOC: ACK rates
0069  *
0070  * AR5212+ can use higher rates for ack transmission
0071  * based on current tx rate instead of the base rate.
0072  * It does this to better utilize channel usage.
0073  * There is a mapping between G rates (that cover both
0074  * CCK and OFDM) and ack rates that we use when setting
0075  * rate -> duration table. This mapping is hw-based so
0076  * don't change anything.
0077  *
0078  * To enable this functionality we must set
0079  * ah->ah_ack_bitrate_high to true else base rate is
0080  * used (1Mb for CCK, 6Mb for OFDM).
0081  */
0082 static const unsigned int ack_rates_high[] =
0083 /* Tx   -> ACK  */
0084 /* 1Mb  -> 1Mb  */  { 0,
0085 /* 2MB  -> 2Mb  */  1,
0086 /* 5.5Mb -> 2Mb */  1,
0087 /* 11Mb -> 2Mb  */  1,
0088 /* 6Mb  -> 6Mb  */  4,
0089 /* 9Mb  -> 6Mb  */  4,
0090 /* 12Mb -> 12Mb */  6,
0091 /* 18Mb -> 12Mb */  6,
0092 /* 24Mb -> 24Mb */  8,
0093 /* 36Mb -> 24Mb */  8,
0094 /* 48Mb -> 24Mb */  8,
0095 /* 54Mb -> 24Mb */  8 };
0096 
0097 /*******************\
0098 * Helper functions *
0099 \*******************/
0100 
0101 /**
0102  * ath5k_hw_get_frame_duration() - Get tx time of a frame
0103  * @ah: The &struct ath5k_hw
0104  * @band: One of enum nl80211_band
0105  * @len: Frame's length in bytes
0106  * @rate: The @struct ieee80211_rate
0107  * @shortpre: Indicate short preample
0108  *
0109  * Calculate tx duration of a frame given it's rate and length
0110  * It extends ieee80211_generic_frame_duration for non standard
0111  * bwmodes.
0112  */
0113 int
0114 ath5k_hw_get_frame_duration(struct ath5k_hw *ah, enum nl80211_band band,
0115         int len, struct ieee80211_rate *rate, bool shortpre)
0116 {
0117     int sifs, preamble, plcp_bits, sym_time;
0118     int bitrate, bits, symbols, symbol_bits;
0119     int dur;
0120 
0121     /* Fallback */
0122     if (!ah->ah_bwmode) {
0123         __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw,
0124                     NULL, band, len, rate);
0125 
0126         /* subtract difference between long and short preamble */
0127         dur = le16_to_cpu(raw_dur);
0128         if (shortpre)
0129             dur -= 96;
0130 
0131         return dur;
0132     }
0133 
0134     bitrate = rate->bitrate;
0135     preamble = AR5K_INIT_OFDM_PREAMPLE_TIME;
0136     plcp_bits = AR5K_INIT_OFDM_PLCP_BITS;
0137     sym_time = AR5K_INIT_OFDM_SYMBOL_TIME;
0138 
0139     switch (ah->ah_bwmode) {
0140     case AR5K_BWMODE_40MHZ:
0141         sifs = AR5K_INIT_SIFS_TURBO;
0142         preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN;
0143         break;
0144     case AR5K_BWMODE_10MHZ:
0145         sifs = AR5K_INIT_SIFS_HALF_RATE;
0146         preamble *= 2;
0147         sym_time *= 2;
0148         bitrate = DIV_ROUND_UP(bitrate, 2);
0149         break;
0150     case AR5K_BWMODE_5MHZ:
0151         sifs = AR5K_INIT_SIFS_QUARTER_RATE;
0152         preamble *= 4;
0153         sym_time *= 4;
0154         bitrate = DIV_ROUND_UP(bitrate, 4);
0155         break;
0156     default:
0157         sifs = AR5K_INIT_SIFS_DEFAULT_BG;
0158         break;
0159     }
0160 
0161     bits = plcp_bits + (len << 3);
0162     /* Bit rate is in 100Kbits */
0163     symbol_bits = bitrate * sym_time;
0164     symbols = DIV_ROUND_UP(bits * 10, symbol_bits);
0165 
0166     dur = sifs + preamble + (sym_time * symbols);
0167 
0168     return dur;
0169 }
0170 
0171 /**
0172  * ath5k_hw_get_default_slottime() - Get the default slot time for current mode
0173  * @ah: The &struct ath5k_hw
0174  */
0175 unsigned int
0176 ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
0177 {
0178     struct ieee80211_channel *channel = ah->ah_current_channel;
0179     unsigned int slot_time;
0180 
0181     switch (ah->ah_bwmode) {
0182     case AR5K_BWMODE_40MHZ:
0183         slot_time = AR5K_INIT_SLOT_TIME_TURBO;
0184         break;
0185     case AR5K_BWMODE_10MHZ:
0186         slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE;
0187         break;
0188     case AR5K_BWMODE_5MHZ:
0189         slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
0190         break;
0191     case AR5K_BWMODE_DEFAULT:
0192     default:
0193         slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
0194         if ((channel->hw_value == AR5K_MODE_11B) && !ah->ah_short_slot)
0195             slot_time = AR5K_INIT_SLOT_TIME_B;
0196         break;
0197     }
0198 
0199     return slot_time;
0200 }
0201 
0202 /**
0203  * ath5k_hw_get_default_sifs() - Get the default SIFS for current mode
0204  * @ah: The &struct ath5k_hw
0205  */
0206 unsigned int
0207 ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
0208 {
0209     struct ieee80211_channel *channel = ah->ah_current_channel;
0210     unsigned int sifs;
0211 
0212     switch (ah->ah_bwmode) {
0213     case AR5K_BWMODE_40MHZ:
0214         sifs = AR5K_INIT_SIFS_TURBO;
0215         break;
0216     case AR5K_BWMODE_10MHZ:
0217         sifs = AR5K_INIT_SIFS_HALF_RATE;
0218         break;
0219     case AR5K_BWMODE_5MHZ:
0220         sifs = AR5K_INIT_SIFS_QUARTER_RATE;
0221         break;
0222     case AR5K_BWMODE_DEFAULT:
0223     default:
0224         sifs = AR5K_INIT_SIFS_DEFAULT_BG;
0225         if (channel->band == NL80211_BAND_5GHZ)
0226             sifs = AR5K_INIT_SIFS_DEFAULT_A;
0227         break;
0228     }
0229 
0230     return sifs;
0231 }
0232 
0233 /**
0234  * ath5k_hw_update_mib_counters() - Update MIB counters (mac layer statistics)
0235  * @ah: The &struct ath5k_hw
0236  *
0237  * Reads MIB counters from PCU and updates sw statistics. Is called after a
0238  * MIB interrupt, because one of these counters might have reached their maximum
0239  * and triggered the MIB interrupt, to let us read and clear the counter.
0240  *
0241  * NOTE: Is called in interrupt context!
0242  */
0243 void
0244 ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
0245 {
0246     struct ath5k_statistics *stats = &ah->stats;
0247 
0248     /* Read-And-Clear */
0249     stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
0250     stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
0251     stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
0252     stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
0253     stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
0254 }
0255 
0256 
0257 /******************\
0258 * ACK/CTS Timeouts *
0259 \******************/
0260 
0261 /**
0262  * ath5k_hw_write_rate_duration() - Fill rate code to duration table
0263  * @ah: The &struct ath5k_hw
0264  *
0265  * Write the rate code to duration table upon hw reset. This is a helper for
0266  * ath5k_hw_pcu_init(). It seems all this is doing is setting an ACK timeout on
0267  * the hardware, based on current mode, for each rate. The rates which are
0268  * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
0269  * different rate code so we write their value twice (one for long preamble
0270  * and one for short).
0271  *
0272  * Note: Band doesn't matter here, if we set the values for OFDM it works
0273  * on both a and g modes. So all we have to do is set values for all g rates
0274  * that include all OFDM and CCK rates.
0275  *
0276  */
0277 static inline void
0278 ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
0279 {
0280     struct ieee80211_rate *rate;
0281     unsigned int i;
0282     /* 802.11g covers both OFDM and CCK */
0283     u8 band = NL80211_BAND_2GHZ;
0284 
0285     /* Write rate duration table */
0286     for (i = 0; i < ah->sbands[band].n_bitrates; i++) {
0287         u32 reg;
0288         u16 tx_time;
0289 
0290         if (ah->ah_ack_bitrate_high)
0291             rate = &ah->sbands[band].bitrates[ack_rates_high[i]];
0292         /* CCK -> 1Mb */
0293         else if (i < 4)
0294             rate = &ah->sbands[band].bitrates[0];
0295         /* OFDM -> 6Mb */
0296         else
0297             rate = &ah->sbands[band].bitrates[4];
0298 
0299         /* Set ACK timeout */
0300         reg = AR5K_RATE_DUR(rate->hw_value);
0301 
0302         /* An ACK frame consists of 10 bytes. If you add the FCS,
0303          * which ieee80211_generic_frame_duration() adds,
0304          * its 14 bytes. Note we use the control rate and not the
0305          * actual rate for this rate. See mac80211 tx.c
0306          * ieee80211_duration() for a brief description of
0307          * what rate we should choose to TX ACKs. */
0308         tx_time = ath5k_hw_get_frame_duration(ah, band, 10,
0309                     rate, false);
0310 
0311         ath5k_hw_reg_write(ah, tx_time, reg);
0312 
0313         if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
0314             continue;
0315 
0316         tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, true);
0317         ath5k_hw_reg_write(ah, tx_time,
0318             reg + (AR5K_SET_SHORT_PREAMBLE << 2));
0319     }
0320 }
0321 
0322 /**
0323  * ath5k_hw_set_ack_timeout() - Set ACK timeout on PCU
0324  * @ah: The &struct ath5k_hw
0325  * @timeout: Timeout in usec
0326  */
0327 static int
0328 ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
0329 {
0330     if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
0331             <= timeout)
0332         return -EINVAL;
0333 
0334     AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
0335         ath5k_hw_htoclock(ah, timeout));
0336 
0337     return 0;
0338 }
0339 
0340 /**
0341  * ath5k_hw_set_cts_timeout() - Set CTS timeout on PCU
0342  * @ah: The &struct ath5k_hw
0343  * @timeout: Timeout in usec
0344  */
0345 static int
0346 ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
0347 {
0348     if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
0349             <= timeout)
0350         return -EINVAL;
0351 
0352     AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
0353             ath5k_hw_htoclock(ah, timeout));
0354 
0355     return 0;
0356 }
0357 
0358 
0359 /*******************\
0360 * RX filter Control *
0361 \*******************/
0362 
0363 /**
0364  * ath5k_hw_set_lladdr() - Set station id
0365  * @ah: The &struct ath5k_hw
0366  * @mac: The card's mac address (array of octets)
0367  *
0368  * Set station id on hw using the provided mac address
0369  */
0370 int
0371 ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
0372 {
0373     struct ath_common *common = ath5k_hw_common(ah);
0374     u32 low_id, high_id;
0375     u32 pcu_reg;
0376 
0377     /* Set new station ID */
0378     memcpy(common->macaddr, mac, ETH_ALEN);
0379 
0380     pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
0381 
0382     low_id = get_unaligned_le32(mac);
0383     high_id = get_unaligned_le16(mac + 4);
0384 
0385     ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
0386     ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
0387 
0388     return 0;
0389 }
0390 
0391 /**
0392  * ath5k_hw_set_bssid() - Set current BSSID on hw
0393  * @ah: The &struct ath5k_hw
0394  *
0395  * Sets the current BSSID and BSSID mask we have from the
0396  * common struct into the hardware
0397  */
0398 void
0399 ath5k_hw_set_bssid(struct ath5k_hw *ah)
0400 {
0401     struct ath_common *common = ath5k_hw_common(ah);
0402     u16 tim_offset = 0;
0403 
0404     /*
0405      * Set BSSID mask on 5212
0406      */
0407     if (ah->ah_version == AR5K_AR5212)
0408         ath_hw_setbssidmask(common);
0409 
0410     /*
0411      * Set BSSID
0412      */
0413     ath5k_hw_reg_write(ah,
0414                get_unaligned_le32(common->curbssid),
0415                AR5K_BSS_ID0);
0416     ath5k_hw_reg_write(ah,
0417                get_unaligned_le16(common->curbssid + 4) |
0418                ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S),
0419                AR5K_BSS_ID1);
0420 
0421     if (common->curaid == 0) {
0422         ath5k_hw_disable_pspoll(ah);
0423         return;
0424     }
0425 
0426     AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
0427                 tim_offset ? tim_offset + 4 : 0);
0428 
0429     ath5k_hw_enable_pspoll(ah, NULL, 0);
0430 }
0431 
0432 /**
0433  * ath5k_hw_set_bssid_mask() - Filter out bssids we listen
0434  * @ah: The &struct ath5k_hw
0435  * @mask: The BSSID mask to set (array of octets)
0436  *
0437  * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
0438  * which bits of the interface's MAC address should be looked at when trying
0439  * to decide which packets to ACK. In station mode and AP mode with a single
0440  * BSS every bit matters since we lock to only one BSS. In AP mode with
0441  * multiple BSSes (virtual interfaces) not every bit matters because hw must
0442  * accept frames for all BSSes and so we tweak some bits of our mac address
0443  * in order to have multiple BSSes.
0444  *
0445  * For more information check out ../hw.c of the common ath module.
0446  */
0447 void
0448 ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
0449 {
0450     struct ath_common *common = ath5k_hw_common(ah);
0451 
0452     /* Cache bssid mask so that we can restore it
0453      * on reset */
0454     memcpy(common->bssidmask, mask, ETH_ALEN);
0455     if (ah->ah_version == AR5K_AR5212)
0456         ath_hw_setbssidmask(common);
0457 }
0458 
0459 /**
0460  * ath5k_hw_set_mcast_filter() - Set multicast filter
0461  * @ah: The &struct ath5k_hw
0462  * @filter0: Lower 32bits of muticast filter
0463  * @filter1: Higher 16bits of multicast filter
0464  */
0465 void
0466 ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
0467 {
0468     ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
0469     ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
0470 }
0471 
0472 /**
0473  * ath5k_hw_get_rx_filter() - Get current rx filter
0474  * @ah: The &struct ath5k_hw
0475  *
0476  * Returns the RX filter by reading rx filter and
0477  * phy error filter registers. RX filter is used
0478  * to set the allowed frame types that PCU will accept
0479  * and pass to the driver. For a list of frame types
0480  * check out reg.h.
0481  */
0482 u32
0483 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
0484 {
0485     u32 data, filter = 0;
0486 
0487     filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
0488 
0489     /*Radar detection for 5212*/
0490     if (ah->ah_version == AR5K_AR5212) {
0491         data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
0492 
0493         if (data & AR5K_PHY_ERR_FIL_RADAR)
0494             filter |= AR5K_RX_FILTER_RADARERR;
0495         if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
0496             filter |= AR5K_RX_FILTER_PHYERR;
0497     }
0498 
0499     return filter;
0500 }
0501 
0502 /**
0503  * ath5k_hw_set_rx_filter() - Set rx filter
0504  * @ah: The &struct ath5k_hw
0505  * @filter: RX filter mask (see reg.h)
0506  *
0507  * Sets RX filter register and also handles PHY error filter
0508  * register on 5212 and newer chips so that we have proper PHY
0509  * error reporting.
0510  */
0511 void
0512 ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
0513 {
0514     u32 data = 0;
0515 
0516     /* Set PHY error filter register on 5212*/
0517     if (ah->ah_version == AR5K_AR5212) {
0518         if (filter & AR5K_RX_FILTER_RADARERR)
0519             data |= AR5K_PHY_ERR_FIL_RADAR;
0520         if (filter & AR5K_RX_FILTER_PHYERR)
0521             data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
0522     }
0523 
0524     /*
0525      * The AR5210 uses promiscuous mode to detect radar activity
0526      */
0527     if (ah->ah_version == AR5K_AR5210 &&
0528             (filter & AR5K_RX_FILTER_RADARERR)) {
0529         filter &= ~AR5K_RX_FILTER_RADARERR;
0530         filter |= AR5K_RX_FILTER_PROM;
0531     }
0532 
0533     /*Zero length DMA (phy error reporting) */
0534     if (data)
0535         AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
0536     else
0537         AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
0538 
0539     /*Write RX Filter register*/
0540     ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
0541 
0542     /*Write PHY error filter register on 5212*/
0543     if (ah->ah_version == AR5K_AR5212)
0544         ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
0545 
0546 }
0547 
0548 
0549 /****************\
0550 * Beacon control *
0551 \****************/
0552 
0553 #define ATH5K_MAX_TSF_READ 10
0554 
0555 /**
0556  * ath5k_hw_get_tsf64() - Get the full 64bit TSF
0557  * @ah: The &struct ath5k_hw
0558  *
0559  * Returns the current TSF
0560  */
0561 u64
0562 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
0563 {
0564     u32 tsf_lower, tsf_upper1, tsf_upper2;
0565     int i;
0566     unsigned long flags;
0567 
0568     /* This code is time critical - we don't want to be interrupted here */
0569     local_irq_save(flags);
0570 
0571     /*
0572      * While reading TSF upper and then lower part, the clock is still
0573      * counting (or jumping in case of IBSS merge) so we might get
0574      * inconsistent values. To avoid this, we read the upper part again
0575      * and check it has not been changed. We make the hypothesis that a
0576      * maximum of 3 changes can happens in a row (we use 10 as a safe
0577      * value).
0578      *
0579      * Impact on performance is pretty small, since in most cases, only
0580      * 3 register reads are needed.
0581      */
0582 
0583     tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
0584     for (i = 0; i < ATH5K_MAX_TSF_READ; i++) {
0585         tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
0586         tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
0587         if (tsf_upper2 == tsf_upper1)
0588             break;
0589         tsf_upper1 = tsf_upper2;
0590     }
0591 
0592     local_irq_restore(flags);
0593 
0594     WARN_ON(i == ATH5K_MAX_TSF_READ);
0595 
0596     return ((u64)tsf_upper1 << 32) | tsf_lower;
0597 }
0598 
0599 #undef ATH5K_MAX_TSF_READ
0600 
0601 /**
0602  * ath5k_hw_set_tsf64() - Set a new 64bit TSF
0603  * @ah: The &struct ath5k_hw
0604  * @tsf64: The new 64bit TSF
0605  *
0606  * Sets the new TSF
0607  */
0608 void
0609 ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
0610 {
0611     ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
0612     ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
0613 }
0614 
0615 /**
0616  * ath5k_hw_reset_tsf() - Force a TSF reset
0617  * @ah: The &struct ath5k_hw
0618  *
0619  * Forces a TSF reset on PCU
0620  */
0621 void
0622 ath5k_hw_reset_tsf(struct ath5k_hw *ah)
0623 {
0624     u32 val;
0625 
0626     val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
0627 
0628     /*
0629      * Each write to the RESET_TSF bit toggles a hardware internal
0630      * signal to reset TSF, but if left high it will cause a TSF reset
0631      * on the next chip reset as well.  Thus we always write the value
0632      * twice to clear the signal.
0633      */
0634     ath5k_hw_reg_write(ah, val, AR5K_BEACON);
0635     ath5k_hw_reg_write(ah, val, AR5K_BEACON);
0636 }
0637 
0638 /**
0639  * ath5k_hw_init_beacon_timers() - Initialize beacon timers
0640  * @ah: The &struct ath5k_hw
0641  * @next_beacon: Next TBTT
0642  * @interval: Current beacon interval
0643  *
0644  * This function is used to initialize beacon timers based on current
0645  * operation mode and settings.
0646  */
0647 void
0648 ath5k_hw_init_beacon_timers(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
0649 {
0650     u32 timer1, timer2, timer3;
0651 
0652     /*
0653      * Set the additional timers by mode
0654      */
0655     switch (ah->opmode) {
0656     case NL80211_IFTYPE_MONITOR:
0657     case NL80211_IFTYPE_STATION:
0658         /* In STA mode timer1 is used as next wakeup
0659          * timer and timer2 as next CFP duration start
0660          * timer. Both in 1/8TUs. */
0661         /* TODO: PCF handling */
0662         if (ah->ah_version == AR5K_AR5210) {
0663             timer1 = 0xffffffff;
0664             timer2 = 0xffffffff;
0665         } else {
0666             timer1 = 0x0000ffff;
0667             timer2 = 0x0007ffff;
0668         }
0669         /* Mark associated AP as PCF incapable for now */
0670         AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF);
0671         break;
0672     case NL80211_IFTYPE_ADHOC:
0673         AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM);
0674         fallthrough;
0675     default:
0676         /* On non-STA modes timer1 is used as next DMA
0677          * beacon alert (DBA) timer and timer2 as next
0678          * software beacon alert. Both in 1/8TUs. */
0679         timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
0680         timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
0681         break;
0682     }
0683 
0684     /* Timer3 marks the end of our ATIM window
0685      * a zero length window is not allowed because
0686      * we 'll get no beacons */
0687     timer3 = next_beacon + 1;
0688 
0689     /*
0690      * Set the beacon register and enable all timers.
0691      */
0692     /* When in AP or Mesh Point mode zero timer0 to start TSF */
0693     if (ah->opmode == NL80211_IFTYPE_AP ||
0694         ah->opmode == NL80211_IFTYPE_MESH_POINT)
0695         ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
0696 
0697     ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
0698     ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
0699     ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
0700     ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
0701 
0702     /* Force a TSF reset if requested and enable beacons */
0703     if (interval & AR5K_BEACON_RESET_TSF)
0704         ath5k_hw_reset_tsf(ah);
0705 
0706     ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
0707                     AR5K_BEACON_ENABLE),
0708                         AR5K_BEACON);
0709 
0710     /* Flush any pending BMISS interrupts on ISR by
0711      * performing a clear-on-write operation on PISR
0712      * register for the BMISS bit (writing a bit on
0713      * ISR toggles a reset for that bit and leaves
0714      * the remaining bits intact) */
0715     if (ah->ah_version == AR5K_AR5210)
0716         ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
0717     else
0718         ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
0719 
0720     /* TODO: Set enhanced sleep registers on AR5212
0721      * based on vif->bss_conf params, until then
0722      * disable power save reporting.*/
0723     AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
0724 
0725 }
0726 
0727 /**
0728  * ath5k_check_timer_win() - Check if timer B is timer A + window
0729  * @a: timer a (before b)
0730  * @b: timer b (after a)
0731  * @window: difference between a and b
0732  * @intval: timers are increased by this interval
0733  *
0734  * This helper function checks if timer B is timer A + window and covers
0735  * cases where timer A or B might have already been updated or wrapped
0736  * around (Timers are 16 bit).
0737  *
0738  * Returns true if O.K.
0739  */
0740 static inline bool
0741 ath5k_check_timer_win(int a, int b, int window, int intval)
0742 {
0743     /*
0744      * 1.) usually B should be A + window
0745      * 2.) A already updated, B not updated yet
0746      * 3.) A already updated and has wrapped around
0747      * 4.) B has wrapped around
0748      */
0749     if ((b - a == window) ||                /* 1.) */
0750         (a - b == intval - window) ||           /* 2.) */
0751         ((a | 0x10000) - b == intval - window) ||       /* 3.) */
0752         ((b | 0x10000) - a == window))          /* 4.) */
0753         return true; /* O.K. */
0754     return false;
0755 }
0756 
0757 /**
0758  * ath5k_hw_check_beacon_timers() - Check if the beacon timers are correct
0759  * @ah: The &struct ath5k_hw
0760  * @intval: beacon interval
0761  *
0762  * This is a workaround for IBSS mode
0763  *
0764  * The need for this function arises from the fact that we have 4 separate
0765  * HW timer registers (TIMER0 - TIMER3), which are closely related to the
0766  * next beacon target time (NBTT), and that the HW updates these timers
0767  * separately based on the current TSF value. The hardware increments each
0768  * timer by the beacon interval, when the local TSF converted to TU is equal
0769  * to the value stored in the timer.
0770  *
0771  * The reception of a beacon with the same BSSID can update the local HW TSF
0772  * at any time - this is something we can't avoid. If the TSF jumps to a
0773  * time which is later than the time stored in a timer, this timer will not
0774  * be updated until the TSF in TU wraps around at 16 bit (the size of the
0775  * timers) and reaches the time which is stored in the timer.
0776  *
0777  * The problem is that these timers are closely related to TIMER0 (NBTT) and
0778  * that they define a time "window". When the TSF jumps between two timers
0779  * (e.g. ATIM and NBTT), the one in the past will be left behind (not
0780  * updated), while the one in the future will be updated every beacon
0781  * interval. This causes the window to get larger, until the TSF wraps
0782  * around as described above and the timer which was left behind gets
0783  * updated again. But - because the beacon interval is usually not an exact
0784  * divisor of the size of the timers (16 bit), an unwanted "window" between
0785  * these timers has developed!
0786  *
0787  * This is especially important with the ATIM window, because during
0788  * the ATIM window only ATIM frames and no data frames are allowed to be
0789  * sent, which creates transmission pauses after each beacon. This symptom
0790  * has been described as "ramping ping" because ping times increase linearly
0791  * for some time and then drop down again. A wrong window on the DMA beacon
0792  * timer has the same effect, so we check for these two conditions.
0793  *
0794  * Returns true if O.K.
0795  */
0796 bool
0797 ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
0798 {
0799     unsigned int nbtt, atim, dma;
0800 
0801     nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0);
0802     atim = ath5k_hw_reg_read(ah, AR5K_TIMER3);
0803     dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3;
0804 
0805     /* NOTE: SWBA is different. Having a wrong window there does not
0806      * stop us from sending data and this condition is caught by
0807      * other means (SWBA interrupt) */
0808 
0809     if (ath5k_check_timer_win(nbtt, atim, 1, intval) &&
0810         ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP,
0811                   intval))
0812         return true; /* O.K. */
0813     return false;
0814 }
0815 
0816 /**
0817  * ath5k_hw_set_coverage_class() - Set IEEE 802.11 coverage class
0818  * @ah: The &struct ath5k_hw
0819  * @coverage_class: IEEE 802.11 coverage class number
0820  *
0821  * Sets IFS intervals and ACK/CTS timeouts for given coverage class.
0822  */
0823 void
0824 ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
0825 {
0826     /* As defined by IEEE 802.11-2007 17.3.8.6 */
0827     int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
0828     int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
0829     int cts_timeout = ack_timeout;
0830 
0831     ath5k_hw_set_ifs_intervals(ah, slot_time);
0832     ath5k_hw_set_ack_timeout(ah, ack_timeout);
0833     ath5k_hw_set_cts_timeout(ah, cts_timeout);
0834 
0835     ah->ah_coverage_class = coverage_class;
0836 }
0837 
0838 /***************************\
0839 * Init/Start/Stop functions *
0840 \***************************/
0841 
0842 /**
0843  * ath5k_hw_start_rx_pcu() - Start RX engine
0844  * @ah: The &struct ath5k_hw
0845  *
0846  * Starts RX engine on PCU so that hw can process RXed frames
0847  * (ACK etc).
0848  *
0849  * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
0850  */
0851 void
0852 ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
0853 {
0854     AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
0855 }
0856 
0857 /**
0858  * ath5k_hw_stop_rx_pcu() - Stop RX engine
0859  * @ah: The &struct ath5k_hw
0860  *
0861  * Stops RX engine on PCU
0862  */
0863 void
0864 ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
0865 {
0866     AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
0867 }
0868 
0869 /**
0870  * ath5k_hw_set_opmode() - Set PCU operating mode
0871  * @ah: The &struct ath5k_hw
0872  * @op_mode: One of enum nl80211_iftype
0873  *
0874  * Configure PCU for the various operating modes (AP/STA etc)
0875  */
0876 int
0877 ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
0878 {
0879     struct ath_common *common = ath5k_hw_common(ah);
0880     u32 pcu_reg, beacon_reg, low_id, high_id;
0881 
0882     ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
0883 
0884     /* Preserve rest settings */
0885     pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
0886     pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
0887             | AR5K_STA_ID1_KEYSRCH_MODE
0888             | (ah->ah_version == AR5K_AR5210 ?
0889             (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
0890 
0891     beacon_reg = 0;
0892 
0893     switch (op_mode) {
0894     case NL80211_IFTYPE_ADHOC:
0895         pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
0896         beacon_reg |= AR5K_BCR_ADHOC;
0897         if (ah->ah_version == AR5K_AR5210)
0898             pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
0899         else
0900             AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
0901         break;
0902 
0903     case NL80211_IFTYPE_AP:
0904     case NL80211_IFTYPE_MESH_POINT:
0905         pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
0906         beacon_reg |= AR5K_BCR_AP;
0907         if (ah->ah_version == AR5K_AR5210)
0908             pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
0909         else
0910             AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
0911         break;
0912 
0913     case NL80211_IFTYPE_STATION:
0914         pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
0915             | (ah->ah_version == AR5K_AR5210 ?
0916                 AR5K_STA_ID1_PWR_SV : 0);
0917         fallthrough;
0918     case NL80211_IFTYPE_MONITOR:
0919         pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
0920             | (ah->ah_version == AR5K_AR5210 ?
0921                 AR5K_STA_ID1_NO_PSPOLL : 0);
0922         break;
0923 
0924     default:
0925         return -EINVAL;
0926     }
0927 
0928     /*
0929      * Set PCU registers
0930      */
0931     low_id = get_unaligned_le32(common->macaddr);
0932     high_id = get_unaligned_le16(common->macaddr + 4);
0933     ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
0934     ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
0935 
0936     /*
0937      * Set Beacon Control Register on 5210
0938      */
0939     if (ah->ah_version == AR5K_AR5210)
0940         ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
0941 
0942     return 0;
0943 }
0944 
0945 /**
0946  * ath5k_hw_pcu_init() - Initialize PCU
0947  * @ah: The &struct ath5k_hw
0948  * @op_mode: One of enum nl80211_iftype
0949  *
0950  * This function is used to initialize PCU by setting current
0951  * operation mode and various other settings.
0952  */
0953 void
0954 ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
0955 {
0956     /* Set bssid and bssid mask */
0957     ath5k_hw_set_bssid(ah);
0958 
0959     /* Set PCU config */
0960     ath5k_hw_set_opmode(ah, op_mode);
0961 
0962     /* Write rate duration table only on AR5212 and if
0963      * virtual interface has already been brought up
0964      * XXX: rethink this after new mode changes to
0965      * mac80211 are integrated */
0966     if (ah->ah_version == AR5K_AR5212 &&
0967         ah->nvifs)
0968         ath5k_hw_write_rate_duration(ah);
0969 
0970     /* Set RSSI/BRSSI thresholds
0971      *
0972      * Note: If we decide to set this value
0973      * dynamically, have in mind that when AR5K_RSSI_THR
0974      * register is read it might return 0x40 if we haven't
0975      * wrote anything to it plus BMISS RSSI threshold is zeroed.
0976      * So doing a save/restore procedure here isn't the right
0977      * choice. Instead store it on ath5k_hw */
0978     ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
0979                 AR5K_TUNE_BMISS_THRES <<
0980                 AR5K_RSSI_THR_BMISS_S),
0981                 AR5K_RSSI_THR);
0982 
0983     /* MIC QoS support */
0984     if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
0985         ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
0986         ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
0987     }
0988 
0989     /* QoS NOACK Policy */
0990     if (ah->ah_version == AR5K_AR5212) {
0991         ath5k_hw_reg_write(ah,
0992             AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
0993             AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET)  |
0994             AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
0995             AR5K_QOS_NOACK);
0996     }
0997 
0998     /* Restore slot time and ACK timeouts */
0999     if (ah->ah_coverage_class > 0)
1000         ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
1001 
1002     /* Set ACK bitrate mode (see ack_rates_high) */
1003     if (ah->ah_version == AR5K_AR5212) {
1004         u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
1005         if (ah->ah_ack_bitrate_high)
1006             AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
1007         else
1008             AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
1009     }
1010     return;
1011 }