Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
933faa43
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 3 年多
通知
13
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
933faa43
编写于
5月 29, 2013
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
上级
531efffc
6abb9cb9
变更
47
展开全部
隐藏空白更改
内联
并排
Showing
47 changed file
with
1007 addition
and
1388 deletion
+1007
-1388
Documentation/DocBook/80211.tmpl
Documentation/DocBook/80211.tmpl
+0
-2
drivers/net/wireless/iwlegacy/commands.h
drivers/net/wireless/iwlegacy/commands.h
+0
-8
drivers/net/wireless/iwlwifi/dvm/commands.h
drivers/net/wireless/iwlwifi/dvm/commands.h
+0
-8
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/mvm/mac80211.c
+1
-13
drivers/net/wireless/iwlwifi/pcie/tx.c
drivers/net/wireless/iwlwifi/pcie/tx.c
+3
-3
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mac80211_hwsim.c
+10
-12
include/linux/ieee80211.h
include/linux/ieee80211.h
+9
-0
include/net/cfg80211.h
include/net/cfg80211.h
+55
-31
include/net/ieee80211_radiotap.h
include/net/ieee80211_radiotap.h
+7
-0
include/net/mac80211.h
include/net/mac80211.h
+20
-6
include/uapi/linux/nl80211.h
include/uapi/linux/nl80211.h
+20
-0
net/mac80211/aes_ccm.c
net/mac80211/aes_ccm.c
+3
-3
net/mac80211/cfg.c
net/mac80211/cfg.c
+15
-5
net/mac80211/debugfs_netdev.c
net/mac80211/debugfs_netdev.c
+8
-7
net/mac80211/ht.c
net/mac80211/ht.c
+2
-2
net/mac80211/ibss.c
net/mac80211/ibss.c
+22
-27
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+21
-8
net/mac80211/iface.c
net/mac80211/iface.c
+17
-1
net/mac80211/key.c
net/mac80211/key.c
+12
-12
net/mac80211/key.h
net/mac80211/key.h
+2
-13
net/mac80211/main.c
net/mac80211/main.c
+2
-2
net/mac80211/mesh.c
net/mac80211/mesh.c
+19
-19
net/mac80211/mesh_plink.c
net/mac80211/mesh_plink.c
+6
-1
net/mac80211/mlme.c
net/mac80211/mlme.c
+175
-235
net/mac80211/rate.c
net/mac80211/rate.c
+8
-1
net/mac80211/rx.c
net/mac80211/rx.c
+27
-6
net/mac80211/sta_info.c
net/mac80211/sta_info.c
+2
-0
net/mac80211/sta_info.h
net/mac80211/sta_info.h
+5
-0
net/mac80211/tkip.c
net/mac80211/tkip.c
+2
-2
net/mac80211/util.c
net/mac80211/util.c
+9
-28
net/mac80211/wep.c
net/mac80211/wep.c
+25
-23
net/mac80211/wpa.c
net/mac80211/wpa.c
+36
-32
net/wireless/core.c
net/wireless/core.c
+54
-183
net/wireless/core.h
net/wireless/core.h
+19
-74
net/wireless/debugfs.c
net/wireless/debugfs.c
+2
-2
net/wireless/ibss.c
net/wireless/ibss.c
+2
-8
net/wireless/mesh.c
net/wireless/mesh.c
+1
-2
net/wireless/mlme.c
net/wireless/mlme.c
+53
-163
net/wireless/nl80211.c
net/wireless/nl80211.c
+159
-187
net/wireless/reg.c
net/wireless/reg.c
+44
-92
net/wireless/scan.c
net/wireless/scan.c
+30
-17
net/wireless/sme.c
net/wireless/sme.c
+36
-77
net/wireless/sysfs.c
net/wireless/sysfs.c
+6
-2
net/wireless/trace.h
net/wireless/trace.h
+15
-12
net/wireless/util.c
net/wireless/util.c
+28
-11
net/wireless/wext-compat.c
net/wireless/wext-compat.c
+4
-18
net/wireless/wext-sme.c
net/wireless/wext-sme.c
+11
-30
未找到文件。
Documentation/DocBook/80211.tmpl
浏览文件 @
933faa43
...
...
@@ -132,9 +132,7 @@
!Finclude/net/cfg80211.h cfg80211_send_rx_assoc
!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
!Finclude/net/cfg80211.h cfg80211_send_deauth
!Finclude/net/cfg80211.h __cfg80211_send_deauth
!Finclude/net/cfg80211.h cfg80211_send_disassoc
!Finclude/net/cfg80211.h __cfg80211_send_disassoc
!Finclude/net/cfg80211.h cfg80211_ibss_joined
!Finclude/net/cfg80211.h cfg80211_connect_result
!Finclude/net/cfg80211.h cfg80211_roamed
...
...
drivers/net/wireless/iwlegacy/commands.h
浏览文件 @
933faa43
...
...
@@ -1347,14 +1347,6 @@ struct il_rx_mpdu_res_start {
#define TX_CMD_SEC_SHIFT 6
#define TX_CMD_SEC_KEY128 0x08
/*
* security overhead sizes
*/
#define WEP_IV_LEN 4
#define WEP_ICV_LEN 4
#define CCMP_MIC_LEN 8
#define TKIP_ICV_LEN 4
/*
* C_TX = 0x1c (command)
*/
...
...
drivers/net/wireless/iwlwifi/dvm/commands.h
浏览文件 @
933faa43
...
...
@@ -1220,14 +1220,6 @@ struct iwl_rx_mpdu_res_start {
#define TX_CMD_SEC_SHIFT 6
#define TX_CMD_SEC_KEY128 0x08
/*
* security overhead sizes
*/
#define WEP_IV_LEN 4
#define WEP_ICV_LEN 4
#define CCMP_MIC_LEN 8
#define TKIP_ICV_LEN 4
/*
* REPLY_TX = 0x1c (command)
*/
...
...
drivers/net/wireless/iwlwifi/mvm/mac80211.c
浏览文件 @
933faa43
...
...
@@ -84,15 +84,6 @@ static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
.
types
=
BIT
(
NL80211_IFTYPE_STATION
)
|
BIT
(
NL80211_IFTYPE_AP
),
},
{
.
max
=
1
,
.
types
=
BIT
(
NL80211_IFTYPE_P2P_CLIENT
)
|
BIT
(
NL80211_IFTYPE_P2P_GO
),
},
{
.
max
=
1
,
.
types
=
BIT
(
NL80211_IFTYPE_P2P_DEVICE
),
},
};
static
const
struct
ieee80211_iface_combination
iwl_mvm_iface_combinations
[]
=
{
...
...
@@ -173,10 +164,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
hw
->
chanctx_data_size
=
sizeof
(
u16
);
hw
->
wiphy
->
interface_modes
=
BIT
(
NL80211_IFTYPE_STATION
)
|
BIT
(
NL80211_IFTYPE_P2P_CLIENT
)
|
BIT
(
NL80211_IFTYPE_AP
)
|
BIT
(
NL80211_IFTYPE_P2P_GO
)
|
BIT
(
NL80211_IFTYPE_P2P_DEVICE
);
BIT
(
NL80211_IFTYPE_AP
);
hw
->
wiphy
->
flags
|=
WIPHY_FLAG_CUSTOM_REGULATORY
|
WIPHY_FLAG_DISABLE_BEACON_HINTS
|
...
...
drivers/net/wireless/iwlwifi/pcie/tx.c
浏览文件 @
933faa43
...
...
@@ -224,13 +224,13 @@ static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
switch
(
sec_ctl
&
TX_CMD_SEC_MSK
)
{
case
TX_CMD_SEC_CCM
:
len
+=
CCMP_MIC_LEN
;
len
+=
IEEE80211_
CCMP_MIC_LEN
;
break
;
case
TX_CMD_SEC_TKIP
:
len
+=
TKIP_ICV_LEN
;
len
+=
IEEE80211_
TKIP_ICV_LEN
;
break
;
case
TX_CMD_SEC_WEP
:
len
+=
WEP_IV_LEN
+
WEP_ICV_LEN
;
len
+=
IEEE80211_WEP_IV_LEN
+
IEEE80211_
WEP_ICV_LEN
;
break
;
}
...
...
drivers/net/wireless/mac80211_hwsim.c
浏览文件 @
933faa43
...
...
@@ -1723,11 +1723,11 @@ static void mac80211_hwsim_free(void)
class_destroy
(
hwsim_class
);
}
static
struct
device_driver
mac80211_hwsim_
driver
=
{
.
name
=
"mac80211_hwsim"
,
.
bus
=
&
platform_bus_type
,
.
owner
=
THIS_MODULE
,
static
struct
platform_driver
mac80211_hwsim_driver
=
{
.
driver
=
{
.
name
=
"mac80211_hwsim"
,
.
owner
=
THIS_MODULE
,
}
,
};
static
const
struct
net_device_ops
hwsim_netdev_ops
=
{
...
...
@@ -2169,7 +2169,6 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
#endif
BIT
(
NL80211_IFTYPE_AP
)
|
BIT
(
NL80211_IFTYPE_P2P_GO
)
},
{
.
max
=
1
,
.
types
=
BIT
(
NL80211_IFTYPE_P2P_DEVICE
)
},
};
static
struct
ieee80211_iface_combination
hwsim_if_comb
=
{
...
...
@@ -2219,7 +2218,7 @@ static int __init init_mac80211_hwsim(void)
spin_lock_init
(
&
hwsim_radio_lock
);
INIT_LIST_HEAD
(
&
hwsim_radios
);
err
=
driver_register
(
&
mac80211_hwsim_driver
);
err
=
platform_
driver_register
(
&
mac80211_hwsim_driver
);
if
(
err
)
return
err
;
...
...
@@ -2254,7 +2253,7 @@ static int __init init_mac80211_hwsim(void)
err
=
-
ENOMEM
;
goto
failed_drvdata
;
}
data
->
dev
->
driver
=
&
mac80211_hwsim_driver
;
data
->
dev
->
driver
=
&
mac80211_hwsim_driver
.
driver
;
err
=
device_bind_driver
(
data
->
dev
);
if
(
err
!=
0
)
{
printk
(
KERN_DEBUG
...
...
@@ -2295,8 +2294,7 @@ static int __init init_mac80211_hwsim(void)
BIT
(
NL80211_IFTYPE_P2P_CLIENT
)
|
BIT
(
NL80211_IFTYPE_P2P_GO
)
|
BIT
(
NL80211_IFTYPE_ADHOC
)
|
BIT
(
NL80211_IFTYPE_MESH_POINT
)
|
BIT
(
NL80211_IFTYPE_P2P_DEVICE
);
BIT
(
NL80211_IFTYPE_MESH_POINT
);
hw
->
flags
=
IEEE80211_HW_MFP_CAPABLE
|
IEEE80211_HW_SIGNAL_DBM
|
...
...
@@ -2564,7 +2562,7 @@ static int __init init_mac80211_hwsim(void)
failed:
mac80211_hwsim_free
();
failed_unregister_driver:
driver_unregister
(
&
mac80211_hwsim_driver
);
platform_
driver_unregister
(
&
mac80211_hwsim_driver
);
return
err
;
}
module_init
(
init_mac80211_hwsim
);
...
...
@@ -2577,6 +2575,6 @@ static void __exit exit_mac80211_hwsim(void)
mac80211_hwsim_free
();
unregister_netdev
(
hwsim_mon
);
driver_unregister
(
&
mac80211_hwsim_driver
);
platform_
driver_unregister
(
&
mac80211_hwsim_driver
);
}
module_exit
(
exit_mac80211_hwsim
);
include/linux/ieee80211.h
浏览文件 @
933faa43
...
...
@@ -1829,6 +1829,15 @@ enum ieee80211_key_len {
WLAN_KEY_LEN_AES_CMAC
=
16
,
};
#define IEEE80211_WEP_IV_LEN 4
#define IEEE80211_WEP_ICV_LEN 4
#define IEEE80211_CCMP_HDR_LEN 8
#define IEEE80211_CCMP_MIC_LEN 8
#define IEEE80211_CCMP_PN_LEN 6
#define IEEE80211_TKIP_IV_LEN 8
#define IEEE80211_TKIP_ICV_LEN 4
#define IEEE80211_CMAC_PN_LEN 6
/* Public action codes */
enum
ieee80211_pub_actioncode
{
WLAN_PUB_ACTION_EXT_CHANSW_ANN
=
4
,
...
...
include/net/cfg80211.h
浏览文件 @
933faa43
...
...
@@ -753,6 +753,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
* @STATION_INFO_LOCAL_PM: @local_pm filled
* @STATION_INFO_PEER_PM: @peer_pm filled
* @STATION_INFO_NONPEER_PM: @nonpeer_pm filled
* @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled
* @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled
*/
enum
station_info_flags
{
STATION_INFO_INACTIVE_TIME
=
1
<<
0
,
...
...
@@ -781,6 +783,8 @@ enum station_info_flags {
STATION_INFO_NONPEER_PM
=
1
<<
23
,
STATION_INFO_RX_BYTES64
=
1
<<
24
,
STATION_INFO_TX_BYTES64
=
1
<<
25
,
STATION_INFO_CHAIN_SIGNAL
=
1
<<
26
,
STATION_INFO_CHAIN_SIGNAL_AVG
=
1
<<
27
,
};
/**
...
...
@@ -857,6 +861,8 @@ struct sta_bss_parameters {
u16
beacon_interval
;
};
#define IEEE80211_MAX_CHAINS 4
/**
* struct station_info - station information
*
...
...
@@ -874,6 +880,9 @@ struct sta_bss_parameters {
* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
* @signal_avg: Average signal strength, type depends on the wiphy's signal_type.
* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_.
* @chains: bitmask for filled values in @chain_signal, @chain_signal_avg
* @chain_signal: per-chain signal strength of last received packet in dBm
* @chain_signal_avg: per-chain signal strength average in dBm
* @txrate: current unicast bitrate from this station
* @rxrate: current unicast bitrate to this station
* @rx_packets: packets received from this station
...
...
@@ -909,6 +918,11 @@ struct station_info {
u8
plink_state
;
s8
signal
;
s8
signal_avg
;
u8
chains
;
s8
chain_signal
[
IEEE80211_MAX_CHAINS
];
s8
chain_signal_avg
[
IEEE80211_MAX_CHAINS
];
struct
rate_info
txrate
;
struct
rate_info
rxrate
;
u32
rx_packets
;
...
...
@@ -1147,6 +1161,7 @@ struct mesh_config {
* @sync_method: which synchronization method to use
* @path_sel_proto: which path selection protocol to use
* @path_metric: which metric to use
* @auth_id: which authentication method this mesh is using
* @ie: vendor information elements (optional)
* @ie_len: length of vendor information elements
* @is_authenticated: this mesh requires authentication
...
...
@@ -1165,6 +1180,7 @@ struct mesh_setup {
u8
sync_method
;
u8
path_sel_proto
;
u8
path_metric
;
u8
auth_id
;
const
u8
*
ie
;
u8
ie_len
;
bool
is_authenticated
;
...
...
@@ -1241,6 +1257,7 @@ struct cfg80211_ssid {
* @scan_start: time (in jiffies) when the scan started
* @wdev: the wireless device to scan for
* @aborted: (internal) scan request was notified as aborted
* @notified: (internal) scan request was notified as done or aborted
* @no_cck: used to send probe requests at non CCK rate in 2GHz band
*/
struct
cfg80211_scan_request
{
...
...
@@ -1258,7 +1275,7 @@ struct cfg80211_scan_request {
/* internal */
struct
wiphy
*
wiphy
;
unsigned
long
scan_start
;
bool
aborted
;
bool
aborted
,
notified
;
bool
no_cck
;
/* keep last */
...
...
@@ -1850,7 +1867,9 @@ struct cfg80211_update_ft_ies_params {
* @get_mpath: get a mesh path for the given parameters
* @dump_mpath: dump mesh path callback -- resume dump at index @idx
* @join_mesh: join the mesh network with the specified parameters
* (invoked with the wireless_dev mutex held)
* @leave_mesh: leave the current mesh network
* (invoked with the wireless_dev mutex held)
*
* @get_mesh_config: Get the current mesh configuration
*
...
...
@@ -1877,20 +1896,28 @@ struct cfg80211_update_ft_ies_params {
* the scan/scan_done bracket too.
*
* @auth: Request to authenticate with the specified peer
* (invoked with the wireless_dev mutex held)
* @assoc: Request to (re)associate with the specified peer
* (invoked with the wireless_dev mutex held)
* @deauth: Request to deauthenticate from the specified peer
* (invoked with the wireless_dev mutex held)
* @disassoc: Request to disassociate from the specified peer
* (invoked with the wireless_dev mutex held)
*
* @connect: Connect to the ESS with the specified parameters. When connected,
* call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
* If the connection fails for some reason, call cfg80211_connect_result()
* with the status from the AP.
* (invoked with the wireless_dev mutex held)
* @disconnect: Disconnect from the BSS/ESS.
* (invoked with the wireless_dev mutex held)
*
* @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
* cfg80211_ibss_joined(), also call that function when changing BSSID due
* to a merge.
* (invoked with the wireless_dev mutex held)
* @leave_ibss: Leave the IBSS.
* (invoked with the wireless_dev mutex held)
*
* @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or
* MESH mode)
...
...
@@ -2556,6 +2583,9 @@ struct wiphy_wowlan_support {
* may request, if implemented.
*
* @wowlan: WoWLAN support information
* @wowlan_config: current WoWLAN configuration; this should usually not be
* used since access to it is necessarily racy, use the parameter passed
* to the suspend() operation instead.
*
* @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.
* @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden.
...
...
@@ -2623,6 +2653,7 @@ struct wiphy {
#ifdef CONFIG_PM
struct
wiphy_wowlan_support
wowlan
;
struct
cfg80211_wowlan
*
wowlan_config
;
#endif
u16
max_remain_on_channel_duration
;
...
...
@@ -2834,7 +2865,8 @@ struct cfg80211_cached_keys;
* by cfg80211 on change_interface
* @mgmt_registrations: list of registrations for management frames
* @mgmt_registrations_lock: lock for the list
* @mtx: mutex used to lock data in this struct
* @mtx: mutex used to lock data in this struct, may be used by drivers
* and some API functions require it held
* @cleanup_work: work struct used for cleanup that can't be done directly
* @beacon_interval: beacon interval used on this device for transmitting
* beacons, 0 when not valid
...
...
@@ -2858,8 +2890,6 @@ struct wireless_dev {
struct
mutex
mtx
;
struct
work_struct
cleanup_work
;
bool
use_4addr
,
p2p_started
;
u8
address
[
ETH_ALEN
]
__aligned
(
sizeof
(
u16
));
...
...
@@ -2989,6 +3019,15 @@ struct ieee80211_rate *
ieee80211_get_response_rate
(
struct
ieee80211_supported_band
*
sband
,
u32
basic_rates
,
int
bitrate
);
/**
* ieee80211_mandatory_rates - get mandatory rates for a given band
* @sband: the band to look for rates in
*
* This function returns a bitmap of the mandatory rates for the given
* band, bits are set according to the rate position in the bitrates array.
*/
u32
ieee80211_mandatory_rates
(
struct
ieee80211_supported_band
*
sband
);
/*
* Radiotap parsing functions -- for controlled injection support
*
...
...
@@ -3400,7 +3439,8 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
* This function is called whenever an authentication has been processed in
* station mode. The driver is required to call either this function or
* cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth()
* call. This function may sleep.
* call. This function may sleep. The caller must hold the corresponding wdev's
* mutex.
*/
void
cfg80211_send_rx_auth
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
);
...
...
@@ -3409,7 +3449,8 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
* @dev: network device
* @addr: The MAC address of the device with which the authentication timed out
*
* This function may sleep.
* This function may sleep. The caller must hold the corresponding wdev's
* mutex.
*/
void
cfg80211_send_auth_timeout
(
struct
net_device
*
dev
,
const
u8
*
addr
);
...
...
@@ -3424,7 +3465,8 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
* This function is called whenever a (re)association response has been
* processed in station mode. The driver is required to call either this
* function or cfg80211_send_assoc_timeout() to indicate the result of
* cfg80211_ops::assoc() call. This function may sleep.
* cfg80211_ops::assoc() call. This function may sleep. The caller must hold
* the corresponding wdev's mutex.
*/
void
cfg80211_send_rx_assoc
(
struct
net_device
*
dev
,
struct
cfg80211_bss
*
bss
,
const
u8
*
buf
,
size_t
len
);
...
...
@@ -3434,7 +3476,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
* @dev: network device
* @addr: The MAC address of the device with which the association timed out
*
* This function may sleep.
* This function may sleep.
The caller must hold the corresponding wdev's mutex.
*/
void
cfg80211_send_assoc_timeout
(
struct
net_device
*
dev
,
const
u8
*
addr
);
...
...
@@ -3446,20 +3488,11 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
*
* This function is called whenever deauthentication has been processed in
* station mode. This includes both received deauthentication frames and
* locally generated ones. This function may sleep.
* locally generated ones. This function may sleep. The caller must hold the
* corresponding wdev's mutex.
*/
void
cfg80211_send_deauth
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
);
/**
* __cfg80211_send_deauth - notification of processed deauthentication
* @dev: network device
* @buf: deauthentication frame (header + body)
* @len: length of the frame data
*
* Like cfg80211_send_deauth(), but doesn't take the wdev lock.
*/
void
__cfg80211_send_deauth
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
);
/**
* cfg80211_send_disassoc - notification of processed disassociation
* @dev: network device
...
...
@@ -3468,21 +3501,11 @@ void __cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
*
* This function is called whenever disassociation has been processed in
* station mode. This includes both received disassociation frames and locally
* generated ones. This function may sleep.
* generated ones. This function may sleep. The caller must hold the
* corresponding wdev's mutex.
*/
void
cfg80211_send_disassoc
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
);
/**
* __cfg80211_send_disassoc - notification of processed disassociation
* @dev: network device
* @buf: disassociation response frame (header + body)
* @len: length of the frame data
*
* Like cfg80211_send_disassoc(), but doesn't take the wdev lock.
*/
void
__cfg80211_send_disassoc
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
);
/**
* cfg80211_send_unprot_deauth - notification of unprotected deauthentication
* @dev: network device
...
...
@@ -4153,6 +4176,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
* cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver.
*
* @wdev: the wireless device for which critical protocol is stopped.
* @gfp: allocation flags
*
* This function can be called by the driver to indicate it has reverted
* operation back to normal. One reason could be that the duration given
...
...
include/net/ieee80211_radiotap.h
浏览文件 @
933faa43
...
...
@@ -269,6 +269,7 @@ enum ieee80211_radiotap_type {
#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04
#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08
#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10
#define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20
#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03
#define IEEE80211_RADIOTAP_MCS_BW_20 0
...
...
@@ -278,6 +279,12 @@ enum ieee80211_radiotap_type {
#define IEEE80211_RADIOTAP_MCS_SGI 0x04
#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08
#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10
#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60
#define IEEE80211_RADIOTAP_MCS_STBC_1 1
#define IEEE80211_RADIOTAP_MCS_STBC_2 2
#define IEEE80211_RADIOTAP_MCS_STBC_3 3
#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5
/* For IEEE80211_RADIOTAP_AMPDU_STATUS */
#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001
...
...
include/net/mac80211.h
浏览文件 @
933faa43
...
...
@@ -805,6 +805,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* on this subframe
* @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
* is stored in the @ampdu_delimiter_crc field)
* @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
*/
enum
mac80211_rx_flags
{
RX_FLAG_MMIC_ERROR
=
BIT
(
0
),
...
...
@@ -832,8 +833,11 @@ enum mac80211_rx_flags {
RX_FLAG_80MHZ
=
BIT
(
23
),
RX_FLAG_80P80MHZ
=
BIT
(
24
),
RX_FLAG_160MHZ
=
BIT
(
25
),
RX_FLAG_STBC_MASK
=
BIT
(
26
)
|
BIT
(
27
),
};
#define RX_FLAG_STBC_SHIFT 26
/**
* struct ieee80211_rx_status - receive status
*
...
...
@@ -850,6 +854,10 @@ enum mac80211_rx_flags {
* @signal: signal strength when receiving this frame, either in dBm, in dB or
* unspecified depending on the hardware capabilities flags
* @IEEE80211_HW_SIGNAL_*
* @chains: bitmask of receive chains for which separate signal strength
* values were filled.
* @chain_signal: per-chain signal strength, in dBm (unlike @signal, doesn't
* support dB or unspecified units)
* @antenna: antenna used
* @rate_idx: index of data rate into band's supported rates or MCS index if
* HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
...
...
@@ -881,6 +889,8 @@ struct ieee80211_rx_status {
u8
band
;
u8
antenna
;
s8
signal
;
u8
chains
;
s8
chain_signal
[
IEEE80211_MAX_CHAINS
];
u8
ampdu_delimiter_crc
;
u8
vendor_radiotap_align
;
u8
vendor_radiotap_oui
[
3
];
...
...
@@ -1235,7 +1245,7 @@ enum ieee80211_sta_rx_bandwidth {
* struct ieee80211_sta_rates - station rate selection table
*
* @rcu_head: RCU head used for freeing the table on update
* @rate
s
: transmit rates/flags to be used by default.
* @rate: transmit rates/flags to be used by default.
* Overriding entries per-packet is possible by using cb tx control.
*/
struct
ieee80211_sta_rates
{
...
...
@@ -1276,7 +1286,7 @@ struct ieee80211_sta_rates {
* notifications and capabilities. The value is only valid after
* the station moves to associated state.
* @smps_mode: current SMPS mode (off, static or dynamic)
* @
tx_
rates: rate control selection table
* @rates: rate control selection table
*/
struct
ieee80211_sta
{
u32
supp_rates
[
IEEE80211_NUM_BANDS
];
...
...
@@ -3043,7 +3053,8 @@ void ieee80211_napi_complete(struct ieee80211_hw *hw);
* This function may not be called in IRQ context. Calls to this function
* for a single hardware must be synchronized against each other. Calls to
* this function, ieee80211_rx_ni() and ieee80211_rx_irqsafe() may not be
* mixed for a single hardware.
* mixed for a single hardware. Must not run concurrently with
* ieee80211_tx_status() or ieee80211_tx_status_ni().
*
* In process context use instead ieee80211_rx_ni().
*
...
...
@@ -3059,7 +3070,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb);
* (internally defers to a tasklet.)
*
* Calls to this function, ieee80211_rx() or ieee80211_rx_ni() may not
* be mixed for a single hardware.
* be mixed for a single hardware.Must not run concurrently with
* ieee80211_tx_status() or ieee80211_tx_status_ni().
*
* @hw: the hardware this frame came in on
* @skb: the buffer to receive, owned by mac80211 after this call
...
...
@@ -3073,7 +3085,8 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb);
* (internally disables bottom halves).
*
* Calls to this function, ieee80211_rx() and ieee80211_rx_irqsafe() may
* not be mixed for a single hardware.
* not be mixed for a single hardware. Must not run concurrently with
* ieee80211_tx_status() or ieee80211_tx_status_ni().
*
* @hw: the hardware this frame came in on
* @skb: the buffer to receive, owned by mac80211 after this call
...
...
@@ -3196,7 +3209,8 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
* This function may not be called in IRQ context. Calls to this function
* for a single hardware must be synchronized against each other. Calls
* to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
* may not be mixed for a single hardware.
* may not be mixed for a single hardware. Must not run concurrently with
* ieee80211_rx() or ieee80211_rx_ni().
*
* @hw: the hardware the frame was transmitted by
* @skb: the frame that was transmitted, owned by mac80211 after this call
...
...
include/uapi/linux/nl80211.h
浏览文件 @
933faa43
...
...
@@ -27,6 +27,8 @@
#include <linux/types.h>
#define NL80211_GENL_NAME "nl80211"
/**
* DOC: Station handling
*
...
...
@@ -1429,6 +1431,11 @@ enum nl80211_commands {
* @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which
* the connection should have increased reliability (u16).
*
* @NL80211_ATTR_PEER_AID: Association ID for the peer TDLS station (u16).
* This is similar to @NL80211_ATTR_STA_AID but with a difference of being
* allowed to be used with the first @NL80211_CMD_SET_STATION command to
* update a TDLS peer STA entry.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
...
...
@@ -1727,6 +1734,8 @@ enum nl80211_attrs {
NL80211_ATTR_CRIT_PROT_ID
,
NL80211_ATTR_MAX_CRIT_PROT_DURATION
,
NL80211_ATTR_PEER_AID
,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST
,
...
...
@@ -1991,6 +2000,10 @@ enum nl80211_sta_bss_param {
* @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode
* @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards
* non-peer STA
* @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU
* Contains a nested array of signal strength attributes (u8, dBm)
* @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
* Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
* @__NL80211_STA_INFO_AFTER_LAST: internal
* @NL80211_STA_INFO_MAX: highest possible station info attribute
*/
...
...
@@ -2020,6 +2033,8 @@ enum nl80211_sta_info {
NL80211_STA_INFO_NONPEER_PM
,
NL80211_STA_INFO_RX_BYTES64
,
NL80211_STA_INFO_TX_BYTES64
,
NL80211_STA_INFO_CHAIN_SIGNAL
,
NL80211_STA_INFO_CHAIN_SIGNAL_AVG
,
/* keep last */
__NL80211_STA_INFO_AFTER_LAST
,
...
...
@@ -2637,6 +2652,10 @@ enum nl80211_meshconf_params {
* @NL80211_MESH_SETUP_USERSPACE_MPM: Enable this option if userspace will
* implement an MPM which handles peer allocation and state.
*
* @NL80211_MESH_SETUP_AUTH_PROTOCOL: Inform the kernel of the authentication
* method (u8, as defined in IEEE 8.4.2.100.6, e.g. 0x1 for SAE).
* Default is no authentication method required.
*
* @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number
*
* @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use
...
...
@@ -2650,6 +2669,7 @@ enum nl80211_mesh_setup_params {
NL80211_MESH_SETUP_USERSPACE_AMPE
,
NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC
,
NL80211_MESH_SETUP_USERSPACE_MPM
,
NL80211_MESH_SETUP_AUTH_PROTOCOL
,
/* keep last */
__NL80211_MESH_SETUP_ATTR_AFTER_LAST
,
...
...
net/mac80211/aes_ccm.c
浏览文件 @
933faa43
...
...
@@ -85,7 +85,7 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
*
cpos
++
=
*
pos
++
^
e
[
i
];
}
for
(
i
=
0
;
i
<
CCMP_MIC_LEN
;
i
++
)
for
(
i
=
0
;
i
<
IEEE80211_
CCMP_MIC_LEN
;
i
++
)
mic
[
i
]
=
b
[
i
]
^
s_0
[
i
];
}
...
...
@@ -123,7 +123,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
crypto_cipher_encrypt_one
(
tfm
,
a
,
a
);
}
for
(
i
=
0
;
i
<
CCMP_MIC_LEN
;
i
++
)
{
for
(
i
=
0
;
i
<
IEEE80211_
CCMP_MIC_LEN
;
i
++
)
{
if
((
mic
[
i
]
^
s_0
[
i
])
!=
a
[
i
])
return
-
1
;
}
...
...
@@ -138,7 +138,7 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
tfm
=
crypto_alloc_cipher
(
"aes"
,
0
,
CRYPTO_ALG_ASYNC
);
if
(
!
IS_ERR
(
tfm
))
crypto_cipher_setkey
(
tfm
,
key
,
ALG_CCMP_KEY_LEN
);
crypto_cipher_setkey
(
tfm
,
key
,
WLAN_KEY_LEN_CCMP
);
return
tfm
;
}
...
...
net/mac80211/cfg.c
浏览文件 @
933faa43
...
...
@@ -444,7 +444,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
timespec
uptime
;
u64
packets
=
0
;
int
ac
;
int
i
,
ac
;
sinfo
->
generation
=
sdata
->
local
->
sta_generation
;
...
...
@@ -488,6 +488,17 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
sinfo
->
signal
=
(
s8
)
sta
->
last_signal
;
sinfo
->
signal_avg
=
(
s8
)
-
ewma_read
(
&
sta
->
avg_signal
);
}
if
(
sta
->
chains
)
{
sinfo
->
filled
|=
STATION_INFO_CHAIN_SIGNAL
|
STATION_INFO_CHAIN_SIGNAL_AVG
;
sinfo
->
chains
=
sta
->
chains
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sinfo
->
chain_signal
);
i
++
)
{
sinfo
->
chain_signal
[
i
]
=
sta
->
chain_signal_last
[
i
];
sinfo
->
chain_signal_avg
[
i
]
=
(
s8
)
-
ewma_read
(
&
sta
->
chain_signal_avg
[
i
]);
}
}
sta_set_rate_info_tx
(
sta
,
&
sta
->
last_tx_rate
,
&
sinfo
->
txrate
);
sta_set_rate_info_rx
(
sta
,
&
sinfo
->
rxrate
);
...
...
@@ -728,7 +739,7 @@ static void ieee80211_get_et_strings(struct wiphy *wiphy,
if
(
sset
==
ETH_SS_STATS
)
{
sz_sta_stats
=
sizeof
(
ieee80211_gstrings_sta_stats
);
memcpy
(
data
,
*
ieee80211_gstrings_sta_stats
,
sz_sta_stats
);
memcpy
(
data
,
ieee80211_gstrings_sta_stats
,
sz_sta_stats
);
}
drv_get_et_strings
(
sdata
,
sset
,
&
(
data
[
sz_sta_stats
]));
}
...
...
@@ -1735,6 +1746,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
ifmsh
->
mesh_pp_id
=
setup
->
path_sel_proto
;
ifmsh
->
mesh_pm_id
=
setup
->
path_metric
;
ifmsh
->
user_mpm
=
setup
->
user_mpm
;
ifmsh
->
mesh_auth_id
=
setup
->
auth_id
;
ifmsh
->
security
=
IEEE80211_MESH_SEC_NONE
;
if
(
setup
->
is_authenticated
)
ifmsh
->
security
|=
IEEE80211_MESH_SEC_AUTHED
;
...
...
@@ -2306,7 +2318,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
enum
ieee80211_smps_mode
old_req
;
int
err
;
lockdep_assert_held
(
&
sdata
->
u
.
mgd
.
mtx
);
lockdep_assert_held
(
&
sdata
->
wdev
.
mtx
);
old_req
=
sdata
->
u
.
mgd
.
req_smps
;
sdata
->
u
.
mgd
.
req_smps
=
smps_mode
;
...
...
@@ -2363,9 +2375,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
local
->
dynamic_ps_forced_timeout
=
timeout
;
/* no change, but if automatic follow powersave */
mutex_lock
(
&
sdata
->
u
.
mgd
.
mtx
);
__ieee80211_request_smps
(
sdata
,
sdata
->
u
.
mgd
.
req_smps
);
mutex_unlock
(
&
sdata
->
u
.
mgd
.
mtx
);
if
(
local
->
hw
.
flags
&
IEEE80211_HW_SUPPORTS_DYNAMIC_PS
)
ieee80211_hw_config
(
local
,
IEEE80211_CONF_CHANGE_PS
);
...
...
net/mac80211/debugfs_netdev.c
浏览文件 @
933faa43
...
...
@@ -228,9 +228,9 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_STATION
)
return
-
EOPNOTSUPP
;
mutex_lock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_lock
(
sdata
);
err
=
__ieee80211_request_smps
(
sdata
,
smps_mode
);
mutex_unlock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_unlock
(
sdata
);
return
err
;
}
...
...
@@ -313,16 +313,16 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
case
NL80211_IFTYPE_STATION
:
fc
|=
cpu_to_le16
(
IEEE80211_FCTL_TODS
);
/* BSSID SA DA */
mutex_lock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_lock
(
sdata
);
if
(
!
sdata
->
u
.
mgd
.
associated
)
{
mutex_unlock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_unlock
(
sdata
);
dev_kfree_skb
(
skb
);
return
-
ENOTCONN
;
}
memcpy
(
hdr
->
addr1
,
sdata
->
u
.
mgd
.
associated
->
bssid
,
ETH_ALEN
);
memcpy
(
hdr
->
addr2
,
sdata
->
vif
.
addr
,
ETH_ALEN
);
memcpy
(
hdr
->
addr3
,
addr
,
ETH_ALEN
);
mutex_unlock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_unlock
(
sdata
);
break
;
default:
dev_kfree_skb
(
skb
);
...
...
@@ -471,6 +471,8 @@ __IEEE80211_IF_FILE_W(tsf);
IEEE80211_IF_FILE
(
peer
,
u
.
wds
.
remote_addr
,
MAC
);
#ifdef CONFIG_MAC80211_MESH
IEEE80211_IF_FILE
(
estab_plinks
,
u
.
mesh
.
estab_plinks
,
ATOMIC
);
/* Mesh stats attributes */
IEEE80211_IF_FILE
(
fwded_mcast
,
u
.
mesh
.
mshstats
.
fwded_mcast
,
DEC
);
IEEE80211_IF_FILE
(
fwded_unicast
,
u
.
mesh
.
mshstats
.
fwded_unicast
,
DEC
);
...
...
@@ -480,7 +482,6 @@ IEEE80211_IF_FILE(dropped_frames_congestion,
u
.
mesh
.
mshstats
.
dropped_frames_congestion
,
DEC
);
IEEE80211_IF_FILE
(
dropped_frames_no_route
,
u
.
mesh
.
mshstats
.
dropped_frames_no_route
,
DEC
);
IEEE80211_IF_FILE
(
estab_plinks
,
u
.
mesh
.
estab_plinks
,
ATOMIC
);
/* Mesh parameters */
IEEE80211_IF_FILE
(
dot11MeshMaxRetries
,
...
...
@@ -583,6 +584,7 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
static
void
add_mesh_files
(
struct
ieee80211_sub_if_data
*
sdata
)
{
DEBUGFS_ADD_MODE
(
tsf
,
0600
);
DEBUGFS_ADD_MODE
(
estab_plinks
,
0400
);
}
static
void
add_mesh_stats
(
struct
ieee80211_sub_if_data
*
sdata
)
...
...
@@ -598,7 +600,6 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
MESHSTATS_ADD
(
dropped_frames_ttl
);
MESHSTATS_ADD
(
dropped_frames_no_route
);
MESHSTATS_ADD
(
dropped_frames_congestion
);
MESHSTATS_ADD
(
estab_plinks
);
#undef MESHSTATS_ADD
}
...
...
net/mac80211/ht.c
浏览文件 @
933faa43
...
...
@@ -429,9 +429,9 @@ void ieee80211_request_smps_work(struct work_struct *work)
container_of
(
work
,
struct
ieee80211_sub_if_data
,
u
.
mgd
.
request_smps_work
);
mutex_lock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_lock
(
sdata
);
__ieee80211_request_smps
(
sdata
,
sdata
->
u
.
mgd
.
driver_smps_mode
);
mutex_unlock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_unlock
(
sdata
);
}
void
ieee80211_request_smps
(
struct
ieee80211_vif
*
vif
,
...
...
net/mac80211/ibss.c
浏览文件 @
933faa43
...
...
@@ -54,7 +54,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
struct
beacon_data
*
presp
;
int
frame_len
;
lockdep_assert_held
(
&
ifibss
->
mtx
);
sdata_assert_lock
(
sdata
);
/* Reset own TSF to allow time synchronization work. */
drv_reset_tsf
(
local
,
sdata
);
...
...
@@ -74,7 +74,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
}
presp
=
rcu_dereference_protected
(
ifibss
->
presp
,
lockdep_is_held
(
&
ifibss
->
mtx
));
lockdep_is_held
(
&
sdata
->
wdev
.
mtx
));
rcu_assign_pointer
(
ifibss
->
presp
,
NULL
);
if
(
presp
)
kfree_rcu
(
presp
,
rcu_head
);
...
...
@@ -263,7 +263,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
const
struct
cfg80211_bss_ies
*
ies
;
u64
tsf
;
lockdep_assert_held
(
&
sdata
->
u
.
ibss
.
mtx
);
sdata_assert_lock
(
sdata
);
if
(
beacon_int
<
10
)
beacon_int
=
10
;
...
...
@@ -341,6 +341,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
sta_info
*
sta
;
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
struct
ieee80211_supported_band
*
sband
;
int
band
;
/*
...
...
@@ -380,8 +381,9 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
sta
->
last_rx
=
jiffies
;
/* make sure mandatory rates are always added */
sband
=
local
->
hw
.
wiphy
->
bands
[
band
];
sta
->
sta
.
supp_rates
[
band
]
=
supp_rates
|
ieee80211_mandatory_rates
(
local
,
band
);
ieee80211_mandatory_rates
(
s
band
);
return
ieee80211_ibss_finish_sta
(
sta
,
auth
);
}
...
...
@@ -408,7 +410,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
struct
sta_info
*
sta
;
u8
deauth_frame_buf
[
IEEE80211_DEAUTH_FRAME_LEN
];
lockdep_assert_held
(
&
sdata
->
u
.
ibss
.
mtx
);
sdata_assert_lock
(
sdata
);
if
(
len
<
24
+
6
)
return
;
...
...
@@ -492,7 +494,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
prev_rates
=
sta
->
sta
.
supp_rates
[
band
];
/* make sure mandatory rates are always added */
sta
->
sta
.
supp_rates
[
band
]
=
supp_rates
|
ieee80211_mandatory_rates
(
local
,
band
);
ieee80211_mandatory_rates
(
s
band
);
if
(
sta
->
sta
.
supp_rates
[
band
]
!=
prev_rates
)
{
ibss_dbg
(
sdata
,
...
...
@@ -624,6 +626,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
sta_info
*
sta
;
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
struct
ieee80211_supported_band
*
sband
;
int
band
;
/*
...
...
@@ -658,8 +661,9 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
sta
->
last_rx
=
jiffies
;
/* make sure mandatory rates are always added */
sband
=
local
->
hw
.
wiphy
->
bands
[
band
];
sta
->
sta
.
supp_rates
[
band
]
=
supp_rates
|
ieee80211_mandatory_rates
(
local
,
band
);
ieee80211_mandatory_rates
(
s
band
);
spin_lock
(
&
ifibss
->
incomplete_lock
);
list_add
(
&
sta
->
list
,
&
ifibss
->
incomplete_stations
);
...
...
@@ -673,7 +677,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
int
active
=
0
;
struct
sta_info
*
sta
;
lockdep_assert_held
(
&
sdata
->
u
.
ibss
.
mtx
);
sdata_assert_lock
(
sdata
);
rcu_read_lock
();
...
...
@@ -699,7 +703,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
{
struct
ieee80211_if_ibss
*
ifibss
=
&
sdata
->
u
.
ibss
;
lockdep_assert_held
(
&
ifibss
->
mtx
);
sdata_assert_lock
(
sdata
);
mod_timer
(
&
ifibss
->
timer
,
round_jiffies
(
jiffies
+
IEEE80211_IBSS_MERGE_INTERVAL
));
...
...
@@ -730,7 +734,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
u16
capability
;
int
i
;
lockdep_assert_held
(
&
ifibss
->
mtx
);
sdata_assert_lock
(
sdata
);
if
(
ifibss
->
fixed_bssid
)
{
memcpy
(
bssid
,
ifibss
->
bssid
,
ETH_ALEN
);
...
...
@@ -773,7 +777,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
int
active_ibss
;
u16
capability
;
lockdep_assert_held
(
&
ifibss
->
mtx
);
sdata_assert_lock
(
sdata
);
active_ibss
=
ieee80211_sta_active_ibss
(
sdata
);
ibss_dbg
(
sdata
,
"sta_find_ibss (active_ibss=%d)
\n
"
,
active_ibss
);
...
...
@@ -843,10 +847,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
struct
beacon_data
*
presp
;
u8
*
pos
,
*
end
;
lockdep_assert_held
(
&
ifibss
->
mtx
);
sdata_assert_lock
(
sdata
);
presp
=
rcu_dereference_protected
(
ifibss
->
presp
,
lockdep_is_held
(
&
ifibss
->
mtx
));
lockdep_is_held
(
&
sdata
->
wdev
.
mtx
));
if
(
ifibss
->
state
!=
IEEE80211_IBSS_MLME_JOINED
||
len
<
24
+
2
||
!
presp
)
...
...
@@ -930,7 +934,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
mgmt
=
(
struct
ieee80211_mgmt
*
)
skb
->
data
;
fc
=
le16_to_cpu
(
mgmt
->
frame_control
);
mutex_lock
(
&
sdata
->
u
.
ibss
.
mtx
);
sdata_lock
(
sdata
);
if
(
!
sdata
->
u
.
ibss
.
ssid_len
)
goto
mgmt_out
;
/* not ready to merge yet */
...
...
@@ -953,7 +957,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
}
mgmt_out:
mutex_unlock
(
&
sdata
->
u
.
ibss
.
mtx
);
sdata_unlock
(
sdata
);
}
void
ieee80211_ibss_work
(
struct
ieee80211_sub_if_data
*
sdata
)
...
...
@@ -961,7 +965,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
struct
ieee80211_if_ibss
*
ifibss
=
&
sdata
->
u
.
ibss
;
struct
sta_info
*
sta
;
mutex_lock
(
&
ifibss
->
mtx
);
sdata_lock
(
sdata
);
/*
* Work could be scheduled after scan or similar
...
...
@@ -997,7 +1001,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
}
out:
mutex_unlock
(
&
ifibss
->
mtx
);
sdata_unlock
(
sdata
);
}
static
void
ieee80211_ibss_timer
(
unsigned
long
data
)
...
...
@@ -1014,7 +1018,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
setup_timer
(
&
ifibss
->
timer
,
ieee80211_ibss_timer
,
(
unsigned
long
)
sdata
);
mutex_init
(
&
ifibss
->
mtx
);
INIT_LIST_HEAD
(
&
ifibss
->
incomplete_stations
);
spin_lock_init
(
&
ifibss
->
incomplete_lock
);
}
...
...
@@ -1041,8 +1044,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
{
u32
changed
=
0
;
mutex_lock
(
&
sdata
->
u
.
ibss
.
mtx
);
if
(
params
->
bssid
)
{
memcpy
(
sdata
->
u
.
ibss
.
bssid
,
params
->
bssid
,
ETH_ALEN
);
sdata
->
u
.
ibss
.
fixed_bssid
=
true
;
...
...
@@ -1075,8 +1076,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
memcpy
(
sdata
->
u
.
ibss
.
ssid
,
params
->
ssid
,
params
->
ssid_len
);
sdata
->
u
.
ibss
.
ssid_len
=
params
->
ssid_len
;
mutex_unlock
(
&
sdata
->
u
.
ibss
.
mtx
);
/*
* 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is
* reserved, but an HT STA shall protect HT transmissions as though
...
...
@@ -1112,8 +1111,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
struct
sta_info
*
sta
;
struct
beacon_data
*
presp
;
mutex_lock
(
&
sdata
->
u
.
ibss
.
mtx
);
active_ibss
=
ieee80211_sta_active_ibss
(
sdata
);
if
(
!
active_ibss
&&
!
is_zero_ether_addr
(
ifibss
->
bssid
))
{
...
...
@@ -1157,7 +1154,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
/* remove beacon */
kfree
(
sdata
->
u
.
ibss
.
ie
);
presp
=
rcu_dereference_protected
(
ifibss
->
presp
,
lockdep_is_held
(
&
sdata
->
u
.
ibss
.
mtx
));
lockdep_is_held
(
&
sdata
->
wdev
.
mtx
));
RCU_INIT_POINTER
(
sdata
->
u
.
ibss
.
presp
,
NULL
);
sdata
->
vif
.
bss_conf
.
ibss_joined
=
false
;
sdata
->
vif
.
bss_conf
.
ibss_creator
=
false
;
...
...
@@ -1173,7 +1170,5 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
del_timer_sync
(
&
sdata
->
u
.
ibss
.
timer
);
mutex_unlock
(
&
sdata
->
u
.
ibss
.
mtx
);
return
0
;
}
net/mac80211/ieee80211_i.h
浏览文件 @
933faa43
...
...
@@ -394,7 +394,6 @@ struct ieee80211_if_managed {
bool
nullfunc_failed
;
bool
connection_loss
;
struct
mutex
mtx
;
struct
cfg80211_bss
*
associated
;
struct
ieee80211_mgd_auth_data
*
auth_data
;
struct
ieee80211_mgd_assoc_data
*
assoc_data
;
...
...
@@ -488,8 +487,6 @@ struct ieee80211_if_managed {
struct
ieee80211_if_ibss
{
struct
timer_list
timer
;
struct
mutex
mtx
;
unsigned
long
last_scan_completed
;
u32
basic_rates
;
...
...
@@ -580,8 +577,6 @@ struct ieee80211_if_mesh {
bool
accepting_plinks
;
int
num_gates
;
struct
beacon_data
__rcu
*
beacon
;
/* just protects beacon updates for now */
struct
mutex
mtx
;
const
u8
*
ie
;
u8
ie_len
;
enum
{
...
...
@@ -778,6 +773,26 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
return
container_of
(
p
,
struct
ieee80211_sub_if_data
,
vif
);
}
static
inline
void
sdata_lock
(
struct
ieee80211_sub_if_data
*
sdata
)
__acquires
(
&
sdata
->
wdev
.
mtx
)
{
mutex_lock
(
&
sdata
->
wdev
.
mtx
);
__acquire
(
&
sdata
->
wdev
.
mtx
);
}
static
inline
void
sdata_unlock
(
struct
ieee80211_sub_if_data
*
sdata
)
__releases
(
&
sdata
->
wdev
.
mtx
)
{
mutex_unlock
(
&
sdata
->
wdev
.
mtx
);
__release
(
&
sdata
->
wdev
.
mtx
);
}
static
inline
void
sdata_assert_lock
(
struct
ieee80211_sub_if_data
*
sdata
)
{
lockdep_assert_held
(
&
sdata
->
wdev
.
mtx
);
}
static
inline
enum
ieee80211_band
ieee80211_get_sdata_band
(
struct
ieee80211_sub_if_data
*
sdata
)
{
...
...
@@ -1267,6 +1282,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_sta_restart
(
struct
ieee80211_sub_if_data
*
sdata
);
/* IBSS code */
void
ieee80211_ibss_notify_scan_completed
(
struct
ieee80211_local
*
local
);
...
...
@@ -1505,9 +1521,6 @@ static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action,
ieee802_11_parse_elems_crc
(
start
,
len
,
action
,
elems
,
0
,
0
);
}
u32
ieee80211_mandatory_rates
(
struct
ieee80211_local
*
local
,
enum
ieee80211_band
band
);
void
ieee80211_dynamic_ps_enable_work
(
struct
work_struct
*
work
);
void
ieee80211_dynamic_ps_disable_work
(
struct
work_struct
*
work
);
void
ieee80211_dynamic_ps_timer
(
unsigned
long
data
);
...
...
net/mac80211/iface.c
浏览文件 @
933faa43
...
...
@@ -474,6 +474,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
master
->
control_port_protocol
;
sdata
->
control_port_no_encrypt
=
master
->
control_port_no_encrypt
;
sdata
->
vif
.
cab_queue
=
master
->
vif
.
cab_queue
;
memcpy
(
sdata
->
vif
.
hw_queue
,
master
->
vif
.
hw_queue
,
sizeof
(
sdata
->
vif
.
hw_queue
));
break
;
}
case
NL80211_IFTYPE_AP
:
...
...
@@ -653,7 +656,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
ieee80211_recalc_ps
(
local
,
-
1
);
if
(
dev
)
{
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_MONITOR
||
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP_VLAN
)
{
/* XXX: for AP_VLAN, actually track AP queues */
netif_tx_start_all_queues
(
dev
);
}
else
if
(
dev
)
{
unsigned
long
flags
;
int
n_acs
=
IEEE80211_NUM_ACS
;
int
ac
;
...
...
@@ -1696,6 +1703,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
ASSERT_RTNL
();
/*
* Close all AP_VLAN interfaces first, as otherwise they
* might be closed while the AP interface they belong to
* is closed, causing unregister_netdevice_many() to crash.
*/
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP_VLAN
)
dev_close
(
sdata
->
dev
);
mutex_lock
(
&
local
->
iflist_mtx
);
list_for_each_entry_safe
(
sdata
,
tmp
,
&
local
->
interfaces
,
list
)
{
list_del
(
&
sdata
->
list
);
...
...
net/mac80211/key.c
浏览文件 @
933faa43
...
...
@@ -335,12 +335,12 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
switch
(
cipher
)
{
case
WLAN_CIPHER_SUITE_WEP40
:
case
WLAN_CIPHER_SUITE_WEP104
:
key
->
conf
.
iv_len
=
WEP_IV_LEN
;
key
->
conf
.
icv_len
=
WEP_ICV_LEN
;
key
->
conf
.
iv_len
=
IEEE80211_
WEP_IV_LEN
;
key
->
conf
.
icv_len
=
IEEE80211_
WEP_ICV_LEN
;
break
;
case
WLAN_CIPHER_SUITE_TKIP
:
key
->
conf
.
iv_len
=
TKIP_IV_LEN
;
key
->
conf
.
icv_len
=
TKIP_ICV_LEN
;
key
->
conf
.
iv_len
=
IEEE80211_
TKIP_IV_LEN
;
key
->
conf
.
icv_len
=
IEEE80211_
TKIP_ICV_LEN
;
if
(
seq
)
{
for
(
i
=
0
;
i
<
IEEE80211_NUM_TIDS
;
i
++
)
{
key
->
u
.
tkip
.
rx
[
i
].
iv32
=
...
...
@@ -352,13 +352,13 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
spin_lock_init
(
&
key
->
u
.
tkip
.
txlock
);
break
;
case
WLAN_CIPHER_SUITE_CCMP
:
key
->
conf
.
iv_len
=
CCMP_HDR_LEN
;
key
->
conf
.
icv_len
=
CCMP_MIC_LEN
;
key
->
conf
.
iv_len
=
IEEE80211_
CCMP_HDR_LEN
;
key
->
conf
.
icv_len
=
IEEE80211_
CCMP_MIC_LEN
;
if
(
seq
)
{
for
(
i
=
0
;
i
<
IEEE80211_NUM_TIDS
+
1
;
i
++
)
for
(
j
=
0
;
j
<
CCMP_PN_LEN
;
j
++
)
for
(
j
=
0
;
j
<
IEEE80211_
CCMP_PN_LEN
;
j
++
)
key
->
u
.
ccmp
.
rx_pn
[
i
][
j
]
=
seq
[
CCMP_PN_LEN
-
j
-
1
];
seq
[
IEEE80211_
CCMP_PN_LEN
-
j
-
1
];
}
/*
* Initialize AES key state here as an optimization so that
...
...
@@ -375,9 +375,9 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
key
->
conf
.
iv_len
=
0
;
key
->
conf
.
icv_len
=
sizeof
(
struct
ieee80211_mmie
);
if
(
seq
)
for
(
j
=
0
;
j
<
CMAC_PN_LEN
;
j
++
)
for
(
j
=
0
;
j
<
IEEE80211_
CMAC_PN_LEN
;
j
++
)
key
->
u
.
aes_cmac
.
rx_pn
[
j
]
=
seq
[
CMAC_PN_LEN
-
j
-
1
];
seq
[
IEEE80211_
CMAC_PN_LEN
-
j
-
1
];
/*
* Initialize AES key state here as an optimization so that
* it does not need to be initialized for every packet.
...
...
@@ -740,13 +740,13 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
pn
=
key
->
u
.
ccmp
.
rx_pn
[
IEEE80211_NUM_TIDS
];
else
pn
=
key
->
u
.
ccmp
.
rx_pn
[
tid
];
memcpy
(
seq
->
ccmp
.
pn
,
pn
,
CCMP_PN_LEN
);
memcpy
(
seq
->
ccmp
.
pn
,
pn
,
IEEE80211_
CCMP_PN_LEN
);
break
;
case
WLAN_CIPHER_SUITE_AES_CMAC
:
if
(
WARN_ON
(
tid
!=
0
))
return
;
pn
=
key
->
u
.
aes_cmac
.
rx_pn
;
memcpy
(
seq
->
aes_cmac
.
pn
,
pn
,
CMAC_PN_LEN
);
memcpy
(
seq
->
aes_cmac
.
pn
,
pn
,
IEEE80211_
CMAC_PN_LEN
);
break
;
}
}
...
...
net/mac80211/key.h
浏览文件 @
933faa43
...
...
@@ -19,17 +19,6 @@
#define NUM_DEFAULT_KEYS 4
#define NUM_DEFAULT_MGMT_KEYS 2
#define WEP_IV_LEN 4
#define WEP_ICV_LEN 4
#define ALG_CCMP_KEY_LEN 16
#define CCMP_HDR_LEN 8
#define CCMP_MIC_LEN 8
#define CCMP_TK_LEN 16
#define CCMP_PN_LEN 6
#define TKIP_IV_LEN 8
#define TKIP_ICV_LEN 4
#define CMAC_PN_LEN 6
struct
ieee80211_local
;
struct
ieee80211_sub_if_data
;
struct
sta_info
;
...
...
@@ -93,13 +82,13 @@ struct ieee80211_key {
* frames and the last counter is used with Robust
* Management frames.
*/
u8
rx_pn
[
IEEE80211_NUM_TIDS
+
1
][
CCMP_PN_LEN
];
u8
rx_pn
[
IEEE80211_NUM_TIDS
+
1
][
IEEE80211_
CCMP_PN_LEN
];
struct
crypto_cipher
*
tfm
;
u32
replays
;
/* dot11RSNAStatsCCMPReplays */
}
ccmp
;
struct
{
atomic64_t
tx_pn
;
u8
rx_pn
[
CMAC_PN_LEN
];
u8
rx_pn
[
IEEE80211_
CMAC_PN_LEN
];
struct
crypto_cipher
*
tfm
;
u32
replays
;
/* dot11RSNAStatsCMACReplays */
u32
icverrors
;
/* dot11RSNAStatsCMACICVErrors */
...
...
net/mac80211/main.c
浏览文件 @
933faa43
...
...
@@ -331,7 +331,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
return
NOTIFY_DONE
;
ifmgd
=
&
sdata
->
u
.
mgd
;
mutex_lock
(
&
ifmgd
->
mtx
);
sdata_lock
(
sdata
);
/* Copy the addresses to the bss_conf list */
ifa
=
idev
->
ifa_list
;
...
...
@@ -349,7 +349,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_ARP_FILTER
);
mutex_unlock
(
&
ifmgd
->
mtx
);
sdata_unlock
(
sdata
);
return
NOTIFY_DONE
;
}
...
...
net/mac80211/mesh.c
浏览文件 @
933faa43
...
...
@@ -161,8 +161,11 @@ void mesh_sta_cleanup(struct sta_info *sta)
del_timer_sync
(
&
sta
->
plink_timer
);
}
if
(
changed
)
if
(
changed
)
{
sdata_lock
(
sdata
);
ieee80211_mbss_info_change_notify
(
sdata
,
changed
);
sdata_unlock
(
sdata
);
}
}
int
mesh_rmc_init
(
struct
ieee80211_sub_if_data
*
sdata
)
...
...
@@ -577,7 +580,9 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
mesh_path_expire
(
sdata
);
changed
=
mesh_accept_plinks_update
(
sdata
);
sdata_lock
(
sdata
);
ieee80211_mbss_info_change_notify
(
sdata
,
changed
);
sdata_unlock
(
sdata
);
mod_timer
(
&
ifmsh
->
housekeeping_timer
,
round_jiffies
(
jiffies
+
...
...
@@ -697,25 +702,21 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
}
static
int
ieee80211_mesh_rebuild_beacon
(
struct
ieee80211_
if_mesh
*
ifmsh
)
ieee80211_mesh_rebuild_beacon
(
struct
ieee80211_
sub_if_data
*
sdata
)
{
struct
beacon_data
*
old_bcn
;
int
ret
;
mutex_lock
(
&
ifmsh
->
mtx
);
old_bcn
=
rcu_dereference_protected
(
ifmsh
->
beacon
,
lockdep_is_held
(
&
ifmsh
->
mtx
));
ret
=
ieee80211_mesh_build_beacon
(
ifmsh
);
old_bcn
=
rcu_dereference_protected
(
sdata
->
u
.
mesh
.
beacon
,
lockdep_is_held
(
&
sdata
->
wdev
.
mtx
));
ret
=
ieee80211_mesh_build_beacon
(
&
sdata
->
u
.
mesh
);
if
(
ret
)
/* just reuse old beacon */
goto
ou
t
;
return
re
t
;
if
(
old_bcn
)
kfree_rcu
(
old_bcn
,
rcu_head
);
out:
mutex_unlock
(
&
ifmsh
->
mtx
);
return
ret
;
return
0
;
}
void
ieee80211_mbss_info_change_notify
(
struct
ieee80211_sub_if_data
*
sdata
,
...
...
@@ -726,7 +727,7 @@ void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
BSS_CHANGED_HT
|
BSS_CHANGED_BASIC_RATES
|
BSS_CHANGED_BEACON_INT
)))
if
(
ieee80211_mesh_rebuild_beacon
(
&
sdata
->
u
.
mesh
))
if
(
ieee80211_mesh_rebuild_beacon
(
sdata
))
return
;
ieee80211_bss_info_change_notify
(
sdata
,
changed
);
}
...
...
@@ -741,6 +742,8 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
BSS_CHANGED_BASIC_RATES
|
BSS_CHANGED_BEACON_INT
;
enum
ieee80211_band
band
=
ieee80211_get_sdata_band
(
sdata
);
struct
ieee80211_supported_band
*
sband
=
sdata
->
local
->
hw
.
wiphy
->
bands
[
band
];
local
->
fif_other_bss
++
;
/* mesh ifaces must set allmulti to forward mcast traffic */
...
...
@@ -748,7 +751,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
ieee80211_configure_filter
(
local
);
ifmsh
->
mesh_cc_id
=
0
;
/* Disabled */
ifmsh
->
mesh_auth_id
=
0
;
/* Disabled */
/* register sync ops from extensible synchronization framework */
ifmsh
->
sync_ops
=
ieee80211_mesh_sync_ops_get
(
ifmsh
->
mesh_sp_id
);
ifmsh
->
adjusting_tbtt
=
false
;
...
...
@@ -759,8 +761,7 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
sdata
->
vif
.
bss_conf
.
ht_operation_mode
=
ifmsh
->
mshcfg
.
ht_opmode
;
sdata
->
vif
.
bss_conf
.
enable_beacon
=
true
;
sdata
->
vif
.
bss_conf
.
basic_rates
=
ieee80211_mandatory_rates
(
local
,
band
);
sdata
->
vif
.
bss_conf
.
basic_rates
=
ieee80211_mandatory_rates
(
sband
);
changed
|=
ieee80211_mps_local_status_update
(
sdata
);
...
...
@@ -788,12 +789,12 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
sdata
->
vif
.
bss_conf
.
enable_beacon
=
false
;
clear_bit
(
SDATA_STATE_OFFCHANNEL_BEACON_STOPPED
,
&
sdata
->
state
);
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BEACON_ENABLED
);
mutex_lock
(
&
ifmsh
->
mtx
);
sdata_lock
(
sdata
);
bcn
=
rcu_dereference_protected
(
ifmsh
->
beacon
,
lockdep_is_held
(
&
ifmsh
->
mtx
));
lockdep_is_held
(
&
sdata
->
wdev
.
mtx
));
rcu_assign_pointer
(
ifmsh
->
beacon
,
NULL
);
kfree_rcu
(
bcn
,
rcu_head
);
mutex_unlock
(
&
ifmsh
->
mtx
);
sdata_unlock
(
sdata
);
/* flush STAs and mpaths on this iface */
sta_info_flush
(
sdata
);
...
...
@@ -1041,7 +1042,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
spin_lock_init
(
&
ifmsh
->
mesh_preq_queue_lock
);
spin_lock_init
(
&
ifmsh
->
sync_offset_lock
);
RCU_INIT_POINTER
(
ifmsh
->
beacon
,
NULL
);
mutex_init
(
&
ifmsh
->
mtx
);
sdata
->
vif
.
bss_conf
.
bssid
=
zero_addr
;
}
net/mac80211/mesh_plink.c
浏览文件 @
933faa43
...
...
@@ -517,7 +517,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
ieee80211_mps_frame_release
(
sta
,
elems
);
out:
rcu_read_unlock
();
sdata_lock
(
sdata
);
ieee80211_mbss_info_change_notify
(
sdata
,
changed
);
sdata_unlock
(
sdata
);
}
static
void
mesh_plink_timer
(
unsigned
long
data
)
...
...
@@ -1068,6 +1070,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
rcu_read_unlock
();
if
(
changed
)
if
(
changed
)
{
sdata_lock
(
sdata
);
ieee80211_mbss_info_change_notify
(
sdata
,
changed
);
sdata_unlock
(
sdata
);
}
}
net/mac80211/mlme.c
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
net/mac80211/rate.c
浏览文件 @
933faa43
...
...
@@ -688,8 +688,15 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
struct
ieee80211_sta
*
pubsta
,
struct
ieee80211_sta_rates
*
rates
)
{
struct
ieee80211_sta_rates
*
old
=
rcu_dereference
(
pubsta
->
rates
)
;
struct
ieee80211_sta_rates
*
old
;
/*
* mac80211 guarantees that this function will not be called
* concurrently, so the following RCU access is safe, even without
* extra locking. This can not be checked easily, so we just set
* the condition to true.
*/
old
=
rcu_dereference_protected
(
pubsta
->
rates
,
true
);
rcu_assign_pointer
(
pubsta
->
rates
,
rates
);
if
(
old
)
kfree_rcu
(
old
,
rcu_head
);
...
...
net/mac80211/rx.c
浏览文件 @
933faa43
...
...
@@ -258,6 +258,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
pos
+=
2
;
if
(
status
->
flag
&
RX_FLAG_HT
)
{
unsigned
int
stbc
;
rthdr
->
it_present
|=
cpu_to_le32
(
1
<<
IEEE80211_RADIOTAP_MCS
);
*
pos
++
=
local
->
hw
.
radiotap_mcs_details
;
*
pos
=
0
;
...
...
@@ -267,6 +269,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
*
pos
|=
IEEE80211_RADIOTAP_MCS_BW_40
;
if
(
status
->
flag
&
RX_FLAG_HT_GF
)
*
pos
|=
IEEE80211_RADIOTAP_MCS_FMT_GF
;
stbc
=
(
status
->
flag
&
RX_FLAG_STBC_MASK
)
>>
RX_FLAG_STBC_SHIFT
;
*
pos
|=
stbc
<<
IEEE80211_RADIOTAP_MCS_STBC_SHIFT
;
pos
++
;
*
pos
++
=
status
->
rate_idx
;
}
...
...
@@ -1372,6 +1376,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
struct
sk_buff
*
skb
=
rx
->
skb
;
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
skb
);
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
int
i
;
if
(
!
sta
)
return
RX_CONTINUE
;
...
...
@@ -1422,6 +1427,19 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
ewma_add
(
&
sta
->
avg_signal
,
-
status
->
signal
);
}
if
(
status
->
chains
)
{
sta
->
chains
=
status
->
chains
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
status
->
chain_signal
);
i
++
)
{
int
signal
=
status
->
chain_signal
[
i
];
if
(
!
(
status
->
chains
&
BIT
(
i
)))
continue
;
sta
->
chain_signal_last
[
i
]
=
signal
;
ewma_add
(
&
sta
->
chain_signal_avg
[
i
],
-
signal
);
}
}
/*
* Change STA power saving mode only at the end of a frame
* exchange sequence.
...
...
@@ -1608,7 +1626,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
entry
->
ccmp
=
1
;
memcpy
(
entry
->
last_pn
,
rx
->
key
->
u
.
ccmp
.
rx_pn
[
queue
],
CCMP_PN_LEN
);
IEEE80211_
CCMP_PN_LEN
);
}
return
RX_QUEUED
;
}
...
...
@@ -1627,21 +1645,21 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
* (IEEE 802.11i, 8.3.3.4.5) */
if
(
entry
->
ccmp
)
{
int
i
;
u8
pn
[
CCMP_PN_LEN
],
*
rpn
;
u8
pn
[
IEEE80211_
CCMP_PN_LEN
],
*
rpn
;
int
queue
;
if
(
!
rx
->
key
||
rx
->
key
->
conf
.
cipher
!=
WLAN_CIPHER_SUITE_CCMP
)
return
RX_DROP_UNUSABLE
;
memcpy
(
pn
,
entry
->
last_pn
,
CCMP_PN_LEN
);
for
(
i
=
CCMP_PN_LEN
-
1
;
i
>=
0
;
i
--
)
{
memcpy
(
pn
,
entry
->
last_pn
,
IEEE80211_
CCMP_PN_LEN
);
for
(
i
=
IEEE80211_
CCMP_PN_LEN
-
1
;
i
>=
0
;
i
--
)
{
pn
[
i
]
++
;
if
(
pn
[
i
])
break
;
}
queue
=
rx
->
security_idx
;
rpn
=
rx
->
key
->
u
.
ccmp
.
rx_pn
[
queue
];
if
(
memcmp
(
pn
,
rpn
,
CCMP_PN_LEN
))
if
(
memcmp
(
pn
,
rpn
,
IEEE80211_
CCMP_PN_LEN
))
return
RX_DROP_UNUSABLE
;
memcpy
(
entry
->
last_pn
,
pn
,
CCMP_PN_LEN
);
memcpy
(
entry
->
last_pn
,
pn
,
IEEE80211_
CCMP_PN_LEN
);
}
skb_pull
(
rx
->
skb
,
ieee80211_hdrlen
(
fc
));
...
...
@@ -3036,6 +3054,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
* and location updates. Note that mac80211
* itself never looks at these frames.
*/
if
(
!
multicast
&&
!
ether_addr_equal
(
sdata
->
vif
.
addr
,
hdr
->
addr1
))
return
0
;
if
(
ieee80211_is_public_action
(
hdr
,
skb
->
len
))
return
1
;
if
(
!
ieee80211_is_beacon
(
hdr
->
frame_control
))
...
...
net/mac80211/sta_info.c
浏览文件 @
933faa43
...
...
@@ -358,6 +358,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
do_posix_clock_monotonic_gettime
(
&
uptime
);
sta
->
last_connected
=
uptime
.
tv_sec
;
ewma_init
(
&
sta
->
avg_signal
,
1024
,
8
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
sta
->
chain_signal_avg
);
i
++
)
ewma_init
(
&
sta
->
chain_signal_avg
[
i
],
1024
,
8
);
if
(
sta_prepare_rate_control
(
local
,
sta
,
gfp
))
{
kfree
(
sta
);
...
...
net/mac80211/sta_info.h
浏览文件 @
933faa43
...
...
@@ -344,6 +344,11 @@ struct sta_info {
int
last_signal
;
struct
ewma
avg_signal
;
int
last_ack_signal
;
u8
chains
;
s8
chain_signal_last
[
IEEE80211_MAX_CHAINS
];
struct
ewma
chain_signal_avg
[
IEEE80211_MAX_CHAINS
];
/* Plus 1 for non-QoS frames */
__le16
last_seq_ctrl
[
IEEE80211_NUM_TIDS
+
1
];
...
...
net/mac80211/tkip.c
浏览文件 @
933faa43
...
...
@@ -208,10 +208,10 @@ void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
u32
iv32
=
get_unaligned_le32
(
&
data
[
4
]);
u16
iv16
=
data
[
2
]
|
(
data
[
0
]
<<
8
);
spin_lock
_bh
(
&
key
->
u
.
tkip
.
txlock
);
spin_lock
(
&
key
->
u
.
tkip
.
txlock
);
ieee80211_compute_tkip_p1k
(
key
,
iv32
);
tkip_mixing_phase2
(
tk
,
ctx
,
iv16
,
p2k
);
spin_unlock
_bh
(
&
key
->
u
.
tkip
.
txlock
);
spin_unlock
(
&
key
->
u
.
tkip
.
txlock
);
}
EXPORT_SYMBOL
(
ieee80211_get_tkip_p2k
);
...
...
net/mac80211/util.c
浏览文件 @
933faa43
...
...
@@ -1072,32 +1072,6 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
ieee80211_set_wmm_default
(
sdata
,
true
);
}
u32
ieee80211_mandatory_rates
(
struct
ieee80211_local
*
local
,
enum
ieee80211_band
band
)
{
struct
ieee80211_supported_band
*
sband
;
struct
ieee80211_rate
*
bitrates
;
u32
mandatory_rates
;
enum
ieee80211_rate_flags
mandatory_flag
;
int
i
;
sband
=
local
->
hw
.
wiphy
->
bands
[
band
];
if
(
WARN_ON
(
!
sband
))
return
1
;
if
(
band
==
IEEE80211_BAND_2GHZ
)
mandatory_flag
=
IEEE80211_RATE_MANDATORY_B
;
else
mandatory_flag
=
IEEE80211_RATE_MANDATORY_A
;
bitrates
=
sband
->
bitrates
;
mandatory_rates
=
0
;
for
(
i
=
0
;
i
<
sband
->
n_bitrates
;
i
++
)
if
(
bitrates
[
i
].
flags
&
mandatory_flag
)
mandatory_rates
|=
BIT
(
i
);
return
mandatory_rates
;
}
void
ieee80211_send_auth
(
struct
ieee80211_sub_if_data
*
sdata
,
u16
transaction
,
u16
auth_alg
,
u16
status
,
const
u8
*
extra
,
size_t
extra_len
,
const
u8
*
da
,
...
...
@@ -1607,9 +1581,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
if
(
sdata
->
u
.
mgd
.
dtim_period
)
changed
|=
BSS_CHANGED_DTIM_PERIOD
;
mutex_lock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_lock
(
sdata
);
ieee80211_bss_info_change_notify
(
sdata
,
changed
);
mutex_unlock
(
&
sdata
->
u
.
mgd
.
mtx
);
sdata_unlock
(
sdata
);
break
;
case
NL80211_IFTYPE_ADHOC
:
changed
|=
BSS_CHANGED_IBSS
;
...
...
@@ -1740,6 +1714,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
mb
();
local
->
resuming
=
false
;
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
if
(
!
ieee80211_sdata_running
(
sdata
))
continue
;
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
)
ieee80211_sta_restart
(
sdata
);
}
mod_timer
(
&
local
->
sta_cleanup
,
jiffies
+
1
);
#else
WARN_ON
(
1
);
...
...
net/mac80211/wep.c
浏览文件 @
933faa43
...
...
@@ -28,7 +28,7 @@
int
ieee80211_wep_init
(
struct
ieee80211_local
*
local
)
{
/* start WEP IV from a random value */
get_random_bytes
(
&
local
->
wep_iv
,
WEP_IV_LEN
);
get_random_bytes
(
&
local
->
wep_iv
,
IEEE80211_
WEP_IV_LEN
);
local
->
wep_tx_tfm
=
crypto_alloc_cipher
(
"arc4"
,
0
,
CRYPTO_ALG_ASYNC
);
if
(
IS_ERR
(
local
->
wep_tx_tfm
))
{
...
...
@@ -98,20 +98,21 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
hdr
->
frame_control
|=
cpu_to_le16
(
IEEE80211_FCTL_PROTECTED
);
if
(
WARN_ON
(
skb_tailroom
(
skb
)
<
WEP_ICV_LEN
||
skb_headroom
(
skb
)
<
WEP_IV_LEN
))
if
(
WARN_ON
(
skb_tailroom
(
skb
)
<
IEEE80211_
WEP_ICV_LEN
||
skb_headroom
(
skb
)
<
IEEE80211_
WEP_IV_LEN
))
return
NULL
;
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
newhdr
=
skb_push
(
skb
,
WEP_IV_LEN
);
memmove
(
newhdr
,
newhdr
+
WEP_IV_LEN
,
hdrlen
);
newhdr
=
skb_push
(
skb
,
IEEE80211_
WEP_IV_LEN
);
memmove
(
newhdr
,
newhdr
+
IEEE80211_
WEP_IV_LEN
,
hdrlen
);
/* the HW only needs room for the IV, but not the actual IV */
if
(
info
->
control
.
hw_key
&&
(
info
->
control
.
hw_key
->
flags
&
IEEE80211_KEY_FLAG_PUT_IV_SPACE
))
return
newhdr
+
hdrlen
;
skb_set_network_header
(
skb
,
skb_network_offset
(
skb
)
+
WEP_IV_LEN
);
skb_set_network_header
(
skb
,
skb_network_offset
(
skb
)
+
IEEE80211_WEP_IV_LEN
);
ieee80211_wep_get_iv
(
local
,
keylen
,
keyidx
,
newhdr
+
hdrlen
);
return
newhdr
+
hdrlen
;
}
...
...
@@ -125,8 +126,8 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
unsigned
int
hdrlen
;
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
memmove
(
skb
->
data
+
WEP_IV_LEN
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
WEP_IV_LEN
);
memmove
(
skb
->
data
+
IEEE80211_
WEP_IV_LEN
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
IEEE80211_
WEP_IV_LEN
);
}
...
...
@@ -146,7 +147,7 @@ int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
put_unaligned
(
icv
,
(
__le32
*
)(
data
+
data_len
));
crypto_cipher_setkey
(
tfm
,
rc4key
,
klen
);
for
(
i
=
0
;
i
<
data_len
+
WEP_ICV_LEN
;
i
++
)
for
(
i
=
0
;
i
<
data_len
+
IEEE80211_
WEP_ICV_LEN
;
i
++
)
crypto_cipher_encrypt_one
(
tfm
,
data
+
i
,
data
+
i
);
return
0
;
...
...
@@ -172,7 +173,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
if
(
!
iv
)
return
-
1
;
len
=
skb
->
len
-
(
iv
+
WEP_IV_LEN
-
skb
->
data
);
len
=
skb
->
len
-
(
iv
+
IEEE80211_
WEP_IV_LEN
-
skb
->
data
);
/* Prepend 24-bit IV to RC4 key */
memcpy
(
rc4key
,
iv
,
3
);
...
...
@@ -181,10 +182,10 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
memcpy
(
rc4key
+
3
,
key
,
keylen
);
/* Add room for ICV */
skb_put
(
skb
,
WEP_ICV_LEN
);
skb_put
(
skb
,
IEEE80211_
WEP_ICV_LEN
);
return
ieee80211_wep_encrypt_data
(
local
->
wep_tx_tfm
,
rc4key
,
keylen
+
3
,
iv
+
WEP_IV_LEN
,
len
);
iv
+
IEEE80211_
WEP_IV_LEN
,
len
);
}
...
...
@@ -201,11 +202,11 @@ int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
return
-
1
;
crypto_cipher_setkey
(
tfm
,
rc4key
,
klen
);
for
(
i
=
0
;
i
<
data_len
+
WEP_ICV_LEN
;
i
++
)
for
(
i
=
0
;
i
<
data_len
+
IEEE80211_
WEP_ICV_LEN
;
i
++
)
crypto_cipher_decrypt_one
(
tfm
,
data
+
i
,
data
+
i
);
crc
=
cpu_to_le32
(
~
crc32_le
(
~
0
,
data
,
data_len
));
if
(
memcmp
(
&
crc
,
data
+
data_len
,
WEP_ICV_LEN
)
!=
0
)
if
(
memcmp
(
&
crc
,
data
+
data_len
,
IEEE80211_
WEP_ICV_LEN
)
!=
0
)
/* ICV mismatch */
return
-
1
;
...
...
@@ -237,10 +238,10 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
return
-
1
;
hdrlen
=
ieee80211_hdrlen
(
hdr
->
frame_control
);
if
(
skb
->
len
<
hdrlen
+
WEP_IV_LEN
+
WEP_ICV_LEN
)
if
(
skb
->
len
<
hdrlen
+
IEEE80211_WEP_IV_LEN
+
IEEE80211_
WEP_ICV_LEN
)
return
-
1
;
len
=
skb
->
len
-
hdrlen
-
WEP_IV_LEN
-
WEP_ICV_LEN
;
len
=
skb
->
len
-
hdrlen
-
IEEE80211_WEP_IV_LEN
-
IEEE80211_
WEP_ICV_LEN
;
keyidx
=
skb
->
data
[
hdrlen
+
3
]
>>
6
;
...
...
@@ -256,16 +257,16 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
memcpy
(
rc4key
+
3
,
key
->
conf
.
key
,
key
->
conf
.
keylen
);
if
(
ieee80211_wep_decrypt_data
(
local
->
wep_rx_tfm
,
rc4key
,
klen
,
skb
->
data
+
hdrlen
+
WEP_IV_LEN
,
len
))
skb
->
data
+
hdrlen
+
IEEE80211_WEP_IV_LEN
,
len
))
ret
=
-
1
;
/* Trim ICV */
skb_trim
(
skb
,
skb
->
len
-
WEP_ICV_LEN
);
skb_trim
(
skb
,
skb
->
len
-
IEEE80211_
WEP_ICV_LEN
);
/* Remove IV */
memmove
(
skb
->
data
+
WEP_IV_LEN
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
WEP_IV_LEN
);
memmove
(
skb
->
data
+
IEEE80211_
WEP_IV_LEN
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
IEEE80211_
WEP_IV_LEN
);
return
ret
;
}
...
...
@@ -305,13 +306,14 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
if
(
ieee80211_wep_decrypt
(
rx
->
local
,
rx
->
skb
,
rx
->
key
))
return
RX_DROP_UNUSABLE
;
}
else
if
(
!
(
status
->
flag
&
RX_FLAG_IV_STRIPPED
))
{
if
(
!
pskb_may_pull
(
rx
->
skb
,
ieee80211_hdrlen
(
fc
)
+
WEP_IV_LEN
))
if
(
!
pskb_may_pull
(
rx
->
skb
,
ieee80211_hdrlen
(
fc
)
+
IEEE80211_WEP_IV_LEN
))
return
RX_DROP_UNUSABLE
;
if
(
rx
->
sta
&&
ieee80211_wep_is_weak_iv
(
rx
->
skb
,
rx
->
key
))
rx
->
sta
->
wep_weak_iv_count
++
;
ieee80211_wep_remove_iv
(
rx
->
local
,
rx
->
skb
,
rx
->
key
);
/* remove ICV */
if
(
pskb_trim
(
rx
->
skb
,
rx
->
skb
->
len
-
WEP_ICV_LEN
))
if
(
pskb_trim
(
rx
->
skb
,
rx
->
skb
->
len
-
IEEE80211_
WEP_ICV_LEN
))
return
RX_DROP_UNUSABLE
;
}
...
...
net/mac80211/wpa.c
浏览文件 @
933faa43
...
...
@@ -62,10 +62,10 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
tail
=
MICHAEL_MIC_LEN
;
if
(
!
info
->
control
.
hw_key
)
tail
+=
TKIP_ICV_LEN
;
tail
+=
IEEE80211_
TKIP_ICV_LEN
;
if
(
WARN_ON
(
skb_tailroom
(
skb
)
<
tail
||
skb_headroom
(
skb
)
<
TKIP_IV_LEN
))
skb_headroom
(
skb
)
<
IEEE80211_
TKIP_IV_LEN
))
return
TX_DROP
;
key
=
&
tx
->
key
->
conf
.
key
[
NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY
];
...
...
@@ -198,15 +198,16 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
if
(
info
->
control
.
hw_key
)
tail
=
0
;
else
tail
=
TKIP_ICV_LEN
;
tail
=
IEEE80211_
TKIP_ICV_LEN
;
if
(
WARN_ON
(
skb_tailroom
(
skb
)
<
tail
||
skb_headroom
(
skb
)
<
TKIP_IV_LEN
))
skb_headroom
(
skb
)
<
IEEE80211_
TKIP_IV_LEN
))
return
-
1
;
pos
=
skb_push
(
skb
,
TKIP_IV_LEN
);
memmove
(
pos
,
pos
+
TKIP_IV_LEN
,
hdrlen
);
skb_set_network_header
(
skb
,
skb_network_offset
(
skb
)
+
TKIP_IV_LEN
);
pos
=
skb_push
(
skb
,
IEEE80211_TKIP_IV_LEN
);
memmove
(
pos
,
pos
+
IEEE80211_TKIP_IV_LEN
,
hdrlen
);
skb_set_network_header
(
skb
,
skb_network_offset
(
skb
)
+
IEEE80211_TKIP_IV_LEN
);
pos
+=
hdrlen
;
/* the HW only needs room for the IV, but not the actual IV */
...
...
@@ -227,7 +228,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
return
0
;
/* Add room for ICV */
skb_put
(
skb
,
TKIP_ICV_LEN
);
skb_put
(
skb
,
IEEE80211_
TKIP_ICV_LEN
);
return
ieee80211_tkip_encrypt_data
(
tx
->
local
->
wep_tx_tfm
,
key
,
skb
,
pos
,
len
);
...
...
@@ -290,11 +291,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
return
RX_DROP_UNUSABLE
;
/* Trim ICV */
skb_trim
(
skb
,
skb
->
len
-
TKIP_ICV_LEN
);
skb_trim
(
skb
,
skb
->
len
-
IEEE80211_
TKIP_ICV_LEN
);
/* Remove IV */
memmove
(
skb
->
data
+
TKIP_IV_LEN
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
TKIP_IV_LEN
);
memmove
(
skb
->
data
+
IEEE80211_
TKIP_IV_LEN
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
IEEE80211_
TKIP_IV_LEN
);
return
RX_CONTINUE
;
}
...
...
@@ -337,9 +338,9 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
else
qos_tid
=
0
;
data_len
=
skb
->
len
-
hdrlen
-
CCMP_HDR_LEN
;
data_len
=
skb
->
len
-
hdrlen
-
IEEE80211_
CCMP_HDR_LEN
;
if
(
encrypted
)
data_len
-=
CCMP_MIC_LEN
;
data_len
-=
IEEE80211_
CCMP_MIC_LEN
;
/* First block, b_0 */
b_0
[
0
]
=
0x59
;
/* flags: Adata: 1, M: 011, L: 001 */
...
...
@@ -348,7 +349,7 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
*/
b_0
[
1
]
=
qos_tid
|
(
mgmt
<<
4
);
memcpy
(
&
b_0
[
2
],
hdr
->
addr2
,
ETH_ALEN
);
memcpy
(
&
b_0
[
8
],
pn
,
CCMP_PN_LEN
);
memcpy
(
&
b_0
[
8
],
pn
,
IEEE80211_
CCMP_PN_LEN
);
/* l(m) */
put_unaligned_be16
(
data_len
,
&
b_0
[
14
]);
...
...
@@ -424,15 +425,16 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
if
(
info
->
control
.
hw_key
)
tail
=
0
;
else
tail
=
CCMP_MIC_LEN
;
tail
=
IEEE80211_
CCMP_MIC_LEN
;
if
(
WARN_ON
(
skb_tailroom
(
skb
)
<
tail
||
skb_headroom
(
skb
)
<
CCMP_HDR_LEN
))
skb_headroom
(
skb
)
<
IEEE80211_
CCMP_HDR_LEN
))
return
-
1
;
pos
=
skb_push
(
skb
,
CCMP_HDR_LEN
);
memmove
(
pos
,
pos
+
CCMP_HDR_LEN
,
hdrlen
);
skb_set_network_header
(
skb
,
skb_network_offset
(
skb
)
+
CCMP_HDR_LEN
);
pos
=
skb_push
(
skb
,
IEEE80211_CCMP_HDR_LEN
);
memmove
(
pos
,
pos
+
IEEE80211_CCMP_HDR_LEN
,
hdrlen
);
skb_set_network_header
(
skb
,
skb_network_offset
(
skb
)
+
IEEE80211_CCMP_HDR_LEN
);
/* the HW only needs room for the IV, but not the actual IV */
if
(
info
->
control
.
hw_key
&&
...
...
@@ -457,10 +459,10 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
if
(
info
->
control
.
hw_key
)
return
0
;
pos
+=
CCMP_HDR_LEN
;
pos
+=
IEEE80211_
CCMP_HDR_LEN
;
ccmp_special_blocks
(
skb
,
pn
,
scratch
,
0
);
ieee80211_aes_ccm_encrypt
(
key
->
u
.
ccmp
.
tfm
,
scratch
,
pos
,
len
,
pos
,
skb_put
(
skb
,
CCMP_MIC_LEN
));
pos
,
skb_put
(
skb
,
IEEE80211_
CCMP_MIC_LEN
));
return
0
;
}
...
...
@@ -490,7 +492,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
struct
ieee80211_key
*
key
=
rx
->
key
;
struct
sk_buff
*
skb
=
rx
->
skb
;
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
skb
);
u8
pn
[
CCMP_PN_LEN
];
u8
pn
[
IEEE80211_
CCMP_PN_LEN
];
int
data_len
;
int
queue
;
...
...
@@ -500,12 +502,13 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
!
ieee80211_is_robust_mgmt_frame
(
hdr
))
return
RX_CONTINUE
;
data_len
=
skb
->
len
-
hdrlen
-
CCMP_HDR_LEN
-
CCMP_MIC_LEN
;
data_len
=
skb
->
len
-
hdrlen
-
IEEE80211_CCMP_HDR_LEN
-
IEEE80211_CCMP_MIC_LEN
;
if
(
!
rx
->
sta
||
data_len
<
0
)
return
RX_DROP_UNUSABLE
;
if
(
status
->
flag
&
RX_FLAG_DECRYPTED
)
{
if
(
!
pskb_may_pull
(
rx
->
skb
,
hdrlen
+
CCMP_HDR_LEN
))
if
(
!
pskb_may_pull
(
rx
->
skb
,
hdrlen
+
IEEE80211_
CCMP_HDR_LEN
))
return
RX_DROP_UNUSABLE
;
}
else
{
if
(
skb_linearize
(
rx
->
skb
))
...
...
@@ -516,7 +519,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
queue
=
rx
->
security_idx
;
if
(
memcmp
(
pn
,
key
->
u
.
ccmp
.
rx_pn
[
queue
],
CCMP_PN_LEN
)
<=
0
)
{
if
(
memcmp
(
pn
,
key
->
u
.
ccmp
.
rx_pn
[
queue
],
IEEE80211_
CCMP_PN_LEN
)
<=
0
)
{
key
->
u
.
ccmp
.
replays
++
;
return
RX_DROP_UNUSABLE
;
}
...
...
@@ -528,19 +531,20 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
if
(
ieee80211_aes_ccm_decrypt
(
key
->
u
.
ccmp
.
tfm
,
scratch
,
skb
->
data
+
hdrlen
+
CCMP_HDR_LEN
,
data_len
,
skb
->
data
+
skb
->
len
-
CCMP_MIC_LEN
,
skb
->
data
+
hdrlen
+
CCMP_HDR_LEN
))
skb
->
data
+
hdrlen
+
IEEE80211_CCMP_HDR_LEN
,
data_len
,
skb
->
data
+
skb
->
len
-
IEEE80211_CCMP_MIC_LEN
,
skb
->
data
+
hdrlen
+
IEEE80211_CCMP_HDR_LEN
))
return
RX_DROP_UNUSABLE
;
}
memcpy
(
key
->
u
.
ccmp
.
rx_pn
[
queue
],
pn
,
CCMP_PN_LEN
);
memcpy
(
key
->
u
.
ccmp
.
rx_pn
[
queue
],
pn
,
IEEE80211_
CCMP_PN_LEN
);
/* Remove CCMP header and MIC */
if
(
pskb_trim
(
skb
,
skb
->
len
-
CCMP_MIC_LEN
))
if
(
pskb_trim
(
skb
,
skb
->
len
-
IEEE80211_
CCMP_MIC_LEN
))
return
RX_DROP_UNUSABLE
;
memmove
(
skb
->
data
+
CCMP_HDR_LEN
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
CCMP_HDR_LEN
);
memmove
(
skb
->
data
+
IEEE80211_
CCMP_HDR_LEN
,
skb
->
data
,
hdrlen
);
skb_pull
(
skb
,
IEEE80211_
CCMP_HDR_LEN
);
return
RX_CONTINUE
;
}
...
...
net/wireless/core.c
浏览文件 @
933faa43
...
...
@@ -34,13 +34,12 @@
MODULE_AUTHOR
(
"Johannes Berg"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"wireless configuration support"
);
MODULE_ALIAS_GENL_FAMILY
(
NL80211_GENL_NAME
);
/* RCU-protected (and
cfg80211_mutex
for writers) */
/* RCU-protected (and
RTNL
for writers) */
LIST_HEAD
(
cfg80211_rdev_list
);
int
cfg80211_rdev_list_generation
;
DEFINE_MUTEX
(
cfg80211_mutex
);
/* for debugfs */
static
struct
dentry
*
ieee80211_debugfs_dir
;
...
...
@@ -52,12 +51,11 @@ module_param(cfg80211_disable_40mhz_24ghz, bool, 0644);
MODULE_PARM_DESC
(
cfg80211_disable_40mhz_24ghz
,
"Disable 40MHz support in the 2.4GHz band"
);
/* requires cfg80211_mutex to be held! */
struct
cfg80211_registered_device
*
cfg80211_rdev_by_wiphy_idx
(
int
wiphy_idx
)
{
struct
cfg80211_registered_device
*
result
=
NULL
,
*
rdev
;
assert_cfg80211_lock
();
ASSERT_RTNL
();
list_for_each_entry
(
rdev
,
&
cfg80211_rdev_list
,
list
)
{
if
(
rdev
->
wiphy_idx
==
wiphy_idx
)
{
...
...
@@ -76,12 +74,11 @@ int get_wiphy_idx(struct wiphy *wiphy)
return
rdev
->
wiphy_idx
;
}
/* requires cfg80211_rdev_mutex to be held! */
struct
wiphy
*
wiphy_idx_to_wiphy
(
int
wiphy_idx
)
{
struct
cfg80211_registered_device
*
rdev
;
assert_cfg80211_lock
();
ASSERT_RTNL
();
rdev
=
cfg80211_rdev_by_wiphy_idx
(
wiphy_idx
);
if
(
!
rdev
)
...
...
@@ -89,35 +86,13 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx)
return
&
rdev
->
wiphy
;
}
struct
cfg80211_registered_device
*
cfg80211_get_dev_from_ifindex
(
struct
net
*
net
,
int
ifindex
)
{
struct
cfg80211_registered_device
*
rdev
=
ERR_PTR
(
-
ENODEV
);
struct
net_device
*
dev
;
mutex_lock
(
&
cfg80211_mutex
);
dev
=
dev_get_by_index
(
net
,
ifindex
);
if
(
!
dev
)
goto
out
;
if
(
dev
->
ieee80211_ptr
)
{
rdev
=
wiphy_to_dev
(
dev
->
ieee80211_ptr
->
wiphy
);
mutex_lock
(
&
rdev
->
mtx
);
}
else
rdev
=
ERR_PTR
(
-
ENODEV
);
dev_put
(
dev
);
out:
mutex_unlock
(
&
cfg80211_mutex
);
return
rdev
;
}
/* requires cfg80211_mutex to be held */
int
cfg80211_dev_rename
(
struct
cfg80211_registered_device
*
rdev
,
char
*
newname
)
{
struct
cfg80211_registered_device
*
rdev2
;
int
wiphy_idx
,
taken
=
-
1
,
result
,
digits
;
assert_cfg80211_lock
();
ASSERT_RTNL
();
/* prohibit calling the thing phy%d when %d is not its number */
sscanf
(
newname
,
PHY_NAME
"%d%n"
,
&
wiphy_idx
,
&
taken
);
...
...
@@ -215,8 +190,7 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
void
cfg80211_stop_p2p_device
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
)
{
lockdep_assert_held
(
&
rdev
->
devlist_mtx
);
lockdep_assert_held
(
&
rdev
->
sched_scan_mtx
);
ASSERT_RTNL
();
if
(
WARN_ON
(
wdev
->
iftype
!=
NL80211_IFTYPE_P2P_DEVICE
))
return
;
...
...
@@ -230,18 +204,15 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
rdev
->
opencount
--
;
if
(
rdev
->
scan_req
&&
rdev
->
scan_req
->
wdev
==
wdev
)
{
bool
busy
=
work_busy
(
&
rdev
->
scan_done_wk
);
/*
* If the
work isn't pending or running (in which case it would
*
be waiting for the lock we hold) the driver didn't properly
*
cancel the scan when the interface was removed. In this case
*
warn and leak the scan request object to not crash later
.
* If the
scan request wasn't notified as done, set it
*
to aborted and leak it after a warning. The driver
*
should have notified us that it ended at the latest
*
during rdev_stop_p2p_device()
.
*/
WARN_ON
(
!
busy
);
rdev
->
scan_req
->
aborted
=
true
;
___cfg80211_scan_done
(
rdev
,
!
busy
);
if
(
WARN_ON
(
!
rdev
->
scan_req
->
notified
))
rdev
->
scan_req
->
aborted
=
true
;
___cfg80211_scan_done
(
rdev
,
!
rdev
->
scan_req
->
notified
);
}
}
...
...
@@ -255,8 +226,6 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
rtnl_lock
();
/* read-only iteration need not hold the devlist_mtx */
list_for_each_entry
(
wdev
,
&
rdev
->
wdev_list
,
list
)
{
if
(
wdev
->
netdev
)
{
dev_close
(
wdev
->
netdev
);
...
...
@@ -265,12 +234,7 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked)
/* otherwise, check iftype */
switch
(
wdev
->
iftype
)
{
case
NL80211_IFTYPE_P2P_DEVICE
:
/* but this requires it */
mutex_lock
(
&
rdev
->
devlist_mtx
);
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
cfg80211_stop_p2p_device
(
rdev
,
wdev
);
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
break
;
default:
break
;
...
...
@@ -298,10 +262,7 @@ static void cfg80211_event_work(struct work_struct *work)
event_work
);
rtnl_lock
();
cfg80211_lock_rdev
(
rdev
);
cfg80211_process_rdev_events
(
rdev
);
cfg80211_unlock_rdev
(
rdev
);
rtnl_unlock
();
}
...
...
@@ -309,7 +270,7 @@ static void cfg80211_event_work(struct work_struct *work)
struct
wiphy
*
wiphy_new
(
const
struct
cfg80211_ops
*
ops
,
int
sizeof_priv
)
{
static
int
wiphy_counter
;
static
atomic_t
wiphy_counter
=
ATOMIC_INIT
(
0
)
;
struct
cfg80211_registered_device
*
rdev
;
int
alloc_size
;
...
...
@@ -331,26 +292,18 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
rdev
->
ops
=
ops
;
mutex_lock
(
&
cfg80211_mutex
);
rdev
->
wiphy_idx
=
wiphy_counter
++
;
rdev
->
wiphy_idx
=
atomic_inc_return
(
&
wiphy_counter
);
if
(
unlikely
(
rdev
->
wiphy_idx
<
0
))
{
wiphy_counter
--
;
mutex_unlock
(
&
cfg80211_mutex
);
/* ugh, wrapped! */
atomic_dec
(
&
wiphy_counter
);
kfree
(
rdev
);
return
NULL
;
}
mutex_unlock
(
&
cfg80211_mutex
);
/* give it a proper name */
dev_set_name
(
&
rdev
->
wiphy
.
dev
,
PHY_NAME
"%d"
,
rdev
->
wiphy_idx
);
mutex_init
(
&
rdev
->
mtx
);
mutex_init
(
&
rdev
->
devlist_mtx
);
mutex_init
(
&
rdev
->
sched_scan_mtx
);
INIT_LIST_HEAD
(
&
rdev
->
wdev_list
);
INIT_LIST_HEAD
(
&
rdev
->
beacon_registrations
);
spin_lock_init
(
&
rdev
->
beacon_registrations_lock
);
...
...
@@ -598,11 +551,11 @@ int wiphy_register(struct wiphy *wiphy)
/* check and set up bitrates */
ieee80211_set_bitrate_flags
(
wiphy
);
mutex_lock
(
&
cfg80211_mutex
);
rtnl_lock
(
);
res
=
device_add
(
&
rdev
->
wiphy
.
dev
);
if
(
res
)
{
mutex_unlock
(
&
cfg80211_mutex
);
rtnl_unlock
(
);
return
res
;
}
...
...
@@ -631,24 +584,21 @@ int wiphy_register(struct wiphy *wiphy)
}
cfg80211_debugfs_rdev_add
(
rdev
);
mutex_unlock
(
&
cfg80211_mutex
);
/*
* due to a locking dependency this has to be outside of the
* cfg80211_mutex lock
*/
res
=
rfkill_register
(
rdev
->
rfkill
);
if
(
res
)
goto
out_rm_dev
;
if
(
res
)
{
device_del
(
&
rdev
->
wiphy
.
dev
);
debugfs_remove_recursive
(
rdev
->
wiphy
.
debugfsdir
);
list_del_rcu
(
&
rdev
->
list
);
wiphy_regulatory_deregister
(
wiphy
);
rtnl_unlock
();
return
res
;
}
rtnl_lock
();
rdev
->
wiphy
.
registered
=
true
;
rtnl_unlock
();
return
0
;
out_rm_dev:
device_del
(
&
rdev
->
wiphy
.
dev
);
return
res
;
}
EXPORT_SYMBOL
(
wiphy_register
);
...
...
@@ -675,25 +625,19 @@ void wiphy_unregister(struct wiphy *wiphy)
{
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wiphy
);
rtnl_lock
();
rdev
->
wiphy
.
registered
=
false
;
rtnl_unlock
();
rfkill_unregister
(
rdev
->
rfkill
);
/* protect the device list */
mutex_lock
(
&
cfg80211_mutex
);
wait_event
(
rdev
->
dev_wait
,
({
int
__count
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
rtnl_lock
(
);
__count
=
rdev
->
opencount
;
mutex_unlock
(
&
rdev
->
devlist_mtx
);
rtnl_unlock
(
);
__count
==
0
;
}));
mutex_lock
(
&
rdev
->
devlist_mtx
);
rtnl_lock
();
rdev
->
wiphy
.
registered
=
false
;
rfkill_unregister
(
rdev
->
rfkill
);
BUG_ON
(
!
list_empty
(
&
rdev
->
wdev_list
));
mutex_unlock
(
&
rdev
->
devlist_mtx
);
/*
* First remove the hardware from everywhere, this makes
...
...
@@ -703,20 +647,6 @@ void wiphy_unregister(struct wiphy *wiphy)
list_del_rcu
(
&
rdev
->
list
);
synchronize_rcu
();
/*
* Try to grab rdev->mtx. If a command is still in progress,
* hopefully the driver will refuse it since it's tearing
* down the device already. We wait for this command to complete
* before unlinking the item from the list.
* Note: as codified by the BUG_ON above we cannot get here if
* a virtual interface is still present. Hence, we can only get
* to lock contention here if userspace issues a command that
* identified the hardware by wiphy index.
*/
cfg80211_lock_rdev
(
rdev
);
/* nothing */
cfg80211_unlock_rdev
(
rdev
);
/*
* If this device got a regulatory hint tell core its
* free to listen now to a new shiny device regulatory hint
...
...
@@ -726,15 +656,17 @@ void wiphy_unregister(struct wiphy *wiphy)
cfg80211_rdev_list_generation
++
;
device_del
(
&
rdev
->
wiphy
.
dev
);
mutex_unlock
(
&
cfg80211_mutex
);
rtnl_unlock
(
);
flush_work
(
&
rdev
->
scan_done_wk
);
cancel_work_sync
(
&
rdev
->
conn_work
);
flush_work
(
&
rdev
->
event_work
);
cancel_delayed_work_sync
(
&
rdev
->
dfs_update_channels_wk
);
if
(
rdev
->
wowlan
&&
rdev
->
ops
->
set_wakeup
)
#ifdef CONFIG_PM
if
(
rdev
->
wiphy
.
wowlan_config
&&
rdev
->
ops
->
set_wakeup
)
rdev_set_wakeup
(
rdev
,
false
);
#endif
cfg80211_rdev_free_wowlan
(
rdev
);
}
EXPORT_SYMBOL
(
wiphy_unregister
);
...
...
@@ -744,9 +676,6 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
struct
cfg80211_internal_bss
*
scan
,
*
tmp
;
struct
cfg80211_beacon_registration
*
reg
,
*
treg
;
rfkill_destroy
(
rdev
->
rfkill
);
mutex_destroy
(
&
rdev
->
mtx
);
mutex_destroy
(
&
rdev
->
devlist_mtx
);
mutex_destroy
(
&
rdev
->
sched_scan_mtx
);
list_for_each_entry_safe
(
reg
,
treg
,
&
rdev
->
beacon_registrations
,
list
)
{
list_del
(
&
reg
->
list
);
kfree
(
reg
);
...
...
@@ -771,36 +700,6 @@ void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
}
EXPORT_SYMBOL
(
wiphy_rfkill_set_hw_state
);
static
void
wdev_cleanup_work
(
struct
work_struct
*
work
)
{
struct
wireless_dev
*
wdev
;
struct
cfg80211_registered_device
*
rdev
;
wdev
=
container_of
(
work
,
struct
wireless_dev
,
cleanup_work
);
rdev
=
wiphy_to_dev
(
wdev
->
wiphy
);
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
if
(
WARN_ON
(
rdev
->
scan_req
&&
rdev
->
scan_req
->
wdev
==
wdev
))
{
rdev
->
scan_req
->
aborted
=
true
;
___cfg80211_scan_done
(
rdev
,
true
);
}
if
(
WARN_ON
(
rdev
->
sched_scan_req
&&
rdev
->
sched_scan_req
->
dev
==
wdev
->
netdev
))
{
__cfg80211_stop_sched_scan
(
rdev
,
false
);
}
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
mutex_lock
(
&
rdev
->
devlist_mtx
);
rdev
->
opencount
--
;
mutex_unlock
(
&
rdev
->
devlist_mtx
);
wake_up
(
&
rdev
->
dev_wait
);
dev_put
(
wdev
->
netdev
);
}
void
cfg80211_unregister_wdev
(
struct
wireless_dev
*
wdev
)
{
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wdev
->
wiphy
);
...
...
@@ -810,8 +709,6 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
if
(
WARN_ON
(
wdev
->
netdev
))
return
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
list_del_rcu
(
&
wdev
->
list
);
rdev
->
devlist_generation
++
;
...
...
@@ -823,8 +720,6 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev)
WARN_ON_ONCE
(
1
);
break
;
}
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
}
EXPORT_SYMBOL
(
cfg80211_unregister_wdev
);
...
...
@@ -843,7 +738,7 @@ void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
}
void
cfg80211_leave
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
)
struct
wireless_dev
*
wdev
)
{
struct
net_device
*
dev
=
wdev
->
netdev
;
...
...
@@ -853,9 +748,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
break
;
case
NL80211_IFTYPE_P2P_CLIENT
:
case
NL80211_IFTYPE_STATION
:
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
__cfg80211_stop_sched_scan
(
rdev
,
false
);
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
wdev_lock
(
wdev
);
#ifdef CONFIG_CFG80211_WEXT
...
...
@@ -864,9 +757,8 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
wdev
->
wext
.
ie_len
=
0
;
wdev
->
wext
.
connect
.
auth_type
=
NL80211_AUTHTYPE_AUTOMATIC
;
#endif
__cfg80211_disconnect
(
rdev
,
dev
,
WLAN_REASON_DEAUTH_LEAVING
,
true
);
cfg80211_mlme_down
(
rdev
,
dev
);
cfg80211_disconnect
(
rdev
,
dev
,
WLAN_REASON_DEAUTH_LEAVING
,
true
);
wdev_unlock
(
wdev
);
break
;
case
NL80211_IFTYPE_MESH_POINT
:
...
...
@@ -909,13 +801,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
* are added with nl80211.
*/
mutex_init
(
&
wdev
->
mtx
);
INIT_WORK
(
&
wdev
->
cleanup_work
,
wdev_cleanup_work
);
INIT_LIST_HEAD
(
&
wdev
->
event_list
);
spin_lock_init
(
&
wdev
->
event_lock
);
INIT_LIST_HEAD
(
&
wdev
->
mgmt_registrations
);
spin_lock_init
(
&
wdev
->
mgmt_registrations_lock
);
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev
->
identifier
=
++
rdev
->
wdev_id
;
list_add_rcu
(
&
wdev
->
list
,
&
rdev
->
wdev_list
);
rdev
->
devlist_generation
++
;
...
...
@@ -928,7 +818,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
}
wdev
->
netdev
=
dev
;
wdev
->
sme_state
=
CFG80211_SME_IDLE
;
mutex_unlock
(
&
rdev
->
devlist_mtx
);
#ifdef CONFIG_CFG80211_WEXT
wdev
->
wext
.
default_key
=
-
1
;
wdev
->
wext
.
default_mgmt_key
=
-
1
;
...
...
@@ -954,26 +843,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
break
;
case
NETDEV_DOWN
:
cfg80211_update_iface_num
(
rdev
,
wdev
->
iftype
,
-
1
);
dev_hold
(
dev
);
queue_work
(
cfg80211_wq
,
&
wdev
->
cleanup_work
);
if
(
rdev
->
scan_req
&&
rdev
->
scan_req
->
wdev
==
wdev
)
{
if
(
WARN_ON
(
!
rdev
->
scan_req
->
notified
))
rdev
->
scan_req
->
aborted
=
true
;
___cfg80211_scan_done
(
rdev
,
true
);
}
if
(
WARN_ON
(
rdev
->
sched_scan_req
&&
rdev
->
sched_scan_req
->
dev
==
wdev
->
netdev
))
{
__cfg80211_stop_sched_scan
(
rdev
,
false
);
}
rdev
->
opencount
--
;
wake_up
(
&
rdev
->
dev_wait
);
break
;
case
NETDEV_UP
:
/*
* If we have a really quick DOWN/UP succession we may
* have this work still pending ... cancel it and see
* if it was pending, in which case we need to account
* for some of the work it would have done.
*/
if
(
cancel_work_sync
(
&
wdev
->
cleanup_work
))
{
mutex_lock
(
&
rdev
->
devlist_mtx
);
rdev
->
opencount
--
;
mutex_unlock
(
&
rdev
->
devlist_mtx
);
dev_put
(
dev
);
}
cfg80211_update_iface_num
(
rdev
,
wdev
->
iftype
,
1
);
cfg80211_lock_rdev
(
rdev
);
mutex_lock
(
&
rdev
->
devlist_mtx
);
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
wdev_lock
(
wdev
);
switch
(
wdev
->
iftype
)
{
#ifdef CONFIG_CFG80211_WEXT
...
...
@@ -1005,10 +890,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
break
;
}
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
rdev
->
opencount
++
;
mutex_unlock
(
&
rdev
->
devlist_mtx
);
cfg80211_unlock_rdev
(
rdev
);
/*
* Configure power management to the driver here so that its
...
...
@@ -1024,12 +906,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
}
break
;
case
NETDEV_UNREGISTER
:
/*
* NB: cannot take rdev->mtx here because this may be
* called within code protected by it when interfaces
* are removed with nl80211.
*/
mutex_lock
(
&
rdev
->
devlist_mtx
);
/*
* It is possible to get NETDEV_UNREGISTER
* multiple times. To detect that, check
...
...
@@ -1046,7 +922,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
kfree
(
wdev
->
wext
.
keys
);
#endif
}
mutex_unlock
(
&
rdev
->
devlist_mtx
);
/*
* synchronise (so that we won't find this netdev
* from other code any more) and then clear the list
...
...
@@ -1066,9 +941,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
return
notifier_from_errno
(
-
EOPNOTSUPP
);
if
(
rfkill_blocked
(
rdev
->
rfkill
))
return
notifier_from_errno
(
-
ERFKILL
);
mutex_lock
(
&
rdev
->
devlist_mtx
);
ret
=
cfg80211_can_add_interface
(
rdev
,
wdev
->
iftype
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
if
(
ret
)
return
notifier_from_errno
(
ret
);
break
;
...
...
@@ -1086,12 +959,10 @@ static void __net_exit cfg80211_pernet_exit(struct net *net)
struct
cfg80211_registered_device
*
rdev
;
rtnl_lock
();
mutex_lock
(
&
cfg80211_mutex
);
list_for_each_entry
(
rdev
,
&
cfg80211_rdev_list
,
list
)
{
if
(
net_eq
(
wiphy_net
(
&
rdev
->
wiphy
),
net
))
WARN_ON
(
cfg80211_switch_netns
(
rdev
,
&
init_net
));
}
mutex_unlock
(
&
cfg80211_mutex
);
rtnl_unlock
();
}
...
...
net/wireless/core.h
浏览文件 @
933faa43
...
...
@@ -5,7 +5,6 @@
*/
#ifndef __NET_WIRELESS_CORE_H
#define __NET_WIRELESS_CORE_H
#include <linux/mutex.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/rbtree.h>
...
...
@@ -23,11 +22,6 @@
struct
cfg80211_registered_device
{
const
struct
cfg80211_ops
*
ops
;
struct
list_head
list
;
/* we hold this mutex during any call so that
* we cannot do multiple calls at once, and also
* to avoid the deregister call to proceed while
* any call is in progress */
struct
mutex
mtx
;
/* rfkill support */
struct
rfkill_ops
rfkill_ops
;
...
...
@@ -49,9 +43,7 @@ struct cfg80211_registered_device {
/* wiphy index, internal only */
int
wiphy_idx
;
/* associated wireless interfaces */
struct
mutex
devlist_mtx
;
/* protected by devlist_mtx or RCU */
/* associated wireless interfaces, protected by rtnl or RCU */
struct
list_head
wdev_list
;
int
devlist_generation
,
wdev_id
;
int
opencount
;
/* also protected by devlist_mtx */
...
...
@@ -75,8 +67,6 @@ struct cfg80211_registered_device {
struct
work_struct
scan_done_wk
;
struct
work_struct
sched_scan_results_wk
;
struct
mutex
sched_scan_mtx
;
#ifdef CONFIG_NL80211_TESTMODE
struct
genl_info
*
testmode_info
;
#endif
...
...
@@ -84,8 +74,6 @@ struct cfg80211_registered_device {
struct
work_struct
conn_work
;
struct
work_struct
event_work
;
struct
cfg80211_wowlan
*
wowlan
;
struct
delayed_work
dfs_update_channels_wk
;
/* netlink port which started critical protocol (0 means not started) */
...
...
@@ -106,29 +94,26 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy)
static
inline
void
cfg80211_rdev_free_wowlan
(
struct
cfg80211_registered_device
*
rdev
)
{
#ifdef CONFIG_PM
int
i
;
if
(
!
rdev
->
w
owlan
)
if
(
!
rdev
->
w
iphy
.
wowlan_config
)
return
;
for
(
i
=
0
;
i
<
rdev
->
wowlan
->
n_patterns
;
i
++
)
kfree
(
rdev
->
wowlan
->
patterns
[
i
].
mask
);
kfree
(
rdev
->
wowlan
->
patterns
);
if
(
rdev
->
wowlan
->
tcp
&&
rdev
->
wowlan
->
tcp
->
sock
)
sock_release
(
rdev
->
wowlan
->
tcp
->
sock
);
kfree
(
rdev
->
wowlan
->
tcp
);
kfree
(
rdev
->
wowlan
);
for
(
i
=
0
;
i
<
rdev
->
wiphy
.
wowlan_config
->
n_patterns
;
i
++
)
kfree
(
rdev
->
wiphy
.
wowlan_config
->
patterns
[
i
].
mask
);
kfree
(
rdev
->
wiphy
.
wowlan_config
->
patterns
);
if
(
rdev
->
wiphy
.
wowlan_config
->
tcp
&&
rdev
->
wiphy
.
wowlan_config
->
tcp
->
sock
)
sock_release
(
rdev
->
wiphy
.
wowlan_config
->
tcp
->
sock
);
kfree
(
rdev
->
wiphy
.
wowlan_config
->
tcp
);
kfree
(
rdev
->
wiphy
.
wowlan_config
);
#endif
}
extern
struct
workqueue_struct
*
cfg80211_wq
;
extern
struct
mutex
cfg80211_mutex
;
extern
struct
list_head
cfg80211_rdev_list
;
extern
int
cfg80211_rdev_list_generation
;
static
inline
void
assert_cfg80211_lock
(
void
)
{
lockdep_assert_held
(
&
cfg80211_mutex
);
}
struct
cfg80211_internal_bss
{
struct
list_head
list
;
struct
list_head
hidden_list
;
...
...
@@ -161,27 +146,11 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss)
struct
cfg80211_registered_device
*
cfg80211_rdev_by_wiphy_idx
(
int
wiphy_idx
);
int
get_wiphy_idx
(
struct
wiphy
*
wiphy
);
/* requires cfg80211_rdev_mutex to be held! */
struct
wiphy
*
wiphy_idx_to_wiphy
(
int
wiphy_idx
);
/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
extern
struct
cfg80211_registered_device
*
cfg80211_get_dev_from_ifindex
(
struct
net
*
net
,
int
ifindex
);
int
cfg80211_switch_netns
(
struct
cfg80211_registered_device
*
rdev
,
struct
net
*
net
);
static
inline
void
cfg80211_lock_rdev
(
struct
cfg80211_registered_device
*
rdev
)
{
mutex_lock
(
&
rdev
->
mtx
);
}
static
inline
void
cfg80211_unlock_rdev
(
struct
cfg80211_registered_device
*
rdev
)
{
BUG_ON
(
IS_ERR
(
rdev
)
||
!
rdev
);
mutex_unlock
(
&
rdev
->
mtx
);
}
static
inline
void
wdev_lock
(
struct
wireless_dev
*
wdev
)
__acquires
(
wdev
)
{
...
...
@@ -196,7 +165,7 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
mutex_unlock
(
&
wdev
->
mtx
);
}
#define ASSERT_RDEV_LOCK(rdev)
lockdep_assert_held(&(rdev)->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
)
...
...
@@ -314,38 +283,21 @@ int cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
struct
net_device
*
dev
);
/* MLME */
int
__cfg80211_mlme_auth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_auth_type
auth_type
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
const
u8
*
ie
,
int
ie_len
,
const
u8
*
key
,
int
key_len
,
int
key_idx
,
const
u8
*
sae_data
,
int
sae_data_len
);
int
cfg80211_mlme_auth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_auth_type
auth_type
,
const
u8
*
bssid
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_auth_type
auth_type
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
const
u8
*
ie
,
int
ie_len
,
const
u8
*
key
,
int
key_len
,
int
key_idx
,
const
u8
*
sae_data
,
int
sae_data_len
);
int
__cfg80211_mlme_assoc
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
struct
cfg80211_assoc_request
*
req
);
int
cfg80211_mlme_assoc
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
struct
cfg80211_assoc_request
*
req
);
int
__cfg80211_mlme_deauth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
const
u8
*
bssid
,
const
u8
*
ie
,
int
ie_len
,
u16
reason
,
bool
local_state_change
);
int
cfg80211_mlme_deauth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
const
u8
*
bssid
,
const
u8
*
ie
,
int
ie_len
,
u16
reason
,
...
...
@@ -377,18 +329,11 @@ void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
const
struct
ieee80211_vht_cap
*
vht_capa_mask
);
/* SME */
int
__cfg80211_connect
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_connect_params
*
connect
,
struct
cfg80211_cached_keys
*
connkeys
,
const
u8
*
prev_bssid
);
int
cfg80211_connect
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_connect_params
*
connect
,
struct
cfg80211_cached_keys
*
connkeys
);
int
__cfg80211_disconnect
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
u16
reason
,
bool
wextev
);
struct
cfg80211_cached_keys
*
connkeys
,
const
u8
*
prev_bssid
);
int
cfg80211_disconnect
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
u16
reason
,
bool
wextev
);
...
...
net/wireless/debugfs.c
浏览文件 @
933faa43
...
...
@@ -74,7 +74,7 @@ static ssize_t ht40allow_map_read(struct file *file,
if
(
!
buf
)
return
-
ENOMEM
;
mutex_lock
(
&
cfg80211_mutex
);
rtnl_lock
(
);
for
(
band
=
0
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
{
sband
=
wiphy
->
bands
[
band
];
...
...
@@ -85,7 +85,7 @@ static ssize_t ht40allow_map_read(struct file *file,
buf
,
buf_size
,
offset
);
}
mutex_unlock
(
&
cfg80211_mutex
);
rtnl_unlock
(
);
r
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
offset
);
...
...
net/wireless/ibss.c
浏览文件 @
933faa43
...
...
@@ -152,11 +152,11 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
ASSERT_RTNL
();
wdev_lock
(
wdev
);
err
=
__cfg80211_join_ibss
(
rdev
,
dev
,
params
,
connkeys
);
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
...
...
@@ -359,11 +359,9 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
wdev
->
wext
.
ibss
.
channel_fixed
=
false
;
}
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
wdev
);
err
=
cfg80211_ibss_wext_join
(
rdev
,
wdev
);
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
...
...
@@ -429,11 +427,9 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
memcpy
(
wdev
->
wext
.
ibss
.
ssid
,
ssid
,
len
);
wdev
->
wext
.
ibss
.
ssid_len
=
len
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
wdev
);
err
=
cfg80211_ibss_wext_join
(
rdev
,
wdev
);
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
...
...
@@ -512,11 +508,9 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
}
else
wdev
->
wext
.
ibss
.
bssid
=
NULL
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
wdev
);
err
=
cfg80211_ibss_wext_join
(
rdev
,
wdev
);
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
...
...
net/wireless/mesh.c
浏览文件 @
933faa43
...
...
@@ -82,6 +82,7 @@ const struct mesh_setup default_mesh_setup = {
.
sync_method
=
IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET
,
.
path_sel_proto
=
IEEE80211_PATH_PROTOCOL_HWMP
,
.
path_metric
=
IEEE80211_PATH_METRIC_AIRTIME
,
.
auth_id
=
0
,
/* open */
.
ie
=
NULL
,
.
ie_len
=
0
,
.
is_secure
=
false
,
...
...
@@ -185,11 +186,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
wdev
);
err
=
__cfg80211_join_mesh
(
rdev
,
dev
,
setup
,
conf
);
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
...
...
net/wireless/mlme.c
浏览文件 @
933faa43
...
...
@@ -25,12 +25,9 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wiphy
);
trace_cfg80211_send_rx_auth
(
dev
);
wdev_lock
(
wdev
);
nl80211_send_rx_auth
(
rdev
,
dev
,
buf
,
len
,
GFP_KERNEL
);
cfg80211_sme_rx_auth
(
dev
,
buf
,
len
);
wdev_unlock
(
wdev
);
}
EXPORT_SYMBOL
(
cfg80211_send_rx_auth
);
...
...
@@ -46,7 +43,6 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
int
ieoffs
=
offsetof
(
struct
ieee80211_mgmt
,
u
.
assoc_resp
.
variable
);
trace_cfg80211_send_rx_assoc
(
dev
,
bss
);
wdev_lock
(
wdev
);
status_code
=
le16_to_cpu
(
mgmt
->
u
.
assoc_resp
.
status_code
);
...
...
@@ -59,7 +55,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
if
(
status_code
!=
WLAN_STATUS_SUCCESS
&&
wdev
->
conn
&&
cfg80211_sme_failed_reassoc
(
wdev
))
{
cfg80211_put_bss
(
wiphy
,
bss
);
goto
out
;
return
;
}
nl80211_send_rx_assoc
(
rdev
,
dev
,
buf
,
len
,
GFP_KERNEL
);
...
...
@@ -71,7 +67,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
* sme will schedule work that does it later.
*/
cfg80211_put_bss
(
wiphy
,
bss
);
goto
out
;
return
;
}
if
(
!
wdev
->
conn
&&
wdev
->
sme_state
==
CFG80211_SME_IDLE
)
{
...
...
@@ -87,13 +83,11 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
__cfg80211_connect_result
(
dev
,
mgmt
->
bssid
,
NULL
,
0
,
ie
,
len
-
ieoffs
,
status_code
,
status_code
==
WLAN_STATUS_SUCCESS
,
bss
);
out:
wdev_unlock
(
wdev
);
}
EXPORT_SYMBOL
(
cfg80211_send_rx_assoc
);
void
__
cfg80211_send_deauth
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
)
void
cfg80211_send_deauth
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
wiphy
*
wiphy
=
wdev
->
wiphy
;
...
...
@@ -102,7 +96,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
const
u8
*
bssid
=
mgmt
->
bssid
;
bool
was_current
=
false
;
trace_
__
cfg80211_send_deauth
(
dev
);
trace_cfg80211_send_deauth
(
dev
);
ASSERT_WDEV_LOCK
(
wdev
);
if
(
wdev
->
current_bss
&&
...
...
@@ -129,20 +123,10 @@ void __cfg80211_send_deauth(struct net_device *dev,
false
,
NULL
);
}
}
EXPORT_SYMBOL
(
__cfg80211_send_deauth
);
void
cfg80211_send_deauth
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
wdev_lock
(
wdev
);
__cfg80211_send_deauth
(
dev
,
buf
,
len
);
wdev_unlock
(
wdev
);
}
EXPORT_SYMBOL
(
cfg80211_send_deauth
);
void
__
cfg80211_send_disassoc
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
)
void
cfg80211_send_disassoc
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
wiphy
*
wiphy
=
wdev
->
wiphy
;
...
...
@@ -152,7 +136,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
u16
reason_code
;
bool
from_ap
;
trace_
__
cfg80211_send_disassoc
(
dev
);
trace_cfg80211_send_disassoc
(
dev
);
ASSERT_WDEV_LOCK
(
wdev
);
nl80211_send_disassoc
(
rdev
,
dev
,
buf
,
len
,
GFP_KERNEL
);
...
...
@@ -175,16 +159,6 @@ void __cfg80211_send_disassoc(struct net_device *dev,
from_ap
=
!
ether_addr_equal
(
mgmt
->
sa
,
dev
->
dev_addr
);
__cfg80211_disconnected
(
dev
,
NULL
,
0
,
reason_code
,
from_ap
);
}
EXPORT_SYMBOL
(
__cfg80211_send_disassoc
);
void
cfg80211_send_disassoc
(
struct
net_device
*
dev
,
const
u8
*
buf
,
size_t
len
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
wdev_lock
(
wdev
);
__cfg80211_send_disassoc
(
dev
,
buf
,
len
);
wdev_unlock
(
wdev
);
}
EXPORT_SYMBOL
(
cfg80211_send_disassoc
);
void
cfg80211_send_auth_timeout
(
struct
net_device
*
dev
,
const
u8
*
addr
)
...
...
@@ -194,15 +168,12 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wiphy
);
trace_cfg80211_send_auth_timeout
(
dev
,
addr
);
wdev_lock
(
wdev
);
nl80211_send_auth_timeout
(
rdev
,
dev
,
addr
,
GFP_KERNEL
);
if
(
wdev
->
sme_state
==
CFG80211_SME_CONNECTING
)
__cfg80211_connect_result
(
dev
,
addr
,
NULL
,
0
,
NULL
,
0
,
WLAN_STATUS_UNSPECIFIED_FAILURE
,
false
,
NULL
);
wdev_unlock
(
wdev
);
}
EXPORT_SYMBOL
(
cfg80211_send_auth_timeout
);
...
...
@@ -213,15 +184,12 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wiphy
);
trace_cfg80211_send_assoc_timeout
(
dev
,
addr
);
wdev_lock
(
wdev
);
nl80211_send_assoc_timeout
(
rdev
,
dev
,
addr
,
GFP_KERNEL
);
if
(
wdev
->
sme_state
==
CFG80211_SME_CONNECTING
)
__cfg80211_connect_result
(
dev
,
addr
,
NULL
,
0
,
NULL
,
0
,
WLAN_STATUS_UNSPECIFIED_FAILURE
,
false
,
NULL
);
wdev_unlock
(
wdev
);
}
EXPORT_SYMBOL
(
cfg80211_send_assoc_timeout
);
...
...
@@ -253,18 +221,27 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
EXPORT_SYMBOL
(
cfg80211_michael_mic_failure
);
/* some MLME handling for userspace SME */
int
__
cfg80211_mlme_auth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_auth_type
auth_type
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
const
u8
*
ie
,
int
ie_len
,
const
u8
*
key
,
int
key_len
,
int
key_idx
,
const
u8
*
sae_data
,
int
sae_data_len
)
int
cfg80211_mlme_auth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_auth_type
auth_type
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
const
u8
*
ie
,
int
ie_len
,
const
u8
*
key
,
int
key_len
,
int
key_idx
,
const
u8
*
sae_data
,
int
sae_data_len
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
cfg80211_auth_request
req
;
struct
cfg80211_auth_request
req
=
{
.
ie
=
ie
,
.
ie_len
=
ie_len
,
.
sae_data
=
sae_data
,
.
sae_data_len
=
sae_data_len
,
.
auth_type
=
auth_type
,
.
key
=
key
,
.
key_len
=
key_len
,
.
key_idx
=
key_idx
,
};
int
err
;
ASSERT_WDEV_LOCK
(
wdev
);
...
...
@@ -277,18 +254,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
ether_addr_equal
(
bssid
,
wdev
->
current_bss
->
pub
.
bssid
))
return
-
EALREADY
;
memset
(
&
req
,
0
,
sizeof
(
req
));
req
.
ie
=
ie
;
req
.
ie_len
=
ie_len
;
req
.
sae_data
=
sae_data
;
req
.
sae_data_len
=
sae_data_len
;
req
.
auth_type
=
auth_type
;
req
.
bss
=
cfg80211_get_bss
(
&
rdev
->
wiphy
,
chan
,
bssid
,
ssid
,
ssid_len
,
WLAN_CAPABILITY_ESS
,
WLAN_CAPABILITY_ESS
);
req
.
key
=
key
;
req
.
key_len
=
key_len
;
req
.
key_idx
=
key_idx
;
if
(
!
req
.
bss
)
return
-
ENOENT
;
...
...
@@ -304,28 +271,6 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
return
err
;
}
int
cfg80211_mlme_auth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_auth_type
auth_type
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
const
u8
*
ie
,
int
ie_len
,
const
u8
*
key
,
int
key_len
,
int
key_idx
,
const
u8
*
sae_data
,
int
sae_data_len
)
{
int
err
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
dev
->
ieee80211_ptr
);
err
=
__cfg80211_mlme_auth
(
rdev
,
dev
,
chan
,
auth_type
,
bssid
,
ssid
,
ssid_len
,
ie
,
ie_len
,
key
,
key_len
,
key_idx
,
sae_data
,
sae_data_len
);
wdev_unlock
(
dev
->
ieee80211_ptr
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
/* Do a logical ht_capa &= ht_capa_mask. */
void
cfg80211_oper_and_ht_capa
(
struct
ieee80211_ht_cap
*
ht_capa
,
const
struct
ieee80211_ht_cap
*
ht_capa_mask
)
...
...
@@ -360,12 +305,12 @@ void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
p1
[
i
]
&=
p2
[
i
];
}
int
__
cfg80211_mlme_assoc
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
struct
cfg80211_assoc_request
*
req
)
int
cfg80211_mlme_assoc
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
struct
cfg80211_assoc_request
*
req
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
...
...
@@ -415,30 +360,10 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
return
err
;
}
int
cfg80211_mlme_assoc
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
ieee80211_channel
*
chan
,
const
u8
*
bssid
,
const
u8
*
ssid
,
int
ssid_len
,
struct
cfg80211_assoc_request
*
req
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
wdev
);
err
=
__cfg80211_mlme_assoc
(
rdev
,
dev
,
chan
,
bssid
,
ssid
,
ssid_len
,
req
);
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
int
__cfg80211_mlme_deauth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
const
u8
*
bssid
,
const
u8
*
ie
,
int
ie_len
,
u16
reason
,
bool
local_state_change
)
int
cfg80211_mlme_deauth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
const
u8
*
bssid
,
const
u8
*
ie
,
int
ie_len
,
u16
reason
,
bool
local_state_change
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
cfg80211_deauth_request
req
=
{
...
...
@@ -458,29 +383,18 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
return
rdev_deauth
(
rdev
,
dev
,
&
req
);
}
int
cfg80211_mlme_deauth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
const
u8
*
bssid
,
const
u8
*
ie
,
int
ie_len
,
u16
reason
,
bool
local_state_change
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
wdev_lock
(
wdev
);
err
=
__cfg80211_mlme_deauth
(
rdev
,
dev
,
bssid
,
ie
,
ie_len
,
reason
,
local_state_change
);
wdev_unlock
(
wdev
);
return
err
;
}
static
int
__cfg80211_mlme_disassoc
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
const
u8
*
bssid
,
const
u8
*
ie
,
int
ie_len
,
u16
reason
,
bool
local_state_change
)
int
cfg80211_mlme_disassoc
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
const
u8
*
bssid
,
const
u8
*
ie
,
int
ie_len
,
u16
reason
,
bool
local_state_change
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
cfg80211_disassoc_request
req
;
struct
cfg80211_disassoc_request
req
=
{
.
reason_code
=
reason
,
.
local_state_change
=
local_state_change
,
.
ie
=
ie
,
.
ie_len
=
ie_len
,
};
ASSERT_WDEV_LOCK
(
wdev
);
...
...
@@ -490,11 +404,6 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
if
(
WARN
(
!
wdev
->
current_bss
,
"sme_state=%d
\n
"
,
wdev
->
sme_state
))
return
-
ENOTCONN
;
memset
(
&
req
,
0
,
sizeof
(
req
));
req
.
reason_code
=
reason
;
req
.
local_state_change
=
local_state_change
;
req
.
ie
=
ie
;
req
.
ie_len
=
ie_len
;
if
(
ether_addr_equal
(
wdev
->
current_bss
->
pub
.
bssid
,
bssid
))
req
.
bss
=
&
wdev
->
current_bss
->
pub
;
else
...
...
@@ -503,44 +412,25 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
return
rdev_disassoc
(
rdev
,
dev
,
&
req
);
}
int
cfg80211_mlme_disassoc
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
const
u8
*
bssid
,
const
u8
*
ie
,
int
ie_len
,
u16
reason
,
bool
local_state_change
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
wdev_lock
(
wdev
);
err
=
__cfg80211_mlme_disassoc
(
rdev
,
dev
,
bssid
,
ie
,
ie_len
,
reason
,
local_state_change
);
wdev_unlock
(
wdev
);
return
err
;
}
void
cfg80211_mlme_down
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
cfg80211_deauth_request
req
;
u8
bssid
[
ETH_ALEN
];
struct
cfg80211_deauth_request
req
=
{
.
reason_code
=
WLAN_REASON_DEAUTH_LEAVING
,
.
bssid
=
bssid
,
};
ASSERT_WDEV_LOCK
(
wdev
);
if
(
!
rdev
->
ops
->
deauth
)
return
;
memset
(
&
req
,
0
,
sizeof
(
req
));
req
.
reason_code
=
WLAN_REASON_DEAUTH_LEAVING
;
req
.
ie
=
NULL
;
req
.
ie_len
=
0
;
if
(
!
wdev
->
current_bss
)
return
;
memcpy
(
bssid
,
wdev
->
current_bss
->
pub
.
bssid
,
ETH_ALEN
);
req
.
bssid
=
bssid
;
rdev_deauth
(
rdev
,
dev
,
&
req
);
if
(
wdev
->
current_bss
)
{
...
...
@@ -848,7 +738,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
dfs_update_channels_wk
);
wiphy
=
&
rdev
->
wiphy
;
mutex_lock
(
&
cfg80211_mutex
);
rtnl_lock
(
);
for
(
bandid
=
0
;
bandid
<
IEEE80211_NUM_BANDS
;
bandid
++
)
{
sband
=
wiphy
->
bands
[
bandid
];
if
(
!
sband
)
...
...
@@ -881,7 +771,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
check_again
=
true
;
}
}
mutex_unlock
(
&
cfg80211_mutex
);
rtnl_unlock
(
);
/* reschedule if there are other channels waiting to be cleared again */
if
(
check_again
)
...
...
net/wireless/nl80211.c
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
net/wireless/reg.c
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
net/wireless/scan.c
浏览文件 @
933faa43
...
...
@@ -169,7 +169,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
union
iwreq_data
wrqu
;
#endif
lockdep_assert_held
(
&
rdev
->
sched_scan_mtx
);
ASSERT_RTNL
(
);
request
=
rdev
->
scan_req
;
...
...
@@ -230,9 +230,9 @@ void __cfg80211_scan_done(struct work_struct *wk)
rdev
=
container_of
(
wk
,
struct
cfg80211_registered_device
,
scan_done_wk
);
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
rtnl_lock
(
);
___cfg80211_scan_done
(
rdev
,
false
);
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
rtnl_unlock
(
);
}
void
cfg80211_scan_done
(
struct
cfg80211_scan_request
*
request
,
bool
aborted
)
...
...
@@ -241,6 +241,7 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
WARN_ON
(
request
!=
wiphy_to_dev
(
request
->
wiphy
)
->
scan_req
);
request
->
aborted
=
aborted
;
request
->
notified
=
true
;
queue_work
(
cfg80211_wq
,
&
wiphy_to_dev
(
request
->
wiphy
)
->
scan_done_wk
);
}
EXPORT_SYMBOL
(
cfg80211_scan_done
);
...
...
@@ -255,7 +256,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
request
=
rdev
->
sched_scan_req
;
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
rtnl_lock
(
);
/* we don't have sched_scan_req anymore if the scan is stopping */
if
(
request
)
{
...
...
@@ -270,7 +271,7 @@ void __cfg80211_sched_scan_results(struct work_struct *wk)
nl80211_send_sched_scan_results
(
rdev
,
request
->
dev
);
}
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
rtnl_unlock
(
);
}
void
cfg80211_sched_scan_results
(
struct
wiphy
*
wiphy
)
...
...
@@ -289,9 +290,9 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
trace_cfg80211_sched_scan_stopped
(
wiphy
);
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
rtnl_lock
(
);
__cfg80211_stop_sched_scan
(
rdev
,
true
);
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
rtnl_unlock
(
);
}
EXPORT_SYMBOL
(
cfg80211_sched_scan_stopped
);
...
...
@@ -300,7 +301,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
{
struct
net_device
*
dev
;
lockdep_assert_held
(
&
rdev
->
sched_scan_mtx
);
ASSERT_RTNL
(
);
if
(
!
rdev
->
sched_scan_req
)
return
-
ENOENT
;
...
...
@@ -1040,6 +1041,25 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
EXPORT_SYMBOL
(
cfg80211_unlink_bss
);
#ifdef CONFIG_CFG80211_WEXT
static
struct
cfg80211_registered_device
*
cfg80211_get_dev_from_ifindex
(
struct
net
*
net
,
int
ifindex
)
{
struct
cfg80211_registered_device
*
rdev
;
struct
net_device
*
dev
;
ASSERT_RTNL
();
dev
=
dev_get_by_index
(
net
,
ifindex
);
if
(
!
dev
)
return
ERR_PTR
(
-
ENODEV
);
if
(
dev
->
ieee80211_ptr
)
rdev
=
wiphy_to_dev
(
dev
->
ieee80211_ptr
->
wiphy
);
else
rdev
=
ERR_PTR
(
-
ENODEV
);
dev_put
(
dev
);
return
rdev
;
}
int
cfg80211_wext_siwscan
(
struct
net_device
*
dev
,
struct
iw_request_info
*
info
,
union
iwreq_data
*
wrqu
,
char
*
extra
)
...
...
@@ -1062,7 +1082,6 @@ int cfg80211_wext_siwscan(struct net_device *dev,
if
(
IS_ERR
(
rdev
))
return
PTR_ERR
(
rdev
);
mutex_lock
(
&
rdev
->
sched_scan_mtx
);
if
(
rdev
->
scan_req
)
{
err
=
-
EBUSY
;
goto
out
;
...
...
@@ -1169,9 +1188,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
dev_hold
(
dev
);
}
out:
mutex_unlock
(
&
rdev
->
sched_scan_mtx
);
kfree
(
creq
);
cfg80211_unlock_rdev
(
rdev
);
return
err
;
}
EXPORT_SYMBOL_GPL
(
cfg80211_wext_siwscan
);
...
...
@@ -1470,10 +1487,8 @@ int cfg80211_wext_giwscan(struct net_device *dev,
if
(
IS_ERR
(
rdev
))
return
PTR_ERR
(
rdev
);
if
(
rdev
->
scan_req
)
{
res
=
-
EAGAIN
;
goto
out
;
}
if
(
rdev
->
scan_req
)
return
-
EAGAIN
;
res
=
ieee80211_scan_results
(
rdev
,
info
,
extra
,
data
->
length
);
data
->
length
=
0
;
...
...
@@ -1482,8 +1497,6 @@ int cfg80211_wext_giwscan(struct net_device *dev,
res
=
0
;
}
out:
cfg80211_unlock_rdev
(
rdev
);
return
res
;
}
EXPORT_SYMBOL_GPL
(
cfg80211_wext_giwscan
);
...
...
net/wireless/sme.c
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
net/wireless/sysfs.c
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
net/wireless/trace.h
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
net/wireless/util.c
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
net/wireless/wext-compat.c
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
net/wireless/wext-sme.c
浏览文件 @
933faa43
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录