diff options
author | Sara Sharon <sara.sharon@intel.com> | 2016-02-28 08:41:47 -0500 |
---|---|---|
committer | Luca Coelho <luciano.coelho@intel.com> | 2016-05-10 15:14:43 -0400 |
commit | a338384bb31f01dc1306c7200ace61a55fa25947 (patch) | |
tree | e799330100df6097aaf7a942fddb48f4ea1b05be /drivers/net/wireless | |
parent | 0690405fef290c3ae9bf466d603731b2ba478053 (diff) |
iwlwifi: mvm: utilize the frame release infrastructure
The firmware will send frame release notification in order
to release "stuck" frames on a queue where no more frames
arrive on.
Upon receiving the message the driver shall indicate the frames
up to the NSSN.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 33 |
3 files changed, 34 insertions, 5 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 3c331bdadff7..6eaf21a0726b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | |||
@@ -1304,7 +1304,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi, | |||
1304 | void iwl_mvm_rx_phy_cmd_mq(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); | 1304 | void iwl_mvm_rx_phy_cmd_mq(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); |
1305 | void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, | 1305 | void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, |
1306 | struct iwl_rx_cmd_buffer *rxb, int queue); | 1306 | struct iwl_rx_cmd_buffer *rxb, int queue); |
1307 | void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, | 1307 | void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi, |
1308 | struct iwl_rx_cmd_buffer *rxb, int queue); | 1308 | struct iwl_rx_cmd_buffer *rxb, int queue); |
1309 | int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask, | 1309 | int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask, |
1310 | const u8 *data, u32 count); | 1310 | const u8 *data, u32 count); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 7c6a5984105f..2ba13691b481 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
@@ -932,7 +932,7 @@ static void iwl_mvm_rx(struct iwl_op_mode *op_mode, | |||
932 | if (likely(pkt->hdr.cmd == REPLY_RX_MPDU_CMD)) | 932 | if (likely(pkt->hdr.cmd == REPLY_RX_MPDU_CMD)) |
933 | iwl_mvm_rx_rx_mpdu(mvm, napi, rxb); | 933 | iwl_mvm_rx_rx_mpdu(mvm, napi, rxb); |
934 | else if (pkt->hdr.cmd == FRAME_RELEASE) | 934 | else if (pkt->hdr.cmd == FRAME_RELEASE) |
935 | iwl_mvm_rx_frame_release(mvm, rxb, 0); | 935 | iwl_mvm_rx_frame_release(mvm, napi, rxb, 0); |
936 | else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD) | 936 | else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD) |
937 | iwl_mvm_rx_rx_phy_cmd(mvm, rxb); | 937 | iwl_mvm_rx_rx_phy_cmd(mvm, rxb); |
938 | else | 938 | else |
@@ -1634,7 +1634,7 @@ static void iwl_mvm_rx_mq_rss(struct iwl_op_mode *op_mode, | |||
1634 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1634 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
1635 | 1635 | ||
1636 | if (unlikely(pkt->hdr.cmd == FRAME_RELEASE)) | 1636 | if (unlikely(pkt->hdr.cmd == FRAME_RELEASE)) |
1637 | iwl_mvm_rx_frame_release(mvm, rxb, queue); | 1637 | iwl_mvm_rx_frame_release(mvm, napi, rxb, queue); |
1638 | else if (unlikely(pkt->hdr.cmd == RX_QUEUES_NOTIFICATION && | 1638 | else if (unlikely(pkt->hdr.cmd == RX_QUEUES_NOTIFICATION && |
1639 | pkt->hdr.group_id == DATA_PATH_GROUP)) | 1639 | pkt->hdr.group_id == DATA_PATH_GROUP)) |
1640 | iwl_mvm_rx_queue_notif(mvm, rxb, queue); | 1640 | iwl_mvm_rx_queue_notif(mvm, rxb, queue); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index ed187afca1f2..0da93b57d620 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | |||
@@ -900,8 +900,37 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, | |||
900 | rcu_read_unlock(); | 900 | rcu_read_unlock(); |
901 | } | 901 | } |
902 | 902 | ||
903 | void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, | 903 | void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, struct napi_struct *napi, |
904 | struct iwl_rx_cmd_buffer *rxb, int queue) | 904 | struct iwl_rx_cmd_buffer *rxb, int queue) |
905 | { | 905 | { |
906 | /* TODO */ | 906 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
907 | struct iwl_frame_release *release = (void *)pkt->data; | ||
908 | struct ieee80211_sta *sta; | ||
909 | struct iwl_mvm_reorder_buffer *reorder_buf; | ||
910 | struct iwl_mvm_baid_data *ba_data; | ||
911 | |||
912 | int baid = release->baid; | ||
913 | |||
914 | if (WARN_ON_ONCE(baid == IWL_RX_REORDER_DATA_INVALID_BAID)) | ||
915 | return; | ||
916 | |||
917 | rcu_read_lock(); | ||
918 | |||
919 | ba_data = rcu_dereference(mvm->baid_map[baid]); | ||
920 | if (WARN_ON_ONCE(!ba_data)) | ||
921 | goto out; | ||
922 | |||
923 | sta = rcu_dereference(mvm->fw_id_to_mac_id[ba_data->sta_id]); | ||
924 | if (WARN_ON_ONCE(IS_ERR_OR_NULL(sta))) | ||
925 | goto out; | ||
926 | |||
927 | reorder_buf = &ba_data->reorder_buf[queue]; | ||
928 | |||
929 | spin_lock_bh(&reorder_buf->lock); | ||
930 | iwl_mvm_release_frames(mvm, sta, napi, reorder_buf, | ||
931 | le16_to_cpu(release->nssn)); | ||
932 | spin_unlock_bh(&reorder_buf->lock); | ||
933 | |||
934 | out: | ||
935 | rcu_read_unlock(); | ||
907 | } | 936 | } |