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
20fb9e50
Commit
20fb9e50
authored
Jan 30, 2013
by
John W. Linville
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-john' of
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
parents
0f496df2
3b4797bc
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
576 additions
and
178 deletions
+576
-178
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+2
-3
drivers/net/wireless/iwlwifi/dvm/mac80211.c
drivers/net/wireless/iwlwifi/dvm/mac80211.c
+1
-0
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/main.c
+1
-2
include/linux/ieee80211.h
include/linux/ieee80211.h
+4
-1
include/net/cfg80211.h
include/net/cfg80211.h
+38
-4
include/net/mac80211.h
include/net/mac80211.h
+24
-7
include/uapi/linux/nl80211.h
include/uapi/linux/nl80211.h
+49
-2
net/mac80211/agg-rx.c
net/mac80211/agg-rx.c
+9
-5
net/mac80211/agg-tx.c
net/mac80211/agg-tx.c
+37
-24
net/mac80211/driver-ops.h
net/mac80211/driver-ops.h
+33
-3
net/mac80211/ieee80211_i.h
net/mac80211/ieee80211_i.h
+1
-2
net/mac80211/iface.c
net/mac80211/iface.c
+0
-3
net/mac80211/key.c
net/mac80211/key.c
+4
-1
net/mac80211/main.c
net/mac80211/main.c
+52
-12
net/mac80211/mesh_plink.c
net/mac80211/mesh_plink.c
+104
-64
net/mac80211/mlme.c
net/mac80211/mlme.c
+14
-28
net/mac80211/sta_info.c
net/mac80211/sta_info.c
+0
-5
net/mac80211/trace.h
net/mac80211/trace.h
+46
-7
net/mac80211/tx.c
net/mac80211/tx.c
+4
-4
net/wireless/core.c
net/wireless/core.c
+5
-0
net/wireless/nl80211.c
net/wireless/nl80211.c
+116
-0
net/wireless/rdev-ops.h
net/wireless/rdev-ops.h
+12
-0
net/wireless/trace.h
net/wireless/trace.h
+18
-0
net/wireless/util.c
net/wireless/util.c
+2
-1
No files found.
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
View file @
20fb9e50
...
...
@@ -542,9 +542,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
if
(
changed
&
BSS_CHANGED_ARP_FILTER
)
{
/* Hardware ARP filter address list or state changed */
brcms_err
(
core
,
"%s: arp filtering: enabled %s, count %d"
" (implement)
\n
"
,
__func__
,
info
->
arp_filter_enabled
?
"true"
:
"false"
,
info
->
arp_addr_cnt
);
brcms_err
(
core
,
"%s: arp filtering: %d addresses"
" (implement)
\n
"
,
__func__
,
info
->
arp_addr_cnt
);
}
if
(
changed
&
BSS_CHANGED_QOS
)
{
...
...
drivers/net/wireless/iwlwifi/dvm/mac80211.c
View file @
20fb9e50
...
...
@@ -1154,6 +1154,7 @@ static int iwlagn_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
}
static
void
iwlagn_mac_rssi_callback
(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
)
{
struct
iwl_priv
*
priv
=
IWL_MAC80211_GET_DVM
(
hw
);
...
...
drivers/net/wireless/ti/wlcore/main.c
View file @
20fb9e50
...
...
@@ -4239,8 +4239,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
wlvif
->
sta
.
qos
=
bss_conf
->
qos
;
WARN_ON
(
wlvif
->
bss_type
!=
BSS_TYPE_STA_BSS
);
if
(
bss_conf
->
arp_addr_cnt
==
1
&&
bss_conf
->
arp_filter_enabled
)
{
if
(
bss_conf
->
arp_addr_cnt
==
1
&&
bss_conf
->
assoc
)
{
wlvif
->
ip_addr
=
addr
;
/*
* The template should have been configured only upon
...
...
include/linux/ieee80211.h
View file @
20fb9e50
...
...
@@ -1898,7 +1898,10 @@ enum ieee80211_sa_query_action {
/* AKM suite selectors */
#define WLAN_AKM_SUITE_8021X 0x000FAC01
#define WLAN_AKM_SUITE_PSK 0x000FAC02
#define WLAN_AKM_SUITE_SAE 0x000FAC08
#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
#define WLAN_AKM_SUITE_TDLS 0x000FAC07
#define WLAN_AKM_SUITE_SAE 0x000FAC08
#define WLAN_AKM_SUITE_FT_OVER_SAE 0x000FAC09
#define WLAN_MAX_KEY_LEN 32
...
...
include/net/cfg80211.h
View file @
20fb9e50
...
...
@@ -527,6 +527,26 @@ struct cfg80211_beacon_data {
size_t
probe_resp_len
;
};
struct
mac_address
{
u8
addr
[
ETH_ALEN
];
};
/**
* struct cfg80211_acl_data - Access control list data
*
* @acl_policy: ACL policy to be applied on the station's
entry specified by mac_addr
* @n_acl_entries: Number of MAC address entries passed
* @mac_addrs: List of MAC addresses of stations to be used for ACL
*/
struct
cfg80211_acl_data
{
enum
nl80211_acl_policy
acl_policy
;
int
n_acl_entries
;
/* Keep it last */
struct
mac_address
mac_addrs
[];
};
/**
* struct cfg80211_ap_settings - AP configuration
*
...
...
@@ -546,6 +566,8 @@ struct cfg80211_beacon_data {
* @inactivity_timeout: time in seconds to determine station's inactivity.
* @p2p_ctwindow: P2P CT Window
* @p2p_opp_ps: P2P opportunistic PS
* @acl: ACL configuration used by the drivers which has support for
* MAC address based access control
*/
struct
cfg80211_ap_settings
{
struct
cfg80211_chan_def
chandef
;
...
...
@@ -562,6 +584,7 @@ struct cfg80211_ap_settings {
int
inactivity_timeout
;
u8
p2p_ctwindow
;
bool
p2p_opp_ps
;
const
struct
cfg80211_acl_data
*
acl
;
};
/**
...
...
@@ -1796,6 +1819,13 @@ struct cfg80211_gtk_rekey_data {
*
* @start_p2p_device: Start the given P2P device.
* @stop_p2p_device: Stop the given P2P device.
*
* @set_mac_acl: Sets MAC address control list in AP and P2P GO mode.
* Parameters include ACL policy, an array of MAC address of stations
* and the number of MAC addresses. If there is already a list in driver
* this new list replaces the existing one. Driver has to clear its ACL
* when number of MAC addresses entries is passed as 0. Drivers which
* advertise the support for MAC based ACL have to implement this callback.
*/
struct
cfg80211_ops
{
int
(
*
suspend
)(
struct
wiphy
*
wiphy
,
struct
cfg80211_wowlan
*
wow
);
...
...
@@ -2016,6 +2046,9 @@ struct cfg80211_ops {
struct
wireless_dev
*
wdev
);
void
(
*
stop_p2p_device
)(
struct
wiphy
*
wiphy
,
struct
wireless_dev
*
wdev
);
int
(
*
set_mac_acl
)(
struct
wiphy
*
wiphy
,
struct
net_device
*
dev
,
const
struct
cfg80211_acl_data
*
params
);
};
/*
...
...
@@ -2181,10 +2214,6 @@ struct ieee80211_iface_combination {
u8
radar_detect_widths
;
};
struct
mac_address
{
u8
addr
[
ETH_ALEN
];
};
struct
ieee80211_txrx_stypes
{
u16
tx
,
rx
;
};
...
...
@@ -2325,6 +2354,9 @@ struct wiphy_wowlan_support {
* @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features.
* @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden.
* If null, then none can be over-ridden.
*
* @max_acl_mac_addrs: Maximum number of MAC addresses that the device
* supports for ACL.
*/
struct
wiphy
{
/* assign these fields before you register the wiphy */
...
...
@@ -2346,6 +2378,8 @@ struct wiphy {
/* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
u16
interface_modes
;
u16
max_acl_mac_addrs
;
u32
flags
,
features
;
u32
ap_sme_capa
;
...
...
include/net/mac80211.h
View file @
20fb9e50
...
...
@@ -297,11 +297,9 @@ enum ieee80211_rssi_event {
* may filter ARP queries targeted for other addresses than listed here.
* The driver must allow ARP queries targeted for all address listed here
* to pass through. An empty list implies no ARP queries need to pass.
* @arp_addr_cnt: Number of addresses currently on the list.
* @arp_filter_enabled: Enable ARP filtering - if enabled, the hardware may
* filter ARP queries based on the @arp_addr_list, if disabled, the
* hardware must not perform any ARP filtering. Note, that the filter will
* be enabled also in promiscuous mode.
* @arp_addr_cnt: Number of addresses currently on the list. Note that this
* may be larger than %IEEE80211_BSS_ARP_ADDR_LIST_LEN (the arp_addr_list
* array size), it's up to the driver what to do in that case.
* @qos: This is a QoS-enabled BSS.
* @idle: This interface is idle. There's also a global idle flag in the
* hardware config which may be more appropriate depending on what
...
...
@@ -338,8 +336,7 @@ struct ieee80211_bss_conf {
u32
cqm_rssi_hyst
;
struct
cfg80211_chan_def
chandef
;
__be32
arp_addr_list
[
IEEE80211_BSS_ARP_ADDR_LIST_LEN
];
u8
arp_addr_cnt
;
bool
arp_filter_enabled
;
int
arp_addr_cnt
;
bool
qos
;
bool
idle
;
bool
ps
;
...
...
@@ -1630,6 +1627,10 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb);
* rekeying), it will not include a valid phase 1 key. The valid phase 1 key is
* provided by update_tkip_key only. The trigger that makes mac80211 call this
* handler is software decryption with wrap around of iv16.
*
* The set_default_unicast_key() call updates the default WEP key index
* configured to the hardware for WEP encryption type. This is required
* for devices that support offload of data packets (e.g. ARP responses).
*/
/**
...
...
@@ -2208,6 +2209,10 @@ enum ieee80211_rate_control_changed {
* After rekeying was done it should (for example during resume) notify
* userspace of the new replay counter using ieee80211_gtk_rekey_notify().
*
* @set_default_unicast_key: Set the default (unicast) key index, useful for
* WEP when the device sends data packets autonomously, e.g. for ARP
* offloading. The index can be 0-3, or -1 for unsetting it.
*
* @hw_scan: Ask the hardware to service the scan request, no need to start
* the scan state machine in stack. The scan must honour the channel
* configuration done by the regulatory agent in the wiphy's
...
...
@@ -2492,6 +2497,9 @@ enum ieee80211_rate_control_changed {
* driver's resume function returned 1, as this is just like an "inline"
* hardware restart. This callback may sleep.
*
* @ipv6_addr_change: IPv6 address assignment on the given interface changed.
* Currently, this is only called for managed or P2P client interfaces.
* This callback is optional; it must not sleep.
*/
struct
ieee80211_ops
{
void
(
*
tx
)(
struct
ieee80211_hw
*
hw
,
...
...
@@ -2539,6 +2547,8 @@ struct ieee80211_ops {
void
(
*
set_rekey_data
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_gtk_rekey_data
*
data
);
void
(
*
set_default_unicast_key
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
int
idx
);
int
(
*
hw_scan
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
cfg80211_scan_request
*
req
);
void
(
*
cancel_hw_scan
)(
struct
ieee80211_hw
*
hw
,
...
...
@@ -2623,6 +2633,7 @@ struct ieee80211_ops {
int
(
*
set_bitrate_mask
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
const
struct
cfg80211_bitrate_mask
*
mask
);
void
(
*
rssi_callback
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
enum
ieee80211_rssi_event
rssi_event
);
void
(
*
allow_buffered_frames
)(
struct
ieee80211_hw
*
hw
,
...
...
@@ -2665,6 +2676,12 @@ struct ieee80211_ops {
struct
ieee80211_chanctx_conf
*
ctx
);
void
(
*
restart_complete
)(
struct
ieee80211_hw
*
hw
);
#if IS_ENABLED(CONFIG_IPV6)
void
(
*
ipv6_addr_change
)(
struct
ieee80211_hw
*
hw
,
struct
ieee80211_vif
*
vif
,
struct
inet6_dev
*
idev
);
#endif
};
/**
...
...
include/uapi/linux/nl80211.h
View file @
20fb9e50
...
...
@@ -170,7 +170,8 @@
* %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE,
* %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS,
* %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY,
* %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT.
* %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT,
* %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS.
* The channel to use can be set on the interface or be given using the
* %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width.
* @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP
...
...
@@ -586,6 +587,16 @@
* @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames
* for IBSS or MESH vif.
*
* @NL80211_CMD_SET_MAC_ACL: sets ACL for MAC address based access control.
* This is to be used with the drivers advertising the support of MAC
* address based access control. List of MAC addresses is passed in
* %NL80211_ATTR_MAC_ADDRS and ACL policy is passed in
* %NL80211_ATTR_ACL_POLICY. Driver will enable ACL with this list, if it
* is not already done. The new list will replace any existing list. Driver
* will clear its ACL when the list of MAC addresses passed is empty. This
* command is used in AP/P2P GO mode. Driver has to make sure to clear its
* ACL list during %NL80211_CMD_STOP_AP.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
...
...
@@ -736,6 +747,8 @@ enum nl80211_commands {
NL80211_CMD_SET_MCAST_RATE
,
NL80211_CMD_SET_MAC_ACL
,
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
...
...
@@ -1313,6 +1326,16 @@ enum nl80211_commands {
* @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode
* defined in &enum nl80211_mesh_power_mode.
*
* @NL80211_ATTR_ACL_POLICY: ACL policy, see &enum nl80211_acl_policy,
* carried in a u32 attribute
*
* @NL80211_ATTR_MAC_ADDRS: Array of nested MAC addresses, used for
* MAC ACL.
*
* @NL80211_ATTR_MAC_ACL_MAX: u32 attribute to advertise the maximum
* number of MAC addresses that a device can support for MAC
* ACL.
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
...
...
@@ -1585,6 +1608,12 @@ enum nl80211_attrs {
NL80211_ATTR_LOCAL_MESH_POWER_MODE
,
NL80211_ATTR_ACL_POLICY
,
NL80211_ATTR_MAC_ADDRS
,
NL80211_ATTR_MAC_ACL_MAX
,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST
,
...
...
@@ -3248,7 +3277,7 @@ enum nl80211_probe_resp_offload_support_attr {
* enum nl80211_connect_failed_reason - connection request failed reasons
* @NL80211_CONN_FAIL_MAX_CLIENTS: Maximum number of clients that can be
* handled by the AP is reached.
* @NL80211_CONN_FAIL_BLOCKED_CLIENT: C
lient's MAC is in the AP's blocklist
.
* @NL80211_CONN_FAIL_BLOCKED_CLIENT: C
onnection request is rejected due to ACL
.
*/
enum
nl80211_connect_failed_reason
{
NL80211_CONN_FAIL_MAX_CLIENTS
,
...
...
@@ -3276,4 +3305,22 @@ enum nl80211_scan_flags {
NL80211_SCAN_FLAG_AP
=
1
<<
2
,
};
/**
* enum nl80211_acl_policy - access control policy
*
* Access control policy is applied on a MAC list set by
* %NL80211_CMD_START_AP and %NL80211_CMD_SET_MAC_ACL, to
* be used with %NL80211_ATTR_ACL_POLICY.
*
* @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
* listed in ACL, i.e. allow all the stations which are not listed
* in ACL to authenticate.
* @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow the stations which are listed
* in ACL, i.e. deny all the stations which are not listed in ACL.
*/
enum
nl80211_acl_policy
{
NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED
,
NL80211_ACL_POLICY_DENY_UNLESS_LISTED
,
};
#endif
/* __LINUX_NL80211_H */
net/mac80211/agg-rx.c
View file @
20fb9e50
...
...
@@ -83,8 +83,8 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
if
(
drv_ampdu_action
(
local
,
sta
->
sdata
,
IEEE80211_AMPDU_RX_STOP
,
&
sta
->
sta
,
tid
,
NULL
,
0
))
sdata_info
(
sta
->
sdata
,
"HW problem - can not stop rx aggregation for tid %d
\n
"
,
tid
);
"HW problem - can not stop rx aggregation for
%pM
tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
/* check if this is a self generated aggregation halt */
if
(
initiator
==
WLAN_BACK_RECIPIENT
&&
tx
)
...
...
@@ -159,7 +159,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
}
rcu_read_unlock
();
ht_dbg
(
sta
->
sdata
,
"rx session timer expired on tid %d
\n
"
,
(
u16
)
*
ptid
);
ht_dbg
(
sta
->
sdata
,
"RX session timer expired on %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
(
u16
)
*
ptid
);
set_bit
(
*
ptid
,
sta
->
ampdu_mlme
.
tid_rx_timer_expired
);
ieee80211_queue_work
(
&
sta
->
local
->
hw
,
&
sta
->
ampdu_mlme
.
work
);
...
...
@@ -247,7 +248,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
status
=
WLAN_STATUS_REQUEST_DECLINED
;
if
(
test_sta_flag
(
sta
,
WLAN_STA_BLOCK_BA
))
{
ht_dbg
(
sta
->
sdata
,
"Suspend in progress - Denying ADDBA request
\n
"
);
ht_dbg
(
sta
->
sdata
,
"Suspend in progress - Denying ADDBA request (%pM tid %d)
\n
"
,
sta
->
sta
.
addr
,
tid
);
goto
end_no_lock
;
}
...
...
@@ -317,7 +320,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
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 tid %d result %d
\n
"
,
tid
,
ret
);
ht_dbg
(
sta
->
sdata
,
"Rx A-MPDU request on %pM tid %d result %d
\n
"
,
sta
->
sta
.
addr
,
tid
,
ret
);
if
(
ret
)
{
kfree
(
tid_agg_rx
->
reorder_buf
);
kfree
(
tid_agg_rx
->
reorder_time
);
...
...
net/mac80211/agg-tx.c
View file @
20fb9e50
...
...
@@ -296,7 +296,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
,
&
sta
->
sta
,
tid
,
NULL
,
0
);
WARN_ON_ONCE
(
ret
);
goto
remove_tid_tx
;
return
0
;
}
if
(
test_bit
(
HT_AGG_STATE_WANT_START
,
&
tid_tx
->
state
))
{
...
...
@@ -354,12 +354,15 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
*/
}
if
(
reason
==
AGG_STOP_DESTROY_STA
)
{
remove_tid_tx:
spin_lock_bh
(
&
sta
->
lock
);
ieee80211_remove_tid_tx
(
sta
,
tid
);
spin_unlock_bh
(
&
sta
->
lock
);
}
/*
* In the case of AGG_STOP_DESTROY_STA, the driver won't
* necessarily call ieee80211_stop_tx_ba_cb(), so this may
* seem like we can leave the tid_tx data pending forever.
* This is true, in a way, but "forever" is only until the
* station struct is actually destroyed. In the meantime,
* leaving it around ensures that we don't transmit packets
* to the driver on this TID which might confuse it.
*/
return
0
;
}
...
...
@@ -387,12 +390,13 @@ static void sta_addba_resp_timer_expired(unsigned long data)
test_bit
(
HT_AGG_STATE_RESPONSE_RECEIVED
,
&
tid_tx
->
state
))
{
rcu_read_unlock
();
ht_dbg
(
sta
->
sdata
,
"timer expired on tid %d but we are not (or no longer) expecting addBA response there
\n
"
,
tid
);
"timer expired on
%pM
tid %d but we are not (or no longer) expecting addBA response there
\n
"
,
sta
->
sta
.
addr
,
tid
);
return
;
}
ht_dbg
(
sta
->
sdata
,
"addBA response timer expired on tid %d
\n
"
,
tid
);
ht_dbg
(
sta
->
sdata
,
"addBA response timer expired on %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
ieee80211_stop_tx_ba_session
(
&
sta
->
sta
,
tid
);
rcu_read_unlock
();
...
...
@@ -429,7 +433,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
&
sta
->
sta
,
tid
,
&
start_seq_num
,
0
);
if
(
ret
)
{
ht_dbg
(
sdata
,
"BA request denied - HW unavailable for tid %d
\n
"
,
tid
);
"BA request denied - HW unavailable for %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
spin_lock_bh
(
&
sta
->
lock
);
ieee80211_agg_splice_packets
(
sdata
,
tid_tx
,
tid
);
ieee80211_assign_tid_tx
(
sta
,
tid
,
NULL
);
...
...
@@ -442,7 +447,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid)
/* activate the timer for the recipient's addBA response */
mod_timer
(
&
tid_tx
->
addba_resp_timer
,
jiffies
+
ADDBA_RESP_INTERVAL
);
ht_dbg
(
sdata
,
"activated addBA response timer on tid %d
\n
"
,
tid
);
ht_dbg
(
sdata
,
"activated addBA response timer on %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
spin_lock_bh
(
&
sta
->
lock
);
sta
->
ampdu_mlme
.
last_addba_req_time
[
tid
]
=
jiffies
;
...
...
@@ -489,7 +495,8 @@ static void sta_tx_agg_session_timer_expired(unsigned long data)
rcu_read_unlock
();
ht_dbg
(
sta
->
sdata
,
"tx session timer expired on tid %d
\n
"
,
(
u16
)
*
ptid
);
ht_dbg
(
sta
->
sdata
,
"tx session timer expired on %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
(
u16
)
*
ptid
);
ieee80211_stop_tx_ba_session
(
&
sta
->
sta
,
*
ptid
);
}
...
...
@@ -525,7 +532,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
if
(
test_sta_flag
(
sta
,
WLAN_STA_BLOCK_BA
))
{
ht_dbg
(
sdata
,
"BA sessions blocked - Denying BA session request
\n
"
);
"BA sessions blocked - Denying BA session request %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
return
-
EINVAL
;
}
...
...
@@ -566,8 +574,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
time_before
(
jiffies
,
sta
->
ampdu_mlme
.
last_addba_req_time
[
tid
]
+
HT_AGG_RETRIES_PERIOD
))
{
ht_dbg
(
sdata
,
"BA request denied - waiting a grace period after %d failed requests on tid %u
\n
"
,
sta
->
ampdu_mlme
.
addba_req_num
[
tid
],
tid
);
"BA request denied - waiting a grace period after %d failed requests on
%pM
tid %u
\n
"
,
sta
->
ampdu_mlme
.
addba_req_num
[
tid
],
sta
->
sta
.
addr
,
tid
);
ret
=
-
EBUSY
;
goto
err_unlock_sta
;
}
...
...
@@ -576,8 +584,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
/* check if the TID is not in aggregation flow already */
if
(
tid_tx
||
sta
->
ampdu_mlme
.
tid_start_tx
[
tid
])
{
ht_dbg
(
sdata
,
"BA request denied - session is not idle on tid %u
\n
"
,
tid
);
"BA request denied - session is not idle on
%pM
tid %u
\n
"
,
sta
->
sta
.
addr
,
tid
);
ret
=
-
EAGAIN
;
goto
err_unlock_sta
;
}
...
...
@@ -632,7 +640,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
tid_tx
=
rcu_dereference_protected_tid_tx
(
sta
,
tid
);
ht_dbg
(
sta
->
sdata
,
"Aggregation is on for tid %d
\n
"
,
tid
);
ht_dbg
(
sta
->
sdata
,
"Aggregation is on for %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
drv_ampdu_action
(
local
,
sta
->
sdata
,
IEEE80211_AMPDU_TX_OPERATIONAL
,
...
...
@@ -802,7 +811,9 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
tid_tx
=
rcu_dereference_protected_tid_tx
(
sta
,
tid
);
if
(
!
tid_tx
||
!
test_bit
(
HT_AGG_STATE_STOPPING
,
&
tid_tx
->
state
))
{
ht_dbg
(
sdata
,
"unexpected callback to A-MPDU stop
\n
"
);
ht_dbg
(
sdata
,
"unexpected callback to A-MPDU stop for %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
goto
unlock_sta
;
}
...
...
@@ -861,13 +872,15 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
goto
out
;
if
(
mgmt
->
u
.
action
.
u
.
addba_resp
.
dialog_token
!=
tid_tx
->
dialog_token
)
{
ht_dbg
(
sta
->
sdata
,
"wrong addBA response token, tid %d
\n
"
,
tid
);
ht_dbg
(
sta
->
sdata
,
"wrong addBA response token, %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
goto
out
;
}
del_timer_sync
(
&
tid_tx
->
addba_resp_timer
);
ht_dbg
(
sta
->
sdata
,
"switched off addBA timer for tid %d
\n
"
,
tid
);
ht_dbg
(
sta
->
sdata
,
"switched off addBA timer for %pM tid %d
\n
"
,
sta
->
sta
.
addr
,
tid
);
/*
* addba_resp_timer may have fired before we got here, and
...
...
@@ -877,8 +890,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
if
(
test_bit
(
HT_AGG_STATE_WANT_STOP
,
&
tid_tx
->
state
)
||
test_bit
(
HT_AGG_STATE_STOPPING
,
&
tid_tx
->
state
))
{
ht_dbg
(
sta
->
sdata
,
"got addBA resp for tid %d but we already gave up
\n
"
,
tid
);
"got addBA resp for
%pM
tid %d but we already gave up
\n
"
,
sta
->
sta
.
addr
,
tid
);
goto
out
;
}
...
...
net/mac80211/driver-ops.h
View file @
20fb9e50
...
...
@@ -569,7 +569,8 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local,
check_sdata_in_driver
(
sdata
);
WARN_ON
(
changed
&
IEEE80211_RC_SUPP_RATES_CHANGED
&&
sdata
->
vif
.
type
!=
NL80211_IFTYPE_ADHOC
);
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_ADHOC
&&
sdata
->
vif
.
type
!=
NL80211_IFTYPE_MESH_POINT
));
trace_drv_sta_rc_update
(
local
,
sdata
,
sta
,
changed
);
if
(
local
->
ops
->
sta_rc_update
)
...
...
@@ -845,11 +846,12 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
}
static
inline
void
drv_rssi_callback
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
const
enum
ieee80211_rssi_event
event
)
{
trace_drv_rssi_callback
(
local
,
event
);
trace_drv_rssi_callback
(
local
,
sdata
,
event
);
if
(
local
->
ops
->
rssi_callback
)
local
->
ops
->
rssi_callback
(
&
local
->
hw
,
event
);
local
->
ops
->
rssi_callback
(
&
local
->
hw
,
&
sdata
->
vif
,
event
);
trace_drv_return_void
(
local
);
}
...
...
@@ -1020,4 +1022,32 @@ static inline void drv_restart_complete(struct ieee80211_local *local)
trace_drv_return_void
(
local
);
}
static
inline
void
drv_set_default_unicast_key
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
int
key_idx
)
{
check_sdata_in_driver
(
sdata
);
WARN_ON_ONCE
(
key_idx
<
-
1
||
key_idx
>
3
);
trace_drv_set_default_unicast_key
(
local
,
sdata
,
key_idx
);
if
(
local
->
ops
->
set_default_unicast_key
)
local
->
ops
->
set_default_unicast_key
(
&
local
->
hw
,
&
sdata
->
vif
,
key_idx
);
trace_drv_return_void
(
local
);
}
#if IS_ENABLED(CONFIG_IPV6)
static
inline
void
drv_ipv6_addr_change
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
struct
inet6_dev
*
idev
)
{
trace_drv_ipv6_addr_change
(
local
,
sdata
);
if
(
local
->
ops
->
ipv6_addr_change
)
local
->
ops
->
ipv6_addr_change
(
&
local
->
hw
,
&
sdata
->
vif
,
idev
);
trace_drv_return_void
(
local
);
}
#endif
#endif
/* __MAC80211_DRIVER_OPS */
net/mac80211/ieee80211_i.h
View file @
20fb9e50
...
...
@@ -747,8 +747,6 @@ struct ieee80211_sub_if_data {
struct
work_struct
work
;
struct
sk_buff_head
skb_queue
;
bool
arp_filter_state
;
u8
needed_rx_chains
;
enum
ieee80211_smps_mode
smps_mode
;
...
...
@@ -1129,6 +1127,7 @@ struct ieee80211_local {
struct
timer_list
dynamic_ps_timer
;
struct
notifier_block
network_latency_notifier
;
struct
notifier_block
ifa_notifier
;
struct
notifier_block
ifa6_notifier
;
/*
* The dynamic ps timeout configured from user space via WEXT -
...
...
net/mac80211/iface.c
View file @
20fb9e50
...
...
@@ -1574,9 +1574,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
/* initialise type-independent data */
sdata
->
wdev
.
wiphy
=
local
->
hw
.
wiphy
;
sdata
->
local
=
local
;
#ifdef CONFIG_INET
sdata
->
arp_filter_state
=
true
;
#endif
for
(
i
=
0
;
i
<
IEEE80211_FRAGMENT_MAX
;
i
++
)
skb_queue_head_init
(
&
sdata
->
fragments
[
i
].
skb_list
);
...
...
net/mac80211/key.c
View file @
20fb9e50
...
...
@@ -204,8 +204,11 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
if
(
idx
>=
0
&&
idx
<
NUM_DEFAULT_KEYS
)
key
=
key_mtx_dereference
(
sdata
->
local
,
sdata
->
keys
[
idx
]);
if
(
uni
)
if
(
uni
)
{
rcu_assign_pointer
(
sdata
->
default_unicast_key
,
key
);
drv_set_default_unicast_key
(
sdata
->
local
,
sdata
,
idx
);
}
if
(
multi
)
rcu_assign_pointer
(
sdata
->
default_multicast_key
,
key
);
...
...
net/mac80211/main.c
View file @
20fb9e50
...
...
@@ -23,6 +23,7 @@
#include <linux/inetdevice.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
#include <net/addrconf.h>
#include "ieee80211_i.h"
#include "driver-ops.h"
...
...
@@ -349,27 +350,19 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
/* Copy the addresses to the bss_conf list */
ifa
=
idev
->
ifa_list
;
while
(
c
<
IEEE80211_BSS_ARP_ADDR_LIST_LEN
&&
ifa
)
{
bss_conf
->
arp_addr_list
[
c
]
=
ifa
->
ifa_address
;
while
(
ifa
)
{
if
(
c
<
IEEE80211_BSS_ARP_ADDR_LIST_LEN
)
bss_conf
->
arp_addr_list
[
c
]
=
ifa
->
ifa_address
;
ifa
=
ifa
->
ifa_next
;
c
++
;
}
/* If not all addresses fit the list, disable filtering */
if
(
ifa
)
{
sdata
->
arp_filter_state
=
false
;
c
=
0
;
}
else
{
sdata
->
arp_filter_state
=
true
;
}
bss_conf
->
arp_addr_cnt
=
c
;
/* Configure driver only if associated (which also implies it is up) */
if
(
ifmgd
->
associated
)
{
bss_conf
->
arp_filter_enabled
=
sdata
->
arp_filter_state
;
if
(
ifmgd
->
associated
)
ieee80211_bss_info_change_notify
(
sdata
,
BSS_CHANGED_ARP_FILTER
);
}
mutex_unlock
(
&
ifmgd
->
mtx
);
...
...
@@ -377,6 +370,37 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
}
#endif
#if IS_ENABLED(CONFIG_IPV6)
static
int
ieee80211_ifa6_changed
(
struct
notifier_block
*
nb
,
unsigned
long
data
,
void
*
arg
)
{
struct
inet6_ifaddr
*
ifa
=
(
struct
inet6_ifaddr
*
)
arg
;
struct
inet6_dev
*
idev
=
ifa
->
idev
;
struct
net_device
*
ndev
=
ifa
->
idev
->
dev
;
struct
ieee80211_local
*
local
=
container_of
(
nb
,
struct
ieee80211_local
,
ifa6_notifier
);
struct
wireless_dev
*
wdev
=
ndev
->
ieee80211_ptr
;
struct
ieee80211_sub_if_data
*
sdata
;
/* Make sure it's our interface that got changed */
if
(
!
wdev
||
wdev
->
wiphy
!=
local
->
hw
.
wiphy
)
return
NOTIFY_DONE
;
sdata
=
IEEE80211_DEV_TO_SUB_IF
(
ndev
);
/*
* For now only support station mode. This is mostly because
* doing AP would have to handle AP_VLAN in some way ...
*/
if
(
sdata
->
vif
.
type
!=
NL80211_IFTYPE_STATION
)
return
NOTIFY_DONE
;
drv_ipv6_addr_change
(
local
,
sdata
,
idev
);
return
NOTIFY_DONE
;
}
#endif
static
int
ieee80211_napi_poll
(
struct
napi_struct
*
napi
,
int
budget
)
{
struct
ieee80211_local
*
local
=
...
...
@@ -985,12 +1009,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
goto
fail_ifa
;
#endif
#if IS_ENABLED(CONFIG_IPV6)
local
->
ifa6_notifier
.
notifier_call
=
ieee80211_ifa6_changed
;
result
=
register_inet6addr_notifier
(
&
local
->
ifa6_notifier
);
if
(
result
)
goto
fail_ifa6
;
#endif
netif_napi_add
(
&
local
->
napi_dev
,
&
local
->
napi
,
ieee80211_napi_poll
,
local
->
hw
.
napi_weight
);
return
0
;
#if IS_ENABLED(CONFIG_IPV6)
fail_ifa6:
#ifdef CONFIG_INET
unregister_inetaddr_notifier
(
&
local
->
ifa_notifier
);
#endif
#endif
#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
fail_ifa:
pm_qos_remove_notifier
(
PM_QOS_NETWORK_LATENCY
,
&
local
->
network_latency_notifier
);
...
...
@@ -1026,6 +1063,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
#ifdef CONFIG_INET
unregister_inetaddr_notifier
(
&
local
->
ifa_notifier
);
#endif
#if IS_ENABLED(CONFIG_IPV6)
unregister_inet6addr_notifier
(
&
local
->
ifa6_notifier
);
#endif
rtnl_lock
();
...
...
net/mac80211/mesh_plink.c
View file @
20fb9e50
...
...
@@ -55,30 +55,6 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
sta
->
plink_retries
=
0
;
}
/*
* Allocate mesh sta entry and insert into station table
*/
static
struct
sta_info
*
mesh_plink_alloc
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
hw_addr
)
{
struct
sta_info
*
sta
;
if
(
sdata
->
local
->
num_sta
>=
MESH_MAX_PLINKS
)
return
NULL
;
sta
=
sta_info_alloc
(
sdata
,
hw_addr
,
GFP_KERNEL
);
if
(
!
sta
)
return
NULL
;
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_AUTH
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_ASSOC
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_AUTHORIZED
);
set_sta_flag
(
sta
,
WLAN_STA_WME
);
return
sta
;
}
/**
* mesh_set_ht_prot_mode - set correct HT protection mode
*
...
...
@@ -309,53 +285,27 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
return
err
;
}
/**
* mesh_peer_init - initialize new mesh peer and return resulting sta_info
*
* @sdata: local meshif
* @addr: peer's address
* @elems: IEs from beacon or mesh peering frame
*
* call under RCU
*/
static
struct
sta_info
*
mesh_peer_init
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
addr
,
struct
ieee802_11_elems
*
elems
)
static
void
mesh_sta_info_init
(
struct
ieee80211_sub_if_data
*
sdata
,
struct
sta_info
*
sta
,
struct
ieee802_11_elems
*
elems
,
bool
insert
)
{
struct
ieee80211_local
*
local
=
sdata
->
local
;
enum
ieee80211_band
band
=
ieee80211_get_sdata_band
(
sdata
);
struct
ieee80211_supported_band
*
sband
;
u32
rates
,
basic_rates
=
0
;
struct
sta_info
*
sta
;
bool
insert
=
false
;
u32
rates
,
basic_rates
=
0
,
changed
=
0
;
sband
=
local
->
hw
.
wiphy
->
bands
[
band
];
rates
=
ieee80211_sta_get_rates
(
local
,
elems
,
band
,
&
basic_rates
);
sta
=
sta_info_get
(
sdata
,
addr
);
if
(
!
sta
)
{
/* Userspace handles peer allocation when security is enabled */
if
(
sdata
->
u
.
mesh
.
security
&
IEEE80211_MESH_SEC_AUTHED
)
{
cfg80211_notify_new_peer_candidate
(
sdata
->
dev
,
addr
,
elems
->
ie_start
,
elems
->
total_len
,
GFP_ATOMIC
);
return
NULL
;
}
sta
=
mesh_plink_alloc
(
sdata
,
addr
);
if
(
!
sta
)
return
NULL
;
insert
=
true
;
}
spin_lock_bh
(
&
sta
->
lock
);
sta
->
last_rx
=
jiffies
;
if
(
sta
->
plink_state
==
NL80211_PLINK_ESTAB
)
{
spin_unlock_bh
(
&
sta
->
lock
);
return
sta
;
}
/* rates and capabilities don't change during peering */
if
(
sta
->
plink_state
==
NL80211_PLINK_ESTAB
)
goto
out
;
if
(
sta
->
sta
.
supp_rates
[
band
]
!=
rates
)
changed
|=
IEEE80211_RC_SUPP_RATES_CHANGED
;
sta
->
sta
.
supp_rates
[
band
]
=
rates
;
if
(
elems
->
ht_cap_elem
&&
sdata
->
vif
.
bss_conf
.
chandef
.
width
!=
NL80211_CHAN_WIDTH_20_NOHT
)
...
...
@@ -374,27 +324,115 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
~
IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
ieee80211_ht_oper_to_chandef
(
sdata
->
vif
.
bss_conf
.
chandef
.
chan
,
elems
->
ht_operation
,
&
chandef
);
if
(
sta
->
ch_width
!=
chandef
.
width
)
changed
|=
IEEE80211_RC_BW_CHANGED
;
sta
->
ch_width
=
chandef
.
width
;
}
if
(
insert
)
rate_control_rate_init
(
sta
);
else
rate_control_rate_update
(
local
,
sband
,
sta
,
changed
);
out:
spin_unlock_bh
(
&
sta
->
lock
);
}
static
struct
sta_info
*
__mesh_sta_info_alloc
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
hw_addr
)
{
struct
sta_info
*
sta
;
if
(
insert
&&
sta_info_insert
(
sta
)
)
if
(
sdata
->
local
->
num_sta
>=
MESH_MAX_PLINKS
)
return
NULL
;
sta
=
sta_info_alloc
(
sdata
,
hw_addr
,
GFP_KERNEL
);
if
(
!
sta
)
return
NULL
;
sta
->
plink_state
=
NL80211_PLINK_LISTEN
;
init_timer
(
&
sta
->
plink_timer
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_AUTH
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_ASSOC
);
sta_info_pre_move_state
(
sta
,
IEEE80211_STA_AUTHORIZED
);
set_sta_flag
(
sta
,
WLAN_STA_WME
);
return
sta
;
}
static
struct
sta_info
*
mesh_sta_info_alloc
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
addr
,
struct
ieee802_11_elems
*
elems
)
{
struct
sta_info
*
sta
=
NULL
;
/* Userspace handles peer allocation when security is enabled */
if
(
sdata
->
u
.
mesh
.
security
&
IEEE80211_MESH_SEC_AUTHED
)
cfg80211_notify_new_peer_candidate
(
sdata
->
dev
,
addr
,
elems
->
ie_start
,
elems
->
total_len
,
GFP_KERNEL
);
else
sta
=
__mesh_sta_info_alloc
(
sdata
,
addr
);
return
sta
;
}
/*
* mesh_sta_info_get - return mesh sta info entry for @addr.
*
* @sdata: local meshif
* @addr: peer's address
* @elems: IEs from beacon or mesh peering frame.
*
* Return existing or newly allocated sta_info under RCU read lock.
* (re)initialize with given IEs.
*/
static
struct
sta_info
*
mesh_sta_info_get
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
addr
,
struct
ieee802_11_elems
*
elems
)
__acquires
(
RCU
)
{
struct
sta_info
*
sta
=
NULL
;
rcu_read_lock
();
sta
=
sta_info_get
(
sdata
,
addr
);
if
(
sta
)
{
mesh_sta_info_init
(
sdata
,
sta
,
elems
,
false
);
}
else
{
rcu_read_unlock
();
/* can't run atomic */
sta
=
mesh_sta_info_alloc
(
sdata
,
addr
,
elems
);
if
(
!
sta
)
{
rcu_read_lock
();
return
NULL
;
}
mesh_sta_info_init
(
sdata
,
sta
,
elems
,
true
);
if
(
sta_info_insert_rcu
(
sta
))
return
NULL
;
}
return
sta
;
}
/*
* mesh_neighbour_update - update or initialize new mesh neighbor.
*
* @sdata: local meshif
* @addr: peer's address
* @elems: IEs from beacon or mesh peering frame
*
* Initiates peering if appropriate.
*/
void
mesh_neighbour_update
(
struct
ieee80211_sub_if_data
*
sdata
,
u8
*
hw_addr
,
struct
ieee802_11_elems
*
elems
)
{
struct
sta_info
*
sta
;
rcu_read_lock
();
sta
=
mesh_peer_init
(
sdata
,
hw_addr
,
elems
);
sta
=
mesh_sta_info_get
(
sdata
,
hw_addr
,
elems
);
if
(
!
sta
)
goto
out
;
...
...
@@ -632,6 +670,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
(
ftype
==
WLAN_SP_MESH_PEERING_CLOSE
&&
ie_len
==
8
))
memcpy
(
&
llid
,
PLINK_GET_PLID
(
elems
.
peering
),
2
);
/* WARNING: Only for sta pointer, is dropped & re-acquired */
rcu_read_lock
();
sta
=
sta_info_get
(
sdata
,
mgmt
->
sa
);
...
...
@@ -735,8 +774,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
}
if
(
event
==
OPN_ACPT
)
{
rcu_read_unlock
();
/* allocate sta entry if necessary and update info */
sta
=
mesh_
peer_ini
t
(
sdata
,
mgmt
->
sa
,
&
elems
);
sta
=
mesh_
sta_info_ge
t
(
sdata
,
mgmt
->
sa
,
&
elems
);
if
(
!
sta
)
{
mpl_dbg
(
sdata
,
"Mesh plink: failed to init peer!
\n
"
);
rcu_read_unlock
();
...
...
net/mac80211/mlme.c
View file @
20fb9e50
...
...
@@ -1465,10 +1465,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
bss_info_changed
|=
BSS_CHANGED_CQM
;
/* Enable ARP filtering */
if
(
bss_conf
->
arp_filter_enabled
!=
sdata
->
arp_filter_state
)
{
bss_conf
->
arp_filter_enabled
=
sdata
->
arp_filter_state
;
if
(
bss_conf
->
arp_addr_cnt
)
bss_info_changed
|=
BSS_CHANGED_ARP_FILTER
;
}
ieee80211_bss_info_change_notify
(
sdata
,
bss_info_changed
);
...
...
@@ -1489,7 +1487,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
{
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
struct
ieee80211_local
*
local
=
sdata
->
local
;
struct
sta_info
*
sta
;
u32
changed
=
0
;
ASSERT_MGD_MTX
(
ifmgd
);
...
...
@@ -1521,14 +1518,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
netif_tx_stop_all_queues
(
sdata
->
dev
);
netif_carrier_off
(
sdata
->
dev
);
mutex_lock
(
&
local
->
sta_mtx
);
sta
=
sta_info_get
(
sdata
,
ifmgd
->
bssid
);
if
(
sta
)
{
set_sta_flag
(
sta
,
WLAN_STA_BLOCK_BA
);
ieee80211_sta_tear_down_BA_sessions
(
sta
,
AGG_STOP_DESTROY_STA
);
}
mutex_unlock
(
&
local
->
sta_mtx
);
/*
* if we want to get out of ps before disassoc (why?) we have
* to do it before sending disassoc, as otherwise the null-packet
...
...
@@ -1582,10 +1571,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
cancel_work_sync
(
&
local
->
dynamic_ps_enable_work
);
/* Disable ARP filtering */
if
(
sdata
->
vif
.
bss_conf
.
arp_filter_enabled
)
{
sdata
->
vif
.
bss_conf
.
arp_filter_enabled
=
false
;
if
(
sdata
->
vif
.
bss_conf
.
arp_addr_cnt
)
changed
|=
BSS_CHANGED_ARP_FILTER
;
}
sdata
->
vif
.
bss_conf
.
qos
=
false
;
changed
|=
BSS_CHANGED_QOS
;
...
...
@@ -2608,12 +2595,12 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
if
(
sig
>
ifmgd
->
rssi_max_thold
&&
(
last_sig
<=
ifmgd
->
rssi_min_thold
||
last_sig
==
0
))
{
ifmgd
->
last_ave_beacon_signal
=
sig
;
drv_rssi_callback
(
local
,
RSSI_EVENT_HIGH
);
drv_rssi_callback
(
local
,
sdata
,
RSSI_EVENT_HIGH
);
}
else
if
(
sig
<
ifmgd
->
rssi_min_thold
&&
(
last_sig
>=
ifmgd
->
rssi_max_thold
||
last_sig
==
0
))
{
ifmgd
->
last_ave_beacon_signal
=
sig
;
drv_rssi_callback
(
local
,
RSSI_EVENT_LOW
);
drv_rssi_callback
(
local
,
sdata
,
RSSI_EVENT_LOW
);
}
}
...
...
@@ -3169,23 +3156,22 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
{
struct
ieee80211_if_managed
*
ifmgd
=
&
sdata
->
u
.
mgd
;
if
(
!
ifmgd
->
associated
)
mutex_lock
(
&
ifmgd
->
mtx
);
if
(
!
ifmgd
->
associated
)
{
mutex_unlock
(
&
ifmgd
->
mtx
);
return
;
}
if
(
sdata
->
flags
&
IEEE80211_SDATA_DISCONNECT_RESUME
)
{
sdata
->
flags
&=
~
IEEE80211_SDATA_DISCONNECT_RESUME
;
mutex_lock
(
&
ifmgd
->
mtx
);
if
(
ifmgd
->
associated
)
{
mlme_dbg
(
sdata
,
"driver requested disconnect after resume
\n
"
);
ieee80211_sta_connection_lost
(
sdata
,
ifmgd
->
associated
->
bssid
,
WLAN_REASON_UNSPECIFIED
);
mutex_unlock
(
&
ifmgd
->
mtx
);
return
;
}
mlme_dbg
(
sdata
,
"driver requested disconnect after resume
\n
"
);
ieee80211_sta_connection_lost
(
sdata
,
ifmgd
->
associated
->
bssid
,
WLAN_REASON_UNSPECIFIED
);
mutex_unlock
(
&
ifmgd
->
mtx
);
return
;
}
mutex_unlock
(
&
ifmgd
->
mtx
);
if
(
test_and_clear_bit
(
TMR_RUNNING_TIMER
,
&
ifmgd
->
timers_running
))
add_timer
(
&
ifmgd
->
timer
);
...
...
net/mac80211/sta_info.c
View file @
20fb9e50
...
...
@@ -380,11 +380,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
sta_dbg
(
sdata
,
"Allocated STA %pM
\n
"
,
sta
->
sta
.
addr
);
#ifdef CONFIG_MAC80211_MESH
sta
->
plink_state
=
NL80211_PLINK_LISTEN
;
init_timer
(
&
sta
->
plink_timer
);
#endif
return
sta
;
}
...
...
net/mac80211/trace.h
View file @
20fb9e50
...
...
@@ -347,8 +347,11 @@ TRACE_EVENT(drv_bss_info_changed,
__field
(
s32
,
cqm_rssi_hyst
);
__field
(
u32
,
channel_width
);
__field
(
u32
,
channel_cfreq1
);
__dynamic_array
(
u32
,
arp_addr_list
,
info
->
arp_addr_cnt
);
__field
(
bool
,
arp_filter_enabled
);
__dynamic_array
(
u32
,
arp_addr_list
,
info
->
arp_addr_cnt
>
IEEE80211_BSS_ARP_ADDR_LIST_LEN
?
IEEE80211_BSS_ARP_ADDR_LIST_LEN
:
info
->
arp_addr_cnt
);
__field
(
int
,
arp_addr_cnt
);
__field
(
bool
,
qos
);
__field
(
bool
,
idle
);
__field
(
bool
,
ps
);
...
...
@@ -384,9 +387,11 @@ TRACE_EVENT(drv_bss_info_changed,
__entry
->
cqm_rssi_hyst
=
info
->
cqm_rssi_hyst
;
__entry
->
channel_width
=
info
->
chandef
.
width
;
__entry
->
channel_cfreq1
=
info
->
chandef
.
center_freq1
;
__entry
->
arp_addr_cnt
=
info
->
arp_addr_cnt
;
memcpy
(
__get_dynamic_array
(
arp_addr_list
),
info
->
arp_addr_list
,
sizeof
(
u32
)
*
info
->
arp_addr_cnt
);
__entry
->
arp_filter_enabled
=
info
->
arp_filter_enabled
;
sizeof
(
u32
)
*
(
info
->
arp_addr_cnt
>
IEEE80211_BSS_ARP_ADDR_LIST_LEN
?
IEEE80211_BSS_ARP_ADDR_LIST_LEN
:
info
->
arp_addr_cnt
));
__entry
->
qos
=
info
->
qos
;
__entry
->
idle
=
info
->
idle
;
__entry
->
ps
=
info
->
ps
;
...
...
@@ -1184,23 +1189,26 @@ TRACE_EVENT(drv_set_rekey_data,
TRACE_EVENT
(
drv_rssi_callback
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
enum
ieee80211_rssi_event
rssi_event
),
TP_ARGS
(
local
,
rssi_event
),
TP_ARGS
(
local
,
sdata
,
rssi_event
),
TP_STRUCT__entry
(
LOCAL_ENTRY
VIF_ENTRY
__field
(
u32
,
rssi_event
)
),
TP_fast_assign
(
LOCAL_ASSIGN
;
VIF_ASSIGN
;
__entry
->
rssi_event
=
rssi_event
;
),
TP_printk
(
LOCAL_PR_FMT
" rssi_event:%d"
,
LOCAL_PR_ARG
,
__entry
->
rssi_event
LOCAL_PR_FMT
VIF_PR_FMT
" rssi_event:%d"
,
LOCAL_PR_ARG
,
VIF_PR_ARG
,
__entry
->
rssi_event
)
);
...
...
@@ -1432,6 +1440,14 @@ DEFINE_EVENT(local_only_evt, drv_restart_complete,
TP_ARGS
(
local
)
);
#if IS_ENABLED(CONFIG_IPV6)
DEFINE_EVENT
(
local_sdata_evt
,
drv_ipv6_addr_change
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
),
TP_ARGS
(
local
,
sdata
)
);
#endif
/*
* Tracing for API calls that drivers call.
*/
...
...
@@ -1821,6 +1837,29 @@ TRACE_EVENT(stop_queue,
)
);
TRACE_EVENT
(
drv_set_default_unicast_key
,
TP_PROTO
(
struct
ieee80211_local
*
local
,
struct
ieee80211_sub_if_data
*
sdata
,
int
key_idx
),
TP_ARGS
(
local
,
sdata
,
key_idx
),
TP_STRUCT__entry
(
LOCAL_ENTRY
VIF_ENTRY
__field
(
int
,
key_idx
)
),
TP_fast_assign
(
LOCAL_ASSIGN
;
VIF_ASSIGN
;
__entry
->
key_idx
=
key_idx
;
),
TP_printk
(
LOCAL_PR_FMT
VIF_PR_FMT
" key_idx:%d"
,
LOCAL_PR_ARG
,
VIF_PR_ARG
,
__entry
->
key_idx
)
);
#ifdef CONFIG_MAC80211_MESSAGE_TRACING
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mac80211_msg
...
...
net/mac80211/tx.c
View file @
20fb9e50
...
...
@@ -1787,16 +1787,16 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
break
;
/* fall through */
case
NL80211_IFTYPE_AP
:
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
chanctx_conf
=
rcu_dereference
(
sdata
->
vif
.
chanctx_conf
);
if
(
!
chanctx_conf
)
goto
fail_rcu
;
fc
|=
cpu_to_le16
(
IEEE80211_FCTL_FROMDS
);
/* DA BSSID SA */
memcpy
(
hdr
.
addr1
,
skb
->
data
,
ETH_ALEN
);
memcpy
(
hdr
.
addr2
,
sdata
->
vif
.
addr
,
ETH_ALEN
);
memcpy
(
hdr
.
addr3
,
skb
->
data
+
ETH_ALEN
,
ETH_ALEN
);
hdrlen
=
24
;
if
(
sdata
->
vif
.
type
==
NL80211_IFTYPE_AP
)
chanctx_conf
=
rcu_dereference
(
sdata
->
vif
.
chanctx_conf
);
if
(
!
chanctx_conf
)
goto
fail_rcu
;
band
=
chanctx_conf
->
def
.
chan
->
band
;
break
;
case
NL80211_IFTYPE_WDS
:
...
...
net/wireless/core.c
View file @
20fb9e50
...
...
@@ -478,6 +478,11 @@ int wiphy_register(struct wiphy *wiphy)
ETH_ALEN
)))
return
-
EINVAL
;
if
(
WARN_ON
(
wiphy
->
max_acl_mac_addrs
&&
(
!
(
wiphy
->
flags
&
WIPHY_FLAG_HAVE_AP_SME
)
||
!
rdev
->
ops
->
set_mac_acl
)))
return
-
EINVAL
;
if
(
wiphy
->
addresses
)
memcpy
(
wiphy
->
perm_addr
,
wiphy
->
addresses
[
0
].
addr
,
ETH_ALEN
);
...
...
net/wireless/nl80211.c
View file @
20fb9e50
...
...
@@ -365,6 +365,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[
NL80211_ATTR_SCAN_FLAGS
]
=
{
.
type
=
NLA_U32
},
[
NL80211_ATTR_P2P_CTWINDOW
]
=
{
.
type
=
NLA_U8
},
[
NL80211_ATTR_P2P_OPPPS
]
=
{
.
type
=
NLA_U8
},
[
NL80211_ATTR_ACL_POLICY
]
=
{.
type
=
NLA_U32
},
[
NL80211_ATTR_MAC_ADDRS
]
=
{
.
type
=
NLA_NESTED
},
};
/* policy for the key attributes */
...
...
@@ -1268,6 +1270,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
dev
->
wiphy
.
ht_capa_mod_mask
))
goto
nla_put_failure
;
if
(
dev
->
wiphy
.
flags
&
WIPHY_FLAG_HAVE_AP_SME
&&
dev
->
wiphy
.
max_acl_mac_addrs
&&
nla_put_u32
(
msg
,
NL80211_ATTR_MAC_ACL_MAX
,
dev
->
wiphy
.
max_acl_mac_addrs
))
goto
nla_put_failure
;
return
genlmsg_end
(
msg
,
hdr
);
nla_put_failure:
...
...
@@ -2491,6 +2499,97 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
return
err
;
}
/* This function returns an error or the number of nested attributes */
static
int
validate_acl_mac_addrs
(
struct
nlattr
*
nl_attr
)
{
struct
nlattr
*
attr
;
int
n_entries
=
0
,
tmp
;
nla_for_each_nested
(
attr
,
nl_attr
,
tmp
)
{
if
(
nla_len
(
attr
)
!=
ETH_ALEN
)
return
-
EINVAL
;
n_entries
++
;
}
return
n_entries
;
}
/*
* This function parses ACL information and allocates memory for ACL data.
* On successful return, the calling function is responsible to free the
* ACL buffer returned by this function.
*/
static
struct
cfg80211_acl_data
*
parse_acl_data
(
struct
wiphy
*
wiphy
,
struct
genl_info
*
info
)
{
enum
nl80211_acl_policy
acl_policy
;
struct
nlattr
*
attr
;
struct
cfg80211_acl_data
*
acl
;
int
i
=
0
,
n_entries
,
tmp
;
if
(
!
wiphy
->
max_acl_mac_addrs
)
return
ERR_PTR
(
-
EOPNOTSUPP
);
if
(
!
info
->
attrs
[
NL80211_ATTR_ACL_POLICY
])
return
ERR_PTR
(
-
EINVAL
);
acl_policy
=
nla_get_u32
(
info
->
attrs
[
NL80211_ATTR_ACL_POLICY
]);
if
(
acl_policy
!=
NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED
&&
acl_policy
!=
NL80211_ACL_POLICY_DENY_UNLESS_LISTED
)
return
ERR_PTR
(
-
EINVAL
);
if
(
!
info
->
attrs
[
NL80211_ATTR_MAC_ADDRS
])
return
ERR_PTR
(
-
EINVAL
);
n_entries
=
validate_acl_mac_addrs
(
info
->
attrs
[
NL80211_ATTR_MAC_ADDRS
]);
if
(
n_entries
<
0
)
return
ERR_PTR
(
n_entries
);
if
(
n_entries
>
wiphy
->
max_acl_mac_addrs
)
return
ERR_PTR
(
-
ENOTSUPP
);
acl
=
kzalloc
(
sizeof
(
*
acl
)
+
(
sizeof
(
struct
mac_address
)
*
n_entries
),
GFP_KERNEL
);
if
(
!
acl
)
return
ERR_PTR
(
-
ENOMEM
);
nla_for_each_nested
(
attr
,
info
->
attrs
[
NL80211_ATTR_MAC_ADDRS
],
tmp
)
{
memcpy
(
acl
->
mac_addrs
[
i
].
addr
,
nla_data
(
attr
),
ETH_ALEN
);
i
++
;
}
acl
->
n_acl_entries
=
n_entries
;
acl
->
acl_policy
=
acl_policy
;
return
acl
;
}
static
int
nl80211_set_mac_acl
(
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
cfg80211_acl_data
*
acl
;
int
err
;
if
(
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_AP
&&
dev
->
ieee80211_ptr
->
iftype
!=
NL80211_IFTYPE_P2P_GO
)
return
-
EOPNOTSUPP
;
if
(
!
dev
->
ieee80211_ptr
->
beacon_interval
)
return
-
EINVAL
;
acl
=
parse_acl_data
(
&
rdev
->
wiphy
,
info
);
if
(
IS_ERR
(
acl
))
return
PTR_ERR
(
acl
);
err
=
rdev_set_mac_acl
(
rdev
,
dev
,
acl
);
kfree
(
acl
);
return
err
;
}
static
int
nl80211_parse_beacon
(
struct
genl_info
*
info
,
struct
cfg80211_beacon_data
*
bcn
)
{
...
...
@@ -2734,6 +2833,12 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
if
(
err
)
return
err
;
if
(
info
->
attrs
[
NL80211_ATTR_ACL_POLICY
])
{
params
.
acl
=
parse_acl_data
(
&
rdev
->
wiphy
,
info
);
if
(
IS_ERR
(
params
.
acl
))
return
PTR_ERR
(
params
.
acl
);
}
err
=
rdev_start_ap
(
rdev
,
dev
,
&
params
);
if
(
!
err
)
{
wdev
->
preset_chandef
=
params
.
chandef
;
...
...
@@ -2742,6 +2847,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
wdev
->
ssid_len
=
params
.
ssid_len
;
memcpy
(
wdev
->
ssid
,
params
.
ssid
,
wdev
->
ssid_len
);
}
kfree
(
params
.
acl
);
return
err
;
}
...
...
@@ -7876,6 +7984,14 @@ static struct genl_ops nl80211_ops[] = {
.
internal_flags
=
NL80211_FLAG_NEED_NETDEV
|
NL80211_FLAG_NEED_RTNL
,
},
{
.
cmd
=
NL80211_CMD_SET_MAC_ACL
,
.
doit
=
nl80211_set_mac_acl
,
.
policy
=
nl80211_policy
,
.
flags
=
GENL_ADMIN_PERM
,
.
internal_flags
=
NL80211_FLAG_NEED_NETDEV
|
NL80211_FLAG_NEED_RTNL
,
},
};
static
struct
genl_multicast_group
nl80211_mlme_mcgrp
=
{
...
...
net/wireless/rdev-ops.h
View file @
20fb9e50
...
...
@@ -875,4 +875,16 @@ static inline void rdev_stop_p2p_device(struct cfg80211_registered_device *rdev,
rdev
->
ops
->
stop_p2p_device
(
&
rdev
->
wiphy
,
wdev
);
trace_rdev_return_void
(
&
rdev
->
wiphy
);
}
static
inline
int
rdev_set_mac_acl
(
struct
cfg80211_registered_device
*
rdev
,
struct
net_device
*
dev
,
struct
cfg80211_acl_data
*
params
)
{
int
ret
;
trace_rdev_set_mac_acl
(
&
rdev
->
wiphy
,
dev
,
params
);
ret
=
rdev
->
ops
->
set_mac_acl
(
&
rdev
->
wiphy
,
dev
,
params
);
trace_rdev_return_int
(
&
rdev
->
wiphy
,
ret
);
return
ret
;
}
#endif
/* __CFG80211_RDEV_OPS */
net/wireless/trace.h
View file @
20fb9e50
...
...
@@ -1767,6 +1767,24 @@ DEFINE_EVENT(wiphy_wdev_evt, rdev_stop_p2p_device,
TP_ARGS
(
wiphy
,
wdev
)
);
TRACE_EVENT
(
rdev_set_mac_acl
,
TP_PROTO
(
struct
wiphy
*
wiphy
,
struct
net_device
*
netdev
,
struct
cfg80211_acl_data
*
params
),
TP_ARGS
(
wiphy
,
netdev
,
params
),
TP_STRUCT__entry
(
WIPHY_ENTRY
NETDEV_ENTRY
__field
(
u32
,
acl_policy
)
),
TP_fast_assign
(
WIPHY_ASSIGN
;
WIPHY_ASSIGN
;
__entry
->
acl_policy
=
params
->
acl_policy
;
),
TP_printk
(
WIPHY_PR_FMT
", "
NETDEV_PR_FMT
", acl policy: %d"
,
WIPHY_PR_ARG
,
NETDEV_PR_ARG
,
__entry
->
acl_policy
)
);
/*************************************************************
* cfg80211 exported functions traces *
*************************************************************/
...
...
net/wireless/util.c
View file @
20fb9e50
...
...
@@ -1212,7 +1212,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
case
NL80211_IFTYPE_MESH_POINT
:
case
NL80211_IFTYPE_P2P_GO
:
case
NL80211_IFTYPE_WDS
:
radar_required
=
!!
(
chan
->
flags
&
IEEE80211_CHAN_RADAR
);
radar_required
=
!!
(
chan
&&
(
chan
->
flags
&
IEEE80211_CHAN_RADAR
));
break
;
case
NL80211_IFTYPE_P2P_CLIENT
:
case
NL80211_IFTYPE_STATION
:
...
...
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