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


ros_rt_wmp
Author(s): Danilo Tardioli, dantard@unizar.es
autogenerated on Mon Oct 6 2014 08:27:09