aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2015-07-22 04:38:40 -0400
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2016-02-27 15:00:06 -0500
commit3af512d6aac7eb6420086f124abb4426f5f4b369 (patch)
treee192787890af13951ae28552c72d5d2e472c9a80 /drivers/net/wireless
parent77fe739554e13d44466e115dbaba3e7aa3aececd (diff)
iwlwifi: mvm: support filtered frames notification
During d0i3 frames might be filtered by the FW and this may cause reordering buffer a delay - as the frames will not be received and reorder will time out. Introduce an API function to receive notification of filtered frames and pass the information to the mac80211. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h22
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rx.c49
4 files changed, 77 insertions, 0 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index ca7fec71854f..e1e11946f7e9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -119,6 +119,8 @@ enum {
119 SCAN_ABORT_UMAC = 0xe, 119 SCAN_ABORT_UMAC = 0xe,
120 SCAN_COMPLETE_UMAC = 0xf, 120 SCAN_COMPLETE_UMAC = 0xf,
121 121
122 BA_WINDOW_STATUS_NOTIFICATION_ID = 0x13,
123
122 /* station table */ 124 /* station table */
123 ADD_STA_KEY = 0x17, 125 ADD_STA_KEY = 0x17,
124 ADD_STA = 0x18, 126 ADD_STA = 0x18,
@@ -1286,6 +1288,26 @@ struct iwl_fw_bcast_filter {
1286 struct iwl_fw_bcast_filter_attr attrs[MAX_BCAST_FILTER_ATTRS]; 1288 struct iwl_fw_bcast_filter_attr attrs[MAX_BCAST_FILTER_ATTRS];
1287} __packed; /* BCAST_FILTER_S_VER_1 */ 1289} __packed; /* BCAST_FILTER_S_VER_1 */
1288 1290
1291#define BA_WINDOW_STREAMS_MAX 16
1292#define BA_WINDOW_STATUS_TID_MSK 0x000F
1293#define BA_WINDOW_STATUS_STA_ID_POS 4
1294#define BA_WINDOW_STATUS_STA_ID_MSK 0x01F0
1295#define BA_WINDOW_STATUS_VALID_MSK BIT(9)
1296
1297/**
1298 * struct iwl_ba_window_status_notif - reordering window's status notification
1299 * @bitmap: bitmap of received frames [start_seq_num + 0]..[start_seq_num + 63]
1300 * @ra_tid: bit 3:0 - TID, bit 8:4 - STA_ID, bit 9 - valid
1301 * @start_seq_num: the start sequence number of the bitmap
1302 * @mpdu_rx_count: the number of received MPDUs since entering D0i3
1303 */
1304struct iwl_ba_window_status_notif {
1305 __le64 bitmap[BA_WINDOW_STREAMS_MAX];
1306 __le16 ra_tid[BA_WINDOW_STREAMS_MAX];
1307 __le32 start_seq_num[BA_WINDOW_STREAMS_MAX];
1308 __le16 mpdu_rx_count[BA_WINDOW_STREAMS_MAX];
1309} __packed; /* BA_WINDOW_STATUS_NTFY_API_S_VER_1 */
1310
1289/** 1311/**
1290 * struct iwl_fw_bcast_mac - per-mac broadcast filtering configuration. 1312 * struct iwl_fw_bcast_mac - per-mac broadcast filtering configuration.
1291 * @default_discard: default action for this mac (discard (1) / pass (0)). 1313 * @default_discard: default action for this mac (discard (1) / pass (0)).
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 416aedb7c19e..fa987bd9da0d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1268,6 +1268,8 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
1268 struct iwl_rx_cmd_buffer *rxb); 1268 struct iwl_rx_cmd_buffer *rxb);
1269void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm, 1269void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
1270 struct iwl_rx_cmd_buffer *rxb); 1270 struct iwl_rx_cmd_buffer *rxb);
1271void iwl_mvm_window_status_notif(struct iwl_mvm *mvm,
1272 struct iwl_rx_cmd_buffer *rxb);
1271void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, 1273void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
1272 struct ieee80211_vif *vif); 1274 struct ieee80211_vif *vif);
1273unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, 1275unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index bfa6da1bf846..52c73d0c1be5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -236,6 +236,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
236 RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION, 236 RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION,
237 iwl_mvm_rx_ant_coupling_notif, true), 237 iwl_mvm_rx_ant_coupling_notif, true),
238 238
239 RX_HANDLER(BA_WINDOW_STATUS_NOTIFICATION_ID,
240 iwl_mvm_window_status_notif, false),
241
239 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false), 242 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
240 RX_HANDLER(MCC_CHUB_UPDATE_CMD, iwl_mvm_rx_chub_update_mcc, true), 243 RX_HANDLER(MCC_CHUB_UPDATE_CMD, iwl_mvm_rx_chub_update_mcc, true),
241 244
@@ -294,6 +297,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
294 HCMD_NAME(SCAN_COMPLETE_UMAC), 297 HCMD_NAME(SCAN_COMPLETE_UMAC),
295 HCMD_NAME(TOF_CMD), 298 HCMD_NAME(TOF_CMD),
296 HCMD_NAME(TOF_NOTIFICATION), 299 HCMD_NAME(TOF_NOTIFICATION),
300 HCMD_NAME(BA_WINDOW_STATUS_NOTIFICATION_ID),
297 HCMD_NAME(ADD_STA_KEY), 301 HCMD_NAME(ADD_STA_KEY),
298 HCMD_NAME(ADD_STA), 302 HCMD_NAME(ADD_STA),
299 HCMD_NAME(REMOVE_STA), 303 HCMD_NAME(REMOVE_STA),
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index ad625f0c79ed..485cfc1a4daa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as 13 * it under the terms of version 2 of the GNU General Public License as
@@ -626,3 +627,51 @@ void iwl_mvm_rx_statistics(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
626{ 627{
627 iwl_mvm_handle_rx_statistics(mvm, rxb_addr(rxb)); 628 iwl_mvm_handle_rx_statistics(mvm, rxb_addr(rxb));
628} 629}
630
631void iwl_mvm_window_status_notif(struct iwl_mvm *mvm,
632 struct iwl_rx_cmd_buffer *rxb)
633{
634 struct iwl_rx_packet *pkt = rxb_addr(rxb);
635 struct iwl_ba_window_status_notif *notif = (void *)pkt->data;
636 int i;
637 u32 pkt_len = iwl_rx_packet_payload_len(pkt);
638
639 if (WARN_ONCE(pkt_len != sizeof(*notif),
640 "Received window status notification of wrong size (%u)\n",
641 pkt_len))
642 return;
643
644 rcu_read_lock();
645 for (i = 0; i < BA_WINDOW_STREAMS_MAX; i++) {
646 struct ieee80211_sta *sta;
647 u8 sta_id, tid;
648 u64 bitmap;
649 u32 ssn;
650 u16 ratid;
651 u16 received_mpdu;
652
653 ratid = le16_to_cpu(notif->ra_tid[i]);
654 /* check that this TID is valid */
655 if (!(ratid & BA_WINDOW_STATUS_VALID_MSK))
656 continue;
657
658 received_mpdu = le16_to_cpu(notif->mpdu_rx_count[i]);
659 if (received_mpdu == 0)
660 continue;
661
662 tid = ratid & BA_WINDOW_STATUS_TID_MSK;
663 /* get the station */
664 sta_id = (ratid & BA_WINDOW_STATUS_STA_ID_MSK)
665 >> BA_WINDOW_STATUS_STA_ID_POS;
666 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
667 if (IS_ERR_OR_NULL(sta))
668 continue;
669 bitmap = le64_to_cpu(notif->bitmap[i]);
670 ssn = le32_to_cpu(notif->start_seq_num[i]);
671
672 /* update mac80211 with the bitmap for the reordering buffer */
673 ieee80211_mark_rx_ba_filtered_frames(sta, tid, ssn, bitmap,
674 received_mpdu);
675 }
676 rcu_read_unlock();
677}