Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
0f622485
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
0f622485
编写于
11月 16, 2012
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
上级
b8d9e572
6352c87f
变更
41
展开全部
隐藏空白更改
内联
并排
Showing
41 changed file
with
1324 addition
and
481 deletion
+1324
-481
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/base.c
+6
-4
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath5k/mac80211-ops.c
+3
-2
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/cfg80211.c
+4
-5
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+3
-3
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
+12
-8
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/main.c
+9
-6
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+4
-2
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mac80211_hwsim.c
+399
-101
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/cfg80211.c
+1
-0
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rndis_wlan.c
+8
-2
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00dev.c
+10
-9
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00mac.c
+3
-3
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/main.c
+1
-1
include/linux/ieee80211.h
include/linux/ieee80211.h
+32
-0
include/net/cfg80211.h
include/net/cfg80211.h
+33
-5
include/net/mac80211.h
include/net/mac80211.h
+50
-3
include/uapi/linux/nl80211.h
include/uapi/linux/nl80211.h
+7
-0
net/mac80211/aes_cmac.c
net/mac80211/aes_cmac.c
+1
-0
net/mac80211/cfg.c
net/mac80211/cfg.c
+92
-31
net/mac80211/chan.c
net/mac80211/chan.c
+2
-0
net/mac80211/debugfs_netdev.c
net/mac80211/debugfs_netdev.c
+35
-31
net/mac80211/driver-ops.h
net/mac80211/driver-ops.h
+35
-0
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+14
-3
net/mac80211/iface.c
net/mac80211/iface.c
+38
-19
net/mac80211/main.c
net/mac80211/main.c
+16
-11
net/mac80211/mlme.c
net/mac80211/mlme.c
+75
-29
net/mac80211/offchannel.c
net/mac80211/offchannel.c
+3
-4
net/mac80211/pm.c
net/mac80211/pm.c
+4
-0
net/mac80211/rx.c
net/mac80211/rx.c
+14
-27
net/mac80211/status.c
net/mac80211/status.c
+71
-74
net/mac80211/trace.h
net/mac80211/trace.h
+48
-28
net/mac80211/tx.c
net/mac80211/tx.c
+1
-0
net/mac80211/util.c
net/mac80211/util.c
+41
-18
net/wireless/ap.c
net/wireless/ap.c
+1
-0
net/wireless/core.c
net/wireless/core.c
+7
-0
net/wireless/core.h
net/wireless/core.h
+6
-1
net/wireless/nl80211.c
net/wireless/nl80211.c
+115
-33
net/wireless/rdev-ops.h
net/wireless/rdev-ops.h
+6
-5
net/wireless/trace.h
net/wireless/trace.h
+13
-11
net/wireless/util.c
net/wireless/util.c
+99
-0
net/wireless/wext-compat.c
net/wireless/wext-compat.c
+2
-2
未找到文件。
drivers/net/wireless/ath/ath5k/base.c
浏览文件 @
0f622485
...
@@ -511,8 +511,9 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
...
@@ -511,8 +511,9 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah,
ath5k_vif_iter
(
&
iter_data
,
vif
->
addr
,
vif
);
ath5k_vif_iter
(
&
iter_data
,
vif
->
addr
,
vif
);
/* Get list of all active MAC addresses */
/* Get list of all active MAC addresses */
ieee80211_iterate_active_interfaces_atomic
(
ah
->
hw
,
ath5k_vif_iter
,
ieee80211_iterate_active_interfaces_atomic
(
&
iter_data
);
ah
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath5k_vif_iter
,
&
iter_data
);
memcpy
(
ah
->
bssidmask
,
iter_data
.
mask
,
ETH_ALEN
);
memcpy
(
ah
->
bssidmask
,
iter_data
.
mask
,
ETH_ALEN
);
ah
->
opmode
=
iter_data
.
opmode
;
ah
->
opmode
=
iter_data
.
opmode
;
...
@@ -3045,8 +3046,9 @@ ath5k_any_vif_assoc(struct ath5k_hw *ah)
...
@@ -3045,8 +3046,9 @@ ath5k_any_vif_assoc(struct ath5k_hw *ah)
iter_data
.
need_set_hw_addr
=
false
;
iter_data
.
need_set_hw_addr
=
false
;
iter_data
.
found_active
=
true
;
iter_data
.
found_active
=
true
;
ieee80211_iterate_active_interfaces_atomic
(
ah
->
hw
,
ath5k_vif_iter
,
ieee80211_iterate_active_interfaces_atomic
(
&
iter_data
);
ah
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath5k_vif_iter
,
&
iter_data
);
return
iter_data
.
any_assoc
;
return
iter_data
.
any_assoc
;
}
}
...
...
drivers/net/wireless/ath/ath5k/mac80211-ops.c
浏览文件 @
0f622485
...
@@ -452,8 +452,9 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
...
@@ -452,8 +452,9 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
iter_data
.
hw_macaddr
=
NULL
;
iter_data
.
hw_macaddr
=
NULL
;
iter_data
.
n_stas
=
0
;
iter_data
.
n_stas
=
0
;
iter_data
.
need_set_hw_addr
=
false
;
iter_data
.
need_set_hw_addr
=
false
;
ieee80211_iterate_active_interfaces_atomic
(
ah
->
hw
,
ath5k_vif_iter
,
ieee80211_iterate_active_interfaces_atomic
(
&
iter_data
);
ah
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath5k_vif_iter
,
&
iter_data
);
/* Set up RX Filter */
/* Set up RX Filter */
if
(
iter_data
.
n_stas
>
1
)
{
if
(
iter_data
.
n_stas
>
1
)
{
...
...
drivers/net/wireless/ath/ath6kl/cfg80211.c
浏览文件 @
0f622485
...
@@ -1384,11 +1384,8 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
...
@@ -1384,11 +1384,8 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
return
0
;
return
0
;
}
}
/*
* The type nl80211_tx_power_setting replaces the following
* data type from 2.6.36 onwards
*/
static
int
ath6kl_cfg80211_set_txpower
(
struct
wiphy
*
wiphy
,
static
int
ath6kl_cfg80211_set_txpower
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
enum
nl80211_tx_power_setting
type
,
enum
nl80211_tx_power_setting
type
,
int
mbm
)
int
mbm
)
{
{
...
@@ -1423,7 +1420,9 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
...
@@ -1423,7 +1420,9 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
return
0
;
return
0
;
}
}
static
int
ath6kl_cfg80211_get_txpower
(
struct
wiphy
*
wiphy
,
int
*
dbm
)
static
int
ath6kl_cfg80211_get_txpower
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
int
*
dbm
)
{
{
struct
ath6kl
*
ar
=
(
struct
ath6kl
*
)
wiphy_priv
(
wiphy
);
struct
ath6kl
*
ar
=
(
struct
ath6kl
*
)
wiphy_priv
(
wiphy
);
struct
ath6kl_vif
*
vif
;
struct
ath6kl_vif
*
vif
;
...
...
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
浏览文件 @
0f622485
...
@@ -587,9 +587,9 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
...
@@ -587,9 +587,9 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
(
priv
->
num_sta_vif
>
1
)
&&
(
priv
->
num_sta_vif
>
1
)
&&
(
vif
->
type
==
NL80211_IFTYPE_STATION
))
{
(
vif
->
type
==
NL80211_IFTYPE_STATION
))
{
beacon_configured
=
false
;
beacon_configured
=
false
;
ieee80211_iterate_active_interfaces_atomic
(
priv
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
ath9k_htc_beacon_iter
,
priv
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
&
beacon_configured
);
ath9k_htc_beacon_iter
,
&
beacon_configured
);
if
(
beacon_configured
)
{
if
(
beacon_configured
)
{
ath_dbg
(
common
,
CONFIG
,
ath_dbg
(
common
,
CONFIG
,
...
...
drivers/net/wireless/ath/ath9k/htc_drv_main.c
浏览文件 @
0f622485
...
@@ -127,8 +127,9 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
...
@@ -127,8 +127,9 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv)
priv
->
rearm_ani
=
false
;
priv
->
rearm_ani
=
false
;
priv
->
reconfig_beacon
=
false
;
priv
->
reconfig_beacon
=
false
;
ieee80211_iterate_active_interfaces_atomic
(
priv
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
ath9k_htc_vif_iter
,
priv
);
priv
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath9k_htc_vif_iter
,
priv
);
if
(
priv
->
rearm_ani
)
if
(
priv
->
rearm_ani
)
ath9k_htc_start_ani
(
priv
);
ath9k_htc_start_ani
(
priv
);
...
@@ -165,8 +166,9 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
...
@@ -165,8 +166,9 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv,
ath9k_htc_bssid_iter
(
&
iter_data
,
vif
->
addr
,
vif
);
ath9k_htc_bssid_iter
(
&
iter_data
,
vif
->
addr
,
vif
);
/* Get list of all active MAC addresses */
/* Get list of all active MAC addresses */
ieee80211_iterate_active_interfaces_atomic
(
priv
->
hw
,
ath9k_htc_bssid_iter
,
ieee80211_iterate_active_interfaces_atomic
(
&
iter_data
);
priv
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath9k_htc_bssid_iter
,
&
iter_data
);
memcpy
(
common
->
bssidmask
,
iter_data
.
mask
,
ETH_ALEN
);
memcpy
(
common
->
bssidmask
,
iter_data
.
mask
,
ETH_ALEN
);
ath_hw_setbssidmask
(
common
);
ath_hw_setbssidmask
(
common
);
...
@@ -1144,8 +1146,9 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
...
@@ -1144,8 +1146,9 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
*/
*/
if
((
vif
->
type
==
NL80211_IFTYPE_AP
)
&&
(
priv
->
num_ap_vif
==
0
))
{
if
((
vif
->
type
==
NL80211_IFTYPE_AP
)
&&
(
priv
->
num_ap_vif
==
0
))
{
priv
->
rearm_ani
=
false
;
priv
->
rearm_ani
=
false
;
ieee80211_iterate_active_interfaces_atomic
(
priv
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
ath9k_htc_vif_iter
,
priv
);
priv
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath9k_htc_vif_iter
,
priv
);
if
(
!
priv
->
rearm_ani
)
if
(
!
priv
->
rearm_ani
)
ath9k_htc_stop_ani
(
priv
);
ath9k_htc_stop_ani
(
priv
);
}
}
...
@@ -1466,8 +1469,9 @@ static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
...
@@ -1466,8 +1469,9 @@ static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
static
void
ath9k_htc_choose_set_bssid
(
struct
ath9k_htc_priv
*
priv
)
static
void
ath9k_htc_choose_set_bssid
(
struct
ath9k_htc_priv
*
priv
)
{
{
if
(
priv
->
num_sta_assoc_vif
==
1
)
{
if
(
priv
->
num_sta_assoc_vif
==
1
)
{
ieee80211_iterate_active_interfaces_atomic
(
priv
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
ath9k_htc_bss_iter
,
priv
);
priv
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath9k_htc_bss_iter
,
priv
);
ath9k_htc_set_bssid
(
priv
);
ath9k_htc_set_bssid
(
priv
);
}
}
}
}
...
...
drivers/net/wireless/ath/ath9k/main.c
浏览文件 @
0f622485
...
@@ -924,8 +924,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
...
@@ -924,8 +924,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
ath9k_vif_iter
(
iter_data
,
vif
->
addr
,
vif
);
ath9k_vif_iter
(
iter_data
,
vif
->
addr
,
vif
);
/* Get list of all active MAC addresses */
/* Get list of all active MAC addresses */
ieee80211_iterate_active_interfaces_atomic
(
sc
->
hw
,
ath9k_vif_iter
,
ieee80211_iterate_active_interfaces_atomic
(
iter_data
);
sc
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath9k_vif_iter
,
iter_data
);
}
}
/* Called with sc->mutex held. */
/* Called with sc->mutex held. */
...
@@ -975,8 +976,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
...
@@ -975,8 +976,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
if
(
ah
->
opmode
==
NL80211_IFTYPE_STATION
&&
if
(
ah
->
opmode
==
NL80211_IFTYPE_STATION
&&
old_opmode
==
NL80211_IFTYPE_AP
&&
old_opmode
==
NL80211_IFTYPE_AP
&&
test_bit
(
SC_OP_PRIM_STA_VIF
,
&
sc
->
sc_flags
))
{
test_bit
(
SC_OP_PRIM_STA_VIF
,
&
sc
->
sc_flags
))
{
ieee80211_iterate_active_interfaces_atomic
(
sc
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
ath9k_sta_vif_iter
,
sc
);
sc
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath9k_sta_vif_iter
,
sc
);
}
}
}
}
...
@@ -1505,8 +1507,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
...
@@ -1505,8 +1507,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
clear_bit
(
SC_OP_BEACONS
,
&
sc
->
sc_flags
);
clear_bit
(
SC_OP_BEACONS
,
&
sc
->
sc_flags
);
}
}
ieee80211_iterate_active_interfaces_atomic
(
sc
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
ath9k_bss_assoc_iter
,
sc
);
sc
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
ath9k_bss_assoc_iter
,
sc
);
if
(
!
test_bit
(
SC_OP_PRIM_STA_VIF
,
&
sc
->
sc_flags
)
&&
if
(
!
test_bit
(
SC_OP_PRIM_STA_VIF
,
&
sc
->
sc_flags
)
&&
ah
->
opmode
==
NL80211_IFTYPE_STATION
)
{
ah
->
opmode
==
NL80211_IFTYPE_STATION
)
{
...
...
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
浏览文件 @
0f622485
...
@@ -1529,7 +1529,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
...
@@ -1529,7 +1529,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
}
}
static
s32
static
s32
brcmf_cfg80211_set_tx_power
(
struct
wiphy
*
wiphy
,
brcmf_cfg80211_set_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
enum
nl80211_tx_power_setting
type
,
s32
mbm
)
enum
nl80211_tx_power_setting
type
,
s32
mbm
)
{
{
...
@@ -1578,7 +1578,9 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
...
@@ -1578,7 +1578,9 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
return
err
;
return
err
;
}
}
static
s32
brcmf_cfg80211_get_tx_power
(
struct
wiphy
*
wiphy
,
s32
*
dbm
)
static
s32
brcmf_cfg80211_get_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
s32
*
dbm
)
{
{
struct
brcmf_cfg80211_info
*
cfg
=
wiphy_to_cfg
(
wiphy
);
struct
brcmf_cfg80211_info
*
cfg
=
wiphy_to_cfg
(
wiphy
);
struct
brcmf_if
*
ifp
=
netdev_priv
(
cfg_to_ndev
(
cfg
));
struct
brcmf_if
*
ifp
=
netdev_priv
(
cfg_to_ndev
(
cfg
));
...
...
drivers/net/wireless/mac80211_hwsim.c
浏览文件 @
0f622485
此差异已折叠。
点击以展开。
drivers/net/wireless/mwifiex/cfg80211.c
浏览文件 @
0f622485
...
@@ -324,6 +324,7 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
...
@@ -324,6 +324,7 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
*/
*/
static
int
static
int
mwifiex_cfg80211_set_tx_power
(
struct
wiphy
*
wiphy
,
mwifiex_cfg80211_set_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
enum
nl80211_tx_power_setting
type
,
enum
nl80211_tx_power_setting
type
,
int
mbm
)
int
mbm
)
{
{
...
...
drivers/net/wireless/rndis_wlan.c
浏览文件 @
0f622485
...
@@ -490,9 +490,12 @@ static int rndis_scan(struct wiphy *wiphy,
...
@@ -490,9 +490,12 @@ static int rndis_scan(struct wiphy *wiphy,
static
int
rndis_set_wiphy_params
(
struct
wiphy
*
wiphy
,
u32
changed
);
static
int
rndis_set_wiphy_params
(
struct
wiphy
*
wiphy
,
u32
changed
);
static
int
rndis_set_tx_power
(
struct
wiphy
*
wiphy
,
static
int
rndis_set_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
enum
nl80211_tx_power_setting
type
,
enum
nl80211_tx_power_setting
type
,
int
mbm
);
int
mbm
);
static
int
rndis_get_tx_power
(
struct
wiphy
*
wiphy
,
int
*
dbm
);
static
int
rndis_get_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
int
*
dbm
);
static
int
rndis_connect
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
static
int
rndis_connect
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_connect_params
*
sme
);
struct
cfg80211_connect_params
*
sme
);
...
@@ -1903,6 +1906,7 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
...
@@ -1903,6 +1906,7 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
}
}
static
int
rndis_set_tx_power
(
struct
wiphy
*
wiphy
,
static
int
rndis_set_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
enum
nl80211_tx_power_setting
type
,
enum
nl80211_tx_power_setting
type
,
int
mbm
)
int
mbm
)
{
{
...
@@ -1930,7 +1934,9 @@ static int rndis_set_tx_power(struct wiphy *wiphy,
...
@@ -1930,7 +1934,9 @@ static int rndis_set_tx_power(struct wiphy *wiphy,
return
-
ENOTSUPP
;
return
-
ENOTSUPP
;
}
}
static
int
rndis_get_tx_power
(
struct
wiphy
*
wiphy
,
int
*
dbm
)
static
int
rndis_get_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
int
*
dbm
)
{
{
struct
rndis_wlan_private
*
priv
=
wiphy_priv
(
wiphy
);
struct
rndis_wlan_private
*
priv
=
wiphy_priv
(
wiphy
);
struct
usbnet
*
usbdev
=
priv
->
usbdev
;
struct
usbnet
*
usbdev
=
priv
->
usbdev
;
...
...
drivers/net/wireless/rt2x00/rt2x00dev.c
浏览文件 @
0f622485
...
@@ -157,6 +157,7 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
...
@@ -157,6 +157,7 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work)
* requested configurations.
* requested configurations.
*/
*/
ieee80211_iterate_active_interfaces
(
rt2x00dev
->
hw
,
ieee80211_iterate_active_interfaces
(
rt2x00dev
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
rt2x00lib_intf_scheduled_iter
,
rt2x00lib_intf_scheduled_iter
,
rt2x00dev
);
rt2x00dev
);
}
}
...
@@ -225,9 +226,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
...
@@ -225,9 +226,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
return
;
return
;
/* send buffered bc/mc frames out for every bssid */
/* send buffered bc/mc frames out for every bssid */
ieee80211_iterate_active_interfaces_atomic
(
rt2x00dev
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
rt2x00lib_bc_buffer_iter
,
rt2x00dev
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
rt2x00dev
);
rt2x00lib_bc_buffer_iter
,
rt2x00dev
);
/*
/*
* Devices with pre tbtt interrupt don't need to update the beacon
* Devices with pre tbtt interrupt don't need to update the beacon
* here as they will fetch the next beacon directly prior to
* here as they will fetch the next beacon directly prior to
...
@@ -237,9 +238,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
...
@@ -237,9 +238,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
return
;
return
;
/* fetch next beacon */
/* fetch next beacon */
ieee80211_iterate_active_interfaces_atomic
(
rt2x00dev
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
rt2x00lib_beaconupdate_iter
,
rt2x00dev
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
rt2x00dev
);
rt2x00lib_beaconupdate_iter
,
rt2x00dev
);
}
}
EXPORT_SYMBOL_GPL
(
rt2x00lib_beacondone
);
EXPORT_SYMBOL_GPL
(
rt2x00lib_beacondone
);
...
@@ -249,9 +250,9 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
...
@@ -249,9 +250,9 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev)
return
;
return
;
/* fetch next beacon */
/* fetch next beacon */
ieee80211_iterate_active_interfaces_atomic
(
rt2x00dev
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
rt2x00lib_beaconupdate_iter
,
rt2x00dev
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
rt2x00dev
);
rt2x00lib_beaconupdate_iter
,
rt2x00dev
);
}
}
EXPORT_SYMBOL_GPL
(
rt2x00lib_pretbtt
);
EXPORT_SYMBOL_GPL
(
rt2x00lib_pretbtt
);
...
...
drivers/net/wireless/rt2x00/rt2x00mac.c
浏览文件 @
0f622485
...
@@ -424,9 +424,9 @@ int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
...
@@ -424,9 +424,9 @@ int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
if
(
!
test_bit
(
DEVICE_STATE_ENABLED_RADIO
,
&
rt2x00dev
->
flags
))
if
(
!
test_bit
(
DEVICE_STATE_ENABLED_RADIO
,
&
rt2x00dev
->
flags
))
return
0
;
return
0
;
ieee80211_iterate_active_interfaces_atomic
(
rt2x00dev
->
hw
,
ieee80211_iterate_active_interfaces_atomic
(
rt2x00mac_set_tim_iter
,
rt2x00dev
->
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
rt2x00dev
);
rt2x00mac_set_tim_iter
,
rt2x00dev
);
/* queue work to upodate the beacon template */
/* queue work to upodate the beacon template */
ieee80211_queue_work
(
rt2x00dev
->
hw
,
&
rt2x00dev
->
intf_work
);
ieee80211_queue_work
(
rt2x00dev
->
hw
,
&
rt2x00dev
->
intf_work
);
...
...
drivers/net/wireless/ti/wlcore/main.c
浏览文件 @
0f622485
...
@@ -677,7 +677,7 @@ static void wl12xx_get_vif_count(struct ieee80211_hw *hw,
...
@@ -677,7 +677,7 @@ static void wl12xx_get_vif_count(struct ieee80211_hw *hw,
memset
(
data
,
0
,
sizeof
(
*
data
));
memset
(
data
,
0
,
sizeof
(
*
data
));
data
->
cur_vif
=
cur_vif
;
data
->
cur_vif
=
cur_vif
;
ieee80211_iterate_active_interfaces
(
hw
,
ieee80211_iterate_active_interfaces
(
hw
,
IEEE80211_IFACE_ITER_RESUME_ALL
,
wl12xx_vif_count_iter
,
data
);
wl12xx_vif_count_iter
,
data
);
}
}
...
...
include/linux/ieee80211.h
浏览文件 @
0f622485
...
@@ -905,6 +905,38 @@ struct ieee80211_tdls_data {
...
@@ -905,6 +905,38 @@ struct ieee80211_tdls_data {
}
u
;
}
u
;
}
__packed
;
}
__packed
;
/*
* Peer-to-Peer IE attribute related definitions.
*/
/**
* enum ieee80211_p2p_attr_id - identifies type of peer-to-peer attribute.
*/
enum
ieee80211_p2p_attr_id
{
IEEE80211_P2P_ATTR_STATUS
=
0
,
IEEE80211_P2P_ATTR_MINOR_REASON
,
IEEE80211_P2P_ATTR_CAPABILITY
,
IEEE80211_P2P_ATTR_DEVICE_ID
,
IEEE80211_P2P_ATTR_GO_INTENT
,
IEEE80211_P2P_ATTR_GO_CONFIG_TIMEOUT
,
IEEE80211_P2P_ATTR_LISTEN_CHANNEL
,
IEEE80211_P2P_ATTR_GROUP_BSSID
,
IEEE80211_P2P_ATTR_EXT_LISTEN_TIMING
,
IEEE80211_P2P_ATTR_INTENDED_IFACE_ADDR
,
IEEE80211_P2P_ATTR_MANAGABILITY
,
IEEE80211_P2P_ATTR_CHANNEL_LIST
,
IEEE80211_P2P_ATTR_ABSENCE_NOTICE
,
IEEE80211_P2P_ATTR_DEVICE_INFO
,
IEEE80211_P2P_ATTR_GROUP_INFO
,
IEEE80211_P2P_ATTR_GROUP_ID
,
IEEE80211_P2P_ATTR_INTERFACE
,
IEEE80211_P2P_ATTR_OPER_CHANNEL
,
IEEE80211_P2P_ATTR_INVITE_FLAGS
,
/* 19 - 220: Reserved */
IEEE80211_P2P_ATTR_VENDOR_SPECIFIC
=
221
,
IEEE80211_P2P_ATTR_MAX
};
/**
/**
* struct ieee80211_bar - HT Block Ack Request
* struct ieee80211_bar - HT Block Ack Request
*
*
...
...
include/net/cfg80211.h
浏览文件 @
0f622485
...
@@ -1545,13 +1545,19 @@ struct cfg80211_gtk_rekey_data {
...
@@ -1545,13 +1545,19 @@ struct cfg80211_gtk_rekey_data {
* to a merge.
* to a merge.
* @leave_ibss: Leave the IBSS.
* @leave_ibss: Leave the IBSS.
*
*
* @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or
* MESH mode)
*
* @set_wiphy_params: Notify that wiphy parameters have changed;
* @set_wiphy_params: Notify that wiphy parameters have changed;
* @changed bitfield (see &enum wiphy_params_flags) describes which values
* @changed bitfield (see &enum wiphy_params_flags) describes which values
* have changed. The actual parameter values are available in
* have changed. The actual parameter values are available in
* struct wiphy. If returning an error, no value should be changed.
* struct wiphy. If returning an error, no value should be changed.
*
*
* @set_tx_power: set the transmit power according to the parameters,
* @set_tx_power: set the transmit power according to the parameters,
* the power passed is in mBm, to get dBm use MBM_TO_DBM().
* the power passed is in mBm, to get dBm use MBM_TO_DBM(). The
* wdev may be %NULL if power was set for the wiphy, and will
* always be %NULL unless the driver supports per-vif TX power
* (as advertised by the nl80211 feature flag.)
* @get_tx_power: store the current TX power into the dbm variable;
* @get_tx_power: store the current TX power into the dbm variable;
* return 0 if successful
* return 0 if successful
*
*
...
@@ -1746,11 +1752,15 @@ struct cfg80211_ops {
...
@@ -1746,11 +1752,15 @@ struct cfg80211_ops {
struct
cfg80211_ibss_params
*
params
);
struct
cfg80211_ibss_params
*
params
);
int
(
*
leave_ibss
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
);
int
(
*
leave_ibss
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
);
int
(
*
set_mcast_rate
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
int
rate
[
IEEE80211_NUM_BANDS
]);
int
(
*
set_wiphy_params
)(
struct
wiphy
*
wiphy
,
u32
changed
);
int
(
*
set_wiphy_params
)(
struct
wiphy
*
wiphy
,
u32
changed
);
int
(
*
set_tx_power
)(
struct
wiphy
*
wiphy
,
int
(
*
set_tx_power
)(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
enum
nl80211_tx_power_setting
type
,
int
mbm
);
enum
nl80211_tx_power_setting
type
,
int
mbm
);
int
(
*
get_tx_power
)(
struct
wiphy
*
wiphy
,
int
*
dbm
);
int
(
*
get_tx_power
)(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
int
*
dbm
);
int
(
*
set_wds_peer
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
int
(
*
set_wds_peer
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
const
u8
*
addr
);
const
u8
*
addr
);
...
@@ -3550,7 +3560,6 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
...
@@ -3550,7 +3560,6 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
* @len: length of the frame
* @len: length of the frame
* @freq: frequency the frame was received on
* @freq: frequency the frame was received on
* @sig_dbm: signal strength in mBm, or 0 if unknown
* @sig_dbm: signal strength in mBm, or 0 if unknown
* @gfp: allocation flags
*
*
* Use this function to report to userspace when a beacon was
* Use this function to report to userspace when a beacon was
* received. It is not useful to call this when there is no
* received. It is not useful to call this when there is no
...
@@ -3558,7 +3567,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
...
@@ -3558,7 +3567,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
*/
*/
void
cfg80211_report_obss_beacon
(
struct
wiphy
*
wiphy
,
void
cfg80211_report_obss_beacon
(
struct
wiphy
*
wiphy
,
const
u8
*
frame
,
size_t
len
,
const
u8
*
frame
,
size_t
len
,
int
freq
,
int
sig_dbm
,
gfp_t
gfp
);
int
freq
,
int
sig_dbm
);
/**
/**
* cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used
* cfg80211_can_beacon_sec_chan - test if ht40 on extension channel can be used
...
@@ -3608,6 +3617,25 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
...
@@ -3608,6 +3617,25 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
*/
*/
void
cfg80211_unregister_wdev
(
struct
wireless_dev
*
wdev
);
void
cfg80211_unregister_wdev
(
struct
wireless_dev
*
wdev
);
/**
* cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer
* @ies: the input IE buffer
* @len: the input length
* @attr: the attribute ID to find
* @buf: output buffer, can be %NULL if the data isn't needed, e.g.
* if the function is only called to get the needed buffer size
* @bufsize: size of the output buffer
*
* The function finds a given P2P attribute in the (vendor) IEs and
* copies its contents to the given buffer.
*
* The return value is a negative error code (-%EILSEQ or -%ENOENT) if
* the data is malformed or the attribute can't be found (respectively),
* or the length of the found attribute (which can be zero).
*/
unsigned
int
cfg80211_get_p2p_attr
(
const
u8
*
ies
,
unsigned
int
len
,
u8
attr
,
u8
*
buf
,
unsigned
int
bufsize
);
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
/* wiphy_printk helpers, similar to dev_printk */
...
...
include/net/mac80211.h
浏览文件 @
0f622485
...
@@ -207,6 +207,9 @@ struct ieee80211_chanctx_conf {
...
@@ -207,6 +207,9 @@ struct ieee80211_chanctx_conf {
* @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode)
* @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode)
* @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode)
* @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode)
* @BSS_CHANGED_PS: PS changed for this BSS (STA mode)
* @BSS_CHANGED_PS: PS changed for this BSS (STA mode)
* @BSS_CHANGED_TXPOWER: TX power setting changed for this interface
* @BSS_CHANGED_P2P_PS: P2P powersave settings (CTWindow, opportunistic PS)
* changed (currently only in P2P client mode, GO mode will be later)
*/
*/
enum
ieee80211_bss_change
{
enum
ieee80211_bss_change
{
BSS_CHANGED_ASSOC
=
1
<<
0
,
BSS_CHANGED_ASSOC
=
1
<<
0
,
...
@@ -227,6 +230,8 @@ enum ieee80211_bss_change {
...
@@ -227,6 +230,8 @@ enum ieee80211_bss_change {
BSS_CHANGED_SSID
=
1
<<
15
,
BSS_CHANGED_SSID
=
1
<<
15
,
BSS_CHANGED_AP_PROBE_RESP
=
1
<<
16
,
BSS_CHANGED_AP_PROBE_RESP
=
1
<<
16
,
BSS_CHANGED_PS
=
1
<<
17
,
BSS_CHANGED_PS
=
1
<<
17
,
BSS_CHANGED_TXPOWER
=
1
<<
18
,
BSS_CHANGED_P2P_PS
=
1
<<
19
,
/* when adding here, make sure to change ieee80211_reconfig */
/* when adding here, make sure to change ieee80211_reconfig */
};
};
...
@@ -309,6 +314,9 @@ enum ieee80211_rssi_event {
...
@@ -309,6 +314,9 @@ enum ieee80211_rssi_event {
* @ssid: The SSID of the current vif. Only valid in AP-mode.
* @ssid: The SSID of the current vif. Only valid in AP-mode.
* @ssid_len: Length of SSID given in @ssid.
* @ssid_len: Length of SSID given in @ssid.
* @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode.
* @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode.
* @txpower: TX power in dBm
* @p2p_ctwindow: P2P CTWindow, only for P2P client interfaces
* @p2p_oppps: P2P opportunistic PS is enabled
*/
*/
struct
ieee80211_bss_conf
{
struct
ieee80211_bss_conf
{
const
u8
*
bssid
;
const
u8
*
bssid
;
...
@@ -341,6 +349,9 @@ struct ieee80211_bss_conf {
...
@@ -341,6 +349,9 @@ struct ieee80211_bss_conf {
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
u8
ssid
[
IEEE80211_MAX_SSID_LEN
];
size_t
ssid_len
;
size_t
ssid_len
;
bool
hidden_ssid
;
bool
hidden_ssid
;
int
txpower
;
u8
p2p_ctwindow
;
bool
p2p_oppps
;
};
};
/**
/**
...
@@ -884,7 +895,8 @@ enum ieee80211_smps_mode {
...
@@ -884,7 +895,8 @@ enum ieee80211_smps_mode {
* powersave documentation below. This variable is valid only when
* powersave documentation below. This variable is valid only when
* the CONF_PS flag is set.
* the CONF_PS flag is set.
*
*
* @power_level: requested transmit power (in dBm)
* @power_level: requested transmit power (in dBm), backward compatibility
* value only that is set to the minimum of all interfaces
*
*
* @channel: the channel to tune to
* @channel: the channel to tune to
* @channel_type: the channel (HT) type
* @channel_type: the channel (HT) type
...
@@ -2381,6 +2393,17 @@ enum ieee80211_rate_control_changed {
...
@@ -2381,6 +2393,17 @@ enum ieee80211_rate_control_changed {
* to vif. Possible use is for hw queue remapping.
* to vif. Possible use is for hw queue remapping.
* @unassign_vif_chanctx: Notifies device driver about channel context being
* @unassign_vif_chanctx: Notifies device driver about channel context being
* unbound from vif.
* unbound from vif.
* @start_ap: Start operation on the AP interface, this is called after all the
* information in bss_conf is set and beacon can be retrieved. A channel
* context is bound before this is called. Note that if the driver uses
* software scan or ROC, this (and @stop_ap) isn't called when the AP is
* just "paused" for scanning/ROC, which is indicated by the beacon being
* disabled/enabled via @bss_info_changed.
* @stop_ap: Stop operation on the AP interface.
*
* @restart_complete: Called after a call to ieee80211_restart_hw(), when the
* reconfiguration has completed. This can help the driver implement the
* reconfiguration step. This callback may sleep.
*/
*/
struct
ieee80211_ops
{
struct
ieee80211_ops
{
void
(
*
tx
)(
struct
ieee80211_hw
*
hw
,
void
(
*
tx
)(
struct
ieee80211_hw
*
hw
,
...
@@ -2406,6 +2429,9 @@ struct ieee80211_ops {
...
@@ -2406,6 +2429,9 @@ struct ieee80211_ops {
struct
ieee80211_bss_conf
*
info
,
struct
ieee80211_bss_conf
*
info
,
u32
changed
);
u32
changed
);
int
(
*
start_ap
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
);
void
(
*
stop_ap
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
);
u64
(
*
prepare_multicast
)(
struct
ieee80211_hw
*
hw
,
u64
(
*
prepare_multicast
)(
struct
ieee80211_hw
*
hw
,
struct
netdev_hw_addr_list
*
mc_list
);
struct
netdev_hw_addr_list
*
mc_list
);
void
(
*
configure_filter
)(
struct
ieee80211_hw
*
hw
,
void
(
*
configure_filter
)(
struct
ieee80211_hw
*
hw
,
...
@@ -2539,6 +2565,8 @@ struct ieee80211_ops {
...
@@ -2539,6 +2565,8 @@ struct ieee80211_ops {
void
(
*
unassign_vif_chanctx
)(
struct
ieee80211_hw
*
hw
,
void
(
*
unassign_vif_chanctx
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_chanctx_conf
*
ctx
);
struct
ieee80211_chanctx_conf
*
ctx
);
void
(
*
restart_complete
)(
struct
ieee80211_hw
*
hw
);
};
};
/**
/**
...
@@ -3384,6 +3412,21 @@ void ieee80211_sched_scan_results(struct ieee80211_hw *hw);
...
@@ -3384,6 +3412,21 @@ void ieee80211_sched_scan_results(struct ieee80211_hw *hw);
*/
*/
void
ieee80211_sched_scan_stopped
(
struct
ieee80211_hw
*
hw
);
void
ieee80211_sched_scan_stopped
(
struct
ieee80211_hw
*
hw
);
/**
* enum ieee80211_interface_iteration_flags - interface iteration flags
* @IEEE80211_IFACE_ITER_NORMAL: Iterate over all interfaces that have
* been added to the driver; However, note that during hardware
* reconfiguration (after restart_hw) it will iterate over a new
* interface and over all the existing interfaces even if they
* haven't been re-added to the driver yet.
* @IEEE80211_IFACE_ITER_RESUME_ALL: During resume, iterate over all
* interfaces, even if they haven't been re-added to the driver yet.
*/
enum
ieee80211_interface_iteration_flags
{
IEEE80211_IFACE_ITER_NORMAL
=
0
,
IEEE80211_IFACE_ITER_RESUME_ALL
=
BIT
(
0
),
};
/**
/**
* ieee80211_iterate_active_interfaces - iterate active interfaces
* ieee80211_iterate_active_interfaces - iterate active interfaces
*
*
...
@@ -3392,13 +3435,15 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw);
...
@@ -3392,13 +3435,15 @@ void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw);
* This function allows the iterator function to sleep, when the iterator
* This function allows the iterator function to sleep, when the iterator
* function is atomic @ieee80211_iterate_active_interfaces_atomic can
* function is atomic @ieee80211_iterate_active_interfaces_atomic can
* be used.
* be used.
* Does not iterate over a new interface during add_interface()
* Does not iterate over a new interface during add_interface()
.
*
*
* @hw: the hardware struct of which the interfaces should be iterated over
* @hw: the hardware struct of which the interfaces should be iterated over
* @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
* @iterator: the iterator function to call
* @iterator: the iterator function to call
* @data: first argument of the iterator function
* @data: first argument of the iterator function
*/
*/
void
ieee80211_iterate_active_interfaces
(
struct
ieee80211_hw
*
hw
,
void
ieee80211_iterate_active_interfaces
(
struct
ieee80211_hw
*
hw
,
u32
iter_flags
,
void
(
*
iterator
)(
void
*
data
,
u8
*
mac
,
void
(
*
iterator
)(
void
*
data
,
u8
*
mac
,
struct
ieee80211_vif
*
vif
),
struct
ieee80211_vif
*
vif
),
void
*
data
);
void
*
data
);
...
@@ -3410,13 +3455,15 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
...
@@ -3410,13 +3455,15 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
* hardware that are currently active and calls the callback for them.
* hardware that are currently active and calls the callback for them.
* This function requires the iterator callback function to be atomic,
* This function requires the iterator callback function to be atomic,
* if that is not desired, use @ieee80211_iterate_active_interfaces instead.
* if that is not desired, use @ieee80211_iterate_active_interfaces instead.
* Does not iterate over a new interface during add_interface()
* Does not iterate over a new interface during add_interface()
.
*
*
* @hw: the hardware struct of which the interfaces should be iterated over
* @hw: the hardware struct of which the interfaces should be iterated over
* @iter_flags: iteration flags, see &enum ieee80211_interface_iteration_flags
* @iterator: the iterator function to call, cannot sleep
* @iterator: the iterator function to call, cannot sleep
* @data: first argument of the iterator function
* @data: first argument of the iterator function
*/
*/
void
ieee80211_iterate_active_interfaces_atomic
(
struct
ieee80211_hw
*
hw
,
void
ieee80211_iterate_active_interfaces_atomic
(
struct
ieee80211_hw
*
hw
,
u32
iter_flags
,
void
(
*
iterator
)(
void
*
data
,
void
(
*
iterator
)(
void
*
data
,
u8
*
mac
,
u8
*
mac
,
struct
ieee80211_vif
*
vif
),
struct
ieee80211_vif
*
vif
),
...
...
include/uapi/linux/nl80211.h
浏览文件 @
0f622485
...
@@ -578,6 +578,9 @@
...
@@ -578,6 +578,9 @@
* station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON
* station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON
* is used for this.
* is used for this.
*
*
* @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
* for IBSS or MESH vif.
*
* @NL80211_CMD_MAX: highest used command number
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
* @__NL80211_CMD_AFTER_LAST: internal use
*/
*/
...
@@ -726,6 +729,8 @@ enum nl80211_commands {
...
@@ -726,6 +729,8 @@ enum nl80211_commands {
NL80211_CMD_CONN_FAILED
,
NL80211_CMD_CONN_FAILED
,
NL80211_CMD_SET_MCAST_RATE
,
/* add new commands above here */
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
/* used to define NL80211_CMD_MAX below */
...
@@ -3051,6 +3056,7 @@ enum nl80211_ap_sme_features {
...
@@ -3051,6 +3056,7 @@ enum nl80211_ap_sme_features {
* @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan
* @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan
* @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported
* @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported
* @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif
* @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif
* @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting
*/
*/
enum
nl80211_feature_flags
{
enum
nl80211_feature_flags
{
NL80211_FEATURE_SK_TX_STATUS
=
1
<<
0
,
NL80211_FEATURE_SK_TX_STATUS
=
1
<<
0
,
...
@@ -3062,6 +3068,7 @@ enum nl80211_feature_flags {
...
@@ -3062,6 +3068,7 @@ enum nl80211_feature_flags {
NL80211_FEATURE_LOW_PRIORITY_SCAN
=
1
<<
6
,
NL80211_FEATURE_LOW_PRIORITY_SCAN
=
1
<<
6
,
NL80211_FEATURE_SCAN_FLUSH
=
1
<<
7
,
NL80211_FEATURE_SCAN_FLUSH
=
1
<<
7
,
NL80211_FEATURE_AP_SCAN
=
1
<<
8
,
NL80211_FEATURE_AP_SCAN
=
1
<<
8
,
NL80211_FEATURE_VIF_TXPOWER
=
1
<<
9
,
};
};
/**
/**
...
...
net/mac80211/aes_cmac.c
浏览文件 @
0f622485
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/crypto.h>
#include <linux/export.h>
#include <linux/err.h>
#include <linux/err.h>
#include <crypto/aes.h>
#include <crypto/aes.h>
...
...
net/mac80211/cfg.c
浏览文件 @
0f622485
...
@@ -922,6 +922,15 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
...
@@ -922,6 +922,15 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
return
err
;
return
err
;
changed
|=
err
;
changed
|=
err
;
err
=
drv_start_ap
(
sdata
->
local
,
sdata
);
if
(
err
)
{
old
=
rtnl_dereference
(
sdata
->
u
.
ap
.
beacon
);
if
(
old
)
kfree_rcu
(
old
,
rcu_head
);
RCU_INIT_POINTER
(
sdata
->
u
.
ap
.
beacon
,
NULL
);
return
err
;
}
ieee80211_bss_info_change_notify
(
sdata
,
changed
);
ieee80211_bss_info_change_notify
(
sdata
,
changed
);
netif_carrier_on
(
dev
);
netif_carrier_on
(
dev
);
...
@@ -953,26 +962,38 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
...
@@ -953,26 +962,38 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
static
int
ieee80211_stop_ap
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
)
static
int
ieee80211_stop_ap
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
)
{
{
struct
ieee80211_sub_if_data
*
sdata
,
*
vlan
;
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
struct
beacon_data
*
old
;
struct
ieee80211_sub_if_data
*
vlan
;
struct
ieee80211_local
*
local
=
sdata
->
local
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
struct
beacon_data
*
old_beacon
;
struct
probe_resp
*
old_probe_resp
;
old
=
rtnl_dereference
(
sdata
->
u
.
ap
.
beacon
);
old
_beacon
=
rtnl_dereference
(
sdata
->
u
.
ap
.
beacon
);
if
(
!
old
)
if
(
!
old
_beacon
)
return
-
ENOENT
;
return
-
ENOENT
;
old_probe_resp
=
rtnl_dereference
(
sdata
->
u
.
ap
.
probe_resp
);
/* turn off carrier for this interface and dependent VLANs */
list_for_each_entry
(
vlan
,
&
sdata
->
u
.
ap
.
vlans
,
u
.
vlan
.
list
)
list_for_each_entry
(
vlan
,
&
sdata
->
u
.
ap
.
vlans
,
u
.
vlan
.
list
)
netif_carrier_off
(
vlan
->
dev
);
netif_carrier_off
(
vlan
->
dev
);
netif_carrier_off
(
dev
);
netif_carrier_off
(
dev
);
/* remove beacon and probe response */
RCU_INIT_POINTER
(
sdata
->
u
.
ap
.
beacon
,
NULL
);
RCU_INIT_POINTER
(
sdata
->
u
.
ap
.
beacon
,
NULL
);
RCU_INIT_POINTER
(
sdata
->
u
.
ap
.
probe_resp
,
NULL
);
kfree_rcu
(
old_beacon
,
rcu_head
);
if
(
old_probe_resp
)
kfree_rcu
(
old_probe_resp
,
rcu_head
);
kfree_rcu
(
old
,
rcu_head
);
sta_info_flush
(
local
,
sdata
);
sta_info_flush
(
sdata
->
local
,
sdata
);
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BEACON_ENABLED
);
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BEACON_ENABLED
);
drv_stop_ap
(
sdata
->
local
,
sdata
);
/* free all potentially still buffered bcast frames */
local
->
total_ps_buffered
-=
skb_queue_len
(
&
sdata
->
u
.
ap
.
ps
.
bc_buf
);
skb_queue_purge
(
&
sdata
->
u
.
ap
.
ps
.
bc_buf
);
ieee80211_vif_release_channel
(
sdata
);
ieee80211_vif_release_channel
(
sdata
);
return
0
;
return
0
;
...
@@ -1933,6 +1954,16 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
...
@@ -1933,6 +1954,16 @@ static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
return
ieee80211_ibss_leave
(
IEEE80211_DEV_TO_SUB_IF
(
dev
));
return
ieee80211_ibss_leave
(
IEEE80211_DEV_TO_SUB_IF
(
dev
));
}
}
static
int
ieee80211_set_mcast_rate
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
int
rate
[
IEEE80211_NUM_BANDS
])
{
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
memcpy
(
sdata
->
vif
.
bss_conf
.
mcast_rate
,
rate
,
sizeof
(
rate
));
return
0
;
}
static
int
ieee80211_set_wiphy_params
(
struct
wiphy
*
wiphy
,
u32
changed
)
static
int
ieee80211_set_wiphy_params
(
struct
wiphy
*
wiphy
,
u32
changed
)
{
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
...
@@ -1971,45 +2002,65 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
...
@@ -1971,45 +2002,65 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
}
}
static
int
ieee80211_set_tx_power
(
struct
wiphy
*
wiphy
,
static
int
ieee80211_set_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
enum
nl80211_tx_power_setting
type
,
int
mbm
)
enum
nl80211_tx_power_setting
type
,
int
mbm
)
{
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_channel
*
chan
=
local
->
_oper_channel
;
struct
ieee80211_sub_if_data
*
sdata
;
u32
changes
=
0
;
/* FIXME */
if
(
wdev
)
{
if
(
local
->
use_chanctx
)
sdata
=
IEEE80211_WDEV_TO_SUB_IF
(
wdev
);
return
-
EOPNOTSUPP
;
switch
(
type
)
{
case
NL80211_TX_POWER_AUTOMATIC
:
sdata
->
user_power_level
=
IEEE80211_UNSET_POWER_LEVEL
;
break
;
case
NL80211_TX_POWER_LIMITED
:
case
NL80211_TX_POWER_FIXED
:
if
(
mbm
<
0
||
(
mbm
%
100
))
return
-
EOPNOTSUPP
;
sdata
->
user_power_level
=
MBM_TO_DBM
(
mbm
);
break
;
}
ieee80211_recalc_txpower
(
sdata
);
return
0
;
}
switch
(
type
)
{
switch
(
type
)
{
case
NL80211_TX_POWER_AUTOMATIC
:
case
NL80211_TX_POWER_AUTOMATIC
:
local
->
user_power_level
=
-
1
;
local
->
user_power_level
=
IEEE80211_UNSET_POWER_LEVEL
;
break
;
break
;
case
NL80211_TX_POWER_LIMITED
:
case
NL80211_TX_POWER_LIMITED
:
if
(
mbm
<
0
||
(
mbm
%
100
))
return
-
EOPNOTSUPP
;
local
->
user_power_level
=
MBM_TO_DBM
(
mbm
);
break
;
case
NL80211_TX_POWER_FIXED
:
case
NL80211_TX_POWER_FIXED
:
if
(
mbm
<
0
||
(
mbm
%
100
))
if
(
mbm
<
0
||
(
mbm
%
100
))
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
/* TODO: move to cfg80211 when it knows the channel */
if
(
MBM_TO_DBM
(
mbm
)
>
chan
->
max_power
)
return
-
EINVAL
;
local
->
user_power_level
=
MBM_TO_DBM
(
mbm
);
local
->
user_power_level
=
MBM_TO_DBM
(
mbm
);
break
;
break
;
}
}
ieee80211_hw_config
(
local
,
changes
);
mutex_lock
(
&
local
->
iflist_mtx
);
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
sdata
->
user_power_level
=
local
->
user_power_level
;
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
ieee80211_recalc_txpower
(
sdata
);
mutex_unlock
(
&
local
->
iflist_mtx
);
return
0
;
return
0
;
}
}
static
int
ieee80211_get_tx_power
(
struct
wiphy
*
wiphy
,
int
*
dbm
)
static
int
ieee80211_get_tx_power
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
int
*
dbm
)
{
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_WDEV_TO_SUB_IF
(
wdev
);
*
dbm
=
local
->
hw
.
conf
.
power_level
;
if
(
!
local
->
use_chanctx
)
*
dbm
=
local
->
hw
.
conf
.
power_level
;
else
*
dbm
=
sdata
->
vif
.
bss_conf
.
txpower
;
return
0
;
return
0
;
}
}
...
@@ -2341,13 +2392,22 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
...
@@ -2341,13 +2392,22 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
list_add_tail
(
&
roc
->
list
,
&
local
->
roc_list
);
list_add_tail
(
&
roc
->
list
,
&
local
->
roc_list
);
/*
/*
* cookie is either the roc (for normal roc)
* cookie is either the roc
cookie
(for normal roc)
* or the SKB (for mgmt TX)
* or the SKB (for mgmt TX)
*/
*/
if
(
txskb
)
if
(
!
txskb
)
{
/* local->mtx protects this */
local
->
roc_cookie_counter
++
;
roc
->
cookie
=
local
->
roc_cookie_counter
;
/* wow, you wrapped 64 bits ... more likely a bug */
if
(
WARN_ON
(
roc
->
cookie
==
0
))
{
roc
->
cookie
=
1
;
local
->
roc_cookie_counter
++
;
}
*
cookie
=
roc
->
cookie
;
}
else
{
*
cookie
=
(
unsigned
long
)
txskb
;
*
cookie
=
(
unsigned
long
)
txskb
;
else
}
*
cookie
=
(
unsigned
long
)
roc
;
return
0
;
return
0
;
}
}
...
@@ -2382,7 +2442,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
...
@@ -2382,7 +2442,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
struct
ieee80211_roc_work
*
dep
,
*
tmp2
;
struct
ieee80211_roc_work
*
dep
,
*
tmp2
;
list_for_each_entry_safe
(
dep
,
tmp2
,
&
roc
->
dependents
,
list
)
{
list_for_each_entry_safe
(
dep
,
tmp2
,
&
roc
->
dependents
,
list
)
{
if
(
!
mgmt_tx
&&
(
unsigned
long
)
dep
!=
cookie
)
if
(
!
mgmt_tx
&&
dep
->
cookie
!=
cookie
)
continue
;
continue
;
else
if
(
mgmt_tx
&&
dep
->
mgmt_tx_cookie
!=
cookie
)
else
if
(
mgmt_tx
&&
dep
->
mgmt_tx_cookie
!=
cookie
)
continue
;
continue
;
...
@@ -2394,7 +2454,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
...
@@ -2394,7 +2454,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local,
return
0
;
return
0
;
}
}
if
(
!
mgmt_tx
&&
(
unsigned
long
)
roc
!=
cookie
)
if
(
!
mgmt_tx
&&
roc
->
cookie
!=
cookie
)
continue
;
continue
;
else
if
(
mgmt_tx
&&
roc
->
mgmt_tx_cookie
!=
cookie
)
else
if
(
mgmt_tx
&&
roc
->
mgmt_tx_cookie
!=
cookie
)
continue
;
continue
;
...
@@ -3130,6 +3190,7 @@ struct cfg80211_ops mac80211_config_ops = {
...
@@ -3130,6 +3190,7 @@ struct cfg80211_ops mac80211_config_ops = {
.
disassoc
=
ieee80211_disassoc
,
.
disassoc
=
ieee80211_disassoc
,
.
join_ibss
=
ieee80211_join_ibss
,
.
join_ibss
=
ieee80211_join_ibss
,
.
leave_ibss
=
ieee80211_leave_ibss
,
.
leave_ibss
=
ieee80211_leave_ibss
,
.
set_mcast_rate
=
ieee80211_set_mcast_rate
,
.
set_wiphy_params
=
ieee80211_set_wiphy_params
,
.
set_wiphy_params
=
ieee80211_set_wiphy_params
,
.
set_tx_power
=
ieee80211_set_tx_power
,
.
set_tx_power
=
ieee80211_set_tx_power
,
.
get_tx_power
=
ieee80211_get_tx_power
,
.
get_tx_power
=
ieee80211_get_tx_power
,
...
...
net/mac80211/chan.c
浏览文件 @
0f622485
...
@@ -173,6 +173,8 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
...
@@ -173,6 +173,8 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
rcu_assign_pointer
(
sdata
->
vif
.
chanctx_conf
,
&
ctx
->
conf
);
rcu_assign_pointer
(
sdata
->
vif
.
chanctx_conf
,
&
ctx
->
conf
);
ctx
->
refcount
++
;
ctx
->
refcount
++
;
ieee80211_recalc_txpower
(
sdata
);
return
0
;
return
0
;
}
}
...
...
net/mac80211/debugfs_netdev.c
浏览文件 @
0f622485
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/device.h>
#include <linux/if.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <linux/rtnetlink.h>
...
@@ -168,6 +169,29 @@ IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
...
@@ -168,6 +169,29 @@ IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
IEEE80211_IF_FILE
(
flags
,
flags
,
HEX
);
IEEE80211_IF_FILE
(
flags
,
flags
,
HEX
);
IEEE80211_IF_FILE
(
state
,
state
,
LHEX
);
IEEE80211_IF_FILE
(
state
,
state
,
LHEX
);
IEEE80211_IF_FILE
(
channel_type
,
vif
.
bss_conf
.
channel_type
,
DEC
);
IEEE80211_IF_FILE
(
channel_type
,
vif
.
bss_conf
.
channel_type
,
DEC
);
IEEE80211_IF_FILE
(
txpower
,
vif
.
bss_conf
.
txpower
,
DEC
);
IEEE80211_IF_FILE
(
ap_power_level
,
ap_power_level
,
DEC
);
IEEE80211_IF_FILE
(
user_power_level
,
user_power_level
,
DEC
);
static
ssize_t
ieee80211_if_fmt_hw_queues
(
const
struct
ieee80211_sub_if_data
*
sdata
,
char
*
buf
,
int
buflen
)
{
int
len
;
len
=
scnprintf
(
buf
,
buflen
,
"AC queues: VO:%d VI:%d BE:%d BK:%d
\n
"
,
sdata
->
vif
.
hw_queue
[
IEEE80211_AC_VO
],
sdata
->
vif
.
hw_queue
[
IEEE80211_AC_VI
],
sdata
->
vif
.
hw_queue
[
IEEE80211_AC_BE
],
sdata
->
vif
.
hw_queue
[
IEEE80211_AC_BK
]);
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
len
+=
scnprintf
(
buf
+
len
,
buflen
-
len
,
"cab queue: %d
\n
"
,
sdata
->
vif
.
cab_queue
);
return
len
;
}
__IEEE80211_IF_FILE
(
hw_queues
,
NULL
);
/* STA attributes */
/* STA attributes */
IEEE80211_IF_FILE
(
bssid
,
u
.
mgd
.
bssid
,
MAC
);
IEEE80211_IF_FILE
(
bssid
,
u
.
mgd
.
bssid
,
MAC
);
...
@@ -245,27 +269,6 @@ static ssize_t ieee80211_if_fmt_tkip_mic_test(
...
@@ -245,27 +269,6 @@ static ssize_t ieee80211_if_fmt_tkip_mic_test(
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
}
}
static
int
hwaddr_aton
(
const
char
*
txt
,
u8
*
addr
)
{
int
i
;
for
(
i
=
0
;
i
<
ETH_ALEN
;
i
++
)
{
int
a
,
b
;
a
=
hex_to_bin
(
*
txt
++
);
if
(
a
<
0
)
return
-
1
;
b
=
hex_to_bin
(
*
txt
++
);
if
(
b
<
0
)
return
-
1
;
*
addr
++
=
(
a
<<
4
)
|
b
;
if
(
i
<
5
&&
*
txt
++
!=
':'
)
return
-
1
;
}
return
0
;
}
static
ssize_t
ieee80211_if_parse_tkip_mic_test
(
static
ssize_t
ieee80211_if_parse_tkip_mic_test
(
struct
ieee80211_sub_if_data
*
sdata
,
const
char
*
buf
,
int
buflen
)
struct
ieee80211_sub_if_data
*
sdata
,
const
char
*
buf
,
int
buflen
)
{
{
...
@@ -275,13 +278,7 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
...
@@ -275,13 +278,7 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
struct
ieee80211_hdr
*
hdr
;
struct
ieee80211_hdr
*
hdr
;
__le16
fc
;
__le16
fc
;
/*
if
(
!
mac_pton
(
buf
,
addr
))
* Assume colon-delimited MAC address with possible white space
* following.
*/
if
(
buflen
<
3
*
ETH_ALEN
-
1
)
return
-
EINVAL
;
if
(
hwaddr_aton
(
buf
,
addr
)
<
0
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
!
ieee80211_sdata_running
(
sdata
))
if
(
!
ieee80211_sdata_running
(
sdata
))
...
@@ -307,13 +304,16 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
...
@@ -307,13 +304,16 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
case
NL80211_IFTYPE_STATION
:
case
NL80211_IFTYPE_STATION
:
fc
|=
cpu_to_le16
(
IEEE80211_FCTL_TODS
);
fc
|=
cpu_to_le16
(
IEEE80211_FCTL_TODS
);
/* BSSID SA DA */
/* BSSID SA DA */
if
(
sdata
->
vif
.
bss_conf
.
bssid
==
NULL
)
{
mutex_lock
(
&
sdata
->
u
.
mgd
.
mtx
);
if
(
!
sdata
->
u
.
mgd
.
associated
)
{
mutex_unlock
(
&
sdata
->
u
.
mgd
.
mtx
);
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
return
-
ENOTCONN
;
return
-
ENOTCONN
;
}
}
memcpy
(
hdr
->
addr1
,
sdata
->
vif
.
bss_conf
.
bssid
,
ETH_ALEN
);
memcpy
(
hdr
->
addr1
,
sdata
->
u
.
mgd
.
associated
->
bssid
,
ETH_ALEN
);
memcpy
(
hdr
->
addr2
,
sdata
->
vif
.
addr
,
ETH_ALEN
);
memcpy
(
hdr
->
addr2
,
sdata
->
vif
.
addr
,
ETH_ALEN
);
memcpy
(
hdr
->
addr3
,
addr
,
ETH_ALEN
);
memcpy
(
hdr
->
addr3
,
addr
,
ETH_ALEN
);
mutex_unlock
(
&
sdata
->
u
.
mgd
.
mtx
);
break
;
break
;
default:
default:
dev_kfree_skb
(
skb
);
dev_kfree_skb
(
skb
);
...
@@ -443,7 +443,7 @@ static ssize_t ieee80211_if_parse_tsf(
...
@@ -443,7 +443,7 @@ static ssize_t ieee80211_if_parse_tsf(
}
}
ret
=
kstrtoull
(
buf
,
10
,
&
tsf
);
ret
=
kstrtoull
(
buf
,
10
,
&
tsf
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
-
EINVAL
;
return
ret
;
if
(
tsf_is_delta
)
if
(
tsf_is_delta
)
tsf
=
drv_get_tsf
(
local
,
sdata
)
+
tsf_is_delta
*
tsf
;
tsf
=
drv_get_tsf
(
local
,
sdata
)
+
tsf_is_delta
*
tsf
;
if
(
local
->
ops
->
set_tsf
)
{
if
(
local
->
ops
->
set_tsf
)
{
...
@@ -531,6 +531,7 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata)
...
@@ -531,6 +531,7 @@ static void add_common_files(struct ieee80211_sub_if_data *sdata)
DEBUGFS_ADD
(
rc_rateidx_mask_5ghz
);
DEBUGFS_ADD
(
rc_rateidx_mask_5ghz
);
DEBUGFS_ADD
(
rc_rateidx_mcs_mask_2ghz
);
DEBUGFS_ADD
(
rc_rateidx_mcs_mask_2ghz
);
DEBUGFS_ADD
(
rc_rateidx_mcs_mask_5ghz
);
DEBUGFS_ADD
(
rc_rateidx_mcs_mask_5ghz
);
DEBUGFS_ADD
(
hw_queues
);
}
}
static
void
add_sta_files
(
struct
ieee80211_sub_if_data
*
sdata
)
static
void
add_sta_files
(
struct
ieee80211_sub_if_data
*
sdata
)
...
@@ -632,6 +633,9 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
...
@@ -632,6 +633,9 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
DEBUGFS_ADD
(
flags
);
DEBUGFS_ADD
(
flags
);
DEBUGFS_ADD
(
state
);
DEBUGFS_ADD
(
state
);
DEBUGFS_ADD
(
channel_type
);
DEBUGFS_ADD
(
channel_type
);
DEBUGFS_ADD
(
txpower
);
DEBUGFS_ADD
(
user_power_level
);
DEBUGFS_ADD
(
ap_power_level
);
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_MONITOR
)
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_MONITOR
)
add_common_files
(
sdata
);
add_common_files
(
sdata
);
...
...
net/mac80211/driver-ops.h
浏览文件 @
0f622485
...
@@ -936,4 +936,39 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
...
@@ -936,4 +936,39 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
trace_drv_return_void
(
local
);
trace_drv_return_void
(
local
);
}
}
static
inline
int
drv_start_ap
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
)
{
int
ret
=
0
;
check_sdata_in_driver
(
sdata
);
trace_drv_start_ap
(
local
,
sdata
,
&
sdata
->
vif
.
bss_conf
);
if
(
local
->
ops
->
start_ap
)
ret
=
local
->
ops
->
start_ap
(
&
local
->
hw
,
&
sdata
->
vif
);
trace_drv_return_int
(
local
,
ret
);
return
ret
;
}
static
inline
void
drv_stop_ap
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
)
{
check_sdata_in_driver
(
sdata
);
trace_drv_stop_ap
(
local
,
sdata
);
if
(
local
->
ops
->
stop_ap
)
local
->
ops
->
stop_ap
(
&
local
->
hw
,
&
sdata
->
vif
);
trace_drv_return_void
(
local
);
}
static
inline
void
drv_restart_complete
(
struct
ieee80211_local
*
local
)
{
might_sleep
();
trace_drv_restart_complete
(
local
);
if
(
local
->
ops
->
restart_complete
)
local
->
ops
->
restart_complete
(
&
local
->
hw
);
trace_drv_return_void
(
local
);
}
#endif
/* __MAC80211_DRIVER_OPS */
#endif
/* __MAC80211_DRIVER_OPS */
net/mac80211/ieee80211_i.h
浏览文件 @
0f622485
...
@@ -56,6 +56,9 @@ struct ieee80211_local;
...
@@ -56,6 +56,9 @@ struct ieee80211_local;
#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024))
#define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024))
#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x))
#define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x))
/* power level hasn't been configured (or set to automatic) */
#define IEEE80211_UNSET_POWER_LEVEL INT_MIN
/*
/*
* Some APs experience problems when working with U-APSD. Decrease the
* Some APs experience problems when working with U-APSD. Decrease the
* probability of that happening by using legacy mode for all ACs but VO.
* probability of that happening by using legacy mode for all ACs but VO.
...
@@ -353,7 +356,7 @@ struct ieee80211_roc_work {
...
@@ -353,7 +356,7 @@ struct ieee80211_roc_work {
u32
duration
,
req_duration
;
u32
duration
,
req_duration
;
struct
sk_buff
*
frame
;
struct
sk_buff
*
frame
;
u64
mgmt_tx_cookie
;
u64
cookie
,
mgmt_tx_cookie
;
};
};
/* flags used in struct ieee80211_if_managed.flags */
/* flags used in struct ieee80211_if_managed.flags */
...
@@ -470,6 +473,8 @@ struct ieee80211_if_managed {
...
@@ -470,6 +473,8 @@ struct ieee80211_if_managed {
u8
use_4addr
;
u8
use_4addr
;
u8
p2p_noa_index
;
/* Signal strength from the last Beacon frame in the current BSS. */
/* Signal strength from the last Beacon frame in the current BSS. */
int
last_beacon_signal
;
int
last_beacon_signal
;
...
@@ -743,6 +748,9 @@ struct ieee80211_sub_if_data {
...
@@ -743,6 +748,9 @@ struct ieee80211_sub_if_data {
u8
needed_rx_chains
;
u8
needed_rx_chains
;
enum
ieee80211_smps_mode
smps_mode
;
enum
ieee80211_smps_mode
smps_mode
;
int
user_power_level
;
/* in dBm */
int
ap_power_level
;
/* in dBm */
/*
/*
* AP this belongs to: self in AP mode and
* AP this belongs to: self in AP mode and
* corresponding AP in VLAN mode, NULL for
* corresponding AP in VLAN mode, NULL for
...
@@ -1117,8 +1125,7 @@ struct ieee80211_local {
...
@@ -1117,8 +1125,7 @@ struct ieee80211_local {
int
dynamic_ps_user_timeout
;
int
dynamic_ps_user_timeout
;
bool
disable_dynamic_ps
;
bool
disable_dynamic_ps
;
int
user_power_level
;
/* in dBm */
int
user_power_level
;
/* in dBm, for all interfaces */
int
ap_power_level
;
/* in dBm */
enum
ieee80211_smps_mode
smps_mode
;
enum
ieee80211_smps_mode
smps_mode
;
...
@@ -1137,6 +1144,7 @@ struct ieee80211_local {
...
@@ -1137,6 +1144,7 @@ struct ieee80211_local {
struct
list_head
roc_list
;
struct
list_head
roc_list
;
struct
work_struct
hw_roc_start
,
hw_roc_done
;
struct
work_struct
hw_roc_start
,
hw_roc_done
;
unsigned
long
hw_roc_start_time
;
unsigned
long
hw_roc_start_time
;
u64
roc_cookie_counter
;
struct
idr
ack_status_frames
;
struct
idr
ack_status_frames
;
spinlock_t
ack_status_lock
;
spinlock_t
ack_status_lock
;
...
@@ -1365,6 +1373,9 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
...
@@ -1365,6 +1373,9 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
int
ieee80211_do_open
(
struct
wireless_dev
*
wdev
,
bool
coming_up
);
int
ieee80211_do_open
(
struct
wireless_dev
*
wdev
,
bool
coming_up
);
void
ieee80211_sdata_stop
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211_sdata_stop
(
struct
ieee80211_sub_if_data
*
sdata
);
bool
__ieee80211_recalc_txpower
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211_recalc_txpower
(
struct
ieee80211_sub_if_data
*
sdata
);
static
inline
bool
ieee80211_sdata_running
(
struct
ieee80211_sub_if_data
*
sdata
)
static
inline
bool
ieee80211_sdata_running
(
struct
ieee80211_sub_if_data
*
sdata
)
{
{
return
test_bit
(
SDATA_STATE_RUNNING
,
&
sdata
->
state
);
return
test_bit
(
SDATA_STATE_RUNNING
,
&
sdata
->
state
);
...
...
net/mac80211/iface.c
浏览文件 @
0f622485
...
@@ -42,6 +42,41 @@
...
@@ -42,6 +42,41 @@
* by either the RTNL, the iflist_mtx or RCU.
* by either the RTNL, the iflist_mtx or RCU.
*/
*/
bool
__ieee80211_recalc_txpower
(
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
ieee80211_chanctx_conf
*
chanctx_conf
;
int
power
;
rcu_read_lock
();
chanctx_conf
=
rcu_dereference
(
sdata
->
vif
.
chanctx_conf
);
if
(
!
chanctx_conf
)
{
rcu_read_unlock
();
return
false
;
}
power
=
chanctx_conf
->
channel
->
max_power
;
rcu_read_unlock
();
if
(
sdata
->
user_power_level
!=
IEEE80211_UNSET_POWER_LEVEL
)
power
=
min
(
power
,
sdata
->
user_power_level
);
if
(
sdata
->
ap_power_level
!=
IEEE80211_UNSET_POWER_LEVEL
)
power
=
min
(
power
,
sdata
->
ap_power_level
);
if
(
power
!=
sdata
->
vif
.
bss_conf
.
txpower
)
{
sdata
->
vif
.
bss_conf
.
txpower
=
power
;
ieee80211_hw_config
(
sdata
->
local
,
0
);
return
true
;
}
return
false
;
}
void
ieee80211_recalc_txpower
(
struct
ieee80211_sub_if_data
*
sdata
)
{
if
(
__ieee80211_recalc_txpower
(
sdata
))
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_TXPOWER
);
}
static
u32
ieee80211_idle_off
(
struct
ieee80211_local
*
local
,
static
u32
ieee80211_idle_off
(
struct
ieee80211_local
*
local
,
const
char
*
reason
)
const
char
*
reason
)
...
@@ -744,31 +779,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
...
@@ -744,31 +779,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
/* APs need special treatment */
/* APs need special treatment */
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
{
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
{
struct
ieee80211_sub_if_data
*
vlan
,
*
tmpsdata
;
struct
ieee80211_sub_if_data
*
vlan
,
*
tmpsdata
;
struct
beacon_data
*
old_beacon
=
rtnl_dereference
(
sdata
->
u
.
ap
.
beacon
);
struct
probe_resp
*
old_probe_resp
=
rtnl_dereference
(
sdata
->
u
.
ap
.
probe_resp
);
/* sdata_running will return false, so this will disable */
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BEACON_ENABLED
);
/* remove beacon and probe response */
RCU_INIT_POINTER
(
sdata
->
u
.
ap
.
beacon
,
NULL
);
RCU_INIT_POINTER
(
sdata
->
u
.
ap
.
probe_resp
,
NULL
);
synchronize_rcu
();
kfree
(
old_beacon
);
kfree
(
old_probe_resp
);
/* down all dependent devices, that is VLANs */
/* down all dependent devices, that is VLANs */
list_for_each_entry_safe
(
vlan
,
tmpsdata
,
&
sdata
->
u
.
ap
.
vlans
,
list_for_each_entry_safe
(
vlan
,
tmpsdata
,
&
sdata
->
u
.
ap
.
vlans
,
u
.
vlan
.
list
)
u
.
vlan
.
list
)
dev_close
(
vlan
->
dev
);
dev_close
(
vlan
->
dev
);
WARN_ON
(
!
list_empty
(
&
sdata
->
u
.
ap
.
vlans
));
WARN_ON
(
!
list_empty
(
&
sdata
->
u
.
ap
.
vlans
));
/* free all potentially still buffered bcast frames */
local
->
total_ps_buffered
-=
skb_queue_len
(
&
sdata
->
u
.
ap
.
ps
.
bc_buf
);
skb_queue_purge
(
&
sdata
->
u
.
ap
.
ps
.
bc_buf
);
}
else
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
)
{
}
else
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
)
{
ieee80211_mgd_stop
(
sdata
);
ieee80211_mgd_stop
(
sdata
);
}
}
...
@@ -1529,6 +1545,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
...
@@ -1529,6 +1545,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
ieee80211_set_default_queues
(
sdata
);
ieee80211_set_default_queues
(
sdata
);
sdata
->
ap_power_level
=
IEEE80211_UNSET_POWER_LEVEL
;
sdata
->
user_power_level
=
local
->
user_power_level
;
/* setup type-dependent data */
/* setup type-dependent data */
ieee80211_setup_sdata
(
sdata
,
type
);
ieee80211_setup_sdata
(
sdata
,
type
);
...
...
net/mac80211/main.c
浏览文件 @
0f622485
...
@@ -95,11 +95,13 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
...
@@ -95,11 +95,13 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
static
u32
ieee80211_hw_conf_chan
(
struct
ieee80211_local
*
local
)
static
u32
ieee80211_hw_conf_chan
(
struct
ieee80211_local
*
local
)
{
{
struct
ieee80211_sub_if_data
*
sdata
;
struct
ieee80211_channel
*
chan
;
struct
ieee80211_channel
*
chan
;
u32
changed
=
0
;
u32
changed
=
0
;
int
power
;
int
power
;
enum
nl80211_channel_type
channel_type
;
enum
nl80211_channel_type
channel_type
;
u32
offchannel_flag
;
u32
offchannel_flag
;
bool
scanning
=
false
;
offchannel_flag
=
local
->
hw
.
conf
.
flags
&
IEEE80211_CONF_OFFCHANNEL
;
offchannel_flag
=
local
->
hw
.
conf
.
flags
&
IEEE80211_CONF_OFFCHANNEL
;
if
(
local
->
scan_channel
)
{
if
(
local
->
scan_channel
)
{
...
@@ -146,16 +148,18 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
...
@@ -146,16 +148,18 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
changed
|=
IEEE80211_CONF_CHANGE_SMPS
;
changed
|=
IEEE80211_CONF_CHANGE_SMPS
;
}
}
if
(
test_bit
(
SCAN_SW_SCANNING
,
&
local
->
scanning
)
||
scanning
=
test_bit
(
SCAN_SW_SCANNING
,
&
local
->
scanning
)
||
test_bit
(
SCAN_ONCHANNEL_SCANNING
,
&
local
->
scanning
)
||
test_bit
(
SCAN_ONCHANNEL_SCANNING
,
&
local
->
scanning
)
||
test_bit
(
SCAN_HW_SCANNING
,
&
local
->
scanning
)
||
test_bit
(
SCAN_HW_SCANNING
,
&
local
->
scanning
);
!
local
->
ap_power_level
)
power
=
chan
->
max_power
;
power
=
chan
->
max_power
;
else
power
=
min
(
chan
->
max_power
,
local
->
ap_power_level
);
if
(
local
->
user_power_level
>=
0
)
rcu_read_lock
();
power
=
min
(
power
,
local
->
user_power_level
);
list_for_each_entry_rcu
(
sdata
,
&
local
->
interfaces
,
list
)
{
if
(
!
rcu_access_pointer
(
sdata
->
vif
.
chanctx_conf
))
continue
;
power
=
min
(
power
,
sdata
->
vif
.
bss_conf
.
txpower
);
}
rcu_read_unlock
();
if
(
local
->
hw
.
conf
.
power_level
!=
power
)
{
if
(
local
->
hw
.
conf
.
power_level
!=
power
)
{
changed
|=
IEEE80211_CONF_CHANGE_POWER
;
changed
|=
IEEE80211_CONF_CHANGE_POWER
;
...
@@ -600,7 +604,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
...
@@ -600,7 +604,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
wiphy
->
features
|=
NL80211_FEATURE_SK_TX_STATUS
|
wiphy
->
features
|=
NL80211_FEATURE_SK_TX_STATUS
|
NL80211_FEATURE_SAE
|
NL80211_FEATURE_SAE
|
NL80211_FEATURE_HT_IBSS
;
NL80211_FEATURE_HT_IBSS
|
NL80211_FEATURE_VIF_TXPOWER
;
if
(
!
ops
->
hw_scan
)
if
(
!
ops
->
hw_scan
)
wiphy
->
features
|=
NL80211_FEATURE_LOW_PRIORITY_SCAN
|
wiphy
->
features
|=
NL80211_FEATURE_LOW_PRIORITY_SCAN
|
...
@@ -633,7 +638,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
...
@@ -633,7 +638,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
local
->
hw
.
radiotap_mcs_details
=
IEEE80211_RADIOTAP_MCS_HAVE_MCS
|
local
->
hw
.
radiotap_mcs_details
=
IEEE80211_RADIOTAP_MCS_HAVE_MCS
|
IEEE80211_RADIOTAP_MCS_HAVE_GI
|
IEEE80211_RADIOTAP_MCS_HAVE_GI
|
IEEE80211_RADIOTAP_MCS_HAVE_BW
;
IEEE80211_RADIOTAP_MCS_HAVE_BW
;
local
->
user_power_level
=
-
1
;
local
->
user_power_level
=
IEEE80211_UNSET_POWER_LEVEL
;
wiphy
->
ht_capa_mod_mask
=
&
mac80211_ht_capa_mod_mask
;
wiphy
->
ht_capa_mod_mask
=
&
mac80211_ht_capa_mod_mask
;
INIT_LIST_HEAD
(
&
local
->
interfaces
);
INIT_LIST_HEAD
(
&
local
->
interfaces
);
...
...
net/mac80211/mlme.c
浏览文件 @
0f622485
...
@@ -820,10 +820,10 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
...
@@ -820,10 +820,10 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
cbss
->
beacon_interval
));
cbss
->
beacon_interval
));
}
}
static
void
ieee80211_handle_pwr_constr
(
struct
ieee80211_sub_if_data
*
sdata
,
static
u32
ieee80211_handle_pwr_constr
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_channel
*
channel
,
struct
ieee80211_channel
*
channel
,
const
u8
*
country_ie
,
u8
country_ie_len
,
const
u8
*
country_ie
,
u8
country_ie_len
,
const
u8
*
pwr_constr_elem
)
const
u8
*
pwr_constr_elem
)
{
{
struct
ieee80211_country_ie_triplet
*
triplet
;
struct
ieee80211_country_ie_triplet
*
triplet
;
int
chan
=
ieee80211_frequency_to_channel
(
channel
->
center_freq
);
int
chan
=
ieee80211_frequency_to_channel
(
channel
->
center_freq
);
...
@@ -832,7 +832,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
...
@@ -832,7 +832,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
/* Invalid IE */
/* Invalid IE */
if
(
country_ie_len
%
2
||
country_ie_len
<
IEEE80211_COUNTRY_IE_MIN_LEN
)
if
(
country_ie_len
%
2
||
country_ie_len
<
IEEE80211_COUNTRY_IE_MIN_LEN
)
return
;
return
0
;
triplet
=
(
void
*
)(
country_ie
+
3
);
triplet
=
(
void
*
)(
country_ie
+
3
);
country_ie_len
-=
3
;
country_ie_len
-=
3
;
...
@@ -873,19 +873,21 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
...
@@ -873,19 +873,21 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
}
}
if
(
!
have_chan_pwr
)
if
(
!
have_chan_pwr
)
return
;
return
0
;
new_ap_level
=
max_t
(
int
,
0
,
chan_pwr
-
*
pwr_constr_elem
);
new_ap_level
=
max_t
(
int
,
0
,
chan_pwr
-
*
pwr_constr_elem
);
if
(
sdata
->
local
->
ap_power_level
==
new_ap_level
)
if
(
sdata
->
ap_power_level
==
new_ap_level
)
return
;
return
0
;
sdata_info
(
sdata
,
sdata_info
(
sdata
,
"Limiting TX power to %d (%d - %d) dBm as advertised by %pM
\n
"
,
"Limiting TX power to %d (%d - %d) dBm as advertised by %pM
\n
"
,
new_ap_level
,
chan_pwr
,
*
pwr_constr_elem
,
new_ap_level
,
chan_pwr
,
*
pwr_constr_elem
,
sdata
->
u
.
mgd
.
bssid
);
sdata
->
u
.
mgd
.
bssid
);
sdata
->
local
->
ap_power_level
=
new_ap_level
;
sdata
->
ap_power_level
=
new_ap_level
;
ieee80211_hw_config
(
sdata
->
local
,
0
);
if
(
__ieee80211_recalc_txpower
(
sdata
))
return
BSS_CHANGED_TXPOWER
;
return
0
;
}
}
void
ieee80211_enable_dyn_ps
(
struct
ieee80211_vif
*
vif
)
void
ieee80211_enable_dyn_ps
(
struct
ieee80211_vif
*
vif
)
...
@@ -1363,6 +1365,22 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
...
@@ -1363,6 +1365,22 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
sdata
->
u
.
mgd
.
flags
|=
IEEE80211_STA_RESET_SIGNAL_AVE
;
sdata
->
u
.
mgd
.
flags
|=
IEEE80211_STA_RESET_SIGNAL_AVE
;
if
(
sdata
->
vif
.
p2p
)
{
u8
noa
[
2
];
int
ret
;
ret
=
cfg80211_get_p2p_attr
(
cbss
->
information_elements
,
cbss
->
len_information_elements
,
IEEE80211_P2P_ATTR_ABSENCE_NOTICE
,
noa
,
sizeof
(
noa
));
if
(
ret
>=
2
)
{
bss_conf
->
p2p_oppps
=
noa
[
1
]
&
0x80
;
bss_conf
->
p2p_ctwindow
=
noa
[
1
]
&
0x7f
;
bss_info_changed
|=
BSS_CHANGED_P2P_PS
;
sdata
->
u
.
mgd
.
p2p_noa_index
=
noa
[
0
];
}
}
/* just to be sure */
/* just to be sure */
ieee80211_stop_poll
(
sdata
);
ieee80211_stop_poll
(
sdata
);
...
@@ -1485,11 +1503,14 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
...
@@ -1485,11 +1503,14 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
changed
|=
BSS_CHANGED_ASSOC
;
changed
|=
BSS_CHANGED_ASSOC
;
sdata
->
vif
.
bss_conf
.
assoc
=
false
;
sdata
->
vif
.
bss_conf
.
assoc
=
false
;
sdata
->
vif
.
bss_conf
.
p2p_ctwindow
=
0
;
sdata
->
vif
.
bss_conf
.
p2p_oppps
=
false
;
/* on the next assoc, re-program HT parameters */
/* on the next assoc, re-program HT parameters */
memset
(
&
ifmgd
->
ht_capa
,
0
,
sizeof
(
ifmgd
->
ht_capa
));
memset
(
&
ifmgd
->
ht_capa
,
0
,
sizeof
(
ifmgd
->
ht_capa
));
memset
(
&
ifmgd
->
ht_capa_mask
,
0
,
sizeof
(
ifmgd
->
ht_capa_mask
));
memset
(
&
ifmgd
->
ht_capa_mask
,
0
,
sizeof
(
ifmgd
->
ht_capa_mask
));
local
->
ap_power_level
=
0
;
sdata
->
ap_power_level
=
IEEE80211_UNSET_POWER_LEVEL
;
del_timer_sync
(
&
local
->
dynamic_ps_timer
);
del_timer_sync
(
&
local
->
dynamic_ps_timer
);
cancel_work_sync
(
&
local
->
dynamic_ps_enable_work
);
cancel_work_sync
(
&
local
->
dynamic_ps_enable_work
);
...
@@ -2592,6 +2613,27 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
...
@@ -2592,6 +2613,27 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
}
}
}
}
if
(
sdata
->
vif
.
p2p
)
{
u8
noa
[
2
];
int
ret
;
ret
=
cfg80211_get_p2p_attr
(
mgmt
->
u
.
beacon
.
variable
,
len
-
baselen
,
IEEE80211_P2P_ATTR_ABSENCE_NOTICE
,
noa
,
sizeof
(
noa
));
if
(
ret
>=
2
&&
sdata
->
u
.
mgd
.
p2p_noa_index
!=
noa
[
0
])
{
bss_conf
->
p2p_oppps
=
noa
[
1
]
&
0x80
;
bss_conf
->
p2p_ctwindow
=
noa
[
1
]
&
0x7f
;
changed
|=
BSS_CHANGED_P2P_PS
;
sdata
->
u
.
mgd
.
p2p_noa_index
=
noa
[
0
];
/*
* make sure we update all information, the CRC
* mechanism doesn't look at P2P attributes.
*/
ifmgd
->
beacon_crc_valid
=
false
;
}
}
if
(
ncrc
==
ifmgd
->
beacon_crc
&&
ifmgd
->
beacon_crc_valid
)
if
(
ncrc
==
ifmgd
->
beacon_crc
&&
ifmgd
->
beacon_crc_valid
)
return
;
return
;
ifmgd
->
beacon_crc
=
ncrc
;
ifmgd
->
beacon_crc
=
ncrc
;
...
@@ -2623,10 +2665,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
...
@@ -2623,10 +2665,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
if
(
elems
.
country_elem
&&
elems
.
pwr_constr_elem
&&
if
(
elems
.
country_elem
&&
elems
.
pwr_constr_elem
&&
mgmt
->
u
.
probe_resp
.
capab_info
&
mgmt
->
u
.
probe_resp
.
capab_info
&
cpu_to_le16
(
WLAN_CAPABILITY_SPECTRUM_MGMT
))
cpu_to_le16
(
WLAN_CAPABILITY_SPECTRUM_MGMT
))
ieee80211_handle_pwr_constr
(
sdata
,
chan
,
changed
|=
ieee80211_handle_pwr_constr
(
sdata
,
chan
,
elems
.
country_elem
,
elems
.
country_elem
,
elems
.
country_elem_len
,
elems
.
country_elem_len
,
elems
.
pwr_constr_elem
);
elems
.
pwr_constr_elem
);
ieee80211_bss_info_change_notify
(
sdata
,
changed
);
ieee80211_bss_info_change_notify
(
sdata
,
changed
);
}
}
...
@@ -3660,40 +3702,44 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
...
@@ -3660,40 +3702,44 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
u8
frame_buf
[
IEEE80211_DEAUTH_FRAME_LEN
];
u8
frame_buf
[
IEEE80211_DEAUTH_FRAME_LEN
];
bool
tx
=
!
req
->
local_state_change
;
bool
tx
=
!
req
->
local_state_change
;
bool
sent_frame
=
false
;
mutex_lock
(
&
ifmgd
->
mtx
);
mutex_lock
(
&
ifmgd
->
mtx
);
if
(
ifmgd
->
auth_data
)
{
ieee80211_destroy_auth_data
(
sdata
,
false
);
mutex_unlock
(
&
ifmgd
->
mtx
);
return
0
;
}
sdata_info
(
sdata
,
sdata_info
(
sdata
,
"deauthenticating from %pM by local choice (reason=%d)
\n
"
,
"deauthenticating from %pM by local choice (reason=%d)
\n
"
,
req
->
bssid
,
req
->
reason_code
);
req
->
bssid
,
req
->
reason_code
);
if
(
ifmgd
->
associated
&&
if
(
ifmgd
->
auth_data
)
{
ether_addr_equal
(
ifmgd
->
associated
->
bssid
,
req
->
bssid
))
{
ieee80211_set_disassoc
(
sdata
,
IEEE80211_STYPE_DEAUTH
,
req
->
reason_code
,
tx
,
frame_buf
);
}
else
{
drv_mgd_prepare_tx
(
sdata
->
local
,
sdata
);
drv_mgd_prepare_tx
(
sdata
->
local
,
sdata
);
ieee80211_send_deauth_disassoc
(
sdata
,
req
->
bssid
,
ieee80211_send_deauth_disassoc
(
sdata
,
req
->
bssid
,
IEEE80211_STYPE_DEAUTH
,
IEEE80211_STYPE_DEAUTH
,
req
->
reason_code
,
tx
,
req
->
reason_code
,
tx
,
frame_buf
);
frame_buf
);
ieee80211_destroy_auth_data
(
sdata
,
false
);
mutex_unlock
(
&
ifmgd
->
mtx
);
sent_frame
=
tx
;
goto
out
;
}
}
if
(
ifmgd
->
associated
&&
ether_addr_equal
(
ifmgd
->
associated
->
bssid
,
req
->
bssid
))
{
ieee80211_set_disassoc
(
sdata
,
IEEE80211_STYPE_DEAUTH
,
req
->
reason_code
,
tx
,
frame_buf
);
sent_frame
=
tx
;
}
mutex_unlock
(
&
ifmgd
->
mtx
);
mutex_unlock
(
&
ifmgd
->
mtx
);
__cfg80211_send_deauth
(
sdata
->
dev
,
frame_buf
,
out:
IEEE80211_DEAUTH_FRAME_LEN
);
mutex_lock
(
&
sdata
->
local
->
mtx
);
mutex_lock
(
&
sdata
->
local
->
mtx
);
ieee80211_recalc_idle
(
sdata
->
local
);
ieee80211_recalc_idle
(
sdata
->
local
);
mutex_unlock
(
&
sdata
->
local
->
mtx
);
mutex_unlock
(
&
sdata
->
local
->
mtx
);
if
(
sent_frame
)
__cfg80211_send_deauth
(
sdata
->
dev
,
frame_buf
,
IEEE80211_DEAUTH_FRAME_LEN
);
return
0
;
return
0
;
}
}
...
...
net/mac80211/offchannel.c
浏览文件 @
0f622485
...
@@ -204,7 +204,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
...
@@ -204,7 +204,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
roc
->
frame
=
NULL
;
roc
->
frame
=
NULL
;
}
}
}
else
{
}
else
{
cfg80211_ready_on_channel
(
&
roc
->
sdata
->
wdev
,
(
unsigned
long
)
roc
,
cfg80211_ready_on_channel
(
&
roc
->
sdata
->
wdev
,
roc
->
cookie
,
roc
->
chan
,
roc
->
chan_type
,
roc
->
chan
,
roc
->
chan_type
,
roc
->
req_duration
,
GFP_KERNEL
);
roc
->
req_duration
,
GFP_KERNEL
);
}
}
...
@@ -320,9 +320,8 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
...
@@ -320,9 +320,8 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
if
(
!
roc
->
mgmt_tx_cookie
)
if
(
!
roc
->
mgmt_tx_cookie
)
cfg80211_remain_on_channel_expired
(
&
roc
->
sdata
->
wdev
,
cfg80211_remain_on_channel_expired
(
&
roc
->
sdata
->
wdev
,
(
unsigned
long
)
roc
,
roc
->
cookie
,
roc
->
chan
,
roc
->
chan
,
roc
->
chan_type
,
roc
->
chan_type
,
GFP_KERNEL
);
GFP_KERNEL
);
list_for_each_entry_safe
(
dep
,
tmp
,
&
roc
->
dependents
,
list
)
list_for_each_entry_safe
(
dep
,
tmp
,
&
roc
->
dependents
,
list
)
ieee80211_roc_notify_destroy
(
dep
);
ieee80211_roc_notify_destroy
(
dep
);
...
...
net/mac80211/pm.c
浏览文件 @
0f622485
...
@@ -135,6 +135,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
...
@@ -135,6 +135,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
ieee80211_bss_info_change_notify
(
sdata
,
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BEACON_ENABLED
);
BSS_CHANGED_BEACON_ENABLED
);
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
&&
rcu_access_pointer
(
sdata
->
u
.
ap
.
beacon
))
drv_stop_ap
(
local
,
sdata
);
/* the interface is leaving the channel and is removed */
/* the interface is leaving the channel and is removed */
ieee80211_vif_release_channel
(
sdata
);
ieee80211_vif_release_channel
(
sdata
);
drv_remove_interface
(
local
,
sdata
);
drv_remove_interface
(
local
,
sdata
);
...
...
net/mac80211/rx.c
浏览文件 @
0f622485
...
@@ -54,8 +54,7 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
...
@@ -54,8 +54,7 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
return
skb
;
return
skb
;
}
}
static
inline
int
should_drop_frame
(
struct
sk_buff
*
skb
,
static
inline
int
should_drop_frame
(
struct
sk_buff
*
skb
,
int
present_fcs_len
)
int
present_fcs_len
)
{
{
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
skb
);
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
skb
);
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
...
@@ -130,15 +129,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
...
@@ -130,15 +129,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
(
1
<<
IEEE80211_RADIOTAP_RX_FLAGS
));
(
1
<<
IEEE80211_RADIOTAP_RX_FLAGS
));
rthdr
->
it_len
=
cpu_to_le16
(
rtap_len
);
rthdr
->
it_len
=
cpu_to_le16
(
rtap_len
);
pos
=
(
unsigned
char
*
)(
rthdr
+
1
);
pos
=
(
unsigned
char
*
)(
rthdr
+
1
);
/* the order of the following fields is important */
/* the order of the following fields is important */
/* IEEE80211_RADIOTAP_TSFT */
/* IEEE80211_RADIOTAP_TSFT */
if
(
status
->
flag
&
RX_FLAG_MACTIME_MPDU
)
{
if
(
status
->
flag
&
RX_FLAG_MACTIME_MPDU
)
{
put_unaligned_le64
(
status
->
mactime
,
pos
);
put_unaligned_le64
(
status
->
mactime
,
pos
);
rthdr
->
it_present
|=
rthdr
->
it_present
|=
cpu_to_le32
(
1
<<
IEEE80211_RADIOTAP_TSFT
);
cpu_to_le32
(
1
<<
IEEE80211_RADIOTAP_TSFT
);
pos
+=
8
;
pos
+=
8
;
}
}
...
@@ -374,7 +372,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
...
@@ -374,7 +372,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
return
origskb
;
return
origskb
;
}
}
static
void
ieee80211_parse_qos
(
struct
ieee80211_rx_data
*
rx
)
static
void
ieee80211_parse_qos
(
struct
ieee80211_rx_data
*
rx
)
{
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
...
@@ -481,8 +478,7 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
...
@@ -481,8 +478,7 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
struct
ieee80211_mgmt
*
hdr
=
(
struct
ieee80211_mgmt
*
)
skb
->
data
;
struct
ieee80211_mgmt
*
hdr
=
(
struct
ieee80211_mgmt
*
)
skb
->
data
;
struct
ieee80211_mmie
*
mmie
;
struct
ieee80211_mmie
*
mmie
;
if
(
skb
->
len
<
24
+
sizeof
(
*
mmie
)
||
if
(
skb
->
len
<
24
+
sizeof
(
*
mmie
)
||
!
is_multicast_ether_addr
(
hdr
->
da
))
!
is_multicast_ether_addr
(
hdr
->
da
))
return
-
1
;
return
-
1
;
if
(
!
ieee80211_is_robust_mgmt_frame
((
struct
ieee80211_hdr
*
)
hdr
))
if
(
!
ieee80211_is_robust_mgmt_frame
((
struct
ieee80211_hdr
*
)
hdr
))
...
@@ -497,9 +493,7 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
...
@@ -497,9 +493,7 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
return
le16_to_cpu
(
mmie
->
key_id
);
return
le16_to_cpu
(
mmie
->
key_id
);
}
}
static
ieee80211_rx_result
ieee80211_rx_mesh_check
(
struct
ieee80211_rx_data
*
rx
)
static
ieee80211_rx_result
ieee80211_rx_mesh_check
(
struct
ieee80211_rx_data
*
rx
)
{
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
char
*
dev_addr
=
rx
->
sdata
->
vif
.
addr
;
char
*
dev_addr
=
rx
->
sdata
->
vif
.
addr
;
...
@@ -507,7 +501,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
...
@@ -507,7 +501,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
if
(
ieee80211_is_data
(
hdr
->
frame_control
))
{
if
(
ieee80211_is_data
(
hdr
->
frame_control
))
{
if
(
is_multicast_ether_addr
(
hdr
->
addr1
))
{
if
(
is_multicast_ether_addr
(
hdr
->
addr1
))
{
if
(
ieee80211_has_tods
(
hdr
->
frame_control
)
||
if
(
ieee80211_has_tods
(
hdr
->
frame_control
)
||
!
ieee80211_has_fromds
(
hdr
->
frame_control
))
!
ieee80211_has_fromds
(
hdr
->
frame_control
))
return
RX_DROP_MONITOR
;
return
RX_DROP_MONITOR
;
if
(
ether_addr_equal
(
hdr
->
addr3
,
dev_addr
))
if
(
ether_addr_equal
(
hdr
->
addr3
,
dev_addr
))
return
RX_DROP_MONITOR
;
return
RX_DROP_MONITOR
;
...
@@ -539,7 +533,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
...
@@ -539,7 +533,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
mgmt
=
(
struct
ieee80211_mgmt
*
)
hdr
;
mgmt
=
(
struct
ieee80211_mgmt
*
)
hdr
;
category
=
mgmt
->
u
.
action
.
category
;
category
=
mgmt
->
u
.
action
.
category
;
if
(
category
!=
WLAN_CATEGORY_MESH_ACTION
&&
if
(
category
!=
WLAN_CATEGORY_MESH_ACTION
&&
category
!=
WLAN_CATEGORY_SELF_PROTECTED
)
category
!=
WLAN_CATEGORY_SELF_PROTECTED
)
return
RX_DROP_MONITOR
;
return
RX_DROP_MONITOR
;
return
RX_CONTINUE
;
return
RX_CONTINUE
;
}
}
...
@@ -551,7 +545,6 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
...
@@ -551,7 +545,6 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
return
RX_CONTINUE
;
return
RX_CONTINUE
;
return
RX_DROP_MONITOR
;
return
RX_DROP_MONITOR
;
}
}
return
RX_CONTINUE
;
return
RX_CONTINUE
;
...
@@ -575,7 +568,6 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
...
@@ -575,7 +568,6 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
return
(
sq1
-
sq2
)
&
SEQ_MASK
;
return
(
sq1
-
sq2
)
&
SEQ_MASK
;
}
}
static
void
ieee80211_release_reorder_frame
(
struct
ieee80211_sub_if_data
*
sdata
,
static
void
ieee80211_release_reorder_frame
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
tid_ampdu_rx
*
tid_agg_rx
,
struct
tid_ampdu_rx
*
tid_agg_rx
,
int
index
)
int
index
)
...
@@ -1585,18 +1577,15 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
...
@@ -1585,18 +1577,15 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
return
RX_CONTINUE
;
return
RX_CONTINUE
;
}
}
static
int
static
int
ieee80211_802_1x_port_control
(
struct
ieee80211_rx_data
*
rx
)
ieee80211_802_1x_port_control
(
struct
ieee80211_rx_data
*
rx
)
{
{
if
(
unlikely
(
!
rx
->
sta
||
if
(
unlikely
(
!
rx
->
sta
||
!
test_sta_flag
(
rx
->
sta
,
WLAN_STA_AUTHORIZED
)))
!
test_sta_flag
(
rx
->
sta
,
WLAN_STA_AUTHORIZED
)))
return
-
EACCES
;
return
-
EACCES
;
return
0
;
return
0
;
}
}
static
int
static
int
ieee80211_drop_unencrypted
(
struct
ieee80211_rx_data
*
rx
,
__le16
fc
)
ieee80211_drop_unencrypted
(
struct
ieee80211_rx_data
*
rx
,
__le16
fc
)
{
{
struct
sk_buff
*
skb
=
rx
->
skb
;
struct
sk_buff
*
skb
=
rx
->
skb
;
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
skb
);
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
skb
);
...
@@ -1618,8 +1607,7 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
...
@@ -1618,8 +1607,7 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
return
0
;
return
0
;
}
}
static
int
static
int
ieee80211_drop_unencrypted_mgmt
(
struct
ieee80211_rx_data
*
rx
)
ieee80211_drop_unencrypted_mgmt
(
struct
ieee80211_rx_data
*
rx
)
{
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
rx
->
skb
->
data
;
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
rx
->
skb
);
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
rx
->
skb
);
...
@@ -2003,7 +1991,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
...
@@ -2003,7 +1991,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
}
else
{
}
else
{
/* unable to resolve next hop */
/* unable to resolve next hop */
mesh_path_error_tx
(
ifmsh
->
mshcfg
.
element_ttl
,
fwd_hdr
->
addr3
,
mesh_path_error_tx
(
ifmsh
->
mshcfg
.
element_ttl
,
fwd_hdr
->
addr3
,
0
,
reason
,
fwd_hdr
->
addr2
,
sdata
);
0
,
reason
,
fwd_hdr
->
addr2
,
sdata
);
IEEE80211_IFSTA_MESH_CTR_INC
(
ifmsh
,
dropped_frames_no_route
);
IEEE80211_IFSTA_MESH_CTR_INC
(
ifmsh
,
dropped_frames_no_route
);
kfree_skb
(
fwd_skb
);
kfree_skb
(
fwd_skb
);
return
RX_DROP_MONITOR
;
return
RX_DROP_MONITOR
;
...
@@ -2212,7 +2200,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
...
@@ -2212,7 +2200,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
cfg80211_report_obss_beacon
(
rx
->
local
->
hw
.
wiphy
,
cfg80211_report_obss_beacon
(
rx
->
local
->
hw
.
wiphy
,
rx
->
skb
->
data
,
rx
->
skb
->
len
,
rx
->
skb
->
data
,
rx
->
skb
->
len
,
status
->
freq
,
sig
,
GFP_ATOMIC
);
status
->
freq
,
sig
);
rx
->
flags
|=
IEEE80211_RX_BEACON_REPORTED
;
rx
->
flags
|=
IEEE80211_RX_BEACON_REPORTED
;
}
}
...
@@ -2412,7 +2400,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
...
@@ -2412,7 +2400,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
if
(
!
ieee80211_vif_is_mesh
(
&
sdata
->
vif
))
if
(
!
ieee80211_vif_is_mesh
(
&
sdata
->
vif
))
break
;
break
;
if
(
mesh_action_is_path_sel
(
mgmt
)
&&
if
(
mesh_action_is_path_sel
(
mgmt
)
&&
(
!
mesh_path_sel_is_hwmp
(
sdata
)
))
!
mesh_path_sel_is_hwmp
(
sdata
))
break
;
break
;
goto
queue
;
goto
queue
;
}
}
...
@@ -2468,7 +2456,6 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
...
@@ -2468,7 +2456,6 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
return
RX_QUEUED
;
return
RX_QUEUED
;
}
}
return
RX_CONTINUE
;
return
RX_CONTINUE
;
}
}
...
...
net/mac80211/status.c
浏览文件 @
0f622485
...
@@ -325,6 +325,75 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
...
@@ -325,6 +325,75 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
}
}
static
void
ieee80211_report_used_skb
(
struct
ieee80211_local
*
local
,
struct
sk_buff
*
skb
,
bool
dropped
)
{
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
struct
ieee80211_hdr
*
hdr
=
(
void
*
)
skb
->
data
;
bool
acked
=
info
->
flags
&
IEEE80211_TX_STAT_ACK
;
if
(
dropped
)
acked
=
false
;
if
(
info
->
flags
&
IEEE80211_TX_INTFL_NL80211_FRAME_TX
)
{
struct
ieee80211_sub_if_data
*
sdata
=
NULL
;
struct
ieee80211_sub_if_data
*
iter_sdata
;
u64
cookie
=
(
unsigned
long
)
skb
;
rcu_read_lock
();
if
(
skb
->
dev
)
{
list_for_each_entry_rcu
(
iter_sdata
,
&
local
->
interfaces
,
list
)
{
if
(
!
iter_sdata
->
dev
)
continue
;
if
(
skb
->
dev
==
iter_sdata
->
dev
)
{
sdata
=
iter_sdata
;
break
;
}
}
}
else
{
sdata
=
rcu_dereference
(
local
->
p2p_sdata
);
}
if
(
!
sdata
)
skb
->
dev
=
NULL
;
else
if
(
ieee80211_is_nullfunc
(
hdr
->
frame_control
)
||
ieee80211_is_qos_nullfunc
(
hdr
->
frame_control
))
{
cfg80211_probe_status
(
sdata
->
dev
,
hdr
->
addr1
,
cookie
,
acked
,
GFP_ATOMIC
);
}
else
{
cfg80211_mgmt_tx_status
(
&
sdata
->
wdev
,
cookie
,
skb
->
data
,
skb
->
len
,
acked
,
GFP_ATOMIC
);
}
rcu_read_unlock
();
}
if
(
unlikely
(
info
->
ack_frame_id
))
{
struct
sk_buff
*
ack_skb
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
local
->
ack_status_lock
,
flags
);
ack_skb
=
idr_find
(
&
local
->
ack_status_frames
,
info
->
ack_frame_id
);
if
(
ack_skb
)
idr_remove
(
&
local
->
ack_status_frames
,
info
->
ack_frame_id
);
spin_unlock_irqrestore
(
&
local
->
ack_status_lock
,
flags
);
if
(
ack_skb
)
{
if
(
!
dropped
)
{
/* consumes ack_skb */
skb_complete_wifi_ack
(
ack_skb
,
acked
);
}
else
{
dev_kfree_skb_any
(
ack_skb
);
}
}
}
}
/*
/*
* Use a static threshold for now, best value to be determined
* Use a static threshold for now, best value to be determined
* by testing ...
* by testing ...
...
@@ -516,62 +585,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
...
@@ -516,62 +585,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
msecs_to_jiffies
(
10
));
msecs_to_jiffies
(
10
));
}
}
if
(
info
->
flags
&
IEEE80211_TX_INTFL_NL80211_FRAME_TX
)
{
ieee80211_report_used_skb
(
local
,
skb
,
false
);
u64
cookie
=
(
unsigned
long
)
skb
;
bool
found
=
false
;
acked
=
info
->
flags
&
IEEE80211_TX_STAT_ACK
;
rcu_read_lock
();
list_for_each_entry_rcu
(
sdata
,
&
local
->
interfaces
,
list
)
{
if
(
!
sdata
->
dev
)
continue
;
if
(
skb
->
dev
!=
sdata
->
dev
)
continue
;
found
=
true
;
break
;
}
if
(
!
skb
->
dev
)
{
sdata
=
rcu_dereference
(
local
->
p2p_sdata
);
if
(
sdata
)
found
=
true
;
}
if
(
!
found
)
skb
->
dev
=
NULL
;
else
if
(
ieee80211_is_nullfunc
(
hdr
->
frame_control
)
||
ieee80211_is_qos_nullfunc
(
hdr
->
frame_control
))
{
cfg80211_probe_status
(
sdata
->
dev
,
hdr
->
addr1
,
cookie
,
acked
,
GFP_ATOMIC
);
}
else
{
cfg80211_mgmt_tx_status
(
&
sdata
->
wdev
,
cookie
,
skb
->
data
,
skb
->
len
,
acked
,
GFP_ATOMIC
);
}
rcu_read_unlock
();
}
if
(
unlikely
(
info
->
ack_frame_id
))
{
struct
sk_buff
*
ack_skb
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
local
->
ack_status_lock
,
flags
);
ack_skb
=
idr_find
(
&
local
->
ack_status_frames
,
info
->
ack_frame_id
);
if
(
ack_skb
)
idr_remove
(
&
local
->
ack_status_frames
,
info
->
ack_frame_id
);
spin_unlock_irqrestore
(
&
local
->
ack_status_lock
,
flags
);
/* consumes ack_skb */
if
(
ack_skb
)
skb_complete_wifi_ack
(
ack_skb
,
info
->
flags
&
IEEE80211_TX_STAT_ACK
);
}
/* this was a transmitted frame, but now we want to reuse it */
/* this was a transmitted frame, but now we want to reuse it */
skb_orphan
(
skb
);
skb_orphan
(
skb
);
...
@@ -647,25 +661,8 @@ EXPORT_SYMBOL(ieee80211_report_low_ack);
...
@@ -647,25 +661,8 @@ EXPORT_SYMBOL(ieee80211_report_low_ack);
void
ieee80211_free_txskb
(
struct
ieee80211_hw
*
hw
,
struct
sk_buff
*
skb
)
void
ieee80211_free_txskb
(
struct
ieee80211_hw
*
hw
,
struct
sk_buff
*
skb
)
{
{
struct
ieee80211_local
*
local
=
hw_to_local
(
hw
);
struct
ieee80211_local
*
local
=
hw_to_local
(
hw
);
struct
ieee80211_tx_info
*
info
=
IEEE80211_SKB_CB
(
skb
);
if
(
unlikely
(
info
->
ack_frame_id
))
{
struct
sk_buff
*
ack_skb
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
local
->
ack_status_lock
,
flags
);
ack_skb
=
idr_find
(
&
local
->
ack_status_frames
,
info
->
ack_frame_id
);
if
(
ack_skb
)
idr_remove
(
&
local
->
ack_status_frames
,
info
->
ack_frame_id
);
spin_unlock_irqrestore
(
&
local
->
ack_status_lock
,
flags
);
/* consumes ack_skb */
if
(
ack_skb
)
dev_kfree_skb_any
(
ack_skb
);
}
ieee80211_report_used_skb
(
local
,
skb
,
true
);
dev_kfree_skb_any
(
skb
);
dev_kfree_skb_any
(
skb
);
}
}
EXPORT_SYMBOL
(
ieee80211_free_txskb
);
EXPORT_SYMBOL
(
ieee80211_free_txskb
);
net/mac80211/trace.h
浏览文件 @
0f622485
...
@@ -342,6 +342,9 @@ TRACE_EVENT(drv_bss_info_changed,
...
@@ -342,6 +342,9 @@ TRACE_EVENT(drv_bss_info_changed,
__field
(
bool
,
ps
);
__field
(
bool
,
ps
);
__dynamic_array
(
u8
,
ssid
,
info
->
ssid_len
);
__dynamic_array
(
u8
,
ssid
,
info
->
ssid_len
);
__field
(
bool
,
hidden_ssid
);
__field
(
bool
,
hidden_ssid
);
__field
(
int
,
txpower
)
__field
(
u8
,
p2p_ctwindow
)
__field
(
bool
,
p2p_oppps
)
),
),
TP_fast_assign
(
TP_fast_assign
(
...
@@ -376,6 +379,9 @@ TRACE_EVENT(drv_bss_info_changed,
...
@@ -376,6 +379,9 @@ TRACE_EVENT(drv_bss_info_changed,
__entry
->
ps
=
info
->
ps
;
__entry
->
ps
=
info
->
ps
;
memcpy
(
__get_dynamic_array
(
ssid
),
info
->
ssid
,
info
->
ssid_len
);
memcpy
(
__get_dynamic_array
(
ssid
),
info
->
ssid
,
info
->
ssid_len
);
__entry
->
hidden_ssid
=
info
->
hidden_ssid
;
__entry
->
hidden_ssid
=
info
->
hidden_ssid
;
__entry
->
txpower
=
info
->
txpower
;
__entry
->
p2p_ctwindow
=
info
->
p2p_ctwindow
;
__entry
->
p2p_oppps
=
info
->
p2p_oppps
;
),
),
TP_printk
(
TP_printk
(
...
@@ -1043,34 +1049,6 @@ DEFINE_EVENT(local_only_evt, drv_cancel_remain_on_channel,
...
@@ -1043,34 +1049,6 @@ DEFINE_EVENT(local_only_evt, drv_cancel_remain_on_channel,
TP_ARGS
(
local
)
TP_ARGS
(
local
)
);
);
TRACE_EVENT
(
drv_offchannel_tx
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
sk_buff
*
skb
,
struct
ieee80211_channel
*
chan
,
enum
nl80211_channel_type
channel_type
,
unsigned
int
wait
),
TP_ARGS
(
local
,
skb
,
chan
,
channel_type
,
wait
),
TP_STRUCT__entry
(
LOCAL_ENTRY
__field
(
int
,
center_freq
)
__field
(
int
,
channel_type
)
__field
(
unsigned
int
,
wait
)
),
TP_fast_assign
(
LOCAL_ASSIGN
;
__entry
->
center_freq
=
chan
->
center_freq
;
__entry
->
channel_type
=
channel_type
;
__entry
->
wait
=
wait
;
),
TP_printk
(
LOCAL_PR_FMT
" freq:%dMHz, wait:%dms"
,
LOCAL_PR_ARG
,
__entry
->
center_freq
,
__entry
->
wait
)
);
TRACE_EVENT
(
drv_set_ringparam
,
TRACE_EVENT
(
drv_set_ringparam
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
u32
tx
,
u32
rx
),
TP_PROTO
(
struct
ieee80211_local
*
local
,
u32
tx
,
u32
rx
),
...
@@ -1396,6 +1374,48 @@ DEFINE_EVENT(local_sdata_chanctx, drv_unassign_vif_chanctx,
...
@@ -1396,6 +1374,48 @@ DEFINE_EVENT(local_sdata_chanctx, drv_unassign_vif_chanctx,
TP_ARGS
(
local
,
sdata
,
ctx
)
TP_ARGS
(
local
,
sdata
,
ctx
)
);
);
TRACE_EVENT
(
drv_start_ap
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_bss_conf
*
info
),
TP_ARGS
(
local
,
sdata
,
info
),
TP_STRUCT__entry
(
LOCAL_ENTRY
VIF_ENTRY
__field
(
u8
,
dtimper
)
__field
(
u16
,
bcnint
)
__dynamic_array
(
u8
,
ssid
,
info
->
ssid_len
);
__field
(
bool
,
hidden_ssid
);
),
TP_fast_assign
(
LOCAL_ASSIGN
;
VIF_ASSIGN
;
__entry
->
dtimper
=
info
->
dtim_period
;
__entry
->
bcnint
=
info
->
beacon_int
;
memcpy
(
__get_dynamic_array
(
ssid
),
info
->
ssid
,
info
->
ssid_len
);
__entry
->
hidden_ssid
=
info
->
hidden_ssid
;
),
TP_printk
(
LOCAL_PR_FMT
VIF_PR_FMT
,
LOCAL_PR_ARG
,
VIF_PR_ARG
)
);
DEFINE_EVENT
(
local_sdata_evt
,
drv_stop_ap
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
),
TP_ARGS
(
local
,
sdata
)
);
DEFINE_EVENT
(
local_only_evt
,
drv_restart_complete
,
TP_PROTO
(
struct
ieee80211_local
*
local
),
TP_ARGS
(
local
)
);
/*
/*
* Tracing for API calls that drivers call.
* Tracing for API calls that drivers call.
*/
*/
...
...
net/mac80211/tx.c
浏览文件 @
0f622485
...
@@ -2089,6 +2089,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
...
@@ -2089,6 +2089,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
head_need
=
max_t
(
int
,
0
,
head_need
);
head_need
=
max_t
(
int
,
0
,
head_need
);
if
(
ieee80211_skb_resize
(
sdata
,
skb
,
head_need
,
true
))
{
if
(
ieee80211_skb_resize
(
sdata
,
skb
,
head_need
,
true
))
{
ieee80211_free_txskb
(
&
local
->
hw
,
skb
);
ieee80211_free_txskb
(
&
local
->
hw
,
skb
);
skb
=
NULL
;
goto
fail_rcu
;
goto
fail_rcu
;
}
}
}
}
...
...
net/mac80211/util.c
浏览文件 @
0f622485
...
@@ -512,7 +512,7 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw)
...
@@ -512,7 +512,7 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw)
EXPORT_SYMBOL
(
ieee80211_wake_queues
);
EXPORT_SYMBOL
(
ieee80211_wake_queues
);
void
ieee80211_iterate_active_interfaces
(
void
ieee80211_iterate_active_interfaces
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_hw
*
hw
,
u32
iter_flags
,
void
(
*
iterator
)(
void
*
data
,
u8
*
mac
,
void
(
*
iterator
)(
void
*
data
,
u8
*
mac
,
struct
ieee80211_vif
*
vif
),
struct
ieee80211_vif
*
vif
),
void
*
data
)
void
*
data
)
...
@@ -530,6 +530,9 @@ void ieee80211_iterate_active_interfaces(
...
@@ -530,6 +530,9 @@ void ieee80211_iterate_active_interfaces(
default:
default:
break
;
break
;
}
}
if
(
!
(
iter_flags
&
IEEE80211_IFACE_ITER_RESUME_ALL
)
&&
!
(
sdata
->
flags
&
IEEE80211_SDATA_IN_DRIVER
))
continue
;
if
(
ieee80211_sdata_running
(
sdata
))
if
(
ieee80211_sdata_running
(
sdata
))
iterator
(
data
,
sdata
->
vif
.
addr
,
iterator
(
data
,
sdata
->
vif
.
addr
,
&
sdata
->
vif
);
&
sdata
->
vif
);
...
@@ -537,7 +540,9 @@ void ieee80211_iterate_active_interfaces(
...
@@ -537,7 +540,9 @@ void ieee80211_iterate_active_interfaces(
sdata
=
rcu_dereference_protected
(
local
->
monitor_sdata
,
sdata
=
rcu_dereference_protected
(
local
->
monitor_sdata
,
lockdep_is_held
(
&
local
->
iflist_mtx
));
lockdep_is_held
(
&
local
->
iflist_mtx
));
if
(
sdata
)
if
(
sdata
&&
(
iter_flags
&
IEEE80211_IFACE_ITER_RESUME_ALL
||
sdata
->
flags
&
IEEE80211_SDATA_IN_DRIVER
))
iterator
(
data
,
sdata
->
vif
.
addr
,
&
sdata
->
vif
);
iterator
(
data
,
sdata
->
vif
.
addr
,
&
sdata
->
vif
);
mutex_unlock
(
&
local
->
iflist_mtx
);
mutex_unlock
(
&
local
->
iflist_mtx
);
...
@@ -545,7 +550,7 @@ void ieee80211_iterate_active_interfaces(
...
@@ -545,7 +550,7 @@ void ieee80211_iterate_active_interfaces(
EXPORT_SYMBOL_GPL
(
ieee80211_iterate_active_interfaces
);
EXPORT_SYMBOL_GPL
(
ieee80211_iterate_active_interfaces
);
void
ieee80211_iterate_active_interfaces_atomic
(
void
ieee80211_iterate_active_interfaces_atomic
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_hw
*
hw
,
u32
iter_flags
,
void
(
*
iterator
)(
void
*
data
,
u8
*
mac
,
void
(
*
iterator
)(
void
*
data
,
u8
*
mac
,
struct
ieee80211_vif
*
vif
),
struct
ieee80211_vif
*
vif
),
void
*
data
)
void
*
data
)
...
@@ -563,13 +568,18 @@ void ieee80211_iterate_active_interfaces_atomic(
...
@@ -563,13 +568,18 @@ void ieee80211_iterate_active_interfaces_atomic(
default:
default:
break
;
break
;
}
}
if
(
!
(
iter_flags
&
IEEE80211_IFACE_ITER_RESUME_ALL
)
&&
!
(
sdata
->
flags
&
IEEE80211_SDATA_IN_DRIVER
))
continue
;
if
(
ieee80211_sdata_running
(
sdata
))
if
(
ieee80211_sdata_running
(
sdata
))
iterator
(
data
,
sdata
->
vif
.
addr
,
iterator
(
data
,
sdata
->
vif
.
addr
,
&
sdata
->
vif
);
&
sdata
->
vif
);
}
}
sdata
=
rcu_dereference
(
local
->
monitor_sdata
);
sdata
=
rcu_dereference
(
local
->
monitor_sdata
);
if
(
sdata
)
if
(
sdata
&&
(
iter_flags
&
IEEE80211_IFACE_ITER_RESUME_ALL
||
sdata
->
flags
&
IEEE80211_SDATA_IN_DRIVER
))
iterator
(
data
,
sdata
->
vif
.
addr
,
&
sdata
->
vif
);
iterator
(
data
,
sdata
->
vif
.
addr
,
&
sdata
->
vif
);
rcu_read_unlock
();
rcu_read_unlock
();
...
@@ -1412,6 +1422,23 @@ int ieee80211_reconfig(struct ieee80211_local *local)
...
@@ -1412,6 +1422,23 @@ int ieee80211_reconfig(struct ieee80211_local *local)
WARN_ON
(
drv_add_chanctx
(
local
,
ctx
));
WARN_ON
(
drv_add_chanctx
(
local
,
ctx
));
mutex_unlock
(
&
local
->
chanctx_mtx
);
mutex_unlock
(
&
local
->
chanctx_mtx
);
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
struct
ieee80211_chanctx_conf
*
ctx_conf
;
if
(
!
ieee80211_sdata_running
(
sdata
))
continue
;
mutex_lock
(
&
local
->
chanctx_mtx
);
ctx_conf
=
rcu_dereference_protected
(
sdata
->
vif
.
chanctx_conf
,
lockdep_is_held
(
&
local
->
chanctx_mtx
));
if
(
ctx_conf
)
{
ctx
=
container_of
(
ctx_conf
,
struct
ieee80211_chanctx
,
conf
);
drv_assign_vif_chanctx
(
local
,
sdata
,
ctx
);
}
mutex_unlock
(
&
local
->
chanctx_mtx
);
}
/* add STAs back */
/* add STAs back */
mutex_lock
(
&
local
->
sta_mtx
);
mutex_lock
(
&
local
->
sta_mtx
);
list_for_each_entry
(
sta
,
&
local
->
sta_list
,
list
)
{
list_for_each_entry
(
sta
,
&
local
->
sta_list
,
list
)
{
...
@@ -1452,22 +1479,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
...
@@ -1452,22 +1479,11 @@ int ieee80211_reconfig(struct ieee80211_local *local)
/* Finally also reconfigure all the BSS information */
/* Finally also reconfigure all the BSS information */
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
struct
ieee80211_chanctx_conf
*
ctx_conf
;
u32
changed
;
u32
changed
;
if
(
!
ieee80211_sdata_running
(
sdata
))
if
(
!
ieee80211_sdata_running
(
sdata
))
continue
;
continue
;
mutex_lock
(
&
local
->
chanctx_mtx
);
ctx_conf
=
rcu_dereference_protected
(
sdata
->
vif
.
chanctx_conf
,
lockdep_is_held
(
&
local
->
chanctx_mtx
));
if
(
ctx_conf
)
{
ctx
=
container_of
(
ctx_conf
,
struct
ieee80211_chanctx
,
conf
);
drv_assign_vif_chanctx
(
local
,
sdata
,
ctx
);
}
mutex_unlock
(
&
local
->
chanctx_mtx
);
/* common change flags for all interface types */
/* common change flags for all interface types */
changed
=
BSS_CHANGED_ERP_CTS_PROT
|
changed
=
BSS_CHANGED_ERP_CTS_PROT
|
BSS_CHANGED_ERP_PREAMBLE
|
BSS_CHANGED_ERP_PREAMBLE
|
...
@@ -1478,7 +1494,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
...
@@ -1478,7 +1494,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
BSS_CHANGED_BSSID
|
BSS_CHANGED_BSSID
|
BSS_CHANGED_CQM
|
BSS_CHANGED_CQM
|
BSS_CHANGED_QOS
|
BSS_CHANGED_QOS
|
BSS_CHANGED_IDLE
;
BSS_CHANGED_IDLE
|
BSS_CHANGED_TXPOWER
;
switch
(
sdata
->
vif
.
type
)
{
switch
(
sdata
->
vif
.
type
)
{
case
NL80211_IFTYPE_STATION
:
case
NL80211_IFTYPE_STATION
:
...
@@ -1495,9 +1512,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
...
@@ -1495,9 +1512,13 @@ int ieee80211_reconfig(struct ieee80211_local *local)
case
NL80211_IFTYPE_AP
:
case
NL80211_IFTYPE_AP
:
changed
|=
BSS_CHANGED_SSID
;
changed
|=
BSS_CHANGED_SSID
;
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
{
changed
|=
BSS_CHANGED_AP_PROBE_RESP
;
changed
|=
BSS_CHANGED_AP_PROBE_RESP
;
if
(
rcu_access_pointer
(
sdata
->
u
.
ap
.
beacon
))
drv_start_ap
(
local
,
sdata
);
}
/* fall through */
/* fall through */
case
NL80211_IFTYPE_MESH_POINT
:
case
NL80211_IFTYPE_MESH_POINT
:
changed
|=
BSS_CHANGED_BEACON
|
changed
|=
BSS_CHANGED_BEACON
|
...
@@ -1594,8 +1615,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
...
@@ -1594,8 +1615,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
* If this is for hw restart things are still running.
* If this is for hw restart things are still running.
* We may want to change that later, however.
* We may want to change that later, however.
*/
*/
if
(
!
local
->
suspended
)
if
(
!
local
->
suspended
)
{
drv_restart_complete
(
local
);
return
0
;
return
0
;
}
#ifdef CONFIG_PM
#ifdef CONFIG_PM
/* first set suspended false, then resuming */
/* first set suspended false, then resuming */
...
...
net/wireless/ap.c
浏览文件 @
0f622485
...
@@ -28,6 +28,7 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
...
@@ -28,6 +28,7 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
if
(
!
err
)
{
if
(
!
err
)
{
wdev
->
beacon_interval
=
0
;
wdev
->
beacon_interval
=
0
;
wdev
->
channel
=
NULL
;
wdev
->
channel
=
NULL
;
wdev
->
ssid_len
=
0
;
}
}
return
err
;
return
err
;
...
...
net/wireless/core.c
浏览文件 @
0f622485
...
@@ -326,6 +326,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
...
@@ -326,6 +326,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
mutex_init
(
&
rdev
->
devlist_mtx
);
mutex_init
(
&
rdev
->
devlist_mtx
);
mutex_init
(
&
rdev
->
sched_scan_mtx
);
mutex_init
(
&
rdev
->
sched_scan_mtx
);
INIT_LIST_HEAD
(
&
rdev
->
wdev_list
);
INIT_LIST_HEAD
(
&
rdev
->
wdev_list
);
INIT_LIST_HEAD
(
&
rdev
->
beacon_registrations
);
spin_lock_init
(
&
rdev
->
beacon_registrations_lock
);
spin_lock_init
(
&
rdev
->
bss_lock
);
spin_lock_init
(
&
rdev
->
bss_lock
);
INIT_LIST_HEAD
(
&
rdev
->
bss_list
);
INIT_LIST_HEAD
(
&
rdev
->
bss_list
);
INIT_WORK
(
&
rdev
->
scan_done_wk
,
__cfg80211_scan_done
);
INIT_WORK
(
&
rdev
->
scan_done_wk
,
__cfg80211_scan_done
);
...
@@ -698,10 +700,15 @@ EXPORT_SYMBOL(wiphy_unregister);
...
@@ -698,10 +700,15 @@ EXPORT_SYMBOL(wiphy_unregister);
void
cfg80211_dev_free
(
struct
cfg80211_registered_device
*
rdev
)
void
cfg80211_dev_free
(
struct
cfg80211_registered_device
*
rdev
)
{
{
struct
cfg80211_internal_bss
*
scan
,
*
tmp
;
struct
cfg80211_internal_bss
*
scan
,
*
tmp
;
struct
cfg80211_beacon_registration
*
reg
,
*
treg
;
rfkill_destroy
(
rdev
->
rfkill
);
rfkill_destroy
(
rdev
->
rfkill
);
mutex_destroy
(
&
rdev
->
mtx
);
mutex_destroy
(
&
rdev
->
mtx
);
mutex_destroy
(
&
rdev
->
devlist_mtx
);
mutex_destroy
(
&
rdev
->
devlist_mtx
);
mutex_destroy
(
&
rdev
->
sched_scan_mtx
);
mutex_destroy
(
&
rdev
->
sched_scan_mtx
);
list_for_each_entry_safe
(
reg
,
treg
,
&
rdev
->
beacon_registrations
,
list
)
{
list_del
(
&
reg
->
list
);
kfree
(
reg
);
}
list_for_each_entry_safe
(
scan
,
tmp
,
&
rdev
->
bss_list
,
list
)
list_for_each_entry_safe
(
scan
,
tmp
,
&
rdev
->
bss_list
,
list
)
cfg80211_put_bss
(
&
scan
->
pub
);
cfg80211_put_bss
(
&
scan
->
pub
);
kfree
(
rdev
);
kfree
(
rdev
);
...
...
net/wireless/core.h
浏览文件 @
0f622485
...
@@ -55,7 +55,8 @@ struct cfg80211_registered_device {
...
@@ -55,7 +55,8 @@ struct cfg80211_registered_device {
int
opencount
;
/* also protected by devlist_mtx */
int
opencount
;
/* also protected by devlist_mtx */
wait_queue_head_t
dev_wait
;
wait_queue_head_t
dev_wait
;
u32
ap_beacons_nlportid
;
struct
list_head
beacon_registrations
;
spinlock_t
beacon_registrations_lock
;
/* protected by RTNL only */
/* protected by RTNL only */
int
num_running_ifaces
;
int
num_running_ifaces
;
...
@@ -260,6 +261,10 @@ enum cfg80211_chan_mode {
...
@@ -260,6 +261,10 @@ enum cfg80211_chan_mode {
CHAN_MODE_EXCLUSIVE
,
CHAN_MODE_EXCLUSIVE
,
};
};
struct
cfg80211_beacon_registration
{
struct
list_head
list
;
u32
nlportid
;
};
/* free object */
/* free object */
extern
void
cfg80211_dev_free
(
struct
cfg80211_registered_device
*
rdev
);
extern
void
cfg80211_dev_free
(
struct
cfg80211_registered_device
*
rdev
);
...
...
net/wireless/nl80211.c
浏览文件 @
0f622485
...
@@ -1110,6 +1110,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
...
@@ -1110,6 +1110,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
goto
nla_put_failure
;
goto
nla_put_failure
;
}
}
CMD
(
start_p2p_device
,
START_P2P_DEVICE
);
CMD
(
start_p2p_device
,
START_P2P_DEVICE
);
CMD
(
set_mcast_rate
,
SET_MCAST_RATE
);
#ifdef CONFIG_NL80211_TESTMODE
#ifdef CONFIG_NL80211_TESTMODE
CMD
(
testmode_cmd
,
TESTMODE
);
CMD
(
testmode_cmd
,
TESTMODE
);
...
@@ -1516,10 +1517,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
...
@@ -1516,10 +1517,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
result
=
0
;
result
=
0
;
mutex_lock
(
&
rdev
->
mtx
);
mutex_lock
(
&
rdev
->
mtx
);
}
else
if
(
nl80211_can_set_dev_channel
(
netdev
->
ieee80211_ptr
))
}
else
wdev
=
netdev
->
ieee80211_ptr
;
wdev
=
netdev
->
ieee80211_ptr
;
else
wdev
=
NULL
;
/*
/*
* end workaround code, by now the rdev is available
* end workaround code, by now the rdev is available
...
@@ -1579,15 +1578,21 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
...
@@ -1579,15 +1578,21 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
}
}
if
(
info
->
attrs
[
NL80211_ATTR_WIPHY_FREQ
])
{
if
(
info
->
attrs
[
NL80211_ATTR_WIPHY_FREQ
])
{
result
=
__nl80211_set_channel
(
rdev
,
wdev
,
info
);
result
=
__nl80211_set_channel
(
rdev
,
nl80211_can_set_dev_channel
(
wdev
)
?
wdev
:
NULL
,
info
);
if
(
result
)
if
(
result
)
goto
bad_res
;
goto
bad_res
;
}
}
if
(
info
->
attrs
[
NL80211_ATTR_WIPHY_TX_POWER_SETTING
])
{
if
(
info
->
attrs
[
NL80211_ATTR_WIPHY_TX_POWER_SETTING
])
{
struct
wireless_dev
*
txp_wdev
=
wdev
;
enum
nl80211_tx_power_setting
type
;
enum
nl80211_tx_power_setting
type
;
int
idx
,
mbm
=
0
;
int
idx
,
mbm
=
0
;
if
(
!
(
rdev
->
wiphy
.
features
&
NL80211_FEATURE_VIF_TXPOWER
))
txp_wdev
=
NULL
;
if
(
!
rdev
->
ops
->
set_tx_power
)
{
if
(
!
rdev
->
ops
->
set_tx_power
)
{
result
=
-
EOPNOTSUPP
;
result
=
-
EOPNOTSUPP
;
goto
bad_res
;
goto
bad_res
;
...
@@ -1607,7 +1612,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
...
@@ -1607,7 +1612,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
mbm
=
nla_get_u32
(
info
->
attrs
[
idx
]);
mbm
=
nla_get_u32
(
info
->
attrs
[
idx
]);
}
}
result
=
rdev_set_tx_power
(
rdev
,
type
,
mbm
);
result
=
rdev_set_tx_power
(
rdev
,
t
xp_wdev
,
t
ype
,
mbm
);
if
(
result
)
if
(
result
)
goto
bad_res
;
goto
bad_res
;
}
}
...
@@ -1782,6 +1787,11 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
...
@@ -1782,6 +1787,11 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
goto
nla_put_failure
;
goto
nla_put_failure
;
}
}
if
(
wdev
->
ssid_len
)
{
if
(
nla_put
(
msg
,
NL80211_ATTR_SSID
,
wdev
->
ssid_len
,
wdev
->
ssid
))
goto
nla_put_failure
;
}
return
genlmsg_end
(
msg
,
hdr
);
return
genlmsg_end
(
msg
,
hdr
);
nla_put_failure:
nla_put_failure:
...
@@ -2644,6 +2654,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
...
@@ -2644,6 +2654,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
wdev
->
preset_chantype
=
params
.
channel_type
;
wdev
->
preset_chantype
=
params
.
channel_type
;
wdev
->
beacon_interval
=
params
.
beacon_interval
;
wdev
->
beacon_interval
=
params
.
beacon_interval
;
wdev
->
channel
=
params
.
channel
;
wdev
->
channel
=
params
.
channel
;
wdev
->
ssid_len
=
params
.
ssid_len
;
memcpy
(
wdev
->
ssid
,
params
.
ssid
,
wdev
->
ssid_len
);
}
}
return
err
;
return
err
;
}
}
...
@@ -5444,6 +5456,36 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
...
@@ -5444,6 +5456,36 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
return
cfg80211_leave_ibss
(
rdev
,
dev
,
false
);
return
cfg80211_leave_ibss
(
rdev
,
dev
,
false
);
}
}
static
int
nl80211_set_mcast_rate
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
{
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
struct
net_device
*
dev
=
info
->
user_ptr
[
1
];
int
mcast_rate
[
IEEE80211_NUM_BANDS
];
u32
nla_rate
;
int
err
;
if
(
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_ADHOC
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_MESH_POINT
)
return
-
EOPNOTSUPP
;
if
(
!
rdev
->
ops
->
set_mcast_rate
)
return
-
EOPNOTSUPP
;
memset
(
mcast_rate
,
0
,
sizeof
(
mcast_rate
));
if
(
!
info
->
attrs
[
NL80211_ATTR_MCAST_RATE
])
return
-
EINVAL
;
nla_rate
=
nla_get_u32
(
info
->
attrs
[
NL80211_ATTR_MCAST_RATE
]);
if
(
!
nl80211_parse_mcast_rate
(
rdev
,
mcast_rate
,
nla_rate
))
return
-
EINVAL
;
err
=
rdev
->
ops
->
set_mcast_rate
(
&
rdev
->
wiphy
,
dev
,
mcast_rate
);
return
err
;
}
#ifdef CONFIG_NL80211_TESTMODE
#ifdef CONFIG_NL80211_TESTMODE
static
struct
genl_multicast_group
nl80211_testmode_mcgrp
=
{
static
struct
genl_multicast_group
nl80211_testmode_mcgrp
=
{
.
name
=
"testmode"
,
.
name
=
"testmode"
,
...
@@ -6899,16 +6941,35 @@ static int nl80211_probe_client(struct sk_buff *skb,
...
@@ -6899,16 +6941,35 @@ static int nl80211_probe_client(struct sk_buff *skb,
static
int
nl80211_register_beacons
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
static
int
nl80211_register_beacons
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
{
{
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
struct
cfg80211_beacon_registration
*
reg
,
*
nreg
;
int
rv
;
if
(
!
(
rdev
->
wiphy
.
flags
&
WIPHY_FLAG_REPORTS_OBSS
))
if
(
!
(
rdev
->
wiphy
.
flags
&
WIPHY_FLAG_REPORTS_OBSS
))
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
if
(
rdev
->
ap_beacons_nlportid
)
nreg
=
kzalloc
(
sizeof
(
*
nreg
),
GFP_KERNEL
);
return
-
EBUSY
;
if
(
!
nreg
)
return
-
ENOMEM
;
/* First, check if already registered. */
spin_lock_bh
(
&
rdev
->
beacon_registrations_lock
);
list_for_each_entry
(
reg
,
&
rdev
->
beacon_registrations
,
list
)
{
if
(
reg
->
nlportid
==
info
->
snd_portid
)
{
rv
=
-
EALREADY
;
goto
out_err
;
}
}
/* Add it to the list */
nreg
->
nlportid
=
info
->
snd_portid
;
list_add
(
&
nreg
->
list
,
&
rdev
->
beacon_registrations
);
rdev
->
ap_beacons_nlportid
=
info
->
snd_portid
;
spin_unlock_bh
(
&
rdev
->
beacon_registrations_lock
)
;
return
0
;
return
0
;
out_err:
spin_unlock_bh
(
&
rdev
->
beacon_registrations_lock
);
kfree
(
nreg
);
return
rv
;
}
}
static
int
nl80211_start_p2p_device
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
static
int
nl80211_start_p2p_device
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
...
@@ -7625,6 +7686,14 @@ static struct genl_ops nl80211_ops[] = {
...
@@ -7625,6 +7686,14 @@ static struct genl_ops nl80211_ops[] = {
.
internal_flags
=
NL80211_FLAG_NEED_WDEV_UP
|
.
internal_flags
=
NL80211_FLAG_NEED_WDEV_UP
|
NL80211_FLAG_NEED_RTNL
,
NL80211_FLAG_NEED_RTNL
,
},
},
{
.
cmd
=
NL80211_CMD_SET_MCAST_RATE
,
.
doit
=
nl80211_set_mcast_rate
,
.
policy
=
nl80211_policy
,
.
flags
=
GENL_ADMIN_PERM
,
.
internal_flags
=
NL80211_FLAG_NEED_NETDEV
|
NL80211_FLAG_NEED_RTNL
,
},
};
};
static
struct
genl_multicast_group
nl80211_mlme_mcgrp
=
{
static
struct
genl_multicast_group
nl80211_mlme_mcgrp
=
{
...
@@ -8914,43 +8983,46 @@ EXPORT_SYMBOL(cfg80211_probe_status);
...
@@ -8914,43 +8983,46 @@ EXPORT_SYMBOL(cfg80211_probe_status);
void
cfg80211_report_obss_beacon
(
struct
wiphy
*
wiphy
,
void
cfg80211_report_obss_beacon
(
struct
wiphy
*
wiphy
,
const
u8
*
frame
,
size_t
len
,
const
u8
*
frame
,
size_t
len
,
int
freq
,
int
sig_dbm
,
gfp_t
gfp
)
int
freq
,
int
sig_dbm
)
{
{
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wiphy
);
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wiphy
);
struct
sk_buff
*
msg
;
struct
sk_buff
*
msg
;
void
*
hdr
;
void
*
hdr
;
u32
nlportid
=
ACCESS_ONCE
(
rdev
->
ap_beacons_nlportid
)
;
struct
cfg80211_beacon_registration
*
reg
;
trace_cfg80211_report_obss_beacon
(
wiphy
,
frame
,
len
,
freq
,
sig_dbm
);
trace_cfg80211_report_obss_beacon
(
wiphy
,
frame
,
len
,
freq
,
sig_dbm
);
if
(
!
nlportid
)
spin_lock_bh
(
&
rdev
->
beacon_registrations_lock
);
return
;
list_for_each_entry
(
reg
,
&
rdev
->
beacon_registrations
,
list
)
{
msg
=
nlmsg_new
(
len
+
100
,
GFP_ATOMIC
);
msg
=
nlmsg_new
(
len
+
100
,
gfp
);
if
(
!
msg
)
{
if
(
!
msg
)
spin_unlock_bh
(
&
rdev
->
beacon_registrations_lock
);
return
;
return
;
}
hdr
=
nl80211hdr_put
(
msg
,
0
,
0
,
0
,
NL80211_CMD_FRAME
);
hdr
=
nl80211hdr_put
(
msg
,
0
,
0
,
0
,
NL80211_CMD_FRAME
);
if
(
!
hdr
)
{
if
(
!
hdr
)
nlmsg_free
(
msg
);
goto
nla_put_failure
;
return
;
}
if
(
nla_put_u32
(
msg
,
NL80211_ATTR_WIPHY
,
rdev
->
wiphy_idx
)
||
if
(
nla_put_u32
(
msg
,
NL80211_ATTR_WIPHY
,
rdev
->
wiphy_idx
)
||
(
freq
&&
(
freq
&&
nla_put_u32
(
msg
,
NL80211_ATTR_WIPHY_FREQ
,
freq
))
||
nla_put_u32
(
msg
,
NL80211_ATTR_WIPHY_FREQ
,
freq
))
||
(
sig_dbm
&&
(
sig_dbm
&&
nla_put_u32
(
msg
,
NL80211_ATTR_RX_SIGNAL_DBM
,
sig_dbm
))
||
nla_put_u32
(
msg
,
NL80211_ATTR_RX_SIGNAL_DBM
,
sig_dbm
))
||
nla_put
(
msg
,
NL80211_ATTR_FRAME
,
len
,
frame
))
nla_put
(
msg
,
NL80211_ATTR_FRAME
,
len
,
frame
))
goto
nla_put_failure
;
goto
nla_put_failure
;
genlmsg_end
(
msg
,
hdr
);
genlmsg_end
(
msg
,
hdr
);
genlmsg_unicast
(
wiphy_net
(
&
rdev
->
wiphy
),
msg
,
nlportid
);
genlmsg_unicast
(
wiphy_net
(
&
rdev
->
wiphy
),
msg
,
reg
->
nlportid
);
}
spin_unlock_bh
(
&
rdev
->
beacon_registrations_lock
);
return
;
return
;
nla_put_failure:
nla_put_failure:
genlmsg_cancel
(
msg
,
hdr
);
spin_unlock_bh
(
&
rdev
->
beacon_registrations_lock
);
if
(
hdr
)
genlmsg_cancel
(
msg
,
hdr
);
nlmsg_free
(
msg
);
nlmsg_free
(
msg
);
}
}
EXPORT_SYMBOL
(
cfg80211_report_obss_beacon
);
EXPORT_SYMBOL
(
cfg80211_report_obss_beacon
);
...
@@ -8962,6 +9034,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
...
@@ -8962,6 +9034,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
struct
netlink_notify
*
notify
=
_notify
;
struct
netlink_notify
*
notify
=
_notify
;
struct
cfg80211_registered_device
*
rdev
;
struct
cfg80211_registered_device
*
rdev
;
struct
wireless_dev
*
wdev
;
struct
wireless_dev
*
wdev
;
struct
cfg80211_beacon_registration
*
reg
,
*
tmp
;
if
(
state
!=
NETLINK_URELEASE
)
if
(
state
!=
NETLINK_URELEASE
)
return
NOTIFY_DONE
;
return
NOTIFY_DONE
;
...
@@ -8971,8 +9044,17 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
...
@@ -8971,8 +9044,17 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
list_for_each_entry_rcu
(
rdev
,
&
cfg80211_rdev_list
,
list
)
{
list_for_each_entry_rcu
(
rdev
,
&
cfg80211_rdev_list
,
list
)
{
list_for_each_entry_rcu
(
wdev
,
&
rdev
->
wdev_list
,
list
)
list_for_each_entry_rcu
(
wdev
,
&
rdev
->
wdev_list
,
list
)
cfg80211_mlme_unregister_socket
(
wdev
,
notify
->
portid
);
cfg80211_mlme_unregister_socket
(
wdev
,
notify
->
portid
);
if
(
rdev
->
ap_beacons_nlportid
==
notify
->
portid
)
rdev
->
ap_beacons_nlportid
=
0
;
spin_lock_bh
(
&
rdev
->
beacon_registrations_lock
);
list_for_each_entry_safe
(
reg
,
tmp
,
&
rdev
->
beacon_registrations
,
list
)
{
if
(
reg
->
nlportid
==
notify
->
portid
)
{
list_del
(
&
reg
->
list
);
kfree
(
reg
);
break
;
}
}
spin_unlock_bh
(
&
rdev
->
beacon_registrations_lock
);
}
}
rcu_read_unlock
();
rcu_read_unlock
();
...
...
net/wireless/rdev-ops.h
浏览文件 @
0f622485
...
@@ -476,21 +476,22 @@ rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed)
...
@@ -476,21 +476,22 @@ rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed)
}
}
static
inline
int
rdev_set_tx_power
(
struct
cfg80211_registered_device
*
rdev
,
static
inline
int
rdev_set_tx_power
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
enum
nl80211_tx_power_setting
type
,
int
mbm
)
enum
nl80211_tx_power_setting
type
,
int
mbm
)
{
{
int
ret
;
int
ret
;
trace_rdev_set_tx_power
(
&
rdev
->
wiphy
,
type
,
mbm
);
trace_rdev_set_tx_power
(
&
rdev
->
wiphy
,
wdev
,
type
,
mbm
);
ret
=
rdev
->
ops
->
set_tx_power
(
&
rdev
->
wiphy
,
type
,
mbm
);
ret
=
rdev
->
ops
->
set_tx_power
(
&
rdev
->
wiphy
,
wdev
,
type
,
mbm
);
trace_rdev_return_int
(
&
rdev
->
wiphy
,
ret
);
trace_rdev_return_int
(
&
rdev
->
wiphy
,
ret
);
return
ret
;
return
ret
;
}
}
static
inline
int
rdev_get_tx_power
(
struct
cfg80211_registered_device
*
rdev
,
static
inline
int
rdev_get_tx_power
(
struct
cfg80211_registered_device
*
rdev
,
int
*
dbm
)
struct
wireless_dev
*
wdev
,
int
*
dbm
)
{
{
int
ret
;
int
ret
;
trace_rdev_get_tx_power
(
&
rdev
->
wiphy
);
trace_rdev_get_tx_power
(
&
rdev
->
wiphy
,
wdev
);
ret
=
rdev
->
ops
->
get_tx_power
(
&
rdev
->
wiphy
,
dbm
);
ret
=
rdev
->
ops
->
get_tx_power
(
&
rdev
->
wiphy
,
wdev
,
dbm
);
trace_rdev_return_int_int
(
&
rdev
->
wiphy
,
ret
,
*
dbm
);
trace_rdev_return_int_int
(
&
rdev
->
wiphy
,
ret
,
*
dbm
);
return
ret
;
return
ret
;
}
}
...
...
net/wireless/trace.h
浏览文件 @
0f622485
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
#define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac)
#define WIPHY_PR_ARG MAC_PR_ARG(wiphy_mac)
#define WDEV_ENTRY __field(u32, id)
#define WDEV_ENTRY __field(u32, id)
#define WDEV_ASSIGN (__entry->id) = (wdev
->identifier
)
#define WDEV_ASSIGN (__entry->id) = (wdev
? wdev->identifier : 0
)
#define WDEV_PR_FMT ", wdev id: %u"
#define WDEV_PR_FMT ", wdev id: %u"
#define WDEV_PR_ARG (__entry->id)
#define WDEV_PR_ARG (__entry->id)
...
@@ -260,11 +260,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna,
...
@@ -260,11 +260,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna,
TP_ARGS
(
wiphy
)
TP_ARGS
(
wiphy
)
);
);
DEFINE_EVENT
(
wiphy_only_evt
,
rdev_get_tx_power
,
TP_PROTO
(
struct
wiphy
*
wiphy
),
TP_ARGS
(
wiphy
)
);
DEFINE_EVENT
(
wiphy_only_evt
,
rdev_rfkill_poll
,
DEFINE_EVENT
(
wiphy_only_evt
,
rdev_rfkill_poll
,
TP_PROTO
(
struct
wiphy
*
wiphy
),
TP_PROTO
(
struct
wiphy
*
wiphy
),
TP_ARGS
(
wiphy
)
TP_ARGS
(
wiphy
)
...
@@ -1230,22 +1225,29 @@ TRACE_EVENT(rdev_set_wiphy_params,
...
@@ -1230,22 +1225,29 @@ TRACE_EVENT(rdev_set_wiphy_params,
WIPHY_PR_ARG
,
__entry
->
changed
)
WIPHY_PR_ARG
,
__entry
->
changed
)
);
);
DEFINE_EVENT
(
wiphy_wdev_evt
,
rdev_get_tx_power
,
TP_PROTO
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
),
TP_ARGS
(
wiphy
,
wdev
)
);
TRACE_EVENT
(
rdev_set_tx_power
,
TRACE_EVENT
(
rdev_set_tx_power
,
TP_PROTO
(
struct
wiphy
*
wiphy
,
enum
nl80211_tx_power_setting
type
,
TP_PROTO
(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
,
int
mbm
),
enum
nl80211_tx_power_setting
type
,
int
mbm
),
TP_ARGS
(
wiphy
,
type
,
mbm
),
TP_ARGS
(
wiphy
,
wdev
,
type
,
mbm
),
TP_STRUCT__entry
(
TP_STRUCT__entry
(
WIPHY_ENTRY
WIPHY_ENTRY
WDEV_ENTRY
__field
(
enum
nl80211_tx_power_setting
,
type
)
__field
(
enum
nl80211_tx_power_setting
,
type
)
__field
(
int
,
mbm
)
__field
(
int
,
mbm
)
),
),
TP_fast_assign
(
TP_fast_assign
(
WIPHY_ASSIGN
;
WIPHY_ASSIGN
;
WDEV_ASSIGN
;
__entry
->
type
=
type
;
__entry
->
type
=
type
;
__entry
->
mbm
=
mbm
;
__entry
->
mbm
=
mbm
;
),
),
TP_printk
(
WIPHY_PR_FMT
", type: %d, mbm: %d"
,
TP_printk
(
WIPHY_PR_FMT
WDEV_PR_FMT
", type: %d, mbm: %d"
,
WIPHY_PR_ARG
,
__entry
->
type
,
__entry
->
mbm
)
WIPHY_PR_ARG
,
WDEV_PR_ARG
,
__entry
->
type
,
__entry
->
mbm
)
);
);
TRACE_EVENT
(
rdev_return_int_int
,
TRACE_EVENT
(
rdev_return_int_int
,
...
...
net/wireless/util.c
浏览文件 @
0f622485
...
@@ -980,6 +980,105 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
...
@@ -980,6 +980,105 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
}
}
EXPORT_SYMBOL
(
cfg80211_calculate_bitrate
);
EXPORT_SYMBOL
(
cfg80211_calculate_bitrate
);
unsigned
int
cfg80211_get_p2p_attr
(
const
u8
*
ies
,
unsigned
int
len
,
u8
attr
,
u8
*
buf
,
unsigned
int
bufsize
)
{
u8
*
out
=
buf
;
u16
attr_remaining
=
0
;
bool
desired_attr
=
false
;
u16
desired_len
=
0
;
while
(
len
>
0
)
{
unsigned
int
iedatalen
;
unsigned
int
copy
;
const
u8
*
iedata
;
if
(
len
<
2
)
return
-
EILSEQ
;
iedatalen
=
ies
[
1
];
if
(
iedatalen
+
2
>
len
)
return
-
EILSEQ
;
if
(
ies
[
0
]
!=
WLAN_EID_VENDOR_SPECIFIC
)
goto
cont
;
if
(
iedatalen
<
4
)
goto
cont
;
iedata
=
ies
+
2
;
/* check WFA OUI, P2P subtype */
if
(
iedata
[
0
]
!=
0x50
||
iedata
[
1
]
!=
0x6f
||
iedata
[
2
]
!=
0x9a
||
iedata
[
3
]
!=
0x09
)
goto
cont
;
iedatalen
-=
4
;
iedata
+=
4
;
/* check attribute continuation into this IE */
copy
=
min_t
(
unsigned
int
,
attr_remaining
,
iedatalen
);
if
(
copy
&&
desired_attr
)
{
desired_len
+=
copy
;
if
(
out
)
{
memcpy
(
out
,
iedata
,
min
(
bufsize
,
copy
));
out
+=
min
(
bufsize
,
copy
);
bufsize
-=
min
(
bufsize
,
copy
);
}
if
(
copy
==
attr_remaining
)
return
desired_len
;
}
attr_remaining
-=
copy
;
if
(
attr_remaining
)
goto
cont
;
iedatalen
-=
copy
;
iedata
+=
copy
;
while
(
iedatalen
>
0
)
{
u16
attr_len
;
/* P2P attribute ID & size must fit */
if
(
iedatalen
<
3
)
return
-
EILSEQ
;
desired_attr
=
iedata
[
0
]
==
attr
;
attr_len
=
get_unaligned_le16
(
iedata
+
1
);
iedatalen
-=
3
;
iedata
+=
3
;
copy
=
min_t
(
unsigned
int
,
attr_len
,
iedatalen
);
if
(
desired_attr
)
{
desired_len
+=
copy
;
if
(
out
)
{
memcpy
(
out
,
iedata
,
min
(
bufsize
,
copy
));
out
+=
min
(
bufsize
,
copy
);
bufsize
-=
min
(
bufsize
,
copy
);
}
if
(
copy
==
attr_len
)
return
desired_len
;
}
iedata
+=
copy
;
iedatalen
-=
copy
;
attr_remaining
=
attr_len
-
copy
;
}
cont:
len
-=
ies
[
1
]
+
2
;
ies
+=
ies
[
1
]
+
2
;
}
if
(
attr_remaining
&&
desired_attr
)
return
-
EILSEQ
;
return
-
ENOENT
;
}
EXPORT_SYMBOL
(
cfg80211_get_p2p_attr
);
int
cfg80211_validate_beacon_int
(
struct
cfg80211_registered_device
*
rdev
,
int
cfg80211_validate_beacon_int
(
struct
cfg80211_registered_device
*
rdev
,
u32
beacon_int
)
u32
beacon_int
)
{
{
...
...
net/wireless/wext-compat.c
浏览文件 @
0f622485
...
@@ -895,7 +895,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev,
...
@@ -895,7 +895,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev,
return
0
;
return
0
;
}
}
return
rdev_set_tx_power
(
rdev
,
type
,
DBM_TO_MBM
(
dbm
));
return
rdev_set_tx_power
(
rdev
,
wdev
,
type
,
DBM_TO_MBM
(
dbm
));
}
}
static
int
cfg80211_wext_giwtxpower
(
struct
net_device
*
dev
,
static
int
cfg80211_wext_giwtxpower
(
struct
net_device
*
dev
,
...
@@ -914,7 +914,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev,
...
@@ -914,7 +914,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev,
if
(
!
rdev
->
ops
->
get_tx_power
)
if
(
!
rdev
->
ops
->
get_tx_power
)
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
err
=
rdev_get_tx_power
(
rdev
,
&
val
);
err
=
rdev_get_tx_power
(
rdev
,
wdev
,
&
val
);
if
(
err
)
if
(
err
)
return
err
;
return
err
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录