mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-23 11:04:44 +08:00
brcfmac
* fix IBSS which got broken over time * new USB id for bcm43242 dongle * arp offload configuration through inet notifier ath9k * add random number generator support (CONFIG_ATH9K_HWRNG) iwlwifi * Make scan parameters low latency aware * Fix in the NL80211_FEATURE_FULL_AP_CLIENT_STATE state case * Fix enable injection mode (Chaya Rachel) * Various cleanups (Dan / Julia / myself) * Allow to stay more time on popular channels (David Spinadel) * Bug fixes for D0i3 (Eliad / Luca) * Fixes for GO uAPSD (myself) * Start of TSO support (myself) * Rate control bug fixes (Eyal / Gregory) * Start the work on 9000 devices (Johannes / Sara / Oren) * Start the work on a new Tx queue allocation model (Liad) * Debug infrastructure enhancements (Golan) mwifiex * add a debugfs file for chip reset * advertise SMS4 cipher suite * increase ap and station interface limit to 3 * enable MSI support on newer pcie devices (8897 onwards) rtlwifi * fix lots of module parameter usage -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJWi5RxAAoJEG4XJFUm622bujQH/Rti4fRBnJcRt5EZAv/pvdIx AGPcYQQfFbFRjzxjrcY30AYCC6OoID9n7BNtELIWabA6dQHWGJd2aebZGH85O4Eh xgAty5CRf9E4+9MNiv+OqkL64/E6/YmSeOYiNSWl6SgRE4VYmexLXttpppImmoER zowmtqzLSN/4l4yX5p2BVy3NAXN0R1WjYKNUXAJvJj59814upXf+XrOKCghzHIs4 2NE/aFoscscKWCSS3+MIIW4q9QWw7f8YvAdrO6k47LLkjm4+C/I5BeAlHUOEQUS7 xyoB/7KoHXlzRen8LmoL9SsqopTL2tKEjE/1f0QgLKOHXqpPRb4iKBFjsR94HJg= =aeCM -----END PGP SIGNATURE----- Merge tag 'wireless-drivers-next-for-davem-2016-01-05' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next Kalle Valo says: ==================== brcfmac * fix IBSS which got broken over time * new USB id for bcm43242 dongle * arp offload configuration through inet notifier ath9k * add random number generator support (CONFIG_ATH9K_HWRNG) iwlwifi * Make scan parameters low latency aware * Fix in the NL80211_FEATURE_FULL_AP_CLIENT_STATE state case * Fix enable injection mode (Chaya Rachel) * Various cleanups (Dan / Julia / myself) * Allow to stay more time on popular channels (David Spinadel) * Bug fixes for D0i3 (Eliad / Luca) * Fixes for GO uAPSD (myself) * Start of TSO support (myself) * Rate control bug fixes (Eyal / Gregory) * Start the work on 9000 devices (Johannes / Sara / Oren) * Start the work on a new Tx queue allocation model (Liad) * Debug infrastructure enhancements (Golan) mwifiex * add a debugfs file for chip reset * advertise SMS4 cipher suite * increase ap and station interface limit to 3 * enable MSI support on newer pcie devices (8897 onwards) rtlwifi * fix lots of module parameter usage ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
56b87180cc
@ -101,50 +101,13 @@ static void bcm47xx_machine_halt(void)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
static int bcm47xx_get_invariants(struct ssb_bus *bus,
|
||||
struct ssb_init_invariants *iv)
|
||||
{
|
||||
char buf[20];
|
||||
int len, err;
|
||||
|
||||
/* Fill boardinfo structure */
|
||||
memset(&iv->boardinfo, 0 , sizeof(struct ssb_boardinfo));
|
||||
|
||||
len = bcm47xx_nvram_getenv("boardvendor", buf, sizeof(buf));
|
||||
if (len > 0) {
|
||||
err = kstrtou16(strim(buf), 0, &iv->boardinfo.vendor);
|
||||
if (err)
|
||||
pr_warn("Couldn't parse nvram board vendor entry with value \"%s\"\n",
|
||||
buf);
|
||||
}
|
||||
if (!iv->boardinfo.vendor)
|
||||
iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM;
|
||||
|
||||
len = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
|
||||
if (len > 0) {
|
||||
err = kstrtou16(strim(buf), 0, &iv->boardinfo.type);
|
||||
if (err)
|
||||
pr_warn("Couldn't parse nvram board type entry with value \"%s\"\n",
|
||||
buf);
|
||||
}
|
||||
|
||||
memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
|
||||
bcm47xx_fill_sprom(&iv->sprom, NULL, false);
|
||||
|
||||
if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
|
||||
iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init bcm47xx_register_ssb(void)
|
||||
{
|
||||
int err;
|
||||
char buf[100];
|
||||
struct ssb_mipscore *mcore;
|
||||
|
||||
err = ssb_bus_ssbbus_register(&bcm47xx_bus.ssb, SSB_ENUM_BASE,
|
||||
bcm47xx_get_invariants);
|
||||
err = ssb_bus_host_soc_register(&bcm47xx_bus.ssb, SSB_ENUM_BASE);
|
||||
if (err)
|
||||
panic("Failed to initialize SSB bus (err %d)", err);
|
||||
|
||||
|
@ -668,11 +668,36 @@ static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
core->id.rev, core->id.class);
|
||||
}
|
||||
|
||||
static unsigned int bcma_bus_registered;
|
||||
|
||||
/*
|
||||
* If built-in, bus has to be registered early, before any driver calls
|
||||
* bcma_driver_register.
|
||||
* Otherwise registering driver would trigger BUG in driver_register.
|
||||
*/
|
||||
static int __init bcma_init_bus_register(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (bcma_bus_registered)
|
||||
return 0;
|
||||
|
||||
err = bus_register(&bcma_bus_type);
|
||||
if (!err)
|
||||
bcma_bus_registered = 1;
|
||||
|
||||
return err;
|
||||
}
|
||||
#ifndef MODULE
|
||||
fs_initcall(bcma_init_bus_register);
|
||||
#endif
|
||||
|
||||
/* Main initialization has to be done with SPI/mtd/NAND/SPROM available */
|
||||
static int __init bcma_modinit(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = bus_register(&bcma_bus_type);
|
||||
err = bcma_init_bus_register();
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -691,7 +716,7 @@ static int __init bcma_modinit(void)
|
||||
|
||||
return err;
|
||||
}
|
||||
fs_initcall(bcma_modinit);
|
||||
module_init(bcma_modinit);
|
||||
|
||||
static void __exit bcma_modexit(void)
|
||||
{
|
||||
|
@ -1139,7 +1139,7 @@ static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
char buf[64];
|
||||
u8 amsdu = 3, ampdu = 64;
|
||||
u8 amsdu, ampdu;
|
||||
unsigned int len;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
@ -250,7 +250,8 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (WARN_ON(arvif->vif->type != NL80211_IFTYPE_AP &&
|
||||
arvif->vif->type != NL80211_IFTYPE_ADHOC))
|
||||
arvif->vif->type != NL80211_IFTYPE_ADHOC &&
|
||||
arvif->vif->type != NL80211_IFTYPE_MESH_POINT))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
@ -4312,34 +4312,58 @@ void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb)
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n");
|
||||
}
|
||||
|
||||
static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
|
||||
static int ath10k_wmi_alloc_chunk(struct ath10k *ar, u32 req_id,
|
||||
u32 num_units, u32 unit_len)
|
||||
{
|
||||
dma_addr_t paddr;
|
||||
u32 pool_size;
|
||||
u32 pool_size = 0;
|
||||
int idx = ar->wmi.num_mem_chunks;
|
||||
void *vaddr = NULL;
|
||||
|
||||
if (ar->wmi.num_mem_chunks == ARRAY_SIZE(ar->wmi.mem_chunks))
|
||||
return -ENOMEM;
|
||||
|
||||
while (!vaddr && num_units) {
|
||||
pool_size = num_units * round_up(unit_len, 4);
|
||||
|
||||
if (!pool_size)
|
||||
return -EINVAL;
|
||||
|
||||
ar->wmi.mem_chunks[idx].vaddr = dma_alloc_coherent(ar->dev,
|
||||
pool_size,
|
||||
&paddr,
|
||||
GFP_KERNEL);
|
||||
if (!ar->wmi.mem_chunks[idx].vaddr) {
|
||||
ath10k_warn(ar, "failed to allocate memory chunk\n");
|
||||
vaddr = kzalloc(pool_size, GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!vaddr)
|
||||
num_units /= 2;
|
||||
}
|
||||
|
||||
if (!num_units)
|
||||
return -ENOMEM;
|
||||
|
||||
paddr = dma_map_single(ar->dev, vaddr, pool_size, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(ar->dev, paddr)) {
|
||||
kfree(vaddr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(ar->wmi.mem_chunks[idx].vaddr, 0, pool_size);
|
||||
|
||||
ar->wmi.mem_chunks[idx].vaddr = vaddr;
|
||||
ar->wmi.mem_chunks[idx].paddr = paddr;
|
||||
ar->wmi.mem_chunks[idx].len = pool_size;
|
||||
ar->wmi.mem_chunks[idx].req_id = req_id;
|
||||
ar->wmi.num_mem_chunks++;
|
||||
|
||||
return num_units;
|
||||
}
|
||||
|
||||
static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
|
||||
u32 num_units, u32 unit_len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while (num_units) {
|
||||
ret = ath10k_wmi_alloc_chunk(ar, req_id, num_units, unit_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
num_units -= ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -7717,10 +7741,11 @@ void ath10k_wmi_free_host_mem(struct ath10k *ar)
|
||||
|
||||
/* free the host memory chunks requested by firmware */
|
||||
for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
|
||||
dma_free_coherent(ar->dev,
|
||||
dma_unmap_single(ar->dev,
|
||||
ar->wmi.mem_chunks[i].paddr,
|
||||
ar->wmi.mem_chunks[i].len,
|
||||
ar->wmi.mem_chunks[i].vaddr,
|
||||
ar->wmi.mem_chunks[i].paddr);
|
||||
DMA_TO_DEVICE);
|
||||
kfree(ar->wmi.mem_chunks[i].vaddr);
|
||||
}
|
||||
|
||||
ar->wmi.num_mem_chunks = 0;
|
||||
|
@ -767,7 +767,7 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
flags |= AR5K_TXDESC_NOACK;
|
||||
|
||||
rc_flags = info->control.rates[0].flags;
|
||||
rc_flags = bf->rates[0].flags;
|
||||
|
||||
hw_rate = ath5k_get_rate_hw_value(ah->hw, info, bf, 0);
|
||||
|
||||
|
@ -3930,8 +3930,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
|
||||
ar->hw.tx_ant = 2;
|
||||
ar->hw.rx_ant = 2;
|
||||
ar->hw.tx_ant = 0x3; /* mask, 2 antenna */
|
||||
ar->hw.rx_ant = 0x3;
|
||||
} else {
|
||||
ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
|
||||
|
@ -2222,6 +2222,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
|
||||
}
|
||||
|
||||
if (status) {
|
||||
if (status != -ECANCELED)
|
||||
ath6kl_err("failed to get pending recv messages: %d\n",
|
||||
status);
|
||||
|
||||
|
@ -954,8 +954,10 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name);
|
||||
|
||||
ret = request_firmware(&fw, filename, ar->dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath6kl_err("Failed request firmware, rv: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
data = fw->data;
|
||||
len = fw->size;
|
||||
@ -964,11 +966,15 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
magic_len = strlen(ATH6KL_FIRMWARE_MAGIC) + 1;
|
||||
|
||||
if (len < magic_len) {
|
||||
ath6kl_err("Magic length is invalid, len: %zd magic_len: %zd\n",
|
||||
len, magic_len);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (memcmp(data, ATH6KL_FIRMWARE_MAGIC, magic_len) != 0) {
|
||||
ath6kl_err("Magic is invalid, magic_len: %zd\n",
|
||||
magic_len);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@ -987,7 +993,12 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
len -= sizeof(*hdr);
|
||||
data += sizeof(*hdr);
|
||||
|
||||
ath6kl_dbg(ATH6KL_DBG_BOOT, "ie-id: %d len: %zd (0x%zx)\n",
|
||||
ie_id, ie_len, ie_len);
|
||||
|
||||
if (len < ie_len) {
|
||||
ath6kl_err("IE len is invalid, len: %zd ie_len: %zd ie-id: %d\n",
|
||||
len, ie_len, ie_id);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@ -1008,6 +1019,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
ar->fw_otp = kmemdup(data, ie_len, GFP_KERNEL);
|
||||
|
||||
if (ar->fw_otp == NULL) {
|
||||
ath6kl_err("fw_otp cannot be allocated\n");
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -1025,6 +1037,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
ar->fw = vmalloc(ie_len);
|
||||
|
||||
if (ar->fw == NULL) {
|
||||
ath6kl_err("fw storage cannot be allocated, len: %zd\n", ie_len);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -1039,6 +1052,7 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)
|
||||
ar->fw_patch = kmemdup(data, ie_len, GFP_KERNEL);
|
||||
|
||||
if (ar->fw_patch == NULL) {
|
||||
ath6kl_err("fw_patch storage cannot be allocated, len: %zd\n", ie_len);
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
@ -176,3 +176,14 @@ config ATH9K_HTC_DEBUGFS
|
||||
depends on ATH9K_HTC && DEBUG_FS
|
||||
---help---
|
||||
Say Y, if you need access to ath9k_htc's statistics.
|
||||
|
||||
config ATH9K_HWRNG
|
||||
bool "Random number generator support"
|
||||
depends on ATH9K && (HW_RANDOM = y || HW_RANDOM = ATH9K)
|
||||
default y
|
||||
---help---
|
||||
This option incorporates the ADC register output as a source of
|
||||
randomness into Linux entropy pool (/dev/urandom and /dev/random)
|
||||
|
||||
Say Y, feeds the entropy directly from the WiFi driver to the input
|
||||
pool.
|
||||
|
@ -15,6 +15,7 @@ ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
|
||||
ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o
|
||||
ath9k-$(CONFIG_ATH9K_TX99) += tx99.o
|
||||
ath9k-$(CONFIG_ATH9K_WOW) += wow.o
|
||||
ath9k-$(CONFIG_ATH9K_HWRNG) += rng.o
|
||||
|
||||
ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/leds.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/hw_random.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
@ -981,6 +982,7 @@ struct ath_softc {
|
||||
struct ath_offchannel offchannel;
|
||||
struct ath_chanctx *next_chan;
|
||||
struct completion go_beacon;
|
||||
struct timespec last_event_time;
|
||||
#endif
|
||||
|
||||
unsigned long driver_data;
|
||||
@ -1040,6 +1042,11 @@ struct ath_softc {
|
||||
u32 wow_intr_before_sleep;
|
||||
bool force_wow;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ATH9K_HWRNG
|
||||
u32 rng_last;
|
||||
struct task_struct *rng_task;
|
||||
#endif
|
||||
};
|
||||
|
||||
/********/
|
||||
@ -1062,6 +1069,22 @@ static inline int ath9k_tx99_send(struct ath_softc *sc,
|
||||
}
|
||||
#endif /* CONFIG_ATH9K_TX99 */
|
||||
|
||||
/***************************/
|
||||
/* Random Number Generator */
|
||||
/***************************/
|
||||
#ifdef CONFIG_ATH9K_HWRNG
|
||||
void ath9k_rng_start(struct ath_softc *sc);
|
||||
void ath9k_rng_stop(struct ath_softc *sc);
|
||||
#else
|
||||
static inline void ath9k_rng_start(struct ath_softc *sc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_rng_stop(struct ath_softc *sc)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void ath_read_cachesize(struct ath_common *common, int *csz)
|
||||
{
|
||||
common->bus_ops->read_cachesize(common, csz);
|
||||
|
@ -148,7 +148,8 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
|
||||
|
||||
ath_assign_seq(common, skb);
|
||||
|
||||
if (vif->p2p)
|
||||
/* Always assign NOA attr when MCC enabled */
|
||||
if (ath9k_is_chanctx_enabled())
|
||||
ath9k_beacon_add_noa(sc, avp, skb);
|
||||
|
||||
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
|
||||
|
@ -226,6 +226,20 @@ static const char *chanctx_state_string(enum ath_chanctx_state state)
|
||||
}
|
||||
}
|
||||
|
||||
static const u32 chanctx_event_delta(struct ath_softc *sc)
|
||||
{
|
||||
u64 ms;
|
||||
struct timespec ts, *old;
|
||||
|
||||
getrawmonotonic(&ts);
|
||||
old = &sc->last_event_time;
|
||||
ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
||||
ms -= old->tv_sec * 1000 + old->tv_nsec / 1000000;
|
||||
sc->last_event_time = ts;
|
||||
|
||||
return (u32)ms;
|
||||
}
|
||||
|
||||
void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
@ -356,14 +370,16 @@ static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
unsigned long timeout;
|
||||
|
||||
ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000);
|
||||
tsf_time -= ath9k_hw_gettsf32(ah);
|
||||
tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1;
|
||||
mod_timer(&sc->sched.timer, jiffies + tsf_time);
|
||||
timeout = msecs_to_jiffies(tsf_time / 1000) + 1;
|
||||
mod_timer(&sc->sched.timer, jiffies + timeout);
|
||||
|
||||
ath_dbg(common, CHAN_CTX,
|
||||
"Setup chanctx timer with timeout: %d ms\n", jiffies_to_msecs(tsf_time));
|
||||
"Setup chanctx timer with timeout: %d (%d) ms\n",
|
||||
tsf_time / 1000, jiffies_to_msecs(timeout));
|
||||
}
|
||||
|
||||
static void ath_chanctx_handle_bmiss(struct ath_softc *sc,
|
||||
@ -403,7 +419,7 @@ static void ath_chanctx_offchannel_noa(struct ath_softc *sc,
|
||||
avp->offchannel_duration = sc->sched.offchannel_duration;
|
||||
|
||||
ath_dbg(common, CHAN_CTX,
|
||||
"offchannel noa_duration: %d, noa_start: %d, noa_index: %d\n",
|
||||
"offchannel noa_duration: %d, noa_start: %u, noa_index: %d\n",
|
||||
avp->offchannel_duration,
|
||||
avp->offchannel_start,
|
||||
avp->noa_index);
|
||||
@ -443,7 +459,7 @@ static void ath_chanctx_set_periodic_noa(struct ath_softc *sc,
|
||||
avp->periodic_noa = true;
|
||||
|
||||
ath_dbg(common, CHAN_CTX,
|
||||
"noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n",
|
||||
"noa_duration: %d, noa_start: %u, noa_index: %d, periodic: %d\n",
|
||||
avp->noa_duration,
|
||||
avp->noa_start,
|
||||
avp->noa_index,
|
||||
@ -464,7 +480,7 @@ static void ath_chanctx_set_oneshot_noa(struct ath_softc *sc,
|
||||
avp->noa_duration = duration + sc->sched.channel_switch_time;
|
||||
|
||||
ath_dbg(common, CHAN_CTX,
|
||||
"oneshot noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n",
|
||||
"oneshot noa_duration: %d, noa_start: %u, noa_index: %d, periodic: %d\n",
|
||||
avp->noa_duration,
|
||||
avp->noa_start,
|
||||
avp->noa_index,
|
||||
@ -487,10 +503,11 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
|
||||
|
||||
spin_lock_bh(&sc->chan_lock);
|
||||
|
||||
ath_dbg(common, CHAN_CTX, "cur_chan: %d MHz, event: %s, state: %s\n",
|
||||
ath_dbg(common, CHAN_CTX, "cur_chan: %d MHz, event: %s, state: %s, delta: %u ms\n",
|
||||
sc->cur_chan->chandef.center_freq1,
|
||||
chanctx_event_string(ev),
|
||||
chanctx_state_string(sc->sched.state));
|
||||
chanctx_state_string(sc->sched.state),
|
||||
chanctx_event_delta(sc));
|
||||
|
||||
switch (ev) {
|
||||
case ATH_CHANCTX_EVENT_BEACON_PREPARE:
|
||||
@ -1099,6 +1116,7 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
|
||||
nullfunc->frame_control |=
|
||||
cpu_to_le16(IEEE80211_FCTL_PM);
|
||||
|
||||
skb->priority = 7;
|
||||
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
|
||||
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
@ -1401,8 +1419,9 @@ void ath9k_chanctx_wake_queues(struct ath_softc *sc, struct ath_chanctx *ctx)
|
||||
|
||||
static void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
s32 tsf, target_tsf;
|
||||
u32 tsf, target_tsf;
|
||||
|
||||
if (!avp || !avp->noa.has_next_tsf)
|
||||
return;
|
||||
@ -1414,11 +1433,17 @@ static void ath9k_update_p2p_ps_timer(struct ath_softc *sc, struct ath_vif *avp)
|
||||
target_tsf = avp->noa.next_tsf;
|
||||
if (!avp->noa.absent)
|
||||
target_tsf -= ATH_P2P_PS_STOP_TIME;
|
||||
else
|
||||
target_tsf += ATH_P2P_PS_STOP_TIME;
|
||||
|
||||
if (target_tsf - tsf < ATH_P2P_PS_STOP_TIME)
|
||||
target_tsf = tsf + ATH_P2P_PS_STOP_TIME;
|
||||
|
||||
ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, (u32) target_tsf, 1000000);
|
||||
ath_dbg(common, CHAN_CTX, "%s absent %d tsf 0x%08X next_tsf 0x%08X (%dms)\n",
|
||||
__func__, avp->noa.absent, tsf, target_tsf,
|
||||
(target_tsf - tsf) / 1000);
|
||||
|
||||
ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, target_tsf, 1000000);
|
||||
}
|
||||
|
||||
static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
|
||||
@ -1433,6 +1458,10 @@ static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
|
||||
return;
|
||||
|
||||
sc->p2p_ps_vif = avp;
|
||||
|
||||
if (sc->ps_flags & PS_BEACON_SYNC)
|
||||
return;
|
||||
|
||||
tsf = ath9k_hw_gettsf32(sc->sc_ah);
|
||||
ieee80211_parse_p2p_noa(&vif->bss_conf.p2p_noa_attr, &avp->noa, tsf);
|
||||
ath9k_update_p2p_ps_timer(sc, avp);
|
||||
@ -1495,6 +1524,8 @@ void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp,
|
||||
|
||||
noa->index = avp->noa_index;
|
||||
noa->oppps_ctwindow = ath9k_get_ctwin(sc, avp);
|
||||
if (noa->oppps_ctwindow)
|
||||
noa->oppps_ctwindow |= BIT(7);
|
||||
|
||||
if (avp->noa_duration) {
|
||||
if (avp->periodic_noa) {
|
||||
@ -1536,6 +1567,8 @@ void ath9k_p2p_ps_timer(void *priv)
|
||||
tsf = ath9k_hw_gettsf32(sc->sc_ah);
|
||||
if (!avp->noa.absent)
|
||||
tsf += ATH_P2P_PS_STOP_TIME;
|
||||
else
|
||||
tsf -= ATH_P2P_PS_STOP_TIME;
|
||||
|
||||
if (!avp->noa.has_next_tsf ||
|
||||
avp->noa.next_tsf - tsf > BIT(31))
|
||||
@ -1571,7 +1604,6 @@ void ath9k_p2p_bss_info_changed(struct ath_softc *sc,
|
||||
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
||||
if (!(sc->ps_flags & PS_BEACON_SYNC))
|
||||
ath9k_update_p2p_ps(sc, vif);
|
||||
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
@ -18,30 +18,16 @@
|
||||
|
||||
#define FUDGE 2
|
||||
|
||||
/* Calculate the modulo of a 64 bit TSF snapshot with a TU divisor */
|
||||
static u32 ath9k_mod_tsf64_tu(u64 tsf, u32 div_tu)
|
||||
{
|
||||
u32 tsf_mod, tsf_hi, tsf_lo, mod_hi, mod_lo;
|
||||
|
||||
tsf_mod = tsf & (BIT(10) - 1);
|
||||
tsf_hi = tsf >> 32;
|
||||
tsf_lo = ((u32) tsf) >> 10;
|
||||
|
||||
mod_hi = tsf_hi % div_tu;
|
||||
mod_lo = ((mod_hi << 22) + tsf_lo) % div_tu;
|
||||
|
||||
return (mod_lo << 10) | tsf_mod;
|
||||
}
|
||||
|
||||
static u32 ath9k_get_next_tbtt(struct ath_hw *ah, u64 tsf,
|
||||
unsigned int interval)
|
||||
{
|
||||
unsigned int offset;
|
||||
unsigned int offset, divisor;
|
||||
|
||||
tsf += TU_TO_USEC(FUDGE + ah->config.sw_beacon_response_time);
|
||||
offset = ath9k_mod_tsf64_tu(tsf, interval);
|
||||
divisor = TU_TO_USEC(interval);
|
||||
div_u64_rem(tsf, divisor, &offset);
|
||||
|
||||
return (u32) tsf + TU_TO_USEC(interval) - offset;
|
||||
return (u32) tsf + divisor - offset;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -138,6 +138,80 @@ bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size)
|
||||
{
|
||||
u16 magic;
|
||||
u16 *eepdata;
|
||||
int i;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
|
||||
ath_err(common, "Reading Magic # failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (magic == AR5416_EEPROM_MAGIC) {
|
||||
*swap_needed = false;
|
||||
} else if (swab16(magic) == AR5416_EEPROM_MAGIC) {
|
||||
if (ah->ah_flags & AH_NO_EEP_SWAP) {
|
||||
ath_info(common,
|
||||
"Ignoring endianness difference in EEPROM magic bytes.\n");
|
||||
|
||||
*swap_needed = false;
|
||||
} else {
|
||||
*swap_needed = true;
|
||||
}
|
||||
} else {
|
||||
ath_err(common,
|
||||
"Invalid EEPROM Magic (0x%04x).\n", magic);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
eepdata = (u16 *)(&ah->eeprom);
|
||||
|
||||
if (*swap_needed) {
|
||||
ath_dbg(common, EEPROM,
|
||||
"EEPROM Endianness is not native.. Changing.\n");
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
eepdata[i] = swab16(eepdata[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size)
|
||||
{
|
||||
u32 i, sum = 0;
|
||||
u16 *eepdata = (u16 *)(&ah->eeprom);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
sum ^= eepdata[i];
|
||||
|
||||
if (sum != 0xffff) {
|
||||
ath_err(common, "Bad EEPROM checksum 0x%x\n", sum);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ath9k_hw_nvram_check_version(struct ath_hw *ah, int version, int minrev)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (ah->eep_ops->get_eeprom_ver(ah) != version ||
|
||||
ah->eep_ops->get_eeprom_rev(ah) < minrev) {
|
||||
ath_err(common, "Bad EEPROM VER 0x%04x or REV 0x%04x\n",
|
||||
ah->eep_ops->get_eeprom_ver(ah),
|
||||
ah->eep_ops->get_eeprom_rev(ah));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
|
||||
u8 *pVpdList, u16 numIntercepts,
|
||||
u8 *pRetVpdList)
|
||||
|
@ -664,6 +664,9 @@ int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
|
||||
bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
|
||||
u16 *indexL, u16 *indexR);
|
||||
bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data);
|
||||
int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size);
|
||||
bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size);
|
||||
bool ath9k_hw_nvram_check_version(struct ath_hw *ah, int version, int minrev);
|
||||
void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
|
||||
int eep_start_loc, int size);
|
||||
void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
|
||||
|
@ -177,74 +177,30 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef SIZE_EEPROM_4K
|
||||
|
||||
static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
|
||||
{
|
||||
#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
|
||||
u16 *eepdata, temp, magic, magic2;
|
||||
u32 sum = 0, el;
|
||||
bool need_swap = false;
|
||||
int i, addr;
|
||||
u32 el;
|
||||
bool need_swap;
|
||||
int i, err;
|
||||
|
||||
|
||||
if (!ath9k_hw_use_flash(ah)) {
|
||||
if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
|
||||
&magic)) {
|
||||
ath_err(common, "Reading Magic # failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic);
|
||||
|
||||
if (magic != AR5416_EEPROM_MAGIC) {
|
||||
magic2 = swab16(magic);
|
||||
|
||||
if (magic2 == AR5416_EEPROM_MAGIC) {
|
||||
need_swap = true;
|
||||
eepdata = (u16 *) (&ah->eeprom);
|
||||
|
||||
for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
|
||||
temp = swab16(*eepdata);
|
||||
*eepdata = temp;
|
||||
eepdata++;
|
||||
}
|
||||
} else {
|
||||
ath_err(common,
|
||||
"Invalid EEPROM Magic. Endianness mismatch.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ath_dbg(common, EEPROM, "need_swap = %s\n",
|
||||
need_swap ? "True" : "False");
|
||||
err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_4K);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (need_swap)
|
||||
el = swab16(ah->eeprom.map4k.baseEepHeader.length);
|
||||
el = swab16(eep->baseEepHeader.length);
|
||||
else
|
||||
el = ah->eeprom.map4k.baseEepHeader.length;
|
||||
el = eep->baseEepHeader.length;
|
||||
|
||||
if (el > sizeof(struct ar5416_eeprom_4k))
|
||||
el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
|
||||
else
|
||||
el = el / sizeof(u16);
|
||||
|
||||
eepdata = (u16 *)(&ah->eeprom);
|
||||
|
||||
for (i = 0; i < el; i++)
|
||||
sum ^= *eepdata++;
|
||||
el = min(el / sizeof(u16), SIZE_EEPROM_4K);
|
||||
if (!ath9k_hw_nvram_validate_checksum(ah, el))
|
||||
return -EINVAL;
|
||||
|
||||
if (need_swap) {
|
||||
u32 integer;
|
||||
u16 word;
|
||||
|
||||
ath_dbg(common, EEPROM,
|
||||
"EEPROM Endianness is not native.. Changing\n");
|
||||
|
||||
word = swab16(eep->baseEepHeader.length);
|
||||
eep->baseEepHeader.length = word;
|
||||
|
||||
@ -283,17 +239,15 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
|
||||
}
|
||||
}
|
||||
|
||||
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
|
||||
ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
|
||||
ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
|
||||
sum, ah->eep_ops->get_eeprom_ver(ah));
|
||||
if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER,
|
||||
AR5416_EEP_NO_BACK_VER))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#undef EEPROM_4K_SIZE
|
||||
}
|
||||
|
||||
#undef SIZE_EEPROM_4K
|
||||
|
||||
static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
||||
enum eeprom_param param)
|
||||
{
|
||||
|
@ -177,59 +177,24 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
|
||||
|
||||
static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
|
||||
{
|
||||
u32 sum = 0, el, integer;
|
||||
u16 temp, word, magic, magic2, *eepdata;
|
||||
int i, addr;
|
||||
bool need_swap = false;
|
||||
u32 el, integer;
|
||||
u16 word;
|
||||
int i, err;
|
||||
bool need_swap;
|
||||
struct ar9287_eeprom *eep = &ah->eeprom.map9287;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (!ath9k_hw_use_flash(ah)) {
|
||||
if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
|
||||
&magic)) {
|
||||
ath_err(common, "Reading Magic # failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ath_dbg(common, EEPROM, "Read Magic = 0x%04X\n", magic);
|
||||
|
||||
if (magic != AR5416_EEPROM_MAGIC) {
|
||||
magic2 = swab16(magic);
|
||||
|
||||
if (magic2 == AR5416_EEPROM_MAGIC) {
|
||||
need_swap = true;
|
||||
eepdata = (u16 *)(&ah->eeprom);
|
||||
|
||||
for (addr = 0; addr < SIZE_EEPROM_AR9287; addr++) {
|
||||
temp = swab16(*eepdata);
|
||||
*eepdata = temp;
|
||||
eepdata++;
|
||||
}
|
||||
} else {
|
||||
ath_err(common,
|
||||
"Invalid EEPROM Magic. Endianness mismatch.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ath_dbg(common, EEPROM, "need_swap = %s\n",
|
||||
need_swap ? "True" : "False");
|
||||
err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_AR9287);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (need_swap)
|
||||
el = swab16(ah->eeprom.map9287.baseEepHeader.length);
|
||||
el = swab16(eep->baseEepHeader.length);
|
||||
else
|
||||
el = ah->eeprom.map9287.baseEepHeader.length;
|
||||
el = eep->baseEepHeader.length;
|
||||
|
||||
if (el > sizeof(struct ar9287_eeprom))
|
||||
el = sizeof(struct ar9287_eeprom) / sizeof(u16);
|
||||
else
|
||||
el = el / sizeof(u16);
|
||||
|
||||
eepdata = (u16 *)(&ah->eeprom);
|
||||
|
||||
for (i = 0; i < el; i++)
|
||||
sum ^= *eepdata++;
|
||||
el = min(el / sizeof(u16), SIZE_EEPROM_AR9287);
|
||||
if (!ath9k_hw_nvram_validate_checksum(ah, el))
|
||||
return -EINVAL;
|
||||
|
||||
if (need_swap) {
|
||||
word = swab16(eep->baseEepHeader.length);
|
||||
@ -270,16 +235,15 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
|
||||
}
|
||||
}
|
||||
|
||||
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
|
||||
|| ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
|
||||
ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
|
||||
sum, ah->eep_ops->get_eeprom_ver(ah));
|
||||
if (!ath9k_hw_nvram_check_version(ah, AR9287_EEP_VER,
|
||||
AR5416_EEP_NO_BACK_VER))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef SIZE_EEPROM_AR9287
|
||||
|
||||
static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
|
||||
enum eeprom_param param)
|
||||
{
|
||||
|
@ -126,8 +126,6 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
|
||||
return __ath9k_hw_def_fill_eeprom(ah);
|
||||
}
|
||||
|
||||
#undef SIZE_EEPROM_DEF
|
||||
|
||||
#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
|
||||
static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
|
||||
struct modal_eep_header *modal_hdr)
|
||||
@ -257,59 +255,31 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
|
||||
{
|
||||
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u16 *eepdata, temp, magic;
|
||||
u32 sum = 0, el;
|
||||
bool need_swap = false;
|
||||
int i, addr, size;
|
||||
u32 el;
|
||||
bool need_swap;
|
||||
int i, err;
|
||||
|
||||
if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
|
||||
ath_err(common, "Reading Magic # failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (swab16(magic) == AR5416_EEPROM_MAGIC &&
|
||||
!(ah->ah_flags & AH_NO_EEP_SWAP)) {
|
||||
size = sizeof(struct ar5416_eeprom_def);
|
||||
need_swap = true;
|
||||
eepdata = (u16 *) (&ah->eeprom);
|
||||
|
||||
for (addr = 0; addr < size / sizeof(u16); addr++) {
|
||||
temp = swab16(*eepdata);
|
||||
*eepdata = temp;
|
||||
eepdata++;
|
||||
}
|
||||
}
|
||||
|
||||
ath_dbg(common, EEPROM, "need_swap = %s\n",
|
||||
need_swap ? "True" : "False");
|
||||
err = ath9k_hw_nvram_swap_data(ah, &need_swap, SIZE_EEPROM_DEF);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (need_swap)
|
||||
el = swab16(ah->eeprom.def.baseEepHeader.length);
|
||||
el = swab16(eep->baseEepHeader.length);
|
||||
else
|
||||
el = ah->eeprom.def.baseEepHeader.length;
|
||||
el = eep->baseEepHeader.length;
|
||||
|
||||
if (el > sizeof(struct ar5416_eeprom_def))
|
||||
el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
|
||||
else
|
||||
el = el / sizeof(u16);
|
||||
|
||||
eepdata = (u16 *)(&ah->eeprom);
|
||||
|
||||
for (i = 0; i < el; i++)
|
||||
sum ^= *eepdata++;
|
||||
el = min(el / sizeof(u16), SIZE_EEPROM_DEF);
|
||||
if (!ath9k_hw_nvram_validate_checksum(ah, el))
|
||||
return -EINVAL;
|
||||
|
||||
if (need_swap) {
|
||||
u32 integer, j;
|
||||
u16 word;
|
||||
|
||||
ath_dbg(common, EEPROM,
|
||||
"EEPROM Endianness is not native.. Changing.\n");
|
||||
|
||||
word = swab16(eep->baseEepHeader.length);
|
||||
eep->baseEepHeader.length = word;
|
||||
|
||||
@ -356,12 +326,9 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
|
||||
}
|
||||
}
|
||||
|
||||
if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
|
||||
ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
|
||||
ath_err(common, "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
|
||||
sum, ah->eep_ops->get_eeprom_ver(ah));
|
||||
if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER,
|
||||
AR5416_EEP_NO_BACK_VER))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Enable fixup for AR_AN_TOP2 if necessary */
|
||||
if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
|
||||
@ -376,6 +343,8 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef SIZE_EEPROM_DEF
|
||||
|
||||
static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
|
||||
enum eeprom_param param)
|
||||
{
|
||||
|
@ -2299,10 +2299,10 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
|
||||
else
|
||||
nextTbtt = bs->bs_nexttbtt;
|
||||
|
||||
ath_dbg(common, BEACON, "next DTIM %d\n", bs->bs_nextdtim);
|
||||
ath_dbg(common, BEACON, "next beacon %d\n", nextTbtt);
|
||||
ath_dbg(common, BEACON, "beacon period %d\n", beaconintval);
|
||||
ath_dbg(common, BEACON, "DTIM period %d\n", dtimperiod);
|
||||
ath_dbg(common, BEACON, "next DTIM %u\n", bs->bs_nextdtim);
|
||||
ath_dbg(common, BEACON, "next beacon %u\n", nextTbtt);
|
||||
ath_dbg(common, BEACON, "beacon period %u\n", beaconintval);
|
||||
ath_dbg(common, BEACON, "DTIM period %u\n", dtimperiod);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
@ -2761,9 +2761,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER;
|
||||
|
||||
REG_WRITE(ah, AR_RX_FILTER, bits);
|
||||
|
||||
phybits = 0;
|
||||
|
@ -739,6 +739,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
ath9k_rng_start(sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -828,6 +830,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
||||
|
||||
ath9k_deinit_channel_context(sc);
|
||||
|
||||
ath9k_rng_stop(sc);
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
ath_cancel_work(sc);
|
||||
|
@ -424,6 +424,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
|
||||
AR_SREV_9561(sc->sc_ah))
|
||||
rfilt |= ATH9K_RX_FILTER_4ADDRESS;
|
||||
|
||||
if (AR_SREV_9462(sc->sc_ah) || AR_SREV_9565(sc->sc_ah))
|
||||
rfilt |= ATH9K_RX_FILTER_CONTROL_WRAPPER;
|
||||
|
||||
if (ath9k_is_chanctx_enabled() &&
|
||||
test_bit(ATH_OP_SCANNING, &common->op_flags))
|
||||
rfilt |= ATH9K_RX_FILTER_BEACON;
|
||||
|
107
drivers/net/wireless/ath/ath9k/rng.c
Normal file
107
drivers/net/wireless/ath/ath9k/rng.c
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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/hw_random.h>
|
||||
#include <linux/kthread.h>
|
||||
|
||||
#include "ath9k.h"
|
||||
#include "hw.h"
|
||||
#include "ar9003_phy.h"
|
||||
|
||||
#define ATH9K_RNG_BUF_SIZE 320
|
||||
#define ATH9K_RNG_ENTROPY(x) (((x) * 8 * 320) >> 10) /* quality: 320/1024 */
|
||||
|
||||
static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size)
|
||||
{
|
||||
int i, j;
|
||||
u32 v1, v2, rng_last = sc->rng_last;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
|
||||
REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0);
|
||||
|
||||
for (i = 0, j = 0; i < buf_size; i++) {
|
||||
v1 = REG_READ(ah, AR_PHY_TST_ADC) & 0xffff;
|
||||
v2 = REG_READ(ah, AR_PHY_TST_ADC) & 0xffff;
|
||||
|
||||
/* wait for data ready */
|
||||
if (v1 && v2 && rng_last != v1 && v1 != v2 && v1 != 0xffff &&
|
||||
v2 != 0xffff)
|
||||
buf[j++] = (v1 << 16) | v2;
|
||||
|
||||
rng_last = v2;
|
||||
}
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
sc->rng_last = rng_last;
|
||||
|
||||
return j << 2;
|
||||
}
|
||||
|
||||
static int ath9k_rng_kthread(void *data)
|
||||
{
|
||||
int bytes_read;
|
||||
struct ath_softc *sc = data;
|
||||
u32 *rng_buf;
|
||||
|
||||
rng_buf = kmalloc_array(ATH9K_RNG_BUF_SIZE, sizeof(u32), GFP_KERNEL);
|
||||
if (!rng_buf)
|
||||
goto out;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
bytes_read = ath9k_rng_data_read(sc, rng_buf,
|
||||
ATH9K_RNG_BUF_SIZE);
|
||||
if (unlikely(!bytes_read)) {
|
||||
msleep_interruptible(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sleep until entropy bits under write_wakeup_threshold */
|
||||
add_hwgenerator_randomness((void *)rng_buf, bytes_read,
|
||||
ATH9K_RNG_ENTROPY(bytes_read));
|
||||
}
|
||||
|
||||
kfree(rng_buf);
|
||||
out:
|
||||
sc->rng_task = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath9k_rng_start(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
||||
if (sc->rng_task)
|
||||
return;
|
||||
|
||||
if (!AR_SREV_9300_20_OR_LATER(ah))
|
||||
return;
|
||||
|
||||
sc->rng_task = kthread_run(ath9k_rng_kthread, sc, "ath9k-hwrng");
|
||||
if (IS_ERR(sc->rng_task))
|
||||
sc->rng_task = NULL;
|
||||
}
|
||||
|
||||
void ath9k_rng_stop(struct ath_softc *sc)
|
||||
{
|
||||
if (sc->rng_task)
|
||||
kthread_stop(sc->rng_task);
|
||||
}
|
@ -1473,11 +1473,14 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
u16 tid, u16 *ssn)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_atx_tid *txtid;
|
||||
struct ath_txq *txq;
|
||||
struct ath_node *an;
|
||||
u8 density;
|
||||
|
||||
ath_dbg(common, XMIT, "%s called\n", __func__);
|
||||
|
||||
an = (struct ath_node *)sta->drv_priv;
|
||||
txtid = ATH_AN_2_TID(an, tid);
|
||||
txq = txtid->txq;
|
||||
@ -1512,10 +1515,13 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
|
||||
void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_node *an = (struct ath_node *)sta->drv_priv;
|
||||
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
|
||||
struct ath_txq *txq = txtid->txq;
|
||||
|
||||
ath_dbg(common, XMIT, "%s called\n", __func__);
|
||||
|
||||
ath_txq_lock(sc, txq);
|
||||
txtid->active = false;
|
||||
ath_tx_flush_tid(sc, txtid);
|
||||
@ -1526,11 +1532,14 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
|
||||
void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
|
||||
struct ath_node *an)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_atx_tid *tid;
|
||||
struct ath_txq *txq;
|
||||
bool buffered;
|
||||
int tidno;
|
||||
|
||||
ath_dbg(common, XMIT, "%s called\n", __func__);
|
||||
|
||||
for (tidno = 0, tid = &an->tid[tidno];
|
||||
tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
|
||||
|
||||
@ -1555,10 +1564,13 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
|
||||
|
||||
void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_atx_tid *tid;
|
||||
struct ath_txq *txq;
|
||||
int tidno;
|
||||
|
||||
ath_dbg(common, XMIT, "%s called\n", __func__);
|
||||
|
||||
for (tidno = 0, tid = &an->tid[tidno];
|
||||
tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
|
||||
|
||||
@ -1579,10 +1591,13 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
|
||||
void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
u16 tidno)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_atx_tid *tid;
|
||||
struct ath_node *an;
|
||||
struct ath_txq *txq;
|
||||
|
||||
ath_dbg(common, XMIT, "%s called\n", __func__);
|
||||
|
||||
an = (struct ath_node *)sta->drv_priv;
|
||||
tid = ATH_AN_2_TID(an, tidno);
|
||||
txq = tid->txq;
|
||||
@ -2316,6 +2331,12 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
|
||||
queue = ieee80211_is_data_present(hdr->frame_control);
|
||||
|
||||
/* If chanctx, queue all null frames while NOA could be there */
|
||||
if (ath9k_is_chanctx_enabled() &&
|
||||
ieee80211_is_nullfunc(hdr->frame_control) &&
|
||||
!txctl->force_channel)
|
||||
queue = true;
|
||||
|
||||
/* Force queueing of all frames that belong to a virtual interface on
|
||||
* a different channel context, to ensure that they are sent on the
|
||||
* correct channel.
|
||||
|
@ -781,8 +781,10 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
|
||||
wil_bcast_fini(wil);
|
||||
|
||||
/* prevent NAPI from being scheduled */
|
||||
/* prevent NAPI from being scheduled and prevent wmi commands */
|
||||
mutex_lock(&wil->wmi_mutex);
|
||||
bitmap_zero(wil->status, wil_status_last);
|
||||
mutex_unlock(&wil->wmi_mutex);
|
||||
|
||||
if (wil->scan_request) {
|
||||
wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
|
||||
|
@ -228,6 +228,10 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
|
||||
wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head);
|
||||
/* wait till FW finish with previous command */
|
||||
for (retry = 5; retry > 0; retry--) {
|
||||
if (!test_bit(wil_status_fwready, wil->status)) {
|
||||
wil_err(wil, "WMI: cannot send command while FW not ready\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
r->tail = wil_r(wil, RGF_MBOX +
|
||||
offsetof(struct wil6210_mbox_ctl, tx.tail));
|
||||
if (next_head != r->tail)
|
||||
|
@ -91,6 +91,10 @@
|
||||
#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
|
||||
#define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
|
||||
|
||||
#define BRCMF_SCAN_CHANNEL_TIME 40
|
||||
#define BRCMF_SCAN_UNASSOC_TIME 40
|
||||
#define BRCMF_SCAN_PASSIVE_TIME 120
|
||||
|
||||
#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
|
||||
(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
|
||||
|
||||
@ -392,15 +396,23 @@ static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
|
||||
{
|
||||
int iftype_num[NUM_NL80211_IFTYPES];
|
||||
struct brcmf_cfg80211_vif *pos;
|
||||
bool check_combos = false;
|
||||
int ret = 0;
|
||||
|
||||
memset(&iftype_num[0], 0, sizeof(iftype_num));
|
||||
list_for_each_entry(pos, &cfg->vif_list, list)
|
||||
if (pos == vif)
|
||||
if (pos == vif) {
|
||||
iftype_num[new_type]++;
|
||||
else
|
||||
} else {
|
||||
/* concurrent interfaces so need check combinations */
|
||||
check_combos = true;
|
||||
iftype_num[pos->wdev.iftype]++;
|
||||
}
|
||||
|
||||
return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
|
||||
if (check_combos)
|
||||
ret = cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
|
||||
@ -1027,11 +1039,11 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
|
||||
struct brcmf_if *ifp = vif->ifp;
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct cfg80211_ssid *ssids;
|
||||
struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
|
||||
u32 passive_scan;
|
||||
bool escan_req;
|
||||
bool spec_scan;
|
||||
s32 err;
|
||||
struct brcmf_ssid_le ssid_le;
|
||||
u32 SSID_len;
|
||||
|
||||
brcmf_dbg(SCAN, "START ESCAN\n");
|
||||
@ -1084,13 +1096,13 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
|
||||
} else {
|
||||
brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
|
||||
ssids->ssid, ssids->ssid_len);
|
||||
memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
|
||||
SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
|
||||
sr->ssid_le.SSID_len = cpu_to_le32(0);
|
||||
memset(&ssid_le, 0, sizeof(ssid_le));
|
||||
SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len);
|
||||
ssid_le.SSID_len = cpu_to_le32(0);
|
||||
spec_scan = false;
|
||||
if (SSID_len) {
|
||||
memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
|
||||
sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
|
||||
memcpy(ssid_le.SSID, ssids->ssid, SSID_len);
|
||||
ssid_le.SSID_len = cpu_to_le32(SSID_len);
|
||||
spec_scan = true;
|
||||
} else
|
||||
brcmf_dbg(SCAN, "Broadcast scan\n");
|
||||
@ -1103,12 +1115,12 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
|
||||
goto scan_out;
|
||||
}
|
||||
brcmf_scan_config_mpc(ifp, 0);
|
||||
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
|
||||
&sr->ssid_le, sizeof(sr->ssid_le));
|
||||
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le,
|
||||
sizeof(ssid_le));
|
||||
if (err) {
|
||||
if (err == -EBUSY)
|
||||
brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
|
||||
sr->ssid_le.SSID);
|
||||
ssid_le.SSID);
|
||||
else
|
||||
brcmf_err("WLC_SCAN error (%d)\n", err);
|
||||
|
||||
@ -1261,17 +1273,17 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
|
||||
if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
|
||||
brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
|
||||
err = brcmf_fil_cmd_data_set(vif->ifp,
|
||||
BRCMF_C_DISASSOC, NULL, 0);
|
||||
if (err) {
|
||||
brcmf_err("WLC_DISASSOC failed (%d)\n", err);
|
||||
}
|
||||
clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
|
||||
if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
|
||||
(vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
|
||||
cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
|
||||
true, GFP_KERNEL);
|
||||
|
||||
}
|
||||
clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
|
||||
clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
|
||||
@ -2685,7 +2697,7 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
|
||||
return err;
|
||||
}
|
||||
|
||||
static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
|
||||
static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
|
||||
struct net_device *ndev, const u8 *bssid)
|
||||
{
|
||||
struct wiphy *wiphy = cfg_to_wiphy(cfg);
|
||||
@ -2731,6 +2743,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
|
||||
band = wiphy->bands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
|
||||
cfg->channel = freq;
|
||||
notify_channel = ieee80211_get_channel(wiphy, freq);
|
||||
|
||||
notify_capability = le16_to_cpu(bi->capability);
|
||||
@ -3219,26 +3232,22 @@ exit:
|
||||
}
|
||||
|
||||
static __used s32
|
||||
brcmf_update_pmklist(struct net_device *ndev,
|
||||
struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
|
||||
brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
|
||||
{
|
||||
int i, j;
|
||||
u32 pmkid_len;
|
||||
struct brcmf_pmk_list_le *pmk_list;
|
||||
int i;
|
||||
u32 npmk;
|
||||
s32 err;
|
||||
|
||||
pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
|
||||
pmk_list = &cfg->pmk_list;
|
||||
npmk = le32_to_cpu(pmk_list->npmk);
|
||||
|
||||
brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
|
||||
for (i = 0; i < pmkid_len; i++) {
|
||||
brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
|
||||
&pmk_list->pmkids.pmkid[i].BSSID);
|
||||
for (j = 0; j < WLAN_PMKID_LEN; j++)
|
||||
brcmf_dbg(CONN, "%02x\n",
|
||||
pmk_list->pmkids.pmkid[i].PMKID[j]);
|
||||
}
|
||||
brcmf_dbg(CONN, "No of elements %d\n", npmk);
|
||||
for (i = 0; i < npmk; i++)
|
||||
brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
|
||||
|
||||
if (!err)
|
||||
brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
|
||||
(char *)pmk_list, sizeof(*pmk_list));
|
||||
err = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
|
||||
sizeof(*pmk_list));
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -3249,34 +3258,37 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
|
||||
s32 err = 0;
|
||||
u32 pmkid_len, i;
|
||||
struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
|
||||
s32 err;
|
||||
u32 npmk, i;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
if (!check_vif_up(ifp->vif))
|
||||
return -EIO;
|
||||
|
||||
pmkid_len = le32_to_cpu(pmkids->npmkid);
|
||||
for (i = 0; i < pmkid_len; i++)
|
||||
if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
|
||||
npmk = le32_to_cpu(cfg->pmk_list.npmk);
|
||||
for (i = 0; i < npmk; i++)
|
||||
if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
|
||||
break;
|
||||
if (i < WL_NUM_PMKIDS_MAX) {
|
||||
memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
|
||||
memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
|
||||
if (i == pmkid_len) {
|
||||
pmkid_len++;
|
||||
pmkids->npmkid = cpu_to_le32(pmkid_len);
|
||||
if (i < BRCMF_MAXPMKID) {
|
||||
memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
|
||||
memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
|
||||
if (i == npmk) {
|
||||
npmk++;
|
||||
cfg->pmk_list.npmk = cpu_to_le32(npmk);
|
||||
}
|
||||
} else {
|
||||
brcmf_err("Too many PMKSA entries cached %d\n", npmk);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else
|
||||
err = -EINVAL;
|
||||
|
||||
brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
|
||||
pmkids->pmkid[pmkid_len].BSSID);
|
||||
for (i = 0; i < WLAN_PMKID_LEN; i++)
|
||||
brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
|
||||
brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid);
|
||||
for (i = 0; i < WLAN_PMKID_LEN; i += 4)
|
||||
brcmf_dbg(CONN, "%02x %02x %02x %02x\n", pmk[npmk].pmkid[i],
|
||||
pmk[npmk].pmkid[i + 1], pmk[npmk].pmkid[i + 2],
|
||||
pmk[npmk].pmkid[i + 3]);
|
||||
|
||||
err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
|
||||
err = brcmf_update_pmklist(cfg, ifp);
|
||||
|
||||
brcmf_dbg(TRACE, "Exit\n");
|
||||
return err;
|
||||
@ -3288,46 +3300,35 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
struct pmkid_list pmkid;
|
||||
s32 err = 0;
|
||||
u32 pmkid_len, i;
|
||||
struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
|
||||
s32 err;
|
||||
u32 npmk, i;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
if (!check_vif_up(ifp->vif))
|
||||
return -EIO;
|
||||
|
||||
memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
|
||||
memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
|
||||
brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid);
|
||||
|
||||
brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
|
||||
&pmkid.pmkid[0].BSSID);
|
||||
for (i = 0; i < WLAN_PMKID_LEN; i++)
|
||||
brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
|
||||
|
||||
pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
|
||||
for (i = 0; i < pmkid_len; i++)
|
||||
if (!memcmp
|
||||
(pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
|
||||
ETH_ALEN))
|
||||
npmk = le32_to_cpu(cfg->pmk_list.npmk);
|
||||
for (i = 0; i < npmk; i++)
|
||||
if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN))
|
||||
break;
|
||||
|
||||
if ((pmkid_len > 0)
|
||||
&& (i < pmkid_len)) {
|
||||
memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
|
||||
sizeof(struct pmkid));
|
||||
for (; i < (pmkid_len - 1); i++) {
|
||||
memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
|
||||
&cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
|
||||
ETH_ALEN);
|
||||
memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
|
||||
&cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
|
||||
if ((npmk > 0) && (i < npmk)) {
|
||||
for (; i < (npmk - 1); i++) {
|
||||
memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
|
||||
memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
|
||||
WLAN_PMKID_LEN);
|
||||
}
|
||||
cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
|
||||
} else
|
||||
err = -EINVAL;
|
||||
memset(&pmk[i], 0, sizeof(*pmk));
|
||||
cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
|
||||
} else {
|
||||
brcmf_err("Cache entry not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
|
||||
err = brcmf_update_pmklist(cfg, ifp);
|
||||
|
||||
brcmf_dbg(TRACE, "Exit\n");
|
||||
return err;
|
||||
@ -3339,14 +3340,14 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
s32 err = 0;
|
||||
s32 err;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
if (!check_vif_up(ifp->vif))
|
||||
return -EIO;
|
||||
|
||||
memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
|
||||
err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
|
||||
memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
|
||||
err = brcmf_update_pmklist(cfg, ifp);
|
||||
|
||||
brcmf_dbg(TRACE, "Exit\n");
|
||||
return err;
|
||||
@ -5071,9 +5072,9 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
|
||||
} else if (brcmf_is_linkup(e)) {
|
||||
brcmf_dbg(CONN, "Linkup\n");
|
||||
if (brcmf_is_ibssmode(ifp->vif)) {
|
||||
brcmf_inform_ibss(cfg, ndev, e->addr);
|
||||
chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
|
||||
memcpy(profile->bssid, e->addr, ETH_ALEN);
|
||||
wl_inform_ibss(cfg, ndev, e->addr);
|
||||
cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
|
||||
clear_bit(BRCMF_VIF_STATUS_CONNECTING,
|
||||
&ifp->vif->sme_state);
|
||||
@ -5199,7 +5200,6 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
|
||||
conf->rts_threshold = (u32)-1;
|
||||
conf->retry_short = (u32)-1;
|
||||
conf->retry_long = (u32)-1;
|
||||
conf->tx_power = -1;
|
||||
}
|
||||
|
||||
static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
|
||||
@ -5246,8 +5246,6 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
|
||||
cfg->escan_ioctl_buf = NULL;
|
||||
kfree(cfg->extra_buf);
|
||||
cfg->extra_buf = NULL;
|
||||
kfree(cfg->pmk_list);
|
||||
cfg->pmk_list = NULL;
|
||||
}
|
||||
|
||||
static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
|
||||
@ -5261,9 +5259,6 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
|
||||
cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
|
||||
if (!cfg->extra_buf)
|
||||
goto init_priv_mem_out;
|
||||
cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
|
||||
if (!cfg->pmk_list)
|
||||
goto init_priv_mem_out;
|
||||
|
||||
return 0;
|
||||
|
||||
@ -5357,36 +5352,26 @@ roam_setup_done:
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
|
||||
s32 scan_unassoc_time, s32 scan_passive_time)
|
||||
brcmf_dongle_scantime(struct brcmf_if *ifp)
|
||||
{
|
||||
s32 err = 0;
|
||||
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
|
||||
scan_assoc_time);
|
||||
BRCMF_SCAN_CHANNEL_TIME);
|
||||
if (err) {
|
||||
if (err == -EOPNOTSUPP)
|
||||
brcmf_dbg(INFO, "Scan assoc time is not supported\n");
|
||||
else
|
||||
brcmf_err("Scan assoc time error (%d)\n", err);
|
||||
goto dongle_scantime_out;
|
||||
}
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
|
||||
scan_unassoc_time);
|
||||
BRCMF_SCAN_UNASSOC_TIME);
|
||||
if (err) {
|
||||
if (err == -EOPNOTSUPP)
|
||||
brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
|
||||
else
|
||||
brcmf_err("Scan unassoc time error (%d)\n", err);
|
||||
goto dongle_scantime_out;
|
||||
}
|
||||
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
|
||||
scan_passive_time);
|
||||
BRCMF_SCAN_PASSIVE_TIME);
|
||||
if (err) {
|
||||
if (err == -EOPNOTSUPP)
|
||||
brcmf_dbg(INFO, "Scan passive time is not supported\n");
|
||||
else
|
||||
brcmf_err("Scan passive time error (%d)\n", err);
|
||||
goto dongle_scantime_out;
|
||||
}
|
||||
@ -5978,7 +5963,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
|
||||
wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
|
||||
wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
|
||||
wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
|
||||
wiphy->max_num_pmkids = BRCMF_MAXPMKID;
|
||||
|
||||
err = brcmf_setup_ifmodes(wiphy, ifp);
|
||||
if (err)
|
||||
@ -6007,8 +5992,9 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
|
||||
wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
|
||||
wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
|
||||
WIPHY_FLAG_OFFCHAN_TX |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_SUPPORTS_TDLS;
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
|
||||
wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
|
||||
if (!brcmf_roamoff)
|
||||
wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
|
||||
wiphy->mgmt_stypes = brcmf_txrx_stypes;
|
||||
@ -6089,8 +6075,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
|
||||
/* make sure RF is ready for work */
|
||||
brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
|
||||
|
||||
brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
|
||||
WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
|
||||
brcmf_dongle_scantime(ifp);
|
||||
|
||||
power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
|
||||
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
|
||||
@ -6401,6 +6386,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
|
||||
goto wiphy_unreg_out;
|
||||
}
|
||||
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
|
||||
err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
|
||||
if (err) {
|
||||
brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
|
||||
@ -6409,6 +6395,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
|
||||
brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
|
||||
brcmf_notify_tdls_peer_event);
|
||||
}
|
||||
}
|
||||
|
||||
/* (re-) activate FWEH event handling */
|
||||
err = brcmf_fweh_activate_events(ifp);
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <brcmu_d11.h>
|
||||
|
||||
#define WL_NUM_SCAN_MAX 10
|
||||
#define WL_NUM_PMKIDS_MAX MAXPMKID
|
||||
#define WL_TLV_INFO_MAX 1024
|
||||
#define WL_BSS_INFO_MAX 2048
|
||||
#define WL_ASSOC_INFO_MAX 512 /* assoc related fil max buf */
|
||||
@ -29,10 +28,6 @@
|
||||
#define WL_ROAM_TRIGGER_LEVEL -75
|
||||
#define WL_ROAM_DELTA 20
|
||||
|
||||
#define WL_SCAN_CHANNEL_TIME 40
|
||||
#define WL_SCAN_UNASSOC_TIME 40
|
||||
#define WL_SCAN_PASSIVE_TIME 120
|
||||
|
||||
#define WL_ESCAN_BUF_SIZE (1024 * 64)
|
||||
#define WL_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */
|
||||
|
||||
@ -99,19 +94,6 @@ struct brcmf_cfg80211_conf {
|
||||
u32 rts_threshold;
|
||||
u32 retry_short;
|
||||
u32 retry_long;
|
||||
s32 tx_power;
|
||||
struct ieee80211_channel channel;
|
||||
};
|
||||
|
||||
/* basic structure of scan request */
|
||||
struct brcmf_cfg80211_scan_req {
|
||||
struct brcmf_ssid_le ssid_le;
|
||||
};
|
||||
|
||||
/* basic structure of information element */
|
||||
struct brcmf_cfg80211_ie {
|
||||
u16 offset;
|
||||
u8 buf[WL_TLV_INFO_MAX];
|
||||
};
|
||||
|
||||
/* security information with currently associated ap */
|
||||
@ -213,12 +195,6 @@ struct brcmf_cfg80211_assoc_ielen_le {
|
||||
__le32 resp_len;
|
||||
};
|
||||
|
||||
/* wpa2 pmk list */
|
||||
struct brcmf_cfg80211_pmk_list {
|
||||
struct pmkid_list pmkids;
|
||||
struct pmkid foo[MAXPMKID - 1];
|
||||
};
|
||||
|
||||
/* dongle escan state */
|
||||
enum wl_escan_state {
|
||||
WL_ESCAN_STATE_IDLE,
|
||||
@ -234,87 +210,6 @@ struct escan_info {
|
||||
struct cfg80211_scan_request *request);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pno_param_le - PNO scan configuration parameters
|
||||
*
|
||||
* @version: PNO parameters version.
|
||||
* @scan_freq: scan frequency.
|
||||
* @lost_network_timeout: #sec. to declare discovered network as lost.
|
||||
* @flags: Bit field to control features of PFN such as sort criteria auto
|
||||
* enable switch and background scan.
|
||||
* @rssi_margin: Margin to avoid jitter for choosing a PFN based on RSSI sort
|
||||
* criteria.
|
||||
* @bestn: number of best networks in each scan.
|
||||
* @mscan: number of scans recorded.
|
||||
* @repeat: minimum number of scan intervals before scan frequency changes
|
||||
* in adaptive scan.
|
||||
* @exp: exponent of 2 for maximum scan interval.
|
||||
* @slow_freq: slow scan period.
|
||||
*/
|
||||
struct brcmf_pno_param_le {
|
||||
__le32 version;
|
||||
__le32 scan_freq;
|
||||
__le32 lost_network_timeout;
|
||||
__le16 flags;
|
||||
__le16 rssi_margin;
|
||||
u8 bestn;
|
||||
u8 mscan;
|
||||
u8 repeat;
|
||||
u8 exp;
|
||||
__le32 slow_freq;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pno_net_param_le - scan parameters per preferred network.
|
||||
*
|
||||
* @ssid: ssid name and its length.
|
||||
* @flags: bit2: hidden.
|
||||
* @infra: BSS vs IBSS.
|
||||
* @auth: Open vs Closed.
|
||||
* @wpa_auth: WPA type.
|
||||
* @wsec: wsec value.
|
||||
*/
|
||||
struct brcmf_pno_net_param_le {
|
||||
struct brcmf_ssid_le ssid;
|
||||
__le32 flags;
|
||||
__le32 infra;
|
||||
__le32 auth;
|
||||
__le32 wpa_auth;
|
||||
__le32 wsec;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pno_net_info_le - information per found network.
|
||||
*
|
||||
* @bssid: BSS network identifier.
|
||||
* @channel: channel number only.
|
||||
* @SSID_len: length of ssid.
|
||||
* @SSID: ssid characters.
|
||||
* @RSSI: receive signal strength (in dBm).
|
||||
* @timestamp: age in seconds.
|
||||
*/
|
||||
struct brcmf_pno_net_info_le {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 channel;
|
||||
u8 SSID_len;
|
||||
u8 SSID[32];
|
||||
__le16 RSSI;
|
||||
__le16 timestamp;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pno_scanresults_le - result returned in PNO NET FOUND event.
|
||||
*
|
||||
* @version: PNO version identifier.
|
||||
* @status: indicates completion status of PNO scan.
|
||||
* @count: amount of brcmf_pno_net_info_le entries appended.
|
||||
*/
|
||||
struct brcmf_pno_scanresults_le {
|
||||
__le32 version;
|
||||
__le32 status;
|
||||
__le32 count;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_cfg80211_vif_event - virtual interface event information.
|
||||
*
|
||||
@ -341,9 +236,7 @@ struct brcmf_cfg80211_vif_event {
|
||||
* @scan_request: cfg80211 scan request object.
|
||||
* @usr_sync: mainly for dongle up/down synchronization.
|
||||
* @bss_list: bss_list holding scanned ap information.
|
||||
* @scan_req_int: internal scan request object.
|
||||
* @bss_info: bss information for cfg80211 layer.
|
||||
* @ie: information element object for internal purpose.
|
||||
* @conn_info: association info.
|
||||
* @pmk_list: wpa2 pmk list.
|
||||
* @scan_status: scan activity on the dongle.
|
||||
@ -376,11 +269,9 @@ struct brcmf_cfg80211_info {
|
||||
struct brcmf_btcoex_info *btcoex;
|
||||
struct cfg80211_scan_request *scan_request;
|
||||
struct mutex usr_sync;
|
||||
struct brcmf_cfg80211_scan_req scan_req_int;
|
||||
struct wl_cfg80211_bss_info *bss_info;
|
||||
struct brcmf_cfg80211_ie ie;
|
||||
struct brcmf_cfg80211_connect_info conn_info;
|
||||
struct brcmf_cfg80211_pmk_list *pmk_list;
|
||||
struct brcmf_pmk_list_le pmk_list;
|
||||
unsigned long scan_status;
|
||||
struct brcmf_pub *pub;
|
||||
u32 channel;
|
||||
|
@ -138,6 +138,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
|
||||
brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
|
||||
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
|
||||
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
|
||||
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
|
||||
|
||||
if (brcmf_feature_disable) {
|
||||
brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n",
|
||||
|
@ -25,6 +25,7 @@
|
||||
* WOWL: Wake-On-WLAN.
|
||||
* P2P: peer-to-peer
|
||||
* RSDB: Real Simultaneous Dual Band
|
||||
* TDLS: Tunneled Direct Link Setup
|
||||
*/
|
||||
#define BRCMF_FEAT_LIST \
|
||||
BRCMF_FEAT_DEF(MBSS) \
|
||||
@ -32,7 +33,8 @@
|
||||
BRCMF_FEAT_DEF(PNO) \
|
||||
BRCMF_FEAT_DEF(WOWL) \
|
||||
BRCMF_FEAT_DEF(P2P) \
|
||||
BRCMF_FEAT_DEF(RSDB)
|
||||
BRCMF_FEAT_DEF(RSDB) \
|
||||
BRCMF_FEAT_DEF(TDLS)
|
||||
|
||||
/*
|
||||
* Quirks:
|
||||
|
@ -126,6 +126,8 @@
|
||||
#define BRCMF_TXBF_SU_BFR_CAP BIT(0)
|
||||
#define BRCMF_TXBF_MU_BFR_CAP BIT(1)
|
||||
|
||||
#define BRCMF_MAXPMKID 16 /* max # PMKID cache entries */
|
||||
|
||||
/* join preference types for join_pref iovar */
|
||||
enum brcmf_join_pref_types {
|
||||
BRCMF_JOIN_PREF_RSSI = 1,
|
||||
@ -646,4 +648,107 @@ struct brcmf_wowl_wakeind_le {
|
||||
__le32 ucode_wakeind;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pmksa - PMK Security Association
|
||||
*
|
||||
* @bssid: The AP's BSSID.
|
||||
* @pmkid: he PMK material itself.
|
||||
*/
|
||||
struct brcmf_pmksa {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 pmkid[WLAN_PMKID_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pmk_list_le - List of pmksa's.
|
||||
*
|
||||
* @npmk: Number of pmksa's.
|
||||
* @pmk: PMK SA information.
|
||||
*/
|
||||
struct brcmf_pmk_list_le {
|
||||
__le32 npmk;
|
||||
struct brcmf_pmksa pmk[BRCMF_MAXPMKID];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pno_param_le - PNO scan configuration parameters
|
||||
*
|
||||
* @version: PNO parameters version.
|
||||
* @scan_freq: scan frequency.
|
||||
* @lost_network_timeout: #sec. to declare discovered network as lost.
|
||||
* @flags: Bit field to control features of PFN such as sort criteria auto
|
||||
* enable switch and background scan.
|
||||
* @rssi_margin: Margin to avoid jitter for choosing a PFN based on RSSI sort
|
||||
* criteria.
|
||||
* @bestn: number of best networks in each scan.
|
||||
* @mscan: number of scans recorded.
|
||||
* @repeat: minimum number of scan intervals before scan frequency changes
|
||||
* in adaptive scan.
|
||||
* @exp: exponent of 2 for maximum scan interval.
|
||||
* @slow_freq: slow scan period.
|
||||
*/
|
||||
struct brcmf_pno_param_le {
|
||||
__le32 version;
|
||||
__le32 scan_freq;
|
||||
__le32 lost_network_timeout;
|
||||
__le16 flags;
|
||||
__le16 rssi_margin;
|
||||
u8 bestn;
|
||||
u8 mscan;
|
||||
u8 repeat;
|
||||
u8 exp;
|
||||
__le32 slow_freq;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pno_net_param_le - scan parameters per preferred network.
|
||||
*
|
||||
* @ssid: ssid name and its length.
|
||||
* @flags: bit2: hidden.
|
||||
* @infra: BSS vs IBSS.
|
||||
* @auth: Open vs Closed.
|
||||
* @wpa_auth: WPA type.
|
||||
* @wsec: wsec value.
|
||||
*/
|
||||
struct brcmf_pno_net_param_le {
|
||||
struct brcmf_ssid_le ssid;
|
||||
__le32 flags;
|
||||
__le32 infra;
|
||||
__le32 auth;
|
||||
__le32 wpa_auth;
|
||||
__le32 wsec;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pno_net_info_le - information per found network.
|
||||
*
|
||||
* @bssid: BSS network identifier.
|
||||
* @channel: channel number only.
|
||||
* @SSID_len: length of ssid.
|
||||
* @SSID: ssid characters.
|
||||
* @RSSI: receive signal strength (in dBm).
|
||||
* @timestamp: age in seconds.
|
||||
*/
|
||||
struct brcmf_pno_net_info_le {
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 channel;
|
||||
u8 SSID_len;
|
||||
u8 SSID[32];
|
||||
__le16 RSSI;
|
||||
__le16 timestamp;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct brcmf_pno_scanresults_le - result returned in PNO NET FOUND event.
|
||||
*
|
||||
* @version: PNO version identifier.
|
||||
* @status: indicates completion status of PNO scan.
|
||||
* @count: amount of brcmf_pno_net_info_le entries appended.
|
||||
*/
|
||||
struct brcmf_pno_scanresults_le {
|
||||
__le32 version;
|
||||
__le32 status;
|
||||
__le32 count;
|
||||
};
|
||||
|
||||
#endif /* FWIL_TYPES_H_ */
|
||||
|
@ -1609,10 +1609,11 @@ static int brcmf_fws_notify_bcmc_credit_support(struct brcmf_if *ifp,
|
||||
{
|
||||
struct brcmf_fws_info *fws = ifp->drvr->fws;
|
||||
|
||||
if (fws) {
|
||||
brcmf_fws_lock(fws);
|
||||
if (fws)
|
||||
fws->bcmc_credit_check = true;
|
||||
brcmf_fws_unlock(fws);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -473,7 +473,6 @@ static int brcmf_msgbuf_ioctl_resp_wait(struct brcmf_msgbuf *msgbuf)
|
||||
static void brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf *msgbuf)
|
||||
{
|
||||
msgbuf->ctl_completed = true;
|
||||
if (waitqueue_active(&msgbuf->ioctl_resp_wait))
|
||||
wake_up(&msgbuf->ioctl_resp_wait);
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ enum brcmf_pcie_state {
|
||||
|
||||
BRCMF_FW_NVRAM_DEF(43602, "brcmfmac43602-pcie.bin", "brcmfmac43602-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4350, "brcmfmac4350-pcie.bin", "brcmfmac4350-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4350C, "brcmfmac4350c2-pcie.bin", "brcmfmac4350c2-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4356, "brcmfmac4356-pcie.bin", "brcmfmac4356-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(43570, "brcmfmac43570-pcie.bin", "brcmfmac43570-pcie.txt");
|
||||
BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt");
|
||||
@ -56,7 +57,8 @@ BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt");
|
||||
|
||||
static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFFFF, 4350),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0x000000FF, 4350C),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4350_CHIP_ID, 0xFFFFFF00, 4350),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43567_CHIP_ID, 0xFFFFFFFF, 43570),
|
||||
BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570),
|
||||
@ -1873,7 +1875,7 @@ static int brcmf_pcie_pm_enter_D3(struct device *dev)
|
||||
struct brcmf_pciedev_info *devinfo;
|
||||
struct brcmf_bus *bus;
|
||||
|
||||
brcmf_err("Enter\n");
|
||||
brcmf_dbg(PCIE, "Enter\n");
|
||||
|
||||
bus = dev_get_drvdata(dev);
|
||||
devinfo = bus->bus_priv.pcie->devinfo;
|
||||
@ -1904,7 +1906,7 @@ static int brcmf_pcie_pm_leave_D3(struct device *dev)
|
||||
struct pci_dev *pdev;
|
||||
int err;
|
||||
|
||||
brcmf_err("Enter\n");
|
||||
brcmf_dbg(PCIE, "Enter\n");
|
||||
|
||||
bus = dev_get_drvdata(dev);
|
||||
devinfo = bus->bus_priv.pcie->devinfo;
|
||||
|
@ -1678,7 +1678,6 @@ static int brcmf_sdio_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition,
|
||||
|
||||
static int brcmf_sdio_dcmd_resp_wake(struct brcmf_sdio *bus)
|
||||
{
|
||||
if (waitqueue_active(&bus->dcmd_resp_wait))
|
||||
wake_up_interruptible(&bus->dcmd_resp_wait);
|
||||
|
||||
return 0;
|
||||
@ -2003,7 +2002,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
|
||||
static void
|
||||
brcmf_sdio_wait_event_wakeup(struct brcmf_sdio *bus)
|
||||
{
|
||||
if (waitqueue_active(&bus->ctrl_wait))
|
||||
wake_up_interruptible(&bus->ctrl_wait);
|
||||
return;
|
||||
}
|
||||
|
@ -196,7 +196,6 @@ static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo)
|
||||
|
||||
static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
|
||||
{
|
||||
if (waitqueue_active(&devinfo->ioctl_resp_wait))
|
||||
wake_up(&devinfo->ioctl_resp_wait);
|
||||
}
|
||||
|
||||
@ -1453,6 +1452,7 @@ static struct usb_device_id brcmf_usb_devid_table[] = {
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID),
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID),
|
||||
BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID),
|
||||
{ USB_DEVICE(BRCM_USB_VENDOR_ID_LG, BRCM_USB_43242_LG_DEVICE_ID) },
|
||||
/* special entry for device with firmware loaded and running */
|
||||
BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID),
|
||||
{ /* end: all zeroes */ }
|
||||
|
@ -177,8 +177,8 @@ static bool brcms_c_country_valid(const char *ccode)
|
||||
* only allow ascii alpha uppercase for the first 2
|
||||
* chars.
|
||||
*/
|
||||
if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
|
||||
(0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A))
|
||||
if (!((ccode[0] & 0x80) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A &&
|
||||
(ccode[1] & 0x80) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A))
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/mmc/sdio_ids.h>
|
||||
|
||||
#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c
|
||||
#define BRCM_USB_VENDOR_ID_LG 0x043e
|
||||
#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
|
||||
|
||||
/* Chipcommon Core Chip IDs */
|
||||
@ -57,6 +58,7 @@
|
||||
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
|
||||
#define BRCM_USB_43236_DEVICE_ID 0xbd17
|
||||
#define BRCM_USB_43242_DEVICE_ID 0xbd1f
|
||||
#define BRCM_USB_43242_LG_DEVICE_ID 0x3101
|
||||
#define BRCM_USB_43569_DEVICE_ID 0xbd27
|
||||
#define BRCM_USB_BCMFW_DEVICE_ID 0x0bdc
|
||||
|
||||
|
@ -237,9 +237,6 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
|
||||
#define WPA2_AUTH_RESERVED4 0x0400
|
||||
#define WPA2_AUTH_RESERVED5 0x0800
|
||||
|
||||
/* pmkid */
|
||||
#define MAXPMKID 16
|
||||
|
||||
#define DOT11_DEFAULT_RTS_LEN 2347
|
||||
#define DOT11_DEFAULT_FRAG_LEN 2346
|
||||
|
||||
@ -251,24 +248,4 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
|
||||
#define HT_CAP_RX_STBC_NO 0x0
|
||||
#define HT_CAP_RX_STBC_ONE_STREAM 0x1
|
||||
|
||||
struct pmkid {
|
||||
u8 BSSID[ETH_ALEN];
|
||||
u8 PMKID[WLAN_PMKID_LEN];
|
||||
};
|
||||
|
||||
struct pmkid_list {
|
||||
__le32 npmkid;
|
||||
struct pmkid pmkid[1];
|
||||
};
|
||||
|
||||
struct pmkid_cand {
|
||||
u8 BSSID[ETH_ALEN];
|
||||
u8 preauth;
|
||||
};
|
||||
|
||||
struct pmkid_cand_list {
|
||||
u32 npmkid_cand;
|
||||
struct pmkid_cand pmkid_cand[1];
|
||||
};
|
||||
|
||||
#endif /* _BRCMU_WIFI_H_ */
|
||||
|
@ -1865,14 +1865,14 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags)
|
||||
|
||||
cmd.len = il->ops->build_addsta_hcmd(sta, data);
|
||||
ret = il_send_cmd(il, &cmd);
|
||||
|
||||
if (ret || (flags & CMD_ASYNC))
|
||||
if (ret)
|
||||
return ret;
|
||||
if (flags & CMD_ASYNC)
|
||||
return 0;
|
||||
|
||||
if (ret == 0) {
|
||||
pkt = (struct il_rx_pkt *)cmd.reply_page;
|
||||
ret = il_process_add_sta_resp(il, sta, pkt, true);
|
||||
}
|
||||
|
||||
il_free_pages(il, cmd.reply_page);
|
||||
|
||||
return ret;
|
||||
@ -3602,7 +3602,7 @@ il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap)
|
||||
}
|
||||
EXPORT_SYMBOL(il_is_ht40_tx_allowed);
|
||||
|
||||
static u16
|
||||
static u16 noinline
|
||||
il_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
|
||||
{
|
||||
u16 new_val;
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -473,13 +473,4 @@ do { \
|
||||
} while (0)
|
||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||
|
||||
extern const char *const iwl_dvm_cmd_strings[REPLY_MAX + 1];
|
||||
|
||||
static inline const char *iwl_dvm_get_cmd_string(u8 cmd)
|
||||
{
|
||||
const char *s = iwl_dvm_cmd_strings[cmd];
|
||||
if (s)
|
||||
return s;
|
||||
return "UNKNOWN";
|
||||
}
|
||||
#endif /* __iwl_agn_h__ */
|
||||
|
@ -311,7 +311,7 @@ static int iwl_sens_energy_cck(struct iwl_priv *priv,
|
||||
/* If previous beacon had too many false alarms,
|
||||
* give it some extra margin by reducing sensitivity again
|
||||
* (but don't go below measured energy of desired Rx) */
|
||||
if (IWL_FA_TOO_MANY == data->nrg_prev_state) {
|
||||
if (data->nrg_prev_state == IWL_FA_TOO_MANY) {
|
||||
IWL_DEBUG_CALIB(priv, "... increasing margin\n");
|
||||
if (data->nrg_th_cck > (max_nrg_cck + NRG_MARGIN))
|
||||
data->nrg_th_cck -= NRG_MARGIN;
|
||||
|
@ -22,7 +22,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
@ -32,7 +32,9 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "iwl-debug.h"
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-io.h"
|
||||
#include "dev.h"
|
||||
#include "agn.h"
|
||||
@ -438,7 +440,7 @@ static ssize_t iwl_dbgfs_rx_handlers_read(struct file *file,
|
||||
if (priv->rx_handlers_stats[cnt] > 0)
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"\tRx handler[%36s]:\t\t %u\n",
|
||||
iwl_dvm_get_cmd_string(cnt),
|
||||
iwl_get_cmd_string(priv->trans, (u32)cnt),
|
||||
priv->rx_handlers_stats[cnt]);
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -1262,7 +1262,7 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
|
||||
if (test_bit(STATUS_FW_ERROR, &priv->status)) {
|
||||
IWL_ERR(priv, "Command %s failed: FW Error\n",
|
||||
iwl_dvm_get_cmd_string(cmd->id));
|
||||
iwl_get_cmd_string(priv->trans, cmd->id));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -115,6 +115,9 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
|
||||
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
|
||||
ieee80211_hw_set(hw, WANT_MONITOR_VIF);
|
||||
|
||||
if (priv->trans->max_skb_frags)
|
||||
hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG;
|
||||
|
||||
hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE;
|
||||
hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FMT;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
@ -22,7 +23,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -69,6 +70,93 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* Please keep this array *SORTED* by hex value.
|
||||
* Access is done through binary search.
|
||||
* A warning will be triggered on violation.
|
||||
*/
|
||||
static const struct iwl_hcmd_names iwl_dvm_cmd_names[] = {
|
||||
HCMD_NAME(REPLY_ALIVE),
|
||||
HCMD_NAME(REPLY_ERROR),
|
||||
HCMD_NAME(REPLY_ECHO),
|
||||
HCMD_NAME(REPLY_RXON),
|
||||
HCMD_NAME(REPLY_RXON_ASSOC),
|
||||
HCMD_NAME(REPLY_QOS_PARAM),
|
||||
HCMD_NAME(REPLY_RXON_TIMING),
|
||||
HCMD_NAME(REPLY_ADD_STA),
|
||||
HCMD_NAME(REPLY_REMOVE_STA),
|
||||
HCMD_NAME(REPLY_REMOVE_ALL_STA),
|
||||
HCMD_NAME(REPLY_TX),
|
||||
HCMD_NAME(REPLY_TXFIFO_FLUSH),
|
||||
HCMD_NAME(REPLY_WEPKEY),
|
||||
HCMD_NAME(REPLY_LEDS_CMD),
|
||||
HCMD_NAME(REPLY_TX_LINK_QUALITY_CMD),
|
||||
HCMD_NAME(COEX_PRIORITY_TABLE_CMD),
|
||||
HCMD_NAME(COEX_MEDIUM_NOTIFICATION),
|
||||
HCMD_NAME(COEX_EVENT_CMD),
|
||||
HCMD_NAME(TEMPERATURE_NOTIFICATION),
|
||||
HCMD_NAME(CALIBRATION_CFG_CMD),
|
||||
HCMD_NAME(CALIBRATION_RES_NOTIFICATION),
|
||||
HCMD_NAME(CALIBRATION_COMPLETE_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_QUIET_CMD),
|
||||
HCMD_NAME(REPLY_CHANNEL_SWITCH),
|
||||
HCMD_NAME(CHANNEL_SWITCH_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_SPECTRUM_MEASUREMENT_CMD),
|
||||
HCMD_NAME(SPECTRUM_MEASURE_NOTIFICATION),
|
||||
HCMD_NAME(POWER_TABLE_CMD),
|
||||
HCMD_NAME(PM_SLEEP_NOTIFICATION),
|
||||
HCMD_NAME(PM_DEBUG_STATISTIC_NOTIFIC),
|
||||
HCMD_NAME(REPLY_SCAN_CMD),
|
||||
HCMD_NAME(REPLY_SCAN_ABORT_CMD),
|
||||
HCMD_NAME(SCAN_START_NOTIFICATION),
|
||||
HCMD_NAME(SCAN_RESULTS_NOTIFICATION),
|
||||
HCMD_NAME(SCAN_COMPLETE_NOTIFICATION),
|
||||
HCMD_NAME(BEACON_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_TX_BEACON),
|
||||
HCMD_NAME(WHO_IS_AWAKE_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_TX_POWER_DBM_CMD),
|
||||
HCMD_NAME(QUIET_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_TX_PWR_TABLE_CMD),
|
||||
HCMD_NAME(REPLY_TX_POWER_DBM_CMD_V1),
|
||||
HCMD_NAME(TX_ANT_CONFIGURATION_CMD),
|
||||
HCMD_NAME(MEASURE_ABORT_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_BT_CONFIG),
|
||||
HCMD_NAME(REPLY_STATISTICS_CMD),
|
||||
HCMD_NAME(STATISTICS_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_CARD_STATE_CMD),
|
||||
HCMD_NAME(CARD_STATE_NOTIFICATION),
|
||||
HCMD_NAME(MISSED_BEACONS_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_CT_KILL_CONFIG_CMD),
|
||||
HCMD_NAME(SENSITIVITY_CMD),
|
||||
HCMD_NAME(REPLY_PHY_CALIBRATION_CMD),
|
||||
HCMD_NAME(REPLY_WIPAN_PARAMS),
|
||||
HCMD_NAME(REPLY_WIPAN_RXON),
|
||||
HCMD_NAME(REPLY_WIPAN_RXON_TIMING),
|
||||
HCMD_NAME(REPLY_WIPAN_RXON_ASSOC),
|
||||
HCMD_NAME(REPLY_WIPAN_QOS_PARAM),
|
||||
HCMD_NAME(REPLY_WIPAN_WEPKEY),
|
||||
HCMD_NAME(REPLY_WIPAN_P2P_CHANNEL_SWITCH),
|
||||
HCMD_NAME(REPLY_WIPAN_NOA_NOTIFICATION),
|
||||
HCMD_NAME(REPLY_WIPAN_DEACTIVATION_COMPLETE),
|
||||
HCMD_NAME(REPLY_RX_PHY_CMD),
|
||||
HCMD_NAME(REPLY_RX_MPDU_CMD),
|
||||
HCMD_NAME(REPLY_RX),
|
||||
HCMD_NAME(REPLY_COMPRESSED_BA),
|
||||
HCMD_NAME(REPLY_BT_COEX_PRIO_TABLE),
|
||||
HCMD_NAME(REPLY_BT_COEX_PROT_ENV),
|
||||
HCMD_NAME(REPLY_BT_COEX_PROFILE_NOTIF),
|
||||
HCMD_NAME(REPLY_D3_CONFIG),
|
||||
HCMD_NAME(REPLY_WOWLAN_PATTERNS),
|
||||
HCMD_NAME(REPLY_WOWLAN_WAKEUP_FILTER),
|
||||
HCMD_NAME(REPLY_WOWLAN_TSC_RSC_PARAMS),
|
||||
HCMD_NAME(REPLY_WOWLAN_TKIP_PARAMS),
|
||||
HCMD_NAME(REPLY_WOWLAN_KEK_KCK_MATERIAL),
|
||||
HCMD_NAME(REPLY_WOWLAN_GET_STATUS),
|
||||
};
|
||||
|
||||
static const struct iwl_hcmd_arr iwl_dvm_groups[] = {
|
||||
[0x0] = HCMD_ARR(iwl_dvm_cmd_names),
|
||||
};
|
||||
|
||||
static const struct iwl_op_mode_ops iwl_dvm_ops;
|
||||
|
||||
void iwl_update_chain_flags(struct iwl_priv *priv)
|
||||
@ -341,7 +429,7 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base,
|
||||
ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32));
|
||||
|
||||
/* Make sure device is powered up for SRAM reads */
|
||||
if (!iwl_trans_grab_nic_access(priv->trans, false, ®_flags))
|
||||
if (!iwl_trans_grab_nic_access(priv->trans, ®_flags))
|
||||
return;
|
||||
|
||||
/* Set starting address; reads will auto-increment */
|
||||
@ -1244,7 +1332,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
|
||||
trans_cfg.cmd_q_wdg_timeout = IWL_WATCHDOG_DISABLED;
|
||||
|
||||
trans_cfg.command_names = iwl_dvm_cmd_strings;
|
||||
trans_cfg.command_groups = iwl_dvm_groups;
|
||||
trans_cfg.command_groups_size = ARRAY_SIZE(iwl_dvm_groups);
|
||||
|
||||
trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM;
|
||||
|
||||
WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE <
|
||||
@ -1265,6 +1355,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
|
||||
|
||||
trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
|
||||
trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
|
||||
trans->command_groups = trans_cfg.command_groups;
|
||||
trans->command_groups_size = trans_cfg.command_groups_size;
|
||||
|
||||
/* At this point both hw and priv are allocated. */
|
||||
|
||||
@ -1639,7 +1731,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
|
||||
ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
|
||||
|
||||
/* Make sure device is powered up for SRAM reads */
|
||||
if (!iwl_trans_grab_nic_access(trans, false, ®_flags))
|
||||
if (!iwl_trans_grab_nic_access(trans, ®_flags))
|
||||
return pos;
|
||||
|
||||
/* Set starting address; reads will auto-increment */
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -1,6 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portionhelp of the ieee80211 subsystem header files.
|
||||
@ -22,7 +23,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -32,91 +33,13 @@
|
||||
#include <linux/sched.h>
|
||||
#include <net/mac80211.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-io.h"
|
||||
#include "dev.h"
|
||||
#include "calib.h"
|
||||
#include "agn.h"
|
||||
|
||||
#define IWL_CMD_ENTRY(x) [x] = #x
|
||||
|
||||
const char *const iwl_dvm_cmd_strings[REPLY_MAX + 1] = {
|
||||
IWL_CMD_ENTRY(REPLY_ALIVE),
|
||||
IWL_CMD_ENTRY(REPLY_ERROR),
|
||||
IWL_CMD_ENTRY(REPLY_ECHO),
|
||||
IWL_CMD_ENTRY(REPLY_RXON),
|
||||
IWL_CMD_ENTRY(REPLY_RXON_ASSOC),
|
||||
IWL_CMD_ENTRY(REPLY_QOS_PARAM),
|
||||
IWL_CMD_ENTRY(REPLY_RXON_TIMING),
|
||||
IWL_CMD_ENTRY(REPLY_ADD_STA),
|
||||
IWL_CMD_ENTRY(REPLY_REMOVE_STA),
|
||||
IWL_CMD_ENTRY(REPLY_REMOVE_ALL_STA),
|
||||
IWL_CMD_ENTRY(REPLY_TXFIFO_FLUSH),
|
||||
IWL_CMD_ENTRY(REPLY_WEPKEY),
|
||||
IWL_CMD_ENTRY(REPLY_TX),
|
||||
IWL_CMD_ENTRY(REPLY_LEDS_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_TX_LINK_QUALITY_CMD),
|
||||
IWL_CMD_ENTRY(COEX_PRIORITY_TABLE_CMD),
|
||||
IWL_CMD_ENTRY(COEX_MEDIUM_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(COEX_EVENT_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_QUIET_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_CHANNEL_SWITCH),
|
||||
IWL_CMD_ENTRY(CHANNEL_SWITCH_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(REPLY_SPECTRUM_MEASUREMENT_CMD),
|
||||
IWL_CMD_ENTRY(SPECTRUM_MEASURE_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(POWER_TABLE_CMD),
|
||||
IWL_CMD_ENTRY(PM_SLEEP_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(PM_DEBUG_STATISTIC_NOTIFIC),
|
||||
IWL_CMD_ENTRY(REPLY_SCAN_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_SCAN_ABORT_CMD),
|
||||
IWL_CMD_ENTRY(SCAN_START_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(SCAN_RESULTS_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(SCAN_COMPLETE_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(BEACON_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(REPLY_TX_BEACON),
|
||||
IWL_CMD_ENTRY(WHO_IS_AWAKE_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(QUIET_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(REPLY_TX_PWR_TABLE_CMD),
|
||||
IWL_CMD_ENTRY(MEASURE_ABORT_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(REPLY_BT_CONFIG),
|
||||
IWL_CMD_ENTRY(REPLY_STATISTICS_CMD),
|
||||
IWL_CMD_ENTRY(STATISTICS_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(REPLY_CARD_STATE_CMD),
|
||||
IWL_CMD_ENTRY(CARD_STATE_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(MISSED_BEACONS_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(REPLY_CT_KILL_CONFIG_CMD),
|
||||
IWL_CMD_ENTRY(SENSITIVITY_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_PHY_CALIBRATION_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_RX_PHY_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_RX_MPDU_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_COMPRESSED_BA),
|
||||
IWL_CMD_ENTRY(CALIBRATION_CFG_CMD),
|
||||
IWL_CMD_ENTRY(CALIBRATION_RES_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(CALIBRATION_COMPLETE_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(REPLY_TX_POWER_DBM_CMD),
|
||||
IWL_CMD_ENTRY(TEMPERATURE_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(TX_ANT_CONFIGURATION_CMD),
|
||||
IWL_CMD_ENTRY(REPLY_BT_COEX_PROFILE_NOTIF),
|
||||
IWL_CMD_ENTRY(REPLY_BT_COEX_PRIO_TABLE),
|
||||
IWL_CMD_ENTRY(REPLY_BT_COEX_PROT_ENV),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_PARAMS),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_RXON),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_RXON_TIMING),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_RXON_ASSOC),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_QOS_PARAM),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_WEPKEY),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_P2P_CHANNEL_SWITCH),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_NOA_NOTIFICATION),
|
||||
IWL_CMD_ENTRY(REPLY_WIPAN_DEACTIVATION_COMPLETE),
|
||||
IWL_CMD_ENTRY(REPLY_WOWLAN_PATTERNS),
|
||||
IWL_CMD_ENTRY(REPLY_WOWLAN_WAKEUP_FILTER),
|
||||
IWL_CMD_ENTRY(REPLY_WOWLAN_TSC_RSC_PARAMS),
|
||||
IWL_CMD_ENTRY(REPLY_WOWLAN_TKIP_PARAMS),
|
||||
IWL_CMD_ENTRY(REPLY_WOWLAN_KEK_KCK_MATERIAL),
|
||||
IWL_CMD_ENTRY(REPLY_WOWLAN_GET_STATUS),
|
||||
IWL_CMD_ENTRY(REPLY_D3_CONFIG),
|
||||
};
|
||||
#undef IWL_CMD_ENTRY
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Generic RX handler implementations
|
||||
@ -1095,7 +1018,9 @@ void iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct napi_struct *napi,
|
||||
} else {
|
||||
/* No handling needed */
|
||||
IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
|
||||
iwl_dvm_get_cmd_string(pkt->hdr.cmd),
|
||||
iwl_get_cmd_string(priv->trans,
|
||||
iwl_cmd_id(pkt->hdr.cmd,
|
||||
0, 0)),
|
||||
pkt->hdr.cmd);
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
#include <linux/slab.h>
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
@ -184,7 +184,7 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
|
||||
priv->thermal_throttle.ct_kill_toggle = true;
|
||||
}
|
||||
iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);
|
||||
if (iwl_trans_grab_nic_access(priv->trans, false, &flags))
|
||||
if (iwl_trans_grab_nic_access(priv->trans, &flags))
|
||||
iwl_trans_release_nic_access(priv->trans, &flags);
|
||||
|
||||
/* Reschedule the ct_kill timer to occur in
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
#ifndef __iwl_tt_setting_h__
|
||||
|
@ -22,7 +22,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -383,6 +383,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
|
||||
iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, sta, fc);
|
||||
|
||||
memset(&info->status, 0, sizeof(info->status));
|
||||
memset(info->driver_data, 0, sizeof(info->driver_data));
|
||||
|
||||
info->driver_data[0] = ctx;
|
||||
info->driver_data[1] = dev_cmd;
|
||||
|
@ -27,7 +27,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -83,7 +83,7 @@
|
||||
|
||||
static const struct iwl_base_params iwl9000_base_params = {
|
||||
.eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_9000,
|
||||
.num_of_queues = IWLAGN_NUM_QUEUES,
|
||||
.num_of_queues = 31,
|
||||
.pll_cfg_val = 0,
|
||||
.shadow_ram_support = true,
|
||||
.led_compensation = 57,
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -21,7 +21,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -1,6 +1,7 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2009 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
@ -51,6 +52,22 @@ TRACE_EVENT(iwlwifi_dev_tx_data,
|
||||
TP_printk("[%s] TX frame data", __get_str(dev))
|
||||
);
|
||||
|
||||
TRACE_EVENT(iwlwifi_dev_tx_tso_chunk,
|
||||
TP_PROTO(const struct device *dev,
|
||||
u8 *data_src, size_t data_len),
|
||||
TP_ARGS(dev, data_src, data_len),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
|
||||
__dynamic_array(u8, data, data_len)
|
||||
),
|
||||
TP_fast_assign(
|
||||
DEV_ASSIGN;
|
||||
memcpy(__get_dynamic_array(data), data_src, data_len);
|
||||
),
|
||||
TP_printk("[%s] TX frame data", __get_str(dev))
|
||||
);
|
||||
|
||||
TRACE_EVENT(iwlwifi_dev_rx_data,
|
||||
TP_PROTO(const struct device *dev,
|
||||
const struct iwl_trans *trans,
|
||||
|
@ -20,7 +20,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -19,7 +19,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -594,7 +594,8 @@ static int iwl_parse_v1_v2_firmware(struct iwl_drv *drv,
|
||||
static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
const struct firmware *ucode_raw,
|
||||
struct iwl_firmware_pieces *pieces,
|
||||
struct iwl_ucode_capabilities *capa)
|
||||
struct iwl_ucode_capabilities *capa,
|
||||
bool *usniffer_images)
|
||||
{
|
||||
struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
|
||||
struct iwl_ucode_tlv *tlv;
|
||||
@ -607,7 +608,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
char buildstr[25];
|
||||
u32 build, paging_mem_size;
|
||||
int num_of_cpus;
|
||||
bool usniffer_images = false;
|
||||
bool usniffer_req = false;
|
||||
bool gscan_capa = false;
|
||||
|
||||
@ -980,7 +980,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
break;
|
||||
}
|
||||
case IWL_UCODE_TLV_SEC_RT_USNIFFER:
|
||||
usniffer_images = true;
|
||||
*usniffer_images = true;
|
||||
iwl_store_ucode_sec(pieces, tlv_data,
|
||||
IWL_UCODE_REGULAR_USNIFFER,
|
||||
tlv_len);
|
||||
@ -1031,7 +1031,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
}
|
||||
}
|
||||
|
||||
if (usniffer_req && !usniffer_images) {
|
||||
if (usniffer_req && !*usniffer_images) {
|
||||
IWL_ERR(drv,
|
||||
"user selected to work with usniffer but usniffer image isn't available in ucode package\n");
|
||||
return -EINVAL;
|
||||
@ -1192,6 +1192,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
u32 api_ver;
|
||||
int i;
|
||||
bool load_module = false;
|
||||
bool usniffer_images = false;
|
||||
|
||||
fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
|
||||
fw->ucode_capa.standard_phy_calibration_size =
|
||||
@ -1229,7 +1230,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
err = iwl_parse_v1_v2_firmware(drv, ucode_raw, pieces);
|
||||
else
|
||||
err = iwl_parse_tlv_firmware(drv, ucode_raw, pieces,
|
||||
&fw->ucode_capa);
|
||||
&fw->ucode_capa, &usniffer_images);
|
||||
|
||||
if (err)
|
||||
goto try_again;
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -69,7 +69,7 @@
|
||||
/* for all modules */
|
||||
#define DRV_NAME "iwlwifi"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2003- 2015 Intel Corporation"
|
||||
#define DRV_AUTHOR "<ilw@linux.intel.com>"
|
||||
#define DRV_AUTHOR "<linuxwifi@intel.com>"
|
||||
|
||||
/* radio config bits (actual values from NVM definition) */
|
||||
#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
|
||||
|
@ -454,11 +454,11 @@ static void iwl_eeprom_enhanced_txpower(struct device *dev,
|
||||
TXP_CHECK_AND_PRINT(COMMON_TYPE),
|
||||
txp->flags);
|
||||
IWL_DEBUG_EEPROM(dev,
|
||||
"\t\t chain_A: 0x%02x chain_B: 0X%02x chain_C: 0X%02x\n",
|
||||
"\t\t chain_A: %d chain_B: %d chain_C: %d\n",
|
||||
txp->chain_a_max, txp->chain_b_max,
|
||||
txp->chain_c_max);
|
||||
IWL_DEBUG_EEPROM(dev,
|
||||
"\t\t MIMO2: 0x%02x MIMO3: 0x%02x High 20_on_40: 0x%02x Low 20_on_40: 0x%02x\n",
|
||||
"\t\t MIMO2: %d MIMO3: %d High 20_on_40: 0x%02x Low 20_on_40: 0x%02x\n",
|
||||
txp->mimo2_max, txp->mimo3_max,
|
||||
((txp->delta_20_in_40 & 0xf0) >> 4),
|
||||
(txp->delta_20_in_40 & 0x0f));
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -22,7 +22,7 @@
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
@ -82,7 +82,7 @@ u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
|
||||
{
|
||||
u32 value = 0x5a5a5a5a;
|
||||
unsigned long flags;
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
value = iwl_read32(trans, reg);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
@ -95,7 +95,7 @@ void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
iwl_write32(trans, reg, value);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
@ -138,7 +138,7 @@ u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
|
||||
unsigned long flags;
|
||||
u32 val = 0x5a5a5a5a;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
val = iwl_read_prph_no_grab(trans, ofs);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
@ -150,7 +150,7 @@ void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
iwl_write_prph_no_grab(trans, ofs, val);
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
}
|
||||
@ -176,7 +176,7 @@ void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
iwl_write_prph_no_grab(trans, ofs,
|
||||
iwl_read_prph_no_grab(trans, ofs) |
|
||||
mask);
|
||||
@ -190,7 +190,7 @@ void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
iwl_write_prph_no_grab(trans, ofs,
|
||||
(iwl_read_prph_no_grab(trans, ofs) &
|
||||
mask) | bits);
|
||||
@ -204,7 +204,7 @@ void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
if (iwl_trans_grab_nic_access(trans, false, &flags)) {
|
||||
if (iwl_trans_grab_nic_access(trans, &flags)) {
|
||||
val = iwl_read_prph_no_grab(trans, ofs);
|
||||
iwl_write_prph_no_grab(trans, ofs, (val & ~mask));
|
||||
iwl_trans_release_nic_access(trans, &flags);
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -27,7 +27,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -123,6 +123,8 @@ struct iwl_cfg;
|
||||
* received on the RSS queue(s). The queue parameter indicates which of the
|
||||
* RSS queues received this frame; it will always be non-zero.
|
||||
* This method must not sleep.
|
||||
* @async_cb: called when an ASYNC command with CMD_WANT_ASYNC_CALLBACK set
|
||||
* completes. Must be atomic.
|
||||
* @queue_full: notifies that a HW queue is full.
|
||||
* Must be atomic and called with BH disabled.
|
||||
* @queue_not_full: notifies that a HW queue is not full any more.
|
||||
@ -155,6 +157,8 @@ struct iwl_op_mode_ops {
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void (*rx_rss)(struct iwl_op_mode *op_mode, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, unsigned int queue);
|
||||
void (*async_cb)(struct iwl_op_mode *op_mode,
|
||||
const struct iwl_device_cmd *cmd);
|
||||
void (*queue_full)(struct iwl_op_mode *op_mode, int queue);
|
||||
void (*queue_not_full)(struct iwl_op_mode *op_mode, int queue);
|
||||
bool (*hw_rf_kill)(struct iwl_op_mode *op_mode, bool state);
|
||||
@ -203,6 +207,13 @@ static inline void iwl_op_mode_rx_rss(struct iwl_op_mode *op_mode,
|
||||
op_mode->ops->rx_rss(op_mode, napi, rxb, queue);
|
||||
}
|
||||
|
||||
static inline void iwl_op_mode_async_cb(struct iwl_op_mode *op_mode,
|
||||
const struct iwl_device_cmd *cmd)
|
||||
{
|
||||
if (op_mode->ops->async_cb)
|
||||
op_mode->ops->async_cb(op_mode, cmd);
|
||||
}
|
||||
|
||||
static inline void iwl_op_mode_queue_full(struct iwl_op_mode *op_mode,
|
||||
int queue)
|
||||
{
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -25,7 +25,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -61,7 +61,10 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bsearch.h>
|
||||
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-drv.h"
|
||||
|
||||
struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
|
||||
struct device *dev,
|
||||
@ -112,3 +115,91 @@ void iwl_trans_free(struct iwl_trans *trans)
|
||||
kmem_cache_destroy(trans->dev_cmd_pool);
|
||||
kfree(trans);
|
||||
}
|
||||
|
||||
int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (unlikely(!(cmd->flags & CMD_SEND_IN_RFKILL) &&
|
||||
test_bit(STATUS_RFKILL, &trans->status)))
|
||||
return -ERFKILL;
|
||||
|
||||
if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status)))
|
||||
return -EIO;
|
||||
|
||||
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (WARN_ON((cmd->flags & CMD_WANT_ASYNC_CALLBACK) &&
|
||||
!(cmd->flags & CMD_ASYNC)))
|
||||
return -EINVAL;
|
||||
|
||||
if (!(cmd->flags & CMD_ASYNC))
|
||||
lock_map_acquire_read(&trans->sync_cmd_lockdep_map);
|
||||
|
||||
ret = trans->ops->send_cmd(trans, cmd);
|
||||
|
||||
if (!(cmd->flags & CMD_ASYNC))
|
||||
lock_map_release(&trans->sync_cmd_lockdep_map);
|
||||
|
||||
return ret;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_send_cmd);
|
||||
|
||||
/* Comparator for struct iwl_hcmd_names.
|
||||
* Used in the binary search over a list of host commands.
|
||||
*
|
||||
* @key: command_id that we're looking for.
|
||||
* @elt: struct iwl_hcmd_names candidate for match.
|
||||
*
|
||||
* @return 0 iff equal.
|
||||
*/
|
||||
static int iwl_hcmd_names_cmp(const void *key, const void *elt)
|
||||
{
|
||||
const struct iwl_hcmd_names *name = elt;
|
||||
u8 cmd1 = *(u8 *)key;
|
||||
u8 cmd2 = name->cmd_id;
|
||||
|
||||
return (cmd1 - cmd2);
|
||||
}
|
||||
|
||||
const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id)
|
||||
{
|
||||
u8 grp, cmd;
|
||||
struct iwl_hcmd_names *ret;
|
||||
const struct iwl_hcmd_arr *arr;
|
||||
size_t size = sizeof(struct iwl_hcmd_names);
|
||||
|
||||
grp = iwl_cmd_groupid(id);
|
||||
cmd = iwl_cmd_opcode(id);
|
||||
|
||||
if (!trans->command_groups || grp >= trans->command_groups_size ||
|
||||
!trans->command_groups[grp].arr)
|
||||
return "UNKNOWN";
|
||||
|
||||
arr = &trans->command_groups[grp];
|
||||
ret = bsearch(&cmd, arr->arr, arr->size, size, iwl_hcmd_names_cmp);
|
||||
if (!ret)
|
||||
return "UNKNOWN";
|
||||
return ret->cmd_name;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_get_cmd_string);
|
||||
|
||||
int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans)
|
||||
{
|
||||
int i, j;
|
||||
const struct iwl_hcmd_arr *arr;
|
||||
|
||||
for (i = 0; i < trans->command_groups_size; i++) {
|
||||
arr = &trans->command_groups[i];
|
||||
if (!arr->arr)
|
||||
continue;
|
||||
for (j = 0; j < arr->size - 1; j++)
|
||||
if (arr->arr[j].cmd_id > arr->arr[j + 1].cmd_id)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_cmd_groups_verify_sorted);
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -68,6 +68,7 @@
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/mm.h> /* for page_address */
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "iwl-debug.h"
|
||||
#include "iwl-config.h"
|
||||
@ -248,6 +249,8 @@ static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt)
|
||||
* @CMD_MAKE_TRANS_IDLE: The command response should mark the trans as idle.
|
||||
* @CMD_WAKE_UP_TRANS: The command response should wake up the trans
|
||||
* (i.e. mark it as non-idle).
|
||||
* @CMD_WANT_ASYNC_CALLBACK: the op_mode's async callback function must be
|
||||
* called after this command completes. Valid only with CMD_ASYNC.
|
||||
* @CMD_TB_BITMAP_POS: Position of the first bit for the TB bitmap. We need to
|
||||
* check that we leave enough room for the TBs bitmap which needs 20 bits.
|
||||
*/
|
||||
@ -259,6 +262,7 @@ enum CMD_MODE {
|
||||
CMD_SEND_IN_IDLE = BIT(4),
|
||||
CMD_MAKE_TRANS_IDLE = BIT(5),
|
||||
CMD_WAKE_UP_TRANS = BIT(6),
|
||||
CMD_WANT_ASYNC_CALLBACK = BIT(7),
|
||||
|
||||
CMD_TB_BITMAP_POS = 11,
|
||||
};
|
||||
@ -377,6 +381,11 @@ static inline void iwl_free_rxb(struct iwl_rx_cmd_buffer *r)
|
||||
|
||||
#define MAX_NO_RECLAIM_CMDS 6
|
||||
|
||||
/*
|
||||
* The first entry in driver_data array in ieee80211_tx_info
|
||||
* that can be used by the transport.
|
||||
*/
|
||||
#define IWL_TRANS_FIRST_DRIVER_DATA 2
|
||||
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
|
||||
|
||||
/*
|
||||
@ -439,6 +448,22 @@ iwl_trans_get_rb_size_order(enum iwl_amsdu_size rb_size)
|
||||
}
|
||||
}
|
||||
|
||||
struct iwl_hcmd_names {
|
||||
u8 cmd_id;
|
||||
const char *const cmd_name;
|
||||
};
|
||||
|
||||
#define HCMD_NAME(x) \
|
||||
{ .cmd_id = x, .cmd_name = #x }
|
||||
|
||||
struct iwl_hcmd_arr {
|
||||
const struct iwl_hcmd_names *arr;
|
||||
int size;
|
||||
};
|
||||
|
||||
#define HCMD_ARR(x) \
|
||||
{ .arr = x, .size = ARRAY_SIZE(x) }
|
||||
|
||||
/**
|
||||
* struct iwl_trans_config - transport configuration
|
||||
*
|
||||
@ -458,8 +483,10 @@ iwl_trans_get_rb_size_order(enum iwl_amsdu_size rb_size)
|
||||
* in DWORD (as opposed to bytes)
|
||||
* @scd_set_active: should the transport configure the SCD for HCMD queue
|
||||
* @wide_cmd_header: firmware supports wide host command header
|
||||
* @command_names: array of command names, must be 256 entries
|
||||
* (one for each command); for debugging only
|
||||
* @sw_csum_tx: transport should compute the TCP checksum
|
||||
* @command_groups: array of command groups, each member is an array of the
|
||||
* commands in the group; for debugging only
|
||||
* @command_groups_size: number of command groups, to avoid illegal access
|
||||
* @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
|
||||
* we get the ALIVE from the uCode
|
||||
*/
|
||||
@ -476,7 +503,9 @@ struct iwl_trans_config {
|
||||
bool bc_table_dword;
|
||||
bool scd_set_active;
|
||||
bool wide_cmd_header;
|
||||
const char *const *command_names;
|
||||
bool sw_csum_tx;
|
||||
const struct iwl_hcmd_arr *command_groups;
|
||||
int command_groups_size;
|
||||
|
||||
u32 sdio_adma_addr;
|
||||
};
|
||||
@ -528,7 +557,11 @@ struct iwl_trans_txq_scd_cfg {
|
||||
* If RFkill is asserted in the middle of a SYNC host command, it must
|
||||
* return -ERFKILL straight away.
|
||||
* May sleep only if CMD_ASYNC is not set
|
||||
* @tx: send an skb
|
||||
* @tx: send an skb. The transport relies on the op_mode to zero the
|
||||
* the ieee80211_tx_info->driver_data. If the MPDU is an A-MSDU, all
|
||||
* the CSUM will be taken care of (TCP CSUM and IP header in case of
|
||||
* IPv4). If the MPDU is a single MSDU, the op_mode must compute the IP
|
||||
* header if it is IPv4.
|
||||
* Must be atomic
|
||||
* @reclaim: free packet until ssn. Returns a list of freed packets.
|
||||
* Must be atomic
|
||||
@ -542,6 +575,11 @@ struct iwl_trans_txq_scd_cfg {
|
||||
* @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
|
||||
* @freeze_txq_timer: prevents the timer of the queue from firing until the
|
||||
* queue is set to awake. Must be atomic.
|
||||
* @block_txq_ptrs: stop updating the write pointers of the Tx queues. Note
|
||||
* that the transport needs to refcount the calls since this function
|
||||
* will be called several times with block = true, and then the queues
|
||||
* need to be unblocked only after the same number of calls with
|
||||
* block = false.
|
||||
* @write8: write a u8 to a register at offset ofs from the BAR
|
||||
* @write32: write a u32 to a register at offset ofs from the BAR
|
||||
* @read32: read a u32 register at offset ofs from the BAR
|
||||
@ -600,6 +638,7 @@ struct iwl_trans_ops {
|
||||
int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
|
||||
void (*freeze_txq_timer)(struct iwl_trans *trans, unsigned long txqs,
|
||||
bool freeze);
|
||||
void (*block_txq_ptrs)(struct iwl_trans *trans, bool block);
|
||||
|
||||
void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
|
||||
void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
|
||||
@ -613,8 +652,7 @@ struct iwl_trans_ops {
|
||||
void (*configure)(struct iwl_trans *trans,
|
||||
const struct iwl_trans_config *trans_cfg);
|
||||
void (*set_pmi)(struct iwl_trans *trans, bool state);
|
||||
bool (*grab_nic_access)(struct iwl_trans *trans, bool silent,
|
||||
unsigned long *flags);
|
||||
bool (*grab_nic_access)(struct iwl_trans *trans, unsigned long *flags);
|
||||
void (*release_nic_access)(struct iwl_trans *trans,
|
||||
unsigned long *flags);
|
||||
void (*set_bits_mask)(struct iwl_trans *trans, u32 reg, u32 mask,
|
||||
@ -641,18 +679,61 @@ enum iwl_trans_state {
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_d0i3_mode - d0i3 mode
|
||||
* DOC: Platform power management
|
||||
*
|
||||
* @IWL_D0I3_MODE_OFF - d0i3 is disabled
|
||||
* @IWL_D0I3_MODE_ON_IDLE - enter d0i3 when device is idle
|
||||
* (e.g. no active references)
|
||||
* @IWL_D0I3_MODE_ON_SUSPEND - enter d0i3 only on suspend
|
||||
* (in case of 'any' trigger)
|
||||
* There are two types of platform power management: system-wide
|
||||
* (WoWLAN) and runtime.
|
||||
*
|
||||
* In system-wide power management the entire platform goes into a low
|
||||
* power state (e.g. idle or suspend to RAM) at the same time and the
|
||||
* device is configured as a wakeup source for the entire platform.
|
||||
* This is usually triggered by userspace activity (e.g. the user
|
||||
* presses the suspend button or a power management daemon decides to
|
||||
* put the platform in low power mode). The device's behavior in this
|
||||
* mode is dictated by the wake-on-WLAN configuration.
|
||||
*
|
||||
* In runtime power management, only the devices which are themselves
|
||||
* idle enter a low power state. This is done at runtime, which means
|
||||
* that the entire system is still running normally. This mode is
|
||||
* usually triggered automatically by the device driver and requires
|
||||
* the ability to enter and exit the low power modes in a very short
|
||||
* time, so there is not much impact in usability.
|
||||
*
|
||||
* The terms used for the device's behavior are as follows:
|
||||
*
|
||||
* - D0: the device is fully powered and the host is awake;
|
||||
* - D3: the device is in low power mode and only reacts to
|
||||
* specific events (e.g. magic-packet received or scan
|
||||
* results found);
|
||||
* - D0I3: the device is in low power mode and reacts to any
|
||||
* activity (e.g. RX);
|
||||
*
|
||||
* These terms reflect the power modes in the firmware and are not to
|
||||
* be confused with the physical device power state. The NIC can be
|
||||
* in D0I3 mode even if, for instance, the PCI device is in D3 state.
|
||||
*/
|
||||
enum iwl_d0i3_mode {
|
||||
IWL_D0I3_MODE_OFF = 0,
|
||||
IWL_D0I3_MODE_ON_IDLE,
|
||||
IWL_D0I3_MODE_ON_SUSPEND,
|
||||
|
||||
/**
|
||||
* enum iwl_plat_pm_mode - platform power management mode
|
||||
*
|
||||
* This enumeration describes the device's platform power management
|
||||
* behavior when in idle mode (i.e. runtime power management) or when
|
||||
* in system-wide suspend (i.e WoWLAN).
|
||||
*
|
||||
* @IWL_PLAT_PM_MODE_DISABLED: power management is disabled for this
|
||||
* device. At runtime, this means that nothing happens and the
|
||||
* device always remains in active. In system-wide suspend mode,
|
||||
* it means that the all connections will be closed automatically
|
||||
* by mac80211 before the platform is suspended.
|
||||
* @IWL_PLAT_PM_MODE_D3: the device goes into D3 mode (i.e. WoWLAN).
|
||||
* For runtime power management, this mode is not officially
|
||||
* supported.
|
||||
* @IWL_PLAT_PM_MODE_D0I3: the device goes into D0I3 mode.
|
||||
*/
|
||||
enum iwl_plat_pm_mode {
|
||||
IWL_PLAT_PM_MODE_DISABLED,
|
||||
IWL_PLAT_PM_MODE_D3,
|
||||
IWL_PLAT_PM_MODE_D0I3,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -692,6 +773,12 @@ enum iwl_d0i3_mode {
|
||||
* the opmode.
|
||||
* @paging_download_buf: Buffer used for copying all of the pages before
|
||||
* downloading them to the FW. The buffer is allocated in the opmode
|
||||
* @system_pm_mode: the system-wide power management mode in use.
|
||||
* This mode is set dynamically, depending on the WoWLAN values
|
||||
* configured from the userspace at runtime.
|
||||
* @runtime_pm_mode: the runtime power management mode in use. This
|
||||
* mode is set during the initialization phase and is not
|
||||
* supposed to change during runtime.
|
||||
*/
|
||||
struct iwl_trans {
|
||||
const struct iwl_trans_ops *ops;
|
||||
@ -711,6 +798,9 @@ struct iwl_trans {
|
||||
bool pm_support;
|
||||
bool ltr_enabled;
|
||||
|
||||
const struct iwl_hcmd_arr *command_groups;
|
||||
int command_groups_size;
|
||||
|
||||
u8 num_rx_queues;
|
||||
|
||||
/* The following fields are internal only */
|
||||
@ -739,21 +829,24 @@ struct iwl_trans {
|
||||
struct iwl_fw_paging *paging_db;
|
||||
void *paging_download_buf;
|
||||
|
||||
enum iwl_d0i3_mode d0i3_mode;
|
||||
|
||||
bool wowlan_d0i3;
|
||||
enum iwl_plat_pm_mode system_pm_mode;
|
||||
enum iwl_plat_pm_mode runtime_pm_mode;
|
||||
|
||||
/* pointer to trans specific struct */
|
||||
/*Ensure that this pointer will always be aligned to sizeof pointer */
|
||||
char trans_specific[0] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
const char *iwl_get_cmd_string(struct iwl_trans *trans, u32 id);
|
||||
int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans);
|
||||
|
||||
static inline void iwl_trans_configure(struct iwl_trans *trans,
|
||||
const struct iwl_trans_config *trans_cfg)
|
||||
{
|
||||
trans->op_mode = trans_cfg->op_mode;
|
||||
|
||||
trans->ops->configure(trans, trans_cfg);
|
||||
WARN_ON(iwl_cmd_groups_verify_sorted(trans_cfg));
|
||||
}
|
||||
|
||||
static inline int _iwl_trans_start_hw(struct iwl_trans *trans, bool low_power)
|
||||
@ -880,34 +973,6 @@ iwl_trans_dump_data(struct iwl_trans *trans,
|
||||
return trans->ops->dump_data(trans, trigger);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
|
||||
struct iwl_host_cmd *cmd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (unlikely(!(cmd->flags & CMD_SEND_IN_RFKILL) &&
|
||||
test_bit(STATUS_RFKILL, &trans->status)))
|
||||
return -ERFKILL;
|
||||
|
||||
if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status)))
|
||||
return -EIO;
|
||||
|
||||
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!(cmd->flags & CMD_ASYNC))
|
||||
lock_map_acquire_read(&trans->sync_cmd_lockdep_map);
|
||||
|
||||
ret = trans->ops->send_cmd(trans, cmd);
|
||||
|
||||
if (!(cmd->flags & CMD_ASYNC))
|
||||
lock_map_release(&trans->sync_cmd_lockdep_map);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline struct iwl_device_cmd *
|
||||
iwl_trans_alloc_tx_cmd(struct iwl_trans *trans)
|
||||
{
|
||||
@ -920,6 +985,8 @@ iwl_trans_alloc_tx_cmd(struct iwl_trans *trans)
|
||||
(dev_cmd_ptr + trans->dev_cmd_headroom);
|
||||
}
|
||||
|
||||
int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
|
||||
|
||||
static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
|
||||
struct iwl_device_cmd *dev_cmd)
|
||||
{
|
||||
@ -934,8 +1001,10 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
if (unlikely(test_bit(STATUS_FW_ERROR, &trans->status)))
|
||||
return -EIO;
|
||||
|
||||
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
|
||||
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return trans->ops->tx(trans, skb, dev_cmd, queue);
|
||||
}
|
||||
@ -943,8 +1012,10 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
|
||||
int ssn, struct sk_buff_head *skbs)
|
||||
{
|
||||
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
|
||||
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return;
|
||||
}
|
||||
|
||||
trans->ops->reclaim(trans, queue, ssn, skbs);
|
||||
}
|
||||
@ -962,8 +1033,10 @@ iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn,
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
|
||||
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return;
|
||||
}
|
||||
|
||||
trans->ops->txq_enable(trans, queue, ssn, cfg, queue_wdg_timeout);
|
||||
}
|
||||
@ -1003,18 +1076,34 @@ static inline void iwl_trans_freeze_txq_timer(struct iwl_trans *trans,
|
||||
unsigned long txqs,
|
||||
bool freeze)
|
||||
{
|
||||
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
|
||||
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return;
|
||||
}
|
||||
|
||||
if (trans->ops->freeze_txq_timer)
|
||||
trans->ops->freeze_txq_timer(trans, txqs, freeze);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_block_txq_ptrs(struct iwl_trans *trans,
|
||||
bool block)
|
||||
{
|
||||
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return;
|
||||
}
|
||||
|
||||
if (trans->ops->block_txq_ptrs)
|
||||
trans->ops->block_txq_ptrs(trans, block);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
|
||||
u32 txqs)
|
||||
{
|
||||
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
|
||||
if (WARN_ON_ONCE(trans->state != IWL_TRANS_FW_ALIVE)) {
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return trans->ops->wait_tx_queue_empty(trans, txqs);
|
||||
}
|
||||
@ -1092,9 +1181,9 @@ iwl_trans_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value)
|
||||
trans->ops->set_bits_mask(trans, reg, mask, value);
|
||||
}
|
||||
|
||||
#define iwl_trans_grab_nic_access(trans, silent, flags) \
|
||||
#define iwl_trans_grab_nic_access(trans, flags) \
|
||||
__cond_lock(nic_access, \
|
||||
likely((trans)->ops->grab_nic_access(trans, silent, flags)))
|
||||
likely((trans)->ops->grab_nic_access(trans, flags)))
|
||||
|
||||
static inline void __releases(nic_access)
|
||||
iwl_trans_release_nic_access(struct iwl_trans *trans, unsigned long *flags)
|
||||
|
@ -1,12 +1,12 @@
|
||||
obj-$(CONFIG_IWLMVM) += iwlmvm.o
|
||||
iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
|
||||
iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o
|
||||
iwlmvm-y += utils.o rx.o rxmq.o tx.o binding.o quota.o sta.o sf.o
|
||||
iwlmvm-y += scan.o time-event.o rs.o
|
||||
iwlmvm-y += power.o coex.o coex_legacy.o
|
||||
iwlmvm-y += tt.o offloading.o tdls.o
|
||||
iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
|
||||
iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
|
||||
iwlmvm-y += tof.o fw-dbg.o
|
||||
iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
|
||||
iwlmvm-$(CONFIG_PM) += d3.o
|
||||
|
||||
ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -106,6 +106,7 @@
|
||||
#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
|
||||
#define IWL_MVM_RS_80_20_FAR_RANGE_TWEAK 1
|
||||
#define IWL_MVM_TOF_IS_RESPONDER 0
|
||||
#define IWL_MVM_SW_TX_CSUM_OFFLOAD 0
|
||||
#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
|
||||
#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2
|
||||
#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -104,9 +104,13 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
|
||||
struct inet6_ifaddr *ifa;
|
||||
int idx = 0;
|
||||
|
||||
memset(mvmvif->tentative_addrs, 0, sizeof(mvmvif->tentative_addrs));
|
||||
|
||||
read_lock_bh(&idev->lock);
|
||||
list_for_each_entry(ifa, &idev->addr_list, if_list) {
|
||||
mvmvif->target_ipv6_addrs[idx] = ifa->addr;
|
||||
if (ifa->flags & IFA_F_TENTATIVE)
|
||||
__set_bit(idx, mvmvif->tentative_addrs);
|
||||
idx++;
|
||||
if (idx >= IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX)
|
||||
break;
|
||||
@ -775,6 +779,9 @@ static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm)
|
||||
*/
|
||||
set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
|
||||
|
||||
/* the fw is reset, so all the keys are cleared */
|
||||
memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
|
||||
|
||||
mvm->ptk_ivlen = 0;
|
||||
mvm->ptk_icvlen = 0;
|
||||
mvm->ptk_ivlen = 0;
|
||||
@ -797,6 +804,8 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
|
||||
|
||||
wowlan_config_cmd->is_11n_connection =
|
||||
ap_sta->ht_cap.ht_supported;
|
||||
wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
|
||||
ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
|
||||
|
||||
/* Query the last used seqno and set it */
|
||||
ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
|
||||
@ -846,15 +855,38 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_iter_d0i3_ap_keys(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
void *data),
|
||||
void *data)
|
||||
{
|
||||
struct ieee80211_sta *ap_sta;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
ap_sta = rcu_dereference(mvm->fw_id_to_mac_id[mvm->d0i3_ap_sta_id]);
|
||||
if (IS_ERR_OR_NULL(ap_sta))
|
||||
goto out;
|
||||
|
||||
ieee80211_iter_keys_rcu(mvm->hw, vif, iter, data);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool configure_keys,
|
||||
bool d0i3,
|
||||
u32 cmd_flags)
|
||||
{
|
||||
struct iwl_wowlan_kek_kck_material_cmd kek_kck_cmd = {};
|
||||
struct iwl_wowlan_tkip_params_cmd tkip_cmd = {};
|
||||
struct wowlan_key_data key_data = {
|
||||
.configure_keys = configure_keys,
|
||||
.configure_keys = !d0i3,
|
||||
.use_rsc_tsc = false,
|
||||
.tkip = &tkip_cmd,
|
||||
.use_tkip = false,
|
||||
@ -866,6 +898,14 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
if (!key_data.rsc_tsc)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* if we have to configure keys, call ieee80211_iter_keys(),
|
||||
* as we need non-atomic context in order to take the
|
||||
* required locks.
|
||||
* for the d0i3 we can't use ieee80211_iter_keys(), as
|
||||
* taking (almost) any mutex might result in deadlock.
|
||||
*/
|
||||
if (!d0i3) {
|
||||
/*
|
||||
* Note that currently we don't propagate cmd_flags
|
||||
* to the iterator. In case of key_data.configure_keys,
|
||||
@ -876,6 +916,11 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
ieee80211_iter_keys(mvm->hw, vif,
|
||||
iwl_mvm_wowlan_program_keys,
|
||||
&key_data);
|
||||
} else {
|
||||
iwl_mvm_iter_d0i3_ap_keys(mvm, vif,
|
||||
iwl_mvm_wowlan_program_keys,
|
||||
&key_data);
|
||||
}
|
||||
|
||||
if (key_data.error) {
|
||||
ret = -EIO;
|
||||
@ -900,7 +945,8 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (mvmvif->rekey_data.valid) {
|
||||
/* configure rekey data only if offloaded rekey is supported (d3) */
|
||||
if (mvmvif->rekey_data.valid && !d0i3) {
|
||||
memset(&kek_kck_cmd, 0, sizeof(kek_kck_cmd));
|
||||
memcpy(kek_kck_cmd.kck, mvmvif->rekey_data.kck,
|
||||
NL80211_KCK_LEN);
|
||||
@ -917,6 +963,7 @@ int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
ret = 0;
|
||||
out:
|
||||
kfree(key_data.rsc_tsc);
|
||||
return ret;
|
||||
@ -946,8 +993,11 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
|
||||
* that isn't really a problem though.
|
||||
*/
|
||||
mutex_unlock(&mvm->mutex);
|
||||
iwl_mvm_wowlan_config_key_params(mvm, vif, true, CMD_ASYNC);
|
||||
ret = iwl_mvm_wowlan_config_key_params(mvm, vif, false,
|
||||
CMD_ASYNC);
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, WOWLAN_CONFIGURATION, 0,
|
||||
@ -960,7 +1010,7 @@ iwl_mvm_wowlan_config(struct iwl_mvm *mvm,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iwl_mvm_send_proto_offload(mvm, vif, false, 0);
|
||||
ret = iwl_mvm_send_proto_offload(mvm, vif, false, true, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1179,19 +1229,20 @@ remove_notif:
|
||||
int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
struct iwl_trans *trans = mvm->trans;
|
||||
int ret;
|
||||
|
||||
/* make sure the d0i3 exit work is not pending */
|
||||
flush_work(&mvm->d0i3_exit_work);
|
||||
|
||||
ret = iwl_trans_suspend(mvm->trans);
|
||||
ret = iwl_trans_suspend(trans);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mvm->trans->wowlan_d0i3 = wowlan->any;
|
||||
if (mvm->trans->wowlan_d0i3) {
|
||||
/* 'any' trigger means d0i3 usage */
|
||||
if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND) {
|
||||
if (wowlan->any) {
|
||||
trans->system_pm_mode = IWL_PLAT_PM_MODE_D0I3;
|
||||
|
||||
if (iwl_mvm_enter_d0i3_on_suspend(mvm)) {
|
||||
ret = iwl_mvm_enter_d0i3_sync(mvm);
|
||||
|
||||
if (ret)
|
||||
@ -1202,11 +1253,13 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
__set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
|
||||
mutex_unlock(&mvm->d0i3_suspend_mutex);
|
||||
|
||||
iwl_trans_d3_suspend(mvm->trans, false);
|
||||
iwl_trans_d3_suspend(trans, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;
|
||||
|
||||
return __iwl_mvm_suspend(hw, wowlan, false);
|
||||
}
|
||||
|
||||
@ -1711,6 +1764,29 @@ out_unlock:
|
||||
return false;
|
||||
}
|
||||
|
||||
void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_wowlan_status *status)
|
||||
{
|
||||
struct iwl_mvm_d3_gtk_iter_data gtkdata = {
|
||||
.status = status,
|
||||
};
|
||||
|
||||
/*
|
||||
* rekey handling requires taking locks that can't be taken now.
|
||||
* however, d0i3 doesn't offload rekey, so we're fine.
|
||||
*/
|
||||
if (WARN_ON_ONCE(status->num_of_gtk_rekeys))
|
||||
return;
|
||||
|
||||
/* find last GTK that we used initially, if any */
|
||||
gtkdata.find_phase = true;
|
||||
iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, >kdata);
|
||||
|
||||
gtkdata.find_phase = false;
|
||||
iwl_mvm_iter_d0i3_ap_keys(mvm, vif, iwl_mvm_d3_update_keys, >kdata);
|
||||
}
|
||||
|
||||
struct iwl_mvm_nd_query_results {
|
||||
u32 matched_profiles;
|
||||
struct iwl_scan_offload_profile_match matches[IWL_SCAN_MAX_PROFILES];
|
||||
@ -1969,8 +2045,9 @@ static int iwl_mvm_resume_d0i3(struct iwl_mvm *mvm)
|
||||
{
|
||||
bool exit_now;
|
||||
enum iwl_d3_status d3_status;
|
||||
struct iwl_trans *trans = mvm->trans;
|
||||
|
||||
iwl_trans_d3_resume(mvm->trans, &d3_status, false);
|
||||
iwl_trans_d3_resume(trans, &d3_status, false);
|
||||
|
||||
/*
|
||||
* make sure to clear D0I3_DEFER_WAKEUP before
|
||||
@ -1987,9 +2064,9 @@ static int iwl_mvm_resume_d0i3(struct iwl_mvm *mvm)
|
||||
_iwl_mvm_exit_d0i3(mvm);
|
||||
}
|
||||
|
||||
iwl_trans_resume(mvm->trans);
|
||||
iwl_trans_resume(trans);
|
||||
|
||||
if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND) {
|
||||
if (iwl_mvm_enter_d0i3_on_suspend(mvm)) {
|
||||
int ret = iwl_mvm_exit_d0i3(mvm->hw->priv);
|
||||
|
||||
if (ret)
|
||||
@ -2005,12 +2082,16 @@ static int iwl_mvm_resume_d0i3(struct iwl_mvm *mvm)
|
||||
int iwl_mvm_resume(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
|
||||
/* 'any' trigger means d0i3 was used */
|
||||
if (hw->wiphy->wowlan_config->any)
|
||||
return iwl_mvm_resume_d0i3(mvm);
|
||||
if (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3)
|
||||
ret = iwl_mvm_resume_d0i3(mvm);
|
||||
else
|
||||
return iwl_mvm_resume_d3(mvm);
|
||||
ret = iwl_mvm_resume_d3(mvm);
|
||||
|
||||
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled)
|
||||
@ -2034,6 +2115,8 @@ static int iwl_mvm_d3_test_open(struct inode *inode, struct file *file)
|
||||
ieee80211_stop_queues(mvm->hw);
|
||||
synchronize_net();
|
||||
|
||||
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_D3;
|
||||
|
||||
/* start pseudo D3 */
|
||||
rtnl_lock();
|
||||
err = __iwl_mvm_suspend(mvm->hw, mvm->hw->wiphy->wowlan_config, true);
|
||||
@ -2088,9 +2171,13 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
|
||||
int remaining_time = 10;
|
||||
|
||||
mvm->d3_test_active = false;
|
||||
|
||||
rtnl_lock();
|
||||
__iwl_mvm_resume(mvm, true);
|
||||
rtnl_unlock();
|
||||
|
||||
mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
|
||||
|
||||
iwl_abort_notification_waits(&mvm->notif_wait);
|
||||
ieee80211_restart_hw(mvm->hw);
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -1029,7 +1029,8 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwl_mvm_fw_dbg_collect(mvm, FW_DBG_TRIGGER_USER, NULL, 0, NULL);
|
||||
iwl_mvm_fw_dbg_collect(mvm, FW_DBG_TRIGGER_USER, buf,
|
||||
(count - 1), NULL);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
|
||||
|
||||
@ -1316,6 +1317,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
|
||||
PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT);
|
||||
PRINT_MVM_REF(IWL_MVM_REF_INIT_UCODE);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
@ -1450,7 +1452,7 @@ MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -7,6 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -94,10 +95,14 @@ struct iwl_d3_manager_config {
|
||||
* enum iwl_d3_proto_offloads - enabled protocol offloads
|
||||
* @IWL_D3_PROTO_OFFLOAD_ARP: ARP data is enabled
|
||||
* @IWL_D3_PROTO_OFFLOAD_NS: NS (Neighbor Solicitation) is enabled
|
||||
* @IWL_D3_PROTO_IPV4_VALID: IPv4 data is valid
|
||||
* @IWL_D3_PROTO_IPV6_VALID: IPv6 data is valid
|
||||
*/
|
||||
enum iwl_proto_offloads {
|
||||
IWL_D3_PROTO_OFFLOAD_ARP = BIT(0),
|
||||
IWL_D3_PROTO_OFFLOAD_NS = BIT(1),
|
||||
IWL_D3_PROTO_IPV4_VALID = BIT(2),
|
||||
IWL_D3_PROTO_IPV6_VALID = BIT(3),
|
||||
};
|
||||
|
||||
#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2
|
||||
@ -241,6 +246,13 @@ enum iwl_wowlan_wakeup_filters {
|
||||
IWL_WOWLAN_WAKEUP_BCN_FILTERING = BIT(16),
|
||||
}; /* WOWLAN_WAKEUP_FILTER_API_E_VER_4 */
|
||||
|
||||
enum iwl_wowlan_flags {
|
||||
IS_11W_ASSOC = BIT(0),
|
||||
ENABLE_L3_FILTERING = BIT(1),
|
||||
ENABLE_NBNS_FILTERING = BIT(2),
|
||||
ENABLE_DHCP_FILTERING = BIT(3),
|
||||
};
|
||||
|
||||
struct iwl_wowlan_config_cmd {
|
||||
__le32 wakeup_filter;
|
||||
__le16 non_qos_seq;
|
||||
@ -248,8 +260,9 @@ struct iwl_wowlan_config_cmd {
|
||||
u8 wowlan_ba_teardown_tids;
|
||||
u8 is_11n_connection;
|
||||
u8 offloading_tid;
|
||||
u8 reserved[3];
|
||||
} __packed; /* WOWLAN_CONFIG_API_S_VER_3 */
|
||||
u8 flags;
|
||||
u8 reserved[2];
|
||||
} __packed; /* WOWLAN_CONFIG_API_S_VER_4 */
|
||||
|
||||
/*
|
||||
* WOWLAN_TSC_RSC_PARAMS
|
||||
|
@ -27,7 +27,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -79,6 +79,11 @@
|
||||
#define IWL_RX_INFO_ENERGY_ANT_B_POS 8
|
||||
#define IWL_RX_INFO_ENERGY_ANT_C_POS 16
|
||||
|
||||
enum iwl_mac_context_info {
|
||||
MAC_CONTEXT_INFO_NONE,
|
||||
MAC_CONTEXT_INFO_GSCAN,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_rx_phy_info - phy info
|
||||
* (REPLY_RX_PHY_CMD = 0xc0)
|
||||
@ -97,6 +102,8 @@
|
||||
* @frame_time: frame's time on the air, based on byte count and frame rate
|
||||
* calculation
|
||||
* @mac_active_msk: what MACs were active when the frame was received
|
||||
* @mac_context_info: additional info on the context in which the frame was
|
||||
* received as defined in &enum iwl_mac_context_info
|
||||
*
|
||||
* Before each Rx, the device sends this data. It contains PHY information
|
||||
* about the reception of the packet.
|
||||
@ -114,7 +121,8 @@ struct iwl_rx_phy_info {
|
||||
__le32 non_cfg_phy[IWL_RX_INFO_PHY_CNT];
|
||||
__le32 rate_n_flags;
|
||||
__le32 byte_count;
|
||||
__le16 mac_active_msk;
|
||||
u8 mac_active_msk;
|
||||
u8 mac_context_info;
|
||||
__le16 frame_time;
|
||||
} __packed;
|
||||
|
||||
@ -279,11 +287,17 @@ enum iwl_rx_mpdu_status {
|
||||
IWL_RX_MPDU_STATUS_KEY_ERROR = BIT(4),
|
||||
IWL_RX_MPDU_STATUS_ICV_OK = BIT(5),
|
||||
IWL_RX_MPDU_STATUS_MIC_OK = BIT(6),
|
||||
/* TODO - verify this is the correct value */
|
||||
IWL_RX_MPDU_RES_STATUS_TTAK_OK = BIT(7),
|
||||
IWL_RX_MPDU_STATUS_SEC_MASK = 0x7 << 8,
|
||||
IWL_RX_MPDU_STATUS_SEC_NONE = 0x0 << 8,
|
||||
IWL_RX_MPDU_STATUS_SEC_WEP = 0x1 << 8,
|
||||
IWL_RX_MPDU_STATUS_SEC_CCM = 0x2 << 8,
|
||||
IWL_RX_MPDU_STATUS_SEC_TKIP = 0x3 << 8,
|
||||
/* TODO - define IWL_RX_MPDU_STATUS_SEC_EXT_ENC - this is a stub */
|
||||
IWL_RX_MPDU_STATUS_SEC_EXT_ENC = 0x4 << 8,
|
||||
/* TODO - define IWL_RX_MPDU_STATUS_SEC_GCM - this is a stub */
|
||||
IWL_RX_MPDU_STATUS_SEC_GCM = 0x5 << 8,
|
||||
IWL_RX_MPDU_STATUS_DECRYPTED = BIT(11),
|
||||
IWL_RX_MPDU_STATUS_WEP_MATCH = BIT(12),
|
||||
IWL_RX_MPDU_STATUS_EXT_IV_MATCH = BIT(13),
|
||||
@ -302,6 +316,8 @@ enum iwl_rx_mpdu_sta_id_flags {
|
||||
IWL_RX_MPDU_SIF_FILTER_STATUS_MASK = 0xc0,
|
||||
};
|
||||
|
||||
#define IWL_RX_REORDER_DATA_INVALID_BAID 0x7f
|
||||
|
||||
enum iwl_rx_mpdu_reorder_data {
|
||||
IWL_RX_MPDU_REORDER_NSSN_MASK = 0x00000fff,
|
||||
IWL_RX_MPDU_REORDER_SN_MASK = 0x00fff000,
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -285,6 +285,8 @@ struct iwl_scan_channel_opt {
|
||||
* @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented
|
||||
* @IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED: insert WFA vendor-specific TPC report
|
||||
* and DS parameter set IEs into probe requests.
|
||||
* @IWL_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL: use extended dwell time on channels
|
||||
* 1, 6 and 11.
|
||||
* @IWL_MVM_LMAC_SCAN_FLAG_MATCH: Send match found notification on matches
|
||||
*/
|
||||
enum iwl_mvm_lmac_scan_flags {
|
||||
@ -295,6 +297,7 @@ enum iwl_mvm_lmac_scan_flags {
|
||||
IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4),
|
||||
IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5),
|
||||
IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED = BIT(6),
|
||||
IWL_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL = BIT(7),
|
||||
IWL_MVM_LMAC_SCAN_FLAG_MATCH = BIT(9),
|
||||
};
|
||||
|
||||
@ -322,6 +325,7 @@ enum iwl_scan_priority_ext {
|
||||
* @active-dwell: dwell time for active channels
|
||||
* @passive-dwell: dwell time for passive channels
|
||||
* @fragmented-dwell: dwell time for fragmented passive scan
|
||||
* @extended_dwell: dwell time for channels 1, 6 and 11 (in certain cases)
|
||||
* @reserved2: for alignment and future use
|
||||
* @rx_chain_selct: PHY_RX_CHAIN_* flags
|
||||
* @scan_flags: &enum iwl_mvm_lmac_scan_flags
|
||||
@ -346,7 +350,8 @@ struct iwl_scan_req_lmac {
|
||||
u8 active_dwell;
|
||||
u8 passive_dwell;
|
||||
u8 fragmented_dwell;
|
||||
__le16 reserved2;
|
||||
u8 extended_dwell;
|
||||
u8 reserved2;
|
||||
__le16 rx_chain_select;
|
||||
__le32 scan_flags;
|
||||
__le32 max_out_time;
|
||||
@ -490,7 +495,7 @@ enum iwl_channel_flags {
|
||||
* @dwell_active: default dwell time for active scan
|
||||
* @dwell_passive: default dwell time for passive scan
|
||||
* @dwell_fragmented: default dwell time for fragmented scan
|
||||
* @reserved: for future use and alignment
|
||||
* @dwell_extended: default dwell time for channels 1, 6 and 11
|
||||
* @mac_addr: default mac address to be used in probes
|
||||
* @bcast_sta_id: the index of the station in the fw
|
||||
* @channel_flags: default channel flags - enum iwl_channel_flags
|
||||
@ -507,7 +512,7 @@ struct iwl_scan_config {
|
||||
u8 dwell_active;
|
||||
u8 dwell_passive;
|
||||
u8 dwell_fragmented;
|
||||
u8 reserved;
|
||||
u8 dwell_extended;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 bcast_sta_id;
|
||||
u8 channel_flags;
|
||||
@ -543,7 +548,8 @@ enum iwl_umac_scan_general_flags {
|
||||
IWL_UMAC_SCAN_GEN_FLAGS_MULTIPLE_SSID = BIT(6),
|
||||
IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED = BIT(7),
|
||||
IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED = BIT(8),
|
||||
IWL_UMAC_SCAN_GEN_FLAGS_MATCH = BIT(9)
|
||||
IWL_UMAC_SCAN_GEN_FLAGS_MATCH = BIT(9),
|
||||
IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL = BIT(10),
|
||||
};
|
||||
|
||||
/**
|
||||
@ -597,7 +603,7 @@ struct iwl_scan_req_umac_tail {
|
||||
* @uid: scan id, &enum iwl_umac_scan_uid_offsets
|
||||
* @ooc_priority: out of channel priority - &enum iwl_scan_priority
|
||||
* @general_flags: &enum iwl_umac_scan_general_flags
|
||||
* @reserved1: for future use and alignment
|
||||
* @extended_dwell: dwell time for channels 1, 6 and 11
|
||||
* @active_dwell: dwell time for active scan
|
||||
* @passive_dwell: dwell time for passive scan
|
||||
* @fragmented_dwell: dwell time for fragmented passive scan
|
||||
@ -606,7 +612,7 @@ struct iwl_scan_req_umac_tail {
|
||||
* @scan_priority: scan internal prioritization &enum iwl_scan_priority
|
||||
* @channel_flags: &enum iwl_scan_channel_flags
|
||||
* @n_channels: num of channels in scan request
|
||||
* @reserved2: for future use and alignment
|
||||
* @reserved: for future use and alignment
|
||||
* @data: &struct iwl_scan_channel_cfg_umac and
|
||||
* &struct iwl_scan_req_umac_tail
|
||||
*/
|
||||
@ -616,7 +622,7 @@ struct iwl_scan_req_umac {
|
||||
__le32 ooc_priority;
|
||||
/* SCAN_GENERAL_PARAMS_API_S_VER_1 */
|
||||
__le32 general_flags;
|
||||
u8 reserved1;
|
||||
u8 extended_dwell;
|
||||
u8 active_dwell;
|
||||
u8 passive_dwell;
|
||||
u8 fragmented_dwell;
|
||||
@ -626,7 +632,7 @@ struct iwl_scan_req_umac {
|
||||
/* SCAN_CHANNEL_PARAMS_API_S_VER_1 */
|
||||
u8 channel_flags;
|
||||
u8 n_channels;
|
||||
__le16 reserved2;
|
||||
__le16 reserved;
|
||||
u8 data[];
|
||||
} __packed; /* SCAN_REQUEST_CMD_UMAC_API_S_VER_1 */
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -270,6 +270,9 @@ enum {
|
||||
REPLY_MAX = 0xff,
|
||||
};
|
||||
|
||||
/* Please keep this enum *SORTED* by hex value.
|
||||
* Needed for binary search, otherwise a warning will be triggered.
|
||||
*/
|
||||
enum iwl_phy_ops_subcmd_ids {
|
||||
CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0,
|
||||
DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
|
||||
@ -277,6 +280,8 @@ enum iwl_phy_ops_subcmd_ids {
|
||||
|
||||
/* command groups */
|
||||
enum {
|
||||
LEGACY_GROUP = 0x0,
|
||||
LONG_GROUP = 0x1,
|
||||
PHY_OPS_GROUP = 0x4,
|
||||
};
|
||||
|
||||
|
@ -122,7 +122,7 @@ static void iwl_mvm_dump_fifos(struct iwl_mvm *mvm,
|
||||
unsigned long flags;
|
||||
int i, j;
|
||||
|
||||
if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags))
|
||||
if (!iwl_trans_grab_nic_access(mvm->trans, &flags))
|
||||
return;
|
||||
|
||||
/* Pull RXF data from all RXFs */
|
||||
@ -349,6 +349,7 @@ static const struct {
|
||||
{ .start = 0x00a04560, .end = 0x00a0457c },
|
||||
{ .start = 0x00a04590, .end = 0x00a04598 },
|
||||
{ .start = 0x00a045c0, .end = 0x00a045f4 },
|
||||
{ .start = 0x00a44000, .end = 0x00a7bf80 },
|
||||
};
|
||||
|
||||
static u32 iwl_dump_prph(struct iwl_trans *trans,
|
||||
@ -358,7 +359,7 @@ static u32 iwl_dump_prph(struct iwl_trans *trans,
|
||||
unsigned long flags;
|
||||
u32 prph_len = 0, i;
|
||||
|
||||
if (!iwl_trans_grab_nic_access(trans, false, &flags))
|
||||
if (!iwl_trans_grab_nic_access(trans, &flags))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr); i++) {
|
||||
@ -400,7 +401,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
struct iwl_fw_error_dump_trigger_desc *dump_trig;
|
||||
struct iwl_mvm_dump_ptrs *fw_error_dump;
|
||||
u32 sram_len, sram_ofs;
|
||||
u32 file_len, fifo_data_len = 0;
|
||||
u32 file_len, fifo_data_len = 0, prph_len = 0;
|
||||
u32 smem_len = mvm->cfg->smem_len;
|
||||
u32 sram2_len = mvm->cfg->dccm2_len;
|
||||
bool monitor_dump_only = false;
|
||||
@ -460,12 +461,24 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
sizeof(*dump_data) +
|
||||
sizeof(struct iwl_fw_error_dump_fifo);
|
||||
}
|
||||
|
||||
/* Make room for PRPH registers */
|
||||
for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr); i++) {
|
||||
/* The range includes both boundaries */
|
||||
int num_bytes_in_chunk = iwl_prph_dump_addr[i].end -
|
||||
iwl_prph_dump_addr[i].start + 4;
|
||||
|
||||
prph_len += sizeof(*dump_data) +
|
||||
sizeof(struct iwl_fw_error_dump_prph) +
|
||||
num_bytes_in_chunk;
|
||||
}
|
||||
}
|
||||
|
||||
file_len = sizeof(*dump_file) +
|
||||
sizeof(*dump_data) * 2 +
|
||||
sram_len + sizeof(*dump_mem) +
|
||||
fifo_data_len +
|
||||
prph_len +
|
||||
sizeof(*dump_info);
|
||||
|
||||
/* Make room for the SMEM, if it exists */
|
||||
@ -489,17 +502,6 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
sizeof(*dump_info);
|
||||
}
|
||||
|
||||
/* Make room for PRPH registers */
|
||||
for (i = 0; i < ARRAY_SIZE(iwl_prph_dump_addr); i++) {
|
||||
/* The range includes both boundaries */
|
||||
int num_bytes_in_chunk = iwl_prph_dump_addr[i].end -
|
||||
iwl_prph_dump_addr[i].start + 4;
|
||||
|
||||
file_len += sizeof(*dump_data) +
|
||||
sizeof(struct iwl_fw_error_dump_prph) +
|
||||
num_bytes_in_chunk;
|
||||
}
|
||||
|
||||
/*
|
||||
* In 8000 HW family B-step include the ICCM (which resides separately)
|
||||
*/
|
||||
@ -625,6 +627,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
|
||||
}
|
||||
|
||||
dump_data = iwl_fw_error_next_data(dump_data);
|
||||
if (prph_len)
|
||||
iwl_dump_prph(mvm->trans, &dump_data);
|
||||
|
||||
dump_trans_data:
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -27,7 +27,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -855,11 +855,17 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
|
||||
u32 action)
|
||||
{
|
||||
struct iwl_mac_ctx_cmd cmd = {};
|
||||
u32 tfd_queue_msk = 0;
|
||||
int ret, i;
|
||||
|
||||
WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
|
||||
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
|
||||
|
||||
for (i = 0; i < IEEE80211_NUM_ACS; i++)
|
||||
if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE)
|
||||
tfd_queue_msk |= BIT(vif->hw_queue[i]);
|
||||
|
||||
cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
|
||||
MAC_FILTER_IN_CONTROL_AND_MGMT |
|
||||
MAC_FILTER_IN_BEACON |
|
||||
@ -867,6 +873,12 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
|
||||
MAC_FILTER_IN_CRC32);
|
||||
ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS);
|
||||
|
||||
/* Allocate sniffer station */
|
||||
ret = iwl_mvm_allocate_int_sta(mvm, &mvm->snif_sta, tfd_queue_msk,
|
||||
vif->type);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
|
||||
}
|
||||
|
||||
@ -1289,8 +1301,10 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
|
||||
mvmvif->uploaded = false;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR)
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR) {
|
||||
__clear_bit(IEEE80211_HW_RX_INCLUDES_FCS, mvm->hw->flags);
|
||||
iwl_mvm_dealloc_snif_sta(mvm);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -439,6 +439,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
|
||||
ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
|
||||
|
||||
if (mvm->trans->max_skb_frags)
|
||||
hw->netdev_features = NETIF_F_HIGHDMA | NETIF_F_SG;
|
||||
|
||||
hw->queues = mvm->first_agg_queue;
|
||||
hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
|
||||
hw->radiotap_mcs_details |= IEEE80211_RADIOTAP_MCS_HAVE_FEC |
|
||||
@ -664,6 +667,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
if (!iwl_mvm_is_csum_supported(mvm))
|
||||
hw->netdev_features &= ~NETIF_F_RXCSUM;
|
||||
|
||||
if (IWL_MVM_SW_TX_CSUM_OFFLOAD)
|
||||
hw->netdev_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
|
||||
NETIF_F_TSO | NETIF_F_TSO6;
|
||||
|
||||
ret = ieee80211_register_hw(mvm->hw);
|
||||
if (ret)
|
||||
iwl_mvm_leds_exit(mvm);
|
||||
@ -964,6 +971,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
mvm->calibrating = false;
|
||||
|
||||
/* just in case one was running */
|
||||
iwl_mvm_cleanup_roc_te(mvm);
|
||||
ieee80211_remain_on_channel_expired(mvm->hw);
|
||||
|
||||
/*
|
||||
@ -976,6 +984,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT;
|
||||
|
||||
iwl_mvm_reset_phy_ctxts(mvm);
|
||||
memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table));
|
||||
memset(mvm->sta_drained, 0, sizeof(mvm->sta_drained));
|
||||
memset(mvm->tfd_drained, 0, sizeof(mvm->tfd_drained));
|
||||
memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
|
||||
@ -993,6 +1002,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
mvm->vif_count = 0;
|
||||
mvm->rx_ba_sessions = 0;
|
||||
mvm->fw_dbg_conf = FW_DBG_INVALID;
|
||||
mvm->scan_type = IWL_SCAN_TYPE_NOT_SET;
|
||||
|
||||
/* keep statistics ticking */
|
||||
iwl_mvm_accu_radio_stats(mvm);
|
||||
@ -1004,10 +1014,18 @@ int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
/* Clean up some internal and mac80211 state on restart */
|
||||
if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
||||
iwl_mvm_restart_cleanup(mvm);
|
||||
|
||||
} else {
|
||||
/* Hold the reference to prevent runtime suspend while
|
||||
* the start procedure runs. It's a bit confusing
|
||||
* that the UCODE_DOWN reference is taken, but it just
|
||||
* means "UCODE is not UP yet". ( TODO: rename this
|
||||
* reference).
|
||||
*/
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
}
|
||||
ret = iwl_mvm_up(mvm);
|
||||
|
||||
if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
@ -1074,15 +1092,13 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
|
||||
|
||||
static void iwl_mvm_resume_complete(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (!iwl_mvm_is_d0i3_supported(mvm))
|
||||
return;
|
||||
|
||||
if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND)
|
||||
if (!wait_event_timeout(mvm->d0i3_exit_waitq,
|
||||
if (iwl_mvm_is_d0i3_supported(mvm) &&
|
||||
iwl_mvm_enter_d0i3_on_suspend(mvm))
|
||||
WARN_ONCE(!wait_event_timeout(mvm->d0i3_exit_waitq,
|
||||
!test_bit(IWL_MVM_STATUS_IN_D0I3,
|
||||
&mvm->status),
|
||||
HZ))
|
||||
WARN_ONCE(1, "D0i3 exit on resume timed out\n");
|
||||
HZ),
|
||||
"D0i3 exit on resume timed out\n");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1110,14 +1126,6 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
|
||||
*/
|
||||
memset(&mvm->accu_radio_stats, 0, sizeof(mvm->accu_radio_stats));
|
||||
|
||||
/*
|
||||
* Disallow low power states when the FW is down by taking
|
||||
* the UCODE_DOWN ref. in case of ongoing hw restart the
|
||||
* ref is already taken, so don't take it again.
|
||||
*/
|
||||
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
/* async_handlers_wk is now blocked */
|
||||
|
||||
/*
|
||||
@ -1729,8 +1737,8 @@ bool iwl_mvm_bcast_filter_build_cmd(struct iwl_mvm *mvm,
|
||||
|
||||
return true;
|
||||
}
|
||||
static int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
|
||||
static int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_bcast_filter_cmd cmd;
|
||||
|
||||
@ -1744,8 +1752,7 @@ static int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm,
|
||||
sizeof(cmd), &cmd);
|
||||
}
|
||||
#else
|
||||
static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -1860,7 +1867,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
iwl_mvm_recalc_multicast(mvm);
|
||||
iwl_mvm_configure_bcast_filter(mvm, vif);
|
||||
iwl_mvm_configure_bcast_filter(mvm);
|
||||
|
||||
/* reset rssi values */
|
||||
mvmvif->bf_data.ave_beacon_signal = 0;
|
||||
@ -1868,6 +1875,9 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
||||
iwl_mvm_bt_coex_vif_change(mvm);
|
||||
iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT,
|
||||
IEEE80211_SMPS_AUTOMATIC);
|
||||
if (fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_UMAC_SCAN))
|
||||
iwl_mvm_config_scan(mvm);
|
||||
} else if (changes & BSS_CHANGED_BEACON_INFO) {
|
||||
/*
|
||||
* We received a beacon _after_ association so
|
||||
@ -1908,7 +1918,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
||||
|
||||
if (changes & BSS_CHANGED_ARP_FILTER) {
|
||||
IWL_DEBUG_MAC80211(mvm, "arp filter changed\n");
|
||||
iwl_mvm_configure_bcast_filter(mvm, vif);
|
||||
iwl_mvm_configure_bcast_filter(mvm);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2238,7 +2248,6 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
/*
|
||||
@ -2254,11 +2263,6 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
|
||||
rcu_assign_pointer(mvm->fw_id_to_mac_id[mvm_sta->sta_id],
|
||||
ERR_PTR(-ENOENT));
|
||||
|
||||
if (mvm_sta->vif->type == NL80211_IFTYPE_AP) {
|
||||
mvmvif->ap_assoc_sta_count--;
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
}
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
@ -2370,6 +2374,10 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
ret = 0;
|
||||
} else if (old_state == IEEE80211_STA_AUTH &&
|
||||
new_state == IEEE80211_STA_ASSOC) {
|
||||
if (vif->type == NL80211_IFTYPE_AP) {
|
||||
mvmvif->ap_assoc_sta_count++;
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
}
|
||||
ret = iwl_mvm_update_sta(mvm, vif, sta);
|
||||
if (ret == 0)
|
||||
iwl_mvm_rs_rate_init(mvm, sta,
|
||||
@ -2396,6 +2404,10 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
|
||||
ret = 0;
|
||||
} else if (old_state == IEEE80211_STA_ASSOC &&
|
||||
new_state == IEEE80211_STA_AUTH) {
|
||||
if (vif->type == NL80211_IFTYPE_AP) {
|
||||
mvmvif->ap_assoc_sta_count--;
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
}
|
||||
ret = 0;
|
||||
} else if (old_state == IEEE80211_STA_AUTH &&
|
||||
new_state == IEEE80211_STA_NONE) {
|
||||
@ -3116,6 +3128,11 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
|
||||
ret = iwl_mvm_update_quotas(mvm, false, NULL);
|
||||
if (ret)
|
||||
goto out_remove_binding;
|
||||
|
||||
ret = iwl_mvm_add_snif_sta(mvm, vif);
|
||||
if (ret)
|
||||
goto out_remove_binding;
|
||||
|
||||
}
|
||||
|
||||
/* Handle binding during CSA */
|
||||
@ -3189,6 +3206,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
mvmvif->monitor_active = false;
|
||||
mvmvif->ps_disabled = false;
|
||||
iwl_mvm_rm_snif_sta(mvm, vif);
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
/* This part is triggered only during CSA */
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
@ -294,6 +294,7 @@ enum iwl_mvm_ref_type {
|
||||
IWL_MVM_REF_EXIT_WORK,
|
||||
IWL_MVM_REF_PROTECT_CSA,
|
||||
IWL_MVM_REF_FW_DBG_COLLECT,
|
||||
IWL_MVM_REF_INIT_UCODE,
|
||||
|
||||
/* update debugfs.c when changing this */
|
||||
|
||||
@ -404,7 +405,7 @@ struct iwl_mvm_vif {
|
||||
*/
|
||||
struct iwl_mvm_phy_ctxt *phy_ctxt;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_PM
|
||||
/* WoWLAN GTK rekey data */
|
||||
struct {
|
||||
u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
|
||||
@ -421,6 +422,7 @@ struct iwl_mvm_vif {
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
/* IPv6 addresses for WoWLAN */
|
||||
struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX];
|
||||
unsigned long tentative_addrs[BITS_TO_LONGS(IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX)];
|
||||
int num_target_ipv6_addrs;
|
||||
#endif
|
||||
|
||||
@ -475,6 +477,14 @@ enum iwl_scan_status {
|
||||
IWL_MVM_SCAN_MASK = 0xff,
|
||||
};
|
||||
|
||||
enum iwl_mvm_scan_type {
|
||||
IWL_SCAN_TYPE_NOT_SET,
|
||||
IWL_SCAN_TYPE_UNASSOC,
|
||||
IWL_SCAN_TYPE_WILD,
|
||||
IWL_SCAN_TYPE_MILD,
|
||||
IWL_SCAN_TYPE_FRAGMENTED,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_nvm_section - describes an NVM section in memory.
|
||||
*
|
||||
@ -643,7 +653,7 @@ struct iwl_mvm {
|
||||
unsigned int scan_status;
|
||||
void *scan_cmd;
|
||||
struct iwl_mcast_filter_cmd *mcast_filter_cmd;
|
||||
bool scan_fragmented;
|
||||
enum iwl_mvm_scan_type scan_type;
|
||||
|
||||
/* max number of simultaneous scans the FW supports */
|
||||
unsigned int max_scans;
|
||||
@ -667,6 +677,7 @@ struct iwl_mvm {
|
||||
|
||||
/* Internal station */
|
||||
struct iwl_mvm_int_sta aux_sta;
|
||||
struct iwl_mvm_int_sta snif_sta;
|
||||
|
||||
bool last_ebs_successful;
|
||||
|
||||
@ -727,7 +738,7 @@ struct iwl_mvm {
|
||||
|
||||
struct ieee80211_vif *p2p_device_vif;
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_PM
|
||||
struct wiphy_wowlan_support wowlan;
|
||||
int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
|
||||
|
||||
@ -924,6 +935,19 @@ static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm)
|
||||
IWL_UCODE_TLV_CAPA_DQA_SUPPORT);
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm)
|
||||
{
|
||||
/* For now we only use this mode to differentiate between
|
||||
* slave transports, which handle D0i3 entry in suspend by
|
||||
* themselves in conjunction with runtime PM D0i3. So, this
|
||||
* function is used to check whether we need to do anything
|
||||
* when entering suspend or if the transport layer has already
|
||||
* done it.
|
||||
*/
|
||||
return (mvm->trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3) &&
|
||||
(mvm->trans->runtime_pm_mode != IWL_PLAT_PM_MODE_D0I3);
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm)
|
||||
{
|
||||
bool nvm_lar = mvm->nvm_data->lar_enabled;
|
||||
@ -1111,6 +1135,11 @@ bool iwl_mvm_bcast_filter_build_cmd(struct iwl_mvm *mvm,
|
||||
void iwl_mvm_rx_rx_phy_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_phy_cmd_mq(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm,
|
||||
struct iwl_rx_cmd_buffer *rxb, int queue);
|
||||
void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
|
||||
void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
|
||||
@ -1249,10 +1278,6 @@ static inline void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
|
||||
/* D3 (WoWLAN, NetDetect) */
|
||||
int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
|
||||
int iwl_mvm_resume(struct ieee80211_hw *hw);
|
||||
int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool configure_keys,
|
||||
u32 cmd_flags);
|
||||
void iwl_mvm_set_wakeup(struct ieee80211_hw *hw, bool enabled);
|
||||
void iwl_mvm_set_rekey_data(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
@ -1263,10 +1288,31 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw,
|
||||
void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif, int idx);
|
||||
extern const struct file_operations iwl_dbgfs_d3_test_ops;
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#ifdef CONFIG_PM
|
||||
int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool host_awake,
|
||||
u32 cmd_flags);
|
||||
void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_wowlan_status *status);
|
||||
void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif);
|
||||
#else
|
||||
static inline int iwl_mvm_wowlan_config_key_params(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool host_awake,
|
||||
u32 cmd_flags)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void iwl_mvm_d0i3_update_keys(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_wowlan_status *status)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
@ -1277,6 +1323,7 @@ void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
|
||||
int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool disable_offloading,
|
||||
bool offload_ns,
|
||||
u32 cmd_flags);
|
||||
|
||||
/* D0i3 */
|
||||
|
@ -26,7 +26,7 @@
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
|
@ -7,6 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@ -33,6 +34,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -64,6 +66,7 @@
|
||||
*****************************************************************************/
|
||||
#include <net/ipv6.h>
|
||||
#include <net/addrconf.h>
|
||||
#include <linux/bitops.h>
|
||||
#include "mvm.h"
|
||||
|
||||
void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
|
||||
@ -86,6 +89,7 @@ void iwl_mvm_set_wowlan_qos_seq(struct iwl_mvm_sta *mvm_ap_sta,
|
||||
int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
bool disable_offloading,
|
||||
bool offload_ns,
|
||||
u32 cmd_flags)
|
||||
{
|
||||
union {
|
||||
@ -106,6 +110,13 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
int i;
|
||||
/*
|
||||
* Skip tentative address when ns offload is enabled to avoid
|
||||
* violating RFC4862.
|
||||
* Keep tentative address when ns offload is disabled so the NS packets
|
||||
* will not be filtered out and will wake up the host.
|
||||
*/
|
||||
bool skip_tentative = offload_ns;
|
||||
|
||||
if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL ||
|
||||
capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) {
|
||||
@ -113,6 +124,7 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
struct iwl_targ_addr *addrs;
|
||||
int n_nsc, n_addrs;
|
||||
int c;
|
||||
int num_skipped = 0;
|
||||
|
||||
if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) {
|
||||
nsc = cmd.v3s.ns_config;
|
||||
@ -126,9 +138,6 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L;
|
||||
}
|
||||
|
||||
if (mvmvif->num_target_ipv6_addrs)
|
||||
enabled |= IWL_D3_PROTO_OFFLOAD_NS;
|
||||
|
||||
/*
|
||||
* For each address we have (and that will fit) fill a target
|
||||
* address struct and combine for NS offload structs with the
|
||||
@ -140,6 +149,12 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
struct in6_addr solicited_addr;
|
||||
int j;
|
||||
|
||||
if (skip_tentative &&
|
||||
test_bit(i, mvmvif->tentative_addrs)) {
|
||||
num_skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
addrconf_addr_solict_mult(&mvmvif->target_ipv6_addrs[i],
|
||||
&solicited_addr);
|
||||
for (j = 0; j < c; j++)
|
||||
@ -154,41 +169,64 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
memcpy(nsc[j].target_mac_addr, vif->addr, ETH_ALEN);
|
||||
}
|
||||
|
||||
if (mvmvif->num_target_ipv6_addrs - num_skipped)
|
||||
enabled |= IWL_D3_PROTO_IPV6_VALID;
|
||||
|
||||
if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL)
|
||||
cmd.v3s.num_valid_ipv6_addrs = cpu_to_le32(i);
|
||||
cmd.v3s.num_valid_ipv6_addrs =
|
||||
cpu_to_le32(i - num_skipped);
|
||||
else
|
||||
cmd.v3l.num_valid_ipv6_addrs = cpu_to_le32(i);
|
||||
cmd.v3l.num_valid_ipv6_addrs =
|
||||
cpu_to_le32(i - num_skipped);
|
||||
} else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) {
|
||||
if (mvmvif->num_target_ipv6_addrs) {
|
||||
enabled |= IWL_D3_PROTO_OFFLOAD_NS;
|
||||
memcpy(cmd.v2.ndp_mac_addr, vif->addr, ETH_ALEN);
|
||||
}
|
||||
bool found = false;
|
||||
|
||||
BUILD_BUG_ON(sizeof(cmd.v2.target_ipv6_addr[0]) !=
|
||||
sizeof(mvmvif->target_ipv6_addrs[0]));
|
||||
|
||||
for (i = 0; i < min(mvmvif->num_target_ipv6_addrs,
|
||||
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2); i++)
|
||||
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2); i++) {
|
||||
if (skip_tentative &&
|
||||
test_bit(i, mvmvif->tentative_addrs))
|
||||
continue;
|
||||
|
||||
memcpy(cmd.v2.target_ipv6_addr[i],
|
||||
&mvmvif->target_ipv6_addrs[i],
|
||||
sizeof(cmd.v2.target_ipv6_addr[i]));
|
||||
} else {
|
||||
if (mvmvif->num_target_ipv6_addrs) {
|
||||
enabled |= IWL_D3_PROTO_OFFLOAD_NS;
|
||||
memcpy(cmd.v1.ndp_mac_addr, vif->addr, ETH_ALEN);
|
||||
}
|
||||
|
||||
found = true;
|
||||
}
|
||||
if (found) {
|
||||
enabled |= IWL_D3_PROTO_IPV6_VALID;
|
||||
memcpy(cmd.v2.ndp_mac_addr, vif->addr, ETH_ALEN);
|
||||
}
|
||||
} else {
|
||||
bool found = false;
|
||||
BUILD_BUG_ON(sizeof(cmd.v1.target_ipv6_addr[0]) !=
|
||||
sizeof(mvmvif->target_ipv6_addrs[0]));
|
||||
|
||||
for (i = 0; i < min(mvmvif->num_target_ipv6_addrs,
|
||||
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1); i++)
|
||||
IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1); i++) {
|
||||
if (skip_tentative &&
|
||||
test_bit(i, mvmvif->tentative_addrs))
|
||||
continue;
|
||||
|
||||
memcpy(cmd.v1.target_ipv6_addr[i],
|
||||
&mvmvif->target_ipv6_addrs[i],
|
||||
sizeof(cmd.v1.target_ipv6_addr[i]));
|
||||
}
|
||||
#endif
|
||||
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
enabled |= IWL_D3_PROTO_IPV6_VALID;
|
||||
memcpy(cmd.v1.ndp_mac_addr, vif->addr, ETH_ALEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (offload_ns && (enabled & IWL_D3_PROTO_IPV6_VALID))
|
||||
enabled |= IWL_D3_PROTO_OFFLOAD_NS;
|
||||
#endif
|
||||
if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) {
|
||||
common = &cmd.v3s.common;
|
||||
size = sizeof(cmd.v3s);
|
||||
@ -204,7 +242,7 @@ int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm,
|
||||
}
|
||||
|
||||
if (vif->bss_conf.arp_addr_cnt) {
|
||||
enabled |= IWL_D3_PROTO_OFFLOAD_ARP;
|
||||
enabled |= IWL_D3_PROTO_OFFLOAD_ARP | IWL_D3_PROTO_IPV4_VALID;
|
||||
common->host_ipv4_addr = vif->bss_conf.arp_addr_list[0];
|
||||
memcpy(common->arp_mac_addr, vif->addr, ETH_ALEN);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user