Commit 9320b5c4 authored by Nick Kossifidis's avatar Nick Kossifidis Committed by John W. Linville
Browse files

ath5k: Reset cleanup and generic cleanup



 * No functional changes

 * Clean up reset:
 Introduce init functions for each unit and call them instead
 of having everything inside ath5k_hw_reset (it's just c/p for
 now so nothing changes except calling order -I tested it with
 various cards and it's ok-)

 * Further cleanups:
 ofdm_timings belongs to phy.c
 rate_duration belongs to pcu.c
 clock functions are general and belong to reset.c (more to follow)

 * Reorder functions for better organization:
 We start with helpers and other functions follow in categories,
 init functions are last
Signed-off-by: default avatarNick Kossifidis <mickflemm@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent ea066d5a
......@@ -58,19 +58,19 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level)
{
/* TODO:
* ANI documents suggest the following five levels to use, but the HAL
* and ath9k use only use the last two levels, making this
* and ath9k use only the last two levels, making this
* essentially an on/off option. There *may* be a reason for this (???),
* so i stick with the HAL version for now...
*/
#if 0
static const s8 hi[] = { -18, -18, -16, -14, -12 };
static const s8 lo[] = { -52, -56, -60, -64, -70 };
static const s8 hi[] = { -18, -18, -16, -14, -12 };
static const s8 sz[] = { -34, -41, -48, -55, -62 };
static const s8 fr[] = { -70, -72, -75, -78, -80 };
#else
static const s8 sz[] = { -55, -62 };
static const s8 lo[] = { -64, -70 };
static const s8 hi[] = { -14, -12 };
static const s8 sz[] = { -55, -62 };
static const s8 fr[] = { -78, -80 };
#endif
if (level < 0 || level >= ARRAY_SIZE(sz)) {
......
......@@ -1140,12 +1140,14 @@ void ath5k_hw_detach(struct ath5k_hw *ah);
int ath5k_sysfs_register(struct ath5k_softc *sc);
void ath5k_sysfs_unregister(struct ath5k_softc *sc);
/* LED functions */
int ath5k_init_leds(struct ath5k_softc *sc);
void ath5k_led_enable(struct ath5k_softc *sc);
void ath5k_led_off(struct ath5k_softc *sc);
void ath5k_unregister_leds(struct ath5k_softc *sc);
/* Reset Functions */
int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
int ath5k_hw_on_hold(struct ath5k_hw *ah);
......@@ -1155,6 +1157,13 @@ int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
bool is_set);
/* Power management functions */
/* Clock rate related functions */
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
/* DMA Related Functions */
void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
......@@ -1171,26 +1180,28 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask);
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
/* Init function */
void ath5k_hw_dma_init(struct ath5k_hw *ah);
/* EEPROM access functions */
int ath5k_eeprom_init(struct ath5k_hw *ah);
void ath5k_eeprom_detach(struct ath5k_hw *ah);
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
/* Protocol Control Unit Functions */
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
/* BSSID Functions */
/* RX filter control*/
int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
void ath5k_hw_set_bssid(struct ath5k_hw *ah);
void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
/* Receive start/stop functions */
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
/* RX Filter functions */
void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
/* Receive (DRU) start/stop functions */
void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
/* Beacon control functions */
u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
......@@ -1199,10 +1210,9 @@ 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 */
unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
void ath5k_hw_set_clockrate(struct ath5k_hw *ah);
/* Init function */
void ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
u8 mode);
/* Queue Control Unit, DFS Control Unit Functions */
int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
......@@ -1216,6 +1226,8 @@ u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
/* Init function */
int ath5k_hw_init_queues(struct ath5k_hw *ah);
/* Hardware Descriptor Functions */
int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
......@@ -1225,6 +1237,7 @@ int ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3);
/* GPIO Functions */
void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
......@@ -1234,11 +1247,13 @@ int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
u32 interrupt_level);
/* rfkill Functions */
/* RFkill Functions */
void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
/* Misc functions */
/* Misc functions TODO: Cleanup */
int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
int ath5k_hw_get_capability(struct ath5k_hw *ah,
enum ath5k_capability_type cap_type, u32 capability,
......@@ -1246,19 +1261,20 @@ int ath5k_hw_get_capability(struct ath5k_hw *ah,
int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
/* Initial register settings functions */
int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
/* Initialize RF */
int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
struct ieee80211_channel *channel,
unsigned int mode);
int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
/* PHY functions */
/* Misc PHY functions */
u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
int ath5k_hw_phy_disable(struct ath5k_hw *ah);
/* Gain_F optimization */
enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
/* PHY/RF channel functions */
bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
/* PHY calibration */
void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah);
int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
......@@ -1267,18 +1283,14 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah);
/* Spur mitigation */
bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
struct ieee80211_channel *channel);
void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
struct ieee80211_channel *channel);
/* Misc PHY functions */
u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
int ath5k_hw_phy_disable(struct ath5k_hw *ah);
/* Antenna control */
void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
/* TX power setup */
int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
u8 ee_mode, u8 txpower);
int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
/* Init function */
int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
u8 mode, u8 ee_mode, u8 freq);
/*
* Functions used internaly
......
......@@ -26,9 +26,10 @@
#include "debug.h"
#include "base.h"
/*
* TX Descriptors
*/
/************************\
* TX Control descriptors *
\************************/
/*
* Initialize the 2-word tx control descriptor on 5210/5211
......@@ -335,6 +336,11 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
return 0;
}
/***********************\
* TX Status descriptors *
\***********************/
/*
* Proccess the tx status descriptor on 5210/5211
*/
......@@ -476,9 +482,10 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
return 0;
}
/*
* RX Descriptors
*/
/****************\
* RX Descriptors *
\****************/
/*
* Initialize an rx control descriptor
......@@ -666,6 +673,11 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
return 0;
}
/********\
* Attach *
\********/
/*
* Init function pointers inside ath5k_hw struct
*/
......
......@@ -37,6 +37,7 @@
#include "debug.h"
#include "base.h"
/*********\
* Receive *
\*********/
......@@ -427,6 +428,7 @@ done:
return ret;
}
/*******************\
* Interrupt masking *
\*******************/
......@@ -688,3 +690,46 @@ enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
return old_mask;
}
/********************\
Init/Stop functions
\********************/
/**
* ath5k_hw_dma_init - Initialize DMA unit
*
* @ah: The &struct ath5k_hw
*
* Set DMA size and pre-enable interrupts
* (driver handles tx/rx buffer setup and
* dma start/stop)
*
* XXX: Save/restore RXDP/TXDP registers ?
*/
void ath5k_hw_dma_init(struct ath5k_hw *ah)
{
/*
* Set Rx/Tx DMA Configuration
*
* Set standard DMA size (128). Note that
* a DMA size of 512 causes rx overruns and tx errors
* on pci-e cards (tested on 5424 but since rx overruns
* also occur on 5416/5418 with madwifi we set 128
* for all PCI-E cards to be safe).
*
* XXX: need to check 5210 for this
* TODO: Check out tx triger level, it's always 64 on dumps but I
* guess we can tweak it and see how it goes ;-)
*/
if (ah->ah_version != AR5K_AR5210) {
AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
}
/* Pre-enable interrupts on 5211/5212*/
if (ah->ah_version != AR5K_AR5210)
ath5k_hw_set_imr(ah, ah->ah_imr);
}
......@@ -28,6 +28,43 @@
#include "debug.h"
#include "base.h"
/******************\
* Helper functions *
\******************/
/*
* Translate binary channel representation in EEPROM to frequency
*/
static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
unsigned int mode)
{
u16 val;
if (bin == AR5K_EEPROM_CHANNEL_DIS)
return bin;
if (mode == AR5K_EEPROM_MODE_11A) {
if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
val = (5 * bin) + 4800;
else
val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
(bin * 10) + 5100;
} else {
if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
val = bin + 2300;
else
val = bin + 2400;
}
return val;
}
/*********\
* Parsers *
\*********/
/*
* Read from eeprom
*/
......@@ -62,33 +99,6 @@ static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
return -ETIMEDOUT;
}
/*
* Translate binary channel representation in EEPROM to frequency
*/
static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
unsigned int mode)
{
u16 val;
if (bin == AR5K_EEPROM_CHANNEL_DIS)
return bin;
if (mode == AR5K_EEPROM_MODE_11A) {
if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
val = (5 * bin) + 4800;
else
val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
(bin * 10) + 5100;
} else {
if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
val = bin + 2300;
else
val = bin + 2400;
}
return val;
}
/*
* Initialize eeprom & capabilities structs
*/
......@@ -647,6 +657,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
return 0;
}
/*
* Read power calibration for RF5111 chips
*
......@@ -1514,6 +1525,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
return 0;
}
/*
* Read per channel calibration info from EEPROM
*
......@@ -1607,15 +1619,6 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
return 0;
}
void
ath5k_eeprom_detach(struct ath5k_hw *ah)
{
u8 mode;
for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
ath5k_eeprom_free_pcal_info(ah, mode);
}
/* Read conformance test limits used for regulatory control */
static int
ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
......@@ -1756,6 +1759,44 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
return ret;
}
/*
* Read the MAC address from eeprom
*/
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
{
u8 mac_d[ETH_ALEN] = {};
u32 total, offset;
u16 data;
int octet, ret;
ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
if (ret)
return ret;
for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
ret = ath5k_hw_eeprom_read(ah, offset, &data);
if (ret)
return ret;
total += data;
mac_d[octet + 1] = data & 0xff;
mac_d[octet] = data >> 8;
octet += 2;
}
if (!total || total == 3 * 0xffff)
return -EINVAL;
memcpy(mac, mac_d, ETH_ALEN);
return 0;
}
/***********************\
* Init/Detach functions *
\***********************/
/*
* Initialize eeprom data structure
*/
......@@ -1787,35 +1828,11 @@ ath5k_eeprom_init(struct ath5k_hw *ah)
return 0;
}
/*
* Read the MAC address from eeprom
*/
int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
void
ath5k_eeprom_detach(struct ath5k_hw *ah)
{
u8 mac_d[ETH_ALEN] = {};
u32 total, offset;
u16 data;
int octet, ret;
ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
if (ret)
return ret;
for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
ret = ath5k_hw_eeprom_read(ah, offset, &data);
if (ret)
return ret;
total += data;
mac_d[octet + 1] = data & 0xff;
mac_d[octet] = data >> 8;
octet += 2;
}
if (!total || total == 3 * 0xffff)
return -EINVAL;
memcpy(mac, mac_d, ETH_ALEN);
u8 mode;
return 0;
for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
ath5k_eeprom_free_pcal_info(ah, mode);
}
......@@ -32,86 +32,47 @@
#include "base.h"
/*******************\
* Generic functions *
* Helper functions *
\*******************/
/**
* ath5k_hw_set_opmode - Set PCU operating mode
* ath5k_hw_get_default_slottime - Get the default slot time for current mode
*
* @ah: The &struct ath5k_hw
* @op_mode: &enum nl80211_iftype operating mode
*
* Initialize PCU for the various operating modes (AP/STA etc)
*/
int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
{
struct ath_common *common = ath5k_hw_common(ah);
u32 pcu_reg, beacon_reg, low_id, high_id;
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
/* Preserve rest settings */
pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
| AR5K_STA_ID1_KEYSRCH_MODE
| (ah->ah_version == AR5K_AR5210 ?
(AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
beacon_reg = 0;
struct ieee80211_channel *channel = ah->ah_current_channel;
switch (op_mode) {
case NL80211_IFTYPE_ADHOC:
pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
beacon_reg |= AR5K_BCR_ADHOC;
if (ah->ah_version == AR5K_AR5210)
pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
else
AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
break;
if (channel->hw_value & CHANNEL_TURBO)
return 6; /* both turbo modes */
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_MESH_POINT:
pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
beacon_reg |= AR5K_BCR_AP;
if (ah->ah_version == AR5K_AR5210)
pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
else
AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
break;
if (channel->hw_value & CHANNEL_CCK)
return 20; /* 802.11b */
case NL80211_IFTYPE_STATION:
pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
| (ah->ah_version == AR5K_AR5210 ?
AR5K_STA_ID1_PWR_SV : 0);
case NL80211_IFTYPE_MONITOR:
pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
| (ah->ah_version == AR5K_AR5210 ?
AR5K_STA_ID1_NO_PSPOLL : 0);
break;
return 9; /* 802.11 a/g */
}
default:
return -EINVAL;
}
/**
* ath5k_hw_get_default_sifs - Get the default SIFS for current mode
*
* @ah: The &struct ath5k_hw
*/
static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
{
struct ieee80211_channel *channel = ah->ah_current_channel;
/*
* Set PCU registers
*/
low_id = get_unaligned_le32(common->macaddr);
high_id = get_unaligned_le16(common->macaddr + 4);
ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
if (channel->hw_value & CHANNEL_TURBO)
return 8; /* both turbo modes */
/*
* Set Beacon Control Register on 5210
*/
if (ah->ah_version == AR5K_AR5210)
ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
if (channel->hw_value & CHANNEL_5GHZ)
return 16; /* 802.11a */
return 0;
return 10; /* 802.11 b/g */
}
/**
* ath5k_hw_update - Update MIB counters (mac layer statistics)
* ath5k_hw_update_mib_counters - Update MIB counters (mac layer statistics)
*
* @ah: The &struct ath5k_hw
*
......@@ -163,6 +124,82 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
* ACK/CTS Timeouts *
\******************/
/*
* index into rates for control rates, we can set it up like this because
* this is only used for AR5212 and we know it supports G mode
*/
static const unsigned int control_rates[] =
{ 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
/**
* ath5k_hw_write_rate_duration - fill rate code to duration table
*
* @ah: the &struct ath5k_hw
* @mode: one of enum ath5k_driver_mode
*
* Write the rate code to duration table upon hw reset. This is a helper for
* ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
* the hardware, based on current mode, for each rate. The rates which are
* capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have