Commit 098401a6 authored by David S. Miller's avatar David S. Miller
parents cb7b48f6 c112d0c5
...@@ -1052,6 +1052,7 @@ struct ath5k_hw { ...@@ -1052,6 +1052,7 @@ struct ath5k_hw {
bool ah_calibration; bool ah_calibration;
bool ah_running; bool ah_running;
bool ah_single_chip; bool ah_single_chip;
bool ah_combined_mic;
enum ath5k_rfgain ah_rf_gain; enum ath5k_rfgain ah_rf_gain;
u32 ah_mac_srev; u32 ah_mac_srev;
......
...@@ -317,6 +317,12 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) ...@@ -317,6 +317,12 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
goto err_free; goto err_free;
} }
if (srev >= AR5K_SREV_AR2414) {
ah->ah_combined_mic = true;
AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
AR5K_MISC_MODE_COMBINED_MIC);
}
/* MAC address is cleared until add_interface */ /* MAC address is cleared until add_interface */
ath5k_hw_set_lladdr(ah, mac); ath5k_hw_set_lladdr(ah, mac);
......
...@@ -267,24 +267,23 @@ void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac) ...@@ -267,24 +267,23 @@ void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
* @mac: The card's mac address * @mac: The card's mac address
* *
* Set station id on hw using the provided mac address * Set station id on hw using the provided mac address
*
* NOTE: This is only called during attach, don't call it
* on reset because it overwrites all AR5K_STA_ID1 settings.
* We have set_opmode (above) for reset.
*/ */
int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
{ {
u32 low_id, high_id; u32 low_id, high_id;
u32 pcu_reg;
ATH5K_TRACE(ah->ah_sc); ATH5K_TRACE(ah->ah_sc);
/* Set new station ID */ /* Set new station ID */
memcpy(ah->ah_sta_id, mac, ETH_ALEN); memcpy(ah->ah_sta_id, mac, ETH_ALEN);
pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
low_id = AR5K_LOW_ID(mac); low_id = AR5K_LOW_ID(mac);
high_id = AR5K_HIGH_ID(mac); high_id = AR5K_HIGH_ID(mac);
ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1); ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
return 0; return 0;
} }
...@@ -1014,6 +1013,23 @@ int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry) ...@@ -1014,6 +1013,23 @@ int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
AR5K_KEYTABLE_VALID; AR5K_KEYTABLE_VALID;
} }
static
int ath5k_keycache_type(const struct ieee80211_key_conf *key)
{
switch (key->alg) {
case ALG_TKIP:
return AR5K_KEYTABLE_TYPE_TKIP;
case ALG_CCMP:
return AR5K_KEYTABLE_TYPE_CCM;
case ALG_WEP:
if (key->keylen == LEN_WEP40)
return AR5K_KEYTABLE_TYPE_40;
else if (key->keylen == LEN_WEP104)
return AR5K_KEYTABLE_TYPE_104;
}
return -EINVAL;
}
/* /*
* Set a key entry on the table * Set a key entry on the table
*/ */
...@@ -1028,6 +1044,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, ...@@ -1028,6 +1044,7 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
u32 keytype; u32 keytype;
u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
bool is_tkip; bool is_tkip;
const u8 *key_ptr;
ATH5K_TRACE(ah->ah_sc); ATH5K_TRACE(ah->ah_sc);
...@@ -1043,33 +1060,25 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, ...@@ -1043,33 +1060,25 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
(is_tkip && micentry > AR5K_KEYTABLE_SIZE)) (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
return -EOPNOTSUPP; return -EOPNOTSUPP;
switch (keylen) { if (unlikely(keylen > 16))
/* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */ return -EOPNOTSUPP;
case 40 / 8:
memcpy(&key_v[0], key->key, 5);
keytype = AR5K_KEYTABLE_TYPE_40;
break;
/* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */ keytype = ath5k_keycache_type(key);
case 104 / 8: if (keytype < 0)
memcpy(&key_v[0], &key->key[0], 6); return keytype;
memcpy(&key_v[2], &key->key[6], 6);
memcpy(&key_v[4], &key->key[12], 1);
keytype = AR5K_KEYTABLE_TYPE_104;
break;
/* WEP/TKIP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */
case 128 / 8:
memcpy(&key_v[0], &key->key[0], 6);
memcpy(&key_v[2], &key->key[6], 6);
memcpy(&key_v[4], &key->key[12], 4);
keytype = is_tkip ?
AR5K_KEYTABLE_TYPE_TKIP :
AR5K_KEYTABLE_TYPE_128;
break;
default: /*
return -EINVAL; /* shouldn't happen */ * each key block is 6 bytes wide, written as pairs of
* alternating 32 and 16 bit le values.
*/
key_ptr = key->key;
for (i = 0; keylen >= 6; keylen -= 6) {
memcpy(&key_v[i], key_ptr, 6);
i += 2;
key_ptr += 6;
} }
if (keylen)
memcpy(&key_v[i], key_ptr, keylen);
/* intentionally corrupt key until mic is installed */ /* intentionally corrupt key until mic is installed */
if (is_tkip) { if (is_tkip) {
...@@ -1087,20 +1096,20 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, ...@@ -1087,20 +1096,20 @@ int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
/* Install rx/tx MIC */ /* Install rx/tx MIC */
rxmic = (__le32 *) &key->key[16]; rxmic = (__le32 *) &key->key[16];
txmic = (__le32 *) &key->key[24]; txmic = (__le32 *) &key->key[24];
#if 0
/* MISC_MODE register & 0x04 - for mac srev >= griffin */ if (ah->ah_combined_mic) {
key_v[0] = rxmic[0]; key_v[0] = rxmic[0];
key_v[1] = (txmic[0] >> 16) & 0xffff; key_v[1] = (txmic[0] >> 16) & 0xffff;
key_v[2] = rxmic[1]; key_v[2] = rxmic[1];
key_v[3] = txmic[0] & 0xffff; key_v[3] = txmic[0] & 0xffff;
key_v[4] = txmic[1]; key_v[4] = txmic[1];
#else } else {
key_v[0] = rxmic[0]; key_v[0] = rxmic[0];
key_v[1] = 0; key_v[1] = 0;
key_v[2] = rxmic[1]; key_v[2] = rxmic[1];
key_v[3] = 0; key_v[3] = 0;
key_v[4] = 0; key_v[4] = 0;
#endif }
for (i = 0; i < ARRAY_SIZE(key_v); i++) for (i = 0; i < ARRAY_SIZE(key_v); i++)
ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
AR5K_KEYTABLE_OFF(micentry, i)); AR5K_KEYTABLE_OFF(micentry, i));
......
...@@ -1729,6 +1729,7 @@ ...@@ -1729,6 +1729,7 @@
#define AR5K_MISC_MODE 0x8120 /* Register Address */ #define AR5K_MISC_MODE 0x8120 /* Register Address */
#define AR5K_MISC_MODE_FBSSID_MATCH 0x00000001 /* Force BSSID match */ #define AR5K_MISC_MODE_FBSSID_MATCH 0x00000001 /* Force BSSID match */
#define AR5K_MISC_MODE_ACKSIFS_MEM 0x00000002 /* ACK SIFS memory (?) */ #define AR5K_MISC_MODE_ACKSIFS_MEM 0x00000002 /* ACK SIFS memory (?) */
#define AR5K_MISC_MODE_COMBINED_MIC 0x00000004 /* use rx/tx MIC key */
/* more bits */ /* more bits */
/* /*
......
...@@ -9,3 +9,14 @@ config ATH9K ...@@ -9,3 +9,14 @@ config ATH9K
Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets. Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
If you choose to build a module, it'll be called ath9k. If you choose to build a module, it'll be called ath9k.
config ATH9K_DEBUG
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=0x00002000
Look in ath9k/core.h for possible debug masks
...@@ -11,4 +11,6 @@ ath9k-y += hw.o \ ...@@ -11,4 +11,6 @@ ath9k-y += hw.o \
xmit.o \ xmit.o \
rc.o rc.o
ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
obj-$(CONFIG_ATH9K) += ath9k.o obj-$(CONFIG_ATH9K) += ath9k.o
...@@ -53,8 +53,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, ...@@ -53,8 +53,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) { if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"%s: level out of range (%u > %u)\n", "level out of range (%u > %u)\n",
__func__, level, level,
(unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired)); (unsigned)ARRAY_SIZE(ahp->ah_totalSizeDesired));
return false; return false;
} }
...@@ -158,8 +158,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, ...@@ -158,8 +158,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
if (level >= ARRAY_SIZE(firstep)) { if (level >= ARRAY_SIZE(firstep)) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"%s: level out of range (%u > %u)\n", "level out of range (%u > %u)\n",
__func__, level, level,
(unsigned) ARRAY_SIZE(firstep)); (unsigned) ARRAY_SIZE(firstep));
return false; return false;
} }
...@@ -180,8 +180,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, ...@@ -180,8 +180,8 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
if (level >= ARRAY_SIZE(cycpwrThr1)) { if (level >= ARRAY_SIZE(cycpwrThr1)) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"%s: level out of range (%u > %u)\n", "level out of range (%u > %u)\n",
__func__, level, level,
(unsigned) (unsigned)
ARRAY_SIZE(cycpwrThr1)); ARRAY_SIZE(cycpwrThr1));
return false; return false;
...@@ -200,11 +200,11 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah, ...@@ -200,11 +200,11 @@ static bool ath9k_hw_ani_control(struct ath_hal *ah,
break; break;
default: default:
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"%s: invalid cmd %u\n", __func__, cmd); "invalid cmd %u\n", cmd);
return false; return false;
} }
DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__); DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n");
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"noiseImmunityLevel=%d, spurImmunityLevel=%d, " "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
"ofdmWeakSigDetectOff=%d\n", "ofdmWeakSigDetectOff=%d\n",
...@@ -262,8 +262,8 @@ static void ath9k_ani_restart(struct ath_hal *ah) ...@@ -262,8 +262,8 @@ static void ath9k_ani_restart(struct ath_hal *ah)
AR_PHY_COUNTMAX - aniState->cckTrigHigh; AR_PHY_COUNTMAX - aniState->cckTrigHigh;
} }
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"%s: Writing ofdmbase=%u cckbase=%u\n", "Writing ofdmbase=%u cckbase=%u\n",
__func__, aniState->ofdmPhyErrBase, aniState->ofdmPhyErrBase,
aniState->cckPhyErrBase); aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
...@@ -303,7 +303,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah) ...@@ -303,7 +303,7 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
} }
} }
if (ah->ah_opmode == ATH9K_M_HOSTAP) { if (ah->ah_opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1); aniState->firstepLevel + 1);
...@@ -368,7 +368,7 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah) ...@@ -368,7 +368,7 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
return; return;
} }
} }
if (ah->ah_opmode == ATH9K_M_HOSTAP) { if (ah->ah_opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1); aniState->firstepLevel + 1);
...@@ -398,7 +398,7 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah) ...@@ -398,7 +398,7 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
aniState = ahp->ah_curani; aniState = ahp->ah_curani;
if (ah->ah_opmode == ATH9K_M_HOSTAP) { if (ah->ah_opmode == NL80211_IFTYPE_AP) {
if (aniState->firstepLevel > 0) { if (aniState->firstepLevel > 0) {
if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel - 1)) aniState->firstepLevel - 1))
...@@ -487,11 +487,10 @@ void ath9k_ani_reset(struct ath_hal *ah) ...@@ -487,11 +487,10 @@ void ath9k_ani_reset(struct ath_hal *ah)
aniState = &ahp->ah_ani[index]; aniState = &ahp->ah_ani[index];
ahp->ah_curani = aniState; ahp->ah_curani = aniState;
if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA if (DO_ANI(ah) && ah->ah_opmode != NL80211_IFTYPE_STATION
&& ah->ah_opmode != ATH9K_M_IBSS) { && ah->ah_opmode != NL80211_IFTYPE_ADHOC) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"%s: Reset ANI state opmode %u\n", __func__, "Reset ANI state opmode %u\n", ah->ah_opmode);
ah->ah_opmode);
ahp->ah_stats.ast_ani_reset++; ahp->ah_stats.ast_ani_reset++;
ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
...@@ -505,7 +504,7 @@ void ath9k_ani_reset(struct ath_hal *ah) ...@@ -505,7 +504,7 @@ void ath9k_ani_reset(struct ath_hal *ah)
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
ATH9K_RX_FILTER_PHYERR); ATH9K_RX_FILTER_PHYERR);
if (ah->ah_opmode == ATH9K_M_HOSTAP) { if (ah->ah_opmode == NL80211_IFTYPE_AP) {
ahp->ah_curani->ofdmTrigHigh = ahp->ah_curani->ofdmTrigHigh =
ah->ah_config.ofdm_trig_high; ah->ah_config.ofdm_trig_high;
ahp->ah_curani->ofdmTrigLow = ahp->ah_curani->ofdmTrigLow =
...@@ -581,9 +580,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah, ...@@ -581,9 +580,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah,
phyCnt2 < aniState->cckPhyErrBase) { phyCnt2 < aniState->cckPhyErrBase) {
if (phyCnt1 < aniState->ofdmPhyErrBase) { if (phyCnt1 < aniState->ofdmPhyErrBase) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"%s: phyCnt1 0x%x, resetting " "phyCnt1 0x%x, resetting "
"counter value to 0x%x\n", "counter value to 0x%x\n",
__func__, phyCnt1, phyCnt1,
aniState->ofdmPhyErrBase); aniState->ofdmPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_1, REG_WRITE(ah, AR_PHY_ERR_1,
aniState->ofdmPhyErrBase); aniState->ofdmPhyErrBase);
...@@ -592,9 +591,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah, ...@@ -592,9 +591,9 @@ void ath9k_hw_ani_monitor(struct ath_hal *ah,
} }
if (phyCnt2 < aniState->cckPhyErrBase) { if (phyCnt2 < aniState->cckPhyErrBase) {
DPRINTF(ah->ah_sc, ATH_DBG_ANI, DPRINTF(ah->ah_sc, ATH_DBG_ANI,
"%s: phyCnt2 0x%x, resetting " "phyCnt2 0x%x, resetting "
"counter value to 0x%x\n", "counter value to 0x%x\n",
__func__, phyCnt2, phyCnt2,
aniState->cckPhyErrBase); aniState->cckPhyErrBase);
REG_WRITE(ah, AR_PHY_ERR_2, REG_WRITE(ah, AR_PHY_ERR_2,
aniState->cckPhyErrBase); aniState->cckPhyErrBase);
...@@ -692,8 +691,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah, ...@@ -692,8 +691,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
if (cycles == 0 || cycles > cc) { if (cycles == 0 || cycles > cc) {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"%s: cycle counter wrap. ExtBusy = 0\n", "cycle counter wrap. ExtBusy = 0\n");
__func__);
good = 0; good = 0;
} else { } else {
u32 cc_d = cc - cycles; u32 cc_d = cc - cycles;
......
...@@ -647,13 +647,6 @@ enum ath9k_ant_setting { ...@@ -647,13 +647,6 @@ enum ath9k_ant_setting {
ATH9K_ANT_FIXED_B ATH9K_ANT_FIXED_B
}; };
enum ath9k_opmode {
ATH9K_M_STA = 1,
ATH9K_M_IBSS = 0,
ATH9K_M_HOSTAP = 6,
ATH9K_M_MONITOR = 8
};
#define ATH9K_SLOT_TIME_6 6 #define ATH9K_SLOT_TIME_6 6
#define ATH9K_SLOT_TIME_9 9 #define ATH9K_SLOT_TIME_9 9
#define ATH9K_SLOT_TIME_20 20 #define ATH9K_SLOT_TIME_20 20
...@@ -780,7 +773,8 @@ struct ath_hal { ...@@ -780,7 +773,8 @@ struct ath_hal {
void __iomem *ah_sh; void __iomem *ah_sh;
struct ath_softc *ah_sc; struct ath_softc *ah_sc;
enum ath9k_opmode ah_opmode;
enum nl80211_iftype ah_opmode;
struct ath9k_ops_config ah_config; struct ath9k_ops_config ah_config;
struct ath9k_hw_capabilities ah_caps; struct ath9k_hw_capabilities ah_caps;
...@@ -1009,7 +1003,6 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints); ...@@ -1009,7 +1003,6 @@ enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints);
/* MAC (PCU/QCU) */ /* MAC (PCU/QCU) */
void ath9k_hw_dmaRegDump(struct ath_hal *ah);
u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q); u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp); bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp);
bool ath9k_hw_txstart(struct ath_hal *ah, u32 q); bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
......
This diff is collapsed.
...@@ -31,11 +31,11 @@ static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 }; ...@@ -31,11 +31,11 @@ static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf) static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
{ {
if (nf > ATH9K_NF_TOO_LOW) { if (nf > ATH9K_NF_TOO_LOW) {
DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: noise floor value detected (%d) is " "noise floor value detected (%d) is "
"lower than what we think is a " "lower than what we think is a "
"reasonable value (%d)\n", "reasonable value (%d)\n",
__func__, nf, ATH9K_NF_TOO_LOW); nf, ATH9K_NF_TOO_LOW);
return false; return false;
} }
return true; return true;
...@@ -116,7 +116,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, ...@@ -116,7 +116,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
if (nf & 0x100) if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1); nf = 0 - ((nf ^ 0x1ff) + 1);
DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"NF calibrated [ctl] [chain 1] is %d\n", nf); "NF calibrated [ctl] [chain 1] is %d\n", nf);
nfarray[1] = nf; nfarray[1] = nf;
...@@ -125,7 +125,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, ...@@ -125,7 +125,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
AR_PHY_CH2_MINCCA_PWR); AR_PHY_CH2_MINCCA_PWR);
if (nf & 0x100) if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1); nf = 0 - ((nf ^ 0x1ff) + 1);
DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"NF calibrated [ctl] [chain 2] is %d\n", nf); "NF calibrated [ctl] [chain 2] is %d\n", nf);
nfarray[2] = nf; nfarray[2] = nf;
} }
...@@ -139,7 +139,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, ...@@ -139,7 +139,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
if (nf & 0x100) if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1); nf = 0 - ((nf ^ 0x1ff) + 1);
DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"NF calibrated [ext] [chain 0] is %d\n", nf); "NF calibrated [ext] [chain 0] is %d\n", nf);
nfarray[3] = nf; nfarray[3] = nf;
...@@ -161,7 +161,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah, ...@@ -161,7 +161,7 @@ static void ath9k_hw_do_getnf(struct ath_hal *ah,
AR_PHY_CH2_EXT_MINCCA_PWR); AR_PHY_CH2_EXT_MINCCA_PWR);
if (nf & 0x100) if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1); nf = 0 - ((nf ^ 0x1ff) + 1);
DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"NF calibrated [ext] [chain 2] is %d\n", nf); "NF calibrated [ext] [chain 2] is %d\n", nf);
nfarray[5] = nf; nfarray[5] = nf;
} }
...@@ -187,8 +187,7 @@ static bool getNoiseFloorThresh(struct ath_hal *ah, ...@@ -187,8 +187,7 @@ static bool getNoiseFloorThresh(struct ath_hal *ah,
break; break;
default: default:
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"%s: invalid channel flags 0x%x\n", __func__, "invalid channel flags 0x%x\n", chan->channelFlags);
chan->channelFlags);
return false; return false;
} }
...@@ -206,24 +205,22 @@ static void ath9k_hw_setup_calibration(struct ath_hal *ah, ...@@ -206,24 +205,22 @@ static void ath9k_hw_setup_calibration(struct ath_hal *ah,
case IQ_MISMATCH_CAL: case IQ_MISMATCH_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: starting IQ Mismatch Calibration\n", "starting IQ Mismatch Calibration\n");
__func__);
break; break;
case ADC_GAIN_CAL: case ADC_GAIN_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: starting ADC Gain Calibration\n", __func__); "starting ADC Gain Calibration\n");
break; break;
case ADC_DC_CAL: case ADC_DC_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: starting ADC DC Calibration\n", __func__); "starting ADC DC Calibration\n");
break; break;
case ADC_DC_INIT_CAL: case ADC_DC_INIT_CAL:
REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: starting Init ADC DC Calibration\n", "starting Init ADC DC Calibration\n");
__func__);
break; break;
} }
...@@ -594,16 +591,16 @@ void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, ...@@ -594,16 +591,16 @@ void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
if (ichan == NULL) { if (ichan == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: invalid channel %u/0x%x; no mapping\n", "invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags); chan->channel, chan->channelFlags);
return; return;
} }
if (currCal->calState != CAL_DONE) { if (currCal->calState != CAL_DONE) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: Calibration state incorrect, %d\n", "Calibration state incorrect, %d\n",
__func__, currCal->calState); currCal->calState);
return; return;
} }
...@@ -612,8 +609,8 @@ void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, ...@@ -612,8 +609,8 @@ void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
return; return;
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: Resetting Cal %d state for channel %u/0x%x\n", "Resetting Cal %d state for channel %u/0x%x\n",
__func__, currCal->calData->calType, chan->channel, currCal->calData->calType, chan->channel,
chan->channelFlags); chan->channelFlags);
ichan->CalValid &= ~currCal->calData->calType; ichan->CalValid &= ~currCal->calData->calType;
...@@ -705,8 +702,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, ...@@ -705,8 +702,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
chan->channelFlags &= (~CHANNEL_CW_INT); chan->channelFlags &= (~CHANNEL_CW_INT);
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: NF did not complete in calibration window\n", "NF did not complete in calibration window\n");
__func__);
nf = 0; nf = 0;
chan->rawNoiseFloor = nf; chan->rawNoiseFloor = nf;
return chan->rawNoiseFloor; return chan->rawNoiseFloor;
...@@ -716,8 +712,8 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, ...@@ -716,8 +712,8 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
if (getNoiseFloorThresh(ah, chan, &nfThresh) if (getNoiseFloorThresh(ah, chan, &nfThresh)
&& nf > nfThresh) { && nf > nfThresh) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: noise floor failed detected; " "noise floor failed detected; "
"detected %d, threshold %d\n", __func__, "detected %d, threshold %d\n",
nf, nfThresh); nf, nfThresh);
chan->channelFlags |= CHANNEL_CW_INT; chan->channelFlags |= CHANNEL_CW_INT;
} }
...@@ -759,9 +755,9 @@ s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) ...@@ -759,9 +755,9 @@ s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
ichan = ath9k_regd_check_channel(ah, chan); ichan = ath9k_regd_check_channel(ah, chan);
if (ichan == NULL) { if (ichan == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: invalid channel %u/0x%x; no mapping\n", "invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags); chan->channel, chan->channelFlags);
return ATH_DEFAULT_NOISE_FLOOR; return ATH_DEFAULT_NOISE_FLOOR;
} }
if (ichan->rawNoiseFloor == 0) { if (ichan->rawNoiseFloor == 0) {
...@@ -788,8 +784,8 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, ...@@ -788,8 +784,8 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
if (ichan == NULL) { if (ichan == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"%s: invalid channel %u/0x%x; no mapping\n", "invalid channel %u/0x%x; no mapping\n",
__func__, chan->channel, chan->channelFlags); chan->channel, chan->channelFlags);
return false; return false;
} }
...@@ -834,8 +830,8 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, ...@@ -834,8 +830,8 @@ bool ath9k_hw_init_cal(struct ath_hal *ah,
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: offset calibration failed to complete in 1ms; " "offset calibration failed to complete in 1ms; "
"noisy environment?\n", __func__); "noisy environment?\n");
return false; return false;
} }
...@@ -850,22 +846,19 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, ...@@ -850,22 +846,19 @@ bool ath9k_hw_init_cal(struct ath_hal *ah,
INIT_CAL(&ahp->ah_adcGainCalData); INIT_CAL(&ahp->ah_adcGainCalData);
INSERT_CAL(ahp, &ahp->ah_adcGainCalData); INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: enabling ADC Gain Calibration.\n", "enabling ADC Gain Calibration.\n");
__func__);
} }
if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) { if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
INIT_CAL(&ahp->ah_adcDcCalData); INIT_CAL(&ahp->ah_adcDcCalData);
INSERT_CAL(ahp, &ahp->ah_adcDcCalData); INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: enabling ADC DC Calibration.\n", "enabling ADC DC Calibration.\n");
__func__);
} }
if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) { if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
INIT_CAL(&ahp->ah_iqCalData); INIT_CAL(&ahp->ah_iqCalData);
INSERT_CAL(ahp, &ahp->ah_iqCalData); INSERT_CAL(ahp, &ahp->ah_iqCalData);
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"%s: enabling IQ Calibration.\n", "enabling IQ Calibration.\n");
__func__);
} }
ahp->ah_cal_list_curr = ahp->ah_cal_list; ahp->ah_cal_list_curr = ahp->ah_cal_list;
......
This diff is collapsed.
/*
* Copyright (c) 2008 Atheros Communications Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "core.h"
#include "reg.h"
#include "hw.h"
static unsigned int ath9k_debug = DBG_DEFAULT;
module_param_named(debug, ath9k_debug, uint, 0);
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
{
if (!sc)
return;
if (sc->sc_debug.debug_mask & dbg_mask) {
va_list args;
va_start(args, fmt);
printk(KERN_DEBUG "ath9k: ");
vprintk(fmt, args);
va_end(args);
}
}
static int ath9k_debugfs_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
static ssize_t read_file_dma(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_hal *ah = sc->sc_ah;
char buf[1024];
unsigned int len = 0;
u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
int i, qcuOffset = 0, dcuOffset = 0;
u32 *qcuBase = &val[0], *dcuBase = &val[4];
REG_WRITE(ah, AR_MACMISC,
((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
(AR_MACMISC_MISC_OBS_BUS_1 <<
AR_MACMISC_MISC_OBS_BUS_MSB_S)));
len += snprintf(buf + len, sizeof(buf) - len,
"Raw DMA Debug values:\n");
for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
if (i % 4 == 0)
len += snprintf(buf + len, sizeof(buf) - len, "\n");
val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
i, val[i]);
}
len += snprintf(buf + len, sizeof(buf) - len, "\n\n");
len += snprintf(buf + len, sizeof(buf) - len,
"Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
if (i == 8) {
qcuOffset = 0;
qcuBase++;
}
if (i == 6) {
dcuOffset = 0;
dcuBase++;
}
len += snprintf(buf + len, sizeof(buf) - len,
"%2d %2x %1x %2x %2x\n",
i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
(*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
val[2] & (0x7 << (i * 3)) >> (i * 3),
(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
}
len += snprintf(buf + len, sizeof(buf) - len, "\n");
len += snprintf(buf + len, sizeof(buf) - len,
"qcu_stitch state: %2x qcu_fetch state: %2x\n",
(val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
len += snprintf(buf + len, sizeof(buf) - len,
"qcu_complete state: %2x dcu_complete state: %2x\n",
(val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
len += snprintf(buf + len, sizeof(buf) - len,
"dcu_arb state: %2x dcu_fp state: %2x\n",
(val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
len += snprintf(buf + len, sizeof(buf) - len,
"chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
(val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
len += snprintf(buf + len, sizeof(buf) - len,
"txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
(val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
len += snprintf(buf + len, sizeof(buf) - len,
"txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
(val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
REG_READ(ah, AR_OBS_BUS_1));
len += snprintf(buf + len, sizeof(buf) - len,
"AR_CR: 0x%x \n", REG_READ(ah, AR_CR));
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static const struct file_operations fops_dma = {
.read = read_file_dma,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE
};
int ath9k_init_debug(struct ath_softc *sc)
{
sc->sc_debug.debug_mask = ath9k_debug;
sc->sc_debug.debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
if (!sc->sc_debug.debugfs_root)
goto err;
sc->sc_debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
sc->sc_debug.debugfs_root);
if (!sc->sc_debug.debugfs_phy)
goto err;
sc->sc_debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
sc->sc_debug.debugfs_phy, sc, &fops_dma);
if (!sc->sc_debug.debugfs_dma)
goto err;
return 0;
err:
ath9k_exit_debug(sc);
return -ENOMEM;
}
void ath9k_exit_debug(struct ath_softc *sc)
{
debugfs_remove(sc->sc_debug.debugfs_dma);
debugfs_remove(sc->sc_debug.debugfs_phy);
debugfs_remove(sc->sc_debug.debugfs_root);
}
...@@ -116,7 +116,7 @@ static int ath9k_hw_flash_map(struct ath_hal *ah) ...@@ -116,7 +116,7 @@ static int ath9k_hw_flash_map(struct ath_hal *ah)
if (!ahp->ah_cal_mem) { if (!ahp->ah_cal_mem) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"%s: cannot remap eeprom region \n", __func__); "cannot remap eeprom region \n");
return -EIO; return -EIO;
} }
...@@ -149,7 +149,7 @@ static bool ath9k_hw_fill_eeprom(struct ath_hal *ah) ...@@ -149,7 +149,7 @@ static bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
if (!ath9k_hw_use_flash(ah)) { if (!ath9k_hw_use_flash(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"%s: Reading from EEPROM, not flash\n", __func__); "Reading from EEPROM, not flash\n");
ar5416_eep_start_loc = 256; ar5416_eep_start_loc = 256;
} }
...@@ -162,8 +162,7 @@ static bool ath9k_hw_fill_eeprom(struct ath_hal *ah) ...@@ -162,8 +162,7 @@ static bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc, if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
eep_data)) { eep_data)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"%s: Unable to read eeprom region \n", "Unable to read eeprom region \n");
__func__);
return false; return false;
} }
eep_data++; eep_data++;
...@@ -185,12 +184,11 @@ static int ath9k_hw_check_eeprom(struct ath_hal *ah) ...@@ -185,12 +184,11 @@ static int ath9k_hw_check_eeprom(struct ath_hal *ah)
if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
&magic)) { &magic)) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
"%s: Reading Magic # failed\n", __func__); "Reading Magic # failed\n");
return false; return false;
} }
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n", DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "Read Magic = 0x%04X\n", magic);
__func__, magic);
if (magic != AR5416_EEPROM_MAGIC) { if (magic != AR5416_EEPROM_MAGIC) {
magic2 = swab16(magic); magic2 = swab16(magic);
...@@ -1205,11 +1203,11 @@ bool ath9k_hw_set_power_cal_table(struct ath_hal *ah, ...@@ -1205,11 +1203,11 @@ bool ath9k_hw_set_power_cal_table(struct ath_hal *ah,
((pdadcValues[4 * j + 3] & 0xFF) << 24); ((pdadcValues[4 * j + 3] & 0xFF) << 24);
REG_WRITE(ah, regOffset, reg32); REG_WRITE(ah, regOffset, reg32);
DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"PDADC (%d,%4x): %4.4x %8.8x\n", "PDADC (%d,%4x): %4.4x %8.8x\n",
i, regChainOffset, regOffset, i, regChainOffset, regOffset,
reg32); reg32);
DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO, DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"PDADC: Chain %d | PDADC %3d Value %3d | " "PDADC: Chain %d | PDADC %3d Value %3d | "
"PDADC %3d Value %3d | PDADC %3d Value %3d | " "PDADC %3d Value %3d | PDADC %3d Value %3d | "
"PDADC %3d Value %3d |\n", "PDADC %3d Value %3d |\n",
......
This diff is collapsed.
...@@ -25,10 +25,10 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah, ...@@ -25,10 +25,10 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
"%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
__func__, ahp->ah_txOkInterruptMask, ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask, ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask); ahp->ah_txUrnInterruptMask);
REG_WRITE(ah, AR_IMR_S0, REG_WRITE(ah, AR_IMR_S0,
SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK) SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
...@@ -40,78 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah, ...@@ -40,78 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask); AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
} }
void ath9k_hw_dmaRegDump(struct ath_hal *ah)
{
u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
int qcuOffset = 0, dcuOffset = 0;
u32 *qcuBase = &val[0], *dcuBase = &val[4];
int i;
REG_WRITE(ah, AR_MACMISC,
((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
(AR_MACMISC_MISC_OBS_BUS_1 <<
AR_MACMISC_MISC_OBS_BUS_MSB_S)));
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
if (i % 4 == 0)
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
}
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
for (i = 0; i < ATH9K_NUM_QUEUES;
i++, qcuOffset += 4, dcuOffset += 5) {
if (i == 8) {
qcuOffset = 0;
qcuBase++;
}
if (i == 6) {
dcuOffset = 0;
dcuBase++;
}
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"%2d %2x %1x %2x %2x\n",
i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
(*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
val[2] & (0x7 << (i * 3)) >> (i * 3),
(*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
}
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"qcu_stitch state: %2x qcu_fetch state: %2x\n",
(val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"qcu_complete state: %2x dcu_complete state: %2x\n",
(val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"dcu_arb state: %2x dcu_fp state: %2x\n",
(val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
(val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
(val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
(val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
REG_READ(ah, AR_OBS_BUS_1));
DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
"AR_CR 0x%x \n", REG_READ(ah, AR_CR));
}
u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q) u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
{ {
return REG_READ(ah, AR_QTXDP(q)); return REG_READ(ah, AR_QTXDP(q));
...@@ -126,7 +54,7 @@ bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp) ...@@ -126,7 +54,7 @@ bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q, u32 txdp)
bool ath9k_hw_txstart(struct ath_hal *ah, u32 q) bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
{ {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q); DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
REG_WRITE(ah, AR_Q_TXE, 1 << q); REG_WRITE(ah, AR_Q_TXE, 1 << q);
...@@ -207,9 +135,8 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) ...@@ -207,9 +135,8 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
break; break;
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
"%s: TSF have moved while trying to set " "TSF have moved while trying to set "
"quiet time TSF: 0x%08x\n", "quiet time TSF: 0x%08x\n", tsfLow);
__func__, tsfLow);
} }
REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH); REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
...@@ -222,9 +149,8 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q) ...@@ -222,9 +149,8 @@ bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
while (ath9k_hw_numtxpending(ah, q)) { while (ath9k_hw_numtxpending(ah, q)) {
if ((--wait) == 0) { if ((--wait) == 0) {
DPRINTF(ah->ah_sc, ATH_DBG_XMIT, DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
"%s: Failed to stop Tx DMA in 100 " "Failed to stop Tx DMA in 100 "
"msec after killing last frame\n", "msec after killing last frame\n");
__func__);
break; break;
} }
udelay(100); udelay(100);
...@@ -523,19 +449,17 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q, ...@@ -523,19 +449,17 @@ bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
struct ath9k_tx_queue_info *qi; struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) { if (q >= pCap->total_queues) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
__func__, q);
return false; return false;
} }
qi = &ahp->ah_txq[q]; qi = &ahp->ah_txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
__func__);
return false; return false;
} }
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi); DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi);
qi->tqi_ver = qinfo->tqi_ver; qi->tqi_ver = qinfo->tqi_ver;
qi->tqi_subtype = qinfo->tqi_subtype; qi->tqi_subtype = qinfo->tqi_subtype;
...@@ -593,15 +517,13 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q, ...@@ -593,15 +517,13 @@ bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
struct ath9k_tx_queue_info *qi; struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) { if (q >= pCap->total_queues) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
__func__, q);
return false; return false;
} }
qi = &ahp->ah_txq[q]; qi = &ahp->ah_txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
__func__);
return false; return false;
} }
...@@ -651,22 +573,21 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type, ...@@ -651,22 +573,21 @@ int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
break; break;
if (q == pCap->total_queues) { if (q == pCap->total_queues) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
"%s: no available tx queue\n", __func__); "no available tx queue\n");
return -1; return -1;
} }
break; break;
default: default:
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type);
__func__, type);
return -1; return -1;
} }
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q); DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
qi = &ahp->ah_txq[q]; qi = &ahp->ah_txq[q];
if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) { if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
"%s: tx queue %u already active\n", __func__, q); "tx queue %u already active\n", q);
return -1; return -1;
} }
memset(qi, 0, sizeof(struct ath9k_tx_queue_info)); memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
...@@ -697,19 +618,16 @@ bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q) ...@@ -697,19 +618,16 @@ bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
struct ath9k_tx_queue_info *qi; struct ath9k_tx_queue_info *qi;
if (q >= pCap->total_queues) { if (q >= pCap->total_queues) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
__func__, q);
return false; return false;
} }
qi = &ahp->ah_txq[q]; qi = &ahp->ah_txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
__func__, q);
return false; return false;
} }
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
__func__, q);
qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE; qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
ahp->ah_txOkInterruptMask &= ~(1 << q); ahp->ah_txOkInterruptMask &= ~(1 << q);
...@@ -731,19 +649,17 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q) ...@@ -731,19 +649,17 @@ bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
u32 cwMin, chanCwMin, value; u32 cwMin, chanCwMin, value;
if (q >= pCap->total_queues) { if (q >= pCap->total_queues) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
__func__, q);
return false; return false;
} }
qi = &ahp->ah_txq[q]; qi = &ahp->ah_txq[q];
if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) { if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n", DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
__func__, q);
return true; return true;
} }
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q); DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q);
if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
if (chan && IS_CHAN_B(chan)) if (chan && IS_CHAN_B(chan))
...@@ -976,8 +892,7 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set) ...@@ -976,8 +892,7 @@ bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
reg = REG_READ(ah, AR_OBS_BUS_1); reg = REG_READ(ah, AR_OBS_BUS_1);
DPRINTF(ah->ah_sc, ATH_DBG_FATAL, DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"%s: rx failed to go idle in 10 ms RXSM=0x%x\n", "rx failed to go idle in 10 ms RXSM=0x%x\n", reg);
__func__, reg);
return false; return false;
} }
...@@ -1022,9 +937,8 @@ bool ath9k_hw_stopdmarecv(struct ath_hal *ah) ...@@ -1022,9 +937,8 @@ bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) { if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
"%s: dma failed to stop in 10ms\n" "dma failed to stop in 10ms\n"
"AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n", "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
__func__,
REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
return false; return false;
} else { } else {
......
This diff is collapsed.
...@@ -52,8 +52,7 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan) ...@@ -52,8 +52,7 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
bModeSynth = 1; bModeSynth = 1;
} else { } else {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"%s: invalid channel %u MHz\n", __func__, "Invalid channel %u MHz\n", freq);
freq);
return false; return false;
} }
...@@ -86,7 +85,7 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan) ...@@ -86,7 +85,7 @@ ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
aModeRefSel = ath9k_hw_reverse_bits(1, 2); aModeRefSel = ath9k_hw_reverse_bits(1, 2);
} else { } else {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"%s: invalid channel %u MHz\n", __func__, freq); "Invalid channel %u MHz\n", freq);
return false; return false;
} }
...@@ -348,8 +347,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) ...@@ -348,8 +347,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
|| ahp->ah_analogBank6TPCData == NULL || ahp->ah_analogBank6TPCData == NULL
|| ahp->ah_analogBank7Data == NULL) { || ahp->ah_analogBank7Data == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL, DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"%s: cannot allocate RF banks\n", "Cannot allocate RF banks\n");
__func__);
*status = -ENOMEM; *status = -ENOMEM;
return false; return false;
} }
...@@ -360,8 +358,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) ...@@ -360,8 +358,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
ahp->ah_iniAddac.ia_columns), GFP_KERNEL); ahp->ah_iniAddac.ia_columns), GFP_KERNEL);
if (ahp->ah_addac5416_21 == NULL) { if (ahp->ah_addac5416_21 == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL, DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"%s: cannot allocate ah_addac5416_21\n", "Cannot allocate ah_addac5416_21\n");
__func__);
*status = -ENOMEM; *status = -ENOMEM;
return false; return false;
} }
...@@ -371,8 +368,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status) ...@@ -371,8 +368,7 @@ bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
ahp->ah_iniBank6.ia_rows), GFP_KERNEL); ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
if (ahp->ah_bank6Temp == NULL) { if (ahp->ah_bank6Temp == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_FATAL, DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"%s: cannot allocate ah_bank6Temp\n", "Cannot allocate ah_bank6Temp\n");
__func__);
*status = -ENOMEM; *status = -ENOMEM;
return false; return false;
} }
......
...@@ -1304,6 +1304,38 @@ static void ath_rc_tx_status(struct ath_softc *sc, ...@@ -1304,6 +1304,38 @@ static void ath_rc_tx_status(struct ath_softc *sc,
xretries, long_retry); xretries, long_retry);
} }
static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
enum ieee80211_band band,
bool is_ht, bool is_cw_40)
{
int mode = 0;
switch(band) {
case IEEE80211_BAND_2GHZ:
mode = ATH9K_MODE_11G;
if (is_ht)
mode = ATH9K_MODE_11NG_HT20;
if (is_cw_40)
mode = ATH9K_MODE_11NG_HT40PLUS;
break;
case IEEE80211_BAND_5GHZ:
mode = ATH9K_MODE_11A;
if (is_ht)
mode = ATH9K_MODE_11NA_HT20;
if (is_cw_40)
mode = ATH9K_MODE_11NA_HT40PLUS;
break;
default:
DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
return NULL;
}
BUG_ON(mode >= ATH9K_MODE_MAX);
DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
return sc->hw_rate_table[mode];
}
static void ath_rc_init(struct ath_softc *sc, static void ath_rc_init(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv, struct ath_rate_priv *ath_rc_priv,
struct ieee80211_supported_band *sband, struct ieee80211_supported_band *sband,
...@@ -1314,16 +1346,25 @@ static void ath_rc_init(struct ath_softc *sc, ...@@ -1314,16 +1346,25 @@ static void ath_rc_init(struct ath_softc *sc,
u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates; u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
u8 i, j, k, hi = 0, hthi = 0; u8 i, j, k, hi = 0, hthi = 0;
rate_table = sc->hw_rate_table[sc->sc_curmode]; /* FIXME: Adhoc */
if ((sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) ||
(sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)) {
bool is_cw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
rate_table = ath_choose_rate_table(sc, sband->band,
sta->ht_cap.ht_supported,
is_cw_40);
} else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
/* sc_curmode would be set on init through config() */
rate_table = sc->hw_rate_table[sc->sc_curmode];
}
if (sta->ht_cap.ht_supported) { if (!rate_table) {
if (sband->band == IEEE80211_BAND_2GHZ) DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
rate_table = sc->hw_rate_table[ATH9K_MODE_11NG_HT20]; return;
else }
rate_table = sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
if (sta->ht_cap.ht_supported) {
ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG); ath_rc_priv->ht_cap = (WLAN_RC_HT_FLAG | WLAN_RC_DS_FLAG);
if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG; ath_rc_priv->ht_cap |= WLAN_RC_40_FLAG;
} }
...@@ -1531,8 +1572,7 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp ...@@ -1531,8 +1572,7 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp); rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
if (!rate_priv) { if (!rate_priv) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: Unable to allocate private rc structure\n", "Unable to allocate private rc structure\n");
__func__);
return NULL; return NULL;
} }
......
...@@ -105,8 +105,7 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len) ...@@ -105,8 +105,7 @@ static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len)
skb_reserve(skb, sc->sc_cachelsz - off); skb_reserve(skb, sc->sc_cachelsz - off);
} else { } else {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: skbuff alloc of size %u failed\n", "skbuff alloc of size %u failed\n", len);
__func__, len);
return NULL; return NULL;
} }
...@@ -166,7 +165,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, ...@@ -166,7 +165,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
* discard the frame. Enable this if you want to see * discard the frame. Enable this if you want to see
* error frames in Monitor mode. * error frames in Monitor mode.
*/ */
if (sc->sc_ah->ah_opmode != ATH9K_M_MONITOR) if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_MONITOR)
goto rx_next; goto rx_next;
} else if (ds->ds_rxstat.rs_status != 0) { } else if (ds->ds_rxstat.rs_status != 0) {
if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
...@@ -192,7 +191,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds, ...@@ -192,7 +191,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
* decryption and MIC failures. For monitor mode, * decryption and MIC failures. For monitor mode,
* we also ignore the CRC error. * we also ignore the CRC error.
*/ */
if (sc->sc_ah->ah_opmode == ATH9K_M_MONITOR) { if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR) {
if (ds->ds_rxstat.rs_status & if (ds->ds_rxstat.rs_status &
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
ATH9K_RXERR_CRC)) ATH9K_RXERR_CRC))
...@@ -263,11 +262,7 @@ static void ath_opmode_init(struct ath_softc *sc) ...@@ -263,11 +262,7 @@ static void ath_opmode_init(struct ath_softc *sc)
/* calculate and install multicast filter */ /* calculate and install multicast filter */
mfilt[0] = mfilt[1] = ~0; mfilt[0] = mfilt[1] = ~0;
ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
DPRINTF(sc, ATH_DBG_CONFIG ,
"%s: RX filter 0x%x, MC filter %08x:%08x\n",
__func__, rfilt, mfilt[0], mfilt[1]);
} }
int ath_rx_init(struct ath_softc *sc, int nbufs) int ath_rx_init(struct ath_softc *sc, int nbufs)
...@@ -285,8 +280,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -285,8 +280,8 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
min(sc->sc_cachelsz, min(sc->sc_cachelsz,
(u16)64)); (u16)64));
DPRINTF(sc, ATH_DBG_CONFIG, "%s: cachelsz %u rxbufsize %u\n", DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
__func__, sc->sc_cachelsz, sc->sc_rxbufsize); sc->sc_cachelsz, sc->sc_rxbufsize);
/* Initialize rx descriptors */ /* Initialize rx descriptors */
...@@ -294,8 +289,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -294,8 +289,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
"rx", nbufs, 1); "rx", nbufs, 1);
if (error != 0) { if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: failed to allocate rx descriptors: %d\n", "failed to allocate rx descriptors: %d\n", error);
__func__, error);
break; break;
} }
...@@ -310,6 +304,15 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) ...@@ -310,6 +304,15 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
sc->sc_rxbufsize, sc->sc_rxbufsize,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev,
bf->bf_buf_addr))) {
dev_kfree_skb_any(skb);
bf->bf_mpdu = NULL;
DPRINTF(sc, ATH_DBG_CONFIG,
"pci_dma_mapping_error() on RX init\n");
error = -ENOMEM;
break;
}
bf->bf_dmacontext = bf->bf_buf_addr; bf->bf_dmacontext = bf->bf_buf_addr;
} }
sc->sc_rxlink = NULL; sc->sc_rxlink = NULL;
...@@ -367,25 +370,25 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -367,25 +370,25 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
| ATH9K_RX_FILTER_MCAST; | ATH9K_RX_FILTER_MCAST;
/* If not a STA, enable processing of Probe Requests */ /* If not a STA, enable processing of Probe Requests */
if (sc->sc_ah->ah_opmode != ATH9K_M_STA) if (sc->sc_ah->ah_opmode != NL80211_IFTYPE_STATION)
rfilt |= ATH9K_RX_FILTER_PROBEREQ; rfilt |= ATH9K_RX_FILTER_PROBEREQ;
/* Can't set HOSTAP into promiscous mode */ /* Can't set HOSTAP into promiscous mode */
if (((sc->sc_ah->ah_opmode != ATH9K_M_HOSTAP) && if (((sc->sc_ah->ah_opmode != NL80211_IFTYPE_AP) &&
(sc->rx_filter & FIF_PROMISC_IN_BSS)) || (sc->rx_filter & FIF_PROMISC_IN_BSS)) ||
(sc->sc_ah->ah_opmode == ATH9K_M_MONITOR)) { (sc->sc_ah->ah_opmode == NL80211_IFTYPE_MONITOR)) {
rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_PROM;
/* ??? To prevent from sending ACK */ /* ??? To prevent from sending ACK */
rfilt &= ~ATH9K_RX_FILTER_UCAST; rfilt &= ~ATH9K_RX_FILTER_UCAST;
} }
if (sc->sc_ah->ah_opmode == ATH9K_M_STA || if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION ||
sc->sc_ah->ah_opmode == ATH9K_M_IBSS) sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC)
rfilt |= ATH9K_RX_FILTER_BEACON; rfilt |= ATH9K_RX_FILTER_BEACON;
/* If in HOSTAP mode, want to enable reception of PSPOLL frames /* If in HOSTAP mode, want to enable reception of PSPOLL frames
& beacon frames */ & beacon frames */
if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP)
rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL); rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
return rfilt; return rfilt;
...@@ -595,6 +598,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) ...@@ -595,6 +598,14 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data, bf->bf_buf_addr = pci_map_single(sc->pdev, requeue_skb->data,
sc->sc_rxbufsize, sc->sc_rxbufsize,
PCI_DMA_FROMDEVICE); PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev,
bf->bf_buf_addr))) {
dev_kfree_skb_any(requeue_skb);
bf->bf_mpdu = NULL;
DPRINTF(sc, ATH_DBG_CONFIG,
"pci_dma_mapping_error() on RX\n");
break;
}
bf->bf_dmacontext = bf->bf_buf_addr; bf->bf_dmacontext = bf->bf_buf_addr;
/* /*
......
...@@ -42,7 +42,7 @@ ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp) ...@@ -42,7 +42,7 @@ ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp)
u8 *u = t - size; u8 *u = t - size;
if (cmp(u, t) <= 0) if (cmp(u, t) <= 0)
break; break;
swap(u, t, size); swap_array(u, t, size);
} }
} }
...@@ -78,8 +78,7 @@ static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) ...@@ -78,8 +78,7 @@ static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah)
return true; return true;
} }
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: invalid regulatory domain/country code 0x%x\n", "invalid regulatory domain/country code 0x%x\n", rd);
__func__, rd);
return false; return false;
} }
...@@ -107,13 +106,12 @@ static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, ...@@ -107,13 +106,12 @@ static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah,
return true; return true;
rd = ath9k_regd_get_eepromRD(ah); rd = ath9k_regd_get_eepromRD(ah);
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n", DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd);
__func__, rd);
if (rd & COUNTRY_ERD_FLAG) { if (rd & COUNTRY_ERD_FLAG) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: EEPROM setting is country code %u\n", "EEPROM setting is country code %u\n",
__func__, rd & ~COUNTRY_ERD_FLAG); rd & ~COUNTRY_ERD_FLAG);
return cc == (rd & ~COUNTRY_ERD_FLAG); return cc == (rd & ~COUNTRY_ERD_FLAG);
} }
...@@ -290,8 +288,7 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, ...@@ -290,8 +288,7 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
} }
if (!found) { if (!found) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: Failed to find reg domain pair %u\n", "Failed to find reg domain pair %u\n", regDmn);
__func__, regDmn);
return false; return false;
} }
if (!(channelFlag & CHANNEL_2GHZ)) { if (!(channelFlag & CHANNEL_2GHZ)) {
...@@ -307,8 +304,7 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, ...@@ -307,8 +304,7 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
found = ath9k_regd_is_valid_reg_domain(regDmn, rd); found = ath9k_regd_is_valid_reg_domain(regDmn, rd);
if (!found) { if (!found) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: Failed to find unitary reg domain %u\n", "Failed to find unitary reg domain %u\n", regDmn);
__func__, regDmn);
return false; return false;
} else { } else {
rd->pscan &= regPair->pscanMask; rd->pscan &= regPair->pscanMask;
...@@ -430,30 +426,27 @@ ath9k_regd_add_channel(struct ath_hal *ah, ...@@ -430,30 +426,27 @@ ath9k_regd_add_channel(struct ath_hal *ah,
if (!(c_lo <= c && c <= c_hi)) { if (!(c_lo <= c && c <= c_hi)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: c %u out of range [%u..%u]\n", "c %u out of range [%u..%u]\n",
__func__, c, c_lo, c_hi); c, c_lo, c_hi);
return false; return false;
} }
if ((fband->channelBW == CHANNEL_HALF_BW) && if ((fband->channelBW == CHANNEL_HALF_BW) &&
!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) { !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: Skipping %u half rate channel\n", "Skipping %u half rate channel\n", c);
__func__, c);
return false; return false;
} }
if ((fband->channelBW == CHANNEL_QUARTER_BW) && if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) { !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: Skipping %u quarter rate channel\n", "Skipping %u quarter rate channel\n", c);
__func__, c);
return false; return false;
} }
if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) { if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: c %u > maxChan %u\n", "c %u > maxChan %u\n", c, maxChan);
__func__, c, maxChan);
return false; return false;
} }
...@@ -463,7 +456,7 @@ ath9k_regd_add_channel(struct ath_hal *ah, ...@@ -463,7 +456,7 @@ ath9k_regd_add_channel(struct ath_hal *ah,
return false; return false;
} }
if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == ATH9K_M_HOSTAP)) { if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping HOSTAP channel\n"); "Skipping HOSTAP channel\n");
return false; return false;
...@@ -606,8 +599,7 @@ static bool ath9k_regd_japan_check(struct ath_hal *ah, ...@@ -606,8 +599,7 @@ static bool ath9k_regd_japan_check(struct ath_hal *ah,
} }
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: Skipping %d freq band\n", "Skipping %d freq band\n", j_bandcheck[i].freqbandbit);
__func__, j_bandcheck[i].freqbandbit);
return skipband; return skipband;
} }
...@@ -632,20 +624,19 @@ ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -632,20 +624,19 @@ ath9k_regd_init_channels(struct ath_hal *ah,
unsigned long *modes_avail; unsigned long *modes_avail;
DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX); DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX);
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u %s %s\n", DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc,
__func__, cc,
enableOutdoor ? "Enable outdoor" : "", enableOutdoor ? "Enable outdoor" : "",
enableExtendedChannels ? "Enable ecm" : ""); enableExtendedChannels ? "Enable ecm" : "");
if (!ath9k_regd_is_ccode_valid(ah, cc)) { if (!ath9k_regd_is_ccode_valid(ah, cc)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: invalid country code %d\n", __func__, cc); "Invalid country code %d\n", cc);
return false; return false;
} }
if (!ath9k_regd_is_eeprom_valid(ah)) { if (!ath9k_regd_is_eeprom_valid(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: invalid EEPROM contents\n", __func__); "Invalid EEPROM contents\n");
return false; return false;
} }
...@@ -693,9 +684,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -693,9 +684,9 @@ ath9k_regd_init_channels(struct ath_hal *ah,
~CHANNEL_2GHZ, ~CHANNEL_2GHZ,
&rd5GHz)) { &rd5GHz)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: couldn't find unitary " "Couldn't find unitary "
"5GHz reg domain for country %u\n", "5GHz reg domain for country %u\n",
__func__, ah->ah_countryCode); ah->ah_countryCode);
return false; return false;
} }
if (!ath9k_regd_get_wmode_regdomain(ah, if (!ath9k_regd_get_wmode_regdomain(ah,
...@@ -703,9 +694,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -703,9 +694,9 @@ ath9k_regd_init_channels(struct ath_hal *ah,
CHANNEL_2GHZ, CHANNEL_2GHZ,
&rd2GHz)) { &rd2GHz)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: couldn't find unitary 2GHz " "Couldn't find unitary 2GHz "
"reg domain for country %u\n", "reg domain for country %u\n",
__func__, ah->ah_countryCode); ah->ah_countryCode);
return false; return false;
} }
...@@ -717,9 +708,9 @@ ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -717,9 +708,9 @@ ath9k_regd_init_channels(struct ath_hal *ah,
~CHANNEL_2GHZ, ~CHANNEL_2GHZ,
&rd5GHz)) { &rd5GHz)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: couldn't find unitary 5GHz " "Couldn't find unitary 5GHz "
"reg domain for country %u\n", "reg domain for country %u\n",
__func__, ah->ah_countryCode); ah->ah_countryCode);
return false; return false;
} }
} }
...@@ -749,15 +740,14 @@ ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -749,15 +740,14 @@ ath9k_regd_init_channels(struct ath_hal *ah,
if (!test_bit(cm->mode, modes_avail)) { if (!test_bit(cm->mode, modes_avail)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: !avail mode %d flags 0x%x\n", "!avail mode %d flags 0x%x\n",
__func__, cm->mode, cm->flags); cm->mode, cm->flags);
continue; continue;
} }
if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: channels 0x%x not supported " "channels 0x%x not supported "
"by hardware\n", "by hardware\n", cm->flags);
__func__, cm->flags);
continue; continue;
} }
...@@ -788,8 +778,7 @@ ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -788,8 +778,7 @@ ath9k_regd_init_channels(struct ath_hal *ah,
break; break;
default: default:
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: Unknown HAL mode 0x%x\n", __func__, "Unknown HAL mode 0x%x\n", cm->mode);
cm->mode);
continue; continue;
} }
...@@ -841,9 +830,8 @@ ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -841,9 +830,8 @@ ath9k_regd_init_channels(struct ath_hal *ah,
if (next >= maxchans) { if (next >= maxchans) {
DPRINTF(ah->ah_sc, DPRINTF(ah->ah_sc,
ATH_DBG_REGULATORY, ATH_DBG_REGULATORY,
"%s: too many channels " "too many channels "
"for channel table\n", "for channel table\n");
__func__);
goto done; goto done;
} }
if (ath9k_regd_add_channel(ah, if (ath9k_regd_add_channel(ah,
...@@ -869,9 +857,8 @@ ath9k_regd_init_channels(struct ath_hal *ah, ...@@ -869,9 +857,8 @@ ath9k_regd_init_channels(struct ath_hal *ah,
if (next > ARRAY_SIZE(ah->ah_channels)) { if (next > ARRAY_SIZE(ah->ah_channels)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: too many channels %u; truncating to %u\n", "too many channels %u; truncating to %u\n",
__func__, next, next, (int) ARRAY_SIZE(ah->ah_channels));
(int) ARRAY_SIZE(ah->ah_channels));
next = ARRAY_SIZE(ah->ah_channels); next = ARRAY_SIZE(ah->ah_channels);
} }
#ifdef ATH_NF_PER_CHAN #ifdef ATH_NF_PER_CHAN
...@@ -919,7 +906,7 @@ ath9k_regd_check_channel(struct ath_hal *ah, ...@@ -919,7 +906,7 @@ ath9k_regd_check_channel(struct ath_hal *ah,
int n, lim; int n, lim;
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: channel %u/0x%x (0x%x) requested\n", __func__, "channel %u/0x%x (0x%x) requested\n",
c->channel, c->channelFlags, flags); c->channel, c->channelFlags, flags);
cc = ah->ah_curchan; cc = ah->ah_curchan;
...@@ -950,15 +937,15 @@ ath9k_regd_check_channel(struct ath_hal *ah, ...@@ -950,15 +937,15 @@ ath9k_regd_check_channel(struct ath_hal *ah,
d = flags - (cc->channelFlags & CHAN_FLAGS); d = flags - (cc->channelFlags & CHAN_FLAGS);
} }
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"%s: channel %u/0x%x d %d\n", __func__, "channel %u/0x%x d %d\n",
cc->channel, cc->channelFlags, d); cc->channel, cc->channelFlags, d);
if (d > 0) { if (d > 0) {
base = cc + 1; base = cc + 1;
lim--; lim--;
} }
} }
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: no match for %u/0x%x\n", DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n",
__func__, c->channel, c->channelFlags); c->channel, c->channelFlags);
return NULL; return NULL;
} }
......
...@@ -125,7 +125,7 @@ ...@@ -125,7 +125,7 @@
#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER) #define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
#define swap(_a, _b, _size) { \ #define swap_array(_a, _b, _size) { \
u8 *s = _b; \ u8 *s = _b; \
int i = _size; \ int i = _size; \
do { \ do { \
......
This diff is collapsed.
...@@ -2,6 +2,13 @@ config HOSTAP ...@@ -2,6 +2,13 @@ config HOSTAP
tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)" tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
depends on WLAN_80211 depends on WLAN_80211
select WIRELESS_EXT select WIRELESS_EXT
select CRYPTO
select CRYPTO_ARC4
select CRYPTO_ECB
select CRYPTO_AES
select CRYPTO_MICHAEL_MIC
select CRYPTO_ECB
select CRC32
select LIB80211 select LIB80211
select LIB80211_CRYPT_WEP select LIB80211_CRYPT_WEP
select LIB80211_CRYPT_TKIP select LIB80211_CRYPT_TKIP
......
...@@ -7797,15 +7797,6 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv, ...@@ -7797,15 +7797,6 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr), memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
rxb->skb->data + IPW_RX_FRAME_SIZE, len); rxb->skb->data + IPW_RX_FRAME_SIZE, len);
/* Zero the radiotap static buffer ... We only need to zero the bytes NOT
* part of our real header, saves a little time.
*
* No longer necessary since we fill in all our data. Purge before merging
* patch officially.
* memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
* IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
*/
ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data; ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
...@@ -8013,15 +8004,6 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv, ...@@ -8013,15 +8004,6 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
memcpy(ipw_rt->payload, hdr, len); memcpy(ipw_rt->payload, hdr, len);
/* Zero the radiotap static buffer ... We only need to zero the bytes
* NOT part of our real header, saves a little time.
*
* No longer necessary since we fill in all our data. Purge before
* merging patch officially.
* memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
* IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
*/
ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */ ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*ipw_rt)); /* total header+data */ ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*ipw_rt)); /* total header+data */
...@@ -10409,9 +10391,9 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv, ...@@ -10409,9 +10391,9 @@ static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
} else } else
len = src->len; len = src->len;
dst = alloc_skb( dst = alloc_skb(len + sizeof(*rt_hdr), GFP_ATOMIC);
len + IEEE80211_RADIOTAP_HDRLEN, GFP_ATOMIC); if (!dst)
if (!dst) continue; continue;
rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr)); rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr));
......
...@@ -8,7 +8,7 @@ iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o ...@@ -8,7 +8,7 @@ iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o iwlcore-$(CONFIG_IWLAGN_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
obj-$(CONFIG_IWLAGN) += iwlagn.o obj-$(CONFIG_IWLAGN) += iwlagn.o
iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-hcmd-check.o
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
......
...@@ -71,9 +71,33 @@ ...@@ -71,9 +71,33 @@
#define IWL_SKU_G 0x1 #define IWL_SKU_G 0x1
#define IWL_SKU_A 0x2 #define IWL_SKU_A 0x2
/**
* struct iwl_3945_cfg
* @fw_name_pre: Firmware filename prefix. The api version and extension
* (.ucode) will be added to filename before loading from disk. The
* filename is constructed as fw_name_pre<api>.ucode.
* @ucode_api_max: Highest version of uCode API supported by driver.
* @ucode_api_min: Lowest version of uCode API supported by driver.
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
* highest and @ucode_api_min the lowest). Firmware will only be loaded if
* it has a supported API version. The firmware's API version will be
* stored in @iwl_priv, enabling the driver to make runtime changes based
* on firmware version used.
*
* For example,
* if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
* Driver interacts with Firmware API version >= 2.
* } else {
* Driver interacts with Firmware API version 1.
* }
*/
struct iwl_3945_cfg { struct iwl_3945_cfg {
const char *name; const char *name;
const char *fw_name; const char *fw_name_pre;
const unsigned int ucode_api_max;
const unsigned int ucode_api_min;
unsigned int sku; unsigned int sku;
}; };
......
This diff is collapsed.
...@@ -337,7 +337,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, ...@@ -337,7 +337,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
u32 status = le32_to_cpu(tx_resp->status); u32 status = le32_to_cpu(tx_resp->status);
int rate_idx; int rate_idx;
int fail, i; int fail;
if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
...@@ -356,27 +356,9 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv, ...@@ -356,27 +356,9 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
rate_idx -= IWL_FIRST_OFDM_RATE; rate_idx -= IWL_FIRST_OFDM_RATE;
fail = tx_resp->failure_frame; fail = tx_resp->failure_frame;
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
int next = iwl3945_rs_next_rate(priv, rate_idx);
info->status.rates[i].idx = rate_idx; info->status.rates[0].idx = rate_idx;
info->status.rates[0].count = fail + 1; /* add final attempt */
/*
* Put remaining into the last count as best approximation
* of saying exactly what the hardware would have done...
*/
if ((rate_idx == next) || (i == IEEE80211_TX_MAX_RATES - 1)) {
info->status.rates[i].count = fail;
break;
}
info->status.rates[i].count = priv->retry_rate;
fail -= priv->retry_rate;
rate_idx = next;
if (fail <= 0)
break;
}
info->status.rates[i].count++; /* add final attempt */
/* tx_status->rts_retry_count = tx_resp->failure_rts; */ /* tx_status->rts_retry_count = tx_resp->failure_rts; */
info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
...@@ -809,12 +791,19 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue * ...@@ -809,12 +791,19 @@ int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *
u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr) u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
{ {
int i; int i, start = IWL_AP_ID;
int ret = IWL_INVALID_STATION; int ret = IWL_INVALID_STATION;
unsigned long flags; unsigned long flags;
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
(priv->iw_mode == NL80211_IFTYPE_AP))
start = IWL_STA_ID;
if (is_broadcast_ether_addr(addr))
return priv->hw_setting.bcast_sta_id;
spin_lock_irqsave(&priv->sta_lock, flags); spin_lock_irqsave(&priv->sta_lock, flags);
for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++) for (i = start; i < priv->hw_setting.max_stations; i++)
if ((priv->stations[i].used) && if ((priv->stations[i].used) &&
(!compare_ether_addr (!compare_ether_addr
(priv->stations[i].sta.sta.addr, addr))) { (priv->stations[i].sta.sta.addr, addr))) {
...@@ -2519,13 +2508,17 @@ void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv) ...@@ -2519,13 +2508,17 @@ void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv)
static struct iwl_3945_cfg iwl3945_bg_cfg = { static struct iwl_3945_cfg iwl3945_bg_cfg = {
.name = "3945BG", .name = "3945BG",
.fw_name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode", .fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_G, .sku = IWL_SKU_G,
}; };
static struct iwl_3945_cfg iwl3945_abg_cfg = { static struct iwl_3945_cfg iwl3945_abg_cfg = {
.name = "3945ABG", .name = "3945ABG",
.fw_name = "iwlwifi-3945" IWL3945_UCODE_API ".ucode", .fw_name_pre = IWL3945_FW_PRE,
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G, .sku = IWL_SKU_A|IWL_SKU_G,
}; };
......
...@@ -50,11 +50,15 @@ extern struct pci_device_id iwl3945_hw_card_ids[]; ...@@ -50,11 +50,15 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
#include "iwl-3945-debug.h" #include "iwl-3945-debug.h"
#include "iwl-3945-led.h" #include "iwl-3945-led.h"
/* Change firmware file name, using "-" and incrementing number, /* Highest firmware API version supported */
* *only* when uCode interface or architecture changes so that it #define IWL3945_UCODE_API_MAX 2
* is not compatible with earlier drivers.
* This number will also appear in << 8 position of 1st dword of uCode file */ /* Lowest firmware API version supported */
#define IWL3945_UCODE_API "-1" #define IWL3945_UCODE_API_MIN 1
#define IWL3945_FW_PRE "iwlwifi-3945-"
#define _IWL3945_MODULE_FIRMWARE(api) IWL3945_FW_PRE #api ".ucode"
#define IWL3945_MODULE_FIRMWARE(api) _IWL3945_MODULE_FIRMWARE(api)
/* Default noise level to report when noise measurement is not available. /* Default noise level to report when noise measurement is not available.
* This may be because we're: * This may be because we're:
...@@ -505,7 +509,7 @@ struct fw_desc { ...@@ -505,7 +509,7 @@ struct fw_desc {
/* uCode file layout */ /* uCode file layout */
struct iwl3945_ucode { struct iwl3945_ucode {
__le32 ver; /* major/minor/subminor */ __le32 ver; /* major/minor/API/serial */
__le32 inst_size; /* bytes of runtime instructions */ __le32 inst_size; /* bytes of runtime instructions */
__le32 data_size; /* bytes of runtime data */ __le32 data_size; /* bytes of runtime data */
__le32 init_size; /* bytes of initialization instructions */ __le32 init_size; /* bytes of initialization instructions */
...@@ -762,6 +766,8 @@ struct iwl3945_priv { ...@@ -762,6 +766,8 @@ struct iwl3945_priv {
void __iomem *hw_base; void __iomem *hw_base;
/* uCode images, save to reload in case of failure */ /* uCode images, save to reload in case of failure */
u32 ucode_ver; /* ucode version, copy of
iwl3945_ucode.ver */
struct fw_desc ucode_code; /* runtime inst */ struct fw_desc ucode_code; /* runtime inst */
struct fw_desc ucode_data; /* runtime data original */ struct fw_desc ucode_data; /* runtime data original */
struct fw_desc ucode_data_backup; /* runtime data save/restore */ struct fw_desc ucode_data_backup; /* runtime data save/restore */
......
...@@ -48,12 +48,15 @@ ...@@ -48,12 +48,15 @@
static int iwl4965_send_tx_power(struct iwl_priv *priv); static int iwl4965_send_tx_power(struct iwl_priv *priv);
static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); static int iwl4965_hw_get_temperature(const struct iwl_priv *priv);
/* Change firmware file name, using "-" and incrementing number, /* Highest firmware API version supported */
* *only* when uCode interface or architecture changes so that it #define IWL4965_UCODE_API_MAX 2
* is not compatible with earlier drivers.
* This number will also appear in << 8 position of 1st dword of uCode file */ /* Lowest firmware API version supported */
#define IWL4965_UCODE_API "-2" #define IWL4965_UCODE_API_MIN 2
#define IWL4965_MODULE_FIRMWARE "iwlwifi-4965" IWL4965_UCODE_API ".ucode"
#define IWL4965_FW_PRE "iwlwifi-4965-"
#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode"
#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api)
/* module parameters */ /* module parameters */
...@@ -523,7 +526,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv) ...@@ -523,7 +526,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
struct iwl_calib_diff_gain_cmd cmd; struct iwl_calib_diff_gain_cmd cmd;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.opCode = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
cmd.diff_gain_a = 0; cmd.diff_gain_a = 0;
cmd.diff_gain_b = 0; cmd.diff_gain_b = 0;
cmd.diff_gain_c = 0; cmd.diff_gain_c = 0;
...@@ -574,7 +577,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv, ...@@ -574,7 +577,7 @@ static void iwl4965_gain_computation(struct iwl_priv *priv,
data->radio_write = 1; data->radio_write = 1;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.opCode = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD; cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
cmd.diff_gain_a = data->delta_gain_code[0]; cmd.diff_gain_a = data->delta_gain_code[0];
cmd.diff_gain_b = data->delta_gain_code[1]; cmd.diff_gain_b = data->delta_gain_code[1];
cmd.diff_gain_c = data->delta_gain_code[2]; cmd.diff_gain_c = data->delta_gain_code[2];
...@@ -816,6 +819,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) ...@@ -816,6 +819,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
} }
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size = priv->hw_params.scd_bc_tbls_size =
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl); IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
priv->hw_params.max_stations = IWL4965_STATION_COUNT; priv->hw_params.max_stations = IWL4965_STATION_COUNT;
...@@ -2335,7 +2339,9 @@ static struct iwl_ops iwl4965_ops = { ...@@ -2335,7 +2339,9 @@ static struct iwl_ops iwl4965_ops = {
struct iwl_cfg iwl4965_agn_cfg = { struct iwl_cfg iwl4965_agn_cfg = {
.name = "4965AGN", .name = "4965AGN",
.fw_name = IWL4965_MODULE_FIRMWARE, .fw_name_pre = IWL4965_FW_PRE,
.ucode_api_max = IWL4965_UCODE_API_MAX,
.ucode_api_min = IWL4965_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.eeprom_size = IWL4965_EEPROM_IMG_SIZE, .eeprom_size = IWL4965_EEPROM_IMG_SIZE,
.eeprom_ver = EEPROM_4965_EEPROM_VERSION, .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
...@@ -2345,7 +2351,7 @@ struct iwl_cfg iwl4965_agn_cfg = { ...@@ -2345,7 +2351,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
}; };
/* Module firmware */ /* Module firmware */
MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE); MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444); module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
......
...@@ -44,9 +44,21 @@ ...@@ -44,9 +44,21 @@
#include "iwl-helpers.h" #include "iwl-helpers.h"
#include "iwl-5000-hw.h" #include "iwl-5000-hw.h"
#define IWL5000_UCODE_API "-1" /* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 1
#define IWL5150_UCODE_API_MAX 1
#define IWL5000_MODULE_FIRMWARE "iwlwifi-5000" IWL5000_UCODE_API ".ucode" /* Lowest firmware API version supported */
#define IWL5000_UCODE_API_MIN 1
#define IWL5150_UCODE_API_MIN 1
#define IWL5000_FW_PRE "iwlwifi-5000-"
#define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode"
#define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api)
#define IWL5150_FW_PRE "iwlwifi-5150-"
#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode"
#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
static const u16 iwl5000_default_queue_to_tx_fifo[] = { static const u16 iwl5000_default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_AC3, IWL_TX_FIFO_AC3,
...@@ -338,9 +350,13 @@ static void iwl5000_gain_computation(struct iwl_priv *priv, ...@@ -338,9 +350,13 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
if (!data->radio_write) { if (!data->radio_write) {
struct iwl_calib_chain_noise_gain_cmd cmd; struct iwl_calib_chain_noise_gain_cmd cmd;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD; cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
cmd.hdr.first_group = 0;
cmd.hdr.groups_num = 1;
cmd.hdr.data_valid = 1;
cmd.delta_gain_1 = data->delta_gain_code[1]; cmd.delta_gain_1 = data->delta_gain_code[1];
cmd.delta_gain_2 = data->delta_gain_code[2]; cmd.delta_gain_2 = data->delta_gain_code[2];
iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
...@@ -362,14 +378,19 @@ static void iwl5000_gain_computation(struct iwl_priv *priv, ...@@ -362,14 +378,19 @@ static void iwl5000_gain_computation(struct iwl_priv *priv,
static void iwl5000_chain_noise_reset(struct iwl_priv *priv) static void iwl5000_chain_noise_reset(struct iwl_priv *priv)
{ {
struct iwl_chain_noise_data *data = &priv->chain_noise_data; struct iwl_chain_noise_data *data = &priv->chain_noise_data;
int ret;
if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) { if ((data->state == IWL_CHAIN_NOISE_ALIVE) && iwl_is_associated(priv)) {
struct iwl_calib_chain_noise_reset_cmd cmd; struct iwl_calib_chain_noise_reset_cmd cmd;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
sizeof(cmd), &cmd)) cmd.hdr.first_group = 0;
cmd.hdr.groups_num = 1;
cmd.hdr.data_valid = 1;
ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
sizeof(cmd), &cmd);
if (ret)
IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n"); IWL_ERROR("Could not send REPLY_PHY_CALIBRATION_CMD\n");
data->state = IWL_CHAIN_NOISE_ACCUMULATE; data->state = IWL_CHAIN_NOISE_ACCUMULATE;
IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); IWL_DEBUG_CALIB("Run chain_noise_calibrate\n");
...@@ -415,22 +436,33 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, ...@@ -415,22 +436,33 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
return &priv->eeprom[address]; return &priv->eeprom[address];
} }
static s32 iwl5150_get_ct_threshold(struct iwl_priv *priv)
{
const s32 volt2temp_coef = -5;
u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
EEPROM_5000_TEMPERATURE);
/* offset = temperate - voltage / coef */
s32 offset = temp_calib[0] - temp_calib[1] / volt2temp_coef;
s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) - offset;
return threshold * volt2temp_coef;
}
/* /*
* Calibration * Calibration
*/ */
static int iwl5000_set_Xtal_calib(struct iwl_priv *priv) static int iwl5000_set_Xtal_calib(struct iwl_priv *priv)
{ {
u8 data[sizeof(struct iwl_calib_hdr) + struct iwl_calib_xtal_freq_cmd cmd;
sizeof(struct iwl_cal_xtal_freq)];
struct iwl_calib_cmd *cmd = (struct iwl_calib_cmd *)data;
struct iwl_cal_xtal_freq *xtal = (struct iwl_cal_xtal_freq *)cmd->data;
u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL); u16 *xtal_calib = (u16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_XTAL);
cmd->hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD; cmd.hdr.op_code = IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD;
xtal->cap_pin1 = (u8)xtal_calib[0]; cmd.hdr.first_group = 0;
xtal->cap_pin2 = (u8)xtal_calib[1]; cmd.hdr.groups_num = 1;
cmd.hdr.data_valid = 1;
cmd.cap_pin1 = (u8)xtal_calib[0];
cmd.cap_pin2 = (u8)xtal_calib[1];
return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL], return iwl_calib_set(&priv->calib_results[IWL_CALIB_XTAL],
data, sizeof(data)); (u8 *)&cmd, sizeof(cmd));
} }
static int iwl5000_send_calib_cfg(struct iwl_priv *priv) static int iwl5000_send_calib_cfg(struct iwl_priv *priv)
...@@ -466,6 +498,9 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv, ...@@ -466,6 +498,9 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
* uCode. iwl_send_calib_results sends them in a row according to their * uCode. iwl_send_calib_results sends them in a row according to their
* index. We sort them here */ * index. We sort them here */
switch (hdr->op_code) { switch (hdr->op_code) {
case IWL_PHY_CALIBRATE_DC_CMD:
index = IWL_CALIB_DC;
break;
case IWL_PHY_CALIBRATE_LO_CMD: case IWL_PHY_CALIBRATE_LO_CMD:
index = IWL_CALIB_LO; index = IWL_CALIB_LO;
break; break;
...@@ -802,6 +837,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -802,6 +837,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
} }
priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues;
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size = priv->hw_params.scd_bc_tbls_size =
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl); IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
priv->hw_params.max_stations = IWL5000_STATION_COUNT; priv->hw_params.max_stations = IWL5000_STATION_COUNT;
...@@ -845,7 +881,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -845,7 +881,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
case CSR_HW_REV_TYPE_5150: case CSR_HW_REV_TYPE_5150:
/* 5150 wants in Kelvin */ /* 5150 wants in Kelvin */
priv->hw_params.ct_kill_threshold = priv->hw_params.ct_kill_threshold =
CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); iwl5150_get_ct_threshold(priv);
break; break;
} }
...@@ -862,7 +898,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -862,7 +898,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
BIT(IWL_CALIB_BASE_BAND); BIT(IWL_CALIB_BASE_BAND);
break; break;
case CSR_HW_REV_TYPE_5150: case CSR_HW_REV_TYPE_5150:
priv->hw_params.calib_init_cfg = 0; priv->hw_params.calib_init_cfg =
BIT(IWL_CALIB_DC) |
BIT(IWL_CALIB_LO) |
BIT(IWL_CALIB_TX_IQ) |
BIT(IWL_CALIB_BASE_BAND);
break; break;
} }
...@@ -1501,7 +1542,9 @@ static struct iwl_mod_params iwl50_mod_params = { ...@@ -1501,7 +1542,9 @@ static struct iwl_mod_params iwl50_mod_params = {
struct iwl_cfg iwl5300_agn_cfg = { struct iwl_cfg iwl5300_agn_cfg = {
.name = "5300AGN", .name = "5300AGN",
.fw_name = IWL5000_MODULE_FIRMWARE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.ops = &iwl5000_ops, .ops = &iwl5000_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE, .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
...@@ -1512,7 +1555,9 @@ struct iwl_cfg iwl5300_agn_cfg = { ...@@ -1512,7 +1555,9 @@ struct iwl_cfg iwl5300_agn_cfg = {
struct iwl_cfg iwl5100_bg_cfg = { struct iwl_cfg iwl5100_bg_cfg = {
.name = "5100BG", .name = "5100BG",
.fw_name = IWL5000_MODULE_FIRMWARE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_G, .sku = IWL_SKU_G,
.ops = &iwl5000_ops, .ops = &iwl5000_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE, .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
...@@ -1523,7 +1568,9 @@ struct iwl_cfg iwl5100_bg_cfg = { ...@@ -1523,7 +1568,9 @@ struct iwl_cfg iwl5100_bg_cfg = {
struct iwl_cfg iwl5100_abg_cfg = { struct iwl_cfg iwl5100_abg_cfg = {
.name = "5100ABG", .name = "5100ABG",
.fw_name = IWL5000_MODULE_FIRMWARE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G, .sku = IWL_SKU_A|IWL_SKU_G,
.ops = &iwl5000_ops, .ops = &iwl5000_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE, .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
...@@ -1534,7 +1581,9 @@ struct iwl_cfg iwl5100_abg_cfg = { ...@@ -1534,7 +1581,9 @@ struct iwl_cfg iwl5100_abg_cfg = {
struct iwl_cfg iwl5100_agn_cfg = { struct iwl_cfg iwl5100_agn_cfg = {
.name = "5100AGN", .name = "5100AGN",
.fw_name = IWL5000_MODULE_FIRMWARE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.ops = &iwl5000_ops, .ops = &iwl5000_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE, .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
...@@ -1545,7 +1594,22 @@ struct iwl_cfg iwl5100_agn_cfg = { ...@@ -1545,7 +1594,22 @@ struct iwl_cfg iwl5100_agn_cfg = {
struct iwl_cfg iwl5350_agn_cfg = { struct iwl_cfg iwl5350_agn_cfg = {
.name = "5350AGN", .name = "5350AGN",
.fw_name = IWL5000_MODULE_FIRMWARE, .fw_name_pre = IWL5000_FW_PRE,
.ucode_api_max = IWL5000_UCODE_API_MAX,
.ucode_api_min = IWL5000_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.ops = &iwl5000_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
.mod_params = &iwl50_mod_params,
};
struct iwl_cfg iwl5150_agn_cfg = {
.name = "5150AGN",
.fw_name_pre = IWL5150_FW_PRE,
.ucode_api_max = IWL5150_UCODE_API_MAX,
.ucode_api_min = IWL5150_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.ops = &iwl5000_ops, .ops = &iwl5000_ops,
.eeprom_size = IWL_5000_EEPROM_IMG_SIZE, .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
...@@ -1554,7 +1618,8 @@ struct iwl_cfg iwl5350_agn_cfg = { ...@@ -1554,7 +1618,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
.mod_params = &iwl50_mod_params, .mod_params = &iwl50_mod_params,
}; };
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE); MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
module_param_named(disable50, iwl50_mod_params.disable, int, 0444); module_param_named(disable50, iwl50_mod_params.disable, int, 0444);
MODULE_PARM_DESC(disable50, MODULE_PARM_DESC(disable50,
......
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.
...@@ -6,4 +6,5 @@ obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o ...@@ -6,4 +6,5 @@ obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o
cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
cfg80211-$(CONFIG_NL80211) += nl80211.o cfg80211-$(CONFIG_NL80211) += nl80211.o
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