Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
0af5491c
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
0af5491c
编写于
7月 09, 2012
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.sipsolutions.net/mac80211-next
上级
635d999f
4d6d0ae2
变更
33
隐藏空白更改
内联
并排
Showing
33 changed file
with
995 addition
and
299 deletion
+995
-299
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/cfg80211.c
+2
-0
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/ath/carl9170/tx.c
+3
-3
drivers/net/wireless/iwlegacy/3945-rs.c
drivers/net/wireless/iwlegacy/3945-rs.c
+1
-1
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mac80211_hwsim.c
+10
-2
drivers/net/wireless/p54/txrx.c
drivers/net/wireless/p54/txrx.c
+3
-3
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/main.c
+2
-0
include/linux/ieee80211.h
include/linux/ieee80211.h
+159
-1
include/linux/nl80211.h
include/linux/nl80211.h
+17
-0
include/net/cfg80211.h
include/net/cfg80211.h
+33
-7
include/net/mac80211.h
include/net/mac80211.h
+19
-25
net/mac80211/cfg.c
net/mac80211/cfg.c
+12
-12
net/mac80211/debugfs_key.c
net/mac80211/debugfs_key.c
+10
-6
net/mac80211/driver-ops.h
net/mac80211/driver-ops.h
+14
-8
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+10
-1
net/mac80211/iface.c
net/mac80211/iface.c
+123
-135
net/mac80211/main.c
net/mac80211/main.c
+11
-6
net/mac80211/mesh_plink.c
net/mac80211/mesh_plink.c
+2
-2
net/mac80211/mlme.c
net/mac80211/mlme.c
+22
-6
net/mac80211/trace.h
net/mac80211/trace.h
+7
-0
net/mac80211/tx.c
net/mac80211/tx.c
+7
-9
net/mac80211/util.c
net/mac80211/util.c
+40
-9
net/wireless/Makefile
net/wireless/Makefile
+1
-1
net/wireless/ap.c
net/wireless/ap.c
+46
-0
net/wireless/chan.c
net/wireless/chan.c
+61
-1
net/wireless/core.c
net/wireless/core.c
+82
-2
net/wireless/core.h
net/wireless/core.h
+61
-3
net/wireless/ibss.c
net/wireless/ibss.c
+11
-0
net/wireless/mesh.c
net/wireless/mesh.c
+26
-4
net/wireless/mlme.c
net/wireless/mlme.c
+17
-0
net/wireless/nl80211.c
net/wireless/nl80211.c
+37
-28
net/wireless/reg.c
net/wireless/reg.c
+4
-1
net/wireless/util.c
net/wireless/util.c
+140
-16
net/wireless/wext-compat.c
net/wireless/wext-compat.c
+2
-7
未找到文件。
drivers/net/wireless/ath/ath6kl/cfg80211.c
浏览文件 @
0af5491c
...
...
@@ -3627,6 +3627,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
wiphy
->
cipher_suites
=
cipher_suites
;
wiphy
->
n_cipher_suites
=
ARRAY_SIZE
(
cipher_suites
);
#ifdef CONFIG_PM
wiphy
->
wowlan
.
flags
=
WIPHY_WOWLAN_MAGIC_PKT
|
WIPHY_WOWLAN_DISCONNECT
|
WIPHY_WOWLAN_GTK_REKEY_FAILURE
|
...
...
@@ -3636,6 +3637,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
wiphy
->
wowlan
.
n_patterns
=
WOW_MAX_FILTERS_PER_LIST
;
wiphy
->
wowlan
.
pattern_min_len
=
1
;
wiphy
->
wowlan
.
pattern_max_len
=
WOW_PATTERN_SIZE
;
#endif
wiphy
->
max_sched_scan_ssids
=
MAX_PROBED_SSIDS
;
...
...
drivers/net/wireless/ath/carl9170/tx.c
浏览文件 @
0af5491c
...
...
@@ -277,11 +277,11 @@ static void carl9170_tx_release(struct kref *ref)
return
;
BUILD_BUG_ON
(
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
mpdu_ack_len
)
!=
23
);
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
ck_signal
)
!=
20
);
memset
(
&
txinfo
->
status
.
a
mpdu_ack_len
,
0
,
memset
(
&
txinfo
->
status
.
a
ck_signal
,
0
,
sizeof
(
struct
ieee80211_tx_info
)
-
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
mpdu_ack_len
));
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
ck_signal
));
if
(
atomic_read
(
&
ar
->
tx_total_queued
))
ar
->
tx_schedule
=
true
;
...
...
drivers/net/wireless/iwlegacy/3945-rs.c
浏览文件 @
0af5491c
...
...
@@ -946,7 +946,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
case
IEEE80211_BAND_5GHZ
:
rs_sta
->
expected_tpt
=
il3945_expected_tpt_a
;
break
;
case
IEEE80211_NUM_BANDS
:
default
:
BUG
();
break
;
}
...
...
drivers/net/wireless/mac80211_hwsim.c
浏览文件 @
0af5491c
...
...
@@ -292,7 +292,7 @@ struct mac80211_hwsim_data {
struct
list_head
list
;
struct
ieee80211_hw
*
hw
;
struct
device
*
dev
;
struct
ieee80211_supported_band
bands
[
2
];
struct
ieee80211_supported_band
bands
[
IEEE80211_NUM_BANDS
];
struct
ieee80211_channel
channels_2ghz
[
ARRAY_SIZE
(
hwsim_channels_2ghz
)];
struct
ieee80211_channel
channels_5ghz
[
ARRAY_SIZE
(
hwsim_channels_5ghz
)];
struct
ieee80211_rate
rates
[
ARRAY_SIZE
(
hwsim_rates
)];
...
...
@@ -1082,6 +1082,8 @@ enum hwsim_testmode_attr {
enum
hwsim_testmode_cmd
{
HWSIM_TM_CMD_SET_PS
=
0
,
HWSIM_TM_CMD_GET_PS
=
1
,
HWSIM_TM_CMD_STOP_QUEUES
=
2
,
HWSIM_TM_CMD_WAKE_QUEUES
=
3
,
};
static
const
struct
nla_policy
hwsim_testmode_policy
[
HWSIM_TM_ATTR_MAX
+
1
]
=
{
...
...
@@ -1121,6 +1123,12 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
if
(
nla_put_u32
(
skb
,
HWSIM_TM_ATTR_PS
,
hwsim
->
ps
))
goto
nla_put_failure
;
return
cfg80211_testmode_reply
(
skb
);
case
HWSIM_TM_CMD_STOP_QUEUES
:
ieee80211_stop_queues
(
hw
);
return
0
;
case
HWSIM_TM_CMD_WAKE_QUEUES
:
ieee80211_wake_queues
(
hw
);
return
0
;
default:
return
-
EOPNOTSUPP
;
}
...
...
@@ -1855,7 +1863,7 @@ static int __init init_mac80211_hwsim(void)
sband
->
n_bitrates
=
ARRAY_SIZE
(
hwsim_rates
)
-
4
;
break
;
default:
break
;
continue
;
}
sband
->
ht_cap
.
ht_supported
=
true
;
...
...
drivers/net/wireless/p54/txrx.c
浏览文件 @
0af5491c
...
...
@@ -422,11 +422,11 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
* Clear manually, ieee80211_tx_info_clear_status would
* clear the counts too and we need them.
*/
memset
(
&
info
->
status
.
a
mpdu_ack_len
,
0
,
memset
(
&
info
->
status
.
a
ck_signal
,
0
,
sizeof
(
struct
ieee80211_tx_info
)
-
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
mpdu_ack_len
));
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
ck_signal
));
BUILD_BUG_ON
(
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
mpdu_ack_len
)
!=
23
);
status
.
a
ck_signal
)
!=
20
);
if
(
entry_hdr
->
flags
&
cpu_to_le16
(
P54_HDR_FLAG_DATA_ALIGN
))
pad
=
entry_data
->
align
[
0
];
...
...
drivers/net/wireless/ti/wlcore/main.c
浏览文件 @
0af5491c
...
...
@@ -5504,6 +5504,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
goto
out_free_hw
;
}
#ifdef CONFIG_PM
ret
=
enable_irq_wake
(
wl
->
irq
);
if
(
!
ret
)
{
wl
->
irq_wake_enabled
=
true
;
...
...
@@ -5517,6 +5518,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
WL1271_RX_FILTER_MAX_PATTERN_SIZE
;
}
}
#endif
disable_irq
(
wl
->
irq
);
ret
=
wl12xx_get_hw_info
(
wl
);
...
...
include/linux/ieee80211.h
浏览文件 @
0af5491c
...
...
@@ -47,6 +47,7 @@
#define IEEE80211_FCTL_MOREDATA 0x2000
#define IEEE80211_FCTL_PROTECTED 0x4000
#define IEEE80211_FCTL_ORDER 0x8000
#define IEEE80211_FCTL_CTL_EXT 0x0f00
#define IEEE80211_SCTL_FRAG 0x000F
#define IEEE80211_SCTL_SEQ 0xFFF0
...
...
@@ -54,6 +55,7 @@
#define IEEE80211_FTYPE_MGMT 0x0000
#define IEEE80211_FTYPE_CTL 0x0004
#define IEEE80211_FTYPE_DATA 0x0008
#define IEEE80211_FTYPE_EXT 0x000c
/* management */
#define IEEE80211_STYPE_ASSOC_REQ 0x0000
...
...
@@ -70,6 +72,7 @@
#define IEEE80211_STYPE_ACTION 0x00D0
/* control */
#define IEEE80211_STYPE_CTL_EXT 0x0060
#define IEEE80211_STYPE_BACK_REQ 0x0080
#define IEEE80211_STYPE_BACK 0x0090
#define IEEE80211_STYPE_PSPOLL 0x00A0
...
...
@@ -97,6 +100,18 @@
#define IEEE80211_STYPE_QOS_CFPOLL 0x00E0
#define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0
/* extension, added by 802.11ad */
#define IEEE80211_STYPE_DMG_BEACON 0x0000
/* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */
#define IEEE80211_CTL_EXT_POLL 0x2000
#define IEEE80211_CTL_EXT_SPR 0x3000
#define IEEE80211_CTL_EXT_GRANT 0x4000
#define IEEE80211_CTL_EXT_DMG_CTS 0x5000
#define IEEE80211_CTL_EXT_DMG_DTS 0x6000
#define IEEE80211_CTL_EXT_SSW 0x8000
#define IEEE80211_CTL_EXT_SSW_FBACK 0x9000
#define IEEE80211_CTL_EXT_SSW_ACK 0xa000
/* miscellaneous IEEE 802.11 constants */
#define IEEE80211_MAX_FRAG_THRESHOLD 2352
...
...
@@ -1092,6 +1107,73 @@ struct ieee80211_ht_operation {
#define WLAN_HT_SMPS_CONTROL_STATIC 1
#define WLAN_HT_SMPS_CONTROL_DYNAMIC 3
#define VHT_MCS_SUPPORTED_SET_SIZE 8
struct
ieee80211_vht_capabilities
{
__le32
vht_capabilities_info
;
u8
vht_supported_mcs_set
[
VHT_MCS_SUPPORTED_SET_SIZE
];
}
__packed
;
struct
ieee80211_vht_operation
{
u8
vht_op_info_chwidth
;
u8
vht_op_info_chan_center_freq_seg1_idx
;
u8
vht_op_info_chan_center_freq_seg2_idx
;
__le16
vht_basic_mcs_set
;
}
__packed
;
/**
* struct ieee80211_vht_mcs_info - VHT MCS information
* @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams
* @rx_highest: Indicates highest long GI VHT PPDU data rate
* STA can receive. Rate expressed in units of 1 Mbps.
* If this field is 0 this value should not be used to
* consider the highest RX data rate supported.
* @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams
* @tx_highest: Indicates highest long GI VHT PPDU data rate
* STA can transmit. Rate expressed in units of 1 Mbps.
* If this field is 0 this value should not be used to
* consider the highest TX data rate supported.
*/
struct
ieee80211_vht_mcs_info
{
__le16
rx_mcs_map
;
__le16
rx_highest
;
__le16
tx_mcs_map
;
__le16
tx_highest
;
}
__packed
;
#define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0
#define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1
#define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2
#define IEEE80211_VHT_MCS_NOT_SUPPORTED 3
/* 802.11ac VHT Capabilities */
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001
#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 0x00000002
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004
#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008
#define IEEE80211_VHT_CAP_RXLDPC 0x00000010
#define IEEE80211_VHT_CAP_SHORT_GI_80 0x00000020
#define IEEE80211_VHT_CAP_SHORT_GI_160 0x00000040
#define IEEE80211_VHT_CAP_TXSTBC 0x00000080
#define IEEE80211_VHT_CAP_RXSTBC_1 0x00000100
#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200
#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300
#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400
#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800
#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000
#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000
#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000
#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000
#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000
#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
#define IEEE80211_VHT_CAP_HTC_VHT 0x00400000
#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT 0x00800000
#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000
#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000
#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000
#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN 0x20000000
/* Authentication algorithms */
#define WLAN_AUTH_OPEN 0
#define WLAN_AUTH_SHARED_KEY 1
...
...
@@ -1124,6 +1206,21 @@ struct ieee80211_ht_operation {
#define WLAN_CAPABILITY_QOS (1<<9)
#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10)
#define WLAN_CAPABILITY_DSSS_OFDM (1<<13)
/* DMG (60gHz) 802.11ad */
/* type - bits 0..1 */
#define WLAN_CAPABILITY_DMG_TYPE_IBSS (1<<0)
/* Tx by: STA */
#define WLAN_CAPABILITY_DMG_TYPE_PBSS (2<<0)
/* Tx by: PCP */
#define WLAN_CAPABILITY_DMG_TYPE_AP (3<<0)
/* Tx by: AP */
#define WLAN_CAPABILITY_DMG_CBAP_ONLY (1<<2)
#define WLAN_CAPABILITY_DMG_CBAP_SOURCE (1<<3)
#define WLAN_CAPABILITY_DMG_PRIVACY (1<<4)
#define WLAN_CAPABILITY_DMG_ECPAC (1<<5)
#define WLAN_CAPABILITY_DMG_SPECTRUM_MGMT (1<<8)
#define WLAN_CAPABILITY_DMG_RADIO_MEASURE (1<<12)
/* measurement */
#define IEEE80211_SPCT_MSR_RPRT_MODE_LATE (1<<0)
#define IEEE80211_SPCT_MSR_RPRT_MODE_INCAPABLE (1<<1)
...
...
@@ -1133,7 +1230,6 @@ struct ieee80211_ht_operation {
#define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA 1
#define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI 2
/* 802.11g ERP information element */
#define WLAN_ERP_NON_ERP_PRESENT (1<<0)
#define WLAN_ERP_USE_PROTECTION (1<<1)
...
...
@@ -1145,6 +1241,16 @@ enum {
WLAN_ERP_PREAMBLE_LONG
=
1
,
};
/* Band ID, 802.11ad #8.4.1.45 */
enum
{
IEEE80211_BANDID_TV_WS
=
0
,
/* TV white spaces */
IEEE80211_BANDID_SUB1
=
1
,
/* Sub-1 GHz (excluding TV white spaces) */
IEEE80211_BANDID_2G
=
2
,
/* 2.4 GHz */
IEEE80211_BANDID_3G
=
3
,
/* 3.6 GHz */
IEEE80211_BANDID_5G
=
4
,
/* 4.9 and 5 GHz */
IEEE80211_BANDID_60G
=
5
,
/* 60 GHz */
};
/* Status codes */
enum
ieee80211_statuscode
{
WLAN_STATUS_SUCCESS
=
0
,
...
...
@@ -1196,6 +1302,17 @@ enum ieee80211_statuscode {
WLAN_STATUS_ANTI_CLOG_REQUIRED
=
76
,
WLAN_STATUS_FCG_NOT_SUPP
=
78
,
WLAN_STATUS_STA_NO_TBTT
=
78
,
/* 802.11ad */
WLAN_STATUS_REJECTED_WITH_SUGGESTED_CHANGES
=
39
,
WLAN_STATUS_REJECTED_FOR_DELAY_PERIOD
=
47
,
WLAN_STATUS_REJECT_WITH_SCHEDULE
=
83
,
WLAN_STATUS_PENDING_ADMITTING_FST_SESSION
=
86
,
WLAN_STATUS_PERFORMING_FST_NOW
=
87
,
WLAN_STATUS_PENDING_GAP_IN_BA_WINDOW
=
88
,
WLAN_STATUS_REJECT_U_PID_SETTING
=
89
,
WLAN_STATUS_REJECT_DSE_BAND
=
96
,
WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL
=
99
,
WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT
=
103
,
};
...
...
@@ -1352,6 +1469,43 @@ enum ieee80211_eid {
WLAN_EID_DSE_REGISTERED_LOCATION
=
58
,
WLAN_EID_SUPPORTED_REGULATORY_CLASSES
=
59
,
WLAN_EID_EXT_CHANSWITCH_ANN
=
60
,
WLAN_EID_VHT_CAPABILITY
=
191
,
WLAN_EID_VHT_OPERATION
=
192
,
/* 802.11ad */
WLAN_EID_NON_TX_BSSID_CAP
=
83
,
WLAN_EID_WAKEUP_SCHEDULE
=
143
,
WLAN_EID_EXT_SCHEDULE
=
144
,
WLAN_EID_STA_AVAILABILITY
=
145
,
WLAN_EID_DMG_TSPEC
=
146
,
WLAN_EID_DMG_AT
=
147
,
WLAN_EID_DMG_CAP
=
148
,
WLAN_EID_DMG_OPERATION
=
151
,
WLAN_EID_DMG_BSS_PARAM_CHANGE
=
152
,
WLAN_EID_DMG_BEAM_REFINEMENT
=
153
,
WLAN_EID_CHANNEL_MEASURE_FEEDBACK
=
154
,
WLAN_EID_AWAKE_WINDOW
=
157
,
WLAN_EID_MULTI_BAND
=
158
,
WLAN_EID_ADDBA_EXT
=
159
,
WLAN_EID_NEXT_PCP_LIST
=
160
,
WLAN_EID_PCP_HANDOVER
=
161
,
WLAN_EID_DMG_LINK_MARGIN
=
162
,
WLAN_EID_SWITCHING_STREAM
=
163
,
WLAN_EID_SESSION_TRANSITION
=
164
,
WLAN_EID_DYN_TONE_PAIRING_REPORT
=
165
,
WLAN_EID_CLUSTER_REPORT
=
166
,
WLAN_EID_RELAY_CAP
=
167
,
WLAN_EID_RELAY_XFER_PARAM_SET
=
168
,
WLAN_EID_BEAM_LINK_MAINT
=
169
,
WLAN_EID_MULTIPLE_MAC_ADDR
=
170
,
WLAN_EID_U_PID
=
171
,
WLAN_EID_DMG_LINK_ADAPT_ACK
=
172
,
WLAN_EID_QUIET_PERIOD_REQ
=
175
,
WLAN_EID_QUIET_PERIOD_RESP
=
177
,
WLAN_EID_EPAC_POLICY
=
182
,
WLAN_EID_CLISTER_TIME_OFF
=
183
,
WLAN_EID_ANTENNA_SECTOR_ID_PATTERN
=
190
,
};
/* Action category code */
...
...
@@ -1368,7 +1522,10 @@ enum ieee80211_category {
WLAN_CATEGORY_MESH_ACTION
=
13
,
WLAN_CATEGORY_MULTIHOP_ACTION
=
14
,
WLAN_CATEGORY_SELF_PROTECTED
=
15
,
WLAN_CATEGORY_DMG
=
16
,
WLAN_CATEGORY_WMM
=
17
,
WLAN_CATEGORY_FST
=
18
,
WLAN_CATEGORY_UNPROT_DMG
=
20
,
WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED
=
126
,
WLAN_CATEGORY_VENDOR_SPECIFIC
=
127
,
};
...
...
@@ -1616,6 +1773,7 @@ enum ieee80211_sa_query_action {
#define WLAN_CIPHER_SUITE_CCMP 0x000FAC04
#define WLAN_CIPHER_SUITE_WEP104 0x000FAC05
#define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06
#define WLAN_CIPHER_SUITE_GCMP 0x000FAC08
#define WLAN_CIPHER_SUITE_SMS4 0x00147201
...
...
include/linux/nl80211.h
浏览文件 @
0af5491c
...
...
@@ -1638,12 +1638,20 @@ struct nl80211_sta_flag_update {
*
* These attribute types are used with %NL80211_STA_INFO_TXRATE
* when getting information about the bitrate of a station.
* There are 2 attributes for bitrate, a legacy one that represents
* a 16-bit value, and new one that represents a 32-bit value.
* If the rate value fits into 16 bit, both attributes are reported
* with the same value. If the rate is too high to fit into 16 bits
* (>6.5535Gbps) only 32-bit attribute is included.
* User space tools encouraged to use the 32-bit attribute and fall
* back to the 16-bit one for compatibility with older kernels.
*
* @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved
* @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s)
* @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8)
* @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate
* @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval
* @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s)
* @NL80211_RATE_INFO_MAX: highest rate_info number currently defined
* @__NL80211_RATE_INFO_AFTER_LAST: internal use
*/
...
...
@@ -1653,6 +1661,7 @@ enum nl80211_rate_info {
NL80211_RATE_INFO_MCS
,
NL80211_RATE_INFO_40_MHZ_WIDTH
,
NL80211_RATE_INFO_SHORT_GI
,
NL80211_RATE_INFO_BITRATE32
,
/* keep last */
__NL80211_RATE_INFO_AFTER_LAST
,
...
...
@@ -1813,6 +1822,9 @@ enum nl80211_mpath_info {
* @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
* @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
* @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
* @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as
* defined in 802.11ac
* @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE
* @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
* @__NL80211_BAND_ATTR_AFTER_LAST: internal use
*/
...
...
@@ -1826,6 +1838,9 @@ enum nl80211_band_attr {
NL80211_BAND_ATTR_HT_AMPDU_FACTOR
,
NL80211_BAND_ATTR_HT_AMPDU_DENSITY
,
NL80211_BAND_ATTR_VHT_MCS_SET
,
NL80211_BAND_ATTR_VHT_CAPA
,
/* keep last */
__NL80211_BAND_ATTR_AFTER_LAST
,
NL80211_BAND_ATTR_MAX
=
__NL80211_BAND_ATTR_AFTER_LAST
-
1
...
...
@@ -2539,10 +2554,12 @@ enum nl80211_tx_rate_attributes {
* enum nl80211_band - Frequency band
* @NL80211_BAND_2GHZ: 2.4 GHz ISM band
* @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz)
* @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz)
*/
enum
nl80211_band
{
NL80211_BAND_2GHZ
,
NL80211_BAND_5GHZ
,
NL80211_BAND_60GHZ
,
};
/**
...
...
include/net/cfg80211.h
浏览文件 @
0af5491c
...
...
@@ -70,11 +70,13 @@
*
* @IEEE80211_BAND_2GHZ: 2.4GHz ISM band
* @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7)
* @IEEE80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz)
* @IEEE80211_NUM_BANDS: number of defined bands
*/
enum
ieee80211_band
{
IEEE80211_BAND_2GHZ
=
NL80211_BAND_2GHZ
,
IEEE80211_BAND_5GHZ
=
NL80211_BAND_5GHZ
,
IEEE80211_BAND_60GHZ
=
NL80211_BAND_60GHZ
,
/* keep last */
IEEE80211_NUM_BANDS
...
...
@@ -210,6 +212,22 @@ struct ieee80211_sta_ht_cap {
struct
ieee80211_mcs_info
mcs
;
};
/**
* struct ieee80211_sta_vht_cap - STA's VHT capabilities
*
* This structure describes most essential parameters needed
* to describe 802.11ac VHT capabilities for an STA.
*
* @vht_supported: is VHT supported by the STA
* @cap: VHT capabilities map as described in 802.11ac spec
* @vht_mcs: Supported VHT MCS rates
*/
struct
ieee80211_sta_vht_cap
{
bool
vht_supported
;
u32
cap
;
/* use IEEE80211_VHT_CAP_ */
struct
ieee80211_vht_mcs_info
vht_mcs
;
};
/**
* struct ieee80211_supported_band - frequency band definition
*
...
...
@@ -233,6 +251,7 @@ struct ieee80211_supported_band {
int
n_channels
;
int
n_bitrates
;
struct
ieee80211_sta_ht_cap
ht_cap
;
struct
ieee80211_sta_vht_cap
vht_cap
;
};
/*
...
...
@@ -561,11 +580,13 @@ enum station_info_flags {
* @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled
* @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission
* @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
* @RATE_INFO_FLAGS_60G: 60gHz MCS
*/
enum
rate_info_flags
{
RATE_INFO_FLAGS_MCS
=
1
<<
0
,
RATE_INFO_FLAGS_40_MHZ_WIDTH
=
1
<<
1
,
RATE_INFO_FLAGS_SHORT_GI
=
1
<<
2
,
RATE_INFO_FLAGS_60G
=
1
<<
3
,
};
/**
...
...
@@ -1482,9 +1503,8 @@ struct cfg80211_gtk_rekey_data {
* interfaces are active this callback should reject the configuration.
* If no interfaces are active or the device is down, the channel should
* be stored for when a monitor interface becomes active.
* @get_channel: Get the current operating channel, should return %NULL if
* there's no single defined operating channel if for example the
* device implements channel hopping for multi-channel virtual interfaces.
* @set_monitor_enabled: Notify driver that there are only monitor
* interfaces running.
*
* @scan: Request to do a scan. If returning zero, the scan request is given
* the driver, and will be valid until passed to cfg80211_scan_done().
...
...
@@ -1791,15 +1811,14 @@ struct cfg80211_ops {
struct
net_device
*
dev
,
u16
noack_map
);
struct
ieee80211_channel
*
(
*
get_channel
)(
struct
wiphy
*
wiphy
,
enum
nl80211_channel_type
*
type
);
int
(
*
get_et_sset_count
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
int
sset
);
void
(
*
get_et_stats
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
ethtool_stats
*
stats
,
u64
*
data
);
void
(
*
get_et_strings
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
u32
sset
,
u8
*
data
);
void
(
*
set_monitor_enabled
)(
struct
wiphy
*
wiphy
,
bool
enabled
);
};
/*
...
...
@@ -2153,7 +2172,9 @@ struct wiphy {
char
fw_version
[
ETHTOOL_BUSINFO_LEN
];
u32
hw_version
;
#ifdef CONFIG_PM
struct
wiphy_wowlan_support
wowlan
;
#endif
u16
max_remain_on_channel_duration
;
...
...
@@ -2389,6 +2410,11 @@ struct wireless_dev {
struct
ieee80211_channel
*
preset_chan
;
enum
nl80211_channel_type
preset_chantype
;
/* for AP and mesh channel tracking */
struct
ieee80211_channel
*
channel
;
bool
ibss_fixed
;
bool
ps
;
int
ps_timeout
;
...
...
@@ -3463,7 +3489,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
*
* return 0 if MCS index >= 32
*/
u
16
cfg80211_calculate_bitrate
(
struct
rate_info
*
rate
);
u
32
cfg80211_calculate_bitrate
(
struct
rate_info
*
rate
);
/* Logging, debugging and troubleshooting/diagnostic helpers. */
...
...
include/net/mac80211.h
浏览文件 @
0af5491c
...
...
@@ -475,7 +475,7 @@ enum mac80211_rate_control_flags {
#define IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE 24
/* maximum number of rate stages */
#define IEEE80211_TX_MAX_RATES
5
#define IEEE80211_TX_MAX_RATES
4
/**
* struct ieee80211_tx_rate - rate selection/status
...
...
@@ -563,11 +563,11 @@ struct ieee80211_tx_info {
}
control
;
struct
{
struct
ieee80211_tx_rate
rates
[
IEEE80211_TX_MAX_RATES
];
u8
ampdu_ack_len
;
int
ack_signal
;
u8
ampdu_ack_len
;
u8
ampdu_len
;
u8
antenna
;
/*
14
bytes free */
/*
21
bytes free */
}
status
;
struct
{
struct
ieee80211_tx_rate
driver_rates
[
...
...
@@ -634,7 +634,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
info
->
status
.
rates
[
i
].
count
=
0
;
BUILD_BUG_ON
(
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
mpdu_ack_len
)
!=
23
);
offsetof
(
struct
ieee80211_tx_info
,
status
.
a
ck_signal
)
!=
20
);
memset
(
&
info
->
status
.
ampdu_ack_len
,
0
,
sizeof
(
struct
ieee80211_tx_info
)
-
offsetof
(
struct
ieee80211_tx_info
,
status
.
ampdu_ack_len
));
...
...
@@ -1896,19 +1896,6 @@ enum ieee80211_rate_control_changed {
* The low-level driver should send the frame out based on
* configuration in the TX control data. This handler should,
* preferably, never fail and stop queues appropriately.
* This must be implemented if @tx_frags is not.
* Must be atomic.
*
* @tx_frags: Called to transmit multiple fragments of a single MSDU.
* This handler must consume all fragments, sending out some of
* them only is useless and it can't ask for some of them to be
* queued again. If the frame is not fragmented the queue has a
* single SKB only. To avoid issues with the networking stack
* when TX status is reported the frames should be removed from
* the skb queue.
* If this is used, the tx_info @vif and @sta pointers will be
* invalid -- you must not use them in that case.
* This must be implemented if @tx isn't.
* Must be atomic.
*
* @start: Called before the first netdevice attached to the hardware
...
...
@@ -2257,11 +2244,21 @@ enum ieee80211_rate_control_changed {
* @get_rssi: Get current signal strength in dBm, the function is optional
* and can sleep.
*
* @mgd_prepare_tx: Prepare for transmitting a management frame for association
* before associated. In multi-channel scenarios, a virtual interface is
* bound to a channel before it is associated, but as it isn't associated
* yet it need not necessarily be given airtime, in particular since any
* transmission to a P2P GO needs to be synchronized against the GO's
* powersave state. mac80211 will call this function before transmitting a
* management frame prior to having successfully associated to allow the
* driver to give it channel time for the transmission, to get a response
* and to be able to synchronize with the GO.
* The callback will be called before each transmission and upon return
* mac80211 will transmit the frame right away.
* The callback is optional and can (should!) sleep.
*/
struct
ieee80211_ops
{
void
(
*
tx
)(
struct
ieee80211_hw
*
hw
,
struct
sk_buff
*
skb
);
void
(
*
tx_frags
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
struct
sk_buff_head
*
skbs
);
int
(
*
start
)(
struct
ieee80211_hw
*
hw
);
void
(
*
stop
)(
struct
ieee80211_hw
*
hw
);
#ifdef CONFIG_PM
...
...
@@ -2398,6 +2395,9 @@ struct ieee80211_ops {
u32
sset
,
u8
*
data
);
int
(
*
get_rssi
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
s8
*
rssi_dbm
);
void
(
*
mgd_prepare_tx
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
);
};
/**
...
...
@@ -3832,12 +3832,6 @@ void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
void
ieee80211_disable_rssi_reports
(
struct
ieee80211_vif
*
vif
);
int
ieee80211_add_srates_ie
(
struct
ieee80211_vif
*
vif
,
struct
sk_buff
*
skb
,
bool
need_basic
);
int
ieee80211_add_ext_srates_ie
(
struct
ieee80211_vif
*
vif
,
struct
sk_buff
*
skb
,
bool
need_basic
);
/**
* ieee80211_ave_rssi - report the average rssi for the specified interface
*
...
...
net/mac80211/cfg.c
浏览文件 @
0af5491c
...
...
@@ -2668,8 +2668,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
tf
->
u
.
setup_req
.
capability
=
cpu_to_le16
(
ieee80211_get_tdls_sta_capab
(
sdata
));
ieee80211_add_srates_ie
(
&
sdata
->
vif
,
skb
,
false
);
ieee80211_add_ext_srates_ie
(
&
sdata
->
vif
,
skb
,
false
);
ieee80211_add_srates_ie
(
sdata
,
skb
,
false
);
ieee80211_add_ext_srates_ie
(
sdata
,
skb
,
false
);
ieee80211_tdls_add_ext_capab
(
skb
);
break
;
case
WLAN_TDLS_SETUP_RESPONSE
:
...
...
@@ -2682,8 +2682,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev,
tf
->
u
.
setup_resp
.
capability
=
cpu_to_le16
(
ieee80211_get_tdls_sta_capab
(
sdata
));
ieee80211_add_srates_ie
(
&
sdata
->
vif
,
skb
,
false
);
ieee80211_add_ext_srates_ie
(
&
sdata
->
vif
,
skb
,
false
);
ieee80211_add_srates_ie
(
sdata
,
skb
,
false
);
ieee80211_add_ext_srates_ie
(
sdata
,
skb
,
false
);
ieee80211_tdls_add_ext_capab
(
skb
);
break
;
case
WLAN_TDLS_SETUP_CONFIRM
:
...
...
@@ -2743,8 +2743,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
mgmt
->
u
.
action
.
u
.
tdls_discover_resp
.
capability
=
cpu_to_le16
(
ieee80211_get_tdls_sta_capab
(
sdata
));
ieee80211_add_srates_ie
(
&
sdata
->
vif
,
skb
,
false
);
ieee80211_add_ext_srates_ie
(
&
sdata
->
vif
,
skb
,
false
);
ieee80211_add_srates_ie
(
sdata
,
skb
,
false
);
ieee80211_add_ext_srates_ie
(
sdata
,
skb
,
false
);
ieee80211_tdls_add_ext_capab
(
skb
);
break
;
default:
...
...
@@ -2980,14 +2980,14 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
return
0
;
}
static
struct
ieee80211_channel
*
ieee80211_wiphy_get_channel
(
struct
wiphy
*
wiphy
,
enum
nl80211_channel_type
*
type
)
static
void
ieee80211_set_monitor_enabled
(
struct
wiphy
*
wiphy
,
bool
enabled
)
{
struct
ieee80211_local
*
local
=
wiphy_priv
(
wiphy
);
*
type
=
local
->
_oper_channel_type
;
return
local
->
oper_channel
;
if
(
enabled
)
WARN_ON
(
ieee80211_add_virtual_monitor
(
local
));
else
ieee80211_del_virtual_monitor
(
local
);
}
#ifdef CONFIG_PM
...
...
@@ -3063,8 +3063,8 @@ struct cfg80211_ops mac80211_config_ops = {
.
tdls_oper
=
ieee80211_tdls_oper
,
.
tdls_mgmt
=
ieee80211_tdls_mgmt
,
.
probe_client
=
ieee80211_probe_client
,
.
get_channel
=
ieee80211_wiphy_get_channel
,
.
set_noack_map
=
ieee80211_set_noack_map
,
.
set_monitor_enabled
=
ieee80211_set_monitor_enabled
,
#ifdef CONFIG_PM
.
set_wakeup
=
ieee80211_set_wakeup
,
#endif
...
...
net/mac80211/debugfs_key.c
浏览文件 @
0af5491c
...
...
@@ -283,6 +283,11 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
lockdep_assert_held
(
&
sdata
->
local
->
key_mtx
);
if
(
sdata
->
debugfs
.
default_unicast_key
)
{
debugfs_remove
(
sdata
->
debugfs
.
default_unicast_key
);
sdata
->
debugfs
.
default_unicast_key
=
NULL
;
}
if
(
sdata
->
default_unicast_key
)
{
key
=
key_mtx_dereference
(
sdata
->
local
,
sdata
->
default_unicast_key
);
...
...
@@ -290,9 +295,11 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
sdata
->
debugfs
.
default_unicast_key
=
debugfs_create_symlink
(
"default_unicast_key"
,
sdata
->
debugfs
.
dir
,
buf
);
}
else
{
debugfs_remove
(
sdata
->
debugfs
.
default_unicast_key
);
sdata
->
debugfs
.
default_unicast_key
=
NULL
;
}
if
(
sdata
->
debugfs
.
default_multicast_key
)
{
debugfs_remove
(
sdata
->
debugfs
.
default_multicast_key
);
sdata
->
debugfs
.
default_multicast_key
=
NULL
;
}
if
(
sdata
->
default_multicast_key
)
{
...
...
@@ -302,9 +309,6 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata)
sdata
->
debugfs
.
default_multicast_key
=
debugfs_create_symlink
(
"default_multicast_key"
,
sdata
->
debugfs
.
dir
,
buf
);
}
else
{
debugfs_remove
(
sdata
->
debugfs
.
default_multicast_key
);
sdata
->
debugfs
.
default_multicast_key
=
NULL
;
}
}
...
...
net/mac80211/driver-ops.h
浏览文件 @
0af5491c
...
...
@@ -27,14 +27,6 @@ static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
local
->
ops
->
tx
(
&
local
->
hw
,
skb
);
}
static
inline
void
drv_tx_frags
(
struct
ieee80211_local
*
local
,
struct
ieee80211_vif
*
vif
,
struct
ieee80211_sta
*
sta
,
struct
sk_buff_head
*
skbs
)
{
local
->
ops
->
tx_frags
(
&
local
->
hw
,
vif
,
sta
,
skbs
);
}
static
inline
void
drv_get_et_strings
(
struct
ieee80211_sub_if_data
*
sdata
,
u32
sset
,
u8
*
data
)
{
...
...
@@ -860,4 +852,18 @@ static inline int drv_get_rssi(struct ieee80211_local *local,
return
ret
;
}
static
inline
void
drv_mgd_prepare_tx
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
)
{
might_sleep
();
check_sdata_in_driver
(
sdata
);
WARN_ON_ONCE
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_STATION
);
trace_drv_mgd_prepare_tx
(
local
,
sdata
);
if
(
local
->
ops
->
mgd_prepare_tx
)
local
->
ops
->
mgd_prepare_tx
(
&
local
->
hw
,
&
sdata
->
vif
);
trace_drv_return_void
(
local
);
}
#endif
/* __MAC80211_DRIVER_OPS */
net/mac80211/ieee80211_i.h
浏览文件 @
0af5491c
...
...
@@ -1284,7 +1284,6 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum
nl80211_iftype
type
);
void
ieee80211_if_remove
(
struct
ieee80211_sub_if_data
*
sdata
);
void
ieee80211_remove_interfaces
(
struct
ieee80211_local
*
local
);
u32
__ieee80211_recalc_idle
(
struct
ieee80211_local
*
local
);
void
ieee80211_recalc_idle
(
struct
ieee80211_local
*
local
);
void
ieee80211_adjust_monitor_flags
(
struct
ieee80211_sub_if_data
*
sdata
,
const
int
offset
);
...
...
@@ -1481,6 +1480,16 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
struct
ieee80211_channel
*
channel
,
enum
nl80211_channel_type
channel_type
,
u16
prot_mode
);
u8
*
ieee80211_ie_build_vht_cap
(
u8
*
pos
,
struct
ieee80211_sta_vht_cap
*
vht_cap
,
u32
cap
);
int
ieee80211_add_srates_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
,
bool
need_basic
);
int
ieee80211_add_ext_srates_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
,
bool
need_basic
);
/* virtual monitor */
int
ieee80211_add_virtual_monitor
(
struct
ieee80211_local
*
local
);
void
ieee80211_del_virtual_monitor
(
struct
ieee80211_local
*
local
);
/* channel management */
enum
ieee80211_chan_mode
{
...
...
net/mac80211/iface.c
浏览文件 @
0af5491c
...
...
@@ -43,6 +43,127 @@
*/
static
u32
ieee80211_idle_off
(
struct
ieee80211_local
*
local
,
const
char
*
reason
)
{
if
(
!
(
local
->
hw
.
conf
.
flags
&
IEEE80211_CONF_IDLE
))
return
0
;
local
->
hw
.
conf
.
flags
&=
~
IEEE80211_CONF_IDLE
;
return
IEEE80211_CONF_CHANGE_IDLE
;
}
static
u32
ieee80211_idle_on
(
struct
ieee80211_local
*
local
)
{
if
(
local
->
hw
.
conf
.
flags
&
IEEE80211_CONF_IDLE
)
return
0
;
drv_flush
(
local
,
false
);
local
->
hw
.
conf
.
flags
|=
IEEE80211_CONF_IDLE
;
return
IEEE80211_CONF_CHANGE_IDLE
;
}
static
u32
__ieee80211_recalc_idle
(
struct
ieee80211_local
*
local
)
{
struct
ieee80211_sub_if_data
*
sdata
;
int
count
=
0
;
bool
working
=
false
,
scanning
=
false
;
unsigned
int
led_trig_start
=
0
,
led_trig_stop
=
0
;
struct
ieee80211_roc_work
*
roc
;
#ifdef CONFIG_PROVE_LOCKING
WARN_ON
(
debug_locks
&&
!
lockdep_rtnl_is_held
()
&&
!
lockdep_is_held
(
&
local
->
iflist_mtx
));
#endif
lockdep_assert_held
(
&
local
->
mtx
);
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
if
(
!
ieee80211_sdata_running
(
sdata
))
{
sdata
->
vif
.
bss_conf
.
idle
=
true
;
continue
;
}
sdata
->
old_idle
=
sdata
->
vif
.
bss_conf
.
idle
;
/* do not count disabled managed interfaces */
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
&&
!
sdata
->
u
.
mgd
.
associated
&&
!
sdata
->
u
.
mgd
.
auth_data
&&
!
sdata
->
u
.
mgd
.
assoc_data
)
{
sdata
->
vif
.
bss_conf
.
idle
=
true
;
continue
;
}
/* do not count unused IBSS interfaces */
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_ADHOC
&&
!
sdata
->
u
.
ibss
.
ssid_len
)
{
sdata
->
vif
.
bss_conf
.
idle
=
true
;
continue
;
}
/* count everything else */
sdata
->
vif
.
bss_conf
.
idle
=
false
;
count
++
;
}
if
(
!
local
->
ops
->
remain_on_channel
)
{
list_for_each_entry
(
roc
,
&
local
->
roc_list
,
list
)
{
working
=
true
;
roc
->
sdata
->
vif
.
bss_conf
.
idle
=
false
;
}
}
if
(
local
->
scan_sdata
&&
!
(
local
->
hw
.
flags
&
IEEE80211_HW_SCAN_WHILE_IDLE
))
{
scanning
=
true
;
local
->
scan_sdata
->
vif
.
bss_conf
.
idle
=
false
;
}
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_MONITOR
||
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP_VLAN
)
continue
;
if
(
sdata
->
old_idle
==
sdata
->
vif
.
bss_conf
.
idle
)
continue
;
if
(
!
ieee80211_sdata_running
(
sdata
))
continue
;
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_IDLE
);
}
if
(
working
||
scanning
)
led_trig_start
|=
IEEE80211_TPT_LEDTRIG_FL_WORK
;
else
led_trig_stop
|=
IEEE80211_TPT_LEDTRIG_FL_WORK
;
if
(
count
)
led_trig_start
|=
IEEE80211_TPT_LEDTRIG_FL_CONNECTED
;
else
led_trig_stop
|=
IEEE80211_TPT_LEDTRIG_FL_CONNECTED
;
ieee80211_mod_tpt_led_trig
(
local
,
led_trig_start
,
led_trig_stop
);
if
(
working
)
return
ieee80211_idle_off
(
local
,
"working"
);
if
(
scanning
)
return
ieee80211_idle_off
(
local
,
"scanning"
);
if
(
!
count
)
return
ieee80211_idle_on
(
local
);
else
return
ieee80211_idle_off
(
local
,
"in use"
);
return
0
;
}
void
ieee80211_recalc_idle
(
struct
ieee80211_local
*
local
)
{
u32
chg
;
mutex_lock
(
&
local
->
iflist_mtx
);
chg
=
__ieee80211_recalc_idle
(
local
);
mutex_unlock
(
&
local
->
iflist_mtx
);
if
(
chg
)
ieee80211_hw_config
(
local
,
chg
);
}
static
int
ieee80211_change_mtu
(
struct
net_device
*
dev
,
int
new_mtu
)
{
int
meshhdrlen
;
...
...
@@ -209,7 +330,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata)
sdata
->
vif
.
cab_queue
=
IEEE80211_INVAL_HW_QUEUE
;
}
static
int
ieee80211_add_virtual_monitor
(
struct
ieee80211_local
*
local
)
int
ieee80211_add_virtual_monitor
(
struct
ieee80211_local
*
local
)
{
struct
ieee80211_sub_if_data
*
sdata
;
int
ret
;
...
...
@@ -250,7 +371,7 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
return
0
;
}
static
void
ieee80211_del_virtual_monitor
(
struct
ieee80211_local
*
local
)
void
ieee80211_del_virtual_monitor
(
struct
ieee80211_local
*
local
)
{
struct
ieee80211_sub_if_data
*
sdata
;
...
...
@@ -366,12 +487,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
break
;
}
if
(
local
->
monitors
==
0
&&
local
->
open_count
==
0
)
{
res
=
ieee80211_add_virtual_monitor
(
local
);
if
(
res
)
goto
err_stop
;
}
/* must be before the call to ieee80211_configure_filter */
local
->
monitors
++
;
if
(
local
->
monitors
==
1
)
{
...
...
@@ -386,8 +501,6 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
break
;
default:
if
(
coming_up
)
{
ieee80211_del_virtual_monitor
(
local
);
res
=
drv_add_interface
(
local
,
sdata
);
if
(
res
)
goto
err_stop
;
...
...
@@ -622,7 +735,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
if
(
local
->
monitors
==
0
)
{
local
->
hw
.
conf
.
flags
&=
~
IEEE80211_CONF_MONITOR
;
hw_reconf_flags
|=
IEEE80211_CONF_CHANGE_MONITOR
;
ieee80211_del_virtual_monitor
(
local
);
}
ieee80211_adjust_monitor_flags
(
sdata
,
-
1
);
...
...
@@ -696,9 +808,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
}
}
spin_unlock_irqrestore
(
&
local
->
queue_stop_reason_lock
,
flags
);
if
(
local
->
monitors
==
local
->
open_count
&&
local
->
monitors
>
0
)
ieee80211_add_virtual_monitor
(
local
);
}
static
int
ieee80211_stop
(
struct
net_device
*
dev
)
...
...
@@ -1403,127 +1512,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
list_del
(
&
unreg_list
);
}
static
u32
ieee80211_idle_off
(
struct
ieee80211_local
*
local
,
const
char
*
reason
)
{
if
(
!
(
local
->
hw
.
conf
.
flags
&
IEEE80211_CONF_IDLE
))
return
0
;
local
->
hw
.
conf
.
flags
&=
~
IEEE80211_CONF_IDLE
;
return
IEEE80211_CONF_CHANGE_IDLE
;
}
static
u32
ieee80211_idle_on
(
struct
ieee80211_local
*
local
)
{
if
(
local
->
hw
.
conf
.
flags
&
IEEE80211_CONF_IDLE
)
return
0
;
drv_flush
(
local
,
false
);
local
->
hw
.
conf
.
flags
|=
IEEE80211_CONF_IDLE
;
return
IEEE80211_CONF_CHANGE_IDLE
;
}
u32
__ieee80211_recalc_idle
(
struct
ieee80211_local
*
local
)
{
struct
ieee80211_sub_if_data
*
sdata
;
int
count
=
0
;
bool
working
=
false
,
scanning
=
false
;
unsigned
int
led_trig_start
=
0
,
led_trig_stop
=
0
;
struct
ieee80211_roc_work
*
roc
;
#ifdef CONFIG_PROVE_LOCKING
WARN_ON
(
debug_locks
&&
!
lockdep_rtnl_is_held
()
&&
!
lockdep_is_held
(
&
local
->
iflist_mtx
));
#endif
lockdep_assert_held
(
&
local
->
mtx
);
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
if
(
!
ieee80211_sdata_running
(
sdata
))
{
sdata
->
vif
.
bss_conf
.
idle
=
true
;
continue
;
}
sdata
->
old_idle
=
sdata
->
vif
.
bss_conf
.
idle
;
/* do not count disabled managed interfaces */
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
&&
!
sdata
->
u
.
mgd
.
associated
&&
!
sdata
->
u
.
mgd
.
auth_data
&&
!
sdata
->
u
.
mgd
.
assoc_data
)
{
sdata
->
vif
.
bss_conf
.
idle
=
true
;
continue
;
}
/* do not count unused IBSS interfaces */
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_ADHOC
&&
!
sdata
->
u
.
ibss
.
ssid_len
)
{
sdata
->
vif
.
bss_conf
.
idle
=
true
;
continue
;
}
/* count everything else */
sdata
->
vif
.
bss_conf
.
idle
=
false
;
count
++
;
}
if
(
!
local
->
ops
->
remain_on_channel
)
{
list_for_each_entry
(
roc
,
&
local
->
roc_list
,
list
)
{
working
=
true
;
roc
->
sdata
->
vif
.
bss_conf
.
idle
=
false
;
}
}
if
(
local
->
scan_sdata
&&
!
(
local
->
hw
.
flags
&
IEEE80211_HW_SCAN_WHILE_IDLE
))
{
scanning
=
true
;
local
->
scan_sdata
->
vif
.
bss_conf
.
idle
=
false
;
}
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_MONITOR
||
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP_VLAN
)
continue
;
if
(
sdata
->
old_idle
==
sdata
->
vif
.
bss_conf
.
idle
)
continue
;
if
(
!
ieee80211_sdata_running
(
sdata
))
continue
;
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_IDLE
);
}
if
(
working
||
scanning
)
led_trig_start
|=
IEEE80211_TPT_LEDTRIG_FL_WORK
;
else
led_trig_stop
|=
IEEE80211_TPT_LEDTRIG_FL_WORK
;
if
(
count
)
led_trig_start
|=
IEEE80211_TPT_LEDTRIG_FL_CONNECTED
;
else
led_trig_stop
|=
IEEE80211_TPT_LEDTRIG_FL_CONNECTED
;
ieee80211_mod_tpt_led_trig
(
local
,
led_trig_start
,
led_trig_stop
);
if
(
working
)
return
ieee80211_idle_off
(
local
,
"working"
);
if
(
scanning
)
return
ieee80211_idle_off
(
local
,
"scanning"
);
if
(
!
count
)
return
ieee80211_idle_on
(
local
);
else
return
ieee80211_idle_off
(
local
,
"in use"
);
return
0
;
}
void
ieee80211_recalc_idle
(
struct
ieee80211_local
*
local
)
{
u32
chg
;
mutex_lock
(
&
local
->
iflist_mtx
);
chg
=
__ieee80211_recalc_idle
(
local
);
mutex_unlock
(
&
local
->
iflist_mtx
);
if
(
chg
)
ieee80211_hw_config
(
local
,
chg
);
}
static
int
netdev_notify
(
struct
notifier_block
*
nb
,
unsigned
long
state
,
void
*
ndev
)
...
...
net/mac80211/main.c
浏览文件 @
0af5491c
...
...
@@ -587,7 +587,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
local
->
hw
.
priv
=
(
char
*
)
local
+
ALIGN
(
sizeof
(
*
local
),
NETDEV_ALIGN
);
BUG_ON
(
!
ops
->
tx
&&
!
ops
->
tx_frags
);
BUG_ON
(
!
ops
->
tx
);
BUG_ON
(
!
ops
->
start
);
BUG_ON
(
!
ops
->
stop
);
BUG_ON
(
!
ops
->
config
);
...
...
@@ -688,7 +688,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
int
result
,
i
;
enum
ieee80211_band
band
;
int
channels
,
max_bitrates
;
bool
supp_ht
;
bool
supp_ht
,
supp_vht
;
netdev_features_t
feature_whitelist
;
static
const
u32
cipher_suites
[]
=
{
/* keep WEP first, it may be removed below */
...
...
@@ -706,12 +706,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
local
->
hw
.
offchannel_tx_hw_queue
>=
local
->
hw
.
queues
))
return
-
EINVAL
;
if
((
hw
->
wiphy
->
wowlan
.
flags
||
hw
->
wiphy
->
wowlan
.
n_patterns
)
#ifdef CONFIG_PM
&&
(
!
local
->
ops
->
suspend
||
!
local
->
ops
->
resume
)
#endif
)
if
((
hw
->
wiphy
->
wowlan
.
flags
||
hw
->
wiphy
->
wowlan
.
n_patterns
)
&&
(
!
local
->
ops
->
suspend
||
!
local
->
ops
->
resume
))
return
-
EINVAL
;
#endif
if
((
hw
->
flags
&
IEEE80211_HW_SCAN_WHILE_IDLE
)
&&
!
local
->
ops
->
hw_scan
)
return
-
EINVAL
;
...
...
@@ -733,6 +732,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
channels
=
0
;
max_bitrates
=
0
;
supp_ht
=
false
;
supp_vht
=
false
;
for
(
band
=
0
;
band
<
IEEE80211_NUM_BANDS
;
band
++
)
{
struct
ieee80211_supported_band
*
sband
;
...
...
@@ -750,6 +750,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if
(
max_bitrates
<
sband
->
n_bitrates
)
max_bitrates
=
sband
->
n_bitrates
;
supp_ht
=
supp_ht
||
sband
->
ht_cap
.
ht_supported
;
supp_vht
=
supp_vht
||
sband
->
vht_cap
.
vht_supported
;
}
local
->
int_scan_req
=
kzalloc
(
sizeof
(
*
local
->
int_scan_req
)
+
...
...
@@ -825,6 +826,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if
(
supp_ht
)
local
->
scan_ies_len
+=
2
+
sizeof
(
struct
ieee80211_ht_cap
);
if
(
supp_vht
)
local
->
scan_ies_len
+=
2
+
sizeof
(
struct
ieee80211_vht_capabilities
);
if
(
!
local
->
ops
->
hw_scan
)
{
/* For hw_scan, driver needs to set these up. */
local
->
hw
.
wiphy
->
max_scan_ssids
=
4
;
...
...
net/mac80211/mesh_plink.c
浏览文件 @
0af5491c
...
...
@@ -258,8 +258,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
pos
=
skb_put
(
skb
,
2
);
memcpy
(
pos
+
2
,
&
plid
,
2
);
}
if
(
ieee80211_add_srates_ie
(
&
sdata
->
vif
,
skb
,
true
)
||
ieee80211_add_ext_srates_ie
(
&
sdata
->
vif
,
skb
,
true
)
||
if
(
ieee80211_add_srates_ie
(
sdata
,
skb
,
true
)
||
ieee80211_add_ext_srates_ie
(
sdata
,
skb
,
true
)
||
mesh_add_rsn_ie
(
skb
,
sdata
)
||
mesh_add_meshid_ie
(
skb
,
sdata
)
||
mesh_add_meshconf_ie
(
skb
,
sdata
))
...
...
net/mac80211/mlme.c
浏览文件 @
0af5491c
...
...
@@ -541,6 +541,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
memcpy
(
pos
,
assoc_data
->
ie
+
offset
,
noffset
-
offset
);
}
drv_mgd_prepare_tx
(
local
,
sdata
);
IEEE80211_SKB_CB
(
skb
)
->
flags
|=
IEEE80211_TX_INTFL_DONT_ENCRYPT
;
ieee80211_tx_skb
(
sdata
,
skb
);
}
...
...
@@ -580,6 +582,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
if
(
!
(
ifmgd
->
flags
&
IEEE80211_STA_MFP_ENABLED
))
IEEE80211_SKB_CB
(
skb
)
->
flags
|=
IEEE80211_TX_INTFL_DONT_ENCRYPT
;
drv_mgd_prepare_tx
(
local
,
sdata
);
ieee80211_tx_skb
(
sdata
,
skb
);
}
}
...
...
@@ -902,9 +907,6 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
if
(
!
mgd
->
associated
)
return
false
;
if
(
!
mgd
->
associated
->
beacon_ies
)
return
false
;
if
(
mgd
->
flags
&
(
IEEE80211_STA_BEACON_POLL
|
IEEE80211_STA_CONNECTION_POLL
))
return
false
;
...
...
@@ -1362,6 +1364,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
}
mutex_unlock
(
&
local
->
sta_mtx
);
/* flush out any pending frame (e.g. DELBA) before deauth/disassoc */
if
(
tx
)
drv_flush
(
local
,
false
);
/* deauthenticate/disassociate now */
if
(
tx
||
frame_buf
)
ieee80211_send_deauth_disassoc
(
sdata
,
ifmgd
->
bssid
,
stype
,
...
...
@@ -1610,6 +1616,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
{
struct
ieee80211_sub_if_data
*
sdata
=
vif_to_sdata
(
vif
);
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
struct
cfg80211_bss
*
cbss
;
struct
sk_buff
*
skb
;
const
u8
*
ssid
;
int
ssid_len
;
...
...
@@ -1619,16 +1626,22 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
ASSERT_MGD_MTX
(
ifmgd
);
if
(
!
ifmgd
->
associated
)
if
(
ifmgd
->
associated
)
cbss
=
ifmgd
->
associated
;
else
if
(
ifmgd
->
auth_data
)
cbss
=
ifmgd
->
auth_data
->
bss
;
else
if
(
ifmgd
->
assoc_data
)
cbss
=
ifmgd
->
assoc_data
->
bss
;
else
return
NULL
;
ssid
=
ieee80211_bss_get_ie
(
ifmgd
->
associated
,
WLAN_EID_SSID
);
ssid
=
ieee80211_bss_get_ie
(
cbss
,
WLAN_EID_SSID
);
if
(
WARN_ON_ONCE
(
ssid
==
NULL
))
ssid_len
=
0
;
else
ssid_len
=
ssid
[
1
];
skb
=
ieee80211_build_probe_req
(
sdata
,
ifmgd
->
associated
->
bssid
,
skb
=
ieee80211_build_probe_req
(
sdata
,
cbss
->
bssid
,
(
u32
)
-
1
,
ssid
+
2
,
ssid_len
,
NULL
,
0
,
true
);
...
...
@@ -1747,6 +1760,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
if
(
!
elems
.
challenge
)
return
;
auth_data
->
expected_transaction
=
4
;
drv_mgd_prepare_tx
(
sdata
->
local
,
sdata
);
ieee80211_send_auth
(
sdata
,
3
,
auth_data
->
algorithm
,
elems
.
challenge
-
2
,
elems
.
challenge_len
+
2
,
auth_data
->
bss
->
bssid
,
auth_data
->
bss
->
bssid
,
...
...
@@ -2630,6 +2644,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
return
-
ETIMEDOUT
;
}
drv_mgd_prepare_tx
(
local
,
sdata
);
if
(
auth_data
->
bss
->
proberesp_ies
)
{
sdata_info
(
sdata
,
"send auth to %pM (try %d/%d)
\n
"
,
auth_data
->
bss
->
bssid
,
auth_data
->
tries
,
...
...
net/mac80211/trace.h
浏览文件 @
0af5491c
...
...
@@ -1244,6 +1244,13 @@ TRACE_EVENT(drv_get_rssi,
)
);
DEFINE_EVENT
(
local_sdata_evt
,
drv_mgd_prepare_tx
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
),
TP_ARGS
(
local
,
sdata
)
);
/*
* Tracing for API calls that drivers call.
*/
...
...
net/mac80211/tx.c
浏览文件 @
0af5491c
...
...
@@ -140,6 +140,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx,
if
(
r
->
flags
&
IEEE80211_RATE_MANDATORY_A
)
mrate
=
r
->
bitrate
;
break
;
case
IEEE80211_BAND_60GHZ
:
/* TODO, for now fall through */
case
IEEE80211_NUM_BANDS
:
WARN_ON
(
1
);
break
;
...
...
@@ -957,8 +959,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
info
->
control
.
rates
[
1
].
idx
=
-
1
;
info
->
control
.
rates
[
2
].
idx
=
-
1
;
info
->
control
.
rates
[
3
].
idx
=
-
1
;
info
->
control
.
rates
[
4
].
idx
=
-
1
;
BUILD_BUG_ON
(
IEEE80211_TX_MAX_RATES
!=
5
);
BUILD_BUG_ON
(
IEEE80211_TX_MAX_RATES
!=
4
);
info
->
flags
&=
~
IEEE80211_TX_CTL_RATE_CTRL_PROBE
;
}
else
{
hdr
->
frame_control
&=
~
morefrags
;
...
...
@@ -1293,11 +1294,8 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
break
;
}
if
(
local
->
ops
->
tx_frags
)
drv_tx_frags
(
local
,
vif
,
pubsta
,
skbs
);
else
result
=
ieee80211_tx_frags
(
local
,
vif
,
pubsta
,
skbs
,
txpending
);
result
=
ieee80211_tx_frags
(
local
,
vif
,
pubsta
,
skbs
,
txpending
);
ieee80211_tpt_led_trig_tx
(
local
,
fc
,
led_len
);
ieee80211_led_tx
(
local
,
1
);
...
...
@@ -2420,9 +2418,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
*
pos
++
=
WLAN_EID_SSID
;
*
pos
++
=
0x0
;
if
(
ieee80211_add_srates_ie
(
&
sdata
->
vif
,
skb
,
true
)
||
if
(
ieee80211_add_srates_ie
(
sdata
,
skb
,
true
)
||
mesh_add_ds_params_ie
(
skb
,
sdata
)
||
ieee80211_add_ext_srates_ie
(
&
sdata
->
vif
,
skb
,
true
)
||
ieee80211_add_ext_srates_ie
(
sdata
,
skb
,
true
)
||
mesh_add_rsn_ie
(
skb
,
sdata
)
||
mesh_add_ht_cap_ie
(
skb
,
sdata
)
||
mesh_add_ht_oper_ie
(
skb
,
sdata
)
||
...
...
net/mac80211/util.c
浏览文件 @
0af5491c
...
...
@@ -268,6 +268,10 @@ EXPORT_SYMBOL(ieee80211_ctstoself_duration);
void
ieee80211_propagate_queue_wake
(
struct
ieee80211_local
*
local
,
int
queue
)
{
struct
ieee80211_sub_if_data
*
sdata
;
int
n_acs
=
IEEE80211_NUM_ACS
;
if
(
local
->
hw
.
queues
<
IEEE80211_NUM_ACS
)
n_acs
=
1
;
list_for_each_entry_rcu
(
sdata
,
&
local
->
interfaces
,
list
)
{
int
ac
;
...
...
@@ -279,7 +283,7 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
local
->
queue_stop_reasons
[
sdata
->
vif
.
cab_queue
]
!=
0
)
continue
;
for
(
ac
=
0
;
ac
<
IEEE80211_NUM_ACS
;
ac
++
)
{
for
(
ac
=
0
;
ac
<
n_acs
;
ac
++
)
{
int
ac_queue
=
sdata
->
vif
.
hw_queue
[
ac
];
if
(
ac_queue
==
queue
||
...
...
@@ -341,6 +345,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
{
struct
ieee80211_local
*
local
=
hw_to_local
(
hw
);
struct
ieee80211_sub_if_data
*
sdata
;
int
n_acs
=
IEEE80211_NUM_ACS
;
trace_stop_queue
(
local
,
queue
,
reason
);
...
...
@@ -352,11 +357,14 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
__set_bit
(
reason
,
&
local
->
queue_stop_reasons
[
queue
]);
if
(
local
->
hw
.
queues
<
IEEE80211_NUM_ACS
)
n_acs
=
1
;
rcu_read_lock
();
list_for_each_entry_rcu
(
sdata
,
&
local
->
interfaces
,
list
)
{
int
ac
;
for
(
ac
=
0
;
ac
<
IEEE80211_NUM_ACS
;
ac
++
)
{
for
(
ac
=
0
;
ac
<
n_acs
;
ac
++
)
{
if
(
sdata
->
vif
.
hw_queue
[
ac
]
==
queue
||
sdata
->
vif
.
cab_queue
==
queue
)
netif_stop_subqueue
(
sdata
->
dev
,
ac
);
...
...
@@ -1072,6 +1080,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
pos
+=
noffset
-
offset
;
}
if
(
sband
->
vht_cap
.
vht_supported
)
pos
=
ieee80211_ie_build_vht_cap
(
pos
,
&
sband
->
vht_cap
,
sband
->
vht_cap
.
cap
);
return
pos
-
buffer
;
}
...
...
@@ -1411,10 +1423,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
if
(
ieee80211_sdata_running
(
sdata
))
ieee80211_enable_keys
(
sdata
);
wake_up:
local
->
in_reconfig
=
false
;
barrier
();
wake_up:
/*
* Clear the WLAN_STA_BLOCK_BA flag so new aggregation
* sessions can be established after a resume.
...
...
@@ -1699,6 +1711,27 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
return
pos
;
}
u8
*
ieee80211_ie_build_vht_cap
(
u8
*
pos
,
struct
ieee80211_sta_vht_cap
*
vht_cap
,
u32
cap
)
{
__le32
tmp
;
*
pos
++
=
WLAN_EID_VHT_CAPABILITY
;
*
pos
++
=
sizeof
(
struct
ieee80211_vht_capabilities
);
memset
(
pos
,
0
,
sizeof
(
struct
ieee80211_vht_capabilities
));
/* capability flags */
tmp
=
cpu_to_le32
(
cap
);
memcpy
(
pos
,
&
tmp
,
sizeof
(
u32
));
pos
+=
sizeof
(
u32
);
/* VHT MCS set */
memcpy
(
pos
,
&
vht_cap
->
vht_mcs
,
sizeof
(
vht_cap
->
vht_mcs
));
pos
+=
sizeof
(
vht_cap
->
vht_mcs
);
return
pos
;
}
u8
*
ieee80211_ie_build_ht_oper
(
u8
*
pos
,
struct
ieee80211_sta_ht_cap
*
ht_cap
,
struct
ieee80211_channel
*
channel
,
enum
nl80211_channel_type
channel_type
,
...
...
@@ -1764,15 +1797,14 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper)
return
channel_type
;
}
int
ieee80211_add_srates_ie
(
struct
ieee80211_
vif
*
vif
,
int
ieee80211_add_srates_ie
(
struct
ieee80211_
sub_if_data
*
sdata
,
struct
sk_buff
*
skb
,
bool
need_basic
)
{
struct
ieee80211_sub_if_data
*
sdata
=
vif_to_sdata
(
vif
);
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_supported_band
*
sband
;
int
rate
;
u8
i
,
rates
,
*
pos
;
u32
basic_rates
=
vif
->
bss_conf
.
basic_rates
;
u32
basic_rates
=
sdata
->
vif
.
bss_conf
.
basic_rates
;
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
rates
=
sband
->
n_bitrates
;
...
...
@@ -1796,15 +1828,14 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif,
return
0
;
}
int
ieee80211_add_ext_srates_ie
(
struct
ieee80211_
vif
*
vif
,
int
ieee80211_add_ext_srates_ie
(
struct
ieee80211_
sub_if_data
*
sdata
,
struct
sk_buff
*
skb
,
bool
need_basic
)
{
struct
ieee80211_sub_if_data
*
sdata
=
vif_to_sdata
(
vif
);
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_supported_band
*
sband
;
int
rate
;
u8
i
,
exrates
,
*
pos
;
u32
basic_rates
=
vif
->
bss_conf
.
basic_rates
;
u32
basic_rates
=
sdata
->
vif
.
bss_conf
.
basic_rates
;
sband
=
local
->
hw
.
wiphy
->
bands
[
local
->
hw
.
conf
.
channel
->
band
];
exrates
=
sband
->
n_bitrates
;
...
...
net/wireless/Makefile
浏览文件 @
0af5491c
...
...
@@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o
obj-$(CONFIG_WEXT_PRIV)
+=
wext-priv.o
cfg80211-y
+=
core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o
cfg80211-y
+=
mlme.o ibss.o sme.o chan.o ethtool.o mesh.o
cfg80211-y
+=
mlme.o ibss.o sme.o chan.o ethtool.o mesh.o
ap.o
cfg80211-$(CONFIG_CFG80211_DEBUGFS)
+=
debugfs.o
cfg80211-$(CONFIG_CFG80211_WEXT)
+=
wext-compat.o wext-sme.o
cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB)
+=
regdb.o
...
...
net/wireless/ap.c
0 → 100644
浏览文件 @
0af5491c
#include <linux/ieee80211.h>
#include <linux/export.h>
#include <net/cfg80211.h>
#include "nl80211.h"
#include "core.h"
static
int
__cfg80211_stop_ap
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
ASSERT_WDEV_LOCK
(
wdev
);
if
(
!
rdev
->
ops
->
stop_ap
)
return
-
EOPNOTSUPP
;
if
(
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_P2P_GO
)
return
-
EOPNOTSUPP
;
if
(
!
wdev
->
beacon_interval
)
return
-
ENOENT
;
err
=
rdev
->
ops
->
stop_ap
(
&
rdev
->
wiphy
,
dev
);
if
(
!
err
)
{
wdev
->
beacon_interval
=
0
;
wdev
->
channel
=
NULL
;
}
return
err
;
}
int
cfg80211_stop_ap
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
)
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
wdev_lock
(
wdev
);
err
=
__cfg80211_stop_ap
(
rdev
,
dev
);
wdev_unlock
(
wdev
);
return
err
;
}
net/wireless/chan.c
浏览文件 @
0af5491c
...
...
@@ -82,13 +82,73 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,
int
freq
,
enum
nl80211_channel_type
chantype
)
{
struct
ieee80211_channel
*
chan
;
int
err
;
if
(
!
rdev
->
ops
->
set_monitor_channel
)
return
-
EOPNOTSUPP
;
if
(
!
cfg80211_has_monitors_only
(
rdev
))
return
-
EBUSY
;
chan
=
rdev_freq_to_chan
(
rdev
,
freq
,
chantype
);
if
(
!
chan
)
return
-
EINVAL
;
return
rdev
->
ops
->
set_monitor_channel
(
&
rdev
->
wiphy
,
chan
,
chantype
);
err
=
rdev
->
ops
->
set_monitor_channel
(
&
rdev
->
wiphy
,
chan
,
chantype
);
if
(
!
err
)
{
rdev
->
monitor_channel
=
chan
;
rdev
->
monitor_channel_type
=
chantype
;
}
return
err
;
}
void
cfg80211_get_chan_state
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
struct
ieee80211_channel
**
chan
,
enum
cfg80211_chan_mode
*
chanmode
)
{
*
chan
=
NULL
;
*
chanmode
=
CHAN_MODE_UNDEFINED
;
ASSERT_RDEV_LOCK
(
rdev
);
ASSERT_WDEV_LOCK
(
wdev
);
if
(
!
netif_running
(
wdev
->
netdev
))
return
;
switch
(
wdev
->
iftype
)
{
case
NL80211_IFTYPE_ADHOC
:
if
(
wdev
->
current_bss
)
{
*
chan
=
wdev
->
current_bss
->
pub
.
channel
;
*
chanmode
=
wdev
->
ibss_fixed
?
CHAN_MODE_SHARED
:
CHAN_MODE_EXCLUSIVE
;
return
;
}
case
NL80211_IFTYPE_STATION
:
case
NL80211_IFTYPE_P2P_CLIENT
:
if
(
wdev
->
current_bss
)
{
*
chan
=
wdev
->
current_bss
->
pub
.
channel
;
*
chanmode
=
CHAN_MODE_SHARED
;
return
;
}
break
;
case
NL80211_IFTYPE_AP
:
case
NL80211_IFTYPE_P2P_GO
:
case
NL80211_IFTYPE_MESH_POINT
:
*
chan
=
wdev
->
channel
;
*
chanmode
=
CHAN_MODE_SHARED
;
return
;
case
NL80211_IFTYPE_MONITOR
:
case
NL80211_IFTYPE_AP_VLAN
:
case
NL80211_IFTYPE_WDS
:
/* these interface types don't really have a channel */
return
;
case
NL80211_IFTYPE_UNSPECIFIED
:
case
NUM_NL80211_IFTYPES
:
WARN_ON
(
1
);
}
return
;
}
net/wireless/core.c
浏览文件 @
0af5491c
...
...
@@ -373,6 +373,14 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
if
(
WARN_ON
(
!
c
->
num_different_channels
))
return
-
EINVAL
;
/*
* Put a sane limit on maximum number of different
* channels to simplify channel accounting code.
*/
if
(
WARN_ON
(
c
->
num_different_channels
>
CFG80211_MAX_NUM_DIFFERENT_CHANNELS
))
return
-
EINVAL
;
if
(
WARN_ON
(
!
c
->
n_limits
))
return
-
EINVAL
;
...
...
@@ -421,9 +429,11 @@ int wiphy_register(struct wiphy *wiphy)
int
i
;
u16
ifmodes
=
wiphy
->
interface_modes
;
#ifdef CONFIG_PM
if
(
WARN_ON
((
wiphy
->
wowlan
.
flags
&
WIPHY_WOWLAN_GTK_REKEY_FAILURE
)
&&
!
(
wiphy
->
wowlan
.
flags
&
WIPHY_WOWLAN_SUPPORTS_GTK_REKEY
)))
return
-
EINVAL
;
#endif
if
(
WARN_ON
(
wiphy
->
ap_sme_capa
&&
!
(
wiphy
->
flags
&
WIPHY_FLAG_HAVE_AP_SME
)))
...
...
@@ -458,8 +468,14 @@ int wiphy_register(struct wiphy *wiphy)
continue
;
sband
->
band
=
band
;
if
(
WARN_ON
(
!
sband
->
n_channels
||
!
sband
->
n_bitrates
))
if
(
WARN_ON
(
!
sband
->
n_channels
))
return
-
EINVAL
;
/*
* on 60gHz band, there are no legacy rates, so
* n_bitrates is 0
*/
if
(
WARN_ON
(
band
!=
IEEE80211_BAND_60GHZ
&&
!
sband
->
n_bitrates
))
return
-
EINVAL
;
/*
...
...
@@ -500,12 +516,14 @@ int wiphy_register(struct wiphy *wiphy)
return
-
EINVAL
;
}
#ifdef CONFIG_PM
if
(
rdev
->
wiphy
.
wowlan
.
n_patterns
)
{
if
(
WARN_ON
(
!
rdev
->
wiphy
.
wowlan
.
pattern_min_len
||
rdev
->
wiphy
.
wowlan
.
pattern_min_len
>
rdev
->
wiphy
.
wowlan
.
pattern_max_len
))
return
-
EINVAL
;
}
#endif
/* check and set up bitrates */
ieee80211_set_bitrate_flags
(
wiphy
);
...
...
@@ -713,6 +731,61 @@ static struct device_type wiphy_type = {
.
name
=
"wlan"
,
};
static
struct
ieee80211_channel
*
cfg80211_get_any_chan
(
struct
cfg80211_registered_device
*
rdev
)
{
struct
ieee80211_supported_band
*
sband
;
int
i
;
for
(
i
=
0
;
i
<
IEEE80211_NUM_BANDS
;
i
++
)
{
sband
=
rdev
->
wiphy
.
bands
[
i
];
if
(
sband
&&
sband
->
n_channels
>
0
)
return
&
sband
->
channels
[
0
];
}
return
NULL
;
}
static
void
cfg80211_init_mon_chan
(
struct
cfg80211_registered_device
*
rdev
)
{
struct
ieee80211_channel
*
chan
;
chan
=
cfg80211_get_any_chan
(
rdev
);
if
(
WARN_ON
(
!
chan
))
return
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
WARN_ON
(
cfg80211_set_monitor_channel
(
rdev
,
chan
->
center_freq
,
NL80211_CHAN_NO_HT
));
mutex_unlock
(
&
rdev
->
devlist_mtx
);
}
void
cfg80211_update_iface_num
(
struct
cfg80211_registered_device
*
rdev
,
enum
nl80211_iftype
iftype
,
int
num
)
{
bool
has_monitors_only_old
=
cfg80211_has_monitors_only
(
rdev
);
bool
has_monitors_only_new
;
ASSERT_RTNL
();
rdev
->
num_running_ifaces
+=
num
;
if
(
iftype
==
NL80211_IFTYPE_MONITOR
)
rdev
->
num_running_monitor_ifaces
+=
num
;
has_monitors_only_new
=
cfg80211_has_monitors_only
(
rdev
);
if
(
has_monitors_only_new
!=
has_monitors_only_old
)
{
rdev
->
ops
->
set_monitor_enabled
(
&
rdev
->
wiphy
,
has_monitors_only_new
);
if
(
!
has_monitors_only_new
)
{
rdev
->
monitor_channel
=
NULL
;
rdev
->
monitor_channel_type
=
NL80211_CHAN_NO_HT
;
}
else
{
cfg80211_init_mon_chan
(
rdev
);
}
}
}
static
int
cfg80211_netdev_notifier_call
(
struct
notifier_block
*
nb
,
unsigned
long
state
,
void
*
ndev
)
...
...
@@ -806,12 +879,16 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
case
NL80211_IFTYPE_MESH_POINT
:
cfg80211_leave_mesh
(
rdev
,
dev
);
break
;
case
NL80211_IFTYPE_AP
:
cfg80211_stop_ap
(
rdev
,
dev
);
break
;
default:
break
;
}
wdev
->
beacon_interval
=
0
;
break
;
case
NETDEV_DOWN
:
cfg80211_update_iface_num
(
rdev
,
wdev
->
iftype
,
-
1
);
dev_hold
(
dev
);
queue_work
(
cfg80211_wq
,
&
wdev
->
cleanup_work
);
break
;
...
...
@@ -917,9 +994,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
return
notifier_from_errno
(
-
EOPNOTSUPP
);
if
(
rfkill_blocked
(
rdev
->
rfkill
))
return
notifier_from_errno
(
-
ERFKILL
);
mutex_lock
(
&
rdev
->
devlist_mtx
);
ret
=
cfg80211_can_add_interface
(
rdev
,
wdev
->
iftype
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
if
(
ret
)
return
notifier_from_errno
(
ret
);
cfg80211_update_iface_num
(
rdev
,
wdev
->
iftype
,
1
);
break
;
}
...
...
net/wireless/core.h
浏览文件 @
0af5491c
...
...
@@ -13,6 +13,7 @@
#include <linux/debugfs.h>
#include <linux/rfkill.h>
#include <linux/workqueue.h>
#include <linux/rtnetlink.h>
#include <net/genetlink.h>
#include <net/cfg80211.h>
#include "reg.h"
...
...
@@ -56,6 +57,13 @@ struct cfg80211_registered_device {
u32
ap_beacons_nlpid
;
/* protected by RTNL only */
int
num_running_ifaces
;
int
num_running_monitor_ifaces
;
struct
ieee80211_channel
*
monitor_channel
;
enum
nl80211_channel_type
monitor_channel_type
;
/* BSSes/scanning */
spinlock_t
bss_lock
;
struct
list_head
bss_list
;
...
...
@@ -197,6 +205,14 @@ static inline void wdev_unlock(struct wireless_dev *wdev)
#define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx)
#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx)
static
inline
bool
cfg80211_has_monitors_only
(
struct
cfg80211_registered_device
*
rdev
)
{
ASSERT_RTNL
();
return
rdev
->
num_running_ifaces
==
rdev
->
num_running_monitor_ifaces
&&
rdev
->
num_running_ifaces
>
0
;
}
enum
cfg80211_event_type
{
EVENT_CONNECT_RESULT
,
EVENT_ROAMED
,
...
...
@@ -241,6 +257,12 @@ struct cfg80211_cached_keys {
int
def
,
defmgmt
;
};
enum
cfg80211_chan_mode
{
CHAN_MODE_UNDEFINED
,
CHAN_MODE_SHARED
,
CHAN_MODE_EXCLUSIVE
,
};
/* free object */
extern
void
cfg80211_dev_free
(
struct
cfg80211_registered_device
*
rdev
);
...
...
@@ -289,6 +311,10 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
struct
wireless_dev
*
wdev
,
int
freq
,
enum
nl80211_channel_type
channel_type
);
/* AP */
int
cfg80211_stop_ap
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
);
/* MLME */
int
__cfg80211_mlme_auth
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
...
...
@@ -404,9 +430,20 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
u32
*
flags
,
struct
vif_params
*
params
);
void
cfg80211_process_rdev_events
(
struct
cfg80211_registered_device
*
rdev
);
int
cfg80211_can_change_interface
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
enum
nl80211_iftype
iftype
);
int
cfg80211_can_use_iftype_chan
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
enum
nl80211_iftype
iftype
,
struct
ieee80211_channel
*
chan
,
enum
cfg80211_chan_mode
chanmode
);
static
inline
int
cfg80211_can_change_interface
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
enum
nl80211_iftype
iftype
)
{
return
cfg80211_can_use_iftype_chan
(
rdev
,
wdev
,
iftype
,
NULL
,
CHAN_MODE_UNDEFINED
);
}
static
inline
int
cfg80211_can_add_interface
(
struct
cfg80211_registered_device
*
rdev
,
...
...
@@ -415,6 +452,22 @@ cfg80211_can_add_interface(struct cfg80211_registered_device *rdev,
return
cfg80211_can_change_interface
(
rdev
,
NULL
,
iftype
);
}
static
inline
int
cfg80211_can_use_chan
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
struct
ieee80211_channel
*
chan
,
enum
cfg80211_chan_mode
chanmode
)
{
return
cfg80211_can_use_iftype_chan
(
rdev
,
wdev
,
wdev
->
iftype
,
chan
,
chanmode
);
}
void
cfg80211_get_chan_state
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
struct
ieee80211_channel
**
chan
,
enum
cfg80211_chan_mode
*
chanmode
);
struct
ieee80211_channel
*
rdev_freq_to_chan
(
struct
cfg80211_registered_device
*
rdev
,
int
freq
,
enum
nl80211_channel_type
channel_type
);
...
...
@@ -428,6 +481,11 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
int
cfg80211_validate_beacon_int
(
struct
cfg80211_registered_device
*
rdev
,
u32
beacon_int
);
void
cfg80211_update_iface_num
(
struct
cfg80211_registered_device
*
rdev
,
enum
nl80211_iftype
iftype
,
int
num
);
#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
#else
...
...
net/wireless/ibss.c
浏览文件 @
0af5491c
...
...
@@ -113,10 +113,21 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
kfree
(
wdev
->
connect_keys
);
wdev
->
connect_keys
=
connkeys
;
wdev
->
ibss_fixed
=
params
->
channel_fixed
;
#ifdef CONFIG_CFG80211_WEXT
wdev
->
wext
.
ibss
.
channel
=
params
->
channel
;
#endif
wdev
->
sme_state
=
CFG80211_SME_CONNECTING
;
err
=
cfg80211_can_use_chan
(
rdev
,
wdev
,
params
->
channel
,
params
->
channel_fixed
?
CHAN_MODE_SHARED
:
CHAN_MODE_EXCLUSIVE
);
if
(
err
)
{
wdev
->
connect_keys
=
NULL
;
return
err
;
}
err
=
rdev
->
ops
->
join_ibss
(
&
rdev
->
wiphy
,
dev
,
params
);
if
(
err
)
{
wdev
->
connect_keys
=
NULL
;
...
...
net/wireless/mesh.c
浏览文件 @
0af5491c
...
...
@@ -155,10 +155,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
setup
->
channel_type
))
return
-
EINVAL
;
err
=
cfg80211_can_use_chan
(
rdev
,
wdev
,
setup
->
channel
,
CHAN_MODE_SHARED
);
if
(
err
)
return
err
;
err
=
rdev
->
ops
->
join_mesh
(
&
rdev
->
wiphy
,
dev
,
conf
,
setup
);
if
(
!
err
)
{
memcpy
(
wdev
->
ssid
,
setup
->
mesh_id
,
setup
->
mesh_id_len
);
wdev
->
mesh_id_len
=
setup
->
mesh_id_len
;
wdev
->
channel
=
setup
->
channel
;
}
return
err
;
...
...
@@ -172,9 +178,11 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
wdev
);
err
=
__cfg80211_join_mesh
(
rdev
,
dev
,
setup
,
conf
);
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
...
...
@@ -184,6 +192,7 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
enum
nl80211_channel_type
channel_type
)
{
struct
ieee80211_channel
*
channel
;
int
err
;
channel
=
rdev_freq_to_chan
(
rdev
,
freq
,
channel_type
);
if
(
!
channel
||
!
cfg80211_can_beacon_sec_chan
(
&
rdev
->
wiphy
,
...
...
@@ -205,9 +214,19 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev,
if
(
!
netif_running
(
wdev
->
netdev
))
return
-
ENETDOWN
;
return
rdev
->
ops
->
libertas_set_mesh_channel
(
&
rdev
->
wiphy
,
wdev
->
netdev
,
channel
);
err
=
cfg80211_can_use_chan
(
rdev
,
wdev
,
channel
,
CHAN_MODE_SHARED
);
if
(
err
)
return
err
;
err
=
rdev
->
ops
->
libertas_set_mesh_channel
(
&
rdev
->
wiphy
,
wdev
->
netdev
,
channel
);
if
(
!
err
)
wdev
->
channel
=
channel
;
return
err
;
}
if
(
wdev
->
mesh_id_len
)
...
...
@@ -249,8 +268,11 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
return
-
ENOTCONN
;
err
=
rdev
->
ops
->
leave_mesh
(
&
rdev
->
wiphy
,
dev
);
if
(
!
err
)
if
(
!
err
)
{
wdev
->
mesh_id_len
=
0
;
wdev
->
channel
=
NULL
;
}
return
err
;
}
...
...
net/wireless/mlme.c
浏览文件 @
0af5491c
...
...
@@ -302,8 +302,14 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
if
(
!
req
.
bss
)
return
-
ENOENT
;
err
=
cfg80211_can_use_chan
(
rdev
,
wdev
,
req
.
bss
->
channel
,
CHAN_MODE_SHARED
);
if
(
err
)
goto
out
;
err
=
rdev
->
ops
->
auth
(
&
rdev
->
wiphy
,
dev
,
&
req
);
out:
cfg80211_put_bss
(
req
.
bss
);
return
err
;
}
...
...
@@ -317,11 +323,13 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
{
int
err
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
dev
->
ieee80211_ptr
);
err
=
__cfg80211_mlme_auth
(
rdev
,
dev
,
chan
,
auth_type
,
bssid
,
ssid
,
ssid_len
,
ie
,
ie_len
,
key
,
key_len
,
key_idx
);
wdev_unlock
(
dev
->
ieee80211_ptr
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
...
...
@@ -397,8 +405,14 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
return
-
ENOENT
;
}
err
=
cfg80211_can_use_chan
(
rdev
,
wdev
,
req
.
bss
->
channel
,
CHAN_MODE_SHARED
);
if
(
err
)
goto
out
;
err
=
rdev
->
ops
->
assoc
(
&
rdev
->
wiphy
,
dev
,
&
req
);
out:
if
(
err
)
{
if
(
was_connected
)
wdev
->
sme_state
=
CFG80211_SME_CONNECTED
;
...
...
@@ -421,11 +435,13 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
wdev_lock
(
wdev
);
err
=
__cfg80211_mlme_assoc
(
rdev
,
dev
,
chan
,
bssid
,
prev_bssid
,
ssid
,
ssid_len
,
ie
,
ie_len
,
use_mfp
,
crypt
,
assoc_flags
,
ht_capa
,
ht_capa_mask
);
wdev_unlock
(
wdev
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
return
err
;
}
...
...
@@ -947,6 +963,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
if
(
WARN_ON
(
!
chan
))
goto
out
;
wdev
->
channel
=
chan
;
nl80211_ch_switch_notify
(
rdev
,
dev
,
freq
,
type
,
GFP_KERNEL
);
out:
wdev_unlock
(
wdev
);
...
...
net/wireless/nl80211.c
浏览文件 @
0af5491c
...
...
@@ -921,6 +921,15 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
dev
->
wiphy
.
bands
[
band
]
->
ht_cap
.
ampdu_density
)))
goto
nla_put_failure
;
/* add VHT info */
if
(
dev
->
wiphy
.
bands
[
band
]
->
vht_cap
.
vht_supported
&&
(
nla_put
(
msg
,
NL80211_BAND_ATTR_VHT_MCS_SET
,
sizeof
(
dev
->
wiphy
.
bands
[
band
]
->
vht_cap
.
vht_mcs
),
&
dev
->
wiphy
.
bands
[
band
]
->
vht_cap
.
vht_mcs
)
||
nla_put_u32
(
msg
,
NL80211_BAND_ATTR_VHT_CAPA
,
dev
->
wiphy
.
bands
[
band
]
->
vht_cap
.
cap
)))
goto
nla_put_failure
;
/* add frequencies */
nl_freqs
=
nla_nest_start
(
msg
,
NL80211_BAND_ATTR_FREQS
);
if
(
!
nl_freqs
)
...
...
@@ -1112,6 +1121,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
nla_nest_end
(
msg
,
nl_ifs
);
}
#ifdef CONFIG_PM
if
(
dev
->
wiphy
.
wowlan
.
flags
||
dev
->
wiphy
.
wowlan
.
n_patterns
)
{
struct
nlattr
*
nl_wowlan
;
...
...
@@ -1152,6 +1162,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
nla_nest_end
(
msg
,
nl_wowlan
);
}
#endif
if
(
nl80211_put_iftypes
(
msg
,
NL80211_ATTR_SOFTWARE_IFTYPES
,
dev
->
wiphy
.
software_iftypes
))
...
...
@@ -1678,16 +1689,11 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
(
cfg80211_rdev_list_generation
<<
2
)))
goto
nla_put_failure
;
if
(
rdev
->
ops
->
get_channel
)
{
struct
ieee80211_channel
*
chan
;
enum
nl80211_channel_type
channel_type
;
chan
=
rdev
->
ops
->
get_channel
(
&
rdev
->
wiphy
,
&
channel_type
);
if
(
chan
&&
(
nla_put_u32
(
msg
,
NL80211_ATTR_WIPHY_FREQ
,
chan
->
center_freq
)
||
nla_put_u32
(
msg
,
NL80211_ATTR_WIPHY_CHANNEL_TYPE
,
channel_type
)))
if
(
rdev
->
monitor_channel
)
{
if
(
nla_put_u32
(
msg
,
NL80211_ATTR_WIPHY_FREQ
,
rdev
->
monitor_channel
->
center_freq
)
||
nla_put_u32
(
msg
,
NL80211_ATTR_WIPHY_CHANNEL_TYPE
,
rdev
->
monitor_channel_type
))
goto
nla_put_failure
;
}
...
...
@@ -2472,11 +2478,20 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
params
.
channel_type
))
return
-
EINVAL
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
err
=
cfg80211_can_use_chan
(
rdev
,
wdev
,
params
.
channel
,
CHAN_MODE_SHARED
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
if
(
err
)
return
err
;
err
=
rdev
->
ops
->
start_ap
(
&
rdev
->
wiphy
,
dev
,
&
params
);
if
(
!
err
)
{
wdev
->
preset_chan
=
params
.
channel
;
wdev
->
preset_chantype
=
params
.
channel_type
;
wdev
->
beacon_interval
=
params
.
beacon_interval
;
wdev
->
channel
=
params
.
channel
;
}
return
err
;
}
...
...
@@ -2510,23 +2525,8 @@ static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
{
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
struct
net_device
*
dev
=
info
->
user_ptr
[
1
];
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
int
err
;
if
(
!
rdev
->
ops
->
stop_ap
)
return
-
EOPNOTSUPP
;
if
(
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_P2P_GO
)
return
-
EOPNOTSUPP
;
if
(
!
wdev
->
beacon_interval
)
return
-
ENOENT
;
err
=
rdev
->
ops
->
stop_ap
(
&
rdev
->
wiphy
,
dev
);
if
(
!
err
)
wdev
->
beacon_interval
=
0
;
return
err
;
return
cfg80211_stop_ap
(
rdev
,
dev
);
}
static
const
struct
nla_policy
sta_flags_policy
[
NL80211_STA_FLAG_MAX
+
1
]
=
{
...
...
@@ -2618,7 +2618,8 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
int
attr
)
{
struct
nlattr
*
rate
;
u16
bitrate
;
u32
bitrate
;
u16
bitrate_compat
;
rate
=
nla_nest_start
(
msg
,
attr
);
if
(
!
rate
)
...
...
@@ -2626,8 +2627,12 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
/* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
bitrate
=
cfg80211_calculate_bitrate
(
info
);
/* report 16-bit bitrate only if we can */
bitrate_compat
=
bitrate
<
(
1UL
<<
16
)
?
bitrate
:
0
;
if
((
bitrate
>
0
&&
nla_put_u16
(
msg
,
NL80211_RATE_INFO_BITRATE
,
bitrate
))
||
nla_put_u32
(
msg
,
NL80211_RATE_INFO_BITRATE32
,
bitrate
))
||
(
bitrate_compat
>
0
&&
nla_put_u16
(
msg
,
NL80211_RATE_INFO_BITRATE
,
bitrate_compat
))
||
((
info
->
flags
&
RATE_INFO_FLAGS_MCS
)
&&
nla_put_u8
(
msg
,
NL80211_RATE_INFO_MCS
,
info
->
mcs
))
||
((
info
->
flags
&
RATE_INFO_FLAGS_40_MHZ_WIDTH
)
&&
...
...
@@ -6276,6 +6281,7 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
return
cfg80211_leave_mesh
(
rdev
,
dev
);
}
#ifdef CONFIG_PM
static
int
nl80211_get_wowlan
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
{
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
...
...
@@ -6504,6 +6510,7 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
kfree
(
new_triggers
.
patterns
);
return
err
;
}
#endif
static
int
nl80211_set_rekey_data
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
{
...
...
@@ -7158,6 +7165,7 @@ static struct genl_ops nl80211_ops[] = {
.
internal_flags
=
NL80211_FLAG_NEED_NETDEV_UP
|
NL80211_FLAG_NEED_RTNL
,
},
#ifdef CONFIG_PM
{
.
cmd
=
NL80211_CMD_GET_WOWLAN
,
.
doit
=
nl80211_get_wowlan
,
...
...
@@ -7174,6 +7182,7 @@ static struct genl_ops nl80211_ops[] = {
.
internal_flags
=
NL80211_FLAG_NEED_WIPHY
|
NL80211_FLAG_NEED_RTNL
,
},
#endif
{
.
cmd
=
NL80211_CMD_SET_REKEY_OFFLOAD
,
.
doit
=
nl80211_set_rekey_data
,
...
...
net/wireless/reg.c
浏览文件 @
0af5491c
...
...
@@ -129,7 +129,7 @@ static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work);
/* We keep a static world regulatory domain in case of the absence of CRDA */
static
const
struct
ieee80211_regdomain
world_regdom
=
{
.
n_reg_rules
=
5
,
.
n_reg_rules
=
6
,
.
alpha2
=
"00"
,
.
reg_rules
=
{
/* IEEE 802.11b/g, channels 1..11 */
...
...
@@ -156,6 +156,9 @@ static const struct ieee80211_regdomain world_regdom = {
REG_RULE
(
5745
-
10
,
5825
+
10
,
40
,
6
,
20
,
NL80211_RRF_PASSIVE_SCAN
|
NL80211_RRF_NO_IBSS
),
/* IEEE 802.11ad (60gHz), channels 1..3 */
REG_RULE
(
56160
+
2160
*
1
-
1080
,
56160
+
2160
*
3
+
1080
,
2160
,
0
,
0
,
0
),
}
};
...
...
net/wireless/util.c
浏览文件 @
0af5491c
...
...
@@ -35,19 +35,29 @@ int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
{
/* see 802.11 17.3.8.3.2 and Annex J
* there are overlapping channel numbers in 5GHz and 2GHz bands */
if
(
band
==
IEEE80211_BAND_5GHZ
)
{
if
(
chan
>=
182
&&
chan
<=
196
)
return
4000
+
chan
*
5
;
else
return
5000
+
chan
*
5
;
}
else
{
/* IEEE80211_BAND_2GHZ */
if
(
chan
<=
0
)
return
0
;
/* not supported */
switch
(
band
)
{
case
IEEE80211_BAND_2GHZ
:
if
(
chan
==
14
)
return
2484
;
else
if
(
chan
<
14
)
return
2407
+
chan
*
5
;
break
;
case
IEEE80211_BAND_5GHZ
:
if
(
chan
>=
182
&&
chan
<=
196
)
return
4000
+
chan
*
5
;
else
return
0
;
/* not supported */
return
5000
+
chan
*
5
;
break
;
case
IEEE80211_BAND_60GHZ
:
if
(
chan
<
5
)
return
56160
+
chan
*
2160
;
break
;
default:
;
}
return
0
;
/* not supported */
}
EXPORT_SYMBOL
(
ieee80211_channel_to_frequency
);
...
...
@@ -60,8 +70,12 @@ int ieee80211_frequency_to_channel(int freq)
return
(
freq
-
2407
)
/
5
;
else
if
(
freq
>=
4910
&&
freq
<=
4980
)
return
(
freq
-
4000
)
/
5
;
else
else
if
(
freq
<=
45000
)
/* DMG band lower limit */
return
(
freq
-
5000
)
/
5
;
else
if
(
freq
>=
58320
&&
freq
<=
64800
)
return
(
freq
-
56160
)
/
2160
;
else
return
0
;
}
EXPORT_SYMBOL
(
ieee80211_frequency_to_channel
);
...
...
@@ -137,6 +151,11 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
}
WARN_ON
(
want
!=
0
&&
want
!=
3
&&
want
!=
6
);
break
;
case
IEEE80211_BAND_60GHZ
:
/* check for mandatory HT MCS 1..4 */
WARN_ON
(
!
sband
->
ht_cap
.
ht_supported
);
WARN_ON
((
sband
->
ht_cap
.
mcs
.
rx_mask
[
0
]
&
0x1e
)
!=
0x1e
);
break
;
case
IEEE80211_NUM_BANDS
:
WARN_ON
(
1
);
break
;
...
...
@@ -805,8 +824,10 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
return
-
EBUSY
;
if
(
ntype
!=
otype
&&
netif_running
(
dev
))
{
mutex_lock
(
&
rdev
->
devlist_mtx
);
err
=
cfg80211_can_change_interface
(
rdev
,
dev
->
ieee80211_ptr
,
ntype
);
mutex_unlock
(
&
rdev
->
devlist_mtx
);
if
(
err
)
return
err
;
...
...
@@ -814,6 +835,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
dev
->
ieee80211_ptr
->
mesh_id_up_len
=
0
;
switch
(
otype
)
{
case
NL80211_IFTYPE_AP
:
cfg80211_stop_ap
(
rdev
,
dev
);
break
;
case
NL80211_IFTYPE_ADHOC
:
cfg80211_leave_ibss
(
rdev
,
dev
,
false
);
break
;
...
...
@@ -868,15 +892,69 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
}
}
if
(
!
err
&&
ntype
!=
otype
&&
netif_running
(
dev
))
{
cfg80211_update_iface_num
(
rdev
,
ntype
,
1
);
cfg80211_update_iface_num
(
rdev
,
otype
,
-
1
);
}
return
err
;
}
u16
cfg80211_calculate_bitrate
(
struct
rate_info
*
rate
)
static
u32
cfg80211_calculate_bitrate_60g
(
struct
rate_info
*
rate
)
{
static
const
u32
__mcs2bitrate
[]
=
{
/* control PHY */
[
0
]
=
275
,
/* SC PHY */
[
1
]
=
3850
,
[
2
]
=
7700
,
[
3
]
=
9625
,
[
4
]
=
11550
,
[
5
]
=
12512
,
/* 1251.25 mbps */
[
6
]
=
15400
,
[
7
]
=
19250
,
[
8
]
=
23100
,
[
9
]
=
25025
,
[
10
]
=
30800
,
[
11
]
=
38500
,
[
12
]
=
46200
,
/* OFDM PHY */
[
13
]
=
6930
,
[
14
]
=
8662
,
/* 866.25 mbps */
[
15
]
=
13860
,
[
16
]
=
17325
,
[
17
]
=
20790
,
[
18
]
=
27720
,
[
19
]
=
34650
,
[
20
]
=
41580
,
[
21
]
=
45045
,
[
22
]
=
51975
,
[
23
]
=
62370
,
[
24
]
=
67568
,
/* 6756.75 mbps */
/* LP-SC PHY */
[
25
]
=
6260
,
[
26
]
=
8340
,
[
27
]
=
11120
,
[
28
]
=
12510
,
[
29
]
=
16680
,
[
30
]
=
22240
,
[
31
]
=
25030
,
};
if
(
WARN_ON_ONCE
(
rate
->
mcs
>=
ARRAY_SIZE
(
__mcs2bitrate
)))
return
0
;
return
__mcs2bitrate
[
rate
->
mcs
];
}
u32
cfg80211_calculate_bitrate
(
struct
rate_info
*
rate
)
{
int
modulation
,
streams
,
bitrate
;
if
(
!
(
rate
->
flags
&
RATE_INFO_FLAGS_MCS
))
return
rate
->
legacy
;
if
(
rate
->
flags
&
RATE_INFO_FLAGS_60G
)
return
cfg80211_calculate_bitrate_60g
(
rate
);
/* the formula below does only work for MCS values smaller than 32 */
if
(
WARN_ON_ONCE
(
rate
->
mcs
>=
32
))
...
...
@@ -930,27 +1008,48 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
return
res
;
}
int
cfg80211_can_change_interface
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
enum
nl80211_iftype
iftype
)
int
cfg80211_can_use_iftype_chan
(
struct
cfg80211_registered_device
*
rdev
,
struct
wireless_dev
*
wdev
,
enum
nl80211_iftype
iftype
,
struct
ieee80211_channel
*
chan
,
enum
cfg80211_chan_mode
chanmode
)
{
struct
wireless_dev
*
wdev_iter
;
u32
used_iftypes
=
BIT
(
iftype
);
int
num
[
NUM_NL80211_IFTYPES
];
struct
ieee80211_channel
*
used_channels
[
CFG80211_MAX_NUM_DIFFERENT_CHANNELS
];
struct
ieee80211_channel
*
ch
;
enum
cfg80211_chan_mode
chmode
;
int
num_different_channels
=
0
;
int
total
=
1
;
int
i
,
j
;
ASSERT_RTNL
();
lockdep_assert_held
(
&
rdev
->
devlist_mtx
);
/* Always allow software iftypes */
if
(
rdev
->
wiphy
.
software_iftypes
&
BIT
(
iftype
))
return
0
;
memset
(
num
,
0
,
sizeof
(
num
));
memset
(
used_channels
,
0
,
sizeof
(
used_channels
));
num
[
iftype
]
=
1
;
mutex_lock
(
&
rdev
->
devlist_mtx
);
switch
(
chanmode
)
{
case
CHAN_MODE_UNDEFINED
:
break
;
case
CHAN_MODE_SHARED
:
WARN_ON
(
!
chan
);
used_channels
[
0
]
=
chan
;
num_different_channels
++
;
break
;
case
CHAN_MODE_EXCLUSIVE
:
num_different_channels
++
;
break
;
}
list_for_each_entry
(
wdev_iter
,
&
rdev
->
netdev_list
,
list
)
{
if
(
wdev_iter
==
wdev
)
continue
;
...
...
@@ -960,11 +1059,33 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
if
(
rdev
->
wiphy
.
software_iftypes
&
BIT
(
wdev_iter
->
iftype
))
continue
;
cfg80211_get_chan_state
(
rdev
,
wdev_iter
,
&
ch
,
&
chmode
);
switch
(
chmode
)
{
case
CHAN_MODE_UNDEFINED
:
break
;
case
CHAN_MODE_SHARED
:
for
(
i
=
0
;
i
<
CFG80211_MAX_NUM_DIFFERENT_CHANNELS
;
i
++
)
if
(
!
used_channels
[
i
]
||
used_channels
[
i
]
==
ch
)
break
;
if
(
i
==
CFG80211_MAX_NUM_DIFFERENT_CHANNELS
)
return
-
EBUSY
;
if
(
used_channels
[
i
]
==
NULL
)
{
used_channels
[
i
]
=
ch
;
num_different_channels
++
;
}
break
;
case
CHAN_MODE_EXCLUSIVE
:
num_different_channels
++
;
break
;
}
num
[
wdev_iter
->
iftype
]
++
;
total
++
;
used_iftypes
|=
BIT
(
wdev_iter
->
iftype
);
}
mutex_unlock
(
&
rdev
->
devlist_mtx
);
if
(
total
==
1
)
return
0
;
...
...
@@ -976,12 +1097,15 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
c
=
&
rdev
->
wiphy
.
iface_combinations
[
i
];
if
(
total
>
c
->
max_interfaces
)
continue
;
if
(
num_different_channels
>
c
->
num_different_channels
)
continue
;
limits
=
kmemdup
(
c
->
limits
,
sizeof
(
limits
[
0
])
*
c
->
n_limits
,
GFP_KERNEL
);
if
(
!
limits
)
return
-
ENOMEM
;
if
(
total
>
c
->
max_interfaces
)
goto
cont
;
for
(
iftype
=
0
;
iftype
<
NUM_NL80211_IFTYPES
;
iftype
++
)
{
if
(
rdev
->
wiphy
.
software_iftypes
&
BIT
(
iftype
))
...
...
net/wireless/wext-compat.c
浏览文件 @
0af5491c
...
...
@@ -827,8 +827,6 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
{
struct
wireless_dev
*
wdev
=
dev
->
ieee80211_ptr
;
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wdev
->
wiphy
);
struct
ieee80211_channel
*
chan
;
enum
nl80211_channel_type
channel_type
;
switch
(
wdev
->
iftype
)
{
case
NL80211_IFTYPE_STATION
:
...
...
@@ -836,13 +834,10 @@ static int cfg80211_wext_giwfreq(struct net_device *dev,
case
NL80211_IFTYPE_ADHOC
:
return
cfg80211_ibss_wext_giwfreq
(
dev
,
info
,
freq
,
extra
);
case
NL80211_IFTYPE_MONITOR
:
if
(
!
rdev
->
ops
->
get
_channel
)
if
(
!
rdev
->
monitor
_channel
)
return
-
EINVAL
;
chan
=
rdev
->
ops
->
get_channel
(
wdev
->
wiphy
,
&
channel_type
);
if
(
!
chan
)
return
-
EINVAL
;
freq
->
m
=
chan
->
center_freq
;
freq
->
m
=
rdev
->
monitor_channel
->
center_freq
;
freq
->
e
=
6
;
return
0
;
default:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录