mac80211: Fix clang warning about constant operand in logical operation
[platform/kernel/linux-exynos.git] / net / mac80211 / rate.c
index 9e2641d..9d7a1cd 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright 2002-2005, Instant802 Networks, Inc.
  * Copyright 2005-2006, Devicescape Software, Inc.
  * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
+ * Copyright 2017      Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -40,8 +41,6 @@ void rate_control_rate_init(struct sta_info *sta)
 
        ieee80211_sta_set_rx_nss(sta);
 
-       ieee80211_recalc_min_chandef(sta->sdata);
-
        if (!ref)
                return;
 
@@ -175,9 +174,11 @@ ieee80211_rate_control_ops_get(const char *name)
                /* try default if specific alg requested but not found */
                ops = ieee80211_try_rate_control_ops_get(ieee80211_default_rc_algo);
 
-       /* try built-in one if specific alg requested but not found */
-       if (!ops && strlen(CONFIG_MAC80211_RC_DEFAULT))
+       /* Note: check for > 0 is intentional to avoid clang warning */
+       if (!ops && (strlen(CONFIG_MAC80211_RC_DEFAULT) > 0))
+               /* try built-in one if specific alg requested but not found */
                ops = ieee80211_try_rate_control_ops_get(CONFIG_MAC80211_RC_DEFAULT);
+
        kernel_param_unlock(THIS_MODULE);
 
        return ops;
@@ -210,7 +211,6 @@ static struct rate_control_ref *rate_control_alloc(const char *name,
        ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
        if (!ref)
                return NULL;
-       ref->local = local;
        ref->ops = ieee80211_rate_control_ops_get(name);
        if (!ref->ops)
                goto free;
@@ -231,18 +231,45 @@ free:
        return NULL;
 }
 
-static void rate_control_free(struct rate_control_ref *ctrl_ref)
+static void rate_control_free(struct ieee80211_local *local,
+                             struct rate_control_ref *ctrl_ref)
 {
        ctrl_ref->ops->free(ctrl_ref->priv);
 
 #ifdef CONFIG_MAC80211_DEBUGFS
-       debugfs_remove_recursive(ctrl_ref->local->debugfs.rcdir);
-       ctrl_ref->local->debugfs.rcdir = NULL;
+       debugfs_remove_recursive(local->debugfs.rcdir);
+       local->debugfs.rcdir = NULL;
 #endif
 
        kfree(ctrl_ref);
 }
 
+void ieee80211_check_rate_mask(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_supported_band *sband;
+       u32 user_mask, basic_rates = sdata->vif.bss_conf.basic_rates;
+       enum nl80211_band band;
+
+       if (WARN_ON(!sdata->vif.bss_conf.chandef.chan))
+               return;
+
+       if (WARN_ON_ONCE(!basic_rates))
+               return;
+
+       band = sdata->vif.bss_conf.chandef.chan->band;
+       user_mask = sdata->rc_rateidx_mask[band];
+       sband = local->hw.wiphy->bands[band];
+
+       if (user_mask & basic_rates)
+               return;
+
+       sdata_dbg(sdata,
+                 "no overlap between basic rates (0x%x) and user mask (0x%x on band %d) - clearing the latter",
+                 basic_rates, user_mask, band);
+       sdata->rc_rateidx_mask[band] = (1 << sband->n_bitrates) - 1;
+}
+
 static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)
 {
        struct sk_buff *skb = txrc->skb;
@@ -938,6 +965,6 @@ void rate_control_deinitialize(struct ieee80211_local *local)
                return;
 
        local->rate_ctrl = NULL;
-       rate_control_free(ref);
+       rate_control_free(local, ref);
 }