Skip to content

Commit

Permalink
Merge tag 'iwlwifi-next-for-kalle-2015-02-03' of https://git.kernel.o…
Browse files Browse the repository at this point in the history
…rg/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next

* Add support for beamforming
* Enable stuck queue detection for iwlmvm
* A few fixes for EBS scan
* Fixes for various failure paths
* Improvements for TDLS Offchannel
  • Loading branch information
Kalle Valo committed Feb 6, 2015
2 parents 297540f + b9a641d commit 8cd4cbf
Show file tree
Hide file tree
Showing 26 changed files with 503 additions and 176 deletions.
7 changes: 2 additions & 5 deletions drivers/net/wireless/iwlwifi/dvm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,11 +1228,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
if (!iwlwifi_mod_params.wd_disable)
trans_cfg.queue_watchdog_timeout =
priv->cfg->base_params->wd_timeout;
else
trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
trans_cfg.cmd_q_wdg_timeout = IWL_WATCHDOG_DISABLED;

trans_cfg.command_names = iwl_dvm_cmd_strings;
trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM;

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/dvm/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
fifo = ctx->ac_to_fifo[tid_to_ac[tid]];

iwl_trans_txq_enable(priv->trans, q, fifo, sta_priv->sta_id, tid,
buf_size, ssn);
buf_size, ssn, 0);

/*
* If the limit is 0, then it wasn't initialised yet,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/dvm/ucode.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
for (i = 0; i < n_queues; i++)
if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED)
iwl_trans_ac_txq_enable(priv->trans, i,
queue_to_txf[i]);
queue_to_txf[i], 0);

priv->passive_no_rx = false;
priv->transport_queue_stop = 0;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-config.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ enum iwl_led_mode {

/* TX queue watchdog timeouts in mSecs */
#define IWL_WATCHDOG_DISABLED 0
#define IWL_DEF_WD_TIMEOUT 2000
#define IWL_DEF_WD_TIMEOUT 2500
#define IWL_LONG_WD_TIMEOUT 10000
#define IWL_MAX_WD_TIMEOUT 120000

