mac80211: refactor set_channel_type

Split functionality for further reuse.

Will prevent code duplication when channel context
channel_type merging is introduced.

Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Michal Kazior 2012-06-26 14:37:21 +02:00 committed by Johannes Berg
parent 964b19f977
commit 23a85b45cf
1 changed files with 48 additions and 19 deletions

View File

@ -68,16 +68,14 @@ ieee80211_get_channel_mode(struct ieee80211_local *local,
return mode; return mode;
} }
bool ieee80211_set_channel_type(struct ieee80211_local *local, static enum nl80211_channel_type
struct ieee80211_sub_if_data *sdata, ieee80211_get_superchan(struct ieee80211_local *local,
enum nl80211_channel_type chantype) struct ieee80211_sub_if_data *sdata)
{ {
struct ieee80211_sub_if_data *tmp;
enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT; enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT;
bool result; struct ieee80211_sub_if_data *tmp;
mutex_lock(&local->iflist_mtx); mutex_lock(&local->iflist_mtx);
list_for_each_entry(tmp, &local->interfaces, list) { list_for_each_entry(tmp, &local->interfaces, list) {
if (tmp == sdata) if (tmp == sdata)
continue; continue;
@ -103,39 +101,70 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
break; break;
} }
} }
mutex_unlock(&local->iflist_mtx);
switch (superchan) { return superchan;
}
static bool
ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1,
enum nl80211_channel_type chantype2,
enum nl80211_channel_type *compat)
{
/*
* start out with chantype1 being the result,
* overwriting later if needed
*/
if (compat)
*compat = chantype1;
switch (chantype1) {
case NL80211_CHAN_NO_HT: case NL80211_CHAN_NO_HT:
if (compat)
*compat = chantype2;
break;
case NL80211_CHAN_HT20: case NL80211_CHAN_HT20:
/* /*
* allow any change that doesn't go to no-HT * allow any change that doesn't go to no-HT
* (if it already is no-HT no change is needed) * (if it already is no-HT no change is needed)
*/ */
if (chantype == NL80211_CHAN_NO_HT) if (chantype2 == NL80211_CHAN_NO_HT)
break; break;
superchan = chantype; if (compat)
*compat = chantype2;
break; break;
case NL80211_CHAN_HT40PLUS: case NL80211_CHAN_HT40PLUS:
case NL80211_CHAN_HT40MINUS: case NL80211_CHAN_HT40MINUS:
/* allow smaller bandwidth and same */ /* allow smaller bandwidth and same */
if (chantype == NL80211_CHAN_NO_HT) if (chantype2 == NL80211_CHAN_NO_HT)
break; break;
if (chantype == NL80211_CHAN_HT20) if (chantype2 == NL80211_CHAN_HT20)
break; break;
if (superchan == chantype) if (chantype2 == chantype1)
break; break;
result = false; return false;
goto out;
} }
local->_oper_channel_type = superchan; return true;
}
bool ieee80211_set_channel_type(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
enum nl80211_channel_type chantype)
{
enum nl80211_channel_type superchan;
enum nl80211_channel_type compatchan;
superchan = ieee80211_get_superchan(local, sdata);
if (!ieee80211_channel_types_are_compatible(superchan, chantype,
&compatchan))
return false;
local->_oper_channel_type = compatchan;
if (sdata) if (sdata)
sdata->vif.bss_conf.channel_type = chantype; sdata->vif.bss_conf.channel_type = chantype;
result = true; return true;
out:
mutex_unlock(&local->iflist_mtx);
return result;
} }