Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
a006827a
Commit
a006827a
authored
Jul 22, 2014
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
parents
1d9e954e
08cf42e8
Changes
19
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
707 additions
and
169 deletions
+707
-169
include/linux/ieee80211.h
include/linux/ieee80211.h
+20
-0
include/net/mac80211.h
include/net/mac80211.h
+34
-0
net/mac80211/agg-rx.c
net/mac80211/agg-rx.c
+84
-26
net/mac80211/chan.c
net/mac80211/chan.c
+1
-1
net/mac80211/ht.c
net/mac80211/ht.c
+6
-4
net/mac80211/ibss.c
net/mac80211/ibss.c
+2
-11
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+30
-4
net/mac80211/iface.c
net/mac80211/iface.c
+29
-2
net/mac80211/key.c
net/mac80211/key.c
+0
-3
net/mac80211/mlme.c
net/mac80211/mlme.c
+5
-17
net/mac80211/rx.c
net/mac80211/rx.c
+46
-19
net/mac80211/sta_info.h
net/mac80211/sta_info.h
+6
-2
net/mac80211/tdls.c
net/mac80211/tdls.c
+394
-65
net/mac80211/util.c
net/mac80211/util.c
+15
-0
net/mac80211/vht.c
net/mac80211/vht.c
+4
-0
net/mac80211/wpa.c
net/mac80211/wpa.c
+1
-1
net/wireless/Kconfig
net/wireless/Kconfig
+6
-0
net/wireless/genregdb.awk
net/wireless/genregdb.awk
+22
-13
net/wireless/nl80211.c
net/wireless/nl80211.c
+2
-1
No files found.
include/linux/ieee80211.h
View file @
a006827a
...
...
@@ -1001,6 +1001,26 @@ struct ieee80211_vendor_ie {
u8
oui_type
;
}
__packed
;
struct
ieee80211_wmm_ac_param
{
u8
aci_aifsn
;
/* AIFSN, ACM, ACI */
u8
cw
;
/* ECWmin, ECWmax (CW = 2^ECW - 1) */
__le16
txop_limit
;
}
__packed
;
struct
ieee80211_wmm_param_ie
{
u8
element_id
;
/* Element ID: 221 (0xdd); */
u8
len
;
/* Length: 24 */
/* required fields for WMM version 1 */
u8
oui
[
3
];
/* 00:50:f2 */
u8
oui_type
;
/* 2 */
u8
oui_subtype
;
/* 1 */
u8
version
;
/* 1 for WMM version 1.0 */
u8
qos_info
;
/* AP/STA specific QoS info */
u8
reserved
;
/* 0 */
/* AC_BE, AC_BK, AC_VI, AC_VO */
struct
ieee80211_wmm_ac_param
ac
[
4
];
}
__packed
;
/* Control frames */
struct
ieee80211_rts
{
__le16
frame_control
;
...
...
include/net/mac80211.h
View file @
a006827a
...
...
@@ -4552,6 +4552,40 @@ void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
*/
void
ieee80211_send_bar
(
struct
ieee80211_vif
*
vif
,
u8
*
ra
,
u16
tid
,
u16
ssn
);
/**
* ieee80211_start_rx_ba_session_offl - start a Rx BA session
*
* Some device drivers may offload part of the Rx aggregation flow including
* AddBa/DelBa negotiation but may otherwise be incapable of full Rx
* reordering.
*
* Create structures responsible for reordering so device drivers may call here
* when they complete AddBa negotiation.
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback
* @addr: station mac address
* @tid: the rx tid
*/
void
ieee80211_start_rx_ba_session_offl
(
struct
ieee80211_vif
*
vif
,
const
u8
*
addr
,
u16
tid
);
/**
* ieee80211_stop_rx_ba_session_offl - stop a Rx BA session
*
* Some device drivers may offload part of the Rx aggregation flow including
* AddBa/DelBa negotiation but may otherwise be incapable of full Rx
* reordering.
*
* Destroy structures responsible for reordering so device drivers may call here
* when they complete DelBa negotiation.
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback
* @addr: station mac address
* @tid: the rx tid
*/
void
ieee80211_stop_rx_ba_session_offl
(
struct
ieee80211_vif
*
vif
,
const
u8
*
addr
,
u16
tid
);
/* Rate control API */
/**
...
...
net/mac80211/agg-rx.c
View file @
a006827a
...
...
@@ -52,7 +52,7 @@ static void ieee80211_free_tid_rx(struct rcu_head *h)
del_timer_sync
(
&
tid_rx
->
reorder_timer
);
for
(
i
=
0
;
i
<
tid_rx
->
buf_size
;
i
++
)
dev_kfree_skb
(
tid_rx
->
reorder_buf
[
i
]);
__skb_queue_purge
(
&
tid_rx
->
reorder_buf
[
i
]);
kfree
(
tid_rx
->
reorder_buf
);
kfree
(
tid_rx
->
reorder_time
);
kfree
(
tid_rx
);
...
...
@@ -224,28 +224,15 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d
ieee80211_tx_skb
(
sdata
,
skb
);
}
void
ieee80211_process_addba_request
(
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
)
void
__ieee80211_start_rx_ba_session
(
struct
sta_info
*
sta
,
u8
dialog_token
,
u16
timeout
,
u16
start_seq_num
,
u16
ba_policy
,
u16
tid
,
u16
buf_size
,
bool
tx
)
{
struct
ieee80211_local
*
local
=
sta
->
sdata
->
local
;
struct
tid_ampdu_rx
*
tid_agg_rx
;
u16
capab
,
tid
,
timeout
,
ba_policy
,
buf_size
,
start_seq_num
,
status
;
u8
dialog_token
;
int
ret
=
-
EOPNOTSUPP
;
/* extract session parameters from addba request frame */
dialog_token
=
mgmt
->
u
.
action
.
u
.
addba_req
.
dialog_token
;
timeout
=
le16_to_cpu
(
mgmt
->
u
.
action
.
u
.
addba_req
.
timeout
);
start_seq_num
=
le16_to_cpu
(
mgmt
->
u
.
action
.
u
.
addba_req
.
start_seq_num
)
>>
4
;
capab
=
le16_to_cpu
(
mgmt
->
u
.
action
.
u
.
addba_req
.
capab
);
ba_policy
=
(
capab
&
IEEE80211_ADDBA_PARAM_POLICY_MASK
)
>>
1
;
tid
=
(
capab
&
IEEE80211_ADDBA_PARAM_TID_MASK
)
>>
2
;
buf_size
=
(
capab
&
IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
)
>>
6
;
status
=
WLAN_STATUS_REQUEST_DECLINED
;
int
i
,
ret
=
-
EOPNOTSUPP
;
u16
status
=
WLAN_STATUS_REQUEST_DECLINED
;
if
(
test_sta_flag
(
sta
,
WLAN_STA_BLOCK_BA
))
{
ht_dbg
(
sta
->
sdata
,
...
...
@@ -264,7 +251,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
status
=
WLAN_STATUS_INVALID_QOS_PARAM
;
ht_dbg_ratelimited
(
sta
->
sdata
,
"AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d
\n
"
,
mgmt
->
sa
,
tid
,
ba_policy
,
buf_size
);
sta
->
sta
.
addr
,
tid
,
ba_policy
,
buf_size
);
goto
end_no_lock
;
}
/* determine default buffer size */
...
...
@@ -281,7 +268,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
if
(
sta
->
ampdu_mlme
.
tid_rx
[
tid
])
{
ht_dbg_ratelimited
(
sta
->
sdata
,
"unexpected AddBA Req from %pM on tid %u
\n
"
,
mgmt
->
sa
,
tid
);
sta
->
sta
.
addr
,
tid
);
/* delete existing Rx BA session on the same tid */
___ieee80211_stop_rx_ba_session
(
sta
,
tid
,
WLAN_BACK_RECIPIENT
,
...
...
@@ -308,7 +295,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
/* prepare reordering buffer */
tid_agg_rx
->
reorder_buf
=
kcalloc
(
buf_size
,
sizeof
(
struct
sk_buff
*
),
GFP_KERNEL
);
kcalloc
(
buf_size
,
sizeof
(
struct
sk_buff
_head
),
GFP_KERNEL
);
tid_agg_rx
->
reorder_time
=
kcalloc
(
buf_size
,
sizeof
(
unsigned
long
),
GFP_KERNEL
);
if
(
!
tid_agg_rx
->
reorder_buf
||
!
tid_agg_rx
->
reorder_time
)
{
...
...
@@ -318,6 +305,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
goto
end
;
}
for
(
i
=
0
;
i
<
buf_size
;
i
++
)
__skb_queue_head_init
(
&
tid_agg_rx
->
reorder_buf
[
i
]);
ret
=
drv_ampdu_action
(
local
,
sta
->
sdata
,
IEEE80211_AMPDU_RX_START
,
&
sta
->
sta
,
tid
,
&
start_seq_num
,
0
);
ht_dbg
(
sta
->
sdata
,
"Rx A-MPDU request on %pM tid %d result %d
\n
"
,
...
...
@@ -350,6 +340,74 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
mutex_unlock
(
&
sta
->
ampdu_mlme
.
mtx
);
end_no_lock:
ieee80211_send_addba_resp
(
sta
->
sdata
,
sta
->
sta
.
addr
,
tid
,
dialog_token
,
status
,
1
,
buf_size
,
timeout
);
if
(
tx
)
ieee80211_send_addba_resp
(
sta
->
sdata
,
sta
->
sta
.
addr
,
tid
,
dialog_token
,
status
,
1
,
buf_size
,
timeout
);
}
void
ieee80211_process_addba_request
(
struct
ieee80211_local
*
local
,
struct
sta_info
*
sta
,
struct
ieee80211_mgmt
*
mgmt
,
size_t
len
)
{
u16
capab
,
tid
,
timeout
,
ba_policy
,
buf_size
,
start_seq_num
;
u8
dialog_token
;
/* extract session parameters from addba request frame */
dialog_token
=
mgmt
->
u
.
action
.
u
.
addba_req
.
dialog_token
;
timeout
=
le16_to_cpu
(
mgmt
->
u
.
action
.
u
.
addba_req
.
timeout
);
start_seq_num
=
le16_to_cpu
(
mgmt
->
u
.
action
.
u
.
addba_req
.
start_seq_num
)
>>
4
;
capab
=
le16_to_cpu
(
mgmt
->
u
.
action
.
u
.
addba_req
.
capab
);
ba_policy
=
(
capab
&
IEEE80211_ADDBA_PARAM_POLICY_MASK
)
>>
1
;
tid
=
(
capab
&
IEEE80211_ADDBA_PARAM_TID_MASK
)
>>
2
;
buf_size
=
(
capab
&
IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
)
>>
6
;
__ieee80211_start_rx_ba_session
(
sta
,
dialog_token
,
timeout
,
start_seq_num
,
ba_policy
,
tid
,
buf_size
,
true
);
}
void
ieee80211_start_rx_ba_session_offl
(
struct
ieee80211_vif
*
vif
,
const
u8
*
addr
,
u16
tid
)
{
struct
ieee80211_sub_if_data
*
sdata
=
vif_to_sdata
(
vif
);
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_rx_agg
*
rx_agg
;
struct
sk_buff
*
skb
=
dev_alloc_skb
(
0
);
if
(
unlikely
(
!
skb
))
return
;
rx_agg
=
(
struct
ieee80211_rx_agg
*
)
&
skb
->
cb
;
memcpy
(
&
rx_agg
->
addr
,
addr
,
ETH_ALEN
);
rx_agg
->
tid
=
tid
;
skb
->
pkt_type
=
IEEE80211_SDATA_QUEUE_RX_AGG_START
;
skb_queue_tail
(
&
sdata
->
skb_queue
,
skb
);
ieee80211_queue_work
(
&
local
->
hw
,
&
sdata
->
work
);
}
EXPORT_SYMBOL
(
ieee80211_start_rx_ba_session_offl
);
void
ieee80211_stop_rx_ba_session_offl
(
struct
ieee80211_vif
*
vif
,
const
u8
*
addr
,
u16
tid
)
{
struct
ieee80211_sub_if_data
*
sdata
=
vif_to_sdata
(
vif
);
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_rx_agg
*
rx_agg
;
struct
sk_buff
*
skb
=
dev_alloc_skb
(
0
);
if
(
unlikely
(
!
skb
))
return
;
rx_agg
=
(
struct
ieee80211_rx_agg
*
)
&
skb
->
cb
;
memcpy
(
&
rx_agg
->
addr
,
addr
,
ETH_ALEN
);
rx_agg
->
tid
=
tid
;
skb
->
pkt_type
=
IEEE80211_SDATA_QUEUE_RX_AGG_STOP
;
skb_queue_tail
(
&
sdata
->
skb_queue
,
skb
);
ieee80211_queue_work
(
&
local
->
hw
,
&
sdata
->
work
);
}
EXPORT_SYMBOL
(
ieee80211_stop_rx_ba_session_offl
);
net/mac80211/chan.c
View file @
a006827a
...
...
@@ -66,7 +66,7 @@ static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local)
static
struct
ieee80211_chanctx
*
ieee80211_vif_get_chanctx
(
struct
ieee80211_sub_if_data
*
sdata
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
ieee80211_local
*
local
__maybe_unused
=
sdata
->
local
;
struct
ieee80211_chanctx_conf
*
conf
;
conf
=
rcu_dereference_protected
(
sdata
->
vif
.
chanctx_conf
,
...
...
net/mac80211/ht.c
View file @
a006827a
...
...
@@ -150,13 +150,12 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
/*
* If user has specified capability over-rides, take care
* of that if the station we're setting up is the AP that
* of that if the station we're setting up is the AP
or TDLS peer
that
* we advertised a restricted capability set to. Override
* our own capabilities and then use those below.
*/
if
((
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
||
sdata
->
vif
.
type
==
NL80211_IFTYPE_ADHOC
)
&&
!
test_sta_flag
(
sta
,
WLAN_STA_TDLS_PEER
))
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_STATION
||
sdata
->
vif
.
type
==
NL80211_IFTYPE_ADHOC
)
ieee80211_apply_htcap_overrides
(
sdata
,
&
own_cap
);
/*
...
...
@@ -228,6 +227,9 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
if
(
own_cap
.
mcs
.
rx_mask
[
32
/
8
]
&
ht_cap_ie
->
mcs
.
rx_mask
[
32
/
8
]
&
1
)
ht_cap
.
mcs
.
rx_mask
[
32
/
8
]
|=
1
;
/* set Rx highest rate */
ht_cap
.
mcs
.
rx_highest
=
ht_cap_ie
->
mcs
.
rx_highest
;
apply:
changed
=
memcmp
(
&
sta
->
sta
.
ht_cap
,
&
ht_cap
,
sizeof
(
ht_cap
));
...
...
net/mac80211/ibss.c
View file @
a006827a
...
...
@@ -189,17 +189,8 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
chandef
,
0
);
}
if
(
local
->
hw
.
queues
>=
IEEE80211_NUM_ACS
)
{
*
pos
++
=
WLAN_EID_VENDOR_SPECIFIC
;
*
pos
++
=
7
;
/* len */
*
pos
++
=
0x00
;
/* Microsoft OUI 00:50:F2 */
*
pos
++
=
0x50
;
*
pos
++
=
0xf2
;
*
pos
++
=
2
;
/* WME */
*
pos
++
=
0
;
/* WME info */
*
pos
++
=
1
;
/* WME ver */
*
pos
++
=
0
;
/* U-APSD no in use */
}
if
(
local
->
hw
.
queues
>=
IEEE80211_NUM_ACS
)
pos
=
ieee80211_add_wmm_info_ie
(
pos
,
0
);
/* U-APSD not in use */
presp
->
head_len
=
pos
-
presp
->
head
;
if
(
WARN_ON
(
presp
->
head_len
>
frame_len
))
...
...
net/mac80211/ieee80211_i.h
View file @
a006827a
...
...
@@ -345,7 +345,6 @@ enum ieee80211_sta_flags {
IEEE80211_STA_CONNECTION_POLL
=
BIT
(
1
),
IEEE80211_STA_CONTROL_PORT
=
BIT
(
2
),
IEEE80211_STA_DISABLE_HT
=
BIT
(
4
),
IEEE80211_STA_CSA_RECEIVED
=
BIT
(
5
),
IEEE80211_STA_MFP_ENABLED
=
BIT
(
6
),
IEEE80211_STA_UAPSD_ENABLED
=
BIT
(
7
),
IEEE80211_STA_NULLFUNC_ACKED
=
BIT
(
8
),
...
...
@@ -503,6 +502,9 @@ struct ieee80211_if_managed {
struct
ieee80211_ht_cap
ht_capa_mask
;
/* Valid parts of ht_capa */
struct
ieee80211_vht_cap
vht_capa
;
/* configured VHT overrides */
struct
ieee80211_vht_cap
vht_capa_mask
;
/* Valid parts of vht_capa */
u8
tdls_peer
[
ETH_ALEN
]
__aligned
(
2
);
struct
delayed_work
tdls_peer_del_work
;
};
struct
ieee80211_if_ibss
{
...
...
@@ -815,9 +817,6 @@ struct ieee80211_sub_if_data {
bool
radar_required
;
struct
delayed_work
dfs_cac_timer_work
;
u8
tdls_peer
[
ETH_ALEN
]
__aligned
(
2
);
struct
delayed_work
tdls_peer_del_work
;
/*
* AP this belongs to: self in AP mode and
* corresponding AP in VLAN mode, NULL for
...
...
@@ -926,10 +925,17 @@ ieee80211_vif_get_shift(struct ieee80211_vif *vif)
return
shift
;
}
struct
ieee80211_rx_agg
{
u8
addr
[
ETH_ALEN
];
u16
tid
;
};
enum
sdata_queue_type
{
IEEE80211_SDATA_QUEUE_TYPE_FRAME
=
0
,
IEEE80211_SDATA_QUEUE_AGG_START
=
1
,
IEEE80211_SDATA_QUEUE_AGG_STOP
=
2
,
IEEE80211_SDATA_QUEUE_RX_AGG_START
=
3
,
IEEE80211_SDATA_QUEUE_RX_AGG_STOP
=
4
,
};
enum
{
...
...
@@ -1578,6 +1584,10 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
u16
initiator
,
u16
reason
,
bool
stop
);
void
__ieee80211_stop_rx_ba_session
(
struct
sta_info
*
sta
,
u16
tid
,
u16
initiator
,
u16
reason
,
bool
stop
);
void
__ieee80211_start_rx_ba_session
(
struct
sta_info
*
sta
,
u8
dialog_token
,
u16
timeout
,
u16
start_seq_num
,
u16
ba_policy
,
u16
tid
,
u16
buf_size
,
bool
tx
);
void
ieee80211_sta_tear_down_BA_sessions
(
struct
sta_info
*
sta
,
enum
ieee80211_agg_stop_reason
reason
);
void
ieee80211_process_delba
(
struct
ieee80211_sub_if_data
*
sdata
,
...
...
@@ -1730,6 +1740,21 @@ static inline void ieee802_11_parse_elems(const u8 *start, size_t len,
ieee802_11_parse_elems_crc
(
start
,
len
,
action
,
elems
,
0
,
0
);
}
static
inline
bool
ieee80211_rx_reorder_ready
(
struct
sk_buff_head
*
frames
)
{
struct
sk_buff
*
tail
=
skb_peek_tail
(
frames
);
struct
ieee80211_rx_status
*
status
;
if
(
!
tail
)
return
false
;
status
=
IEEE80211_SKB_RXCB
(
tail
);
if
(
status
->
flag
&
RX_FLAG_AMSDU_MORE
)
return
false
;
return
true
;
}
void
ieee80211_dynamic_ps_enable_work
(
struct
work_struct
*
work
);
void
ieee80211_dynamic_ps_disable_work
(
struct
work_struct
*
work
);
void
ieee80211_dynamic_ps_timer
(
unsigned
long
data
);
...
...
@@ -1824,6 +1849,7 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata,
int
ieee80211_add_ext_srates_ie
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sk_buff
*
skb
,
bool
need_basic
,
enum
ieee80211_band
band
);
u8
*
ieee80211_add_wmm_info_ie
(
u8
*
buf
,
u8
qosinfo
);
/* channel management */
void
ieee80211_ht_oper_to_chandef
(
struct
ieee80211_channel
*
control_chan
,
...
...
net/mac80211/iface.c
View file @
a006827a
...
...
@@ -1140,6 +1140,7 @@ static void ieee80211_iface_work(struct work_struct *work)
struct
sk_buff
*
skb
;
struct
sta_info
*
sta
;
struct
ieee80211_ra_tid
*
ra_tid
;
struct
ieee80211_rx_agg
*
rx_agg
;
if
(
!
ieee80211_sdata_running
(
sdata
))
return
;
...
...
@@ -1167,6 +1168,34 @@ static void ieee80211_iface_work(struct work_struct *work)
ra_tid
=
(
void
*
)
&
skb
->
cb
;
ieee80211_stop_tx_ba_cb
(
&
sdata
->
vif
,
ra_tid
->
ra
,
ra_tid
->
tid
);
}
else
if
(
skb
->
pkt_type
==
IEEE80211_SDATA_QUEUE_RX_AGG_START
)
{
rx_agg
=
(
void
*
)
&
skb
->
cb
;
mutex_lock
(
&
local
->
sta_mtx
);
sta
=
sta_info_get_bss
(
sdata
,
rx_agg
->
addr
);
if
(
sta
)
{
u16
last_seq
;
last_seq
=
le16_to_cpu
(
sta
->
last_seq_ctrl
[
rx_agg
->
tid
]);
__ieee80211_start_rx_ba_session
(
sta
,
0
,
0
,
ieee80211_sn_inc
(
last_seq
),
1
,
rx_agg
->
tid
,
IEEE80211_MAX_AMPDU_BUF
,
false
);
}
mutex_unlock
(
&
local
->
sta_mtx
);
}
else
if
(
skb
->
pkt_type
==
IEEE80211_SDATA_QUEUE_RX_AGG_STOP
)
{
rx_agg
=
(
void
*
)
&
skb
->
cb
;
mutex_lock
(
&
local
->
sta_mtx
);
sta
=
sta_info_get_bss
(
sdata
,
rx_agg
->
addr
);
if
(
sta
)
__ieee80211_stop_rx_ba_session
(
sta
,
rx_agg
->
tid
,
WLAN_BACK_RECIPIENT
,
0
,
false
);
mutex_unlock
(
&
local
->
sta_mtx
);
}
else
if
(
ieee80211_is_action
(
mgmt
->
frame_control
)
&&
mgmt
->
u
.
action
.
category
==
WLAN_CATEGORY_BACK
)
{
int
len
=
skb
->
len
;
...
...
@@ -1672,8 +1701,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
ieee80211_dfs_cac_timer_work
);
INIT_DELAYED_WORK
(
&
sdata
->
dec_tailroom_needed_wk
,
ieee80211_delayed_tailroom_dec
);
INIT_DELAYED_WORK
(
&
sdata
->
tdls_peer_del_work
,
ieee80211_tdls_peer_del_work
);
for
(
i
=
0
;
i
<
IEEE80211_NUM_BANDS
;
i
++
)
{
struct
ieee80211_supported_band
*
sband
;
...
...
net/mac80211/key.c
View file @
a006827a
...
...
@@ -482,9 +482,6 @@ int ieee80211_key_link(struct ieee80211_key *key,
int
idx
,
ret
;
bool
pairwise
;
if
(
WARN_ON
(
!
sdata
||
!
key
))
return
-
EINVAL
;
pairwise
=
key
->
conf
.
flags
&
IEEE80211_KEY_FLAG_PAIRWISE
;
idx
=
key
->
conf
.
keyidx
;
key
->
local
=
sdata
->
local
;
...
...
net/mac80211/mlme.c
View file @
a006827a
...
...
@@ -830,16 +830,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
qos_info
=
0
;
}
pos
=
skb_put
(
skb
,
9
);
*
pos
++
=
WLAN_EID_VENDOR_SPECIFIC
;
*
pos
++
=
7
;
/* len */
*
pos
++
=
0x00
;
/* Microsoft OUI 00:50:F2 */
*
pos
++
=
0x50
;
*
pos
++
=
0xf2
;
*
pos
++
=
2
;
/* WME */
*
pos
++
=
0
;
/* WME info */
*
pos
++
=
1
;
/* WME ver */
*
pos
++
=
qos_info
;
pos
=
ieee80211_add_wmm_info_ie
(
skb_put
(
skb
,
9
),
qos_info
);
}
/* add any remaining custom (i.e. vendor specific here) IEs */
...
...
@@ -1005,8 +996,6 @@ static void ieee80211_chswitch_work(struct work_struct *work)
sdata
->
csa_block_tx
=
false
;
}
ifmgd
->
flags
&=
~
IEEE80211_STA_CSA_RECEIVED
;
ieee80211_sta_reset_beacon_monitor
(
sdata
);
ieee80211_sta_reset_conn_monitor
(
sdata
);
...
...
@@ -1064,7 +1053,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
return
;
/* disregard subsequent announcements if we are already processing */
if
(
ifmgd
->
flags
&
IEEE80211_STA_CSA_RECEIVED
)
if
(
sdata
->
vif
.
csa_active
)
return
;
current_band
=
cbss
->
channel
->
band
;
...
...
@@ -1091,8 +1080,6 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
return
;
}
ifmgd
->
flags
|=
IEEE80211_STA_CSA_RECEIVED
;
mutex_lock
(
&
local
->
mtx
);
mutex_lock
(
&
local
->
chanctx_mtx
);
conf
=
rcu_dereference_protected
(
sdata
->
vif
.
chanctx_conf
,
...
...
@@ -2108,8 +2095,6 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
ieee80211_set_disassoc
(
sdata
,
IEEE80211_STYPE_DEAUTH
,
WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY
,
true
,
frame_buf
);
ifmgd
->
flags
&=
~
IEEE80211_STA_CSA_RECEIVED
;
mutex_lock
(
&
local
->
mtx
);
sdata
->
vif
.
csa_active
=
false
;
if
(
sdata
->
csa_block_tx
)
{
...
...
@@ -3722,6 +3707,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
INIT_WORK
(
&
ifmgd
->
csa_connection_drop_work
,
ieee80211_csa_connection_drop_work
);
INIT_WORK
(
&
ifmgd
->
request_smps_work
,
ieee80211_request_smps_mgd_work
);
INIT_DELAYED_WORK
(
&
ifmgd
->
tdls_peer_del_work
,
ieee80211_tdls_peer_del_work
);
setup_timer
(
&
ifmgd
->
timer
,
ieee80211_sta_timer
,
(
unsigned
long
)
sdata
);
setup_timer
(
&
ifmgd
->
bcn_mon_timer
,
ieee80211_sta_bcn_mon_timer
,
...
...
@@ -4585,6 +4572,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
cancel_work_sync
(
&
ifmgd
->
request_smps_work
);
cancel_work_sync
(
&
ifmgd
->
csa_connection_drop_work
);
cancel_work_sync
(
&
ifmgd
->
chswitch_work
);
cancel_delayed_work_sync
(
&
ifmgd
->
tdls_peer_del_work
);
sdata_lock
(
sdata
);
if
(
ifmgd
->
assoc_data
)
{
...
...
net/mac80211/rx.c
View file @
a006827a
...
...
@@ -688,20 +688,27 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata,
int
index
,
struct
sk_buff_head
*
frames
)
{
struct
sk_buff
*
skb
=
tid_agg_rx
->
reorder_buf
[
index
];
struct
sk_buff_head
*
skb_list
=
&
tid_agg_rx
->
reorder_buf
[
index
];
struct
sk_buff
*
skb
;
struct
ieee80211_rx_status
*
status
;
lockdep_assert_held
(
&
tid_agg_rx
->
reorder_lock
);
if
(
!
skb
)
if
(
skb_queue_empty
(
skb_list
))
goto
no_frame
;
if
(
!
ieee80211_rx_reorder_ready
(
skb_list
))
{
__skb_queue_purge
(
skb_list
);
goto
no_frame
;
}
/* release
the frame
from the reorder ring buffer */
/* release
frames
from the reorder ring buffer */
tid_agg_rx
->
stored_mpdu_num
--
;
tid_agg_rx
->
reorder_buf
[
index
]
=
NULL
;
status
=
IEEE80211_SKB_RXCB
(
skb
);
status
->
rx_flags
|=
IEEE80211_RX_DEFERRED_RELEASE
;
__skb_queue_tail
(
frames
,
skb
);
while
((
skb
=
__skb_dequeue
(
skb_list
)))
{
status
=
IEEE80211_SKB_RXCB
(
skb
);
status
->
rx_flags
|=
IEEE80211_RX_DEFERRED_RELEASE
;
__skb_queue_tail
(
frames
,
skb
);
}
no_frame:
tid_agg_rx
->
head_seq_num
=
ieee80211_sn_inc
(
tid_agg_rx
->
head_seq_num
);
...
...
@@ -738,13 +745,13 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
struct
tid_ampdu_rx
*
tid_agg_rx
,
struct
sk_buff_head
*
frames
)
{
int
index
,
j
;
int
index
,
i
,
j
;
lockdep_assert_held
(
&
tid_agg_rx
->
reorder_lock
);
/* release the buffer until next missing frame */
index
=
tid_agg_rx
->
head_seq_num
%
tid_agg_rx
->
buf_size
;
if
(
!
tid_agg_rx
->
reorder_buf
[
index
]
&&
if
(
!
ieee80211_rx_reorder_ready
(
&
tid_agg_rx
->
reorder_buf
[
index
])
&&
tid_agg_rx
->
stored_mpdu_num
)
{
/*
* No buffers ready to be released, but check whether any
...
...
@@ -753,7 +760,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
int
skipped
=
1
;
for
(
j
=
(
index
+
1
)
%
tid_agg_rx
->
buf_size
;
j
!=
index
;
j
=
(
j
+
1
)
%
tid_agg_rx
->
buf_size
)
{
if
(
!
tid_agg_rx
->
reorder_buf
[
j
])
{
if
(
!
ieee80211_rx_reorder_ready
(
&
tid_agg_rx
->
reorder_buf
[
j
]))
{
skipped
++
;
continue
;
}
...
...
@@ -762,6 +770,11 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
HT_RX_REORDER_BUF_TIMEOUT
))
goto
set_release_timer
;
/* don't leave incomplete A-MSDUs around */
for
(
i
=
(
index
+
1
)
%
tid_agg_rx
->
buf_size
;
i
!=
j
;
i
=
(
i
+
1
)
%
tid_agg_rx
->
buf_size
)
__skb_queue_purge
(
&
tid_agg_rx
->
reorder_buf
[
i
]);
ht_dbg_ratelimited
(
sdata
,
"release an RX reorder frame due to timeout on earlier frames
\n
"
);
ieee80211_release_reorder_frame
(
sdata
,
tid_agg_rx
,
j
,
...
...
@@ -775,7 +788,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
skipped
)
&
IEEE80211_SN_MASK
;
skipped
=
0
;
}
}
else
while
(
tid_agg_rx
->
reorder_buf
[
index
])
{
}
else
while
(
ieee80211_rx_reorder_ready
(
&
tid_agg_rx
->
reorder_buf
[
index
]))
{
ieee80211_release_reorder_frame
(
sdata
,
tid_agg_rx
,
index
,
frames
);
index
=
tid_agg_rx
->
head_seq_num
%
tid_agg_rx
->
buf_size
;
...
...
@@ -786,7 +800,8 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
for
(;
j
!=
(
index
-
1
)
%
tid_agg_rx
->
buf_size
;
j
=
(
j
+
1
)
%
tid_agg_rx
->
buf_size
)
{
if
(
tid_agg_rx
->
reorder_buf
[
j
])
if
(
ieee80211_rx_reorder_ready
(
&
tid_agg_rx
->
reorder_buf
[
j
]))
break
;
}
...
...
@@ -811,6 +826,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
struct
sk_buff_head
*
frames
)
{
struct
ieee80211_hdr
*
hdr
=
(
struct
ieee80211_hdr
*
)
skb
->
data
;
struct
ieee80211_rx_status
*
status
=
IEEE80211_SKB_RXCB
(
skb
);
u16
sc
=
le16_to_cpu
(
hdr
->
seq_ctrl
);
u16
mpdu_seq_num
=
(
sc
&
IEEE80211_SCTL_SEQ
)
>>
4
;
u16
head_seq_num
,
buf_size
;
...
...
@@ -845,7 +861,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
index
=
mpdu_seq_num
%
tid_agg_rx
->
buf_size
;
/* check if we already stored this frame */
if
(
tid_agg_rx
->
reorder_buf
[
index
]
)
{
if
(
ieee80211_rx_reorder_ready
(
&
tid_agg_rx
->
reorder_buf
[
index
])
)
{
dev_kfree_skb
(
skb
);
goto
out
;
}
...
...
@@ -858,17 +874,20 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
*/
if
(
mpdu_seq_num
==
tid_agg_rx
->
head_seq_num
&&
tid_agg_rx
->
stored_mpdu_num
==
0
)
{
tid_agg_rx
->
head_seq_num
=
ieee80211_sn_inc
(
tid_agg_rx
->
head_seq_num
);
if
(
!
(
status
->
flag
&
RX_FLAG_AMSDU_MORE
))
tid_agg_rx
->
head_seq_num
=
ieee80211_sn_inc
(
tid_agg_rx
->
head_seq_num
);
ret
=
false
;
goto
out
;
}
/* put the frame in the reordering buffer */
tid_agg_rx
->
reorder_buf
[
index
]
=
skb
;
tid_agg_rx
->
reorder_time
[
index
]
=
jiffies
;
tid_agg_rx
->
stored_mpdu_num
++
;
ieee80211_sta_reorder_release
(
sdata
,
tid_agg_rx
,
frames
);
__skb_queue_tail
(
&
tid_agg_rx
->
reorder_buf
[
index
],
skb
);
if
(
!
(
status
->
flag
&
RX_FLAG_AMSDU_MORE
))
{
tid_agg_rx
->
reorder_time
[
index
]
=
jiffies
;
tid_agg_rx
->
stored_mpdu_num
++
;
ieee80211_sta_reorder_release
(
sdata
,
tid_agg_rx
,
frames
);
}
out:
spin_unlock
(
&
tid_agg_rx
->
reorder_lock
);
...
...
@@ -3129,6 +3148,14 @@ static bool prepare_for_handlers(struct ieee80211_rx_data *rx,
if
(
!
ieee80211_is_beacon
(
hdr
->
frame_control
))
return
false
;
status
->
rx_flags
&=
~
IEEE80211_RX_RA_MATCH
;
}
else
if
(
!
ieee80211_has_tods
(
hdr
->
frame_control
))
{
/* ignore data frames to TDLS-peers */
if
(
ieee80211_is_data
(
hdr
->
frame_control
))
return
false
;
/* ignore action frames to TDLS-peers */
if
(
ieee80211_is_action
(
hdr
->
frame_control
)
&&
!
ether_addr_equal
(
bssid
,
hdr
->
addr1
))
return
false
;
}
break
;
case
NL80211_IFTYPE_WDS
:
...
...
net/mac80211/sta_info.h
View file @
a006827a
...
...
@@ -47,6 +47,8 @@
* @WLAN_STA_TDLS_PEER: Station is a TDLS peer.
* @WLAN_STA_TDLS_PEER_AUTH: This TDLS peer is authorized to send direct
* packets. This means the link is enabled.
* @WLAN_STA_TDLS_INITIATOR: We are the initiator of the TDLS link with this
* station.
* @WLAN_STA_UAPSD: Station requested unscheduled SP while driver was
* keeping station in power-save mode, reply when the driver
* unblocks the station.
...
...
@@ -76,6 +78,7 @@ enum ieee80211_sta_info_flags {
WLAN_STA_PSPOLL
,
WLAN_STA_TDLS_PEER
,
WLAN_STA_TDLS_PEER_AUTH
,
WLAN_STA_TDLS_INITIATOR
,
WLAN_STA_UAPSD
,
WLAN_STA_SP
,
WLAN_STA_4ADDR_EVENT
,
...
...
@@ -152,7 +155,8 @@ struct tid_ampdu_tx {
/**
* struct tid_ampdu_rx - TID aggregation information (Rx).
*
* @reorder_buf: buffer to reorder incoming aggregated MPDUs
* @reorder_buf: buffer to reorder incoming aggregated MPDUs. An MPDU may be an
* A-MSDU with individually reported subframes.
* @reorder_time: jiffies when skb was added
* @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
* @reorder_timer: releases expired frames from the reorder buffer.
...
...
@@ -177,7 +181,7 @@ struct tid_ampdu_tx {
struct
tid_ampdu_rx
{
struct
rcu_head
rcu_head
;
spinlock_t
reorder_lock
;
struct
sk_buff
*
*
reorder_buf
;
struct
sk_buff
_head
*
reorder_buf
;
unsigned
long
*
reorder_time
;
struct
timer_list
session_timer
;
struct
timer_list
reorder_timer
;
...
...
net/mac80211/tdls.c
View file @
a006827a
This diff is collapsed.
Click to expand it.
net/mac80211/util.c
View file @
a006827a
...
...
@@ -3083,3 +3083,18 @@ int ieee80211_max_num_channels(struct ieee80211_local *local)
return
max_num_different_channels
;
}
u8
*
ieee80211_add_wmm_info_ie
(
u8
*
buf
,
u8
qosinfo
)
{
*
buf
++
=
WLAN_EID_VENDOR_SPECIFIC
;
*
buf
++
=
7
;
/* len */
*
buf
++
=
0x00
;
/* Microsoft OUI 00:50:F2 */
*
buf
++
=
0x50
;
*
buf
++
=
0xf2
;
*
buf
++
=
2
;
/* WME */
*
buf
++
=
0
;
/* WME info */
*
buf
++
=
1
;
/* WME ver */
*
buf
++
=
qosinfo
;
/* U-APSD no in use */
return
buf
;
}
net/mac80211/vht.c
View file @
a006827a
...
...
@@ -129,6 +129,10 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
if
(
!
vht_cap_ie
||
!
sband
->
vht_cap
.
vht_supported
)
return
;
/* don't support VHT for TDLS peers for now */
if
(
test_sta_flag
(
sta
,
WLAN_STA_TDLS_PEER
))
return
;
/*
* A VHT STA must support 40 MHz, but if we verify that here
* then we break a few things - some APs (e.g. Netgear R6300v2
...
...
net/mac80211/wpa.c
View file @
a006827a
...
...
@@ -811,7 +811,7 @@ ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx)
ieee80211_rx_result
ieee80211_crypto_hw_decrypt
(
struct
ieee80211_rx_data
*
rx
)
{
if
(
rx
->
sta
->
cipher_scheme
)
if
(
rx
->
sta
&&
rx
->
sta
->
cipher_scheme
)
return
ieee80211_crypto_cs_decrypt
(
rx
);
return
RX_DROP_UNUSABLE
;
...
...
net/wireless/Kconfig
View file @
a006827a
...
...
@@ -162,6 +162,12 @@ config CFG80211_INTERNAL_REGDB
and includes code to query that database. This is an alternative
to using CRDA for defining regulatory rules for the kernel.
Using this option requires some parsing of the db.txt at build time,
the parser will be upkept with the latest wireless-regdb updates but
older wireless-regdb formats will be ignored. The parser may later
be replaced to avoid issues with conflicts on versions of
wireless-regdb.
For details see:
http://wireless.kernel.org/en/developers/Regulatory
...
...
net/wireless/genregdb.awk
View file @
a006827a
...
...
@@ -51,32 +51,41 @@ function parse_country_head() {
function
parse_reg_rule
()
{
flag_starts_at
=
7
start
=
$1
sub
(
/
\(
/
,
""
,
start
)
end
=
$3
bw
=
$5
sub
(
/
\)
,/
,
""
,
bw
)
gain
=
$6
sub
(
/
\(
/
,
""
,
gain
)
sub
(
/,/
,
""
,
gain
)
power
=
$7
sub
(
/
\)
/
,
""
,
power
)
sub
(
/,/
,
""
,
power
)
gain
=
0
power
=
$6
# power might be in mW...
units
=
$8
units
=
$7
dfs_cac
=
0
sub
(
/
\(
/
,
""
,
power
)
sub
(
/
\)
,/
,
""
,
power
)
sub
(
/
\)
,/
,
""
,
units
)
sub
(
/
\)
/
,
""
,
units
)
sub
(
/,/
,
""
,
units
)
dfs_cac
=
$9
if
(
units
==
"mW"
)
{
flag_starts_at
=
8
power
=
10
*
log
(
power
)
/
log
(
10
)
if
(
$8
~
/
[
[:digit:
]
]/
)
{
flag_starts_at
=
9
dfs_cac
=
$8
}
}
else
{
dfs_cac
=
$8
if
(
$7
~
/
[
[:digit:
]
]/
)
{
flag_starts_at
=
8
dfs_cac
=
$7
}
}
sub
(
/,/
,
""
,
dfs_cac
)
sub
(
/
\(
/
,
""
,
dfs_cac
)
sub
(
/
\)
/
,
""
,
dfs_cac
)
sub
(
/
\)
,
/
,
""
,
dfs_cac
)
flagstr
=
""
for
(
i
=
8
;
i
<=
NF
;
i
++
)
for
(
i
=
flag_starts_at
;
i
<=
NF
;
i
++
)
flagstr
=
flagstr
$i
split
(
flagstr
,
flagarray
,
","
)
flags
=
""
...
...
net/wireless/nl80211.c
View file @
a006827a
...
...
@@ -3814,7 +3814,8 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
{
if
(
params
->
listen_interval
!=
-
1
)
return
-
EINVAL
;
if
(
params
->
aid
)
if
(
params
->
aid
&&
!
(
params
->
sta_flags_set
&
BIT
(
NL80211_STA_FLAG_TDLS_PEER
)))
return
-
EINVAL
;
/* When you run into this, adjust the code below for the new flag */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment