Skip to content

Commit

Permalink
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/linville/wireless-next-2.6
  • Loading branch information
David S. Miller committed Oct 4, 2010
2 parents 10651db + 41f4a6f commit 7282907
Show file tree
Hide file tree
Showing 49 changed files with 671 additions and 486 deletions.
3 changes: 1 addition & 2 deletions drivers/net/wireless/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ obj-$(CONFIG_ATH_COMMON) += ath/
obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o

obj-$(CONFIG_WL12XX) += wl12xx/
# small builtin driver bit
obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/wl12xx_platform_data.o
obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/

obj-$(CONFIG_IWM) += iwmc3200wifi/
11 changes: 0 additions & 11 deletions drivers/net/wireless/airo.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ static const char *statsLabels[] = {
(no spaces) list of rates (up to 8). */

static int rates[8];
static int basic_rate;
static char *ssids[3];

static int io[4];
Expand Down Expand Up @@ -250,7 +249,6 @@ MODULE_LICENSE("Dual BSD/GPL");
MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
module_param_array(io, int, NULL, 0);
module_param_array(irq, int, NULL, 0);
module_param(basic_rate, int, 0);
module_param_array(rates, int, NULL, 0);
module_param_array(ssids, charp, NULL, 0);
module_param(auto_wep, int, 0);
Expand Down Expand Up @@ -3883,15 +3881,6 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
ai->config.rates[i] = rates[i];
}
}
if ( basic_rate > 0 ) {
for( i = 0; i < 8; i++ ) {
if ( ai->config.rates[i] == basic_rate ||
!ai->config.rates ) {
ai->config.rates[i] = basic_rate | 0x80;
break;
}
}
}
set_bit (FLAG_COMMIT, &ai->flags);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath5k/ath5k.h
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,6 @@ struct ath5k_hw {
#define ah_modes ah_capabilities.cap_mode
#define ah_ee_version ah_capabilities.cap_eeprom.ee_version

u32 ah_atim_window;
u32 ah_limit_tx_retries;
u8 ah_coverage_class;

Expand Down Expand Up @@ -1196,6 +1195,7 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval);
/* ACK bit rate */
void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
/* Clock rate related functions */
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/ath/ath5k/attach.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc)
ah->ah_turbo = false;
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
ah->ah_imr = 0;
ah->ah_atim_window = 0;
ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
ah->ah_software_retry = false;
ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT;
Expand Down
16 changes: 14 additions & 2 deletions drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,15 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
*/
if (hw_tu >= sc->nexttbtt)
ath5k_beacon_update_timers(sc, bc_tstamp);

/* Check if the beacon timers are still correct, because a TSF
* update might have created a window between them - for a
* longer description see the comment of this function: */
if (!ath5k_hw_check_beacon_timers(sc->ah, sc->bintval)) {
ath5k_beacon_update_timers(sc, bc_tstamp);
ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
"fixed beacon timers after beacon receive\n");
}
}
}

Expand Down Expand Up @@ -1877,8 +1886,11 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
hw_tsf = ath5k_hw_get_tsf64(ah);
hw_tu = TSF_TO_TU(hw_tsf);

#define FUDGE 3
/* we use FUDGE to make sure the next TBTT is ahead of the current TU */
#define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3
/* We use FUDGE to make sure the next TBTT is ahead of the current TU.
* Since we later substract AR5K_TUNE_SW_BEACON_RESP (10) in the timer
* configuration we need to make sure it is bigger than that. */

if (bc_tsf == -1) {
/*
* no beacons received, called internally.
Expand Down
58 changes: 58 additions & 0 deletions drivers/net/wireless/ath/ath5k/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,59 @@ static const struct file_operations fops_antenna = {
.owner = THIS_MODULE,
};

/* debugfs: misc */

static ssize_t read_file_misc(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath5k_softc *sc = file->private_data;
char buf[700];
unsigned int len = 0;
u32 filt = ath5k_hw_get_rx_filter(sc->ah);

len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n",
sc->bssidmask);
len += snprintf(buf+len, sizeof(buf)-len, "filter-flags: 0x%x ",
filt);
if (filt & AR5K_RX_FILTER_UCAST)
len += snprintf(buf+len, sizeof(buf)-len, " UCAST");
if (filt & AR5K_RX_FILTER_MCAST)
len += snprintf(buf+len, sizeof(buf)-len, " MCAST");
if (filt & AR5K_RX_FILTER_BCAST)
len += snprintf(buf+len, sizeof(buf)-len, " BCAST");
if (filt & AR5K_RX_FILTER_CONTROL)
len += snprintf(buf+len, sizeof(buf)-len, " CONTROL");
if (filt & AR5K_RX_FILTER_BEACON)
len += snprintf(buf+len, sizeof(buf)-len, " BEACON");
if (filt & AR5K_RX_FILTER_PROM)
len += snprintf(buf+len, sizeof(buf)-len, " PROM");
if (filt & AR5K_RX_FILTER_XRPOLL)
len += snprintf(buf+len, sizeof(buf)-len, " XRPOLL");
if (filt & AR5K_RX_FILTER_PROBEREQ)
len += snprintf(buf+len, sizeof(buf)-len, " PROBEREQ");
if (filt & AR5K_RX_FILTER_PHYERR_5212)
len += snprintf(buf+len, sizeof(buf)-len, " PHYERR-5212");
if (filt & AR5K_RX_FILTER_RADARERR_5212)
len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5212");
if (filt & AR5K_RX_FILTER_PHYERR_5211)
snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211");
if (filt & AR5K_RX_FILTER_RADARERR_5211)
len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211\n");
else
len += snprintf(buf+len, sizeof(buf)-len, "\n");

if (len > sizeof(buf))
len = sizeof(buf);

return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}

static const struct file_operations fops_misc = {
.read = read_file_misc,
.open = ath5k_debugfs_open,
.owner = THIS_MODULE,
};


/* debugfs: frameerrors */

Expand Down Expand Up @@ -856,6 +909,10 @@ ath5k_debug_init_device(struct ath5k_softc *sc)
S_IWUSR | S_IRUSR,
sc->debug.debugfs_phydir, sc, &fops_antenna);

sc->debug.debugfs_misc = debugfs_create_file("misc",
S_IRUSR,
sc->debug.debugfs_phydir, sc, &fops_misc);

sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors",
S_IWUSR | S_IRUSR,
sc->debug.debugfs_phydir, sc,
Expand Down Expand Up @@ -886,6 +943,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc)
debugfs_remove(sc->debug.debugfs_beacon);
debugfs_remove(sc->debug.debugfs_reset);
debugfs_remove(sc->debug.debugfs_antenna);
debugfs_remove(sc->debug.debugfs_misc);
debugfs_remove(sc->debug.debugfs_frameerrors);
debugfs_remove(sc->debug.debugfs_ani);
debugfs_remove(sc->debug.debugfs_queue);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath5k/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct ath5k_dbg_info {
struct dentry *debugfs_beacon;
struct dentry *debugfs_reset;
struct dentry *debugfs_antenna;
struct dentry *debugfs_misc;
struct dentry *debugfs_frameerrors;
struct dentry *debugfs_ani;
struct dentry *debugfs_queue;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath5k/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)

/* Force channel idle high */
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);

/* Wait a while and disable mechanism */
udelay(200);
Expand All @@ -261,7 +261,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
} while (--i && pending);

AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
AR5K_DIAG_SW_CHANNEL_IDLE_HIGH);
}

