iwlwifi: mvm: add low-latency framework
authorJohannes Berg <johannes.berg@intel.com>
Tue, 12 Nov 2013 16:30:52 +0000 (17:30 +0100)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 3 Feb 2014 20:23:34 +0000 (22:23 +0200)
For various traffic use cases, we want to be able to treat multi-
channel scenarios differently. Introduce a low-latency framework
that currently only has a debugfs file to enable low-latency mode,
but can later be extended.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/iwlwifi/mvm/mvm.h
drivers/net/wireless/iwlwifi/mvm/utils.c

index 0e29cd83a06a83c158860a5523549edf7e3c44db..19ecade5ec5f05a178de4563db5bc4790e87a0f3 100644 (file)
@@ -460,6 +460,41 @@ static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
+static ssize_t iwl_dbgfs_low_latency_write(struct ieee80211_vif *vif, char *buf,
+                                          size_t count, loff_t *ppos)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_mvm *mvm = mvmvif->mvm;
+       u8 value;
+       int ret;
+
+       ret = kstrtou8(buf, 0, &value);
+       if (ret)
+               return ret;
+       if (value > 1)
+               return -EINVAL;
+
+       mutex_lock(&mvm->mutex);
+       iwl_mvm_update_low_latency(mvm, vif, value);
+       mutex_unlock(&mvm->mutex);
+
+       return count;
+}
+
+static ssize_t iwl_dbgfs_low_latency_read(struct file *file,
+                                         char __user *user_buf,
+                                         size_t count, loff_t *ppos)
+{
+       struct ieee80211_vif *vif = file->private_data;
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       char buf[3];
+
+       buf[0] = mvmvif->low_latency ? '1' : '0';
+       buf[1] = '\n';
+       buf[2] = '\0';
+       return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
+}
+
 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
        _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -473,6 +508,7 @@ static ssize_t iwl_dbgfs_bf_params_read(struct file *file,
 MVM_DEBUGFS_READ_FILE_OPS(mac_params);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
+MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
 
 void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 {
@@ -505,6 +541,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
 
        MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir,
                                 S_IRUSR);
+       MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir,
+                                S_IRUSR | S_IWUSR);
 
        if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
            mvmvif == mvm->bf_allowed_vif)
index 02e4bdc80de2ce03c9dbba9a11dad2d0df5213dc..00bc4ce06ccaa371d99f05fbb55cd04e7bc5b32a 100644 (file)
@@ -269,7 +269,9 @@ struct iwl_mvm_vif_bf_data {
  * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface
  *     should get quota etc.
  * @monitor_active: indicates that monitor context is configured, and that the
- * interface should get quota etc.
+ *     interface should get quota etc.
+ * @low_latency: indicates that this interface is in low-latency mode
+ *     (VMACLowLatencyMode)
  * @queue_params: QoS params for this MAC
  * @bcast_sta: station used for broadcast packets. Used by the following
  *  vifs: P2P_DEVICE, GO and AP.
@@ -285,6 +287,7 @@ struct iwl_mvm_vif {
        bool uploaded;
        bool ap_ibss_active;
        bool monitor_active;
+       bool low_latency;
        struct iwl_mvm_vif_bf_data bf_data;
 
        u32 ap_beacon_time;
@@ -909,6 +912,26 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                                enum iwl_mvm_smps_type_request req_type,
                                enum ieee80211_smps_mode smps_request);
 
+/* Low latency */
+int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+                              bool value);
+/* get VMACLowLatencyMode */
+static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
+{
+       /*
+        * should this consider associated/active/... state?
+        *
+        * Normally low-latency should only be active on interfaces
+        * that are active, but at least with debugfs it can also be
+        * enabled on interfaces that aren't active. However, when
+        * interface aren't active then they aren't added into the
+        * binding, so this has no real impact. For now, just return
+        * the current desired low-latency state.
+        */
+
+       return mvmvif->low_latency;
+}
+
 /* Thermal management and CT-kill */
 void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
 void iwl_mvm_tt_initialize(struct iwl_mvm *mvm);
index a4a5e25623c30044db0333e1a0ced761c976ab89..e2cc876d93889bd6c53264e5e2143413a5bb9803 100644 (file)
@@ -536,3 +536,15 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 
        ieee80211_request_smps(vif, smps_mode);
 }
+
+int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
+                              bool value)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+       lockdep_assert_held(&mvm->mutex);
+
+       mvmvif->low_latency = value;
+
+       return iwl_mvm_update_quotas(mvm, NULL);
+}