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
7eb2450a
Commit
7eb2450a
authored
Mar 20, 2014
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-next
parents
474a41e9
73fb08e2
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
339 additions
and
195 deletions
+339
-195
include/linux/ieee80211.h
include/linux/ieee80211.h
+4
-0
include/net/cfg80211.h
include/net/cfg80211.h
+14
-9
include/net/mac80211.h
include/net/mac80211.h
+4
-2
include/net/regulatory.h
include/net/regulatory.h
+13
-8
include/uapi/linux/nl80211.h
include/uapi/linux/nl80211.h
+6
-0
net/mac80211/cfg.c
net/mac80211/cfg.c
+67
-54
net/mac80211/ibss.c
net/mac80211/ibss.c
+2
-10
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+1
-0
net/mac80211/mlme.c
net/mac80211/mlme.c
+46
-24
net/mac80211/pm.c
net/mac80211/pm.c
+11
-3
net/mac80211/rx.c
net/mac80211/rx.c
+3
-0
net/mac80211/scan.c
net/mac80211/scan.c
+4
-2
net/mac80211/tx.c
net/mac80211/tx.c
+1
-1
net/wireless/ap.c
net/wireless/ap.c
+5
-4
net/wireless/chan.c
net/wireless/chan.c
+56
-0
net/wireless/core.c
net/wireless/core.c
+1
-1
net/wireless/core.h
net/wireless/core.h
+4
-6
net/wireless/genregdb.awk
net/wireless/genregdb.awk
+7
-1
net/wireless/ibss.c
net/wireless/ibss.c
+4
-4
net/wireless/mlme.c
net/wireless/mlme.c
+1
-1
net/wireless/nl80211.c
net/wireless/nl80211.c
+21
-3
net/wireless/reg.c
net/wireless/reg.c
+42
-44
net/wireless/reg.h
net/wireless/reg.h
+0
-1
net/wireless/scan.c
net/wireless/scan.c
+19
-12
net/wireless/sme.c
net/wireless/sme.c
+0
-1
net/wireless/util.c
net/wireless/util.c
+2
-3
net/wireless/wext-sme.c
net/wireless/wext-sme.c
+1
-1
No files found.
include/linux/ieee80211.h
View file @
7eb2450a
...
...
@@ -154,6 +154,10 @@ static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2)
802.11e clarifies the figure in section 7.1.2. The frame body is
up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */
#define IEEE80211_MAX_DATA_LEN 2304
/* 802.11ad extends maximum MSDU size for DMG (freq > 40Ghz) networks
* to 7920 bytes, see 8.2.3 General frame format
*/
#define IEEE80211_MAX_DATA_LEN_DMG 7920
/* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */
#define IEEE80211_MAX_FRAME_LEN 2352
...
...
include/net/cfg80211.h
View file @
7eb2450a
...
...
@@ -151,6 +151,7 @@ enum ieee80211_channel_flags {
* @dfs_state: current state of this channel. Only relevant if radar is required
* on this channel.
* @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
* @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
*/
struct
ieee80211_channel
{
enum
ieee80211_band
band
;
...
...
@@ -165,6 +166,7 @@ struct ieee80211_channel {
int
orig_mag
,
orig_mpwr
;
enum
nl80211_dfs_state
dfs_state
;
unsigned
long
dfs_state_entered
;
unsigned
int
dfs_cac_ms
;
};
/**
...
...
@@ -2503,7 +2505,8 @@ struct cfg80211_ops {
int
(
*
start_radar_detection
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_chan_def
*
chandef
);
struct
cfg80211_chan_def
*
chandef
,
u32
cac_time_ms
);
int
(
*
update_ft_ies
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_update_ft_ies_params
*
ftie
);
int
(
*
crit_proto_start
)(
struct
wiphy
*
wiphy
,
...
...
@@ -3180,6 +3183,7 @@ struct cfg80211_cached_keys;
* @p2p_started: true if this is a P2P Device that has been started
* @cac_started: true if DFS channel availability check has been started
* @cac_start_time: timestamp (jiffies) when the dfs state was entered.
* @cac_time_ms: CAC time in ms
* @ps: powersave mode is enabled
* @ps_timeout: dynamic powersave timeout
* @ap_unexpected_nlportid: (private) netlink port ID of application
...
...
@@ -3235,6 +3239,7 @@ struct wireless_dev {
bool
cac_started
;
unsigned
long
cac_start_time
;
unsigned
int
cac_time_ms
;
#ifdef CONFIG_CFG80211_WEXT
/* wext data */
...
...
@@ -3667,7 +3672,7 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
* cfg80211_inform_bss_width_frame - inform cfg80211 of a received BSS frame
*
* @wiphy: the wiphy reporting the BSS
* @channel: The channel the frame was received on
* @
rx_
channel: The channel the frame was received on
* @scan_width: width of the control channel
* @mgmt: the management frame (probe response or beacon)
* @len: length of the management frame
...
...
@@ -3682,18 +3687,18 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
*/
struct
cfg80211_bss
*
__must_check
cfg80211_inform_bss_width_frame
(
struct
wiphy
*
wiphy
,
struct
ieee80211_channel
*
channel
,
struct
ieee80211_channel
*
rx_
channel
,
enum
nl80211_bss_scan_width
scan_width
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
,
s32
signal
,
gfp_t
gfp
);
static
inline
struct
cfg80211_bss
*
__must_check
cfg80211_inform_bss_frame
(
struct
wiphy
*
wiphy
,
struct
ieee80211_channel
*
channel
,
struct
ieee80211_channel
*
rx_
channel
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
,
s32
signal
,
gfp_t
gfp
)
{
return
cfg80211_inform_bss_width_frame
(
wiphy
,
channel
,
return
cfg80211_inform_bss_width_frame
(
wiphy
,
rx_
channel
,
NL80211_BSS_CHAN_WIDTH_20
,
mgmt
,
len
,
signal
,
gfp
);
}
...
...
@@ -3702,7 +3707,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
* cfg80211_inform_bss - inform cfg80211 of a new BSS
*
* @wiphy: the wiphy reporting the BSS
* @channel: The channel the frame was received on
* @
rx_
channel: The channel the frame was received on
* @scan_width: width of the control channel
* @bssid: the BSSID of the BSS
* @tsf: the TSF sent by the peer in the beacon/probe response (or 0)
...
...
@@ -3721,7 +3726,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
*/
struct
cfg80211_bss
*
__must_check
cfg80211_inform_bss_width
(
struct
wiphy
*
wiphy
,
struct
ieee80211_channel
*
channel
,
struct
ieee80211_channel
*
rx_
channel
,
enum
nl80211_bss_scan_width
scan_width
,
const
u8
*
bssid
,
u64
tsf
,
u16
capability
,
u16
beacon_interval
,
const
u8
*
ie
,
size_t
ielen
,
...
...
@@ -3729,12 +3734,12 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
static
inline
struct
cfg80211_bss
*
__must_check
cfg80211_inform_bss
(
struct
wiphy
*
wiphy
,
struct
ieee80211_channel
*
channel
,
struct
ieee80211_channel
*
rx_
channel
,
const
u8
*
bssid
,
u64
tsf
,
u16
capability
,
u16
beacon_interval
,
const
u8
*
ie
,
size_t
ielen
,
s32
signal
,
gfp_t
gfp
)
{
return
cfg80211_inform_bss_width
(
wiphy
,
channel
,
return
cfg80211_inform_bss_width
(
wiphy
,
rx_
channel
,
NL80211_BSS_CHAN_WIDTH_20
,
bssid
,
tsf
,
capability
,
beacon_interval
,
ie
,
ielen
,
signal
,
...
...
include/net/mac80211.h
View file @
7eb2450a
...
...
@@ -697,11 +697,11 @@ struct ieee80211_tx_info {
}
control
;
struct
{
struct
ieee80211_tx_rate
rates
[
IEEE80211_TX_MAX_RATES
];
int
ack_signal
;
s32
ack_signal
;
u8
ampdu_ack_len
;
u8
ampdu_len
;
u8
antenna
;
/* 21 bytes free */
void
*
status_driver_data
[
21
/
sizeof
(
void
*
)];
}
status
;
struct
{
struct
ieee80211_tx_rate
driver_rates
[
...
...
@@ -877,11 +877,13 @@ enum mac80211_rx_flags {
* @RX_VHT_FLAG_80MHZ: 80 MHz was used
* @RX_VHT_FLAG_80P80MHZ: 80+80 MHz was used
* @RX_VHT_FLAG_160MHZ: 160 MHz was used
* @RX_VHT_FLAG_BF: packet was beamformed
*/
enum
mac80211_rx_vht_flags
{
RX_VHT_FLAG_80MHZ
=
BIT
(
0
),
RX_VHT_FLAG_80P80MHZ
=
BIT
(
1
),
RX_VHT_FLAG_160MHZ
=
BIT
(
2
),
RX_VHT_FLAG_BF
=
BIT
(
3
),
};
/**
...
...
include/net/regulatory.h
View file @
7eb2450a
...
...
@@ -155,6 +155,7 @@ struct ieee80211_reg_rule {
struct
ieee80211_freq_range
freq_range
;
struct
ieee80211_power_rule
power_rule
;
u32
flags
;
u32
dfs_cac_ms
;
};
struct
ieee80211_regdomain
{
...
...
@@ -172,14 +173,18 @@ struct ieee80211_regdomain {
#define DBM_TO_MBM(gain) ((gain) * 100)
#define MBM_TO_DBM(gain) ((gain) / 100)
#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \
{ \
.freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
.freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
.freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
.power_rule.max_antenna_gain = DBI_TO_MBI(gain),\
.power_rule.max_eirp = DBM_TO_MBM(eirp), \
.flags = reg_flags, \
#define REG_RULE_EXT(start, end, bw, gain, eirp, dfs_cac, reg_flags) \
{ \
.freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
.freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
.freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
.power_rule.max_antenna_gain = DBI_TO_MBI(gain), \
.power_rule.max_eirp = DBM_TO_MBM(eirp), \
.flags = reg_flags, \
.dfs_cac_ms = dfs_cac, \
}
#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \
REG_RULE_EXT(start, end, bw, gain, eirp, 0, reg_flags)
#endif
include/uapi/linux/nl80211.h
View file @
7eb2450a
...
...
@@ -2335,6 +2335,7 @@ enum nl80211_band_attr {
* @NL80211_FREQUENCY_ATTR_NO_160MHZ: any 160 MHz (but not 80+80) channel
* using this channel as the primary or any of the secondary channels
* isn't possible
* @NL80211_FREQUENCY_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
* @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
* currently defined
* @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
...
...
@@ -2353,6 +2354,7 @@ enum nl80211_frequency_attr {
NL80211_FREQUENCY_ATTR_NO_HT40_PLUS
,
NL80211_FREQUENCY_ATTR_NO_80MHZ
,
NL80211_FREQUENCY_ATTR_NO_160MHZ
,
NL80211_FREQUENCY_ATTR_DFS_CAC_TIME
,
/* keep last */
__NL80211_FREQUENCY_ATTR_AFTER_LAST
,
...
...
@@ -2449,6 +2451,8 @@ enum nl80211_reg_type {
* If you don't have one then don't send this.
* @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for
* a given frequency range. The value is in mBm (100 * dBm).
* @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
* If not present or 0 default CAC time will be used.
* @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
* currently defined
* @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
...
...
@@ -2464,6 +2468,8 @@ enum nl80211_reg_rule_attr {
NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN
,
NL80211_ATTR_POWER_RULE_MAX_EIRP
,
NL80211_ATTR_DFS_CAC_TIME
,
/* keep last */
__NL80211_REG_RULE_ATTR_AFTER_LAST
,
NL80211_REG_RULE_ATTR_MAX
=
__NL80211_REG_RULE_ATTR_AFTER_LAST
-
1
...
...
net/mac80211/cfg.c
View file @
7eb2450a
...
...
@@ -2914,11 +2914,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
static
int
ieee80211_start_radar_detection
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_chan_def
*
chandef
)
struct
cfg80211_chan_def
*
chandef
,
u32
cac_time_ms
)
{
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
struct
ieee80211_local
*
local
=
sdata
->
local
;
unsigned
long
timeout
;
int
err
;
mutex_lock
(
&
local
->
mtx
);
...
...
@@ -2937,9 +2937,9 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
if
(
err
)
goto
out_unlock
;
timeout
=
msecs_to_jiffies
(
IEEE80211_DFS_MIN_CAC_TIME_MS
);
ieee80211_queue_delayed_work
(
&
sdata
->
local
->
hw
,
&
sdata
->
dfs_cac_timer_work
,
timeout
);
&
sdata
->
dfs_cac_timer_work
,
msecs_to_jiffies
(
cac_time_ms
));
out_unlock:
mutex_unlock
(
&
local
->
mtx
);
...
...
@@ -3089,52 +3089,11 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
sdata_unlock
(
sdata
);
}
int
ieee80211_channel_switch
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_csa_settings
*
params
)
static
int
ieee80211_set_csa_beacon
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
cfg80211_csa_settings
*
params
,
u32
*
changed
)
{
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
struct
ieee80211_chanctx
*
chanctx
;
struct
ieee80211_if_mesh
__maybe_unused
*
ifmsh
;
int
err
,
num_chanctx
,
changed
=
0
;
sdata_assert_lock
(
sdata
);
if
(
!
list_empty
(
&
local
->
roc_list
)
||
local
->
scanning
)
return
-
EBUSY
;
if
(
sdata
->
wdev
.
cac_started
)
return
-
EBUSY
;
if
(
cfg80211_chandef_identical
(
&
params
->
chandef
,
&
sdata
->
vif
.
bss_conf
.
chandef
))
return
-
EINVAL
;
rcu_read_lock
();
chanctx_conf
=
rcu_dereference
(
sdata
->
vif
.
chanctx_conf
);
if
(
!
chanctx_conf
)
{
rcu_read_unlock
();
return
-
EBUSY
;
}
/* don't handle for multi-VIF cases */
chanctx
=
container_of
(
chanctx_conf
,
struct
ieee80211_chanctx
,
conf
);
if
(
chanctx
->
refcount
>
1
)
{
rcu_read_unlock
();
return
-
EBUSY
;
}
num_chanctx
=
0
;
list_for_each_entry_rcu
(
chanctx
,
&
local
->
chanctx_list
,
list
)
num_chanctx
++
;
rcu_read_unlock
();
if
(
num_chanctx
>
1
)
return
-
EBUSY
;
/* don't allow another channel switch if one is already active. */
if
(
sdata
->
vif
.
csa_active
)
return
-
EBUSY
;
int
err
;
switch
(
sdata
->
vif
.
type
)
{
case
NL80211_IFTYPE_AP
:
...
...
@@ -3170,7 +3129,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
kfree
(
sdata
->
u
.
ap
.
next_beacon
);
return
err
;
}
changed
|=
err
;
*
changed
|=
err
;
break
;
case
NL80211_IFTYPE_ADHOC
:
...
...
@@ -3204,15 +3163,15 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
err
=
ieee80211_ibss_csa_beacon
(
sdata
,
params
);
if
(
err
<
0
)
return
err
;
changed
|=
err
;
*
changed
|=
err
;
}
ieee80211_send_action_csa
(
sdata
,
params
);
break
;
#ifdef CONFIG_MAC80211_MESH
case
NL80211_IFTYPE_MESH_POINT
:
ifmsh
=
&
sdata
->
u
.
mesh
;
case
NL80211_IFTYPE_MESH_POINT
:
{
struct
ieee80211_if_mesh
*
ifmsh
=
&
sdata
->
u
.
mesh
;
if
(
params
->
chandef
.
width
!=
sdata
->
vif
.
bss_conf
.
chandef
.
width
)
return
-
EINVAL
;
...
...
@@ -3237,18 +3196,72 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
ifmsh
->
csa_role
=
IEEE80211_MESH_CSA_ROLE_NONE
;
return
err
;
}
changed
|=
err
;
*
changed
|=
err
;
}
if
(
ifmsh
->
csa_role
==
IEEE80211_MESH_CSA_ROLE_INIT
)
ieee80211_send_action_csa
(
sdata
,
params
);
break
;
}
#endif
default:
return
-
EOPNOTSUPP
;
}
return
0
;
}
int
ieee80211_channel_switch
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_csa_settings
*
params
)
{
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
struct
ieee80211_chanctx
*
chanctx
;
int
err
,
num_chanctx
,
changed
=
0
;
sdata_assert_lock
(
sdata
);
if
(
!
list_empty
(
&
local
->
roc_list
)
||
local
->
scanning
)
return
-
EBUSY
;
if
(
sdata
->
wdev
.
cac_started
)
return
-
EBUSY
;
if
(
cfg80211_chandef_identical
(
&
params
->
chandef
,
&
sdata
->
vif
.
bss_conf
.
chandef
))
return
-
EINVAL
;
rcu_read_lock
();
chanctx_conf
=
rcu_dereference
(
sdata
->
vif
.
chanctx_conf
);
if
(
!
chanctx_conf
)
{
rcu_read_unlock
();
return
-
EBUSY
;
}
/* don't handle for multi-VIF cases */
chanctx
=
container_of
(
chanctx_conf
,
struct
ieee80211_chanctx
,
conf
);
if
(
chanctx
->
refcount
>
1
)
{
rcu_read_unlock
();
return
-
EBUSY
;
}
num_chanctx
=
0
;
list_for_each_entry_rcu
(
chanctx
,
&
local
->
chanctx_list
,
list
)
num_chanctx
++
;
rcu_read_unlock
();
if
(
num_chanctx
>
1
)
return
-
EBUSY
;
/* don't allow another channel switch if one is already active. */
if
(
sdata
->
vif
.
csa_active
)
return
-
EBUSY
;
err
=
ieee80211_set_csa_beacon
(
sdata
,
params
,
&
changed
);
if
(
err
)
return
err
;
sdata
->
csa_radar_required
=
params
->
radar_required
;
if
(
params
->
block_tx
)
...
...
net/mac80211/ibss.c
View file @
7eb2450a
...
...
@@ -991,7 +991,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct
ieee802_11_elems
*
elems
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
int
freq
;
struct
cfg80211_bss
*
cbss
;
struct
ieee80211_bss
*
bss
;
struct
sta_info
*
sta
;
...
...
@@ -1003,15 +1002,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct
ieee80211_supported_band
*
sband
=
local
->
hw
.
wiphy
->
bands
[
band
];
bool
rates_updated
=
false
;
if
(
elems
->
ds_params
)
freq
=
ieee80211_channel_to_frequency
(
elems
->
ds_params
[
0
],
band
);
else
freq
=
rx_status
->
freq
;
channel
=
ieee80211_get_channel
(
local
->
hw
.
wiphy
,
freq
);
if
(
!
channel
||
channel
->
flags
&
IEEE80211_CHAN_DISABLED
)
channel
=
ieee80211_get_channel
(
local
->
hw
.
wiphy
,
rx_status
->
freq
);
if
(
!
channel
)
return
;
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_ADHOC
&&
...
...
net/mac80211/ieee80211_i.h
View file @
7eb2450a
...
...
@@ -1391,6 +1391,7 @@ void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
void
ieee80211_mgd_stop
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211_mgd_conn_tx_status
(
struct
ieee80211_sub_if_data
*
sdata
,
__le16
fc
,
bool
acked
);
void
ieee80211_mgd_quiesce
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211_sta_restart
(
struct
ieee80211_sub_if_data
*
sdata
);
/* IBSS code */
...
...
net/mac80211/mlme.c
View file @
7eb2450a
...
...
@@ -2783,28 +2783,20 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
struct
ieee802_11_elems
*
elems
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
int
freq
;
struct
ieee80211_bss
*
bss
;
struct
ieee80211_channel
*
channel
;
sdata_assert_lock
(
sdata
);
if
(
elems
->
ds_params
)
freq
=
ieee80211_channel_to_frequency
(
elems
->
ds_params
[
0
],
rx_status
->
band
);
else
freq
=
rx_status
->
freq
;
channel
=
ieee80211_get_channel
(
local
->
hw
.
wiphy
,
freq
);
if
(
!
channel
||
channel
->
flags
&
IEEE80211_CHAN_DISABLED
)
channel
=
ieee80211_get_channel
(
local
->
hw
.
wiphy
,
rx_status
->
freq
);
if
(
!
channel
)
return
;
bss
=
ieee80211_bss_info_update
(
local
,
rx_status
,
mgmt
,
len
,
elems
,
channel
);
if
(
bss
)
{
ieee80211_rx_bss_put
(
local
,
bss
);
sdata
->
vif
.
bss_conf
.
beacon_rate
=
bss
->
beacon_rate
;
ieee80211_rx_bss_put
(
local
,
bss
);
}
}
...
...
@@ -3599,6 +3591,32 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
}
#ifdef CONFIG_PM
void
ieee80211_mgd_quiesce
(
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
u8
frame_buf
[
IEEE80211_DEAUTH_FRAME_LEN
];
sdata_lock
(
sdata
);
if
(
ifmgd
->
auth_data
)
{
/*
* If we are trying to authenticate while suspending, cfg80211
* won't know and won't actually abort those attempts, thus we
* need to do that ourselves.
*/
ieee80211_send_deauth_disassoc
(
sdata
,
ifmgd
->
auth_data
->
bss
->
bssid
,
IEEE80211_STYPE_DEAUTH
,
WLAN_REASON_DEAUTH_LEAVING
,
false
,
frame_buf
);
ieee80211_destroy_auth_data
(
sdata
,
false
);
cfg80211_tx_mlme_mgmt
(
sdata
->
dev
,
frame_buf
,
IEEE80211_DEAUTH_FRAME_LEN
);
}
sdata_unlock
(
sdata
);
}
void
ieee80211_sta_restart
(
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
...
...
@@ -4417,37 +4435,41 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
u8
frame_buf
[
IEEE80211_DEAUTH_FRAME_LEN
];
bool
tx
=
!
req
->
local_state_change
;
bool
report_frame
=
false
;
sdata_info
(
sdata
,
"deauthenticating from %pM by local choice (Reason: %u=%s)
\n
"
,
req
->
bssid
,
req
->
reason_code
,
ieee80211_get_reason_code_string
(
req
->
reason_code
));
if
(
ifmgd
->
auth_data
&&
ether_addr_equal
(
ifmgd
->
auth_data
->
bss
->
bssid
,
req
->
bssid
))
{
sdata_info
(
sdata
,
"aborting authentication with %pM by local choice (Reason: %u=%s)
\n
"
,
req
->
bssid
,
req
->
reason_code
,
ieee80211_get_reason_code_string
(
req
->
reason_code
));
if
(
ifmgd
->
auth_data
)
{
drv_mgd_prepare_tx
(
sdata
->
local
,
sdata
);
ieee80211_send_deauth_disassoc
(
sdata
,
req
->
bssid
,
IEEE80211_STYPE_DEAUTH
,
req
->
reason_code
,
tx
,
frame_buf
);
ieee80211_destroy_auth_data
(
sdata
,
false
);
cfg80211_tx_mlme_mgmt
(
sdata
->
dev
,
frame_buf
,
IEEE80211_DEAUTH_FRAME_LEN
);
report_frame
=
true
;
goto
out
;
return
0
;
}
if
(
ifmgd
->
associated
&&
ether_addr_equal
(
ifmgd
->
associated
->
bssid
,
req
->
bssid
))
{
sdata_info
(
sdata
,
"deauthenticating from %pM by local choice (Reason: %u=%s)
\n
"
,
req
->
bssid
,
req
->
reason_code
,
ieee80211_get_reason_code_string
(
req
->
reason_code
));
ieee80211_set_disassoc
(
sdata
,
IEEE80211_STYPE_DEAUTH
,
req
->
reason_code
,
tx
,
frame_buf
);
report_frame
=
true
;
}
out:
if
(
report_frame
)
cfg80211_tx_mlme_mgmt
(
sdata
->
dev
,
frame_buf
,
IEEE80211_DEAUTH_FRAME_LEN
);
return
0
;
}
return
0
;
return
-
ENOTCONN
;
}
int
ieee80211_mgd_disassoc
(
struct
ieee80211_sub_if_data
*
sdata
,
...
...
net/mac80211/pm.c
View file @
7eb2450a
...
...
@@ -100,10 +100,18 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
/* remove all interfaces that were created in the driver */
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
if
(
!
ieee80211_sdata_running
(
sdata
)
||
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP_VLAN
||
sdata
->
vif
.
type
==
NL80211_IFTYPE_MONITOR
)
if
(
!
ieee80211_sdata_running
(
sdata
))
continue
;
switch
(
sdata
->
vif
.
type
)
{
case
NL80211_IFTYPE_AP_VLAN
:
case
NL80211_IFTYPE_MONITOR
:
continue
;
case
NL80211_IFTYPE_STATION
:
ieee80211_mgd_quiesce
(
sdata
);
break
;
default:
break
;
}
drv_remove_interface
(
local
,
sdata
);
}
...
...
net/mac80211/rx.c
View file @
7eb2450a
...
...
@@ -333,6 +333,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
/* in VHT, STBC is binary */
if
(
status
->
flag
&
RX_FLAG_STBC_MASK
)
*
pos
|=
IEEE80211_RADIOTAP_VHT_FLAG_STBC
;
if
(
status
->
vht_flag
&
RX_VHT_FLAG_BF
)
*
pos
|=
IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED
;
pos
++
;
/* bandwidth */
if
(
status
->
vht_flag
&
RX_VHT_FLAG_80MHZ
)
...
...
@@ -1245,6 +1247,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
if
(
ieee80211_is_data
(
hdr
->
frame_control
))
{
sta
->
last_rx_rate_idx
=
status
->
rate_idx
;
sta
->
last_rx_rate_flag
=
status
->
flag
;
sta
->
last_rx_rate_vht_flag
=
status
->
vht_flag
;
sta
->
last_rx_rate_vht_nss
=
status
->
vht_nss
;
}
}
...
...
net/mac80211/scan.c
View file @
7eb2450a
...
...
@@ -1055,9 +1055,11 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
/* We don't want to restart sched scan anymore. */
local
->
sched_scan_req
=
NULL
;
if
(
rcu_access_pointer
(
local
->
sched_scan_sdata
))
if
(
rcu_access_pointer
(
local
->
sched_scan_sdata
))
{
ret
=
drv_sched_scan_stop
(
local
,
sdata
);
if
(
!
ret
)
rcu_assign_pointer
(
local
->
sched_scan_sdata
,
NULL
);
}
out:
mutex_unlock
(
&
local
->
mtx
);
...
...
net/mac80211/tx.c
View file @
7eb2450a
...
...
@@ -2900,7 +2900,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
cpu_to_le16
(
IEEE80211_FCTL_MOREDATA
);
}
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
_VLAN
)
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
skb
->
dev
);
if
(
!
ieee80211_tx_prepare
(
sdata
,
&
tx
,
skb
))
break
;
...
...
net/wireless/ap.c
View file @
7eb2450a
...
...
@@ -7,7 +7,7 @@
static
int
__cfg80211_stop_ap
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
)
struct
net_device
*
dev
,
bool
notify
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
...
...
@@ -30,20 +30,21 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
memset
(
&
wdev
->
chandef
,
0
,
sizeof
(
wdev
->
chandef
));
wdev
->
ssid_len
=
0
;
rdev_set_qos_map
(
rdev
,
dev
,
NULL
);
nl80211_send_ap_stopped
(
wdev
);
if
(
notify
)
nl80211_send_ap_stopped
(
wdev
);
}
return
err
;
}
int
cfg80211_stop_ap
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
)
struct
net_device
*
dev
,
bool
notify
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
wdev_lock
(
wdev
);
err
=
__cfg80211_stop_ap
(
rdev
,
dev
);
err
=
__cfg80211_stop_ap
(
rdev
,
dev
,
notify
);
wdev_unlock
(
wdev
);
return
err
;
...
...
net/wireless/chan.c
View file @
7eb2450a
...
...
@@ -490,6 +490,62 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
return
r
;
}
static
unsigned
int
cfg80211_get_chans_dfs_cac_time
(
struct
wiphy
*
wiphy
,
u32
center_freq
,
u32
bandwidth
)
{
struct
ieee80211_channel
*
c
;
u32
start_freq
,
end_freq
,
freq
;
unsigned
int
dfs_cac_ms
=
0
;
start_freq
=
cfg80211_get_start_freq
(
center_freq
,
bandwidth
);
end_freq
=
cfg80211_get_end_freq
(
center_freq
,
bandwidth
);
for
(
freq
=
start_freq
;
freq
<=
end_freq
;
freq
+=
20
)
{
c
=
ieee80211_get_channel
(
wiphy
,
freq
);
if
(
!
c
)
return
0
;
if
(
c
->
flags
&
IEEE80211_CHAN_DISABLED
)
return
0
;
if
(
!
(
c
->
flags
&
IEEE80211_CHAN_RADAR
))
continue
;
if
(
c
->
dfs_cac_ms
>
dfs_cac_ms
)
dfs_cac_ms
=
c
->
dfs_cac_ms
;
}
return
dfs_cac_ms
;
}
unsigned
int
cfg80211_chandef_dfs_cac_time
(
struct
wiphy
*
wiphy
,
const
struct
cfg80211_chan_def
*
chandef
)
{
int
width
;
unsigned
int
t1
=
0
,
t2
=
0
;
if
(
WARN_ON
(
!
cfg80211_chandef_valid
(
chandef
)))
return
0
;
width
=
cfg80211_chandef_get_width
(
chandef
);
if
(
width
<
0
)
return
0
;
t1
=
cfg80211_get_chans_dfs_cac_time
(
wiphy
,
chandef
->
center_freq1
,
width
);
if
(
!
chandef
->
center_freq2
)
return
t1
;
t2
=
cfg80211_get_chans_dfs_cac_time
(
wiphy
,
chandef
->
center_freq2
,
width
);
return
max
(
t1
,
t2
);
}
static
bool
cfg80211_secondary_chans_ok
(
struct
wiphy
*
wiphy
,
u32
center_freq
,
u32
bandwidth
,
...
...
net/wireless/core.c
View file @
7eb2450a
...
...
@@ -783,7 +783,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
break
;
case
NL80211_IFTYPE_AP
:
case
NL80211_IFTYPE_P2P_GO
:
cfg80211_stop_ap
(
rdev
,
dev
);
cfg80211_stop_ap
(
rdev
,
dev
,
true
);
break
;
default:
break
;
...
...
net/wireless/core.h
View file @
7eb2450a
...
...
@@ -166,7 +166,6 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
mutex_unlock
(
&
wdev
->
mtx
);
}
#define ASSERT_RDEV_LOCK(rdev) ASSERT_RTNL()
#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
static
inline
bool
cfg80211_has_monitors_only
(
struct
cfg80211_registered_device
*
rdev
)
...
...
@@ -246,10 +245,6 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev,
unsigned
long
age_secs
);
/* IBSS */
int
__cfg80211_join_ibss
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_ibss_params
*
params
,
struct
cfg80211_cached_keys
*
connkeys
);
int
cfg80211_join_ibss
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_ibss_params
*
params
,
...
...
@@ -283,7 +278,7 @@ int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
/* AP */
int
cfg80211_stop_ap
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
);
struct
net_device
*
dev
,
bool
notify
);
/* MLME */
int
cfg80211_mlme_auth
(
struct
cfg80211_registered_device
*
rdev
,
...
...
@@ -402,6 +397,9 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
void
cfg80211_dfs_channels_update_work
(
struct
work_struct
*
work
);
unsigned
int
cfg80211_chandef_dfs_cac_time
(
struct
wiphy
*
wiphy
,
const
struct
cfg80211_chan_def
*
chandef
);
static
inline
int
cfg80211_can_change_interface
(
struct
cfg80211_registered_device
*
rdev
,
...
...
net/wireless/genregdb.awk
View file @
7eb2450a
...
...
@@ -66,6 +66,7 @@ function parse_reg_rule()
units
=
$8
sub
(
/
\)
/
,
""
,
units
)
sub
(
/,/
,
""
,
units
)
dfs_cac
=
$9
if
(
units
==
"mW"
)
{
if
(
power
==
100
)
{
power
=
20
...
...
@@ -78,7 +79,12 @@ function parse_reg_rule()
}
else
{
print
"Unknown power value in database!"
}
}
else
{
dfs_cac
=
$8
}
sub
(
/,/
,
""
,
dfs_cac
)
sub
(
/
\(
/
,
""
,
dfs_cac
)
sub
(
/
\)
/
,
""
,
dfs_cac
)
flagstr
=
""
for
(
i
=
8
;
i
<=
NF
;
i
++
)
flagstr
=
flagstr
$i
...
...
@@ -111,7 +117,7 @@ function parse_reg_rule()
}
flags
=
flags
"0"
printf
"\t\tREG_RULE
(%d, %d, %d, %d, %d, %s),\n"
,
start
,
end
,
bw
,
gain
,
power
,
flags
printf
"\t\tREG_RULE
_EXT(%d, %d, %d, %d, %d, %d, %s),\n"
,
start
,
end
,
bw
,
gain
,
power
,
dfs_cac
,
flags
rules
++
}
...
...
net/wireless/ibss.c
View file @
7eb2450a
...
...
@@ -82,10 +82,10 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid,
}
EXPORT_SYMBOL
(
cfg80211_ibss_joined
);
int
__cfg80211_join_ibss
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_ibss_params
*
params
,
struct
cfg80211_cached_keys
*
connkeys
)
static
int
__cfg80211_join_ibss
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_ibss_params
*
params
,
struct
cfg80211_cached_keys
*
connkeys
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
ieee80211_channel
*
check_chan
;
...
...
net/wireless/mlme.c
View file @
7eb2450a
...
...
@@ -778,7 +778,7 @@ void cfg80211_cac_event(struct net_device *netdev,
switch
(
event
)
{
case
NL80211_RADAR_CAC_FINISHED
:
timeout
=
wdev
->
cac_start_time
+
msecs_to_jiffies
(
IEEE80211_DFS_MIN_CAC_TIME_MS
);
msecs_to_jiffies
(
wdev
->
cac_time_ms
);
WARN_ON
(
!
time_after_eq
(
jiffies
,
timeout
));
cfg80211_set_dfs_state
(
wiphy
,
chandef
,
NL80211_DFS_AVAILABLE
);
break
;
...
...
net/wireless/nl80211.c
View file @
7eb2450a
...
...
@@ -593,6 +593,10 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
if
(
nla_put_u32
(
msg
,
NL80211_FREQUENCY_ATTR_DFS_TIME
,
time
))
goto
nla_put_failure
;
if
(
nla_put_u32
(
msg
,
NL80211_FREQUENCY_ATTR_DFS_CAC_TIME
,
chan
->
dfs_cac_ms
))
goto
nla_put_failure
;
}
}
...
...
@@ -3328,7 +3332,7 @@ static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
struct
net_device
*
dev
=
info
->
user_ptr
[
1
];
return
cfg80211_stop_ap
(
rdev
,
dev
);
return
cfg80211_stop_ap
(
rdev
,
dev
,
false
);
}
static
const
struct
nla_policy
sta_flags_policy
[
NL80211_STA_FLAG_MAX
+
1
]
=
{
...
...
@@ -4614,6 +4618,7 @@ static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] =
[
NL80211_ATTR_FREQ_RANGE_MAX_BW
]
=
{
.
type
=
NLA_U32
},
[
NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN
]
=
{
.
type
=
NLA_U32
},
[
NL80211_ATTR_POWER_RULE_MAX_EIRP
]
=
{
.
type
=
NLA_U32
},
[
NL80211_ATTR_DFS_CAC_TIME
]
=
{
.
type
=
NLA_U32
},
};
static
int
parse_reg_rule
(
struct
nlattr
*
tb
[],
...
...
@@ -4649,6 +4654,10 @@ static int parse_reg_rule(struct nlattr *tb[],
power_rule
->
max_antenna_gain
=
nla_get_u32
(
tb
[
NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN
]);
if
(
tb
[
NL80211_ATTR_DFS_CAC_TIME
])
reg_rule
->
dfs_cac_ms
=
nla_get_u32
(
tb
[
NL80211_ATTR_DFS_CAC_TIME
]);
return
0
;
}
...
...
@@ -5136,7 +5145,9 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
nla_put_u32
(
msg
,
NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN
,
power_rule
->
max_antenna_gain
)
||
nla_put_u32
(
msg
,
NL80211_ATTR_POWER_RULE_MAX_EIRP
,
power_rule
->
max_eirp
))
power_rule
->
max_eirp
)
||
nla_put_u32
(
msg
,
NL80211_ATTR_DFS_CAC_TIME
,
reg_rule
->
dfs_cac_ms
))
goto
nla_put_failure_rcu
;
nla_nest_end
(
msg
,
nl_reg_rule
);
...
...
@@ -5768,6 +5779,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
cfg80211_chan_def
chandef
;
enum
nl80211_dfs_regions
dfs_region
;
unsigned
int
cac_time_ms
;
int
err
;
dfs_region
=
reg_get_dfs_region
(
wdev
->
wiphy
);
...
...
@@ -5803,11 +5815,17 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
if
(
err
)
return
err
;
err
=
rdev
->
ops
->
start_radar_detection
(
&
rdev
->
wiphy
,
dev
,
&
chandef
);
cac_time_ms
=
cfg80211_chandef_dfs_cac_time
(
&
rdev
->
wiphy
,
&
chandef
);
if
(
WARN_ON
(
!
cac_time_ms
))
cac_time_ms
=
IEEE80211_DFS_MIN_CAC_TIME_MS
;
err
=
rdev
->
ops
->
start_radar_detection
(
&
rdev
->
wiphy
,
dev
,
&
chandef
,
cac_time_ms
);
if
(
!
err
)
{
wdev
->
chandef
=
chandef
;
wdev
->
cac_started
=
true
;
wdev
->
cac_start_time
=
jiffies
;
wdev
->
cac_time_ms
=
cac_time_ms
;
}
return
err
;
}
...
...
net/wireless/reg.c
View file @
7eb2450a
...
...
@@ -91,10 +91,6 @@ static struct regulatory_request __rcu *last_request =
/* To trigger userspace events */
static
struct
platform_device
*
reg_pdev
;
static
const
struct
device_type
reg_device_type
=
{
.
uevent
=
reg_device_uevent
,
};
/*
* Central wireless core regulatory domains, we only need two,
* the current one and a world regulatory domain in case we have no
...
...
@@ -244,19 +240,21 @@ static char user_alpha2[2];
module_param
(
ieee80211_regdom
,
charp
,
0444
);
MODULE_PARM_DESC
(
ieee80211_regdom
,
"IEEE 802.11 regulatory domain code"
);
static
void
reg_
kfree_last_request
(
void
)
static
void
reg_
free_request
(
struct
regulatory_request
*
lr
)
{
struct
regulatory_request
*
lr
;
lr
=
get_last_request
();
if
(
lr
!=
&
core_request_world
&&
lr
)
kfree_rcu
(
lr
,
rcu_head
);
}
static
void
reg_update_last_request
(
struct
regulatory_request
*
request
)
{
reg_kfree_last_request
();
struct
regulatory_request
*
lr
;
lr
=
get_last_request
();
if
(
lr
==
request
)
return
;
reg_free_request
(
lr
);
rcu_assign_pointer
(
last_request
,
request
);
}
...
...
@@ -487,11 +485,16 @@ static inline void reg_regdb_query(const char *alpha2) {}
/*
* This lets us keep regulatory code which is updated on a regulatory
* basis in userspace. Country information is filled in by
* reg_device_uevent
* basis in userspace.
*/
static
int
call_crda
(
const
char
*
alpha2
)
{
char
country
[
12
];
char
*
env
[]
=
{
country
,
NULL
};
snprintf
(
country
,
sizeof
(
country
),
"COUNTRY=%c%c"
,
alpha2
[
0
],
alpha2
[
1
]);
if
(
!
is_world_regdom
((
char
*
)
alpha2
))
pr_info
(
"Calling CRDA for country: %c%c
\n
"
,
alpha2
[
0
],
alpha2
[
1
]);
...
...
@@ -501,7 +504,7 @@ static int call_crda(const char *alpha2)
/* query internal regulatory database (if it exists) */
reg_regdb_query
(
alpha2
);
return
kobject_uevent
(
&
reg_pdev
->
dev
.
kobj
,
KOBJ_CHANGE
);
return
kobject_uevent
_env
(
&
reg_pdev
->
dev
.
kobj
,
KOBJ_CHANGE
,
env
);
}
static
enum
reg_request_treatment
...
...
@@ -755,6 +758,9 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
power_rule
->
max_antenna_gain
=
min
(
power_rule1
->
max_antenna_gain
,
power_rule2
->
max_antenna_gain
);
intersected_rule
->
dfs_cac_ms
=
max
(
rule1
->
dfs_cac_ms
,
rule2
->
dfs_cac_ms
);
if
(
!
is_valid_reg_rule
(
intersected_rule
))
return
-
EINVAL
;
...
...
@@ -1077,6 +1083,14 @@ static void handle_channel(struct wiphy *wiphy,
min_t
(
int
,
chan
->
orig_mag
,
MBI_TO_DBI
(
power_rule
->
max_antenna_gain
));
chan
->
max_reg_power
=
(
int
)
MBM_TO_DBM
(
power_rule
->
max_eirp
);
if
(
chan
->
flags
&
IEEE80211_CHAN_RADAR
)
{
if
(
reg_rule
->
dfs_cac_ms
)
chan
->
dfs_cac_ms
=
reg_rule
->
dfs_cac_ms
;
else
chan
->
dfs_cac_ms
=
IEEE80211_DFS_MIN_CAC_TIME_MS
;
}
if
(
chan
->
orig_mpwr
)
{
/*
* Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
...
...
@@ -2255,9 +2269,9 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
const
struct
ieee80211_reg_rule
*
reg_rule
=
NULL
;
const
struct
ieee80211_freq_range
*
freq_range
=
NULL
;
const
struct
ieee80211_power_rule
*
power_rule
=
NULL
;
char
bw
[
32
];
char
bw
[
32
]
,
cac_time
[
32
]
;
pr_info
(
" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
\n
"
);
pr_info
(
" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
, (dfs_cac_time)
\n
"
);
for
(
i
=
0
;
i
<
rd
->
n_reg_rules
;
i
++
)
{
reg_rule
=
&
rd
->
reg_rules
[
i
];
...
...
@@ -2272,23 +2286,32 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
snprintf
(
bw
,
sizeof
(
bw
),
"%d KHz"
,
freq_range
->
max_bandwidth_khz
);
if
(
reg_rule
->
flags
&
NL80211_RRF_DFS
)
scnprintf
(
cac_time
,
sizeof
(
cac_time
),
"%u s"
,
reg_rule
->
dfs_cac_ms
/
1000
);
else
scnprintf
(
cac_time
,
sizeof
(
cac_time
),
"N/A"
);
/*
* There may not be documentation for max antenna gain
* in certain regions
*/
if
(
power_rule
->
max_antenna_gain
)
pr_info
(
" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm)
\n
"
,
pr_info
(
" (%d KHz - %d KHz @ %s), (%d mBi, %d mBm)
, (%s)
\n
"
,
freq_range
->
start_freq_khz
,
freq_range
->
end_freq_khz
,
bw
,
power_rule
->
max_antenna_gain
,
power_rule
->
max_eirp
);
power_rule
->
max_eirp
,
cac_time
);
else
pr_info
(
" (%d KHz - %d KHz @ %s), (N/A, %d mBm)
\n
"
,
pr_info
(
" (%d KHz - %d KHz @ %s), (N/A, %d mBm)
, (%s)
\n
"
,
freq_range
->
start_freq_khz
,
freq_range
->
end_freq_khz
,
bw
,
power_rule
->
max_eirp
);
power_rule
->
max_eirp
,
cac_time
);
}
}
...
...
@@ -2361,9 +2384,6 @@ static int reg_set_rd_user(const struct ieee80211_regdomain *rd,
{
const
struct
ieee80211_regdomain
*
intersected_rd
=
NULL
;
if
(
is_world_regdom
(
rd
->
alpha2
))
return
-
EINVAL
;
if
(
!
regdom_changes
(
rd
->
alpha2
))
return
-
EALREADY
;
...
...
@@ -2552,26 +2572,6 @@ int set_regdom(const struct ieee80211_regdomain *rd)
return
0
;
}
int
reg_device_uevent
(
struct
device
*
dev
,
struct
kobj_uevent_env
*
env
)
{
struct
regulatory_request
*
lr
;
u8
alpha2
[
2
];
bool
add
=
false
;
rcu_read_lock
();
lr
=
get_last_request
();
if
(
lr
&&
!
lr
->
processed
)
{
memcpy
(
alpha2
,
lr
->
alpha2
,
2
);
add
=
true
;
}
rcu_read_unlock
();
if
(
add
)
return
add_uevent_var
(
env
,
"COUNTRY=%c%c"
,
alpha2
[
0
],
alpha2
[
1
]);
return
0
;
}
void
wiphy_regulatory_register
(
struct
wiphy
*
wiphy
)
{
struct
regulatory_request
*
lr
;
...
...
@@ -2622,8 +2622,6 @@ int __init regulatory_init(void)
if
(
IS_ERR
(
reg_pdev
))
return
PTR_ERR
(
reg_pdev
);
reg_pdev
->
dev
.
type
=
&
reg_device_type
;
spin_lock_init
(
&
reg_requests_lock
);
spin_lock_init
(
&
reg_pending_beacons_lock
);
...
...
net/wireless/reg.h
View file @
7eb2450a
...
...
@@ -26,7 +26,6 @@ enum nl80211_dfs_regions reg_get_dfs_region(struct wiphy *wiphy);
int
regulatory_hint_user
(
const
char
*
alpha2
,
enum
nl80211_user_reg_hint_type
user_reg_hint_type
);
int
reg_device_uevent
(
struct
device
*
dev
,
struct
kobj_uevent_env
*
env
);
void
wiphy_regulatory_register
(
struct
wiphy
*
wiphy
);
void
wiphy_regulatory_deregister
(
struct
wiphy
*
wiphy
);
...
...
net/wireless/scan.c
View file @
7eb2450a
...
...
@@ -659,9 +659,6 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
continue
;
if
(
ssidlen
&&
ie
[
1
]
!=
ssidlen
)
continue
;
/* that would be odd ... */
if
(
bss
->
pub
.
beacon_ies
)
continue
;
if
(
WARN_ON_ONCE
(
bss
->
pub
.
hidden_beacon_bss
))
continue
;
if
(
WARN_ON_ONCE
(
!
list_empty
(
&
bss
->
hidden_list
)))
...
...
@@ -680,7 +677,8 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
/* Returned bss is reference counted and must be cleaned up appropriately. */
static
struct
cfg80211_internal_bss
*
cfg80211_bss_update
(
struct
cfg80211_registered_device
*
dev
,
struct
cfg80211_internal_bss
*
tmp
)
struct
cfg80211_internal_bss
*
tmp
,
bool
signal_valid
)
{
struct
cfg80211_internal_bss
*
found
=
NULL
;
...
...
@@ -765,7 +763,12 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
}
found
->
pub
.
beacon_interval
=
tmp
->
pub
.
beacon_interval
;
found
->
pub
.
signal
=
tmp
->
pub
.
signal
;
/*
* don't update the signal if beacon was heard on
* adjacent channel.
*/
if
(
signal_valid
)
found
->
pub
.
signal
=
tmp
->
pub
.
signal
;
found
->
pub
.
capability
=
tmp
->
pub
.
capability
;
found
->
ts
=
tmp
->
ts
;
}
else
{
...
...
@@ -869,13 +872,14 @@ cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
/* Returned bss is reference counted and must be cleaned up appropriately. */
struct
cfg80211_bss
*
cfg80211_inform_bss_width
(
struct
wiphy
*
wiphy
,
struct
ieee80211_channel
*
channel
,
struct
ieee80211_channel
*
rx_
channel
,
enum
nl80211_bss_scan_width
scan_width
,
const
u8
*
bssid
,
u64
tsf
,
u16
capability
,
u16
beacon_interval
,
const
u8
*
ie
,
size_t
ielen
,
s32
signal
,
gfp_t
gfp
)
{
struct
cfg80211_bss_ies
*
ies
;
struct
ieee80211_channel
*
channel
;
struct
cfg80211_internal_bss
tmp
=
{},
*
res
;
if
(
WARN_ON
(
!
wiphy
))
...
...
@@ -885,7 +889,7 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
(
signal
<
0
||
signal
>
100
)))
return
NULL
;
channel
=
cfg80211_get_bss_channel
(
wiphy
,
ie
,
ielen
,
channel
);
channel
=
cfg80211_get_bss_channel
(
wiphy
,
ie
,
ielen
,
rx_
channel
);
if
(
!
channel
)
return
NULL
;
...
...
@@ -913,7 +917,8 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
rcu_assign_pointer
(
tmp
.
pub
.
beacon_ies
,
ies
);
rcu_assign_pointer
(
tmp
.
pub
.
ies
,
ies
);
res
=
cfg80211_bss_update
(
wiphy_to_dev
(
wiphy
),
&
tmp
);
res
=
cfg80211_bss_update
(
wiphy_to_dev
(
wiphy
),
&
tmp
,
rx_channel
==
channel
);
if
(
!
res
)
return
NULL
;
...
...
@@ -929,20 +934,21 @@ EXPORT_SYMBOL(cfg80211_inform_bss_width);
/* Returned bss is reference counted and must be cleaned up appropriately. */
struct
cfg80211_bss
*
cfg80211_inform_bss_width_frame
(
struct
wiphy
*
wiphy
,
struct
ieee80211_channel
*
channel
,
struct
ieee80211_channel
*
rx_
channel
,
enum
nl80211_bss_scan_width
scan_width
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
,
s32
signal
,
gfp_t
gfp
)
{
struct
cfg80211_internal_bss
tmp
=
{},
*
res
;
struct
cfg80211_bss_ies
*
ies
;
struct
ieee80211_channel
*
channel
;
size_t
ielen
=
len
-
offsetof
(
struct
ieee80211_mgmt
,
u
.
probe_resp
.
variable
);
BUILD_BUG_ON
(
offsetof
(
struct
ieee80211_mgmt
,
u
.
probe_resp
.
variable
)
!=
offsetof
(
struct
ieee80211_mgmt
,
u
.
beacon
.
variable
));
trace_cfg80211_inform_bss_width_frame
(
wiphy
,
channel
,
scan_width
,
mgmt
,
trace_cfg80211_inform_bss_width_frame
(
wiphy
,
rx_
channel
,
scan_width
,
mgmt
,
len
,
signal
);
if
(
WARN_ON
(
!
mgmt
))
...
...
@@ -959,7 +965,7 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
return
NULL
;
channel
=
cfg80211_get_bss_channel
(
wiphy
,
mgmt
->
u
.
beacon
.
variable
,
ielen
,
channel
);
ielen
,
rx_
channel
);
if
(
!
channel
)
return
NULL
;
...
...
@@ -983,7 +989,8 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
tmp
.
pub
.
beacon_interval
=
le16_to_cpu
(
mgmt
->
u
.
probe_resp
.
beacon_int
);
tmp
.
pub
.
capability
=
le16_to_cpu
(
mgmt
->
u
.
probe_resp
.
capab_info
);
res
=
cfg80211_bss_update
(
wiphy_to_dev
(
wiphy
),
&
tmp
);
res
=
cfg80211_bss_update
(
wiphy_to_dev
(
wiphy
),
&
tmp
,
rx_channel
==
channel
);
if
(
!
res
)
return
NULL
;
...
...
net/wireless/sme.c
View file @
7eb2450a
...
...
@@ -64,7 +64,6 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
int
n_channels
,
err
;
ASSERT_RTNL
();
ASSERT_RDEV_LOCK
(
rdev
);
ASSERT_WDEV_LOCK
(
wdev
);
if
(
rdev
->
scan_req
||
rdev
->
scan_msg
)
...
...
net/wireless/util.c
View file @
7eb2450a
...
...
@@ -838,7 +838,6 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
struct
wireless_dev
*
wdev
;
ASSERT_RTNL
();
ASSERT_RDEV_LOCK
(
rdev
);
list_for_each_entry
(
wdev
,
&
rdev
->
wdev_list
,
list
)
cfg80211_process_wdev_events
(
wdev
);
...
...
@@ -851,7 +850,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
int
err
;
enum
nl80211_iftype
otype
=
dev
->
ieee80211_ptr
->
iftype
;
ASSERT_R
DEV_LOCK
(
rdev
);
ASSERT_R
TNL
(
);
/* don't support changing VLANs, you just re-create them */
if
(
otype
==
NL80211_IFTYPE_AP_VLAN
)
...
...
@@ -886,7 +885,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
switch
(
otype
)
{
case
NL80211_IFTYPE_AP
:
cfg80211_stop_ap
(
rdev
,
dev
);
cfg80211_stop_ap
(
rdev
,
dev
,
true
);
break
;
case
NL80211_IFTYPE_ADHOC
:
cfg80211_leave_ibss
(
rdev
,
dev
,
false
);
...
...
net/wireless/wext-sme.c
View file @
7eb2450a
...
...
@@ -21,7 +21,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
const
u8
*
prev_bssid
=
NULL
;
int
err
,
i
;
ASSERT_R
DEV_LOCK
(
rdev
);
ASSERT_R
TNL
(
);
ASSERT_WDEV_LOCK
(
wdev
);
if
(
!
netif_running
(
wdev
->
netdev
))
...
...
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