iwlwifi: mvm: change RX sync notification to be an attribute and not a type
authorSara Sharon <sara.sharon@intel.com>
Wed, 23 Mar 2016 14:31:43 +0000 (16:31 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Tue, 10 May 2016 19:14:40 +0000 (22:14 +0300)
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>
drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

index ade170bd8683fa7e3d66a0ee3ef58875aa78e3b0..1ca8e4988b885043db9a6ad06bee5dbe6621568f 100644 (file)
@@ -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;
index d6ad77a2c767115b4aa3fc702b47b71a27acb0b5..f746ff6251c3e89294588fbdec4d2a306b880801 100644 (file)
@@ -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);
 }
 
index c7c8a6205eaae78ebe379701cf3dc04df4febaab..14b5f6ab53e270ebcfde1a49fa04e63f7e5bdaba 100644 (file)
@@ -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);
index b4d9c42d411afd53a869e5f393f7f1a703d912a5..306dd9be7c9e9f6a25bcc94a150177fa2663021a 100644 (file)
@@ -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);