Commit b5ddedc9 authored by David S. Miller's avatar David S. Miller
parents 244e6c2d b235507c
......@@ -214,6 +214,21 @@ config HERMES
configure your card and that /etc/pcmcia/wireless.opts works :
<http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
config HERMES_CACHE_FW_ON_INIT
bool "Cache Hermes firmware on driver initialisation"
depends on HERMES
default y
---help---
Say Y to cache any firmware required by the Hermes drivers
on startup. The firmware will remain cached until the
driver is unloaded. The cache uses 64K of RAM.
Otherwise load the firmware from userspace as required. In
this case the driver should be unloaded and restarted
whenever the firmware is changed.
If you are not sure, say Y.
config APPLE_AIRPORT
tristate "Apple Airport support (built-in)"
depends on PPC_PMAC && HERMES
......@@ -508,7 +523,7 @@ config RTL8180
config RTL8187
tristate "Realtek 8187 and 8187B USB support"
depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
depends on MAC80211 && USB && WLAN_80211
select EEPROM_93CX6
---help---
This is a driver for RTL8187 and RTL8187B based cards.
......
......@@ -821,13 +821,6 @@ struct ath5k_athchan_2ghz {
return (false); \
} while (0)
enum ath5k_ant_setting {
AR5K_ANT_VARIABLE = 0, /* variable by programming */
AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */
AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */
AR5K_ANT_MAX = 3,
};
/*
* Hardware interrupt abstraction
*/
......
......@@ -106,7 +106,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
{
struct ath5k_hw *ah;
struct pci_dev *pdev = sc->pdev;
u8 mac[ETH_ALEN];
u8 mac[ETH_ALEN] = {};
int ret;
u32 srev;
......@@ -317,15 +317,9 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
goto err_free;
}
/* Set MAC address */
ret = ath5k_eeprom_read_mac(ah, mac);
if (ret) {
ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
sc->pdev->device);
goto err_free;
}
/* MAC address is cleared until add_interface */
ath5k_hw_set_lladdr(ah, mac);
/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
memset(ah->ah_bssid, 0xff, ETH_ALEN);
ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
......
......@@ -200,7 +200,7 @@ static int ath5k_pci_resume(struct pci_dev *pdev);
#endif /* CONFIG_PM */
static struct pci_driver ath5k_pci_driver = {
.name = "ath5k_pci",
.name = KBUILD_MODNAME,
.id_table = ath5k_pci_id_table,
.probe = ath5k_pci_probe,
.remove = __devexit_p(ath5k_pci_remove),
......@@ -707,7 +707,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
u8 mac[ETH_ALEN];
u8 mac[ETH_ALEN] = {};
int ret;
ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
......@@ -777,7 +777,13 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
ath5k_hw_get_lladdr(ah, mac);
ret = ath5k_eeprom_read_mac(ah, mac);
if (ret) {
ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
sc->pdev->device);
goto err_queues;
}
SET_IEEE80211_PERM_ADDR(hw, mac);
/* All MAC address bits matter for ACKs */
memset(sc->bssidmask, 0xff, ETH_ALEN);
......@@ -2765,6 +2771,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
/* Set to a reasonable value. Note that this will
* be set to mac80211's value at ath5k_config(). */
sc->bintval = 1000;
ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
ret = 0;
end:
......@@ -2777,11 +2784,13 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf)
{
struct ath5k_softc *sc = hw->priv;
u8 mac[ETH_ALEN] = {};
mutex_lock(&sc->lock);
if (sc->vif != conf->vif)
goto end;
ath5k_hw_set_lladdr(sc->ah, mac);
sc->vif = NULL;
end:
mutex_unlock(&sc->lock);
......
This diff is collapsed.
This diff is collapsed.
......@@ -674,7 +674,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
(ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
0xffffc07f);
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
(ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
(ee->ee_atn_tx_rx[ee_mode] << 12) & 0x3f000,
0xfffc0fff);
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
(ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
......
......@@ -9,7 +9,6 @@ ath9k-y += hw.o \
main.o \
recv.o \
xmit.o \
rc.o \
core.o
rc.o
obj-$(CONFIG_ATH9K) += ath9k.o
......@@ -401,22 +401,6 @@ enum ath9k_int {
ATH9K_INT_NOCARD = 0xffffffff
};
struct ath9k_rate_table {
int rateCount;
u8 rateCodeToIndex[256];
struct {
u8 valid;
u8 phy;
u32 rateKbps;
u8 rateCode;
u8 shortPreamble;
u8 dot11Rate;
u8 controlRate;
u16 lpAckDuration;
u16 spAckDuration;
} info[32];
};
#define ATH9K_RATESERIES_RTS_CTS 0x0001
#define ATH9K_RATESERIES_2040 0x0002
#define ATH9K_RATESERIES_HALFGI 0x0004
......@@ -492,12 +476,10 @@ struct ath9k_channel {
(((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
(((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
(((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
#define IS_CHAN_B(_c) (((_c)->channelFlags & CHANNEL_B) == CHANNEL_B)
#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
(((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
(((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
(((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
#define IS_CHAN_CCK(_c) (((_c)->channelFlags & CHANNEL_CCK) != 0)
#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
......@@ -506,6 +488,7 @@ struct ath9k_channel {
#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
/* These macros check chanmode and not channelFlags */
#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
((_c)->chanmode == CHANNEL_G_HT20))
#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
......@@ -702,13 +685,19 @@ enum ath9k_ani_cmd {
ATH9K_ANI_ALL = 0xff
};
enum phytype {
PHY_DS,
PHY_FH,
PHY_OFDM,
PHY_HT,
enum {
WLAN_RC_PHY_OFDM,
WLAN_RC_PHY_CCK,
WLAN_RC_PHY_HT_20_SS,
WLAN_RC_PHY_HT_20_DS,
WLAN_RC_PHY_HT_40_SS,
WLAN_RC_PHY_HT_40_DS,
WLAN_RC_PHY_HT_20_SS_HGI,
WLAN_RC_PHY_HT_20_DS_HGI,
WLAN_RC_PHY_HT_40_SS_HGI,
WLAN_RC_PHY_HT_40_DS_HGI,
WLAN_RC_PHY_MAX
};
#define PHY_CCK PHY_DS
enum ath9k_tp_scale {
ATH9K_TP_SCALE_MAX = 0,
......@@ -828,6 +817,8 @@ struct chan_centers {
u16 ext_center;
};
struct ath_rate_table;
/* Helpers */
enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
......@@ -838,7 +829,7 @@ bool ath9k_get_channel_edges(struct ath_hal *ah,
u16 flags, u16 *low,
u16 *high);
u16 ath9k_hw_computetxtime(struct ath_hal *ah,
const struct ath9k_rate_table *rates,
struct ath_rate_table *rates,
u32 frameLen, u16 rateix,
bool shortPreamble);
u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
......@@ -883,12 +874,6 @@ void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
void ath9k_hw_beaconinit(struct ath_hal *ah, u32 next_beacon, u32 beacon_period);
void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
const struct ath9k_beacon_state *bs);
/* Rate table */
const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
u32 mode);
/* HW Capabilities */
bool ath9k_hw_fill_cap_info(struct ath_hal *ah);
......@@ -904,7 +889,7 @@ u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio);
void ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
u32 ah_signal_type);
void ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio, u32 val);
#ifdef CONFIG_RFKILL
#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
void ath9k_enable_rfkill(struct ath_hal *ah);
#endif
int ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg);
......
......@@ -14,13 +14,9 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* Implementation of beacon processing. */
#include "core.h"
/*
* Configure parameters for the beacon queue
*
* This function will modify certain transmit queue properties depending on
* the operating mode of the station (AP or AdHoc). Parameters are AIFS
* settings and channel width min/max
......@@ -54,9 +50,15 @@ static int ath_beaconq_config(struct ath_softc *sc)
}
}
static void ath_bstuck_process(struct ath_softc *sc)
{
DPRINTF(sc, ATH_DBG_BEACON,
"%s: stuck beacon; resetting (bmiss count %u)\n",
__func__, sc->sc_bmisscount);
ath_reset(sc, false);
}
/*
* Setup the beacon frame for transmit.
*
* Associates the beacon frame buffer with a transmit descriptor. Will set
* up all required antenna switch parameters, rate codes, and channel flags.
* Beacons are always sent out at the lowest rate, and are not retried.
......@@ -68,7 +70,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
struct ath_hal *ah = sc->sc_ah;
struct ath_desc *ds;
struct ath9k_11n_rate_series series[4];
const struct ath9k_rate_table *rt;
struct ath_rate_table *rt;
int flags, antenna;
u8 rix, rate;
int ctsrate = 0;
......@@ -106,10 +108,10 @@ static void ath_beacon_setup(struct ath_softc *sc,
* XXX everything at min xmit rate
*/
rix = 0;
rt = sc->sc_currates;
rate = rt->info[rix].rateCode;
rt = sc->hw_rate_table[sc->sc_curmode];
rate = rt->info[rix].ratecode;
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
rate |= rt->info[rix].shortPreamble;
rate |= rt->info[rix].short_preamble;
ath9k_hw_set11n_txdesc(ah, ds,
skb->len + FCS_LEN, /* frame length */
......@@ -138,14 +140,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
ctsrate, ctsduration, series, 4, 0);
}
/*
* Generate beacon frame and queue cab data for a vap.
*
* Updates the contents of the beacon frame. It is assumed that the buffer for
* the beacon frame has been allocated in the ATH object, and simply needs to
* be filled for this cycle. Also, any CAB (crap after beacon?) traffic will
* be added to the beacon frame at this point.
*/
/* Generate beacon frame and queue cab data for a vap */
static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
{
struct ath_buf *bf;
......@@ -275,14 +270,6 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
}
/*
* Setup a h/w transmit queue for beacons.
*
* This function allocates an information structure (struct ath9k_txq_info)
* on the stack, sets some specific parameters (zero out channel width
* min/max, and enable aifs). The info structure does not need to be
* persistant.
*/
int ath_beaconq_setup(struct ath_hal *ah)
{
struct ath9k_tx_queue_info qi;
......@@ -295,14 +282,6 @@ int ath_beaconq_setup(struct ath_hal *ah)
return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
}
/*
* Allocate and setup an initial beacon frame.
*
* Allocate a beacon state variable for a specific VAP instance created on
* the ATH interface. This routine also calculates the beacon "slot" for
* staggared beacons in the mBSSID case.
*/
int ath_beacon_alloc(struct ath_softc *sc, int if_id)
{
struct ieee80211_vif *vif;
......@@ -321,7 +300,6 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
if (!avp->av_bcbuf) {
/* Allocate beacon state for hostap/ibss. We know
* a buffer is available. */
avp->av_bcbuf = list_first_entry(&sc->sc_bbuf,
struct ath_buf, list);
list_del(&avp->av_bcbuf->list);
......@@ -427,12 +405,6 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
return 0;
}
/*
* Reclaim beacon resources and return buffer to the pool.
*
* Checks the VAP to put the beacon frame buffer back to the ATH object
* queue, and de-allocates any skbs that were sent as CAB traffic.
*/
void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
{
if (avp->av_bcbuf != NULL) {
......@@ -458,13 +430,6 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
}
}
/*
* Tasklet for Sending Beacons
*
* Transmit one or more beacon frames at SWBA. Dynamic updates to the frame
* contents are done as needed and the slot time is also adjusted based on
* current state.
*/
void ath9k_beacon_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
......@@ -481,9 +446,7 @@ void ath9k_beacon_tasklet(unsigned long data)
if (sc->sc_flags & SC_OP_NO_RESET) {
show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
&rx_clear,
&rx_frame,
&tx_frame);
&rx_clear, &rx_frame, &tx_frame);
}
/*
......@@ -605,9 +568,10 @@ void ath9k_beacon_tasklet(unsigned long data)
if (sc->sc_updateslot == UPDATE) {
sc->sc_updateslot = COMMIT; /* commit next beacon */
sc->sc_slotupdate = slot;
} else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot)
ath_setslottime(sc); /* commit change to hardware */
} else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot) {
ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime);
sc->sc_updateslot = OK;
}
if (bfaddr != 0) {
/*
* Stop any current dma and put the new frame(s) on the queue.
......@@ -629,20 +593,6 @@ void ath9k_beacon_tasklet(unsigned long data)
}
}
/*
* Tasklet for Beacon Stuck processing
*
* Processing for Beacon Stuck.
* Basically resets the chip.
*/
void ath_bstuck_process(struct ath_softc *sc)
{
DPRINTF(sc, ATH_DBG_BEACON,
"%s: stuck beacon; resetting (bmiss count %u)\n",
__func__, sc->sc_bmisscount);
ath_reset(sc, false);
}
/*
* Configure the beacon and sleep timers.
*
......@@ -886,8 +836,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
}
}
/* Function to collect beacon rssi data and resync beacon if necessary */
void ath_beacon_sync(struct ath_softc *sc, int if_id)
{
/*
......
......@@ -176,14 +176,14 @@ static bool getNoiseFloorThresh(struct ath_hal *ah,
case CHANNEL_A_HT20:
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
*nft = (int16_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
*nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_5);
break;
case CHANNEL_B:
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
*nft = (int16_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
*nft = (int8_t)ath9k_hw_get_eeprom(ah, EEP_NFTHRESH_2);
break;
default:
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
......
This diff is collapsed.
This diff is collapsed.
......@@ -1244,7 +1244,7 @@ bool ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 1, &ant_config);
ath9k_hw_get_eeprom_antenna_cfg(ah, chan, 0, &ant_config);
REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
......@@ -1551,9 +1551,9 @@ u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
switch (param) {
case EEP_NFTHRESH_5:
return -pModal[0].noiseFloorThreshCh[0];
return pModal[0].noiseFloorThreshCh[0];
case EEP_NFTHRESH_2:
return -pModal[1].noiseFloorThreshCh[0];
return pModal[1].noiseFloorThreshCh[0];
case AR_EEPROM_MAC(0):
return pBase->macAddr[0] << 8 | pBase->macAddr[1];
case AR_EEPROM_MAC(1):
......@@ -1584,6 +1584,11 @@ u32 ath9k_hw_get_eeprom(struct ath_hal *ah,
return pBase->txMask;
case EEP_RX_MASK:
return pBase->rxMask;
case EEP_RXGAIN_TYPE:
return pBase->rxGainType;
case EEP_TXGAIN_TYPE:
return pBase->txGainType;
default:
return 0;
}
......
This diff is collapsed.
......@@ -415,6 +415,9 @@ struct ar5416Stats {
#define AR5416_EEP_MINOR_VER_3 0x3
#define AR5416_EEP_MINOR_VER_7 0x7
#define AR5416_EEP_MINOR_VER_9 0x9
#define AR5416_EEP_MINOR_VER_16 0x10
#define AR5416_EEP_MINOR_VER_17 0x11
#define AR5416_EEP_MINOR_VER_19 0x13
#define AR5416_NUM_5G_CAL_PIERS 8
#define AR5416_NUM_2G_CAL_PIERS 4
......@@ -436,6 +439,16 @@ struct ar5416Stats {
#define AR5416_MAX_CHAINS 3
#define AR5416_PWR_TABLE_OFFSET -5
/* Rx gain type values */
#define AR5416_EEP_RXGAIN_23DB_BACKOFF 0
#define AR5416_EEP_RXGAIN_13DB_BACKOFF 1
#define AR5416_EEP_RXGAIN_ORIG 2
/* Tx gain type values */
#define AR5416_EEP_TXGAIN_ORIGINAL 0
#define AR5416_EEP_TXGAIN_HIGH_POWER 1
enum eeprom_param {
EEP_NFTHRESH_5,
EEP_NFTHRESH_2,
......@@ -454,6 +467,8 @@ enum eeprom_param {
EEP_MINOR_REV,
EEP_TX_MASK,
EEP_RX_MASK,
EEP_RXGAIN_TYPE,
EEP_TXGAIN_TYPE,
};
enum ar5416_rates {
......@@ -485,7 +500,11 @@ struct base_eep_header {
u32 binBuildNumber;
u8 deviceType;
u8 pwdclkind;
u8 futureBase[32];
u8 futureBase_1[2];
u8 rxGainType;
u8 futureBase_2[3];
u8 txGainType;
u8 futureBase_3[25];
} __packed;
struct spur_chan {
......@@ -792,6 +811,8 @@ struct ath_hal_5416 {
struct ar5416IniArray ah_iniAddac;
struct ar5416IniArray ah_iniPcieSerdes;
struct ar5416IniArray ah_iniModesAdditional;
struct ar5416IniArray ah_iniModesRxGain;
struct ar5416IniArray ah_iniModesTxGain;
};
#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
......
This diff is collapsed.
......@@ -293,8 +293,10 @@ int ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
if (ads->ds_txstatus1 & AR_Filtered)
ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
if (ads->ds_txstatus1 & AR_FIFOUnderrun)
if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
ath9k_hw_updatetxtriglevel(ah, true);
}
if (ads->ds_txstatus9 & AR_TxOpExceeded)
ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
if (ads->ds_txstatus1 & AR_TxTimerExpired)
......
This diff is collapsed.
This diff is collapsed.
......@@ -20,83 +20,24 @@
#define RC_H
#include "ath9k.h"
/*
* Interface definitions for transmit rate control modules for the
* Atheros driver.
*
* A rate control module is responsible for choosing the transmit rate
* for each data frame. Management+control frames are always sent at
* a fixed rate.
*
* Only one module may be present at a time; the driver references
* rate control interfaces by symbol name. If multiple modules are
* to be supported we'll need to switch to a registration-based scheme
* as is currently done, for example, for authentication modules.
*
* An instance of the rate control module is attached to each device
* at attach time and detached when the device is destroyed. The module
* may associate data with each device and each node (station). Both
* sets of storage are opaque except for the size of the per-node storage
* which must be provided when the module is attached.
*
* The rate control module is notified for each state transition and
* station association/reassociation. Otherwise it is queried for a
* rate for each outgoing frame and provided status from each transmitted
* frame. Any ancillary processing is the responsibility of the module
* (e.g. if periodic processing is required then the module should setup
* it's own timer).
*
* In addition to the transmit rate for each frame the module must also
* indicate the number of attempts to make at the specified rate. If this
* number is != ATH_TXMAXTRY then an additional callback is made to setup
* additional transmit state. The rate control code is assumed to write
* this additional data directly to the transmit descriptor.
*/
struct ath_softc;
#define TRUE 1
#define FALSE 0
#define ATH_RATE_MAX 30
#define RATE_TABLE_SIZE 64
#define MAX_TX_RATE_PHY 48
#define ATH_RATE_MAX 30
/* VALID_ALL - valid for 20/40/Legacy,
* VALID - Legacy only,
* VALID_20 - HT 20 only,
* VALID_40 - HT 40 only */
enum ieee80211_fixed_rate_mode {
IEEE80211_FIXED_RATE_NONE = 0,
IEEE80211_FIXED_RATE_MCS = 1 /* HT rates */
};
/*
* Use the hal os glue code to get ms time
*/
#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8)))
#define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS
#define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS
#define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI
#define WLAN_PHY_HT_40_SS WLAN_RC_PHY_HT_40_SS
#define WLAN_PHY_HT_40_SS_HGI WLAN_RC_PHY_HT_40_SS_HGI
#define WLAN_PHY_HT_40_DS WLAN_RC_PHY_HT_40_DS
#define WLAN_PHY_HT_40_DS_HGI WLAN_RC_PHY_HT_40_DS_HGI
#define WLAN_PHY_OFDM PHY_OFDM
#define WLAN_PHY_CCK PHY_CCK
#define TRUE_20 0x2
#define TRUE_40 0x4
#define TRUE_2040 (TRUE_20|TRUE_40)
#define TRUE_ALL (TRUE_2040|TRUE)
enum {
WLAN_RC_PHY_HT_20_SS = 4,
WLAN_RC_PHY_HT_20_DS,
WLAN_RC_PHY_HT_40_SS,
WLAN_RC_PHY_HT_40_DS,
WLAN_RC_PHY_HT_20_SS_HGI,
WLAN_RC_PHY_HT_20_DS_HGI,
WLAN_RC_PHY_HT_40_SS_HGI,
WLAN_RC_PHY_HT_40_DS_HGI,
WLAN_RC_PHY_MAX
};
#define INVALID 0x0
#define VALID 0x1
#define VALID_20 0x2
#define VALID_40 0x4
#define VALID_2040 (VALID_20|VALID_40)
#define VALID_ALL (VALID_2040|VALID)
#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
......@@ -113,26 +54,22 @@ enum {
#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
/* Returns the capflag mode */
#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \
(capflag & WLAN_RC_40_FLAG) ? TRUE_40 : TRUE_20 : TRUE))
(capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID))
/* Return TRUE if flag supports HT20 && client supports HT20 or
* return TRUE if flag supports HT40 && client supports HT40.
* This is used becos some rates overlap between HT20/HT40.
*/
#define WLAN_RC_PHY_HT_VALID(flag, capflag) (((flag & TRUE_20) && !(capflag \
& WLAN_RC_40_FLAG)) || ((flag & TRUE_40) && \
(capflag & WLAN_RC_40_FLAG)))
#define WLAN_RC_PHY_HT_VALID(flag, capflag) \
(((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \
((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG)))
#define WLAN_RC_DS_FLAG (0x01)
#define WLAN_RC_40_FLAG (0x02)
#define WLAN_RC_SGI_FLAG (0x04)
#define WLAN_RC_HT_FLAG (0x08)
#define RATE_TABLE_SIZE 64
/**
* struct ath_rate_table - Rate Control table
* @valid: valid for use in rate control
......@@ -149,10 +86,11 @@ enum {
* @max_4ms_framelen: maximum frame length(bytes) for tx duration
* @probe_interval: interval for rate control to probe for other rates
* @rssi_reduce_interval: interval for rate control to reduce rssi
* @initial_ratemax: initial ratemax value used in ath_rc_sib_update()
* @initial_ratemax: initial ratemax value
*/
struct ath_rate_table {
int rate_cnt;
u8 rateCodeToIndex[256];
struct {
int valid;
int valid_single_stream;
......@@ -170,42 +108,26 @@ struct ath_rate_table {
u8 sgi_index;
u8 ht_index;
u32 max_4ms_framelen;
u16 lpAckDuration;
u16 spAckDuration;
} info[RATE_TABLE_SIZE];
u32 probe_interval;
u32 rssi_reduce_interval;
u8 initial_ratemax;
};
#define ATH_RC_PROBE_ALLOWED 0x00000001
#define ATH_RC_MINRATE_LASTRATE 0x00000002
struct ath_rc_series {
u8 rix;
u8 tries;
u8 flags;
u32 max_4ms_framelen;
};
/* rcs_flags definition */
#define ATH_RC_DS_FLAG 0x01
#define ATH_RC_CW40_FLAG 0x02 /* CW 40 */
#define ATH_RC_SGI_FLAG 0x04 /* Short Guard Interval */
#define ATH_RC_HT_FLAG 0x08 /* HT */
#define ATH_RC_RTSCTS_FLAG 0x10 /* RTS-CTS */
/*
* State structures for new rate adaptation code
*/
#define MAX_TX_RATE_TBL 64
#define MAX_TX_RATE_PHY 48
struct ath_tx_ratectrl_state {
int8_t rssi_thres; /* required rssi for this rate (dB) */
u8 per; /* recent estimate of packet error rate (%) */
};
struct ath_rateset {
u8 rs_nrates;
u8 rs_rates[ATH_RATE_MAX];
};
/**
* struct ath_tx_ratectrl - TX Rate control Information
* struct ath_rate_priv - Rate Control priv data
* @state: RC state
* @rssi_last: last ACK rssi
* @rssi_last_lookup: last ACK rssi used for lookup
......@@ -224,9 +146,13 @@ struct ath_tx_ratectrl_state {
* @valid_phy_ratecnt: valid rate count
* @rate_max_phy: phy index for the max rate
* @probe_interval: interval for ratectrl to probe for other rates
* @prev_data_rix: rate idx of last data frame
* @ht_cap: HT capabilities
* @single_stream: When TRUE, only single TX stream possible
* @neg_rates: Negotatied rates
* @neg_ht_rates: Negotiated HT rates
*/
struct ath_tx_ratectrl {
struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL];
struct ath_rate_priv {
int8_t rssi_last;
int8_t rssi_last_lookup;
int8_t rssi_last_prev;
......@@ -236,89 +162,40 @@ struct ath_tx_ratectrl {
int32_t rssi_sum;
u8 rate_table_size;
u8 probe_rate;
u32 rssi_time;
u32 rssi_down_time;
u32 probe_time;
u8 hw_maxretry_pktcnt;
u8 max_valid_rate;
u8 valid_rate_index[MAX_TX_RATE_TBL];
u32 per_down_time;
/* 11n state */
u8 valid_rate_index[RATE_TABLE_SIZE];
u8 ht_cap;
u8 single_stream;
u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL];
u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
u8 rc_phy_mode;
u8 rate_max_phy;
u32 rssi_time;
u32 rssi_down_time;
u32 probe_time;
u32 per_down_time;
u32 probe_interval;
};
struct ath_rateset {
u8 rs_nrates;
u8 rs_rates[ATH_RATE_MAX];
};
/* per-device state */
struct ath_rate_softc {
/* phy tables that contain rate control data */
const void *hw_rate_table[ATH9K_MODE_MAX];
/* -1 or index of fixed rate */
int fixedrix;
};
/* per-node state */
struct ath_rate_node {
struct ath_tx_ratectrl tx_ratectrl;
/* rate idx of last data frame */
u32 prev_data_rix;
/* ht capabilities */
u8 ht_cap;
/* When TRUE, only single stream Tx possible */
u8 single_stream;
/* Negotiated rates */
u32 tx_triglevel_max;
struct ath_tx_ratectrl_state state[RATE_TABLE_SIZE];
struct ath_rateset neg_rates;
/* Negotiated HT rates */
struct ath_rateset neg_ht_rates;
struct ath_rate_softc *asc;
struct ath_vap *avp;
};
/* Driver data of ieee80211_tx_info */
struct ath_tx_info_priv {
struct ath_rc_series rcs[4];
struct ath_tx_status tx;
int n_frames;
int n_bad_frames;
u8 min_rate;
bool update_rc;
};
/*
* Attach/detach a rate control module.
*/
struct ath_rate_softc *ath_rate_attach(struct ath_hal *ah);
void ath_rate_detach(struct ath_rate_softc *asc);
/*
* Update/reset rate control state for 802.11 state transitions.
* Important mostly as the analog to ath_rate_newassoc when operating
* in station mode.
*/
void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv);
void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp);
/*
* Return rate index for given Dot11 Rate.
*/
u8 ath_rate_findrateix(struct ath_softc *sc,
u8 dot11_rate);
#define ATH_TX_INFO_PRIV(tx_info) \
((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0]))
/* Routines to register/unregister rate control algorithm */
void ath_rate_attach(struct ath_softc *sc);
u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate);
int ath_rate_control_register(void);
void ath_rate_control_unregister(void);
......
This diff is collapsed.
This diff is collapsed.
......@@ -107,7 +107,7 @@ static inline int __iwl3945_poll_bit(const char *f, u32 l,
int ret = _iwl3945_poll_bit(priv, addr, bits, mask, timeout);
IWL_DEBUG_IO("poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
addr, bits, mask,
unlikely(ret == -ETIMEDOUT)?"timeout":"", f, l);
unlikely(ret == -ETIMEDOUT) ? "timeout" : "", f, l);
return ret;
}
#define iwl3945_poll_bit(priv, addr, bits, mask, timeout) \
......
......@@ -886,7 +886,6 @@ struct iwl3945_priv {
struct work_struct report_work;
struct work_struct request_scan;
struct work_struct beacon_update;
struct work_struct set_monitor;
struct tasklet_struct irq_tasklet;
......
This diff is collapsed.
......@@ -475,6 +475,9 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
case IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD:
index = IWL_CALIB_TX_IQ_PERD;
break;
case IWL_PHY_CALIBRATE_BASE_BAND_CMD:
index = IWL_CALIB_BASE_BAND;
break;
default:
IWL_ERROR("Unknown calibration notification %d\n",
hdr->op_code);
......@@ -697,9 +700,10 @@ static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
static int iwl5000_alive_notify(struct iwl_priv *priv)
{
u32 a;
int i = 0;
unsigned long flags;
int ret;
int i, chan;
u32 reg_val;
spin_lock_irqsave(&priv->lock, flags);
......@@ -722,6 +726,18 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
iwl_write_prph(priv, IWL50_SCD_DRAM_BASE_ADDR,
priv->scd_bc_tbls.dma >> 10);
/* Enable DMA channel */
for (chan = 0; chan < FH50_TCSR_CHNL_NUM ; chan++)
iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
/* Update FH chicken bits */
reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
iwl_write_prph(priv, IWL50_SCD_QUEUECHAIN_SEL,
IWL50_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num));
iwl_write_prph(priv, IWL50_SCD_AGGR_SEL, 0);
......@@ -841,8 +857,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.calib_init_cfg =
BIT(IWL_CALIB_XTAL) |
BIT(IWL_CALIB_LO) |
BIT(IWL_CALIB_TX_IQ) |
BIT(IWL_CALIB_TX_IQ_PERD);
BIT(IWL_CALIB_TX_IQ) |
BIT(IWL_CALIB_TX_IQ_PERD) |
BIT(IWL_CALIB_BASE_BAND);
break;
case CSR_HW_REV_TYPE_5150:
priv->hw_params.calib_init_cfg = 0;
......@@ -969,7 +986,7 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
ra_tid = BUILD_RAxTID(sta_id, tid);
/* Modify device's station table to Tx this TID */
iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);
iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
......@@ -1111,7 +1128,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb[0]);
info->status.rates[0].count = tx_resp->failure_frame + 1;
info->flags &= ~IEEE80211_TX_CTL_AMPDU;
info->flags |= iwl_is_tx_success(status)?
info->flags |= iwl_is_tx_success(status) ?
IEEE80211_TX_STAT_ACK : 0;
iwl_hwrate_to_tx_control(priv, rate_n_flags, info);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -36,7 +36,7 @@
#include "iwl-core.h"
#define IWL_CMD(x) case x : return #x
#define IWL_CMD(x) case x: return #x
const char *get_cmd_string(u8 cmd)
{
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment