mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/ath/ar9170/main.c
This commit is contained in:
commit
cc755896a4
63 changed files with 1363 additions and 1506 deletions
|
|
@ -23,7 +23,8 @@ mac80211-y := \
|
|||
key.o \
|
||||
util.o \
|
||||
wme.o \
|
||||
event.o
|
||||
event.o \
|
||||
chan.o
|
||||
|
||||
mac80211-$(CONFIG_MAC80211_LEDS) += led.o
|
||||
mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
|
||||
|
|
|
|||
|
|
@ -1162,15 +1162,39 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
|
|||
}
|
||||
|
||||
static int ieee80211_set_channel(struct wiphy *wiphy,
|
||||
struct net_device *netdev,
|
||||
struct ieee80211_channel *chan,
|
||||
enum nl80211_channel_type channel_type)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = NULL;
|
||||
|
||||
if (netdev)
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
|
||||
|
||||
switch (ieee80211_get_channel_mode(local, NULL)) {
|
||||
case CHAN_MODE_HOPPING:
|
||||
return -EBUSY;
|
||||
case CHAN_MODE_FIXED:
|
||||
if (local->oper_channel != chan)
|
||||
return -EBUSY;
|
||||
if (!sdata && local->_oper_channel_type == channel_type)
|
||||
return 0;
|
||||
break;
|
||||
case CHAN_MODE_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
|
||||
local->oper_channel = chan;
|
||||
local->oper_channel_type = channel_type;
|
||||
|
||||
return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
if (!ieee80211_set_channel_type(local, sdata, channel_type))
|
||||
return -EBUSY;
|
||||
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR)
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
@ -1214,6 +1238,20 @@ static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
|
|||
static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_assoc_request *req)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
|
||||
switch (ieee80211_get_channel_mode(local, sdata)) {
|
||||
case CHAN_MODE_HOPPING:
|
||||
return -EBUSY;
|
||||
case CHAN_MODE_FIXED:
|
||||
if (local->oper_channel == req->bss->channel)
|
||||
break;
|
||||
return -EBUSY;
|
||||
case CHAN_MODE_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
|
||||
return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
|
||||
}
|
||||
|
||||
|
|
@ -1236,8 +1274,22 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
|
|||
static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_ibss_params *params)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
|
||||
switch (ieee80211_get_channel_mode(local, sdata)) {
|
||||
case CHAN_MODE_HOPPING:
|
||||
return -EBUSY;
|
||||
case CHAN_MODE_FIXED:
|
||||
if (!params->channel_fixed)
|
||||
return -EBUSY;
|
||||
if (local->oper_channel == params->channel)
|
||||
break;
|
||||
return -EBUSY;
|
||||
case CHAN_MODE_UNDEFINED:
|
||||
break;
|
||||
}
|
||||
|
||||
return ieee80211_ibss_join(sdata, params);
|
||||
}
|
||||
|
||||
|
|
@ -1366,7 +1418,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
|
|||
* association, there's no need to send an action frame.
|
||||
*/
|
||||
if (!sdata->u.mgd.associated ||
|
||||
sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) {
|
||||
sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) {
|
||||
mutex_lock(&sdata->local->iflist_mtx);
|
||||
ieee80211_recalc_smps(sdata->local, sdata);
|
||||
mutex_unlock(&sdata->local->iflist_mtx);
|
||||
|
|
|
|||
127
net/mac80211/chan.c
Normal file
127
net/mac80211/chan.c
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* mac80211 - channel management
|
||||
*/
|
||||
|
||||
#include <linux/nl80211.h>
|
||||
#include "ieee80211_i.h"
|
||||
|
||||
enum ieee80211_chan_mode
|
||||
__ieee80211_get_channel_mode(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *ignore)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&local->iflist_mtx));
|
||||
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
if (sdata == ignore)
|
||||
continue;
|
||||
|
||||
if (!ieee80211_sdata_running(sdata))
|
||||
continue;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
|
||||
continue;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
|
||||
!sdata->u.mgd.associated)
|
||||
continue;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
|
||||
if (!sdata->u.ibss.ssid_len)
|
||||
continue;
|
||||
if (!sdata->u.ibss.fixed_channel)
|
||||
return CHAN_MODE_HOPPING;
|
||||
}
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP &&
|
||||
!sdata->u.ap.beacon)
|
||||
continue;
|
||||
|
||||
return CHAN_MODE_FIXED;
|
||||
}
|
||||
|
||||
return CHAN_MODE_UNDEFINED;
|
||||
}
|
||||
|
||||
enum ieee80211_chan_mode
|
||||
ieee80211_get_channel_mode(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *ignore)
|
||||
{
|
||||
enum ieee80211_chan_mode mode;
|
||||
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
mode = __ieee80211_get_channel_mode(local, ignore);
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
bool ieee80211_set_channel_type(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
enum nl80211_channel_type chantype)
|
||||
{
|
||||
struct ieee80211_sub_if_data *tmp;
|
||||
enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT;
|
||||
bool result;
|
||||
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
|
||||
list_for_each_entry(tmp, &local->interfaces, list) {
|
||||
if (tmp == sdata)
|
||||
continue;
|
||||
|
||||
if (!ieee80211_sdata_running(tmp))
|
||||
continue;
|
||||
|
||||
switch (tmp->vif.bss_conf.channel_type) {
|
||||
case NL80211_CHAN_NO_HT:
|
||||
case NL80211_CHAN_HT20:
|
||||
superchan = tmp->vif.bss_conf.channel_type;
|
||||
break;
|
||||
case NL80211_CHAN_HT40PLUS:
|
||||
WARN_ON(superchan == NL80211_CHAN_HT40MINUS);
|
||||
superchan = NL80211_CHAN_HT40PLUS;
|
||||
break;
|
||||
case NL80211_CHAN_HT40MINUS:
|
||||
WARN_ON(superchan == NL80211_CHAN_HT40PLUS);
|
||||
superchan = NL80211_CHAN_HT40MINUS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (superchan) {
|
||||
case NL80211_CHAN_NO_HT:
|
||||
case NL80211_CHAN_HT20:
|
||||
/*
|
||||
* allow any change that doesn't go to no-HT
|
||||
* (if it already is no-HT no change is needed)
|
||||
*/
|
||||
if (chantype == NL80211_CHAN_NO_HT)
|
||||
break;
|
||||
superchan = chantype;
|
||||
break;
|
||||
case NL80211_CHAN_HT40PLUS:
|
||||
case NL80211_CHAN_HT40MINUS:
|
||||
/* allow smaller bandwidth and same */
|
||||
if (chantype == NL80211_CHAN_NO_HT)
|
||||
break;
|
||||
if (chantype == NL80211_CHAN_HT20)
|
||||
break;
|
||||
if (superchan == chantype)
|
||||
break;
|
||||
result = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
local->_oper_channel_type = superchan;
|
||||
|
||||
if (sdata)
|
||||
sdata->vif.bss_conf.channel_type = chantype;
|
||||
|
||||
result = true;
|
||||
out:
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
|
||||
|
||||
local->oper_channel = chan;
|
||||
local->oper_channel_type = NL80211_CHAN_NO_HT;
|
||||
WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
|
||||
|
||||
sband = local->hw.wiphy->bands[chan->band];
|
||||
|
|
@ -911,7 +911,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
|
|||
/* fix ourselves to that channel now already */
|
||||
if (params->channel_fixed) {
|
||||
sdata->local->oper_channel = params->channel;
|
||||
sdata->local->oper_channel_type = NL80211_CHAN_NO_HT;
|
||||
WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata,
|
||||
NL80211_CHAN_NO_HT));
|
||||
}
|
||||
|
||||
if (params->ie) {
|
||||
|
|
|
|||
|
|
@ -767,7 +767,7 @@ struct ieee80211_local {
|
|||
enum mac80211_scan_state next_scan_state;
|
||||
struct delayed_work scan_work;
|
||||
struct ieee80211_sub_if_data *scan_sdata;
|
||||
enum nl80211_channel_type oper_channel_type;
|
||||
enum nl80211_channel_type _oper_channel_type;
|
||||
struct ieee80211_channel *oper_channel, *csa_channel;
|
||||
|
||||
/* Temporary remain-on-channel for off-channel operations */
|
||||
|
|
@ -1228,6 +1228,20 @@ int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
|
|||
int ieee80211_wk_cancel_remain_on_channel(
|
||||
struct ieee80211_sub_if_data *sdata, u64 cookie);
|
||||
|
||||
/* channel management */
|
||||
enum ieee80211_chan_mode {
|
||||
CHAN_MODE_UNDEFINED,
|
||||
CHAN_MODE_HOPPING,
|
||||
CHAN_MODE_FIXED,
|
||||
};
|
||||
|
||||
enum ieee80211_chan_mode
|
||||
ieee80211_get_channel_mode(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *ignore);
|
||||
bool ieee80211_set_channel_type(struct ieee80211_local *local,
|
||||
struct ieee80211_sub_if_data *sdata,
|
||||
enum nl80211_channel_type chantype);
|
||||
|
||||
#ifdef CONFIG_MAC80211_NOINLINE
|
||||
#define debug_noinline noinline
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
|
|||
channel_type = local->tmp_channel_type;
|
||||
} else {
|
||||
chan = local->oper_channel;
|
||||
channel_type = local->oper_channel_type;
|
||||
channel_type = local->_oper_channel_type;
|
||||
}
|
||||
|
||||
if (chan != local->hw.conf.channel ||
|
||||
|
|
|
|||
|
|
@ -137,11 +137,14 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
|
|||
struct sta_info *sta;
|
||||
u32 changed = 0;
|
||||
u16 ht_opmode;
|
||||
bool enable_ht = true, ht_changed;
|
||||
bool enable_ht = true;
|
||||
enum nl80211_channel_type prev_chantype;
|
||||
enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
|
||||
|
||||
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
||||
|
||||
prev_chantype = sdata->vif.bss_conf.channel_type;
|
||||
|
||||
/* HT is not supported */
|
||||
if (!sband->ht_cap.ht_supported)
|
||||
enable_ht = false;
|
||||
|
|
@ -172,38 +175,37 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
}
|
||||
|
||||
ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
|
||||
channel_type != local->hw.conf.channel_type;
|
||||
|
||||
if (local->tmp_channel)
|
||||
local->tmp_channel_type = channel_type;
|
||||
local->oper_channel_type = channel_type;
|
||||
|
||||
if (ht_changed) {
|
||||
/* channel_type change automatically detected */
|
||||
ieee80211_hw_config(local, 0);
|
||||
if (!ieee80211_set_channel_type(local, sdata, channel_type)) {
|
||||
/* can only fail due to HT40+/- mismatch */
|
||||
channel_type = NL80211_CHAN_HT20;
|
||||
WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type));
|
||||
}
|
||||
|
||||
/* channel_type change automatically detected */
|
||||
ieee80211_hw_config(local, 0);
|
||||
|
||||
if (prev_chantype != channel_type) {
|
||||
rcu_read_lock();
|
||||
sta = sta_info_get(sdata, bssid);
|
||||
if (sta)
|
||||
rate_control_rate_update(local, sband, sta,
|
||||
IEEE80211_RC_HT_CHANGED,
|
||||
local->oper_channel_type);
|
||||
channel_type);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/* disable HT */
|
||||
if (!enable_ht)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ht_opmode = le16_to_cpu(hti->operation_mode);
|
||||
|
||||
/* if bss configuration changed store the new one */
|
||||
if (!sdata->ht_opmode_valid ||
|
||||
sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
|
||||
if (sdata->ht_opmode_valid != enable_ht ||
|
||||
sdata->vif.bss_conf.ht_operation_mode != ht_opmode ||
|
||||
prev_chantype != channel_type) {
|
||||
changed |= BSS_CHANGED_HT;
|
||||
sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
|
||||
sdata->ht_opmode_valid = true;
|
||||
sdata->ht_opmode_valid = enable_ht;
|
||||
}
|
||||
|
||||
return changed;
|
||||
|
|
@ -866,7 +868,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_set_wmm_default(sdata);
|
||||
|
||||
/* channel(_type) changes are handled by ieee80211_hw_config */
|
||||
local->oper_channel_type = NL80211_CHAN_NO_HT;
|
||||
WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT));
|
||||
|
||||
/* on the next assoc, re-program HT parameters */
|
||||
sdata->ht_opmode_valid = false;
|
||||
|
|
@ -883,8 +885,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
ieee80211_hw_config(local, config_changed);
|
||||
|
||||
/* And the BSSID changed -- not very interesting here */
|
||||
changed |= BSS_CHANGED_BSSID;
|
||||
/* The BSSID (not really interesting) and HT changed */
|
||||
changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
|
||||
if (remove_sta)
|
||||
|
|
@ -2266,7 +2268,7 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata,
|
|||
if ((chan != local->tmp_channel ||
|
||||
channel_type != local->tmp_channel_type) &&
|
||||
(chan != local->oper_channel ||
|
||||
channel_type != local->oper_channel_type))
|
||||
channel_type != local->_oper_channel_type))
|
||||
return -EBUSY;
|
||||
|
||||
skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
|
||||
|
|
|
|||
|
|
@ -2251,8 +2251,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
|
|||
|
||||
info->control.vif = vif;
|
||||
|
||||
info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
|
||||
info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
|
||||
info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT |
|
||||
IEEE80211_TX_CTL_ASSIGN_SEQ |
|
||||
IEEE80211_TX_CTL_FIRST_FRAGMENT;
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
return skb;
|
||||
|
|
|
|||
|
|
@ -1160,18 +1160,33 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
|||
|
||||
/* Finally also reconfigure all the BSS information */
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
u32 changed = ~0;
|
||||
u32 changed;
|
||||
|
||||
if (!ieee80211_sdata_running(sdata))
|
||||
continue;
|
||||
|
||||
/* common change flags for all interface types */
|
||||
changed = BSS_CHANGED_ERP_CTS_PROT |
|
||||
BSS_CHANGED_ERP_PREAMBLE |
|
||||
BSS_CHANGED_ERP_SLOT |
|
||||
BSS_CHANGED_HT |
|
||||
BSS_CHANGED_BASIC_RATES |
|
||||
BSS_CHANGED_BEACON_INT |
|
||||
BSS_CHANGED_BSSID |
|
||||
BSS_CHANGED_CQM;
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
/* disable beacon change bits */
|
||||
changed &= ~(BSS_CHANGED_BEACON |
|
||||
BSS_CHANGED_BEACON_ENABLED);
|
||||
/* fall through */
|
||||
changed |= BSS_CHANGED_ASSOC;
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
changed |= BSS_CHANGED_IBSS;
|
||||
/* fall through */
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
changed |= BSS_CHANGED_BEACON |
|
||||
BSS_CHANGED_BEACON_ENABLED;
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
break;
|
||||
case NL80211_IFTYPE_WDS:
|
||||
|
|
|
|||
Loading…
Reference in a new issue