~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/wireless/of.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (C) 2017 Rafał Miłecki <rafal@milecki.pl>
  3  *
  4  * Permission to use, copy, modify, and/or distribute this software for any
  5  * purpose with or without fee is hereby granted, provided that the above
  6  * copyright notice and this permission notice appear in all copies.
  7  *
  8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15  */
 16 
 17 #include <linux/of.h>
 18 #include <net/cfg80211.h>
 19 #include "core.h"
 20 
 21 static bool wiphy_freq_limits_valid_chan(struct wiphy *wiphy,
 22                                          struct ieee80211_freq_range *freq_limits,
 23                                          unsigned int n_freq_limits,
 24                                          struct ieee80211_channel *chan)
 25 {
 26         u32 bw = MHZ_TO_KHZ(20);
 27         int i;
 28 
 29         for (i = 0; i < n_freq_limits; i++) {
 30                 struct ieee80211_freq_range *limit = &freq_limits[i];
 31 
 32                 if (cfg80211_does_bw_fit_range(limit,
 33                                                MHZ_TO_KHZ(chan->center_freq),
 34                                                bw))
 35                         return true;
 36         }
 37 
 38         return false;
 39 }
 40 
 41 static void wiphy_freq_limits_apply(struct wiphy *wiphy,
 42                                     struct ieee80211_freq_range *freq_limits,
 43                                     unsigned int n_freq_limits)
 44 {
 45         enum nl80211_band band;
 46         int i;
 47 
 48         if (WARN_ON(!n_freq_limits))
 49                 return;
 50 
 51         for (band = 0; band < NUM_NL80211_BANDS; band++) {
 52                 struct ieee80211_supported_band *sband = wiphy->bands[band];
 53 
 54                 if (!sband)
 55                         continue;
 56 
 57                 for (i = 0; i < sband->n_channels; i++) {
 58                         struct ieee80211_channel *chan = &sband->channels[i];
 59 
 60                         if (chan->flags & IEEE80211_CHAN_DISABLED)
 61                                 continue;
 62 
 63                         if (!wiphy_freq_limits_valid_chan(wiphy, freq_limits,
 64                                                           n_freq_limits,
 65                                                           chan)) {
 66                                 pr_debug("Disabling freq %d MHz as it's out of OF limits\n",
 67                                          chan->center_freq);
 68                                 chan->flags |= IEEE80211_CHAN_DISABLED;
 69                         }
 70                 }
 71         }
 72 }
 73 
 74 void wiphy_read_of_freq_limits(struct wiphy *wiphy)
 75 {
 76         struct device *dev = wiphy_dev(wiphy);
 77         struct device_node *np;
 78         struct property *prop;
 79         struct ieee80211_freq_range *freq_limits;
 80         unsigned int n_freq_limits;
 81         const __be32 *p;
 82         int len, i;
 83         int err = 0;
 84 
 85         if (!dev)
 86                 return;
 87         np = dev_of_node(dev);
 88         if (!np)
 89                 return;
 90 
 91         prop = of_find_property(np, "ieee80211-freq-limit", &len);
 92         if (!prop)
 93                 return;
 94 
 95         if (!len || len % sizeof(u32) || len / sizeof(u32) % 2) {
 96                 dev_err(dev, "ieee80211-freq-limit wrong format");
 97                 return;
 98         }
 99         n_freq_limits = len / sizeof(u32) / 2;
100 
101         freq_limits = kcalloc(n_freq_limits, sizeof(*freq_limits), GFP_KERNEL);
102         if (!freq_limits) {
103                 err = -ENOMEM;
104                 goto out_kfree;
105         }
106 
107         p = NULL;
108         for (i = 0; i < n_freq_limits; i++) {
109                 struct ieee80211_freq_range *limit = &freq_limits[i];
110 
111                 p = of_prop_next_u32(prop, p, &limit->start_freq_khz);
112                 if (!p) {
113                         err = -EINVAL;
114                         goto out_kfree;
115                 }
116 
117                 p = of_prop_next_u32(prop, p, &limit->end_freq_khz);
118                 if (!p) {
119                         err = -EINVAL;
120                         goto out_kfree;
121                 }
122 
123                 if (!limit->start_freq_khz ||
124                     !limit->end_freq_khz ||
125                     limit->start_freq_khz >= limit->end_freq_khz) {
126                         err = -EINVAL;
127                         goto out_kfree;
128                 }
129         }
130 
131         wiphy_freq_limits_apply(wiphy, freq_limits, n_freq_limits);
132 
133 out_kfree:
134         kfree(freq_limits);
135         if (err)
136                 dev_err(dev, "Failed to get limits: %d\n", err);
137 }
138 EXPORT_SYMBOL(wiphy_read_of_freq_limits);
139 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php