Expand Down
5 changes: 0 additions & 5 deletions drivers/net/wireless/iwlwifi/iwl-drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1367,7 +1367,6 @@ struct iwl_mod_params iwlwifi_mod_params = {
.restart_fw = true,
.bt_coex_active = true,
.power_level = IWL_POWER_INDEX_1,
.wd_disable = true,
.d0i3_disable = true,
#ifndef CONFIG_IWLWIFI_UAPSD
.uapsd_disable = true,
Expand Down Expand Up @@ -1478,10 +1477,6 @@ module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
MODULE_PARM_DESC(antenna_coupling,
"specify antenna coupling in dB (default: 0 dB)");

module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
MODULE_PARM_DESC(wd_disable,
"Disable stuck queue watchdog timer 0=system default, 1=disable (default: 1)");

module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
MODULE_PARM_DESC(nvm_file, "NVM file name");

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-fw-file.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ enum iwl_ucode_tlv_api {
* @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
* @IWL_UCODE_TLV_CAPA_LAR_SUPPORT: supports Location Aware Regulatory
* @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan.
* @IWL_UCODE_TLV_CAPA_BEAMFORMER: supports Beamformer
* @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality
* @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
* tx power value into TPC Report action frame and Link Measurement Report
Expand All @@ -288,6 +289,7 @@ enum iwl_ucode_tlv_capa {
IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
IWL_UCODE_TLV_CAPA_LAR_SUPPORT = BIT(1),
IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2),
IWL_UCODE_TLV_CAPA_BEAMFORMER = BIT(3),
IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6),
IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl-modparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ enum iwl_disable_11n {
* use IWL_[DIS,EN]ABLE_HT_* constants
* @amsdu_size_8K: enable 8K amsdu size, default = 0
* @restart_fw: restart firmware, default = 1
* @wd_disable: disable stuck queue check, default = 1
* @bt_coex_active: enable bt coex, default = true
* @led_mode: system default, default = 0
* @power_save: enable power save, default = false
Expand All @@ -111,7 +110,6 @@ struct iwl_mod_params {
unsigned int disable_11n;
int amsdu_size_8K;
bool restart_fw;
int wd_disable;
bool bt_coex_active;
int led_mode;
bool power_save;
Expand Down
26 changes: 2 additions & 24 deletions drivers/net/wireless/iwlwifi/iwl-prph.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
#define SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F)
#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
#define SCD_GP_CTRL_ENABLE_31_QUEUES BIT(0)

/* Context Data */
#define SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600)
Expand Down Expand Up @@ -285,32 +286,9 @@
#define SCD_CHAINEXT_EN (SCD_BASE + 0x244)
#define SCD_AGGR_SEL (SCD_BASE + 0x248)
#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108)
#define SCD_GP_CTRL (SCD_BASE + 0x1a8)
#define SCD_EN_CTRL (SCD_BASE + 0x254)

static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
{
if (chnl < 20)
return SCD_BASE + 0x18 + chnl * 4;
WARN_ON_ONCE(chnl >= 32);
return SCD_BASE + 0x284 + (chnl - 20) * 4;
}

static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
{
if (chnl < 20)
return SCD_BASE + 0x68 + chnl * 4;
WARN_ON_ONCE(chnl >= 32);
return SCD_BASE + 0x2B4 + (chnl - 20) * 4;
}

static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
{
if (chnl < 20)
return SCD_BASE + 0x10c + chnl * 4;
WARN_ON_ONCE(chnl >= 32);
return SCD_BASE + 0x384 + (chnl - 20) * 4;
}

/*********************** END TX SCHEDULER *************************************/

/* Oscillator clock */
Expand Down
41 changes: 33 additions & 8 deletions drivers/net/wireless/iwlwifi/iwl-scd.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,6 @@
#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)
{
Expand Down Expand Up @@ -115,4 +107,37 @@ static inline void iwl_scd_enable_set_active(struct iwl_trans *trans,
{
iwl_write_prph(trans, SCD_EN_CTRL, value);
}

static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
{
if (chnl < 20)
return SCD_BASE + 0x18 + chnl * 4;
WARN_ON_ONCE(chnl >= 32);
return SCD_BASE + 0x284 + (chnl - 20) * 4;
}

static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
{
if (chnl < 20)
return SCD_BASE + 0x68 + chnl * 4;
WARN_ON_ONCE(chnl >= 32);
return SCD_BASE + 0x2B4 + chnl * 4;
}

static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
{
if (chnl < 20)
return SCD_BASE + 0x10c + chnl * 4;
WARN_ON_ONCE(chnl >= 32);
return SCD_BASE + 0x334 + chnl * 4;
}

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));
}

#endif
29 changes: 16 additions & 13 deletions drivers/net/wireless/iwlwifi/iwl-trans.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ enum iwl_trans_status {
* @cmd_queue: the index of the command queue.
* Must be set before start_fw.
* @cmd_fifo: the fifo for host commands
* @cmd_q_wdg_timeout: the timeout of the watchdog timer for the command queue.
* @no_reclaim_cmds: Some devices erroneously don't set the
* SEQ_RX_FRAME bit on some notifications, this is the
* list of such notifications to filter. Max length is
Expand All @@ -378,8 +379,6 @@ enum iwl_trans_status {
* @bc_table_dword: set to true if the BC table expects the byte count to be
* in DWORD (as opposed to bytes)
* @scd_set_active: should the transport configure the SCD for HCMD queue
* @queue_watchdog_timeout: time (in ms) after which queues
* are considered stuck and will trigger device restart
* @command_names: array of command names, must be 256 entries
* (one for each command); for debugging only
* @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
Expand All @@ -390,13 +389,13 @@ struct iwl_trans_config {

u8 cmd_queue;
u8 cmd_fifo;
unsigned int cmd_q_wdg_timeout;
const u8 *no_reclaim_cmds;
unsigned int n_no_reclaim_cmds;

bool rx_buf_size_8k;
bool bc_table_dword;
bool scd_set_active;
unsigned int queue_watchdog_timeout;
const char *const *command_names;

u32 sdio_adma_addr;
Expand Down Expand Up @@ -511,7 +510,8 @@ struct iwl_trans_ops {
struct sk_buff_head *skbs);

void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
const struct iwl_trans_txq_scd_cfg *cfg);
const struct iwl_trans_txq_scd_cfg *cfg,
unsigned int queue_wdg_timeout);
void (*txq_disable)(struct iwl_trans *trans, int queue,
bool configure_scd);

Expand Down Expand Up @@ -829,19 +829,21 @@ static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue,

static inline void
iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn,
const struct iwl_trans_txq_scd_cfg *cfg)
const struct iwl_trans_txq_scd_cfg *cfg,
unsigned int queue_wdg_timeout)
{
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, ssn, cfg);
trans->ops->txq_enable(trans, queue, ssn, cfg, queue_wdg_timeout);
}

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)
int frame_limit, u16 ssn,
unsigned int queue_wdg_timeout)
{
struct iwl_trans_txq_scd_cfg cfg = {
.fifo = fifo,
Expand All @@ -851,11 +853,12 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
.aggregate = sta_id >= 0,
};

iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg);
iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg, queue_wdg_timeout);
}

