summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-01-16 12:54:17 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-01-16 12:54:17 -0500
commit2b755bbd8198161416ce24e3358817d8ede93037 (patch)
tree7b04bc63c08adb384a1fd4eb118f364c56aa4dab /drivers/net/wireless/iwlwifi
parent608cfbe4abaf76e9d732efd7ed1cfa3998163d91 (diff)
parentcf38e4f756d6396657c76f72ef42b6f47c523f97 (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c28
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c13
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c13
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c22
18 files changed, 94 insertions, 63 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 40eb5e69147..c24d1d3d55f 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -406,9 +406,8 @@ static bool iwl_resume_status_fn(struct iwl_notif_wait_data *notif_wait,
{
struct iwl_resume_data *resume_data = data;
struct iwl_priv *priv = resume_data->priv;
- u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
- if (len - 4 != sizeof(*resume_data->cmd)) {
+ if (iwl_rx_packet_payload_len(pkt) != sizeof(*resume_data->cmd)) {
IWL_ERR(priv, "rx wrong size data\n");
return true;
}
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index b68bb2f4d2c..7a1bc1c547e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -205,8 +205,7 @@ static int iwlagn_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
struct iwl_device_cmd *cmd)
{
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- u32 __maybe_unused len =
- le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ u32 __maybe_unused len = iwl_rx_packet_len(pkt);
IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
"notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len);
iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len);
@@ -457,7 +456,7 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
const int reg_recalib_period = 60;
int change;
struct iwl_rx_packet *pkt = rxb_addr(rxb);
- u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ u32 len = iwl_rx_packet_payload_len(pkt);
__le32 *flag;
struct statistics_general_common *common;
struct statistics_rx_non_phy *rx_non_phy;
@@ -467,8 +466,6 @@ static int iwlagn_rx_statistics(struct iwl_priv *priv,
struct statistics_tx *tx;
struct statistics_bt_activity *bt_activity;
- len -= sizeof(struct iwl_cmd_header); /* skip header */
-
IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",
len);
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index f59709a9b79..cf03ef5619d 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -388,7 +388,6 @@ static bool iwlagn_wait_calib(struct iwl_notif_wait_data *notif_wait,
{
struct iwl_priv *priv = data;
struct iwl_calib_hdr *hdr;
- int len;
if (pkt->hdr.cmd != CALIBRATION_RES_NOTIFICATION) {
WARN_ON(pkt->hdr.cmd != CALIBRATION_COMPLETE_NOTIFICATION);
@@ -396,12 +395,8 @@ static bool iwlagn_wait_calib(struct iwl_notif_wait_data *notif_wait,
}
hdr = (struct iwl_calib_hdr *)pkt->data;
- len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
- /* reduce the size by the length field itself */
- len -= sizeof(__le32);
-
- if (iwl_calib_set(priv, hdr, len))
+ if (iwl_calib_set(priv, hdr, iwl_rx_packet_payload_len(pkt)))
IWL_ERR(priv, "Failed to record calibration data %d\n",
hdr->op_code);
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 1b61cb52994..f06f4cbe131 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -264,14 +264,13 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
struct ieee80211_sta_vht_cap *vht_cap)
{
int num_ants = num_of_ant(data->valid_rx_ant);
- int bf_sts_cap = num_ants - 1;
vht_cap->vht_supported = true;
vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
IEEE80211_VHT_CAP_RXSTBC_1 |
IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
- bf_sts_cap << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
+ 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
if (num_ants > 1)
@@ -290,9 +289,6 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
- /* Max rate for Long GI NSS=2 80Mhz is 780Mbps */
- vht_cap->vht_mcs.rx_highest = cpu_to_le16(780);
-
if (num_ants == 1 ||
cfg->rx_with_siso_diversity) {
vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
@@ -300,12 +296,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
/* this works because NOT_SUPPORTED == 3 */
vht_cap->vht_mcs.rx_mcs_map |=
cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
- /* Max rate for Long GI NSS=1 80Mhz is 390Mbps */
- vht_cap->vht_mcs.rx_highest = cpu_to_le16(390);
}
vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
- vht_cap->vht_mcs.tx_highest = vht_cap->vht_mcs.rx_highest;
}
static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index d69b0fb0a43..100bd0d7968 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -277,4 +277,8 @@ static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
/*********************** END TX SCHEDULER *************************************/
+/* Oscillator clock */
+#define OSC_CLK (0xa04068)
+#define OSC_CLK_FORCE_CONTROL (0x8)
+
#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 8d1b5ed3502..1f065cf4a4b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -176,6 +176,16 @@ struct iwl_rx_packet {
u8 data[];
} __packed;
+static inline u32 iwl_rx_packet_len(const struct iwl_rx_packet *pkt)
+{
+ return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+}
+
+static inline u32 iwl_rx_packet_payload_len(const struct iwl_rx_packet *pkt)
+{
+ return iwl_rx_packet_len(pkt) - sizeof(pkt->hdr);
+}
+
/**
* enum CMD_MODE - how to send the host commands ?
*
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index f04d2f4d80c..f36a7ee0267 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -886,8 +886,7 @@ static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm,
if (err)
return err;
- size = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
- size -= sizeof(cmd.resp_pkt->hdr);
+ size = iwl_rx_packet_payload_len(cmd.resp_pkt);
if (size < sizeof(__le16)) {
err = -EINVAL;
} else {
@@ -1211,9 +1210,8 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
if (ret)
goto out;
#ifdef CONFIG_IWLWIFI_DEBUGFS
- len = le32_to_cpu(d3_cfg_cmd.resp_pkt->len_n_flags) &
- FH_RSCSR_FRAME_SIZE_MSK;
- if (len >= sizeof(u32) * 2) {
+ len = iwl_rx_packet_payload_len(d3_cfg_cmd.resp_pkt);
+ if (len >= sizeof(u32)) {
mvm->d3_test_pme_ptr =
le32_to_cpup((__le32 *)d3_cfg_cmd.resp_pkt->data);
}
@@ -1668,8 +1666,8 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
else
status_size = sizeof(struct iwl_wowlan_status_v4);
- len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
- if (len - sizeof(struct iwl_cmd_header) < status_size) {
+ len = iwl_rx_packet_payload_len(cmd.resp_pkt);
+ if (len < status_size) {
IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
goto out_free_resp;
}
@@ -1704,8 +1702,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
status.wake_packet = status_v4->wake_packet;
}
- if (len - sizeof(struct iwl_cmd_header) !=
- status_size + ALIGN(status.wake_packet_bufsize, 4)) {
+ if (len != status_size + ALIGN(status.wake_packet_bufsize, 4)) {
IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
goto out_free_resp;
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 76cdce9edf5..369d4c90e66 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -135,7 +135,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf,
ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
len = img->sec[IWL_UCODE_SECTION_DATA].len;
- if (!mvm->dbgfs_sram_offset && !mvm->dbgfs_sram_len) {
+ if (mvm->dbgfs_sram_len) {
ofs = mvm->dbgfs_sram_offset;
len = mvm->dbgfs_sram_len;
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 6bbbad453a3..1b60fdff6a5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -97,9 +97,6 @@ enum iwl_sta_flags {
STA_FLG_FLG_ANT_B),
STA_FLG_PS = BIT(8),
- STA_FLG_INVALID = BIT(9),
- STA_FLG_DLP_EN = BIT(10),
- STA_FLG_SET_ALL_KEYS = BIT(11),
STA_FLG_DRAIN_FLOW = BIT(12),
STA_FLG_PAN = BIT(13),
STA_FLG_CLASS_AUTH = BIT(14),
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index b41177eb488..c49b5073c25 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -262,9 +262,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
/* currently FW API supports only one optional cipher scheme */
- if (mvm->fw->cs->cipher) {
+ if (mvm->fw->cs[0].cipher) {
mvm->hw->n_cipher_schemes = 1;
- mvm->hw->cipher_schemes = mvm->fw->cs;
+ mvm->hw->cipher_schemes = &mvm->fw->cs[0];
}
#ifdef CONFIG_PM_SLEEP
@@ -944,6 +944,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
IWL_ERR(mvm, "failed to update power mode\n");
}
iwl_mvm_bt_coex_vif_change(mvm);
+ iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT,
+ IEEE80211_SMPS_AUTOMATIC);
} else if (changes & BSS_CHANGED_BEACON_INFO) {
/*
* We received a beacon _after_ association so
@@ -1012,9 +1014,16 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
if (ret)
goto out_unbind;
+ /* must be set before quota calculations */
+ mvmvif->ap_ibss_active = true;
+
+ /* power updated needs to be done before quotas */
+ mvm->bound_vif_cnt++;
+ iwl_mvm_power_update_binding(mvm, vif, true);
+
ret = iwl_mvm_update_quotas(mvm, vif);
if (ret)
- goto out_rm_bcast;
+ goto out_quota_failed;
/* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
if (vif->p2p && mvm->p2p_device_vif)
@@ -1025,7 +1034,10 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
mutex_unlock(&mvm->mutex);
return 0;
-out_rm_bcast:
+out_quota_failed:
+ mvm->bound_vif_cnt--;
+ iwl_mvm_power_update_binding(mvm, vif, false);
+ mvmvif->ap_ibss_active = false;
iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
out_unbind:
iwl_mvm_binding_remove_vif(mvm, vif);
@@ -1057,6 +1069,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
iwl_mvm_update_quotas(mvm, NULL);
iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);
iwl_mvm_binding_remove_vif(mvm, vif);
+
+ mvm->bound_vif_cnt--;
+ iwl_mvm_power_update_binding(mvm, vif, false);
+
iwl_mvm_mac_ctxt_remove(mvm, vif);
mutex_unlock(&mvm->mutex);
@@ -1790,11 +1806,11 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
}
iwl_mvm_binding_remove_vif(mvm, vif);
-out_unlock:
- mvmvif->phy_ctxt = NULL;
mvm->bound_vif_cnt--;
iwl_mvm_power_update_binding(mvm, vif, false);
+out_unlock:
+ mvmvif->phy_ctxt = NULL;
mutex_unlock(&mvm->mutex);
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index c6beb0f842d..35b71af78d0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -392,17 +392,16 @@ out:
/* Loads the NVM data stored in mvm->nvm_sections into the NIC */
int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
{
- int i, ret;
- u16 section_id;
+ int i, ret = 0;
struct iwl_nvm_section *sections = mvm->nvm_sections;
IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n");
- for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {
- section_id = nvm_to_read[i];
- ret = iwl_nvm_write_section(mvm, section_id,
- sections[section_id].data,
- sections[section_id].length);
+ for (i = 0; i < ARRAY_SIZE(mvm->nvm_sections); i++) {
+ if (!mvm->nvm_sections[i].data || !mvm->nvm_sections[i].length)
+ continue;
+ ret = iwl_nvm_write_section(mvm, i, sections[i].data,
+ sections[i].length);
if (ret < 0) {
IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);
break;
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 552c76a926e..a3d43de342d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -309,6 +309,7 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = {
CMD(BT_PROFILE_NOTIFICATION),
CMD(BT_CONFIG),
CMD(MCAST_FILTER_CMD),
+ CMD(REPLY_SF_CFG_CMD),
CMD(REPLY_BEACON_FILTERING_CMD),
CMD(REPLY_THERMAL_MNG_BACKOFF),
CMD(MAC_PM_POWER_TABLE),
@@ -472,6 +473,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
out_unregister:
ieee80211_unregister_hw(mvm->hw);
+ iwl_mvm_leds_exit(mvm);
out_free:
iwl_phy_db_free(mvm->phy_db);
kfree(mvm->scan_cmd);
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index ba078a3322b..6abf74e1351 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -356,7 +356,7 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
return idx;
}
- return -1;
+ return IWL_RATE_INVALID;
}
static void rs_rate_scale_perform(struct iwl_mvm *mvm,
@@ -702,10 +702,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
memset(rate, 0, sizeof(*rate));
rate->index = iwl_hwrate_to_plcp_idx(ucode_rate);
- if (rate->index == IWL_RATE_INVALID) {
- rate->index = -1;
+ if (rate->index == IWL_RATE_INVALID)
return -EINVAL;
- }
rate->ant = (ant_msk >> RATE_MCS_ANT_POS);
@@ -1590,6 +1588,8 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
search_tbl->column = col_id;
rs_set_expected_tpt_table(lq_sta, search_tbl);
+ lq_sta->visited_columns |= BIT(col_id);
+
/* Get the best matching rate if we're changing modes. e.g.
* SISO->MIMO, LEGACY->SISO, MIMO->SISO
*/
@@ -1613,7 +1613,6 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
IWL_DEBUG_RATE(mvm, "Switched to column %d: Index %d\n",
col_id, rate->index);
- lq_sta->visited_columns |= BIT(col_id);
return 0;
err:
@@ -2560,7 +2559,9 @@ static int rs_pretty_print_rate(char *buf, const u32 rate)
int index = iwl_hwrate_to_plcp_idx(rate);
return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n",
- rs_pretty_ant(ant), iwl_rate_mcs[index].mbps);
+ rs_pretty_ant(ant),
+ index == IWL_RATE_INVALID ? "BAD" :
+ iwl_rate_mcs[index].mbps);
}
if (rate & RATE_MCS_VHT_MSK) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 50f3d7f560b..b4c2abaa297 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -249,12 +249,12 @@ static bool iwl_mvm_time_event_response(struct iwl_notif_wait_data *notif_wait,
container_of(notif_wait, struct iwl_mvm, notif_wait);
struct iwl_mvm_time_event_data *te_data = data;
struct iwl_time_event_resp *resp;
- int resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ int resp_len = iwl_rx_packet_payload_len(pkt);
if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD))
return true;
- if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) {
+ if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
IWL_ERR(mvm, "Invalid TIME_EVENT_CMD response\n");
return true;
}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 3c575a39987..90378c217bc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -390,7 +390,6 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
seq_number &= IEEE80211_SCTL_SEQ;
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
hdr->seq_ctrl |= cpu_to_le16(seq_number);
- seq_number += 0x10;
is_data_qos = true;
is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;
}
@@ -407,13 +406,13 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
}
IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,
- tid, txq_id, seq_number);
+ tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number));
if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))
goto drop_unlock_sta;
if (is_data_qos && !ieee80211_has_morefrags(fc))
- mvmsta->tid_data[tid].seq_number = seq_number;
+ mvmsta->tid_data[tid].seq_number = seq_number + 0x10;
spin_unlock(&mvmsta->lock);
@@ -704,7 +703,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
*/
spin_lock_bh(&mvmsta->lock);
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
- if (IS_ERR_OR_NULL(sta)) {
+ if (!sta || PTR_ERR(sta) == -EBUSY) {
/*
* Station disappeared in the meantime:
* so we are draining.
@@ -713,7 +712,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
schedule_work(&mvm->sta_drained_wk);
}
spin_unlock_bh(&mvmsta->lock);
- } else if (!mvmsta) {
+ } else if (!mvmsta && PTR_ERR(sta) == -EBUSY) {
/* Tx response without STA, so we are draining */
set_bit(sta_id, mvm->sta_drained);
schedule_work(&mvm->sta_drained_wk);
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 487d61b2535..a4a5e25623c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -168,8 +168,8 @@ int iwl_mvm_send_cmd_status(struct iwl_mvm *mvm, struct iwl_host_cmd *cmd,
goto out_free_resp;
}
- resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
- if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) {
+ resp_len = iwl_rx_packet_payload_len(pkt);
+ if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
ret = -EIO;
goto out_free_resp;
}
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 1890ea29c26..08c23d497a0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -615,7 +615,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd),
pkt->hdr.cmd);
- len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+ len = iwl_rx_packet_len(pkt);
len += sizeof(u32); /* account for status word */
trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len);
trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len);
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 16f66c1a23d..f9507807b48 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -178,6 +178,28 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans)
goto out;
}
+ if (trans->cfg->host_interrupt_operation_mode) {
+ /*
+ * This is a bit of an abuse - This is needed for 7260 / 3160
+ * only check host_interrupt_operation_mode even if this is
+ * not related to host_interrupt_operation_mode.
+ *
+ * Enable the oscillator to count wake up time for L1 exit. This
+ * consumes slightly more power (100uA) - but allows to be sure
+ * that we wake up from L1 on time.
+ *
+ * This looks weird: read twice the same register, discard the
+ * value, set a bit, and yet again, read that same register
+ * just to discard the value. But that's the way the hardware
+ * seems to like it.
+ */
+ iwl_read_prph(trans, OSC_CLK);
+ iwl_read_prph(trans, OSC_CLK);
+ iwl_set_bits_prph(trans, OSC_CLK, OSC_CLK_FORCE_CONTROL);
+ iwl_read_prph(trans, OSC_CLK);
+ iwl_read_prph(trans, OSC_CLK);
+ }
+
/*
* Enable DMA clock and wait for it to stabilize.
*