You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (78 commits) AX.25: Fix sysctl registration if !CONFIG_AX25_DAMA_SLAVE pktgen: mac count pktgen: random flow bridge: Eliminate unnecessary forward delay bridge: fix compile warning in net/bridge/br_netfilter.c ipv4: remove unused field in struct flowi (include/net/flow.h). tg3: Fix 'scheduling while atomic' errors net: Kill plain NET_XMIT_BYPASS. net_sched: Add qdisc __NET_XMIT_BYPASS flag net_sched: Add qdisc __NET_XMIT_STOLEN flag iwl3945: fix merge mistake for packet injection iwlwifi: grap nic access before accessing periphery registers iwlwifi: decrement rx skb counter in scan abort handler iwlwifi: fix unhandled interrupt when HW rfkill is on iwlwifi: implement iwl5000_calc_rssi iwlwifi: memory allocation optimization iwlwifi: HW bug fixes p54: Fix potential concurrent access to private data rt2x00: Disable link tuning in rt2500usb iwlwifi: Don't use buffer allocated on the stack for led names ...
This commit is contained in:
+4
-16
@@ -7687,21 +7687,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
|
||||
*/
|
||||
static int tg3_init_hw(struct tg3 *tp, int reset_phy)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Force the chip into D0. */
|
||||
err = tg3_set_power_state(tp, PCI_D0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
tg3_switch_clocks(tp);
|
||||
|
||||
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
|
||||
err = tg3_reset_hw(tp, reset_phy);
|
||||
|
||||
out:
|
||||
return err;
|
||||
return tg3_reset_hw(tp, reset_phy);
|
||||
}
|
||||
|
||||
#define TG3_STAT_ADD32(PSTAT, REG) \
|
||||
@@ -8016,13 +8006,11 @@ static int tg3_open(struct net_device *dev)
|
||||
|
||||
netif_carrier_off(tp->dev);
|
||||
|
||||
tg3_full_lock(tp, 0);
|
||||
|
||||
err = tg3_set_power_state(tp, PCI_D0);
|
||||
if (err) {
|
||||
tg3_full_unlock(tp);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
tg3_full_lock(tp, 0);
|
||||
|
||||
tg3_disable_ints(tp);
|
||||
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
|
||||
|
||||
@@ -649,6 +649,7 @@ config RTL8187
|
||||
Trendnet TEW-424UB
|
||||
ASUS P5B Deluxe
|
||||
Toshiba Satellite Pro series of laptops
|
||||
Asus Wireless Link
|
||||
|
||||
Thanks to Realtek for their support!
|
||||
|
||||
|
||||
@@ -186,11 +186,13 @@ struct ath5k_srev_name {
|
||||
#define AR5K_SREV_RAD_2111 0x20
|
||||
#define AR5K_SREV_RAD_5112 0x30
|
||||
#define AR5K_SREV_RAD_5112A 0x35
|
||||
#define AR5K_SREV_RAD_5112B 0x36
|
||||
#define AR5K_SREV_RAD_2112 0x40
|
||||
#define AR5K_SREV_RAD_2112A 0x45
|
||||
#define AR5K_SREV_RAD_SC0 0x56 /* Found on 2413/2414 */
|
||||
#define AR5K_SREV_RAD_SC1 0x63 /* Found on 5413/5414 */
|
||||
#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424-5/5424 */
|
||||
#define AR5K_SREV_RAD_2112B 0x46
|
||||
#define AR5K_SREV_RAD_SC0 0x50 /* Found on 2413/2414 */
|
||||
#define AR5K_SREV_RAD_SC1 0x60 /* Found on 5413/5414 */
|
||||
#define AR5K_SREV_RAD_SC2 0xa0 /* Found on 2424-5/5424 */
|
||||
#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */
|
||||
|
||||
/* IEEE defs */
|
||||
|
||||
@@ -2170,6 +2170,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
|
||||
|
||||
ath5k_hw_set_intr(ah, 0);
|
||||
sc->bmisscount = 0;
|
||||
sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
|
||||
|
||||
if (sc->opmode == IEEE80211_IF_TYPE_STA) {
|
||||
sc->imask |= AR5K_INT_BMISS;
|
||||
|
||||
@@ -129,7 +129,7 @@ static struct reg regs[] = {
|
||||
REG_STRUCT_INIT(AR5K_CPC1),
|
||||
REG_STRUCT_INIT(AR5K_CPC2),
|
||||
REG_STRUCT_INIT(AR5K_CPC3),
|
||||
REG_STRUCT_INIT(AR5K_CPCORN),
|
||||
REG_STRUCT_INIT(AR5K_CPCOVF),
|
||||
REG_STRUCT_INIT(AR5K_RESET_CTL),
|
||||
REG_STRUCT_INIT(AR5K_SLEEP_CTL),
|
||||
REG_STRUCT_INIT(AR5K_INTPEND),
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
|
||||
struct ath5k_softc;
|
||||
struct ath5k_hw;
|
||||
struct ieee80211_hw_mode;
|
||||
struct sk_buff;
|
||||
struct ath5k_buf;
|
||||
|
||||
|
||||
+158
-99
@@ -139,6 +139,8 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
|
||||
for (c = 0; c < 2; c++) {
|
||||
|
||||
cur_reg = regs[c];
|
||||
|
||||
/* Save previous value */
|
||||
init_val = ath5k_hw_reg_read(ah, cur_reg);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
@@ -170,6 +172,10 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
|
||||
var_pattern = 0x003b080f;
|
||||
ath5k_hw_reg_write(ah, var_pattern, cur_reg);
|
||||
}
|
||||
|
||||
/* Restore previous value */
|
||||
ath5k_hw_reg_write(ah, init_val, cur_reg);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -287,67 +293,42 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
|
||||
/* Identify the radio chip*/
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
ah->ah_radio = AR5K_RF5110;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
|
||||
ah->ah_radio = AR5K_RF5111;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
|
||||
|
||||
ah->ah_radio = AR5K_RF5112;
|
||||
|
||||
if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
|
||||
} else {
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
|
||||
}
|
||||
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
|
||||
ah->ah_radio = AR5K_RF2413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
|
||||
ah->ah_radio = AR5K_RF5413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
|
||||
|
||||
/* AR5424 */
|
||||
if (srev >= AR5K_SREV_VER_AR5424) {
|
||||
ah->ah_radio = AR5K_RF5413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
|
||||
/* AR2424 */
|
||||
} else {
|
||||
ah->ah_radio = AR5K_RF2413; /* For testing */
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register returns 0x4 for radio revision
|
||||
* Register returns 0x0/0x04 for radio revision
|
||||
* so ath5k_hw_radio_revision doesn't parse the value
|
||||
* correctly. For now we are based on mac's srev to
|
||||
* identify RF2425 radio.
|
||||
*/
|
||||
} else if (srev == AR5K_SREV_VER_AR2425) {
|
||||
ah->ah_radio = AR5K_RF2425;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
|
||||
ah->ah_radio = AR5K_RF5111;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
|
||||
ah->ah_radio = AR5K_RF5112;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
|
||||
ah->ah_radio = AR5K_RF2413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
|
||||
ah->ah_radio = AR5K_RF5413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
|
||||
/* AR5424 */
|
||||
if (srev >= AR5K_SREV_VER_AR5424) {
|
||||
ah->ah_radio = AR5K_RF5413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
|
||||
/* AR2424 */
|
||||
} else {
|
||||
ah->ah_radio = AR5K_RF2413; /* For testing */
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
|
||||
}
|
||||
}
|
||||
|
||||
ah->ah_phy = AR5K_PHY(0);
|
||||
|
||||
/*
|
||||
* Identify AR5212-based PCI-E cards
|
||||
* And write some initial settings.
|
||||
*
|
||||
* (doing a "strings" on ndis driver
|
||||
* -ar5211.sys- reveals the following
|
||||
* pci-e related functions:
|
||||
*
|
||||
* pcieClockReq
|
||||
* pcieRxErrNotify
|
||||
* pcieL1SKPEnable
|
||||
* pcieAspm
|
||||
* pcieDisableAspmOnRfWake
|
||||
* pciePowerSaveEnable
|
||||
*
|
||||
* I guess these point to ClockReq but
|
||||
* i'm not sure.)
|
||||
* Write PCI-E power save settings
|
||||
*/
|
||||
if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
|
||||
ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
|
||||
@@ -369,10 +350,15 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
/* Write AR5K_PCICFG_UNK on 2112B and later chips */
|
||||
if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B ||
|
||||
srev > AR5K_SREV_VER_AR2413) {
|
||||
ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get card capabilities, values, ...
|
||||
*/
|
||||
|
||||
ret = ath5k_eeprom_init(ah);
|
||||
if (ret) {
|
||||
ATH5K_ERR(sc, "unable to init EEPROM\n");
|
||||
@@ -843,27 +829,41 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
* Write some more initial register settings
|
||||
*/
|
||||
if (ah->ah_version == AR5K_AR5212) {
|
||||
ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11));
|
||||
ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
|
||||
|
||||
if (channel->hw_value == CHANNEL_G)
|
||||
if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
|
||||
ath5k_hw_reg_write(ah, 0x00f80d80,
|
||||
AR5K_PHY(83));
|
||||
0x994c);
|
||||
else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
|
||||
ath5k_hw_reg_write(ah, 0x00380140,
|
||||
AR5K_PHY(83));
|
||||
0x994c);
|
||||
else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
|
||||
ath5k_hw_reg_write(ah, 0x00fc0ec0,
|
||||
AR5K_PHY(83));
|
||||
0x994c);
|
||||
else /* 2425 */
|
||||
ath5k_hw_reg_write(ah, 0x00fc0fc0,
|
||||
AR5K_PHY(83));
|
||||
0x994c);
|
||||
else
|
||||
ath5k_hw_reg_write(ah, 0x00000000,
|
||||
AR5K_PHY(83));
|
||||
ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
|
||||
|
||||
ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
|
||||
ath5k_hw_reg_write(ah, 0x0000000f, 0x8060);
|
||||
/* Some bits are disabled here, we know nothing about
|
||||
* register 0xa228 yet, most of the times this ends up
|
||||
* with a value 0x9b5 -haven't seen any dump with
|
||||
* a different value- */
|
||||
/* Got this from decompiling binary HAL */
|
||||
data = ath5k_hw_reg_read(ah, 0xa228);
|
||||
data &= 0xfffffdff;
|
||||
ath5k_hw_reg_write(ah, data, 0xa228);
|
||||
|
||||
data = ath5k_hw_reg_read(ah, 0xa228);
|
||||
data &= 0xfffe03ff;
|
||||
ath5k_hw_reg_write(ah, data, 0xa228);
|
||||
data = 0;
|
||||
|
||||
/* Just write 0x9b5 ? */
|
||||
/* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
|
||||
ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
|
||||
ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
|
||||
ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
|
||||
}
|
||||
@@ -879,6 +879,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
else
|
||||
data = 0xffb80d20;
|
||||
ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -898,7 +899,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
|
||||
/*
|
||||
* Write RF registers
|
||||
* TODO:Does this work on 5211 (5111) ?
|
||||
*/
|
||||
ret = ath5k_hw_rfregs(ah, channel, mode);
|
||||
if (ret)
|
||||
@@ -935,7 +935,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
return ret;
|
||||
|
||||
/* Set antenna mode */
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x44),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
|
||||
ah->ah_antenna[ee_mode][0], 0xfffffc06);
|
||||
|
||||
/*
|
||||
@@ -965,15 +965,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
|
||||
AR5K_PHY(0x5a));
|
||||
AR5K_PHY_NFTHRES);
|
||||
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x11),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
|
||||
(ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
|
||||
0xffffc07f);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x12),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
|
||||
(ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
|
||||
0xfffc0fff);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x14),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
|
||||
(ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
|
||||
((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
|
||||
0xffff0000);
|
||||
@@ -982,13 +982,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
(ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
|
||||
(ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
|
||||
(ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
|
||||
(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY(0x0d));
|
||||
(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
|
||||
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x0a),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
|
||||
ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x19),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
|
||||
(ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x49), 4, 0xffffff01);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
|
||||
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
|
||||
AR5K_PHY_IQ_CORR_ENABLE |
|
||||
@@ -1063,7 +1063,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
|
||||
|
||||
/*
|
||||
* 5111/5112 Specific
|
||||
* On 5211+ read activation -> rx delay
|
||||
* and use it.
|
||||
*/
|
||||
if (ah->ah_version != AR5K_AR5210) {
|
||||
data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
|
||||
@@ -1071,32 +1072,45 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
data = (channel->hw_value & CHANNEL_CCK) ?
|
||||
((data << 2) / 22) : (data / 10);
|
||||
|
||||
udelay(100 + data);
|
||||
udelay(100 + (2 * data));
|
||||
data = 0;
|
||||
} else {
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable calibration and wait until completion
|
||||
* Perform ADC test (?)
|
||||
*/
|
||||
data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
|
||||
for (i = 0; i <= 20; i++) {
|
||||
if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
|
||||
break;
|
||||
udelay(200);
|
||||
}
|
||||
ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
|
||||
data = 0;
|
||||
|
||||
/*
|
||||
* Start automatic gain calibration
|
||||
*
|
||||
* During AGC calibration RX path is re-routed to
|
||||
* a signal detector so we don't receive anything.
|
||||
*
|
||||
* This method is used to calibrate some static offsets
|
||||
* used together with on-the fly I/Q calibration (the
|
||||
* one performed via ath5k_hw_phy_calibrate), that doesn't
|
||||
* interrupt rx path.
|
||||
*
|
||||
* If we are in a noisy environment AGC calibration may time
|
||||
* out.
|
||||
*/
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_CAL);
|
||||
|
||||
if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_CAL, 0, false)) {
|
||||
ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
|
||||
channel->center_freq);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* At the same time start I/Q calibration for QAM constellation
|
||||
* -no need for CCK- */
|
||||
ah->ah_calibration = false;
|
||||
|
||||
/* A and G modes can use QAM modulation which requires enabling
|
||||
* I and Q calibration. Don't bother in B mode. */
|
||||
if (!(mode == AR5K_MODE_11B)) {
|
||||
ah->ah_calibration = true;
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
|
||||
@@ -1105,6 +1119,30 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
AR5K_PHY_IQ_RUN);
|
||||
}
|
||||
|
||||
/* Wait for gain calibration to finish (we check for I/Q calibration
|
||||
* during ath5k_phy_calibrate) */
|
||||
if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_CAL, 0, false)) {
|
||||
ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
|
||||
channel->center_freq);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start noise floor calibration
|
||||
*
|
||||
* If we run NF calibration before AGC, it always times out.
|
||||
* Binary HAL starts NF and AGC calibration at the same time
|
||||
* and only waits for AGC to finish. I believe that's wrong because
|
||||
* during NF calibration, rx path is also routed to a detector, so if
|
||||
* it doesn't finish we won't have RX.
|
||||
*
|
||||
* XXX: Find an interval that's OK for all cards...
|
||||
*/
|
||||
ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Reset queues and start beacon timers at the end of the reset routine
|
||||
*/
|
||||
@@ -1154,6 +1192,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
|
||||
ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
|
||||
|
||||
data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
|
||||
data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
|
||||
0x00000f80 : 0x00001380 ;
|
||||
ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
if (ah->ah_version == AR5K_AR5212) {
|
||||
@@ -1226,7 +1270,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
|
||||
bool set_chip, u16 sleep_duration)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 staid;
|
||||
u32 staid, data;
|
||||
|
||||
ATH5K_TRACE(ah->ah_sc);
|
||||
staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
|
||||
@@ -1238,7 +1282,8 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
|
||||
case AR5K_PM_NETWORK_SLEEP:
|
||||
if (set_chip)
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_SLEEP_CTL_SLE | sleep_duration,
|
||||
AR5K_SLEEP_CTL_SLE_ALLOW |
|
||||
sleep_duration,
|
||||
AR5K_SLEEP_CTL);
|
||||
|
||||
staid |= AR5K_STA_ID1_PWR_SV;
|
||||
@@ -1253,13 +1298,24 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
|
||||
break;
|
||||
|
||||
case AR5K_PM_AWAKE:
|
||||
|
||||
staid &= ~AR5K_STA_ID1_PWR_SV;
|
||||
|
||||
if (!set_chip)
|
||||
goto commit;
|
||||
|
||||
ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
|
||||
AR5K_SLEEP_CTL);
|
||||
/* Preserve sleep duration */
|
||||
data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
|
||||
if( data & 0xffc00000 ){
|
||||
data = 0;
|
||||
} else {
|
||||
data = data & 0xfffcffff;
|
||||
}
|
||||
|
||||
for (i = 5000; i > 0; i--) {
|
||||
ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
|
||||
udelay(15);
|
||||
|
||||
for (i = 50; i > 0; i--) {
|
||||
/* Check if the chip did wake up */
|
||||
if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
|
||||
AR5K_PCICFG_SPWR_DN) == 0)
|
||||
@@ -1267,15 +1323,13 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
|
||||
|
||||
/* Wait a bit and retry */
|
||||
udelay(200);
|
||||
ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
|
||||
AR5K_SLEEP_CTL);
|
||||
ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
|
||||
}
|
||||
|
||||
/* Fail if the chip didn't wake up */
|
||||
if (i <= 0)
|
||||
return -EIO;
|
||||
|
||||
staid &= ~AR5K_STA_ID1_PWR_SV;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1304,6 +1358,7 @@ void ath5k_hw_start_rx(struct ath5k_hw *ah)
|
||||
{
|
||||
ATH5K_TRACE(ah->ah_sc);
|
||||
ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
|
||||
ath5k_hw_reg_read(ah, AR5K_CR);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1390,6 +1445,7 @@ int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue)
|
||||
}
|
||||
/* Start queue */
|
||||
ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
|
||||
ath5k_hw_reg_read(ah, AR5K_CR);
|
||||
} else {
|
||||
/* Return if queue is disabled */
|
||||
if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
|
||||
@@ -1687,6 +1743,7 @@ enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
|
||||
* (they will be re-enabled afterwards).
|
||||
*/
|
||||
ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
|
||||
ath5k_hw_reg_read(ah, AR5K_IER);
|
||||
|
||||
old_mask = ah->ah_imr;
|
||||
|
||||
@@ -3363,11 +3420,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
|
||||
AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
|
||||
/* Set PHY register 0x9844 (??) */
|
||||
/* Set AR5K_PHY_SETTLING */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 :
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C,
|
||||
AR5K_PHY(17));
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
|
||||
| 0x38 :
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
|
||||
| 0x1C,
|
||||
AR5K_PHY_SETTLING);
|
||||
/* Set Frame Control Register */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
(AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
|
||||
@@ -3488,7 +3547,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
|
||||
AR5K_REG_ENABLE_BITS(ah,
|
||||
AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_TXE);
|
||||
AR5K_QCU_MISC_RDY_VEOL_POLICY);
|
||||
}
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
|
||||
|
||||
@@ -489,7 +489,7 @@ static const struct ath5k_ini ar5212_ini[] = {
|
||||
{ AR5K_QUEUE_TXDP(9), 0x00000000 },
|
||||
{ AR5K_DCU_FP, 0x00000000 },
|
||||
{ AR5K_DCU_TXP, 0x00000000 },
|
||||
{ AR5K_DCU_TX_FILTER, 0x00000000 },
|
||||
{ AR5K_DCU_TX_FILTER_0_BASE, 0x00000000 },
|
||||
/* Unknown table */
|
||||
{ 0x1078, 0x00000000 },
|
||||
{ 0x10b8, 0x00000000 },
|
||||
@@ -679,7 +679,7 @@ static const struct ath5k_ini ar5212_ini[] = {
|
||||
{ AR5K_PHY(645), 0x00106c10 },
|
||||
{ AR5K_PHY(646), 0x009c4060 },
|
||||
{ AR5K_PHY(647), 0x1483800a },
|
||||
/* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413 */
|
||||
/* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413/2425 */
|
||||
{ AR5K_PHY(648), 0x01831061 },
|
||||
{ AR5K_PHY(649), 0x00000400 },
|
||||
/*{ AR5K_PHY(650), 0x000001b5 },*/
|
||||
|
||||
@@ -1020,6 +1020,74 @@ static const struct ath5k_ini_rfgain rfgain_2413[] = {
|
||||
{ AR5K_RF_GAIN(63), { 0x000000f9 } },
|
||||
};
|
||||
|
||||
/* Initial RF Gain settings for RF2425 */
|
||||
static const struct ath5k_ini_rfgain rfgain_2425[] = {
|
||||
{ AR5K_RF_GAIN(0), { 0x00000000 } },
|
||||
{ AR5K_RF_GAIN(1), { 0x00000040 } },
|
||||
{ AR5K_RF_GAIN(2), { 0x00000080 } },
|
||||
{ AR5K_RF_GAIN(3), { 0x00000181 } },
|
||||
{ AR5K_RF_GAIN(4), { 0x000001c1 } },
|
||||
{ AR5K_RF_GAIN(5), { 0x00000001 } },
|
||||
{ AR5K_RF_GAIN(6), { 0x00000041 } },
|
||||
{ AR5K_RF_GAIN(7), { 0x00000081 } },
|
||||
{ AR5K_RF_GAIN(8), { 0x00000188 } },
|
||||
{ AR5K_RF_GAIN(9), { 0x000001c8 } },
|
||||
{ AR5K_RF_GAIN(10), { 0x00000008 } },
|
||||
{ AR5K_RF_GAIN(11), { 0x00000048 } },
|
||||
{ AR5K_RF_GAIN(12), { 0x00000088 } },
|
||||
{ AR5K_RF_GAIN(13), { 0x00000189 } },
|
||||
{ AR5K_RF_GAIN(14), { 0x000001c9 } },
|
||||
{ AR5K_RF_GAIN(15), { 0x00000009 } },
|
||||
{ AR5K_RF_GAIN(16), { 0x00000049 } },
|
||||
{ AR5K_RF_GAIN(17), { 0x00000089 } },
|
||||
{ AR5K_RF_GAIN(18), { 0x000001b0 } },
|
||||
{ AR5K_RF_GAIN(19), { 0x000001f0 } },
|
||||
{ AR5K_RF_GAIN(20), { 0x00000030 } },
|
||||
{ AR5K_RF_GAIN(21), { 0x00000070 } },
|
||||
{ AR5K_RF_GAIN(22), { 0x00000171 } },
|
||||
{ AR5K_RF_GAIN(23), { 0x000001b1 } },
|
||||
{ AR5K_RF_GAIN(24), { 0x000001f1 } },
|
||||
{ AR5K_RF_GAIN(25), { 0x00000031 } },
|
||||
{ AR5K_RF_GAIN(26), { 0x00000071 } },
|
||||
{ AR5K_RF_GAIN(27), { 0x000001b8 } },
|
||||
{ AR5K_RF_GAIN(28), { 0x000001f8 } },
|
||||
{ AR5K_RF_GAIN(29), { 0x00000038 } },
|
||||
{ AR5K_RF_GAIN(30), { 0x00000078 } },
|
||||
{ AR5K_RF_GAIN(31), { 0x000000b8 } },
|
||||
{ AR5K_RF_GAIN(32), { 0x000001b9 } },
|
||||
{ AR5K_RF_GAIN(33), { 0x000001f9 } },
|
||||
{ AR5K_RF_GAIN(34), { 0x00000039 } },
|
||||
{ AR5K_RF_GAIN(35), { 0x00000079 } },
|
||||
{ AR5K_RF_GAIN(36), { 0x000000b9 } },
|
||||
{ AR5K_RF_GAIN(37), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(38), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(39), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(40), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(41), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(42), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(43), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(44), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(45), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(46), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(47), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(48), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(49), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(50), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(51), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(52), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(53), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(54), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(55), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(56), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(57), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(58), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(59), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(60), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(61), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(62), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(63), { 0x000000f9 } },
|
||||
};
|
||||
|
||||
static const struct ath5k_gain_opt rfgain_opt_5112 = {
|
||||
1,
|
||||
8,
|
||||
@@ -1588,8 +1656,8 @@ int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
|
||||
freq = 0; /* only 2Ghz */
|
||||
break;
|
||||
case AR5K_RF2425:
|
||||
ath5k_rfg = rfgain_2413;
|
||||
size = ARRAY_SIZE(rfgain_2413);
|
||||
ath5k_rfg = rfgain_2425;
|
||||
size = ARRAY_SIZE(rfgain_2425);
|
||||
freq = 0; /* only 2Ghz */
|
||||
break;
|
||||
default:
|
||||
@@ -1830,9 +1898,6 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
|
||||
data = data0 = data1 = data2 = 0;
|
||||
c = channel->center_freq;
|
||||
|
||||
/*
|
||||
* Set the channel on the RF5112 or newer
|
||||
*/
|
||||
if (c < 4800) {
|
||||
if (!((c - 2224) % 5)) {
|
||||
data0 = ((2 * (c - 704)) - 3040) / 10;
|
||||
@@ -1844,7 +1909,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
|
||||
return -EINVAL;
|
||||
|
||||
data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
|
||||
} else {
|
||||
} else if ((c - (c % 5)) != 2 || c > 5435) {
|
||||
if (!(c % 20) && c >= 5120) {
|
||||
data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
|
||||
data2 = ath5k_hw_bitswap(3, 2);
|
||||
@@ -1856,6 +1921,9 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
|
||||
data2 = ath5k_hw_bitswap(1, 2);
|
||||
} else
|
||||
return -EINVAL;
|
||||
} else {
|
||||
data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
|
||||
data2 = ath5k_hw_bitswap(0, 2);
|
||||
}
|
||||
|
||||
data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
|
||||
@@ -1866,6 +1934,45 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the channel on the RF2425
|
||||
*/
|
||||
static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
u32 data, data0, data2;
|
||||
u16 c;
|
||||
|
||||
data = data0 = data2 = 0;
|
||||
c = channel->center_freq;
|
||||
|
||||
if (c < 4800) {
|
||||
data0 = ath5k_hw_bitswap((c - 2272), 8);
|
||||
data2 = 0;
|
||||
/* ? 5GHz ? */
|
||||
} else if ((c - (c % 5)) != 2 || c > 5435) {
|
||||
if (!(c % 20) && c < 5120)
|
||||
data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
|
||||
else if (!(c % 10))
|
||||
data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
|
||||
else if (!(c % 5))
|
||||
data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
|
||||
else
|
||||
return -EINVAL;
|
||||
data2 = ath5k_hw_bitswap(1, 2);
|
||||
} else {
|
||||
data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
|
||||
data2 = ath5k_hw_bitswap(0, 2);
|
||||
}
|
||||
|
||||
data = (data0 << 4) | data2 << 2 | 0x1001;
|
||||
|
||||
ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
|
||||
ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a channel on the radio chip
|
||||
*/
|
||||
@@ -1895,6 +2002,9 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
|
||||
case AR5K_RF5111:
|
||||
ret = ath5k_hw_rf5111_channel(ah, channel);
|
||||
break;
|
||||
case AR5K_RF2425:
|
||||
ret = ath5k_hw_rf2425_channel(ah, channel);
|
||||
break;
|
||||
default:
|
||||
ret = ath5k_hw_rf5112_channel(ah, channel);
|
||||
break;
|
||||
@@ -1903,6 +2013,15 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set JAPAN setting for channel 14 */
|
||||
if (channel->center_freq == 2484) {
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
|
||||
AR5K_PHY_CCKTXCTL_JAPAN);
|
||||
} else {
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
|
||||
AR5K_PHY_CCKTXCTL_WORLD);
|
||||
}
|
||||
|
||||
ah->ah_current_channel.center_freq = channel->center_freq;
|
||||
ah->ah_current_channel.hw_value = channel->hw_value;
|
||||
ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
|
||||
@@ -1933,6 +2052,8 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
|
||||
* http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
|
||||
* &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
|
||||
*
|
||||
* XXX: Since during noise floor calibration antennas are detached according to
|
||||
* the patent, we should stop tx queues here.
|
||||
*/
|
||||
int
|
||||
ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
|
||||
@@ -1942,7 +2063,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
|
||||
s32 noise_floor;
|
||||
|
||||
/*
|
||||
* Enable noise floor calibration and wait until completion
|
||||
* Enable noise floor calibration
|
||||
*/
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_NF);
|
||||
@@ -1952,7 +2073,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
|
||||
if (ret) {
|
||||
ATH5K_ERR(ah->ah_sc,
|
||||
"noise floor calibration timeout (%uMHz)\n", freq);
|
||||
return ret;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Wait until the noise floor is calibrated and read the value */
|
||||
@@ -1974,7 +2095,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
|
||||
if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
|
||||
ATH5K_ERR(ah->ah_sc,
|
||||
"noise floor calibration failed (%uMHz)\n", freq);
|
||||
return -EIO;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
ah->ah_noise_floor = noise_floor;
|
||||
@@ -2087,38 +2208,66 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a PHY calibration on RF5111/5112
|
||||
* Perform a PHY calibration on RF5111/5112 and newer chips
|
||||
*/
|
||||
static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
u32 i_pwr, q_pwr;
|
||||
s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
|
||||
int i;
|
||||
ATH5K_TRACE(ah->ah_sc);
|
||||
|
||||
if (!ah->ah_calibration ||
|
||||
ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
|
||||
ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
|
||||
goto done;
|
||||
|
||||
ah->ah_calibration = false;
|
||||
/* Calibration has finished, get the results and re-run */
|
||||
for (i = 0; i <= 10; i++) {
|
||||
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
|
||||
i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
|
||||
q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
|
||||
}
|
||||
|
||||
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
|
||||
i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
|
||||
q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
|
||||
i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
|
||||
q_coffd = q_pwr >> 6;
|
||||
q_coffd = q_pwr >> 7;
|
||||
|
||||
/* No correction */
|
||||
if (i_coffd == 0 || q_coffd == 0)
|
||||
goto done;
|
||||
|
||||
i_coff = ((-iq_corr) / i_coffd) & 0x3f;
|
||||
q_coff = (((s32)i_pwr / q_coffd) - 64) & 0x1f;
|
||||
|
||||
/* Commit new IQ value */
|
||||
/* Boundary check */
|
||||
if (i_coff > 31)
|
||||
i_coff = 31;
|
||||
if (i_coff < -32)
|
||||
i_coff = -32;
|
||||
|
||||
q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
|
||||
|
||||
/* Boundary check */
|
||||
if (q_coff > 15)
|
||||
q_coff = 15;
|
||||
if (q_coff < -16)
|
||||
q_coff = -16;
|
||||
|
||||
/* Commit new I/Q value */
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
|
||||
((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
|
||||
|
||||
/* Re-enable calibration -if we don't we'll commit
|
||||
* the same values again and again */
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
|
||||
AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
|
||||
|
||||
done:
|
||||
|
||||
/* TODO: Separate noise floor calibration from I/Q calibration
|
||||
* since noise floor calibration interrupts rx path while I/Q
|
||||
* calibration doesn't. We don't need to run noise floor calibration
|
||||
* as often as I/Q calibration.*/
|
||||
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
|
||||
/* Request RF gain */
|
||||
|
||||
+696
-240
File diff suppressed because it is too large
Load Diff
@@ -305,9 +305,10 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
|
||||
#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
|
||||
|
||||
/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
|
||||
#define ipw_write8(ipw, ofs, val) \
|
||||
#define ipw_write8(ipw, ofs, val) do { \
|
||||
IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
|
||||
_ipw_write8(ipw, ofs, val)
|
||||
_ipw_write8(ipw, ofs, val); \
|
||||
} while (0)
|
||||
|
||||
/* 16-bit direct write (low 4K) */
|
||||
#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
|
||||
|
||||
@@ -14,18 +14,49 @@ config IWLWIFI_LEDS
|
||||
default n
|
||||
|
||||
config IWLWIFI_RFKILL
|
||||
boolean "IWLWIFI RF kill support"
|
||||
boolean "Iwlwifi RF kill support"
|
||||
depends on IWLCORE
|
||||
|
||||
config IWL4965
|
||||
tristate "Intel Wireless WiFi 4965AGN"
|
||||
config IWLWIFI_DEBUG
|
||||
bool "Enable full debugging output in iwlagn driver"
|
||||
depends on IWLCORE
|
||||
---help---
|
||||
This option will enable debug tracing output for the iwlwifi drivers
|
||||
|
||||
This will result in the kernel module being ~100k larger. You can
|
||||
control which debug output is sent to the kernel log by setting the
|
||||
value in
|
||||
|
||||
/sys/class/net/wlan0/device/debug_level
|
||||
|
||||
This entry will only exist if this option is enabled.
|
||||
|
||||
To set a value, simply echo an 8-byte hex value to the same file:
|
||||
|
||||
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
|
||||
|
||||
You can find the list of debug mask values in:
|
||||
drivers/net/wireless/iwlwifi/iwl-debug.h
|
||||
|
||||
If this is your first time using this driver, you should say Y here
|
||||
as the debug information can assist others in helping you resolve
|
||||
any problems you may encounter.
|
||||
|
||||
config IWLWIFI_DEBUGFS
|
||||
bool "Iwlwifi debugfs support"
|
||||
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
|
||||
---help---
|
||||
Enable creation of debugfs files for the iwlwifi drivers.
|
||||
|
||||
config IWLAGN
|
||||
tristate "Intel Wireless WiFi Next Gen AGN"
|
||||
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
|
||||
select FW_LOADER
|
||||
select IWLCORE
|
||||
---help---
|
||||
Select to build the driver supporting the:
|
||||
|
||||
Intel Wireless WiFi Link 4965AGN
|
||||
Intel Wireless WiFi Link Next-Gen AGN
|
||||
|
||||
This driver uses the kernel's mac80211 subsystem.
|
||||
|
||||
@@ -42,60 +73,33 @@ config IWL4965
|
||||
If you want to compile the driver as a module ( = code which can be
|
||||
inserted in and removed from the running kernel whenever you want),
|
||||
say M here and read <file:Documentation/kbuild/modules.txt>. The
|
||||
module will be called iwl4965.ko.
|
||||
module will be called iwlagn.ko.
|
||||
|
||||
config IWL4965_LEDS
|
||||
bool "Enable LEDS features in iwl4965 driver"
|
||||
depends on IWL4965
|
||||
config IWLAGN_SPECTRUM_MEASUREMENT
|
||||
bool "Enable Spectrum Measurement in iwlagn driver"
|
||||
depends on IWLAGN
|
||||
---help---
|
||||
This option will enable spectrum measurement for the iwlagn driver.
|
||||
|
||||
config IWLAGN_LEDS
|
||||
bool "Enable LEDS features in iwlagn driver"
|
||||
depends on IWLAGN
|
||||
select IWLWIFI_LEDS
|
||||
---help---
|
||||
This option enables LEDS for the iwlwifi drivers
|
||||
This option enables LEDS for the iwlagn drivers
|
||||
|
||||
|
||||
config IWL4965_SPECTRUM_MEASUREMENT
|
||||
bool "Enable Spectrum Measurement in iwl4965 driver"
|
||||
depends on IWL4965
|
||||
config IWL4965
|
||||
bool "Intel Wireless WiFi 4965AGN"
|
||||
depends on IWLAGN
|
||||
---help---
|
||||
This option will enable spectrum measurement for the iwl4965 driver.
|
||||
|
||||
config IWLWIFI_DEBUG
|
||||
bool "Enable full debugging output in iwl4965 driver"
|
||||
depends on IWL4965
|
||||
---help---
|
||||
This option will enable debug tracing output for the iwl4965
|
||||
driver.
|
||||
|
||||
This will result in the kernel module being ~100k larger. You can
|
||||
control which debug output is sent to the kernel log by setting the
|
||||
value in
|
||||
|
||||
/sys/class/net/wlan0/device/debug_level
|
||||
|
||||
This entry will only exist if this option is enabled.
|
||||
|
||||
To set a value, simply echo an 8-byte hex value to the same file:
|
||||
|
||||
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
|
||||
|
||||
You can find the list of debug mask values in:
|
||||
drivers/net/wireless/iwlwifi/iwl-4965-debug.h
|
||||
|
||||
If this is your first time using this driver, you should say Y here
|
||||
as the debug information can assist others in helping you resolve
|
||||
any problems you may encounter.
|
||||
This option enables support for Intel Wireless WiFi Link 4965AGN
|
||||
|
||||
config IWL5000
|
||||
bool "Intel Wireless WiFi 5000AGN"
|
||||
depends on IWL4965
|
||||
depends on IWLAGN
|
||||
---help---
|
||||
This option enables support for Intel Wireless WiFi Link 5000AGN Family
|
||||
Dependency on 4965 is temporary
|
||||
|
||||
config IWLWIFI_DEBUGFS
|
||||
bool "Iwlwifi debugfs support"
|
||||
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
|
||||
---help---
|
||||
Enable creation of debugfs files for the iwlwifi drivers.
|
||||
|
||||
config IWL3945
|
||||
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
|
||||
|
||||
@@ -6,15 +6,14 @@ iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
|
||||
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
|
||||
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
|
||||
|
||||
obj-$(CONFIG_IWLAGN) += iwlagn.o
|
||||
iwlagn-objs := iwl-agn.o iwl-agn-rs.o
|
||||
|
||||
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
|
||||
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
|
||||
|
||||
obj-$(CONFIG_IWL3945) += iwl3945.o
|
||||
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
|
||||
iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
|
||||
|
||||
obj-$(CONFIG_IWL4965) += iwl4965.o
|
||||
iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o
|
||||
|
||||
ifeq ($(CONFIG_IWL5000),y)
|
||||
iwl4965-objs += iwl-5000.o
|
||||
endif
|
||||
|
||||
|
||||
|
||||
@@ -206,12 +206,12 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
|
||||
static int iwl3945_led_register_led(struct iwl3945_priv *priv,
|
||||
struct iwl3945_led *led,
|
||||
enum led_type type, u8 set_led,
|
||||
const char *name, char *trigger)
|
||||
char *trigger)
|
||||
{
|
||||
struct device *device = wiphy_dev(priv->hw->wiphy);
|
||||
int ret;
|
||||
|
||||
led->led_dev.name = name;
|
||||
led->led_dev.name = led->name;
|
||||
led->led_dev.brightness_set = iwl3945_led_brightness_set;
|
||||
led->led_dev.default_trigger = trigger;
|
||||
|
||||
@@ -308,7 +308,6 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
|
||||
int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
{
|
||||
char *trigger;
|
||||
char name[32];
|
||||
int ret;
|
||||
|
||||
priv->last_blink_rate = 0;
|
||||
@@ -318,7 +317,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
priv->allow_blinking = 0;
|
||||
|
||||
trigger = ieee80211_get_radio_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:radio",
|
||||
snprintf(priv->led[IWL_LED_TRG_RADIO].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
|
||||
@@ -327,19 +327,20 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
|
||||
ret = iwl3945_led_register_led(priv,
|
||||
&priv->led[IWL_LED_TRG_RADIO],
|
||||
IWL_LED_TRG_RADIO, 1,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_RADIO, 1, trigger);
|
||||
|
||||
if (ret)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_assoc_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:assoc",
|
||||
snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
ret = iwl3945_led_register_led(priv,
|
||||
&priv->led[IWL_LED_TRG_ASSOC],
|
||||
IWL_LED_TRG_ASSOC, 0,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_ASSOC, 0, trigger);
|
||||
|
||||
/* for assoc always turn led on */
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
|
||||
@@ -349,14 +350,13 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_rx_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:RX",
|
||||
snprintf(priv->led[IWL_LED_TRG_RX].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
|
||||
ret = iwl3945_led_register_led(priv,
|
||||
&priv->led[IWL_LED_TRG_RX],
|
||||
IWL_LED_TRG_RX, 0,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_RX, 0, trigger);
|
||||
|
||||
priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
|
||||
priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
|
||||
@@ -366,13 +366,14 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_tx_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:TX",
|
||||
snprintf(priv->led[IWL_LED_TRG_TX].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
ret = iwl3945_led_register_led(priv,
|
||||
&priv->led[IWL_LED_TRG_TX],
|
||||
IWL_LED_TRG_TX, 0,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_TX, 0, trigger);
|
||||
|
||||
priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
|
||||
priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
|
||||
priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
|
||||
|
||||
@@ -50,6 +50,7 @@ enum led_type {
|
||||
struct iwl3945_led {
|
||||
struct iwl3945_priv *priv;
|
||||
struct led_classdev led_dev;
|
||||
char name[32];
|
||||
|
||||
int (*led_on) (struct iwl3945_priv *priv, int led_id);
|
||||
int (*led_off) (struct iwl3945_priv *priv, int led_id);
|
||||
|
||||
@@ -710,10 +710,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
||||
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Convert 3945's rssi indicator to dBm */
|
||||
rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
|
||||
@@ -775,6 +772,11 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
|
||||
priv->last_rx_noise = rx_status.noise;
|
||||
}
|
||||
|
||||
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
||||
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
|
||||
case IEEE80211_FTYPE_MGMT:
|
||||
switch (le16_to_cpu(header->frame_control) &
|
||||
@@ -793,8 +795,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
|
||||
struct ieee80211_mgmt *mgmt =
|
||||
(struct ieee80211_mgmt *)header;
|
||||
__le32 *pos;
|
||||
pos =
|
||||
(__le32 *) & mgmt->u.beacon.
|
||||
pos = (__le32 *)&mgmt->u.beacon.
|
||||
timestamp;
|
||||
priv->timestamp0 = le32_to_cpu(pos[0]);
|
||||
priv->timestamp1 = le32_to_cpu(pos[1]);
|
||||
@@ -1507,7 +1508,7 @@ static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
|
||||
*/
|
||||
static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
|
||||
{
|
||||
return (((temperature < -260) || (temperature > 25)) ? 1 : 0);
|
||||
return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
|
||||
}
|
||||
|
||||
int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
|
||||
@@ -2628,7 +2629,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
|
||||
tx_beacon_cmd->tx.supp_rates[1] =
|
||||
(IWL_CCK_BASIC_RATES_MASK & 0xF);
|
||||
|
||||
return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size);
|
||||
return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
|
||||
}
|
||||
|
||||
void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
|
||||
|
||||
@@ -341,39 +341,6 @@ err:
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
ret = iwl_grab_nic_access(priv);
|
||||
if (ret) {
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (src == IWL_PWR_SRC_VAUX) {
|
||||
u32 val;
|
||||
ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
|
||||
&val);
|
||||
|
||||
if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
|
||||
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
|
||||
~APMG_PS_CTRL_MSK_PWR_SRC);
|
||||
}
|
||||
} else {
|
||||
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
|
||||
~APMG_PS_CTRL_MSK_PWR_SRC);
|
||||
}
|
||||
|
||||
iwl_release_nic_access(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
|
||||
@@ -875,18 +842,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set card power command */
|
||||
static int iwl4965_set_power(struct iwl_priv *priv,
|
||||
void *cmd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
|
||||
sizeof(struct iwl4965_powertable_cmd),
|
||||
cmd, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
|
||||
{
|
||||
s32 sign = 1;
|
||||
@@ -1560,11 +1515,11 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
|
||||
c, atten_value, power_index,
|
||||
tx_power.s.radio_tx_gain[c],
|
||||
tx_power.s.dsp_predis_atten[c]);
|
||||
}/* for each chain */
|
||||
} /* for each chain */
|
||||
|
||||
tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
|
||||
|
||||
}/* for each rate */
|
||||
} /* for each rate */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1701,38 +1656,6 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
|
||||
return le32_to_cpu(s->rb_closed) & 0xFFF;
|
||||
}
|
||||
|
||||
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
|
||||
struct iwl_frame *frame, u8 rate)
|
||||
{
|
||||
struct iwl4965_tx_beacon_cmd *tx_beacon_cmd;
|
||||
unsigned int frame_size;
|
||||
|
||||
tx_beacon_cmd = &frame->u.beacon;
|
||||
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
|
||||
|
||||
tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
|
||||
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
|
||||
|
||||
frame_size = iwl4965_fill_beacon_frame(priv,
|
||||
tx_beacon_cmd->frame,
|
||||
iwl_bcast_addr,
|
||||
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
|
||||
|
||||
BUG_ON(frame_size > MAX_MPDU_SIZE);
|
||||
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
|
||||
|
||||
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
|
||||
tx_beacon_cmd->tx.rate_n_flags =
|
||||
iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
|
||||
else
|
||||
tx_beacon_cmd->tx.rate_n_flags =
|
||||
iwl_hw_set_rate_n_flags(rate, 0);
|
||||
|
||||
tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
|
||||
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
|
||||
return (sizeof(*tx_beacon_cmd) + frame_size);
|
||||
}
|
||||
|
||||
static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
|
||||
{
|
||||
priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
|
||||
@@ -2079,39 +2002,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
const u8 *addr, u16 tid, u16 *ssn)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
|
||||
print_mac(mac, addr), tid);
|
||||
|
||||
if (!(priv->cfg->sku & IWL_SKU_N))
|
||||
return -EACCES;
|
||||
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
IWL_DEBUG_HT("start Rx\n");
|
||||
return iwl_rx_agg_start(priv, addr, tid, *ssn);
|
||||
case IEEE80211_AMPDU_RX_STOP:
|
||||
IWL_DEBUG_HT("stop Rx\n");
|
||||
return iwl_rx_agg_stop(priv, addr, tid);
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
IWL_DEBUG_HT("start Tx\n");
|
||||
return iwl_tx_agg_start(priv, addr, tid, ssn);
|
||||
case IEEE80211_AMPDU_TX_STOP:
|
||||
IWL_DEBUG_HT("stop Tx\n");
|
||||
return iwl_tx_agg_stop(priv, addr, tid);
|
||||
default:
|
||||
IWL_DEBUG_HT("unknown\n");
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
|
||||
{
|
||||
@@ -2240,9 +2130,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
|
||||
bitmap = bitmap << sh;
|
||||
sh = 0;
|
||||
}
|
||||
bitmap |= (1 << sh);
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
|
||||
start, (u32)(bitmap & 0xFFFFFFFF));
|
||||
bitmap |= 1ULL << sh;
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
|
||||
start, (unsigned long long)bitmap);
|
||||
}
|
||||
|
||||
agg->bitmap = bitmap;
|
||||
@@ -2368,6 +2258,40 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
|
||||
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
|
||||
}
|
||||
|
||||
static int iwl4965_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp)
|
||||
{
|
||||
/* data from PHY/DSP regarding signal strength, etc.,
|
||||
* contents are always there, not configurable by host. */
|
||||
struct iwl4965_rx_non_cfg_phy *ncphy =
|
||||
(struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
|
||||
u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK)
|
||||
>> IWL49_AGC_DB_POS;
|
||||
|
||||
u32 valid_antennae =
|
||||
(le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK)
|
||||
>> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET;
|
||||
u8 max_rssi = 0;
|
||||
u32 i;
|
||||
|
||||
/* Find max rssi among 3 possible receivers.
|
||||
* These values are measured by the digital signal processor (DSP).
|
||||
* They should stay fairly constant even as the signal strength varies,
|
||||
* if the radio's automatic gain control (AGC) is working right.
|
||||
* AGC value (see below) will provide the "interesting" info. */
|
||||
for (i = 0; i < 3; i++)
|
||||
if (valid_antennae & (1 << i))
|
||||
max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
|
||||
|
||||
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
|
||||
ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
|
||||
max_rssi, agc);
|
||||
|
||||
/* dBm = max_rssi dB - agc dB - constant.
|
||||
* Higher AGC (higher radio gain) means lower signal. */
|
||||
return max_rssi - agc - IWL_RSSI_OFFSET;
|
||||
}
|
||||
|
||||
|
||||
/* Set up 4965-specific Rx frame reply handlers */
|
||||
static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
|
||||
@@ -2399,6 +2323,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
|
||||
.chain_noise_reset = iwl4965_chain_noise_reset,
|
||||
.gain_computation = iwl4965_gain_computation,
|
||||
.rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
|
||||
.calc_rssi = iwl4965_calc_rssi,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl4965_lib = {
|
||||
@@ -2440,7 +2365,6 @@ static struct iwl_lib_ops iwl4965_lib = {
|
||||
.check_version = iwl4965_eeprom_check_version,
|
||||
.query_addr = iwlcore_eeprom_query_addr,
|
||||
},
|
||||
.set_power = iwl4965_set_power,
|
||||
.send_tx_power = iwl4965_send_tx_power,
|
||||
.update_chain_flags = iwl4965_update_chain_flags,
|
||||
.temperature = iwl4965_temperature_calib,
|
||||
|
||||
@@ -93,6 +93,13 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
|
||||
iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
|
||||
CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
|
||||
|
||||
/* Set FH wait treshold to maximum (HW error during stress W/A) */
|
||||
iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
|
||||
|
||||
/* enable HAP INTA to move device L1a -> L0s */
|
||||
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
|
||||
|
||||
iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
|
||||
|
||||
/* set "initialization complete" bit to move adapter
|
||||
@@ -230,6 +237,16 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
|
||||
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
|
||||
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
|
||||
|
||||
/* W/A : NIC is stuck in a reset state after Early PCIe power off
|
||||
* (PCIe power is lost before PERST# is asserted),
|
||||
* causing ME FW to lose ownership and not being able to obtain it back.
|
||||
*/
|
||||
iwl_grab_nic_access(priv);
|
||||
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
|
||||
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
|
||||
iwl_release_nic_access(priv);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
@@ -924,8 +941,8 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
|
||||
len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
|
||||
|
||||
if (txq_id != IWL_CMD_QUEUE_NUM) {
|
||||
sta = txq->cmd[txq->q.write_ptr].cmd.tx.sta_id;
|
||||
sec_ctl = txq->cmd[txq->q.write_ptr].cmd.tx.sec_ctl;
|
||||
sta = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
|
||||
sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
|
||||
|
||||
switch (sec_ctl & TX_CMD_SEC_MSK) {
|
||||
case TX_CMD_SEC_CCM:
|
||||
@@ -964,7 +981,7 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
|
||||
u8 sta = 0;
|
||||
|
||||
if (txq_id != IWL_CMD_QUEUE_NUM)
|
||||
sta = txq->cmd[txq->q.read_ptr].cmd.tx.sta_id;
|
||||
sta = txq->cmd[txq->q.read_ptr]->cmd.tx.sta_id;
|
||||
|
||||
shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr].
|
||||
val = cpu_to_le16(1 | (sta << 12));
|
||||
@@ -1131,7 +1148,7 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
|
||||
|
||||
static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
|
||||
{
|
||||
return le32_to_cpup((__le32*)&tx_resp->status +
|
||||
return le32_to_cpup((__le32 *)&tx_resp->status +
|
||||
tx_resp->frame_count) & MAX_SN;
|
||||
}
|
||||
|
||||
@@ -1228,9 +1245,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
|
||||
bitmap = bitmap << sh;
|
||||
sh = 0;
|
||||
}
|
||||
bitmap |= (1 << sh);
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
|
||||
start, (u32)(bitmap & 0xFFFFFFFF));
|
||||
bitmap |= 1ULL << sh;
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
|
||||
start, (unsigned long long)bitmap);
|
||||
}
|
||||
|
||||
agg->bitmap = bitmap;
|
||||
@@ -1444,6 +1461,44 @@ static void iwl5000_temperature(struct iwl_priv *priv)
|
||||
priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
|
||||
}
|
||||
|
||||
/* Calc max signal level (dBm) among 3 possible receivers */
|
||||
static int iwl5000_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp)
|
||||
{
|
||||
/* data from PHY/DSP regarding signal strength, etc.,
|
||||
* contents are always there, not configurable by host
|
||||
*/
|
||||
struct iwl5000_non_cfg_phy *ncphy =
|
||||
(struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
|
||||
u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
|
||||
u8 agc;
|
||||
|
||||
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
|
||||
agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
|
||||
|
||||
/* Find max rssi among 3 possible receivers.
|
||||
* These values are measured by the digital signal processor (DSP).
|
||||
* They should stay fairly constant even as the signal strength varies,
|
||||
* if the radio's automatic gain control (AGC) is working right.
|
||||
* AGC value (see below) will provide the "interesting" info.
|
||||
*/
|
||||
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
|
||||
rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
|
||||
rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
|
||||
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
|
||||
rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
|
||||
|
||||
max_rssi = max_t(u32, rssi_a, rssi_b);
|
||||
max_rssi = max_t(u32, max_rssi, rssi_c);
|
||||
|
||||
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
|
||||
rssi_a, rssi_b, rssi_c, max_rssi, agc);
|
||||
|
||||
/* dBm = max_rssi dB - agc dB - constant.
|
||||
* Higher AGC (higher radio gain) means lower signal. */
|
||||
return max_rssi - agc - IWL_RSSI_OFFSET;
|
||||
}
|
||||
|
||||
static struct iwl_hcmd_ops iwl5000_hcmd = {
|
||||
.rxon_assoc = iwl5000_send_rxon_assoc,
|
||||
};
|
||||
@@ -1454,6 +1509,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
|
||||
.gain_computation = iwl5000_gain_computation,
|
||||
.chain_noise_reset = iwl5000_chain_noise_reset,
|
||||
.rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
|
||||
.calc_rssi = iwl5000_calc_rssi,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl5000_lib = {
|
||||
@@ -1474,6 +1530,7 @@ static struct iwl_lib_ops iwl5000_lib = {
|
||||
.alive_notify = iwl5000_alive_notify,
|
||||
.send_tx_power = iwl5000_send_tx_power,
|
||||
.temperature = iwl5000_temperature,
|
||||
.update_chain_flags = iwl4965_update_chain_flags,
|
||||
.apm_ops = {
|
||||
.init = iwl5000_apm_init,
|
||||
.reset = iwl5000_apm_reset,
|
||||
|
||||
+114
-213
File diff suppressed because it is too large
Load Diff
+7
-16
@@ -24,8 +24,8 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __iwl_4965_rs_h__
|
||||
#define __iwl_4965_rs_h__
|
||||
#ifndef __iwl_agn_rs_h__
|
||||
#define __iwl_agn_rs_h__
|
||||
|
||||
#include "iwl-dev.h"
|
||||
|
||||
@@ -88,7 +88,7 @@ enum {
|
||||
#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
|
||||
#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
|
||||
|
||||
/* 4965 uCode API values for legacy bit rates, both OFDM and CCK */
|
||||
/* uCode API values for legacy bit rates, both OFDM and CCK */
|
||||
enum {
|
||||
IWL_RATE_6M_PLCP = 13,
|
||||
IWL_RATE_9M_PLCP = 15,
|
||||
@@ -107,7 +107,7 @@ enum {
|
||||
/*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/
|
||||
};
|
||||
|
||||
/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */
|
||||
/* uCode API values for OFDM high-throughput (HT) bit rates */
|
||||
enum {
|
||||
IWL_RATE_SISO_6M_PLCP = 0,
|
||||
IWL_RATE_SISO_12M_PLCP = 1,
|
||||
@@ -286,15 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
|
||||
*
|
||||
* NOTE: This is provided as a quick mechanism for a user to visualize
|
||||
* the performance of the rate control algorithm and is not meant to be
|
||||
* parsed software.
|
||||
*/
|
||||
extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
|
||||
|
||||
/**
|
||||
* iwl4965_rate_control_register - Register the rate control algorithm callbacks
|
||||
*
|
||||
@@ -305,7 +296,7 @@ extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
|
||||
* ieee80211_register_hw
|
||||
*
|
||||
*/
|
||||
extern int iwl4965_rate_control_register(void);
|
||||
extern int iwlagn_rate_control_register(void);
|
||||
|
||||
/**
|
||||
* iwl4965_rate_control_unregister - Unregister the rate control callbacks
|
||||
@@ -313,6 +304,6 @@ extern int iwl4965_rate_control_register(void);
|
||||
* This should be called after calling ieee80211_unregister_hw, but before
|
||||
* the driver is unloaded.
|
||||
*/
|
||||
extern void iwl4965_rate_control_unregister(void);
|
||||
extern void iwlagn_rate_control_unregister(void);
|
||||
|
||||
#endif
|
||||
#endif /* __iwl_agn__rs__ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user