Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
694c6186
Commit
694c6186
authored
Jan 03, 2013
by
Johannes Berg
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'mac80211/master' into HEAD
parents
a49f0d1e
09b1426e
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
202 additions
and
91 deletions
+202
-91
net/mac80211/cfg.c
net/mac80211/cfg.c
+2
-0
net/mac80211/chan.c
net/mac80211/chan.c
+38
-0
net/mac80211/ibss.c
net/mac80211/ibss.c
+4
-5
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+9
-7
net/mac80211/iface.c
net/mac80211/iface.c
+23
-25
net/mac80211/mesh.c
net/mac80211/mesh.c
+4
-4
net/mac80211/mesh.h
net/mac80211/mesh.h
+1
-1
net/mac80211/mlme.c
net/mac80211/mlme.c
+54
-21
net/mac80211/scan.c
net/mac80211/scan.c
+24
-22
net/mac80211/sta_info.c
net/mac80211/sta_info.c
+41
-5
net/mac80211/sta_info.h
net/mac80211/sta_info.h
+2
-1
No files found.
net/mac80211/cfg.c
View file @
694c6186
...
...
@@ -1009,6 +1009,8 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
if
(
old_probe_resp
)
kfree_rcu
(
old_probe_resp
,
rcu_head
);
list_for_each_entry
(
vlan
,
&
sdata
->
u
.
ap
.
vlans
,
u
.
vlan
.
list
)
sta_info_flush
(
local
,
vlan
);
sta_info_flush
(
local
,
sdata
);
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BEACON_ENABLED
);
...
...
net/mac80211/chan.c
View file @
694c6186
...
...
@@ -4,6 +4,7 @@
#include <linux/nl80211.h>
#include <linux/export.h>
#include <linux/rtnetlink.h>
#include <net/cfg80211.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
...
...
@@ -197,6 +198,15 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
ctx
=
container_of
(
conf
,
struct
ieee80211_chanctx
,
conf
);
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
{
struct
ieee80211_sub_if_data
*
vlan
;
/* for the VLAN list */
ASSERT_RTNL
();
list_for_each_entry
(
vlan
,
&
sdata
->
u
.
ap
.
vlans
,
u
.
vlan
.
list
)
rcu_assign_pointer
(
vlan
->
vif
.
chanctx_conf
,
NULL
);
}
ieee80211_unassign_vif_chanctx
(
sdata
,
ctx
);
if
(
ctx
->
refcount
==
0
)
ieee80211_free_chanctx
(
local
,
ctx
);
...
...
@@ -316,6 +326,15 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
goto
out
;
}
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
{
struct
ieee80211_sub_if_data
*
vlan
;
/* for the VLAN list */
ASSERT_RTNL
();
list_for_each_entry
(
vlan
,
&
sdata
->
u
.
ap
.
vlans
,
u
.
vlan
.
list
)
rcu_assign_pointer
(
vlan
->
vif
.
chanctx_conf
,
&
ctx
->
conf
);
}
ieee80211_recalc_smps_chanctx
(
local
,
ctx
);
out:
mutex_unlock
(
&
local
->
chanctx_mtx
);
...
...
@@ -331,6 +350,25 @@ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
mutex_unlock
(
&
sdata
->
local
->
chanctx_mtx
);
}
void
ieee80211_vif_vlan_copy_chanctx
(
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_sub_if_data
*
ap
;
struct
ieee80211_chanctx_conf
*
conf
;
if
(
WARN_ON
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_AP_VLAN
||
!
sdata
->
bss
))
return
;
ap
=
container_of
(
sdata
->
bss
,
struct
ieee80211_sub_if_data
,
u
.
ap
);
mutex_lock
(
&
local
->
chanctx_mtx
);
conf
=
rcu_dereference_protected
(
ap
->
vif
.
chanctx_conf
,
lockdep_is_held
(
&
local
->
chanctx_mtx
));
rcu_assign_pointer
(
sdata
->
vif
.
chanctx_conf
,
conf
);
mutex_unlock
(
&
local
->
chanctx_mtx
);
}
void
ieee80211_iter_chan_contexts_atomic
(
struct
ieee80211_hw
*
hw
,
void
(
*
iter
)(
struct
ieee80211_hw
*
hw
,
...
...
net/mac80211/ibss.c
View file @
694c6186
...
...
@@ -703,8 +703,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
sdata_info
(
sdata
,
"No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)
\n
"
);
ieee80211_request_i
nternal_scan
(
sdata
,
ifibss
->
ssid
,
ifibss
->
ssid_len
,
NULL
);
ieee80211_request_i
bss_scan
(
sdata
,
ifibss
->
ssid
,
ifibss
->
ssid_len
,
NULL
);
}
static
void
ieee80211_sta_create_ibss
(
struct
ieee80211_sub_if_data
*
sdata
)
...
...
@@ -802,9 +802,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
IEEE80211_SCAN_INTERVAL
))
{
sdata_info
(
sdata
,
"Trigger new scan to find an IBSS to join
\n
"
);
ieee80211_request_internal_scan
(
sdata
,
ifibss
->
ssid
,
ifibss
->
ssid_len
,
ifibss
->
fixed_channel
?
ifibss
->
channel
:
NULL
);
ieee80211_request_ibss_scan
(
sdata
,
ifibss
->
ssid
,
ifibss
->
ssid_len
,
chan
);
}
else
{
int
interval
=
IEEE80211_SCAN_INTERVAL
;
...
...
net/mac80211/ieee80211_i.h
View file @
694c6186
...
...
@@ -92,8 +92,6 @@ struct ieee80211_bss {
u32
device_ts
;
u8
dtim_period
;
bool
wmm_used
;
bool
uapsd_supported
;
...
...
@@ -140,7 +138,6 @@ enum ieee80211_bss_corrupt_data_flags {
/**
* enum ieee80211_valid_data_flags - BSS valid data flags
* @IEEE80211_BSS_VALID_DTIM: DTIM data was gathered from non-corrupt IE
* @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE
* @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE
* @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE
...
...
@@ -151,7 +148,6 @@ enum ieee80211_bss_corrupt_data_flags {
* beacon/probe response.
*/
enum
ieee80211_bss_valid_data_flags
{
IEEE80211_BSS_VALID_DTIM
=
BIT
(
0
),
IEEE80211_BSS_VALID_WMM
=
BIT
(
1
),
IEEE80211_BSS_VALID_RATES
=
BIT
(
2
),
IEEE80211_BSS_VALID_ERP
=
BIT
(
3
)
...
...
@@ -440,6 +436,7 @@ struct ieee80211_if_managed {
unsigned
long
timers_running
;
/* used for quiesce/restart */
bool
powersave
;
/* powersave requested for this iface */
bool
broken_ap
;
/* AP is broken -- turn off powersave */
u8
dtim_period
;
enum
ieee80211_smps_mode
req_smps
,
/* requested smps mode */
driver_smps_mode
;
/* smps mode request */
...
...
@@ -773,6 +770,10 @@ struct ieee80211_sub_if_data {
u32
mntr_flags
;
}
u
;
spinlock_t
cleanup_stations_lock
;
struct
list_head
cleanup_stations
;
struct
work_struct
cleanup_stations_wk
;
#ifdef CONFIG_MAC80211_DEBUGFS
struct
{
struct
dentry
*
dir
;
...
...
@@ -1329,9 +1330,9 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
/* scan/BSS handling */
void
ieee80211_scan_work
(
struct
work_struct
*
work
);
int
ieee80211_request_i
nternal
_scan
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
ssid
,
u8
ssid_len
,
struct
ieee80211_channel
*
chan
);
int
ieee80211_request_i
bss
_scan
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
ssid
,
u8
ssid_len
,
struct
ieee80211_channel
*
chan
);
int
ieee80211_request_scan
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
cfg80211_scan_request
*
req
);
void
ieee80211_scan_cancel
(
struct
ieee80211_local
*
local
);
...
...
@@ -1628,6 +1629,7 @@ ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
const
struct
cfg80211_chan_def
*
chandef
,
enum
ieee80211_chanctx_mode
mode
);
void
ieee80211_vif_release_channel
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211_vif_vlan_copy_chanctx
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211_recalc_smps_chanctx
(
struct
ieee80211_local
*
local
,
struct
ieee80211_chanctx
*
chanctx
);
...
...
net/mac80211/iface.c
View file @
694c6186
...
...
@@ -207,17 +207,8 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
static
int
ieee80211_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
int
meshhdrlen
;
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
meshhdrlen
=
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_MESH_POINT
)
?
5
:
0
;
/* FIX: what would be proper limits for MTU?
* This interface uses 802.3 frames. */
if
(
new_mtu
<
256
||
new_mtu
>
IEEE80211_MAX_DATA_LEN
-
24
-
6
-
meshhdrlen
)
{
if
(
new_mtu
<
256
||
new_mtu
>
IEEE80211_MAX_DATA_LEN
)
return
-
EINVAL
;
}
dev
->
mtu
=
new_mtu
;
return
0
;
...
...
@@ -586,11 +577,13 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
switch
(
sdata
->
vif
.
type
)
{
case
NL80211_IFTYPE_AP_VLAN
:
/* no need to tell driver, but set carrier */
if
(
rtnl_dereference
(
sdata
->
bss
->
beacon
))
/* no need to tell driver, but set carrier and chanctx */
if
(
rtnl_dereference
(
sdata
->
bss
->
beacon
))
{
ieee80211_vif_vlan_copy_chanctx
(
sdata
);
netif_carrier_on
(
dev
);
else
}
else
{
netif_carrier_off
(
dev
);
}
break
;
case
NL80211_IFTYPE_MONITOR
:
if
(
sdata
->
u
.
mntr_flags
&
MONITOR_FLAG_COOK_FRAMES
)
{
...
...
@@ -839,6 +832,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
switch
(
sdata
->
vif
.
type
)
{
case
NL80211_IFTYPE_AP_VLAN
:
list_del
(
&
sdata
->
u
.
vlan
.
list
);
rcu_assign_pointer
(
sdata
->
vif
.
chanctx_conf
,
NULL
);
/* no need to tell driver */
break
;
case
NL80211_IFTYPE_MONITOR
:
...
...
@@ -865,20 +859,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
cancel_work_sync
(
&
sdata
->
work
);
/*
* When we get here, the interface is marked down.
* Call
rcu_barrier() to wait both
for the RX path
* Call
synchronize_rcu() to wait
for the RX path
* should it be using the interface and enqueuing
* frames at this very time on another CPU, and
* for the sta free call_rcu callbacks.
*/
rcu_barrier
();
/*
* free_sta_rcu() enqueues a work for the actual
* sta cleanup, so we need to flush it while
* sdata is still valid.
* frames at this very time on another CPU.
*/
flush_workqueue
(
local
->
workqueue
);
synchronize_rcu
();
skb_queue_purge
(
&
sdata
->
skb_queue
);
/*
...
...
@@ -1498,6 +1483,15 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
mutex_unlock
(
&
local
->
iflist_mtx
);
}
static
void
ieee80211_cleanup_sdata_stas_wk
(
struct
work_struct
*
wk
)
{
struct
ieee80211_sub_if_data
*
sdata
;
sdata
=
container_of
(
wk
,
struct
ieee80211_sub_if_data
,
cleanup_stations_wk
);
ieee80211_cleanup_sdata_stas
(
sdata
);
}
int
ieee80211_if_add
(
struct
ieee80211_local
*
local
,
const
char
*
name
,
struct
wireless_dev
**
new_wdev
,
enum
nl80211_iftype
type
,
struct
vif_params
*
params
)
...
...
@@ -1573,6 +1567,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
INIT_LIST_HEAD
(
&
sdata
->
key_list
);
spin_lock_init
(
&
sdata
->
cleanup_stations_lock
);
INIT_LIST_HEAD
(
&
sdata
->
cleanup_stations
);
INIT_WORK
(
&
sdata
->
cleanup_stations_wk
,
ieee80211_cleanup_sdata_stas_wk
);
for
(
i
=
0
;
i
<
IEEE80211_NUM_BANDS
;
i
++
)
{
struct
ieee80211_supported_band
*
sband
;
sband
=
local
->
hw
.
wiphy
->
bands
[
i
];
...
...
net/mac80211/mesh.c
View file @
694c6186
...
...
@@ -163,7 +163,7 @@ int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
return
-
ENOMEM
;
sdata
->
u
.
mesh
.
rmc
->
idx_mask
=
RMC_BUCKETS
-
1
;
for
(
i
=
0
;
i
<
RMC_BUCKETS
;
i
++
)
INIT_LIST_HEAD
(
&
sdata
->
u
.
mesh
.
rmc
->
bucket
[
i
]
.
list
);
INIT_LIST_HEAD
(
&
sdata
->
u
.
mesh
.
rmc
->
bucket
[
i
]);
return
0
;
}
...
...
@@ -177,7 +177,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
return
;
for
(
i
=
0
;
i
<
RMC_BUCKETS
;
i
++
)
list_for_each_entry_safe
(
p
,
n
,
&
rmc
->
bucket
[
i
]
.
list
,
list
)
{
list_for_each_entry_safe
(
p
,
n
,
&
rmc
->
bucket
[
i
],
list
)
{
list_del
(
&
p
->
list
);
kmem_cache_free
(
rm_cache
,
p
);
}
...
...
@@ -210,7 +210,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
/* Don't care about endianness since only match matters */
memcpy
(
&
seqnum
,
&
mesh_hdr
->
seqnum
,
sizeof
(
mesh_hdr
->
seqnum
));
idx
=
le32_to_cpu
(
mesh_hdr
->
seqnum
)
&
rmc
->
idx_mask
;
list_for_each_entry_safe
(
p
,
n
,
&
rmc
->
bucket
[
idx
]
.
list
,
list
)
{
list_for_each_entry_safe
(
p
,
n
,
&
rmc
->
bucket
[
idx
],
list
)
{
++
entries
;
if
(
time_after
(
jiffies
,
p
->
exp_time
)
||
(
entries
==
RMC_QUEUE_MAX_LEN
))
{
...
...
@@ -229,7 +229,7 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
p
->
seqnum
=
seqnum
;
p
->
exp_time
=
jiffies
+
RMC_TIMEOUT
;
memcpy
(
p
->
sa
,
sa
,
ETH_ALEN
);
list_add
(
&
p
->
list
,
&
rmc
->
bucket
[
idx
]
.
list
);
list_add
(
&
p
->
list
,
&
rmc
->
bucket
[
idx
]);
return
0
;
}
...
...
net/mac80211/mesh.h
View file @
694c6186
...
...
@@ -184,7 +184,7 @@ struct rmc_entry {
};
struct
mesh_rmc
{
struct
rmc_entry
bucket
[
RMC_BUCKETS
];
struct
list_head
bucket
[
RMC_BUCKETS
];
u32
idx_mask
;
};
...
...
net/mac80211/mlme.c
View file @
694c6186
...
...
@@ -1074,12 +1074,8 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
if
(
beaconint_us
>
latency
)
{
local
->
ps_sdata
=
NULL
;
}
else
{
struct
ieee80211_bss
*
bss
;
int
maxslp
=
1
;
u8
dtimper
;
bss
=
(
void
*
)
found
->
u
.
mgd
.
associated
->
priv
;
dtimper
=
bss
->
dtim_period
;
u8
dtimper
=
found
->
u
.
mgd
.
dtim_period
;
/* If the TIM IE is invalid, pretend the value is 1 */
if
(
!
dtimper
)
...
...
@@ -1410,10 +1406,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
ieee80211_led_assoc
(
local
,
1
);
if
(
local
->
hw
.
flags
&
IEEE80211_HW_NEED_DTIM_PERIOD
)
bss_conf
->
dtim_period
=
bss
->
dtim_period
;
else
if
(
local
->
hw
.
flags
&
IEEE80211_HW_NEED_DTIM_PERIOD
)
{
/*
* If the AP is buggy we may get here with no DTIM period
* known, so assume it's 1 which is the only safe assumption
* in that case, although if the TIM IE is broken powersave
* probably just won't work at all.
*/
bss_conf
->
dtim_period
=
sdata
->
u
.
mgd
.
dtim_period
?:
1
;
}
else
{
bss_conf
->
dtim_period
=
0
;
}
bss_conf
->
assoc
=
1
;
...
...
@@ -1562,6 +1565,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
sdata
->
u
.
mgd
.
timers_running
=
0
;
sdata
->
vif
.
bss_conf
.
dtim_period
=
0
;
ifmgd
->
flags
=
0
;
ieee80211_vif_release_channel
(
sdata
);
}
...
...
@@ -2373,11 +2378,18 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct
ieee80211_channel
*
channel
;
bool
need_ps
=
false
;
if
(
sdata
->
u
.
mgd
.
associated
&&
ether_addr_equal
(
mgmt
->
bssid
,
sdata
->
u
.
mgd
.
associated
->
bssid
))
{
bss
=
(
void
*
)
sdata
->
u
.
mgd
.
associated
->
priv
;
if
((
sdata
->
u
.
mgd
.
associated
&&
ether_addr_equal
(
mgmt
->
bssid
,
sdata
->
u
.
mgd
.
associated
->
bssid
))
||
(
sdata
->
u
.
mgd
.
assoc_data
&&
ether_addr_equal
(
mgmt
->
bssid
,
sdata
->
u
.
mgd
.
assoc_data
->
bss
->
bssid
)))
{
/* not previously set so we may need to recalc */
need_ps
=
!
bss
->
dtim_period
;
need_ps
=
sdata
->
u
.
mgd
.
associated
&&
!
sdata
->
u
.
mgd
.
dtim_period
;
if
(
elems
->
tim
&&
!
elems
->
parse_error
)
{
struct
ieee80211_tim_ie
*
tim_ie
=
elems
->
tim
;
sdata
->
u
.
mgd
.
dtim_period
=
tim_ie
->
dtim_period
;
}
}
if
(
elems
->
ds_params
&&
elems
->
ds_params_len
==
1
)
...
...
@@ -3896,20 +3908,41 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
/* kick off associate process */
ifmgd
->
assoc_data
=
assoc_data
;
ifmgd
->
dtim_period
=
0
;
err
=
ieee80211_prep_connection
(
sdata
,
req
->
bss
,
true
);
if
(
err
)
goto
err_clear
;
if
(
!
bss
->
dtim_period
&&
sdata
->
local
->
hw
.
flags
&
IEEE80211_HW_NEED_DTIM_PERIOD
)
{
/*
* Wait up to one beacon interval ...
* should this be more if we miss one?
*/
sdata_info
(
sdata
,
"waiting for beacon from %pM
\n
"
,
ifmgd
->
bssid
);
assoc_data
->
timeout
=
TU_TO_EXP_TIME
(
req
->
bss
->
beacon_interval
);
if
(
sdata
->
local
->
hw
.
flags
&
IEEE80211_HW_NEED_DTIM_PERIOD
)
{
const
struct
cfg80211_bss_ies
*
beacon_ies
;
rcu_read_lock
();
beacon_ies
=
rcu_dereference
(
req
->
bss
->
beacon_ies
);
if
(
!
beacon_ies
)
{
/*
* Wait up to one beacon interval ...
* should this be more if we miss one?
*/
sdata_info
(
sdata
,
"waiting for beacon from %pM
\n
"
,
ifmgd
->
bssid
);
assoc_data
->
timeout
=
TU_TO_EXP_TIME
(
req
->
bss
->
beacon_interval
);
}
else
{
const
u8
*
tim_ie
=
cfg80211_find_ie
(
WLAN_EID_TIM
,
beacon_ies
->
data
,
beacon_ies
->
len
);
if
(
tim_ie
&&
tim_ie
[
1
]
>=
sizeof
(
struct
ieee80211_tim_ie
))
{
const
struct
ieee80211_tim_ie
*
tim
;
tim
=
(
void
*
)(
tim_ie
+
2
);
ifmgd
->
dtim_period
=
tim
->
dtim_period
;
}
assoc_data
->
have_beacon
=
true
;
assoc_data
->
sent_assoc
=
false
;
assoc_data
->
timeout
=
jiffies
;
}
rcu_read_unlock
();
}
else
{
assoc_data
->
have_beacon
=
true
;
assoc_data
->
sent_assoc
=
false
;
...
...
net/mac80211/scan.c
View file @
694c6186
...
...
@@ -113,18 +113,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
bss
->
valid_data
|=
IEEE80211_BSS_VALID_ERP
;
}
if
(
elems
->
tim
&&
(
!
elems
->
parse_error
||
!
(
bss
->
valid_data
&
IEEE80211_BSS_VALID_DTIM
)))
{
struct
ieee80211_tim_ie
*
tim_ie
=
elems
->
tim
;
bss
->
dtim_period
=
tim_ie
->
dtim_period
;
if
(
!
elems
->
parse_error
)
bss
->
valid_data
|=
IEEE80211_BSS_VALID_DTIM
;
}
/* If the beacon had no TIM IE, or it was invalid, use 1 */
if
(
beacon
&&
!
bss
->
dtim_period
)
bss
->
dtim_period
=
1
;
/* replace old supported rates if we get new values */
if
(
!
elems
->
parse_error
||
!
(
bss
->
valid_data
&
IEEE80211_BSS_VALID_RATES
))
{
...
...
@@ -832,9 +820,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
return
res
;
}
int
ieee80211_request_i
nternal
_scan
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
ssid
,
u8
ssid_len
,
struct
ieee80211_channel
*
chan
)
int
ieee80211_request_i
bss
_scan
(
struct
ieee80211_sub_if_data
*
sdata
,
const
u8
*
ssid
,
u8
ssid_len
,
struct
ieee80211_channel
*
chan
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
int
ret
=
-
EBUSY
;
...
...
@@ -848,22 +836,36 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
/* fill internal scan request */
if
(
!
chan
)
{
int
i
,
nchan
=
0
;
int
i
,
max_n
;
int
n_ch
=
0
;
for
(
band
=
0
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
{
if
(
!
local
->
hw
.
wiphy
->
bands
[
band
])
continue
;
for
(
i
=
0
;
i
<
local
->
hw
.
wiphy
->
bands
[
band
]
->
n_channels
;
i
++
)
{
local
->
int_scan_req
->
channels
[
nchan
]
=
max_n
=
local
->
hw
.
wiphy
->
bands
[
band
]
->
n_channels
;
for
(
i
=
0
;
i
<
max_n
;
i
++
)
{
struct
ieee80211_channel
*
tmp_ch
=
&
local
->
hw
.
wiphy
->
bands
[
band
]
->
channels
[
i
];
nchan
++
;
if
(
tmp_ch
->
flags
&
(
IEEE80211_CHAN_NO_IBSS
|
IEEE80211_CHAN_DISABLED
))
continue
;
local
->
int_scan_req
->
channels
[
n_ch
]
=
tmp_ch
;
n_ch
++
;
}
}
local
->
int_scan_req
->
n_channels
=
nchan
;
if
(
WARN_ON_ONCE
(
n_ch
==
0
))
goto
unlock
;
local
->
int_scan_req
->
n_channels
=
n_ch
;
}
else
{
if
(
WARN_ON_ONCE
(
chan
->
flags
&
(
IEEE80211_CHAN_NO_IBSS
|
IEEE80211_CHAN_DISABLED
)))
goto
unlock
;
local
->
int_scan_req
->
channels
[
0
]
=
chan
;
local
->
int_scan_req
->
n_channels
=
1
;
}
...
...
net/mac80211/sta_info.c
View file @
694c6186
...
...
@@ -91,9 +91,8 @@ static int sta_info_hash_del(struct ieee80211_local *local,
return
-
ENOENT
;
}
static
void
free_sta_work
(
struct
work_struct
*
wk
)
static
void
cleanup_single_sta
(
struct
sta_info
*
sta
)
{
struct
sta_info
*
sta
=
container_of
(
wk
,
struct
sta_info
,
free_sta_wk
);
int
ac
,
i
;
struct
tid_ampdu_tx
*
tid_tx
;
struct
ieee80211_sub_if_data
*
sdata
=
sta
->
sdata
;
...
...
@@ -153,11 +152,35 @@ static void free_sta_work(struct work_struct *wk)
sta_info_free
(
local
,
sta
);
}
void
ieee80211_cleanup_sdata_stas
(
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
sta_info
*
sta
;
spin_lock_bh
(
&
sdata
->
cleanup_stations_lock
);
while
(
!
list_empty
(
&
sdata
->
cleanup_stations
))
{
sta
=
list_first_entry
(
&
sdata
->
cleanup_stations
,
struct
sta_info
,
list
);
list_del
(
&
sta
->
list
);
spin_unlock_bh
(
&
sdata
->
cleanup_stations_lock
);
cleanup_single_sta
(
sta
);
spin_lock_bh
(
&
sdata
->
cleanup_stations_lock
);
}
spin_unlock_bh
(
&
sdata
->
cleanup_stations_lock
);
}
static
void
free_sta_rcu
(
struct
rcu_head
*
h
)
{
struct
sta_info
*
sta
=
container_of
(
h
,
struct
sta_info
,
rcu_head
);
struct
ieee80211_sub_if_data
*
sdata
=
sta
->
sdata
;
ieee80211_queue_work
(
&
sta
->
local
->
hw
,
&
sta
->
free_sta_wk
);
spin_lock
(
&
sdata
->
cleanup_stations_lock
);
list_add_tail
(
&
sta
->
list
,
&
sdata
->
cleanup_stations
);
spin_unlock
(
&
sdata
->
cleanup_stations_lock
);
ieee80211_queue_work
(
&
sdata
->
local
->
hw
,
&
sdata
->
cleanup_stations_wk
);
}
/* protected by RCU */
...
...
@@ -310,7 +333,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
spin_lock_init
(
&
sta
->
lock
);
INIT_WORK
(
&
sta
->
drv_unblock_wk
,
sta_unblock
);
INIT_WORK
(
&
sta
->
free_sta_wk
,
free_sta_work
);
INIT_WORK
(
&
sta
->
ampdu_mlme
.
work
,
ieee80211_ba_session_work
);
mutex_init
(
&
sta
->
ampdu_mlme
.
mtx
);
...
...
@@ -862,7 +884,7 @@ void sta_info_init(struct ieee80211_local *local)
void
sta_info_stop
(
struct
ieee80211_local
*
local
)
{
del_timer
(
&
local
->
sta_cleanup
);
del_timer
_sync
(
&
local
->
sta_cleanup
);
sta_info_flush
(
local
,
NULL
);
}
...
...
@@ -891,6 +913,20 @@ int sta_info_flush(struct ieee80211_local *local,
}
mutex_unlock
(
&
local
->
sta_mtx
);
rcu_barrier
();
if
(
sdata
)
{
ieee80211_cleanup_sdata_stas
(
sdata
);
cancel_work_sync
(
&
sdata
->
cleanup_stations_wk
);
}
else
{
mutex_lock
(
&
local
->
iflist_mtx
);
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
ieee80211_cleanup_sdata_stas
(
sdata
);
cancel_work_sync
(
&
sdata
->
cleanup_stations_wk
);
}
mutex_unlock
(
&
local
->
iflist_mtx
);
}
return
ret
;
}
...
...
net/mac80211/sta_info.h
View file @
694c6186
...
...
@@ -299,7 +299,6 @@ struct sta_info {
spinlock_t
lock
;
struct
work_struct
drv_unblock_wk
;
struct
work_struct
free_sta_wk
;
u16
listen_interval
;
...
...
@@ -563,4 +562,6 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta);
void
ieee80211_sta_ps_deliver_poll_response
(
struct
sta_info
*
sta
);
void
ieee80211_sta_ps_deliver_uapsd
(
struct
sta_info
*
sta
);
void
ieee80211_cleanup_sdata_stas
(
struct
ieee80211_sub_if_data
*
sdata
);
#endif
/* STA_INFO_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment