Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 150158
b: refs/heads/master
c: 5cff20e
h: refs/heads/master
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed May 6, 2009
1 parent 9e738ca commit b3c9b4f
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9955151df7c6452cae2ed9649f53d265c91cf155
refs/heads/master: 5cff20e6c5a6591a79d3b027af222870f52bb550
6 changes: 4 additions & 2 deletions trunk/drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,11 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
struct mac80211_hwsim_data *data = hw->priv;
struct ieee80211_conf *conf = &hw->conf;

printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d)\n",
printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d idle=%d ps=%d)\n",
wiphy_name(hw->wiphy), __func__,
conf->channel->center_freq, conf->radio_enabled);
conf->channel->center_freq, conf->radio_enabled,
!!(conf->flags & IEEE80211_CONF_IDLE),
!!(conf->flags & IEEE80211_CONF_PS));

data->channel = conf->channel;
data->radio_enabled = conf->radio_enabled;
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,10 +533,16 @@ struct ieee80211_rx_status {
*
* @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
* @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only)
* @IEEE80211_CONF_IDLE: The device is running, but idle; if the flag is set
* the driver should be prepared to handle configuration requests but
* may turn the device off as much as possible. Typically, this flag will
* be set when an interface is set UP but not associated or scanning, but
* it can also be unset in that case when monitor interfaces are active.
*/
enum ieee80211_conf_flags {
IEEE80211_CONF_RADIOTAP = (1<<0),
IEEE80211_CONF_PS = (1<<1),
IEEE80211_CONF_IDLE = (1<<2),
};


Expand All @@ -551,6 +557,7 @@ enum ieee80211_conf_flags {
* @IEEE80211_CONF_CHANGE_POWER: the TX power changed
* @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed
* @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
* @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
*/
enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),
Expand All @@ -561,6 +568,7 @@ enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_POWER = BIT(5),
IEEE80211_CONF_CHANGE_CHANNEL = BIT(6),
IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(7),
IEEE80211_CONF_CHANGE_IDLE = BIT(8),
};

static inline __deprecated enum ieee80211_conf_changed
Expand Down
5 changes: 5 additions & 0 deletions trunk/net/mac80211/ibss.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,6 +862,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,

sdata->u.ibss.ssid_len = params->ssid_len;

ieee80211_recalc_idle(sdata->local);

set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);

Expand Down Expand Up @@ -889,6 +891,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)

skb_queue_purge(&sdata->u.ibss.skb_queue);
memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
sdata->u.ibss.ssid_len = 0;

ieee80211_recalc_idle(sdata->local);

return 0;
}
2 changes: 2 additions & 0 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum nl80211_iftype type);
void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
void ieee80211_remove_interfaces(struct ieee80211_local *local);
u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
void ieee80211_recalc_idle(struct ieee80211_local *local);

/* tx handling */
void ieee80211_clear_tx_pending(struct ieee80211_local *local);
Expand Down
78 changes: 76 additions & 2 deletions trunk/net/mac80211/iface.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,8 @@ static int ieee80211_open(struct net_device *dev)
if (sdata->flags & IEEE80211_SDATA_PROMISC)
atomic_inc(&local->iff_promiscs);

hw_reconf_flags |= __ieee80211_recalc_idle(local);

local->open_count++;
if (hw_reconf_flags) {
ieee80211_hw_config(local, hw_reconf_flags);
Expand Down Expand Up @@ -548,6 +550,10 @@ static int ieee80211_stop(struct net_device *dev)

sdata->bss = NULL;

hw_reconf_flags |= __ieee80211_recalc_idle(local);

ieee80211_recalc_ps(local, -1);

if (local->open_count == 0) {
if (netif_running(local->mdev))
dev_close(local->mdev);
Expand All @@ -565,8 +571,6 @@ static int ieee80211_stop(struct net_device *dev)
hw_reconf_flags = 0;
}

ieee80211_recalc_ps(local, -1);

/* do after stop to avoid reconfiguring when we stop anyway */
if (hw_reconf_flags)
ieee80211_hw_config(local, hw_reconf_flags);
Expand Down Expand Up @@ -892,3 +896,73 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
unregister_netdevice(sdata->dev);
}
}

static u32 ieee80211_idle_off(struct ieee80211_local *local,
const char *reason)
{
if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
return 0;

#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: device no longer idle - %s\n",
wiphy_name(local->hw.wiphy), reason);
#endif

local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
return IEEE80211_CONF_CHANGE_IDLE;
}

static u32 ieee80211_idle_on(struct ieee80211_local *local)
{
if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
return 0;

#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: device now idle\n",
wiphy_name(local->hw.wiphy));
#endif

