Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
55d1cad2
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
55d1cad2
编写于
1月 03, 2014
作者:
J
John W. Linville
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
上级
39731b78
32db6b54
变更
28
隐藏空白更改
内联
并排
Showing
28 changed file
with
687 addition
and
90 deletion
+687
-90
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+1
-1
drivers/net/wireless/mwifiex/main.c
drivers/net/wireless/mwifiex/main.c
+1
-1
include/net/cfg80211.h
include/net/cfg80211.h
+113
-5
include/net/mac80211.h
include/net/mac80211.h
+47
-0
include/uapi/linux/nl80211.h
include/uapi/linux/nl80211.h
+17
-0
net/mac80211/aes_cmac.c
net/mac80211/aes_cmac.c
+1
-1
net/mac80211/aes_cmac.h
net/mac80211/aes_cmac.h
+1
-1
net/mac80211/cfg.c
net/mac80211/cfg.c
+48
-6
net/mac80211/chan.c
net/mac80211/chan.c
+34
-33
net/mac80211/ibss.c
net/mac80211/ibss.c
+7
-0
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+8
-3
net/mac80211/iface.c
net/mac80211/iface.c
+6
-2
net/mac80211/mlme.c
net/mac80211/mlme.c
+20
-5
net/mac80211/rc80211_minstrel.c
net/mac80211/rc80211_minstrel.c
+4
-4
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rc80211_minstrel_ht.c
+1
-1
net/mac80211/tkip.c
net/mac80211/tkip.c
+1
-1
net/mac80211/trace.h
net/mac80211/trace.h
+1
-1
net/mac80211/tx.c
net/mac80211/tx.c
+2
-2
net/mac80211/util.c
net/mac80211/util.c
+148
-2
net/mac80211/wme.c
net/mac80211/wme.c
+6
-1
net/wireless/ap.c
net/wireless/ap.c
+1
-0
net/wireless/ibss.c
net/wireless/ibss.c
+2
-0
net/wireless/mesh.c
net/wireless/mesh.c
+1
-0
net/wireless/nl80211.c
net/wireless/nl80211.c
+141
-19
net/wireless/rdev-ops.h
net/wireless/rdev-ops.h
+15
-0
net/wireless/sme.c
net/wireless/sme.c
+2
-0
net/wireless/trace.h
net/wireless/trace.h
+40
-0
net/wireless/util.c
net/wireless/util.c
+18
-1
未找到文件。
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
浏览文件 @
55d1cad2
...
...
@@ -1873,7 +1873,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
brcmf_dbg
(
DATA
,
"tx proto=0x%X
\n
"
,
ntohs
(
eh
->
h_proto
));
/* determine the priority */
if
(
!
skb
->
priority
)
skb
->
priority
=
cfg80211_classify8021d
(
skb
);
skb
->
priority
=
cfg80211_classify8021d
(
skb
,
NULL
);
drvr
->
tx_multicast
+=
!!
multicast
;
if
(
pae
)
...
...
drivers/net/wireless/mwifiex/main.c
浏览文件 @
55d1cad2
...
...
@@ -749,7 +749,7 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
static
u16
mwifiex_netdev_select_wmm_queue
(
struct
net_device
*
dev
,
struct
sk_buff
*
skb
)
{
skb
->
priority
=
cfg80211_classify8021d
(
skb
);
skb
->
priority
=
cfg80211_classify8021d
(
skb
,
NULL
);
return
mwifiex_1d_to_wmm_queue
[
skb
->
priority
];
}
...
...
include/net/cfg80211.h
浏览文件 @
55d1cad2
...
...
@@ -1971,6 +1971,50 @@ struct cfg80211_mgmt_tx_params {
bool
dont_wait_for_ack
;
};
/**
* struct cfg80211_dscp_exception - DSCP exception
*
* @dscp: DSCP value that does not adhere to the user priority range definition
* @up: user priority value to which the corresponding DSCP value belongs
*/
struct
cfg80211_dscp_exception
{
u8
dscp
;
u8
up
;
};
/**
* struct cfg80211_dscp_range - DSCP range definition for user priority
*
* @low: lowest DSCP value of this user priority range, inclusive
* @high: highest DSCP value of this user priority range, inclusive
*/
struct
cfg80211_dscp_range
{
u8
low
;
u8
high
;
};
/* QoS Map Set element length defined in IEEE Std 802.11-2012, 8.4.2.97 */
#define IEEE80211_QOS_MAP_MAX_EX 21
#define IEEE80211_QOS_MAP_LEN_MIN 16
#define IEEE80211_QOS_MAP_LEN_MAX \
(IEEE80211_QOS_MAP_LEN_MIN + 2 * IEEE80211_QOS_MAP_MAX_EX)
/**
* struct cfg80211_qos_map - QoS Map Information
*
* This struct defines the Interworking QoS map setting for DSCP values
*
* @num_des: number of DSCP exceptions (0..21)
* @dscp_exception: optionally up to maximum of 21 DSCP exceptions from
* the user priority DSCP range definition
* @up: DSCP range definition for a particular user priority
*/
struct
cfg80211_qos_map
{
u8
num_des
;
struct
cfg80211_dscp_exception
dscp_exception
[
IEEE80211_QOS_MAP_MAX_EX
];
struct
cfg80211_dscp_range
up
[
8
];
};
/**
* struct cfg80211_ops - backend description for wireless configuration
*
...
...
@@ -2213,6 +2257,8 @@ struct cfg80211_mgmt_tx_params {
* @set_coalesce: Set coalesce parameters.
*
* @channel_switch: initiate channel-switch procedure (with CSA)
*
* @set_qos_map: Set QoS mapping information to the driver
*/
struct
cfg80211_ops
{
int
(
*
suspend
)(
struct
wiphy
*
wiphy
,
struct
cfg80211_wowlan
*
wow
);
...
...
@@ -2454,6 +2500,9 @@ struct cfg80211_ops {
int
(
*
channel_switch
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_csa_settings
*
params
);
int
(
*
set_qos_map
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_qos_map
*
qos_map
);
};
/*
...
...
@@ -2824,6 +2873,8 @@ struct wiphy_vendor_command {
*
* @vendor_commands: array of vendor commands supported by the hardware
* @n_vendor_commands: number of vendor commands
* @vendor_events: array of vendor events supported by the hardware
* @n_vendor_events: number of vendor events
*/
struct
wiphy
{
/* assign these fields before you register the wiphy */
...
...
@@ -2936,7 +2987,8 @@ struct wiphy {
const
struct
wiphy_coalesce_support
*
coalesce
;
const
struct
wiphy_vendor_command
*
vendor_commands
;
int
n_vendor_commands
;
const
struct
nl80211_vendor_cmd_info
*
vendor_events
;
int
n_vendor_commands
,
n_vendor_events
;
char
priv
[
0
]
__aligned
(
NETDEV_ALIGN
);
};
...
...
@@ -3429,9 +3481,11 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
/**
* cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
* @skb: the data frame
* @qos_map: Interworking QoS mapping or %NULL if not in use
* Return: The 802.1p/1d tag.
*/
unsigned
int
cfg80211_classify8021d
(
struct
sk_buff
*
skb
);
unsigned
int
cfg80211_classify8021d
(
struct
sk_buff
*
skb
,
struct
cfg80211_qos_map
*
qos_map
);
/**
* cfg80211_find_ie - find information element in data
...
...
@@ -3907,6 +3961,14 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
enum
nl80211_attrs
attr
,
int
approxlen
);
struct
sk_buff
*
__cfg80211_alloc_event_skb
(
struct
wiphy
*
wiphy
,
enum
nl80211_commands
cmd
,
enum
nl80211_attrs
attr
,
int
vendor_event_idx
,
int
approxlen
,
gfp_t
gfp
);
void
__cfg80211_send_event_skb
(
struct
sk_buff
*
skb
,
gfp_t
gfp
);
/**
* cfg80211_vendor_cmd_alloc_reply_skb - allocate vendor command reply
* @wiphy: the wiphy
...
...
@@ -3951,6 +4013,44 @@ cfg80211_vendor_cmd_alloc_reply_skb(struct wiphy *wiphy, int approxlen)
*/
int
cfg80211_vendor_cmd_reply
(
struct
sk_buff
*
skb
);
/**
* cfg80211_vendor_event_alloc - allocate vendor-specific event skb
* @wiphy: the wiphy
* @event_idx: index of the vendor event in the wiphy's vendor_events
* @approxlen: an upper bound of the length of the data that will
* be put into the skb
* @gfp: allocation flags
*
* This function allocates and pre-fills an skb for an event on the
* vendor-specific multicast group.
*
* When done filling the skb, call cfg80211_vendor_event() with the
* skb to send the event.
*
* Return: An allocated and pre-filled skb. %NULL if any errors happen.
*/
static
inline
struct
sk_buff
*
cfg80211_vendor_event_alloc
(
struct
wiphy
*
wiphy
,
int
approxlen
,
int
event_idx
,
gfp_t
gfp
)
{
return
__cfg80211_alloc_event_skb
(
wiphy
,
NL80211_CMD_VENDOR
,
NL80211_ATTR_VENDOR_DATA
,
event_idx
,
approxlen
,
gfp
);
}
/**
* cfg80211_vendor_event - send the event
* @skb: The skb, must have been allocated with cfg80211_vendor_event_alloc()
* @gfp: allocation flags
*
* This function sends the given @skb, which must have been allocated
* by cfg80211_vendor_event_alloc(), as an event. It always consumes it.
*/
static
inline
void
cfg80211_vendor_event
(
struct
sk_buff
*
skb
,
gfp_t
gfp
)
{
__cfg80211_send_event_skb
(
skb
,
gfp
);
}
#ifdef CONFIG_NL80211_TESTMODE
/**
* DOC: Test mode
...
...
@@ -4031,8 +4131,13 @@ static inline int cfg80211_testmode_reply(struct sk_buff *skb)
*
* Return: An allocated and pre-filled skb. %NULL if any errors happen.
*/
struct
sk_buff
*
cfg80211_testmode_alloc_event_skb
(
struct
wiphy
*
wiphy
,
int
approxlen
,
gfp_t
gfp
);
static
inline
struct
sk_buff
*
cfg80211_testmode_alloc_event_skb
(
struct
wiphy
*
wiphy
,
int
approxlen
,
gfp_t
gfp
)
{
return
__cfg80211_alloc_event_skb
(
wiphy
,
NL80211_CMD_TESTMODE
,
NL80211_ATTR_TESTDATA
,
-
1
,
approxlen
,
gfp
);
}
/**
* cfg80211_testmode_event - send the event
...
...
@@ -4044,7 +4149,10 @@ struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
* by cfg80211_testmode_alloc_event_skb(), as an event. It always
* consumes it.
*/
void
cfg80211_testmode_event
(
struct
sk_buff
*
skb
,
gfp_t
gfp
);
static
inline
void
cfg80211_testmode_event
(
struct
sk_buff
*
skb
,
gfp_t
gfp
)
{
__cfg80211_send_event_skb
(
skb
,
gfp
);
}
#define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd),
#define CFG80211_TESTMODE_DUMP(cmd) .testmode_dump = (cmd),
...
...
include/net/mac80211.h
浏览文件 @
55d1cad2
...
...
@@ -4652,4 +4652,51 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
struct
ieee80211_vif
*
vif
,
struct
sk_buff
*
skb
,
int
band
,
struct
ieee80211_sta
**
sta
);
/**
* struct ieee80211_noa_data - holds temporary data for tracking P2P NoA state
*
* @next_tsf: TSF timestamp of the next absent state change
* @has_next_tsf: next absent state change event pending
*
* @absent: descriptor bitmask, set if GO is currently absent
*
* private:
*
* @count: count fields from the NoA descriptors
* @desc: adjusted data from the NoA
*/
struct
ieee80211_noa_data
{
u32
next_tsf
;
bool
has_next_tsf
;
u8
absent
;
u8
count
[
IEEE80211_P2P_NOA_DESC_MAX
];
struct
{
u32
start
;
u32
duration
;
u32
interval
;
}
desc
[
IEEE80211_P2P_NOA_DESC_MAX
];
};
/**
* ieee80211_parse_p2p_noa - initialize NoA tracking data from P2P IE
*
* @attr: P2P NoA IE
* @data: NoA tracking data
* @tsf: current TSF timestamp
*
* Return: number of successfully parsed descriptors
*/
int
ieee80211_parse_p2p_noa
(
const
struct
ieee80211_p2p_noa_attr
*
attr
,
struct
ieee80211_noa_data
*
data
,
u32
tsf
);
/**
* ieee80211_update_p2p_noa - get next pending P2P GO absent state change
*
* @data: NoA tracking data
* @tsf: current TSF timestamp
*/
void
ieee80211_update_p2p_noa
(
struct
ieee80211_noa_data
*
data
,
u32
tsf
);
#endif
/* MAC80211_H */
include/uapi/linux/nl80211.h
浏览文件 @
55d1cad2
...
...
@@ -702,6 +702,12 @@
* (&struct nl80211_vendor_cmd_info) of the supported vendor commands.
* This may also be sent as an event with the same attributes.
*
* @NL80211_CMD_SET_QOS_MAP: Set Interworking QoS mapping for IP DSCP values.
* The QoS mapping information is included in %NL80211_ATTR_QOS_MAP. If
* that attribute is not included, QoS mapping is disabled. Since this
* QoS mapping is relevant for IP packets, it is only valid during an
* association. This is cleared on disassociation and AP restart.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
...
...
@@ -871,6 +877,8 @@ enum nl80211_commands {
NL80211_CMD_VENDOR
,
NL80211_CMD_SET_QOS_MAP
,
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
...
...
@@ -1540,6 +1548,12 @@ enum nl80211_commands {
* @NL80211_ATTR_VENDOR_SUBCMD: vendor sub-command
* @NL80211_ATTR_VENDOR_DATA: data for the vendor command, if any; this
* attribute is also used for vendor command feature advertisement
* @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy
* info, containing a nested array of possible events
*
* @NL80211_ATTR_QOS_MAP: IP DSCP mapping for Interworking QoS mapping. This
* data is in the format defined for the payload of the QoS Map Set element
* in IEEE Std 802.11-2012, 8.4.2.97.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
...
...
@@ -1865,6 +1879,9 @@ enum nl80211_attrs {
NL80211_ATTR_VENDOR_ID
,
NL80211_ATTR_VENDOR_SUBCMD
,
NL80211_ATTR_VENDOR_DATA
,
NL80211_ATTR_VENDOR_EVENTS
,
NL80211_ATTR_QOS_MAP
,
/* add attributes here, update the policy in nl80211.c */
...
...
net/mac80211/aes_cmac.c
浏览文件 @
55d1cad2
...
...
@@ -111,7 +111,7 @@ void ieee80211_aes_cmac(struct crypto_cipher *tfm, const u8 *aad,
}
struct
crypto_cipher
*
ieee80211_aes_cmac_key_setup
(
const
u8
key
[])
struct
crypto_cipher
*
ieee80211_aes_cmac_key_setup
(
const
u8
key
[])
{
struct
crypto_cipher
*
tfm
;
...
...
net/mac80211/aes_cmac.h
浏览文件 @
55d1cad2
...
...
@@ -11,7 +11,7 @@
#include <linux/crypto.h>
struct
crypto_cipher
*
ieee80211_aes_cmac_key_setup
(
const
u8
key
[]);
struct
crypto_cipher
*
ieee80211_aes_cmac_key_setup
(
const
u8
key
[]);
void
ieee80211_aes_cmac
(
struct
crypto_cipher
*
tfm
,
const
u8
*
aad
,
const
u8
*
data
,
size_t
data_len
,
u8
*
mic
);
void
ieee80211_aes_cmac_key_free
(
struct
crypto_cipher
*
tfm
);
...
...
net/mac80211/cfg.c
浏览文件 @
55d1cad2
...
...
@@ -828,6 +828,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
if
(
cfg80211_chandef_identical
(
&
local
->
monitor_chandef
,
chandef
))
return
0
;
mutex_lock
(
&
local
->
mtx
);
mutex_lock
(
&
local
->
iflist_mtx
);
if
(
local
->
use_chanctx
)
{
sdata
=
rcu_dereference_protected
(
...
...
@@ -846,6 +847,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
if
(
ret
==
0
)
local
->
monitor_chandef
=
*
chandef
;
mutex_unlock
(
&
local
->
iflist_mtx
);
mutex_unlock
(
&
local
->
mtx
);
return
ret
;
}
...
...
@@ -951,6 +953,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
struct
cfg80211_ap_settings
*
params
)
{
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
beacon_data
*
old
;
struct
ieee80211_sub_if_data
*
vlan
;
u32
changed
=
BSS_CHANGED_BEACON_INT
|
...
...
@@ -969,8 +972,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
sdata
->
needed_rx_chains
=
sdata
->
local
->
rx_chains
;
sdata
->
radar_required
=
params
->
radar_required
;
mutex_lock
(
&
local
->
mtx
);
err
=
ieee80211_vif_use_channel
(
sdata
,
&
params
->
chandef
,
IEEE80211_CHANCTX_SHARED
);
mutex_unlock
(
&
local
->
mtx
);
if
(
err
)
return
err
;
ieee80211_vif_copy_chanctx_to_vlans
(
sdata
,
false
);
...
...
@@ -1121,7 +1126,9 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
skb_queue_purge
(
&
sdata
->
u
.
ap
.
ps
.
bc_buf
);
ieee80211_vif_copy_chanctx_to_vlans
(
sdata
,
true
);
mutex_lock
(
&
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
local
->
mtx
);
return
0
;
}
...
...
@@ -1944,8 +1951,10 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
sdata
->
smps_mode
=
IEEE80211_SMPS_OFF
;
sdata
->
needed_rx_chains
=
sdata
->
local
->
rx_chains
;
mutex_lock
(
&
sdata
->
local
->
mtx
);
err
=
ieee80211_vif_use_channel
(
sdata
,
&
setup
->
chandef
,
IEEE80211_CHANCTX_SHARED
);
mutex_unlock
(
&
sdata
->
local
->
mtx
);
if
(
err
)
return
err
;
...
...
@@ -1957,7 +1966,9 @@ static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
ieee80211_stop_mesh
(
sdata
);
mutex_lock
(
&
sdata
->
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
sdata
->
local
->
mtx
);
return
0
;
}
...
...
@@ -2895,26 +2906,29 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
unsigned
long
timeout
;
int
err
;
if
(
!
list_empty
(
&
local
->
roc_list
)
||
local
->
scanning
)
return
-
EBUSY
;
mutex_lock
(
&
local
->
mtx
);
if
(
!
list_empty
(
&
local
->
roc_list
)
||
local
->
scanning
)
{
err
=
-
EBUSY
;
goto
out_unlock
;
}
/* whatever, but channel contexts should not complain about that one */
sdata
->
smps_mode
=
IEEE80211_SMPS_OFF
;
sdata
->
needed_rx_chains
=
local
->
rx_chains
;
sdata
->
radar_required
=
true
;
mutex_lock
(
&
local
->
iflist_mtx
);
err
=
ieee80211_vif_use_channel
(
sdata
,
chandef
,
IEEE80211_CHANCTX_SHARED
);
mutex_unlock
(
&
local
->
iflist_mtx
);
if
(
err
)
return
err
;
goto
out_unlock
;
timeout
=
msecs_to_jiffies
(
IEEE80211_DFS_MIN_CAC_TIME_MS
);
ieee80211_queue_delayed_work
(
&
sdata
->
local
->
hw
,
&
sdata
->
dfs_cac_timer_work
,
timeout
);
return
0
;
out_unlock:
mutex_unlock
(
&
local
->
mtx
);
return
err
;
}
static
struct
cfg80211_beacon_data
*
...
...
@@ -2990,7 +3004,9 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
goto
unlock
;
sdata
->
radar_required
=
sdata
->
csa_radar_required
;
mutex_lock
(
&
local
->
mtx
);
err
=
ieee80211_vif_change_channel
(
sdata
,
&
changed
);
mutex_unlock
(
&
local
->
mtx
);
if
(
WARN_ON
(
err
<
0
))
goto
unlock
;
...
...
@@ -3821,6 +3837,31 @@ static void ieee80211_set_wakeup(struct wiphy *wiphy, bool enabled)
}
#endif
static
int
ieee80211_set_qos_map
(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
struct
cfg80211_qos_map
*
qos_map
)
{
struct
ieee80211_sub_if_data
*
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
dev
);
struct
mac80211_qos_map
*
new_qos_map
,
*
old_qos_map
;
if
(
qos_map
)
{
new_qos_map
=
kzalloc
(
sizeof
(
*
new_qos_map
),
GFP_KERNEL
);
if
(
!
new_qos_map
)
return
-
ENOMEM
;
memcpy
(
&
new_qos_map
->
qos_map
,
qos_map
,
sizeof
(
*
qos_map
));
}
else
{
/* A NULL qos_map was passed to disable QoS mapping */
new_qos_map
=
NULL
;
}
old_qos_map
=
rtnl_dereference
(
sdata
->
qos_map
);
rcu_assign_pointer
(
sdata
->
qos_map
,
new_qos_map
);
if
(
old_qos_map
)
kfree_rcu
(
old_qos_map
,
rcu_head
);
return
0
;
}
struct
cfg80211_ops
mac80211_config_ops
=
{
.
add_virtual_intf
=
ieee80211_add_iface
,
.
del_virtual_intf
=
ieee80211_del_iface
,
...
...
@@ -3900,4 +3941,5 @@ struct cfg80211_ops mac80211_config_ops = {
.
get_channel
=
ieee80211_cfg_get_channel
,
.
start_radar_detection
=
ieee80211_start_radar_detection
,
.
channel_switch
=
ieee80211_channel_switch
,
.
set_qos_map
=
ieee80211_set_qos_map
,
};
net/mac80211/chan.c
浏览文件 @
55d1cad2
...
...
@@ -232,8 +232,8 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
if
(
!
local
->
use_chanctx
)
local
->
hw
.
conf
.
radar_enabled
=
ctx
->
conf
.
radar_enabled
;
/*
acquir
e mutex to prevent idle from changing */
mutex_lock
(
&
local
->
mtx
);
/*
we hold th
e mutex to prevent idle from changing */
lockdep_assert_held
(
&
local
->
mtx
);
/* turn idle off *before* setting channel -- some drivers need that */
changed
=
ieee80211_idle_off
(
local
);
if
(
changed
)
...
...
@@ -246,19 +246,14 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
err
=
drv_add_chanctx
(
local
,
ctx
);
if
(
err
)
{
kfree
(
ctx
);
ctx
=
ERR_PTR
(
err
);
ieee80211_recalc_idle
(
local
);
goto
out
;
return
ERR_PTR
(
err
)
;
}
}
/* and keep the mutex held until the new chanctx is on the list */
list_add_rcu
(
&
ctx
->
list
,
&
local
->
chanctx_list
);
out:
mutex_unlock
(
&
local
->
mtx
);
return
ctx
;
}
...
...
@@ -294,9 +289,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local,
/* throw a warning if this wasn't the only channel context. */
WARN_ON
(
check_single_channel
&&
!
list_empty
(
&
local
->
chanctx_list
));
mutex_lock
(
&
local
->
mtx
);
ieee80211_recalc_idle
(
local
);
mutex_unlock
(
&
local
->
mtx
);
}
static
int
ieee80211_assign_vif_chanctx
(
struct
ieee80211_sub_if_data
*
sdata
,
...
...
@@ -358,6 +351,31 @@ static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
ieee80211_change_chanctx
(
local
,
ctx
,
compat
);
}
static
void
ieee80211_recalc_radar_chanctx
(
struct
ieee80211_local
*
local
,
struct
ieee80211_chanctx
*
chanctx
)
{
bool
radar_enabled
;
lockdep_assert_held
(
&
local
->
chanctx_mtx
);
/* for setting local->radar_detect_enabled */
lockdep_assert_held
(
&
local
->
mtx
);
radar_enabled
=
ieee80211_is_radar_required
(
local
);
if
(
radar_enabled
==
chanctx
->
conf
.
radar_enabled
)
return
;
chanctx
->
conf
.
radar_enabled
=
radar_enabled
;
local
->
radar_detect_enabled
=
chanctx
->
conf
.
radar_enabled
;
if
(
!
local
->
use_chanctx
)
{
local
->
hw
.
conf
.
radar_enabled
=
chanctx
->
conf
.
radar_enabled
;
ieee80211_hw_config
(
local
,
IEEE80211_CONF_CHANGE_CHANNEL
);
}
drv_change_chanctx
(
local
,
chanctx
,
IEEE80211_CHANCTX_CHANGE_RADAR
);
}
static
void
ieee80211_unassign_vif_chanctx
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
ieee80211_chanctx
*
ctx
)
{
...
...
@@ -404,29 +422,6 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
ieee80211_free_chanctx
(
local
,
ctx
);
}
void
ieee80211_recalc_radar_chanctx
(
struct
ieee80211_local
*
local
,
struct
ieee80211_chanctx
*
chanctx
)
{
bool
radar_enabled
;
lockdep_assert_held
(
&
local
->
chanctx_mtx
);
radar_enabled
=
ieee80211_is_radar_required
(
local
);
if
(
radar_enabled
==
chanctx
->
conf
.
radar_enabled
)
return
;
chanctx
->
conf
.
radar_enabled
=
radar_enabled
;
local
->
radar_detect_enabled
=
chanctx
->
conf
.
radar_enabled
;
if
(
!
local
->
use_chanctx
)
{
local
->
hw
.
conf
.
radar_enabled
=
chanctx
->
conf
.
radar_enabled
;
ieee80211_hw_config
(
local
,
IEEE80211_CONF_CHANGE_CHANNEL
);
}
drv_change_chanctx
(
local
,
chanctx
,
IEEE80211_CHANCTX_CHANGE_RADAR
);
}
void
ieee80211_recalc_smps_chanctx
(
struct
ieee80211_local
*
local
,
struct
ieee80211_chanctx
*
chanctx
)
{
...
...
@@ -518,6 +513,8 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
struct
ieee80211_chanctx
*
ctx
;
int
ret
;
lockdep_assert_held
(
&
local
->
mtx
);
WARN_ON
(
sdata
->
dev
&&
netif_carrier_ok
(
sdata
->
dev
));
mutex_lock
(
&
local
->
chanctx_mtx
);
...
...
@@ -558,6 +555,8 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
int
ret
;
u32
chanctx_changed
=
0
;
lockdep_assert_held
(
&
local
->
mtx
);
/* should never be called if not performing a channel switch. */
if
(
WARN_ON
(
!
sdata
->
vif
.
csa_active
))
return
-
EINVAL
;
...
...
@@ -655,6 +654,8 @@ void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
{
WARN_ON
(
sdata
->
dev
&&
netif_carrier_ok
(
sdata
->
dev
));
lockdep_assert_held
(
&
sdata
->
local
->
mtx
);
mutex_lock
(
&
sdata
->
local
->
chanctx_mtx
);
__ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
sdata
->
local
->
chanctx_mtx
);
...
...
net/mac80211/ibss.c
浏览文件 @
55d1cad2
...
...
@@ -293,14 +293,17 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
radar_required
=
true
;
}
mutex_lock
(
&
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
if
(
ieee80211_vif_use_channel
(
sdata
,
&
chandef
,
ifibss
->
fixed_channel
?
IEEE80211_CHANCTX_SHARED
:
IEEE80211_CHANCTX_EXCLUSIVE
))
{
sdata_info
(
sdata
,
"Failed to join IBSS, no channel context
\n
"
);
mutex_unlock
(
&
local
->
mtx
);
return
;
}
mutex_unlock
(
&
local
->
mtx
);
memcpy
(
ifibss
->
bssid
,
bssid
,
ETH_ALEN
);
...
...
@@ -363,7 +366,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
sdata
->
vif
.
bss_conf
.
ssid_len
=
0
;
RCU_INIT_POINTER
(
ifibss
->
presp
,
NULL
);
kfree_rcu
(
presp
,
rcu_head
);
mutex_lock
(
&
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
local
->
mtx
);
sdata_info
(
sdata
,
"Failed to join IBSS, driver failure: %d
\n
"
,
err
);
return
;
...
...
@@ -747,7 +752,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BEACON_ENABLED
|
BSS_CHANGED_IBSS
);
drv_leave_ibss
(
local
,
sdata
);
mutex_lock
(
&
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
local
->
mtx
);
}
static
void
ieee80211_csa_connection_drop_work
(
struct
work_struct
*
work
)
...
...
net/mac80211/ieee80211_i.h
浏览文件 @
55d1cad2
...
...
@@ -246,7 +246,8 @@ struct ps_data {
/* yes, this looks ugly, but guarantees that we can later use
* bitmap_empty :)
* NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */
u8
tim
[
sizeof
(
unsigned
long
)
*
BITS_TO_LONGS
(
IEEE80211_MAX_AID
+
1
)];
u8
tim
[
sizeof
(
unsigned
long
)
*
BITS_TO_LONGS
(
IEEE80211_MAX_AID
+
1
)]
__aligned
(
__alignof__
(
unsigned
long
));
struct
sk_buff_head
bc_buf
;
atomic_t
num_sta_ps
;
/* number of stations in PS mode */
int
dtim_count
;
...
...
@@ -693,6 +694,11 @@ struct ieee80211_chanctx {
struct
ieee80211_chanctx_conf
conf
;
};
struct
mac80211_qos_map
{
struct
cfg80211_qos_map
qos_map
;
struct
rcu_head
rcu_head
;
};
struct
ieee80211_sub_if_data
{
struct
list_head
list
;
...
...
@@ -738,6 +744,7 @@ struct ieee80211_sub_if_data {
int
encrypt_headroom
;
struct
ieee80211_tx_queue_params
tx_conf
[
IEEE80211_NUM_ACS
];
struct
mac80211_qos_map
__rcu
*
qos_map
;
struct
work_struct
csa_finalize_work
;
int
csa_counter_offset_beacon
;
...
...
@@ -1775,8 +1782,6 @@ void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
void
ieee80211_recalc_smps_chanctx
(
struct
ieee80211_local
*
local
,
struct
ieee80211_chanctx
*
chanctx
);
void
ieee80211_recalc_radar_chanctx
(
struct
ieee80211_local
*
local
,
struct
ieee80211_chanctx
*
chanctx
);
void
ieee80211_recalc_chanctx_min_def
(
struct
ieee80211_local
*
local
,
struct
ieee80211_chanctx
*
ctx
);
...
...
net/mac80211/iface.c
浏览文件 @
55d1cad2
...
...
@@ -418,8 +418,10 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
return
ret
;
}
mutex_lock
(
&
local
->
mtx
);
ret
=
ieee80211_vif_use_channel
(
sdata
,
&
local
->
monitor_chandef
,
IEEE80211_CHANCTX_EXCLUSIVE
);
mutex_unlock
(
&
local
->
mtx
);
if
(
ret
)
{
drv_remove_interface
(
local
,
sdata
);
kfree
(
sdata
);
...
...
@@ -456,7 +458,9 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local)
synchronize_net
();
mutex_lock
(
&
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
local
->
mtx
);
drv_remove_interface
(
local
,
sdata
);
...
...
@@ -826,9 +830,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
if
(
sdata
->
wdev
.
cac_started
)
{
chandef
=
sdata
->
vif
.
bss_conf
.
chandef
;
WARN_ON
(
local
->
suspended
);
mutex_lock
(
&
local
->
iflist_
mtx
);
mutex_lock
(
&
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
local
->
iflist_
mtx
);
mutex_unlock
(
&
local
->
mtx
);
cfg80211_cac_event
(
sdata
->
dev
,
&
chandef
,
NL80211_RADAR_CAC_ABORTED
,
GFP_KERNEL
);
...
...
net/mac80211/mlme.c
浏览文件 @
55d1cad2
...
...
@@ -888,7 +888,9 @@ static void ieee80211_chswitch_work(struct work_struct *work)
if
(
!
ifmgd
->
associated
)
goto
out
;
mutex_lock
(
&
local
->
mtx
);
ret
=
ieee80211_vif_change_channel
(
sdata
,
&
changed
);
mutex_unlock
(
&
local
->
mtx
);
if
(
ret
)
{
sdata_info
(
sdata
,
"vif channel switch failed, disconnecting
\n
"
);
...
...
@@ -1401,10 +1403,14 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work)
dfs_cac_timer_work
);
struct
cfg80211_chan_def
chandef
=
sdata
->
vif
.
bss_conf
.
chandef
;
ieee80211_vif_release_channel
(
sdata
);
cfg80211_cac_event
(
sdata
->
dev
,
&
chandef
,
NL80211_RADAR_CAC_FINISHED
,
GFP_KERNEL
);
mutex_lock
(
&
sdata
->
local
->
mtx
);
if
(
sdata
->
wdev
.
cac_started
)
{
ieee80211_vif_release_channel
(
sdata
);
cfg80211_cac_event
(
sdata
->
dev
,
&
chandef
,
NL80211_RADAR_CAC_FINISHED
,
GFP_KERNEL
);
}
mutex_unlock
(
&
sdata
->
local
->
mtx
);
}
/* MLME */
...
...
@@ -1747,7 +1753,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
ifmgd
->
have_beacon
=
false
;
ifmgd
->
flags
=
0
;
mutex_lock
(
&
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
local
->
mtx
);
sdata
->
encrypt_headroom
=
IEEE80211_ENCRYPT_HEADROOM
;
}
...
...
@@ -2070,7 +2078,9 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
memset
(
sdata
->
u
.
mgd
.
bssid
,
0
,
ETH_ALEN
);
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BSSID
);
sdata
->
u
.
mgd
.
flags
=
0
;
mutex_lock
(
&
sdata
->
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
sdata
->
local
->
mtx
);
}
cfg80211_put_bss
(
sdata
->
local
->
hw
.
wiphy
,
auth_data
->
bss
);
...
...
@@ -2319,7 +2329,9 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
memset
(
sdata
->
u
.
mgd
.
bssid
,
0
,
ETH_ALEN
);
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_BSSID
);
sdata
->
u
.
mgd
.
flags
=
0
;
mutex_lock
(
&
sdata
->
local
->
mtx
);
ieee80211_vif_release_channel
(
sdata
);
mutex_unlock
(
&
sdata
->
local
->
mtx
);
}
kfree
(
assoc_data
);
...
...
@@ -3670,6 +3682,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
/* will change later if needed */
sdata
->
smps_mode
=
IEEE80211_SMPS_OFF
;
mutex_lock
(
&
local
->
mtx
);
/*
* If this fails (possibly due to channel context sharing
* on incompatible channels, e.g. 80+80 and 160 sharing the
...
...
@@ -3681,13 +3694,15 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
/* don't downgrade for 5 and 10 MHz channels, though. */
if
(
chandef
.
width
==
NL80211_CHAN_WIDTH_5
||
chandef
.
width
==
NL80211_CHAN_WIDTH_10
)
return
re
t
;
goto
ou
t
;
while
(
ret
&&
chandef
.
width
!=
NL80211_CHAN_WIDTH_20_NOHT
)
{
ifmgd
->
flags
|=
ieee80211_chandef_downgrade
(
&
chandef
);
ret
=
ieee80211_vif_use_channel
(
sdata
,
&
chandef
,
IEEE80211_CHANCTX_SHARED
);
}
out:
mutex_unlock
(
&
local
->
mtx
);
return
ret
;
}
...
...
net/mac80211/rc80211_minstrel.c
浏览文件 @
55d1cad2
...
...
@@ -135,7 +135,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
u32
usecs
;
int
i
;
for
(
i
=
0
;
i
<
MAX_THR_RATES
;
i
++
)
for
(
i
=
0
;
i
<
MAX_THR_RATES
;
i
++
)
tmp_tp_rate
[
i
]
=
0
;
for
(
i
=
0
;
i
<
mi
->
n_rates
;
i
++
)
{
...
...
@@ -190,7 +190,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
* choose the maximum throughput rate as max_prob_rate
* (2) if all success probabilities < 95%, the rate with
* highest success probability is choosen as max_prob_rate */
if
(
mr
->
probability
>=
MINSTREL_FRAC
(
95
,
100
))
{
if
(
mr
->
probability
>=
MINSTREL_FRAC
(
95
,
100
))
{
if
(
mr
->
cur_tp
>=
mi
->
r
[
tmp_prob_rate
].
cur_tp
)
tmp_prob_rate
=
i
;
}
else
{
...
...
@@ -220,7 +220,7 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
static
void
minstrel_tx_status
(
void
*
priv
,
struct
ieee80211_supported_band
*
sband
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
ieee80211_sta
*
sta
,
void
*
priv_sta
,
struct
sk_buff
*
skb
)
{
struct
minstrel_priv
*
mp
=
priv
;
...
...
@@ -260,7 +260,7 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
static
inline
unsigned
int
minstrel_get_retry_count
(
struct
minstrel_rate
*
mr
,
struct
ieee80211_tx_info
*
info
)
struct
ieee80211_tx_info
*
info
)
{
unsigned
int
retry
=
mr
->
adjusted_retry_count
;
...
...
net/mac80211/rc80211_minstrel_ht.c
浏览文件 @
55d1cad2
...
...
@@ -63,7 +63,7 @@
#define CCK_DURATION(_bitrate, _short, _len) \
(1000 * (10
/* SIFS */
+ \
(_short ? 72 + 24 : 144 + 48
) + \
(_short ? 72 + 24 : 144 + 48) + \
(8 * (_len + 4) * 10) / (_bitrate)))
#define CCK_ACK_DURATION(_bitrate, _short) \
...
...
net/mac80211/tkip.c
浏览文件 @
55d1cad2
...
...
@@ -186,7 +186,7 @@ void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf,
EXPORT_SYMBOL
(
ieee80211_get_tkip_p1k_iv
);
void
ieee80211_get_tkip_rx_p1k
(
struct
ieee80211_key_conf
*
keyconf
,
const
u8
*
ta
,
u32
iv32
,
u16
*
p1k
)
const
u8
*
ta
,
u32
iv32
,
u16
*
p1k
)
{
const
u8
*
tk
=
&
keyconf
->
key
[
NL80211_TKIP_DATA_OFFSET_ENCR_KEY
];
struct
tkip_ctx
ctx
;
...
...
net/mac80211/trace.h
浏览文件 @
55d1cad2
...
...
@@ -553,7 +553,7 @@ TRACE_EVENT(drv_update_tkip_key,
TP_printk
(
LOCAL_PR_FMT
VIF_PR_FMT
STA_PR_FMT
" iv32:%#x"
,
LOCAL_PR_ARG
,
VIF_PR_ARG
,
STA_PR_ARG
,
__entry
->
iv32
LOCAL_PR_ARG
,
VIF_PR_ARG
,
STA_PR_ARG
,
__entry
->
iv32
)
);
...
...
net/mac80211/tx.c
浏览文件 @
55d1cad2
...
...
@@ -2161,7 +2161,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
if
(
ieee80211_is_data_qos
(
fc
))
{
__le16
*
qos_control
;
qos_control
=
(
__le16
*
)
skb_push
(
skb
,
2
);
qos_control
=
(
__le16
*
)
skb_push
(
skb
,
2
);
memcpy
(
skb_push
(
skb
,
hdrlen
-
2
),
&
hdr
,
hdrlen
-
2
);
/*
* Maybe we could actually set some fields here, for now just
...
...
@@ -2323,7 +2323,7 @@ static void __ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
if
(
atomic_read
(
&
ps
->
num_sta_ps
)
>
0
)
/* in the hope that this is faster than
* checking byte-for-byte */
have_bits
=
!
bitmap_empty
((
unsigned
long
*
)
ps
->
tim
,
have_bits
=
!
bitmap_empty
((
unsigned
long
*
)
ps
->
tim
,
IEEE80211_MAX_AID
+
1
);
if
(
ps
->
dtim_count
==
0
)
...
...
net/mac80211/util.c
浏览文件 @
55d1cad2
...
...
@@ -76,7 +76,7 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
}
if
(
ieee80211_is_ctl
(
fc
))
{
if
(
ieee80211_is_pspoll
(
fc
))
if
(
ieee80211_is_pspoll
(
fc
))
return
hdr
->
addr1
;
if
(
ieee80211_is_back_req
(
fc
))
{
...
...
@@ -2315,9 +2315,14 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
struct
ieee80211_sub_if_data
*
sdata
;
struct
cfg80211_chan_def
chandef
;
mutex_lock
(
&
local
->
mtx
);
mutex_lock
(
&
local
->
iflist_mtx
);
list_for_each_entry
(
sdata
,
&
local
->
interfaces
,
list
)
{
cancel_delayed_work_sync
(
&
sdata
->
dfs_cac_timer_work
);
/* it might be waiting for the local->mtx, but then
* by the time it gets it, sdata->wdev.cac_started
* will no longer be true
*/
cancel_delayed_work
(
&
sdata
->
dfs_cac_timer_work
);
if
(
sdata
->
wdev
.
cac_started
)
{
chandef
=
sdata
->
vif
.
bss_conf
.
chandef
;
...
...
@@ -2329,6 +2334,7 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
}
}
mutex_unlock
(
&
local
->
iflist_mtx
);
mutex_unlock
(
&
local
->
mtx
);
}
void
ieee80211_dfs_radar_detected_work
(
struct
work_struct
*
work
)
...
...
@@ -2588,3 +2594,143 @@ int ieee80211_cs_headroom(struct ieee80211_local *local,
return
headroom
;
}
static
bool
ieee80211_extend_noa_desc
(
struct
ieee80211_noa_data
*
data
,
u32
tsf
,
int
i
)
{
s32
end
=
data
->
desc
[
i
].
start
+
data
->
desc
[
i
].
duration
-
(
tsf
+
1
);
int
skip
;
if
(
end
>
0
)
return
false
;
/* End time is in the past, check for repetitions */
skip
=
DIV_ROUND_UP
(
-
end
,
data
->
desc
[
i
].
interval
);
if
(
data
->
count
[
i
]
<
255
)
{
if
(
data
->
count
[
i
]
<=
skip
)
{
data
->
count
[
i
]
=
0
;
return
false
;
}
data
->
count
[
i
]
-=
skip
;
}
data
->
desc
[
i
].
start
+=
skip
*
data
->
desc
[
i
].
interval
;
return
true
;
}
static
bool
ieee80211_extend_absent_time
(
struct
ieee80211_noa_data
*
data
,
u32
tsf
,
s32
*
offset
)
{
bool
ret
=
false
;
int
i
;
for
(
i
=
0
;
i
<
IEEE80211_P2P_NOA_DESC_MAX
;
i
++
)
{
s32
cur
;
if
(
!
data
->
count
[
i
])
continue
;
if
(
ieee80211_extend_noa_desc
(
data
,
tsf
+
*
offset
,
i
))
ret
=
true
;
cur
=
data
->
desc
[
i
].
start
-
tsf
;
if
(
cur
>
*
offset
)
continue
;
cur
=
data
->
desc
[
i
].
start
+
data
->
desc
[
i
].
duration
-
tsf
;
if
(
cur
>
*
offset
)
*
offset
=
cur
;
}
return
ret
;
}
static
u32
ieee80211_get_noa_absent_time
(
struct
ieee80211_noa_data
*
data
,
u32
tsf
)
{
s32
offset
=
0
;
int
tries
=
0
;
/*
* arbitrary limit, used to avoid infinite loops when combined NoA
* descriptors cover the full time period.
*/
int
max_tries
=
5
;
ieee80211_extend_absent_time
(
data
,
tsf
,
&
offset
);
do
{
if
(
!
ieee80211_extend_absent_time
(
data
,
tsf
,
&
offset
))
break
;
tries
++
;
}
while
(
tries
<
max_tries
);
return
offset
;
}
void
ieee80211_update_p2p_noa
(
struct
ieee80211_noa_data
*
data
,
u32
tsf
)
{
u32
next_offset
=
BIT
(
31
)
-
1
;
int
i
;
data
->
absent
=
0
;
data
->
has_next_tsf
=
false
;
for
(
i
=
0
;
i
<
IEEE80211_P2P_NOA_DESC_MAX
;
i
++
)
{
s32
start
;
if
(
!
data
->
count
[
i
])
continue
;
ieee80211_extend_noa_desc
(
data
,
tsf
,
i
);
start
=
data
->
desc
[
i
].
start
-
tsf
;
if
(
start
<=
0
)
data
->
absent
|=
BIT
(
i
);
if
(
next_offset
>
start
)
next_offset
=
start
;
data
->
has_next_tsf
=
true
;
}
if
(
data
->
absent
)
next_offset
=
ieee80211_get_noa_absent_time
(
data
,
tsf
);
data
->
next_tsf
=
tsf
+
next_offset
;
}
EXPORT_SYMBOL
(
ieee80211_update_p2p_noa
);
int
ieee80211_parse_p2p_noa
(
const
struct
ieee80211_p2p_noa_attr
*
attr
,
struct
ieee80211_noa_data
*
data
,
u32
tsf
)
{
int
ret
=
0
;
int
i
;
memset
(
data
,
0
,
sizeof
(
*
data
));
for
(
i
=
0
;
i
<
IEEE80211_P2P_NOA_DESC_MAX
;
i
++
)
{
const
struct
ieee80211_p2p_noa_desc
*
desc
=
&
attr
->
desc
[
i
];
if
(
!
desc
->
count
||
!
desc
->
duration
)
continue
;
data
->
count
[
i
]
=
desc
->
count
;
data
->
desc
[
i
].
start
=
le32_to_cpu
(
desc
->
start_time
);
data
->
desc
[
i
].
duration
=
le32_to_cpu
(
desc
->
duration
);
data
->
desc
[
i
].
interval
=
le32_to_cpu
(
desc
->
interval
);
if
(
data
->
count
[
i
]
>
1
&&
data
->
desc
[
i
].
interval
<
data
->
desc
[
i
].
duration
)
continue
;
ieee80211_extend_noa_desc
(
data
,
tsf
,
i
);
ret
++
;
}
if
(
ret
)
ieee80211_update_p2p_noa
(
data
,
tsf
);
return
ret
;
}
EXPORT_SYMBOL
(
ieee80211_parse_p2p_noa
);
net/mac80211/wme.c
浏览文件 @
55d1cad2
...
...
@@ -106,6 +106,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
struct
sta_info
*
sta
=
NULL
;
const
u8
*
ra
=
NULL
;
bool
qos
=
false
;
struct
mac80211_qos_map
*
qos_map
;
if
(
local
->
hw
.
queues
<
IEEE80211_NUM_ACS
||
skb
->
len
<
6
)
{
skb
->
priority
=
0
;
/* required for correct WPA/11i MIC */
...
...
@@ -155,7 +156,11 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
/* use the data classifier to determine what 802.1d tag the
* data frame has */
skb
->
priority
=
cfg80211_classify8021d
(
skb
);
rcu_read_lock
();
qos_map
=
rcu_dereference
(
sdata
->
qos_map
);
skb
->
priority
=
cfg80211_classify8021d
(
skb
,
qos_map
?
&
qos_map
->
qos_map
:
NULL
);
rcu_read_unlock
();
return
ieee80211_downgrade_queue
(
sdata
,
skb
);
}
...
...
net/wireless/ap.c
浏览文件 @
55d1cad2
...
...
@@ -29,6 +29,7 @@ static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
wdev
->
beacon_interval
=
0
;
wdev
->
channel
=
NULL
;
wdev
->
ssid_len
=
0
;
rdev_set_qos_map
(
rdev
,
dev
,
NULL
);
}
return
err
;
...
...
net/wireless/ibss.c
浏览文件 @
55d1cad2
...
...
@@ -183,6 +183,8 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
kfree
(
wdev
->
connect_keys
);
wdev
->
connect_keys
=
NULL
;
rdev_set_qos_map
(
rdev
,
dev
,
NULL
);
/*
* Delete all the keys ... pairwise keys can't really
* exist any more anyway, but default keys might.
...
...
net/wireless/mesh.c
浏览文件 @
55d1cad2
...
...
@@ -277,6 +277,7 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
if
(
!
err
)
{
wdev
->
mesh_id_len
=
0
;
wdev
->
channel
=
NULL
;
rdev_set_qos_map
(
rdev
,
dev
,
NULL
);
}
return
err
;
...
...
net/wireless/nl80211.c
浏览文件 @
55d1cad2
...
...
@@ -53,6 +53,7 @@ enum nl80211_multicast_groups {
NL80211_MCGRP_SCAN
,
NL80211_MCGRP_REGULATORY
,
NL80211_MCGRP_MLME
,
NL80211_MCGRP_VENDOR
,
NL80211_MCGRP_TESTMODE
/* keep last - ifdef! */
};
...
...
@@ -61,6 +62,7 @@ static const struct genl_multicast_group nl80211_mcgrps[] = {
[
NL80211_MCGRP_SCAN
]
=
{
.
name
=
"scan"
,
},
[
NL80211_MCGRP_REGULATORY
]
=
{
.
name
=
"regulatory"
,
},
[
NL80211_MCGRP_MLME
]
=
{
.
name
=
"mlme"
,
},
[
NL80211_MCGRP_VENDOR
]
=
{
.
name
=
"vendor"
,
},
#ifdef CONFIG_NL80211_TESTMODE
[
NL80211_MCGRP_TESTMODE
]
=
{
.
name
=
"testmode"
,
}
#endif
...
...
@@ -380,6 +382,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[
NL80211_ATTR_VENDOR_ID
]
=
{
.
type
=
NLA_U32
},
[
NL80211_ATTR_VENDOR_SUBCMD
]
=
{
.
type
=
NLA_U32
},
[
NL80211_ATTR_VENDOR_DATA
]
=
{
.
type
=
NLA_BINARY
},
[
NL80211_ATTR_QOS_MAP
]
=
{
.
type
=
NLA_BINARY
,
.
len
=
IEEE80211_QOS_MAP_LEN_MAX
},
};
/* policy for the key attributes */
...
...
@@ -1188,7 +1192,6 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
struct
nlattr
*
nl_bands
,
*
nl_band
;
struct
nlattr
*
nl_freqs
,
*
nl_freq
;
struct
nlattr
*
nl_cmds
;
struct
nlattr
*
nl_vendor_cmds
;
enum
ieee80211_band
band
;
struct
ieee80211_channel
*
chan
;
int
i
;
...
...
@@ -1455,6 +1458,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
if
(
dev
->
wiphy
.
flags
&
WIPHY_FLAG_HAS_CHANNEL_SWITCH
)
CMD
(
channel_switch
,
CHANNEL_SWITCH
);
}
CMD
(
set_qos_map
,
SET_QOS_MAP
);
#ifdef CONFIG_NL80211_TESTMODE
CMD
(
testmode_cmd
,
TESTMODE
);
...
...
@@ -1587,16 +1591,38 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
state
->
split_start
++
;
break
;
case
11
:
nl_vendor_cmds
=
nla_nest_start
(
msg
,
NL80211_ATTR_VENDOR_DATA
);
if
(
!
nl_vendor_cmds
)
goto
nla_put_failure
;
if
(
dev
->
wiphy
.
n_vendor_commands
)
{
const
struct
nl80211_vendor_cmd_info
*
info
;
struct
nlattr
*
nested
;
nested
=
nla_nest_start
(
msg
,
NL80211_ATTR_VENDOR_DATA
);
if
(
!
nested
)
goto
nla_put_failure
;
for
(
i
=
0
;
i
<
dev
->
wiphy
.
n_vendor_commands
;
i
++
)
{
info
=
&
dev
->
wiphy
.
vendor_commands
[
i
].
info
;
if
(
nla_put
(
msg
,
i
+
1
,
sizeof
(
*
info
),
info
))
goto
nla_put_failure
;
}
nla_nest_end
(
msg
,
nested
);
}
if
(
dev
->
wiphy
.
n_vendor_events
)
{
const
struct
nl80211_vendor_cmd_info
*
info
;
struct
nlattr
*
nested
;
for
(
i
=
0
;
i
<
dev
->
wiphy
.
n_vendor_commands
;
i
++
)
if
(
nla_put
(
msg
,
i
+
1
,
sizeof
(
struct
nl80211_vendor_cmd_info
),
&
dev
->
wiphy
.
vendor_commands
[
i
].
info
))
nested
=
nla_nest_start
(
msg
,
NL80211_ATTR_VENDOR_EVENTS
);
if
(
!
nested
)
goto
nla_put_failure
;
nla_nest_end
(
msg
,
nl_vendor_cmds
);
for
(
i
=
0
;
i
<
dev
->
wiphy
.
n_vendor_events
;
i
++
)
{
info
=
&
dev
->
wiphy
.
vendor_events
[
i
];
if
(
nla_put
(
msg
,
i
+
1
,
sizeof
(
*
info
),
info
))
goto
nla_put_failure
;
}
nla_nest_end
(
msg
,
nested
);
}
/* done */
state
->
split_start
=
0
;
...
...
@@ -6726,7 +6752,9 @@ static struct sk_buff *
__cfg80211_alloc_vendor_skb
(
struct
cfg80211_registered_device
*
rdev
,
int
approxlen
,
u32
portid
,
u32
seq
,
enum
nl80211_commands
cmd
,
enum
nl80211_attrs
attr
,
gfp_t
gfp
)
enum
nl80211_attrs
attr
,
const
struct
nl80211_vendor_cmd_info
*
info
,
gfp_t
gfp
)
{
struct
sk_buff
*
skb
;
void
*
hdr
;
...
...
@@ -6744,6 +6772,16 @@ __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
if
(
nla_put_u32
(
skb
,
NL80211_ATTR_WIPHY
,
rdev
->
wiphy_idx
))
goto
nla_put_failure
;
if
(
info
)
{
if
(
nla_put_u32
(
skb
,
NL80211_ATTR_VENDOR_ID
,
info
->
vendor_id
))
goto
nla_put_failure
;
if
(
nla_put_u32
(
skb
,
NL80211_ATTR_VENDOR_SUBCMD
,
info
->
subcmd
))
goto
nla_put_failure
;
}
data
=
nla_nest_start
(
skb
,
attr
);
((
void
**
)
skb
->
cb
)[
0
]
=
rdev
;
...
...
@@ -6884,29 +6922,54 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
return
err
;
}
struct
sk_buff
*
cfg80211_testmode_alloc_event_skb
(
struct
wiphy
*
wiphy
,
int
approxlen
,
gfp_t
gfp
)
struct
sk_buff
*
__cfg80211_alloc_event_skb
(
struct
wiphy
*
wiphy
,
enum
nl80211_commands
cmd
,
enum
nl80211_attrs
attr
,
int
vendor_event_idx
,
int
approxlen
,
gfp_t
gfp
)
{
struct
cfg80211_registered_device
*
rdev
=
wiphy_to_dev
(
wiphy
);
const
struct
nl80211_vendor_cmd_info
*
info
;
switch
(
cmd
)
{
case
NL80211_CMD_TESTMODE
:
if
(
WARN_ON
(
vendor_event_idx
!=
-
1
))
return
NULL
;
info
=
NULL
;
break
;
case
NL80211_CMD_VENDOR
:
if
(
WARN_ON
(
vendor_event_idx
<
0
||
vendor_event_idx
>=
wiphy
->
n_vendor_events
))
return
NULL
;
info
=
&
wiphy
->
vendor_events
[
vendor_event_idx
];
break
;
default:
WARN_ON
(
1
);
return
NULL
;
}
return
__cfg80211_alloc_vendor_skb
(
rdev
,
approxlen
,
0
,
0
,
NL80211_CMD_TESTMODE
,
NL80211_ATTR_TESTDATA
,
gfp
);
cmd
,
attr
,
info
,
gfp
);
}
EXPORT_SYMBOL
(
cfg80211_testmode
_alloc_event_skb
);
EXPORT_SYMBOL
(
__cfg80211
_alloc_event_skb
);
void
cfg80211_testmode_event
(
struct
sk_buff
*
skb
,
gfp_t
gfp
)
void
__cfg80211_send_event_skb
(
struct
sk_buff
*
skb
,
gfp_t
gfp
)
{
struct
cfg80211_registered_device
*
rdev
=
((
void
**
)
skb
->
cb
)[
0
];
void
*
hdr
=
((
void
**
)
skb
->
cb
)[
1
];
struct
nlattr
*
data
=
((
void
**
)
skb
->
cb
)[
2
];
enum
nl80211_multicast_groups
mcgrp
=
NL80211_MCGRP_TESTMODE
;
nla_nest_end
(
skb
,
data
);
genlmsg_end
(
skb
,
hdr
);
if
(
data
->
nla_type
==
NL80211_ATTR_VENDOR_DATA
)
mcgrp
=
NL80211_MCGRP_VENDOR
;
genlmsg_multicast_netns
(
&
nl80211_fam
,
wiphy_net
(
&
rdev
->
wiphy
),
skb
,
0
,
NL80211_MCGRP_TESTMODE
,
gfp
);
mcgrp
,
gfp
);
}
EXPORT_SYMBOL
(
cfg80211_testmode_event
);
EXPORT_SYMBOL
(
__cfg80211_send_event_skb
);
#endif
static
int
nl80211_connect
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
...
...
@@ -9039,7 +9102,7 @@ struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
return
__cfg80211_alloc_vendor_skb
(
rdev
,
approxlen
,
rdev
->
cur_cmd_info
->
snd_portid
,
rdev
->
cur_cmd_info
->
snd_seq
,
cmd
,
attr
,
GFP_KERNEL
);
cmd
,
attr
,
NULL
,
GFP_KERNEL
);
}
EXPORT_SYMBOL
(
__cfg80211_alloc_reply_skb
);
...
...
@@ -9061,6 +9124,57 @@ int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
EXPORT_SYMBOL_GPL
(
cfg80211_vendor_cmd_reply
);
static
int
nl80211_set_qos_map
(
struct
sk_buff
*
skb
,
struct
genl_info
*
info
)
{
struct
cfg80211_registered_device
*
rdev
=
info
->
user_ptr
[
0
];
struct
cfg80211_qos_map
*
qos_map
=
NULL
;
struct
net_device
*
dev
=
info
->
user_ptr
[
1
];
u8
*
pos
,
len
,
num_des
,
des_len
,
des
;
int
ret
;
if
(
!
rdev
->
ops
->
set_qos_map
)
return
-
EOPNOTSUPP
;
if
(
info
->
attrs
[
NL80211_ATTR_QOS_MAP
])
{
pos
=
nla_data
(
info
->
attrs
[
NL80211_ATTR_QOS_MAP
]);
len
=
nla_len
(
info
->
attrs
[
NL80211_ATTR_QOS_MAP
]);
if
(
len
%
2
||
len
<
IEEE80211_QOS_MAP_LEN_MIN
||
len
>
IEEE80211_QOS_MAP_LEN_MAX
)
return
-
EINVAL
;
qos_map
=
kzalloc
(
sizeof
(
struct
cfg80211_qos_map
),
GFP_KERNEL
);
if
(
!
qos_map
)
return
-
ENOMEM
;
num_des
=
(
len
-
IEEE80211_QOS_MAP_LEN_MIN
)
>>
1
;
if
(
num_des
)
{
des_len
=
num_des
*
sizeof
(
struct
cfg80211_dscp_exception
);
memcpy
(
qos_map
->
dscp_exception
,
pos
,
des_len
);
qos_map
->
num_des
=
num_des
;
for
(
des
=
0
;
des
<
num_des
;
des
++
)
{
if
(
qos_map
->
dscp_exception
[
des
].
up
>
7
)
{
kfree
(
qos_map
);
return
-
EINVAL
;
}
}
pos
+=
des_len
;
}
memcpy
(
qos_map
->
up
,
pos
,
IEEE80211_QOS_MAP_LEN_MIN
);
}
wdev_lock
(
dev
->
ieee80211_ptr
);
ret
=
nl80211_key_allowed
(
dev
->
ieee80211_ptr
);
if
(
!
ret
)
ret
=
rdev_set_qos_map
(
rdev
,
dev
,
qos_map
);
wdev_unlock
(
dev
->
ieee80211_ptr
);
kfree
(
qos_map
);
return
ret
;
}
#define NL80211_FLAG_NEED_WIPHY 0x01
#define NL80211_FLAG_NEED_NETDEV 0x02
#define NL80211_FLAG_NEED_RTNL 0x04
...
...
@@ -9793,6 +9907,14 @@ static const struct genl_ops nl80211_ops[] = {
.
internal_flags
=
NL80211_FLAG_NEED_WIPHY
|
NL80211_FLAG_NEED_RTNL
,
},
{
.
cmd
=
NL80211_CMD_SET_QOS_MAP
,
.
doit
=
nl80211_set_qos_map
,
.
policy
=
nl80211_policy
,
.
flags
=
GENL_ADMIN_PERM
,
.
internal_flags
=
NL80211_FLAG_NEED_NETDEV_UP
|
NL80211_FLAG_NEED_RTNL
,
},
};
/* notification functions */
...
...
net/wireless/rdev-ops.h
浏览文件 @
55d1cad2
...
...
@@ -932,4 +932,19 @@ static inline int rdev_channel_switch(struct cfg80211_registered_device *rdev,
return
ret
;
}
static
inline
int
rdev_set_qos_map
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_qos_map
*
qos_map
)
{
int
ret
=
-
EOPNOTSUPP
;
if
(
rdev
->
ops
->
set_qos_map
)
{
trace_rdev_set_qos_map
(
&
rdev
->
wiphy
,
dev
,
qos_map
);
ret
=
rdev
->
ops
->
set_qos_map
(
&
rdev
->
wiphy
,
dev
,
qos_map
);
trace_rdev_return_int
(
&
rdev
->
wiphy
,
ret
);
}
return
ret
;
}
#endif
/* __CFG80211_RDEV_OPS */
net/wireless/sme.c
浏览文件 @
55d1cad2
...
...
@@ -870,6 +870,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
for
(
i
=
0
;
i
<
6
;
i
++
)
rdev_del_key
(
rdev
,
dev
,
i
,
false
,
NULL
);
rdev_set_qos_map
(
rdev
,
dev
,
NULL
);
#ifdef CONFIG_CFG80211_WEXT
memset
(
&
wrqu
,
0
,
sizeof
(
wrqu
));
wrqu
.
ap_addr
.
sa_family
=
ARPHRD_ETHER
;
...
...
net/wireless/trace.h
浏览文件 @
55d1cad2
...
...
@@ -186,6 +186,28 @@
#define BOOL_TO_STR(bo) (bo) ? "true" : "false"
#define QOS_MAP_ENTRY __field(u8, num_des) \
__array(u8, dscp_exception, \
2 * IEEE80211_QOS_MAP_MAX_EX) \
__array(u8, up, IEEE80211_QOS_MAP_LEN_MIN)
#define QOS_MAP_ASSIGN(qos_map) \
do { \
if ((qos_map)) { \
__entry->num_des = (qos_map)->num_des; \
memcpy(__entry->dscp_exception, \
&(qos_map)->dscp_exception, \
2 * IEEE80211_QOS_MAP_MAX_EX); \
memcpy(__entry->up, &(qos_map)->up, \
IEEE80211_QOS_MAP_LEN_MIN); \
} else { \
__entry->num_des = 0; \
memset(__entry->dscp_exception, 0, \
2 * IEEE80211_QOS_MAP_MAX_EX); \
memset(__entry->up, 0, \
IEEE80211_QOS_MAP_LEN_MIN); \
} \
} while (0)
/*************************************************************
* rdev->ops traces *
*************************************************************/
...
...
@@ -1875,6 +1897,24 @@ TRACE_EVENT(rdev_channel_switch,
__entry
->
counter_offset_presp
)
);
TRACE_EVENT
(
rdev_set_qos_map
,
TP_PROTO
(
struct
wiphy
*
wiphy
,
struct
net_device
*
netdev
,
struct
cfg80211_qos_map
*
qos_map
),
TP_ARGS
(
wiphy
,
netdev
,
qos_map
),
TP_STRUCT__entry
(
WIPHY_ENTRY
NETDEV_ENTRY
QOS_MAP_ENTRY
),
TP_fast_assign
(
WIPHY_ASSIGN
;
NETDEV_ASSIGN
;
QOS_MAP_ASSIGN
(
qos_map
);
),
TP_printk
(
WIPHY_PR_FMT
", "
NETDEV_PR_FMT
", num_des: %u"
,
WIPHY_PR_ARG
,
NETDEV_PR_ARG
,
__entry
->
num_des
)
);
/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/
...
...
net/wireless/util.c
浏览文件 @
55d1cad2
...
...
@@ -689,7 +689,8 @@ void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
EXPORT_SYMBOL
(
ieee80211_amsdu_to_8023s
);
/* Given a data frame determine the 802.1p/1d tag to use. */
unsigned
int
cfg80211_classify8021d
(
struct
sk_buff
*
skb
)
unsigned
int
cfg80211_classify8021d
(
struct
sk_buff
*
skb
,
struct
cfg80211_qos_map
*
qos_map
)
{
unsigned
int
dscp
;
unsigned
char
vlan_priority
;
...
...
@@ -720,6 +721,21 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb)
return
0
;
}
if
(
qos_map
)
{
unsigned
int
i
,
tmp_dscp
=
dscp
>>
2
;
for
(
i
=
0
;
i
<
qos_map
->
num_des
;
i
++
)
{
if
(
tmp_dscp
==
qos_map
->
dscp_exception
[
i
].
dscp
)
return
qos_map
->
dscp_exception
[
i
].
up
;
}
for
(
i
=
0
;
i
<
8
;
i
++
)
{
if
(
tmp_dscp
>=
qos_map
->
up
[
i
].
low
&&
tmp_dscp
<=
qos_map
->
up
[
i
].
high
)
return
i
;
}
}
return
dscp
>>
5
;
}
EXPORT_SYMBOL
(
cfg80211_classify8021d
);
...
...
@@ -863,6 +879,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
dev
->
ieee80211_ptr
->
use_4addr
=
false
;
dev
->
ieee80211_ptr
->
mesh_id_up_len
=
0
;
rdev_set_qos_map
(
rdev
,
dev
,
NULL
);
switch
(
otype
)
{
case
NL80211_IFTYPE_AP
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录