提交 098401a6 编写于 作者: D David S. Miller
...@@ -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);
......
...@@ -27,7 +27,7 @@ static int ath_beaconq_config(struct ath_softc *sc) ...@@ -27,7 +27,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
struct ath9k_tx_queue_info qi; struct ath9k_tx_queue_info qi;
ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi); ath9k_hw_get_txq_props(ah, sc->sc_bhalq, &qi);
if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
/* Always burst out beacon and CAB traffic. */ /* Always burst out beacon and CAB traffic. */
qi.tqi_aifs = 1; qi.tqi_aifs = 1;
qi.tqi_cwmin = 0; qi.tqi_cwmin = 0;
...@@ -41,8 +41,7 @@ static int ath_beaconq_config(struct ath_softc *sc) ...@@ -41,8 +41,7 @@ static int ath_beaconq_config(struct ath_softc *sc)
if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) { if (!ath9k_hw_set_txq_props(ah, sc->sc_bhalq, &qi)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to update h/w beacon queue parameters\n", "unable to update h/w beacon queue parameters\n");
__func__);
return 0; return 0;
} else { } else {
ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */ ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */
...@@ -53,8 +52,8 @@ static int ath_beaconq_config(struct ath_softc *sc) ...@@ -53,8 +52,8 @@ static int ath_beaconq_config(struct ath_softc *sc)
static void ath_bstuck_process(struct ath_softc *sc) static void ath_bstuck_process(struct ath_softc *sc)
{ {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: stuck beacon; resetting (bmiss count %u)\n", "stuck beacon; resetting (bmiss count %u)\n",
__func__, sc->sc_bmisscount); sc->sc_bmisscount);
ath_reset(sc, false); ath_reset(sc, false);
} }
...@@ -76,15 +75,14 @@ static void ath_beacon_setup(struct ath_softc *sc, ...@@ -76,15 +75,14 @@ static void ath_beacon_setup(struct ath_softc *sc,
int ctsrate = 0; int ctsrate = 0;
int ctsduration = 0; int ctsduration = 0;
DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n", DPRINTF(sc, ATH_DBG_BEACON, "m %p len %u\n", skb, skb->len);
__func__, skb, skb->len);
/* setup descriptors */ /* setup descriptors */
ds = bf->bf_desc; ds = bf->bf_desc;
flags = ATH9K_TXDESC_NOACK; flags = ATH9K_TXDESC_NOACK;
if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS && if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC &&
(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
ds->ds_link = bf->bf_daddr; /* self-linked */ ds->ds_link = bf->bf_daddr; /* self-linked */
flags |= ATH9K_TXDESC_VEOL; flags |= ATH9K_TXDESC_VEOL;
...@@ -158,8 +156,8 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -158,8 +156,8 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
cabq = sc->sc_cabq; cabq = sc->sc_cabq;
if (avp->av_bcbuf == NULL) { if (avp->av_bcbuf == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
__func__, avp, avp->av_bcbuf); avp, avp->av_bcbuf);
return NULL; return NULL;
} }
...@@ -192,6 +190,13 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -192,6 +190,13 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
pci_map_single(sc->pdev, skb->data, pci_map_single(sc->pdev, skb->data,
skb->len, skb->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
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 beaconing\n");
return NULL;
}
skb = ieee80211_get_buffered_bc(sc->hw, vif); skb = ieee80211_get_buffered_bc(sc->hw, vif);
...@@ -216,7 +221,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) ...@@ -216,7 +221,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
if (sc->sc_nvaps > 1) { if (sc->sc_nvaps > 1) {
ath_tx_draintxq(sc, cabq, false); ath_tx_draintxq(sc, cabq, false);
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: flush previous cabq traffic\n", __func__); "flush previous cabq traffic\n");
} }
} }
...@@ -253,8 +258,8 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) ...@@ -253,8 +258,8 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
avp = (void *)vif->drv_priv; avp = (void *)vif->drv_priv;
if (avp->av_bcbuf == NULL) { if (avp->av_bcbuf == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
__func__, avp, avp != NULL ? avp->av_bcbuf : NULL); avp, avp != NULL ? avp->av_bcbuf : NULL);
return; return;
} }
bf = avp->av_bcbuf; bf = avp->av_bcbuf;
...@@ -266,7 +271,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) ...@@ -266,7 +271,7 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
/* NB: caller is known to have already stopped tx dma */ /* NB: caller is known to have already stopped tx dma */
ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
ath9k_hw_txstart(ah, sc->sc_bhalq); ath9k_hw_txstart(ah, sc->sc_bhalq);
DPRINTF(sc, ATH_DBG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__, DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc); sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
} }
...@@ -304,7 +309,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -304,7 +309,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
struct ath_buf, list); struct ath_buf, list);
list_del(&avp->av_bcbuf->list); list_del(&avp->av_bcbuf->list);
if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP || if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP ||
!(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) { !(sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
int slot; int slot;
/* /*
...@@ -351,8 +356,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -351,8 +356,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
*/ */
skb = ieee80211_beacon_get(sc->hw, vif); skb = ieee80211_beacon_get(sc->hw, vif);
if (skb == NULL) { if (skb == NULL) {
DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n", DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
__func__);
return -ENOMEM; return -ENOMEM;
} }
...@@ -388,19 +392,25 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) ...@@ -388,19 +392,25 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */ val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: %s beacons, bslot %d intval %u tsfadjust %llu\n", "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
__func__, "stagger",
avp->av_bslot, intval, (unsigned long long)tsfadjust); avp->av_bslot, intval, (unsigned long long)tsfadjust);
hdr = (struct ieee80211_hdr *)skb->data; hdr = (struct ieee80211_hdr *)skb->data;
memcpy(&hdr[1], &val, sizeof(val)); memcpy(&hdr[1], &val, sizeof(val));
} }
bf->bf_mpdu = skb;
bf->bf_buf_addr = bf->bf_dmacontext = bf->bf_buf_addr = bf->bf_dmacontext =
pci_map_single(sc->pdev, skb->data, pci_map_single(sc->pdev, skb->data,
skb->len, skb->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
bf->bf_mpdu = skb; 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 beacon alloc\n");
return -ENOMEM;
}
return 0; return 0;
} }
...@@ -468,40 +478,38 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -468,40 +478,38 @@ void ath9k_beacon_tasklet(unsigned long data)
if (sc->sc_bmisscount < BSTUCK_THRESH) { if (sc->sc_bmisscount < BSTUCK_THRESH) {
if (sc->sc_flags & SC_OP_NO_RESET) { if (sc->sc_flags & SC_OP_NO_RESET) {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: missed %u consecutive beacons\n", "missed %u consecutive beacons\n",
__func__, sc->sc_bmisscount); sc->sc_bmisscount);
if (show_cycles) { if (show_cycles) {
/* /*
* Display cycle counter stats from HW * Display cycle counter stats from HW
* to aide in debug of stickiness. * to aide in debug of stickiness.
*/ */
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: busy times: rx_clear=%d, " "busy times: rx_clear=%d, "
"rx_frame=%d, tx_frame=%d\n", "rx_frame=%d, tx_frame=%d\n",
__func__, rx_clear, rx_frame, rx_clear, rx_frame,
tx_frame); tx_frame);
} else { } else {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: unable to obtain " "unable to obtain "
"busy times\n", __func__); "busy times\n");
} }
} else { } else {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: missed %u consecutive beacons\n", "missed %u consecutive beacons\n",
__func__, sc->sc_bmisscount); sc->sc_bmisscount);
} }
} else if (sc->sc_bmisscount >= BSTUCK_THRESH) { } else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
if (sc->sc_flags & SC_OP_NO_RESET) { if (sc->sc_flags & SC_OP_NO_RESET) {
if (sc->sc_bmisscount == BSTUCK_THRESH) { if (sc->sc_bmisscount == BSTUCK_THRESH) {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: beacon is officially " "beacon is officially "
"stuck\n", __func__); "stuck\n");
ath9k_hw_dmaRegDump(ah);
} }
} else { } else {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: beacon is officially stuck\n", "beacon is officially stuck\n");
__func__);
ath_bstuck_process(sc); ath_bstuck_process(sc);
} }
} }
...@@ -511,12 +519,12 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -511,12 +519,12 @@ void ath9k_beacon_tasklet(unsigned long data)
if (sc->sc_bmisscount != 0) { if (sc->sc_bmisscount != 0) {
if (sc->sc_flags & SC_OP_NO_RESET) { if (sc->sc_flags & SC_OP_NO_RESET) {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: resume beacon xmit after %u misses\n", "resume beacon xmit after %u misses\n",
__func__, sc->sc_bmisscount); sc->sc_bmisscount);
} else { } else {
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: resume beacon xmit after %u misses\n", "resume beacon xmit after %u misses\n",
__func__, sc->sc_bmisscount); sc->sc_bmisscount);
} }
sc->sc_bmisscount = 0; sc->sc_bmisscount = 0;
} }
...@@ -536,8 +544,8 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -536,8 +544,8 @@ void ath9k_beacon_tasklet(unsigned long data)
if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF]; if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", "slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
__func__, slot, (unsigned long long)tsf, tsftu, slot, (unsigned long long)tsf, tsftu,
intval, if_id); intval, if_id);
bfaddr = 0; bfaddr = 0;
...@@ -580,8 +588,7 @@ void ath9k_beacon_tasklet(unsigned long data) ...@@ -580,8 +588,7 @@ void ath9k_beacon_tasklet(unsigned long data)
*/ */
if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) { if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: beacon queue %u did not stop?\n", "beacon queue %u did not stop?\n", sc->sc_bhalq);
__func__, sc->sc_bhalq);
/* NB: the HAL still stops DMA, so proceed */ /* NB: the HAL still stops DMA, so proceed */
} }
...@@ -614,16 +621,16 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -614,16 +621,16 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
struct ath_beacon_config conf; struct ath_beacon_config conf;
struct ath_vap *avp; struct ath_vap *avp;
enum ath9k_opmode av_opmode; enum nl80211_iftype opmode;
u32 nexttbtt, intval; u32 nexttbtt, intval;
if (if_id != ATH_IF_ID_ANY) { if (if_id != ATH_IF_ID_ANY) {
vif = sc->sc_vaps[if_id]; vif = sc->sc_vaps[if_id];
ASSERT(vif); ASSERT(vif);
avp = (void *)vif->drv_priv; avp = (void *)vif->drv_priv;
av_opmode = avp->av_opmode; opmode = avp->av_opmode;
} else { } else {
av_opmode = sc->sc_ah->ah_opmode; opmode = sc->sc_ah->ah_opmode;
} }
memset(&conf, 0, sizeof(struct ath_beacon_config)); memset(&conf, 0, sizeof(struct ath_beacon_config));
...@@ -639,7 +646,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -639,7 +646,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp); nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp);
/* XXX conditionalize multi-bss support? */ /* XXX conditionalize multi-bss support? */
if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
/* /*
* For multi-bss ap support beacons are either staggered * For multi-bss ap support beacons are either staggered
* evenly over N slots or burst together. For the former * evenly over N slots or burst together. For the former
...@@ -658,11 +665,11 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -658,11 +665,11 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
else if (intval) /* NB: can be 0 for monitor mode */ else if (intval) /* NB: can be 0 for monitor mode */
nexttbtt = roundup(nexttbtt, intval); nexttbtt = roundup(nexttbtt, intval);
DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", DPRINTF(sc, ATH_DBG_BEACON, "nexttbtt %u intval %u (%u)\n",
__func__, nexttbtt, intval, conf.beacon_interval); nexttbtt, intval, conf.beacon_interval);
/* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */ /* Check for NL80211_IFTYPE_AP and sc_nostabeacons for WDS client */
if (sc->sc_ah->ah_opmode == ATH9K_M_STA) { if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_STATION) {
struct ath9k_beacon_state bs; struct ath9k_beacon_state bs;
u64 tsf; u64 tsf;
u32 tsftu; u32 tsftu;
...@@ -746,7 +753,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -746,7 +753,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
bs.bs_sleepduration = bs.bs_dtimperiod; bs.bs_sleepduration = bs.bs_dtimperiod;
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: tsf %llu " "tsf %llu "
"tsf:tu %u " "tsf:tu %u "
"intval %u " "intval %u "
"nexttbtt %u " "nexttbtt %u "
...@@ -758,7 +765,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -758,7 +765,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
"maxdur %u " "maxdur %u "
"next %u " "next %u "
"timoffset %u\n", "timoffset %u\n",
__func__,
(unsigned long long)tsf, tsftu, (unsigned long long)tsf, tsftu,
bs.bs_intval, bs.bs_intval,
bs.bs_nexttbtt, bs.bs_nexttbtt,
...@@ -782,7 +788,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -782,7 +788,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
ath9k_hw_set_interrupts(ah, 0); ath9k_hw_set_interrupts(ah, 0);
if (nexttbtt == intval) if (nexttbtt == intval)
intval |= ATH9K_BEACON_RESET_TSF; intval |= ATH9K_BEACON_RESET_TSF;
if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) { if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC) {
/* /*
* Pull nexttbtt forward to reflect the current * Pull nexttbtt forward to reflect the current
* TSF * TSF
...@@ -798,8 +804,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -798,8 +804,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
} }
#undef FUDGE #undef FUDGE
DPRINTF(sc, ATH_DBG_BEACON, DPRINTF(sc, ATH_DBG_BEACON,
"%s: IBSS nexttbtt %u intval %u (%u)\n", "IBSS nexttbtt %u intval %u (%u)\n",
__func__, nexttbtt, nexttbtt,
intval & ~ATH9K_BEACON_RESET_TSF, intval & ~ATH9K_BEACON_RESET_TSF,
conf.beacon_interval); conf.beacon_interval);
...@@ -814,7 +820,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -814,7 +820,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) if (!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
sc->sc_imask |= ATH9K_INT_SWBA; sc->sc_imask |= ATH9K_INT_SWBA;
ath_beaconq_config(sc); ath_beaconq_config(sc);
} else if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { } else if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_AP) {
/* /*
* In AP mode we enable the beacon timers and * In AP mode we enable the beacon timers and
* SWBA interrupts to prepare beacon frames. * SWBA interrupts to prepare beacon frames.
...@@ -830,7 +836,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) ...@@ -830,7 +836,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
* When using a self-linked beacon descriptor in * When using a self-linked beacon descriptor in
* ibss mode load it once here. * ibss mode load it once here.
*/ */
if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS && if (sc->sc_ah->ah_opmode == NL80211_IFTYPE_ADHOC &&
(ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL)) (ah->ah_caps.hw_caps & ATH9K_HW_CAP_VEOL))
ath_beacon_start_adhoc(sc, 0); ath_beacon_start_adhoc(sc, 0);
} }
......
...@@ -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;
......
...@@ -17,27 +17,8 @@ ...@@ -17,27 +17,8 @@
#ifndef CORE_H #ifndef CORE_H
#define CORE_H #define CORE_H
#include <linux/version.h>
#include <linux/autoconf.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
#include <linux/delay.h>
#include <linux/wait.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <asm/byteorder.h>
#include <linux/scatterlist.h>
#include <asm/page.h>
#include <net/mac80211.h> #include <net/mac80211.h>
#include <linux/leds.h> #include <linux/leds.h>
#include <linux/rfkill.h> #include <linux/rfkill.h>
...@@ -84,52 +65,64 @@ struct ath_node; ...@@ -84,52 +65,64 @@ struct ath_node;
static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
/*************/
/* Debugging */
/*************/
enum ATH_DEBUG { enum ATH_DEBUG {
ATH_DBG_RESET = 0x00000001, ATH_DBG_RESET = 0x00000001,
ATH_DBG_PHY_IO = 0x00000002, ATH_DBG_REG_IO = 0x00000002,
ATH_DBG_REG_IO = 0x00000004, ATH_DBG_QUEUE = 0x00000004,
ATH_DBG_QUEUE = 0x00000008, ATH_DBG_EEPROM = 0x00000008,
ATH_DBG_EEPROM = 0x00000010, ATH_DBG_CALIBRATE = 0x00000010,
ATH_DBG_NF_CAL = 0x00000020, ATH_DBG_CHANNEL = 0x00000020,
ATH_DBG_CALIBRATE = 0x00000040, ATH_DBG_INTERRUPT = 0x00000040,
ATH_DBG_CHANNEL = 0x00000080, ATH_DBG_REGULATORY = 0x00000080,
ATH_DBG_INTERRUPT = 0x00000100, ATH_DBG_ANI = 0x00000100,
ATH_DBG_REGULATORY = 0x00000200, ATH_DBG_POWER_MGMT = 0x00000200,
ATH_DBG_ANI = 0x00000400, ATH_DBG_XMIT = 0x00000400,
ATH_DBG_POWER_MGMT = 0x00000800, ATH_DBG_BEACON = 0x00001000,
ATH_DBG_XMIT = 0x00001000, ATH_DBG_CONFIG = 0x00002000,
ATH_DBG_BEACON = 0x00002000, ATH_DBG_KEYCACHE = 0x00004000,
ATH_DBG_RATE = 0x00004000, ATH_DBG_FATAL = 0x00008000,
ATH_DBG_CONFIG = 0x00008000,
ATH_DBG_KEYCACHE = 0x00010000,
ATH_DBG_AGGR = 0x00020000,
ATH_DBG_FATAL = 0x00040000,
ATH_DBG_ANY = 0xffffffff ATH_DBG_ANY = 0xffffffff
}; };
#define DBG_DEFAULT (ATH_DBG_FATAL) #define DBG_DEFAULT (ATH_DBG_FATAL)
#define DPRINTF(sc, _m, _fmt, ...) do { \ #ifdef CONFIG_ATH9K_DEBUG
if (sc->sc_debug & (_m)) \
printk(_fmt , ##__VA_ARGS__); \ struct ath9k_debug {
} while (0) int debug_mask;
struct dentry *debugfs_root;
struct dentry *debugfs_phy;
struct dentry *debugfs_dma;
};
void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
int ath9k_init_debug(struct ath_softc *sc);
void ath9k_exit_debug(struct ath_softc *sc);
#else
static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
const char *fmt, ...)
{
}
/***************************/ static inline int ath9k_init_debug(struct ath_softc *sc)
/* Load-time Configuration */ {
/***************************/ return 0;
}
static inline void ath9k_exit_debug(struct ath_softc *sc)
{
}
#endif /* CONFIG_ATH9K_DEBUG */
/* Per-instance load-time (note: NOT run-time) configurations
* for Atheros Device */
struct ath_config { struct ath_config {
u32 ath_aggr_prot; u32 ath_aggr_prot;
u16 txpowlimit; u16 txpowlimit;
u16 txpowlimit_override; u16 txpowlimit_override;
u8 cabqReadytime; /* Cabq Readytime % */ u8 cabqReadytime;
u8 swBeaconProcess; /* Process received beacons in SW (vs HW) */ u8 swBeaconProcess;
}; };
/*************************/ /*************************/
...@@ -160,14 +153,13 @@ enum buffer_type { ...@@ -160,14 +153,13 @@ enum buffer_type {
}; };
struct ath_buf_state { struct ath_buf_state {
int bfs_nframes; /* # frames in aggregate */ int bfs_nframes; /* # frames in aggregate */
u16 bfs_al; /* length of aggregate */ u16 bfs_al; /* length of aggregate */
u16 bfs_frmlen; /* length of frame */ u16 bfs_frmlen; /* length of frame */
int bfs_seqno; /* sequence number */ int bfs_seqno; /* sequence number */
int bfs_tidno; /* tid of this frame */ int bfs_tidno; /* tid of this frame */
int bfs_retries; /* current retries */ int bfs_retries; /* current retries */
u32 bf_type; /* BUF_* (enum buffer_type) */ u32 bf_type; /* BUF_* (enum buffer_type) */
/* key type use to encrypt this frame */
u32 bfs_keyix; u32 bfs_keyix;
enum ath9k_key_type bfs_keytype; enum ath9k_key_type bfs_keytype;
}; };
...@@ -213,13 +205,6 @@ struct ath_buf { ...@@ -213,13 +205,6 @@ struct ath_buf {
dma_addr_t bf_dmacontext; dma_addr_t bf_dmacontext;
}; };
/*
* reset the rx buffer.
* any new fields added to the athbuf and require
* reset need to be added to this macro.
* currently bf_status is the only one requires that
* requires reset.
*/
#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0) #define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
/* hw processing complete, desc processed by hal */ /* hw processing complete, desc processed by hal */
...@@ -263,11 +248,8 @@ void ath_rx_cleanup(struct ath_softc *sc); ...@@ -263,11 +248,8 @@ void ath_rx_cleanup(struct ath_softc *sc);
int ath_rx_tasklet(struct ath_softc *sc, int flush); int ath_rx_tasklet(struct ath_softc *sc, int flush);
#define ATH_TXBUF 512 #define ATH_TXBUF 512
/* max number of transmit attempts (tries) */
#define ATH_TXMAXTRY 13 #define ATH_TXMAXTRY 13
/* max number of 11n transmit attempts (tries) */
#define ATH_11N_TXMAXTRY 10 #define ATH_11N_TXMAXTRY 10
/* max number of tries for management and control frames */
#define ATH_MGT_TXMAXTRY 4 #define ATH_MGT_TXMAXTRY 4
#define WME_BA_BMP_SIZE 64 #define WME_BA_BMP_SIZE 64
#define WME_MAX_BA WME_BA_BMP_SIZE #define WME_MAX_BA WME_BA_BMP_SIZE
...@@ -279,22 +261,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush); ...@@ -279,22 +261,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush);
WME_AC_VO) WME_AC_VO)
/* Wireless Multimedia Extension Defines */ #define WME_AC_BE 0
#define WME_AC_BE 0 /* best effort */ #define WME_AC_BK 1
#define WME_AC_BK 1 /* background */ #define WME_AC_VI 2
#define WME_AC_VI 2 /* video */ #define WME_AC_VO 3
#define WME_AC_VO 3 /* voice */ #define WME_NUM_AC 4
#define WME_NUM_AC 4
/*
* Data transmit queue state. One of these exists for each
* hardware transmit queue. Packets sent to us from above
* are assigned to queues based on their priority. Not all
* devices support a complete set of hardware transmit queues.
* For those devices the array sc_ac2q will map multiple
* priorities to fewer hardware queues (typically all to one
* hardware queue).
*/
struct ath_txq { struct ath_txq {
u32 axq_qnum; /* hardware q number */ u32 axq_qnum; /* hardware q number */
u32 *axq_link; /* link ptr in last TX desc */ u32 *axq_link; /* link ptr in last TX desc */
...@@ -372,14 +344,15 @@ struct ath_xmit_status { ...@@ -372,14 +344,15 @@ struct ath_xmit_status {
#define ATH_TX_BAR 0x04 #define ATH_TX_BAR 0x04
}; };
/* All RSSI values are noise floor adjusted */
struct ath_tx_stat { struct ath_tx_stat {
int rssi; /* RSSI (noise floor ajusted) */ int rssi;
int rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ int rssictl[ATH_MAX_ANTENNA];
int rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */ int rssiextn[ATH_MAX_ANTENNA];
int rateieee; /* data rate xmitted (IEEE rate code) */ int rateieee;
int rateKbps; /* data rate xmitted (Kbps) */ int rateKbps;
int ratecode; /* phy rate code */ int ratecode;
int flags; /* validity flags */ int flags;
/* if any of ctl,extn chain rssis are valid */ /* if any of ctl,extn chain rssis are valid */
#define ATH_TX_CHAIN_RSSI_VALID 0x01 #define ATH_TX_CHAIN_RSSI_VALID 0x01
/* if extn chain rssis are valid */ /* if extn chain rssis are valid */
...@@ -415,7 +388,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb); ...@@ -415,7 +388,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
/**********************/ /**********************/
#define ADDBA_EXCHANGE_ATTEMPTS 10 #define ADDBA_EXCHANGE_ATTEMPTS 10
#define ATH_AGGR_DELIM_SZ 4 /* delimiter size */ #define ATH_AGGR_DELIM_SZ 4
#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
/* number of delimiters for encryption padding */ /* number of delimiters for encryption padding */
#define ATH_AGGR_ENCRYPTDELIM 10 #define ATH_AGGR_ENCRYPTDELIM 10
...@@ -466,10 +439,9 @@ struct aggr_rifs_param { ...@@ -466,10 +439,9 @@ struct aggr_rifs_param {
/* Per-node aggregation state */ /* Per-node aggregation state */
struct ath_node_aggr { struct ath_node_aggr {
struct ath_atx tx; /* node transmit state */ struct ath_atx tx;
}; };
/* driver-specific node state */
struct ath_node { struct ath_node {
struct ath_softc *an_sc; struct ath_softc *an_sc;
struct ath_node_aggr an_aggr; struct ath_node_aggr an_aggr;
...@@ -500,12 +472,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid ...@@ -500,12 +472,11 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
#define ATH_SET_VAP_BSSID_MASK(bssid_mask) \ #define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02)) ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
/* driver-specific vap state */
struct ath_vap { struct ath_vap {
int av_bslot; /* beacon slot index */ int av_bslot;
enum ath9k_opmode av_opmode; /* VAP operational mode */ enum nl80211_iftype av_opmode;
struct ath_buf *av_bcbuf; /* beacon buffer */ struct ath_buf *av_bcbuf;
struct ath_tx_control av_btxctl; /* txctl information for beacon */ struct ath_tx_control av_btxctl;
}; };
/*******************/ /*******************/
...@@ -518,12 +489,11 @@ struct ath_vap { ...@@ -518,12 +489,11 @@ struct ath_vap {
* number of beacon intervals, the game's up. * number of beacon intervals, the game's up.
*/ */
#define BSTUCK_THRESH (9 * ATH_BCBUF) #define BSTUCK_THRESH (9 * ATH_BCBUF)
#define ATH_BCBUF 4 /* number of beacon buffers */ #define ATH_BCBUF 4
#define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */ #define ATH_DEFAULT_BINTVAL 100 /* TU */
#define ATH_DEFAULT_BMISS_LIMIT 10 #define ATH_DEFAULT_BMISS_LIMIT 10
#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
/* beacon configuration */
struct ath_beacon_config { struct ath_beacon_config {
u16 beacon_interval; u16 beacon_interval;
u16 listen_interval; u16 listen_interval;
...@@ -661,7 +631,9 @@ struct ath_softc { ...@@ -661,7 +631,9 @@ struct ath_softc {
u8 sc_myaddr[ETH_ALEN]; u8 sc_myaddr[ETH_ALEN];
u8 sc_bssidmask[ETH_ALEN]; u8 sc_bssidmask[ETH_ALEN];
int sc_debug; #ifdef CONFIG_ATH9K_DEBUG
struct ath9k_debug sc_debug;
#endif
u32 sc_intrstatus; u32 sc_intrstatus;
u32 sc_flags; /* SC_OP_* */ u32 sc_flags; /* SC_OP_* */
unsigned int rx_filter; unsigned int rx_filter;
...@@ -674,18 +646,18 @@ struct ath_softc { ...@@ -674,18 +646,18 @@ struct ath_softc {
u8 sc_tx_chainmask; u8 sc_tx_chainmask;
u8 sc_rx_chainmask; u8 sc_rx_chainmask;
enum ath9k_int sc_imask; enum ath9k_int sc_imask;
enum wireless_mode sc_curmode; /* current phy mode */ enum wireless_mode sc_curmode;
enum PROT_MODE sc_protmode; enum PROT_MODE sc_protmode;
u8 sc_nbcnvaps; /* # of vaps sending beacons */ u8 sc_nbcnvaps;
u16 sc_nvaps; /* # of active virtual ap's */ u16 sc_nvaps;
struct ieee80211_vif *sc_vaps[ATH_BCBUF]; struct ieee80211_vif *sc_vaps[ATH_BCBUF];
u8 sc_mcastantenna; u8 sc_mcastantenna;
u8 sc_defant; /* current default antenna */ u8 sc_defant;
u8 sc_rxotherant; /* rx's on non-default antenna */ u8 sc_rxotherant;
struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */ struct ath9k_node_stats sc_halstats;
enum ath9k_ht_extprotspacing sc_ht_extprotspacing; enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
enum ath9k_ht_macmode tx_chan_width; enum ath9k_ht_macmode tx_chan_width;
...@@ -699,22 +671,22 @@ struct ath_softc { ...@@ -699,22 +671,22 @@ struct ath_softc {
} sc_updateslot; /* slot time update fsm */ } sc_updateslot; /* slot time update fsm */
/* Crypto */ /* Crypto */
u32 sc_keymax; /* size of key cache */ u32 sc_keymax;
DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);
u8 sc_splitmic; /* split TKIP MIC keys */ u8 sc_splitmic; /* split TKIP MIC keys */
/* RX */ /* RX */
struct list_head sc_rxbuf; struct list_head sc_rxbuf;
struct ath_descdma sc_rxdma; struct ath_descdma sc_rxdma;
int sc_rxbufsize; /* rx size based on mtu */ int sc_rxbufsize;
u32 *sc_rxlink; /* link ptr in last RX desc */ u32 *sc_rxlink;
/* TX */ /* TX */
struct list_head sc_txbuf; struct list_head sc_txbuf;
struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES]; struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES];
struct ath_descdma sc_txdma; struct ath_descdma sc_txdma;
u32 sc_txqsetup; u32 sc_txqsetup;
int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME AC -> h/w qnum */ int sc_haltype2q[ATH9K_WME_AC_VO+1];
u16 seq_no; /* TX sequence number */ u16 seq_no; /* TX sequence number */
/* Beacon */ /* Beacon */
...@@ -724,13 +696,13 @@ struct ath_softc { ...@@ -724,13 +696,13 @@ struct ath_softc {
struct list_head sc_bbuf; struct list_head sc_bbuf;
u32 sc_bhalq; u32 sc_bhalq;
u32 sc_bmisscount; u32 sc_bmisscount;
u32 ast_be_xmit; /* beacons transmitted */ u32 ast_be_xmit;
u64 bc_tstamp; u64 bc_tstamp;
/* Rate */ /* Rate */
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
u8 sc_protrix; /* protection rate index */ u8 sc_protrix;
/* Channel, Band */ /* Channel, Band */
struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX]; struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
......
/*
* 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",
......
此差异已折叠。
...@@ -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 {
......
此差异已折叠。
...@@ -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 { \
......
...@@ -83,18 +83,16 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, ...@@ -83,18 +83,16 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
DPRINTF(sc, ATH_DBG_QUEUE, DPRINTF(sc, ATH_DBG_QUEUE,
"%s: txq depth = %d\n", __func__, txq->axq_depth); "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
if (txq->axq_link == NULL) { if (txq->axq_link == NULL) {
ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
DPRINTF(sc, ATH_DBG_XMIT, DPRINTF(sc, ATH_DBG_XMIT,
"%s: TXDP[%u] = %llx (%p)\n", "TXDP[%u] = %llx (%p)\n",
__func__, txq->axq_qnum, txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
ito64(bf->bf_daddr), bf->bf_desc);
} else { } else {
*txq->axq_link = bf->bf_daddr; *txq->axq_link = bf->bf_daddr;
DPRINTF(sc, ATH_DBG_XMIT, "%s: link[%u] (%p)=%llx (%p)\n", DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
__func__,
txq->axq_qnum, txq->axq_link, txq->axq_qnum, txq->axq_link,
ito64(bf->bf_daddr), bf->bf_desc); ito64(bf->bf_daddr), bf->bf_desc);
} }
...@@ -109,8 +107,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ...@@ -109,8 +107,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info); struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
DPRINTF(sc, ATH_DBG_XMIT, DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
"%s: TX complete: skb: %p\n", __func__, skb);
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK || if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) { tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
...@@ -763,7 +760,8 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc, ...@@ -763,7 +760,8 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
* when perform internal reset in this routine. * when perform internal reset in this routine.
* Only enable reset in STA mode for now. * Only enable reset in STA mode for now.
*/ */
if (sc->sc_ah->ah_opmode == ATH9K_M_STA) if (sc->sc_ah->ah_opmode ==
NL80211_IFTYPE_STATION)
needreset = 1; needreset = 1;
} }
} else { } else {
...@@ -983,8 +981,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) ...@@ -983,8 +981,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
int txok, nbad = 0; int txok, nbad = 0;
int status; int status;
DPRINTF(sc, ATH_DBG_QUEUE, DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
"%s: tx queue %d (%x), link %p\n", __func__,
txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
txq->axq_link); txq->axq_link);
...@@ -1116,9 +1113,9 @@ static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq) ...@@ -1116,9 +1113,9 @@ static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
struct ath_hal *ah = sc->sc_ah; struct ath_hal *ah = sc->sc_ah;
(void) ath9k_hw_stoptxdma(ah, txq->axq_qnum); (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum);
DPRINTF(sc, ATH_DBG_XMIT, "%s: tx queue [%u] %x, link %p\n", DPRINTF(sc, ATH_DBG_XMIT, "tx queue [%u] %x, link %p\n",
__func__, txq->axq_qnum, txq->axq_qnum, ath9k_hw_gettxbuf(ah, txq->axq_qnum),
ath9k_hw_gettxbuf(ah, txq->axq_qnum), txq->axq_link); txq->axq_link);
} }
/* Drain only the data queues */ /* Drain only the data queues */
...@@ -1142,8 +1139,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) ...@@ -1142,8 +1139,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
if (npend) { if (npend) {
/* TxDMA not stopped, reset the hal */ /* TxDMA not stopped, reset the hal */
DPRINTF(sc, ATH_DBG_XMIT, DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
"%s: Unable to stop TxDMA. Reset HAL!\n", __func__);
spin_lock_bh(&sc->sc_resetlock); spin_lock_bh(&sc->sc_resetlock);
if (!ath9k_hw_reset(ah, if (!ath9k_hw_reset(ah,
...@@ -1153,8 +1149,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx) ...@@ -1153,8 +1149,7 @@ static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
sc->sc_ht_extprotspacing, true, &status)) { sc->sc_ht_extprotspacing, true, &status)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to reset hardware; hal status %u\n", "Unable to reset hardware; hal status %u\n",
__func__,
status); status);
} }
spin_unlock_bh(&sc->sc_resetlock); spin_unlock_bh(&sc->sc_resetlock);
...@@ -1194,7 +1189,6 @@ static void ath_tx_addto_baw(struct ath_softc *sc, ...@@ -1194,7 +1189,6 @@ static void ath_tx_addto_baw(struct ath_softc *sc,
* Function to send an A-MPDU * Function to send an A-MPDU
* NB: must be called with txq lock held * NB: must be called with txq lock held
*/ */
static int ath_tx_send_ampdu(struct ath_softc *sc, static int ath_tx_send_ampdu(struct ath_softc *sc,
struct ath_atx_tid *tid, struct ath_atx_tid *tid,
struct list_head *bf_head, struct list_head *bf_head,
...@@ -1242,7 +1236,6 @@ static int ath_tx_send_ampdu(struct ath_softc *sc, ...@@ -1242,7 +1236,6 @@ static int ath_tx_send_ampdu(struct ath_softc *sc,
* looks up the rate * looks up the rate
* returns aggr limit based on lowest of the rates * returns aggr limit based on lowest of the rates
*/ */
static u32 ath_lookup_rate(struct ath_softc *sc, static u32 ath_lookup_rate(struct ath_softc *sc,
struct ath_buf *bf, struct ath_buf *bf,
struct ath_atx_tid *tid) struct ath_atx_tid *tid)
...@@ -1310,7 +1303,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, ...@@ -1310,7 +1303,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc,
* meet the minimum required mpdudensity. * meet the minimum required mpdudensity.
* caller should make sure that the rate is HT rate . * caller should make sure that the rate is HT rate .
*/ */
static int ath_compute_num_delims(struct ath_softc *sc, static int ath_compute_num_delims(struct ath_softc *sc,
struct ath_atx_tid *tid, struct ath_atx_tid *tid,
struct ath_buf *bf, struct ath_buf *bf,
...@@ -1382,7 +1374,6 @@ static int ath_compute_num_delims(struct ath_softc *sc, ...@@ -1382,7 +1374,6 @@ static int ath_compute_num_delims(struct ath_softc *sc,
* For aggregation from software buffer queue. * For aggregation from software buffer queue.
* NB: must be called with txq lock held * NB: must be called with txq lock held
*/ */
static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
struct ath_atx_tid *tid, struct ath_atx_tid *tid,
struct list_head *bf_q, struct list_head *bf_q,
...@@ -1505,7 +1496,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, ...@@ -1505,7 +1496,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
* process pending frames possibly doing a-mpdu aggregation * process pending frames possibly doing a-mpdu aggregation
* NB: must be called with txq lock held * NB: must be called with txq lock held
*/ */
static void ath_tx_sched_aggr(struct ath_softc *sc, static void ath_tx_sched_aggr(struct ath_softc *sc,
struct ath_txq *txq, struct ath_atx_tid *tid) struct ath_txq *txq, struct ath_atx_tid *tid)
{ {
...@@ -1635,7 +1625,6 @@ static void ath_tid_drain(struct ath_softc *sc, ...@@ -1635,7 +1625,6 @@ static void ath_tid_drain(struct ath_softc *sc,
* Drain all pending buffers * Drain all pending buffers
* NB: must be called with txq lock held * NB: must be called with txq lock held
*/ */
static void ath_txq_drain_pending_buffers(struct ath_softc *sc, static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
struct ath_txq *txq) struct ath_txq *txq)
{ {
...@@ -1653,7 +1642,7 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc, ...@@ -1653,7 +1642,7 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
} }
} }
static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, static int ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
struct sk_buff *skb, struct sk_buff *skb,
struct ath_tx_control *txctl) struct ath_tx_control *txctl)
{ {
...@@ -1663,7 +1652,9 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, ...@@ -1663,7 +1652,9 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
int hdrlen; int hdrlen;
__le16 fc; __le16 fc;
tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_KERNEL); tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
if (unlikely(!tx_info_priv))
return -ENOMEM;
tx_info->rate_driver_data[0] = tx_info_priv; tx_info->rate_driver_data[0] = tx_info_priv;
hdrlen = ieee80211_get_hdrlen_from_skb(skb); hdrlen = ieee80211_get_hdrlen_from_skb(skb);
fc = hdr->frame_control; fc = hdr->frame_control;
...@@ -1712,9 +1703,18 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf, ...@@ -1712,9 +1703,18 @@ static void ath_tx_setup_buffer(struct ath_softc *sc, struct ath_buf *bf,
/* DMA setup */ /* DMA setup */
bf->bf_mpdu = skb; bf->bf_mpdu = skb;
bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data,
skb->len, PCI_DMA_TODEVICE); skb->len, PCI_DMA_TODEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev, bf->bf_dmacontext))) {
bf->bf_mpdu = NULL;
DPRINTF(sc, ATH_DBG_CONFIG,
"pci_dma_mapping_error() on TX\n");
return -ENOMEM;
}
bf->bf_buf_addr = bf->bf_dmacontext; bf->bf_buf_addr = bf->bf_dmacontext;
return 0;
} }
/* FIXME: tx power */ /* FIXME: tx power */
...@@ -1786,21 +1786,46 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, ...@@ -1786,21 +1786,46 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
spin_unlock_bh(&txctl->txq->axq_lock); spin_unlock_bh(&txctl->txq->axq_lock);
} }
/* Upon failure caller should free skb */
int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb, int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
struct ath_tx_control *txctl) struct ath_tx_control *txctl)
{ {
struct ath_buf *bf; struct ath_buf *bf;
int r;
/* Check if a tx buffer is available */ /* Check if a tx buffer is available */
bf = ath_tx_get_buffer(sc); bf = ath_tx_get_buffer(sc);
if (!bf) { if (!bf) {
DPRINTF(sc, ATH_DBG_XMIT, "%s: TX buffers are full\n", DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
__func__);
return -1; return -1;
} }
ath_tx_setup_buffer(sc, bf, skb, txctl); r = ath_tx_setup_buffer(sc, bf, skb, txctl);
if (unlikely(r)) {
struct ath_txq *txq = txctl->txq;
DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
/* upon ath_tx_processq() this TX queue will be resumed, we
* guarantee this will happen by knowing beforehand that
* we will at least have to run TX completionon one buffer
* on the queue */
spin_lock_bh(&txq->axq_lock);
if (ath_txq_depth(sc, txq->axq_qnum) > 1) {
ieee80211_stop_queue(sc->hw,
skb_get_queue_mapping(skb));
txq->stopped = 1;
}
spin_unlock_bh(&txq->axq_lock);
spin_lock_bh(&sc->sc_txbuflock);
list_add_tail(&bf->list, &sc->sc_txbuf);
spin_unlock_bh(&sc->sc_txbuflock);
return r;
}
ath_tx_start_dma(sc, bf, txctl); ath_tx_start_dma(sc, bf, txctl);
return 0; return 0;
...@@ -1820,8 +1845,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) ...@@ -1820,8 +1845,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
"tx", nbufs, 1); "tx", nbufs, 1);
if (error != 0) { if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: failed to allocate tx descriptors: %d\n", "Failed to allocate tx descriptors: %d\n",
__func__, error); error);
break; break;
} }
...@@ -1830,9 +1855,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) ...@@ -1830,9 +1855,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
"beacon", ATH_BCBUF, 1); "beacon", ATH_BCBUF, 1);
if (error != 0) { if (error != 0) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: failed to allocate " "Failed to allocate beacon descriptors: %d\n",
"beacon descripotrs: %d\n", error);
__func__, error);
break; break;
} }
...@@ -1904,8 +1928,8 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) ...@@ -1904,8 +1928,8 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
} }
if (qnum >= ARRAY_SIZE(sc->sc_txq)) { if (qnum >= ARRAY_SIZE(sc->sc_txq)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: hal qnum %u out of range, max %u!\n", "qnum %u out of range, max %u!\n",
__func__, qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq)); qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq));
ath9k_hw_releasetxqueue(ah, qnum); ath9k_hw_releasetxqueue(ah, qnum);
return NULL; return NULL;
} }
...@@ -1950,8 +1974,8 @@ int ath_tx_setup(struct ath_softc *sc, int haltype) ...@@ -1950,8 +1974,8 @@ int ath_tx_setup(struct ath_softc *sc, int haltype)
if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: HAL AC %u out of range, max %zu!\n", "HAL AC %u out of range, max %zu!\n",
__func__, haltype, ARRAY_SIZE(sc->sc_haltype2q)); haltype, ARRAY_SIZE(sc->sc_haltype2q));
return 0; return 0;
} }
txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
...@@ -1970,8 +1994,7 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) ...@@ -1970,8 +1994,7 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
case ATH9K_TX_QUEUE_DATA: case ATH9K_TX_QUEUE_DATA:
if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) { if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: HAL AC %u out of range, max %zu!\n", "HAL AC %u out of range, max %zu!\n",
__func__,
haltype, ARRAY_SIZE(sc->sc_haltype2q)); haltype, ARRAY_SIZE(sc->sc_haltype2q));
return -1; return -1;
} }
...@@ -2004,8 +2027,8 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) ...@@ -2004,8 +2027,8 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
/* Try to avoid running out of descriptors */ /* Try to avoid running out of descriptors */
if (txq->axq_depth >= (ATH_TXBUF - 20)) { if (txq->axq_depth >= (ATH_TXBUF - 20)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: TX queue: %d is full, depth: %d\n", "TX queue: %d is full, depth: %d\n",
__func__, qnum, txq->axq_depth); qnum, txq->axq_depth);
ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb)); ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
txq->stopped = 1; txq->stopped = 1;
spin_unlock_bh(&txq->axq_lock); spin_unlock_bh(&txq->axq_lock);
...@@ -2047,8 +2070,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, ...@@ -2047,8 +2070,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) { if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
DPRINTF(sc, ATH_DBG_FATAL, DPRINTF(sc, ATH_DBG_FATAL,
"%s: unable to update hardware queue %u!\n", "Unable to update hardware queue %u!\n", qnum);
__func__, qnum);
error = -EIO; error = -EIO;
} else { } else {
ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */ ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */
...@@ -2167,7 +2189,7 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx) ...@@ -2167,7 +2189,7 @@ void ath_draintxq(struct ath_softc *sc, bool retry_tx)
* we go to INIT state */ * we go to INIT state */
if (!(sc->sc_flags & SC_OP_INVALID)) { if (!(sc->sc_flags & SC_OP_INVALID)) {
(void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq); (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__, DPRINTF(sc, ATH_DBG_XMIT, "beacon queue %x\n",
ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq)); ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq));
} }
...@@ -2267,8 +2289,6 @@ void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid) ...@@ -2267,8 +2289,6 @@ void ath_tx_aggr_teardown(struct ath_softc *sc, struct ath_node *an, u8 tid)
struct list_head bf_head; struct list_head bf_head;
INIT_LIST_HEAD(&bf_head); INIT_LIST_HEAD(&bf_head);
DPRINTF(sc, ATH_DBG_AGGR, "%s: teardown TX aggregation\n", __func__);
if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */ if (txtid->state & AGGR_CLEANUP) /* cleanup is in progress */
return; return;
...@@ -2501,8 +2521,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) ...@@ -2501,8 +2521,7 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
if (hdrlen & 3) { if (hdrlen & 3) {
padsize = hdrlen % 4; padsize = hdrlen % 4;
if (skb_headroom(skb) < padsize) { if (skb_headroom(skb) < padsize) {
DPRINTF(sc, ATH_DBG_XMIT, "%s: TX CABQ padding " DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
"failed\n", __func__);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
return; return;
} }
...@@ -2512,12 +2531,10 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb) ...@@ -2512,12 +2531,10 @@ void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb)
txctl.txq = sc->sc_cabq; txctl.txq = sc->sc_cabq;
DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting CABQ packet, skb: %p\n", DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
__func__,
skb);
if (ath_tx_start(sc, skb, &txctl) != 0) { if (ath_tx_start(sc, skb, &txctl) != 0) {
DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__); DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
goto exit; goto exit;
} }
......
...@@ -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
......
...@@ -69,6 +69,12 @@ ...@@ -69,6 +69,12 @@
#ifndef __iwl_3945_commands_h__ #ifndef __iwl_3945_commands_h__
#define __iwl_3945_commands_h__ #define __iwl_3945_commands_h__
/* uCode version contains 4 values: Major/Minor/API/Serial */
#define IWL_UCODE_MAJOR(ver) (((ver) & 0xFF000000) >> 24)
#define IWL_UCODE_MINOR(ver) (((ver) & 0x00FF0000) >> 16)
#define IWL_UCODE_API(ver) (((ver) & 0x0000FF00) >> 8)
#define IWL_UCODE_SERIAL(ver) ((ver) & 0x000000FF)
enum { enum {
REPLY_ALIVE = 0x1, REPLY_ALIVE = 0x1,
REPLY_ERROR = 0x2, REPLY_ERROR = 0x2,
...@@ -220,7 +226,7 @@ struct iwl3945_power_per_rate { ...@@ -220,7 +226,7 @@ struct iwl3945_power_per_rate {
* *
*****************************************************************************/ *****************************************************************************/
#define UCODE_VALID_OK __constant_cpu_to_le32(0x1) #define UCODE_VALID_OK cpu_to_le32(0x1)
#define INITIALIZE_SUBTYPE (9) #define INITIALIZE_SUBTYPE (9)
/* /*
...@@ -322,42 +328,42 @@ enum { ...@@ -322,42 +328,42 @@ enum {
/* rx_config flags */ /* rx_config flags */
/* band & modulation selection */ /* band & modulation selection */
#define RXON_FLG_BAND_24G_MSK __constant_cpu_to_le32(1 << 0) #define RXON_FLG_BAND_24G_MSK cpu_to_le32(1 << 0)
#define RXON_FLG_CCK_MSK __constant_cpu_to_le32(1 << 1) #define RXON_FLG_CCK_MSK cpu_to_le32(1 << 1)
/* auto detection enable */ /* auto detection enable */
#define RXON_FLG_AUTO_DETECT_MSK __constant_cpu_to_le32(1 << 2) #define RXON_FLG_AUTO_DETECT_MSK cpu_to_le32(1 << 2)
/* TGg protection when tx */ /* TGg protection when tx */
#define RXON_FLG_TGG_PROTECT_MSK __constant_cpu_to_le32(1 << 3) #define RXON_FLG_TGG_PROTECT_MSK cpu_to_le32(1 << 3)
/* cck short slot & preamble */ /* cck short slot & preamble */
#define RXON_FLG_SHORT_SLOT_MSK __constant_cpu_to_le32(1 << 4) #define RXON_FLG_SHORT_SLOT_MSK cpu_to_le32(1 << 4)
#define RXON_FLG_SHORT_PREAMBLE_MSK __constant_cpu_to_le32(1 << 5) #define RXON_FLG_SHORT_PREAMBLE_MSK cpu_to_le32(1 << 5)
/* antenna selection */ /* antenna selection */
#define RXON_FLG_DIS_DIV_MSK __constant_cpu_to_le32(1 << 7) #define RXON_FLG_DIS_DIV_MSK cpu_to_le32(1 << 7)
#define RXON_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0x0f00) #define RXON_FLG_ANT_SEL_MSK cpu_to_le32(0x0f00)
#define RXON_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) #define RXON_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
#define RXON_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) #define RXON_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
/* radar detection enable */ /* radar detection enable */
#define RXON_FLG_RADAR_DETECT_MSK __constant_cpu_to_le32(1 << 12) #define RXON_FLG_RADAR_DETECT_MSK cpu_to_le32(1 << 12)
#define RXON_FLG_TGJ_NARROW_BAND_MSK __constant_cpu_to_le32(1 << 13) #define RXON_FLG_TGJ_NARROW_BAND_MSK cpu_to_le32(1 << 13)
/* rx response to host with 8-byte TSF /* rx response to host with 8-byte TSF
* (according to ON_AIR deassertion) */ * (according to ON_AIR deassertion) */
#define RXON_FLG_TSF2HOST_MSK __constant_cpu_to_le32(1 << 15) #define RXON_FLG_TSF2HOST_MSK cpu_to_le32(1 << 15)
/* rx_config filter flags */ /* rx_config filter flags */
/* accept all data frames */ /* accept all data frames */
#define RXON_FILTER_PROMISC_MSK __constant_cpu_to_le32(1 << 0) #define RXON_FILTER_PROMISC_MSK cpu_to_le32(1 << 0)
/* pass control & management to host */ /* pass control & management to host */
#define RXON_FILTER_CTL2HOST_MSK __constant_cpu_to_le32(1 << 1) #define RXON_FILTER_CTL2HOST_MSK cpu_to_le32(1 << 1)
/* accept multi-cast */ /* accept multi-cast */
#define RXON_FILTER_ACCEPT_GRP_MSK __constant_cpu_to_le32(1 << 2) #define RXON_FILTER_ACCEPT_GRP_MSK cpu_to_le32(1 << 2)
/* don't decrypt uni-cast frames */ /* don't decrypt uni-cast frames */
#define RXON_FILTER_DIS_DECRYPT_MSK __constant_cpu_to_le32(1 << 3) #define RXON_FILTER_DIS_DECRYPT_MSK cpu_to_le32(1 << 3)
/* don't decrypt multi-cast frames */ /* don't decrypt multi-cast frames */
#define RXON_FILTER_DIS_GRP_DECRYPT_MSK __constant_cpu_to_le32(1 << 4) #define RXON_FILTER_DIS_GRP_DECRYPT_MSK cpu_to_le32(1 << 4)
/* STA is associated */ /* STA is associated */
#define RXON_FILTER_ASSOC_MSK __constant_cpu_to_le32(1 << 5) #define RXON_FILTER_ASSOC_MSK cpu_to_le32(1 << 5)
/* transfer to host non bssid beacons in associated state */ /* transfer to host non bssid beacons in associated state */
#define RXON_FILTER_BCON_AWARE_MSK __constant_cpu_to_le32(1 << 6) #define RXON_FILTER_BCON_AWARE_MSK cpu_to_le32(1 << 6)
/** /**
* REPLY_RXON = 0x10 (command, has simple generic response) * REPLY_RXON = 0x10 (command, has simple generic response)
...@@ -471,9 +477,9 @@ struct iwl3945_ac_qos { ...@@ -471,9 +477,9 @@ struct iwl3945_ac_qos {
} __attribute__ ((packed)); } __attribute__ ((packed));
/* QoS flags defines */ /* QoS flags defines */
#define QOS_PARAM_FLG_UPDATE_EDCA_MSK __constant_cpu_to_le32(0x01) #define QOS_PARAM_FLG_UPDATE_EDCA_MSK cpu_to_le32(0x01)
#define QOS_PARAM_FLG_TGN_MSK __constant_cpu_to_le32(0x02) #define QOS_PARAM_FLG_TGN_MSK cpu_to_le32(0x02)
#define QOS_PARAM_FLG_TXOP_TYPE_MSK __constant_cpu_to_le32(0x10) #define QOS_PARAM_FLG_TXOP_TYPE_MSK cpu_to_le32(0x10)
/* Number of Access Categories (AC) (EDCA), queues 0..3 */ /* Number of Access Categories (AC) (EDCA), queues 0..3 */
#define AC_NUM 4 #define AC_NUM 4
...@@ -508,27 +514,27 @@ struct iwl3945_qosparam_cmd { ...@@ -508,27 +514,27 @@ struct iwl3945_qosparam_cmd {
#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/ #define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
#define IWL_INVALID_STATION 255 #define IWL_INVALID_STATION 255
#define STA_FLG_TX_RATE_MSK __constant_cpu_to_le32(1 << 2); #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2);
#define STA_FLG_PWR_SAVE_MSK __constant_cpu_to_le32(1 << 8); #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
/* Use in mode field. 1: modify existing entry, 0: add new station entry */ /* Use in mode field. 1: modify existing entry, 0: add new station entry */
#define STA_CONTROL_MODIFY_MSK 0x01 #define STA_CONTROL_MODIFY_MSK 0x01
/* key flags __le16*/ /* key flags __le16*/
#define STA_KEY_FLG_ENCRYPT_MSK __constant_cpu_to_le16(0x0007) #define STA_KEY_FLG_ENCRYPT_MSK cpu_to_le16(0x0007)
#define STA_KEY_FLG_NO_ENC __constant_cpu_to_le16(0x0000) #define STA_KEY_FLG_NO_ENC cpu_to_le16(0x0000)
#define STA_KEY_FLG_WEP __constant_cpu_to_le16(0x0001) #define STA_KEY_FLG_WEP cpu_to_le16(0x0001)
#define STA_KEY_FLG_CCMP __constant_cpu_to_le16(0x0002) #define STA_KEY_FLG_CCMP cpu_to_le16(0x0002)
#define STA_KEY_FLG_TKIP __constant_cpu_to_le16(0x0003) #define STA_KEY_FLG_TKIP cpu_to_le16(0x0003)
#define STA_KEY_FLG_KEYID_POS 8 #define STA_KEY_FLG_KEYID_POS 8
#define STA_KEY_FLG_INVALID __constant_cpu_to_le16(0x0800) #define STA_KEY_FLG_INVALID cpu_to_le16(0x0800)
/* wep key is either from global key (0) or from station info array (1) */ /* wep key is either from global key (0) or from station info array (1) */
#define STA_KEY_FLG_WEP_KEY_MAP_MSK __constant_cpu_to_le16(0x0008) #define STA_KEY_FLG_WEP_KEY_MAP_MSK cpu_to_le16(0x0008)
/* wep key in STA: 5-bytes (0) or 13-bytes (1) */ /* wep key in STA: 5-bytes (0) or 13-bytes (1) */
#define STA_KEY_FLG_KEY_SIZE_MSK __constant_cpu_to_le16(0x1000) #define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000)
#define STA_KEY_MULTICAST_MSK __constant_cpu_to_le16(0x4000) #define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000)
/* Flags indicate whether to modify vs. don't change various station params */ /* Flags indicate whether to modify vs. don't change various station params */
#define STA_MODIFY_KEY_MASK 0x01 #define STA_MODIFY_KEY_MASK 0x01
...@@ -666,14 +672,14 @@ struct iwl3945_rx_frame_hdr { ...@@ -666,14 +672,14 @@ struct iwl3945_rx_frame_hdr {
u8 payload[0]; u8 payload[0];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define RX_RES_STATUS_NO_CRC32_ERROR __constant_cpu_to_le32(1 << 0) #define RX_RES_STATUS_NO_CRC32_ERROR cpu_to_le32(1 << 0)
#define RX_RES_STATUS_NO_RXE_OVERFLOW __constant_cpu_to_le32(1 << 1) #define RX_RES_STATUS_NO_RXE_OVERFLOW cpu_to_le32(1 << 1)
#define RX_RES_PHY_FLAGS_BAND_24_MSK __constant_cpu_to_le16(1 << 0) #define RX_RES_PHY_FLAGS_BAND_24_MSK cpu_to_le16(1 << 0)
#define RX_RES_PHY_FLAGS_MOD_CCK_MSK __constant_cpu_to_le16(1 << 1) #define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK __constant_cpu_to_le16(1 << 2) #define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK __constant_cpu_to_le16(1 << 3) #define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
#define RX_RES_PHY_FLAGS_ANTENNA_MSK __constant_cpu_to_le16(0xf0) #define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0)
#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) #define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) #define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
...@@ -733,57 +739,57 @@ struct iwl3945_rx_frame { ...@@ -733,57 +739,57 @@ struct iwl3945_rx_frame {
/* 1: Use Request-To-Send protocol before this frame. /* 1: Use Request-To-Send protocol before this frame.
* Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */ * Mutually exclusive vs. TX_CMD_FLG_CTS_MSK. */
#define TX_CMD_FLG_RTS_MSK __constant_cpu_to_le32(1 << 1) #define TX_CMD_FLG_RTS_MSK cpu_to_le32(1 << 1)
/* 1: Transmit Clear-To-Send to self before this frame. /* 1: Transmit Clear-To-Send to self before this frame.
* Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames. * Driver should set this for AUTH/DEAUTH/ASSOC-REQ/REASSOC mgmnt frames.
* Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */ * Mutually exclusive vs. TX_CMD_FLG_RTS_MSK. */
#define TX_CMD_FLG_CTS_MSK __constant_cpu_to_le32(1 << 2) #define TX_CMD_FLG_CTS_MSK cpu_to_le32(1 << 2)
/* 1: Expect ACK from receiving station /* 1: Expect ACK from receiving station
* 0: Don't expect ACK (MAC header's duration field s/b 0) * 0: Don't expect ACK (MAC header's duration field s/b 0)
* Set this for unicast frames, but not broadcast/multicast. */ * Set this for unicast frames, but not broadcast/multicast. */
#define TX_CMD_FLG_ACK_MSK __constant_cpu_to_le32(1 << 3) #define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3)
/* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). /* 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD).
* Tx command's initial_rate_index indicates first rate to try; * Tx command's initial_rate_index indicates first rate to try;
* uCode walks through table for additional Tx attempts. * uCode walks through table for additional Tx attempts.
* 0: Use Tx rate/MCS from Tx command's rate_n_flags field. * 0: Use Tx rate/MCS from Tx command's rate_n_flags field.
* This rate will be used for all Tx attempts; it will not be scaled. */ * This rate will be used for all Tx attempts; it will not be scaled. */
#define TX_CMD_FLG_STA_RATE_MSK __constant_cpu_to_le32(1 << 4) #define TX_CMD_FLG_STA_RATE_MSK cpu_to_le32(1 << 4)
/* 1: Expect immediate block-ack. /* 1: Expect immediate block-ack.
* Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */ * Set when Txing a block-ack request frame. Also set TX_CMD_FLG_ACK_MSK. */
#define TX_CMD_FLG_IMM_BA_RSP_MASK __constant_cpu_to_le32(1 << 6) #define TX_CMD_FLG_IMM_BA_RSP_MASK cpu_to_le32(1 << 6)
/* 1: Frame requires full Tx-Op protection. /* 1: Frame requires full Tx-Op protection.
* Set this if either RTS or CTS Tx Flag gets set. */ * Set this if either RTS or CTS Tx Flag gets set. */
#define TX_CMD_FLG_FULL_TXOP_PROT_MSK __constant_cpu_to_le32(1 << 7) #define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7)
/* Tx antenna selection field; used only for 3945, reserved (0) for 4965. /* Tx antenna selection field; used only for 3945, reserved (0) for 4965.
* Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */
#define TX_CMD_FLG_ANT_SEL_MSK __constant_cpu_to_le32(0xf00) #define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00)
#define TX_CMD_FLG_ANT_A_MSK __constant_cpu_to_le32(1 << 8) #define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8)
#define TX_CMD_FLG_ANT_B_MSK __constant_cpu_to_le32(1 << 9) #define TX_CMD_FLG_ANT_B_MSK cpu_to_le32(1 << 9)
/* 1: Ignore Bluetooth priority for this frame. /* 1: Ignore Bluetooth priority for this frame.
* 0: Delay Tx until Bluetooth device is done (normal usage). */ * 0: Delay Tx until Bluetooth device is done (normal usage). */
#define TX_CMD_FLG_BT_DIS_MSK __constant_cpu_to_le32(1 << 12) #define TX_CMD_FLG_BT_DIS_MSK cpu_to_le32(1 << 12)
/* 1: uCode overrides sequence control field in MAC header. /* 1: uCode overrides sequence control field in MAC header.
* 0: Driver provides sequence control field in MAC header. * 0: Driver provides sequence control field in MAC header.
* Set this for management frames, non-QOS data frames, non-unicast frames, * Set this for management frames, non-QOS data frames, non-unicast frames,
* and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */ * and also in Tx command embedded in REPLY_SCAN_CMD for active scans. */
#define TX_CMD_FLG_SEQ_CTL_MSK __constant_cpu_to_le32(1 << 13) #define TX_CMD_FLG_SEQ_CTL_MSK cpu_to_le32(1 << 13)
/* 1: This frame is non-last MPDU; more fragments are coming. /* 1: This frame is non-last MPDU; more fragments are coming.
* 0: Last fragment, or not using fragmentation. */ * 0: Last fragment, or not using fragmentation. */
#define TX_CMD_FLG_MORE_FRAG_MSK __constant_cpu_to_le32(1 << 14) #define TX_CMD_FLG_MORE_FRAG_MSK cpu_to_le32(1 << 14)
/* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame. /* 1: uCode calculates and inserts Timestamp Function (TSF) in outgoing frame.
* 0: No TSF required in outgoing frame. * 0: No TSF required in outgoing frame.
* Set this for transmitting beacons and probe responses. */ * Set this for transmitting beacons and probe responses. */
#define TX_CMD_FLG_TSF_MSK __constant_cpu_to_le32(1 << 16) #define TX_CMD_FLG_TSF_MSK cpu_to_le32(1 << 16)
/* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword /* 1: Driver inserted 2 bytes pad after the MAC header, for (required) dword
* alignment of frame's payload data field. * alignment of frame's payload data field.
...@@ -791,10 +797,10 @@ struct iwl3945_rx_frame { ...@@ -791,10 +797,10 @@ struct iwl3945_rx_frame {
* Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4 * Set this for MAC headers with 26 or 30 bytes, i.e. those with QOS or ADDR4
* field (but not both). Driver must align frame data (i.e. data following * field (but not both). Driver must align frame data (i.e. data following
* MAC header) to DWORD boundary. */ * MAC header) to DWORD boundary. */
#define TX_CMD_FLG_MH_PAD_MSK __constant_cpu_to_le32(1 << 20) #define TX_CMD_FLG_MH_PAD_MSK cpu_to_le32(1 << 20)
/* HCCA-AP - disable duration overwriting. */ /* HCCA-AP - disable duration overwriting. */
#define TX_CMD_FLG_DUR_MSK __constant_cpu_to_le32(1 << 25) #define TX_CMD_FLG_DUR_MSK cpu_to_le32(1 << 25)
/* /*
* TX command security control * TX command security control
...@@ -1158,9 +1164,9 @@ struct iwl3945_spectrum_notification { ...@@ -1158,9 +1164,9 @@ struct iwl3945_spectrum_notification {
*/ */
#define IWL_POWER_VEC_SIZE 5 #define IWL_POWER_VEC_SIZE 5
#define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK __constant_cpu_to_le32(1 << 0) #define IWL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le32(1 << 0)
#define IWL_POWER_SLEEP_OVER_DTIM_MSK __constant_cpu_to_le32(1 << 2) #define IWL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le32(1 << 2)
#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le32(1 << 3) #define IWL_POWER_PCI_PM_MSK cpu_to_le32(1 << 3)
struct iwl3945_powertable_cmd { struct iwl3945_powertable_cmd {
__le32 flags; __le32 flags;
__le32 rx_data_timeout; __le32 rx_data_timeout;
...@@ -1278,8 +1284,8 @@ struct iwl3945_ssid_ie { ...@@ -1278,8 +1284,8 @@ struct iwl3945_ssid_ie {
} __attribute__ ((packed)); } __attribute__ ((packed));
#define PROBE_OPTION_MAX 0x4 #define PROBE_OPTION_MAX 0x4
#define TX_CMD_LIFE_TIME_INFINITE __constant_cpu_to_le32(0xFFFFFFFF) #define TX_CMD_LIFE_TIME_INFINITE cpu_to_le32(0xFFFFFFFF)
#define IWL_GOOD_CRC_TH __constant_cpu_to_le16(1) #define IWL_GOOD_CRC_TH cpu_to_le16(1)
#define IWL_MAX_SCAN_SIZE 1024 #define IWL_MAX_SCAN_SIZE 1024
/* /*
...@@ -1379,7 +1385,7 @@ struct iwl3945_scan_cmd { ...@@ -1379,7 +1385,7 @@ struct iwl3945_scan_cmd {
} __attribute__ ((packed)); } __attribute__ ((packed));
/* Can abort will notify by complete notification with abort status. */ /* Can abort will notify by complete notification with abort status. */
#define CAN_ABORT_STATUS __constant_cpu_to_le32(0x1) #define CAN_ABORT_STATUS cpu_to_le32(0x1)
/* complete notification statuses */ /* complete notification statuses */
#define ABORT_STATUS 0x2 #define ABORT_STATUS 0x2
...@@ -1572,8 +1578,8 @@ struct statistics_general { ...@@ -1572,8 +1578,8 @@ struct statistics_general {
* STATISTICS_NOTIFICATIONs after received beacons (see below). This flag * STATISTICS_NOTIFICATIONs after received beacons (see below). This flag
* does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself. * does not affect the response to the REPLY_STATISTICS_CMD 0x9c itself.
*/ */
#define IWL_STATS_CONF_CLEAR_STATS __constant_cpu_to_le32(0x1) /* see above */ #define IWL_STATS_CONF_CLEAR_STATS cpu_to_le32(0x1) /* see above */
#define IWL_STATS_CONF_DISABLE_NOTIF __constant_cpu_to_le32(0x2)/* see above */ #define IWL_STATS_CONF_DISABLE_NOTIF cpu_to_le32(0x2)/* see above */
struct iwl3945_statistics_cmd { struct iwl3945_statistics_cmd {
__le32 configuration_flags; /* IWL_STATS_CONF_* */ __le32 configuration_flags; /* IWL_STATS_CONF_* */
} __attribute__ ((packed)); } __attribute__ ((packed));
...@@ -1593,8 +1599,8 @@ struct iwl3945_statistics_cmd { ...@@ -1593,8 +1599,8 @@ struct iwl3945_statistics_cmd {
* appropriately so that each notification contains statistics for only the * appropriately so that each notification contains statistics for only the
* one channel that has just been scanned. * one channel that has just been scanned.
*/ */
#define STATISTICS_REPLY_FLG_BAND_24G_MSK __constant_cpu_to_le32(0x2) #define STATISTICS_REPLY_FLG_BAND_24G_MSK cpu_to_le32(0x2)
#define STATISTICS_REPLY_FLG_FAT_MODE_MSK __constant_cpu_to_le32(0x8) #define STATISTICS_REPLY_FLG_FAT_MODE_MSK cpu_to_le32(0x8)
struct iwl3945_notif_statistics { struct iwl3945_notif_statistics {
__le32 flag; __le32 flag;
struct statistics_rx rx; struct statistics_rx rx;
......
...@@ -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;
}; };
......
...@@ -63,6 +63,9 @@ struct iwl3945_rs_sta { ...@@ -63,6 +63,9 @@ struct iwl3945_rs_sta {
u8 ibss_sta_added; u8 ibss_sta_added;
struct timer_list rate_scale_flush; struct timer_list rate_scale_flush;
struct iwl3945_rate_scale_data win[IWL_RATE_COUNT]; struct iwl3945_rate_scale_data win[IWL_RATE_COUNT];
#ifdef CONFIG_MAC80211_DEBUGFS
struct dentry *rs_sta_dbgfs_stats_table_file;
#endif
/* used to be in sta_info */ /* used to be in sta_info */
int last_txrate_idx; int last_txrate_idx;
...@@ -114,9 +117,11 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = { ...@@ -114,9 +117,11 @@ static struct iwl3945_tpt_entry iwl3945_tpt_table_g[] = {
}; };
#define IWL_RATE_MAX_WINDOW 62 #define IWL_RATE_MAX_WINDOW 62
#define IWL_RATE_FLUSH (3*HZ/10) #define IWL_RATE_FLUSH (3*HZ)
#define IWL_RATE_WIN_FLUSH (HZ/2) #define IWL_RATE_WIN_FLUSH (HZ/2)
#define IWL_RATE_HIGH_TH 11520 #define IWL_RATE_HIGH_TH 11520
#define IWL_SUCCESS_UP_TH 8960
#define IWL_SUCCESS_DOWN_TH 10880
#define IWL_RATE_MIN_FAILURE_TH 8 #define IWL_RATE_MIN_FAILURE_TH 8
#define IWL_RATE_MIN_SUCCESS_TH 8 #define IWL_RATE_MIN_SUCCESS_TH 8
#define IWL_RATE_DECREASE_TH 1920 #define IWL_RATE_DECREASE_TH 1920
...@@ -203,6 +208,7 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta) ...@@ -203,6 +208,7 @@ static int iwl3945_rate_scale_flush_windows(struct iwl3945_rs_sta *rs_sta)
#define IWL_RATE_FLUSH_MAX 5000 /* msec */ #define IWL_RATE_FLUSH_MAX 5000 /* msec */
#define IWL_RATE_FLUSH_MIN 50 /* msec */ #define IWL_RATE_FLUSH_MIN 50 /* msec */
#define IWL_AVERAGE_PACKETS 1500
static void iwl3945_bg_rate_scale_flush(unsigned long data) static void iwl3945_bg_rate_scale_flush(unsigned long data)
{ {
...@@ -217,8 +223,6 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) ...@@ -217,8 +223,6 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
spin_lock_irqsave(&rs_sta->lock, flags); spin_lock_irqsave(&rs_sta->lock, flags);
rs_sta->flush_pending = 0;
/* Number of packets Rx'd since last time this timer ran */ /* Number of packets Rx'd since last time this timer ran */
packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1;
...@@ -227,7 +231,6 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) ...@@ -227,7 +231,6 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
if (unflushed) { if (unflushed) {
duration = duration =
jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); jiffies_to_msecs(jiffies - rs_sta->last_partial_flush);
/* duration = jiffies_to_msecs(rs_sta->flush_time); */
IWL_DEBUG_RATE("Tx'd %d packets in %dms\n", IWL_DEBUG_RATE("Tx'd %d packets in %dms\n",
packet_count, duration); packet_count, duration);
...@@ -239,9 +242,11 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) ...@@ -239,9 +242,11 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
pps = 0; pps = 0;
if (pps) { if (pps) {
duration = IWL_RATE_FLUSH_MAX / pps; duration = (IWL_AVERAGE_PACKETS * 1000) / pps;
if (duration < IWL_RATE_FLUSH_MIN) if (duration < IWL_RATE_FLUSH_MIN)
duration = IWL_RATE_FLUSH_MIN; duration = IWL_RATE_FLUSH_MIN;
else if (duration > IWL_RATE_FLUSH_MAX)
duration = IWL_RATE_FLUSH_MAX;
} else } else
duration = IWL_RATE_FLUSH_MAX; duration = IWL_RATE_FLUSH_MAX;
...@@ -254,8 +259,10 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) ...@@ -254,8 +259,10 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
rs_sta->flush_time); rs_sta->flush_time);
rs_sta->last_partial_flush = jiffies; rs_sta->last_partial_flush = jiffies;
} else {
rs_sta->flush_time = IWL_RATE_FLUSH;
rs_sta->flush_pending = 0;
} }
/* If there weren't any unflushed entries, we don't schedule the timer /* If there weren't any unflushed entries, we don't schedule the timer
* to run again */ * to run again */
...@@ -275,17 +282,18 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data) ...@@ -275,17 +282,18 @@ static void iwl3945_bg_rate_scale_flush(unsigned long data)
*/ */
static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
struct iwl3945_rate_scale_data *window, struct iwl3945_rate_scale_data *window,
int success, int retries) int success, int retries, int index)
{ {
unsigned long flags; unsigned long flags;
s32 fail_count;
if (!retries) { if (!retries) {
IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n"); IWL_DEBUG_RATE("leave: retries == 0 -- should be at least 1\n");
return; return;
} }
spin_lock_irqsave(&rs_sta->lock, flags);
while (retries--) { while (retries--) {
spin_lock_irqsave(&rs_sta->lock, flags);
/* If we have filled up the window then subtract one from the /* If we have filled up the window then subtract one from the
* success counter if the high-bit is counting toward * success counter if the high-bit is counting toward
...@@ -313,8 +321,18 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, ...@@ -313,8 +321,18 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
/* Tag this window as having been updated */ /* Tag this window as having been updated */
window->stamp = jiffies; window->stamp = jiffies;
spin_unlock_irqrestore(&rs_sta->lock, flags);
} }
fail_count = window->counter - window->success_counter;
if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
(window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
window->average_tpt = ((window->success_ratio *
rs_sta->expected_tpt[index] + 64) / 128);
else
window->average_tpt = IWL_INV_TPT;
spin_unlock_irqrestore(&rs_sta->lock, flags);
} }
static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband, static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
...@@ -426,19 +444,16 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband ...@@ -426,19 +444,16 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb) struct sk_buff *skb)
{ {
u8 retries = 0, current_count; s8 retries = 0, current_count;
int scale_rate_index, first_index, last_index; int scale_rate_index, first_index, last_index;
unsigned long flags; unsigned long flags;
struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
struct iwl3945_rs_sta *rs_sta = priv_sta; struct iwl3945_rs_sta *rs_sta = priv_sta;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
int i;
IWL_DEBUG_RATE("enter\n"); IWL_DEBUG_RATE("enter\n");
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) retries = info->status.rates[0].count;
retries += info->status.rates[i].count;
retries--;
first_index = sband->bitrates[info->status.rates[0].idx].hw_value; first_index = sband->bitrates[info->status.rates[0].idx].hw_value;
if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
...@@ -466,9 +481,9 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband ...@@ -466,9 +481,9 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
* at which the frame was finally transmitted (or failed if no * at which the frame was finally transmitted (or failed if no
* ACK) * ACK)
*/ */
while (retries > 0) { while (retries > 1) {
if (retries < priv->retry_rate) { if ((retries - 1) < priv->retry_rate) {
current_count = retries; current_count = (retries - 1);
last_index = scale_rate_index; last_index = scale_rate_index;
} else { } else {
current_count = priv->retry_rate; current_count = priv->retry_rate;
...@@ -480,15 +495,13 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband ...@@ -480,15 +495,13 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
* as was used for it (per current_count) */ * as was used for it (per current_count) */
iwl3945_collect_tx_data(rs_sta, iwl3945_collect_tx_data(rs_sta,
&rs_sta->win[scale_rate_index], &rs_sta->win[scale_rate_index],
0, current_count); 0, current_count, scale_rate_index);
IWL_DEBUG_RATE("Update rate %d for %d retries.\n", IWL_DEBUG_RATE("Update rate %d for %d retries.\n",
scale_rate_index, current_count); scale_rate_index, current_count);
retries -= current_count; retries -= current_count;
if (retries) scale_rate_index = last_index;
scale_rate_index =
iwl3945_rs_next_rate(priv, scale_rate_index);
} }
...@@ -499,7 +512,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband ...@@ -499,7 +512,7 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
"success" : "failure"); "success" : "failure");
iwl3945_collect_tx_data(rs_sta, iwl3945_collect_tx_data(rs_sta,
&rs_sta->win[last_index], &rs_sta->win[last_index],
info->flags & IEEE80211_TX_STAT_ACK, 1); info->flags & IEEE80211_TX_STAT_ACK, 1, last_index);
/* We updated the rate scale window -- if its been more than /* We updated the rate scale window -- if its been more than
* flush_time since the last run, schedule the flush * flush_time since the last run, schedule the flush
...@@ -507,9 +520,10 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband ...@@ -507,9 +520,10 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
spin_lock_irqsave(&rs_sta->lock, flags); spin_lock_irqsave(&rs_sta->lock, flags);
if (!rs_sta->flush_pending && if (!rs_sta->flush_pending &&
time_after(jiffies, rs_sta->last_partial_flush + time_after(jiffies, rs_sta->last_flush +
rs_sta->flush_time)) { rs_sta->flush_time)) {
rs_sta->last_partial_flush = jiffies;
rs_sta->flush_pending = 1; rs_sta->flush_pending = 1;
mod_timer(&rs_sta->rate_scale_flush, mod_timer(&rs_sta->rate_scale_flush,
jiffies + rs_sta->flush_time); jiffies + rs_sta->flush_time);
...@@ -657,8 +671,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -657,8 +671,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
spin_lock_irqsave(&rs_sta->lock, flags); spin_lock_irqsave(&rs_sta->lock, flags);
/* for recent assoc, choose best rate regarding
* to rssi value
*/
if (rs_sta->start_rate != IWL_RATE_INVALID) { if (rs_sta->start_rate != IWL_RATE_INVALID) {
index = rs_sta->start_rate; if (rs_sta->start_rate < index &&
(rate_mask & (1 << rs_sta->start_rate)))
index = rs_sta->start_rate;
rs_sta->start_rate = IWL_RATE_INVALID; rs_sta->start_rate = IWL_RATE_INVALID;
} }
...@@ -668,7 +687,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -668,7 +687,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) && if (((fail_count <= IWL_RATE_MIN_FAILURE_TH) &&
(window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) { (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))) {
window->average_tpt = IWL_INV_TPT;
spin_unlock_irqrestore(&rs_sta->lock, flags); spin_unlock_irqrestore(&rs_sta->lock, flags);
IWL_DEBUG_RATE("Invalid average_tpt on rate %d: " IWL_DEBUG_RATE("Invalid average_tpt on rate %d: "
...@@ -682,8 +700,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -682,8 +700,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
} }
window->average_tpt = ((window->success_ratio *
rs_sta->expected_tpt[index] + 64) / 128);
current_tpt = window->average_tpt; current_tpt = window->average_tpt;
high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask, high_low = iwl3945_get_adjacent_rate(rs_sta, index, rate_mask,
...@@ -731,13 +747,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -731,13 +747,15 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
} }
} }
if ((window->success_ratio > IWL_RATE_HIGH_TH) || if (scale_action == -1) {
(current_tpt > window->average_tpt)) { if (window->success_ratio > IWL_SUCCESS_DOWN_TH)
IWL_DEBUG_RATE("No action -- success_ratio [%d] > HIGH_TH or " scale_action = 0;
"current_tpt [%d] > average_tpt [%d]\n", } else if (scale_action == 1) {
window->success_ratio, if (window->success_ratio < IWL_SUCCESS_UP_TH) {
current_tpt, window->average_tpt); IWL_DEBUG_RATE("No action -- success_ratio [%d] < "
scale_action = 0; "SUCCESS UP\n", window->success_ratio);
scale_action = 0;
}
} }
switch (scale_action) { switch (scale_action) {
...@@ -772,6 +790,60 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, ...@@ -772,6 +790,60 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
IWL_DEBUG_RATE("leave: %d\n", index); IWL_DEBUG_RATE("leave: %d\n", index);
} }
#ifdef CONFIG_MAC80211_DEBUGFS
static int iwl3945_open_file_generic(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
static ssize_t iwl3945_sta_dbgfs_stats_table_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
char buff[1024];
int desc = 0;
int j;
struct iwl3945_rs_sta *lq_sta = file->private_data;
desc += sprintf(buff + desc, "tx packets=%d last rate index=%d\n"
"rate=0x%X flush time %d\n",
lq_sta->tx_packets,
lq_sta->last_txrate_idx,
lq_sta->start_rate, jiffies_to_msecs(lq_sta->flush_time));
for (j = 0; j < IWL_RATE_COUNT; j++) {
desc += sprintf(buff+desc,
"counter=%d success=%d %%=%d\n",
lq_sta->win[j].counter,
lq_sta->win[j].success_counter,
lq_sta->win[j].success_ratio);
}
return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
}
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.read = iwl3945_sta_dbgfs_stats_table_read,
.open = iwl3945_open_file_generic,
};
static void iwl3945_add_debugfs(void *priv, void *priv_sta,
struct dentry *dir)
{
struct iwl3945_rs_sta *lq_sta = priv_sta;
lq_sta->rs_sta_dbgfs_stats_table_file =
debugfs_create_file("rate_stats_table", 0600, dir,
lq_sta, &rs_sta_dbgfs_stats_table_ops);
}
static void iwl3945_remove_debugfs(void *priv, void *priv_sta)
{
struct iwl3945_rs_sta *lq_sta = priv_sta;
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
}
#endif
static struct rate_control_ops rs_ops = { static struct rate_control_ops rs_ops = {
.module = NULL, .module = NULL,
.name = RS_NAME, .name = RS_NAME,
...@@ -782,6 +854,11 @@ static struct rate_control_ops rs_ops = { ...@@ -782,6 +854,11 @@ static struct rate_control_ops rs_ops = {
.free = rs_free, .free = rs_free,
.alloc_sta = rs_alloc_sta, .alloc_sta = rs_alloc_sta,
.free_sta = rs_free_sta, .free_sta = rs_free_sta,
#ifdef CONFIG_MAC80211_DEBUGFS
.add_sta_debugfs = iwl3945_add_debugfs,
.remove_sta_debugfs = iwl3945_remove_debugfs,
#endif
}; };
void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
......
...@@ -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,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -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
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册