Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 78244
b: refs/heads/master
c: ece8edd
h: refs/heads/master
v: v3
  • Loading branch information
Zhu Yi authored and David S. Miller committed Jan 28, 2008
1 parent 4da5f43 commit 73725d3
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 36 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: f68635e627f9b21db05102e2d8fcd2894493d6bc
refs/heads/master: ece8edddf067d21c4e5abfe3f1205da1588edbb2
13 changes: 8 additions & 5 deletions trunk/net/mac80211/ieee80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,11 +350,14 @@ static int ieee80211_stop(struct net_device *dev)
synchronize_rcu();
skb_queue_purge(&sdata->u.sta.skb_queue);

if (!local->ops->hw_scan &&
local->scan_dev == sdata->dev) {
local->sta_scanning = 0;
cancel_delayed_work(&local->scan_work);
if (local->scan_dev == sdata->dev) {
if (!local->ops->hw_scan) {
local->sta_sw_scanning = 0;
cancel_delayed_work(&local->scan_work);
} else
local->sta_hw_scanning = 0;
}

flush_workqueue(local->hw.workqueue);

sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
Expand Down Expand Up @@ -526,7 +529,7 @@ int ieee80211_hw_config(struct ieee80211_local *local)
struct ieee80211_channel *chan;
int ret = 0;

if (local->sta_scanning) {
if (local->sta_sw_scanning) {
chan = local->scan_channel;
mode = local->scan_hw_mode;
} else {
Expand Down
6 changes: 4 additions & 2 deletions trunk/net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,8 @@ struct ieee80211_local {

struct list_head interfaces;

int sta_scanning;
bool sta_sw_scanning;
bool sta_hw_scanning;
int scan_channel_idx;
enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
unsigned long last_scan_completed;
Expand Down Expand Up @@ -745,7 +746,8 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
void ieee80211_sta_req_auth(struct net_device *dev,
struct ieee80211_if_sta *ifsta);
int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len);
void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
ieee80211_txrx_result ieee80211_sta_rx_scan(struct net_device *dev,
struct sk_buff *skb,
struct ieee80211_rx_status *rx_status);
void ieee80211_rx_bss_list_init(struct net_device *dev);
void ieee80211_rx_bss_list_deinit(struct net_device *dev);
Expand Down
6 changes: 4 additions & 2 deletions trunk/net/mac80211/ieee80211_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq)
}

if (set) {
if (local->sta_scanning)
if (local->sta_sw_scanning)
ret = 0;
else
ret = ieee80211_hw_config(local);
Expand Down Expand Up @@ -545,8 +545,10 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
{
int res;
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
if (local->sta_scanning)

if (local->sta_sw_scanning || local->sta_hw_scanning)
return -EAGAIN;

res = ieee80211_sta_scan_results(dev, extra, data->length);
if (res >= 0) {
data->length = res;
Expand Down
66 changes: 44 additions & 22 deletions trunk/net/mac80211/ieee80211_sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -1483,8 +1483,18 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
u32 supp_rates, prev_rates;
int i, j;

mode = local->sta_scanning ?
mode = local->sta_sw_scanning ?
local->scan_hw_mode : local->oper_hw_mode;

if (local->sta_hw_scanning) {
/* search for the correct mode matches the beacon */
list_for_each_entry(mode, &local->modes_list, list)
if (mode->mode == rx_status->phymode)
break;

if (mode == NULL)
mode = local->oper_hw_mode;
}
rates = mode->rates;
num_rates = mode->num_rates;

Expand Down Expand Up @@ -1867,31 +1877,39 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
}


void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status)
ieee80211_txrx_result
ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status)
{
struct ieee80211_mgmt *mgmt;
u16 fc;

if (skb->len < 24) {
dev_kfree_skb(skb);
return;
}
if (skb->len < 2)
return TXRX_DROP;

mgmt = (struct ieee80211_mgmt *) skb->data;
fc = le16_to_cpu(mgmt->frame_control);

if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
return TXRX_CONTINUE;

if (skb->len < 24)
return TXRX_DROP;

if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) {
ieee80211_rx_mgmt_probe_resp(dev, mgmt,
skb->len, rx_status);
dev_kfree_skb(skb);
return TXRX_QUEUED;
} else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) {
ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len,
rx_status);
dev_kfree_skb(skb);
return TXRX_QUEUED;
}
}

