Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Michal Kazior and committed by
Johannes Berg
23a85b45 964b19f9

+48 -19
+48 -19
net/mac80211/chan.c
··· 68 68 return mode; 69 69 } 70 70 71 - bool ieee80211_set_channel_type(struct ieee80211_local *local, 72 - struct ieee80211_sub_if_data *sdata, 73 - enum nl80211_channel_type chantype) 71 + static enum nl80211_channel_type 72 + ieee80211_get_superchan(struct ieee80211_local *local, 73 + struct ieee80211_sub_if_data *sdata) 74 74 { 75 - struct ieee80211_sub_if_data *tmp; 76 75 enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT; 77 - bool result; 76 + struct ieee80211_sub_if_data *tmp; 78 77 79 78 mutex_lock(&local->iflist_mtx); 80 - 81 79 list_for_each_entry(tmp, &local->interfaces, list) { 82 80 if (tmp == sdata) 83 81 continue; ··· 101 103 break; 102 104 } 103 105 } 106 + mutex_unlock(&local->iflist_mtx); 104 107 105 - switch (superchan) { 108 + return superchan; 109 + } 110 + 111 + static bool 112 + ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1, 113 + enum nl80211_channel_type chantype2, 114 + enum nl80211_channel_type *compat) 115 + { 116 + /* 117 + * start out with chantype1 being the result, 118 + * overwriting later if needed 119 + */ 120 + if (compat) 121 + *compat = chantype1; 122 + 123 + switch (chantype1) { 106 124 case NL80211_CHAN_NO_HT: 125 + if (compat) 126 + *compat = chantype2; 127 + break; 107 128 case NL80211_CHAN_HT20: 108 129 /* 109 130 * allow any change that doesn't go to no-HT 110 131 * (if it already is no-HT no change is needed) 111 132 */ 112 - if (chantype == NL80211_CHAN_NO_HT) 133 + if (chantype2 == NL80211_CHAN_NO_HT) 113 134 break; 114 - superchan = chantype; 135 + if (compat) 136 + *compat = chantype2; 115 137 break; 116 138 case NL80211_CHAN_HT40PLUS: 117 139 case NL80211_CHAN_HT40MINUS: 118 140 /* allow smaller bandwidth and same */ 119 - if (chantype == NL80211_CHAN_NO_HT) 141 + if (chantype2 == NL80211_CHAN_NO_HT) 120 142 break; 121 - if (chantype == NL80211_CHAN_HT20) 143 + if (chantype2 == NL80211_CHAN_HT20) 122 144 break; 123 - if (superchan == chantype) 145 + if (chantype2 == chantype1) 124 146 break; 125 - result = false; 126 - goto out; 147 + return false; 127 148 } 128 149 129 - local->_oper_channel_type = superchan; 150 + return true; 151 + } 152 + 153 + bool ieee80211_set_channel_type(struct ieee80211_local *local, 154 + struct ieee80211_sub_if_data *sdata, 155 + enum nl80211_channel_type chantype) 156 + { 157 + enum nl80211_channel_type superchan; 158 + enum nl80211_channel_type compatchan; 159 + 160 + superchan = ieee80211_get_superchan(local, sdata); 161 + if (!ieee80211_channel_types_are_compatible(superchan, chantype, 162 + &compatchan)) 163 + return false; 164 + 165 + local->_oper_channel_type = compatchan; 130 166 131 167 if (sdata) 132 168 sdata->vif.bss_conf.channel_type = chantype; 133 169 134 - result = true; 135 - out: 136 - mutex_unlock(&local->iflist_mtx); 170 + return true; 137 171 138 - return result; 139 172 }