static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
int fifo)
static inline
void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, int fifo,
unsigned int queue_wdg_timeout)
{
struct iwl_trans_txq_scd_cfg cfg = {
.fifo = fifo,
Expand All @@ -865,16 +868,16 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
.aggregate = false,
};

iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg);
iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg, queue_wdg_timeout);
}

static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
u32 txq_bm)
u32 txqs)
{
if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);

return trans->ops->wait_tx_queue_empty(trans, txq_bm);
return trans->ops->wait_tx_queue_empty(trans, txqs);
}

static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/mvm/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30
#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0
#define IWL_MVM_QUOTA_THRESHOLD 8
#define IWL_MVM_QUOTA_THRESHOLD 4
#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
#define IWL_MVM_RS_DISABLE_P2P_MIMO 0
#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
Expand Down
43 changes: 34 additions & 9 deletions drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,16 +308,41 @@ enum {
#define LQ_FLAG_DYNAMIC_BW_POS 6
#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS)

/* Single Stream Parameters
* SS_STBC/BFER_ALLOWED - Controls whether STBC or Beamformer (BFER) is allowed
* ucode will make a smart decision between SISO/STBC/BFER
* SS_PARAMS_VALID - if not set ignore the ss_params field.
/* Single Stream Tx Parameters (lq_cmd->ss_params)
* Flags to control a smart FW decision about whether BFER/STBC/SISO will be
* used for single stream Tx.
*/
enum {
RS_SS_STBC_ALLOWED = BIT(0),
RS_SS_BFER_ALLOWED = BIT(1),
RS_SS_PARAMS_VALID = BIT(31),
};

/* Bit 0-1: Max STBC streams allowed. Can be 0-3.
* (0) - No STBC allowed
* (1) - 2x1 STBC allowed (HT/VHT)
* (2) - 4x2 STBC allowed (HT/VHT)
* (3) - 3x2 STBC allowed (HT only)
* All our chips are at most 2 antennas so only (1) is valid for now.
*/
#define LQ_SS_STBC_ALLOWED_POS 0
#define LQ_SS_STBC_ALLOWED_MSK (3 << LQ_SS_STBC_ALLOWED_MSK)

/* 2x1 STBC is allowed */
#define LQ_SS_STBC_1SS_ALLOWED (1 << LQ_SS_STBC_ALLOWED_POS)

/* Bit 2: Beamformer (VHT only) is allowed */
#define LQ_SS_BFER_ALLOWED_POS 2
#define LQ_SS_BFER_ALLOWED (1 << LQ_SS_BFER_ALLOWED_POS)

/* Bit 3: Force BFER or STBC for testing
* If this is set:
* If BFER is allowed then force the ucode to choose BFER else
* If STBC is allowed then force the ucode to choose STBC over SISO
*/
#define LQ_SS_FORCE_POS 3
#define LQ_SS_FORCE (1 << LQ_SS_FORCE_POS)

/* Bit 31: ss_params field is valid. Used for FW backward compatibility
* with other drivers which don't support the ss_params API yet
*/
#define LQ_SS_PARAMS_VALID_POS 31
#define LQ_SS_PARAMS_VALID (1 << LQ_SS_PARAMS_VALID_POS)

/**
* struct iwl_lq_cmd - link quality command
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/wireless/iwlwifi/mvm/fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
goto error;
}

iwl_mvm_get_shared_mem_conf(mvm);
if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 10)
iwl_mvm_get_shared_mem_conf(mvm);

ret = iwl_mvm_sf_update(mvm, NULL, false);
if (ret)
Expand Down
10 changes: 7 additions & 3 deletions drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,

int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
{
unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
mvm->cfg->base_params->wd_timeout :
IWL_WATCHDOG_DISABLED;
u32 ac;
int ret;

Expand All @@ -474,16 +477,17 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
switch (vif->type) {
case NL80211_IFTYPE_P2P_DEVICE:
iwl_mvm_enable_ac_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE,
IWL_MVM_TX_FIFO_VO);
IWL_MVM_TX_FIFO_VO, wdg_timeout);
break;
case NL80211_IFTYPE_AP:
iwl_mvm_enable_ac_txq(mvm, vif->cab_queue,
IWL_MVM_TX_FIFO_MCAST);
IWL_MVM_TX_FIFO_MCAST, wdg_timeout);
/* fall through */
default:
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
iwl_mvm_enable_ac_txq(mvm, vif->hw_queue[ac],
iwl_mvm_ac_to_tx_fifo[ac]);
iwl_mvm_ac_to_tx_fifo[ac],
wdg_timeout);
break;
}

Expand Down
Loading

0 comments on commit 8cd4cbf

Please sign in to comment.