chan.c
Go to the documentation of this file.
00001 /*
00002  * mac80211 - channel management
00003  */
00004 
00005 #include <linux/nl80211.h>
00006 #include "ieee80211_i.h"
00007 
00008 static enum ieee80211_chan_mode
00009 __ieee80211_get_channel_mode(struct ieee80211_local *local,
00010                              struct ieee80211_sub_if_data *ignore)
00011 {
00012         struct ieee80211_sub_if_data *sdata;
00013 
00014         lockdep_assert_held(&local->iflist_mtx);
00015 
00016         list_for_each_entry(sdata, &local->interfaces, list) {
00017                 if (sdata == ignore)
00018                         continue;
00019 
00020                 if (!ieee80211_sdata_running(sdata))
00021                         continue;
00022 
00023                 if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
00024                         continue;
00025 
00026                 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
00027                     !sdata->u.mgd.associated)
00028                         continue;
00029 
00030                 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
00031                         if (!sdata->u.ibss.ssid_len)
00032                                 continue;
00033                         if (!sdata->u.ibss.fixed_channel)
00034                                 return CHAN_MODE_HOPPING;
00035                 }
00036 
00037                 if (sdata->vif.type == NL80211_IFTYPE_AP &&
00038                     !sdata->u.ap.beacon)
00039                         continue;
00040 
00041                 return CHAN_MODE_FIXED;
00042         }
00043 
00044         return CHAN_MODE_UNDEFINED;
00045 }
00046 
00047 enum ieee80211_chan_mode
00048 ieee80211_get_channel_mode(struct ieee80211_local *local,
00049                            struct ieee80211_sub_if_data *ignore)
00050 {
00051         enum ieee80211_chan_mode mode;
00052 
00053         mutex_lock(&local->iflist_mtx);
00054         mode = __ieee80211_get_channel_mode(local, ignore);
00055         mutex_unlock(&local->iflist_mtx);
00056 
00057         return mode;
00058 }
00059 
00060 bool ieee80211_set_channel_type(struct ieee80211_local *local,
00061                                 struct ieee80211_sub_if_data *sdata,
00062                                 enum nl80211_channel_type chantype)
00063 {
00064         struct ieee80211_sub_if_data *tmp;
00065         enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT;
00066         bool result;
00067 
00068         mutex_lock(&local->iflist_mtx);
00069 
00070         list_for_each_entry(tmp, &local->interfaces, list) {
00071                 if (tmp == sdata)
00072                         continue;
00073 
00074                 if (!ieee80211_sdata_running(tmp))
00075                         continue;
00076 
00077                 switch (tmp->vif.bss_conf.channel_type) {
00078                 case NL80211_CHAN_NO_HT:
00079                 case NL80211_CHAN_HT20:
00080                         if (superchan > tmp->vif.bss_conf.channel_type)
00081                                 break;
00082 
00083                         superchan = tmp->vif.bss_conf.channel_type;
00084                         break;
00085                 case NL80211_CHAN_HT40PLUS:
00086                         WARN_ON(superchan == NL80211_CHAN_HT40MINUS);
00087                         superchan = NL80211_CHAN_HT40PLUS;
00088                         break;
00089                 case NL80211_CHAN_HT40MINUS:
00090                         WARN_ON(superchan == NL80211_CHAN_HT40PLUS);
00091                         superchan = NL80211_CHAN_HT40MINUS;
00092                         break;
00093                 }
00094         }
00095 
00096         switch (superchan) {
00097         case NL80211_CHAN_NO_HT:
00098         case NL80211_CHAN_HT20:
00099                 /*
00100                  * allow any change that doesn't go to no-HT
00101                  * (if it already is no-HT no change is needed)
00102                  */
00103                 if (chantype == NL80211_CHAN_NO_HT)
00104                         break;
00105                 superchan = chantype;
00106                 break;
00107         case NL80211_CHAN_HT40PLUS:
00108         case NL80211_CHAN_HT40MINUS:
00109                 /* allow smaller bandwidth and same */
00110                 if (chantype == NL80211_CHAN_NO_HT)
00111                         break;
00112                 if (chantype == NL80211_CHAN_HT20)
00113                         break;
00114                 if (superchan == chantype)
00115                         break;
00116                 result = false;
00117                 goto out;
00118         }
00119 
00120         local->_oper_channel_type = superchan;
00121 
00122         if (sdata)
00123                 sdata->vif.bss_conf.channel_type = chantype;
00124 
00125         result = true;
00126  out:
00127         mutex_unlock(&local->iflist_mtx);
00128 
00129         return result;
00130 }


ros_rt_wmp
Author(s): Danilo Tardioli, dantard@unizar.es
autogenerated on Fri Jan 3 2014 12:07:54