Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
This commit is contained in:
commit
d17ec4d552
|
@ -87,6 +87,16 @@ config IWLWIFI_BCAST_FILTERING
|
|||
If unsure, don't enable this option, as some programs might
|
||||
expect incoming broadcasts for their normal operations.
|
||||
|
||||
config IWLWIFI_UAPSD
|
||||
bool "enable U-APSD by default"
|
||||
depends on IWLMVM
|
||||
help
|
||||
Say Y here to enable U-APSD by default. This may cause
|
||||
interoperability problems with some APs, manifesting in lower than
|
||||
expected throughput due to those APs not enabling aggregation
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
menu "Debugging Options"
|
||||
|
||||
config IWLWIFI_DEBUG
|
||||
|
|
|
@ -580,7 +580,7 @@ turn_off:
|
|||
* time, or we hadn't time to drain the AC queues.
|
||||
*/
|
||||
if (agg_state == IWL_AGG_ON)
|
||||
iwl_trans_txq_disable(priv->trans, txq_id);
|
||||
iwl_trans_txq_disable(priv->trans, txq_id, true);
|
||||
else
|
||||
IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n",
|
||||
agg_state);
|
||||
|
@ -686,7 +686,7 @@ int iwlagn_tx_agg_flush(struct iwl_priv *priv, struct ieee80211_vif *vif,
|
|||
* time, or we hadn't time to drain the AC queues.
|
||||
*/
|
||||
if (agg_state == IWL_AGG_ON)
|
||||
iwl_trans_txq_disable(priv->trans, txq_id);
|
||||
iwl_trans_txq_disable(priv->trans, txq_id, true);
|
||||
else
|
||||
IWL_DEBUG_TX_QUEUES(priv, "Don't disable tx agg: %d\n",
|
||||
agg_state);
|
||||
|
@ -781,7 +781,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid)
|
|||
"Can continue DELBA flow ssn = next_recl = %d\n",
|
||||
tid_data->next_reclaimed);
|
||||
iwl_trans_txq_disable(priv->trans,
|
||||
tid_data->agg.txq_id);
|
||||
tid_data->agg.txq_id, true);
|
||||
iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id);
|
||||
tid_data->agg.state = IWL_AGG_OFF;
|
||||
ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -145,6 +145,7 @@ do { \
|
|||
#define IWL_DL_HCMD 0x00000004
|
||||
#define IWL_DL_STATE 0x00000008
|
||||
/* 0x000000F0 - 0x00000010 */
|
||||
#define IWL_DL_QUOTA 0x00000010
|
||||
#define IWL_DL_TE 0x00000020
|
||||
#define IWL_DL_EEPROM 0x00000040
|
||||
#define IWL_DL_RADIO 0x00000080
|
||||
|
@ -189,6 +190,7 @@ do { \
|
|||
#define IWL_DEBUG_LED(p, f, a...) IWL_DEBUG(p, IWL_DL_LED, f, ## a)
|
||||
#define IWL_DEBUG_WEP(p, f, a...) IWL_DEBUG(p, IWL_DL_WEP, f, ## a)
|
||||
#define IWL_DEBUG_HC(p, f, a...) IWL_DEBUG(p, IWL_DL_HCMD, f, ## a)
|
||||
#define IWL_DEBUG_QUOTA(p, f, a...) IWL_DEBUG(p, IWL_DL_QUOTA, f, ## a)
|
||||
#define IWL_DEBUG_TE(p, f, a...) IWL_DEBUG(p, IWL_DL_TE, f, ## a)
|
||||
#define IWL_DEBUG_EEPROM(d, f, a...) IWL_DEBUG_DEV(d, IWL_DL_EEPROM, f, ## a)
|
||||
#define IWL_DEBUG_CALIB(p, f, a...) IWL_DEBUG(p, IWL_DL_CALIB, f, ## a)
|
||||
|
|
|
@ -36,15 +36,8 @@
|
|||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite8);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ioread32);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_iowrite32);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_rx);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_tx);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_event);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_error);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_cont_event);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dev_ucode_wrap_event);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_info);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_warn);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_crit);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_err);
|
||||
EXPORT_TRACEPOINT_SYMBOL(iwlwifi_dbg);
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -1254,7 +1256,9 @@ struct iwl_mod_params iwlwifi_mod_params = {
|
|||
.bt_coex_active = true,
|
||||
.power_level = IWL_POWER_INDEX_1,
|
||||
.wd_disable = true,
|
||||
.uapsd_disable = false,
|
||||
#ifndef CONFIG_IWLWIFI_UAPSD
|
||||
.uapsd_disable = true,
|
||||
#endif /* CONFIG_IWLWIFI_UAPSD */
|
||||
/* the rest are 0 by default */
|
||||
};
|
||||
IWL_EXPORT_SYMBOL(iwlwifi_mod_params);
|
||||
|
@ -1370,7 +1374,11 @@ MODULE_PARM_DESC(nvm_file, "NVM file name");
|
|||
|
||||
module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable,
|
||||
bool, S_IRUGO);
|
||||
#ifdef CONFIG_IWLWIFI_UAPSD
|
||||
MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)");
|
||||
#else
|
||||
MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: Y)");
|
||||
#endif
|
||||
|
||||
/*
|
||||
* set bt_coex_active to true, uCode will do kill/defer
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -125,6 +127,8 @@ enum iwl_ucode_tlv_flag {
|
|||
* @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
|
||||
* @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
|
||||
* @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
|
||||
* @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
|
||||
* longer than the passive one, which is essential for fragmented scan.
|
||||
*/
|
||||
enum iwl_ucode_tlv_api {
|
||||
IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
|
||||
|
@ -133,6 +137,7 @@ enum iwl_ucode_tlv_api {
|
|||
IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
|
||||
IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
|
||||
IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
|
||||
IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -281,6 +283,7 @@
|
|||
#define SCD_CHAINEXT_EN (SCD_BASE + 0x244)
|
||||
#define SCD_AGGR_SEL (SCD_BASE + 0x248)
|
||||
#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108)
|
||||
#define SCD_EN_CTRL (SCD_BASE + 0x254)
|
||||
|
||||
static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2014 Intel Mobile Communications 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
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __iwl_scd_h__
|
||||
#define __iwl_scd_h__
|
||||
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-prph.h"
|
||||
|
||||
|
||||
static inline void iwl_scd_txq_set_inactive(struct iwl_trans *trans,
|
||||
u16 txq_id)
|
||||
{
|
||||
iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
|
||||
(0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
|
||||
(1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
|
||||
}
|
||||
|
||||
static inline void iwl_scd_txq_set_chain(struct iwl_trans *trans,
|
||||
u16 txq_id)
|
||||
{
|
||||
iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id));
|
||||
}
|
||||
|
||||
static inline void iwl_scd_txq_enable_agg(struct iwl_trans *trans,
|
||||
u16 txq_id)
|
||||
{
|
||||
iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
|
||||
}
|
||||
|
||||
static inline void iwl_scd_txq_disable_agg(struct iwl_trans *trans,
|
||||
u16 txq_id)
|
||||
{
|
||||
iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
|
||||
}
|
||||
|
||||
static inline void iwl_scd_disable_agg(struct iwl_trans *trans)
|
||||
{
|
||||
iwl_set_bits_prph(trans, SCD_AGGR_SEL, 0);
|
||||
}
|
||||
|
||||
static inline void iwl_scd_activate_fifos(struct iwl_trans *trans)
|
||||
{
|
||||
iwl_write_prph(trans, SCD_TXFACT, IWL_MASK(0, 7));
|
||||
}
|
||||
|
||||
static inline void iwl_scd_deactivate_fifos(struct iwl_trans *trans)
|
||||
{
|
||||
iwl_write_prph(trans, SCD_TXFACT, 0);
|
||||
}
|
||||
|
||||
static inline void iwl_scd_enable_set_active(struct iwl_trans *trans,
|
||||
u32 value)
|
||||
{
|
||||
iwl_write_prph(trans, SCD_EN_CTRL, value);
|
||||
}
|
||||
#endif
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -401,6 +403,14 @@ struct iwl_trans_dump_data {
|
|||
|
||||
struct iwl_trans;
|
||||
|
||||
struct iwl_trans_txq_scd_cfg {
|
||||
u8 fifo;
|
||||
s8 sta_id;
|
||||
u8 tid;
|
||||
bool aggregate;
|
||||
int frame_limit;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_trans_ops - transport specific operations
|
||||
*
|
||||
|
@ -437,7 +447,9 @@ struct iwl_trans;
|
|||
* Must be atomic
|
||||
* @txq_enable: setup a queue. To setup an AC queue, use the
|
||||
* iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before
|
||||
* this one. The op_mode must not configure the HCMD queue. May sleep.
|
||||
* this one. The op_mode must not configure the HCMD queue. The scheduler
|
||||
* configuration may be %NULL, in which case the hardware will not be
|
||||
* configured. May sleep.
|
||||
* @txq_disable: de-configure a Tx queue to send AMPDUs
|
||||
* Must be atomic
|
||||
* @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
|
||||
|
@ -492,9 +504,10 @@ struct iwl_trans_ops {
|
|||
void (*reclaim)(struct iwl_trans *trans, int queue, int ssn,
|
||||
struct sk_buff_head *skbs);
|
||||
|
||||
void (*txq_enable)(struct iwl_trans *trans, int queue, int fifo,
|
||||
int sta_id, int tid, int frame_limit, u16 ssn);
|
||||
void (*txq_disable)(struct iwl_trans *trans, int queue);
|
||||
void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
|
||||
const struct iwl_trans_txq_scd_cfg *cfg);
|
||||
void (*txq_disable)(struct iwl_trans *trans, int queue,
|
||||
bool configure_scd);
|
||||
|
||||
int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
|
||||
int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
|
||||
|
@ -766,29 +779,57 @@ static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue,
|
|||
trans->ops->reclaim(trans, queue, ssn, skbs);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue)
|
||||
static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue,
|
||||
bool configure_scd)
|
||||
{
|
||||
trans->ops->txq_disable(trans, queue);
|
||||
trans->ops->txq_disable(trans, queue, configure_scd);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
|
||||
int fifo, int sta_id, int tid,
|
||||
int frame_limit, u16 ssn)
|
||||
static inline void
|
||||
iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn,
|
||||
const struct iwl_trans_txq_scd_cfg *cfg)
|
||||
{
|
||||
might_sleep();
|
||||
|
||||
if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
|
||||
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
|
||||
|
||||
trans->ops->txq_enable(trans, queue, fifo, sta_id, tid,
|
||||
frame_limit, ssn);
|
||||
trans->ops->txq_enable(trans, queue, ssn, cfg);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
|
||||
int fifo, int sta_id, int tid,
|
||||
int frame_limit, u16 ssn)
|
||||
{
|
||||
struct iwl_trans_txq_scd_cfg cfg = {
|
||||
.fifo = fifo,
|
||||
.sta_id = sta_id,
|
||||
.tid = tid,
|
||||
.frame_limit = frame_limit,
|
||||
.aggregate = sta_id >= 0,
|
||||
};
|
||||
|
||||
iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
|
||||
int fifo)
|
||||
{
|
||||
iwl_trans_txq_enable(trans, queue, fifo, -1,
|
||||
IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0);
|
||||
struct iwl_trans_txq_scd_cfg cfg = {
|
||||
.fifo = fifo,
|
||||
.sta_id = -1,
|
||||
.tid = IWL_MAX_TID_COUNT,
|
||||
.frame_limit = IWL_FRAME_LIMIT,
|
||||
.aggregate = false,
|
||||
};
|
||||
|
||||
iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg);
|
||||
}
|
||||
|
||||
static inline void
|
||||
iwl_trans_txq_enable_no_scd(struct iwl_trans *trans, int queue, u16 ssn)
|
||||
{
|
||||
iwl_trans_txq_enable_cfg(trans, queue, ssn, NULL);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -700,7 +702,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
return ret;
|
||||
rcu_assign_pointer(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id], ap_sta);
|
||||
|
||||
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false);
|
||||
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -119,6 +121,10 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
|
|||
IWL_DEBUG_POWER(mvm, "uapsd_misbehaving_enable=%d\n", val);
|
||||
dbgfs_pm->uapsd_misbehaving = val;
|
||||
break;
|
||||
case MVM_DEBUGFS_PM_USE_PS_POLL:
|
||||
IWL_DEBUG_POWER(mvm, "use_ps_poll=%d\n", val);
|
||||
dbgfs_pm->use_ps_poll = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,6 +175,10 @@ static ssize_t iwl_dbgfs_pm_params_write(struct ieee80211_vif *vif, char *buf,
|
|||
if (sscanf(buf + 18, "%d", &val) != 1)
|
||||
return -EINVAL;
|
||||
param = MVM_DEBUGFS_PM_UAPSD_MISBEHAVING;
|
||||
} else if (!strncmp("use_ps_poll=", buf, 12)) {
|
||||
if (sscanf(buf + 12, "%d", &val) != 1)
|
||||
return -EINVAL;
|
||||
param = MVM_DEBUGFS_PM_USE_PS_POLL;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -257,6 +259,70 @@ static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf,
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
char buf[16];
|
||||
int pos;
|
||||
|
||||
if (!mvm->temperature_test)
|
||||
pos = scnprintf(buf , sizeof(buf), "disabled\n");
|
||||
else
|
||||
pos = scnprintf(buf , sizeof(buf), "%d\n", mvm->temperature);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set NIC Temperature
|
||||
* Cause the driver to ignore the actual NIC temperature reported by the FW
|
||||
* Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -
|
||||
* IWL_MVM_DEBUG_SET_TEMPERATURE_MAX
|
||||
* Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE
|
||||
*/
|
||||
static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
|
||||
char *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
int temperature;
|
||||
|
||||
if (kstrtoint(buf, 10, &temperature))
|
||||
return -EINVAL;
|
||||
/* not a legal temperature */
|
||||
if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX &&
|
||||
temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) ||
|
||||
temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) {
|
||||
if (!mvm->temperature_test)
|
||||
goto out;
|
||||
|
||||
mvm->temperature_test = false;
|
||||
/* Since we can't read the temp while awake, just set
|
||||
* it to zero until we get the next RX stats from the
|
||||
* firmware.
|
||||
*/
|
||||
mvm->temperature = 0;
|
||||
} else {
|
||||
mvm->temperature_test = true;
|
||||
mvm->temperature = temperature;
|
||||
}
|
||||
IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n",
|
||||
mvm->temperature_test ? "En" : "Dis" ,
|
||||
mvm->temperature);
|
||||
/* handle the temperature change */
|
||||
iwl_mvm_tt_handler(mvm);
|
||||
|
||||
out:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
@ -1296,6 +1362,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
|
|||
MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(stations);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(bt_notif);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
|
||||
|
@ -1336,6 +1403,8 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
|||
MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir,
|
||||
S_IWUSR | S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_error_dump, dbgfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR);
|
||||
|
@ -1380,6 +1449,13 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
|||
goto err;
|
||||
#endif
|
||||
|
||||
if (!debugfs_create_u8("low_latency_agg_frame_limit", S_IRUSR | S_IWUSR,
|
||||
mvm->debugfs_dir,
|
||||
&mvm->low_latency_agg_frame_limit))
|
||||
goto err;
|
||||
if (!debugfs_create_u8("ps_disabled", S_IRUSR,
|
||||
mvm->debugfs_dir, &mvm->ps_disabled))
|
||||
goto err;
|
||||
if (!debugfs_create_blob("nvm_hw", S_IRUSR,
|
||||
mvm->debugfs_dir, &mvm->nvm_hw_blob))
|
||||
goto err;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -73,16 +75,20 @@
|
|||
#include "fw-api-coex.h"
|
||||
#include "fw-api-scan.h"
|
||||
|
||||
/* maximal number of Tx queues in any platform */
|
||||
#define IWL_MVM_MAX_QUEUES 20
|
||||
|
||||
/* Tx queue numbers */
|
||||
enum {
|
||||
IWL_MVM_OFFCHANNEL_QUEUE = 8,
|
||||
IWL_MVM_CMD_QUEUE = 9,
|
||||
};
|
||||
|
||||
#define IWL_MVM_CMD_FIFO 7
|
||||
enum iwl_mvm_tx_fifo {
|
||||
IWL_MVM_TX_FIFO_BK = 0,
|
||||
IWL_MVM_TX_FIFO_BE,
|
||||
IWL_MVM_TX_FIFO_VI,
|
||||
IWL_MVM_TX_FIFO_VO,
|
||||
IWL_MVM_TX_FIFO_MCAST = 5,
|
||||
IWL_MVM_TX_FIFO_CMD = 7,
|
||||
};
|
||||
|
||||
#define IWL_MVM_STATION_COUNT 16
|
||||
|
||||
|
@ -184,6 +190,8 @@ enum {
|
|||
REPLY_RX_MPDU_CMD = 0xc1,
|
||||
BA_NOTIF = 0xc5,
|
||||
|
||||
MARKER_CMD = 0xcb,
|
||||
|
||||
/* BT Coex */
|
||||
BT_COEX_PRIO_TABLE = 0xcc,
|
||||
BT_COEX_PROT_ENV = 0xcd,
|
||||
|
@ -1307,6 +1315,38 @@ struct iwl_bcast_filter_cmd {
|
|||
struct iwl_fw_bcast_mac macs[NUM_MAC_INDEX_DRIVER];
|
||||
} __packed; /* BCAST_FILTERING_HCMD_API_S_VER_1 */
|
||||
|
||||
/*
|
||||
* enum iwl_mvm_marker_id - maker ids
|
||||
*
|
||||
* The ids for different type of markers to insert into the usniffer logs
|
||||
*/
|
||||
enum iwl_mvm_marker_id {
|
||||
MARKER_ID_TX_FRAME_LATENCY = 1,
|
||||
}; /* MARKER_ID_API_E_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_marker - mark info into the usniffer logs
|
||||
*
|
||||
* (MARKER_CMD = 0xcb)
|
||||
*
|
||||
* Mark the UTC time stamp into the usniffer logs together with additional
|
||||
* metadata, so the usniffer output can be parsed.
|
||||
* In the command response the ucode will return the GP2 time.
|
||||
*
|
||||
* @dw_len: The amount of dwords following this byte including this byte.
|
||||
* @marker_id: A unique marker id (iwl_mvm_marker_id).
|
||||
* @reserved: reserved.
|
||||
* @timestamp: in milliseconds since 1970-01-01 00:00:00 UTC
|
||||
* @metadata: additional meta data that will be written to the unsiffer log
|
||||
*/
|
||||
struct iwl_mvm_marker {
|
||||
u8 dwLen;
|
||||
u8 markerId;
|
||||
__le16 reserved;
|
||||
__le64 timestamp;
|
||||
__le32 metadata[0];
|
||||
} __packed; /* MARKER_API_S_VER_1 */
|
||||
|
||||
struct mvm_statistics_dbg {
|
||||
__le32 burst_check;
|
||||
__le32 burst_count;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -242,10 +244,10 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
|
|||
mvm->queue_to_mac80211[i] = i;
|
||||
else
|
||||
mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE;
|
||||
atomic_set(&mvm->queue_stop_count[i], 0);
|
||||
}
|
||||
|
||||
mvm->transport_queue_stop = 0;
|
||||
for (i = 0; i < IEEE80211_MAX_QUEUES; i++)
|
||||
atomic_set(&mvm->mac80211_queue_stop_count[i], 0);
|
||||
|
||||
mvm->ucode_loaded = true;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -81,7 +83,7 @@ struct iwl_mvm_mac_iface_iterator_data {
|
|||
struct ieee80211_vif *vif;
|
||||
unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)];
|
||||
unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)];
|
||||
unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)];
|
||||
u32 used_hw_queues;
|
||||
enum iwl_tsf_id preferred_tsf;
|
||||
bool found_vif;
|
||||
};
|
||||
|
@ -192,12 +194,31 @@ static void iwl_mvm_mac_tsf_id_iter(void *_data, u8 *mac,
|
|||
data->preferred_tsf = NUM_TSF_IDS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the mask of the queues used by the vif
|
||||
*/
|
||||
u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
u32 qmask = 0, ac;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
|
||||
return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
|
||||
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
|
||||
qmask |= BIT(vif->hw_queue[ac]);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
qmask |= BIT(vif->cab_queue);
|
||||
|
||||
return qmask;
|
||||
}
|
||||
|
||||
static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_mac_iface_iterator_data *data = _data;
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
u32 ac;
|
||||
|
||||
/* Iterator may already find the interface being added -- skip it */
|
||||
if (vif == data->vif) {
|
||||
|
@ -206,12 +227,7 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
|
|||
}
|
||||
|
||||
/* Mark the queues used by the vif */
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
|
||||
if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
|
||||
__set_bit(vif->hw_queue[ac], data->used_hw_queues);
|
||||
|
||||
if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
|
||||
__set_bit(vif->cab_queue, data->used_hw_queues);
|
||||
data->used_hw_queues |= iwl_mvm_mac_get_queues_mask(data->mvm, vif);
|
||||
|
||||
/* Mark MAC IDs as used by clearing the available bit, and
|
||||
* (below) mark TSFs as used if their existing use is not
|
||||
|
@ -225,24 +241,6 @@ static void iwl_mvm_mac_iface_iterator(void *_data, u8 *mac,
|
|||
iwl_mvm_mac_tsf_id_iter(_data, mac, vif);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the mask of the queus used by the vif
|
||||
*/
|
||||
u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
u32 qmask = 0, ac;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
|
||||
return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
|
||||
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
|
||||
if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
|
||||
qmask |= BIT(vif->hw_queue[ac]);
|
||||
|
||||
return qmask;
|
||||
}
|
||||
|
||||
void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
|
@ -277,15 +275,15 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
|
|||
.available_tsf_ids = { (1 << NUM_TSF_IDS) - 1 },
|
||||
/* no preference yet */
|
||||
.preferred_tsf = NUM_TSF_IDS,
|
||||
.used_hw_queues = {
|
||||
.used_hw_queues =
|
||||
BIT(IWL_MVM_OFFCHANNEL_QUEUE) |
|
||||
BIT(mvm->aux_queue) |
|
||||
BIT(IWL_MVM_CMD_QUEUE)
|
||||
},
|
||||
BIT(IWL_MVM_CMD_QUEUE),
|
||||
.found_vif = false,
|
||||
};
|
||||
u32 ac;
|
||||
int ret, i;
|
||||
unsigned long used_hw_queues;
|
||||
|
||||
/*
|
||||
* Allocate a MAC ID and a TSF for this MAC, along with the queues
|
||||
|
@ -368,9 +366,11 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
used_hw_queues = data.used_hw_queues;
|
||||
|
||||
/* Find available queues, and allocate them to the ACs */
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
||||
u8 queue = find_first_zero_bit(data.used_hw_queues,
|
||||
u8 queue = find_first_zero_bit(&used_hw_queues,
|
||||
mvm->first_agg_queue);
|
||||
|
||||
if (queue >= mvm->first_agg_queue) {
|
||||
|
@ -379,13 +379,13 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
|
|||
goto exit_fail;
|
||||
}
|
||||
|
||||
__set_bit(queue, data.used_hw_queues);
|
||||
__set_bit(queue, &used_hw_queues);
|
||||
vif->hw_queue[ac] = queue;
|
||||
}
|
||||
|
||||
/* Allocate the CAB queue for softAP and GO interfaces */
|
||||
if (vif->type == NL80211_IFTYPE_AP) {
|
||||
u8 queue = find_first_zero_bit(data.used_hw_queues,
|
||||
u8 queue = find_first_zero_bit(&used_hw_queues,
|
||||
mvm->first_agg_queue);
|
||||
|
||||
if (queue >= mvm->first_agg_queue) {
|
||||
|
@ -452,14 +452,16 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE);
|
||||
iwl_trans_txq_disable(mvm->trans, IWL_MVM_OFFCHANNEL_QUEUE,
|
||||
true);
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
iwl_trans_txq_disable(mvm->trans, vif->cab_queue);
|
||||
iwl_trans_txq_disable(mvm->trans, vif->cab_queue, true);
|
||||
/* fall through */
|
||||
default:
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
|
||||
iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac]);
|
||||
iwl_trans_txq_disable(mvm->trans, vif->hw_queue[ac],
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,6 +588,7 @@ static void iwl_mvm_mac_ctxt_set_ht_flags(struct iwl_mvm *mvm,
|
|||
static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
struct iwl_mac_ctx_cmd *cmd,
|
||||
const u8 *bssid_override,
|
||||
u32 action)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
@ -593,6 +596,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
|
|||
bool ht_enabled = !!(vif->bss_conf.ht_operation_mode &
|
||||
IEEE80211_HT_OP_MODE_PROTECTION);
|
||||
u8 cck_ack_rates, ofdm_ack_rates;
|
||||
const u8 *bssid = bssid_override ?: vif->bss_conf.bssid;
|
||||
int i;
|
||||
|
||||
cmd->id_and_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
|
||||
|
@ -625,8 +629,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
|
|||
cmd->tsf_id = cpu_to_le32(mvmvif->tsf_id);
|
||||
|
||||
memcpy(cmd->node_addr, vif->addr, ETH_ALEN);
|
||||
if (vif->bss_conf.bssid)
|
||||
memcpy(cmd->bssid_addr, vif->bss_conf.bssid, ETH_ALEN);
|
||||
|
||||
if (bssid)
|
||||
memcpy(cmd->bssid_addr, bssid, ETH_ALEN);
|
||||
else
|
||||
eth_broadcast_addr(cmd->bssid_addr);
|
||||
|
||||
|
@ -695,7 +700,8 @@ static int iwl_mvm_mac_ctxt_send_cmd(struct iwl_mvm *mvm,
|
|||
|
||||
static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 action, bool force_assoc_off)
|
||||
u32 action, bool force_assoc_off,
|
||||
const u8 *bssid_override)
|
||||
{
|
||||
struct iwl_mac_ctx_cmd cmd = {};
|
||||
struct iwl_mac_data_sta *ctxt_sta;
|
||||
|
@ -703,7 +709,7 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
|
|||
WARN_ON(vif->type != NL80211_IFTYPE_STATION);
|
||||
|
||||
/* Fill the common data for all mac context types */
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, bssid_override, action);
|
||||
|
||||
if (vif->p2p) {
|
||||
struct ieee80211_p2p_noa_attr *noa =
|
||||
|
@ -784,7 +790,7 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
|
|||
|
||||
WARN_ON(vif->type != NL80211_IFTYPE_MONITOR);
|
||||
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
|
||||
|
||||
cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC |
|
||||
MAC_FILTER_IN_CONTROL_AND_MGMT |
|
||||
|
@ -805,7 +811,7 @@ static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
|
|||
|
||||
WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);
|
||||
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
|
||||
|
||||
cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
|
||||
MAC_FILTER_IN_PROBE_REQUEST);
|
||||
|
@ -844,7 +850,7 @@ static int iwl_mvm_mac_ctxt_cmd_p2p_device(struct iwl_mvm *mvm,
|
|||
|
||||
WARN_ON(vif->type != NL80211_IFTYPE_P2P_DEVICE);
|
||||
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
|
||||
|
||||
cmd.protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
|
||||
|
||||
|
@ -1072,7 +1078,7 @@ static int iwl_mvm_mac_ctxt_cmd_ap(struct iwl_mvm *mvm,
|
|||
WARN_ON(vif->type != NL80211_IFTYPE_AP || vif->p2p);
|
||||
|
||||
/* Fill the common data for all mac context types */
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
|
||||
|
||||
/*
|
||||
* pass probe requests and beacons from other APs (needed
|
||||
|
@ -1098,7 +1104,7 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
|
|||
WARN_ON(vif->type != NL80211_IFTYPE_AP || !vif->p2p);
|
||||
|
||||
/* Fill the common data for all mac context types */
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
|
||||
iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
|
||||
|
||||
/*
|
||||
* pass probe requests and beacons from other APs (needed
|
||||
|
@ -1121,12 +1127,14 @@ static int iwl_mvm_mac_ctxt_cmd_go(struct iwl_mvm *mvm,
|
|||
}
|
||||
|
||||
static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
u32 action, bool force_assoc_off)
|
||||
u32 action, bool force_assoc_off,
|
||||
const u8 *bssid_override)
|
||||
{
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
return iwl_mvm_mac_ctxt_cmd_sta(mvm, vif, action,
|
||||
force_assoc_off);
|
||||
force_assoc_off,
|
||||
bssid_override);
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
if (!vif->p2p)
|
||||
|
@ -1157,7 +1165,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
return -EIO;
|
||||
|
||||
ret = iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_ADD,
|
||||
true);
|
||||
true, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1169,7 +1177,7 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
|||
}
|
||||
|
||||
int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
bool force_assoc_off)
|
||||
bool force_assoc_off, const u8 *bssid_override)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
|
@ -1178,7 +1186,7 @@ int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
return -EIO;
|
||||
|
||||
return iwl_mvm_mac_ctx_send(mvm, vif, FW_CTXT_ACTION_MODIFY,
|
||||
force_assoc_off);
|
||||
force_assoc_off, bssid_override);
|
||||
}
|
||||
|
||||
int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -776,6 +778,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
|||
iwl_trans_stop_device(mvm->trans);
|
||||
|
||||
mvm->scan_status = IWL_MVM_SCAN_NONE;
|
||||
mvm->ps_disabled = false;
|
||||
|
||||
/* just in case one was running */
|
||||
ieee80211_remain_on_channel_expired(mvm->hw);
|
||||
|
@ -803,6 +806,9 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
|||
* ucode_down ref until reconfig is complete */
|
||||
iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
|
||||
|
||||
/* clear any stale d0i3 state */
|
||||
clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
|
||||
|
||||
mvm->vif_count = 0;
|
||||
mvm->rx_ba_sessions = 0;
|
||||
}
|
||||
|
@ -880,7 +886,7 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
|
|||
/* async_handlers_list is empty and will stay empty: HW is stopped */
|
||||
|
||||
/* the fw is stopped, the aux sta is dead: clean up driver state */
|
||||
iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
|
||||
iwl_mvm_del_aux_sta(mvm);
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
|
@ -965,10 +971,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
|||
*/
|
||||
if (vif->type == NL80211_IFTYPE_AP ||
|
||||
vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
|
||||
ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
|
||||
qmask,
|
||||
ieee80211_vif_type_p2p(vif));
|
||||
ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
|
||||
if (ret) {
|
||||
IWL_ERR(mvm, "Failed to allocate bcast sta\n");
|
||||
goto out_release;
|
||||
|
@ -1016,7 +1019,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
|||
if (ret)
|
||||
goto out_unref_phy;
|
||||
|
||||
ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
|
||||
ret = iwl_mvm_add_bcast_sta(mvm, vif);
|
||||
if (ret)
|
||||
goto out_unbind;
|
||||
|
||||
|
@ -1057,14 +1060,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
|||
static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
u32 tfd_msk = 0, ac;
|
||||
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
|
||||
if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
|
||||
tfd_msk |= BIT(vif->hw_queue[ac]);
|
||||
|
||||
if (vif->cab_queue != IEEE80211_INVAL_HW_QUEUE)
|
||||
tfd_msk |= BIT(vif->cab_queue);
|
||||
u32 tfd_msk = iwl_mvm_mac_get_queues_mask(mvm, vif);
|
||||
|
||||
if (tfd_msk) {
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
@ -1120,13 +1116,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
|
|||
mvm->noa_duration = 0;
|
||||
}
|
||||
#endif
|
||||
iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
|
||||
iwl_mvm_dealloc_bcast_sta(mvm, vif);
|
||||
goto out_release;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||
mvm->p2p_device_vif = NULL;
|
||||
iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
|
||||
iwl_mvm_rm_bcast_sta(mvm, vif);
|
||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||
iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
|
||||
mvmvif->phy_ctxt = NULL;
|
||||
|
@ -1445,10 +1441,23 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
|||
if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
|
||||
iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
|
||||
|
||||
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false);
|
||||
/*
|
||||
* If we're not associated yet, take the (new) BSSID before associating
|
||||
* so the firmware knows. If we're already associated, then use the old
|
||||
* BSSID here, and we'll send a cleared one later in the CHANGED_ASSOC
|
||||
* branch for disassociation below.
|
||||
*/
|
||||
if (changes & BSS_CHANGED_BSSID && !mvmvif->associated)
|
||||
memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
|
||||
|
||||
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, mvmvif->bssid);
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
|
||||
|
||||
/* after sending it once, adopt mac80211 data */
|
||||
memcpy(mvmvif->bssid, bss_conf->bssid, ETH_ALEN);
|
||||
mvmvif->associated = bss_conf->assoc;
|
||||
|
||||
if (changes & BSS_CHANGED_ASSOC) {
|
||||
if (bss_conf->assoc) {
|
||||
/* add quota for this interface */
|
||||
|
@ -1476,13 +1485,17 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
|||
*/
|
||||
u32 dur = (11 * vif->bss_conf.beacon_int) / 10;
|
||||
iwl_mvm_protect_session(mvm, vif, dur, dur,
|
||||
5 * dur);
|
||||
5 * dur, false);
|
||||
}
|
||||
|
||||
iwl_mvm_sf_update(mvm, vif, false);
|
||||
iwl_mvm_power_vif_assoc(mvm, vif);
|
||||
if (vif->p2p)
|
||||
if (vif->p2p) {
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_P2P_CLIENT);
|
||||
iwl_mvm_update_smps(mvm, vif,
|
||||
IWL_MVM_SMPS_REQ_PROT,
|
||||
IEEE80211_SMPS_DYNAMIC);
|
||||
}
|
||||
} else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) {
|
||||
/*
|
||||
* If update fails - SF might be running in associated
|
||||
|
@ -1506,6 +1519,13 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
|||
|
||||
if (vif->p2p)
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_P2P_CLIENT);
|
||||
|
||||
/* this will take the cleared BSSID from bss_conf */
|
||||
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
if (ret)
|
||||
IWL_ERR(mvm,
|
||||
"failed to update MAC %pM (clear after unassoc)\n",
|
||||
vif->addr);
|
||||
}
|
||||
|
||||
iwl_mvm_recalc_multicast(mvm);
|
||||
|
@ -1601,7 +1621,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
|
||||
/* Send the bcast station. At this stage the TBTT and DTIM time events
|
||||
* are added and applied to the scheduler */
|
||||
ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta);
|
||||
ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
|
||||
if (ret)
|
||||
goto out_unbind;
|
||||
|
||||
|
@ -1617,7 +1637,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
|
||||
/* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
|
||||
if (vif->p2p && mvm->p2p_device_vif)
|
||||
iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false);
|
||||
iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
|
||||
|
||||
iwl_mvm_ref(mvm, IWL_MVM_REF_AP_IBSS);
|
||||
|
||||
|
@ -1633,7 +1653,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
|
|||
out_quota_failed:
|
||||
iwl_mvm_power_update_mac(mvm);
|
||||
mvmvif->ap_ibss_active = false;
|
||||
iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
|
||||
iwl_mvm_send_rm_bcast_sta(mvm, vif);
|
||||
out_unbind:
|
||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||
out_remove:
|
||||
|
@ -1675,10 +1695,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
|
|||
|
||||
/* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
|
||||
if (vif->p2p && mvm->p2p_device_vif)
|
||||
iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false);
|
||||
iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
|
||||
|
||||
iwl_mvm_update_quotas(mvm, NULL);
|
||||
iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
|
||||
iwl_mvm_send_rm_bcast_sta(mvm, vif);
|
||||
iwl_mvm_binding_remove_vif(mvm, vif);
|
||||
|
||||
iwl_mvm_power_update_mac(mvm);
|
||||
|
@ -1702,7 +1722,7 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
|
|||
|
||||
if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT |
|
||||
BSS_CHANGED_BANDWIDTH) &&
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false))
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL))
|
||||
IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
|
||||
|
||||
/* Need to send a new beacon template to the FW */
|
||||
|
@ -2113,7 +2133,7 @@ static int iwl_mvm_mac_conf_tx(struct ieee80211_hw *hw,
|
|||
int ret;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false);
|
||||
ret = iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
@ -2141,7 +2161,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
|
|||
|
||||
mutex_lock(&mvm->mutex);
|
||||
/* Try really hard to protect the session and hear a beacon */
|
||||
iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500);
|
||||
iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500, false);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX);
|
||||
|
@ -2162,7 +2182,7 @@ static void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
|
|||
|
||||
mutex_lock(&mvm->mutex);
|
||||
/* Protect the session to hear the TDLS setup response on the channel */
|
||||
iwl_mvm_protect_session(mvm, vif, duration, duration, 100);
|
||||
iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
|
||||
|
@ -2700,7 +2720,10 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
|
|||
ret = 0;
|
||||
goto out;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
break;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
/* always disable PS when a monitor interface is active */
|
||||
mvmvif->ps_disabled = true;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
|
@ -2732,7 +2755,20 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
|
|||
if ((vif->type == NL80211_IFTYPE_AP) ||
|
||||
(switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) {
|
||||
iwl_mvm_update_quotas(mvm, NULL);
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false);
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
|
||||
}
|
||||
|
||||
if (vif->csa_active && vif->type == NL80211_IFTYPE_STATION) {
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
|
||||
mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
|
||||
mvmvif->ap_sta_id);
|
||||
|
||||
if (WARN_ON(!mvmsta))
|
||||
goto out;
|
||||
|
||||
/* TODO: only re-enable after the first beacon */
|
||||
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, false);
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
@ -2766,6 +2802,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
|
|||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct ieee80211_vif *disabled_vif = NULL;
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
|
@ -2776,6 +2813,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
|
|||
goto out;
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
mvmvif->monitor_active = false;
|
||||
mvmvif->ps_disabled = false;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
/* This part is triggered only during CSA */
|
||||
|
@ -2796,7 +2834,13 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
|
|||
|
||||
disabled_vif = vif;
|
||||
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, true);
|
||||
mvmsta = iwl_mvm_sta_from_staid_protected(mvm,
|
||||
mvmvif->ap_sta_id);
|
||||
|
||||
if (!WARN_ON(!mvmsta))
|
||||
iwl_mvm_sta_modify_disable_tx(mvm, mvmsta, true);
|
||||
|
||||
iwl_mvm_mac_ctxt_changed(mvm, vif, true, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -103,14 +105,6 @@
|
|||
*/
|
||||
#define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3
|
||||
|
||||
enum iwl_mvm_tx_fifo {
|
||||
IWL_MVM_TX_FIFO_BK = 0,
|
||||
IWL_MVM_TX_FIFO_BE,
|
||||
IWL_MVM_TX_FIFO_VI,
|
||||
IWL_MVM_TX_FIFO_VO,
|
||||
IWL_MVM_TX_FIFO_MCAST = 5,
|
||||
};
|
||||
|
||||
extern const struct ieee80211_ops iwl_mvm_hw_ops;
|
||||
|
||||
/**
|
||||
|
@ -203,6 +197,7 @@ enum iwl_dbgfs_pm_mask {
|
|||
MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
|
||||
MVM_DEBUGFS_PM_SNOOZE_ENABLE = BIT(8),
|
||||
MVM_DEBUGFS_PM_UAPSD_MISBEHAVING = BIT(9),
|
||||
MVM_DEBUGFS_PM_USE_PS_POLL = BIT(10),
|
||||
};
|
||||
|
||||
struct iwl_dbgfs_pm {
|
||||
|
@ -215,6 +210,7 @@ struct iwl_dbgfs_pm {
|
|||
u32 lprx_rssi_threshold;
|
||||
bool snooze_ena;
|
||||
bool uapsd_misbehaving;
|
||||
bool use_ps_poll;
|
||||
int mask;
|
||||
};
|
||||
|
||||
|
@ -253,6 +249,7 @@ struct iwl_dbgfs_bf {
|
|||
enum iwl_mvm_smps_type_request {
|
||||
IWL_MVM_SMPS_REQ_BT_COEX,
|
||||
IWL_MVM_SMPS_REQ_TT,
|
||||
IWL_MVM_SMPS_REQ_PROT,
|
||||
NUM_IWL_MVM_SMPS_REQ,
|
||||
};
|
||||
|
||||
|
@ -315,6 +312,9 @@ struct iwl_mvm_vif_bf_data {
|
|||
* @id: between 0 and 3
|
||||
* @color: to solve races upon MAC addition and removal
|
||||
* @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA
|
||||
* @bssid: BSSID for this (client) interface
|
||||
* @associated: indicates that we're currently associated, used only for
|
||||
* managing the firmware state in iwl_mvm_bss_info_changed_station()
|
||||
* @uploaded: indicates the MAC context has been added to the device
|
||||
* @ap_ibss_active: indicates that AP/IBSS is configured and that the interface
|
||||
* should get quota etc.
|
||||
|
@ -323,6 +323,7 @@ struct iwl_mvm_vif_bf_data {
|
|||
* interface should get quota etc.
|
||||
* @low_latency: indicates that this interface is in low-latency mode
|
||||
* (VMACLowLatencyMode)
|
||||
* @ps_disabled: indicates that this interface requires PS to be disabled
|
||||
* @queue_params: QoS params for this MAC
|
||||
* @bcast_sta: station used for broadcast packets. Used by the following
|
||||
* vifs: P2P_DEVICE, GO and AP.
|
||||
|
@ -335,11 +336,15 @@ struct iwl_mvm_vif {
|
|||
u16 color;
|
||||
u8 ap_sta_id;
|
||||
|
||||
u8 bssid[ETH_ALEN];
|
||||
bool associated;
|
||||
|
||||
bool uploaded;
|
||||
bool ap_ibss_active;
|
||||
bool pm_enabled;
|
||||
bool monitor_active;
|
||||
bool low_latency;
|
||||
bool ps_disabled;
|
||||
struct iwl_mvm_vif_bf_data bf_data;
|
||||
|
||||
u32 ap_beacon_time;
|
||||
|
@ -512,6 +517,10 @@ enum {
|
|||
D0I3_PENDING_WAKEUP,
|
||||
};
|
||||
|
||||
#define IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 0xff
|
||||
#define IWL_MVM_DEBUG_SET_TEMPERATURE_MIN -100
|
||||
#define IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 200
|
||||
|
||||
struct iwl_mvm {
|
||||
/* for logger access */
|
||||
struct device *dev;
|
||||
|
@ -553,9 +562,8 @@ struct iwl_mvm {
|
|||
|
||||
struct mvm_statistics_rx rx_stats;
|
||||
|
||||
unsigned long transport_queue_stop;
|
||||
u8 queue_to_mac80211[IWL_MAX_HW_QUEUES];
|
||||
atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
|
||||
atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES];
|
||||
|
||||
const char *nvm_file_name;
|
||||
struct iwl_nvm_data *nvm_data;
|
||||
|
@ -694,6 +702,12 @@ struct iwl_mvm {
|
|||
/* Thermal Throttling and CTkill */
|
||||
struct iwl_mvm_tt_mgmt thermal_throttle;
|
||||
s32 temperature; /* Celsius */
|
||||
/*
|
||||
* Debug option to set the NIC temperature. This option makes the
|
||||
* driver think this is the actual NIC temperature, and ignore the
|
||||
* real temperature that is received from the fw
|
||||
*/
|
||||
bool temperature_test; /* Debug test temperature is enabled */
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
u32 noa_duration;
|
||||
|
@ -706,7 +720,7 @@ struct iwl_mvm {
|
|||
u8 last_agg_queue;
|
||||
|
||||
/* Indicate if device power save is allowed */
|
||||
bool ps_disabled;
|
||||
u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */
|
||||
|
||||
struct ieee80211_vif __rcu *csa_vif;
|
||||
struct ieee80211_vif __rcu *csa_tx_blocked_vif;
|
||||
|
@ -714,6 +728,8 @@ struct iwl_mvm {
|
|||
|
||||
/* system time of last beacon (for AP/GO interface) */
|
||||
u32 ap_last_beacon_gp2;
|
||||
|
||||
u8 low_latency_agg_frame_limit;
|
||||
};
|
||||
|
||||
/* Extract MVM priv from op_mode and _hw */
|
||||
|
@ -878,7 +894,7 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
|||
void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
int iwl_mvm_mac_ctxt_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
bool force_assoc_off);
|
||||
bool force_assoc_off, const u8 *bssid_override);
|
||||
int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
u32 iwl_mvm_mac_get_queues_mask(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif);
|
||||
|
@ -968,6 +984,7 @@ int rs_pretty_print_rate(char *buf, const u32 rate);
|
|||
/* power management */
|
||||
int iwl_mvm_power_update_device(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_power_update_mac(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_power_update_ps(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
char *buf, int bufsz);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -415,6 +417,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||
mvm->first_agg_queue = 12;
|
||||
}
|
||||
mvm->sf_state = SF_UNINIT;
|
||||
mvm->low_latency_agg_frame_limit = 1;
|
||||
|
||||
mutex_init(&mvm->mutex);
|
||||
mutex_init(&mvm->d0i3_suspend_mutex);
|
||||
|
@ -456,7 +459,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||
trans_cfg.command_names = iwl_mvm_cmd_strings;
|
||||
|
||||
trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
|
||||
trans_cfg.cmd_fifo = IWL_MVM_CMD_FIFO;
|
||||
trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD;
|
||||
|
||||
snprintf(mvm->hw->wiphy->fw_version,
|
||||
sizeof(mvm->hw->wiphy->fw_version),
|
||||
|
@ -494,7 +497,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
|||
goto out_free;
|
||||
|
||||
/*
|
||||
* Even if nvm exists in the nvm_file driver should read agin the nvm
|
||||
* Even if nvm exists in the nvm_file driver should read again the nvm
|
||||
* from the nic because there might be entries that exist in the OTP
|
||||
* and not in the file.
|
||||
* for nics with no_power_up_nic_in_init: rely completley on nvm_file
|
||||
|
@ -700,14 +703,13 @@ static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue)
|
|||
if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
|
||||
return;
|
||||
|
||||
if (atomic_inc_return(&mvm->queue_stop_count[mq]) > 1) {
|
||||
if (atomic_inc_return(&mvm->mac80211_queue_stop_count[mq]) > 1) {
|
||||
IWL_DEBUG_TX_QUEUES(mvm,
|
||||
"queue %d (mac80211 %d) already stopped\n",
|
||||
queue, mq);
|
||||
return;
|
||||
}
|
||||
|
||||
set_bit(mq, &mvm->transport_queue_stop);
|
||||
ieee80211_stop_queue(mvm->hw, mq);
|
||||
}
|
||||
|
||||
|
@ -719,15 +721,13 @@ static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
|
|||
if (WARN_ON_ONCE(mq == IWL_INVALID_MAC80211_QUEUE))
|
||||
return;
|
||||
|
||||
if (atomic_dec_return(&mvm->queue_stop_count[mq]) > 0) {
|
||||
if (atomic_dec_return(&mvm->mac80211_queue_stop_count[mq]) > 0) {
|
||||
IWL_DEBUG_TX_QUEUES(mvm,
|
||||
"queue %d (mac80211 %d) already awake\n",
|
||||
"queue %d (mac80211 %d) still stopped\n",
|
||||
queue, mq);
|
||||
return;
|
||||
}
|
||||
|
||||
clear_bit(mq, &mvm->transport_queue_stop);
|
||||
|
||||
ieee80211_wake_queue(mvm->hw, mq);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -198,8 +200,15 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
|
|||
}
|
||||
}
|
||||
|
||||
if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)))
|
||||
if (!(cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK))) {
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
/* set advanced pm flag with no uapsd ACs to enable ps-poll */
|
||||
if (mvmvif->dbgfs_pm.use_ps_poll)
|
||||
cmd->flags |=
|
||||
cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
cmd->flags |= cpu_to_le16(POWER_FLAGS_UAPSD_MISBEHAVING_ENA_MSK);
|
||||
|
||||
|
@ -497,13 +506,31 @@ struct iwl_power_vifs {
|
|||
bool p2p_tdls;
|
||||
};
|
||||
|
||||
static void iwl_mvm_power_iterator(void *_data, u8 *mac,
|
||||
static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
mvmvif->pm_enabled = false;
|
||||
}
|
||||
|
||||
static void iwl_mvm_power_ps_disabled_iterator(void *_data, u8* mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
bool *disable_ps = _data;
|
||||
|
||||
if (mvmvif->phy_ctxt)
|
||||
if (mvmvif->phy_ctxt->id < MAX_PHYS)
|
||||
*disable_ps |= mvmvif->ps_disabled;
|
||||
}
|
||||
|
||||
static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_power_vifs *power_iterator = _data;
|
||||
|
||||
mvmvif->pm_enabled = false;
|
||||
switch (ieee80211_vif_type_p2p(vif)) {
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
break;
|
||||
|
@ -559,8 +586,7 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
|
||||
static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
|
||||
struct iwl_power_vifs *vifs)
|
||||
{
|
||||
struct iwl_mvm_vif *bss_mvmvif = NULL;
|
||||
|
@ -571,10 +597,11 @@ iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
|
|||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* get vifs info + set pm_enable to false */
|
||||
/* set pm_enable to false */
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_power_iterator, vifs);
|
||||
iwl_mvm_power_disable_pm_iterator,
|
||||
NULL);
|
||||
|
||||
if (vifs->bss_vif)
|
||||
bss_mvmvif = iwl_mvm_vif_from_mac80211(vifs->bss_vif);
|
||||
|
@ -817,32 +844,92 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
|
||||
static int iwl_mvm_power_set_ps(struct iwl_mvm *mvm)
|
||||
{
|
||||
bool disable_ps;
|
||||
int ret;
|
||||
|
||||
/* disable PS if CAM */
|
||||
disable_ps = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM);
|
||||
/* ...or if any of the vifs require PS to be off */
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_power_ps_disabled_iterator,
|
||||
&disable_ps);
|
||||
|
||||
/* update device power state if it has changed */
|
||||
if (mvm->ps_disabled != disable_ps) {
|
||||
bool old_ps_disabled = mvm->ps_disabled;
|
||||
|
||||
mvm->ps_disabled = disable_ps;
|
||||
ret = iwl_mvm_power_update_device(mvm);
|
||||
if (ret) {
|
||||
mvm->ps_disabled = old_ps_disabled;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl_mvm_power_set_ba(struct iwl_mvm *mvm,
|
||||
struct iwl_power_vifs *vifs)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
bool ba_enable;
|
||||
|
||||
if (!vifs->bf_vif)
|
||||
return 0;
|
||||
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(vifs->bf_vif);
|
||||
|
||||
ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled ||
|
||||
!vifs->bf_vif->bss_conf.ps ||
|
||||
iwl_mvm_vif_low_latency(mvmvif));
|
||||
|
||||
return iwl_mvm_update_beacon_abort(mvm, vifs->bf_vif, ba_enable);
|
||||
}
|
||||
|
||||
int iwl_mvm_power_update_ps(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_power_vifs vifs = {
|
||||
.mvm = mvm,
|
||||
};
|
||||
bool ba_enable;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
iwl_mvm_power_set_pm(mvm, &vifs);
|
||||
/* get vifs info */
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_power_get_vifs_iterator, &vifs);
|
||||
|
||||
/* disable PS if CAM */
|
||||
if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) {
|
||||
mvm->ps_disabled = true;
|
||||
} else {
|
||||
/* don't update device power state unless we add / remove monitor */
|
||||
if (vifs.monitor_vif) {
|
||||
if (vifs.monitor_active)
|
||||
mvm->ps_disabled = true;
|
||||
ret = iwl_mvm_power_update_device(mvm);
|
||||
ret = iwl_mvm_power_set_ps(mvm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return iwl_mvm_power_set_ba(mvm, &vifs);
|
||||
}
|
||||
}
|
||||
|
||||
int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
|
||||
{
|
||||
struct iwl_power_vifs vifs = {
|
||||
.mvm = mvm,
|
||||
};
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
/* get vifs info */
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_power_get_vifs_iterator, &vifs);
|
||||
|
||||
iwl_mvm_power_set_pm(mvm, &vifs);
|
||||
|
||||
ret = iwl_mvm_power_set_ps(mvm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (vifs.bss_vif) {
|
||||
ret = iwl_mvm_power_send_cmd(mvm, vifs.bss_vif);
|
||||
|
@ -856,16 +943,7 @@ int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!vifs.bf_vif)
|
||||
return 0;
|
||||
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(vifs.bf_vif);
|
||||
|
||||
ba_enable = !(!mvmvif->pm_enabled || mvm->ps_disabled ||
|
||||
!vifs.bf_vif->bss_conf.ps ||
|
||||
iwl_mvm_vif_low_latency(mvmvif));
|
||||
|
||||
return iwl_mvm_update_beacon_abort(mvm, vifs.bf_vif, ba_enable);
|
||||
return iwl_mvm_power_set_ba(mvm, &vifs);
|
||||
}
|
||||
|
||||
int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -161,6 +163,9 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
|
|||
quota *= (beacon_int - mvm->noa_duration);
|
||||
quota /= beacon_int;
|
||||
|
||||
IWL_DEBUG_QUOTA(mvm, "quota: adjust for NoA from %d to %d\n",
|
||||
le32_to_cpu(cmd->quotas[i].quota), quota);
|
||||
|
||||
cmd->quotas[i].quota = cpu_to_le32(quota);
|
||||
}
|
||||
#endif
|
||||
|
@ -222,6 +227,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
|||
quota = (QUOTA_100 - QUOTA_LOWLAT_MIN) / n_non_lowlat;
|
||||
quota_rem = QUOTA_100 - n_non_lowlat * quota -
|
||||
QUOTA_LOWLAT_MIN;
|
||||
IWL_DEBUG_QUOTA(mvm,
|
||||
"quota: low-latency binding active, remaining quota per other binding: %d\n",
|
||||
quota);
|
||||
} else if (num_active_macs) {
|
||||
/*
|
||||
* There are 0 or more than 1 low latency bindings, or all the
|
||||
|
@ -230,6 +238,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
|||
*/
|
||||
quota = QUOTA_100 / num_active_macs;
|
||||
quota_rem = QUOTA_100 % num_active_macs;
|
||||
IWL_DEBUG_QUOTA(mvm,
|
||||
"quota: splitting evenly per binding: %d\n",
|
||||
quota);
|
||||
} else {
|
||||
/* values don't really matter - won't be used */
|
||||
quota = 0;
|
||||
|
@ -271,6 +282,9 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
|||
for (i = 0; i < MAX_BINDINGS; i++) {
|
||||
if (le32_to_cpu(cmd.quotas[i].quota) != 0) {
|
||||
le32_add_cpu(&cmd.quotas[i].quota, quota_rem);
|
||||
IWL_DEBUG_QUOTA(mvm,
|
||||
"quota: giving remainder of %d to binding %d\n",
|
||||
quota_rem, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -2678,6 +2679,7 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
|
|||
int i;
|
||||
int num_rates = ARRAY_SIZE(lq_cmd->rs_table);
|
||||
__le32 ucode_rate_le32 = cpu_to_le32(ucode_rate);
|
||||
u8 ant = (ucode_rate & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS;
|
||||
|
||||
for (i = 0; i < num_rates; i++)
|
||||
lq_cmd->rs_table[i] = ucode_rate_le32;
|
||||
|
@ -2688,6 +2690,13 @@ static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
|
|||
lq_cmd->mimo_delim = num_rates - 1;
|
||||
else
|
||||
lq_cmd->mimo_delim = 0;
|
||||
|
||||
lq_cmd->reduced_tpc = 0;
|
||||
|
||||
if (num_of_ant(ant) == 1)
|
||||
lq_cmd->single_stream_ant_msk = ant;
|
||||
|
||||
lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
|
||||
}
|
||||
#endif /* CONFIG_MAC80211_DEBUGFS */
|
||||
|
||||
|
@ -2811,30 +2820,54 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
|
|||
const struct rs_rate *initial_rate)
|
||||
{
|
||||
struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
|
||||
u8 ant = initial_rate->ant;
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
struct iwl_mvm_vif *mvmvif;
|
||||
|
||||
lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
|
||||
lq_cmd->agg_time_limit =
|
||||
cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
if (lq_sta->pers.dbg_fixed_rate) {
|
||||
rs_build_rates_table_from_fixed(mvm, lq_cmd,
|
||||
lq_sta->band,
|
||||
lq_sta->pers.dbg_fixed_rate);
|
||||
lq_cmd->reduced_tpc = 0;
|
||||
ant = (lq_sta->pers.dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >>
|
||||
RATE_MCS_ANT_POS;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (WARN_ON_ONCE(!sta || !initial_rate))
|
||||
return;
|
||||
|
||||
rs_build_rates_table(mvm, lq_sta, initial_rate);
|
||||
|
||||
if (num_of_ant(ant) == 1)
|
||||
lq_cmd->single_stream_ant_msk = ant;
|
||||
if (num_of_ant(initial_rate->ant) == 1)
|
||||
lq_cmd->single_stream_ant_msk = initial_rate->ant;
|
||||
|
||||
lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
|
||||
lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
|
||||
|
||||
lq_cmd->agg_time_limit =
|
||||
cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
|
||||
if (num_of_ant(initial_rate->ant) == 1)
|
||||
lq_cmd->single_stream_ant_msk = initial_rate->ant;
|
||||
|
||||
lq_cmd->agg_frame_cnt_limit = mvmsta->max_agg_bufsize;
|
||||
|
||||
/*
|
||||
* In case of low latency, tell the firwmare to leave a frame in the
|
||||
* Tx Fifo so that it can start a transaction in the same TxOP. This
|
||||
* basically allows the firmware to send bursts.
|
||||
*/
|
||||
if (iwl_mvm_vif_low_latency(mvmvif)) {
|
||||
lq_cmd->agg_frame_cnt_limit--;
|
||||
|
||||
if (mvm->low_latency_agg_frame_limit)
|
||||
lq_cmd->agg_frame_cnt_limit =
|
||||
min(lq_cmd->agg_frame_cnt_limit,
|
||||
mvm->low_latency_agg_frame_limit);
|
||||
}
|
||||
|
||||
if (mvmsta->vif->p2p)
|
||||
lq_cmd->flags |= LQ_FLAG_USE_RTS_MSK;
|
||||
|
||||
if (sta)
|
||||
lq_cmd->agg_time_limit =
|
||||
cpu_to_le16(iwl_mvm_coex_agg_time_limit(mvm, sta));
|
||||
}
|
||||
|
@ -2932,10 +2965,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
|
|||
lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate);
|
||||
|
||||
if (lq_sta->pers.dbg_fixed_rate) {
|
||||
struct rs_rate rate;
|
||||
rs_rate_from_ucode_rate(lq_sta->pers.dbg_fixed_rate,
|
||||
lq_sta->band, &rate);
|
||||
rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate);
|
||||
rs_fill_lq_cmd(mvm, NULL, lq_sta, NULL);
|
||||
iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -491,10 +493,29 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
|
|||
.mvm = mvm,
|
||||
};
|
||||
|
||||
/*
|
||||
* set temperature debug enabled - ignore FW temperature updates
|
||||
* and use the user set temperature.
|
||||
*/
|
||||
if (mvm->temperature_test) {
|
||||
if (mvm->temperature < le32_to_cpu(common->temperature))
|
||||
IWL_DEBUG_TEMP(mvm,
|
||||
"Ignoring FW temperature update that is greater than the debug set temperature (debug temp = %d, fw temp = %d)\n",
|
||||
mvm->temperature,
|
||||
le32_to_cpu(common->temperature));
|
||||
/*
|
||||
* skip iwl_mvm_tt_handler since we are in
|
||||
* temperature debug mode and we are ignoring
|
||||
* the new temperature value
|
||||
*/
|
||||
goto update;
|
||||
}
|
||||
|
||||
if (mvm->temperature != le32_to_cpu(common->temperature)) {
|
||||
mvm->temperature = le32_to_cpu(common->temperature);
|
||||
iwl_mvm_tt_handler(mvm);
|
||||
}
|
||||
update:
|
||||
iwl_mvm_update_rx_statistics(mvm, stats);
|
||||
|
||||
ieee80211_iterate_active_interfaces(mvm->hw,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -279,6 +281,7 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
|
|||
{
|
||||
bool global_bound = false;
|
||||
enum ieee80211_band band;
|
||||
u8 frag_passive_dwell = 0;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(mvm->hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
|
@ -288,12 +291,36 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
|
|||
if (!global_bound)
|
||||
goto not_bound;
|
||||
|
||||
params->suspend_time = 100;
|
||||
params->max_out_time = 600;
|
||||
params->suspend_time = 30;
|
||||
params->max_out_time = 170;
|
||||
|
||||
if (iwl_mvm_low_latency(mvm)) {
|
||||
params->suspend_time = 250;
|
||||
params->max_out_time = 250;
|
||||
if (mvm->fw->ucode_capa.api[0] &
|
||||
IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
|
||||
params->suspend_time = 105;
|
||||
params->max_out_time = 70;
|
||||
frag_passive_dwell = 20;
|
||||
} else {
|
||||
params->suspend_time = 120;
|
||||
params->max_out_time = 120;
|
||||
}
|
||||
}
|
||||
|
||||
if (frag_passive_dwell && (mvm->fw->ucode_capa.api[0] &
|
||||
IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) {
|
||||
/*
|
||||
* P2P device scan should not be fragmented to avoid negative
|
||||
* impact on P2P device discovery. Configure max_out_time to be
|
||||
* equal to dwell time on passive channel. Take a longest
|
||||
* possible value, one that corresponds to 2GHz band
|
||||
*/
|
||||
if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
|
||||
u32 passive_dwell =
|
||||
iwl_mvm_get_passive_dwell(IEEE80211_BAND_2GHZ);
|
||||
params->max_out_time = passive_dwell;
|
||||
} else {
|
||||
params->passive_fragmented = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
|
||||
|
@ -302,7 +329,11 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
|
|||
not_bound:
|
||||
|
||||
for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
|
||||
params->dwell[band].passive = iwl_mvm_get_passive_dwell(band);
|
||||
if (params->passive_fragmented)
|
||||
params->dwell[band].passive = frag_passive_dwell;
|
||||
else
|
||||
params->dwell[band].passive =
|
||||
iwl_mvm_get_passive_dwell(band);
|
||||
params->dwell[band].active = iwl_mvm_get_active_dwell(band,
|
||||
n_ssids);
|
||||
}
|
||||
|
@ -1100,10 +1131,11 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
|
|||
struct iwl_mvm_scan_params *params)
|
||||
{
|
||||
memset(cmd, 0, ksize(cmd));
|
||||
cmd->active_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].active;
|
||||
cmd->passive_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].passive;
|
||||
/* TODO: Use params; now fragmented isn't used. */
|
||||
cmd->fragmented_dwell = 0;
|
||||
cmd->active_dwell = params->dwell[IEEE80211_BAND_2GHZ].active;
|
||||
cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive;
|
||||
if (params->passive_fragmented)
|
||||
cmd->fragmented_dwell =
|
||||
params->dwell[IEEE80211_BAND_2GHZ].passive;
|
||||
cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
|
||||
cmd->max_out_time = cpu_to_le32(params->max_out_time);
|
||||
cmd->suspend_time = cpu_to_le32(params->suspend_time);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -250,10 +252,14 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* The first station added is the AP, the others are TDLS STAs */
|
||||
if (vif->type == NL80211_IFTYPE_STATION &&
|
||||
mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
|
||||
if (vif->type == NL80211_IFTYPE_STATION) {
|
||||
if (!sta->tdls) {
|
||||
WARN_ON(mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT);
|
||||
mvmvif->ap_sta_id = sta_id;
|
||||
} else {
|
||||
WARN_ON(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
|
||||
|
||||
|
@ -458,7 +464,8 @@ int iwl_mvm_rm_sta_id(struct iwl_mvm *mvm,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
|
||||
static int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_int_sta *sta,
|
||||
u32 qmask, enum nl80211_iftype iftype)
|
||||
{
|
||||
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
|
||||
|
@ -474,7 +481,8 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta)
|
||||
static void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_int_sta *sta)
|
||||
{
|
||||
RCU_INIT_POINTER(mvm->fw_id_to_mac_id[sta->sta_id], NULL);
|
||||
memset(sta, 0, sizeof(struct iwl_mvm_int_sta));
|
||||
|
@ -544,6 +552,13 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm)
|
||||
{
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
iwl_mvm_dealloc_int_sta(mvm, &mvm->aux_sta);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the add station command for the vif's broadcast station.
|
||||
* Assumes that the station was already allocated.
|
||||
|
@ -552,10 +567,10 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
|
|||
* @vif: the interface to which the broadcast station is added
|
||||
* @bsta: the broadcast station to add.
|
||||
*/
|
||||
int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_int_sta *bsta)
|
||||
int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
|
||||
static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
const u8 *baddr = _baddr;
|
||||
|
||||
|
@ -573,19 +588,40 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
|
||||
/* Send the FW a request to remove the station from it's internal data
|
||||
* structures, but DO NOT remove the entry from the local data structures. */
|
||||
int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_int_sta *bsta)
|
||||
int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
|
||||
ret = iwl_mvm_rm_sta_common(mvm, mvmvif->bcast_sta.sta_id);
|
||||
if (ret)
|
||||
IWL_WARN(mvm, "Failed sending remove station\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
u32 qmask;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
|
||||
|
||||
/*
|
||||
* The firmware defines the TFD queue mask to only be relevant
|
||||
* for *unicast* queues, so the multicast (CAB) queue shouldn't
|
||||
* be included.
|
||||
*/
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
qmask &= ~BIT(vif->cab_queue);
|
||||
|
||||
return iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, qmask,
|
||||
ieee80211_vif_type_p2p(vif));
|
||||
}
|
||||
|
||||
/* Allocate a new station entry for the broadcast station to the given vif,
|
||||
* and send it to the FW.
|
||||
* Note that each P2P mac should have its own broadcast station.
|
||||
|
@ -593,45 +629,47 @@ int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
|
|||
* @mvm: the mvm component
|
||||
* @vif: the interface to which the broadcast station is added
|
||||
* @bsta: the broadcast station to add. */
|
||||
int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_int_sta *bsta)
|
||||
int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
u32 qmask;
|
||||
struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
|
||||
ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask,
|
||||
ieee80211_vif_type_p2p(vif));
|
||||
ret = iwl_mvm_alloc_bcast_sta(mvm, vif);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr,
|
||||
mvmvif->id, mvmvif->color);
|
||||
ret = iwl_mvm_send_add_bcast_sta(mvm, vif);
|
||||
|
||||
if (ret)
|
||||
iwl_mvm_dealloc_int_sta(mvm, bsta);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
|
||||
iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the FW a request to remove the station from it's internal data
|
||||
* structures, and in addition remove it from the local data structure.
|
||||
*/
|
||||
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta)
|
||||
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
{
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
||||
ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = iwl_mvm_send_rm_bcast_sta(mvm, vif);
|
||||
|
||||
iwl_mvm_dealloc_bcast_sta(mvm, vif);
|
||||
|
||||
iwl_mvm_dealloc_int_sta(mvm, bsta);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -910,7 +948,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
}
|
||||
|
||||
tid_data->ssn = 0xffff;
|
||||
iwl_trans_txq_disable(mvm->trans, txq_id);
|
||||
iwl_trans_txq_disable(mvm->trans, txq_id, true);
|
||||
/* fall through */
|
||||
case IWL_AGG_STARTING:
|
||||
case IWL_EMPTYING_HW_QUEUE_ADDBA:
|
||||
|
@ -965,7 +1003,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
|
||||
IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
|
||||
|
||||
iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
|
||||
iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true);
|
||||
}
|
||||
|
||||
mvm->queue_to_mac80211[tid_data->txq_id] =
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -387,17 +389,15 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||
struct ieee80211_sta *sta, u16 tid);
|
||||
|
||||
int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
|
||||
int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta,
|
||||
u32 qmask, enum nl80211_iftype iftype);
|
||||
void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_int_sta *sta);
|
||||
int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_int_sta *bsta);
|
||||
int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm,
|
||||
struct iwl_mvm_int_sta *bsta);
|
||||
int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
struct iwl_mvm_int_sta *bsta);
|
||||
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta);
|
||||
void iwl_mvm_del_aux_sta(struct iwl_mvm *mvm);
|
||||
|
||||
int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
|
||||
void iwl_mvm_sta_drained_wk(struct work_struct *wk);
|
||||
void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm,
|
||||
struct ieee80211_sta *sta);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -348,6 +350,38 @@ unlock:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool iwl_mvm_te_notif(struct iwl_notif_wait_data *notif_wait,
|
||||
struct iwl_rx_packet *pkt, void *data)
|
||||
{
|
||||
struct iwl_mvm *mvm =
|
||||
container_of(notif_wait, struct iwl_mvm, notif_wait);
|
||||
struct iwl_mvm_time_event_data *te_data = data;
|
||||
struct iwl_time_event_notif *resp;
|
||||
int resp_len = iwl_rx_packet_payload_len(pkt);
|
||||
|
||||
if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_NOTIFICATION))
|
||||
return true;
|
||||
|
||||
if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
|
||||
IWL_ERR(mvm, "Invalid TIME_EVENT_NOTIFICATION response\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
resp = (void *)pkt->data;
|
||||
|
||||
/* te_data->uid is already set in the TIME_EVENT_CMD response */
|
||||
if (le32_to_cpu(resp->unique_id) != te_data->uid)
|
||||
return false;
|
||||
|
||||
IWL_DEBUG_TE(mvm, "TIME_EVENT_NOTIFICATION response - UID = 0x%x\n",
|
||||
te_data->uid);
|
||||
if (!resp->status)
|
||||
IWL_ERR(mvm,
|
||||
"TIME_EVENT_NOTIFICATION received but not executed\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
|
||||
struct iwl_rx_packet *pkt, void *data)
|
||||
{
|
||||
|
@ -441,10 +475,12 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm,
|
|||
void iwl_mvm_protect_session(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 duration, u32 min_duration,
|
||||
u32 max_delay)
|
||||
u32 max_delay, bool wait_for_notif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
|
||||
const u8 te_notif_response[] = { TIME_EVENT_NOTIFICATION };
|
||||
struct iwl_notification_wait wait_te_notif;
|
||||
struct iwl_time_event_cmd time_cmd = {};
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
|
@ -489,7 +525,28 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
|
|||
TE_V2_NOTIF_HOST_EVENT_END |
|
||||
T2_V2_START_IMMEDIATELY);
|
||||
|
||||
if (!wait_for_notif) {
|
||||
iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create notification_wait for the TIME_EVENT_NOTIFICATION to use
|
||||
* right after we send the time event
|
||||
*/
|
||||
iwl_init_notification_wait(&mvm->notif_wait, &wait_te_notif,
|
||||
te_notif_response,
|
||||
ARRAY_SIZE(te_notif_response),
|
||||
iwl_mvm_te_notif, te_data);
|
||||
|
||||
/* If TE was sent OK - wait for the notification that started */
|
||||
if (iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd)) {
|
||||
IWL_ERR(mvm, "Failed to add TE to protect session\n");
|
||||
iwl_remove_notification(&mvm->notif_wait, &wait_te_notif);
|
||||
} else if (iwl_wait_notification(&mvm->notif_wait, &wait_te_notif,
|
||||
TU_TO_JIFFIES(max_delay))) {
|
||||
IWL_ERR(mvm, "Failed to protect session until TE\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -124,10 +126,12 @@
|
|||
* @min_duration: will start a new session if the current session will end
|
||||
* in less than min_duration.
|
||||
* @max_delay: maximum delay before starting the time event (in TU)
|
||||
* @wait_for_notif: true if it is required that a time event notification be
|
||||
* waited for (that the time event has been scheduled before returning)
|
||||
*
|
||||
* This function can be used to start a session protection which means that the
|
||||
* fw will stay on the channel for %duration_ms milliseconds. This function
|
||||
* will block (sleep) until the session starts. This function can also be used
|
||||
* can block (sleep) until the session starts. This function can also be used
|
||||
* to extend a currently running session.
|
||||
* This function is meant to be used for BSS association for example, where we
|
||||
* want to make sure that the fw stays on the channel during the association.
|
||||
|
@ -135,7 +139,7 @@
|
|||
void iwl_mvm_protect_session(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
u32 duration, u32 min_duration,
|
||||
u32 max_delay);
|
||||
u32 max_delay, bool wait_for_notif);
|
||||
|
||||
/**
|
||||
* iwl_mvm_stop_session_protection - cancel the session protection.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -314,14 +316,26 @@ static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
|
|||
{
|
||||
u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
|
||||
|
||||
if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
|
||||
return;
|
||||
|
||||
IWL_ERR(mvm, "Enter CT Kill\n");
|
||||
iwl_mvm_set_hw_ctkill_state(mvm, true);
|
||||
|
||||
/* Don't schedule an exit work if we're in test mode, since
|
||||
* the temperature will not change unless we manually set it
|
||||
* again (or disable testing).
|
||||
*/
|
||||
if (!mvm->temperature_test)
|
||||
schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
|
||||
round_jiffies_relative(duration * HZ));
|
||||
}
|
||||
|
||||
static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm)
|
||||
{
|
||||
if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
|
||||
return;
|
||||
|
||||
IWL_ERR(mvm, "Exit CT Kill\n");
|
||||
iwl_mvm_set_hw_ctkill_state(mvm, false);
|
||||
}
|
||||
|
@ -444,6 +458,12 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
|
|||
return;
|
||||
}
|
||||
|
||||
if (params->support_ct_kill &&
|
||||
temperature <= tt->params->ct_kill_exit) {
|
||||
iwl_mvm_exit_ctkill(mvm);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params->support_dynamic_smps) {
|
||||
if (!tt->dynamic_smps &&
|
||||
temperature >= params->dynamic_smps_entry) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -482,7 +484,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
|
|||
IWL_DEBUG_TX_QUEUES(mvm,
|
||||
"Can continue DELBA flow ssn = next_recl = %d\n",
|
||||
tid_data->next_reclaimed);
|
||||
iwl_trans_txq_disable(mvm->trans, tid_data->txq_id);
|
||||
iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true);
|
||||
tid_data->state = IWL_AGG_OFF;
|
||||
/*
|
||||
* we can't hold the mutex - but since we are after a sequence
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -387,15 +389,19 @@ struct iwl_error_event_table {
|
|||
struct iwl_umac_error_event_table {
|
||||
u32 valid; /* (nonzero) valid, (0) log is empty */
|
||||
u32 error_id; /* type of error */
|
||||
u32 pc; /* program counter */
|
||||
u32 blink1; /* branch link */
|
||||
u32 blink2; /* branch link */
|
||||
u32 ilink1; /* interrupt link */
|
||||
u32 ilink2; /* interrupt link */
|
||||
u32 data1; /* error-specific data */
|
||||
u32 data2; /* error-specific data */
|
||||
u32 line; /* source code line of error */
|
||||
u32 umac_ver; /* umac version */
|
||||
u32 data3; /* error-specific data */
|
||||
u32 umac_fw_ver; /* UMAC version */
|
||||
u32 umac_fw_api_ver; /* UMAC FW API ver */
|
||||
u32 frame_pointer; /* core register 27*/
|
||||
u32 stack_pointer; /* core register 28 */
|
||||
u32 cmd_header; /* latest host cmd sent to UMAC */
|
||||
u32 nic_isr_pref; /* ISR status register */
|
||||
} __packed;
|
||||
|
||||
#define ERROR_START_OFFSET (1 * sizeof(u32))
|
||||
|
@ -409,7 +415,7 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
|
|||
|
||||
base = mvm->umac_error_event_table;
|
||||
|
||||
if (base < 0x800000 || base >= 0x80C000) {
|
||||
if (base < 0x800000) {
|
||||
IWL_ERR(mvm,
|
||||
"Not valid error log pointer 0x%08X for %s uCode\n",
|
||||
base,
|
||||
|
@ -428,14 +434,19 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
|
|||
|
||||
IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
|
||||
desc_lookup(table.error_id));
|
||||
IWL_ERR(mvm, "0x%08X | umac uPc\n", table.pc);
|
||||
IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1);
|
||||
IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2);
|
||||
IWL_ERR(mvm, "0x%08X | umac interruptlink1\n", table.ilink1);
|
||||
IWL_ERR(mvm, "0x%08X | umac interruptlink2\n", table.ilink2);
|
||||
IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1);
|
||||
IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2);
|
||||
IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_ver);
|
||||
IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3);
|
||||
IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_fw_ver);
|
||||
IWL_ERR(mvm, "0x%08X | umac api version\n", table.umac_fw_api_ver);
|
||||
IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer);
|
||||
IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer);
|
||||
IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header);
|
||||
IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref);
|
||||
}
|
||||
|
||||
void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
@ -364,9 +365,10 @@ int iwl_pcie_tx_init(struct iwl_trans *trans);
|
|||
void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr);
|
||||
int iwl_pcie_tx_stop(struct iwl_trans *trans);
|
||||
void iwl_pcie_tx_free(struct iwl_trans *trans);
|
||||
void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
|
||||
int sta_id, int tid, int frame_limit, u16 ssn);
|
||||
void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue);
|
||||
void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn,
|
||||
const struct iwl_trans_txq_scd_cfg *cfg);
|
||||
void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue,
|
||||
bool configure_scd);
|
||||
int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
|
||||
struct iwl_device_cmd *dev_cmd, int txq_id);
|
||||
void iwl_pcie_txq_check_wrptrs(struct iwl_trans *trans);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications 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
|
||||
|
@ -31,6 +32,7 @@
|
|||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
*
|
||||
* Portions of this file are derived from the ipw3945 project, as well
|
||||
* as portions of the ieee80211 subsystem header files.
|
||||
|
@ -34,6 +35,7 @@
|
|||
#include "iwl-csr.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-scd.h"
|
||||
#include "iwl-op-mode.h"
|
||||
#include "internal.h"
|
||||
/* FIXME: need to abstract out TX command (once we know what it looks like) */
|
||||
|
@ -644,17 +646,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
|
|||
memset(txq, 0, sizeof(*txq));
|
||||
}
|
||||
|
||||
/*
|
||||
* Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
|
||||
*/
|
||||
static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask)
|
||||
{
|
||||
struct iwl_trans_pcie __maybe_unused *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
iwl_write_prph(trans, SCD_TXFACT, mask);
|
||||
}
|
||||
|
||||
void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
@ -692,7 +683,7 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
|
|||
trans_pcie->cmd_fifo);
|
||||
|
||||
/* Activate all Tx DMA/FIFO channels */
|
||||
iwl_pcie_txq_set_sched(trans, IWL_MASK(0, 7));
|
||||
iwl_scd_activate_fifos(trans);
|
||||
|
||||
/* Enable DMA channel */
|
||||
for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++)
|
||||
|
@ -745,7 +736,7 @@ int iwl_pcie_tx_stop(struct iwl_trans *trans)
|
|||
/* Turn off all Tx DMA fifos */
|
||||
spin_lock(&trans_pcie->irq_lock);
|
||||
|
||||
iwl_pcie_txq_set_sched(trans, 0);
|
||||
iwl_scd_deactivate_fifos(trans);
|
||||
|
||||
/* Stop each Tx DMA channel, and wait for it to be idle */
|
||||
for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
|
||||
|
@ -886,7 +877,7 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
|
|||
spin_lock(&trans_pcie->irq_lock);
|
||||
|
||||
/* Turn off all Tx DMA fifos */
|
||||
iwl_write_prph(trans, SCD_TXFACT, 0);
|
||||
iwl_scd_deactivate_fifos(trans);
|
||||
|
||||
/* Tell NIC where to find the "keep warm" buffer */
|
||||
iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
|
||||
|
@ -1072,62 +1063,62 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans,
|
||||
u16 txq_id)
|
||||
{
|
||||
/* Simply stop the queue, but don't change any configuration;
|
||||
* the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
|
||||
iwl_write_prph(trans,
|
||||
SCD_QUEUE_STATUS_BITS(txq_id),
|
||||
(0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
|
||||
(1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
|
||||
}
|
||||
|
||||
/* Receiver address (actually, Rx station's index into station table),
|
||||
* combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
|
||||
#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
|
||||
|
||||
void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
|
||||
int sta_id, int tid, int frame_limit, u16 ssn)
|
||||
void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
|
||||
const struct iwl_trans_txq_scd_cfg *cfg)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int fifo = -1;
|
||||
|
||||
if (test_and_set_bit(txq_id, trans_pcie->queue_used))
|
||||
WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
|
||||
|
||||
if (cfg) {
|
||||
fifo = cfg->fifo;
|
||||
|
||||
/* Disable the scheduler prior configuring the cmd queue */
|
||||
if (txq_id == trans_pcie->cmd_queue)
|
||||
iwl_scd_enable_set_active(trans, 0);
|
||||
|
||||
/* Stop this Tx queue before configuring it */
|
||||
iwl_pcie_txq_set_inactive(trans, txq_id);
|
||||
iwl_scd_txq_set_inactive(trans, txq_id);
|
||||
|
||||
/* Set this queue as a chain-building queue unless it is CMD queue */
|
||||
/* Set this queue as a chain-building queue unless it is CMD */
|
||||
if (txq_id != trans_pcie->cmd_queue)
|
||||
iwl_set_bits_prph(trans, SCD_QUEUECHAIN_SEL, BIT(txq_id));
|
||||
iwl_scd_txq_set_chain(trans, txq_id);
|
||||
|
||||
/* If this queue is mapped to a certain station: it is an AGG queue */
|
||||
if (sta_id >= 0) {
|
||||
u16 ra_tid = BUILD_RAxTID(sta_id, tid);
|
||||
if (cfg->aggregate) {
|
||||
u16 ra_tid = BUILD_RAxTID(cfg->sta_id, cfg->tid);
|
||||
|
||||
/* Map receiver-address / traffic-ID to this queue */
|
||||
iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id);
|
||||
|
||||
/* enable aggregations for the queue */
|
||||
iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
|
||||
iwl_scd_txq_enable_agg(trans, txq_id);
|
||||
trans_pcie->txq[txq_id].ampdu = true;
|
||||
} else {
|
||||
/*
|
||||
* disable aggregations for the queue, this will also make the
|
||||
* ra_tid mapping configuration irrelevant since it is now a
|
||||
* non-AGG queue.
|
||||
* disable aggregations for the queue, this will also
|
||||
* make the ra_tid mapping configuration irrelevant
|
||||
* since it is now a non-AGG queue.
|
||||
*/
|
||||
iwl_clear_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id));
|
||||
iwl_scd_txq_disable_agg(trans, txq_id);
|
||||
|
||||
ssn = trans_pcie->txq[txq_id].q.read_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Place first TFD at index corresponding to start sequence number.
|
||||
* Assumes that ssn_idx is valid (!= 0xFFF) */
|
||||
trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff);
|
||||
trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff);
|
||||
|
||||
if (cfg) {
|
||||
u8 frame_limit = cfg->frame_limit;
|
||||
|
||||
iwl_write_direct32(trans, HBUS_TARG_WRPTR,
|
||||
(ssn & 0xff) | (txq_id << 8));
|
||||
iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);
|
||||
|
@ -1135,25 +1126,33 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
|
|||
/* Set up Tx window size and frame limit for this queue */
|
||||
iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr +
|
||||
SCD_CONTEXT_QUEUE_OFFSET(txq_id), 0);
|
||||
iwl_trans_write_mem32(trans, trans_pcie->scd_base_addr +
|
||||
iwl_trans_write_mem32(trans,
|
||||
trans_pcie->scd_base_addr +
|
||||
SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
|
||||
((frame_limit << SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
|
||||
SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
|
||||
((frame_limit << SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
|
||||
SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
|
||||
|
||||
/* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
|
||||
/* Set up status area in SRAM, map to Tx DMA/FIFO, activate */
|
||||
iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
|
||||
(1 << SCD_QUEUE_STTS_REG_POS_ACTIVE) |
|
||||
(fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
|
||||
(cfg->fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
|
||||
(1 << SCD_QUEUE_STTS_REG_POS_WSL) |
|
||||
SCD_QUEUE_STTS_REG_MSK);
|
||||
|
||||
/* enable the scheduler for this queue (only) */
|
||||
if (txq_id == trans_pcie->cmd_queue)
|
||||
iwl_scd_enable_set_active(trans, BIT(txq_id));
|
||||
}
|
||||
|
||||
trans_pcie->txq[txq_id].active = true;
|
||||
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
|
||||
txq_id, fifo, ssn & 0xff);
|
||||
}
|
||||
|
||||
void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
|
||||
void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
|
||||
bool configure_scd)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
u32 stts_addr = trans_pcie->scd_base_addr +
|
||||
|
@ -1172,10 +1171,12 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)
|
|||
return;
|
||||
}
|
||||
|
||||
iwl_pcie_txq_set_inactive(trans, txq_id);
|
||||
if (configure_scd) {
|
||||
iwl_scd_txq_set_inactive(trans, txq_id);
|
||||
|
||||
iwl_trans_write_mem(trans, stts_addr, (void *)zero_val,
|
||||
ARRAY_SIZE(zero_val));
|
||||
}
|
||||
|
||||
iwl_pcie_txq_unmap(trans, txq_id);
|
||||
trans_pcie->txq[txq_id].ampdu = false;
|
||||
|
|
Loading…
Reference in New Issue