local->hw.conf.flags |= IEEE80211_CONF_IDLE;
return IEEE80211_CONF_CHANGE_IDLE;
}

u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata;
int count = 0;

if (local->hw_scanning || local->sw_scanning)
return ieee80211_idle_off(local, "scanning");

list_for_each_entry(sdata, &local->interfaces, list) {
if (!netif_running(sdata->dev))
continue;
/* do not count disabled managed interfaces */
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
sdata->u.mgd.state == IEEE80211_STA_MLME_DISABLED)
continue;
/* do not count unused IBSS interfaces */
if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
!sdata->u.ibss.ssid_len)
continue;
/* count everything else */
count++;
}

if (!count)
return ieee80211_idle_on(local);
else
return ieee80211_idle_off(local, "in use");

return 0;
}

void ieee80211_recalc_idle(struct ieee80211_local *local)
{
u32 chg;

mutex_lock(&local->iflist_mtx);
chg = __ieee80211_recalc_idle(local);
mutex_unlock(&local->iflist_mtx);
ieee80211_hw_config(local, chg);
}
11 changes: 11 additions & 0 deletions trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,7 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
sdata->dev->name, ifmgd->bssid);
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
ieee80211_recalc_idle(local);
cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);

/*
Expand Down Expand Up @@ -938,6 +939,7 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
" timed out\n",
sdata->dev->name, ifmgd->bssid);
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
ieee80211_recalc_idle(local);
cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
sdata->local->hw.conf.channel->center_freq,
Expand Down Expand Up @@ -1041,6 +1043,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,

rcu_read_unlock();

ieee80211_recalc_idle(local);

/* channel(_type) changes are handled by ieee80211_hw_config */
local->oper_channel_type = NL80211_CHAN_NO_HT;

Expand Down Expand Up @@ -1121,6 +1125,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
" timed out\n",
sdata->dev->name, ifmgd->bssid);
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
ieee80211_recalc_idle(local);
cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid);
ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
sdata->local->hw.conf.channel->center_freq,
Expand All @@ -1141,6 +1146,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
"mixed-cell disabled - abort association\n", sdata->dev->name);
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
ieee80211_recalc_idle(local);
return;
}

Expand Down Expand Up @@ -1279,6 +1285,7 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata)
if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
/* Wait for SME to request association */
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
ieee80211_recalc_idle(sdata->local);
} else
ieee80211_associate(sdata);
}
Expand Down Expand Up @@ -1515,6 +1522,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
/* Wait for SME to decide what to do next */
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
ieee80211_recalc_idle(local);
}
return;
}
Expand Down Expand Up @@ -2083,6 +2091,7 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
} else {
ifmgd->assoc_scan_tries = 0;
ifmgd->state = IEEE80211_STA_MLME_DISABLED;
ieee80211_recalc_idle(local);
}
}
return -1;
Expand Down Expand Up @@ -2126,6 +2135,8 @@ static void ieee80211_sta_work(struct work_struct *work)
} else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request))
return;

ieee80211_recalc_idle(local);

switch (ifmgd->state) {
case IEEE80211_STA_MLME_DISABLED:
break;
Expand Down
17 changes: 7 additions & 10 deletions trunk/net/mac80211/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,17 +302,9 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
/* we only have to protect scan_req and hw/sw scan */
mutex_unlock(&local->scan_mtx);

if (was_hw_scan) {
/*
* Somebody might have requested channel change during scan
* that we won't have acted upon, try now. ieee80211_hw_config
* will set the flag based on actual changes.
*/
ieee80211_hw_config(local, 0);
goto done;
}

ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
if (was_hw_scan)
goto done;

netif_tx_lock_bh(local->mdev);
netif_addr_lock(local->mdev);
Expand Down Expand Up @@ -351,6 +343,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
mutex_unlock(&local->iflist_mtx);

done:
ieee80211_recalc_idle(local);
ieee80211_mlme_notify_scan_completed(local);
ieee80211_ibss_notify_scan_completed(local);
ieee80211_mesh_notify_scan_completed(local);
Expand Down Expand Up @@ -471,6 +464,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
* dependency, so that the scan completed calls
* have more locking freedom.
*/

ieee80211_recalc_idle(local);
mutex_unlock(&local->scan_mtx);

if (local->ops->hw_scan)
Expand All @@ -487,6 +482,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
} else
local->sw_scanning = false;

ieee80211_recalc_idle(local);

local->scan_req = NULL;
local->scan_sdata = NULL;
}
Expand Down

0 comments on commit b3c9b4f

Please sign in to comment.