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
Kirill Smelkov
linux
Commits
d339fc89
Commit
d339fc89
authored
Jan 04, 2013
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211
parents
9a6f7347
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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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 @
d339fc89
...
...
@@ -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