/* Clear register */
Expand Down
99 changes: 98 additions & 1 deletion drivers/net/wireless/ath/ath5k/pcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,10 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
{
u32 tsf_lower, tsf_upper1, tsf_upper2;
int i;
unsigned long flags;

/* This code is time critical - we don't want to be interrupted here */
local_irq_save(flags);

/*
* While reading TSF upper and then lower part, the clock is still
Expand All @@ -517,6 +521,8 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
tsf_upper1 = tsf_upper2;
}

local_irq_restore(flags);

WARN_ON( i == ATH5K_MAX_TSF_READ );

return (((u64)tsf_upper1 << 32) | tsf_lower);
Expand Down Expand Up @@ -600,7 +606,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
/* Timer3 marks the end of our ATIM window
* a zero length window is not allowed because
* we 'll get no beacons */
timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
timer3 = next_beacon + 1;

/*
* Set the beacon register and enable all timers.
Expand Down Expand Up @@ -640,6 +646,97 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)

}

/**
* ath5k_check_timer_win - Check if timer B is timer A + window
*
* @a: timer a (before b)
* @b: timer b (after a)
* @window: difference between a and b
* @intval: timers are increased by this interval
*
* This helper function checks if timer B is timer A + window and covers
* cases where timer A or B might have already been updated or wrapped
* around (Timers are 16 bit).
*
* Returns true if O.K.
*/
static inline bool
ath5k_check_timer_win(int a, int b, int window, int intval)
{
/*
* 1.) usually B should be A + window
* 2.) A already updated, B not updated yet
* 3.) A already updated and has wrapped around
* 4.) B has wrapped around
*/
if ((b - a == window) || /* 1.) */
(a - b == intval - window) || /* 2.) */
((a | 0x10000) - b == intval - window) || /* 3.) */
((b | 0x10000) - a == window)) /* 4.) */
return true; /* O.K. */
return false;
}

/**
* ath5k_hw_check_beacon_timers - Check if the beacon timers are correct
*
* @ah: The &struct ath5k_hw
* @intval: beacon interval
*
* This is a workaround for IBSS mode:
*
* The need for this function arises from the fact that we have 4 separate
* HW timer registers (TIMER0 - TIMER3), which are closely related to the
* next beacon target time (NBTT), and that the HW updates these timers
* seperately based on the current TSF value. The hardware increments each
* timer by the beacon interval, when the local TSF coverted to TU is equal
* to the value stored in the timer.
*
* The reception of a beacon with the same BSSID can update the local HW TSF
* at any time - this is something we can't avoid. If the TSF jumps to a
* time which is later than the time stored in a timer, this timer will not
* be updated until the TSF in TU wraps around at 16 bit (the size of the
* timers) and reaches the time which is stored in the timer.
*
* The problem is that these timers are closely related to TIMER0 (NBTT) and
* that they define a time "window". When the TSF jumps between two timers
* (e.g. ATIM and NBTT), the one in the past will be left behind (not
* updated), while the one in the future will be updated every beacon
* interval. This causes the window to get larger, until the TSF wraps
* around as described above and the timer which was left behind gets
* updated again. But - because the beacon interval is usually not an exact
* divisor of the size of the timers (16 bit), an unwanted "window" between
* these timers has developed!
*
* This is especially important with the ATIM window, because during
* the ATIM window only ATIM frames and no data frames are allowed to be
* sent, which creates transmission pauses after each beacon. This symptom
* has been described as "ramping ping" because ping times increase linearly
* for some time and then drop down again. A wrong window on the DMA beacon
* timer has the same effect, so we check for these two conditions.
*
* Returns true if O.K.
*/
bool
ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
{
unsigned int nbtt, atim, dma;

nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0);
atim = ath5k_hw_reg_read(ah, AR5K_TIMER3);
dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3;

/* NOTE: SWBA is different. Having a wrong window there does not
* stop us from sending data and this condition is catched thru
* other means (SWBA interrupt) */

if (ath5k_check_timer_win(nbtt, atim, 1, intval) &&
ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP,
intval))
return true; /* O.K. */
return false;
}

/**
* ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class
*
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath5k/phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1257,7 +1257,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
* Disable beacons and RX/TX queues, wait
*/
AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);

Expand Down Expand Up @@ -1336,7 +1336,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
* Re-enable RX/TX and beacons
*/
AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210);
ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);

return 0;
Expand Down
Loading

0 comments on commit 7282907

Please sign in to comment.