From d0b2f91bede3bd5e3d24dd6803e56eee959c1797 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Thu, 20 Oct 2016 00:10:27 -0300 Subject: Linux-libre 4.8.2-gnu --- drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 61 +++++++++++++++++++++------- 1 file changed, 46 insertions(+), 15 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/ops.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index a68054f12..55d9096da 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -431,6 +431,7 @@ static const struct iwl_hcmd_names iwl_mvm_system_names[] = { static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = { HCMD_NAME(LINK_QUALITY_MEASUREMENT_CMD), HCMD_NAME(LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF), + HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF), }; /* Please keep this array *SORTED* by hex value. @@ -494,6 +495,29 @@ static u32 calc_min_backoff(struct iwl_trans *trans, const struct iwl_cfg *cfg) static void iwl_mvm_fw_error_dump_wk(struct work_struct *work); +static void iwl_mvm_tx_unblock_dwork(struct work_struct *work) +{ + struct iwl_mvm *mvm = + container_of(work, struct iwl_mvm, cs_tx_unblock_dwork.work); + struct ieee80211_vif *tx_blocked_vif; + struct iwl_mvm_vif *mvmvif; + + mutex_lock(&mvm->mutex); + + tx_blocked_vif = + rcu_dereference_protected(mvm->csa_tx_blocked_vif, + lockdep_is_held(&mvm->mutex)); + + if (!tx_blocked_vif) + goto unlock; + + mvmvif = iwl_mvm_vif_from_mac80211(tx_blocked_vif); + iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, false); + RCU_INIT_POINTER(mvm->csa_tx_blocked_vif, NULL); +unlock: + mutex_unlock(&mvm->mutex); +} + static struct iwl_op_mode * iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, const struct iwl_fw *fw, struct dentry *dbgfs_dir) @@ -553,18 +577,21 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0; - mvm->aux_queue = 15; if (!iwl_mvm_is_dqa_supported(mvm)) { - mvm->first_agg_queue = 16; mvm->last_agg_queue = mvm->cfg->base_params->num_of_queues - 1; + + if (mvm->cfg->base_params->num_of_queues == 16) { + mvm->aux_queue = 11; + mvm->first_agg_queue = 12; + } else { + mvm->aux_queue = 15; + mvm->first_agg_queue = 16; + } } else { + mvm->aux_queue = IWL_MVM_DQA_AUX_QUEUE; mvm->first_agg_queue = IWL_MVM_DQA_MIN_DATA_QUEUE; mvm->last_agg_queue = IWL_MVM_DQA_MAX_DATA_QUEUE; } - if (mvm->cfg->base_params->num_of_queues == 16) { - mvm->aux_queue = 11; - mvm->first_agg_queue = 12; - } mvm->sf_state = SF_UNINIT; mvm->cur_ucode = IWL_UCODE_INIT; mvm->drop_bcn_ap_mode = true; @@ -584,6 +611,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); INIT_DELAYED_WORK(&mvm->fw_dump_wk, iwl_mvm_fw_error_dump_wk); INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work); + INIT_DELAYED_WORK(&mvm->scan_timeout_dwork, iwl_mvm_scan_timeout_wk); INIT_WORK(&mvm->add_stream_wk, iwl_mvm_add_new_dqa_stream_wk); spin_lock_init(&mvm->d0i3_tx_lock); @@ -595,6 +623,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev); + INIT_DELAYED_WORK(&mvm->cs_tx_unblock_dwork, iwl_mvm_tx_unblock_dwork); + /* * Populate the state variables that the transport layer needs * to know about. @@ -603,6 +633,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.no_reclaim_cmds = no_reclaim_cmds; trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); switch (iwlwifi_mod_params.amsdu_size) { + case IWL_AMSDU_DEF: case IWL_AMSDU_4K: trans_cfg.rx_buf_size = IWL_AMSDU_4K; break; @@ -617,6 +648,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, iwlwifi_mod_params.amsdu_size); trans_cfg.rx_buf_size = IWL_AMSDU_4K; } + + /* the hardware splits the A-MSDU */ + if (mvm->cfg->mq_rx_supported) + trans_cfg.rx_buf_size = IWL_AMSDU_4K; trans_cfg.wide_cmd_header = fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_WIDE_CMD_HDR); @@ -633,6 +668,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; trans_cfg.scd_set_active = true; + trans_cfg.cb_data_offs = offsetof(struct ieee80211_tx_info, + driver_data[2]); + trans_cfg.sdio_adma_addr = fw->sdio_adma_addr; trans_cfg.sw_csum_tx = IWL_MVM_SW_TX_CSUM_OFFLOAD; @@ -735,9 +773,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, iwl_mvm_tof_init(mvm); - setup_timer(&mvm->scan_timer, iwl_mvm_scan_timeout, - (unsigned long)mvm); - return op_mode; out_unregister: @@ -791,8 +826,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) iwl_mvm_tof_clean(mvm); - del_timer_sync(&mvm->scan_timer); - mutex_destroy(&mvm->mutex); mutex_destroy(&mvm->d0i3_suspend_mutex); @@ -936,8 +969,6 @@ static void iwl_mvm_rx(struct iwl_op_mode *op_mode, if (likely(pkt->hdr.cmd == REPLY_RX_MPDU_CMD)) iwl_mvm_rx_rx_mpdu(mvm, napi, rxb); - else if (pkt->hdr.cmd == FRAME_RELEASE) - iwl_mvm_rx_frame_release(mvm, napi, rxb, 0); else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD) iwl_mvm_rx_rx_phy_cmd(mvm, rxb); else @@ -953,11 +984,11 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode, if (likely(pkt->hdr.cmd == REPLY_RX_MPDU_CMD)) iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, 0); - else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD) - iwl_mvm_rx_phy_cmd_mq(mvm, rxb); else if (unlikely(pkt->hdr.group_id == DATA_PATH_GROUP && pkt->hdr.cmd == RX_QUEUES_NOTIFICATION)) iwl_mvm_rx_queue_notif(mvm, rxb, 0); + else if (pkt->hdr.cmd == FRAME_RELEASE) + iwl_mvm_rx_frame_release(mvm, napi, rxb, 0); else iwl_mvm_rx_common(mvm, rxb, pkt); } -- cgit v1.2.3-54-g00ecf