Commit 8f56874b authored by David S. Miller's avatar David S. Miller
Browse files
parents 47e1c323 159bcfeb
......@@ -2816,6 +2816,15 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
S: Supported
F: drivers/net/wireless/iwlwifi/
INTEL WIRELESS MULTICOMM 3200 WIFI (iwmc3200wifi)
M: Samuel Ortiz <samuel.ortiz@intel.com>
M: Zhu Yi <yi.zhu@intel.com>
M: Intel Linux Wireless <ilw@linux.intel.com>
L: linux-wireless@vger.kernel.org
S: Supported
W: http://wireless.kernel.org/en/users/Drivers/iwmc3200wifi
F: drivers/net/wireless/iwmc3200wifi/
IOC3 ETHERNET DRIVER
M: Ralf Baechle <ralf@linux-mips.org>
L: linux-mips@linux-mips.org
......
......@@ -4806,7 +4806,7 @@ static int airo_config_commit(struct net_device *dev,
static inline int sniffing_mode(struct airo_info *ai)
{
return le16_to_cpu(ai->config.rmode & RXMODE_MASK) >=
return (le16_to_cpu(ai->config.rmode) & le16_to_cpu(RXMODE_MASK)) >=
le16_to_cpu(RXMODE_RFMON);
}
......
......@@ -23,17 +23,12 @@ config ATH9K
If you choose to build a module, it'll be called ath9k.
if ATH_DEBUG
config ATH9K_DEBUG
config ATH9K_DEBUGFS
bool "Atheros ath9k debugging"
depends on ATH9K
---help---
Say Y, if you need ath9k to display debug messages.
Pass the debug mask as a module parameter:
modprobe ath9k debug=0x00000200
Say Y, if you need access to ath9k's statistics for
interrupts, rate control, etc.
Look in ath9k/debug.h for possible debug masks
Also required for changing debug message flags at run time.
endif # ATH_DEBUG
......@@ -7,7 +7,7 @@ ath9k-y += beacon.o \
ath9k-$(CONFIG_PCI) += pci.o
ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
obj-$(CONFIG_ATH9K) += ath9k.o
......
......@@ -21,7 +21,6 @@
#include <linux/device.h>
#include <linux/leds.h>
#include "rc.h"
#include "debug.h"
#include "common.h"
......@@ -330,6 +329,7 @@ void ath_beacon_tasklet(unsigned long data);
void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
int ath_beaconq_config(struct ath_softc *sc);
/*******/
/* ANI */
......@@ -421,8 +421,11 @@ struct ath_led {
#define SC_OP_WAIT_FOR_TX_ACK BIT(18)
#define SC_OP_BEACON_SYNC BIT(19)
#define SC_OP_BT_PRIORITY_DETECTED BIT(21)
#define SC_OP_NULLFUNC_COMPLETED BIT(22)
#define SC_OP_PS_ENABLED BIT(23)
struct ath_wiphy;
struct ath_rate_table;
struct ath_softc {
struct ieee80211_hw *hw;
......@@ -467,9 +470,8 @@ struct ath_softc {
struct ath_rx rx;
struct ath_tx tx;
struct ath_beacon beacon;
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
const struct ath_rate_table *cur_rate_table;
enum wireless_mode cur_rate_mode;
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath_led radio_led;
......@@ -484,7 +486,7 @@ struct ath_softc {
int beacon_interval;
#ifdef CONFIG_ATH9K_DEBUG
#ifdef CONFIG_ATH9K_DEBUGFS
struct ath9k_debug debug;
#endif
struct ath_beacon_config cur_beacon_conf;
......
......@@ -23,11 +23,12 @@
* the operating mode of the station (AP or AdHoc). Parameters are AIFS
* settings and channel width min/max
*/
static int ath_beaconq_config(struct ath_softc *sc)
int ath_beaconq_config(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_tx_queue_info qi;
struct ath9k_tx_queue_info qi, qi_be;
int qnum;
ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
......@@ -37,9 +38,12 @@ static int ath_beaconq_config(struct ath_softc *sc)
qi.tqi_cwmax = 0;
} else {
/* Adhoc mode; important thing is to use 2x cwmin. */
qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA,
ATH9K_WME_AC_BE);
ath9k_hw_get_txq_props(ah, qnum, &qi_be);
qi.tqi_aifs = qi_be.tqi_aifs;
qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
qi.tqi_cwmax = qi_be.tqi_cwmax;
}
if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
......@@ -65,9 +69,9 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
struct ath_common *common = ath9k_hw_common(ah);
struct ath_desc *ds;
struct ath9k_11n_rate_series series[4];
const struct ath_rate_table *rt;
int flags, antenna, ctsrate = 0, ctsduration = 0;
u8 rate;
struct ieee80211_supported_band *sband;
u8 rate = 0;
ds = bf->bf_desc;
flags = ATH9K_TXDESC_NOACK;
......@@ -91,10 +95,10 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
ds->ds_data = bf->bf_buf_addr;
rt = sc->cur_rate_table;
rate = rt->info[0].ratecode;
sband = &sc->sbands[common->hw->conf.channel->band];
rate = sband->bitrates[0].hw_value;
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
rate |= rt->info[0].short_preamble;
rate |= sband->bitrates[0].hw_value_short;
ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
ATH9K_PKT_TYPE_BEACON,
......
......@@ -181,8 +181,6 @@ static void ath9k_process_rssi(struct ath_common *common,
ATH_RSSI_EP_MULTIPLIER);
if (rx_stats->rs_rssi < 0)
rx_stats->rs_rssi = 0;
else if (rx_stats->rs_rssi > 127)
rx_stats->rs_rssi = 127;
/* Update Beacon RSSI, this is used by ANI. */
if (ieee80211_is_beacon(fc))
......@@ -238,16 +236,8 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
/* see if any padding is done by the hw and remove it */
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
padpos = 24;
fc = hdr->frame_control;
if ((fc & cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) ==
cpu_to_le16(IEEE80211_FCTL_FROMDS|IEEE80211_FCTL_TODS)) {
padpos += 6; /* ETH_ALEN */
}
if ((fc & cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FCTL_FTYPE)) ==
cpu_to_le16(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) {
padpos += 2;
}
padpos = ath9k_cmn_padpos(hdr->frame_control);
/* The MAC header is padded to have 32-bit boundary if the
* packet payload is non-zero. The general calculation for
......@@ -282,6 +272,20 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
}
EXPORT_SYMBOL(ath9k_cmn_rx_skb_postprocess);
int ath9k_cmn_padpos(__le16 frame_control)
{
int padpos = 24;
if (ieee80211_has_a4(frame_control)) {
padpos += ETH_ALEN;
}
if (ieee80211_is_data_qos(frame_control)) {
padpos += IEEE80211_QOS_CTL_LEN;
}
return padpos;
}
EXPORT_SYMBOL(ath9k_cmn_padpos);
static int __init ath9k_cmn_init(void)
{
return 0;
......
......@@ -78,6 +78,7 @@ struct ath_buf {
dma_addr_t bf_daddr; /* physical addr of desc */
dma_addr_t bf_buf_addr; /* physical addr of data buffer */
bool bf_stale;
bool bf_isnullfunc;
u16 bf_flags;
struct ath_buf_state bf_state;
dma_addr_t bf_dmacontext;
......@@ -122,3 +123,5 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
struct ath_rx_status *rx_stats,
struct ieee80211_rx_status *rxs,
bool decrypt_error);
int ath9k_cmn_padpos(__le16 frame_control);
......@@ -31,6 +31,8 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file)
return 0;
}
#ifdef CONFIG_ATH_DEBUG
static ssize_t read_file_debug(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
......@@ -71,6 +73,8 @@ static const struct file_operations fops_debug = {
.owner = THIS_MODULE
};
#endif
static ssize_t read_file_dma(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
......@@ -255,21 +259,11 @@ static const struct file_operations fops_interrupt = {
.owner = THIS_MODULE
};
void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
void ath_debug_stat_rc(struct ath_softc *sc, int final_rate)
{
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *rates = tx_info->status.rates;
int final_ts_idx = 0, idx, i;
struct ath_rc_stats *stats;
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
if (!rates[i].count)
break;
final_ts_idx = i;
}
idx = rates[final_ts_idx].idx;
stats = &sc->debug.stats.rcstats[idx];
stats = &sc->debug.stats.rcstats[final_rate];
stats->success++;
}
......@@ -573,10 +567,12 @@ int ath9k_init_debug(struct ath_hw *ah)
if (!sc->debug.debugfs_phy)
goto err;
#ifdef CONFIG_ATH_DEBUG
sc->debug.debugfs_debug = debugfs_create_file("debug",
S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
if (!sc->debug.debugfs_debug)
goto err;
#endif
sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR,
sc->debug.debugfs_phy, sc, &fops_dma);
......
......@@ -18,17 +18,18 @@
#define DEBUG_H
#include "hw.h"
#include "rc.h"
struct ath_txq;
struct ath_buf;
#ifdef CONFIG_ATH9K_DEBUG
#ifdef CONFIG_ATH9K_DEBUGFS
#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
#else
#define TX_STAT_INC(q, c) do { } while (0)
#endif
#ifdef CONFIG_ATH9K_DEBUG
#ifdef CONFIG_ATH9K_DEBUGFS
/**
* struct ath_interrupt_stats - Contains statistics about interrupts
......@@ -138,7 +139,7 @@ void ath9k_exit_debug(struct ath_hw *ah);
int ath9k_debug_create_root(void);
void ath9k_debug_remove_root(void);
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf);
void ath_debug_stat_retries(struct ath_softc *sc, int rix,
......@@ -170,7 +171,7 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
}
static inline void ath_debug_stat_rc(struct ath_softc *sc,
struct sk_buff *skb)
int final_rate)
{
}
......@@ -185,6 +186,6 @@ static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
{
}
#endif /* CONFIG_ATH9K_DEBUG */
#endif /* CONFIG_ATH9K_DEBUGFS */
#endif /* DEBUG_H */
......@@ -148,22 +148,19 @@ bool ath9k_get_channel_edges(struct ath_hw *ah,
}
u16 ath9k_hw_computetxtime(struct ath_hw *ah,
const struct ath_rate_table *rates,
u8 phy, int kbps,
u32 frameLen, u16 rateix,
bool shortPreamble)
{
u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
u32 kbps;
kbps = rates->info[rateix].ratekbps;
if (kbps == 0)
return 0;
switch (rates->info[rateix].phy) {
switch (phy) {
case WLAN_RC_PHY_CCK:
phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
if (shortPreamble && rates->info[rateix].short_preamble)
if (shortPreamble)
phyTime >>= 1;
numBits = frameLen << 3;
txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
......@@ -194,8 +191,7 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
break;
default:
ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
"Unknown phy %u (rate ix %u)\n",
rates->info[rateix].phy, rateix);
"Unknown phy %u (rate ix %u)\n", phy, rateix);
txTime = 0;
break;
}
......@@ -922,6 +918,11 @@ int ath9k_hw_init(struct ath_hw *ah)
ath_print(common, ATH_DBG_RESET, "serialize_regmode is %d\n",
ah->config.serialize_regmode);
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD >> 1;
else
ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD;
if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
ath_print(common, ATH_DBG_FATAL,
"Mac Chip Rev 0x%02x.%x is not supported by "
......@@ -975,7 +976,10 @@ int ath9k_hw_init(struct ath_hw *ah)
return r;
ath9k_hw_init_mode_gain_regs(ah);
ath9k_hw_fill_cap_info(ah);
r = ath9k_hw_fill_cap_info(ah);
if (r)
return r;
ath9k_hw_init_11a_eeprom_fix(ah);
r = ath9k_hw_init_macaddr(ah);
......@@ -3111,7 +3115,7 @@ EXPORT_SYMBOL(ath9k_hw_set_sta_beacon_timers);
/* HW Capabilities */
/*******************/
void ath9k_hw_fill_cap_info(struct ath_hw *ah)
int ath9k_hw_fill_cap_info(struct ath_hw *ah)
{
struct ath9k_hw_capabilities *pCap = &ah->caps;
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
......@@ -3142,6 +3146,12 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
}
eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
if ((eeval & (AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A)) == 0) {
ath_print(common, ATH_DBG_FATAL,
"no band has been marked as supported in EEPROM.\n");
return -EINVAL;
}
bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
if (eeval & AR5416_OPFLAGS_11A) {
......@@ -3228,7 +3238,11 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->keycache_size = AR_KEYTABLE_SIZE;
pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
else
pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
if (AR_SREV_9285_10_OR_LATER(ah))
pCap->num_gpio_pins = AR9285_NUM_GPIO;
......@@ -3301,6 +3315,8 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
} else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
}
return 0;
}
bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
......
......@@ -60,7 +60,7 @@
#define ATH_DEFAULT_NOISE_FLOOR -95
#define ATH9K_RSSI_BAD 0x80
#define ATH9K_RSSI_BAD -128
/* Register read/write primitives */
#define REG_WRITE(_ah, _reg, _val) \
......@@ -226,6 +226,7 @@ struct ath9k_ops_config {
#define AR_SPUR_FEEQ_BOUND_HT20 10
int spurmode;
u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
u8 max_txtrig_level;
};
enum ath9k_int {
......@@ -619,7 +620,7 @@ void ath9k_hw_detach(struct ath_hw *ah);
int ath9k_hw_init(struct ath_hw *ah);
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
bool bChannelChange);
void ath9k_hw_fill_cap_info(struct ath_hw *ah);
int ath9k_hw_fill_cap_info(struct ath_hw *ah);
bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
u32 capability, u32 *result);
bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
......@@ -647,7 +648,7 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
u32 ath9k_hw_reverse_bits(u32 val, u32 n);
bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
u16 ath9k_hw_computetxtime(struct ath_hw *ah,
const struct ath_rate_table *rates,
u8 phy, int kbps,
u32 frameLen, u16 rateix, bool shortPreamble);
void ath9k_hw_get_channel_centers(struct ath_hw *ah,
struct ath9k_channel *chan,
......
......@@ -70,12 +70,37 @@ u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
}
EXPORT_SYMBOL(ath9k_hw_numtxpending);
/**
* ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
*
* @ah: atheros hardware struct
* @bIncTrigLevel: whether or not the frame trigger level should be updated
*
* The frame trigger level specifies the minimum number of bytes,
* in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO
* before the PCU will initiate sending the frame on the air. This can
* mean we initiate transmit before a full frame is on the PCU TX FIFO.
* Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs
* first)
*
* Caution must be taken to ensure to set the frame trigger level based
* on the DMA request size. For example if the DMA request size is set to
* 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because
* there need to be enough space in the tx FIFO for the requested transfer
* size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set
* the threshold to a value beyond 6, then the transmit will hang.
*
* Current dual stream devices have a PCU TX FIFO size of 8 KB.
* Current single stream devices have a PCU TX FIFO size of 4 KB, however,
* there is a hardware issue which forces us to use 2 KB instead so the
* frame trigger level must not exceed 2 KB for these chipsets.
*/
bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
{
u32 txcfg, curLevel, newLevel;
enum ath9k_int omask;
if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
if (ah->tx_trig_level >= ah->config.max_txtrig_level)
return false;
omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
......@@ -84,7 +109,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
curLevel = MS(txcfg, AR_FTRIG);
newLevel = curLevel;
if (bIncTrigLevel) {
if (curLevel < MAX_TX_FIFO_THRESHOLD)
if (curLevel < ah->config.max_txtrig_level)
newLevel++;
} else if (curLevel > MIN_TX_FIFO_THRESHOLD)
newLevel--;
......@@ -231,6 +256,8 @@ int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
ds->ds_txstat.ts_status = 0;
ds->ds_txstat.ts_flags = 0;
if (ads->ds_txstatus1 & AR_FrmXmitOK)
ds->ds_txstat.ts_status |= ATH9K_TX_ACKED;
if (ads->ds_txstatus1 & AR_ExcessiveRetries)
ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
if (ads->ds_txstatus1 & AR_Filtered)
......@@ -926,6 +953,13 @@ void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
}
EXPORT_SYMBOL(ath9k_hw_setuprxdesc);
/*
* This can stop or re-enables RX.
*
* If bool is set this will kill any frame which is currently being
* transferred between the MAC and baseband and also prevent any new
* frames from getting started.
*/
bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
{
u32 reg;
......
......@@ -76,6 +76,7 @@
#define ATH9K_TXERR_FIFO 0x04
#define ATH9K_TXERR_XTXOP 0x08
#define ATH9K_TXERR_TIMER_EXPIRED 0x10
#define ATH9K_TX_ACKED 0x20
#define ATH9K_TX_BA 0x01
#define ATH9K_TX_PWRMGMT 0x02
......@@ -85,9 +86,15 @@
#define ATH9K_TX_SW_ABORTED 0x40
#define ATH9K_TX_SW_FILTERED 0x80
/* 64 bytes */
#define MIN_TX_FIFO_THRESHOLD 0x1
/*
* Single stream device AR9285 and AR9271 require 2 KB
* to work around a hardware issue, all other devices
* have can use the max 4 KB limit.
*/
#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
struct ath_tx_status {
u32 ts_tstamp;
......@@ -380,6 +387,11 @@ struct ar5416_desc {
#define AR_TxBaStatus 0x40000000
#define AR_TxStatusRsvd01 0x80000000
/*
* AR_FrmXmitOK - Frame transmission success flag. If set, the frame was
* transmitted successfully. If clear, no ACK or BA was received to indicate
* successful transmission when we were expecting an ACK or BA.
*/
#define AR_FrmXmitOK 0x00000001
#define AR_ExcessiveRetries 0x00000002
#define AR_FIFOUnderrun 0x00000004
......@@ -616,7 +628,6 @@ enum ath9k_cipher {
struct ath_hw;
struct ath9k_channel;
struct ath_rate_table;
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
......
......@@ -104,37 +104,55 @@ static struct ieee80211_channel ath9k_5ghz_chantable[] = {
CHAN5G(5825, 37), /* Channel 165 */
};
/* Atheros hardware rate code addition for short premble */
#define SHPCHECK(__hw_rate, __flags) \
((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
#define RATE(_bitrate, _hw_rate, _flags) { \
.bitrate = (_bitrate), \
.flags = (_flags), \
.hw_value = (_hw_rate), \
.hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
}
static struct ieee80211_rate ath9k_legacy_rates[] = {
RATE(10, 0x1b, 0),
RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
RATE(60, 0x0b, 0),
RATE(90, 0x0f, 0),
RATE(120, 0x0a, 0),
RATE(180, 0x0e, 0),
RATE(240, 0x09, 0),
RATE(360, 0x0d, 0),
RATE(480, 0x08, 0),
RATE(540, 0x0c, 0),
};
static void ath_cache_conf_rate(struct ath_softc *sc,
struct ieee80211_conf *conf)
{
switch (conf->channel->band) {
case IEEE80211_BAND_2GHZ:
if (conf_is_ht20(conf))
sc->cur_rate_table =
sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
sc->cur_rate_mode = ATH9K_MODE_11NG_HT20;
else if (conf_is_ht40_minus(conf))
sc->cur_rate_table =
sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS;
else if (conf_is_ht40_plus(conf))