dev_kfree_skb(skb);
return TXRX_CONTINUE;
}


Expand Down Expand Up @@ -1981,7 +1999,7 @@ void ieee80211_sta_work(struct work_struct *work)
if (!netif_running(dev))
return;

if (local->sta_scanning)
if (local->sta_sw_scanning || local->sta_hw_scanning)
return;

if (sdata->type != IEEE80211_IF_TYPE_STA &&
Expand Down Expand Up @@ -2639,9 +2657,15 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
union iwreq_data wrqu;

local->last_scan_completed = jiffies;
wmb();
local->sta_scanning = 0;
memset(&wrqu, 0, sizeof(wrqu));
wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);

if (local->sta_hw_scanning) {
local->sta_hw_scanning = 0;
goto done;
}

local->sta_sw_scanning = 0;
if (ieee80211_hw_config(local))
printk(KERN_DEBUG "%s: failed to restore operational "
"channel after scan\n", dev->name);
Expand All @@ -2657,9 +2681,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)

netif_tx_unlock_bh(local->mdev);

memset(&wrqu, 0, sizeof(wrqu));
wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);

rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list) {

Expand All @@ -2677,6 +2698,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
}
rcu_read_unlock();

done:
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->type == IEEE80211_IF_TYPE_IBSS) {
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
Expand All @@ -2699,7 +2721,7 @@ void ieee80211_sta_scan_work(struct work_struct *work)
int skip;
unsigned long next_delay = 0;

if (!local->sta_scanning)
if (!local->sta_sw_scanning)
return;

switch (local->scan_state) {
Expand Down Expand Up @@ -2762,7 +2784,7 @@ void ieee80211_sta_scan_work(struct work_struct *work)
break;
}

if (local->sta_scanning)
if (local->sta_sw_scanning)
queue_delayed_work(local->hw.workqueue, &local->scan_work,
next_delay);
}
Expand Down Expand Up @@ -2794,23 +2816,23 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
* ResultCode: SUCCESS, INVALID_PARAMETERS
*/

if (local->sta_scanning) {
if (local->sta_sw_scanning || local->sta_hw_scanning) {
if (local->scan_dev == dev)
return 0;
return -EBUSY;
}

if (local->ops->hw_scan) {
int rc = local->ops->hw_scan(local_to_hw(local),
ssid, ssid_len);
ssid, ssid_len);
if (!rc) {
local->sta_scanning = 1;
local->sta_hw_scanning = 1;
local->scan_dev = dev;
}
return rc;
}

local->sta_scanning = 1;
local->sta_sw_scanning = 1;

rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
Expand Down Expand Up @@ -2865,7 +2887,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
if (sdata->type != IEEE80211_IF_TYPE_STA)
return ieee80211_sta_start_scan(dev, ssid, ssid_len);

if (local->sta_scanning) {
if (local->sta_sw_scanning || local->sta_hw_scanning) {
if (local->scan_dev == dev)
return 0;
return -EBUSY;
Expand Down
12 changes: 9 additions & 3 deletions trunk/net/mac80211/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,14 @@ ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx)
struct ieee80211_local *local = rx->local;
struct sk_buff *skb = rx->skb;

if (unlikely(local->sta_scanning != 0)) {
ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status);
if (unlikely(local->sta_hw_scanning))
return ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status);

if (unlikely(local->sta_sw_scanning)) {
/* drop all the other packets during a software scan anyway */
if (ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status)
!= TXRX_QUEUED)
dev_kfree_skb(skb);
return TXRX_QUEUED;
}

Expand Down Expand Up @@ -1499,7 +1505,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
goto end;
}

if (unlikely(local->sta_scanning))
if (unlikely(local->sta_sw_scanning || local->sta_hw_scanning))
rx.flags |= IEEE80211_TXRXD_RXIN_SCAN;

if (__ieee80211_invoke_rx_handlers(local, local->rx_pre_handlers, &rx,
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/mac80211/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
if (unlikely(tx->flags & IEEE80211_TXRXD_TX_INJECTED))
return TXRX_CONTINUE;

if (unlikely(tx->local->sta_scanning != 0) &&
if (unlikely(tx->local->sta_sw_scanning) &&
((tx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
(tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))
return TXRX_DROP;
Expand Down

0 comments on commit 73725d3

Please sign in to comment.