summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2016-03-23 16:31:43 +0200
committerLuca Coelho <luciano.coelho@intel.com>2016-05-10 22:14:40 +0300
commitd0ff5d2297aa03f346c82d8c90528f00f90ea26d (patch)
tree533ea5488d784b6b45c1cabe9a253ab15045647f /drivers/net/wireless/intel
parent0636b938214c90c3a7d145ad86b64a061bb10c50 (diff)
iwlwifi: mvm: change RX sync notification to be an attribute and not a type
Currently the sync notification is a type of notification. However, it is better fitted as an attribute of a notification, since there might be another message in the payload (delba for instance) that should be sent while control path is waiting for all queues to process. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless/intel')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c30
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h3
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c15
4 files changed, 37 insertions, 20 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
index ade170bd8683..1ca8e4988b88 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
@@ -437,24 +437,27 @@ struct iwl_rxq_sync_notification {
/**
* Internal message identifier
*
-* @IWL_MVM_RXQ_SYNC: sync RSS queues
+* @IWL_MVM_RXQ_EMPTY: empty sync notification
* @IWL_MVM_RXQ_NOTIF_DEL_BA: notify RSS queues of delBA
*/
enum iwl_mvm_rxq_notif_type {
- IWL_MVM_RXQ_SYNC,
+ IWL_MVM_RXQ_EMPTY,
IWL_MVM_RXQ_NOTIF_DEL_BA,
};
/**
* struct iwl_mvm_internal_rxq_notif - Internal representation of the data sent
* in &iwl_rxq_sync_cmd. Should be DWORD aligned.
+* FW is agnostic to the payload, so there are no endianity requirements.
*
* @type: value from &iwl_mvm_rxq_notif_type
+* @sync: ctrl path is waiting for all notifications to be received
* @cookie: internal cookie to identify old notifications
* @data: payload
*/
struct iwl_mvm_internal_rxq_notif {
- u32 type;
+ u16 type;
+ u16 sync;
u32 cookie;
u8 data[];
} __packed;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index d6ad77a2c767..f746ff6251c3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -4037,12 +4037,10 @@ static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
}
}
-static void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm)
+void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
+ struct iwl_mvm_internal_rxq_notif *notif,
+ u32 size)
{
- struct iwl_mvm_internal_rxq_notif data = {
- .type = IWL_MVM_RXQ_SYNC,
- .cookie = mvm->queue_sync_cookie,
- };
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(notif_waitq);
u32 qmask = BIT(mvm->trans->num_rx_queues) - 1;
int ret;
@@ -4052,16 +4050,22 @@ static void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm)
if (!iwl_mvm_has_new_rx_api(mvm))
return;
- atomic_set(&mvm->queue_sync_counter, mvm->trans->num_rx_queues);
+ notif->cookie = mvm->queue_sync_cookie;
+
+ if (notif->sync)
+ atomic_set(&mvm->queue_sync_counter,
+ mvm->trans->num_rx_queues);
- ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)&data, sizeof(data));
+ ret = iwl_mvm_notify_rx_queue(mvm, qmask, (u8 *)notif, size);
if (ret) {
IWL_ERR(mvm, "Failed to trigger RX queues sync (%d)\n", ret);
goto out;
}
- ret = wait_event_timeout(notif_waitq,
- atomic_read(&mvm->queue_sync_counter) == 0,
- HZ);
+
+ if (notif->sync)
+ ret = wait_event_timeout(notif_waitq,
+ atomic_read(&mvm->queue_sync_counter) == 0,
+ HZ);
WARN_ON_ONCE(!ret);
out:
@@ -4072,9 +4076,13 @@ out:
static void iwl_mvm_sync_rx_queues(struct ieee80211_hw *hw)
{
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+ struct iwl_mvm_internal_rxq_notif data = {
+ .type = IWL_MVM_RXQ_EMPTY,
+ .sync = 1,
+ };
mutex_lock(&mvm->mutex);
- iwl_mvm_sync_rx_queues_internal(mvm);
+ iwl_mvm_sync_rx_queues_internal(mvm, &data, sizeof(data));
mutex_unlock(&mvm->mutex);
}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index c7c8a6205eaa..14b5f6ab53e2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -1630,6 +1630,9 @@ void iwl_mvm_tdls_cancel_channel_switch(struct ieee80211_hw *hw,
void iwl_mvm_rx_tdls_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
void iwl_mvm_tdls_ch_switch_work(struct work_struct *work);
+void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
+ struct iwl_mvm_internal_rxq_notif *notif,
+ u32 size);
struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index b4d9c42d411a..306dd9be7c9e 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -405,16 +405,19 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
notif = (void *)pkt->data;
internal_notif = (void *)notif->payload;
- switch (internal_notif->type) {
- case IWL_MVM_RXQ_SYNC:
- if (mvm->queue_sync_cookie == internal_notif->cookie)
- atomic_dec(&mvm->queue_sync_counter);
- else
+ if (internal_notif->sync) {
+ if (mvm->queue_sync_cookie != internal_notif->cookie) {
WARN_ONCE(1,
"Received expired RX queue sync message\n");
+ return;
+ }
+ atomic_dec(&mvm->queue_sync_counter);
+ }
+
+ switch (internal_notif->type) {
+ case IWL_MVM_RXQ_EMPTY:
break;
case IWL_MVM_RXQ_NOTIF_DEL_BA:
- /* TODO */
break;
default:
WARN_ONCE(1, "Invalid identifier %d", internal_notif->type);