Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 150383
b: refs/heads/master
c: cc32abd
h: refs/heads/master
i:
  150381: c52e5b7
  150379: bc272c4
  150375: 08349cf
  150367: 5146a20
v: v3
  • Loading branch information
Johannes Berg authored and John W. Linville committed May 20, 2009
1 parent 985168f commit 7fdcba0
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 112 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: 9f26a952210e44691f784b77bf1f83a500d63f58
refs/heads/master: cc32abd494c0a8f76f2638e3f3a76e01c68bc9ea
11 changes: 3 additions & 8 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,9 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
int ieee80211_max_network_latency(struct notifier_block *nb,
unsigned long data, void *dummy);
void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel_sw_ie *sw_elem,
struct ieee80211_bss *bss);

/* IBSS code */
void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
Expand Down Expand Up @@ -1031,14 +1034,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
size_t len);
void ieee80211_chswitch_timer(unsigned long data);
void ieee80211_chswitch_work(struct work_struct *work);
void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel_sw_ie *sw_elem,
struct ieee80211_bss *bss);
void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
u16 capab_info, u8 *pwr_constr_elem,
u8 pwr_constr_elem_len);

/* Suspend/resume and hw reconfiguration */
int ieee80211_reconfig(struct ieee80211_local *local);
Expand Down
99 changes: 98 additions & 1 deletion trunk/net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,103 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
ieee80211_tx_skb(sdata, skb, 0);
}

/* spectrum management related things */
static void ieee80211_chswitch_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
struct ieee80211_bss *bss;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

if (!netif_running(sdata->dev))
return;

bss = ieee80211_rx_bss_get(sdata->local, ifmgd->bssid,
sdata->local->hw.conf.channel->center_freq,
ifmgd->ssid, ifmgd->ssid_len);
if (!bss)
goto exit;

sdata->local->oper_channel = sdata->local->csa_channel;
/* XXX: shouldn't really modify cfg80211-owned data! */
if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL))
bss->cbss.channel = sdata->local->oper_channel;

ieee80211_rx_bss_put(sdata->local, bss);
exit:
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
ieee80211_wake_queues_by_reason(&sdata->local->hw,
IEEE80211_QUEUE_STOP_REASON_CSA);
}

static void ieee80211_chswitch_timer(unsigned long data)
{
struct ieee80211_sub_if_data *sdata =
(struct ieee80211_sub_if_data *) data;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
}

void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel_sw_ie *sw_elem,
struct ieee80211_bss *bss)
{
struct ieee80211_channel *new_ch;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);

if (ifmgd->state != IEEE80211_STA_MLME_ASSOCIATED)
return;

if (sdata->local->sw_scanning || sdata->local->hw_scanning)
return;

/* Disregard subsequent beacons if we are already running a timer
processing a CSA */

if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
return;

new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
return;

sdata->local->csa_channel = new_ch;

if (sw_elem->count <= 1) {
queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
} else {
ieee80211_stop_queues_by_reason(&sdata->local->hw,
IEEE80211_QUEUE_STOP_REASON_CSA);
ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
mod_timer(&ifmgd->chswitch_timer,
jiffies +
msecs_to_jiffies(sw_elem->count *
bss->cbss.beacon_interval));
}
}

static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
u16 capab_info, u8 *pwr_constr_elem,
u8 pwr_constr_elem_len)
{
struct ieee80211_conf *conf = &sdata->local->hw.conf;

if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
return;

/* Power constraint IE length should be 1 octet */
if (pwr_constr_elem_len != 1)
return;

if ((*pwr_constr_elem <= conf->channel->max_power) &&
(*pwr_constr_elem != sdata->local->power_constr_level)) {
sdata->local->power_constr_level = *pwr_constr_elem;
ieee80211_hw_config(sdata->local, 0);
}
}

/* powersave */
static void ieee80211_enable_ps(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata)
Expand Down Expand Up @@ -1736,7 +1833,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
(memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN) == 0)) {
struct ieee80211_channel_sw_ie *sw_elem =
(struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
ieee80211_process_chanswitch(sdata, sw_elem, bss);
ieee80211_sta_process_chanswitch(sdata, sw_elem, bss);
}

ieee80211_rx_bss_put(local, bss);
Expand Down
5 changes: 4 additions & 1 deletion trunk/net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1846,6 +1846,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
sizeof(mgmt->u.action.u.chan_switch)))
return RX_DROP_MONITOR;

if (sdata->vif.type != NL80211_IFTYPE_STATION)
return RX_DROP_MONITOR;

if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN))
return RX_DROP_MONITOR;

Expand All @@ -1856,7 +1859,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
if (!bss)
return RX_DROP_MONITOR;

ieee80211_process_chanswitch(sdata,
ieee80211_sta_process_chanswitch(sdata,
&mgmt->u.action.u.chan_switch.sw_elem, bss);
ieee80211_rx_bss_put(local, bss);
break;
Expand Down
101 changes: 0 additions & 101 deletions trunk/net/mac80211/spectmgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,104 +84,3 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
mgmt->sa, mgmt->bssid,
mgmt->u.action.u.measurement.dialog_token);
}

void ieee80211_chswitch_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
struct ieee80211_bss *bss;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

if (!netif_running(sdata->dev))
return;

bss = ieee80211_rx_bss_get(sdata->local, ifmgd->bssid,
sdata->local->hw.conf.channel->center_freq,
ifmgd->ssid, ifmgd->ssid_len);
if (!bss)
goto exit;

sdata->local->oper_channel = sdata->local->csa_channel;
/* XXX: shouldn't really modify cfg80211-owned data! */
if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL))
bss->cbss.channel = sdata->local->oper_channel;

ieee80211_rx_bss_put(sdata->local, bss);
exit:
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
ieee80211_wake_queues_by_reason(&sdata->local->hw,
IEEE80211_QUEUE_STOP_REASON_CSA);
}

void ieee80211_chswitch_timer(unsigned long data)
{
struct ieee80211_sub_if_data *sdata =
(struct ieee80211_sub_if_data *) data;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
}

void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel_sw_ie *sw_elem,
struct ieee80211_bss *bss)
{
struct ieee80211_channel *new_ch;
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);

/* FIXME: Handle ADHOC later */
if (sdata->vif.type != NL80211_IFTYPE_STATION)
return;

if (ifmgd->state != IEEE80211_STA_MLME_ASSOCIATED)
return;

if (sdata->local->sw_scanning || sdata->local->hw_scanning)
return;

/* Disregard subsequent beacons if we are already running a timer
processing a CSA */

if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
return;

new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
return;

sdata->local->csa_channel = new_ch;

if (sw_elem->count <= 1) {
queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
} else {
ieee80211_stop_queues_by_reason(&sdata->local->hw,
IEEE80211_QUEUE_STOP_REASON_CSA);
ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
mod_timer(&ifmgd->chswitch_timer,
jiffies +
msecs_to_jiffies(sw_elem->count *
bss->cbss.beacon_interval));
}
}

void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
u16 capab_info, u8 *pwr_constr_elem,
u8 pwr_constr_elem_len)
{
struct ieee80211_conf *conf = &sdata->local->hw.conf;

if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
return;

/* Power constraint IE length should be 1 octet */
if (pwr_constr_elem_len != 1)
return;

if ((*pwr_constr_elem <= conf->channel->max_power) &&
(*pwr_constr_elem != sdata->local->power_constr_level)) {
sdata->local->power_constr_level = *pwr_constr_elem;
ieee80211_hw_config(sdata->local, 0);
}
}

0 comments on commit 7fdcba0

Please sign in to comment.