Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
This commit is contained in:
commit
d86804cb70
@ -159,10 +159,10 @@ struct ieee80211_regdomain mydriver_jp_regdom = {
|
||||
REG_RULE(2412-20, 2484+20, 40, 6, 20, 0),
|
||||
/* IEEE 802.11a, channels 34..48 */
|
||||
REG_RULE(5170-20, 5240+20, 40, 6, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN),
|
||||
NL80211_RRF_NO_IR),
|
||||
/* IEEE 802.11a, channels 52..64 */
|
||||
REG_RULE(5260-20, 5320+20, 40, 6, 20,
|
||||
NL80211_RRF_NO_IBSS |
|
||||
NL80211_RRF_NO_IR|
|
||||
NL80211_RRF_DFS),
|
||||
}
|
||||
};
|
||||
|
19
MAINTAINERS
19
MAINTAINERS
@ -1458,17 +1458,6 @@ T: git git://github.com/kvalo/ath.git
|
||||
S: Supported
|
||||
F: drivers/net/wireless/ath/ath6kl/
|
||||
|
||||
ATHEROS ATH9K WIRELESS DRIVER
|
||||
M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
|
||||
M: Jouni Malinen <jouni@qca.qualcomm.com>
|
||||
M: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
|
||||
M: Senthil Balasubramanian <senthilb@qca.qualcomm.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ath9k-devel@lists.ath9k.org
|
||||
W: http://wireless.kernel.org/en/users/Drivers/ath9k
|
||||
S: Supported
|
||||
F: drivers/net/wireless/ath/ath9k/
|
||||
|
||||
WILOCITY WIL6210 WIRELESS DRIVER
|
||||
M: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
@ -6928,6 +6917,14 @@ T: git git://linuxtv.org/anttip/media_tree.git
|
||||
S: Maintained
|
||||
F: drivers/media/tuners/qt1010*
|
||||
|
||||
QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
|
||||
M: QCA ath9k Development <ath9k-devel@qca.qualcomm.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: ath9k-devel@lists.ath9k.org
|
||||
W: http://wireless.kernel.org/en/users/Drivers/ath9k
|
||||
S: Supported
|
||||
F: drivers/net/wireless/ath/ath9k/
|
||||
|
||||
QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
L: ath10k@lists.infradead.org
|
||||
|
@ -238,7 +238,6 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
|
||||
pci_release_regions(dev);
|
||||
pci_disable_device(dev);
|
||||
kfree(bus);
|
||||
pci_set_drvdata(dev, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
@ -1351,12 +1351,12 @@ static int ath10k_update_channel_list(struct ath10k *ar)
|
||||
ch->allow_vht = true;
|
||||
|
||||
ch->allow_ibss =
|
||||
!(channel->flags & IEEE80211_CHAN_NO_IBSS);
|
||||
!(channel->flags & IEEE80211_CHAN_NO_IR);
|
||||
|
||||
ch->ht40plus =
|
||||
!(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
|
||||
|
||||
passive = channel->flags & IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
passive = channel->flags & IEEE80211_CHAN_NO_IR;
|
||||
ch->passive = passive;
|
||||
|
||||
ch->freq = channel->center_freq;
|
||||
|
@ -1109,7 +1109,9 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
|
||||
(mode == WMI_11G_HT20) ?
|
||||
NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
|
||||
|
||||
mutex_lock(&vif->wdev.mtx);
|
||||
cfg80211_ch_switch_notify(vif->ndev, &chandef);
|
||||
mutex_unlock(&vif->wdev.mtx);
|
||||
}
|
||||
|
||||
static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
|
||||
@ -3169,12 +3171,15 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
|
||||
}
|
||||
|
||||
static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
unsigned int wait, const u8 *buf, size_t len,
|
||||
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
|
||||
struct cfg80211_mgmt_tx_params *params, u64 *cookie)
|
||||
{
|
||||
struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
|
||||
struct ath6kl *ar = ath6kl_priv(vif->ndev);
|
||||
struct ieee80211_channel *chan = params->chan;
|
||||
const u8 *buf = params->buf;
|
||||
size_t len = params->len;
|
||||
unsigned int wait = params->wait;
|
||||
bool no_cck = params->no_cck;
|
||||
u32 id, freq;
|
||||
const struct ieee80211_mgmt *mgmt;
|
||||
bool more_data, queued;
|
||||
|
@ -86,7 +86,7 @@ config ATH9K_DFS_CERTIFIED
|
||||
|
||||
config ATH9K_TX99
|
||||
bool "Atheros ath9k TX99 testing support"
|
||||
depends on CFG80211_CERTIFICATION_ONUS
|
||||
depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS
|
||||
default n
|
||||
---help---
|
||||
Say N. This should only be enabled on systems undergoing
|
||||
@ -104,6 +104,14 @@ config ATH9K_TX99
|
||||
be evaluated to meet the RF exposure limits set forth in the
|
||||
governmental SAR regulations.
|
||||
|
||||
config ATH9K_WOW
|
||||
bool "Wake on Wireless LAN support (EXPERIMENTAL)"
|
||||
depends on ATH9K && PM
|
||||
default n
|
||||
---help---
|
||||
This option enables Wake on Wireless LAN support for certain cards.
|
||||
Currently, AR9462 is supported.
|
||||
|
||||
config ATH9K_LEGACY_RATE_CONTROL
|
||||
bool "Atheros ath9k rate control"
|
||||
depends on ATH9K
|
||||
|
@ -13,9 +13,9 @@ ath9k-$(CONFIG_ATH9K_PCI) += pci.o
|
||||
ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
|
||||
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
|
||||
ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
|
||||
ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += \
|
||||
dfs.o
|
||||
ath9k-$(CONFIG_PM_SLEEP) += wow.o
|
||||
ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o
|
||||
ath9k-$(CONFIG_ATH9K_TX99) += tx99.o
|
||||
ath9k-$(CONFIG_ATH9K_WOW) += wow.o
|
||||
|
||||
obj-$(CONFIG_ATH9K) += ath9k.o
|
||||
|
||||
@ -41,6 +41,8 @@ ath9k_hw-y:= \
|
||||
ar9003_eeprom.o \
|
||||
ar9003_paprd.o
|
||||
|
||||
ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o
|
||||
|
||||
ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
|
||||
ar9003_mci.o
|
||||
obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
|
||||
|
@ -352,7 +352,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
|
||||
{0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
|
||||
{0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
|
||||
{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
|
||||
{0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
|
||||
{0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982},
|
||||
{0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
|
||||
{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
|
||||
@ -378,9 +378,9 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
|
||||
{0x00009814, 0x9280c00a},
|
||||
{0x00009818, 0x00000000},
|
||||
{0x0000981c, 0x00020028},
|
||||
{0x00009834, 0x6400a290},
|
||||
{0x00009834, 0x6400a190},
|
||||
{0x00009838, 0x0108ecff},
|
||||
{0x0000983c, 0x0d000600},
|
||||
{0x0000983c, 0x14000600},
|
||||
{0x00009880, 0x201fff00},
|
||||
{0x00009884, 0x00001042},
|
||||
{0x000098a4, 0x00200400},
|
||||
@ -401,7 +401,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
|
||||
{0x00009d04, 0x40206c10},
|
||||
{0x00009d08, 0x009c4060},
|
||||
{0x00009d0c, 0x9883800a},
|
||||
{0x00009d10, 0x01834061},
|
||||
{0x00009d10, 0x01884061},
|
||||
{0x00009d14, 0x00c0040b},
|
||||
{0x00009d18, 0x00000000},
|
||||
{0x00009e08, 0x0038230c},
|
||||
@ -459,7 +459,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
|
||||
{0x0000a3e8, 0x20202020},
|
||||
{0x0000a3ec, 0x20202020},
|
||||
{0x0000a3f0, 0x00000000},
|
||||
{0x0000a3f4, 0x00000246},
|
||||
{0x0000a3f4, 0x00000000},
|
||||
{0x0000a3f8, 0x0c9bd380},
|
||||
{0x0000a3fc, 0x000f0f01},
|
||||
{0x0000a400, 0x8fa91f01},
|
||||
@ -644,7 +644,7 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
|
||||
{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
|
||||
{0x0000a410, 0x000050d4, 0x000050d4, 0x000050d9, 0x000050d9},
|
||||
{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
|
||||
@ -1086,8 +1086,8 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
|
||||
{0x0000b074, 0x00000000},
|
||||
{0x0000b078, 0x00000000},
|
||||
{0x0000b07c, 0x00000000},
|
||||
{0x0000b080, 0x2a2d2f32},
|
||||
{0x0000b084, 0x21232328},
|
||||
{0x0000b080, 0x23232323},
|
||||
{0x0000b084, 0x21232323},
|
||||
{0x0000b088, 0x19191c1e},
|
||||
{0x0000b08c, 0x12141417},
|
||||
{0x0000b090, 0x07070e0e},
|
||||
@ -1385,9 +1385,9 @@ static const u32 ar9300_2p2_mac_core[][2] = {
|
||||
{0x000081f8, 0x00000000},
|
||||
{0x000081fc, 0x00000000},
|
||||
{0x00008240, 0x00100000},
|
||||
{0x00008244, 0x0010f424},
|
||||
{0x00008244, 0x0010f400},
|
||||
{0x00008248, 0x00000800},
|
||||
{0x0000824c, 0x0001e848},
|
||||
{0x0000824c, 0x0001e800},
|
||||
{0x00008250, 0x00000000},
|
||||
{0x00008254, 0x00000000},
|
||||
{0x00008258, 0x00000000},
|
||||
@ -1726,16 +1726,23 @@ static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
|
||||
|
||||
static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00004040, 0x08253e5e},
|
||||
{0x00004040, 0x0825365e},
|
||||
{0x00004040, 0x0008003b},
|
||||
{0x00004044, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00004040, 0x08213e5e},
|
||||
{0x00004040, 0x0821365e},
|
||||
{0x00004040, 0x0008003b},
|
||||
{0x00004044, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9300_2p2_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a398, 0x00000000},
|
||||
{0x0000a39c, 0x6f7f0301},
|
||||
{0x0000a3a0, 0xca9228ee},
|
||||
};
|
||||
|
||||
#endif /* INITVALS_9003_2P2_H */
|
||||
|
@ -1040,14 +1040,14 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
|
||||
}
|
||||
}
|
||||
|
||||
static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
bool txiqcal_done = false;
|
||||
bool is_reusable = true, status = true;
|
||||
bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false;
|
||||
bool run_rtt_cal = false, run_agc_cal;
|
||||
bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
|
||||
u32 rx_delay = 0;
|
||||
u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
|
||||
@ -1119,22 +1119,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
|
||||
AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
|
||||
txiqcal_done = run_agc_cal = true;
|
||||
} else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) {
|
||||
run_agc_cal = true;
|
||||
sep_iq_cal = true;
|
||||
}
|
||||
|
||||
skip_tx_iqcal:
|
||||
if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
|
||||
ar9003_mci_init_cal_req(ah, &is_reusable);
|
||||
|
||||
if (sep_iq_cal) {
|
||||
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
|
||||
udelay(5);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
|
||||
}
|
||||
|
||||
if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
|
||||
rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
|
||||
/* Disable BB_active */
|
||||
@ -1228,13 +1218,109 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
bool txiqcal_done = false;
|
||||
bool is_reusable = true, status = true;
|
||||
bool run_agc_cal = false, sep_iq_cal = false;
|
||||
|
||||
/* Use chip chainmask only for calibration */
|
||||
ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
|
||||
|
||||
if (ah->enabled_cals & TX_CL_CAL) {
|
||||
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
|
||||
run_agc_cal = true;
|
||||
}
|
||||
|
||||
if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
|
||||
goto skip_tx_iqcal;
|
||||
|
||||
/* Do Tx IQ Calibration */
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
|
||||
AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
|
||||
DELPT);
|
||||
|
||||
/*
|
||||
* For AR9485 or later chips, TxIQ cal runs as part of
|
||||
* AGC calibration. Specifically, AR9550 in SoC chips.
|
||||
*/
|
||||
if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
|
||||
txiqcal_done = true;
|
||||
run_agc_cal = true;
|
||||
} else {
|
||||
sep_iq_cal = true;
|
||||
run_agc_cal = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* In the SoC family, this will run for AR9300, AR9331 and AR9340.
|
||||
*/
|
||||
if (sep_iq_cal) {
|
||||
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
|
||||
udelay(5);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
|
||||
}
|
||||
|
||||
skip_tx_iqcal:
|
||||
if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
|
||||
/* Calibrate the AGC */
|
||||
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
|
||||
REG_READ(ah, AR_PHY_AGC_CONTROL) |
|
||||
AR_PHY_AGC_CONTROL_CAL);
|
||||
|
||||
/* Poll for offset calibration complete */
|
||||
status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
|
||||
AR_PHY_AGC_CONTROL_CAL,
|
||||
0, AH_WAIT_TIMEOUT);
|
||||
}
|
||||
|
||||
if (!status) {
|
||||
ath_dbg(common, CALIBRATE,
|
||||
"offset calibration failed to complete in %d ms; noisy environment?\n",
|
||||
AH_WAIT_TIMEOUT / 1000);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (txiqcal_done)
|
||||
ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
|
||||
|
||||
/* Revert chainmask to runtime parameters */
|
||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
|
||||
/* Initialize list pointers */
|
||||
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
|
||||
|
||||
INIT_CAL(&ah->iq_caldata);
|
||||
INSERT_CAL(ah, &ah->iq_caldata);
|
||||
ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
|
||||
|
||||
/* Initialize current pointer to first element in list */
|
||||
ah->cal_list_curr = ah->cal_list;
|
||||
|
||||
if (ah->cal_list_curr)
|
||||
ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
|
||||
|
||||
if (caldata)
|
||||
caldata->CalValid = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
priv_ops->init_cal = ar9003_hw_init_cal_pcoem;
|
||||
else
|
||||
priv_ops->init_cal = ar9003_hw_init_cal_soc;
|
||||
|
||||
priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
|
||||
priv_ops->init_cal = ar9003_hw_init_cal;
|
||||
priv_ops->setup_calibration = ar9003_hw_setup_calibration;
|
||||
|
||||
ops->calibrate = ar9003_hw_calibrate;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ar9462_2p0_initvals.h"
|
||||
#include "ar9462_2p1_initvals.h"
|
||||
#include "ar9565_1p0_initvals.h"
|
||||
#include "ar9565_1p1_initvals.h"
|
||||
|
||||
/* General hardware code for the AR9003 hadware family */
|
||||
|
||||
@ -148,7 +149,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ar9340Modes_high_ob_db_tx_gain_table_1p0);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9340Modes_fast_clock_1p0);
|
||||
ar9340Modes_fast_clock_1p0);
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
ar9340_1p0_baseband_core_txfir_coeff_japan_2484);
|
||||
|
||||
if (!ah->is_clk_25mhz)
|
||||
INIT_INI_ARRAY(&ah->iniAdditional,
|
||||
@ -223,6 +226,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ar9462_2p1_modes_fast_clock);
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
ar9462_2p1_baseband_core_txfir_coeff_japan_2484);
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9462_2p1_pciephy_clkreq_disable_L1);
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
ar9462_2p1_pciephy_clkreq_disable_L1);
|
||||
} else if (AR_SREV_9462_20(ah)) {
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
|
||||
@ -247,18 +254,18 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ar9462_2p0_soc_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9462_common_rx_gain_table_2p0);
|
||||
ar9462_2p0_common_rx_gain);
|
||||
|
||||
/* Awake -> Sleep Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9462_pciephy_clkreq_disable_L1_2p0);
|
||||
ar9462_2p0_pciephy_clkreq_disable_L1);
|
||||
/* Sleep -> Awake Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
ar9462_pciephy_clkreq_disable_L1_2p0);
|
||||
ar9462_2p0_pciephy_clkreq_disable_L1);
|
||||
|
||||
/* Fast clock modal settings */
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9462_modes_fast_clock_2p0);
|
||||
ar9462_2p0_modes_fast_clock);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
ar9462_2p0_baseband_core_txfir_coeff_japan_2484);
|
||||
@ -330,7 +337,44 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ar9580_1p0_low_ob_db_tx_gain_table);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9580_1p0_modes_fast_clock);
|
||||
ar9580_1p0_modes_fast_clock);
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
ar9580_1p0_baseband_core_txfir_coeff_japan_2484);
|
||||
} else if (AR_SREV_9565_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
ar9565_1p1_mac_core);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9565_1p1_mac_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9565_1p1_baseband_core);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9565_1p1_baseband_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9565_1p1_radio_core);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
|
||||
ar9565_1p1_radio_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9565_1p1_soc_preamble);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9565_1p1_soc_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9565_1p1_Common_rx_gain_table);
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p1_Modes_lowest_ob_db_tx_gain_table);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9565_1p1_pciephy_clkreq_disable_L1);
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
ar9565_1p1_pciephy_clkreq_disable_L1);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9565_1p1_modes_fast_clock);
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
ar9565_1p1_baseband_core_txfir_coeff_japan_2484);
|
||||
} else if (AR_SREV_9565(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
ar9565_1p0_mac_core);
|
||||
@ -411,7 +455,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
||||
/* Fast clock modal settings */
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9300Modes_fast_clock_2p2);
|
||||
ar9300Modes_fast_clock_2p2);
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
ar9300_2p2_baseband_core_txfir_coeff_japan_2484);
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,7 +486,10 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
|
||||
ar9462_2p1_modes_low_ob_db_tx_gain);
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9462_modes_low_ob_db_tx_gain_table_2p0);
|
||||
ar9462_2p0_modes_low_ob_db_tx_gain);
|
||||
else if (AR_SREV_9565_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p1_modes_low_ob_db_tx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_modes_low_ob_db_tx_gain_table);
|
||||
@ -474,7 +523,10 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
|
||||
ar9462_2p1_modes_high_ob_db_tx_gain);
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9462_modes_high_ob_db_tx_gain_table_2p0);
|
||||
ar9462_2p0_modes_high_ob_db_tx_gain);
|
||||
else if (AR_SREV_9565_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p1_modes_high_ob_db_tx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_modes_high_ob_db_tx_gain_table);
|
||||
@ -500,6 +552,9 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_low_ob_db_tx_gain_table);
|
||||
else if (AR_SREV_9565_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p1_modes_low_ob_db_tx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_modes_low_ob_db_tx_gain_table);
|
||||
@ -525,6 +580,9 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_high_power_tx_gain_table);
|
||||
else if (AR_SREV_9565_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p1_modes_high_power_tx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_modes_high_power_tx_gain_table);
|
||||
@ -546,7 +604,7 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
|
||||
ar9462_2p1_modes_mix_ob_db_tx_gain);
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9462_modes_mix_ob_db_tx_gain_table_2p0);
|
||||
ar9462_2p0_modes_mix_ob_db_tx_gain);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
|
||||
@ -581,6 +639,13 @@ static void ar9003_tx_gain_table_mode6(struct ath_hw *ah)
|
||||
ar9580_1p0_type6_tx_gain_table);
|
||||
}
|
||||
|
||||
static void ar9003_tx_gain_table_mode7(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340_cus227_tx_gain_table_1p0);
|
||||
}
|
||||
|
||||
typedef void (*ath_txgain_tab)(struct ath_hw *ah);
|
||||
|
||||
static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
||||
@ -593,6 +658,7 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
||||
ar9003_tx_gain_table_mode4,
|
||||
ar9003_tx_gain_table_mode5,
|
||||
ar9003_tx_gain_table_mode6,
|
||||
ar9003_tx_gain_table_mode7,
|
||||
};
|
||||
int idx = ar9003_hw_get_tx_gain_idx(ah);
|
||||
|
||||
@ -629,7 +695,10 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
|
||||
ar9462_2p1_common_rx_gain);
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9462_common_rx_gain_table_2p0);
|
||||
ar9462_2p0_common_rx_gain);
|
||||
else if (AR_SREV_9565_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9565_1p1_Common_rx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9565_1p0_Common_rx_gain_table);
|
||||
@ -657,7 +726,7 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
|
||||
ar9462_2p1_common_wo_xlna_rx_gain);
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9462_common_wo_xlna_rx_gain_table_2p0);
|
||||
ar9462_2p0_common_wo_xlna_rx_gain);
|
||||
else if (AR_SREV_9550(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar955x_1p0_common_wo_xlna_rx_gain_table);
|
||||
@ -666,6 +735,9 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
|
||||
} else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9580_1p0_wo_xlna_rx_gain_table);
|
||||
else if (AR_SREV_9565_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9565_1p1_common_wo_xlna_rx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9565_1p0_common_wo_xlna_rx_gain_table);
|
||||
@ -687,7 +759,7 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
|
||||
ar9462_2p1_baseband_postamble_5g_xlna);
|
||||
} else if (AR_SREV_9462_20(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9462_common_mixed_rx_gain_table_2p0);
|
||||
ar9462_2p0_common_mixed_rx_gain);
|
||||
INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
|
||||
ar9462_2p0_baseband_core_mix_rxgain);
|
||||
INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
|
||||
@ -701,12 +773,12 @@ static void ar9003_rx_gain_table_mode3(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9462_21(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9462_2p1_common_5g_xlna_only_rx_gain);
|
||||
ar9462_2p1_common_5g_xlna_only_rxgain);
|
||||
INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
|
||||
ar9462_2p1_baseband_postamble_5g_xlna);
|
||||
} else if (AR_SREV_9462_20(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9462_2p0_5g_xlna_only_rxgain);
|
||||
ar9462_2p0_common_5g_xlna_only_rxgain);
|
||||
INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
|
||||
ar9462_2p0_baseband_postamble_5g_xlna);
|
||||
}
|
||||
@ -750,6 +822,9 @@ static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
|
||||
bool power_off)
|
||||
{
|
||||
unsigned int i;
|
||||
struct ar5416IniArray *array;
|
||||
|
||||
/*
|
||||
* Increase L1 Entry Latency. Some WB222 boards don't have
|
||||
* this change in eeprom/OTP.
|
||||
@ -775,18 +850,13 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
|
||||
* Configire PCIE after Ini init. SERDES values now come from ini file
|
||||
* This enables PCIe low power mode.
|
||||
*/
|
||||
if (ah->config.pcieSerDesWrite) {
|
||||
unsigned int i;
|
||||
struct ar5416IniArray *array;
|
||||
array = power_off ? &ah->iniPcieSerdes :
|
||||
&ah->iniPcieSerdesLowPower;
|
||||
|
||||
array = power_off ? &ah->iniPcieSerdes :
|
||||
&ah->iniPcieSerdesLowPower;
|
||||
|
||||
for (i = 0; i < array->ia_rows; i++) {
|
||||
REG_WRITE(ah,
|
||||
INI_RA(array, i, 0),
|
||||
INI_RA(array, i, 1));
|
||||
}
|
||||
for (i = 0; i < array->ia_rows; i++) {
|
||||
REG_WRITE(ah,
|
||||
INI_RA(array, i, 0),
|
||||
INI_RA(array, i, 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -641,11 +641,12 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
|
||||
else
|
||||
ah->enabled_cals &= ~TX_IQ_CAL;
|
||||
|
||||
if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
|
||||
ah->enabled_cals |= TX_CL_CAL;
|
||||
else
|
||||
ah->enabled_cals &= ~TX_CL_CAL;
|
||||
}
|
||||
|
||||
if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
|
||||
ah->enabled_cals |= TX_CL_CAL;
|
||||
else
|
||||
ah->enabled_cals &= ~TX_CL_CAL;
|
||||
}
|
||||
|
||||
static void ar9003_hw_prog_ini(struct ath_hw *ah,
|
||||
|
422
drivers/net/wireless/ath/ath9k/ar9003_wow.c
Normal file
422
drivers/net/wireless/ath/ath9k/ar9003_wow.c
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Qualcomm Atheros, 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 <linux/export.h>
|
||||
#include "ath9k.h"
|
||||
#include "reg.h"
|
||||
#include "hw-ops.h"
|
||||
|
||||
const char *ath9k_hw_wow_event_to_string(u32 wow_event)
|
||||
{
|
||||
if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
|
||||
return "Magic pattern";
|
||||
if (wow_event & AH_WOW_USER_PATTERN_EN)
|
||||
return "User pattern";
|
||||
if (wow_event & AH_WOW_LINK_CHANGE)
|
||||
return "Link change";
|
||||
if (wow_event & AH_WOW_BEACON_MISS)
|
||||
return "Beacon miss";
|
||||
|
||||
return "unknown reason";
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
|
||||
|
||||
static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
|
||||
|
||||
/* set rx disable bit */
|
||||
REG_WRITE(ah, AR_CR, AR_CR_RXD);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
|
||||
ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
|
||||
REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
|
||||
return;
|
||||
}
|
||||
|
||||
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
|
||||
}
|
||||
|
||||
static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
|
||||
u32 ctl[13] = {0};
|
||||
u32 data_word[KAL_NUM_DATA_WORDS];
|
||||
u8 i;
|
||||
u32 wow_ka_data_word0;
|
||||
|
||||
memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
|
||||
memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
|
||||
|
||||
/* set the transmit buffer */
|
||||
ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
|
||||
ctl[1] = 0;
|
||||
ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
|
||||
ctl[4] = 0;
|
||||
ctl[7] = (ah->txchainmask) << 2;
|
||||
ctl[2] = 0xf << 16; /* tx_tries 0 */
|
||||
|
||||
for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
|
||||
REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
|
||||
|
||||
REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
|
||||
|
||||
data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
|
||||
(KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
|
||||
data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
|
||||
(ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
|
||||
data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
|
||||
(ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
|
||||
data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
|
||||
(sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
|
||||
data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
|
||||
(ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
|
||||
data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
|
||||
|
||||
if (AR_SREV_9462_20(ah)) {
|
||||
/* AR9462 2.0 has an extra descriptor word (time based
|
||||
* discard) compared to other chips */
|
||||
REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
|
||||
wow_ka_data_word0 = AR_WOW_TXBUF(13);
|
||||
} else {
|
||||
wow_ka_data_word0 = AR_WOW_TXBUF(12);
|
||||
}
|
||||
|
||||
for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
|
||||
REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
|
||||
|
||||
}
|
||||
|
||||
void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
|
||||
u8 *user_mask, int pattern_count,
|
||||
int pattern_len)
|
||||
{
|
||||
int i;
|
||||
u32 pattern_val, mask_val;
|
||||
u32 set, clr;
|
||||
|
||||
/* FIXME: should check count by querying the hardware capability */
|
||||
if (pattern_count >= MAX_NUM_PATTERN)
|
||||
return;
|
||||
|
||||
REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
|
||||
|
||||
/* set the registers for pattern */
|
||||
for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
|
||||
memcpy(&pattern_val, user_pattern, 4);
|
||||
REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
|
||||
pattern_val);
|
||||
user_pattern += 4;
|
||||
}
|
||||
|
||||
/* set the registers for mask */
|
||||
for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
|
||||
memcpy(&mask_val, user_mask, 4);
|
||||
REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
|
||||
user_mask += 4;
|
||||
}
|
||||
|
||||
/* set the pattern length to be matched
|
||||
*
|
||||
* AR_WOW_LENGTH1_REG1
|
||||
* bit 31:24 pattern 0 length
|
||||
* bit 23:16 pattern 1 length
|
||||
* bit 15:8 pattern 2 length
|
||||
* bit 7:0 pattern 3 length
|
||||
*
|
||||
* AR_WOW_LENGTH1_REG2
|
||||
* bit 31:24 pattern 4 length
|
||||
* bit 23:16 pattern 5 length
|
||||
* bit 15:8 pattern 6 length
|
||||
* bit 7:0 pattern 7 length
|
||||
*
|
||||
* the below logic writes out the new
|
||||
* pattern length for the corresponding
|
||||
* pattern_count, while masking out the
|
||||
* other fields
|
||||
*/
|
||||
|
||||
ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
|
||||
|
||||
if (pattern_count < 4) {
|
||||
/* Pattern 0-3 uses AR_WOW_LENGTH1 register */
|
||||
set = (pattern_len & AR_WOW_LENGTH_MAX) <<
|
||||
AR_WOW_LEN1_SHIFT(pattern_count);
|
||||
clr = AR_WOW_LENGTH1_MASK(pattern_count);
|
||||
REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
|
||||
} else {
|
||||
/* Pattern 4-7 uses AR_WOW_LENGTH2 register */
|
||||
set = (pattern_len & AR_WOW_LENGTH_MAX) <<
|
||||
AR_WOW_LEN2_SHIFT(pattern_count);
|
||||
clr = AR_WOW_LENGTH2_MASK(pattern_count);
|
||||
REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
|
||||
}
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
|
||||
|
||||
u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
|
||||
{
|
||||
u32 wow_status = 0;
|
||||
u32 val = 0, rval;
|
||||
|
||||
/*
|
||||
* read the WoW status register to know
|
||||
* the wakeup reason
|
||||
*/
|
||||
rval = REG_READ(ah, AR_WOW_PATTERN);
|
||||
val = AR_WOW_STATUS(rval);
|
||||
|
||||
/*
|
||||
* mask only the WoW events that we have enabled. Sometimes
|
||||
* we have spurious WoW events from the AR_WOW_PATTERN
|
||||
* register. This mask will clean it up.
|
||||
*/
|
||||
|
||||
val &= ah->wow_event_mask;
|
||||
|
||||
if (val) {
|
||||
if (val & AR_WOW_MAGIC_PAT_FOUND)
|
||||
wow_status |= AH_WOW_MAGIC_PATTERN_EN;
|
||||
if (AR_WOW_PATTERN_FOUND(val))
|
||||
wow_status |= AH_WOW_USER_PATTERN_EN;
|
||||
if (val & AR_WOW_KEEP_ALIVE_FAIL)
|
||||
wow_status |= AH_WOW_LINK_CHANGE;
|
||||
if (val & AR_WOW_BEACON_FAIL)
|
||||
wow_status |= AH_WOW_BEACON_MISS;
|
||||
}
|
||||
|
||||
/*
|
||||
* set and clear WOW_PME_CLEAR registers for the chip to
|
||||
* generate next wow signal.
|
||||
* disable D3 before accessing other registers ?
|
||||
*/
|
||||
|
||||
/* do we need to check the bit value 0x01000000 (7-10) ?? */
|
||||
REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
|
||||
AR_PMCTRL_PWR_STATE_D1D3);
|
||||
|
||||
/*
|
||||
* clear all events
|
||||
*/
|
||||
REG_WRITE(ah, AR_WOW_PATTERN,
|
||||
AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
|
||||
|
||||
/*
|
||||
* restore the beacon threshold to init value
|
||||
*/
|
||||
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
|
||||
|
||||
/*
|
||||
* Restore the way the PCI-E reset, Power-On-Reset, external
|
||||
* PCIE_POR_SHORT pins are tied to its original value.
|
||||
* Previously just before WoW sleep, we untie the PCI-E
|
||||
* reset to our Chip's Power On Reset so that any PCI-E
|
||||
* reset from the bus will not reset our chip
|
||||
*/
|
||||
if (ah->is_pciexpress)
|
||||
ath9k_hw_configpcipowersave(ah, false);
|
||||
|
||||
ah->wow_event_mask = 0;
|
||||
|
||||
return wow_status;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
|
||||
|
||||
void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
|
||||
{
|
||||
u32 wow_event_mask;
|
||||
u32 set, clr;
|
||||
|
||||
/*
|
||||
* wow_event_mask is a mask to the AR_WOW_PATTERN register to
|
||||
* indicate which WoW events we have enabled. The WoW events
|
||||
* are from the 'pattern_enable' in this function and
|
||||
* 'pattern_count' of ath9k_hw_wow_apply_pattern()
|
||||
*/
|
||||
wow_event_mask = ah->wow_event_mask;
|
||||
|
||||
/*
|
||||
* Untie Power-on-Reset from the PCI-E-Reset. When we are in
|
||||
* WOW sleep, we do want the Reset from the PCI-E to disturb
|
||||
* our hw state
|
||||
*/
|
||||
if (ah->is_pciexpress) {
|
||||
/*
|
||||
* we need to untie the internal POR (power-on-reset)
|
||||
* to the external PCI-E reset. We also need to tie
|
||||
* the PCI-E Phy reset to the PCI-E reset.
|
||||
*/
|
||||
set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
|
||||
clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
|
||||
REG_RMW(ah, AR_WA, set, clr);
|
||||
}
|
||||
|
||||
/*
|
||||
* set the power states appropriately and enable PME
|
||||
*/
|
||||
set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
|
||||
AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
|
||||
|
||||
/*
|
||||
* set and clear WOW_PME_CLEAR registers for the chip
|
||||
* to generate next wow signal.
|
||||
*/
|
||||
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
|
||||
clr = AR_PMCTRL_WOW_PME_CLR;
|
||||
REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
|
||||
|
||||
/*
|
||||
* Setup for:
|
||||
* - beacon misses
|
||||
* - magic pattern
|
||||
* - keep alive timeout
|
||||
* - pattern matching
|
||||
*/
|
||||
|
||||
/*
|
||||
* Program default values for pattern backoff, aifs/slot/KAL count,
|
||||
* beacon miss timeout, KAL timeout, etc.
|
||||
*/
|
||||
set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
|
||||
REG_SET_BIT(ah, AR_WOW_PATTERN, set);
|
||||
|
||||
set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
|
||||
AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
|
||||
AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
|
||||
REG_SET_BIT(ah, AR_WOW_COUNT, set);
|
||||
|
||||
if (pattern_enable & AH_WOW_BEACON_MISS)
|
||||
set = AR_WOW_BEACON_TIMO;
|
||||
/* We are not using beacon miss, program a large value */
|
||||
else
|
||||
set = AR_WOW_BEACON_TIMO_MAX;
|
||||
|
||||
REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
|
||||
|
||||
/*
|
||||
* Keep alive timo in ms except AR9280
|
||||
*/
|
||||
if (!pattern_enable)
|
||||
set = AR_WOW_KEEP_ALIVE_NEVER;
|
||||
else
|
||||
set = KAL_TIMEOUT * 32;
|
||||
|
||||
REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
|
||||
|
||||
/*
|
||||
* Keep alive delay in us. based on 'power on clock',
|
||||
* therefore in usec
|
||||
*/
|
||||
set = KAL_DELAY * 1000;
|
||||
REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
|
||||
|
||||
/*
|
||||
* Create keep alive pattern to respond to beacons
|
||||
*/
|
||||
ath9k_wow_create_keep_alive_pattern(ah);
|
||||
|
||||
/*
|
||||
* Configure MAC WoW Registers
|
||||
*/
|
||||
set = 0;
|
||||
/* Send keep alive timeouts anyway */
|
||||
clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
|
||||
|
||||
if (pattern_enable & AH_WOW_LINK_CHANGE)
|
||||
wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
|
||||
else
|
||||
set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
|
||||
|
||||
set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
|
||||
REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
|
||||
|
||||
/*
|
||||
* we are relying on a bmiss failure. ensure we have
|
||||
* enough threshold to prevent false positives
|
||||
*/
|
||||
REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
|
||||
AR_WOW_BMISSTHRESHOLD);
|
||||
|
||||
set = 0;
|
||||
clr = 0;
|
||||
|
||||
if (pattern_enable & AH_WOW_BEACON_MISS) {
|
||||
set = AR_WOW_BEACON_FAIL_EN;
|
||||
wow_event_mask |= AR_WOW_BEACON_FAIL;
|
||||
} else {
|
||||
clr = AR_WOW_BEACON_FAIL_EN;
|
||||
}
|
||||
|
||||
REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
|
||||
|
||||
set = 0;
|
||||
clr = 0;
|
||||
/*
|
||||
* Enable the magic packet registers
|
||||
*/
|
||||
if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
|
||||
set = AR_WOW_MAGIC_EN;
|
||||
wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
|
||||
} else {
|
||||
clr = AR_WOW_MAGIC_EN;
|
||||
}
|
||||
set |= AR_WOW_MAC_INTR_EN;
|
||||
REG_RMW(ah, AR_WOW_PATTERN, set, clr);
|
||||
|
||||
REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
|
||||
AR_WOW_PATTERN_SUPPORTED);
|
||||
|
||||
/*
|
||||
* Set the power states appropriately and enable PME
|
||||
*/
|
||||
clr = 0;
|
||||
set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
|
||||
AR_PMCTRL_PWR_PM_CTRL_ENA;
|
||||
|
||||
clr = AR_PCIE_PM_CTRL_ENA;
|
||||
REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
|
||||
|
||||
/*
|
||||
* this is needed to prevent the chip waking up
|
||||
* the host within 3-4 seconds with certain
|
||||
* platform/BIOS. The fix is to enable
|
||||
* D1 & D3 to match original definition and
|
||||
* also match the OTP value. Anyway this
|
||||
* is more related to SW WOW.
|
||||
*/
|
||||
clr = AR_PMCTRL_PWR_STATE_D1D3;
|
||||
REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
|
||||
|
||||
set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
|
||||
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
|
||||
|
||||
REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
|
||||
|
||||
/* to bring down WOW power low margin */
|
||||
set = BIT(13);
|
||||
REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
|
||||
/* HW WoW */
|
||||
clr = BIT(5);
|
||||
REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
|
||||
|
||||
ath9k_hw_set_powermode_wow_sleep(ah);
|
||||
ah->wow_event_mask = wow_event_mask;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_wow_enable);
|
@ -18,6 +18,18 @@
|
||||
#ifndef INITVALS_9340_H
|
||||
#define INITVALS_9340_H
|
||||
|
||||
#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble
|
||||
|
||||
#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble
|
||||
|
||||
#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2
|
||||
|
||||
#define ar9340Common_rx_gain_table_1p0 ar9300Common_rx_gain_table_2p2
|
||||
|
||||
#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2
|
||||
|
||||
#define ar9340_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
static const u32 ar9340_1p0_radio_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
|
||||
@ -100,8 +112,6 @@ static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
|
||||
{0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
|
||||
};
|
||||
|
||||
#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2
|
||||
|
||||
static const u32 ar9340_1p0_radio_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00016000, 0x36db6db6},
|
||||
@ -215,16 +225,12 @@ static const u32 ar9340_1p0_radio_core_40M[][2] = {
|
||||
{0x0000824c, 0x0001e800},
|
||||
};
|
||||
|
||||
#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble
|
||||
|
||||
#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble
|
||||
|
||||
static const u32 ar9340_1p0_baseband_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
|
||||
{0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
|
||||
{0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
|
||||
{0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
|
||||
{0x00009828, 0x06903081, 0x06903081, 0x09103881, 0x09103881},
|
||||
{0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
|
||||
{0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
|
||||
{0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
|
||||
@ -340,9 +346,9 @@ static const u32 ar9340_1p0_baseband_core[][2] = {
|
||||
{0x0000a370, 0x00000000},
|
||||
{0x0000a390, 0x00000001},
|
||||
{0x0000a394, 0x00000444},
|
||||
{0x0000a398, 0x001f0e0f},
|
||||
{0x0000a39c, 0x0075393f},
|
||||
{0x0000a3a0, 0xb79f6427},
|
||||
{0x0000a398, 0x00000000},
|
||||
{0x0000a39c, 0x210d0401},
|
||||
{0x0000a3a0, 0xab9a7144},
|
||||
{0x0000a3a4, 0x00000000},
|
||||
{0x0000a3a8, 0xaaaaaaaa},
|
||||
{0x0000a3ac, 0x3c466478},
|
||||
@ -714,266 +720,6 @@ static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
|
||||
{0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000},
|
||||
};
|
||||
|
||||
static const u32 ar9340Common_rx_gain_table_1p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
{0x0000a008, 0x00050004},
|
||||
{0x0000a00c, 0x00810080},
|
||||
{0x0000a010, 0x00830082},
|
||||
{0x0000a014, 0x01810180},
|
||||
{0x0000a018, 0x01830182},
|
||||
{0x0000a01c, 0x01850184},
|
||||
{0x0000a020, 0x01890188},
|
||||
{0x0000a024, 0x018b018a},
|
||||
{0x0000a028, 0x018d018c},
|
||||
{0x0000a02c, 0x01910190},
|
||||
{0x0000a030, 0x01930192},
|
||||
{0x0000a034, 0x01950194},
|
||||
{0x0000a038, 0x038a0196},
|
||||
{0x0000a03c, 0x038c038b},
|
||||
{0x0000a040, 0x0390038d},
|
||||
{0x0000a044, 0x03920391},
|
||||
{0x0000a048, 0x03940393},
|
||||
{0x0000a04c, 0x03960395},
|
||||
{0x0000a050, 0x00000000},
|
||||
{0x0000a054, 0x00000000},
|
||||
{0x0000a058, 0x00000000},
|
||||
{0x0000a05c, 0x00000000},
|
||||
{0x0000a060, 0x00000000},
|
||||
{0x0000a064, 0x00000000},
|
||||
{0x0000a068, 0x00000000},
|
||||
{0x0000a06c, 0x00000000},
|
||||
{0x0000a070, 0x00000000},
|
||||
{0x0000a074, 0x00000000},
|
||||
{0x0000a078, 0x00000000},
|
||||
{0x0000a07c, 0x00000000},
|
||||
{0x0000a080, 0x22222229},
|
||||
{0x0000a084, 0x1d1d1d1d},
|
||||
{0x0000a088, 0x1d1d1d1d},
|
||||
{0x0000a08c, 0x1d1d1d1d},
|
||||
{0x0000a090, 0x171d1d1d},
|
||||
{0x0000a094, 0x11111717},
|
||||
{0x0000a098, 0x00030311},
|
||||
{0x0000a09c, 0x00000000},
|
||||
{0x0000a0a0, 0x00000000},
|
||||
{0x0000a0a4, 0x00000000},
|
||||
{0x0000a0a8, 0x00000000},
|
||||
{0x0000a0ac, 0x00000000},
|
||||
{0x0000a0b0, 0x00000000},
|
||||
{0x0000a0b4, 0x00000000},
|
||||
{0x0000a0b8, 0x00000000},
|
||||
{0x0000a0bc, 0x00000000},
|
||||
{0x0000a0c0, 0x001f0000},
|
||||
{0x0000a0c4, 0x01000101},
|
||||
{0x0000a0c8, 0x011e011f},
|
||||
{0x0000a0cc, 0x011c011d},
|
||||
{0x0000a0d0, 0x02030204},
|
||||
{0x0000a0d4, 0x02010202},
|
||||
{0x0000a0d8, 0x021f0200},
|
||||
{0x0000a0dc, 0x0302021e},
|
||||
{0x0000a0e0, 0x03000301},
|
||||
{0x0000a0e4, 0x031e031f},
|
||||
{0x0000a0e8, 0x0402031d},
|
||||
{0x0000a0ec, 0x04000401},
|
||||
{0x0000a0f0, 0x041e041f},
|
||||
{0x0000a0f4, 0x0502041d},
|
||||
{0x0000a0f8, 0x05000501},
|
||||
{0x0000a0fc, 0x051e051f},
|
||||
{0x0000a100, 0x06010602},
|
||||
{0x0000a104, 0x061f0600},
|
||||
{0x0000a108, 0x061d061e},
|
||||
{0x0000a10c, 0x07020703},
|
||||
{0x0000a110, 0x07000701},
|
||||
{0x0000a114, 0x00000000},
|
||||
{0x0000a118, 0x00000000},
|
||||
{0x0000a11c, 0x00000000},
|
||||
{0x0000a120, 0x00000000},
|
||||
{0x0000a124, 0x00000000},
|
||||
{0x0000a128, 0x00000000},
|
||||
{0x0000a12c, 0x00000000},
|
||||
{0x0000a130, 0x00000000},
|
||||
{0x0000a134, 0x00000000},
|
||||
{0x0000a138, 0x00000000},
|
||||
{0x0000a13c, 0x00000000},
|
||||
{0x0000a140, 0x001f0000},
|
||||
{0x0000a144, 0x01000101},
|
||||
{0x0000a148, 0x011e011f},
|
||||
{0x0000a14c, 0x011c011d},
|
||||
{0x0000a150, 0x02030204},
|
||||
{0x0000a154, 0x02010202},
|
||||
{0x0000a158, 0x021f0200},
|
||||
{0x0000a15c, 0x0302021e},
|
||||
{0x0000a160, 0x03000301},
|
||||
{0x0000a164, 0x031e031f},
|
||||
{0x0000a168, 0x0402031d},
|
||||
{0x0000a16c, 0x04000401},
|
||||
{0x0000a170, 0x041e041f},
|
||||
{0x0000a174, 0x0502041d},
|
||||
{0x0000a178, 0x05000501},
|
||||
{0x0000a17c, 0x051e051f},
|
||||
{0x0000a180, 0x06010602},
|
||||
{0x0000a184, 0x061f0600},
|
||||
{0x0000a188, 0x061d061e},
|
||||
{0x0000a18c, 0x07020703},
|
||||
{0x0000a190, 0x07000701},
|
||||
{0x0000a194, 0x00000000},
|
||||
{0x0000a198, 0x00000000},
|
||||
{0x0000a19c, 0x00000000},
|
||||
{0x0000a1a0, 0x00000000},
|
||||
{0x0000a1a4, 0x00000000},
|
||||
{0x0000a1a8, 0x00000000},
|
||||
{0x0000a1ac, 0x00000000},
|
||||
{0x0000a1b0, 0x00000000},
|
||||
{0x0000a1b4, 0x00000000},
|
||||
{0x0000a1b8, 0x00000000},
|
||||
{0x0000a1bc, 0x00000000},
|
||||
{0x0000a1c0, 0x00000000},
|
||||
{0x0000a1c4, 0x00000000},
|
||||
{0x0000a1c8, 0x00000000},
|
||||
{0x0000a1cc, 0x00000000},
|
||||
{0x0000a1d0, 0x00000000},
|
||||
{0x0000a1d4, 0x00000000},
|
||||
{0x0000a1d8, 0x00000000},
|
||||
{0x0000a1dc, 0x00000000},
|
||||
{0x0000a1e0, 0x00000000},
|
||||
{0x0000a1e4, 0x00000000},
|
||||
{0x0000a1e8, 0x00000000},
|
||||
{0x0000a1ec, 0x00000000},
|
||||
{0x0000a1f0, 0x00000396},
|
||||
{0x0000a1f4, 0x00000396},
|
||||
{0x0000a1f8, 0x00000396},
|
||||
{0x0000a1fc, 0x00000196},
|
||||
{0x0000b000, 0x00010000},
|
||||
{0x0000b004, 0x00030002},
|
||||
{0x0000b008, 0x00050004},
|
||||
{0x0000b00c, 0x00810080},
|
||||
{0x0000b010, 0x00830082},
|
||||
{0x0000b014, 0x01810180},
|
||||
{0x0000b018, 0x01830182},
|
||||
{0x0000b01c, 0x01850184},
|
||||
{0x0000b020, 0x02810280},
|
||||
{0x0000b024, 0x02830282},
|
||||
{0x0000b028, 0x02850284},
|
||||
{0x0000b02c, 0x02890288},
|
||||
{0x0000b030, 0x028b028a},
|
||||
{0x0000b034, 0x0388028c},
|
||||
{0x0000b038, 0x038a0389},
|
||||
{0x0000b03c, 0x038c038b},
|
||||
{0x0000b040, 0x0390038d},
|
||||
{0x0000b044, 0x03920391},
|
||||
{0x0000b048, 0x03940393},
|
||||
{0x0000b04c, 0x03960395},
|
||||
{0x0000b050, 0x00000000},
|
||||
{0x0000b054, 0x00000000},
|
||||
{0x0000b058, 0x00000000},
|
||||
{0x0000b05c, 0x00000000},
|
||||
{0x0000b060, 0x00000000},
|
||||
{0x0000b064, 0x00000000},
|
||||
{0x0000b068, 0x00000000},
|
||||
{0x0000b06c, 0x00000000},
|
||||
{0x0000b070, 0x00000000},
|
||||
{0x0000b074, 0x00000000},
|
||||
{0x0000b078, 0x00000000},
|
||||
{0x0000b07c, 0x00000000},
|
||||
{0x0000b080, 0x23232323},
|
||||
{0x0000b084, 0x21232323},
|
||||
{0x0000b088, 0x19191c1e},
|
||||
{0x0000b08c, 0x12141417},
|
||||
{0x0000b090, 0x07070e0e},
|
||||
{0x0000b094, 0x03030305},
|
||||
{0x0000b098, 0x00000003},
|
||||
{0x0000b09c, 0x00000000},
|
||||
{0x0000b0a0, 0x00000000},
|
||||
{0x0000b0a4, 0x00000000},
|
||||
{0x0000b0a8, 0x00000000},
|
||||
{0x0000b0ac, 0x00000000},
|
||||
{0x0000b0b0, 0x00000000},
|
||||
{0x0000b0b4, 0x00000000},
|
||||
{0x0000b0b8, 0x00000000},
|
||||
{0x0000b0bc, 0x00000000},
|
||||
{0x0000b0c0, 0x003f0020},
|
||||
{0x0000b0c4, 0x00400041},
|
||||
{0x0000b0c8, 0x0140005f},
|
||||
{0x0000b0cc, 0x0160015f},
|
||||
{0x0000b0d0, 0x017e017f},
|
||||
{0x0000b0d4, 0x02410242},
|
||||
{0x0000b0d8, 0x025f0240},
|
||||
{0x0000b0dc, 0x027f0260},
|
||||
{0x0000b0e0, 0x0341027e},
|
||||
{0x0000b0e4, 0x035f0340},
|
||||
{0x0000b0e8, 0x037f0360},
|
||||
{0x0000b0ec, 0x04400441},
|
||||
{0x0000b0f0, 0x0460045f},
|
||||
{0x0000b0f4, 0x0541047f},
|
||||
{0x0000b0f8, 0x055f0540},
|
||||
{0x0000b0fc, 0x057f0560},
|
||||
{0x0000b100, 0x06400641},
|
||||
{0x0000b104, 0x0660065f},
|
||||
{0x0000b108, 0x067e067f},
|
||||
{0x0000b10c, 0x07410742},
|
||||
{0x0000b110, 0x075f0740},
|
||||
{0x0000b114, 0x077f0760},
|
||||
{0x0000b118, 0x07800781},
|
||||
{0x0000b11c, 0x07a0079f},
|
||||
{0x0000b120, 0x07c107bf},
|
||||
{0x0000b124, 0x000007c0},
|
||||
{0x0000b128, 0x00000000},
|
||||
{0x0000b12c, 0x00000000},
|
||||
{0x0000b130, 0x00000000},
|
||||
{0x0000b134, 0x00000000},
|
||||
{0x0000b138, 0x00000000},
|
||||
{0x0000b13c, 0x00000000},
|
||||
{0x0000b140, 0x003f0020},
|
||||
{0x0000b144, 0x00400041},
|
||||
{0x0000b148, 0x0140005f},
|
||||
{0x0000b14c, 0x0160015f},
|
||||
{0x0000b150, 0x017e017f},
|
||||
{0x0000b154, 0x02410242},
|
||||
{0x0000b158, 0x025f0240},
|
||||
{0x0000b15c, 0x027f0260},
|
||||
{0x0000b160, 0x0341027e},
|
||||
{0x0000b164, 0x035f0340},
|
||||
{0x0000b168, 0x037f0360},
|
||||
{0x0000b16c, 0x04400441},
|
||||
{0x0000b170, 0x0460045f},
|
||||
{0x0000b174, 0x0541047f},
|
||||
{0x0000b178, 0x055f0540},
|
||||
{0x0000b17c, 0x057f0560},
|
||||
{0x0000b180, 0x06400641},
|
||||
{0x0000b184, 0x0660065f},
|
||||
{0x0000b188, 0x067e067f},
|
||||
{0x0000b18c, 0x07410742},
|
||||
{0x0000b190, 0x075f0740},
|
||||
{0x0000b194, 0x077f0760},
|
||||
{0x0000b198, 0x07800781},
|
||||
{0x0000b19c, 0x07a0079f},
|
||||
{0x0000b1a0, 0x07c107bf},
|
||||
{0x0000b1a4, 0x000007c0},
|
||||
{0x0000b1a8, 0x00000000},
|
||||
{0x0000b1ac, 0x00000000},
|
||||
{0x0000b1b0, 0x00000000},
|
||||
{0x0000b1b4, 0x00000000},
|
||||
{0x0000b1b8, 0x00000000},
|
||||
{0x0000b1bc, 0x00000000},
|
||||
{0x0000b1c0, 0x00000000},
|
||||
{0x0000b1c4, 0x00000000},
|
||||
{0x0000b1c8, 0x00000000},
|
||||
{0x0000b1cc, 0x00000000},
|
||||
{0x0000b1d0, 0x00000000},
|
||||
{0x0000b1d4, 0x00000000},
|
||||
{0x0000b1d8, 0x00000000},
|
||||
{0x0000b1dc, 0x00000000},
|
||||
{0x0000b1e0, 0x00000000},
|
||||
{0x0000b1e4, 0x00000000},
|
||||
{0x0000b1e8, 0x00000000},
|
||||
{0x0000b1ec, 0x00000000},
|
||||
{0x0000b1f0, 0x00000396},
|
||||
{0x0000b1f4, 0x00000396},
|
||||
{0x0000b1f8, 0x00000396},
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
@ -1437,8 +1183,6 @@ static const u32 ar9340_1p0_mac_core[][2] = {
|
||||
{0x000083d0, 0x000101ff},
|
||||
};
|
||||
|
||||
#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2
|
||||
|
||||
static const u32 ar9340_1p0_soc_preamble[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00007008, 0x00000000},
|
||||
@ -1447,4 +1191,106 @@ static const u32 ar9340_1p0_soc_preamble[][2] = {
|
||||
{0x00007038, 0x000004c2},
|
||||
};
|
||||
|
||||
static const u32 ar9340_cus227_tx_gain_table_1p0[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
|
||||
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
|
||||
{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
|
||||
{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
|
||||
{0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
|
||||
{0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402},
|
||||
{0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
|
||||
{0x0000a520, 0x2c022220, 0x2c022220, 0x1b000603, 0x1b000603},
|
||||
{0x0000a524, 0x30022222, 0x30022222, 0x1f000a02, 0x1f000a02},
|
||||
{0x0000a528, 0x35022225, 0x35022225, 0x23000a04, 0x23000a04},
|
||||
{0x0000a52c, 0x3b02222a, 0x3b02222a, 0x26000a20, 0x26000a20},
|
||||
{0x0000a530, 0x3f02222c, 0x3f02222c, 0x2a000e20, 0x2a000e20},
|
||||
{0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
|
||||
{0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
|
||||
{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
|
||||
{0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
|
||||
{0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
|
||||
{0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
|
||||
{0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83},
|
||||
{0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84},
|
||||
{0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3},
|
||||
{0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5},
|
||||
{0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9},
|
||||
{0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb},
|
||||
{0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
|
||||
{0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
|
||||
{0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
|
||||
{0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
|
||||
{0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
|
||||
{0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
|
||||
{0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
|
||||
{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
|
||||
{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
|
||||
{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
|
||||
{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
|
||||
{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
|
||||
{0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
|
||||
{0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402},
|
||||
{0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
|
||||
{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
|
||||
{0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
|
||||
{0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
|
||||
{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
|
||||
{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
|
||||
{0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
|
||||
{0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
|
||||
{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
|
||||
{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
|
||||
{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
|
||||
{0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
|
||||
{0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83},
|
||||
{0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84},
|
||||
{0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3},
|
||||
{0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5},
|
||||
{0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9},
|
||||
{0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb},
|
||||
{0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
|
||||
{0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
|
||||
{0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
|
||||
{0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
|
||||
{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
|
||||
{0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
|
||||
{0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
|
||||
{0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
|
||||
{0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
|
||||
{0x00016048, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
|
||||
{0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015},
|
||||
{0x00016288, 0x30318000, 0x30318000, 0x00318000, 0x00318000},
|
||||
{0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
|
||||
{0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
|
||||
{0x0000a3a4, 0x00000011, 0x00000011, 0x00000011, 0x00000011},
|
||||
{0x0000a3a8, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c},
|
||||
{0x0000a3ac, 0x30303030, 0x30303030, 0x30303030, 0x30303030},
|
||||
};
|
||||
|
||||
#endif /* INITVALS_9340_H */
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
/* AR9462 2.0 */
|
||||
|
||||
static const u32 ar9462_modes_fast_clock_2p0[][3] = {
|
||||
static const u32 ar9462_2p0_modes_fast_clock[][3] = {
|
||||
/* Addr 5G_HT20 5G_HT40 */
|
||||
{0x00001030, 0x00000268, 0x000004d0},
|
||||
{0x00001070, 0x0000018c, 0x00000318},
|
||||
@ -33,13 +33,6 @@ static const u32 ar9462_modes_fast_clock_2p0[][3] = {
|
||||
{0x0000a254, 0x00000898, 0x00001130},
|
||||
};
|
||||
|
||||
static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18253ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003780c},
|
||||
};
|
||||
|
||||
static const u32 ar9462_2p0_baseband_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
|
||||
@ -99,7 +92,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
|
||||
{0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
|
||||
};
|
||||
|
||||
static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
|
||||
static const u32 ar9462_2p0_common_rx_gain[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -359,20 +352,13 @@ static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = {
|
||||
static const u32 ar9462_2p0_pciephy_clkreq_disable_L1[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18213ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003780c},
|
||||
};
|
||||
|
||||
static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18212ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003780c},
|
||||
};
|
||||
|
||||
static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
|
||||
@ -380,7 +366,7 @@ static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
|
||||
{0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
};
|
||||
|
||||
static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = {
|
||||
static const u32 ar9462_2p0_common_wo_xlna_rx_gain[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -647,7 +633,7 @@ static const u32 ar9462_2p0_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
{0x0000a3a0, 0xca9228ee},
|
||||
};
|
||||
|
||||
static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = {
|
||||
static const u32 ar9462_2p0_modes_low_ob_db_tx_gain[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
|
||||
{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
@ -879,7 +865,7 @@ static const u32 ar9462_2p0_radio_postamble[][5] = {
|
||||
{0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
|
||||
};
|
||||
|
||||
static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
|
||||
static const u32 ar9462_2p0_modes_mix_ob_db_tx_gain[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
|
||||
{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
|
||||
@ -942,7 +928,7 @@ static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
|
||||
{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
};
|
||||
|
||||
static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
|
||||
static const u32 ar9462_2p0_modes_high_ob_db_tx_gain[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
|
||||
{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
|
||||
@ -1252,7 +1238,7 @@ static const u32 ar9462_2p0_mac_postamble[][5] = {
|
||||
{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
|
||||
};
|
||||
|
||||
static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
|
||||
static const u32 ar9462_2p0_common_mixed_rx_gain[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -1517,7 +1503,7 @@ static const u32 ar9462_2p0_baseband_postamble_5g_xlna[][5] = {
|
||||
{0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
|
||||
};
|
||||
|
||||
static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = {
|
||||
static const u32 ar9462_2p0_common_5g_xlna_only_rxgain[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
|
File diff suppressed because it is too large
Load Diff
64
drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h
Normal file
64
drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2012 Qualcomm Atheros 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.
|
||||
*/
|
||||
|
||||
#ifndef INITVALS_9565_1P1_H
|
||||
#define INITVALS_9565_1P1_H
|
||||
|
||||
/* AR9565 1.1 */
|
||||
|
||||
#define ar9565_1p1_mac_core ar9565_1p0_mac_core
|
||||
|
||||
#define ar9565_1p1_mac_postamble ar9565_1p0_mac_postamble
|
||||
|
||||
#define ar9565_1p1_baseband_core ar9565_1p0_baseband_core
|
||||
|
||||
#define ar9565_1p1_baseband_postamble ar9565_1p0_baseband_postamble
|
||||
|
||||
#define ar9565_1p1_radio_core ar9565_1p0_radio_core
|
||||
|
||||
#define ar9565_1p1_soc_preamble ar9565_1p0_soc_preamble
|
||||
|
||||
#define ar9565_1p1_soc_postamble ar9565_1p0_soc_postamble
|
||||
|
||||
#define ar9565_1p1_Common_rx_gain_table ar9565_1p0_Common_rx_gain_table
|
||||
|
||||
#define ar9565_1p1_Modes_lowest_ob_db_tx_gain_table ar9565_1p0_Modes_lowest_ob_db_tx_gain_table
|
||||
|
||||
#define ar9565_1p1_pciephy_clkreq_disable_L1 ar9565_1p0_pciephy_clkreq_disable_L1
|
||||
|
||||
#define ar9565_1p1_modes_fast_clock ar9565_1p0_modes_fast_clock
|
||||
|
||||
#define ar9565_1p1_common_wo_xlna_rx_gain_table ar9565_1p0_common_wo_xlna_rx_gain_table
|
||||
|
||||
#define ar9565_1p1_modes_low_ob_db_tx_gain_table ar9565_1p0_modes_low_ob_db_tx_gain_table
|
||||
|
||||
#define ar9565_1p1_modes_high_ob_db_tx_gain_table ar9565_1p0_modes_high_ob_db_tx_gain_table
|
||||
|
||||
#define ar9565_1p1_modes_high_power_tx_gain_table ar9565_1p0_modes_high_power_tx_gain_table
|
||||
|
||||
#define ar9565_1p1_baseband_core_txfir_coeff_japan_2484 ar9565_1p0_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
static const u32 ar9565_1p1_radio_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
|
||||
{0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
|
||||
{0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
|
||||
{0x0001610c, 0x40000000, 0x40000000, 0x40000000, 0x40000000},
|
||||
{0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
};
|
||||
|
||||
#endif /* INITVALS_9565_1P1_H */
|
@ -20,18 +20,34 @@
|
||||
|
||||
/* AR9580 1.0 */
|
||||
|
||||
#define ar9580_1p0_soc_preamble ar9300_2p2_soc_preamble
|
||||
|
||||
#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
|
||||
|
||||
#define ar9580_1p0_radio_core ar9300_2p2_radio_core
|
||||
|
||||
#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
|
||||
|
||||
#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
|
||||
|
||||
#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
|
||||
|
||||
#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
|
||||
|
||||
#define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2
|
||||
|
||||
#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
static const u32 ar9580_1p0_radio_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
|
||||
{0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
|
||||
{0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
|
||||
{0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0001610c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
|
||||
{0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
{0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0001650c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
|
||||
{0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
{0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0001690c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
|
||||
{0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
};
|
||||
|
||||
@ -44,9 +60,9 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
|
||||
{0x00009814, 0x3280c00a},
|
||||
{0x00009818, 0x00000000},
|
||||
{0x0000981c, 0x00020028},
|
||||
{0x00009834, 0x6400a290},
|
||||
{0x00009834, 0x6400a190},
|
||||
{0x00009838, 0x0108ecff},
|
||||
{0x0000983c, 0x0d000600},
|
||||
{0x0000983c, 0x14000600},
|
||||
{0x00009880, 0x201fff00},
|
||||
{0x00009884, 0x00001042},
|
||||
{0x000098a4, 0x00200400},
|
||||
@ -67,7 +83,7 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
|
||||
{0x00009d04, 0x40206c10},
|
||||
{0x00009d08, 0x009c4060},
|
||||
{0x00009d0c, 0x9883800a},
|
||||
{0x00009d10, 0x01834061},
|
||||
{0x00009d10, 0x01884061},
|
||||
{0x00009d14, 0x00c0040b},
|
||||
{0x00009d18, 0x00000000},
|
||||
{0x00009e08, 0x0038230c},
|
||||
@ -198,8 +214,6 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
|
||||
{0x0000c420, 0x00000000},
|
||||
};
|
||||
|
||||
#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
|
||||
|
||||
static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
@ -306,7 +320,112 @@ static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
#define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table
|
||||
static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
|
||||
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
|
||||
{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
|
||||
{0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
|
||||
{0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
|
||||
{0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
|
||||
{0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
|
||||
{0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
|
||||
{0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
|
||||
{0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
|
||||
{0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
|
||||
{0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
|
||||
{0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
|
||||
{0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
|
||||
{0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
|
||||
{0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
|
||||
{0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
|
||||
{0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
|
||||
{0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
|
||||
{0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
|
||||
{0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
|
||||
{0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
|
||||
{0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
|
||||
{0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
|
||||
{0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
|
||||
{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
|
||||
{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
|
||||
{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
|
||||
{0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
|
||||
{0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
|
||||
{0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
|
||||
{0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
|
||||
{0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
|
||||
{0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
|
||||
{0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
|
||||
{0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
|
||||
{0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
|
||||
{0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
|
||||
{0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
|
||||
{0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
|
||||
{0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
|
||||
{0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
|
||||
{0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
|
||||
{0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
|
||||
{0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
|
||||
{0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
|
||||
{0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
|
||||
{0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
|
||||
{0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
|
||||
{0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
|
||||
{0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
|
||||
{0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
|
||||
{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
|
||||
{0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
|
||||
{0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
|
||||
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
{0x00016288, 0x05a2040a, 0x05a2040a, 0x05a20408, 0x05a20408},
|
||||
{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
|
||||
{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
@ -414,8 +533,6 @@ static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
static const u32 ar9580_1p0_mac_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00000008, 0x00000000},
|
||||
@ -679,14 +796,6 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = {
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
|
||||
|
||||
#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
|
||||
|
||||
#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
|
||||
|
||||
#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
|
||||
|
||||
static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
|
||||
@ -761,160 +870,264 @@ static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
static const u32 ar9580_1p0_soc_preamble[][2] = {
|
||||
static const u32 ar9580_1p0_rx_gain_table[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000040a4, 0x00a0c1c9},
|
||||
{0x00007008, 0x00000000},
|
||||
{0x00007020, 0x00000000},
|
||||
{0x00007034, 0x00000002},
|
||||
{0x00007038, 0x000004c2},
|
||||
{0x00007048, 0x00000008},
|
||||
};
|
||||
|
||||
#define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0
|
||||
|
||||
static const u32 ar9580_1p0_radio_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00016000, 0x36db6db6},
|
||||
{0x00016004, 0x6db6db40},
|
||||
{0x00016008, 0x73f00000},
|
||||
{0x0001600c, 0x00000000},
|
||||
{0x00016040, 0x7f80fff8},
|
||||
{0x0001604c, 0x76d005b5},
|
||||
{0x00016050, 0x556cf031},
|
||||
{0x00016054, 0x13449440},
|
||||
{0x00016058, 0x0c51c92c},
|
||||
{0x0001605c, 0x3db7fffc},
|
||||
{0x00016060, 0xfffffffc},
|
||||
{0x00016064, 0x000f0278},
|
||||
{0x0001606c, 0x6db60000},
|
||||
{0x00016080, 0x00000000},
|
||||
{0x00016084, 0x0e48048c},
|
||||
{0x00016088, 0x54214514},
|
||||
{0x0001608c, 0x119f481e},
|
||||
{0x00016090, 0x24926490},
|
||||
{0x00016098, 0xd2888888},
|
||||
{0x000160a0, 0x0a108ffe},
|
||||
{0x000160a4, 0x812fc370},
|
||||
{0x000160a8, 0x423c8000},
|
||||
{0x000160b4, 0x92480080},
|
||||
{0x000160c0, 0x00adb6d0},
|
||||
{0x000160c4, 0x6db6db60},
|
||||
{0x000160c8, 0x6db6db6c},
|
||||
{0x000160cc, 0x01e6c000},
|
||||
{0x00016100, 0x3fffbe01},
|
||||
{0x00016104, 0xfff80000},
|
||||
{0x00016108, 0x00080010},
|
||||
{0x00016144, 0x02084080},
|
||||
{0x00016148, 0x00000000},
|
||||
{0x00016280, 0x058a0001},
|
||||
{0x00016284, 0x3d840208},
|
||||
{0x00016288, 0x05a20408},
|
||||
{0x0001628c, 0x00038c07},
|
||||
{0x00016290, 0x00000004},
|
||||
{0x00016294, 0x458aa14f},
|
||||
{0x00016380, 0x00000000},
|
||||
{0x00016384, 0x00000000},
|
||||
{0x00016388, 0x00800700},
|
||||
{0x0001638c, 0x00800700},
|
||||
{0x00016390, 0x00800700},
|
||||
{0x00016394, 0x00000000},
|
||||
{0x00016398, 0x00000000},
|
||||
{0x0001639c, 0x00000000},
|
||||
{0x000163a0, 0x00000001},
|
||||
{0x000163a4, 0x00000001},
|
||||
{0x000163a8, 0x00000000},
|
||||
{0x000163ac, 0x00000000},
|
||||
{0x000163b0, 0x00000000},
|
||||
{0x000163b4, 0x00000000},
|
||||
{0x000163b8, 0x00000000},
|
||||
{0x000163bc, 0x00000000},
|
||||
{0x000163c0, 0x000000a0},
|
||||
{0x000163c4, 0x000c0000},
|
||||
{0x000163c8, 0x14021402},
|
||||
{0x000163cc, 0x00001402},
|
||||
{0x000163d0, 0x00000000},
|
||||
{0x000163d4, 0x00000000},
|
||||
{0x00016400, 0x36db6db6},
|
||||
{0x00016404, 0x6db6db40},
|
||||
{0x00016408, 0x73f00000},
|
||||
{0x0001640c, 0x00000000},
|
||||
{0x00016440, 0x7f80fff8},
|
||||
{0x0001644c, 0x76d005b5},
|
||||
{0x00016450, 0x556cf031},
|
||||
{0x00016454, 0x13449440},
|
||||
{0x00016458, 0x0c51c92c},
|
||||
{0x0001645c, 0x3db7fffc},
|
||||
{0x00016460, 0xfffffffc},
|
||||
{0x00016464, 0x000f0278},
|
||||
{0x0001646c, 0x6db60000},
|
||||
{0x00016500, 0x3fffbe01},
|
||||
{0x00016504, 0xfff80000},
|
||||
{0x00016508, 0x00080010},
|
||||
{0x00016544, 0x02084080},
|
||||
{0x00016548, 0x00000000},
|
||||
{0x00016780, 0x00000000},
|
||||
{0x00016784, 0x00000000},
|
||||
{0x00016788, 0x00800700},
|
||||
{0x0001678c, 0x00800700},
|
||||
{0x00016790, 0x00800700},
|
||||
{0x00016794, 0x00000000},
|
||||
{0x00016798, 0x00000000},
|
||||
{0x0001679c, 0x00000000},
|
||||
{0x000167a0, 0x00000001},
|
||||
{0x000167a4, 0x00000001},
|
||||
{0x000167a8, 0x00000000},
|
||||
{0x000167ac, 0x00000000},
|
||||
{0x000167b0, 0x00000000},
|
||||
{0x000167b4, 0x00000000},
|
||||
{0x000167b8, 0x00000000},
|
||||
{0x000167bc, 0x00000000},
|
||||
{0x000167c0, 0x000000a0},
|
||||
{0x000167c4, 0x000c0000},
|
||||
{0x000167c8, 0x14021402},
|
||||
{0x000167cc, 0x00001402},
|
||||
{0x000167d0, 0x00000000},
|
||||
{0x000167d4, 0x00000000},
|
||||
{0x00016800, 0x36db6db6},
|
||||
{0x00016804, 0x6db6db40},
|
||||
{0x00016808, 0x73f00000},
|
||||
{0x0001680c, 0x00000000},
|
||||
{0x00016840, 0x7f80fff8},
|
||||
{0x0001684c, 0x76d005b5},
|
||||
{0x00016850, 0x556cf031},
|
||||
{0x00016854, 0x13449440},
|
||||
{0x00016858, 0x0c51c92c},
|
||||
{0x0001685c, 0x3db7fffc},
|
||||
{0x00016860, 0xfffffffc},
|
||||
{0x00016864, 0x000f0278},
|
||||
{0x0001686c, 0x6db60000},
|
||||
{0x00016900, 0x3fffbe01},
|
||||
{0x00016904, 0xfff80000},
|
||||
{0x00016908, 0x00080010},
|
||||
{0x00016944, 0x02084080},
|
||||
{0x00016948, 0x00000000},
|
||||
{0x00016b80, 0x00000000},
|
||||
{0x00016b84, 0x00000000},
|
||||
{0x00016b88, 0x00800700},
|
||||
{0x00016b8c, 0x00800700},
|
||||
{0x00016b90, 0x00800700},
|
||||
{0x00016b94, 0x00000000},
|
||||
{0x00016b98, 0x00000000},
|
||||
{0x00016b9c, 0x00000000},
|
||||
{0x00016ba0, 0x00000001},
|
||||
{0x00016ba4, 0x00000001},
|
||||
{0x00016ba8, 0x00000000},
|
||||
{0x00016bac, 0x00000000},
|
||||
{0x00016bb0, 0x00000000},
|
||||
{0x00016bb4, 0x00000000},
|
||||
{0x00016bb8, 0x00000000},
|
||||
{0x00016bbc, 0x00000000},
|
||||
{0x00016bc0, 0x000000a0},
|
||||
{0x00016bc4, 0x000c0000},
|
||||
{0x00016bc8, 0x14021402},
|
||||
{0x00016bcc, 0x00001402},
|
||||
{0x00016bd0, 0x00000000},
|
||||
{0x00016bd4, 0x00000000},
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
{0x0000a008, 0x00050004},
|
||||
{0x0000a00c, 0x00810080},
|
||||
{0x0000a010, 0x00830082},
|
||||
{0x0000a014, 0x01810180},
|
||||
{0x0000a018, 0x01830182},
|
||||
{0x0000a01c, 0x01850184},
|
||||
{0x0000a020, 0x01890188},
|
||||
{0x0000a024, 0x018b018a},
|
||||
{0x0000a028, 0x018d018c},
|
||||
{0x0000a02c, 0x01910190},
|
||||
{0x0000a030, 0x01930192},
|
||||
{0x0000a034, 0x01950194},
|
||||
{0x0000a038, 0x038a0196},
|
||||
{0x0000a03c, 0x038c038b},
|
||||
{0x0000a040, 0x0390038d},
|
||||
{0x0000a044, 0x03920391},
|
||||
{0x0000a048, 0x03940393},
|
||||
{0x0000a04c, 0x03960395},
|
||||
{0x0000a050, 0x00000000},
|
||||
{0x0000a054, 0x00000000},
|
||||
{0x0000a058, 0x00000000},
|
||||
{0x0000a05c, 0x00000000},
|
||||
{0x0000a060, 0x00000000},
|
||||
{0x0000a064, 0x00000000},
|
||||
{0x0000a068, 0x00000000},
|
||||
{0x0000a06c, 0x00000000},
|
||||
{0x0000a070, 0x00000000},
|
||||
{0x0000a074, 0x00000000},
|
||||
{0x0000a078, 0x00000000},
|
||||
{0x0000a07c, 0x00000000},
|
||||
{0x0000a080, 0x22222229},
|
||||
{0x0000a084, 0x1d1d1d1d},
|
||||
{0x0000a088, 0x1d1d1d1d},
|
||||
{0x0000a08c, 0x1d1d1d1d},
|
||||
{0x0000a090, 0x171d1d1d},
|
||||
{0x0000a094, 0x11111717},
|
||||
{0x0000a098, 0x00030311},
|
||||
{0x0000a09c, 0x00000000},
|
||||
{0x0000a0a0, 0x00000000},
|
||||
{0x0000a0a4, 0x00000000},
|
||||
{0x0000a0a8, 0x00000000},
|
||||
{0x0000a0ac, 0x00000000},
|
||||
{0x0000a0b0, 0x00000000},
|
||||
{0x0000a0b4, 0x00000000},
|
||||
{0x0000a0b8, 0x00000000},
|
||||
{0x0000a0bc, 0x00000000},
|
||||
{0x0000a0c0, 0x001f0000},
|
||||
{0x0000a0c4, 0x01000101},
|
||||
{0x0000a0c8, 0x011e011f},
|
||||
{0x0000a0cc, 0x011c011d},
|
||||
{0x0000a0d0, 0x02030204},
|
||||
{0x0000a0d4, 0x02010202},
|
||||
{0x0000a0d8, 0x021f0200},
|
||||
{0x0000a0dc, 0x0302021e},
|
||||
{0x0000a0e0, 0x03000301},
|
||||
{0x0000a0e4, 0x031e031f},
|
||||
{0x0000a0e8, 0x0402031d},
|
||||
{0x0000a0ec, 0x04000401},
|
||||
{0x0000a0f0, 0x041e041f},
|
||||
{0x0000a0f4, 0x0502041d},
|
||||
{0x0000a0f8, 0x05000501},
|
||||
{0x0000a0fc, 0x051e051f},
|
||||
{0x0000a100, 0x06010602},
|
||||
{0x0000a104, 0x061f0600},
|
||||
{0x0000a108, 0x061d061e},
|
||||
{0x0000a10c, 0x07020703},
|
||||
{0x0000a110, 0x07000701},
|
||||
{0x0000a114, 0x00000000},
|
||||
{0x0000a118, 0x00000000},
|
||||
{0x0000a11c, 0x00000000},
|
||||
{0x0000a120, 0x00000000},
|
||||
{0x0000a124, 0x00000000},
|
||||
{0x0000a128, 0x00000000},
|
||||
{0x0000a12c, 0x00000000},
|
||||
{0x0000a130, 0x00000000},
|
||||
{0x0000a134, 0x00000000},
|
||||
{0x0000a138, 0x00000000},
|
||||
{0x0000a13c, 0x00000000},
|
||||
{0x0000a140, 0x001f0000},
|
||||
{0x0000a144, 0x01000101},
|
||||
{0x0000a148, 0x011e011f},
|
||||
{0x0000a14c, 0x011c011d},
|
||||
{0x0000a150, 0x02030204},
|
||||
{0x0000a154, 0x02010202},
|
||||
{0x0000a158, 0x021f0200},
|
||||
{0x0000a15c, 0x0302021e},
|
||||
{0x0000a160, 0x03000301},
|
||||
{0x0000a164, 0x031e031f},
|
||||
{0x0000a168, 0x0402031d},
|
||||
{0x0000a16c, 0x04000401},
|
||||
{0x0000a170, 0x041e041f},
|
||||
{0x0000a174, 0x0502041d},
|
||||
{0x0000a178, 0x05000501},
|
||||
{0x0000a17c, 0x051e051f},
|
||||
{0x0000a180, 0x06010602},
|
||||
{0x0000a184, 0x061f0600},
|
||||
{0x0000a188, 0x061d061e},
|
||||
{0x0000a18c, 0x07020703},
|
||||
{0x0000a190, 0x07000701},
|
||||
{0x0000a194, 0x00000000},
|
||||
{0x0000a198, 0x00000000},
|
||||
{0x0000a19c, 0x00000000},
|
||||
{0x0000a1a0, 0x00000000},
|
||||
{0x0000a1a4, 0x00000000},
|
||||
{0x0000a1a8, 0x00000000},
|
||||
{0x0000a1ac, 0x00000000},
|
||||
{0x0000a1b0, 0x00000000},
|
||||
{0x0000a1b4, 0x00000000},
|
||||
{0x0000a1b8, 0x00000000},
|
||||
{0x0000a1bc, 0x00000000},
|
||||
{0x0000a1c0, 0x00000000},
|
||||
{0x0000a1c4, 0x00000000},
|
||||
{0x0000a1c8, 0x00000000},
|
||||
{0x0000a1cc, 0x00000000},
|
||||
{0x0000a1d0, 0x00000000},
|
||||
{0x0000a1d4, 0x00000000},
|
||||
{0x0000a1d8, 0x00000000},
|
||||
{0x0000a1dc, 0x00000000},
|
||||
{0x0000a1e0, 0x00000000},
|
||||
{0x0000a1e4, 0x00000000},
|
||||
{0x0000a1e8, 0x00000000},
|
||||
{0x0000a1ec, 0x00000000},
|
||||
{0x0000a1f0, 0x00000396},
|
||||
{0x0000a1f4, 0x00000396},
|
||||
{0x0000a1f8, 0x00000396},
|
||||
{0x0000a1fc, 0x00000196},
|
||||
{0x0000b000, 0x00010000},
|
||||
{0x0000b004, 0x00030002},
|
||||
{0x0000b008, 0x00050004},
|
||||
{0x0000b00c, 0x00810080},
|
||||
{0x0000b010, 0x00830082},
|
||||
{0x0000b014, 0x01810180},
|
||||
{0x0000b018, 0x01830182},
|
||||
{0x0000b01c, 0x01850184},
|
||||
{0x0000b020, 0x02810280},
|
||||
{0x0000b024, 0x02830282},
|
||||
{0x0000b028, 0x02850284},
|
||||
{0x0000b02c, 0x02890288},
|
||||
{0x0000b030, 0x028b028a},
|
||||
{0x0000b034, 0x0388028c},
|
||||
{0x0000b038, 0x038a0389},
|
||||
{0x0000b03c, 0x038c038b},
|
||||
{0x0000b040, 0x0390038d},
|
||||
{0x0000b044, 0x03920391},
|
||||
{0x0000b048, 0x03940393},
|
||||
{0x0000b04c, 0x03960395},
|
||||
{0x0000b050, 0x00000000},
|
||||
{0x0000b054, 0x00000000},
|
||||
{0x0000b058, 0x00000000},
|
||||
{0x0000b05c, 0x00000000},
|
||||
{0x0000b060, 0x00000000},
|
||||
{0x0000b064, 0x00000000},
|
||||
{0x0000b068, 0x00000000},
|
||||
{0x0000b06c, 0x00000000},
|
||||
{0x0000b070, 0x00000000},
|
||||
{0x0000b074, 0x00000000},
|
||||
{0x0000b078, 0x00000000},
|
||||
{0x0000b07c, 0x00000000},
|
||||
{0x0000b080, 0x23232323},
|
||||
{0x0000b084, 0x21232323},
|
||||
{0x0000b088, 0x19191c1e},
|
||||
{0x0000b08c, 0x12141417},
|
||||
{0x0000b090, 0x07070e0e},
|
||||
{0x0000b094, 0x03030305},
|
||||
{0x0000b098, 0x00000003},
|
||||
{0x0000b09c, 0x00000000},
|
||||
{0x0000b0a0, 0x00000000},
|
||||
{0x0000b0a4, 0x00000000},
|
||||
{0x0000b0a8, 0x00000000},
|
||||
{0x0000b0ac, 0x00000000},
|
||||
{0x0000b0b0, 0x00000000},
|
||||
{0x0000b0b4, 0x00000000},
|
||||
{0x0000b0b8, 0x00000000},
|
||||
{0x0000b0bc, 0x00000000},
|
||||
{0x0000b0c0, 0x003f0020},
|
||||
{0x0000b0c4, 0x00400041},
|
||||
{0x0000b0c8, 0x0140005f},
|
||||
{0x0000b0cc, 0x0160015f},
|
||||
{0x0000b0d0, 0x017e017f},
|
||||
{0x0000b0d4, 0x02410242},
|
||||
{0x0000b0d8, 0x025f0240},
|
||||
{0x0000b0dc, 0x027f0260},
|
||||
{0x0000b0e0, 0x0341027e},
|
||||
{0x0000b0e4, 0x035f0340},
|
||||
{0x0000b0e8, 0x037f0360},
|
||||
{0x0000b0ec, 0x04400441},
|
||||
{0x0000b0f0, 0x0460045f},
|
||||
{0x0000b0f4, 0x0541047f},
|
||||
{0x0000b0f8, 0x055f0540},
|
||||
{0x0000b0fc, 0x057f0560},
|
||||
{0x0000b100, 0x06400641},
|
||||
{0x0000b104, 0x0660065f},
|
||||
{0x0000b108, 0x067e067f},
|
||||
{0x0000b10c, 0x07410742},
|
||||
{0x0000b110, 0x075f0740},
|
||||
{0x0000b114, 0x077f0760},
|
||||
{0x0000b118, 0x07800781},
|
||||
{0x0000b11c, 0x07a0079f},
|
||||
{0x0000b120, 0x07c107bf},
|
||||
{0x0000b124, 0x000007c0},
|
||||
{0x0000b128, 0x00000000},
|
||||
{0x0000b12c, 0x00000000},
|
||||
{0x0000b130, 0x00000000},
|
||||
{0x0000b134, 0x00000000},
|
||||
{0x0000b138, 0x00000000},
|
||||
{0x0000b13c, 0x00000000},
|
||||
{0x0000b140, 0x003f0020},
|
||||
{0x0000b144, 0x00400041},
|
||||
{0x0000b148, 0x0140005f},
|
||||
{0x0000b14c, 0x0160015f},
|
||||
{0x0000b150, 0x017e017f},
|
||||
{0x0000b154, 0x02410242},
|
||||
{0x0000b158, 0x025f0240},
|
||||
{0x0000b15c, 0x027f0260},
|
||||
{0x0000b160, 0x0341027e},
|
||||
{0x0000b164, 0x035f0340},
|
||||
{0x0000b168, 0x037f0360},
|
||||
{0x0000b16c, 0x04400441},
|
||||
{0x0000b170, 0x0460045f},
|
||||
{0x0000b174, 0x0541047f},
|
||||
{0x0000b178, 0x055f0540},
|
||||
{0x0000b17c, 0x057f0560},
|
||||
{0x0000b180, 0x06400641},
|
||||
{0x0000b184, 0x0660065f},
|
||||
{0x0000b188, 0x067e067f},
|
||||
{0x0000b18c, 0x07410742},
|
||||
{0x0000b190, 0x075f0740},
|
||||
{0x0000b194, 0x077f0760},
|
||||
{0x0000b198, 0x07800781},
|
||||
{0x0000b19c, 0x07a0079f},
|
||||
{0x0000b1a0, 0x07c107bf},
|
||||
{0x0000b1a4, 0x000007c0},
|
||||
{0x0000b1a8, 0x00000000},
|
||||
{0x0000b1ac, 0x00000000},
|
||||
{0x0000b1b0, 0x00000000},
|
||||
{0x0000b1b4, 0x00000000},
|
||||
{0x0000b1b8, 0x00000000},
|
||||
{0x0000b1bc, 0x00000000},
|
||||
{0x0000b1c0, 0x00000000},
|
||||
{0x0000b1c4, 0x00000000},
|
||||
{0x0000b1c8, 0x00000000},
|
||||
{0x0000b1cc, 0x00000000},
|
||||
{0x0000b1d0, 0x00000000},
|
||||
{0x0000b1d4, 0x00000000},
|
||||
{0x0000b1d8, 0x00000000},
|
||||
{0x0000b1dc, 0x00000000},
|
||||
{0x0000b1e0, 0x00000000},
|
||||
{0x0000b1e4, 0x00000000},
|
||||
{0x0000b1e8, 0x00000000},
|
||||
{0x0000b1ec, 0x00000000},
|
||||
{0x0000b1f0, 0x00000396},
|
||||
{0x0000b1f4, 0x00000396},
|
||||
{0x0000b1f8, 0x00000396},
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9580_1p0_baseband_postamble[][5] = {
|
||||
@ -956,7 +1169,7 @@ static const u32 ar9580_1p0_baseband_postamble[][5] = {
|
||||
{0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
|
||||
{0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
|
||||
{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
|
||||
{0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
|
||||
{0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982},
|
||||
{0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
|
||||
{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
|
||||
|
@ -459,6 +459,7 @@ void ath_check_ani(struct ath_softc *sc);
|
||||
int ath_update_survey_stats(struct ath_softc *sc);
|
||||
void ath_update_survey_nf(struct ath_softc *sc, int channel);
|
||||
void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
|
||||
void ath_ps_full_sleep(unsigned long data);
|
||||
|
||||
/**********/
|
||||
/* BTCOEX */
|
||||
@ -570,6 +571,34 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************/
|
||||
/* Wake on Wireless LAN */
|
||||
/************************/
|
||||
|
||||
#ifdef CONFIG_ATH9K_WOW
|
||||
void ath9k_init_wow(struct ieee80211_hw *hw);
|
||||
int ath9k_suspend(struct ieee80211_hw *hw,
|
||||
struct cfg80211_wowlan *wowlan);
|
||||
int ath9k_resume(struct ieee80211_hw *hw);
|
||||
void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled);
|
||||
#else
|
||||
static inline void ath9k_init_wow(struct ieee80211_hw *hw)
|
||||
{
|
||||
}
|
||||
static inline int ath9k_suspend(struct ieee80211_hw *hw,
|
||||
struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int ath9k_resume(struct ieee80211_hw *hw)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ATH9K_WOW */
|
||||
|
||||
/*******************************/
|
||||
/* Antenna diversity/combining */
|
||||
/*******************************/
|
||||
@ -642,6 +671,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
|
||||
#define ATH9K_PCI_AR9565_1ANT 0x0080
|
||||
#define ATH9K_PCI_AR9565_2ANT 0x0100
|
||||
#define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200
|
||||
#define ATH9K_PCI_KILLER 0x0400
|
||||
|
||||
/*
|
||||
* Default cache line size, in bytes.
|
||||
@ -724,6 +754,7 @@ struct ath_softc {
|
||||
struct work_struct hw_check_work;
|
||||
struct work_struct hw_reset_work;
|
||||
struct completion paprd_complete;
|
||||
wait_queue_head_t tx_wait;
|
||||
|
||||
unsigned int hw_busy_count;
|
||||
unsigned long sc_flags;
|
||||
@ -760,6 +791,7 @@ struct ath_softc {
|
||||
struct delayed_work tx_complete_work;
|
||||
struct delayed_work hw_pll_work;
|
||||
struct timer_list rx_poll_timer;
|
||||
struct timer_list sleep_timer;
|
||||
|
||||
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
|
||||
struct ath_btcoex btcoex;
|
||||
@ -784,7 +816,7 @@ struct ath_softc {
|
||||
bool tx99_state;
|
||||
s16 tx99_power;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_ATH9K_WOW
|
||||
atomic_t wow_got_bmiss_intr;
|
||||
atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */
|
||||
u32 wow_intr_before_sleep;
|
||||
@ -947,10 +979,25 @@ struct fft_sample_ht20_40 {
|
||||
u8 data[SPECTRAL_HT20_40_NUM_BINS];
|
||||
} __packed;
|
||||
|
||||
int ath9k_tx99_init(struct ath_softc *sc);
|
||||
void ath9k_tx99_deinit(struct ath_softc *sc);
|
||||
/********/
|
||||
/* TX99 */
|
||||
/********/
|
||||
|
||||
#ifdef CONFIG_ATH9K_TX99
|
||||
void ath9k_tx99_init_debug(struct ath_softc *sc);
|
||||
int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
|
||||
struct ath_tx_control *txctl);
|
||||
#else
|
||||
static inline void ath9k_tx99_init_debug(struct ath_softc *sc)
|
||||
{
|
||||
}
|
||||
static inline int ath9k_tx99_send(struct ath_softc *sc,
|
||||
struct sk_buff *skb,
|
||||
struct ath_tx_control *txctl)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_ATH9K_TX99 */
|
||||
|
||||
void ath9k_tasklet(unsigned long data);
|
||||
int ath_cabq_update(struct ath_softc *);
|
||||
@ -967,6 +1014,9 @@ extern bool is_ath9k_unloaded;
|
||||
|
||||
u8 ath9k_parse_mpdudensity(u8 mpdudensity);
|
||||
irqreturn_t ath_isr(int irq, void *dev);
|
||||
int ath_reset(struct ath_softc *sc);
|
||||
void ath_cancel_work(struct ath_softc *sc);
|
||||
void ath_restart_work(struct ath_softc *sc);
|
||||
int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||
const struct ath_bus_ops *bus_ops);
|
||||
void ath9k_deinit_device(struct ath_softc *sc);
|
||||
|
@ -1778,111 +1778,6 @@ void ath9k_deinit_debug(struct ath_softc *sc)
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
char buf[3];
|
||||
unsigned int len;
|
||||
|
||||
len = sprintf(buf, "%d\n", sc->tx99_state);
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
char buf[32];
|
||||
bool start;
|
||||
ssize_t len;
|
||||
int r;
|
||||
|
||||
if (sc->nvifs > 1)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
len = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
if (strtobool(buf, &start))
|
||||
return -EINVAL;
|
||||
|
||||
if (start == sc->tx99_state) {
|
||||
if (!start)
|
||||
return count;
|
||||
ath_dbg(common, XMIT, "Resetting TX99\n");
|
||||
ath9k_tx99_deinit(sc);
|
||||
}
|
||||
|
||||
if (!start) {
|
||||
ath9k_tx99_deinit(sc);
|
||||
return count;
|
||||
}
|
||||
|
||||
r = ath9k_tx99_init(sc);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_tx99 = {
|
||||
.read = read_file_tx99,
|
||||
.write = write_file_tx99,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t read_file_tx99_power(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
char buf[32];
|
||||
unsigned int len;
|
||||
|
||||
len = sprintf(buf, "%d (%d dBm)\n",
|
||||
sc->tx99_power,
|
||||
sc->tx99_power / 2);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t write_file_tx99_power(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
int r;
|
||||
u8 tx_power;
|
||||
|
||||
r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (tx_power > MAX_RATE_POWER)
|
||||
return -EINVAL;
|
||||
|
||||
sc->tx99_power = tx_power;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_tx99_power = {
|
||||
.read = read_file_tx99_power,
|
||||
.write = write_file_tx99_power,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int ath9k_init_debug(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@ -1899,6 +1794,7 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
#endif
|
||||
|
||||
ath9k_dfs_init_debug(sc);
|
||||
ath9k_tx99_init_debug(sc);
|
||||
|
||||
debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
|
||||
&fops_dma);
|
||||
@ -1974,15 +1870,6 @@ int ath9k_init_debug(struct ath_hw *ah)
|
||||
debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc,
|
||||
&fops_btcoex);
|
||||
#endif
|
||||
if (config_enabled(CONFIG_ATH9K_TX99) &&
|
||||
AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
|
||||
sc->debug.debugfs_phy, sc,
|
||||
&fops_tx99);
|
||||
debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
|
||||
sc->debug.debugfs_phy, sc,
|
||||
&fops_tx99_power);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "hw.h"
|
||||
@ -453,7 +454,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
|
||||
}
|
||||
|
||||
ah->config.rx_intr_mitigation = true;
|
||||
ah->config.pcieSerDesWrite = true;
|
||||
|
||||
/*
|
||||
* We need this for PCI devices only (Cardbus, PCI, miniPCI)
|
||||
@ -1501,8 +1501,9 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
|
||||
int r;
|
||||
|
||||
if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
|
||||
band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan);
|
||||
mode_diff = (chan->channelFlags != ah->curchan->channelFlags);
|
||||
u32 flags_diff = chan->channelFlags ^ ah->curchan->channelFlags;
|
||||
band_switch = !!(flags_diff & CHANNEL_5GHZ);
|
||||
mode_diff = !!(flags_diff & ~CHANNEL_HT);
|
||||
}
|
||||
|
||||
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
|
||||
@ -1814,7 +1815,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
* If cross-band fcc is not supoprted, bail out if channelFlags differ.
|
||||
*/
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) &&
|
||||
chan->channelFlags != ah->curchan->channelFlags)
|
||||
((chan->channelFlags ^ ah->curchan->channelFlags) & ~CHANNEL_HT))
|
||||
goto fail;
|
||||
|
||||
if (!ath9k_hw_check_alive(ah))
|
||||
@ -1855,10 +1856,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct timespec ts;
|
||||
u32 saveLedState;
|
||||
u32 saveDefAntenna;
|
||||
u32 macStaId1;
|
||||
u64 tsf = 0;
|
||||
s64 usec = 0;
|
||||
int r;
|
||||
bool start_mci_reset = false;
|
||||
bool save_fullsleep = ah->chip_fullsleep;
|
||||
@ -1901,10 +1904,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
|
||||
macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
|
||||
|
||||
/* For chips on which RTC reset is done, save TSF before it gets cleared */
|
||||
if (AR_SREV_9100(ah) ||
|
||||
(AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)))
|
||||
tsf = ath9k_hw_gettsf64(ah);
|
||||
/* Save TSF before chip reset, a cold reset clears it */
|
||||
tsf = ath9k_hw_gettsf64(ah);
|
||||
getrawmonotonic(&ts);
|
||||
usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000;
|
||||
|
||||
saveLedState = REG_READ(ah, AR_CFG_LED) &
|
||||
(AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
|
||||
@ -1937,8 +1940,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
}
|
||||
|
||||
/* Restore TSF */
|
||||
if (tsf)
|
||||
ath9k_hw_settsf64(ah, tsf);
|
||||
getrawmonotonic(&ts);
|
||||
usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec;
|
||||
ath9k_hw_settsf64(ah, tsf + usec);
|
||||
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
|
||||
|
@ -283,7 +283,6 @@ struct ath9k_ops_config {
|
||||
int additional_swba_backoff;
|
||||
int ack_6mb;
|
||||
u32 cwm_ignore_extcca;
|
||||
bool pcieSerDesWrite;
|
||||
u8 pcie_clock_req;
|
||||
u32 pcie_waen;
|
||||
u8 analog_shiftreg;
|
||||
@ -921,7 +920,7 @@ struct ath_hw {
|
||||
/* Enterprise mode cap */
|
||||
u32 ent_mode;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_ATH9K_WOW
|
||||
u32 wow_event_mask;
|
||||
#endif
|
||||
bool is_clk_25mhz;
|
||||
@ -1127,7 +1126,7 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
|
||||
#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
|
||||
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_ATH9K_WOW
|
||||
const char *ath9k_hw_wow_event_to_string(u32 wow_event);
|
||||
void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
|
||||
u8 *user_mask, int pattern_count,
|
||||
|
@ -589,6 +589,9 @@ static void ath9k_init_platform(struct ath_softc *sc)
|
||||
if (sc->driver_data & ATH9K_PCI_AR9565_2ANT)
|
||||
ath_info(common, "WB335 2-ANT card detected\n");
|
||||
|
||||
if (sc->driver_data & ATH9K_PCI_KILLER)
|
||||
ath_info(common, "Killer Wireless card detected\n");
|
||||
|
||||
/*
|
||||
* Some WB335 cards do not support antenna diversity. Since
|
||||
* we use a hardcoded value for AR9565 instead of using the
|
||||
@ -688,6 +691,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
|
||||
common = ath9k_hw_common(ah);
|
||||
sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
|
||||
sc->tx99_power = MAX_RATE_POWER + 1;
|
||||
init_waitqueue_head(&sc->tx_wait);
|
||||
|
||||
if (!pdata) {
|
||||
ah->ah_flags |= AH_USE_EEPROM;
|
||||
@ -735,6 +739,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
|
||||
tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
|
||||
(unsigned long)sc);
|
||||
|
||||
setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);
|
||||
INIT_WORK(&sc->hw_reset_work, ath_reset_work);
|
||||
INIT_WORK(&sc->hw_check_work, ath_hw_check);
|
||||
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
|
||||
@ -873,15 +878,6 @@ static const struct ieee80211_iface_combination if_comb[] = {
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static const struct wiphy_wowlan_support ath9k_wowlan_support = {
|
||||
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
|
||||
.n_patterns = MAX_NUM_USER_PATTERN,
|
||||
.pattern_min_len = 1,
|
||||
.pattern_max_len = MAX_PATTERN_SIZE,
|
||||
};
|
||||
#endif
|
||||
|
||||
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@ -931,16 +927,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
|
||||
hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
|
||||
(sc->driver_data & ATH9K_PCI_WOW) &&
|
||||
device_can_wakeup(sc->dev))
|
||||
hw->wiphy->wowlan = &ath9k_wowlan_support;
|
||||
|
||||
atomic_set(&sc->wow_sleep_proc_intr, -1);
|
||||
atomic_set(&sc->wow_got_bmiss_intr, -1);
|
||||
#endif
|
||||
|
||||
hw->queues = 4;
|
||||
hw->max_rates = 4;
|
||||
hw->channel_change_time = 5000;
|
||||
@ -966,6 +952,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
|
||||
&sc->sbands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
ath9k_init_wow(hw);
|
||||
ath9k_reload_chainmask_settings(sc);
|
||||
|
||||
SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
|
||||
@ -1064,6 +1051,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
|
||||
if (ATH_TXQ_SETUP(sc, i))
|
||||
ath_tx_cleanupq(sc, &sc->tx.txq[i]);
|
||||
|
||||
del_timer_sync(&sc->sleep_timer);
|
||||
ath9k_hw_deinit(sc->sc_ah);
|
||||
if (sc->dfs_detector != NULL)
|
||||
sc->dfs_detector->exit(sc->dfs_detector);
|
||||
|
@ -82,6 +82,22 @@ static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ath_ps_full_sleep(unsigned long data)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *) data;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
bool reset;
|
||||
|
||||
spin_lock(&common->cc_lock);
|
||||
ath_hw_cycle_counters_update(common);
|
||||
spin_unlock(&common->cc_lock);
|
||||
|
||||
ath9k_hw_setrxabort(sc->sc_ah, 1);
|
||||
ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
|
||||
|
||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
|
||||
}
|
||||
|
||||
void ath9k_ps_wakeup(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
@ -92,6 +108,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
|
||||
if (++sc->ps_usecount != 1)
|
||||
goto unlock;
|
||||
|
||||
del_timer_sync(&sc->sleep_timer);
|
||||
power_mode = sc->sc_ah->power_mode;
|
||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
|
||||
|
||||
@ -117,17 +134,17 @@ void ath9k_ps_restore(struct ath_softc *sc)
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
enum ath9k_power_mode mode;
|
||||
unsigned long flags;
|
||||
bool reset;
|
||||
|
||||
spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
||||
if (--sc->ps_usecount != 0)
|
||||
goto unlock;
|
||||
|
||||
if (sc->ps_idle) {
|
||||
ath9k_hw_setrxabort(sc->sc_ah, 1);
|
||||
ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
|
||||
mode = ATH9K_PM_FULL_SLEEP;
|
||||
} else if (sc->ps_enabled &&
|
||||
mod_timer(&sc->sleep_timer, jiffies + HZ / 10);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (sc->ps_enabled &&
|
||||
!(sc->ps_flags & (PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA |
|
||||
@ -163,13 +180,13 @@ static void __ath_cancel_work(struct ath_softc *sc)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ath_cancel_work(struct ath_softc *sc)
|
||||
void ath_cancel_work(struct ath_softc *sc)
|
||||
{
|
||||
__ath_cancel_work(sc);
|
||||
cancel_work_sync(&sc->hw_reset_work);
|
||||
}
|
||||
|
||||
static void ath_restart_work(struct ath_softc *sc)
|
||||
void ath_restart_work(struct ath_softc *sc)
|
||||
{
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
||||
|
||||
@ -487,6 +504,8 @@ void ath9k_tasklet(unsigned long data)
|
||||
ath_tx_edma_tasklet(sc);
|
||||
else
|
||||
ath_tx_tasklet(sc);
|
||||
|
||||
wake_up(&sc->tx_wait);
|
||||
}
|
||||
|
||||
ath9k_btcoex_handle_interrupt(sc, status);
|
||||
@ -579,7 +598,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
|
||||
goto chip_reset;
|
||||
}
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
#ifdef CONFIG_ATH9K_WOW
|
||||
if (status & ATH9K_INT_BMISS) {
|
||||
if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
|
||||
ath_dbg(common, ANY, "during WoW we got a BMISS\n");
|
||||
@ -588,6 +608,8 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (status & ATH9K_INT_SWBA)
|
||||
tasklet_schedule(&sc->bcon_tasklet);
|
||||
|
||||
@ -627,7 +649,7 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
#undef SCHED_INTR
|
||||
}
|
||||
|
||||
static int ath_reset(struct ath_softc *sc)
|
||||
int ath_reset(struct ath_softc *sc)
|
||||
{
|
||||
int r;
|
||||
|
||||
@ -1817,13 +1839,31 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
static bool ath9k_has_tx_pending(struct ath_softc *sc)
|
||||
{
|
||||
int i, npend;
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (!ATH_TXQ_SETUP(sc, i))
|
||||
continue;
|
||||
|
||||
if (!sc->tx.txq[i].axq_depth)
|
||||
continue;
|
||||
|
||||
npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
|
||||
if (npend)
|
||||
break;
|
||||
}
|
||||
|
||||
return !!npend;
|
||||
}
|
||||
|
||||
static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int timeout = 200; /* ms */
|
||||
int i, j;
|
||||
int timeout = HZ / 5; /* 200 ms */
|
||||
bool drain_txq;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
@ -1841,25 +1881,9 @@ static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
|
||||
return;
|
||||
}
|
||||
|
||||
for (j = 0; j < timeout; j++) {
|
||||
bool npend = false;
|
||||
|
||||
if (j)
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (!ATH_TXQ_SETUP(sc, i))
|
||||
continue;
|
||||
|
||||
npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
|
||||
|
||||
if (npend)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!npend)
|
||||
break;
|
||||
}
|
||||
if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc),
|
||||
timeout) > 0)
|
||||
drop = false;
|
||||
|
||||
if (drop) {
|
||||
ath9k_ps_wakeup(sc);
|
||||
@ -2021,333 +2045,6 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
static void ath9k_wow_map_triggers(struct ath_softc *sc,
|
||||
struct cfg80211_wowlan *wowlan,
|
||||
u32 *wow_triggers)
|
||||
{
|
||||
if (wowlan->disconnect)
|
||||
*wow_triggers |= AH_WOW_LINK_CHANGE |
|
||||
AH_WOW_BEACON_MISS;
|
||||
if (wowlan->magic_pkt)
|
||||
*wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
|
||||
|
||||
if (wowlan->n_patterns)
|
||||
*wow_triggers |= AH_WOW_USER_PATTERN_EN;
|
||||
|
||||
sc->wow_enabled = *wow_triggers;
|
||||
|
||||
}
|
||||
|
||||
static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int pattern_count = 0;
|
||||
int i, byte_cnt;
|
||||
u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
|
||||
u8 dis_deauth_mask[MAX_PATTERN_SIZE];
|
||||
|
||||
memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
|
||||
memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
|
||||
|
||||
/*
|
||||
* Create Dissassociate / Deauthenticate packet filter
|
||||
*
|
||||
* 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
|
||||
* +--------------+----------+---------+--------+--------+----
|
||||
* + Frame Control+ Duration + DA + SA + BSSID +
|
||||
* +--------------+----------+---------+--------+--------+----
|
||||
*
|
||||
* The above is the management frame format for disassociate/
|
||||
* deauthenticate pattern, from this we need to match the first byte
|
||||
* of 'Frame Control' and DA, SA, and BSSID fields
|
||||
* (skipping 2nd byte of FC and Duration feild.
|
||||
*
|
||||
* Disassociate pattern
|
||||
* --------------------
|
||||
* Frame control = 00 00 1010
|
||||
* DA, SA, BSSID = x:x:x:x:x:x
|
||||
* Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
|
||||
* | x:x:x:x:x:x -- 22 bytes
|
||||
*
|
||||
* Deauthenticate pattern
|
||||
* ----------------------
|
||||
* Frame control = 00 00 1100
|
||||
* DA, SA, BSSID = x:x:x:x:x:x
|
||||
* Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
|
||||
* | x:x:x:x:x:x -- 22 bytes
|
||||
*/
|
||||
|
||||
/* Create Disassociate Pattern first */
|
||||
|
||||
byte_cnt = 0;
|
||||
|
||||
/* Fill out the mask with all FF's */
|
||||
|
||||
for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
|
||||
dis_deauth_mask[i] = 0xff;
|
||||
|
||||
/* copy the first byte of frame control field */
|
||||
dis_deauth_pattern[byte_cnt] = 0xa0;
|
||||
byte_cnt++;
|
||||
|
||||
/* skip 2nd byte of frame control and Duration field */
|
||||
byte_cnt += 3;
|
||||
|
||||
/*
|
||||
* need not match the destination mac address, it can be a broadcast
|
||||
* mac address or an unicast to this station
|
||||
*/
|
||||
byte_cnt += 6;
|
||||
|
||||
/* copy the source mac address */
|
||||
memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
|
||||
|
||||
byte_cnt += 6;
|
||||
|
||||
/* copy the bssid, its same as the source mac address */
|
||||
|
||||
memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
|
||||
|
||||
/* Create Disassociate pattern mask */
|
||||
|
||||
dis_deauth_mask[0] = 0xfe;
|
||||
dis_deauth_mask[1] = 0x03;
|
||||
dis_deauth_mask[2] = 0xc0;
|
||||
|
||||
ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
|
||||
|
||||
ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
|
||||
pattern_count, byte_cnt);
|
||||
|
||||
pattern_count++;
|
||||
/*
|
||||
* for de-authenticate pattern, only the first byte of the frame
|
||||
* control field gets changed from 0xA0 to 0xC0
|
||||
*/
|
||||
dis_deauth_pattern[0] = 0xC0;
|
||||
|
||||
ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
|
||||
pattern_count, byte_cnt);
|
||||
|
||||
}
|
||||
|
||||
static void ath9k_wow_add_pattern(struct ath_softc *sc,
|
||||
struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath9k_wow_pattern *wow_pattern = NULL;
|
||||
struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
|
||||
int mask_len;
|
||||
s8 i = 0;
|
||||
|
||||
if (!wowlan->n_patterns)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Add the new user configured patterns
|
||||
*/
|
||||
for (i = 0; i < wowlan->n_patterns; i++) {
|
||||
|
||||
wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
|
||||
|
||||
if (!wow_pattern)
|
||||
return;
|
||||
|
||||
/*
|
||||
* TODO: convert the generic user space pattern to
|
||||
* appropriate chip specific/802.11 pattern.
|
||||
*/
|
||||
|
||||
mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
|
||||
memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
|
||||
memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
|
||||
memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
|
||||
patterns[i].pattern_len);
|
||||
memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
|
||||
wow_pattern->pattern_len = patterns[i].pattern_len;
|
||||
|
||||
/*
|
||||
* just need to take care of deauth and disssoc pattern,
|
||||
* make sure we don't overwrite them.
|
||||
*/
|
||||
|
||||
ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
|
||||
wow_pattern->mask_bytes,
|
||||
i + 2,
|
||||
wow_pattern->pattern_len);
|
||||
kfree(wow_pattern);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int ath9k_suspend(struct ieee80211_hw *hw,
|
||||
struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 wow_triggers_enabled = 0;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
ath_cancel_work(sc);
|
||||
ath_stop_ani(sc);
|
||||
del_timer_sync(&sc->rx_poll_timer);
|
||||
|
||||
if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
|
||||
ath_dbg(common, ANY, "Device not present\n");
|
||||
ret = -EINVAL;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
if (WARN_ON(!wowlan)) {
|
||||
ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
|
||||
ret = -EINVAL;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
if (!device_can_wakeup(sc->dev)) {
|
||||
ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
|
||||
ret = 1;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
/*
|
||||
* none of the sta vifs are associated
|
||||
* and we are not currently handling multivif
|
||||
* cases, for instance we have to seperately
|
||||
* configure 'keep alive frame' for each
|
||||
* STA.
|
||||
*/
|
||||
|
||||
if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
|
||||
ath_dbg(common, WOW, "None of the STA vifs are associated\n");
|
||||
ret = 1;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
if (sc->nvifs > 1) {
|
||||
ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
|
||||
ret = 1;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
|
||||
|
||||
ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
|
||||
wow_triggers_enabled);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
ath9k_stop_btcoex(sc);
|
||||
|
||||
/*
|
||||
* Enable wake up on recieving disassoc/deauth
|
||||
* frame by default.
|
||||
*/
|
||||
ath9k_wow_add_disassoc_deauth_pattern(sc);
|
||||
|
||||
if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
|
||||
ath9k_wow_add_pattern(sc, wowlan);
|
||||
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
/*
|
||||
* To avoid false wake, we enable beacon miss interrupt only
|
||||
* when we go to sleep. We save the current interrupt mask
|
||||
* so we can restore it after the system wakes up
|
||||
*/
|
||||
sc->wow_intr_before_sleep = ah->imask;
|
||||
ah->imask &= ~ATH9K_INT_GLOBAL;
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
/*
|
||||
* we can now sync irq and kill any running tasklets, since we already
|
||||
* disabled interrupts and not holding a spin lock
|
||||
*/
|
||||
synchronize_irq(sc->irq);
|
||||
tasklet_kill(&sc->intr_tq);
|
||||
|
||||
ath9k_hw_wow_enable(ah, wow_triggers_enabled);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
ath_dbg(common, ANY, "WoW enabled in ath9k\n");
|
||||
atomic_inc(&sc->wow_sleep_proc_intr);
|
||||
|
||||
fail_wow:
|
||||
mutex_unlock(&sc->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath9k_resume(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 wow_status;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
ah->imask = sc->wow_intr_before_sleep;
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
wow_status = ath9k_hw_wow_wakeup(ah);
|
||||
|
||||
if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
|
||||
/*
|
||||
* some devices may not pick beacon miss
|
||||
* as the reason they woke up so we add
|
||||
* that here for that shortcoming.
|
||||
*/
|
||||
wow_status |= AH_WOW_BEACON_MISS;
|
||||
atomic_dec(&sc->wow_got_bmiss_intr);
|
||||
ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
|
||||
}
|
||||
|
||||
atomic_dec(&sc->wow_sleep_proc_intr);
|
||||
|
||||
if (wow_status) {
|
||||
ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
|
||||
ath9k_hw_wow_event_to_string(wow_status), wow_status);
|
||||
}
|
||||
|
||||
ath_restart_work(sc);
|
||||
ath9k_start_btcoex(sc);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
mutex_unlock(&sc->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
device_init_wakeup(sc->dev, 1);
|
||||
device_set_wakeup_enable(sc->dev, enabled);
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
#endif
|
||||
static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
@ -2373,134 +2070,6 @@ static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw,
|
||||
sc->csa_vif = vif;
|
||||
}
|
||||
|
||||
static void ath9k_tx99_stop(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
ath_drain_all_txq(sc);
|
||||
ath_startrecv(sc);
|
||||
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
ieee80211_wake_queues(sc->hw);
|
||||
|
||||
kfree_skb(sc->tx99_skb);
|
||||
sc->tx99_skb = NULL;
|
||||
sc->tx99_state = false;
|
||||
|
||||
ath9k_hw_tx99_stop(sc->sc_ah);
|
||||
ath_dbg(common, XMIT, "TX99 stopped\n");
|
||||
}
|
||||
|
||||
static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
|
||||
{
|
||||
static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
|
||||
0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
|
||||
0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
|
||||
0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
|
||||
0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
|
||||
0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
|
||||
0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
|
||||
0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
|
||||
u32 len = 1200;
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = alloc_skb(len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
skb_put(skb, len);
|
||||
|
||||
memset(skb->data, 0, len);
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
|
||||
hdr->duration_id = 0;
|
||||
|
||||
memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
|
||||
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->band = hw->conf.chandef.chan->band;
|
||||
tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
|
||||
tx_info->control.vif = sc->tx99_vif;
|
||||
|
||||
memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
void ath9k_tx99_deinit(struct ath_softc *sc)
|
||||
{
|
||||
ath_reset(sc);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_tx99_stop(sc);
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
int ath9k_tx99_init(struct ath_softc *sc)
|
||||
{
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_tx_control txctl;
|
||||
int r;
|
||||
|
||||
if (sc->sc_flags & SC_OP_INVALID) {
|
||||
ath_err(common,
|
||||
"driver is in invalid state unable to use TX99");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sc->tx99_skb = ath9k_build_tx99_skb(sc);
|
||||
if (!sc->tx99_skb)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&txctl, 0, sizeof(txctl));
|
||||
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
|
||||
|
||||
ath_reset(sc);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
atomic_set(&ah->intr_ref_cnt, -1);
|
||||
ath_drain_all_txq(sc);
|
||||
ath_stoprecv(sc);
|
||||
|
||||
sc->tx99_state = true;
|
||||
|
||||
ieee80211_stop_queues(hw);
|
||||
|
||||
if (sc->tx99_power == MAX_RATE_POWER + 1)
|
||||
sc->tx99_power = MAX_RATE_POWER;
|
||||
|
||||
ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
|
||||
r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
|
||||
if (r) {
|
||||
ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
|
||||
sc->tx99_power,
|
||||
sc->tx99_power / 2);
|
||||
|
||||
/* We leave the harware awake as it will be chugging on */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ieee80211_ops ath9k_ops = {
|
||||
.tx = ath9k_tx,
|
||||
.start = ath9k_start,
|
||||
@ -2531,7 +2100,7 @@ struct ieee80211_ops ath9k_ops = {
|
||||
.set_antenna = ath9k_set_antenna,
|
||||
.get_antenna = ath9k_get_antenna,
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_ATH9K_WOW
|
||||
.suspend = ath9k_suspend,
|
||||
.resume = ath9k_resume,
|
||||
.set_wakeup = ath9k_set_wakeup,
|
||||
|
@ -87,6 +87,19 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
|
||||
|
||||
/* Killer Wireless (3x3) */
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0030,
|
||||
0x1A56,
|
||||
0x2000),
|
||||
.driver_data = ATH9K_PCI_KILLER },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0030,
|
||||
0x1A56,
|
||||
0x2001),
|
||||
.driver_data = ATH9K_PCI_KILLER },
|
||||
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
|
||||
|
||||
/* PCI-E CUS198 */
|
||||
@ -354,6 +367,13 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
0x1783),
|
||||
.driver_data = ATH9K_PCI_WOW },
|
||||
|
||||
/* Killer Wireless (2x2) */
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0030,
|
||||
0x1A56,
|
||||
0x2003),
|
||||
.driver_data = ATH9K_PCI_KILLER },
|
||||
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */
|
||||
|
||||
@ -446,6 +466,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
0x11AD, /* LITEON */
|
||||
0x0662),
|
||||
.driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0036,
|
||||
0x11AD, /* LITEON */
|
||||
0x0682),
|
||||
.driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0036,
|
||||
PCI_VENDOR_ID_AZWAVE,
|
||||
@ -456,6 +481,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
PCI_VENDOR_ID_LENOVO,
|
||||
0x3026),
|
||||
.driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0036,
|
||||
PCI_VENDOR_ID_LENOVO,
|
||||
0x4026),
|
||||
.driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0036,
|
||||
PCI_VENDOR_ID_HP,
|
||||
@ -466,6 +496,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
PCI_VENDOR_ID_HP,
|
||||
0x217F),
|
||||
.driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0036,
|
||||
PCI_VENDOR_ID_HP,
|
||||
0x2005),
|
||||
.driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0036,
|
||||
PCI_VENDOR_ID_DELL,
|
||||
@ -545,6 +580,16 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
0x185F, /* WNC */
|
||||
0x3027),
|
||||
.driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0036,
|
||||
0x185F, /* WNC */
|
||||
0xA120),
|
||||
.driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
|
||||
0x0036,
|
||||
PCI_VENDOR_ID_FOXCONN,
|
||||
0xE07F),
|
||||
.driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
|
||||
|
||||
/* PCI-E AR9565 (WB335) */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0036),
|
||||
|
@ -809,6 +809,8 @@
|
||||
#define AR_SREV_REVISION_9462_21 3
|
||||
#define AR_SREV_VERSION_9565 0x2C0
|
||||
#define AR_SREV_REVISION_9565_10 0
|
||||
#define AR_SREV_REVISION_9565_101 1
|
||||
#define AR_SREV_REVISION_9565_11 2
|
||||
#define AR_SREV_VERSION_9550 0x400
|
||||
|
||||
#define AR_SREV_5416(_ah) \
|
||||
@ -927,10 +929,18 @@
|
||||
|
||||
#define AR_SREV_9565(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
|
||||
|
||||
#define AR_SREV_9565_10(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10))
|
||||
#define AR_SREV_9565_101(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101))
|
||||
#define AR_SREV_9565_11(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11))
|
||||
#define AR_SREV_9565_11_OR_LATER(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11))
|
||||
|
||||
#define AR_SREV_9550(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550))
|
||||
|
264
drivers/net/wireless/ath/ath9k/tx99.c
Normal file
264
drivers/net/wireless/ath/ath9k/tx99.c
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Qualcomm Atheros, 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 "ath9k.h"
|
||||
|
||||
static void ath9k_tx99_stop(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
ath_drain_all_txq(sc);
|
||||
ath_startrecv(sc);
|
||||
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
ieee80211_wake_queues(sc->hw);
|
||||
|
||||
kfree_skb(sc->tx99_skb);
|
||||
sc->tx99_skb = NULL;
|
||||
sc->tx99_state = false;
|
||||
|
||||
ath9k_hw_tx99_stop(sc->sc_ah);
|
||||
ath_dbg(common, XMIT, "TX99 stopped\n");
|
||||
}
|
||||
|
||||
static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
|
||||
{
|
||||
static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
|
||||
0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
|
||||
0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
|
||||
0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
|
||||
0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
|
||||
0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
|
||||
0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
|
||||
0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
|
||||
u32 len = 1200;
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = alloc_skb(len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
|
||||
skb_put(skb, len);
|
||||
|
||||
memset(skb->data, 0, len);
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
|
||||
hdr->duration_id = 0;
|
||||
|
||||
memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
|
||||
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
memset(tx_info, 0, sizeof(*tx_info));
|
||||
tx_info->band = hw->conf.chandef.chan->band;
|
||||
tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
|
||||
tx_info->control.vif = sc->tx99_vif;
|
||||
tx_info->control.rates[0].count = 1;
|
||||
|
||||
memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static void ath9k_tx99_deinit(struct ath_softc *sc)
|
||||
{
|
||||
ath_reset(sc);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_tx99_stop(sc);
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
static int ath9k_tx99_init(struct ath_softc *sc)
|
||||
{
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_tx_control txctl;
|
||||
int r;
|
||||
|
||||
if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
|
||||
ath_err(common,
|
||||
"driver is in invalid state unable to use TX99");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sc->tx99_skb = ath9k_build_tx99_skb(sc);
|
||||
if (!sc->tx99_skb)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&txctl, 0, sizeof(txctl));
|
||||
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
|
||||
|
||||
ath_reset(sc);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
atomic_set(&ah->intr_ref_cnt, -1);
|
||||
ath_drain_all_txq(sc);
|
||||
ath_stoprecv(sc);
|
||||
|
||||
sc->tx99_state = true;
|
||||
|
||||
ieee80211_stop_queues(hw);
|
||||
|
||||
if (sc->tx99_power == MAX_RATE_POWER + 1)
|
||||
sc->tx99_power = MAX_RATE_POWER;
|
||||
|
||||
ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
|
||||
r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
|
||||
if (r) {
|
||||
ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
|
||||
sc->tx99_power,
|
||||
sc->tx99_power / 2);
|
||||
|
||||
/* We leave the harware awake as it will be chugging on */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
char buf[3];
|
||||
unsigned int len;
|
||||
|
||||
len = sprintf(buf, "%d\n", sc->tx99_state);
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
char buf[32];
|
||||
bool start;
|
||||
ssize_t len;
|
||||
int r;
|
||||
|
||||
if (sc->nvifs > 1)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
len = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
if (strtobool(buf, &start))
|
||||
return -EINVAL;
|
||||
|
||||
if (start == sc->tx99_state) {
|
||||
if (!start)
|
||||
return count;
|
||||
ath_dbg(common, XMIT, "Resetting TX99\n");
|
||||
ath9k_tx99_deinit(sc);
|
||||
}
|
||||
|
||||
if (!start) {
|
||||
ath9k_tx99_deinit(sc);
|
||||
return count;
|
||||
}
|
||||
|
||||
r = ath9k_tx99_init(sc);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_tx99 = {
|
||||
.read = read_file_tx99,
|
||||
.write = write_file_tx99,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t read_file_tx99_power(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
char buf[32];
|
||||
unsigned int len;
|
||||
|
||||
len = sprintf(buf, "%d (%d dBm)\n",
|
||||
sc->tx99_power,
|
||||
sc->tx99_power / 2);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t write_file_tx99_power(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
int r;
|
||||
u8 tx_power;
|
||||
|
||||
r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (tx_power > MAX_RATE_POWER)
|
||||
return -EINVAL;
|
||||
|
||||
sc->tx99_power = tx_power;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_tx99_power = {
|
||||
.read = read_file_tx99_power,
|
||||
.write = write_file_tx99_power,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
void ath9k_tx99_init_debug(struct ath_softc *sc)
|
||||
{
|
||||
if (!AR_SREV_9300_20_OR_LATER(sc->sc_ah))
|
||||
return;
|
||||
|
||||
debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
|
||||
sc->debug.debugfs_phy, sc,
|
||||
&fops_tx99);
|
||||
debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
|
||||
sc->debug.debugfs_phy, sc,
|
||||
&fops_tx99_power);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Qualcomm Atheros, Inc.
|
||||
* Copyright (c) 2013 Qualcomm Atheros, 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
|
||||
@ -14,409 +14,348 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include "ath9k.h"
|
||||
#include "reg.h"
|
||||
#include "hw-ops.h"
|
||||
|
||||
const char *ath9k_hw_wow_event_to_string(u32 wow_event)
|
||||
static const struct wiphy_wowlan_support ath9k_wowlan_support = {
|
||||
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
|
||||
.n_patterns = MAX_NUM_USER_PATTERN,
|
||||
.pattern_min_len = 1,
|
||||
.pattern_max_len = MAX_PATTERN_SIZE,
|
||||
};
|
||||
|
||||
static void ath9k_wow_map_triggers(struct ath_softc *sc,
|
||||
struct cfg80211_wowlan *wowlan,
|
||||
u32 *wow_triggers)
|
||||
{
|
||||
if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
|
||||
return "Magic pattern";
|
||||
if (wow_event & AH_WOW_USER_PATTERN_EN)
|
||||
return "User pattern";
|
||||
if (wow_event & AH_WOW_LINK_CHANGE)
|
||||
return "Link change";
|
||||
if (wow_event & AH_WOW_BEACON_MISS)
|
||||
return "Beacon miss";
|
||||
if (wowlan->disconnect)
|
||||
*wow_triggers |= AH_WOW_LINK_CHANGE |
|
||||
AH_WOW_BEACON_MISS;
|
||||
if (wowlan->magic_pkt)
|
||||
*wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
|
||||
|
||||
if (wowlan->n_patterns)
|
||||
*wow_triggers |= AH_WOW_USER_PATTERN_EN;
|
||||
|
||||
sc->wow_enabled = *wow_triggers;
|
||||
|
||||
return "unknown reason";
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
|
||||
|
||||
static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
|
||||
static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int pattern_count = 0;
|
||||
int i, byte_cnt;
|
||||
u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
|
||||
u8 dis_deauth_mask[MAX_PATTERN_SIZE];
|
||||
|
||||
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
|
||||
memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
|
||||
memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
|
||||
|
||||
/* set rx disable bit */
|
||||
REG_WRITE(ah, AR_CR, AR_CR_RXD);
|
||||
/*
|
||||
* Create Dissassociate / Deauthenticate packet filter
|
||||
*
|
||||
* 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
|
||||
* +--------------+----------+---------+--------+--------+----
|
||||
* + Frame Control+ Duration + DA + SA + BSSID +
|
||||
* +--------------+----------+---------+--------+--------+----
|
||||
*
|
||||
* The above is the management frame format for disassociate/
|
||||
* deauthenticate pattern, from this we need to match the first byte
|
||||
* of 'Frame Control' and DA, SA, and BSSID fields
|
||||
* (skipping 2nd byte of FC and Duration feild.
|
||||
*
|
||||
* Disassociate pattern
|
||||
* --------------------
|
||||
* Frame control = 00 00 1010
|
||||
* DA, SA, BSSID = x:x:x:x:x:x
|
||||
* Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
|
||||
* | x:x:x:x:x:x -- 22 bytes
|
||||
*
|
||||
* Deauthenticate pattern
|
||||
* ----------------------
|
||||
* Frame control = 00 00 1100
|
||||
* DA, SA, BSSID = x:x:x:x:x:x
|
||||
* Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
|
||||
* | x:x:x:x:x:x -- 22 bytes
|
||||
*/
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
|
||||
ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
|
||||
REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
|
||||
return;
|
||||
}
|
||||
/* Create Disassociate Pattern first */
|
||||
|
||||
REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
|
||||
}
|
||||
byte_cnt = 0;
|
||||
|
||||
static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
|
||||
u32 ctl[13] = {0};
|
||||
u32 data_word[KAL_NUM_DATA_WORDS];
|
||||
u8 i;
|
||||
u32 wow_ka_data_word0;
|
||||
/* Fill out the mask with all FF's */
|
||||
|
||||
memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
|
||||
memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
|
||||
for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
|
||||
dis_deauth_mask[i] = 0xff;
|
||||
|
||||
/* set the transmit buffer */
|
||||
ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
|
||||
ctl[1] = 0;
|
||||
ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
|
||||
ctl[4] = 0;
|
||||
ctl[7] = (ah->txchainmask) << 2;
|
||||
ctl[2] = 0xf << 16; /* tx_tries 0 */
|
||||
/* copy the first byte of frame control field */
|
||||
dis_deauth_pattern[byte_cnt] = 0xa0;
|
||||
byte_cnt++;
|
||||
|
||||
for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
|
||||
REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
|
||||
/* skip 2nd byte of frame control and Duration field */
|
||||
byte_cnt += 3;
|
||||
|
||||
REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
|
||||
/*
|
||||
* need not match the destination mac address, it can be a broadcast
|
||||
* mac address or an unicast to this station
|
||||
*/
|
||||
byte_cnt += 6;
|
||||
|
||||
data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
|
||||
(KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
|
||||
data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
|
||||
(ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
|
||||
data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
|
||||
(ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
|
||||
data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
|
||||
(sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
|
||||
data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
|
||||
(ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
|
||||
data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
|
||||
/* copy the source mac address */
|
||||
memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
|
||||
|
||||
if (AR_SREV_9462_20(ah)) {
|
||||
/* AR9462 2.0 has an extra descriptor word (time based
|
||||
* discard) compared to other chips */
|
||||
REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
|
||||
wow_ka_data_word0 = AR_WOW_TXBUF(13);
|
||||
} else {
|
||||
wow_ka_data_word0 = AR_WOW_TXBUF(12);
|
||||
}
|
||||
byte_cnt += 6;
|
||||
|
||||
for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
|
||||
REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
|
||||
/* copy the bssid, its same as the source mac address */
|
||||
|
||||
memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
|
||||
|
||||
/* Create Disassociate pattern mask */
|
||||
|
||||
dis_deauth_mask[0] = 0xfe;
|
||||
dis_deauth_mask[1] = 0x03;
|
||||
dis_deauth_mask[2] = 0xc0;
|
||||
|
||||
ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
|
||||
|
||||
ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
|
||||
pattern_count, byte_cnt);
|
||||
|
||||
pattern_count++;
|
||||
/*
|
||||
* for de-authenticate pattern, only the first byte of the frame
|
||||
* control field gets changed from 0xA0 to 0xC0
|
||||
*/
|
||||
dis_deauth_pattern[0] = 0xC0;
|
||||
|
||||
ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
|
||||
pattern_count, byte_cnt);
|
||||
|
||||
}
|
||||
|
||||
void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
|
||||
u8 *user_mask, int pattern_count,
|
||||
int pattern_len)
|
||||
static void ath9k_wow_add_pattern(struct ath_softc *sc,
|
||||
struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
int i;
|
||||
u32 pattern_val, mask_val;
|
||||
u32 set, clr;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath9k_wow_pattern *wow_pattern = NULL;
|
||||
struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
|
||||
int mask_len;
|
||||
s8 i = 0;
|
||||
|
||||
/* FIXME: should check count by querying the hardware capability */
|
||||
if (pattern_count >= MAX_NUM_PATTERN)
|
||||
if (!wowlan->n_patterns)
|
||||
return;
|
||||
|
||||
REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
|
||||
|
||||
/* set the registers for pattern */
|
||||
for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
|
||||
memcpy(&pattern_val, user_pattern, 4);
|
||||
REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
|
||||
pattern_val);
|
||||
user_pattern += 4;
|
||||
}
|
||||
|
||||
/* set the registers for mask */
|
||||
for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
|
||||
memcpy(&mask_val, user_mask, 4);
|
||||
REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
|
||||
user_mask += 4;
|
||||
}
|
||||
|
||||
/* set the pattern length to be matched
|
||||
*
|
||||
* AR_WOW_LENGTH1_REG1
|
||||
* bit 31:24 pattern 0 length
|
||||
* bit 23:16 pattern 1 length
|
||||
* bit 15:8 pattern 2 length
|
||||
* bit 7:0 pattern 3 length
|
||||
*
|
||||
* AR_WOW_LENGTH1_REG2
|
||||
* bit 31:24 pattern 4 length
|
||||
* bit 23:16 pattern 5 length
|
||||
* bit 15:8 pattern 6 length
|
||||
* bit 7:0 pattern 7 length
|
||||
*
|
||||
* the below logic writes out the new
|
||||
* pattern length for the corresponding
|
||||
* pattern_count, while masking out the
|
||||
* other fields
|
||||
*/
|
||||
|
||||
ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
|
||||
|
||||
if (pattern_count < 4) {
|
||||
/* Pattern 0-3 uses AR_WOW_LENGTH1 register */
|
||||
set = (pattern_len & AR_WOW_LENGTH_MAX) <<
|
||||
AR_WOW_LEN1_SHIFT(pattern_count);
|
||||
clr = AR_WOW_LENGTH1_MASK(pattern_count);
|
||||
REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
|
||||
} else {
|
||||
/* Pattern 4-7 uses AR_WOW_LENGTH2 register */
|
||||
set = (pattern_len & AR_WOW_LENGTH_MAX) <<
|
||||
AR_WOW_LEN2_SHIFT(pattern_count);
|
||||
clr = AR_WOW_LENGTH2_MASK(pattern_count);
|
||||
REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
|
||||
}
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
|
||||
|
||||
u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
|
||||
{
|
||||
u32 wow_status = 0;
|
||||
u32 val = 0, rval;
|
||||
|
||||
/*
|
||||
* read the WoW status register to know
|
||||
* the wakeup reason
|
||||
* Add the new user configured patterns
|
||||
*/
|
||||
rval = REG_READ(ah, AR_WOW_PATTERN);
|
||||
val = AR_WOW_STATUS(rval);
|
||||
for (i = 0; i < wowlan->n_patterns; i++) {
|
||||
|
||||
/*
|
||||
* mask only the WoW events that we have enabled. Sometimes
|
||||
* we have spurious WoW events from the AR_WOW_PATTERN
|
||||
* register. This mask will clean it up.
|
||||
*/
|
||||
wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
|
||||
|
||||
val &= ah->wow_event_mask;
|
||||
if (!wow_pattern)
|
||||
return;
|
||||
|
||||
if (val) {
|
||||
if (val & AR_WOW_MAGIC_PAT_FOUND)
|
||||
wow_status |= AH_WOW_MAGIC_PATTERN_EN;
|
||||
if (AR_WOW_PATTERN_FOUND(val))
|
||||
wow_status |= AH_WOW_USER_PATTERN_EN;
|
||||
if (val & AR_WOW_KEEP_ALIVE_FAIL)
|
||||
wow_status |= AH_WOW_LINK_CHANGE;
|
||||
if (val & AR_WOW_BEACON_FAIL)
|
||||
wow_status |= AH_WOW_BEACON_MISS;
|
||||
}
|
||||
|
||||
/*
|
||||
* set and clear WOW_PME_CLEAR registers for the chip to
|
||||
* generate next wow signal.
|
||||
* disable D3 before accessing other registers ?
|
||||
*/
|
||||
|
||||
/* do we need to check the bit value 0x01000000 (7-10) ?? */
|
||||
REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
|
||||
AR_PMCTRL_PWR_STATE_D1D3);
|
||||
|
||||
/*
|
||||
* clear all events
|
||||
*/
|
||||
REG_WRITE(ah, AR_WOW_PATTERN,
|
||||
AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
|
||||
|
||||
/*
|
||||
* restore the beacon threshold to init value
|
||||
*/
|
||||
REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
|
||||
|
||||
/*
|
||||
* Restore the way the PCI-E reset, Power-On-Reset, external
|
||||
* PCIE_POR_SHORT pins are tied to its original value.
|
||||
* Previously just before WoW sleep, we untie the PCI-E
|
||||
* reset to our Chip's Power On Reset so that any PCI-E
|
||||
* reset from the bus will not reset our chip
|
||||
*/
|
||||
if (ah->is_pciexpress)
|
||||
ath9k_hw_configpcipowersave(ah, false);
|
||||
|
||||
ah->wow_event_mask = 0;
|
||||
|
||||
return wow_status;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
|
||||
|
||||
void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
|
||||
{
|
||||
u32 wow_event_mask;
|
||||
u32 set, clr;
|
||||
|
||||
/*
|
||||
* wow_event_mask is a mask to the AR_WOW_PATTERN register to
|
||||
* indicate which WoW events we have enabled. The WoW events
|
||||
* are from the 'pattern_enable' in this function and
|
||||
* 'pattern_count' of ath9k_hw_wow_apply_pattern()
|
||||
*/
|
||||
wow_event_mask = ah->wow_event_mask;
|
||||
|
||||
/*
|
||||
* Untie Power-on-Reset from the PCI-E-Reset. When we are in
|
||||
* WOW sleep, we do want the Reset from the PCI-E to disturb
|
||||
* our hw state
|
||||
*/
|
||||
if (ah->is_pciexpress) {
|
||||
/*
|
||||
* we need to untie the internal POR (power-on-reset)
|
||||
* to the external PCI-E reset. We also need to tie
|
||||
* the PCI-E Phy reset to the PCI-E reset.
|
||||
* TODO: convert the generic user space pattern to
|
||||
* appropriate chip specific/802.11 pattern.
|
||||
*/
|
||||
set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
|
||||
clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
|
||||
REG_RMW(ah, AR_WA, set, clr);
|
||||
|
||||
mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
|
||||
memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
|
||||
memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
|
||||
memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
|
||||
patterns[i].pattern_len);
|
||||
memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
|
||||
wow_pattern->pattern_len = patterns[i].pattern_len;
|
||||
|
||||
/*
|
||||
* just need to take care of deauth and disssoc pattern,
|
||||
* make sure we don't overwrite them.
|
||||
*/
|
||||
|
||||
ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
|
||||
wow_pattern->mask_bytes,
|
||||
i + 2,
|
||||
wow_pattern->pattern_len);
|
||||
kfree(wow_pattern);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* set the power states appropriately and enable PME
|
||||
*/
|
||||
set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
|
||||
AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
|
||||
|
||||
/*
|
||||
* set and clear WOW_PME_CLEAR registers for the chip
|
||||
* to generate next wow signal.
|
||||
*/
|
||||
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
|
||||
clr = AR_PMCTRL_WOW_PME_CLR;
|
||||
REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
|
||||
|
||||
/*
|
||||
* Setup for:
|
||||
* - beacon misses
|
||||
* - magic pattern
|
||||
* - keep alive timeout
|
||||
* - pattern matching
|
||||
*/
|
||||
|
||||
/*
|
||||
* Program default values for pattern backoff, aifs/slot/KAL count,
|
||||
* beacon miss timeout, KAL timeout, etc.
|
||||
*/
|
||||
set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
|
||||
REG_SET_BIT(ah, AR_WOW_PATTERN, set);
|
||||
|
||||
set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
|
||||
AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
|
||||
AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
|
||||
REG_SET_BIT(ah, AR_WOW_COUNT, set);
|
||||
|
||||
if (pattern_enable & AH_WOW_BEACON_MISS)
|
||||
set = AR_WOW_BEACON_TIMO;
|
||||
/* We are not using beacon miss, program a large value */
|
||||
else
|
||||
set = AR_WOW_BEACON_TIMO_MAX;
|
||||
|
||||
REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
|
||||
|
||||
/*
|
||||
* Keep alive timo in ms except AR9280
|
||||
*/
|
||||
if (!pattern_enable)
|
||||
set = AR_WOW_KEEP_ALIVE_NEVER;
|
||||
else
|
||||
set = KAL_TIMEOUT * 32;
|
||||
|
||||
REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
|
||||
|
||||
/*
|
||||
* Keep alive delay in us. based on 'power on clock',
|
||||
* therefore in usec
|
||||
*/
|
||||
set = KAL_DELAY * 1000;
|
||||
REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
|
||||
|
||||
/*
|
||||
* Create keep alive pattern to respond to beacons
|
||||
*/
|
||||
ath9k_wow_create_keep_alive_pattern(ah);
|
||||
|
||||
/*
|
||||
* Configure MAC WoW Registers
|
||||
*/
|
||||
set = 0;
|
||||
/* Send keep alive timeouts anyway */
|
||||
clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
|
||||
|
||||
if (pattern_enable & AH_WOW_LINK_CHANGE)
|
||||
wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
|
||||
else
|
||||
set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
|
||||
|
||||
set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
|
||||
REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
|
||||
|
||||
/*
|
||||
* we are relying on a bmiss failure. ensure we have
|
||||
* enough threshold to prevent false positives
|
||||
*/
|
||||
REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
|
||||
AR_WOW_BMISSTHRESHOLD);
|
||||
|
||||
set = 0;
|
||||
clr = 0;
|
||||
|
||||
if (pattern_enable & AH_WOW_BEACON_MISS) {
|
||||
set = AR_WOW_BEACON_FAIL_EN;
|
||||
wow_event_mask |= AR_WOW_BEACON_FAIL;
|
||||
} else {
|
||||
clr = AR_WOW_BEACON_FAIL_EN;
|
||||
}
|
||||
|
||||
REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
|
||||
|
||||
set = 0;
|
||||
clr = 0;
|
||||
/*
|
||||
* Enable the magic packet registers
|
||||
*/
|
||||
if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
|
||||
set = AR_WOW_MAGIC_EN;
|
||||
wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
|
||||
} else {
|
||||
clr = AR_WOW_MAGIC_EN;
|
||||
}
|
||||
set |= AR_WOW_MAC_INTR_EN;
|
||||
REG_RMW(ah, AR_WOW_PATTERN, set, clr);
|
||||
|
||||
REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
|
||||
AR_WOW_PATTERN_SUPPORTED);
|
||||
|
||||
/*
|
||||
* Set the power states appropriately and enable PME
|
||||
*/
|
||||
clr = 0;
|
||||
set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
|
||||
AR_PMCTRL_PWR_PM_CTRL_ENA;
|
||||
|
||||
clr = AR_PCIE_PM_CTRL_ENA;
|
||||
REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
|
||||
|
||||
/*
|
||||
* this is needed to prevent the chip waking up
|
||||
* the host within 3-4 seconds with certain
|
||||
* platform/BIOS. The fix is to enable
|
||||
* D1 & D3 to match original definition and
|
||||
* also match the OTP value. Anyway this
|
||||
* is more related to SW WOW.
|
||||
*/
|
||||
clr = AR_PMCTRL_PWR_STATE_D1D3;
|
||||
REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
|
||||
|
||||
set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
|
||||
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
|
||||
|
||||
REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
|
||||
|
||||
/* to bring down WOW power low margin */
|
||||
set = BIT(13);
|
||||
REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
|
||||
/* HW WoW */
|
||||
clr = BIT(5);
|
||||
REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
|
||||
|
||||
ath9k_hw_set_powermode_wow_sleep(ah);
|
||||
ah->wow_event_mask = wow_event_mask;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_wow_enable);
|
||||
|
||||
int ath9k_suspend(struct ieee80211_hw *hw,
|
||||
struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 wow_triggers_enabled = 0;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
ath_cancel_work(sc);
|
||||
ath_stop_ani(sc);
|
||||
del_timer_sync(&sc->rx_poll_timer);
|
||||
|
||||
if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
|
||||
ath_dbg(common, ANY, "Device not present\n");
|
||||
ret = -EINVAL;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
if (WARN_ON(!wowlan)) {
|
||||
ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
|
||||
ret = -EINVAL;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
if (!device_can_wakeup(sc->dev)) {
|
||||
ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
|
||||
ret = 1;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
/*
|
||||
* none of the sta vifs are associated
|
||||
* and we are not currently handling multivif
|
||||
* cases, for instance we have to seperately
|
||||
* configure 'keep alive frame' for each
|
||||
* STA.
|
||||
*/
|
||||
|
||||
if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
|
||||
ath_dbg(common, WOW, "None of the STA vifs are associated\n");
|
||||
ret = 1;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
if (sc->nvifs > 1) {
|
||||
ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
|
||||
ret = 1;
|
||||
goto fail_wow;
|
||||
}
|
||||
|
||||
ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
|
||||
|
||||
ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
|
||||
wow_triggers_enabled);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
ath9k_stop_btcoex(sc);
|
||||
|
||||
/*
|
||||
* Enable wake up on recieving disassoc/deauth
|
||||
* frame by default.
|
||||
*/
|
||||
ath9k_wow_add_disassoc_deauth_pattern(sc);
|
||||
|
||||
if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
|
||||
ath9k_wow_add_pattern(sc, wowlan);
|
||||
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
/*
|
||||
* To avoid false wake, we enable beacon miss interrupt only
|
||||
* when we go to sleep. We save the current interrupt mask
|
||||
* so we can restore it after the system wakes up
|
||||
*/
|
||||
sc->wow_intr_before_sleep = ah->imask;
|
||||
ah->imask &= ~ATH9K_INT_GLOBAL;
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
/*
|
||||
* we can now sync irq and kill any running tasklets, since we already
|
||||
* disabled interrupts and not holding a spin lock
|
||||
*/
|
||||
synchronize_irq(sc->irq);
|
||||
tasklet_kill(&sc->intr_tq);
|
||||
|
||||
ath9k_hw_wow_enable(ah, wow_triggers_enabled);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
ath_dbg(common, ANY, "WoW enabled in ath9k\n");
|
||||
atomic_inc(&sc->wow_sleep_proc_intr);
|
||||
|
||||
fail_wow:
|
||||
mutex_unlock(&sc->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath9k_resume(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 wow_status;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
ah->imask = sc->wow_intr_before_sleep;
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
wow_status = ath9k_hw_wow_wakeup(ah);
|
||||
|
||||
if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
|
||||
/*
|
||||
* some devices may not pick beacon miss
|
||||
* as the reason they woke up so we add
|
||||
* that here for that shortcoming.
|
||||
*/
|
||||
wow_status |= AH_WOW_BEACON_MISS;
|
||||
atomic_dec(&sc->wow_got_bmiss_intr);
|
||||
ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
|
||||
}
|
||||
|
||||
atomic_dec(&sc->wow_sleep_proc_intr);
|
||||
|
||||
if (wow_status) {
|
||||
ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
|
||||
ath9k_hw_wow_event_to_string(wow_status), wow_status);
|
||||
}
|
||||
|
||||
ath_restart_work(sc);
|
||||
ath9k_start_btcoex(sc);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
mutex_unlock(&sc->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
device_init_wakeup(sc->dev, 1);
|
||||
device_set_wakeup_enable(sc->dev, enabled);
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
void ath9k_init_wow(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
||||
if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
|
||||
(sc->driver_data & ATH9K_PCI_WOW) &&
|
||||
device_can_wakeup(sc->dev))
|
||||
hw->wiphy->wowlan = &ath9k_wowlan_support;
|
||||
|
||||
atomic_set(&sc->wow_sleep_proc_intr, -1);
|
||||
atomic_set(&sc->wow_got_bmiss_intr, -1);
|
||||
}
|
||||
|
@ -1786,6 +1786,9 @@ bool ath_drain_all_txq(struct ath_softc *sc)
|
||||
if (!ATH_TXQ_SETUP(sc, i))
|
||||
continue;
|
||||
|
||||
if (!sc->tx.txq[i].axq_depth)
|
||||
continue;
|
||||
|
||||
if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum))
|
||||
npend |= BIT(i);
|
||||
}
|
||||
@ -2749,6 +2752,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ATH9K_TX99
|
||||
|
||||
int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
|
||||
struct ath_tx_control *txctl)
|
||||
{
|
||||
@ -2791,3 +2796,5 @@ int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ATH9K_TX99 */
|
||||
|
@ -37,17 +37,18 @@ static int __ath_regd_init(struct ath_regulatory *reg);
|
||||
|
||||
/* We enable active scan on these a case by case basis by regulatory domain */
|
||||
#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
|
||||
NL80211_RRF_PASSIVE_SCAN)
|
||||
NL80211_RRF_NO_IR)
|
||||
#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
|
||||
NL80211_RRF_NO_IR | \
|
||||
NL80211_RRF_NO_OFDM)
|
||||
|
||||
/* We allow IBSS on these on a case by case basis by regulatory domain */
|
||||
#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \
|
||||
ATH9K_2GHZ_CH12_13, \
|
||||
@ -113,286 +114,6 @@ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
|
||||
}
|
||||
};
|
||||
|
||||
static inline bool is_wwr_sku(u16 regd)
|
||||
{
|
||||
return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
|
||||
(((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
|
||||
(regd == WORLD));
|
||||
}
|
||||
|
||||
static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
|
||||
{
|
||||
return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
|
||||
}
|
||||
|
||||
bool ath_is_world_regd(struct ath_regulatory *reg)
|
||||
{
|
||||
return is_wwr_sku(ath_regd_get_eepromRD(reg));
|
||||
}
|
||||
EXPORT_SYMBOL(ath_is_world_regd);
|
||||
|
||||
static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
|
||||
{
|
||||
/* this is the most restrictive */
|
||||
return &ath_world_regdom_64;
|
||||
}
|
||||
|
||||
static const struct
|
||||
ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
|
||||
{
|
||||
switch (reg->regpair->regDmnEnum) {
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
return &ath_world_regdom_60_61_62;
|
||||
case 0x63:
|
||||
case 0x65:
|
||||
return &ath_world_regdom_63_65;
|
||||
case 0x64:
|
||||
return &ath_world_regdom_64;
|
||||
case 0x66:
|
||||
case 0x69:
|
||||
return &ath_world_regdom_66_69;
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
case 0x6A:
|
||||
case 0x6C:
|
||||
return &ath_world_regdom_67_68_6A_6C;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return ath_default_world_regdomain();
|
||||
}
|
||||
}
|
||||
|
||||
bool ath_is_49ghz_allowed(u16 regdomain)
|
||||
{
|
||||
/* possibly more */
|
||||
return regdomain == MKK9_MKKC;
|
||||
}
|
||||
EXPORT_SYMBOL(ath_is_49ghz_allowed);
|
||||
|
||||
/* Frequency is one where radar detection is required */
|
||||
static bool ath_is_radar_freq(u16 center_freq)
|
||||
{
|
||||
return (center_freq >= 5260 && center_freq <= 5700);
|
||||
}
|
||||
|
||||
/*
|
||||
* N.B: These exception rules do not apply radar freqs.
|
||||
*
|
||||
* - We enable adhoc (or beaconing) if allowed by 11d
|
||||
* - We enable active scan if the channel is allowed by 11d
|
||||
* - If no country IE has been processed and a we determine we have
|
||||
* received a beacon on a channel we can enable active scan and
|
||||
* adhoc (or beaconing).
|
||||
*/
|
||||
static void
|
||||
ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
{
|
||||
enum ieee80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
|
||||
sband = wiphy->bands[band];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
|
||||
ch = &sband->channels[i];
|
||||
|
||||
if (ath_is_radar_freq(ch->center_freq) ||
|
||||
(ch->flags & IEEE80211_CHAN_RADAR))
|
||||
continue;
|
||||
|
||||
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
reg_rule = freq_reg_info(wiphy, ch->center_freq);
|
||||
if (IS_ERR(reg_rule))
|
||||
continue;
|
||||
/*
|
||||
* If 11d had a rule for this channel ensure
|
||||
* we enable adhoc/beaconing if it allows us to
|
||||
* use it. Note that we would have disabled it
|
||||
* by applying our static world regdomain by
|
||||
* default during init, prior to calling our
|
||||
* regulatory_hint().
|
||||
*/
|
||||
if (!(reg_rule->flags &
|
||||
NL80211_RRF_NO_IBSS))
|
||||
ch->flags &=
|
||||
~IEEE80211_CHAN_NO_IBSS;
|
||||
if (!(reg_rule->flags &
|
||||
NL80211_RRF_PASSIVE_SCAN))
|
||||
ch->flags &=
|
||||
~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
} else {
|
||||
if (ch->beacon_found)
|
||||
ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Allows active scan scan on Ch 12 and 13 */
|
||||
static void
|
||||
ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
|
||||
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If no country IE has been received always enable active scan
|
||||
* on these channels. This is only done for specific regulatory SKUs
|
||||
*/
|
||||
if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
ch = &sband->channels[11]; /* CH 12 */
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
ch = &sband->channels[12]; /* CH 13 */
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a country IE has been received check its rule for this
|
||||
* channel first before enabling active scan. The passive scan
|
||||
* would have been enforced by the initial processing of our
|
||||
* custom regulatory domain.
|
||||
*/
|
||||
|
||||
ch = &sband->channels[11]; /* CH 12 */
|
||||
reg_rule = freq_reg_info(wiphy, ch->center_freq);
|
||||
if (!IS_ERR(reg_rule)) {
|
||||
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
}
|
||||
|
||||
ch = &sband->channels[12]; /* CH 13 */
|
||||
reg_rule = freq_reg_info(wiphy, ch->center_freq);
|
||||
if (!IS_ERR(reg_rule)) {
|
||||
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
|
||||
static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
if (!wiphy->bands[IEEE80211_BAND_5GHZ])
|
||||
return;
|
||||
|
||||
sband = wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (!ath_is_radar_freq(ch->center_freq))
|
||||
continue;
|
||||
/* We always enable radar detection/DFS on this
|
||||
* frequency range. Additionally we also apply on
|
||||
* this frequency range:
|
||||
* - If STA mode does not yet have DFS supports disable
|
||||
* active scanning
|
||||
* - If adhoc mode does not support DFS yet then
|
||||
* disable adhoc in the frequency.
|
||||
* - If AP mode does not yet support radar detection/DFS
|
||||
* do not allow AP mode
|
||||
*/
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
|
||||
ch->flags |= IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
}
|
||||
}
|
||||
|
||||
static void ath_reg_apply_world_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator,
|
||||
struct ath_regulatory *reg)
|
||||
{
|
||||
switch (reg->regpair->regDmnEnum) {
|
||||
case 0x60:
|
||||
case 0x63:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
case 0x6C:
|
||||
ath_reg_apply_beaconing_flags(wiphy, initiator);
|
||||
break;
|
||||
case 0x68:
|
||||
ath_reg_apply_beaconing_flags(wiphy, initiator);
|
||||
ath_reg_apply_active_scan_flags(wiphy, initiator);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static u16 ath_regd_find_country_by_name(char *alpha2)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
|
||||
if (!memcmp(allCountries[i].isoName, alpha2, 2))
|
||||
return allCountries[i].countryCode;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __ath_reg_dyn_country(struct wiphy *wiphy,
|
||||
struct ath_regulatory *reg,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
u16 country_code;
|
||||
|
||||
if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
|
||||
!ath_is_world_regd(reg))
|
||||
return -EINVAL;
|
||||
|
||||
country_code = ath_regd_find_country_by_name(request->alpha2);
|
||||
if (country_code == (u16) -1)
|
||||
return -EINVAL;
|
||||
|
||||
reg->current_rd = COUNTRY_ERD_FLAG;
|
||||
reg->current_rd |= country_code;
|
||||
|
||||
__ath_regd_init(reg);
|
||||
|
||||
ath_reg_apply_world_flags(wiphy, request->initiator, reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath_reg_dyn_country(struct wiphy *wiphy,
|
||||
struct ath_regulatory *reg,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
if (__ath_reg_dyn_country(wiphy, reg, request))
|
||||
return;
|
||||
|
||||
printk(KERN_DEBUG "ath: regdomain 0x%0x "
|
||||
"dynamically updated by %s\n",
|
||||
reg->current_rd,
|
||||
reg_initiator_name(request->initiator));
|
||||
}
|
||||
|
||||
static bool dynamic_country_user_possible(struct ath_regulatory *reg)
|
||||
{
|
||||
if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
|
||||
@ -465,15 +186,316 @@ static bool dynamic_country_user_possible(struct ath_regulatory *reg)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ath_reg_dyn_country_user(struct wiphy *wiphy,
|
||||
struct ath_regulatory *reg,
|
||||
struct regulatory_request *request)
|
||||
static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
|
||||
{
|
||||
if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
|
||||
return;
|
||||
return false;
|
||||
if (!dynamic_country_user_possible(reg))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool is_wwr_sku(u16 regd)
|
||||
{
|
||||
return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
|
||||
(((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
|
||||
(regd == WORLD));
|
||||
}
|
||||
|
||||
static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
|
||||
{
|
||||
return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
|
||||
}
|
||||
|
||||
bool ath_is_world_regd(struct ath_regulatory *reg)
|
||||
{
|
||||
return is_wwr_sku(ath_regd_get_eepromRD(reg));
|
||||
}
|
||||
EXPORT_SYMBOL(ath_is_world_regd);
|
||||
|
||||
static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
|
||||
{
|
||||
/* this is the most restrictive */
|
||||
return &ath_world_regdom_64;
|
||||
}
|
||||
|
||||
static const struct
|
||||
ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
|
||||
{
|
||||
switch (reg->regpair->regDmnEnum) {
|
||||
case 0x60:
|
||||
case 0x61:
|
||||
case 0x62:
|
||||
return &ath_world_regdom_60_61_62;
|
||||
case 0x63:
|
||||
case 0x65:
|
||||
return &ath_world_regdom_63_65;
|
||||
case 0x64:
|
||||
return &ath_world_regdom_64;
|
||||
case 0x66:
|
||||
case 0x69:
|
||||
return &ath_world_regdom_66_69;
|
||||
case 0x67:
|
||||
case 0x68:
|
||||
case 0x6A:
|
||||
case 0x6C:
|
||||
return &ath_world_regdom_67_68_6A_6C;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return ath_default_world_regdomain();
|
||||
}
|
||||
}
|
||||
|
||||
bool ath_is_49ghz_allowed(u16 regdomain)
|
||||
{
|
||||
/* possibly more */
|
||||
return regdomain == MKK9_MKKC;
|
||||
}
|
||||
EXPORT_SYMBOL(ath_is_49ghz_allowed);
|
||||
|
||||
/* Frequency is one where radar detection is required */
|
||||
static bool ath_is_radar_freq(u16 center_freq)
|
||||
{
|
||||
return (center_freq >= 5260 && center_freq <= 5700);
|
||||
}
|
||||
|
||||
static void ath_force_clear_no_ir_chan(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *ch)
|
||||
{
|
||||
const struct ieee80211_reg_rule *reg_rule;
|
||||
|
||||
reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
|
||||
if (IS_ERR(reg_rule))
|
||||
return;
|
||||
ath_reg_dyn_country(wiphy, reg, request);
|
||||
|
||||
if (!(reg_rule->flags & NL80211_RRF_NO_IR))
|
||||
if (ch->flags & IEEE80211_CHAN_NO_IR)
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
|
||||
static void ath_force_clear_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
|
||||
{
|
||||
struct ieee80211_channel *ch;
|
||||
|
||||
ch = ieee80211_get_channel(wiphy, center_freq);
|
||||
if (!ch)
|
||||
return;
|
||||
|
||||
ath_force_clear_no_ir_chan(wiphy, ch);
|
||||
}
|
||||
|
||||
static void ath_force_no_ir_chan(struct ieee80211_channel *ch)
|
||||
{
|
||||
ch->flags |= IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
|
||||
static void ath_force_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
|
||||
{
|
||||
struct ieee80211_channel *ch;
|
||||
|
||||
ch = ieee80211_get_channel(wiphy, center_freq);
|
||||
if (!ch)
|
||||
return;
|
||||
|
||||
ath_force_no_ir_chan(ch);
|
||||
}
|
||||
|
||||
static void
|
||||
__ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
struct ath_regulatory *reg,
|
||||
enum nl80211_reg_initiator initiator,
|
||||
struct ieee80211_channel *ch)
|
||||
{
|
||||
if (ath_is_radar_freq(ch->center_freq) ||
|
||||
(ch->flags & IEEE80211_CHAN_RADAR))
|
||||
return;
|
||||
|
||||
switch (initiator) {
|
||||
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
||||
ath_force_clear_no_ir_chan(wiphy, ch);
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_USER:
|
||||
if (ath_reg_dyn_country_user_allow(reg))
|
||||
ath_force_clear_no_ir_chan(wiphy, ch);
|
||||
break;
|
||||
default:
|
||||
if (ch->beacon_found)
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* These exception rules do not apply radar frequencies.
|
||||
*
|
||||
* - We enable initiating radiation if the country IE says its fine:
|
||||
* - If no country IE has been processed and a we determine we have
|
||||
* received a beacon on a channel we can enable initiating radiation.
|
||||
*/
|
||||
static void
|
||||
ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
struct ath_regulatory *reg,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
{
|
||||
enum ieee80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
sband = wiphy->bands[band];
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
__ath_reg_apply_beaconing_flags(wiphy, reg,
|
||||
initiator, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ath_reg_apply_ir_flags()
|
||||
* @wiphy: the wiphy to use
|
||||
* @initiator: the regulatory hint initiator
|
||||
*
|
||||
* If no country IE has been received always enable passive scan
|
||||
* and no-ibss on these channels. This is only done for specific
|
||||
* regulatory SKUs.
|
||||
*
|
||||
* If a country IE has been received check its rule for this
|
||||
* channel first before enabling active scan. The passive scan
|
||||
* would have been enforced by the initial processing of our
|
||||
* custom regulatory domain.
|
||||
*/
|
||||
static void
|
||||
ath_reg_apply_ir_flags(struct wiphy *wiphy,
|
||||
struct ath_regulatory *reg,
|
||||
enum nl80211_reg_initiator initiator)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
switch(initiator) {
|
||||
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
||||
ath_force_clear_no_ir_freq(wiphy, 2467);
|
||||
ath_force_clear_no_ir_freq(wiphy, 2472);
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_USER:
|
||||
if (!ath_reg_dyn_country_user_allow(reg))
|
||||
break;
|
||||
ath_force_clear_no_ir_freq(wiphy, 2467);
|
||||
ath_force_clear_no_ir_freq(wiphy, 2472);
|
||||
break;
|
||||
default:
|
||||
ath_force_no_ir_freq(wiphy, 2467);
|
||||
ath_force_no_ir_freq(wiphy, 2472);
|
||||
}
|
||||
}
|
||||
|
||||
/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
|
||||
static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
unsigned int i;
|
||||
|
||||
if (!wiphy->bands[IEEE80211_BAND_5GHZ])
|
||||
return;
|
||||
|
||||
sband = wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
for (i = 0; i < sband->n_channels; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (!ath_is_radar_freq(ch->center_freq))
|
||||
continue;
|
||||
/* We always enable radar detection/DFS on this
|
||||
* frequency range. Additionally we also apply on
|
||||
* this frequency range:
|
||||
* - If STA mode does not yet have DFS supports disable
|
||||
* active scanning
|
||||
* - If adhoc mode does not support DFS yet then
|
||||
* disable adhoc in the frequency.
|
||||
* - If AP mode does not yet support radar detection/DFS
|
||||
* do not allow AP mode
|
||||
*/
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
|
||||
ch->flags |= IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
|
||||
static void ath_reg_apply_world_flags(struct wiphy *wiphy,
|
||||
enum nl80211_reg_initiator initiator,
|
||||
struct ath_regulatory *reg)
|
||||
{
|
||||
switch (reg->regpair->regDmnEnum) {
|
||||
case 0x60:
|
||||
case 0x63:
|
||||
case 0x66:
|
||||
case 0x67:
|
||||
case 0x6C:
|
||||
ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
|
||||
break;
|
||||
case 0x68:
|
||||
ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
|
||||
ath_reg_apply_ir_flags(wiphy, reg, initiator);
|
||||
break;
|
||||
default:
|
||||
if (ath_reg_dyn_country_user_allow(reg))
|
||||
ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
|
||||
}
|
||||
}
|
||||
|
||||
static u16 ath_regd_find_country_by_name(char *alpha2)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
|
||||
if (!memcmp(allCountries[i].isoName, alpha2, 2))
|
||||
return allCountries[i].countryCode;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __ath_reg_dyn_country(struct wiphy *wiphy,
|
||||
struct ath_regulatory *reg,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
u16 country_code;
|
||||
|
||||
if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
|
||||
!ath_is_world_regd(reg))
|
||||
return -EINVAL;
|
||||
|
||||
country_code = ath_regd_find_country_by_name(request->alpha2);
|
||||
if (country_code == (u16) -1)
|
||||
return -EINVAL;
|
||||
|
||||
reg->current_rd = COUNTRY_ERD_FLAG;
|
||||
reg->current_rd |= country_code;
|
||||
|
||||
__ath_regd_init(reg);
|
||||
|
||||
ath_reg_apply_world_flags(wiphy, request->initiator, reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath_reg_dyn_country(struct wiphy *wiphy,
|
||||
struct ath_regulatory *reg,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
if (__ath_reg_dyn_country(wiphy, reg, request))
|
||||
return;
|
||||
|
||||
printk(KERN_DEBUG "ath: regdomain 0x%0x "
|
||||
"dynamically updated by %s\n",
|
||||
reg->current_rd,
|
||||
reg_initiator_name(request->initiator));
|
||||
}
|
||||
|
||||
void ath_reg_notifier_apply(struct wiphy *wiphy,
|
||||
@ -508,7 +530,8 @@ void ath_reg_notifier_apply(struct wiphy *wiphy,
|
||||
case NL80211_REGDOM_SET_BY_DRIVER:
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_USER:
|
||||
ath_reg_dyn_country_user(wiphy, reg, request);
|
||||
if (ath_reg_dyn_country_user_allow(reg))
|
||||
ath_reg_dyn_country(wiphy, reg, request);
|
||||
break;
|
||||
case NL80211_REGDOM_SET_BY_COUNTRY_IE:
|
||||
ath_reg_dyn_country(wiphy, reg, request);
|
||||
@ -609,7 +632,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
|
||||
const struct ieee80211_regdomain *regd;
|
||||
|
||||
wiphy->reg_notifier = reg_notifier;
|
||||
wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
|
||||
wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
|
||||
|
||||
if (ath_is_world_regd(reg)) {
|
||||
/*
|
||||
@ -617,7 +640,8 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
|
||||
* saved on the wiphy orig_* parameters
|
||||
*/
|
||||
regd = ath_world_regdomain(reg);
|
||||
wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
|
||||
REGULATORY_COUNTRY_IE_FOLLOW_POWER;
|
||||
} else {
|
||||
/*
|
||||
* This gets applied in the case of the absence of CRDA,
|
||||
|
@ -2644,7 +2644,7 @@ struct wcn36xx_hal_trigger_ba_rsp_candidate {
|
||||
struct add_ba_info ba_info[STACFG_MAX_TC];
|
||||
} __packed;
|
||||
|
||||
struct wcn36xx_hal_trigget_ba_req_candidate {
|
||||
struct wcn36xx_hal_trigger_ba_req_candidate {
|
||||
u8 sta_index;
|
||||
u8 tid_bitmap;
|
||||
} __packed;
|
||||
|
@ -641,7 +641,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BEACON_ENABLED) {
|
||||
if (changed & BSS_CHANGED_BEACON_ENABLED ||
|
||||
changed & BSS_CHANGED_BEACON) {
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC,
|
||||
"mac bss changed beacon enabled %d\n",
|
||||
bss_conf->enable_beacon);
|
||||
|
@ -115,6 +115,22 @@ static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta,
|
||||
}
|
||||
}
|
||||
|
||||
static void wcn36xx_smd_set_sta_default_ht_params(
|
||||
struct wcn36xx_hal_config_sta_params *sta_params)
|
||||
{
|
||||
sta_params->ht_capable = 1;
|
||||
sta_params->tx_channel_width_set = 1;
|
||||
sta_params->lsig_txop_protection = 1;
|
||||
sta_params->max_ampdu_size = 3;
|
||||
sta_params->max_ampdu_density = 5;
|
||||
sta_params->max_amsdu_size = 0;
|
||||
sta_params->sgi_20Mhz = 1;
|
||||
sta_params->sgi_40mhz = 1;
|
||||
sta_params->green_field_capable = 1;
|
||||
sta_params->delayed_ba_support = 0;
|
||||
sta_params->dsss_cck_mode_40mhz = 1;
|
||||
}
|
||||
|
||||
static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
@ -172,6 +188,7 @@ static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
|
||||
sizeof(priv_sta->supported_rates));
|
||||
} else {
|
||||
wcn36xx_set_default_rates(&sta_params->supported_rates);
|
||||
wcn36xx_smd_set_sta_default_ht_params(sta_params);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1838,7 +1855,7 @@ int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index)
|
||||
int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
|
||||
{
|
||||
struct wcn36xx_hal_trigger_ba_req_msg msg_body;
|
||||
struct wcn36xx_hal_trigget_ba_req_candidate *candidate;
|
||||
struct wcn36xx_hal_trigger_ba_req_candidate *candidate;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&wcn->hal_mutex);
|
||||
@ -1849,7 +1866,7 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
|
||||
msg_body.header.len += sizeof(*candidate);
|
||||
PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
|
||||
|
||||
candidate = (struct wcn36xx_hal_trigget_ba_req_candidate *)
|
||||
candidate = (struct wcn36xx_hal_trigger_ba_req_candidate *)
|
||||
(wcn->hal_buf + sizeof(msg_body));
|
||||
candidate->sta_index = sta_index;
|
||||
candidate->tid_bitmap = 1;
|
||||
|
@ -54,7 +54,7 @@ enum wcn36xx_debug_mask {
|
||||
};
|
||||
|
||||
#define wcn36xx_err(fmt, arg...) \
|
||||
printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg);
|
||||
printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg)
|
||||
|
||||
#define wcn36xx_warn(fmt, arg...) \
|
||||
printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg)
|
||||
|
@ -4,13 +4,12 @@ config BRCMUTIL
|
||||
config BRCMSMAC
|
||||
tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
|
||||
depends on MAC80211
|
||||
depends on BCMA
|
||||
depends on BCMA_POSSIBLE
|
||||
select BCMA
|
||||
select NEW_LEDS if BCMA_DRIVER_GPIO
|
||||
select LEDS_CLASS if BCMA_DRIVER_GPIO
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select CRC_CCITT
|
||||
select CRC8
|
||||
select CORDIC
|
||||
---help---
|
||||
This module adds support for PCIe wireless adapters based on Broadcom
|
||||
|
@ -28,7 +28,8 @@ brcmfmac-objs += \
|
||||
fweh.o \
|
||||
fwsignal.o \
|
||||
p2p.o \
|
||||
dhd_cdc.o \
|
||||
proto.o \
|
||||
bcdc.o \
|
||||
dhd_common.o \
|
||||
dhd_linux.o \
|
||||
btcoex.o
|
||||
|
384
drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
Normal file
384
drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
Normal file
@ -0,0 +1,384 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Communicates with the dongle by using dcmd codes.
|
||||
* For certain dcmd codes, the dongle interprets string data from the host.
|
||||
******************************************************************************/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "fwsignal.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "tracepoint.h"
|
||||
#include "proto.h"
|
||||
#include "bcdc.h"
|
||||
|
||||
struct brcmf_proto_bcdc_dcmd {
|
||||
__le32 cmd; /* dongle command value */
|
||||
__le32 len; /* lower 16: output buflen;
|
||||
* upper 16: input buflen (excludes header) */
|
||||
__le32 flags; /* flag defns given below */
|
||||
__le32 status; /* status code returned from the device */
|
||||
};
|
||||
|
||||
/* Max valid buffer size that can be sent to the dongle */
|
||||
#define BCDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
|
||||
|
||||
/* BCDC flag definitions */
|
||||
#define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */
|
||||
#define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
|
||||
#define BCDC_DCMD_IF_MASK 0xF000 /* I/F index */
|
||||
#define BCDC_DCMD_IF_SHIFT 12
|
||||
#define BCDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
|
||||
#define BCDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
|
||||
#define BCDC_DCMD_ID(flags) \
|
||||
(((flags) & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* BCDC header - Broadcom specific extension of CDC.
|
||||
* Used on data packets to convey priority across USB.
|
||||
*/
|
||||
#define BCDC_HEADER_LEN 4
|
||||
#define BCDC_PROTO_VER 2 /* Protocol version */
|
||||
#define BCDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
|
||||
#define BCDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
|
||||
#define BCDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
|
||||
#define BCDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
|
||||
#define BCDC_PRIORITY_MASK 0x7
|
||||
#define BCDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
|
||||
#define BCDC_FLAG2_IF_SHIFT 0
|
||||
|
||||
#define BCDC_GET_IF_IDX(hdr) \
|
||||
((int)((((hdr)->flags2) & BCDC_FLAG2_IF_MASK) >> BCDC_FLAG2_IF_SHIFT))
|
||||
#define BCDC_SET_IF_IDX(hdr, idx) \
|
||||
((hdr)->flags2 = (((hdr)->flags2 & ~BCDC_FLAG2_IF_MASK) | \
|
||||
((idx) << BCDC_FLAG2_IF_SHIFT)))
|
||||
|
||||
/**
|
||||
* struct brcmf_proto_bcdc_header - BCDC header format
|
||||
*
|
||||
* @flags: flags contain protocol and checksum info.
|
||||
* @priority: 802.1d priority and USB flow control info (bit 4:7).
|
||||
* @flags2: additional flags containing dongle interface index.
|
||||
* @data_offset: start of packet data. header is following by firmware signals.
|
||||
*/
|
||||
struct brcmf_proto_bcdc_header {
|
||||
u8 flags;
|
||||
u8 priority;
|
||||
u8 flags2;
|
||||
u8 data_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* maximum length of firmware signal data between
|
||||
* the BCDC header and packet data in the tx path.
|
||||
*/
|
||||
#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
|
||||
|
||||
#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
|
||||
#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
|
||||
* (amount of header tha might be added)
|
||||
* plus any space that might be needed
|
||||
* for bus alignment padding.
|
||||
*/
|
||||
#define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for
|
||||
* round off at the end of buffer
|
||||
* Currently is SDIO
|
||||
*/
|
||||
|
||||
struct brcmf_bcdc {
|
||||
u16 reqid;
|
||||
u8 bus_header[BUS_HEADER_LEN];
|
||||
struct brcmf_proto_bcdc_dcmd msg;
|
||||
unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
|
||||
};
|
||||
|
||||
static int brcmf_proto_bcdc_msg(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
|
||||
int len = le32_to_cpu(bcdc->msg.len) +
|
||||
sizeof(struct brcmf_proto_bcdc_dcmd);
|
||||
|
||||
brcmf_dbg(BCDC, "Enter\n");
|
||||
|
||||
/* NOTE : bcdc->msg.len holds the desired length of the buffer to be
|
||||
* returned. Only up to BCDC_MAX_MSG_SIZE of this buffer area
|
||||
* is actually sent to the dongle
|
||||
*/
|
||||
if (len > BCDC_MAX_MSG_SIZE)
|
||||
len = BCDC_MAX_MSG_SIZE;
|
||||
|
||||
/* Send request */
|
||||
return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len);
|
||||
}
|
||||
|
||||
static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
|
||||
{
|
||||
int ret;
|
||||
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
|
||||
|
||||
brcmf_dbg(BCDC, "Enter\n");
|
||||
len += sizeof(struct brcmf_proto_bcdc_dcmd);
|
||||
do {
|
||||
ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&bcdc->msg,
|
||||
len);
|
||||
if (ret < 0)
|
||||
break;
|
||||
} while (BCDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
|
||||
struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
|
||||
void *info;
|
||||
int ret = 0, retries = 0;
|
||||
u32 id, flags;
|
||||
|
||||
brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
|
||||
|
||||
memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd));
|
||||
|
||||
msg->cmd = cpu_to_le32(cmd);
|
||||
msg->len = cpu_to_le32(len);
|
||||
flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT);
|
||||
flags = (flags & ~BCDC_DCMD_IF_MASK) |
|
||||
(ifidx << BCDC_DCMD_IF_SHIFT);
|
||||
msg->flags = cpu_to_le32(flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(bcdc->buf, buf, len);
|
||||
|
||||
ret = brcmf_proto_bcdc_msg(drvr);
|
||||
if (ret < 0) {
|
||||
brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
|
||||
ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
retry:
|
||||
/* wait for interrupt and get first fragment */
|
||||
ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
flags = le32_to_cpu(msg->flags);
|
||||
id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
|
||||
|
||||
if ((id < bcdc->reqid) && (++retries < RETRIES))
|
||||
goto retry;
|
||||
if (id != bcdc->reqid) {
|
||||
brcmf_err("%s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check info buffer */
|
||||
info = (void *)&msg[1];
|
||||
|
||||
/* Copy info buffer */
|
||||
if (buf) {
|
||||
if (ret < (int)len)
|
||||
len = ret;
|
||||
memcpy(buf, info, len);
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & BCDC_DCMD_ERROR)
|
||||
ret = le32_to_cpu(msg->status);
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
|
||||
struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
|
||||
int ret = 0;
|
||||
u32 flags, id;
|
||||
|
||||
brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
|
||||
|
||||
memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd));
|
||||
|
||||
msg->cmd = cpu_to_le32(cmd);
|
||||
msg->len = cpu_to_le32(len);
|
||||
flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT) | BCDC_DCMD_SET;
|
||||
flags = (flags & ~BCDC_DCMD_IF_MASK) |
|
||||
(ifidx << BCDC_DCMD_IF_SHIFT);
|
||||
msg->flags = cpu_to_le32(flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(bcdc->buf, buf, len);
|
||||
|
||||
ret = brcmf_proto_bcdc_msg(drvr);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
flags = le32_to_cpu(msg->flags);
|
||||
id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
|
||||
|
||||
if (id != bcdc->reqid) {
|
||||
brcmf_err("%s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & BCDC_DCMD_ERROR)
|
||||
ret = le32_to_cpu(msg->status);
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bcdc_header *h;
|
||||
|
||||
brcmf_dbg(BCDC, "Enter\n");
|
||||
|
||||
/* Push BDC header used to convey priority for buses that don't */
|
||||
skb_push(pktbuf, BCDC_HEADER_LEN);
|
||||
|
||||
h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
|
||||
|
||||
h->flags = (BCDC_PROTO_VER << BCDC_FLAG_VER_SHIFT);
|
||||
if (pktbuf->ip_summed == CHECKSUM_PARTIAL)
|
||||
h->flags |= BCDC_FLAG_SUM_NEEDED;
|
||||
|
||||
h->priority = (pktbuf->priority & BCDC_PRIORITY_MASK);
|
||||
h->flags2 = 0;
|
||||
h->data_offset = offset;
|
||||
BCDC_SET_IF_IDX(h, ifidx);
|
||||
trace_brcmf_bcdchdr(pktbuf->data);
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bcdc_header *h;
|
||||
|
||||
brcmf_dbg(BCDC, "Enter\n");
|
||||
|
||||
/* Pop BCDC header used to convey priority for buses that don't */
|
||||
if (pktbuf->len <= BCDC_HEADER_LEN) {
|
||||
brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
|
||||
pktbuf->len, BCDC_HEADER_LEN);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
trace_brcmf_bcdchdr(pktbuf->data);
|
||||
h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
|
||||
|
||||
*ifidx = BCDC_GET_IF_IDX(h);
|
||||
if (*ifidx >= BRCMF_MAX_IFS) {
|
||||
brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
|
||||
return -EBADE;
|
||||
}
|
||||
/* The ifidx is the idx to map to matching netdev/ifp. When receiving
|
||||
* events this is easy because it contains the bssidx which maps
|
||||
* 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
|
||||
* bssidx 1 is used for p2p0 and no data can be received or
|
||||
* transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
|
||||
*/
|
||||
if (*ifidx)
|
||||
(*ifidx)++;
|
||||
|
||||
if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
|
||||
BCDC_PROTO_VER) {
|
||||
brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, *ifidx), h->flags);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
if (h->flags & BCDC_FLAG_SUM_GOOD) {
|
||||
brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, *ifidx), h->flags);
|
||||
pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
}
|
||||
|
||||
pktbuf->priority = h->priority & BCDC_PRIORITY_MASK;
|
||||
|
||||
skb_pull(pktbuf, BCDC_HEADER_LEN);
|
||||
if (do_fws)
|
||||
brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
|
||||
else
|
||||
skb_pull(pktbuf, h->data_offset << 2);
|
||||
|
||||
if (pktbuf->len == 0)
|
||||
return -ENODATA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_bcdc *bcdc;
|
||||
|
||||
bcdc = kzalloc(sizeof(*bcdc), GFP_ATOMIC);
|
||||
if (!bcdc)
|
||||
goto fail;
|
||||
|
||||
/* ensure that the msg buf directly follows the cdc msg struct */
|
||||
if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) {
|
||||
brcmf_err("struct brcmf_proto_bcdc is not correctly defined\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
drvr->proto->hdrpush = brcmf_proto_bcdc_hdrpush;
|
||||
drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull;
|
||||
drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd;
|
||||
drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd;
|
||||
drvr->proto->pd = bcdc;
|
||||
|
||||
drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
|
||||
drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
|
||||
sizeof(struct brcmf_proto_bcdc_dcmd) + ROUND_UP_MARGIN;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
kfree(bcdc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
kfree(drvr->proto->pd);
|
||||
drvr->proto->pd = NULL;
|
||||
}
|
24
drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
Normal file
24
drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef BRCMFMAC_BCDC_H
|
||||
#define BRCMFMAC_BCDC_H
|
||||
|
||||
|
||||
int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
|
||||
void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
|
||||
|
||||
|
||||
#endif /* BRCMFMAC_BCDC_H */
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/sched.h>
|
||||
@ -774,7 +773,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmf_sdio_probe);
|
||||
|
||||
int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
@ -791,7 +789,6 @@ int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmf_sdio_remove);
|
||||
|
||||
void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
|
||||
{
|
||||
|
@ -158,10 +158,21 @@ int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
|
||||
}
|
||||
}
|
||||
|
||||
if (err_ret)
|
||||
brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
|
||||
rw ? "write" : "read", func, regaddr, *byte, err_ret);
|
||||
|
||||
if (err_ret) {
|
||||
/*
|
||||
* SleepCSR register access can fail when
|
||||
* waking up the device so reduce this noise
|
||||
* in the logs.
|
||||
*/
|
||||
if (regaddr != SBSDIO_FUNC1_SLEEPCSR)
|
||||
brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
|
||||
rw ? "write" : "read", func, regaddr, *byte,
|
||||
err_ret);
|
||||
else
|
||||
brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
|
||||
rw ? "write" : "read", func, regaddr, *byte,
|
||||
err_ret);
|
||||
}
|
||||
return err_ret;
|
||||
}
|
||||
|
||||
@ -269,6 +280,9 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
|
||||
int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
int err_ret = 0;
|
||||
struct mmc_host *host;
|
||||
struct sdio_func *func;
|
||||
uint max_blocks;
|
||||
|
||||
brcmf_dbg(SDIO, "\n");
|
||||
|
||||
@ -290,6 +304,20 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
|
||||
|
||||
brcmf_sdioh_enablefuncs(sdiodev);
|
||||
|
||||
/*
|
||||
* determine host related variables after brcmf_sdio_probe()
|
||||
* as func->cur_blksize is properly set and F2 init has been
|
||||
* completed successfully.
|
||||
*/
|
||||
func = sdiodev->func[2];
|
||||
host = func->card->host;
|
||||
sdiodev->sg_support = host->max_segs > 1;
|
||||
max_blocks = min_t(uint, host->max_blk_count, 511u);
|
||||
sdiodev->max_request_size = min_t(uint, host->max_req_size,
|
||||
max_blocks * func->cur_blksize);
|
||||
sdiodev->max_segment_count = min_t(uint, host->max_segs,
|
||||
SG_MAX_SINGLE_ALLOC);
|
||||
sdiodev->max_segment_size = host->max_seg_size;
|
||||
out:
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
brcmf_dbg(SDIO, "Done\n");
|
||||
@ -318,8 +346,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
||||
int err;
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
struct brcmf_bus *bus_if;
|
||||
struct mmc_host *host;
|
||||
uint max_blocks;
|
||||
|
||||
brcmf_dbg(SDIO, "Enter\n");
|
||||
brcmf_dbg(SDIO, "Class=%x\n", func->class);
|
||||
@ -367,19 +393,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* determine host related variables after brcmf_sdio_probe()
|
||||
* as func->cur_blksize is properly set and F2 init has been
|
||||
* completed successfully.
|
||||
*/
|
||||
host = func->card->host;
|
||||
sdiodev->sg_support = host->max_segs > 1;
|
||||
max_blocks = min_t(uint, host->max_blk_count, 511u);
|
||||
sdiodev->max_request_size = min_t(uint, host->max_req_size,
|
||||
max_blocks * func->cur_blksize);
|
||||
sdiodev->max_segment_count = min_t(uint, host->max_segs,
|
||||
SG_MAX_SINGLE_ALLOC);
|
||||
sdiodev->max_segment_size = host->max_seg_size;
|
||||
brcmf_dbg(SDIO, "F2 init completed...\n");
|
||||
return 0;
|
||||
|
||||
|
@ -25,184 +25,14 @@
|
||||
|
||||
#include "fweh.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* IO codes that are interpreted by dongle firmware
|
||||
******************************************************************************/
|
||||
#define BRCMF_C_GET_VERSION 1
|
||||
#define BRCMF_C_UP 2
|
||||
#define BRCMF_C_DOWN 3
|
||||
#define BRCMF_C_SET_PROMISC 10
|
||||
#define BRCMF_C_GET_RATE 12
|
||||
#define BRCMF_C_GET_INFRA 19
|
||||
#define BRCMF_C_SET_INFRA 20
|
||||
#define BRCMF_C_GET_AUTH 21
|
||||
#define BRCMF_C_SET_AUTH 22
|
||||
#define BRCMF_C_GET_BSSID 23
|
||||
#define BRCMF_C_GET_SSID 25
|
||||
#define BRCMF_C_SET_SSID 26
|
||||
#define BRCMF_C_TERMINATED 28
|
||||
#define BRCMF_C_GET_CHANNEL 29
|
||||
#define BRCMF_C_SET_CHANNEL 30
|
||||
#define BRCMF_C_GET_SRL 31
|
||||
#define BRCMF_C_SET_SRL 32
|
||||
#define BRCMF_C_GET_LRL 33
|
||||
#define BRCMF_C_SET_LRL 34
|
||||
#define BRCMF_C_GET_RADIO 37
|
||||
#define BRCMF_C_SET_RADIO 38
|
||||
#define BRCMF_C_GET_PHYTYPE 39
|
||||
#define BRCMF_C_SET_KEY 45
|
||||
#define BRCMF_C_SET_PASSIVE_SCAN 49
|
||||
#define BRCMF_C_SCAN 50
|
||||
#define BRCMF_C_SCAN_RESULTS 51
|
||||
#define BRCMF_C_DISASSOC 52
|
||||
#define BRCMF_C_REASSOC 53
|
||||
#define BRCMF_C_SET_ROAM_TRIGGER 55
|
||||
#define BRCMF_C_SET_ROAM_DELTA 57
|
||||
#define BRCMF_C_GET_BCNPRD 75
|
||||
#define BRCMF_C_SET_BCNPRD 76
|
||||
#define BRCMF_C_GET_DTIMPRD 77
|
||||
#define BRCMF_C_SET_DTIMPRD 78
|
||||
#define BRCMF_C_SET_COUNTRY 84
|
||||
#define BRCMF_C_GET_PM 85
|
||||
#define BRCMF_C_SET_PM 86
|
||||
#define BRCMF_C_GET_CURR_RATESET 114
|
||||
#define BRCMF_C_GET_AP 117
|
||||
#define BRCMF_C_SET_AP 118
|
||||
#define BRCMF_C_GET_RSSI 127
|
||||
#define BRCMF_C_GET_WSEC 133
|
||||
#define BRCMF_C_SET_WSEC 134
|
||||
#define BRCMF_C_GET_PHY_NOISE 135
|
||||
#define BRCMF_C_GET_BSS_INFO 136
|
||||
#define BRCMF_C_GET_BANDLIST 140
|
||||
#define BRCMF_C_SET_SCB_TIMEOUT 158
|
||||
#define BRCMF_C_GET_PHYLIST 180
|
||||
#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
|
||||
#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
|
||||
#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
|
||||
#define BRCMF_C_GET_VALID_CHANNELS 217
|
||||
#define BRCMF_C_GET_KEY_PRIMARY 235
|
||||
#define BRCMF_C_SET_KEY_PRIMARY 236
|
||||
#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
|
||||
#define BRCMF_C_GET_VAR 262
|
||||
#define BRCMF_C_SET_VAR 263
|
||||
|
||||
/* phy types (returned by WLC_GET_PHYTPE) */
|
||||
#define WLC_PHY_TYPE_A 0
|
||||
#define WLC_PHY_TYPE_B 1
|
||||
#define WLC_PHY_TYPE_G 2
|
||||
#define WLC_PHY_TYPE_N 4
|
||||
#define WLC_PHY_TYPE_LP 5
|
||||
#define WLC_PHY_TYPE_SSN 6
|
||||
#define WLC_PHY_TYPE_HT 7
|
||||
#define WLC_PHY_TYPE_LCN 8
|
||||
#define WLC_PHY_TYPE_NULL 0xf
|
||||
|
||||
#define TOE_TX_CSUM_OL 0x00000001
|
||||
#define TOE_RX_CSUM_OL 0x00000002
|
||||
|
||||
#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
|
||||
|
||||
/* size of brcmf_scan_params not including variable length array */
|
||||
#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
|
||||
|
||||
/* masks for channel and ssid count */
|
||||
#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
|
||||
#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
|
||||
|
||||
/* primary (ie tx) key */
|
||||
#define BRCMF_PRIMARY_KEY (1 << 1)
|
||||
|
||||
/* For supporting multiple interfaces */
|
||||
#define BRCMF_MAX_IFS 16
|
||||
|
||||
#define DOT11_BSSTYPE_ANY 2
|
||||
#define DOT11_MAX_DEFAULT_KEYS 4
|
||||
|
||||
#define BRCMF_ESCAN_REQ_VERSION 1
|
||||
|
||||
#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
|
||||
|
||||
#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
|
||||
#define BRCMF_STA_ASSOC 0x10 /* Associated */
|
||||
|
||||
#define BRCMF_E_STATUS_SUCCESS 0
|
||||
#define BRCMF_E_STATUS_FAIL 1
|
||||
#define BRCMF_E_STATUS_TIMEOUT 2
|
||||
#define BRCMF_E_STATUS_NO_NETWORKS 3
|
||||
#define BRCMF_E_STATUS_ABORT 4
|
||||
#define BRCMF_E_STATUS_NO_ACK 5
|
||||
#define BRCMF_E_STATUS_UNSOLICITED 6
|
||||
#define BRCMF_E_STATUS_ATTEMPT 7
|
||||
#define BRCMF_E_STATUS_PARTIAL 8
|
||||
#define BRCMF_E_STATUS_NEWSCAN 9
|
||||
#define BRCMF_E_STATUS_NEWASSOC 10
|
||||
#define BRCMF_E_STATUS_11HQUIET 11
|
||||
#define BRCMF_E_STATUS_SUPPRESS 12
|
||||
#define BRCMF_E_STATUS_NOCHANS 13
|
||||
#define BRCMF_E_STATUS_CS_ABORT 15
|
||||
#define BRCMF_E_STATUS_ERROR 16
|
||||
|
||||
#define BRCMF_E_REASON_INITIAL_ASSOC 0
|
||||
#define BRCMF_E_REASON_LOW_RSSI 1
|
||||
#define BRCMF_E_REASON_DEAUTH 2
|
||||
#define BRCMF_E_REASON_DISASSOC 3
|
||||
#define BRCMF_E_REASON_BCNS_LOST 4
|
||||
#define BRCMF_E_REASON_MINTXRATE 9
|
||||
#define BRCMF_E_REASON_TXFAIL 10
|
||||
|
||||
#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4
|
||||
#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
|
||||
#define BRCMF_E_REASON_DIRECTED_ROAM 6
|
||||
#define BRCMF_E_REASON_TSPEC_REJECTED 7
|
||||
#define BRCMF_E_REASON_BETTER_AP 8
|
||||
|
||||
#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
|
||||
#define BRCMF_E_PRUNE_BCAST_BSSID 2
|
||||
#define BRCMF_E_PRUNE_MAC_DENY 3
|
||||
#define BRCMF_E_PRUNE_MAC_NA 4
|
||||
#define BRCMF_E_PRUNE_REG_PASSV 5
|
||||
#define BRCMF_E_PRUNE_SPCT_MGMT 6
|
||||
#define BRCMF_E_PRUNE_RADAR 7
|
||||
#define BRCMF_E_RSN_MISMATCH 8
|
||||
#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
|
||||
#define BRCMF_E_PRUNE_BASIC_RATES 10
|
||||
#define BRCMF_E_PRUNE_CIPHER_NA 12
|
||||
#define BRCMF_E_PRUNE_KNOWN_STA 13
|
||||
#define BRCMF_E_PRUNE_WDS_PEER 15
|
||||
#define BRCMF_E_PRUNE_QBSS_LOAD 16
|
||||
#define BRCMF_E_PRUNE_HOME_AP 17
|
||||
|
||||
#define BRCMF_E_SUP_OTHER 0
|
||||
#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
|
||||
#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
|
||||
#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
|
||||
#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
|
||||
#define BRCMF_E_SUP_PW_KEY_CIPHER 5
|
||||
#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
|
||||
#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
|
||||
#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
|
||||
#define BRCMF_E_SUP_MSG3_NO_GTK 9
|
||||
#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
|
||||
#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
|
||||
#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
|
||||
#define BRCMF_E_SUP_SEND_FAIL 13
|
||||
#define BRCMF_E_SUP_DEAUTH 14
|
||||
|
||||
#define BRCMF_E_IF_ADD 1
|
||||
#define BRCMF_E_IF_DEL 2
|
||||
#define BRCMF_E_IF_CHANGE 3
|
||||
|
||||
#define BRCMF_E_IF_FLAG_NOIF 1
|
||||
|
||||
#define BRCMF_E_IF_ROLE_STA 0
|
||||
#define BRCMF_E_IF_ROLE_AP 1
|
||||
#define BRCMF_E_IF_ROLE_WDS 2
|
||||
|
||||
#define BRCMF_E_LINK_BCN_LOSS 1
|
||||
#define BRCMF_E_LINK_DISASSOC 2
|
||||
#define BRCMF_E_LINK_ASSOC_REC 3
|
||||
#define BRCMF_E_LINK_BSSCFG_DIS 4
|
||||
|
||||
/* Small, medium and maximum buffer size for dcmd
|
||||
*/
|
||||
#define BRCMF_DCMD_SMLEN 256
|
||||
@ -211,291 +41,10 @@
|
||||
|
||||
#define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256
|
||||
|
||||
/* Pattern matching filter. Specifies an offset within received packets to
|
||||
* start matching, the pattern to match, the size of the pattern, and a bitmask
|
||||
* that indicates which bits within the pattern should be matched.
|
||||
/* Length of firmware version string stored for
|
||||
* ethtool driver info which uses 32 bytes as well.
|
||||
*/
|
||||
struct brcmf_pkt_filter_pattern_le {
|
||||
/*
|
||||
* Offset within received packet to start pattern matching.
|
||||
* Offset '0' is the first byte of the ethernet header.
|
||||
*/
|
||||
__le32 offset;
|
||||
/* Size of the pattern. Bitmask must be the same size.*/
|
||||
__le32 size_bytes;
|
||||
/*
|
||||
* Variable length mask and pattern data. mask starts at offset 0.
|
||||
* Pattern immediately follows mask.
|
||||
*/
|
||||
u8 mask_and_pattern[1];
|
||||
};
|
||||
|
||||
/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
|
||||
struct brcmf_pkt_filter_le {
|
||||
__le32 id; /* Unique filter id, specified by app. */
|
||||
__le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
|
||||
__le32 negate_match; /* Negate the result of filter matches */
|
||||
union { /* Filter definitions */
|
||||
struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
|
||||
} u;
|
||||
};
|
||||
|
||||
/* IOVAR "pkt_filter_enable" parameter. */
|
||||
struct brcmf_pkt_filter_enable_le {
|
||||
__le32 id; /* Unique filter id */
|
||||
__le32 enable; /* Enable/disable bool */
|
||||
};
|
||||
|
||||
/* BSS info structure
|
||||
* Applications MUST CHECK ie_offset field and length field to access IEs and
|
||||
* next bss_info structure in a vector (in struct brcmf_scan_results)
|
||||
*/
|
||||
struct brcmf_bss_info_le {
|
||||
__le32 version; /* version field */
|
||||
__le32 length; /* byte length of data in this record,
|
||||
* starting at version and including IEs
|
||||
*/
|
||||
u8 BSSID[ETH_ALEN];
|
||||
__le16 beacon_period; /* units are Kusec */
|
||||
__le16 capability; /* Capability information */
|
||||
u8 SSID_len;
|
||||
u8 SSID[32];
|
||||
struct {
|
||||
__le32 count; /* # rates in this set */
|
||||
u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
|
||||
} rateset; /* supported rates */
|
||||
__le16 chanspec; /* chanspec for bss */
|
||||
__le16 atim_window; /* units are Kusec */
|
||||
u8 dtim_period; /* DTIM period */
|
||||
__le16 RSSI; /* receive signal strength (in dBm) */
|
||||
s8 phy_noise; /* noise (in dBm) */
|
||||
|
||||
u8 n_cap; /* BSS is 802.11N Capable */
|
||||
/* 802.11N BSS Capabilities (based on HT_CAP_*): */
|
||||
__le32 nbss_cap;
|
||||
u8 ctl_ch; /* 802.11N BSS control channel number */
|
||||
__le32 reserved32[1]; /* Reserved for expansion of BSS properties */
|
||||
u8 flags; /* flags */
|
||||
u8 reserved[3]; /* Reserved for expansion of BSS properties */
|
||||
u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
|
||||
|
||||
__le16 ie_offset; /* offset at which IEs start, from beginning */
|
||||
__le32 ie_length; /* byte length of Information Elements */
|
||||
__le16 SNR; /* average SNR of during frame reception */
|
||||
/* Add new fields here */
|
||||
/* variable length Information Elements */
|
||||
};
|
||||
|
||||
struct brcm_rateset_le {
|
||||
/* # rates in this set */
|
||||
__le32 count;
|
||||
/* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 rates[BRCMF_MAXRATES_IN_SET];
|
||||
};
|
||||
|
||||
struct brcmf_ssid {
|
||||
u32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
};
|
||||
|
||||
struct brcmf_ssid_le {
|
||||
__le32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
};
|
||||
|
||||
struct brcmf_scan_params_le {
|
||||
struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
|
||||
u8 bssid[ETH_ALEN]; /* default: bcast */
|
||||
s8 bss_type; /* default: any,
|
||||
* DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
|
||||
*/
|
||||
u8 scan_type; /* flags, 0 use default */
|
||||
__le32 nprobes; /* -1 use default, number of probes per channel */
|
||||
__le32 active_time; /* -1 use default, dwell time per channel for
|
||||
* active scanning
|
||||
*/
|
||||
__le32 passive_time; /* -1 use default, dwell time per channel
|
||||
* for passive scanning
|
||||
*/
|
||||
__le32 home_time; /* -1 use default, dwell time for the
|
||||
* home channel between channel scans
|
||||
*/
|
||||
__le32 channel_num; /* count of channels and ssids that follow
|
||||
*
|
||||
* low half is count of channels in
|
||||
* channel_list, 0 means default (use all
|
||||
* available channels)
|
||||
*
|
||||
* high half is entries in struct brcmf_ssid
|
||||
* array that follows channel_list, aligned for
|
||||
* s32 (4 bytes) meaning an odd channel count
|
||||
* implies a 2-byte pad between end of
|
||||
* channel_list and first ssid
|
||||
*
|
||||
* if ssid count is zero, single ssid in the
|
||||
* fixed parameter portion is assumed, otherwise
|
||||
* ssid in the fixed portion is ignored
|
||||
*/
|
||||
__le16 channel_list[1]; /* list of chanspecs */
|
||||
};
|
||||
|
||||
struct brcmf_scan_results {
|
||||
u32 buflen;
|
||||
u32 version;
|
||||
u32 count;
|
||||
struct brcmf_bss_info_le bss_info_le[];
|
||||
};
|
||||
|
||||
struct brcmf_escan_params_le {
|
||||
__le32 version;
|
||||
__le16 action;
|
||||
__le16 sync_id;
|
||||
struct brcmf_scan_params_le params_le;
|
||||
};
|
||||
|
||||
struct brcmf_escan_result_le {
|
||||
__le32 buflen;
|
||||
__le32 version;
|
||||
__le16 sync_id;
|
||||
__le16 bss_count;
|
||||
struct brcmf_bss_info_le bss_info_le;
|
||||
};
|
||||
|
||||
#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
|
||||
sizeof(struct brcmf_bss_info_le))
|
||||
|
||||
/* used for association with a specific BSSID and chanspec list */
|
||||
struct brcmf_assoc_params_le {
|
||||
/* 00:00:00:00:00:00: broadcast scan */
|
||||
u8 bssid[ETH_ALEN];
|
||||
/* 0: all available channels, otherwise count of chanspecs in
|
||||
* chanspec_list */
|
||||
__le32 chanspec_num;
|
||||
/* list of chanspecs */
|
||||
__le16 chanspec_list[1];
|
||||
};
|
||||
|
||||
/* used for join with or without a specific bssid and channel list */
|
||||
struct brcmf_join_params {
|
||||
struct brcmf_ssid_le ssid_le;
|
||||
struct brcmf_assoc_params_le params_le;
|
||||
};
|
||||
|
||||
/* scan params for extended join */
|
||||
struct brcmf_join_scan_params_le {
|
||||
u8 scan_type; /* 0 use default, active or passive scan */
|
||||
__le32 nprobes; /* -1 use default, nr of probes per channel */
|
||||
__le32 active_time; /* -1 use default, dwell time per channel for
|
||||
* active scanning
|
||||
*/
|
||||
__le32 passive_time; /* -1 use default, dwell time per channel
|
||||
* for passive scanning
|
||||
*/
|
||||
__le32 home_time; /* -1 use default, dwell time for the home
|
||||
* channel between channel scans
|
||||
*/
|
||||
};
|
||||
|
||||
/* extended join params */
|
||||
struct brcmf_ext_join_params_le {
|
||||
struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */
|
||||
struct brcmf_join_scan_params_le scan_le;
|
||||
struct brcmf_assoc_params_le assoc_le;
|
||||
};
|
||||
|
||||
struct brcmf_wsec_key {
|
||||
u32 index; /* key index */
|
||||
u32 len; /* key length */
|
||||
u8 data[WLAN_MAX_KEY_LEN]; /* key data */
|
||||
u32 pad_1[18];
|
||||
u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
|
||||
u32 flags; /* misc flags */
|
||||
u32 pad_2[3];
|
||||
u32 iv_initialized; /* has IV been initialized already? */
|
||||
u32 pad_3;
|
||||
/* Rx IV */
|
||||
struct {
|
||||
u32 hi; /* upper 32 bits of IV */
|
||||
u16 lo; /* lower 16 bits of IV */
|
||||
} rxiv;
|
||||
u32 pad_4[2];
|
||||
u8 ea[ETH_ALEN]; /* per station */
|
||||
};
|
||||
|
||||
/*
|
||||
* dongle requires same struct as above but with fields in little endian order
|
||||
*/
|
||||
struct brcmf_wsec_key_le {
|
||||
__le32 index; /* key index */
|
||||
__le32 len; /* key length */
|
||||
u8 data[WLAN_MAX_KEY_LEN]; /* key data */
|
||||
__le32 pad_1[18];
|
||||
__le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
|
||||
__le32 flags; /* misc flags */
|
||||
__le32 pad_2[3];
|
||||
__le32 iv_initialized; /* has IV been initialized already? */
|
||||
__le32 pad_3;
|
||||
/* Rx IV */
|
||||
struct {
|
||||
__le32 hi; /* upper 32 bits of IV */
|
||||
__le16 lo; /* lower 16 bits of IV */
|
||||
} rxiv;
|
||||
__le32 pad_4[2];
|
||||
u8 ea[ETH_ALEN]; /* per station */
|
||||
};
|
||||
|
||||
/* Used to get specific STA parameters */
|
||||
struct brcmf_scb_val_le {
|
||||
__le32 val;
|
||||
u8 ea[ETH_ALEN];
|
||||
};
|
||||
|
||||
/* channel encoding */
|
||||
struct brcmf_channel_info_le {
|
||||
__le32 hw_channel;
|
||||
__le32 target_channel;
|
||||
__le32 scan_channel;
|
||||
};
|
||||
|
||||
struct brcmf_sta_info_le {
|
||||
__le16 ver; /* version of this struct */
|
||||
__le16 len; /* length in bytes of this structure */
|
||||
__le16 cap; /* sta's advertised capabilities */
|
||||
__le32 flags; /* flags defined below */
|
||||
__le32 idle; /* time since data pkt rx'd from sta */
|
||||
u8 ea[ETH_ALEN]; /* Station address */
|
||||
__le32 count; /* # rates in this set */
|
||||
u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
|
||||
/* w/hi bit set if basic */
|
||||
__le32 in; /* seconds elapsed since associated */
|
||||
__le32 listen_interval_inms; /* Min Listen interval in ms for STA */
|
||||
__le32 tx_pkts; /* # of packets transmitted */
|
||||
__le32 tx_failures; /* # of packets failed */
|
||||
__le32 rx_ucast_pkts; /* # of unicast packets received */
|
||||
__le32 rx_mcast_pkts; /* # of multicast packets received */
|
||||
__le32 tx_rate; /* Rate of last successful tx frame */
|
||||
__le32 rx_rate; /* Rate of last successful rx frame */
|
||||
__le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
|
||||
__le32 rx_decrypt_failures; /* # of packet decrypted failed */
|
||||
};
|
||||
|
||||
struct brcmf_chanspec_list {
|
||||
__le32 count; /* # of entries */
|
||||
__le32 element[1]; /* variable length uint32 list */
|
||||
};
|
||||
|
||||
/*
|
||||
* WLC_E_PROBRESP_MSG
|
||||
* WLC_E_P2P_PROBREQ_MSG
|
||||
* WLC_E_ACTION_FRAME_RX
|
||||
*/
|
||||
struct brcmf_rx_mgmt_data {
|
||||
__be16 version;
|
||||
__be16 chanspec;
|
||||
__be32 rssi;
|
||||
__be32 mactime;
|
||||
__be32 rate;
|
||||
};
|
||||
#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32
|
||||
|
||||
/* Bus independent dongle command */
|
||||
struct brcmf_dcmd {
|
||||
@ -535,7 +84,7 @@ struct brcmf_fws_info; /* firmware signalling info */
|
||||
struct brcmf_pub {
|
||||
/* Linkage ponters */
|
||||
struct brcmf_bus *bus_if;
|
||||
struct brcmf_proto *prot;
|
||||
struct brcmf_proto *proto;
|
||||
struct brcmf_cfg80211_info *config;
|
||||
|
||||
/* Internal brcmf items */
|
||||
@ -544,7 +93,7 @@ struct brcmf_pub {
|
||||
u8 wme_dp; /* wme discard priority */
|
||||
|
||||
/* Dongle media info */
|
||||
unsigned long drv_version; /* Version of dongle-resident driver */
|
||||
char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN];
|
||||
u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
|
||||
|
||||
/* Multicast data packets sent to dongle */
|
||||
@ -566,14 +115,6 @@ struct brcmf_pub {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct brcmf_if_event {
|
||||
u8 ifidx;
|
||||
u8 action;
|
||||
u8 flags;
|
||||
u8 bssidx;
|
||||
u8 role;
|
||||
};
|
||||
|
||||
/* forward declarations */
|
||||
struct brcmf_cfg80211_vif;
|
||||
struct brcmf_fws_mac_descriptor;
|
||||
@ -635,16 +176,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
|
||||
/* Return pointer to interface name */
|
||||
char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
|
||||
|
||||
/* Query dongle */
|
||||
int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len);
|
||||
int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len);
|
||||
|
||||
/* Remove any protocol-specific data header. */
|
||||
int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
|
||||
struct sk_buff *rxp);
|
||||
|
||||
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
|
||||
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
|
||||
char *name, u8 *mac_addr);
|
||||
@ -655,4 +186,7 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp);
|
||||
void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
|
||||
bool success);
|
||||
|
||||
/* Sets dongle media info (drv_version, mac address). */
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
|
||||
|
||||
#endif /* _BRCMF_H_ */
|
||||
|
@ -34,6 +34,7 @@ struct brcmf_bus_dcmd {
|
||||
/**
|
||||
* struct brcmf_bus_ops - bus callback operations.
|
||||
*
|
||||
* @preinit: execute bus/device specific dongle init commands (optional).
|
||||
* @init: prepare for communication with dongle.
|
||||
* @stop: clear pending frames, disable data flow.
|
||||
* @txdata: send a data frame to the dongle. When the data
|
||||
@ -51,6 +52,7 @@ struct brcmf_bus_dcmd {
|
||||
* indicated otherwise these callbacks are mandatory.
|
||||
*/
|
||||
struct brcmf_bus_ops {
|
||||
int (*preinit)(struct device *dev);
|
||||
int (*init)(struct device *dev);
|
||||
void (*stop)(struct device *dev);
|
||||
int (*txdata)(struct device *dev, struct sk_buff *skb);
|
||||
@ -85,7 +87,6 @@ struct brcmf_bus {
|
||||
unsigned long tx_realloc;
|
||||
u32 chip;
|
||||
u32 chiprev;
|
||||
struct list_head dcmd_list;
|
||||
|
||||
struct brcmf_bus_ops *ops;
|
||||
};
|
||||
@ -93,6 +94,13 @@ struct brcmf_bus {
|
||||
/*
|
||||
* callback wrappers
|
||||
*/
|
||||
static inline int brcmf_bus_preinit(struct brcmf_bus *bus)
|
||||
{
|
||||
if (!bus->ops->preinit)
|
||||
return 0;
|
||||
return bus->ops->preinit(bus->dev);
|
||||
}
|
||||
|
||||
static inline int brcmf_bus_init(struct brcmf_bus *bus)
|
||||
{
|
||||
return bus->ops->init(bus->dev);
|
||||
@ -139,7 +147,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
|
||||
void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
|
||||
|
||||
/* Indication from bus module regarding presence/insertion of dongle. */
|
||||
int brcmf_attach(uint bus_hdrlen, struct device *dev);
|
||||
int brcmf_attach(struct device *dev);
|
||||
/* Indication from bus module regarding removal/absence of dongle */
|
||||
void brcmf_detach(struct device *dev);
|
||||
/* Indication from bus module that dongle should be reset */
|
||||
@ -151,6 +159,9 @@ void brcmf_txflowblock(struct device *dev, bool state);
|
||||
void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
|
||||
|
||||
int brcmf_bus_start(struct device *dev);
|
||||
s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data,
|
||||
u32 len);
|
||||
void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
|
||||
|
||||
#ifdef CONFIG_BRCMFMAC_SDIO
|
||||
void brcmf_sdio_exit(void);
|
||||
|
@ -1,392 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Communicates with the dongle by using dcmd codes.
|
||||
* For certain dcmd codes, the dongle interprets string data from the host.
|
||||
******************************************************************************/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
|
||||
#include "dhd.h"
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "fwsignal.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "tracepoint.h"
|
||||
|
||||
struct brcmf_proto_cdc_dcmd {
|
||||
__le32 cmd; /* dongle command value */
|
||||
__le32 len; /* lower 16: output buflen;
|
||||
* upper 16: input buflen (excludes header) */
|
||||
__le32 flags; /* flag defns given below */
|
||||
__le32 status; /* status code returned from the device */
|
||||
};
|
||||
|
||||
/* Max valid buffer size that can be sent to the dongle */
|
||||
#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
|
||||
|
||||
/* CDC flag definitions */
|
||||
#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */
|
||||
#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
|
||||
#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */
|
||||
#define CDC_DCMD_IF_SHIFT 12
|
||||
#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
|
||||
#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
|
||||
#define CDC_DCMD_ID(flags) \
|
||||
(((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* BDC header - Broadcom specific extension of CDC.
|
||||
* Used on data packets to convey priority across USB.
|
||||
*/
|
||||
#define BDC_HEADER_LEN 4
|
||||
#define BDC_PROTO_VER 2 /* Protocol version */
|
||||
#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
|
||||
#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
|
||||
#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
|
||||
#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
|
||||
#define BDC_PRIORITY_MASK 0x7
|
||||
#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
|
||||
#define BDC_FLAG2_IF_SHIFT 0
|
||||
|
||||
#define BDC_GET_IF_IDX(hdr) \
|
||||
((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
|
||||
#define BDC_SET_IF_IDX(hdr, idx) \
|
||||
((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
|
||||
((idx) << BDC_FLAG2_IF_SHIFT)))
|
||||
|
||||
/**
|
||||
* struct brcmf_proto_bdc_header - BDC header format
|
||||
*
|
||||
* @flags: flags contain protocol and checksum info.
|
||||
* @priority: 802.1d priority and USB flow control info (bit 4:7).
|
||||
* @flags2: additional flags containing dongle interface index.
|
||||
* @data_offset: start of packet data. header is following by firmware signals.
|
||||
*/
|
||||
struct brcmf_proto_bdc_header {
|
||||
u8 flags;
|
||||
u8 priority;
|
||||
u8 flags2;
|
||||
u8 data_offset;
|
||||
};
|
||||
|
||||
/*
|
||||
* maximum length of firmware signal data between
|
||||
* the BDC header and packet data in the tx path.
|
||||
*/
|
||||
#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
|
||||
|
||||
#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
|
||||
#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
|
||||
* (amount of header tha might be added)
|
||||
* plus any space that might be needed
|
||||
* for bus alignment padding.
|
||||
*/
|
||||
#define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for
|
||||
* round off at the end of buffer
|
||||
* Currently is SDIO
|
||||
*/
|
||||
|
||||
struct brcmf_proto {
|
||||
u16 reqid;
|
||||
u8 bus_header[BUS_HEADER_LEN];
|
||||
struct brcmf_proto_cdc_dcmd msg;
|
||||
unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
|
||||
};
|
||||
|
||||
static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
int len = le32_to_cpu(prot->msg.len) +
|
||||
sizeof(struct brcmf_proto_cdc_dcmd);
|
||||
|
||||
brcmf_dbg(CDC, "Enter\n");
|
||||
|
||||
/* NOTE : cdc->msg.len holds the desired length of the buffer to be
|
||||
* returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
|
||||
* is actually sent to the dongle
|
||||
*/
|
||||
if (len > CDC_MAX_MSG_SIZE)
|
||||
len = CDC_MAX_MSG_SIZE;
|
||||
|
||||
/* Send request */
|
||||
return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len);
|
||||
}
|
||||
|
||||
static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
|
||||
{
|
||||
int ret;
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
|
||||
brcmf_dbg(CDC, "Enter\n");
|
||||
len += sizeof(struct brcmf_proto_cdc_dcmd);
|
||||
do {
|
||||
ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg,
|
||||
len);
|
||||
if (ret < 0)
|
||||
break;
|
||||
} while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
|
||||
void *info;
|
||||
int ret = 0, retries = 0;
|
||||
u32 id, flags;
|
||||
|
||||
brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
|
||||
|
||||
memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
|
||||
|
||||
msg->cmd = cpu_to_le32(cmd);
|
||||
msg->len = cpu_to_le32(len);
|
||||
flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
|
||||
flags = (flags & ~CDC_DCMD_IF_MASK) |
|
||||
(ifidx << CDC_DCMD_IF_SHIFT);
|
||||
msg->flags = cpu_to_le32(flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(prot->buf, buf, len);
|
||||
|
||||
ret = brcmf_proto_cdc_msg(drvr);
|
||||
if (ret < 0) {
|
||||
brcmf_err("brcmf_proto_cdc_msg failed w/status %d\n",
|
||||
ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
retry:
|
||||
/* wait for interrupt and get first fragment */
|
||||
ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
flags = le32_to_cpu(msg->flags);
|
||||
id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
|
||||
|
||||
if ((id < prot->reqid) && (++retries < RETRIES))
|
||||
goto retry;
|
||||
if (id != prot->reqid) {
|
||||
brcmf_err("%s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), id, prot->reqid);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check info buffer */
|
||||
info = (void *)&msg[1];
|
||||
|
||||
/* Copy info buffer */
|
||||
if (buf) {
|
||||
if (ret < (int)len)
|
||||
len = ret;
|
||||
memcpy(buf, info, len);
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & CDC_DCMD_ERROR)
|
||||
ret = le32_to_cpu(msg->status);
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
|
||||
int ret = 0;
|
||||
u32 flags, id;
|
||||
|
||||
brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
|
||||
|
||||
memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
|
||||
|
||||
msg->cmd = cpu_to_le32(cmd);
|
||||
msg->len = cpu_to_le32(len);
|
||||
flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
|
||||
flags = (flags & ~CDC_DCMD_IF_MASK) |
|
||||
(ifidx << CDC_DCMD_IF_SHIFT);
|
||||
msg->flags = cpu_to_le32(flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(prot->buf, buf, len);
|
||||
|
||||
ret = brcmf_proto_cdc_msg(drvr);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
flags = le32_to_cpu(msg->flags);
|
||||
id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
|
||||
|
||||
if (id != prot->reqid) {
|
||||
brcmf_err("%s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), id, prot->reqid);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & CDC_DCMD_ERROR)
|
||||
ret = le32_to_cpu(msg->status);
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool pkt_sum_needed(struct sk_buff *skb)
|
||||
{
|
||||
return skb->ip_summed == CHECKSUM_PARTIAL;
|
||||
}
|
||||
|
||||
static void pkt_set_sum_good(struct sk_buff *skb, bool x)
|
||||
{
|
||||
skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
|
||||
}
|
||||
|
||||
void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bdc_header *h;
|
||||
|
||||
brcmf_dbg(CDC, "Enter\n");
|
||||
|
||||
/* Push BDC header used to convey priority for buses that don't */
|
||||
skb_push(pktbuf, BDC_HEADER_LEN);
|
||||
|
||||
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
|
||||
|
||||
h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
|
||||
if (pkt_sum_needed(pktbuf))
|
||||
h->flags |= BDC_FLAG_SUM_NEEDED;
|
||||
|
||||
h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
|
||||
h->flags2 = 0;
|
||||
h->data_offset = offset;
|
||||
BDC_SET_IF_IDX(h, ifidx);
|
||||
trace_brcmf_bdchdr(pktbuf->data);
|
||||
}
|
||||
|
||||
int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bdc_header *h;
|
||||
|
||||
brcmf_dbg(CDC, "Enter\n");
|
||||
|
||||
/* Pop BDC header used to convey priority for buses that don't */
|
||||
|
||||
if (pktbuf->len <= BDC_HEADER_LEN) {
|
||||
brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
|
||||
pktbuf->len, BDC_HEADER_LEN);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
trace_brcmf_bdchdr(pktbuf->data);
|
||||
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
|
||||
|
||||
*ifidx = BDC_GET_IF_IDX(h);
|
||||
if (*ifidx >= BRCMF_MAX_IFS) {
|
||||
brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
|
||||
return -EBADE;
|
||||
}
|
||||
/* The ifidx is the idx to map to matching netdev/ifp. When receiving
|
||||
* events this is easy because it contains the bssidx which maps
|
||||
* 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
|
||||
* bssidx 1 is used for p2p0 and no data can be received or
|
||||
* transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
|
||||
*/
|
||||
if (*ifidx)
|
||||
(*ifidx)++;
|
||||
|
||||
if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
|
||||
BDC_PROTO_VER) {
|
||||
brcmf_err("%s: non-BDC packet received, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, *ifidx), h->flags);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
if (h->flags & BDC_FLAG_SUM_GOOD) {
|
||||
brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, *ifidx), h->flags);
|
||||
pkt_set_sum_good(pktbuf, true);
|
||||
}
|
||||
|
||||
pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
|
||||
|
||||
skb_pull(pktbuf, BDC_HEADER_LEN);
|
||||
if (do_fws)
|
||||
brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
|
||||
else
|
||||
skb_pull(pktbuf, h->data_offset << 2);
|
||||
|
||||
if (pktbuf->len == 0)
|
||||
return -ENODATA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_proto_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_proto *cdc;
|
||||
|
||||
cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
|
||||
if (!cdc)
|
||||
goto fail;
|
||||
|
||||
/* ensure that the msg buf directly follows the cdc msg struct */
|
||||
if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
|
||||
brcmf_err("struct brcmf_proto is not correctly defined\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
drvr->prot = cdc;
|
||||
drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
|
||||
drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
|
||||
sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
kfree(cdc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
|
||||
void brcmf_proto_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
kfree(drvr->prot);
|
||||
drvr->prot = NULL;
|
||||
}
|
||||
|
||||
void brcmf_proto_stop(struct brcmf_pub *drvr)
|
||||
{
|
||||
/* Nothing to do for CDC */
|
||||
}
|
@ -21,9 +21,9 @@
|
||||
#include <brcmu_utils.h>
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "fwil.h"
|
||||
#include "fwil_types.h"
|
||||
#include "tracepoint.h"
|
||||
|
||||
#define PKTFILTER_BUF_SIZE 128
|
||||
@ -257,8 +257,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
u8 buf[BRCMF_DCMD_SMLEN];
|
||||
char *ptr;
|
||||
s32 err;
|
||||
struct brcmf_bus_dcmd *cmdlst;
|
||||
struct list_head *cur, *q;
|
||||
|
||||
/* retreive mac address */
|
||||
err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
|
||||
@ -281,9 +279,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
}
|
||||
ptr = (char *)buf;
|
||||
strsep(&ptr, "\n");
|
||||
|
||||
/* Print fw version info */
|
||||
brcmf_err("Firmware version = %s\n", buf);
|
||||
|
||||
/* locate firmware version number for ethtool */
|
||||
ptr = strrchr(buf, ' ') + 1;
|
||||
strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
|
||||
|
||||
/*
|
||||
* Setup timeout if Beacons are lost and roam is off to report
|
||||
* link down
|
||||
@ -342,17 +345,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
||||
brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
|
||||
0, true);
|
||||
|
||||
/* set bus specific command if there is any */
|
||||
list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) {
|
||||
cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
|
||||
if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
|
||||
brcmf_fil_iovar_data_set(ifp, cmdlst->name,
|
||||
cmdlst->param,
|
||||
cmdlst->param_len);
|
||||
}
|
||||
list_del(cur);
|
||||
kfree(cmdlst);
|
||||
}
|
||||
/* do bus specific preinit here */
|
||||
err = brcmf_bus_preinit(ifp->drvr->bus_if);
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "tracepoint.h"
|
||||
|
||||
static struct dentry *root_folder;
|
||||
|
||||
@ -42,6 +41,40 @@ void brcmf_debugfs_exit(void)
|
||||
root_folder = NULL;
|
||||
}
|
||||
|
||||
static
|
||||
ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct brcmf_pub *drvr = f->private_data;
|
||||
struct brcmf_bus *bus = drvr->bus_if;
|
||||
char buf[40];
|
||||
int res;
|
||||
|
||||
/* only allow read from start */
|
||||
if (*ppos > 0)
|
||||
return 0;
|
||||
|
||||
res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n",
|
||||
bus->chip, bus->chip, bus->chiprev);
|
||||
return simple_read_from_buffer(data, count, ppos, buf, res);
|
||||
}
|
||||
|
||||
static const struct file_operations brcmf_debugfs_chipinfo_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = brcmf_debugfs_chipinfo_read
|
||||
};
|
||||
|
||||
static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct dentry *dentry = drvr->dbgfs_dir;
|
||||
|
||||
if (!IS_ERR_OR_NULL(dentry))
|
||||
debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr,
|
||||
&brcmf_debugfs_chipinfo_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct device *dev = drvr->bus_if->dev;
|
||||
@ -50,6 +83,7 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
||||
return -ENODEV;
|
||||
|
||||
drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
|
||||
brcmf_debugfs_create_chipinfo(drvr);
|
||||
return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#define BRCMF_USB_VAL 0x00002000
|
||||
#define BRCMF_SCAN_VAL 0x00004000
|
||||
#define BRCMF_CONN_VAL 0x00008000
|
||||
#define BRCMF_CDC_VAL 0x00010000
|
||||
#define BRCMF_BCDC_VAL 0x00010000
|
||||
#define BRCMF_SDIO_VAL 0x00020000
|
||||
|
||||
/* set default print format */
|
||||
|
@ -24,13 +24,13 @@
|
||||
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "fwil_types.h"
|
||||
#include "p2p.h"
|
||||
#include "wl_cfg80211.h"
|
||||
#include "fwil.h"
|
||||
#include "fwsignal.h"
|
||||
#include "proto.h"
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
@ -592,28 +592,6 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
|
||||
return &ifp->stats;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set current toe component enables in toe_ol iovar,
|
||||
* and set toe global enable iovar
|
||||
*/
|
||||
static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol)
|
||||
{
|
||||
s32 err;
|
||||
|
||||
err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
|
||||
if (err < 0) {
|
||||
brcmf_err("Setting toe_ol failed, %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
|
||||
if (err < 0)
|
||||
brcmf_err("Setting toe failed, %d\n", err);
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
|
||||
struct ethtool_drvinfo *info)
|
||||
{
|
||||
@ -621,8 +599,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
|
||||
strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
|
||||
snprintf(info->version, sizeof(info->version), "%lu",
|
||||
drvr->drv_version);
|
||||
snprintf(info->version, sizeof(info->version), "n/a");
|
||||
strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));
|
||||
strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
|
||||
sizeof(info->bus_info));
|
||||
}
|
||||
@ -631,124 +609,6 @@ static const struct ethtool_ops brcmf_ethtool_ops = {
|
||||
.get_drvinfo = brcmf_ethtool_get_drvinfo,
|
||||
};
|
||||
|
||||
static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
|
||||
{
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
struct ethtool_drvinfo info;
|
||||
char drvname[sizeof(info.driver)];
|
||||
u32 cmd;
|
||||
struct ethtool_value edata;
|
||||
u32 toe_cmpnt, csum_dir;
|
||||
int ret;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
|
||||
|
||||
/* all ethtool calls start with a cmd word */
|
||||
if (copy_from_user(&cmd, uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
switch (cmd) {
|
||||
case ETHTOOL_GDRVINFO:
|
||||
/* Copy out any request driver name */
|
||||
if (copy_from_user(&info, uaddr, sizeof(info)))
|
||||
return -EFAULT;
|
||||
strncpy(drvname, info.driver, sizeof(info.driver));
|
||||
drvname[sizeof(info.driver) - 1] = '\0';
|
||||
|
||||
/* clear struct for return */
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.cmd = cmd;
|
||||
|
||||
/* if requested, identify ourselves */
|
||||
if (strcmp(drvname, "?dhd") == 0) {
|
||||
sprintf(info.driver, "dhd");
|
||||
strcpy(info.version, BRCMF_VERSION_STR);
|
||||
}
|
||||
/* report dongle driver type */
|
||||
else
|
||||
sprintf(info.driver, "wl");
|
||||
|
||||
sprintf(info.version, "%lu", drvr->drv_version);
|
||||
if (copy_to_user(uaddr, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
brcmf_dbg(TRACE, "given %*s, returning %s\n",
|
||||
(int)sizeof(drvname), drvname, info.driver);
|
||||
break;
|
||||
|
||||
/* Get toe offload components from dongle */
|
||||
case ETHTOOL_GRXCSUM:
|
||||
case ETHTOOL_GTXCSUM:
|
||||
ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
csum_dir =
|
||||
(cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
|
||||
|
||||
edata.cmd = cmd;
|
||||
edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
|
||||
|
||||
if (copy_to_user(uaddr, &edata, sizeof(edata)))
|
||||
return -EFAULT;
|
||||
break;
|
||||
|
||||
/* Set toe offload components in dongle */
|
||||
case ETHTOOL_SRXCSUM:
|
||||
case ETHTOOL_STXCSUM:
|
||||
if (copy_from_user(&edata, uaddr, sizeof(edata)))
|
||||
return -EFAULT;
|
||||
|
||||
/* Read the current settings, update and write back */
|
||||
ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
csum_dir =
|
||||
(cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
|
||||
|
||||
if (edata.data != 0)
|
||||
toe_cmpnt |= csum_dir;
|
||||
else
|
||||
toe_cmpnt &= ~csum_dir;
|
||||
|
||||
ret = brcmf_toe_set(ifp, toe_cmpnt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* If setting TX checksum mode, tell Linux the new mode */
|
||||
if (cmd == ETHTOOL_STXCSUM) {
|
||||
if (edata.data)
|
||||
ifp->ndev->features |= NETIF_F_IP_CSUM;
|
||||
else
|
||||
ifp->ndev->features &= ~NETIF_F_IP_CSUM;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
|
||||
int cmd)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
|
||||
|
||||
if (!drvr->iflist[ifp->bssidx])
|
||||
return -1;
|
||||
|
||||
if (cmd == SIOCETHTOOL)
|
||||
return brcmf_ethtool(ifp, ifr->ifr_data);
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int brcmf_netdev_stop(struct net_device *ndev)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
@ -769,7 +629,6 @@ static int brcmf_netdev_open(struct net_device *ndev)
|
||||
struct brcmf_pub *drvr = ifp->drvr;
|
||||
struct brcmf_bus *bus_if = drvr->bus_if;
|
||||
u32 toe_ol;
|
||||
s32 ret = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
|
||||
|
||||
@ -788,21 +647,20 @@ static int brcmf_netdev_open(struct net_device *ndev)
|
||||
else
|
||||
ndev->features &= ~NETIF_F_IP_CSUM;
|
||||
|
||||
/* Allow transmit calls */
|
||||
netif_start_queue(ndev);
|
||||
if (brcmf_cfg80211_up(ndev)) {
|
||||
brcmf_err("failed to bring up cfg80211\n");
|
||||
return -1;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* Allow transmit calls */
|
||||
netif_start_queue(ndev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct net_device_ops brcmf_netdev_ops_pri = {
|
||||
.ndo_open = brcmf_netdev_open,
|
||||
.ndo_stop = brcmf_netdev_stop,
|
||||
.ndo_get_stats = brcmf_netdev_get_stats,
|
||||
.ndo_do_ioctl = brcmf_netdev_ioctl_entry,
|
||||
.ndo_start_xmit = brcmf_netdev_start_xmit,
|
||||
.ndo_set_mac_address = brcmf_netdev_set_mac_address,
|
||||
.ndo_set_rx_mode = brcmf_netdev_set_multicast_list
|
||||
@ -868,13 +726,6 @@ static int brcmf_net_p2p_stop(struct net_device *ndev)
|
||||
return brcmf_cfg80211_down(ndev);
|
||||
}
|
||||
|
||||
static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
|
||||
struct ifreq *ifr, int cmd)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *ndev)
|
||||
{
|
||||
@ -887,7 +738,6 @@ static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
|
||||
static const struct net_device_ops brcmf_netdev_ops_p2p = {
|
||||
.ndo_open = brcmf_net_p2p_open,
|
||||
.ndo_stop = brcmf_net_p2p_stop,
|
||||
.ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
|
||||
.ndo_start_xmit = brcmf_net_p2p_start_xmit
|
||||
};
|
||||
|
||||
@ -1016,7 +866,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
|
||||
}
|
||||
}
|
||||
|
||||
int brcmf_attach(uint bus_hdrlen, struct device *dev)
|
||||
int brcmf_attach(struct device *dev)
|
||||
{
|
||||
struct brcmf_pub *drvr = NULL;
|
||||
int ret = 0;
|
||||
@ -1031,7 +881,7 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
|
||||
mutex_init(&drvr->proto_block);
|
||||
|
||||
/* Link to bus module */
|
||||
drvr->hdrlen = bus_hdrlen;
|
||||
drvr->hdrlen = 0;
|
||||
drvr->bus_if = dev_get_drvdata(dev);
|
||||
drvr->bus_if->drvr = drvr;
|
||||
|
||||
@ -1048,8 +898,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
|
||||
/* attach firmware event handler */
|
||||
brcmf_fweh_attach(drvr);
|
||||
|
||||
INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
@ -1138,14 +986,21 @@ int brcmf_bus_start(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_pub *drvr = bus_if->drvr;
|
||||
|
||||
if (drvr) {
|
||||
drvr->hdrlen += len;
|
||||
}
|
||||
}
|
||||
|
||||
static void brcmf_bus_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
if (drvr) {
|
||||
/* Stop the protocol module */
|
||||
brcmf_proto_stop(drvr);
|
||||
|
||||
/* Stop the bus module */
|
||||
brcmf_bus_stop(drvr->bus_if);
|
||||
}
|
||||
@ -1186,8 +1041,7 @@ void brcmf_detach(struct device *dev)
|
||||
|
||||
brcmf_bus_detach(drvr);
|
||||
|
||||
if (drvr->prot)
|
||||
brcmf_proto_detach(drvr);
|
||||
brcmf_proto_detach(drvr);
|
||||
|
||||
brcmf_fws_deinit(drvr);
|
||||
|
||||
@ -1196,6 +1050,14 @@ void brcmf_detach(struct device *dev)
|
||||
kfree(drvr);
|
||||
}
|
||||
|
||||
s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_if *ifp = bus_if->drvr->iflist[0];
|
||||
|
||||
return brcmf_fil_iovar_data_set(ifp, name, data, len);
|
||||
}
|
||||
|
||||
static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
|
||||
{
|
||||
return atomic_read(&ifp->pend_8021x_cnt);
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _BRCMF_PROTO_H_
|
||||
#define _BRCMF_PROTO_H_
|
||||
|
||||
/*
|
||||
* Exported from the brcmf protocol module (brcmf_cdc)
|
||||
*/
|
||||
|
||||
/* Linkage, sets prot link and updates hdrlen in pub */
|
||||
int brcmf_proto_attach(struct brcmf_pub *drvr);
|
||||
|
||||
/* Unlink, frees allocated protocol memory (including brcmf_proto) */
|
||||
void brcmf_proto_detach(struct brcmf_pub *drvr);
|
||||
|
||||
/* Stop protocol: sync w/dongle state. */
|
||||
void brcmf_proto_stop(struct brcmf_pub *drvr);
|
||||
|
||||
/* Add any protocol-specific data header.
|
||||
* Caller must reserve prot_hdrlen prepend space.
|
||||
*/
|
||||
void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset,
|
||||
struct sk_buff *txp);
|
||||
|
||||
/* Sets dongle media info (drv_version, mac address). */
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
|
||||
|
||||
#endif /* _BRCMF_PROTO_H_ */
|
@ -32,6 +32,7 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/platform_data/brcmfmac-sdio.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <defs.h>
|
||||
#include <brcmu_wifi.h>
|
||||
@ -110,6 +111,8 @@ struct rte_console {
|
||||
#define BRCMF_TXBOUND 20 /* Default for max tx frames in
|
||||
one scheduling */
|
||||
|
||||
#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
|
||||
|
||||
#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
|
||||
|
||||
#define MEMBLOCK 2048 /* Block size used for downloading
|
||||
@ -360,6 +363,8 @@ struct brcmf_sdio_hdrinfo {
|
||||
u16 len_left;
|
||||
u16 len_nxtfrm;
|
||||
u8 dat_offset;
|
||||
bool lastfrm;
|
||||
u16 tail_pad;
|
||||
};
|
||||
|
||||
/* misc chip info needed by some of the routines */
|
||||
@ -384,7 +389,7 @@ struct brcmf_sdio {
|
||||
u8 tx_seq; /* Transmit sequence number (next) */
|
||||
u8 tx_max; /* Maximum transmit sequence allowed */
|
||||
|
||||
u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
|
||||
u8 *hdrbuf; /* buffer for handling rx frame */
|
||||
u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
|
||||
u8 rx_seq; /* Receive sequence number (expected) */
|
||||
struct brcmf_sdio_hdrinfo cur_read;
|
||||
@ -455,6 +460,10 @@ struct brcmf_sdio {
|
||||
bool sleeping; /* SDIO bus sleeping */
|
||||
|
||||
u8 tx_hdrlen; /* sdio bus header length for tx packet */
|
||||
bool txglom; /* host tx glomming enable flag */
|
||||
struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */
|
||||
u16 head_align; /* buffer pointer alignment */
|
||||
u16 sgentry_align; /* scatter-gather buffer alignment */
|
||||
};
|
||||
|
||||
/* clkstate */
|
||||
@ -479,6 +488,10 @@ static const uint max_roundup = 512;
|
||||
|
||||
#define ALIGNMENT 4
|
||||
|
||||
static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
|
||||
module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
|
||||
MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
|
||||
|
||||
enum brcmf_sdio_frmtype {
|
||||
BRCMF_SDIO_FT_NORMAL,
|
||||
BRCMF_SDIO_FT_SUPER,
|
||||
@ -499,6 +512,8 @@ enum brcmf_sdio_frmtype {
|
||||
#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt"
|
||||
#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin"
|
||||
#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt"
|
||||
#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
|
||||
#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
|
||||
|
||||
MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
|
||||
@ -514,6 +529,8 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4334_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4335_NVRAM_NAME);
|
||||
MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
|
||||
MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
|
||||
|
||||
struct brcmf_firmware_names {
|
||||
u32 chipid;
|
||||
@ -537,7 +554,8 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = {
|
||||
{ BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
|
||||
{ BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
|
||||
{ BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
|
||||
{ BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }
|
||||
{ BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
|
||||
{ BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }
|
||||
};
|
||||
|
||||
|
||||
@ -1097,10 +1115,18 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
|
||||
* host and WiFi dongle which contains information needed for SDIO core and
|
||||
* firmware
|
||||
*
|
||||
* It consists of 2 parts: hw header and software header
|
||||
* It consists of 3 parts: hardware header, hardware extension header and
|
||||
* software header
|
||||
* hardware header (frame tag) - 4 bytes
|
||||
* Byte 0~1: Frame length
|
||||
* Byte 2~3: Checksum, bit-wise inverse of frame length
|
||||
* hardware extension header - 8 bytes
|
||||
* Tx glom mode only, N/A for Rx or normal Tx
|
||||
* Byte 0~1: Packet length excluding hw frame tag
|
||||
* Byte 2: Reserved
|
||||
* Byte 3: Frame flags, bit 0: last frame indication
|
||||
* Byte 4~5: Reserved
|
||||
* Byte 6~7: Tail padding length
|
||||
* software header - 8 bytes
|
||||
* Byte 0: Rx/Tx sequence number
|
||||
* Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag
|
||||
@ -1111,6 +1137,7 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
|
||||
* Byte 6~7: Reserved
|
||||
*/
|
||||
#define SDPCM_HWHDR_LEN 4
|
||||
#define SDPCM_HWEXT_LEN 8
|
||||
#define SDPCM_SWHDR_LEN 8
|
||||
#define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN)
|
||||
/* software header */
|
||||
@ -1147,7 +1174,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
|
||||
u8 rx_seq, fc, tx_seq_max;
|
||||
u32 swheader;
|
||||
|
||||
trace_brcmf_sdpcm_hdr(false, header);
|
||||
trace_brcmf_sdpcm_hdr(SDPCM_RX, header);
|
||||
|
||||
/* hw header */
|
||||
len = get_unaligned_le16(header);
|
||||
@ -1260,25 +1287,34 @@ static inline void brcmf_sdio_update_hwhdr(u8 *header, u16 frm_length)
|
||||
static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header,
|
||||
struct brcmf_sdio_hdrinfo *hd_info)
|
||||
{
|
||||
u32 sw_header;
|
||||
u32 hdrval;
|
||||
u8 hdr_offset;
|
||||
|
||||
brcmf_sdio_update_hwhdr(header, hd_info->len);
|
||||
hdr_offset = SDPCM_HWHDR_LEN;
|
||||
|
||||
sw_header = bus->tx_seq;
|
||||
sw_header |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) &
|
||||
SDPCM_CHANNEL_MASK;
|
||||
sw_header |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) &
|
||||
SDPCM_DOFFSET_MASK;
|
||||
*(((__le32 *)header) + 1) = cpu_to_le32(sw_header);
|
||||
*(((__le32 *)header) + 2) = 0;
|
||||
trace_brcmf_sdpcm_hdr(true, header);
|
||||
if (bus->txglom) {
|
||||
hdrval = (hd_info->len - hdr_offset) | (hd_info->lastfrm << 24);
|
||||
*((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval);
|
||||
hdrval = (u16)hd_info->tail_pad << 16;
|
||||
*(((__le32 *)(header + hdr_offset)) + 1) = cpu_to_le32(hdrval);
|
||||
hdr_offset += SDPCM_HWEXT_LEN;
|
||||
}
|
||||
|
||||
hdrval = hd_info->seq_num;
|
||||
hdrval |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) &
|
||||
SDPCM_CHANNEL_MASK;
|
||||
hdrval |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) &
|
||||
SDPCM_DOFFSET_MASK;
|
||||
*((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval);
|
||||
*(((__le32 *)(header + hdr_offset)) + 1) = 0;
|
||||
trace_brcmf_sdpcm_hdr(SDPCM_TX + !!(bus->txglom), header);
|
||||
}
|
||||
|
||||
static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
||||
{
|
||||
u16 dlen, totlen;
|
||||
u8 *dptr, num = 0;
|
||||
u32 align = 0;
|
||||
u16 sublen;
|
||||
struct sk_buff *pfirst, *pnext;
|
||||
|
||||
@ -1293,11 +1329,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
||||
brcmf_dbg(SDIO, "start: glomd %p glom %p\n",
|
||||
bus->glomd, skb_peek(&bus->glom));
|
||||
|
||||
if (bus->sdiodev->pdata)
|
||||
align = bus->sdiodev->pdata->sd_sgentry_align;
|
||||
if (align < 4)
|
||||
align = 4;
|
||||
|
||||
/* If there's a descriptor, generate the packet chain */
|
||||
if (bus->glomd) {
|
||||
pfirst = pnext = NULL;
|
||||
@ -1321,9 +1352,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
||||
pnext = NULL;
|
||||
break;
|
||||
}
|
||||
if (sublen % align) {
|
||||
if (sublen % bus->sgentry_align) {
|
||||
brcmf_err("sublen %d not multiple of %d\n",
|
||||
sublen, align);
|
||||
sublen, bus->sgentry_align);
|
||||
}
|
||||
totlen += sublen;
|
||||
|
||||
@ -1336,7 +1367,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
||||
}
|
||||
|
||||
/* Allocate/chain packet for next subframe */
|
||||
pnext = brcmu_pkt_buf_get_skb(sublen + align);
|
||||
pnext = brcmu_pkt_buf_get_skb(sublen + bus->sgentry_align);
|
||||
if (pnext == NULL) {
|
||||
brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n",
|
||||
num, sublen);
|
||||
@ -1345,7 +1376,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
||||
skb_queue_tail(&bus->glom, pnext);
|
||||
|
||||
/* Adhere to start alignment requirements */
|
||||
pkt_align(pnext, sublen, align);
|
||||
pkt_align(pnext, sublen, bus->sgentry_align);
|
||||
}
|
||||
|
||||
/* If all allocations succeeded, save packet chain
|
||||
@ -1549,9 +1580,9 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
|
||||
goto done;
|
||||
|
||||
rbuf = bus->rxbuf;
|
||||
pad = ((unsigned long)rbuf % BRCMF_SDALIGN);
|
||||
pad = ((unsigned long)rbuf % bus->head_align);
|
||||
if (pad)
|
||||
rbuf += (BRCMF_SDALIGN - pad);
|
||||
rbuf += (bus->head_align - pad);
|
||||
|
||||
/* Copy the already-read portion over */
|
||||
memcpy(buf, hdr, BRCMF_FIRSTREAD);
|
||||
@ -1565,14 +1596,10 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
|
||||
if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
|
||||
((len + pad) < bus->sdiodev->bus_if->maxctl))
|
||||
rdlen += pad;
|
||||
} else if (rdlen % BRCMF_SDALIGN) {
|
||||
rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
|
||||
} else if (rdlen % bus->head_align) {
|
||||
rdlen += bus->head_align - (rdlen % bus->head_align);
|
||||
}
|
||||
|
||||
/* Satisfy length-alignment requirements */
|
||||
if (rdlen & (ALIGNMENT - 1))
|
||||
rdlen = roundup(rdlen, ALIGNMENT);
|
||||
|
||||
/* Drop if the read is too big or it exceeds our maximum */
|
||||
if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
|
||||
brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
|
||||
@ -1637,8 +1664,8 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
|
||||
if (*pad <= bus->roundup && *pad < bus->blocksize &&
|
||||
*rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
|
||||
*rdlen += *pad;
|
||||
} else if (*rdlen % BRCMF_SDALIGN) {
|
||||
*rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN);
|
||||
} else if (*rdlen % bus->head_align) {
|
||||
*rdlen += bus->head_align - (*rdlen % bus->head_align);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1726,7 +1753,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
|
||||
brcmf_pad(bus, &pad, &rd->len_left);
|
||||
|
||||
pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read +
|
||||
BRCMF_SDALIGN);
|
||||
bus->head_align);
|
||||
if (!pkt) {
|
||||
/* Give up on data, request rtx of events */
|
||||
brcmf_err("brcmu_pkt_buf_get_skb failed\n");
|
||||
@ -1736,7 +1763,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
|
||||
continue;
|
||||
}
|
||||
skb_pull(pkt, head_read);
|
||||
pkt_align(pkt, rd->len_left, BRCMF_SDALIGN);
|
||||
pkt_align(pkt, rd->len_left, bus->head_align);
|
||||
|
||||
ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
|
||||
SDIO_FUNC_2, F2SYNC, pkt);
|
||||
@ -1871,6 +1898,29 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
|
||||
return;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
|
||||
{
|
||||
u16 head_pad;
|
||||
u8 *dat_buf;
|
||||
|
||||
dat_buf = (u8 *)(pkt->data);
|
||||
|
||||
/* Check head padding */
|
||||
head_pad = ((unsigned long)dat_buf % bus->head_align);
|
||||
if (head_pad) {
|
||||
if (skb_headroom(pkt) < head_pad) {
|
||||
bus->sdiodev->bus_if->tx_realloc++;
|
||||
head_pad = 0;
|
||||
if (skb_cow(pkt, head_pad))
|
||||
return -ENOMEM;
|
||||
}
|
||||
skb_push(pkt, head_pad);
|
||||
dat_buf = (u8 *)(pkt->data);
|
||||
memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
|
||||
}
|
||||
return head_pad;
|
||||
}
|
||||
|
||||
/**
|
||||
* struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
|
||||
* bus layer usage.
|
||||
@ -1880,32 +1930,40 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
|
||||
/* bit mask of data length chopped from the previous packet */
|
||||
#define ALIGN_SKB_CHOP_LEN_MASK 0x7fff
|
||||
|
||||
static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev,
|
||||
static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
|
||||
struct sk_buff_head *pktq,
|
||||
struct sk_buff *pkt, uint chan)
|
||||
struct sk_buff *pkt, u16 total_len)
|
||||
{
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
struct sk_buff *pkt_pad;
|
||||
u16 tail_pad, tail_chop, sg_align;
|
||||
u16 tail_pad, tail_chop, chain_pad;
|
||||
unsigned int blksize;
|
||||
u8 *dat_buf;
|
||||
int ntail;
|
||||
bool lastfrm;
|
||||
int ntail, ret;
|
||||
|
||||
sdiodev = bus->sdiodev;
|
||||
blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
|
||||
sg_align = 4;
|
||||
if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4)
|
||||
sg_align = sdiodev->pdata->sd_sgentry_align;
|
||||
/* sg entry alignment should be a divisor of block size */
|
||||
WARN_ON(blksize % sg_align);
|
||||
WARN_ON(blksize % bus->sgentry_align);
|
||||
|
||||
/* Check tail padding */
|
||||
pkt_pad = NULL;
|
||||
tail_chop = pkt->len % sg_align;
|
||||
tail_pad = sg_align - tail_chop;
|
||||
tail_pad += blksize - (pkt->len + tail_pad) % blksize;
|
||||
lastfrm = skb_queue_is_last(pktq, pkt);
|
||||
tail_pad = 0;
|
||||
tail_chop = pkt->len % bus->sgentry_align;
|
||||
if (tail_chop)
|
||||
tail_pad = bus->sgentry_align - tail_chop;
|
||||
chain_pad = (total_len + tail_pad) % blksize;
|
||||
if (lastfrm && chain_pad)
|
||||
tail_pad += blksize - chain_pad;
|
||||
if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) {
|
||||
pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop);
|
||||
pkt_pad = bus->txglom_sgpad;
|
||||
if (pkt_pad == NULL)
|
||||
brcmu_pkt_buf_get_skb(tail_pad + tail_chop);
|
||||
if (pkt_pad == NULL)
|
||||
return -ENOMEM;
|
||||
ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad);
|
||||
if (unlikely(ret < 0))
|
||||
return ret;
|
||||
memcpy(pkt_pad->data,
|
||||
pkt->data + pkt->len - tail_chop,
|
||||
tail_chop);
|
||||
@ -1920,14 +1978,10 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev,
|
||||
return -ENOMEM;
|
||||
if (skb_linearize(pkt))
|
||||
return -ENOMEM;
|
||||
dat_buf = (u8 *)(pkt->data);
|
||||
__skb_put(pkt, tail_pad);
|
||||
}
|
||||
|
||||
if (pkt_pad)
|
||||
return pkt->len + tail_chop;
|
||||
else
|
||||
return pkt->len - tail_pad;
|
||||
return tail_pad;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1946,58 +2000,66 @@ static int
|
||||
brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
|
||||
uint chan)
|
||||
{
|
||||
u16 head_pad, head_align;
|
||||
u16 head_pad, total_len;
|
||||
struct sk_buff *pkt_next;
|
||||
u8 *dat_buf;
|
||||
int err;
|
||||
u8 txseq;
|
||||
int ret;
|
||||
struct brcmf_sdio_hdrinfo hd_info = {0};
|
||||
|
||||
/* SDIO ADMA requires at least 32 bit alignment */
|
||||
head_align = 4;
|
||||
if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4)
|
||||
head_align = bus->sdiodev->pdata->sd_head_align;
|
||||
txseq = bus->tx_seq;
|
||||
total_len = 0;
|
||||
skb_queue_walk(pktq, pkt_next) {
|
||||
/* alignment packet inserted in previous
|
||||
* loop cycle can be skipped as it is
|
||||
* already properly aligned and does not
|
||||
* need an sdpcm header.
|
||||
*/
|
||||
if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
|
||||
continue;
|
||||
|
||||
pkt_next = pktq->next;
|
||||
dat_buf = (u8 *)(pkt_next->data);
|
||||
/* align packet data pointer */
|
||||
ret = brcmf_sdio_txpkt_hdalign(bus, pkt_next);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
head_pad = (u16)ret;
|
||||
if (head_pad)
|
||||
memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen);
|
||||
|
||||
/* Check head padding */
|
||||
head_pad = ((unsigned long)dat_buf % head_align);
|
||||
if (head_pad) {
|
||||
if (skb_headroom(pkt_next) < head_pad) {
|
||||
bus->sdiodev->bus_if->tx_realloc++;
|
||||
head_pad = 0;
|
||||
if (skb_cow(pkt_next, head_pad))
|
||||
return -ENOMEM;
|
||||
}
|
||||
skb_push(pkt_next, head_pad);
|
||||
dat_buf = (u8 *)(pkt_next->data);
|
||||
memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
|
||||
}
|
||||
total_len += pkt_next->len;
|
||||
|
||||
if (bus->sdiodev->sg_support && pktq->qlen > 1) {
|
||||
err = brcmf_sdio_txpkt_prep_sg(bus->sdiodev, pktq,
|
||||
pkt_next, chan);
|
||||
if (err < 0)
|
||||
return err;
|
||||
hd_info.len = (u16)err;
|
||||
} else {
|
||||
hd_info.len = pkt_next->len;
|
||||
hd_info.lastfrm = skb_queue_is_last(pktq, pkt_next);
|
||||
if (bus->txglom && pktq->qlen > 1) {
|
||||
ret = brcmf_sdio_txpkt_prep_sg(bus, pktq,
|
||||
pkt_next, total_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
hd_info.tail_pad = (u16)ret;
|
||||
total_len += (u16)ret;
|
||||
}
|
||||
|
||||
hd_info.channel = chan;
|
||||
hd_info.dat_offset = head_pad + bus->tx_hdrlen;
|
||||
hd_info.seq_num = txseq++;
|
||||
|
||||
/* Now fill the header */
|
||||
brcmf_sdio_hdpack(bus, pkt_next->data, &hd_info);
|
||||
|
||||
if (BRCMF_BYTES_ON() &&
|
||||
((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
|
||||
(BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
|
||||
brcmf_dbg_hex_dump(true, pkt_next, hd_info.len,
|
||||
"Tx Frame:\n");
|
||||
else if (BRCMF_HDRS_ON())
|
||||
brcmf_dbg_hex_dump(true, pkt_next,
|
||||
head_pad + bus->tx_hdrlen,
|
||||
"Tx Header:\n");
|
||||
}
|
||||
|
||||
hd_info.channel = chan;
|
||||
hd_info.dat_offset = head_pad + bus->tx_hdrlen;
|
||||
|
||||
/* Now fill the header */
|
||||
brcmf_sdio_hdpack(bus, dat_buf, &hd_info);
|
||||
|
||||
if (BRCMF_BYTES_ON() &&
|
||||
((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
|
||||
(BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
|
||||
brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, "Tx Frame:\n");
|
||||
else if (BRCMF_HDRS_ON())
|
||||
brcmf_dbg_hex_dump(true, pkt_next, head_pad + bus->tx_hdrlen,
|
||||
"Tx Header:\n");
|
||||
|
||||
/* Hardware length tag of the first packet should be total
|
||||
* length of the chain (including padding)
|
||||
*/
|
||||
if (bus->txglom)
|
||||
brcmf_sdio_update_hwhdr(pktq->next->data, total_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2015,6 +2077,7 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
|
||||
{
|
||||
u8 *hdr;
|
||||
u32 dat_offset;
|
||||
u16 tail_pad;
|
||||
u32 dummy_flags, chop_len;
|
||||
struct sk_buff *pkt_next, *tmp, *pkt_prev;
|
||||
|
||||
@ -2024,42 +2087,42 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
|
||||
chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
|
||||
if (chop_len) {
|
||||
pkt_prev = pkt_next->prev;
|
||||
memcpy(pkt_prev->data + pkt_prev->len,
|
||||
pkt_next->data, chop_len);
|
||||
skb_put(pkt_prev, chop_len);
|
||||
}
|
||||
__skb_unlink(pkt_next, pktq);
|
||||
brcmu_pkt_buf_free_skb(pkt_next);
|
||||
} else {
|
||||
hdr = pkt_next->data + SDPCM_HWHDR_LEN;
|
||||
hdr = pkt_next->data + bus->tx_hdrlen - SDPCM_SWHDR_LEN;
|
||||
dat_offset = le32_to_cpu(*(__le32 *)hdr);
|
||||
dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >>
|
||||
SDPCM_DOFFSET_SHIFT;
|
||||
skb_pull(pkt_next, dat_offset);
|
||||
if (bus->txglom) {
|
||||
tail_pad = le16_to_cpu(*(__le16 *)(hdr - 2));
|
||||
skb_trim(pkt_next, pkt_next->len - tail_pad);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Writes a HW/SW header into the packet and sends it. */
|
||||
/* Assumes: (a) header space already there, (b) caller holds lock */
|
||||
static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
|
||||
static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
|
||||
uint chan)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
struct sk_buff_head localq;
|
||||
struct sk_buff *pkt_next, *tmp;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
__skb_queue_head_init(&localq);
|
||||
__skb_queue_tail(&localq, pkt);
|
||||
ret = brcmf_sdio_txpkt_prep(bus, &localq, chan);
|
||||
ret = brcmf_sdio_txpkt_prep(bus, pktq, chan);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
sdio_claim_host(bus->sdiodev->func[1]);
|
||||
ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
|
||||
SDIO_FUNC_2, F2SYNC, &localq);
|
||||
SDIO_FUNC_2, F2SYNC, pktq);
|
||||
bus->sdcnt.f2txdata++;
|
||||
|
||||
if (ret < 0) {
|
||||
@ -2083,42 +2146,56 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
|
||||
if ((hi == 0) && (lo == 0))
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
sdio_release_host(bus->sdiodev->func[1]);
|
||||
if (ret == 0)
|
||||
bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
|
||||
|
||||
done:
|
||||
brcmf_sdio_txpkt_postp(bus, &localq);
|
||||
__skb_dequeue_tail(&localq);
|
||||
brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0);
|
||||
brcmf_sdio_txpkt_postp(bus, pktq);
|
||||
if (ret == 0)
|
||||
bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP;
|
||||
skb_queue_walk_safe(pktq, pkt_next, tmp) {
|
||||
__skb_unlink(pkt_next, pktq);
|
||||
brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
|
||||
{
|
||||
struct sk_buff *pkt;
|
||||
struct sk_buff_head pktq;
|
||||
u32 intstatus = 0;
|
||||
int ret = 0, prec_out;
|
||||
int ret = 0, prec_out, i;
|
||||
uint cnt = 0;
|
||||
u8 tx_prec_map;
|
||||
u8 tx_prec_map, pkt_num;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
tx_prec_map = ~bus->flowcontrol;
|
||||
|
||||
/* Send frames until the limit or some other event */
|
||||
for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) {
|
||||
for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
|
||||
pkt_num = 1;
|
||||
__skb_queue_head_init(&pktq);
|
||||
if (bus->txglom)
|
||||
pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
|
||||
brcmf_sdio_txglomsz);
|
||||
pkt_num = min_t(u32, pkt_num,
|
||||
brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
|
||||
spin_lock_bh(&bus->txqlock);
|
||||
pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
|
||||
if (pkt == NULL) {
|
||||
spin_unlock_bh(&bus->txqlock);
|
||||
break;
|
||||
for (i = 0; i < pkt_num; i++) {
|
||||
pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map,
|
||||
&prec_out);
|
||||
if (pkt == NULL)
|
||||
break;
|
||||
__skb_queue_tail(&pktq, pkt);
|
||||
}
|
||||
spin_unlock_bh(&bus->txqlock);
|
||||
if (i == 0)
|
||||
break;
|
||||
|
||||
ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL);
|
||||
ret = brcmf_sdbrcm_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
|
||||
cnt += i;
|
||||
|
||||
/* In poll mode, need to check for other events */
|
||||
if (!bus->intr && cnt) {
|
||||
@ -2665,7 +2742,7 @@ static int
|
||||
brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
|
||||
{
|
||||
u8 *frame;
|
||||
u16 len;
|
||||
u16 len, pad;
|
||||
uint retries = 0;
|
||||
u8 doff = 0;
|
||||
int ret = -1;
|
||||
@ -2681,28 +2758,26 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
|
||||
len = (msglen += bus->tx_hdrlen);
|
||||
|
||||
/* Add alignment padding (optional for ctl frames) */
|
||||
doff = ((unsigned long)frame % BRCMF_SDALIGN);
|
||||
doff = ((unsigned long)frame % bus->head_align);
|
||||
if (doff) {
|
||||
frame -= doff;
|
||||
len += doff;
|
||||
msglen += doff;
|
||||
memset(frame, 0, doff + bus->tx_hdrlen);
|
||||
}
|
||||
/* precondition: doff < BRCMF_SDALIGN */
|
||||
/* precondition: doff < bus->head_align */
|
||||
doff += bus->tx_hdrlen;
|
||||
|
||||
/* Round send length to next SDIO block */
|
||||
pad = 0;
|
||||
if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
|
||||
u16 pad = bus->blocksize - (len % bus->blocksize);
|
||||
if ((pad <= bus->roundup) && (pad < bus->blocksize))
|
||||
len += pad;
|
||||
} else if (len % BRCMF_SDALIGN) {
|
||||
len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN);
|
||||
pad = bus->blocksize - (len % bus->blocksize);
|
||||
if ((pad > bus->roundup) || (pad >= bus->blocksize))
|
||||
pad = 0;
|
||||
} else if (len % bus->head_align) {
|
||||
pad = bus->head_align - (len % bus->head_align);
|
||||
}
|
||||
|
||||
/* Satisfy length-alignment requirements */
|
||||
if (len & (ALIGNMENT - 1))
|
||||
len = roundup(len, ALIGNMENT);
|
||||
len += pad;
|
||||
|
||||
/* precondition: IS_ALIGNED((unsigned long)frame, 2) */
|
||||
|
||||
@ -2714,8 +2789,14 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
|
||||
hd_info.len = (u16)msglen;
|
||||
hd_info.channel = SDPCM_CONTROL_CHANNEL;
|
||||
hd_info.dat_offset = doff;
|
||||
hd_info.seq_num = bus->tx_seq;
|
||||
hd_info.lastfrm = true;
|
||||
hd_info.tail_pad = pad;
|
||||
brcmf_sdio_hdpack(bus, frame, &hd_info);
|
||||
|
||||
if (bus->txglom)
|
||||
brcmf_sdio_update_hwhdr(frame, len);
|
||||
|
||||
if (!data_ok(bus)) {
|
||||
brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
|
||||
bus->tx_max, bus->tx_seq);
|
||||
@ -3425,6 +3506,65 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int brcmf_sdbrcm_bus_preinit(struct device *dev)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
struct brcmf_sdio *bus = sdiodev->bus;
|
||||
uint pad_size;
|
||||
u32 value;
|
||||
u8 idx;
|
||||
int err;
|
||||
|
||||
/* the commands below use the terms tx and rx from
|
||||
* a device perspective, ie. bus:txglom affects the
|
||||
* bus transfers from device to host.
|
||||
*/
|
||||
idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
if (bus->ci->c_inf[idx].rev < 12) {
|
||||
/* for sdio core rev < 12, disable txgloming */
|
||||
value = 0;
|
||||
err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
|
||||
sizeof(u32));
|
||||
} else {
|
||||
/* otherwise, set txglomalign */
|
||||
value = 4;
|
||||
if (sdiodev->pdata)
|
||||
value = sdiodev->pdata->sd_sgentry_align;
|
||||
/* SDIO ADMA requires at least 32 bit alignment */
|
||||
value = max_t(u32, value, 4);
|
||||
err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
|
||||
sizeof(u32));
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
goto done;
|
||||
|
||||
bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
|
||||
if (sdiodev->sg_support) {
|
||||
bus->txglom = false;
|
||||
value = 1;
|
||||
pad_size = bus->sdiodev->func[2]->cur_blksize << 1;
|
||||
bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size);
|
||||
if (!bus->txglom_sgpad)
|
||||
brcmf_err("allocating txglom padding skb failed, reduced performance\n");
|
||||
|
||||
err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom",
|
||||
&value, sizeof(u32));
|
||||
if (err < 0) {
|
||||
/* bus:rxglom is allowed to fail */
|
||||
err = 0;
|
||||
} else {
|
||||
bus->txglom = true;
|
||||
bus->tx_hdrlen += SDPCM_HWEXT_LEN;
|
||||
}
|
||||
}
|
||||
brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
|
||||
|
||||
done:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int brcmf_sdbrcm_bus_init(struct device *dev)
|
||||
{
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
@ -3673,7 +3813,7 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
|
||||
if (bus->sdiodev->bus_if->maxctl) {
|
||||
bus->rxblen =
|
||||
roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
|
||||
ALIGNMENT) + BRCMF_SDALIGN;
|
||||
ALIGNMENT) + bus->head_align;
|
||||
bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
|
||||
if (!(bus->rxbuf))
|
||||
return false;
|
||||
@ -3774,9 +3914,13 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
|
||||
|
||||
brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
|
||||
|
||||
/* allocate header buffer */
|
||||
bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL);
|
||||
if (!bus->hdrbuf)
|
||||
return false;
|
||||
/* Locate an appropriately-aligned portion of hdrbuf */
|
||||
bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
|
||||
BRCMF_SDALIGN);
|
||||
bus->head_align);
|
||||
|
||||
/* Set the poll and/or interrupt flags */
|
||||
bus->intr = true;
|
||||
@ -3895,8 +4039,9 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
|
||||
brcmf_sdbrcm_release_dongle(bus);
|
||||
}
|
||||
|
||||
brcmu_pkt_buf_free_skb(bus->txglom_sgpad);
|
||||
brcmf_sdbrcm_release_malloc(bus);
|
||||
|
||||
kfree(bus->hdrbuf);
|
||||
kfree(bus);
|
||||
}
|
||||
|
||||
@ -3905,6 +4050,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
|
||||
|
||||
static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
|
||||
.stop = brcmf_sdbrcm_bus_stop,
|
||||
.preinit = brcmf_sdbrcm_bus_preinit,
|
||||
.init = brcmf_sdbrcm_bus_init,
|
||||
.txdata = brcmf_sdbrcm_bus_txdata,
|
||||
.txctl = brcmf_sdbrcm_bus_txctl,
|
||||
@ -3916,10 +4062,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret;
|
||||
struct brcmf_sdio *bus;
|
||||
struct brcmf_bus_dcmd *dlst;
|
||||
u32 dngl_txglom;
|
||||
u32 txglomalign = 0;
|
||||
u8 idx;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
@ -3939,6 +4081,18 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
||||
bus->txminmax = BRCMF_TXMINMAX;
|
||||
bus->tx_seq = SDPCM_SEQ_WRAP - 1;
|
||||
|
||||
/* platform specific configuration:
|
||||
* alignments must be at least 4 bytes for ADMA
|
||||
*/
|
||||
bus->head_align = ALIGNMENT;
|
||||
bus->sgentry_align = ALIGNMENT;
|
||||
if (sdiodev->pdata) {
|
||||
if (sdiodev->pdata->sd_head_align > ALIGNMENT)
|
||||
bus->head_align = sdiodev->pdata->sd_head_align;
|
||||
if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
|
||||
bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
|
||||
}
|
||||
|
||||
INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
|
||||
bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
|
||||
if (bus->brcmf_wq == NULL) {
|
||||
@ -3983,7 +4137,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
||||
bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
|
||||
|
||||
/* Attach to the common layer, reserve hdr space */
|
||||
ret = brcmf_attach(bus->tx_hdrlen, bus->sdiodev->dev);
|
||||
ret = brcmf_attach(bus->sdiodev->dev);
|
||||
if (ret != 0) {
|
||||
brcmf_err("brcmf_attach failed\n");
|
||||
goto fail;
|
||||
@ -4003,30 +4157,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
||||
brcmf_sdio_debugfs_create(bus);
|
||||
brcmf_dbg(INFO, "completed!!\n");
|
||||
|
||||
/* sdio bus core specific dcmd */
|
||||
idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
|
||||
dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
|
||||
if (dlst) {
|
||||
if (bus->ci->c_inf[idx].rev < 12) {
|
||||
/* for sdio core rev < 12, disable txgloming */
|
||||
dngl_txglom = 0;
|
||||
dlst->name = "bus:txglom";
|
||||
dlst->param = (char *)&dngl_txglom;
|
||||
dlst->param_len = sizeof(u32);
|
||||
} else {
|
||||
/* otherwise, set txglomalign */
|
||||
if (sdiodev->pdata)
|
||||
txglomalign = sdiodev->pdata->sd_sgentry_align;
|
||||
/* SDIO ADMA requires at least 32 bit alignment */
|
||||
if (txglomalign < 4)
|
||||
txglomalign = 4;
|
||||
dlst->name = "bus:txglomalign";
|
||||
dlst->param = (char *)&txglomalign;
|
||||
dlst->param_len = sizeof(u32);
|
||||
}
|
||||
list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
|
||||
}
|
||||
|
||||
/* if firmware path present try to download and bring up bus */
|
||||
ret = brcmf_bus_start(bus->sdiodev->dev);
|
||||
if (ret != 0) {
|
||||
|
@ -122,6 +122,52 @@ enum brcmf_fweh_event_code {
|
||||
#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
|
||||
#define BRCMF_EVENT_MSG_GROUP 0x04
|
||||
|
||||
/* status field values in struct brcmf_event_msg */
|
||||
#define BRCMF_E_STATUS_SUCCESS 0
|
||||
#define BRCMF_E_STATUS_FAIL 1
|
||||
#define BRCMF_E_STATUS_TIMEOUT 2
|
||||
#define BRCMF_E_STATUS_NO_NETWORKS 3
|
||||
#define BRCMF_E_STATUS_ABORT 4
|
||||
#define BRCMF_E_STATUS_NO_ACK 5
|
||||
#define BRCMF_E_STATUS_UNSOLICITED 6
|
||||
#define BRCMF_E_STATUS_ATTEMPT 7
|
||||
#define BRCMF_E_STATUS_PARTIAL 8
|
||||
#define BRCMF_E_STATUS_NEWSCAN 9
|
||||
#define BRCMF_E_STATUS_NEWASSOC 10
|
||||
#define BRCMF_E_STATUS_11HQUIET 11
|
||||
#define BRCMF_E_STATUS_SUPPRESS 12
|
||||
#define BRCMF_E_STATUS_NOCHANS 13
|
||||
#define BRCMF_E_STATUS_CS_ABORT 15
|
||||
#define BRCMF_E_STATUS_ERROR 16
|
||||
|
||||
/* reason field values in struct brcmf_event_msg */
|
||||
#define BRCMF_E_REASON_INITIAL_ASSOC 0
|
||||
#define BRCMF_E_REASON_LOW_RSSI 1
|
||||
#define BRCMF_E_REASON_DEAUTH 2
|
||||
#define BRCMF_E_REASON_DISASSOC 3
|
||||
#define BRCMF_E_REASON_BCNS_LOST 4
|
||||
#define BRCMF_E_REASON_MINTXRATE 9
|
||||
#define BRCMF_E_REASON_TXFAIL 10
|
||||
|
||||
#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4
|
||||
#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
|
||||
#define BRCMF_E_REASON_DIRECTED_ROAM 6
|
||||
#define BRCMF_E_REASON_TSPEC_REJECTED 7
|
||||
#define BRCMF_E_REASON_BETTER_AP 8
|
||||
|
||||
/* action field values for brcmf_ifevent */
|
||||
#define BRCMF_E_IF_ADD 1
|
||||
#define BRCMF_E_IF_DEL 2
|
||||
#define BRCMF_E_IF_CHANGE 3
|
||||
|
||||
/* flag field values for brcmf_ifevent */
|
||||
#define BRCMF_E_IF_FLAG_NOIF 1
|
||||
|
||||
/* role field values for brcmf_ifevent */
|
||||
#define BRCMF_E_IF_ROLE_STA 0
|
||||
#define BRCMF_E_IF_ROLE_AP 1
|
||||
#define BRCMF_E_IF_ROLE_WDS 2
|
||||
|
||||
/**
|
||||
* definitions for event packet validation.
|
||||
*/
|
||||
@ -160,6 +206,14 @@ struct brcmf_event_msg {
|
||||
u8 bsscfgidx;
|
||||
};
|
||||
|
||||
struct brcmf_if_event {
|
||||
u8 ifidx;
|
||||
u8 action;
|
||||
u8 flags;
|
||||
u8 bssidx;
|
||||
u8 role;
|
||||
};
|
||||
|
||||
typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
|
||||
const struct brcmf_event_msg *evtmsg,
|
||||
void *data);
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "dhd_dbg.h"
|
||||
#include "tracepoint.h"
|
||||
#include "fwil.h"
|
||||
#include "proto.h"
|
||||
|
||||
|
||||
#define MAX_HEX_DUMP_LEN 64
|
||||
@ -46,11 +47,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
|
||||
if (data != NULL)
|
||||
len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
|
||||
if (set)
|
||||
err = brcmf_proto_cdc_set_dcmd(drvr, ifp->ifidx, cmd, data,
|
||||
len);
|
||||
err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len);
|
||||
else
|
||||
err = brcmf_proto_cdc_query_dcmd(drvr, ifp->ifidx, cmd, data,
|
||||
len);
|
||||
err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
|
||||
|
||||
if (err >= 0)
|
||||
err = 0;
|
||||
|
@ -17,6 +17,67 @@
|
||||
#ifndef _fwil_h_
|
||||
#define _fwil_h_
|
||||
|
||||
/*******************************************************************************
|
||||
* Dongle command codes that are interpreted by firmware
|
||||
******************************************************************************/
|
||||
#define BRCMF_C_GET_VERSION 1
|
||||
#define BRCMF_C_UP 2
|
||||
#define BRCMF_C_DOWN 3
|
||||
#define BRCMF_C_SET_PROMISC 10
|
||||
#define BRCMF_C_GET_RATE 12
|
||||
#define BRCMF_C_GET_INFRA 19
|
||||
#define BRCMF_C_SET_INFRA 20
|
||||
#define BRCMF_C_GET_AUTH 21
|
||||
#define BRCMF_C_SET_AUTH 22
|
||||
#define BRCMF_C_GET_BSSID 23
|
||||
#define BRCMF_C_GET_SSID 25
|
||||
#define BRCMF_C_SET_SSID 26
|
||||
#define BRCMF_C_TERMINATED 28
|
||||
#define BRCMF_C_GET_CHANNEL 29
|
||||
#define BRCMF_C_SET_CHANNEL 30
|
||||
#define BRCMF_C_GET_SRL 31
|
||||
#define BRCMF_C_SET_SRL 32
|
||||
#define BRCMF_C_GET_LRL 33
|
||||
#define BRCMF_C_SET_LRL 34
|
||||
#define BRCMF_C_GET_RADIO 37
|
||||
#define BRCMF_C_SET_RADIO 38
|
||||
#define BRCMF_C_GET_PHYTYPE 39
|
||||
#define BRCMF_C_SET_KEY 45
|
||||
#define BRCMF_C_SET_PASSIVE_SCAN 49
|
||||
#define BRCMF_C_SCAN 50
|
||||
#define BRCMF_C_SCAN_RESULTS 51
|
||||
#define BRCMF_C_DISASSOC 52
|
||||
#define BRCMF_C_REASSOC 53
|
||||
#define BRCMF_C_SET_ROAM_TRIGGER 55
|
||||
#define BRCMF_C_SET_ROAM_DELTA 57
|
||||
#define BRCMF_C_GET_BCNPRD 75
|
||||
#define BRCMF_C_SET_BCNPRD 76
|
||||
#define BRCMF_C_GET_DTIMPRD 77
|
||||
#define BRCMF_C_SET_DTIMPRD 78
|
||||
#define BRCMF_C_SET_COUNTRY 84
|
||||
#define BRCMF_C_GET_PM 85
|
||||
#define BRCMF_C_SET_PM 86
|
||||
#define BRCMF_C_GET_CURR_RATESET 114
|
||||
#define BRCMF_C_GET_AP 117
|
||||
#define BRCMF_C_SET_AP 118
|
||||
#define BRCMF_C_GET_RSSI 127
|
||||
#define BRCMF_C_GET_WSEC 133
|
||||
#define BRCMF_C_SET_WSEC 134
|
||||
#define BRCMF_C_GET_PHY_NOISE 135
|
||||
#define BRCMF_C_GET_BSS_INFO 136
|
||||
#define BRCMF_C_GET_BANDLIST 140
|
||||
#define BRCMF_C_SET_SCB_TIMEOUT 158
|
||||
#define BRCMF_C_GET_PHYLIST 180
|
||||
#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
|
||||
#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
|
||||
#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
|
||||
#define BRCMF_C_GET_VALID_CHANNELS 217
|
||||
#define BRCMF_C_GET_KEY_PRIMARY 235
|
||||
#define BRCMF_C_SET_KEY_PRIMARY 236
|
||||
#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
|
||||
#define BRCMF_C_GET_VAR 262
|
||||
#define BRCMF_C_SET_VAR 263
|
||||
|
||||
s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
|
||||
s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
|
||||
s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
|
||||
|
@ -29,6 +29,24 @@
|
||||
#define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004
|
||||
#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008
|
||||
|
||||
#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
|
||||
#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002
|
||||
|
||||
#define BRCMF_STA_ASSOC 0x10 /* Associated */
|
||||
|
||||
/* size of brcmf_scan_params not including variable length array */
|
||||
#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
|
||||
|
||||
/* masks for channel and ssid count */
|
||||
#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
|
||||
#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
|
||||
|
||||
/* primary (ie tx) key */
|
||||
#define BRCMF_PRIMARY_KEY (1 << 1)
|
||||
#define DOT11_BSSTYPE_ANY 2
|
||||
#define BRCMF_ESCAN_REQ_VERSION 1
|
||||
|
||||
#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
|
||||
|
||||
enum brcmf_fil_p2p_if_types {
|
||||
BRCMF_FIL_P2P_IF_CLIENT,
|
||||
@ -90,4 +108,290 @@ enum brcmf_tdls_manual_ep_ops {
|
||||
BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6
|
||||
};
|
||||
|
||||
/* Pattern matching filter. Specifies an offset within received packets to
|
||||
* start matching, the pattern to match, the size of the pattern, and a bitmask
|
||||
* that indicates which bits within the pattern should be matched.
|
||||
*/
|
||||
struct brcmf_pkt_filter_pattern_le {
|
||||
/*
|
||||
* Offset within received packet to start pattern matching.
|
||||
* Offset '0' is the first byte of the ethernet header.
|
||||
*/
|
||||
__le32 offset;
|
||||
/* Size of the pattern. Bitmask must be the same size.*/
|
||||
__le32 size_bytes;
|
||||
/*
|
||||
* Variable length mask and pattern data. mask starts at offset 0.
|
||||
* Pattern immediately follows mask.
|
||||
*/
|
||||
u8 mask_and_pattern[1];
|
||||
};
|
||||
|
||||
/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
|
||||
struct brcmf_pkt_filter_le {
|
||||
__le32 id; /* Unique filter id, specified by app. */
|
||||
__le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
|
||||
__le32 negate_match; /* Negate the result of filter matches */
|
||||
union { /* Filter definitions */
|
||||
struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
|
||||
} u;
|
||||
};
|
||||
|
||||
/* IOVAR "pkt_filter_enable" parameter. */
|
||||
struct brcmf_pkt_filter_enable_le {
|
||||
__le32 id; /* Unique filter id */
|
||||
__le32 enable; /* Enable/disable bool */
|
||||
};
|
||||
|
||||
/* BSS info structure
|
||||
* Applications MUST CHECK ie_offset field and length field to access IEs and
|
||||
* next bss_info structure in a vector (in struct brcmf_scan_results)
|
||||
*/
|
||||
struct brcmf_bss_info_le {
|
||||
__le32 version; /* version field */
|
||||
__le32 length; /* byte length of data in this record,
|
||||
* starting at version and including IEs
|
||||
*/
|
||||
u8 BSSID[ETH_ALEN];
|
||||
__le16 beacon_period; /* units are Kusec */
|
||||
__le16 capability; /* Capability information */
|
||||
u8 SSID_len;
|
||||
u8 SSID[32];
|
||||
struct {
|
||||
__le32 count; /* # rates in this set */
|
||||
u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
|
||||
} rateset; /* supported rates */
|
||||
__le16 chanspec; /* chanspec for bss */
|
||||
__le16 atim_window; /* units are Kusec */
|
||||
u8 dtim_period; /* DTIM period */
|
||||
__le16 RSSI; /* receive signal strength (in dBm) */
|
||||
s8 phy_noise; /* noise (in dBm) */
|
||||
|
||||
u8 n_cap; /* BSS is 802.11N Capable */
|
||||
/* 802.11N BSS Capabilities (based on HT_CAP_*): */
|
||||
__le32 nbss_cap;
|
||||
u8 ctl_ch; /* 802.11N BSS control channel number */
|
||||
__le32 reserved32[1]; /* Reserved for expansion of BSS properties */
|
||||
u8 flags; /* flags */
|
||||
u8 reserved[3]; /* Reserved for expansion of BSS properties */
|
||||
u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
|
||||
|
||||
__le16 ie_offset; /* offset at which IEs start, from beginning */
|
||||
__le32 ie_length; /* byte length of Information Elements */
|
||||
__le16 SNR; /* average SNR of during frame reception */
|
||||
/* Add new fields here */
|
||||
/* variable length Information Elements */
|
||||
};
|
||||
|
||||
struct brcm_rateset_le {
|
||||
/* # rates in this set */
|
||||
__le32 count;
|
||||
/* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 rates[BRCMF_MAXRATES_IN_SET];
|
||||
};
|
||||
|
||||
struct brcmf_ssid {
|
||||
u32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
};
|
||||
|
||||
struct brcmf_ssid_le {
|
||||
__le32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
};
|
||||
|
||||
struct brcmf_scan_params_le {
|
||||
struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
|
||||
u8 bssid[ETH_ALEN]; /* default: bcast */
|
||||
s8 bss_type; /* default: any,
|
||||
* DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
|
||||
*/
|
||||
u8 scan_type; /* flags, 0 use default */
|
||||
__le32 nprobes; /* -1 use default, number of probes per channel */
|
||||
__le32 active_time; /* -1 use default, dwell time per channel for
|
||||
* active scanning
|
||||
*/
|
||||
__le32 passive_time; /* -1 use default, dwell time per channel
|
||||
* for passive scanning
|
||||
*/
|
||||
__le32 home_time; /* -1 use default, dwell time for the
|
||||
* home channel between channel scans
|
||||
*/
|
||||
__le32 channel_num; /* count of channels and ssids that follow
|
||||
*
|
||||
* low half is count of channels in
|
||||
* channel_list, 0 means default (use all
|
||||
* available channels)
|
||||
*
|
||||
* high half is entries in struct brcmf_ssid
|
||||
* array that follows channel_list, aligned for
|
||||
* s32 (4 bytes) meaning an odd channel count
|
||||
* implies a 2-byte pad between end of
|
||||
* channel_list and first ssid
|
||||
*
|
||||
* if ssid count is zero, single ssid in the
|
||||
* fixed parameter portion is assumed, otherwise
|
||||
* ssid in the fixed portion is ignored
|
||||
*/
|
||||
__le16 channel_list[1]; /* list of chanspecs */
|
||||
};
|
||||
|
||||
struct brcmf_scan_results {
|
||||
u32 buflen;
|
||||
u32 version;
|
||||
u32 count;
|
||||
struct brcmf_bss_info_le bss_info_le[];
|
||||
};
|
||||
|
||||
struct brcmf_escan_params_le {
|
||||
__le32 version;
|
||||
__le16 action;
|
||||
__le16 sync_id;
|
||||
struct brcmf_scan_params_le params_le;
|
||||
};
|
||||
|
||||
struct brcmf_escan_result_le {
|
||||
__le32 buflen;
|
||||
__le32 version;
|
||||
__le16 sync_id;
|
||||
__le16 bss_count;
|
||||
struct brcmf_bss_info_le bss_info_le;
|
||||
};
|
||||
|
||||
#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
|
||||
sizeof(struct brcmf_bss_info_le))
|
||||
|
||||
/* used for association with a specific BSSID and chanspec list */
|
||||
struct brcmf_assoc_params_le {
|
||||
/* 00:00:00:00:00:00: broadcast scan */
|
||||
u8 bssid[ETH_ALEN];
|
||||
/* 0: all available channels, otherwise count of chanspecs in
|
||||
* chanspec_list */
|
||||
__le32 chanspec_num;
|
||||
/* list of chanspecs */
|
||||
__le16 chanspec_list[1];
|
||||
};
|
||||
|
||||
/* used for join with or without a specific bssid and channel list */
|
||||
struct brcmf_join_params {
|
||||
struct brcmf_ssid_le ssid_le;
|
||||
struct brcmf_assoc_params_le params_le;
|
||||
};
|
||||
|
||||
/* scan params for extended join */
|
||||
struct brcmf_join_scan_params_le {
|
||||
u8 scan_type; /* 0 use default, active or passive scan */
|
||||
__le32 nprobes; /* -1 use default, nr of probes per channel */
|
||||
__le32 active_time; /* -1 use default, dwell time per channel for
|
||||
* active scanning
|
||||
*/
|
||||
__le32 passive_time; /* -1 use default, dwell time per channel
|
||||
* for passive scanning
|
||||
*/
|
||||
__le32 home_time; /* -1 use default, dwell time for the home
|
||||
* channel between channel scans
|
||||
*/
|
||||
};
|
||||
|
||||
/* extended join params */
|
||||
struct brcmf_ext_join_params_le {
|
||||
struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */
|
||||
struct brcmf_join_scan_params_le scan_le;
|
||||
struct brcmf_assoc_params_le assoc_le;
|
||||
};
|
||||
|
||||
struct brcmf_wsec_key {
|
||||
u32 index; /* key index */
|
||||
u32 len; /* key length */
|
||||
u8 data[WLAN_MAX_KEY_LEN]; /* key data */
|
||||
u32 pad_1[18];
|
||||
u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
|
||||
u32 flags; /* misc flags */
|
||||
u32 pad_2[3];
|
||||
u32 iv_initialized; /* has IV been initialized already? */
|
||||
u32 pad_3;
|
||||
/* Rx IV */
|
||||
struct {
|
||||
u32 hi; /* upper 32 bits of IV */
|
||||
u16 lo; /* lower 16 bits of IV */
|
||||
} rxiv;
|
||||
u32 pad_4[2];
|
||||
u8 ea[ETH_ALEN]; /* per station */
|
||||
};
|
||||
|
||||
/*
|
||||
* dongle requires same struct as above but with fields in little endian order
|
||||
*/
|
||||
struct brcmf_wsec_key_le {
|
||||
__le32 index; /* key index */
|
||||
__le32 len; /* key length */
|
||||
u8 data[WLAN_MAX_KEY_LEN]; /* key data */
|
||||
__le32 pad_1[18];
|
||||
__le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
|
||||
__le32 flags; /* misc flags */
|
||||
__le32 pad_2[3];
|
||||
__le32 iv_initialized; /* has IV been initialized already? */
|
||||
__le32 pad_3;
|
||||
/* Rx IV */
|
||||
struct {
|
||||
__le32 hi; /* upper 32 bits of IV */
|
||||
__le16 lo; /* lower 16 bits of IV */
|
||||
} rxiv;
|
||||
__le32 pad_4[2];
|
||||
u8 ea[ETH_ALEN]; /* per station */
|
||||
};
|
||||
|
||||
/* Used to get specific STA parameters */
|
||||
struct brcmf_scb_val_le {
|
||||
__le32 val;
|
||||
u8 ea[ETH_ALEN];
|
||||
};
|
||||
|
||||
/* channel encoding */
|
||||
struct brcmf_channel_info_le {
|
||||
__le32 hw_channel;
|
||||
__le32 target_channel;
|
||||
__le32 scan_channel;
|
||||
};
|
||||
|
||||
struct brcmf_sta_info_le {
|
||||
__le16 ver; /* version of this struct */
|
||||
__le16 len; /* length in bytes of this structure */
|
||||
__le16 cap; /* sta's advertised capabilities */
|
||||
__le32 flags; /* flags defined below */
|
||||
__le32 idle; /* time since data pkt rx'd from sta */
|
||||
u8 ea[ETH_ALEN]; /* Station address */
|
||||
__le32 count; /* # rates in this set */
|
||||
u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
|
||||
/* w/hi bit set if basic */
|
||||
__le32 in; /* seconds elapsed since associated */
|
||||
__le32 listen_interval_inms; /* Min Listen interval in ms for STA */
|
||||
__le32 tx_pkts; /* # of packets transmitted */
|
||||
__le32 tx_failures; /* # of packets failed */
|
||||
__le32 rx_ucast_pkts; /* # of unicast packets received */
|
||||
__le32 rx_mcast_pkts; /* # of multicast packets received */
|
||||
__le32 tx_rate; /* Rate of last successful tx frame */
|
||||
__le32 rx_rate; /* Rate of last successful rx frame */
|
||||
__le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
|
||||
__le32 rx_decrypt_failures; /* # of packet decrypted failed */
|
||||
};
|
||||
|
||||
struct brcmf_chanspec_list {
|
||||
__le32 count; /* # of entries */
|
||||
__le32 element[1]; /* variable length uint32 list */
|
||||
};
|
||||
|
||||
/*
|
||||
* WLC_E_PROBRESP_MSG
|
||||
* WLC_E_P2P_PROBREQ_MSG
|
||||
* WLC_E_ACTION_FRAME_RX
|
||||
*/
|
||||
struct brcmf_rx_mgmt_data {
|
||||
__be16 version;
|
||||
__be16 chanspec;
|
||||
__be32 rssi;
|
||||
__be32 mactime;
|
||||
__be32 rate;
|
||||
};
|
||||
|
||||
#endif /* FWIL_TYPES_H_ */
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include "dhd.h"
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "fwil.h"
|
||||
@ -36,6 +35,7 @@
|
||||
#include "fwsignal.h"
|
||||
#include "p2p.h"
|
||||
#include "wl_cfg80211.h"
|
||||
#include "proto.h"
|
||||
|
||||
/**
|
||||
* DOC: Firmware Signalling
|
||||
@ -105,6 +105,7 @@ static struct {
|
||||
};
|
||||
#undef BRCMF_FWS_TLV_DEF
|
||||
|
||||
|
||||
static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
|
||||
{
|
||||
int i;
|
||||
@ -122,6 +123,12 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* The PKTTAG tlv has additional bytes when firmware-signalling
|
||||
* mode has REUSESEQ flag set.
|
||||
*/
|
||||
#define BRCMF_FWS_TYPE_SEQ_LEN 2
|
||||
|
||||
/*
|
||||
* flags used to enable tlv signalling from firmware.
|
||||
*/
|
||||
@ -147,8 +154,15 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
|
||||
#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01
|
||||
#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02
|
||||
|
||||
#define BRCMF_FWS_RET_OK_NOSCHEDULE 0
|
||||
#define BRCMF_FWS_RET_OK_SCHEDULE 1
|
||||
#define BRCMF_FWS_RET_OK_NOSCHEDULE 0
|
||||
#define BRCMF_FWS_RET_OK_SCHEDULE 1
|
||||
|
||||
#define BRCMF_FWS_MODE_REUSESEQ_SHIFT 3 /* seq reuse */
|
||||
#define BRCMF_FWS_MODE_SET_REUSESEQ(x, val) ((x) = \
|
||||
((x) & ~(1 << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) | \
|
||||
(((val) & 1) << BRCMF_FWS_MODE_REUSESEQ_SHIFT))
|
||||
#define BRCMF_FWS_MODE_GET_REUSESEQ(x) \
|
||||
(((x) >> BRCMF_FWS_MODE_REUSESEQ_SHIFT) & 1)
|
||||
|
||||
/**
|
||||
* enum brcmf_fws_skb_state - indicates processing state of skb.
|
||||
@ -171,6 +185,7 @@ enum brcmf_fws_skb_state {
|
||||
* @bus_flags: 2 bytes reserved for bus specific parameters
|
||||
* @if_flags: holds interface index and packet related flags.
|
||||
* @htod: host to device packet identifier (used in PKTTAG tlv).
|
||||
* @htod_seq: this 16-bit is original seq number for every suppress packet.
|
||||
* @state: transmit state of the packet.
|
||||
* @mac: descriptor related to destination for this packet.
|
||||
*
|
||||
@ -181,6 +196,7 @@ struct brcmf_skbuff_cb {
|
||||
u16 bus_flags;
|
||||
u16 if_flags;
|
||||
u32 htod;
|
||||
u16 htod_seq;
|
||||
enum brcmf_fws_skb_state state;
|
||||
struct brcmf_fws_mac_descriptor *mac;
|
||||
};
|
||||
@ -257,6 +273,22 @@ struct brcmf_skbuff_cb {
|
||||
BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
|
||||
BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT)
|
||||
|
||||
#define BRCMF_SKB_HTOD_SEQ_FROMFW_MASK 0x2000
|
||||
#define BRCMF_SKB_HTOD_SEQ_FROMFW_SHIFT 13
|
||||
#define BRCMF_SKB_HTOD_SEQ_FROMDRV_MASK 0x1000
|
||||
#define BRCMF_SKB_HTOD_SEQ_FROMDRV_SHIFT 12
|
||||
#define BRCMF_SKB_HTOD_SEQ_NR_MASK 0x0fff
|
||||
#define BRCMF_SKB_HTOD_SEQ_NR_SHIFT 0
|
||||
|
||||
#define brcmf_skb_htod_seq_set_field(skb, field, value) \
|
||||
brcmu_maskset16(&(brcmf_skbcb(skb)->htod_seq), \
|
||||
BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
|
||||
BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT, (value))
|
||||
#define brcmf_skb_htod_seq_get_field(skb, field) \
|
||||
brcmu_maskget16(brcmf_skbcb(skb)->htod_seq, \
|
||||
BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
|
||||
BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT)
|
||||
|
||||
#define BRCMF_FWS_TXSTAT_GENERATION_MASK 0x80000000
|
||||
#define BRCMF_FWS_TXSTAT_GENERATION_SHIFT 31
|
||||
#define BRCMF_FWS_TXSTAT_FLAGS_MASK 0x78000000
|
||||
@ -265,8 +297,8 @@ struct brcmf_skbuff_cb {
|
||||
#define BRCMF_FWS_TXSTAT_FIFO_SHIFT 24
|
||||
#define BRCMF_FWS_TXSTAT_HSLOT_MASK 0x00FFFF00
|
||||
#define BRCMF_FWS_TXSTAT_HSLOT_SHIFT 8
|
||||
#define BRCMF_FWS_TXSTAT_PKTID_MASK 0x00FFFFFF
|
||||
#define BRCMF_FWS_TXSTAT_PKTID_SHIFT 0
|
||||
#define BRCMF_FWS_TXSTAT_FREERUN_MASK 0x000000FF
|
||||
#define BRCMF_FWS_TXSTAT_FREERUN_SHIFT 0
|
||||
|
||||
#define brcmf_txstatus_get_field(txs, field) \
|
||||
brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \
|
||||
@ -443,6 +475,7 @@ struct brcmf_fws_info {
|
||||
unsigned long borrow_defer_timestamp;
|
||||
bool bus_flow_blocked;
|
||||
bool creditmap_received;
|
||||
u8 mode;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -812,13 +845,16 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
|
||||
u16 data_offset = 0;
|
||||
u8 fillers;
|
||||
__le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
|
||||
__le16 pktseq = cpu_to_le16(brcmf_skbcb(skb)->htod_seq);
|
||||
|
||||
brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n",
|
||||
brcmf_dbg(TRACE, "enter: %s, idx=%d hslot=%d htod %X seq %X\n",
|
||||
entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
|
||||
le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff);
|
||||
(le32_to_cpu(pkttag) >> 8) & 0xffff,
|
||||
brcmf_skbcb(skb)->htod, brcmf_skbcb(skb)->htod_seq);
|
||||
if (entry->send_tim_signal)
|
||||
data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
|
||||
|
||||
if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
|
||||
data_offset += BRCMF_FWS_TYPE_SEQ_LEN;
|
||||
/* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
|
||||
data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
|
||||
fillers = round_up(data_offset, 4) - data_offset;
|
||||
@ -830,7 +866,12 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
|
||||
wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
|
||||
wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
|
||||
memcpy(&wlh[2], &pkttag, sizeof(pkttag));
|
||||
wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2;
|
||||
if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
|
||||
wlh[1] += BRCMF_FWS_TYPE_SEQ_LEN;
|
||||
memcpy(&wlh[2 + BRCMF_FWS_TYPE_PKTTAG_LEN], &pktseq,
|
||||
sizeof(pktseq));
|
||||
}
|
||||
wlh += wlh[1] + 2;
|
||||
|
||||
if (entry->send_tim_signal) {
|
||||
entry->send_tim_signal = 0;
|
||||
@ -875,6 +916,7 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
|
||||
/* create a dummy packet and sent that. The traffic */
|
||||
/* bitmap info will automatically be attached to that packet */
|
||||
len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 +
|
||||
BRCMF_FWS_TYPE_SEQ_LEN +
|
||||
BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 +
|
||||
4 + fws->drvr->hdrlen;
|
||||
skb = brcmu_pkt_buf_get_skb(len);
|
||||
@ -884,6 +926,8 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
|
||||
skcb = brcmf_skbcb(skb);
|
||||
skcb->mac = entry;
|
||||
skcb->state = BRCMF_FWS_SKBSTATE_TIM;
|
||||
skcb->htod = 0;
|
||||
skcb->htod_seq = 0;
|
||||
bus = fws->drvr->bus_if;
|
||||
err = brcmf_fws_hdrpush(fws, skb);
|
||||
if (err == 0) {
|
||||
@ -1172,8 +1216,13 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
|
||||
{
|
||||
int prec = 2 * fifo;
|
||||
u32 *qfull_stat = &fws->stats.delayq_full_error;
|
||||
|
||||
struct brcmf_fws_mac_descriptor *entry;
|
||||
struct pktq *pq;
|
||||
struct sk_buff_head *queue;
|
||||
struct sk_buff *p_head;
|
||||
struct sk_buff *p_tail;
|
||||
u32 fr_new;
|
||||
u32 fr_compare;
|
||||
|
||||
entry = brcmf_skbcb(p)->mac;
|
||||
if (entry == NULL) {
|
||||
@ -1185,9 +1234,55 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
|
||||
if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
|
||||
prec += 1;
|
||||
qfull_stat = &fws->stats.supprq_full_error;
|
||||
}
|
||||
|
||||
if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
|
||||
/* Fix out of order delivery of frames. Dont assume frame */
|
||||
/* can be inserted at the end, but look for correct position */
|
||||
pq = &entry->psq;
|
||||
if (pktq_full(pq) || pktq_pfull(pq, prec)) {
|
||||
*qfull_stat += 1;
|
||||
return -ENFILE;
|
||||
}
|
||||
queue = &pq->q[prec].skblist;
|
||||
|
||||
p_head = skb_peek(queue);
|
||||
p_tail = skb_peek_tail(queue);
|
||||
fr_new = brcmf_skb_htod_tag_get_field(p, FREERUN);
|
||||
|
||||
while (p_head != p_tail) {
|
||||
fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
|
||||
FREERUN);
|
||||
/* be sure to handle wrap of 256 */
|
||||
if (((fr_new > fr_compare) &&
|
||||
((fr_new - fr_compare) < 128)) ||
|
||||
((fr_new < fr_compare) &&
|
||||
((fr_compare - fr_new) > 128)))
|
||||
break;
|
||||
p_tail = skb_queue_prev(queue, p_tail);
|
||||
}
|
||||
/* Position found. Determine what to do */
|
||||
if (p_tail == NULL) {
|
||||
/* empty list */
|
||||
__skb_queue_tail(queue, p);
|
||||
} else {
|
||||
fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
|
||||
FREERUN);
|
||||
if (((fr_new > fr_compare) &&
|
||||
((fr_new - fr_compare) < 128)) ||
|
||||
((fr_new < fr_compare) &&
|
||||
((fr_compare - fr_new) > 128))) {
|
||||
/* After tail */
|
||||
__skb_queue_after(queue, p_tail, p);
|
||||
} else {
|
||||
/* Before tail */
|
||||
__skb_insert(p, p_tail->prev, p_tail, queue);
|
||||
}
|
||||
}
|
||||
|
||||
/* Complete the counters and statistics */
|
||||
pq->len++;
|
||||
if (pq->hi_prec < prec)
|
||||
pq->hi_prec = (u8) prec;
|
||||
} else if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
|
||||
*qfull_stat += 1;
|
||||
return -ENFILE;
|
||||
}
|
||||
@ -1277,7 +1372,8 @@ static struct sk_buff *brcmf_fws_deq(struct brcmf_fws_info *fws, int fifo)
|
||||
}
|
||||
|
||||
static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
|
||||
struct sk_buff *skb, u32 genbit)
|
||||
struct sk_buff *skb, u32 genbit,
|
||||
u16 seq)
|
||||
{
|
||||
struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
|
||||
u32 hslot;
|
||||
@ -1298,6 +1394,14 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
|
||||
|
||||
ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
|
||||
if (ret == 0)
|
||||
brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
|
||||
brcmf_skbcb(skb)->htod_seq = seq;
|
||||
if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
|
||||
brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
|
||||
brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
|
||||
} else {
|
||||
brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
|
||||
}
|
||||
ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
|
||||
skb);
|
||||
if (ret != 0) {
|
||||
@ -1317,7 +1421,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
|
||||
|
||||
static int
|
||||
brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
|
||||
u32 genbit)
|
||||
u32 genbit, u16 seq)
|
||||
{
|
||||
u32 fifo;
|
||||
int ret;
|
||||
@ -1360,8 +1464,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
|
||||
if (entry->suppressed && entry->suppr_transit_count)
|
||||
entry->suppr_transit_count--;
|
||||
|
||||
brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
|
||||
skcb->htod);
|
||||
brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
|
||||
skcb->htod, seq);
|
||||
|
||||
/* pick up the implicit credit from this packet */
|
||||
fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
|
||||
@ -1374,7 +1478,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
|
||||
brcmf_fws_macdesc_return_req_credit(skb);
|
||||
|
||||
if (!remove_from_hanger)
|
||||
ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit);
|
||||
ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
|
||||
seq);
|
||||
|
||||
if (remove_from_hanger || ret)
|
||||
brcmf_txfinalize(fws->drvr, skb, true);
|
||||
@ -1406,10 +1511,12 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
|
||||
static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
|
||||
{
|
||||
__le32 status_le;
|
||||
__le16 seq_le;
|
||||
u32 status;
|
||||
u32 hslot;
|
||||
u32 genbit;
|
||||
u8 flags;
|
||||
u16 seq;
|
||||
|
||||
fws->stats.txs_indicate++;
|
||||
memcpy(&status_le, data, sizeof(status_le));
|
||||
@ -1417,9 +1524,16 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
|
||||
flags = brcmf_txstatus_get_field(status, FLAGS);
|
||||
hslot = brcmf_txstatus_get_field(status, HSLOT);
|
||||
genbit = brcmf_txstatus_get_field(status, GENERATION);
|
||||
if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
|
||||
memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
|
||||
sizeof(seq_le));
|
||||
seq = le16_to_cpu(seq_le);
|
||||
} else {
|
||||
seq = 0;
|
||||
}
|
||||
|
||||
brcmf_fws_lock(fws);
|
||||
brcmf_fws_txs_process(fws, flags, hslot, genbit);
|
||||
brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
|
||||
brcmf_fws_unlock(fws);
|
||||
return BRCMF_FWS_RET_OK_NOSCHEDULE;
|
||||
}
|
||||
@ -1610,8 +1724,8 @@ static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
|
||||
struct brcmf_fws_mac_descriptor *entry = skcb->mac;
|
||||
u8 flags;
|
||||
|
||||
brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
|
||||
brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
|
||||
if (skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED)
|
||||
brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
|
||||
flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
|
||||
if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
|
||||
/*
|
||||
@ -1652,7 +1766,7 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
|
||||
fws->stats.rollback_failed++;
|
||||
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
|
||||
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
|
||||
hslot, 0);
|
||||
hslot, 0, 0);
|
||||
} else {
|
||||
fws->stats.rollback_success++;
|
||||
brcmf_fws_return_credits(fws, fifo, 1);
|
||||
@ -1732,6 +1846,8 @@ static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
|
||||
struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
|
||||
int rc, hslot;
|
||||
|
||||
skcb->htod = 0;
|
||||
skcb->htod_seq = 0;
|
||||
hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
|
||||
brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
|
||||
brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
|
||||
@ -1908,6 +2024,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
|
||||
struct brcmf_fws_info *fws;
|
||||
u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
|
||||
int rc;
|
||||
u32 mode;
|
||||
|
||||
drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL);
|
||||
if (!drvr->fws) {
|
||||
@ -1966,6 +2083,18 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
|
||||
if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1))
|
||||
brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n");
|
||||
|
||||
/* Enable seq number reuse, if supported */
|
||||
if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) {
|
||||
if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) {
|
||||
mode = 0;
|
||||
BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1);
|
||||
if (brcmf_fil_iovar_int_set(drvr->iflist[0],
|
||||
"wlfc_mode", mode) == 0) {
|
||||
BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
brcmf_fws_hanger_init(&fws->hanger);
|
||||
brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0);
|
||||
brcmf_fws_macdesc_set_name(fws, &fws->desc.other);
|
||||
@ -2022,7 +2151,7 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
|
||||
}
|
||||
brcmf_fws_lock(fws);
|
||||
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
|
||||
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0);
|
||||
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
|
||||
brcmf_fws_unlock(fws);
|
||||
}
|
||||
|
||||
|
@ -812,7 +812,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
|
||||
struct ieee80211_channel *chan = request->channels[i];
|
||||
|
||||
if (chan->flags & (IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN))
|
||||
IEEE80211_CHAN_NO_IR))
|
||||
continue;
|
||||
|
||||
chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf,
|
||||
|
62
drivers/net/wireless/brcm80211/brcmfmac/proto.c
Normal file
62
drivers/net/wireless/brcm80211/brcmfmac/proto.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Broadcom Corporation
|
||||
*
|
||||
* 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 <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/netdevice.h>
|
||||
|
||||
#include <brcmu_wifi.h>
|
||||
#include "dhd.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "proto.h"
|
||||
#include "bcdc.h"
|
||||
|
||||
|
||||
int brcmf_proto_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_proto *proto;
|
||||
|
||||
proto = kzalloc(sizeof(*proto), GFP_ATOMIC);
|
||||
if (!proto)
|
||||
goto fail;
|
||||
|
||||
drvr->proto = proto;
|
||||
/* BCDC protocol is only protocol supported for the moment */
|
||||
if (brcmf_proto_bcdc_attach(drvr))
|
||||
goto fail;
|
||||
|
||||
if ((proto->hdrpush == NULL) || (proto->hdrpull == NULL) ||
|
||||
(proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) {
|
||||
brcmf_err("Not all proto handlers have been installed\n");
|
||||
goto fail;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
kfree(proto);
|
||||
drvr->proto = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void brcmf_proto_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
if (drvr->proto) {
|
||||
brcmf_proto_bcdc_detach(drvr);
|
||||
kfree(drvr->proto);
|
||||
drvr->proto = NULL;
|
||||
}
|
||||
}
|
57
drivers/net/wireless/brcm80211/brcmfmac/proto.h
Normal file
57
drivers/net/wireless/brcm80211/brcmfmac/proto.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef BRCMFMAC_PROTO_H
|
||||
#define BRCMFMAC_PROTO_H
|
||||
|
||||
struct brcmf_proto {
|
||||
void (*hdrpush)(struct brcmf_pub *drvr, int ifidx, u8 offset,
|
||||
struct sk_buff *skb);
|
||||
int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
|
||||
struct sk_buff *skb);
|
||||
int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len);
|
||||
int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
|
||||
uint len);
|
||||
void *pd;
|
||||
};
|
||||
|
||||
|
||||
int brcmf_proto_attach(struct brcmf_pub *drvr);
|
||||
void brcmf_proto_detach(struct brcmf_pub *drvr);
|
||||
|
||||
static inline void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
|
||||
u8 offset, struct sk_buff *skb)
|
||||
{
|
||||
drvr->proto->hdrpush(drvr, ifidx, offset, skb);
|
||||
}
|
||||
static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
|
||||
u8 *ifidx, struct sk_buff *skb)
|
||||
{
|
||||
return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb);
|
||||
}
|
||||
static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
uint cmd, void *buf, uint len)
|
||||
{
|
||||
return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len);
|
||||
}
|
||||
static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
uint cmd, void *buf, uint len)
|
||||
{
|
||||
return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
|
||||
}
|
||||
|
||||
|
||||
#endif /* BRCMFMAC_PROTO_H */
|
@ -89,7 +89,7 @@ TRACE_EVENT(brcmf_hexdump,
|
||||
TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len)
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcmf_bdchdr,
|
||||
TRACE_EVENT(brcmf_bcdchdr,
|
||||
TP_PROTO(void *data),
|
||||
TP_ARGS(data),
|
||||
TP_STRUCT__entry(
|
||||
@ -107,24 +107,35 @@ TRACE_EVENT(brcmf_bdchdr,
|
||||
memcpy(__get_dynamic_array(signal),
|
||||
(u8 *)data + 4, __entry->siglen);
|
||||
),
|
||||
TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen)
|
||||
TP_printk("bcdc: prio=%d siglen=%d", __entry->prio, __entry->siglen)
|
||||
);
|
||||
|
||||
#ifndef SDPCM_RX
|
||||
#define SDPCM_RX 0
|
||||
#endif
|
||||
#ifndef SDPCM_TX
|
||||
#define SDPCM_TX 1
|
||||
#endif
|
||||
#ifndef SDPCM_GLOM
|
||||
#define SDPCM_GLOM 2
|
||||
#endif
|
||||
|
||||
TRACE_EVENT(brcmf_sdpcm_hdr,
|
||||
TP_PROTO(bool tx, void *data),
|
||||
TP_ARGS(tx, data),
|
||||
TP_PROTO(u8 dir, void *data),
|
||||
TP_ARGS(dir, data),
|
||||
TP_STRUCT__entry(
|
||||
__field(u8, tx)
|
||||
__field(u8, dir)
|
||||
__field(u16, len)
|
||||
__array(u8, hdr, 12)
|
||||
__dynamic_array(u8, hdr, dir == SDPCM_GLOM ? 20 : 12)
|
||||
),
|
||||
TP_fast_assign(
|
||||
memcpy(__entry->hdr, data, 12);
|
||||
__entry->len = __entry->hdr[0] | (__entry->hdr[1] << 8);
|
||||
__entry->tx = tx ? 1 : 0;
|
||||
memcpy(__get_dynamic_array(hdr), data, dir == SDPCM_GLOM ? 20 : 12);
|
||||
__entry->len = *(u8 *)data | (*((u8 *)data + 1) << 8);
|
||||
__entry->dir = dir;
|
||||
),
|
||||
TP_printk("sdpcm: %s len %u, seq %d", __entry->tx ? "TX" : "RX",
|
||||
__entry->len, __entry->hdr[4])
|
||||
TP_printk("sdpcm: %s len %u, seq %d",
|
||||
__entry->dir == SDPCM_RX ? "RX" : "TX",
|
||||
__entry->len, ((u8 *)__get_dynamic_array(hdr))[4])
|
||||
);
|
||||
|
||||
#ifdef CONFIG_BRCM_TRACING
|
||||
|
@ -1255,7 +1255,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
|
||||
bus->chiprev = bus_pub->chiprev;
|
||||
|
||||
/* Attach to the common driver interface */
|
||||
ret = brcmf_attach(0, dev);
|
||||
ret = brcmf_attach(dev);
|
||||
if (ret) {
|
||||
brcmf_err("brcmf_attach failed\n");
|
||||
goto fail;
|
||||
@ -1454,7 +1454,7 @@ static int brcmf_usb_resume(struct usb_interface *intf)
|
||||
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
|
||||
|
||||
brcmf_dbg(USB, "Enter\n");
|
||||
if (!brcmf_attach(0, devinfo->dev))
|
||||
if (!brcmf_attach(devinfo->dev))
|
||||
return brcmf_bus_start(&usb->dev);
|
||||
|
||||
return 0;
|
||||
|
@ -202,9 +202,9 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = {
|
||||
|
||||
/* This is to override regulatory domains defined in cfg80211 module (reg.c)
|
||||
* By default world regulatory domain defined in reg.c puts the flags
|
||||
* NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for
|
||||
* 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't
|
||||
* start p2p operations on 5GHz channels. All the changes in world regulatory
|
||||
* NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
|
||||
* With respect to these flags, wpa_supplicant doesn't * start p2p
|
||||
* operations on 5GHz channels. All the changes in world regulatory
|
||||
* domain are to be done here.
|
||||
*/
|
||||
static const struct ieee80211_regdomain brcmf_regdom = {
|
||||
@ -2556,8 +2556,8 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
|
||||
ch_bss.band == ch_bss_info_le.band &&
|
||||
bss_info_le->SSID_len == bss->SSID_len &&
|
||||
!memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
|
||||
if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
|
||||
(bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
|
||||
if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
|
||||
(bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
|
||||
s16 bss_rssi = le16_to_cpu(bss->RSSI);
|
||||
s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
|
||||
|
||||
@ -2566,13 +2566,13 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
|
||||
*/
|
||||
if (bss_info_rssi > bss_rssi)
|
||||
bss->RSSI = bss_info_le->RSSI;
|
||||
} else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
|
||||
(bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
|
||||
} else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
|
||||
(bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
|
||||
/* preserve the on-channel rssi measurement
|
||||
* if the new measurement is off channel
|
||||
*/
|
||||
bss->RSSI = bss_info_le->RSSI;
|
||||
bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
|
||||
bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -3973,11 +3973,12 @@ brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
|
||||
|
||||
static int
|
||||
brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
unsigned int wait, const u8 *buf, size_t len,
|
||||
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
|
||||
struct cfg80211_mgmt_tx_params *params, u64 *cookie)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct ieee80211_channel *chan = params->chan;
|
||||
const u8 *buf = params->buf;
|
||||
size_t len = params->len;
|
||||
const struct ieee80211_mgmt *mgmt;
|
||||
struct brcmf_cfg80211_vif *vif;
|
||||
s32 err = 0;
|
||||
@ -4341,7 +4342,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
|
||||
wiphy->max_remain_on_channel_duration = 5000;
|
||||
brcmf_wiphy_pno_params(wiphy);
|
||||
brcmf_dbg(INFO, "Registering custom regulatory\n");
|
||||
wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
|
||||
wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
|
||||
err = wiphy_register(wiphy);
|
||||
if (err < 0) {
|
||||
@ -5197,10 +5198,10 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
|
||||
if (channel & WL_CHAN_RADAR)
|
||||
band_chan_arr[index].flags |=
|
||||
(IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IBSS);
|
||||
IEEE80211_CHAN_NO_IR);
|
||||
if (channel & WL_CHAN_PASSIVE)
|
||||
band_chan_arr[index].flags |=
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
if (!update)
|
||||
|
@ -59,23 +59,18 @@
|
||||
|
||||
#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
|
||||
#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_DFS | \
|
||||
NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_DFS | \
|
||||
NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
static const struct ieee80211_regdomain brcms_regdom_x2 = {
|
||||
.n_reg_rules = 6,
|
||||
@ -395,7 +390,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
|
||||
brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
|
||||
|
||||
brcms_b_set_chanspec(wlc->hw, chanspec,
|
||||
!!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN),
|
||||
!!(ch->flags & IEEE80211_CHAN_NO_IR),
|
||||
&txpwr);
|
||||
}
|
||||
|
||||
@ -657,8 +652,8 @@ static void brcms_reg_apply_radar_flags(struct wiphy *wiphy)
|
||||
*/
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
|
||||
ch->flags |= IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
IEEE80211_CHAN_NO_IR |
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,18 +679,15 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
continue;
|
||||
|
||||
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
rule = freq_reg_info(wiphy, ch->center_freq);
|
||||
rule = freq_reg_info(wiphy,
|
||||
MHZ_TO_KHZ(ch->center_freq));
|
||||
if (IS_ERR(rule))
|
||||
continue;
|
||||
|
||||
if (!(rule->flags & NL80211_RRF_NO_IBSS))
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
|
||||
if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
ch->flags &=
|
||||
~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
if (!(rule->flags & NL80211_RRF_NO_IR))
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
} else if (ch->beacon_found) {
|
||||
ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN);
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -775,8 +767,8 @@ void brcms_c_regd_init(struct brcms_c_info *wlc)
|
||||
}
|
||||
|
||||
wlc->wiphy->reg_notifier = brcms_reg_notifier;
|
||||
wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
|
||||
WIPHY_FLAG_STRICT_REGULATORY;
|
||||
wlc->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
|
||||
REGULATORY_STRICT_REG;
|
||||
wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain);
|
||||
brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER);
|
||||
}
|
||||
|
@ -125,13 +125,13 @@ static struct ieee80211_channel brcms_2ghz_chantable[] = {
|
||||
CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN2GHZ(12, 2467,
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_NO_IR |
|
||||
IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN2GHZ(13, 2472,
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_NO_IR |
|
||||
IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN2GHZ(14, 2484,
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_NO_IR |
|
||||
IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS |
|
||||
IEEE80211_CHAN_NO_OFDM)
|
||||
};
|
||||
@ -144,51 +144,51 @@ static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
|
||||
CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
|
||||
/* UNII-2 */
|
||||
CHAN5GHZ(52,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
CHAN5GHZ(56,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN5GHZ(60,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
CHAN5GHZ(64,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
/* MID */
|
||||
CHAN5GHZ(100,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
CHAN5GHZ(104,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN5GHZ(108,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
CHAN5GHZ(112,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN5GHZ(116,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
CHAN5GHZ(120,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN5GHZ(124,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
CHAN5GHZ(128,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN5GHZ(132,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
|
||||
CHAN5GHZ(136,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
|
||||
CHAN5GHZ(140,
|
||||
IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
|
||||
IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS |
|
||||
IEEE80211_CHAN_NO_HT40MINUS),
|
||||
/* UNII-3 */
|
||||
CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
|
||||
|
@ -108,9 +108,9 @@ static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
|
||||
struct hwbus_priv *self = dev_id;
|
||||
|
||||
if (self->core) {
|
||||
sdio_claim_host(self->func);
|
||||
cw1200_sdio_lock(self);
|
||||
cw1200_irq_handler(self->core);
|
||||
sdio_release_host(self->func);
|
||||
cw1200_sdio_unlock(self);
|
||||
return IRQ_HANDLED;
|
||||
} else {
|
||||
return IRQ_NONE;
|
||||
|
@ -173,8 +173,9 @@ void cw1200_scan_work(struct work_struct *work)
|
||||
cw1200_set_pm(priv, &priv->powersave_mode);
|
||||
|
||||
if (priv->scan.status < 0)
|
||||
wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n",
|
||||
priv->scan.status);
|
||||
wiphy_warn(priv->hw->wiphy,
|
||||
"[SCAN] Scan failed (%d).\n",
|
||||
priv->scan.status);
|
||||
else if (priv->scan.req)
|
||||
wiphy_dbg(priv->hw->wiphy,
|
||||
"[SCAN] Scan completed.\n");
|
||||
@ -197,9 +198,9 @@ void cw1200_scan_work(struct work_struct *work)
|
||||
if ((*it)->band != first->band)
|
||||
break;
|
||||
if (((*it)->flags ^ first->flags) &
|
||||
IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
IEEE80211_CHAN_NO_IR)
|
||||
break;
|
||||
if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
|
||||
if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
|
||||
(*it)->max_power != first->max_power)
|
||||
break;
|
||||
}
|
||||
@ -210,7 +211,7 @@ void cw1200_scan_work(struct work_struct *work)
|
||||
else
|
||||
scan.max_tx_rate = WSM_TRANSMIT_RATE_1;
|
||||
scan.num_probes =
|
||||
(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2;
|
||||
(first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2;
|
||||
scan.num_ssids = priv->scan.n_ssids;
|
||||
scan.ssids = &priv->scan.ssids[0];
|
||||
scan.num_channels = it - priv->scan.curr;
|
||||
@ -233,7 +234,7 @@ void cw1200_scan_work(struct work_struct *work)
|
||||
}
|
||||
for (i = 0; i < scan.num_channels; ++i) {
|
||||
scan.ch[i].number = priv->scan.curr[i]->hw_value;
|
||||
if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
|
||||
if (priv->scan.curr[i]->flags & IEEE80211_CHAN_NO_IR) {
|
||||
scan.ch[i].min_chan_time = 50;
|
||||
scan.ch[i].max_chan_time = 100;
|
||||
} else {
|
||||
@ -241,7 +242,7 @@ void cw1200_scan_work(struct work_struct *work)
|
||||
scan.ch[i].max_chan_time = 25;
|
||||
}
|
||||
}
|
||||
if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
|
||||
if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
|
||||
priv->scan.output_power != first->max_power) {
|
||||
priv->scan.output_power = first->max_power;
|
||||
wsm_set_output_power(priv,
|
||||
|
@ -1930,10 +1930,10 @@ static int ipw2100_wdev_init(struct net_device *dev)
|
||||
bg_band->channels[i].max_power = geo->bg[i].max_power;
|
||||
if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
|
||||
bg_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
|
||||
bg_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_NO_IBSS;
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
|
||||
bg_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_RADAR;
|
||||
@ -6362,7 +6362,6 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
|
||||
&ipw2100_attribute_group);
|
||||
|
||||
free_libipw(dev, 0);
|
||||
pci_set_drvdata(pci_dev, NULL);
|
||||
}
|
||||
|
||||
pci_iounmap(pci_dev, ioaddr);
|
||||
|
@ -11472,10 +11472,10 @@ static int ipw_wdev_init(struct net_device *dev)
|
||||
bg_band->channels[i].max_power = geo->bg[i].max_power;
|
||||
if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
|
||||
bg_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
|
||||
bg_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_NO_IBSS;
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
|
||||
bg_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_RADAR;
|
||||
@ -11511,10 +11511,10 @@ static int ipw_wdev_init(struct net_device *dev)
|
||||
a_band->channels[i].max_power = geo->a[i].max_power;
|
||||
if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
|
||||
a_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
|
||||
a_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_NO_IBSS;
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
|
||||
a_band->channels[i].flags |=
|
||||
IEEE80211_CHAN_RADAR;
|
||||
|
@ -1595,7 +1595,7 @@ il3945_get_channels_for_scan(struct il_priv *il, enum ieee80211_band band,
|
||||
* and use long active_dwell time.
|
||||
*/
|
||||
if (!is_active || il_is_channel_passive(ch_info) ||
|
||||
(chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
|
||||
(chan->flags & IEEE80211_CHAN_NO_IR)) {
|
||||
scan_ch->type = 0; /* passive */
|
||||
if (IL_UCODE_API(il->ucode_ver) == 1)
|
||||
scan_ch->active_dwell =
|
||||
@ -2396,8 +2396,7 @@ __il3945_up(struct il_priv *il)
|
||||
clear_bit(S_RFKILL, &il->status);
|
||||
else {
|
||||
set_bit(S_RFKILL, &il->status);
|
||||
IL_WARN("Radio disabled by HW RF Kill switch\n");
|
||||
return -ENODEV;
|
||||
return -ERFKILL;
|
||||
}
|
||||
|
||||
_il_wr(il, CSR_INT, 0xFFFFFFFF);
|
||||
@ -3575,9 +3574,9 @@ il3945_setup_mac(struct il_priv *il)
|
||||
hw->wiphy->interface_modes =
|
||||
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
hw->wiphy->flags |=
|
||||
WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS |
|
||||
WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
|
||||
REGULATORY_DISABLE_BEACON_HINTS;
|
||||
|
||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
|
||||
|
@ -805,7 +805,7 @@ il4965_get_channels_for_scan(struct il_priv *il, struct ieee80211_vif *vif,
|
||||
}
|
||||
|
||||
if (!is_active || il_is_channel_passive(ch_info) ||
|
||||
(chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
|
||||
(chan->flags & IEEE80211_CHAN_NO_IR))
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
else
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
|
||||
@ -5778,9 +5778,9 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
|
||||
hw->wiphy->interface_modes =
|
||||
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
hw->wiphy->flags |=
|
||||
WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS |
|
||||
WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
|
||||
REGULATORY_DISABLE_BEACON_HINTS;
|
||||
|
||||
/*
|
||||
* For now, disable PS by default because it affects
|
||||
|
@ -3445,10 +3445,10 @@ il_init_geos(struct il_priv *il)
|
||||
|
||||
if (il_is_channel_valid(ch)) {
|
||||
if (!(ch->flags & EEPROM_CHANNEL_IBSS))
|
||||
geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
|
||||
geo_ch->flags |= IEEE80211_CHAN_NO_IR;
|
||||
|
||||
if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
|
||||
geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
geo_ch->flags |= IEEE80211_CHAN_NO_IR;
|
||||
|
||||
if (ch->flags & EEPROM_CHANNEL_RADAR)
|
||||
geo_ch->flags |= IEEE80211_CHAN_RADAR;
|
||||
|
@ -567,12 +567,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
|
||||
flags & IEEE80211_CHAN_RADAR ?
|
||||
" (IEEE 802.11h required)" : "",
|
||||
((channels[i].
|
||||
flags & IEEE80211_CHAN_NO_IBSS) ||
|
||||
flags & IEEE80211_CHAN_NO_IR) ||
|
||||
(channels[i].
|
||||
flags & IEEE80211_CHAN_RADAR)) ? "" :
|
||||
", IBSS",
|
||||
channels[i].
|
||||
flags & IEEE80211_CHAN_PASSIVE_SCAN ?
|
||||
flags & IEEE80211_CHAN_NO_IR ?
|
||||
"passive only" : "active/passive");
|
||||
}
|
||||
supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
|
||||
@ -594,12 +594,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
|
||||
flags & IEEE80211_CHAN_RADAR ?
|
||||
" (IEEE 802.11h required)" : "",
|
||||
((channels[i].
|
||||
flags & IEEE80211_CHAN_NO_IBSS) ||
|
||||
flags & IEEE80211_CHAN_NO_IR) ||
|
||||
(channels[i].
|
||||
flags & IEEE80211_CHAN_RADAR)) ? "" :
|
||||
", IBSS",
|
||||
channels[i].
|
||||
flags & IEEE80211_CHAN_PASSIVE_SCAN ?
|
||||
flags & IEEE80211_CHAN_NO_IR ?
|
||||
"passive only" : "active/passive");
|
||||
}
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
|
@ -352,12 +352,12 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
|
||||
channels[i].max_power,
|
||||
channels[i].flags & IEEE80211_CHAN_RADAR ?
|
||||
" (IEEE 802.11h required)" : "",
|
||||
((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
|
||||
((channels[i].flags & IEEE80211_CHAN_NO_IR)
|
||||
|| (channels[i].flags &
|
||||
IEEE80211_CHAN_RADAR)) ? "" :
|
||||
", IBSS",
|
||||
channels[i].flags &
|
||||
IEEE80211_CHAN_PASSIVE_SCAN ?
|
||||
IEEE80211_CHAN_NO_IR ?
|
||||
"passive only" : "active/passive");
|
||||
}
|
||||
supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
|
||||
@ -375,12 +375,12 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
|
||||
channels[i].max_power,
|
||||
channels[i].flags & IEEE80211_CHAN_RADAR ?
|
||||
" (IEEE 802.11h required)" : "",
|
||||
((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
|
||||
((channels[i].flags & IEEE80211_CHAN_NO_IR)
|
||||
|| (channels[i].flags &
|
||||
IEEE80211_CHAN_RADAR)) ? "" :
|
||||
", IBSS",
|
||||
channels[i].flags &
|
||||
IEEE80211_CHAN_PASSIVE_SCAN ?
|
||||
IEEE80211_CHAN_NO_IR ?
|
||||
"passive only" : "active/passive");
|
||||
}
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
|
@ -155,9 +155,9 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||
ARRAY_SIZE(iwlagn_iface_combinations_dualmode);
|
||||
}
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
|
||||
WIPHY_FLAG_DISABLE_BEACON_HINTS |
|
||||
WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
|
||||
REGULATORY_DISABLE_BEACON_HINTS;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
|
||||
|
@ -544,7 +544,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
|
||||
channel = chan->hw_value;
|
||||
scan_ch->channel = cpu_to_le16(channel);
|
||||
|
||||
if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
|
||||
if (!is_active || (chan->flags & IEEE80211_CHAN_NO_IR))
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
|
||||
else
|
||||
scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
|
||||
|
@ -614,10 +614,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
channel->flags = IEEE80211_CHAN_NO_HT40;
|
||||
|
||||
if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS))
|
||||
channel->flags |= IEEE80211_CHAN_NO_IBSS;
|
||||
channel->flags |= IEEE80211_CHAN_NO_IR;
|
||||
|
||||
if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE))
|
||||
channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
channel->flags |= IEEE80211_CHAN_NO_IR;
|
||||
|
||||
if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR)
|
||||
channel->flags |= IEEE80211_CHAN_RADAR;
|
||||
|
@ -223,10 +223,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
channel->flags |= IEEE80211_CHAN_NO_160MHZ;
|
||||
|
||||
if (!(ch_flags & NVM_CHANNEL_IBSS))
|
||||
channel->flags |= IEEE80211_CHAN_NO_IBSS;
|
||||
channel->flags |= IEEE80211_CHAN_NO_IR;
|
||||
|
||||
if (!(ch_flags & NVM_CHANNEL_ACTIVE))
|
||||
channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
channel->flags |= IEEE80211_CHAN_NO_IR;
|
||||
|
||||
if (ch_flags & NVM_CHANNEL_RADAR)
|
||||
channel->flags |= IEEE80211_CHAN_RADAR;
|
||||
|
@ -199,9 +199,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
|
||||
hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
|
||||
WIPHY_FLAG_DISABLE_BEACON_HINTS |
|
||||
WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
|
||||
hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
|
||||
REGULATORY_DISABLE_BEACON_HINTS;
|
||||
|
||||
hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
|
||||
hw->wiphy->n_iface_combinations =
|
||||
|
@ -192,7 +192,7 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
|
||||
for (i = 0; i < cmd->channel_count; i++) {
|
||||
chan->channel = cpu_to_le16(req->channels[i]->hw_value);
|
||||
chan->type = cpu_to_le32(type);
|
||||
if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
|
||||
chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
|
||||
chan->active_dwell = cpu_to_le16(active_dwell);
|
||||
chan->passive_dwell = cpu_to_le16(passive_dwell);
|
||||
@ -642,7 +642,7 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
|
||||
channels->iter_count[index] = cpu_to_le16(1);
|
||||
channels->iter_interval[index] = 0;
|
||||
|
||||
if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN))
|
||||
if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR))
|
||||
channels->type[index] |=
|
||||
cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
|
||||
|
||||
|
@ -849,7 +849,7 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
|
||||
card->started = true;
|
||||
/* Tell PM core that we don't need the card to be
|
||||
* powered now */
|
||||
pm_runtime_put_noidle(&func->dev);
|
||||
pm_runtime_put(&func->dev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -907,8 +907,8 @@ static int if_sdio_power_on(struct if_sdio_card *card)
|
||||
sdio_release_host(func);
|
||||
ret = if_sdio_prog_firmware(card);
|
||||
if (ret) {
|
||||
sdio_disable_func(func);
|
||||
return ret;
|
||||
sdio_claim_host(func);
|
||||
goto disable;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -93,7 +93,6 @@ static void free_if_spi_card(struct if_spi_card *card)
|
||||
list_del(&packet->list);
|
||||
kfree(packet);
|
||||
}
|
||||
spi_set_drvdata(card->spi, NULL);
|
||||
kfree(card);
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
|
||||
.reg_rules = {
|
||||
REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
|
||||
REG_RULE(5725-10, 5850+10, 40, 0, 30,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
|
||||
NL80211_RRF_NO_IR),
|
||||
}
|
||||
};
|
||||
|
||||
@ -353,7 +353,6 @@ struct mac80211_hwsim_data {
|
||||
} ps;
|
||||
bool ps_poll_pending;
|
||||
struct dentry *debugfs;
|
||||
struct dentry *debugfs_ps;
|
||||
|
||||
struct sk_buff_head pending; /* packets pending */
|
||||
/*
|
||||
@ -362,7 +361,6 @@ struct mac80211_hwsim_data {
|
||||
* radio can be in more then one group.
|
||||
*/
|
||||
u64 group;
|
||||
struct dentry *debugfs_group;
|
||||
|
||||
int power_level;
|
||||
|
||||
@ -1493,7 +1491,7 @@ static void hw_scan_work(struct work_struct *work)
|
||||
req->channels[hwsim->scan_chan_idx]->center_freq);
|
||||
|
||||
hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
|
||||
if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
|
||||
if (hwsim->tmp_chan->flags & IEEE80211_CHAN_NO_IR ||
|
||||
!req->n_ssids) {
|
||||
dwell = 120;
|
||||
} else {
|
||||
@ -1742,9 +1740,7 @@ static void mac80211_hwsim_free(void)
|
||||
spin_unlock_bh(&hwsim_radio_lock);
|
||||
|
||||
list_for_each_entry_safe(data, tmpdata, &tmplist, list) {
|
||||
debugfs_remove(data->debugfs_group);
|
||||
debugfs_remove(data->debugfs_ps);
|
||||
debugfs_remove(data->debugfs);
|
||||
debugfs_remove_recursive(data->debugfs);
|
||||
ieee80211_unregister_hw(data->hw);
|
||||
device_release_driver(data->dev);
|
||||
device_unregister(data->dev);
|
||||
@ -1901,6 +1897,17 @@ static int hwsim_fops_ps_write(void *dat, u64 val)
|
||||
DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
|
||||
"%llu\n");
|
||||
|
||||
static int hwsim_write_simulate_radar(void *dat, u64 val)
|
||||
{
|
||||
struct mac80211_hwsim_data *data = dat;
|
||||
|
||||
ieee80211_radar_detected(data->hw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(hwsim_simulate_radar, NULL,
|
||||
hwsim_write_simulate_radar, "%llu\n");
|
||||
|
||||
static int hwsim_fops_group_read(void *dat, u64 *val)
|
||||
{
|
||||
@ -2201,11 +2208,28 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
|
||||
{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
|
||||
};
|
||||
|
||||
static struct ieee80211_iface_combination hwsim_if_comb = {
|
||||
.limits = hwsim_if_limits,
|
||||
.n_limits = ARRAY_SIZE(hwsim_if_limits),
|
||||
.max_interfaces = 2048,
|
||||
.num_different_channels = 1,
|
||||
static const struct ieee80211_iface_limit hwsim_if_dfs_limits[] = {
|
||||
{ .max = 8, .types = BIT(NL80211_IFTYPE_AP) },
|
||||
};
|
||||
|
||||
static struct ieee80211_iface_combination hwsim_if_comb[] = {
|
||||
{
|
||||
.limits = hwsim_if_limits,
|
||||
.n_limits = ARRAY_SIZE(hwsim_if_limits),
|
||||
.max_interfaces = 2048,
|
||||
.num_different_channels = 1,
|
||||
},
|
||||
{
|
||||
.limits = hwsim_if_dfs_limits,
|
||||
.n_limits = ARRAY_SIZE(hwsim_if_dfs_limits),
|
||||
.max_interfaces = 8,
|
||||
.num_different_channels = 1,
|
||||
.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
|
||||
BIT(NL80211_CHAN_WIDTH_20) |
|
||||
BIT(NL80211_CHAN_WIDTH_40) |
|
||||
BIT(NL80211_CHAN_WIDTH_80) |
|
||||
BIT(NL80211_CHAN_WIDTH_160),
|
||||
}
|
||||
};
|
||||
|
||||
static int __init init_mac80211_hwsim(void)
|
||||
@ -2223,7 +2247,7 @@ static int __init init_mac80211_hwsim(void)
|
||||
return -EINVAL;
|
||||
|
||||
if (channels > 1) {
|
||||
hwsim_if_comb.num_different_channels = channels;
|
||||
hwsim_if_comb[0].num_different_channels = channels;
|
||||
mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan;
|
||||
mac80211_hwsim_ops.cancel_hw_scan =
|
||||
mac80211_hwsim_cancel_hw_scan;
|
||||
@ -2303,13 +2327,15 @@ static int __init init_mac80211_hwsim(void)
|
||||
hw->wiphy->n_addresses = 2;
|
||||
hw->wiphy->addresses = data->addresses;
|
||||
|
||||
hw->wiphy->iface_combinations = &hwsim_if_comb;
|
||||
hw->wiphy->n_iface_combinations = 1;
|
||||
hw->wiphy->iface_combinations = hwsim_if_comb;
|
||||
hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
|
||||
|
||||
if (channels > 1) {
|
||||
hw->wiphy->max_scan_ssids = 255;
|
||||
hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
|
||||
hw->wiphy->max_remain_on_channel_duration = 1000;
|
||||
/* For channels > 1 DFS is not allowed */
|
||||
hw->wiphy->n_iface_combinations = 1;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
|
||||
@ -2333,7 +2359,8 @@ static int __init init_mac80211_hwsim(void)
|
||||
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
|
||||
IEEE80211_HW_AMPDU_AGGREGATION |
|
||||
IEEE80211_HW_WANT_MONITOR_VIF |
|
||||
IEEE80211_HW_QUEUE_CONTROL;
|
||||
IEEE80211_HW_QUEUE_CONTROL |
|
||||
IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
|
||||
if (rctbl)
|
||||
hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE;
|
||||
|
||||
@ -2393,6 +2420,7 @@ static int __init init_mac80211_hwsim(void)
|
||||
sband->vht_cap.cap =
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
|
||||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
|
||||
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
|
||||
IEEE80211_VHT_CAP_RXLDPC |
|
||||
IEEE80211_VHT_CAP_SHORT_GI_80 |
|
||||
IEEE80211_VHT_CAP_SHORT_GI_160 |
|
||||
@ -2435,46 +2463,53 @@ static int __init init_mac80211_hwsim(void)
|
||||
break;
|
||||
case HWSIM_REGTEST_WORLD_ROAM:
|
||||
if (i == 0) {
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |=
|
||||
REGULATORY_CUSTOM_REG;
|
||||
wiphy_apply_custom_regulatory(hw->wiphy,
|
||||
&hwsim_world_regdom_custom_01);
|
||||
}
|
||||
break;
|
||||
case HWSIM_REGTEST_CUSTOM_WORLD:
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
|
||||
wiphy_apply_custom_regulatory(hw->wiphy,
|
||||
&hwsim_world_regdom_custom_01);
|
||||
break;
|
||||
case HWSIM_REGTEST_CUSTOM_WORLD_2:
|
||||
if (i == 0) {
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |=
|
||||
REGULATORY_CUSTOM_REG;
|
||||
wiphy_apply_custom_regulatory(hw->wiphy,
|
||||
&hwsim_world_regdom_custom_01);
|
||||
} else if (i == 1) {
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |=
|
||||
REGULATORY_CUSTOM_REG;
|
||||
wiphy_apply_custom_regulatory(hw->wiphy,
|
||||
&hwsim_world_regdom_custom_02);
|
||||
}
|
||||
break;
|
||||
case HWSIM_REGTEST_STRICT_ALL:
|
||||
hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
|
||||
break;
|
||||
case HWSIM_REGTEST_STRICT_FOLLOW:
|
||||
case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
|
||||
if (i == 0)
|
||||
hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |=
|
||||
REGULATORY_STRICT_REG;
|
||||
break;
|
||||
case HWSIM_REGTEST_ALL:
|
||||
if (i == 0) {
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |=
|
||||
REGULATORY_CUSTOM_REG;
|
||||
wiphy_apply_custom_regulatory(hw->wiphy,
|
||||
&hwsim_world_regdom_custom_01);
|
||||
} else if (i == 1) {
|
||||
hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |=
|
||||
REGULATORY_CUSTOM_REG;
|
||||
wiphy_apply_custom_regulatory(hw->wiphy,
|
||||
&hwsim_world_regdom_custom_02);
|
||||
} else if (i == 4)
|
||||
hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
|
||||
hw->wiphy->regulatory_flags |=
|
||||
REGULATORY_STRICT_REG;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -2541,16 +2576,18 @@ static int __init init_mac80211_hwsim(void)
|
||||
|
||||
data->debugfs = debugfs_create_dir("hwsim",
|
||||
hw->wiphy->debugfsdir);
|
||||
data->debugfs_ps = debugfs_create_file("ps", 0666,
|
||||
data->debugfs, data,
|
||||
&hwsim_fops_ps);
|
||||
data->debugfs_group = debugfs_create_file("group", 0666,
|
||||
data->debugfs, data,
|
||||
&hwsim_fops_group);
|
||||
debugfs_create_file("ps", 0666, data->debugfs, data,
|
||||
&hwsim_fops_ps);
|
||||
debugfs_create_file("group", 0666, data->debugfs, data,
|
||||
&hwsim_fops_group);
|
||||
if (channels == 1)
|
||||
debugfs_create_file("dfs_simulate_radar", 0222,
|
||||
data->debugfs,
|
||||
data, &hwsim_simulate_radar);
|
||||
|
||||
tasklet_hrtimer_init(&data->beacon_timer,
|
||||
mac80211_hwsim_beacon,
|
||||
CLOCK_REALTIME, HRTIMER_MODE_ABS);
|
||||
CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
|
||||
|
||||
list_add_tail(&data->list, &hwsim_radios);
|
||||
}
|
||||
|
@ -50,24 +50,24 @@ static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
|
||||
REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
|
||||
/* Channel 12 - 13 */
|
||||
REG_RULE(2467-10, 2472+10, 20, 3, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
|
||||
NL80211_RRF_NO_IR),
|
||||
/* Channel 14 */
|
||||
REG_RULE(2484-10, 2484+10, 20, 3, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
|
||||
NL80211_RRF_NO_IR |
|
||||
NL80211_RRF_NO_OFDM),
|
||||
/* Channel 36 - 48 */
|
||||
REG_RULE(5180-10, 5240+10, 40, 3, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
|
||||
NL80211_RRF_NO_IR),
|
||||
/* Channel 149 - 165 */
|
||||
REG_RULE(5745-10, 5825+10, 40, 3, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
|
||||
NL80211_RRF_NO_IR),
|
||||
/* Channel 52 - 64 */
|
||||
REG_RULE(5260-10, 5320+10, 40, 3, 30,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
|
||||
NL80211_RRF_NO_IR |
|
||||
NL80211_RRF_DFS),
|
||||
/* Channel 100 - 140 */
|
||||
REG_RULE(5500-10, 5700+10, 40, 3, 30,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
|
||||
NL80211_RRF_NO_IR |
|
||||
NL80211_RRF_DFS),
|
||||
}
|
||||
};
|
||||
@ -184,10 +184,10 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
|
||||
*/
|
||||
static int
|
||||
mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct ieee80211_channel *chan, bool offchan,
|
||||
unsigned int wait, const u8 *buf, size_t len,
|
||||
bool no_cck, bool dont_wait_for_ack, u64 *cookie)
|
||||
struct cfg80211_mgmt_tx_params *params, u64 *cookie)
|
||||
{
|
||||
const u8 *buf = params->buf;
|
||||
size_t len = params->len;
|
||||
struct sk_buff *skb;
|
||||
u16 pkt_len;
|
||||
const struct ieee80211_mgmt *mgmt;
|
||||
@ -1968,7 +1968,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
|
||||
user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
|
||||
user_scan_cfg->chan_list[i].radio_type = chan->band;
|
||||
|
||||
if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
if (chan->flags & IEEE80211_CHAN_NO_IR)
|
||||
user_scan_cfg->chan_list[i].scan_type =
|
||||
MWIFIEX_SCAN_TYPE_PASSIVE;
|
||||
else
|
||||
@ -2702,9 +2702,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
||||
WIPHY_FLAG_AP_UAPSD |
|
||||
WIPHY_FLAG_CUSTOM_REGULATORY |
|
||||
WIPHY_FLAG_STRICT_REGULATORY |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
|
||||
wiphy->regulatory_flags |=
|
||||
REGULATORY_CUSTOM_REG |
|
||||
REGULATORY_STRICT_REG;
|
||||
|
||||
wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
|
||||
|
||||
|
@ -515,14 +515,14 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
|
||||
scan_chan_list[chan_idx].max_scan_time =
|
||||
cpu_to_le16((u16) user_scan_in->
|
||||
chan_list[0].scan_time);
|
||||
else if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
else if (ch->flags & IEEE80211_CHAN_NO_IR)
|
||||
scan_chan_list[chan_idx].max_scan_time =
|
||||
cpu_to_le16(adapter->passive_scan_time);
|
||||
else
|
||||
scan_chan_list[chan_idx].max_scan_time =
|
||||
cpu_to_le16(adapter->active_scan_time);
|
||||
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
if (ch->flags & IEEE80211_CHAN_NO_IR)
|
||||
scan_chan_list[chan_idx].chan_scan_mode_bitmap
|
||||
|= MWIFIEX_PASSIVE_SCAN;
|
||||
else
|
||||
|
@ -338,8 +338,7 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
|
||||
if (!data_buf)
|
||||
return -1;
|
||||
|
||||
pg_tlv_hdr = (struct mwifiex_types_power_group *)
|
||||
((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
pg_tlv_hdr = (struct mwifiex_types_power_group *)((u8 *)data_buf);
|
||||
pg = (struct mwifiex_power_group *)
|
||||
((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group));
|
||||
length = le16_to_cpu(pg_tlv_hdr->length);
|
||||
@ -383,19 +382,25 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
|
||||
struct mwifiex_types_power_group *pg_tlv_hdr;
|
||||
struct mwifiex_power_group *pg;
|
||||
u16 action = le16_to_cpu(txp_cfg->action);
|
||||
u16 tlv_buf_left;
|
||||
|
||||
pg_tlv_hdr = (struct mwifiex_types_power_group *)
|
||||
((u8 *)txp_cfg +
|
||||
sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
|
||||
pg = (struct mwifiex_power_group *)
|
||||
((u8 *)pg_tlv_hdr +
|
||||
sizeof(struct mwifiex_types_power_group));
|
||||
|
||||
tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*txp_cfg);
|
||||
if (tlv_buf_left <
|
||||
le16_to_cpu(pg_tlv_hdr->length) + sizeof(*pg_tlv_hdr))
|
||||
return 0;
|
||||
|
||||
switch (action) {
|
||||
case HostCmd_ACT_GEN_GET:
|
||||
pg_tlv_hdr = (struct mwifiex_types_power_group *)
|
||||
((u8 *) txp_cfg +
|
||||
sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
|
||||
pg = (struct mwifiex_power_group *)
|
||||
((u8 *) pg_tlv_hdr +
|
||||
sizeof(struct mwifiex_types_power_group));
|
||||
|
||||
if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
|
||||
mwifiex_get_power_level(priv, txp_cfg);
|
||||
mwifiex_get_power_level(priv, pg_tlv_hdr);
|
||||
|
||||
priv->tx_power_level = (u16) pg->power_min;
|
||||
break;
|
||||
@ -404,14 +409,6 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
|
||||
if (!le32_to_cpu(txp_cfg->mode))
|
||||
break;
|
||||
|
||||
pg_tlv_hdr = (struct mwifiex_types_power_group *)
|
||||
((u8 *) txp_cfg +
|
||||
sizeof(struct host_cmd_ds_txpwr_cfg));
|
||||
|
||||
pg = (struct mwifiex_power_group *)
|
||||
((u8 *) pg_tlv_hdr +
|
||||
sizeof(struct mwifiex_types_power_group));
|
||||
|
||||
if (pg->power_max == pg->power_min)
|
||||
priv->tx_power_level = (u16) pg->power_min;
|
||||
break;
|
||||
|
@ -914,7 +914,6 @@ islpci_setup(struct pci_dev *pdev)
|
||||
do_islpci_free_memory:
|
||||
islpci_free_memory(priv);
|
||||
do_free_netdev:
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
free_netdev(ndev);
|
||||
priv = NULL;
|
||||
return NULL;
|
||||
|
@ -199,7 +199,6 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
do_unregister_netdev:
|
||||
unregister_netdev(ndev);
|
||||
islpci_free_memory(priv);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
free_netdev(ndev);
|
||||
priv = NULL;
|
||||
do_pci_clear_mwi:
|
||||
@ -247,7 +246,6 @@ prism54_remove(struct pci_dev *pdev)
|
||||
/* free the PCI memory and unmap the remapped page */
|
||||
islpci_free_memory(priv);
|
||||
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
free_netdev(ndev);
|
||||
priv = NULL;
|
||||
|
||||
|
@ -5462,15 +5462,14 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 68, 0x0b);
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 69, 0x12);
|
||||
rt2800_bbp_write(rt2x00dev, 69, 0x0d);
|
||||
rt2800_bbp_write(rt2x00dev, 70, 0x06);
|
||||
rt2800_bbp_write(rt2x00dev, 73, 0x13);
|
||||
rt2800_bbp_write(rt2x00dev, 75, 0x46);
|
||||
rt2800_bbp_write(rt2x00dev, 76, 0x28);
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 77, 0x59);
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 70, 0x0a);
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 79, 0x13);
|
||||
rt2800_bbp_write(rt2x00dev, 80, 0x05);
|
||||
rt2800_bbp_write(rt2x00dev, 81, 0x33);
|
||||
@ -5513,6 +5512,7 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
|
||||
if (rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
rt2800_bbp_write(rt2x00dev, 134, 0xd0);
|
||||
rt2800_bbp_write(rt2x00dev, 135, 0xf6);
|
||||
rt2800_bbp_write(rt2x00dev, 148, 0x84);
|
||||
}
|
||||
|
||||
rt2800_disable_unused_dac_adc(rt2x00dev);
|
||||
@ -6453,7 +6453,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
|
||||
rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
|
||||
rt2800_rfcsr_write(rt2x00dev, 12, 0xc6);
|
||||
rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
|
||||
rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
|
||||
@ -6466,7 +6466,8 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
|
||||
rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
|
||||
if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
|
||||
if (rt2x00_is_usb(rt2x00dev) &&
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
|
||||
else
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0xc0);
|
||||
@ -6486,10 +6487,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
|
||||
rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
|
||||
|
||||
if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
|
||||
rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
|
||||
else
|
||||
rt2800_rfcsr_write(rt2x00dev, 40, 0x4b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
|
||||
rt2800_rfcsr_write(rt2x00dev, 42, 0xd2);
|
||||
rt2800_rfcsr_write(rt2x00dev, 43, 0x9a);
|
||||
@ -6510,16 +6508,26 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_rfcsr_write(rt2x00dev, 53, 0x84);
|
||||
rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
|
||||
rt2800_rfcsr_write(rt2x00dev, 55, 0x44);
|
||||
rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
|
||||
if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
|
||||
rt2800_rfcsr_write(rt2x00dev, 56, 0x42);
|
||||
else
|
||||
rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
|
||||
rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 59, 0x8f);
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
|
||||
if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
|
||||
else
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
|
||||
if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
|
||||
if (rt2x00_is_usb(rt2x00dev))
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
|
||||
else
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0xd5);
|
||||
} else {
|
||||
if (rt2x00_is_usb(rt2x00dev))
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
|
||||
else
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0xb5);
|
||||
}
|
||||
rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
|
||||
|
||||
@ -6602,7 +6610,6 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, 0x3F);
|
||||
rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
|
||||
rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
|
||||
rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
|
||||
rt2800_rfcsr_write(rt2x00dev, 6, 0xE4);
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
|
||||
|
@ -156,8 +156,6 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
|
||||
exit_disable_device:
|
||||
pci_disable_device(pci_dev);
|
||||
|
||||
pci_set_drvdata(pci_dev, NULL);
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00pci_probe);
|
||||
@ -177,7 +175,6 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
|
||||
/*
|
||||
* Free the PCI device data.
|
||||
*/
|
||||
pci_set_drvdata(pci_dev, NULL);
|
||||
pci_disable_device(pci_dev);
|
||||
pci_release_regions(pci_dev);
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
|
||||
struct rtl8187_rx_info *info;
|
||||
int ret = 0;
|
||||
|
||||
while (skb_queue_len(&priv->rx_queue) < 16) {
|
||||
while (skb_queue_len(&priv->rx_queue) < 32) {
|
||||
skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
|
||||
if (!skb) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -1437,7 +1437,8 @@ void rtl_watchdog_wq_callback(void *data)
|
||||
/* if we can't recv beacon for 6s, we should
|
||||
* reconnect this AP
|
||||
*/
|
||||
if (rtlpriv->link_info.roam_times >= 3) {
|
||||
if ((rtlpriv->link_info.roam_times >= 3) &&
|
||||
!is_zero_ether_addr(rtlpriv->mac80211.bssid)) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"AP off, try to reconnect now\n");
|
||||
rtlpriv->link_info.roam_times = 0;
|
||||
|
@ -46,10 +46,20 @@ void rtl_fw_cb(const struct firmware *firmware, void *context)
|
||||
"Firmware callback routine entered!\n");
|
||||
complete(&rtlpriv->firmware_loading_complete);
|
||||
if (!firmware) {
|
||||
if (rtlpriv->cfg->alt_fw_name) {
|
||||
err = request_firmware(&firmware,
|
||||
rtlpriv->cfg->alt_fw_name,
|
||||
rtlpriv->io.dev);
|
||||
pr_info("Loading alternative firmware %s\n",
|
||||
rtlpriv->cfg->alt_fw_name);
|
||||
if (!err)
|
||||
goto found_alt;
|
||||
}
|
||||
pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
|
||||
rtlpriv->max_fw_size = 0;
|
||||
return;
|
||||
}
|
||||
found_alt:
|
||||
if (firmware->size > rtlpriv->max_fw_size) {
|
||||
RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
|
||||
"Firmware is too big!\n");
|
||||
@ -184,6 +194,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
|
||||
rtlpriv->cfg->maps
|
||||
[RTL_IBSS_INT_MASKS]);
|
||||
}
|
||||
mac->link_state = MAC80211_LINKED;
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
|
||||
|
@ -688,8 +688,6 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
rtlpriv->stats.rxbytesunicast += skb->len;
|
||||
}
|
||||
|
||||
rtl_is_special_data(hw, skb, false);
|
||||
|
||||
if (ieee80211_is_data(fc)) {
|
||||
rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
|
||||
|
||||
|
@ -59,30 +59,26 @@ static struct country_code_to_enum_rd allCountries[] = {
|
||||
*/
|
||||
#define RTL819x_2GHZ_CH12_13 \
|
||||
REG_RULE(2467-10, 2472+10, 40, 0, 20,\
|
||||
NL80211_RRF_PASSIVE_SCAN)
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
#define RTL819x_2GHZ_CH14 \
|
||||
REG_RULE(2484-10, 2484+10, 40, 0, 20, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_NO_OFDM)
|
||||
NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM)
|
||||
|
||||
/* 5G chan 36 - chan 64*/
|
||||
#define RTL819x_5GHZ_5150_5350 \
|
||||
REG_RULE(5150-10, 5350+10, 40, 0, 30, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
/* 5G chan 100 - chan 165*/
|
||||
#define RTL819x_5GHZ_5470_5850 \
|
||||
REG_RULE(5470-10, 5850+10, 40, 0, 30, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
/* 5G chan 149 - chan 165*/
|
||||
#define RTL819x_5GHZ_5725_5850 \
|
||||
REG_RULE(5725-10, 5850+10, 40, 0, 30, \
|
||||
NL80211_RRF_PASSIVE_SCAN | \
|
||||
NL80211_RRF_NO_IBSS)
|
||||
NL80211_RRF_NO_IR)
|
||||
|
||||
#define RTL819x_5GHZ_ALL \
|
||||
(RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
|
||||
@ -172,7 +168,8 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
(ch->flags & IEEE80211_CHAN_RADAR))
|
||||
continue;
|
||||
if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
reg_rule = freq_reg_info(wiphy, ch->center_freq);
|
||||
reg_rule = freq_reg_info(wiphy,
|
||||
MHZ_TO_KHZ(ch->center_freq));
|
||||
if (IS_ERR(reg_rule))
|
||||
continue;
|
||||
|
||||
@ -185,16 +182,11 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
|
||||
*regulatory_hint().
|
||||
*/
|
||||
|
||||
if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IBSS;
|
||||
if (!(reg_rule->
|
||||
flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
ch->flags &=
|
||||
~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
if (!(reg_rule->flags & NL80211_RRF_NO_IR))
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
} else {
|
||||
if (ch->beacon_found)
|
||||
ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN);
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -219,11 +211,11 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
|
||||
*/
|
||||
if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
|
||||
ch = &sband->channels[11]; /* CH 12 */
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
if (ch->flags & IEEE80211_CHAN_NO_IR)
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
ch = &sband->channels[12]; /* CH 13 */
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
if (ch->flags & IEEE80211_CHAN_NO_IR)
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -235,19 +227,19 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
|
||||
*/
|
||||
|
||||
ch = &sband->channels[11]; /* CH 12 */
|
||||
reg_rule = freq_reg_info(wiphy, ch->center_freq);
|
||||
reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
|
||||
if (!IS_ERR(reg_rule)) {
|
||||
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
if (!(reg_rule->flags & NL80211_RRF_NO_IR))
|
||||
if (ch->flags & IEEE80211_CHAN_NO_IR)
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
|
||||
ch = &sband->channels[12]; /* CH 13 */
|
||||
reg_rule = freq_reg_info(wiphy, ch->center_freq);
|
||||
reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
|
||||
if (!IS_ERR(reg_rule)) {
|
||||
if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
|
||||
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
|
||||
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
if (!(reg_rule->flags & NL80211_RRF_NO_IR))
|
||||
if (ch->flags & IEEE80211_CHAN_NO_IR)
|
||||
ch->flags &= ~IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,8 +276,7 @@ static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
|
||||
*/
|
||||
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
|
||||
ch->flags |= IEEE80211_CHAN_RADAR |
|
||||
IEEE80211_CHAN_NO_IBSS |
|
||||
IEEE80211_CHAN_PASSIVE_SCAN;
|
||||
IEEE80211_CHAN_NO_IR;
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,9 +345,9 @@ static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
|
||||
|
||||
wiphy->reg_notifier = reg_notifier;
|
||||
|
||||
wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
|
||||
wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
|
||||
wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
|
||||
wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
|
||||
wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
|
||||
|
||||
regd = _rtl_regdomain_select(reg);
|
||||
wiphy_apply_custom_regulatory(wiphy, regd);
|
||||
|
@ -1078,7 +1078,7 @@ static void rtl88e_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
|
||||
rtldm->swing_flag_ofdm = true;
|
||||
}
|
||||
|
||||
if (rtldm->swing_idx_cck != rtldm->swing_idx_cck) {
|
||||
if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {
|
||||
rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
|
||||
rtldm->swing_flag_cck = true;
|
||||
}
|
||||
|
@ -158,6 +158,42 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
|
||||
{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
|
||||
};
|
||||
|
||||
static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
|
||||
|
||||
void dm_restorepowerindex(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 index;
|
||||
|
||||
for (index = 0; index < 6; index++)
|
||||
rtl_write_byte(rtlpriv, power_index_reg[index],
|
||||
rtlpriv->dm.powerindex_backup[index]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_restorepowerindex);
|
||||
|
||||
void dm_writepowerindex(struct ieee80211_hw *hw, u8 value)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 index;
|
||||
|
||||
for (index = 0; index < 6; index++)
|
||||
rtl_write_byte(rtlpriv, power_index_reg[index], value);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_writepowerindex);
|
||||
|
||||
void dm_savepowerindex(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
u8 index;
|
||||
u8 tmp;
|
||||
|
||||
for (index = 0; index < 6; index++) {
|
||||
tmp = rtl_read_byte(rtlpriv, power_index_reg[index]);
|
||||
rtlpriv->dm.powerindex_backup[index] = tmp;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dm_savepowerindex);
|
||||
|
||||
static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
@ -180,7 +216,12 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
|
||||
dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
|
||||
dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
|
||||
dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
|
||||
dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
|
||||
dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LowRssi;
|
||||
|
||||
dm_digtable->forbidden_igi = DM_DIG_MIN;
|
||||
dm_digtable->large_fa_hit = 0;
|
||||
dm_digtable->recover_cnt = 0;
|
||||
dm_digtable->dig_dynamic_min = 0x25;
|
||||
}
|
||||
|
||||
static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
|
||||
@ -206,7 +247,9 @@ static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
|
||||
rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
|
||||
}
|
||||
|
||||
return (u8) rssi_val_min;
|
||||
if (rssi_val_min > 100)
|
||||
rssi_val_min = 100;
|
||||
return (u8)rssi_val_min;
|
||||
}
|
||||
|
||||
static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
|
||||
@ -224,9 +267,17 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
|
||||
|
||||
ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
|
||||
falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
|
||||
|
||||
ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
|
||||
falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
|
||||
falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
|
||||
|
||||
falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
|
||||
falsealm_cnt->cnt_rate_illegal +
|
||||
falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
|
||||
falsealm_cnt->cnt_rate_illegal +
|
||||
falsealm_cnt->cnt_crc8_fail +
|
||||
falsealm_cnt->cnt_mcs_fail +
|
||||
falsealm_cnt->cnt_fast_fsync_fail +
|
||||
falsealm_cnt->cnt_sb_search_fail;
|
||||
|
||||
rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
|
||||
ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
|
||||
@ -271,12 +322,14 @@ static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
|
||||
value_igi++;
|
||||
else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
|
||||
value_igi += 2;
|
||||
|
||||
if (value_igi > DM_DIG_FA_UPPER)
|
||||
value_igi = DM_DIG_FA_UPPER;
|
||||
else if (value_igi < DM_DIG_FA_LOWER)
|
||||
value_igi = DM_DIG_FA_LOWER;
|
||||
|
||||
if (rtlpriv->falsealm_cnt.cnt_all > 10000)
|
||||
value_igi = 0x32;
|
||||
value_igi = DM_DIG_FA_UPPER;
|
||||
|
||||
dm_digtable->cur_igvalue = value_igi;
|
||||
rtl92c_dm_write_dig(hw);
|
||||
@ -286,32 +339,80 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct dig_t *digtable = &rtlpriv->dm_digtable;
|
||||
u32 isbt;
|
||||
|
||||
if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) {
|
||||
if ((digtable->back_val - 2) < digtable->back_range_min)
|
||||
digtable->back_val = digtable->back_range_min;
|
||||
else
|
||||
digtable->back_val -= 2;
|
||||
} else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) {
|
||||
if ((digtable->back_val + 2) > digtable->back_range_max)
|
||||
digtable->back_val = digtable->back_range_max;
|
||||
else
|
||||
digtable->back_val += 2;
|
||||
/* modify DIG lower bound, deal with abnorally large false alarm */
|
||||
if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
|
||||
digtable->large_fa_hit++;
|
||||
if (digtable->forbidden_igi < digtable->cur_igvalue) {
|
||||
digtable->forbidden_igi = digtable->cur_igvalue;
|
||||
digtable->large_fa_hit = 1;
|
||||
}
|
||||
|
||||
if (digtable->large_fa_hit >= 3) {
|
||||
if ((digtable->forbidden_igi + 1) >
|
||||
digtable->rx_gain_max)
|
||||
digtable->rx_gain_min = digtable->rx_gain_max;
|
||||
else
|
||||
digtable->rx_gain_min = (digtable->forbidden_igi + 1);
|
||||
digtable->recover_cnt = 3600; /* 3600=2hr */
|
||||
}
|
||||
} else {
|
||||
/* Recovery mechanism for IGI lower bound */
|
||||
if (digtable->recover_cnt != 0) {
|
||||
digtable->recover_cnt--;
|
||||
} else {
|
||||
if (digtable->large_fa_hit == 0) {
|
||||
if ((digtable->forbidden_igi-1) < DM_DIG_MIN) {
|
||||
digtable->forbidden_igi = DM_DIG_MIN;
|
||||
digtable->rx_gain_min = DM_DIG_MIN;
|
||||
} else {
|
||||
digtable->forbidden_igi--;
|
||||
digtable->rx_gain_min = digtable->forbidden_igi + 1;
|
||||
}
|
||||
} else if (digtable->large_fa_hit == 3) {
|
||||
digtable->large_fa_hit = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rtlpriv->falsealm_cnt.cnt_all < 250) {
|
||||
isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01;
|
||||
|
||||
if (!isbt) {
|
||||
if (rtlpriv->falsealm_cnt.cnt_all >
|
||||
digtable->fa_lowthresh) {
|
||||
if ((digtable->back_val - 2) <
|
||||
digtable->back_range_min)
|
||||
digtable->back_val = digtable->back_range_min;
|
||||
else
|
||||
digtable->back_val -= 2;
|
||||
} else if (rtlpriv->falsealm_cnt.cnt_all <
|
||||
digtable->fa_lowthresh) {
|
||||
if ((digtable->back_val + 2) >
|
||||
digtable->back_range_max)
|
||||
digtable->back_val = digtable->back_range_max;
|
||||
else
|
||||
digtable->back_val += 2;
|
||||
}
|
||||
} else {
|
||||
digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
|
||||
}
|
||||
} else {
|
||||
/* Adjust initial gain by false alarm */
|
||||
if (rtlpriv->falsealm_cnt.cnt_all > 1000)
|
||||
digtable->cur_igvalue = digtable->pre_igvalue + 2;
|
||||
else if (rtlpriv->falsealm_cnt.cnt_all > 750)
|
||||
digtable->cur_igvalue = digtable->pre_igvalue + 1;
|
||||
else if (rtlpriv->falsealm_cnt.cnt_all < 500)
|
||||
digtable->cur_igvalue = digtable->pre_igvalue - 1;
|
||||
}
|
||||
|
||||
if ((digtable->rssi_val_min + 10 - digtable->back_val) >
|
||||
digtable->rx_gain_max)
|
||||
/* Check initial gain by upper/lower bound */
|
||||
if (digtable->cur_igvalue > digtable->rx_gain_max)
|
||||
digtable->cur_igvalue = digtable->rx_gain_max;
|
||||
else if ((digtable->rssi_val_min + 10 -
|
||||
digtable->back_val) < digtable->rx_gain_min)
|
||||
digtable->cur_igvalue = digtable->rx_gain_min;
|
||||
else
|
||||
digtable->cur_igvalue = digtable->rssi_val_min + 10 -
|
||||
digtable->back_val;
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
|
||||
"rssi_val_min = %x back_val %x\n",
|
||||
digtable->rssi_val_min, digtable->back_val);
|
||||
if (digtable->cur_igvalue < digtable->rx_gain_min)
|
||||
digtable->cur_igvalue = digtable->rx_gain_min;
|
||||
|
||||
rtl92c_dm_write_dig(hw);
|
||||
}
|
||||
@ -329,7 +430,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
|
||||
multi_sta = true;
|
||||
|
||||
if (!multi_sta ||
|
||||
dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
|
||||
dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) {
|
||||
initialized = false;
|
||||
dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
|
||||
return;
|
||||
@ -375,7 +476,6 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
|
||||
RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
|
||||
"presta_cstate = %x, cursta_cstate = %x\n",
|
||||
dm_digtable->presta_cstate, dm_digtable->cursta_cstate);
|
||||
|
||||
if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
|
||||
dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
|
||||
dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
|
||||
@ -383,6 +483,8 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
|
||||
if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
|
||||
dm_digtable->rssi_val_min =
|
||||
rtl92c_dm_initial_gain_min_pwdb(hw);
|
||||
if (dm_digtable->rssi_val_min > 100)
|
||||
dm_digtable->rssi_val_min = 100;
|
||||
rtl92c_dm_ctrl_initgain_by_rssi(hw);
|
||||
}
|
||||
} else {
|
||||
@ -398,11 +500,12 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
|
||||
static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
|
||||
|
||||
if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
|
||||
dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
|
||||
if (dm_digtable->rssi_val_min > 100)
|
||||
dm_digtable->rssi_val_min = 100;
|
||||
|
||||
if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
|
||||
if (dm_digtable->rssi_val_min <= 25)
|
||||
@ -424,48 +527,14 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
|
||||
}
|
||||
|
||||
if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
|
||||
if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
|
||||
if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
|
||||
dm_digtable->cur_cck_fa_state =
|
||||
CCK_FA_STAGE_High;
|
||||
else
|
||||
dm_digtable->cur_cck_fa_state = CCK_FA_STAGE_Low;
|
||||
|
||||
if (dm_digtable->pre_cck_fa_state !=
|
||||
dm_digtable->cur_cck_fa_state) {
|
||||
if (dm_digtable->cur_cck_fa_state ==
|
||||
CCK_FA_STAGE_Low)
|
||||
rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
|
||||
0x83);
|
||||
else
|
||||
rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
|
||||
0xcd);
|
||||
|
||||
dm_digtable->pre_cck_fa_state =
|
||||
dm_digtable->cur_cck_fa_state;
|
||||
}
|
||||
|
||||
rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
|
||||
|
||||
if (IS_92C_SERIAL(rtlhal->version))
|
||||
rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
|
||||
MASKBYTE2, 0xd7);
|
||||
} else {
|
||||
if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) ||
|
||||
(dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX))
|
||||
rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
|
||||
else
|
||||
rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
|
||||
rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
|
||||
|
||||
if (IS_92C_SERIAL(rtlhal->version))
|
||||
rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
|
||||
MASKBYTE2, 0xd3);
|
||||
}
|
||||
dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
|
||||
}
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n",
|
||||
dm_digtable->cur_cck_pd_state);
|
||||
|
||||
RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n",
|
||||
IS_92C_SERIAL(rtlhal->version));
|
||||
}
|
||||
|
||||
static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
|
||||
@ -482,6 +551,8 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
|
||||
else
|
||||
dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
|
||||
|
||||
dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
|
||||
|
||||
rtl92c_dm_initial_gain_sta(hw);
|
||||
rtl92c_dm_initial_gain_multi_sta(hw);
|
||||
rtl92c_dm_cck_packet_detection_thresh(hw);
|
||||
@ -493,23 +564,26 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
|
||||
static void rtl92c_dm_dig(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
|
||||
|
||||
if (rtlpriv->dm.dm_initialgain_enable == false)
|
||||
return;
|
||||
if (dm_digtable->dig_enable_flag == false)
|
||||
if (!rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG)
|
||||
return;
|
||||
|
||||
rtl92c_dm_ctrl_initgain_by_twoport(hw);
|
||||
|
||||
}
|
||||
|
||||
static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
rtlpriv->dm.dynamic_txpower_enable = false;
|
||||
|
||||
if (rtlpriv->rtlhal.interface == INTF_USB &&
|
||||
rtlpriv->rtlhal.board_type & 0x1) {
|
||||
dm_savepowerindex(hw);
|
||||
rtlpriv->dm.dynamic_txpower_enable = true;
|
||||
} else {
|
||||
rtlpriv->dm.dynamic_txpower_enable = false;
|
||||
}
|
||||
rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
|
||||
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
|
||||
}
|
||||
@ -524,9 +598,14 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
|
||||
dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
|
||||
dm_digtable->back_val);
|
||||
|
||||
dm_digtable->cur_igvalue += 2;
|
||||
if (dm_digtable->cur_igvalue > 0x3f)
|
||||
dm_digtable->cur_igvalue = 0x3f;
|
||||
if (rtlpriv->rtlhal.interface == INTF_USB &&
|
||||
!dm_digtable->dig_enable_flag) {
|
||||
dm_digtable->pre_igvalue = 0x17;
|
||||
return;
|
||||
}
|
||||
dm_digtable->cur_igvalue -= 1;
|
||||
if (dm_digtable->cur_igvalue < DM_DIG_MIN)
|
||||
dm_digtable->cur_igvalue = DM_DIG_MIN;
|
||||
|
||||
if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
|
||||
rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
|
||||
@ -536,11 +615,47 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
|
||||
|
||||
dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
|
||||
}
|
||||
RT_TRACE(rtlpriv, COMP_DIG, DBG_WARNING,
|
||||
"dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
||||
dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
|
||||
dm_digtable->rssi_val_min, dm_digtable->back_val,
|
||||
dm_digtable->rx_gain_max, dm_digtable->rx_gain_min,
|
||||
dm_digtable->large_fa_hit, dm_digtable->forbidden_igi);
|
||||
}
|
||||
EXPORT_SYMBOL(rtl92c_dm_write_dig);
|
||||
|
||||
static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
|
||||
|
||||
if (mac->link_state != MAC80211_LINKED)
|
||||
return;
|
||||
|
||||
if (mac->opmode == NL80211_IFTYPE_ADHOC ||
|
||||
mac->opmode == NL80211_IFTYPE_AP) {
|
||||
/* TODO: Handle ADHOC and AP Mode */
|
||||
}
|
||||
|
||||
if (tmpentry_max_pwdb != 0)
|
||||
rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb;
|
||||
else
|
||||
rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
|
||||
|
||||
if (tmpentry_min_pwdb != 0xff)
|
||||
rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb;
|
||||
else
|
||||
rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
|
||||
|
||||
/* TODO:
|
||||
* if (mac->opmode == NL80211_IFTYPE_STATION) {
|
||||
* if (rtlpriv->rtlhal.fw_ready) {
|
||||
* u32 param = (u32)(rtlpriv->dm.undec_sm_pwdb << 16);
|
||||
* rtl8192c_set_rssi_cmd(hw, param);
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
}
|
||||
|
||||
void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
|
||||
@ -750,6 +865,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
|
||||
rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
|
||||
rtlpriv->dm.cck_index = cck_index_old;
|
||||
}
|
||||
/* Handle USB High PA boards */
|
||||
|
||||
delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
|
||||
(thermalvalue - rtlpriv->dm.thermalvalue) :
|
||||
@ -1140,22 +1256,22 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
|
||||
static u8 initialize;
|
||||
static u32 reg_874, reg_c70, reg_85c, reg_a74;
|
||||
|
||||
if (initialize == 0) {
|
||||
reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
|
||||
MASKDWORD) & 0x1CC000) >> 14;
|
||||
if (!rtlpriv->reg_init) {
|
||||
rtlpriv->reg_874 = (rtl_get_bbreg(hw,
|
||||
RFPGA0_XCD_RFINTERFACESW,
|
||||
MASKDWORD) & 0x1CC000) >> 14;
|
||||
|
||||
reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
|
||||
MASKDWORD) & BIT(3)) >> 3;
|
||||
rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
|
||||
MASKDWORD) & BIT(3)) >> 3;
|
||||
|
||||
reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
|
||||
MASKDWORD) & 0xFF000000) >> 24;
|
||||
rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
|
||||
MASKDWORD) & 0xFF000000) >> 24;
|
||||
|
||||
reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
|
||||
rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
|
||||
0xF000) >> 12;
|
||||
|
||||
initialize = 1;
|
||||
rtlpriv->reg_init = true;
|
||||
}
|
||||
|
||||
if (!bforce_in_normal) {
|
||||
@ -1192,12 +1308,12 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
|
||||
rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
|
||||
} else {
|
||||
rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
|
||||
0x1CC000, reg_874);
|
||||
0x1CC000, rtlpriv->reg_874);
|
||||
rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
|
||||
reg_c70);
|
||||
rtlpriv->reg_c70);
|
||||
rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
|
||||
reg_85c);
|
||||
rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
|
||||
rtlpriv->reg_85c);
|
||||
rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
|
||||
rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
|
||||
}
|
||||
|
||||
@ -1213,6 +1329,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
|
||||
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
|
||||
/* Determine the minimum RSSI */
|
||||
if (((mac->link_state == MAC80211_NOLINK)) &&
|
||||
(rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
|
||||
dm_pstable->rssi_val_min = 0;
|
||||
@ -1241,6 +1358,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
|
||||
dm_pstable->rssi_val_min);
|
||||
}
|
||||
|
||||
/* Power Saving for 92C */
|
||||
if (IS_92C_SERIAL(rtlhal->version))
|
||||
;/* rtl92c_dm_1r_cca(hw); */
|
||||
else
|
||||
@ -1252,12 +1370,23 @@ void rtl92c_dm_init(struct ieee80211_hw *hw)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
|
||||
rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG;
|
||||
rtlpriv->dm.undec_sm_pwdb = -1;
|
||||
rtlpriv->dm.undec_sm_cck = -1;
|
||||
rtlpriv->dm.dm_initialgain_enable = true;
|
||||
rtl92c_dm_diginit(hw);
|
||||
|
||||
rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE;
|
||||
rtl92c_dm_init_dynamic_txpower(hw);
|
||||
|
||||
rtl92c_dm_init_edca_turbo(hw);
|
||||
rtl92c_dm_init_rate_adaptive_mask(hw);
|
||||
rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS;
|
||||
rtl92c_dm_initialize_txpower_tracking(hw);
|
||||
rtl92c_dm_init_dynamic_bb_powersaving(hw);
|
||||
|
||||
rtlpriv->dm.ofdm_pkt_cnt = 0;
|
||||
rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT;
|
||||
}
|
||||
EXPORT_SYMBOL(rtl92c_dm_init);
|
||||
|
||||
@ -1308,7 +1437,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
|
||||
}
|
||||
|
||||
if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
|
||||
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
|
||||
rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2;
|
||||
RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
|
||||
"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
|
||||
} else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
|
||||
@ -1328,8 +1457,16 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
|
||||
"PHY_SetTxPowerLevel8192S() Channel = %d\n",
|
||||
rtlphy->current_channel);
|
||||
rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
|
||||
if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
||||
TXHIGHPWRLEVEL_NORMAL)
|
||||
dm_restorepowerindex(hw);
|
||||
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
||||
TXHIGHPWRLEVEL_LEVEL1)
|
||||
dm_writepowerindex(hw, 0x14);
|
||||
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
||||
TXHIGHPWRLEVEL_LEVEL2)
|
||||
dm_writepowerindex(hw, 0x10);
|
||||
}
|
||||
|
||||
rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
|
||||
}
|
||||
|
||||
@ -1400,12 +1537,6 @@ u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
|
||||
else
|
||||
curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
|
||||
|
||||
/* Set Tx Power according to BT status. */
|
||||
if (undec_sm_pwdb >= 30)
|
||||
curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW;
|
||||
else if (undec_sm_pwdb < 25)
|
||||
curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW);
|
||||
|
||||
/* Check BT state related to BT_Idle in B/G mode. */
|
||||
if (undec_sm_pwdb < 15)
|
||||
curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW;
|
||||
|
@ -91,6 +91,17 @@
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
|
||||
#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
|
||||
|
||||
#define DYNAMIC_FUNC_DISABLE 0x0
|
||||
#define DYNAMIC_FUNC_DIG BIT(0)
|
||||
#define DYNAMIC_FUNC_HP BIT(1)
|
||||
#define DYNAMIC_FUNC_SS BIT(2) /*Tx Power Tracking*/
|
||||
#define DYNAMIC_FUNC_BT BIT(3)
|
||||
#define DYNAMIC_FUNC_ANT_DIV BIT(4)
|
||||
|
||||
#define RSSI_CCK 0
|
||||
#define RSSI_OFDM 1
|
||||
#define RSSI_DEFAULT 2
|
||||
|
||||
struct swat_t {
|
||||
u8 failure_cnt;
|
||||
u8 try_flag;
|
||||
@ -167,5 +178,8 @@ void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
|
||||
void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
|
||||
void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);
|
||||
void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
|
||||
void dm_savepowerindex(struct ieee80211_hw *hw);
|
||||
void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
|
||||
void dm_restorepowerindex(struct ieee80211_hw *hw);
|
||||
|
||||
#endif
|
||||
|
@ -1147,6 +1147,12 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
|
||||
0x522, 0x550, 0x551, 0x040
|
||||
};
|
||||
|
||||
u32 iqk_bb_reg_92C[9] = {
|
||||
0xc04, 0xc08, 0x874, 0xb68,
|
||||
0xb6c, 0x870, 0x860, 0x864,
|
||||
0x800
|
||||
};
|
||||
|
||||
const u32 retrycount = 2;
|
||||
|
||||
if (t == 0) {
|
||||
@ -1157,6 +1163,8 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
|
||||
rtlphy->adda_backup, 16);
|
||||
_rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
|
||||
rtlphy->iqk_mac_backup);
|
||||
_rtl92c_phy_save_adda_registers(hw, iqk_bb_reg_92C,
|
||||
rtlphy->iqk_bb_backup, 9);
|
||||
}
|
||||
_rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
|
||||
if (t == 0) {
|
||||
@ -1167,14 +1175,18 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
|
||||
|
||||
if (!rtlphy->rfpi_enable)
|
||||
_rtl92c_phy_pi_mode_switch(hw, true);
|
||||
if (t == 0) {
|
||||
rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
|
||||
rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
|
||||
rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
|
||||
}
|
||||
|
||||
rtl_set_bbreg(hw, 0x800, BIT(24), 0x0);
|
||||
|
||||
rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
|
||||
rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
|
||||
rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
|
||||
|
||||
rtl_set_bbreg(hw, 0x870, BIT(10), 0x1);
|
||||
rtl_set_bbreg(hw, 0x870, BIT(26), 0x1);
|
||||
rtl_set_bbreg(hw, 0x860, BIT(10), 0x0);
|
||||
rtl_set_bbreg(hw, 0x864, BIT(10), 0x0);
|
||||
|
||||
if (is2t) {
|
||||
rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
|
||||
rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
|
||||
@ -1239,13 +1251,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
|
||||
0x3FF0000) >> 16;
|
||||
}
|
||||
}
|
||||
rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
|
||||
rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
|
||||
rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
|
||||
|
||||
rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
|
||||
rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
|
||||
if (is2t)
|
||||
rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
|
||||
|
||||
if (t != 0) {
|
||||
if (!rtlphy->rfpi_enable)
|
||||
_rtl92c_phy_pi_mode_switch(hw, false);
|
||||
@ -1253,6 +1261,15 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
|
||||
rtlphy->adda_backup, 16);
|
||||
_rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
|
||||
rtlphy->iqk_mac_backup);
|
||||
_rtl92c_phy_reload_adda_registers(hw, iqk_bb_reg_92C,
|
||||
rtlphy->iqk_bb_backup, 9);
|
||||
|
||||
rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
|
||||
if (is2t)
|
||||
rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
|
||||
|
||||
rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
|
||||
rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,15 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
|
||||
"PHY_SetTxPowerLevel8192S() Channel = %d\n",
|
||||
rtlphy->current_channel);
|
||||
rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
|
||||
if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
||||
TXHIGHPWRLEVEL_NORMAL)
|
||||
dm_restorepowerindex(hw);
|
||||
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
||||
TXHIGHPWRLEVEL_LEVEL1)
|
||||
dm_writepowerindex(hw, 0x14);
|
||||
else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
|
||||
TXHIGHPWRLEVEL_LEVEL2)
|
||||
dm_writepowerindex(hw, 0x10);
|
||||
}
|
||||
|
||||
rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
|
||||
|
@ -30,3 +30,6 @@
|
||||
#include "../rtl8192ce/dm.h"
|
||||
|
||||
void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw);
|
||||
void dm_savepowerindex(struct ieee80211_hw *hw);
|
||||
void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
|
||||
void dm_restorepowerindex(struct ieee80211_hw *hw);
|
||||
|
@ -1022,7 +1022,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
|
||||
if (ppsc->rfpwr_state == ERFON) {
|
||||
rtl92c_phy_set_rfpath_switch(hw, 1);
|
||||
if (iqk_initialized) {
|
||||
rtl92c_phy_iq_calibrate(hw, false);
|
||||
rtl92c_phy_iq_calibrate(hw, true);
|
||||
} else {
|
||||
rtl92c_phy_iq_calibrate(hw, false);
|
||||
iqk_initialized = true;
|
||||
|
@ -120,6 +120,7 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
|
||||
u16 regval;
|
||||
u32 regval32;
|
||||
u8 b_reg_hwparafile = 1;
|
||||
|
||||
_rtl92c_phy_init_bb_rf_register_definition(hw);
|
||||
@ -135,8 +136,11 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
|
||||
} else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) {
|
||||
rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
|
||||
FEN_BB_GLB_RSTn | FEN_BBRSTB);
|
||||
rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
|
||||
}
|
||||
regval32 = rtl_read_dword(rtlpriv, 0x87c);
|
||||
rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31)));
|
||||
if (IS_HARDWARE_TYPE_8192CU(rtlhal))
|
||||
rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
|
||||
rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
|
||||
if (b_reg_hwparafile == 1)
|
||||
rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
|
||||
|
@ -85,17 +85,15 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||
if (mac->act_scanning) {
|
||||
tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
|
||||
tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
|
||||
if (turbo_scanoff) {
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
(ppowerlevel[idx1] << 16) |
|
||||
(ppowerlevel[idx1] << 24);
|
||||
if (rtlhal->interface == INTF_USB) {
|
||||
if (tx_agc[idx1] > 0x20 &&
|
||||
rtlefuse->external_pa)
|
||||
tx_agc[idx1] = 0x20;
|
||||
}
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
(ppowerlevel[idx1] << 16) |
|
||||
(ppowerlevel[idx1] << 24);
|
||||
if (rtlhal->interface == INTF_USB) {
|
||||
if (tx_agc[idx1] > 0x20 &&
|
||||
rtlefuse->external_pa)
|
||||
tx_agc[idx1] = 0x20;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -107,7 +105,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
|
||||
TXHIGHPWRLEVEL_LEVEL2) {
|
||||
tx_agc[RF90_PATH_A] = 0x00000000;
|
||||
tx_agc[RF90_PATH_B] = 0x00000000;
|
||||
} else{
|
||||
} else {
|
||||
for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
|
||||
tx_agc[idx1] = ppowerlevel[idx1] |
|
||||
(ppowerlevel[idx1] << 8) |
|
||||
@ -373,7 +371,12 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
|
||||
regoffset == RTXAGC_B_MCS07_MCS04)
|
||||
regoffset = 0xc98;
|
||||
for (i = 0; i < 3; i++) {
|
||||
writeVal = (writeVal > 6) ? (writeVal - 6) : 0;
|
||||
if (i != 2)
|
||||
writeVal = (writeVal > 8) ?
|
||||
(writeVal - 8) : 0;
|
||||
else
|
||||
writeVal = (writeVal > 6) ?
|
||||
(writeVal - 6) : 0;
|
||||
rtl_write_byte(rtlpriv, (u32)(regoffset + i),
|
||||
(u8)writeVal);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user