mirror of
https://github.com/hanwckf/immortalwrt-mt798x.git
synced 2025-01-09 02:43:53 +08:00
Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
e2e94600f3
@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=5.10.68-1
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.10.68/
|
||||
PKG_HASH:=bba161b0084590c677a84b80993709e388a3c478f29ed0c475d4fce1b9162968
|
||||
|
||||
|
@ -26,7 +26,6 @@ drv_mac80211_init_device_config() {
|
||||
hostapd_common_add_device_config
|
||||
|
||||
config_add_string path phy 'macaddr:macaddr'
|
||||
config_add_string hwmode
|
||||
config_add_string tx_burst
|
||||
config_add_string distance
|
||||
config_add_int beacon_int chanbw frag rts
|
||||
@ -44,11 +43,26 @@ drv_mac80211_init_device_config() {
|
||||
su_beamformee \
|
||||
mu_beamformer \
|
||||
mu_beamformee \
|
||||
he_su_beamformer \
|
||||
he_su_beamformee \
|
||||
he_mu_beamformer \
|
||||
vht_txop_ps \
|
||||
htc_vht \
|
||||
rx_antenna_pattern \
|
||||
tx_antenna_pattern
|
||||
config_add_int vht_max_a_mpdu_len_exp vht_max_mpdu vht_link_adapt vht160 rx_stbc tx_stbc
|
||||
tx_antenna_pattern \
|
||||
he_spr_sr_control \
|
||||
he_twt_required
|
||||
config_add_int \
|
||||
beamformer_antennas \
|
||||
beamformee_antennas \
|
||||
vht_max_a_mpdu_len_exp \
|
||||
vht_max_mpdu \
|
||||
vht_link_adapt \
|
||||
vht160 \
|
||||
rx_stbc \
|
||||
tx_stbc \
|
||||
he_bss_color \
|
||||
he_spr_non_srg_obss_pd_max_offset
|
||||
config_add_boolean \
|
||||
ldpc \
|
||||
greenfield \
|
||||
@ -96,6 +110,23 @@ mac80211_add_capabilities() {
|
||||
export -n -- "$__var=$__out"
|
||||
}
|
||||
|
||||
mac80211_add_he_capabilities() {
|
||||
local __out= oifs
|
||||
|
||||
oifs="$IFS"
|
||||
IFS=:
|
||||
for capab in "$@"; do
|
||||
set -- $capab
|
||||
[ "$(($4))" -gt 0 ] || continue
|
||||
[ "$(((0x$2) & $3))" -gt 0 ] || {
|
||||
eval "$1=0"
|
||||
continue
|
||||
}
|
||||
append base_cfg "$1=1" "$N"
|
||||
done
|
||||
IFS="$oifs"
|
||||
}
|
||||
|
||||
mac80211_hostapd_setup_base() {
|
||||
local phy="$1"
|
||||
|
||||
@ -119,6 +150,9 @@ mac80211_hostapd_setup_base() {
|
||||
[ "$noscan" -gt 0 ] && hostapd_noscan=1
|
||||
[ "$tx_burst" = 0 ] && tx_burst=
|
||||
|
||||
chan_ofs=0
|
||||
[ "$band" = "6g" ] && chan_ofs=1
|
||||
|
||||
ieee80211n=1
|
||||
ht_capab=
|
||||
case "$htmode" in
|
||||
@ -126,7 +160,7 @@ mac80211_hostapd_setup_base() {
|
||||
HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160)
|
||||
case "$hwmode" in
|
||||
a)
|
||||
case "$(( ($channel / 4) % 2 ))" in
|
||||
case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in
|
||||
1) ht_capab="[HT40+]";;
|
||||
0) ht_capab="[HT40-]";;
|
||||
esac
|
||||
@ -200,7 +234,7 @@ mac80211_hostapd_setup_base() {
|
||||
case "$htmode" in
|
||||
VHT20|HE20) enable_ac=1;;
|
||||
VHT40|HE40)
|
||||
case "$(( ($channel / 4) % 2 ))" in
|
||||
case "$(( (($channel / 4) + $chan_ofs) % 2 ))" in
|
||||
1) idx=$(($channel + 2));;
|
||||
0) idx=$(($channel - 2));;
|
||||
esac
|
||||
@ -208,7 +242,7 @@ mac80211_hostapd_setup_base() {
|
||||
vht_center_seg0=$idx
|
||||
;;
|
||||
VHT80|HE80)
|
||||
case "$(( ($channel / 4) % 4 ))" in
|
||||
case "$(( (($channel / 4) + $chan_ofs) % 4 ))" in
|
||||
1) idx=$(($channel + 6));;
|
||||
2) idx=$(($channel + 2));;
|
||||
3) idx=$(($channel - 2));;
|
||||
@ -219,15 +253,35 @@ mac80211_hostapd_setup_base() {
|
||||
vht_center_seg0=$idx
|
||||
;;
|
||||
VHT160|HE160)
|
||||
case "$channel" in
|
||||
36|40|44|48|52|56|60|64) idx=50;;
|
||||
100|104|108|112|116|120|124|128) idx=114;;
|
||||
esac
|
||||
if [ "$band" = "6g" ]; then
|
||||
case "$channel" in
|
||||
1|5|9|13|17|21|25|29) idx=15;;
|
||||
33|37|41|45|49|53|57|61) idx=47;;
|
||||
65|69|73|77|81|85|89|93) idx=79;;
|
||||
97|101|105|109|113|117|121|125) idx=111;;
|
||||
129|133|137|141|145|149|153|157) idx=143;;
|
||||
161|165|169|173|177|181|185|189) idx=175;;
|
||||
193|197|201|205|209|213|217|221) idx=207;;
|
||||
esac
|
||||
else
|
||||
case "$channel" in
|
||||
36|40|44|48|52|56|60|64) idx=50;;
|
||||
100|104|108|112|116|120|124|128) idx=114;;
|
||||
esac
|
||||
fi
|
||||
enable_ac=1
|
||||
vht_oper_chwidth=2
|
||||
vht_center_seg0=$idx
|
||||
;;
|
||||
esac
|
||||
[ "$band" = "6g" ] && {
|
||||
op_class=
|
||||
case "$htmode" in
|
||||
HE20) op_class=131;;
|
||||
HE*) op_class=$((132 + $vht_oper_chwidth))
|
||||
esac
|
||||
[ -n "$op_class" ] && append base_cfg "op_class=$op_class" "$N"
|
||||
}
|
||||
[ "$hwmode" = "a" ] || enable_ac=0
|
||||
|
||||
if [ "$enable_ac" != "0" -o "$vendor_vht" = "1" ]; then
|
||||
@ -242,6 +296,8 @@ mac80211_hostapd_setup_base() {
|
||||
mu_beamformee:1 \
|
||||
vht_txop_ps:1 \
|
||||
htc_vht:1 \
|
||||
beamformee_antennas:4 \
|
||||
beamformer_antennas:4 \
|
||||
rx_antenna_pattern:1 \
|
||||
tx_antenna_pattern:1 \
|
||||
vht_max_a_mpdu_len_exp:7 \
|
||||
@ -282,6 +338,18 @@ mac80211_hostapd_setup_base() {
|
||||
RX-STBC-123:0x700:0x300:1 \
|
||||
RX-STBC-1234:0x700:0x400:1 \
|
||||
|
||||
[ "$(($vht_cap & 0x800))" -gt 0 -a "$su_beamformer" -gt 0 ] && {
|
||||
cap_ant="$(( ( ($vht_cap >> 16) & 3 ) + 1 ))"
|
||||
[ "$cap_ant" -gt "$beamformer_antennas" ] && cap_ant="$beamformer_antennas"
|
||||
[ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[SOUNDING-DIMENSION-$cap_ant]"
|
||||
}
|
||||
|
||||
[ "$(($vht_cap & 0x1000))" -gt 0 -a "$su_beamformee" -gt 0 ] && {
|
||||
cap_ant="$(( ( ($vht_cap >> 13) & 3 ) + 1 ))"
|
||||
[ "$cap_ant" -gt "$beamformee_antennas" ] && cap_ant="$beamformee_antennas"
|
||||
[ "$cap_ant" -gt 1 ] && vht_capab="$vht_capab[BF-ANTENNA-$cap_ant]"
|
||||
}
|
||||
|
||||
# supported Channel widths
|
||||
vht160_hw=0
|
||||
[ "$(($vht_cap & 12))" -eq 4 -a 1 -le "$vht160" ] && \
|
||||
@ -337,16 +405,62 @@ mac80211_hostapd_setup_base() {
|
||||
esac
|
||||
|
||||
if [ "$enable_ax" != "0" ]; then
|
||||
json_get_vars \
|
||||
he_su_beamformer:1 \
|
||||
he_su_beamformee:0 \
|
||||
he_mu_beamformer:1 \
|
||||
he_twt_required:0 \
|
||||
he_spr_sr_control:0 \
|
||||
he_spr_non_srg_obss_pd_max_offset:1 \
|
||||
he_bss_color
|
||||
|
||||
he_phy_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1)
|
||||
he_phy_cap=${he_phy_cap:2}
|
||||
he_mac_cap=$(iw phy "$phy" info | awk -F "[()]" '/HE MAC Capabilities/ { print $2 }' | head -1)
|
||||
he_mac_cap=${he_mac_cap:2}
|
||||
|
||||
append base_cfg "ieee80211ax=1" "$N"
|
||||
[ -n "$he_bss_color" ] && append base_cfg "he_bss_color=$he_bss_color" "$N"
|
||||
[ "$hwmode" = "a" ] && {
|
||||
append base_cfg "he_oper_chwidth=$vht_oper_chwidth" "$N"
|
||||
append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N"
|
||||
}
|
||||
|
||||
mac80211_add_he_capabilities \
|
||||
he_su_beamformer:${he_phy_cap:6:2}:0x80:$he_su_beamformer \
|
||||
he_su_beamformee:${he_phy_cap:8:2}:0x1:$he_su_beamformee \
|
||||
he_mu_beamformer:${he_phy_cap:8:2}:0x2:$he_mu_beamformer \
|
||||
he_spr_sr_control:${he_phy_cap:14:2}:0x1:$he_spr_sr_control \
|
||||
he_twt_required:${he_mac_cap:0:2}:0x6:$he_twt_required
|
||||
|
||||
[ "$he_spr_sr_control" -gt 0 ] && append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N"
|
||||
|
||||
append base_cfg "he_default_pe_duration=4" "$N"
|
||||
append base_cfg "he_rts_threshold=1023" "$N"
|
||||
append base_cfg "he_su_beamformer=1" "$N"
|
||||
append base_cfg "he_su_beamformee=1" "$N"
|
||||
append base_cfg "he_mu_beamformer=1" "$N"
|
||||
append base_cfg "he_mu_edca_qos_info_param_count=0" "$N"
|
||||
append base_cfg "he_mu_edca_qos_info_q_ack=0" "$N"
|
||||
append base_cfg "he_mu_edca_qos_info_queue_request=0" "$N"
|
||||
append base_cfg "he_mu_edca_qos_info_txop_request=0" "$N"
|
||||
append base_cfg "he_mu_edca_ac_be_aifsn=8" "$N"
|
||||
append base_cfg "he_mu_edca_ac_be_aci=0" "$N"
|
||||
append base_cfg "he_mu_edca_ac_be_ecwmin=9" "$N"
|
||||
append base_cfg "he_mu_edca_ac_be_ecwmax=10" "$N"
|
||||
append base_cfg "he_mu_edca_ac_be_timer=255" "$N"
|
||||
append base_cfg "he_mu_edca_ac_bk_aifsn=15" "$N"
|
||||
append base_cfg "he_mu_edca_ac_bk_aci=1" "$N"
|
||||
append base_cfg "he_mu_edca_ac_bk_ecwmin=9" "$N"
|
||||
append base_cfg "he_mu_edca_ac_bk_ecwmax=10" "$N"
|
||||
append base_cfg "he_mu_edca_ac_bk_timer=255" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vi_ecwmin=5" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vi_ecwmax=7" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vi_aifsn=5" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vi_aci=2" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vi_timer=255" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vo_aifsn=5" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vo_aci=3" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vo_ecwmin=5" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vo_ecwmax=7" "$N"
|
||||
append base_cfg "he_mu_edca_ac_vo_timer=255" "$N"
|
||||
fi
|
||||
|
||||
hostapd_prepare_device_config "$hostapd_conf_file" nl80211
|
||||
@ -528,7 +642,7 @@ mac80211_iw_interface_add() {
|
||||
rc="$?"
|
||||
}
|
||||
|
||||
[ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED
|
||||
[ "$rc" != 0 ] && echo "Failed to create interface $ifname"
|
||||
return $rc
|
||||
}
|
||||
|
||||
@ -689,14 +803,8 @@ mac80211_prepare_iw_htmode() {
|
||||
case "$htmode" in
|
||||
VHT20|HT20) iw_htmode=HT20;;
|
||||
HT40*|VHT40|VHT160)
|
||||
case "$hwmode" in
|
||||
a)
|
||||
case "$(( ($channel / 4) % 2 ))" in
|
||||
1) iw_htmode="HT40+" ;;
|
||||
0) iw_htmode="HT40-";;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case "$band" in
|
||||
2g)
|
||||
case "$htmode" in
|
||||
HT40+) iw_htmode="HT40+";;
|
||||
HT40-) iw_htmode="HT40-";;
|
||||
@ -709,6 +817,12 @@ mac80211_prepare_iw_htmode() {
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case "$(( ($channel / 4) % 2 ))" in
|
||||
1) iw_htmode="HT40+" ;;
|
||||
0) iw_htmode="HT40-";;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
[ "$auto_channel" -gt 0 ] && iw_htmode="HT40+"
|
||||
;;
|
||||
@ -763,6 +877,7 @@ mac80211_setup_adhoc() {
|
||||
mcval=
|
||||
[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
|
||||
|
||||
iw dev "$ifname" set type ibss
|
||||
iw dev "$ifname" ibss join "$ssid" $freq $iw_htmode fixed-freq $bssid \
|
||||
beacon-interval $beacon_int \
|
||||
${brstr:+basic-rates $brstr} \
|
||||
@ -818,7 +933,6 @@ mac80211_setup_vif() {
|
||||
mesh)
|
||||
wireless_vif_parse_encryption
|
||||
[ -z "$htmode" ] && htmode="NOHT";
|
||||
freq="$(get_freq "$phy" "$channel")"
|
||||
if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then
|
||||
mac80211_setup_supplicant $vif_enable || failed=1
|
||||
else
|
||||
@ -832,7 +946,6 @@ mac80211_setup_vif() {
|
||||
adhoc)
|
||||
wireless_vif_parse_encryption
|
||||
if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then
|
||||
freq="$(get_freq "$phy" "$channel")"
|
||||
mac80211_setup_supplicant_noctl $vif_enable || failed=1
|
||||
else
|
||||
mac80211_setup_adhoc $vif_enable
|
||||
@ -849,10 +962,30 @@ mac80211_setup_vif() {
|
||||
|
||||
get_freq() {
|
||||
local phy="$1"
|
||||
local chan="$2"
|
||||
iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}'
|
||||
local channel="$2"
|
||||
local band="$3"
|
||||
|
||||
case "$band" in
|
||||
2g) band="1:";;
|
||||
5g) band="2:";;
|
||||
60g) band="3:";;
|
||||
6g) band="4:";;
|
||||
esac
|
||||
|
||||
iw "$phy" info | awk -v band="$band" -v channel="[$channel]" '
|
||||
|
||||
$1 ~ /Band/ {
|
||||
band_match = band == $2
|
||||
}
|
||||
|
||||
band_match && $3 == "MHz" && $4 == channel {
|
||||
print $2
|
||||
exit
|
||||
}
|
||||
'
|
||||
}
|
||||
|
||||
|
||||
chan_is_dfs() {
|
||||
local phy="$1"
|
||||
local chan="$2"
|
||||
@ -933,7 +1066,7 @@ drv_mac80211_setup() {
|
||||
done
|
||||
|
||||
# convert channel to frequency
|
||||
[ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel")"
|
||||
[ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel" "$band")"
|
||||
|
||||
[ -n "$country" ] && {
|
||||
iw reg get | grep -q "^country $country:" || {
|
||||
|
@ -57,6 +57,85 @@ check_mac80211_device() {
|
||||
[ "$phy" = "$dev" ] && found=1
|
||||
}
|
||||
|
||||
|
||||
__get_band_defaults() {
|
||||
local phy="$1"
|
||||
|
||||
( iw phy "$phy" info; echo ) | awk '
|
||||
BEGIN {
|
||||
bands = ""
|
||||
}
|
||||
|
||||
($1 == "Band" || $1 == "") && band {
|
||||
if (channel) {
|
||||
mode="NOHT"
|
||||
if (ht) mode="HT20"
|
||||
if (vht && band != "1:") mode="VHT80"
|
||||
if (he) mode="HE80"
|
||||
if (he && band == "1:") mode="HE20"
|
||||
sub("\\[", "", channel)
|
||||
sub("\\]", "", channel)
|
||||
bands = bands band channel ":" mode " "
|
||||
}
|
||||
band=""
|
||||
}
|
||||
|
||||
$1 == "Band" {
|
||||
band = $2
|
||||
channel = ""
|
||||
vht = ""
|
||||
ht = ""
|
||||
he = ""
|
||||
}
|
||||
|
||||
$0 ~ "Capabilities:" {
|
||||
ht=1
|
||||
}
|
||||
|
||||
$0 ~ "VHT Capabilities" {
|
||||
vht=1
|
||||
}
|
||||
|
||||
$0 ~ "HE Iftypes" {
|
||||
he=1
|
||||
}
|
||||
|
||||
$1 == "*" && $3 == "MHz" && $0 !~ /disabled/ && band && !channel {
|
||||
channel = $4
|
||||
}
|
||||
|
||||
END {
|
||||
print bands
|
||||
}'
|
||||
}
|
||||
|
||||
get_band_defaults() {
|
||||
local phy="$1"
|
||||
|
||||
for c in $(__get_band_defaults "$phy"); do
|
||||
local band="${c%%:*}"
|
||||
c="${c#*:}"
|
||||
local chan="${c%%:*}"
|
||||
c="${c#*:}"
|
||||
local mode="${c%%:*}"
|
||||
|
||||
case "$band" in
|
||||
1) band=2g;;
|
||||
2) band=5g;;
|
||||
3) band=60g;;
|
||||
4) band=6g;;
|
||||
*) band="";;
|
||||
esac
|
||||
|
||||
[ -n "$band" ] || continue
|
||||
[ -n "$mode_band" -a "$band" = "6g" ] && return
|
||||
|
||||
mode_band="$band"
|
||||
channel="$chan"
|
||||
htmode="$mode"
|
||||
done
|
||||
}
|
||||
|
||||
detect_mac80211() {
|
||||
devidx=0
|
||||
config_load wireless
|
||||
@ -75,26 +154,12 @@ detect_mac80211() {
|
||||
config_foreach check_mac80211_device wifi-device
|
||||
[ "$found" -gt 0 ] && continue
|
||||
|
||||
mode_band="g"
|
||||
channel="11"
|
||||
mode_band=""
|
||||
channel=""
|
||||
htmode=""
|
||||
ht_capab=""
|
||||
|
||||
iw phy "$dev" info | grep -q 'Capabilities:' && htmode=HT20
|
||||
|
||||
iw phy "$dev" info | grep -q '\* 5... MHz \[' && {
|
||||
mode_band="a"
|
||||
channel=$(iw phy "$dev" info | grep '\* 5... MHz \[' | grep '(disabled)' -v -m 1 | sed 's/[^[]*\[\|\].*//g')
|
||||
iw phy "$dev" info | grep -q 'VHT Capabilities' && htmode="VHT80"
|
||||
}
|
||||
|
||||
iw phy "$dev" info | grep -q '\* 5.... MHz \[' && {
|
||||
mode_band="ad"
|
||||
channel=$(iw phy "$dev" info | grep '\* 5.... MHz \[' | grep '(disabled)' -v -m 1 | sed 's/[^[]*\[\|\|\].*//g')
|
||||
iw phy "$dev" info | grep -q 'Capabilities:' && htmode="HT20"
|
||||
}
|
||||
|
||||
[ -n "$htmode" ] && ht_capab="set wireless.radio${devidx}.htmode=$htmode"
|
||||
get_band_defaults "$dev"
|
||||
|
||||
path="$(mac80211_phy_to_path "$dev")"
|
||||
if [ -n "$path" ]; then
|
||||
@ -106,10 +171,10 @@ detect_mac80211() {
|
||||
uci -q batch <<-EOF
|
||||
set wireless.radio${devidx}=wifi-device
|
||||
set wireless.radio${devidx}.type=mac80211
|
||||
set wireless.radio${devidx}.channel=${channel}
|
||||
set wireless.radio${devidx}.hwmode=11${mode_band}
|
||||
${dev_id}
|
||||
${ht_capab}
|
||||
set wireless.radio${devidx}.channel=${channel}
|
||||
set wireless.radio${devidx}.band=${mode_band}
|
||||
set wireless.radio${devidx}.htmode=$htmode
|
||||
set wireless.radio${devidx}.disabled=0
|
||||
|
||||
set wireless.default_radio${devidx}=wifi-iface
|
||||
|
@ -0,0 +1,44 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 24 Nov 2021 10:30:41 +0100
|
||||
Subject: [PATCH] mac80211: fix regression in SSN handling of addba tx
|
||||
|
||||
Some drivers that do their own sequence number allocation (e.g. ath9k) rely
|
||||
on being able to modify params->ssn on starting tx ampdu sessions.
|
||||
This was broken by a change that modified it to use sta->tid_seq[tid] instead.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 31d8bb4e07f8 ("mac80211: agg-tx: refactor sending addba")
|
||||
Reported-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/agg-tx.c
|
||||
+++ b/net/mac80211/agg-tx.c
|
||||
@@ -480,8 +480,7 @@ static void ieee80211_send_addba_with_ti
|
||||
|
||||
/* send AddBA request */
|
||||
ieee80211_send_addba_request(sdata, sta->sta.addr, tid,
|
||||
- tid_tx->dialog_token,
|
||||
- sta->tid_seq[tid] >> 4,
|
||||
+ tid_tx->dialog_token, tid_tx->ssn,
|
||||
buf_size, tid_tx->timeout);
|
||||
|
||||
WARN_ON(test_and_set_bit(HT_AGG_STATE_SENT_ADDBA, &tid_tx->state));
|
||||
@@ -523,6 +522,7 @@ void ieee80211_tx_ba_session_handle_star
|
||||
|
||||
params.ssn = sta->tid_seq[tid] >> 4;
|
||||
ret = drv_ampdu_action(local, sdata, ¶ms);
|
||||
+ tid_tx->ssn = params.ssn;
|
||||
if (ret == IEEE80211_AMPDU_TX_START_DELAY_ADDBA) {
|
||||
return;
|
||||
} else if (ret == IEEE80211_AMPDU_TX_START_IMMEDIATE) {
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -190,6 +190,7 @@ struct tid_ampdu_tx {
|
||||
u8 stop_initiator;
|
||||
bool tx_stop;
|
||||
u16 buf_size;
|
||||
+ u16 ssn;
|
||||
|
||||
u16 failed_bar_ssn;
|
||||
bool bar_pending;
|
@ -0,0 +1,62 @@
|
||||
From: Xing Song <xing.song@mediatek.com>
|
||||
Date: Tue, 23 Nov 2021 11:31:23 +0800
|
||||
Subject: [PATCH] mac80211: set up the fwd_skb->dev for mesh forwarding
|
||||
|
||||
Mesh forwarding requires that the fwd_skb->dev is set up for TX handling,
|
||||
otherwise the following warning will be generated, so set it up for the
|
||||
pending frames.
|
||||
|
||||
[ 72.835674 ] WARNING: CPU: 0 PID: 1193 at __skb_flow_dissect+0x284/0x1298
|
||||
[ 72.842379 ] Modules linked in: ksmbd pppoe ppp_async l2tp_ppp ...
|
||||
[ 72.962020 ] CPU: 0 PID: 1193 Comm: kworker/u5:1 Tainted: P S 5.4.137 #0
|
||||
[ 72.969938 ] Hardware name: MT7622_MT7531 RFB (DT)
|
||||
[ 72.974659 ] Workqueue: napi_workq napi_workfn
|
||||
[ 72.979025 ] pstate: 60000005 (nZCv daif -PAN -UAO)
|
||||
[ 72.983822 ] pc : __skb_flow_dissect+0x284/0x1298
|
||||
[ 72.988444 ] lr : __skb_flow_dissect+0x54/0x1298
|
||||
[ 72.992977 ] sp : ffffffc010c738c0
|
||||
[ 72.996293 ] x29: ffffffc010c738c0 x28: 0000000000000000
|
||||
[ 73.001615 ] x27: 000000000000ffc2 x26: ffffff800c2eb818
|
||||
[ 73.006937 ] x25: ffffffc010a987c8 x24: 00000000000000ce
|
||||
[ 73.012259 ] x23: ffffffc010c73a28 x22: ffffffc010a99c60
|
||||
[ 73.017581 ] x21: 000000000000ffc2 x20: ffffff80094da800
|
||||
[ 73.022903 ] x19: 0000000000000000 x18: 0000000000000014
|
||||
[ 73.028226 ] x17: 00000000084d16af x16: 00000000d1fc0bab
|
||||
[ 73.033548 ] x15: 00000000715f6034 x14: 000000009dbdd301
|
||||
[ 73.038870 ] x13: 00000000ea4dcbc3 x12: 0000000000000040
|
||||
[ 73.044192 ] x11: 000000000eb00ff0 x10: 0000000000000000
|
||||
[ 73.049513 ] x9 : 000000000eb00073 x8 : 0000000000000088
|
||||
[ 73.054834 ] x7 : 0000000000000000 x6 : 0000000000000001
|
||||
[ 73.060155 ] x5 : 0000000000000000 x4 : 0000000000000000
|
||||
[ 73.065476 ] x3 : ffffffc010a98000 x2 : 0000000000000000
|
||||
[ 73.070797 ] x1 : 0000000000000000 x0 : 0000000000000000
|
||||
[ 73.076120 ] Call trace:
|
||||
[ 73.078572 ] __skb_flow_dissect+0x284/0x1298
|
||||
[ 73.082846 ] __skb_get_hash+0x7c/0x228
|
||||
[ 73.086629 ] ieee80211_txq_may_transmit+0x7fc/0x17b8 [mac80211]
|
||||
[ 73.092564 ] ieee80211_tx_prepare_skb+0x20c/0x268 [mac80211]
|
||||
[ 73.098238 ] ieee80211_tx_pending+0x144/0x330 [mac80211]
|
||||
[ 73.103560 ] tasklet_action_common.isra.16+0xb4/0x158
|
||||
[ 73.108618 ] tasklet_action+0x2c/0x38
|
||||
[ 73.112286 ] __do_softirq+0x168/0x3b0
|
||||
[ 73.115954 ] do_softirq.part.15+0x88/0x98
|
||||
[ 73.119969 ] __local_bh_enable_ip+0xb0/0xb8
|
||||
[ 73.124156 ] napi_workfn+0x58/0x90
|
||||
[ 73.127565 ] process_one_work+0x20c/0x478
|
||||
[ 73.131579 ] worker_thread+0x50/0x4f0
|
||||
[ 73.135249 ] kthread+0x124/0x128
|
||||
[ 73.138484 ] ret_from_fork+0x10/0x1c
|
||||
|
||||
Signed-off-by: Xing Song <xing.song@mediatek.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -2940,6 +2940,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
|
||||
if (!fwd_skb)
|
||||
goto out;
|
||||
|
||||
+ fwd_skb->dev = sdata->dev;
|
||||
fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data;
|
||||
fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY);
|
||||
info = IEEE80211_SKB_CB(fwd_skb);
|
@ -0,0 +1,26 @@
|
||||
From: Xing Song <xing.song@mediatek.com>
|
||||
Date: Mon, 1 Nov 2021 10:46:57 +0800
|
||||
Subject: [PATCH] mac80211: do not access the IV when it was stripped
|
||||
|
||||
ieee80211_get_keyid() will return false value if IV has been stripped,
|
||||
such as return 0 for IP/ARP frames due to LLC header, and return -EINVAL
|
||||
for disassociation frames due to its length... etc. Don't try to access
|
||||
it if it's not present.
|
||||
|
||||
Signed-off-by: Xing Song <xing.song@mediatek.com>
|
||||
Link: https://lore.kernel.org/r/20211101024657.143026-1-xing.song@mediatek.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -1945,7 +1945,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_
|
||||
int keyid = rx->sta->ptk_idx;
|
||||
sta_ptk = rcu_dereference(rx->sta->ptk[keyid]);
|
||||
|
||||
- if (ieee80211_has_protected(fc)) {
|
||||
+ if (ieee80211_has_protected(fc) &&
|
||||
+ !(status->flag & RX_FLAG_IV_STRIPPED)) {
|
||||
cs = rx->sta->cipher_scheme;
|
||||
keyid = ieee80211_get_keyid(rx->skb, cs);
|
||||
|
@ -183,7 +183,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
enabled = bss->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -4195,7 +4195,9 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
@@ -4197,7 +4197,9 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
.vif_type = sdata->vif.type,
|
||||
.control_port_protocol = sdata->control_port_protocol,
|
||||
}, *old, *new = NULL;
|
||||
@ -193,7 +193,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
/* use sparse to check that we don't return without updating */
|
||||
__acquire(check_fast_rx);
|
||||
@@ -4308,6 +4310,17 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
@@ -4310,6 +4312,17 @@ void ieee80211_check_fast_rx(struct sta_
|
||||
if (assign)
|
||||
new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL);
|
||||
|
||||
@ -211,7 +211,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
spin_lock_bh(&sta->lock);
|
||||
old = rcu_dereference_protected(sta->fast_rx, true);
|
||||
rcu_assign_pointer(sta->fast_rx, new);
|
||||
@@ -4354,6 +4367,108 @@ void ieee80211_check_fast_rx_iface(struc
|
||||
@@ -4356,6 +4369,108 @@ void ieee80211_check_fast_rx_iface(struc
|
||||
mutex_unlock(&local->sta_mtx);
|
||||
}
|
||||
|
||||
@ -320,7 +320,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
|
||||
struct ieee80211_fast_rx *fast_rx)
|
||||
{
|
||||
@@ -4374,9 +4489,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
@@ -4376,9 +4491,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
} addrs __aligned(2);
|
||||
struct ieee80211_sta_rx_stats *stats = &sta->rx_stats;
|
||||
|
||||
@ -330,7 +330,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
/* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write
|
||||
* to a common data structure; drivers can implement that per queue
|
||||
* but we don't have that information in mac80211
|
||||
@@ -4450,32 +4562,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
@@ -4452,32 +4564,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
pskb_trim(skb, skb->len - fast_rx->icv_len))
|
||||
goto drop;
|
||||
|
||||
@ -363,7 +363,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
if (rx->key && !ieee80211_has_protected(hdr->frame_control))
|
||||
goto drop;
|
||||
|
||||
@@ -4487,12 +4573,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
@@ -4489,12 +4575,6 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
/* do the header conversion - first grab the addresses */
|
||||
ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs);
|
||||
ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs);
|
||||
@@ -4501,62 +4581,14 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
@@ -4503,62 +4583,14 @@ static bool ieee80211_invoke_fast_rx(str
|
||||
/* push the addresses in front */
|
||||
memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs));
|
||||
|
||||
@ -443,7 +443,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
stats->dropped++;
|
||||
return true;
|
||||
}
|
||||
@@ -4610,6 +4642,47 @@ static bool ieee80211_prepare_and_rx_han
|
||||
@@ -4612,6 +4644,47 @@ static bool ieee80211_prepare_and_rx_han
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -491,7 +491,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
/*
|
||||
* This is the actual Rx frames handler. as it belongs to Rx path it must
|
||||
* be called with rcu_read_lock protection.
|
||||
@@ -4847,15 +4920,20 @@ void ieee80211_rx_list(struct ieee80211_
|
||||
@@ -4849,15 +4922,20 @@ void ieee80211_rx_list(struct ieee80211_
|
||||
* if it was previously present.
|
||||
* Also, frames with less than 16 bytes are dropped.
|
||||
*/
|
||||
|
@ -7,24 +7,6 @@ The software rate control cannot deal with encap offload, so fix it.
|
||||
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -2024,6 +2024,15 @@ static inline void ieee80211_tx_skb(stru
|
||||
ieee80211_tx_skb_tid(sdata, skb, 7);
|
||||
}
|
||||
|
||||
+static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+
|
||||
+ return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP ||
|
||||
+ ieee80211_is_data(hdr->frame_control);
|
||||
+}
|
||||
+
|
||||
u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
||||
struct ieee802_11_elems *elems,
|
||||
u64 filter, u32 crc, u8 *transmitter_bssid,
|
||||
--- a/net/mac80211/rate.c
|
||||
+++ b/net/mac80211/rate.c
|
||||
@@ -297,15 +297,11 @@ void ieee80211_check_rate_mask(struct ie
|
||||
@ -117,3 +99,28 @@ Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||
|
||||
if (info->control.flags & IEEE80211_TX_CTRL_FAST_XMIT) {
|
||||
struct sta_info *sta = container_of(txq->sta, struct sta_info,
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -6733,4 +6733,22 @@ struct sk_buff *ieee80211_get_fils_disco
|
||||
struct sk_buff *
|
||||
ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
+
|
||||
+/**
|
||||
+ * ieee80211_is_tx_data - check if frame is a data frame
|
||||
+ *
|
||||
+ * The function is used to check if a frame is a data frame. Frames with
|
||||
+ * hardware encapsulation enabled are data frames.
|
||||
+ *
|
||||
+ * @skb: the frame to be transmitted.
|
||||
+ */
|
||||
+static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
+ struct ieee80211_hdr *hdr = (void *) skb->data;
|
||||
+
|
||||
+ return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP ||
|
||||
+ ieee80211_is_data(hdr->frame_control);
|
||||
+}
|
||||
+
|
||||
#endif /* MAC80211_H */
|
||||
|
@ -0,0 +1,111 @@
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sat, 9 Jan 2021 18:57:51 +0100
|
||||
Subject: [PATCH] mac80211: introduce aql_enable node in debugfs
|
||||
|
||||
Introduce aql_enable node in debugfs in order to enable/disable aql.
|
||||
This is useful for debugging purpose.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://lore.kernel.org/r/e7a934d5d84e4796c4f97ea5de4e66c824296b07.1610214851.git.lorenzo@kernel.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/debugfs.c
|
||||
+++ b/net/mac80211/debugfs.c
|
||||
@@ -281,6 +281,56 @@ static const struct file_operations aql_
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
+static ssize_t aql_enable_read(struct file *file, char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ char buf[3];
|
||||
+ int len;
|
||||
+
|
||||
+ len = scnprintf(buf, sizeof(buf), "%d\n",
|
||||
+ !static_key_false(&aql_disable.key));
|
||||
+
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static ssize_t aql_enable_write(struct file *file, const char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ bool aql_disabled = static_key_false(&aql_disable.key);
|
||||
+ char buf[3];
|
||||
+ size_t len;
|
||||
+
|
||||
+ if (count > sizeof(buf))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (copy_from_user(buf, user_buf, count))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ buf[sizeof(buf) - 1] = '\0';
|
||||
+ len = strlen(buf);
|
||||
+ if (len > 0 && buf[len - 1] == '\n')
|
||||
+ buf[len - 1] = 0;
|
||||
+
|
||||
+ if (buf[0] == '0' && buf[1] == '\0') {
|
||||
+ if (!aql_disabled)
|
||||
+ static_branch_inc(&aql_disable);
|
||||
+ } else if (buf[0] == '1' && buf[1] == '\0') {
|
||||
+ if (aql_disabled)
|
||||
+ static_branch_dec(&aql_disable);
|
||||
+ } else {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations aql_enable_ops = {
|
||||
+ .write = aql_enable_write,
|
||||
+ .read = aql_enable_read,
|
||||
+ .open = simple_open,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
static ssize_t force_tx_status_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count,
|
||||
@@ -569,6 +619,7 @@ void debugfs_hw_add(struct ieee80211_loc
|
||||
DEBUGFS_ADD(power);
|
||||
DEBUGFS_ADD(hw_conf);
|
||||
DEBUGFS_ADD_MODE(force_tx_status, 0600);
|
||||
+ DEBUGFS_ADD_MODE(aql_enable, 0600);
|
||||
|
||||
if (local->ops->wake_tx_queue)
|
||||
DEBUGFS_ADD_MODE(aqm, 0600);
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1140,6 +1140,8 @@ enum mac80211_scan_state {
|
||||
SCAN_ABORT,
|
||||
};
|
||||
|
||||
+DECLARE_STATIC_KEY_FALSE(aql_disable);
|
||||
+
|
||||
struct ieee80211_local {
|
||||
/* embed the driver visible part.
|
||||
* don't cast (use the static inlines below), but we keep
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3909,6 +3909,8 @@ void __ieee80211_schedule_txq(struct iee
|
||||
}
|
||||
EXPORT_SYMBOL(__ieee80211_schedule_txq);
|
||||
|
||||
+DEFINE_STATIC_KEY_FALSE(aql_disable);
|
||||
+
|
||||
bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
|
||||
struct ieee80211_txq *txq)
|
||||
{
|
||||
@@ -3918,6 +3920,9 @@ bool ieee80211_txq_airtime_check(struct
|
||||
if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
|
||||
return true;
|
||||
|
||||
+ if (static_branch_unlikely(&aql_disable))
|
||||
+ return true;
|
||||
+
|
||||
if (!txq->sta)
|
||||
return true;
|
||||
|
@ -0,0 +1,39 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 18 Jun 2021 13:41:44 +0300
|
||||
Subject: [PATCH] mac80211: rearrange struct txq_info for fewer holes
|
||||
|
||||
We can slightly decrease the size of struct txq_info by
|
||||
rearranging some fields for fewer holes, so do that.
|
||||
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210618133832.1bf019a1fe2e.Ib54622b8d6dc1a9a7dc484e573c073119450538b@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
||||
- * Copyright (C) 2018-2020 Intel Corporation
|
||||
+ * Copyright (C) 2018-2021 Intel Corporation
|
||||
*/
|
||||
|
||||
#ifndef IEEE80211_I_H
|
||||
@@ -848,9 +848,12 @@ struct txq_info {
|
||||
struct fq_tin tin;
|
||||
struct codel_vars def_cvars;
|
||||
struct codel_stats cstats;
|
||||
- struct sk_buff_head frags;
|
||||
- struct list_head schedule_order;
|
||||
+
|
||||
u16 schedule_round;
|
||||
+ struct list_head schedule_order;
|
||||
+
|
||||
+ struct sk_buff_head frags;
|
||||
+
|
||||
unsigned long flags;
|
||||
|
||||
/* keep last! */
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,398 @@
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Thu, 3 Dec 2020 05:37:26 -0500
|
||||
Subject: [PATCH] nl80211: add common API to configure SAR power limitations
|
||||
|
||||
NL80211_CMD_SET_SAR_SPECS is added to configure SAR from
|
||||
user space. NL80211_ATTR_SAR_SPEC is used to pass the SAR
|
||||
power specification when used with NL80211_CMD_SET_SAR_SPECS.
|
||||
|
||||
Wireless driver needs to register SAR type, supported frequency
|
||||
ranges to wiphy, so user space can query it. The index in
|
||||
frequency range is used to specify which sub band the power
|
||||
limitation applies to. The SAR type is for compatibility, so later
|
||||
other SAR mechanism can be implemented without breaking the user
|
||||
space SAR applications.
|
||||
|
||||
Normal process is user space queries the SAR capability, and
|
||||
gets the index of supported frequency ranges and associates the
|
||||
power limitation with this index and sends to kernel.
|
||||
|
||||
Here is an example of message send to kernel:
|
||||
8c 00 00 00 08 00 01 00 00 00 00 00 38 00 2b 81
|
||||
08 00 01 00 00 00 00 00 2c 00 02 80 14 00 00 80
|
||||
08 00 02 00 00 00 00 00 08 00 01 00 38 00 00 00
|
||||
14 00 01 80 08 00 02 00 01 00 00 00 08 00 01 00
|
||||
48 00 00 00
|
||||
|
||||
NL80211_CMD_SET_SAR_SPECS: 0x8c
|
||||
NL80211_ATTR_WIPHY: 0x01(phy idx is 0)
|
||||
NL80211_ATTR_SAR_SPEC: 0x812b (NLA_NESTED)
|
||||
NL80211_SAR_ATTR_TYPE: 0x00 (NL80211_SAR_TYPE_POWER)
|
||||
NL80211_SAR_ATTR_SPECS: 0x8002 (NLA_NESTED)
|
||||
freq range 0 power: 0x38 in 0.25dbm unit (14dbm)
|
||||
freq range 1 power: 0x48 in 0.25dbm unit (18dbm)
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Reviewed-by: Brian Norris <briannorris@chromium.org>
|
||||
Reviewed-by: Abhishek Kumar <kuabhs@chromium.org>
|
||||
Link: https://lore.kernel.org/r/20201203103728.3034-2-cjhuang@codeaurora.org
|
||||
[minor edits, NLA parse cleanups]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -1737,6 +1737,54 @@ struct station_info {
|
||||
u8 connected_to_as;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct cfg80211_sar_sub_specs - sub specs limit
|
||||
+ * @power: power limitation in 0.25dbm
|
||||
+ * @freq_range_index: index the power limitation applies to
|
||||
+ */
|
||||
+struct cfg80211_sar_sub_specs {
|
||||
+ s32 power;
|
||||
+ u32 freq_range_index;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct cfg80211_sar_specs - sar limit specs
|
||||
+ * @type: it's set with power in 0.25dbm or other types
|
||||
+ * @num_sub_specs: number of sar sub specs
|
||||
+ * @sub_specs: memory to hold the sar sub specs
|
||||
+ */
|
||||
+struct cfg80211_sar_specs {
|
||||
+ enum nl80211_sar_type type;
|
||||
+ u32 num_sub_specs;
|
||||
+ struct cfg80211_sar_sub_specs sub_specs[];
|
||||
+};
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ * @struct cfg80211_sar_chan_ranges - sar frequency ranges
|
||||
+ * @start_freq: start range edge frequency
|
||||
+ * @end_freq: end range edge frequency
|
||||
+ */
|
||||
+struct cfg80211_sar_freq_ranges {
|
||||
+ u32 start_freq;
|
||||
+ u32 end_freq;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct cfg80211_sar_capa - sar limit capability
|
||||
+ * @type: it's set via power in 0.25dbm or other types
|
||||
+ * @num_freq_ranges: number of frequency ranges
|
||||
+ * @freq_ranges: memory to hold the freq ranges.
|
||||
+ *
|
||||
+ * Note: WLAN driver may append new ranges or split an existing
|
||||
+ * range to small ones and then append them.
|
||||
+ */
|
||||
+struct cfg80211_sar_capa {
|
||||
+ enum nl80211_sar_type type;
|
||||
+ u32 num_freq_ranges;
|
||||
+ const struct cfg80211_sar_freq_ranges *freq_ranges;
|
||||
+};
|
||||
+
|
||||
#if IS_ENABLED(CPTCFG_CFG80211)
|
||||
/**
|
||||
* cfg80211_get_station - retrieve information about a given station
|
||||
@@ -4259,6 +4307,8 @@ struct cfg80211_ops {
|
||||
struct cfg80211_tid_config *tid_conf);
|
||||
int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u8 tids);
|
||||
+ int (*set_sar_specs)(struct wiphy *wiphy,
|
||||
+ struct cfg80211_sar_specs *sar);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -5030,6 +5080,8 @@ struct wiphy {
|
||||
|
||||
u8 max_data_retry_count;
|
||||
|
||||
+ const struct cfg80211_sar_capa *sar_capa;
|
||||
+
|
||||
char priv[] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -405,6 +405,18 @@ nl80211_unsol_bcast_probe_resp_policy[NL
|
||||
.len = IEEE80211_MAX_DATA_LEN }
|
||||
};
|
||||
|
||||
+static const struct nla_policy
|
||||
+sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
|
||||
+ [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 },
|
||||
+ [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 },
|
||||
+};
|
||||
+
|
||||
+static const struct nla_policy
|
||||
+sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
|
||||
+ [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE),
|
||||
+ [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
|
||||
+};
|
||||
+
|
||||
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
[0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
|
||||
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
|
||||
@@ -739,6 +751,7 @@ static const struct nla_policy nl80211_p
|
||||
[NL80211_ATTR_SAE_PWE] =
|
||||
NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
|
||||
NL80211_SAE_PWE_BOTH),
|
||||
+ [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
};
|
||||
|
||||
@@ -2117,6 +2130,56 @@ fail:
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
+static int
|
||||
+nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct sk_buff *msg)
|
||||
+{
|
||||
+ struct nlattr *sar_capa, *specs, *sub_freq_range;
|
||||
+ u8 num_freq_ranges;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!rdev->wiphy.sar_capa)
|
||||
+ return 0;
|
||||
+
|
||||
+ num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges;
|
||||
+
|
||||
+ sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
|
||||
+ if (!sar_capa)
|
||||
+ return -ENOSPC;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type))
|
||||
+ goto fail;
|
||||
+
|
||||
+ specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
|
||||
+ if (!specs)
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* report supported freq_ranges */
|
||||
+ for (i = 0; i < num_freq_ranges; i++) {
|
||||
+ sub_freq_range = nla_nest_start(msg, i + 1);
|
||||
+ if (!sub_freq_range)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
|
||||
+ rdev->wiphy.sar_capa->freq_ranges[i].start_freq))
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
|
||||
+ rdev->wiphy.sar_capa->freq_ranges[i].end_freq))
|
||||
+ goto fail;
|
||||
+
|
||||
+ nla_nest_end(msg, sub_freq_range);
|
||||
+ }
|
||||
+
|
||||
+ nla_nest_end(msg, specs);
|
||||
+ nla_nest_end(msg, sar_capa);
|
||||
+
|
||||
+ return 0;
|
||||
+fail:
|
||||
+ nla_nest_cancel(msg, sar_capa);
|
||||
+ return -ENOBUFS;
|
||||
+}
|
||||
+
|
||||
struct nl80211_dump_wiphy_state {
|
||||
s64 filter_wiphy;
|
||||
long start;
|
||||
@@ -2366,6 +2429,8 @@ static int nl80211_send_wiphy(struct cfg
|
||||
CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
|
||||
CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
|
||||
CMD(update_ft_ies, UPDATE_FT_IES);
|
||||
+ if (rdev->wiphy.sar_capa)
|
||||
+ CMD(set_sar_specs, SET_SAR_SPECS);
|
||||
}
|
||||
#undef CMD
|
||||
|
||||
@@ -2691,6 +2756,11 @@ static int nl80211_send_wiphy(struct cfg
|
||||
|
||||
if (nl80211_put_tid_config_support(rdev, msg))
|
||||
goto nla_put_failure;
|
||||
+ state->split_start++;
|
||||
+ break;
|
||||
+ case 16:
|
||||
+ if (nl80211_put_sar_specs(rdev, msg))
|
||||
+ goto nla_put_failure;
|
||||
|
||||
/* done */
|
||||
state->split_start = 0;
|
||||
@@ -14712,6 +14782,111 @@ static void nl80211_post_doit(__genl_con
|
||||
}
|
||||
}
|
||||
|
||||
+static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct cfg80211_sar_specs *sar_specs,
|
||||
+ struct nlattr *spec[], int index)
|
||||
+{
|
||||
+ u32 range_index, i;
|
||||
+
|
||||
+ if (!sar_specs || !spec)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
|
||||
+ !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]);
|
||||
+
|
||||
+ /* check if range_index exceeds num_freq_ranges */
|
||||
+ if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* check if range_index duplicates */
|
||||
+ for (i = 0; i < index; i++) {
|
||||
+ if (sar_specs->sub_specs[i].freq_range_index == range_index)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ sar_specs->sub_specs[index].power =
|
||||
+ nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]);
|
||||
+
|
||||
+ sar_specs->sub_specs[index].freq_range_index = range_index;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
|
||||
+{
|
||||
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
+ struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1];
|
||||
+ struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1];
|
||||
+ struct cfg80211_sar_specs *sar_spec;
|
||||
+ enum nl80211_sar_type type;
|
||||
+ struct nlattr *spec_list;
|
||||
+ u32 specs;
|
||||
+ int rem, err;
|
||||
+
|
||||
+ if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!info->attrs[NL80211_ATTR_SAR_SPEC])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ nla_parse_nested(tb, NL80211_SAR_ATTR_MAX,
|
||||
+ info->attrs[NL80211_ATTR_SAR_SPEC],
|
||||
+ NULL, NULL);
|
||||
+
|
||||
+ if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
|
||||
+ if (type != rdev->wiphy.sar_capa->type)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ specs = 0;
|
||||
+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
|
||||
+ specs++;
|
||||
+
|
||||
+ if (specs > rdev->wiphy.sar_capa->num_freq_ranges)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ sar_spec = kzalloc(sizeof(*sar_spec) +
|
||||
+ specs * sizeof(struct cfg80211_sar_sub_specs),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!sar_spec)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sar_spec->type = type;
|
||||
+ specs = 0;
|
||||
+ nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
|
||||
+ nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX,
|
||||
+ spec_list, NULL, NULL);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case NL80211_SAR_TYPE_POWER:
|
||||
+ if (nl80211_set_sar_sub_specs(rdev, sar_spec,
|
||||
+ spec, specs)) {
|
||||
+ err = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ err = -EINVAL;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ specs++;
|
||||
+ }
|
||||
+
|
||||
+ sar_spec->num_sub_specs = specs;
|
||||
+
|
||||
+ rdev->cur_cmd_info = info;
|
||||
+ err = rdev_set_sar_specs(rdev, sar_spec);
|
||||
+ rdev->cur_cmd_info = NULL;
|
||||
+error:
|
||||
+ kfree(sar_spec);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static __genl_const struct genl_ops nl80211_ops[] = {
|
||||
{
|
||||
.cmd = NL80211_CMD_GET_WIPHY,
|
||||
@@ -15575,6 +15750,14 @@ static const struct genl_small_ops nl802
|
||||
.internal_flags = NL80211_FLAG_NEED_NETDEV |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
+ {
|
||||
+ .cmd = NL80211_CMD_SET_SAR_SPECS,
|
||||
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
+ .doit = nl80211_set_sar_specs,
|
||||
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||
+ .internal_flags = NL80211_FLAG_NEED_WIPHY |
|
||||
+ NL80211_FLAG_NEED_RTNL,
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct genl_family nl80211_fam __genl_ro_after_init = {
|
||||
--- a/net/wireless/rdev-ops.h
|
||||
+++ b/net/wireless/rdev-ops.h
|
||||
@@ -1356,4 +1356,16 @@ static inline int rdev_reset_tid_config(
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static inline int rdev_set_sar_specs(struct cfg80211_registered_device *rdev,
|
||||
+ struct cfg80211_sar_specs *sar)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ trace_rdev_set_sar_specs(&rdev->wiphy, sar);
|
||||
+ ret = rdev->ops->set_sar_specs(&rdev->wiphy, sar);
|
||||
+ trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#endif /* __CFG80211_RDEV_OPS */
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -3551,6 +3551,25 @@ TRACE_EVENT(rdev_reset_tid_config,
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT ", tids: 0x%x",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tids)
|
||||
);
|
||||
+
|
||||
+TRACE_EVENT(rdev_set_sar_specs,
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_sar_specs *sar),
|
||||
+ TP_ARGS(wiphy, sar),
|
||||
+ TP_STRUCT__entry(
|
||||
+ WIPHY_ENTRY
|
||||
+ __field(u16, type)
|
||||
+ __field(u16, num)
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ WIPHY_ASSIGN;
|
||||
+ __entry->type = sar->type;
|
||||
+ __entry->num = sar->num_sub_specs;
|
||||
+
|
||||
+ ),
|
||||
+ TP_printk(WIPHY_PR_FMT ", Set type:%d, num_specs:%d",
|
||||
+ WIPHY_PR_ARG, __entry->type, __entry->num)
|
||||
+);
|
||||
+
|
||||
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -0,0 +1,51 @@
|
||||
From: Carl Huang <cjhuang@codeaurora.org>
|
||||
Date: Thu, 3 Dec 2020 05:37:27 -0500
|
||||
Subject: [PATCH] mac80211: add ieee80211_set_sar_specs
|
||||
|
||||
This change registers ieee80211_set_sar_specs to
|
||||
mac80211_config_ops, so cfg80211 can call it.
|
||||
|
||||
Signed-off-by: Carl Huang <cjhuang@codeaurora.org>
|
||||
Reviewed-by: Brian Norris <briannorris@chromium.org>
|
||||
Reviewed-by: Abhishek Kumar <kuabhs@chromium.org>
|
||||
Link: https://lore.kernel.org/r/20201203103728.3034-3-cjhuang@codeaurora.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -4207,6 +4207,8 @@ struct ieee80211_ops {
|
||||
struct ieee80211_vif *vif);
|
||||
void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
+ int (*set_sar_specs)(struct ieee80211_hw *hw,
|
||||
+ const struct cfg80211_sar_specs *sar);
|
||||
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -4136,6 +4136,17 @@ static int ieee80211_reset_tid_config(st
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int ieee80211_set_sar_specs(struct wiphy *wiphy,
|
||||
+ struct cfg80211_sar_specs *sar)
|
||||
+{
|
||||
+ struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
+
|
||||
+ if (!local->ops->set_sar_specs)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return local->ops->set_sar_specs(&local->hw, sar);
|
||||
+}
|
||||
+
|
||||
const struct cfg80211_ops mac80211_config_ops = {
|
||||
.add_virtual_intf = ieee80211_add_iface,
|
||||
.del_virtual_intf = ieee80211_del_iface,
|
||||
@@ -4239,4 +4250,5 @@ const struct cfg80211_ops mac80211_confi
|
||||
.probe_mesh_link = ieee80211_probe_mesh_link,
|
||||
.set_tid_config = ieee80211_set_tid_config,
|
||||
.reset_tid_config = ieee80211_reset_tid_config,
|
||||
+ .set_sar_specs = ieee80211_set_sar_specs,
|
||||
};
|
@ -0,0 +1,26 @@
|
||||
From: Ryder Lee <ryder.lee@mediatek.com>
|
||||
Date: Fri, 18 Jun 2021 04:38:59 +0800
|
||||
Subject: [PATCH] mac80211: check per vif offload_flags in Tx path
|
||||
|
||||
offload_flags has been introduced to indicate encap status of each interface.
|
||||
An interface can encap offload at runtime, or if it has some extra limitations
|
||||
it can simply override the flags, so it's more flexible to check offload_flags
|
||||
in Tx path.
|
||||
|
||||
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
|
||||
Link: https://lore.kernel.org/r/177785418cf407808bf3a44760302d0647076990.1623961575.git.ryder.lee@mediatek.com
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -3331,6 +3331,9 @@ static bool ieee80211_amsdu_aggregate(st
|
||||
if (!ieee80211_hw_check(&local->hw, TX_AMSDU))
|
||||
return false;
|
||||
|
||||
+ if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED)
|
||||
+ return false;
|
||||
+
|
||||
if (skb_is_gso(skb))
|
||||
return false;
|
||||
|
@ -0,0 +1,485 @@
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Fri, 2 Jul 2021 19:44:07 +0200
|
||||
Subject: [PATCH] nl80211: add support for BSS coloring
|
||||
|
||||
This patch adds support for BSS color collisions to the wireless subsystem.
|
||||
Add the required functionality to nl80211 that will notify about color
|
||||
collisions, triggering the color change and notifying when it is completed.
|
||||
|
||||
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
Link: https://lore.kernel.org/r/500b3582aec8fe2c42ef46f3117b148cb7cbceb5.1625247619.git.lorenzo@kernel.org
|
||||
[remove unnecessary NULL initialisation]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -1252,6 +1252,27 @@ struct cfg80211_csa_settings {
|
||||
#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
|
||||
|
||||
/**
|
||||
+ * struct cfg80211_color_change_settings - color change settings
|
||||
+ *
|
||||
+ * Used for bss color change
|
||||
+ *
|
||||
+ * @beacon_color_change: beacon data while performing the color countdown
|
||||
+ * @counter_offsets_beacon: offsets of the counters within the beacon (tail)
|
||||
+ * @counter_offsets_presp: offsets of the counters within the probe response
|
||||
+ * @beacon_next: beacon data to be used after the color change
|
||||
+ * @count: number of beacons until the color change
|
||||
+ * @color: the color used after the change
|
||||
+ */
|
||||
+struct cfg80211_color_change_settings {
|
||||
+ struct cfg80211_beacon_data beacon_color_change;
|
||||
+ u16 counter_offset_beacon;
|
||||
+ u16 counter_offset_presp;
|
||||
+ struct cfg80211_beacon_data beacon_next;
|
||||
+ u8 count;
|
||||
+ u8 color;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
* struct iface_combination_params - input parameters for interface combinations
|
||||
*
|
||||
* Used to pass interface combination parameters
|
||||
@@ -3979,6 +4000,8 @@ struct mgmt_frame_regs {
|
||||
* This callback may sleep.
|
||||
* @reset_tid_config: Reset TID specific configuration for the peer, for the
|
||||
* given TIDs. This callback may sleep.
|
||||
+ *
|
||||
+ * @color_change: Initiate a color change.
|
||||
*/
|
||||
struct cfg80211_ops {
|
||||
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
|
||||
@@ -4309,6 +4332,9 @@ struct cfg80211_ops {
|
||||
const u8 *peer, u8 tids);
|
||||
int (*set_sar_specs)(struct wiphy *wiphy,
|
||||
struct cfg80211_sar_specs *sar);
|
||||
+ int (*color_change)(struct wiphy *wiphy,
|
||||
+ struct net_device *dev,
|
||||
+ struct cfg80211_color_change_settings *params);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -8094,4 +8120,70 @@ void cfg80211_update_owe_info_event(stru
|
||||
*/
|
||||
void cfg80211_bss_flush(struct wiphy *wiphy);
|
||||
|
||||
+/**
|
||||
+ * cfg80211_bss_color_notify - notify about bss color event
|
||||
+ * @dev: network device
|
||||
+ * @gfp: allocation flags
|
||||
+ * @cmd: the actual event we want to notify
|
||||
+ * @count: the number of TBTTs until the color change happens
|
||||
+ * @color_bitmap: representations of the colors that the local BSS is aware of
|
||||
+ */
|
||||
+int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp,
|
||||
+ enum nl80211_commands cmd, u8 count,
|
||||
+ u64 color_bitmap);
|
||||
+
|
||||
+/**
|
||||
+ * cfg80211_obss_color_collision_notify - notify about bss color collision
|
||||
+ * @dev: network device
|
||||
+ * @color_bitmap: representations of the colors that the local BSS is aware of
|
||||
+ */
|
||||
+static inline int cfg80211_obss_color_collision_notify(struct net_device *dev,
|
||||
+ u64 color_bitmap)
|
||||
+{
|
||||
+ return cfg80211_bss_color_notify(dev, GFP_KERNEL,
|
||||
+ NL80211_CMD_OBSS_COLOR_COLLISION,
|
||||
+ 0, color_bitmap);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cfg80211_color_change_started_notify - notify color change start
|
||||
+ * @dev: the device on which the color is switched
|
||||
+ * @count: the number of TBTTs until the color change happens
|
||||
+ *
|
||||
+ * Inform the userspace about the color change that has started.
|
||||
+ */
|
||||
+static inline int cfg80211_color_change_started_notify(struct net_device *dev,
|
||||
+ u8 count)
|
||||
+{
|
||||
+ return cfg80211_bss_color_notify(dev, GFP_KERNEL,
|
||||
+ NL80211_CMD_COLOR_CHANGE_STARTED,
|
||||
+ count, 0);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cfg80211_color_change_aborted_notify - notify color change abort
|
||||
+ * @dev: the device on which the color is switched
|
||||
+ *
|
||||
+ * Inform the userspace about the color change that has aborted.
|
||||
+ */
|
||||
+static inline int cfg80211_color_change_aborted_notify(struct net_device *dev)
|
||||
+{
|
||||
+ return cfg80211_bss_color_notify(dev, GFP_KERNEL,
|
||||
+ NL80211_CMD_COLOR_CHANGE_ABORTED,
|
||||
+ 0, 0);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * cfg80211_color_change_notify - notify color change completion
|
||||
+ * @dev: the device on which the color was switched
|
||||
+ *
|
||||
+ * Inform the userspace about the color change that has completed.
|
||||
+ */
|
||||
+static inline int cfg80211_color_change_notify(struct net_device *dev)
|
||||
+{
|
||||
+ return cfg80211_bss_color_notify(dev, GFP_KERNEL,
|
||||
+ NL80211_CMD_COLOR_CHANGE_COMPLETED,
|
||||
+ 0, 0);
|
||||
+}
|
||||
+
|
||||
#endif /* __NET_CFG80211_H */
|
||||
--- a/include/uapi/linux/nl80211.h
|
||||
+++ b/include/uapi/linux/nl80211.h
|
||||
@@ -1185,6 +1185,21 @@
|
||||
* passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to
|
||||
* specify the wiphy index to be applied to.
|
||||
*
|
||||
+ * @NL80211_CMD_OBSS_COLOR_COLLISION: This notification is sent out whenever
|
||||
+ * mac80211/drv detects a bss color collision.
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_REQUEST: This command is used to indicate that
|
||||
+ * userspace wants to change the BSS color.
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_STARTED: Notify userland, that a color change has
|
||||
+ * started
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_ABORTED: Notify userland, that the color change has
|
||||
+ * been aborted
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_COMPLETED: Notify userland that the color change
|
||||
+ * has completed
|
||||
+ *
|
||||
* @NL80211_CMD_MAX: highest used command number
|
||||
* @__NL80211_CMD_AFTER_LAST: internal use
|
||||
*/
|
||||
@@ -1417,6 +1432,14 @@ enum nl80211_commands {
|
||||
|
||||
NL80211_CMD_SET_SAR_SPECS,
|
||||
|
||||
+ NL80211_CMD_OBSS_COLOR_COLLISION,
|
||||
+
|
||||
+ NL80211_CMD_COLOR_CHANGE_REQUEST,
|
||||
+
|
||||
+ NL80211_CMD_COLOR_CHANGE_STARTED,
|
||||
+ NL80211_CMD_COLOR_CHANGE_ABORTED,
|
||||
+ NL80211_CMD_COLOR_CHANGE_COMPLETED,
|
||||
+
|
||||
/* add new commands above here */
|
||||
|
||||
/* used to define NL80211_CMD_MAX below */
|
||||
@@ -2560,6 +2583,16 @@ enum nl80211_commands {
|
||||
* disassoc events to indicate that an immediate reconnect to the AP
|
||||
* is desired.
|
||||
*
|
||||
+ * @NL80211_ATTR_OBSS_COLOR_BITMAP: bitmap of the u64 BSS colors for the
|
||||
+ * %NL80211_CMD_OBSS_COLOR_COLLISION event.
|
||||
+ *
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_COUNT: u8 attribute specifying the number of TBTT's
|
||||
+ * until the color switch event.
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_COLOR: u8 attribute specifying the color that we are
|
||||
+ * switching to
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_ELEMS: Nested set of attributes containing the IE
|
||||
+ * information for the time while performing a color switch.
|
||||
+ *
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@@ -3057,6 +3090,12 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_DISABLE_HE,
|
||||
|
||||
+ NL80211_ATTR_OBSS_COLOR_BITMAP,
|
||||
+
|
||||
+ NL80211_ATTR_COLOR_CHANGE_COUNT,
|
||||
+ NL80211_ATTR_COLOR_CHANGE_COLOR,
|
||||
+ NL80211_ATTR_COLOR_CHANGE_ELEMS,
|
||||
+
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
@@ -5950,6 +5989,9 @@ enum nl80211_feature_flags {
|
||||
* frame protection for all management frames exchanged during the
|
||||
* negotiation and range measurement procedure.
|
||||
*
|
||||
+ * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision
|
||||
+ * detection and change announcemnts.
|
||||
+ *
|
||||
* @NUM_NL80211_EXT_FEATURES: number of extended features.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
|
||||
*/
|
||||
@@ -6014,6 +6056,7 @@ enum nl80211_ext_feature_index {
|
||||
NL80211_EXT_FEATURE_SECURE_LTF,
|
||||
NL80211_EXT_FEATURE_SECURE_RTT,
|
||||
NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
|
||||
+ NL80211_EXT_FEATURE_BSS_COLOR,
|
||||
|
||||
/* add new features before the definition below */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -753,6 +753,10 @@ static const struct nla_policy nl80211_p
|
||||
NL80211_SAE_PWE_BOTH),
|
||||
[NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
+ [NL80211_ATTR_OBSS_COLOR_BITMAP] = { .type = NLA_U64 },
|
||||
+ [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 },
|
||||
+ [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
|
||||
+ [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -14677,6 +14681,106 @@ bad_tid_conf:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info)
|
||||
+{
|
||||
+ struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
+ struct cfg80211_color_change_settings params = {};
|
||||
+ struct net_device *dev = info->user_ptr[1];
|
||||
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
+ struct nlattr **tb;
|
||||
+ u16 offset;
|
||||
+ int err;
|
||||
+
|
||||
+ if (!rdev->ops->color_change)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
+ NL80211_EXT_FEATURE_BSS_COLOR))
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (wdev->iftype != NL80211_IFTYPE_AP)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT] ||
|
||||
+ !info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR] ||
|
||||
+ !info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS])
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]);
|
||||
+ params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]);
|
||||
+
|
||||
+ err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_next);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ tb = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*tb), GFP_KERNEL);
|
||||
+ if (!tb)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = nla_parse_nested(tb, NL80211_ATTR_MAX,
|
||||
+ info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS],
|
||||
+ nl80211_policy, info->extack);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ err = nl80211_parse_beacon(rdev, tb, ¶ms.beacon_color_change);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) != sizeof(u16)) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
|
||||
+ if (offset >= params.beacon_color_change.tail_len) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (params.beacon_color_change.tail[offset] != params.count) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ params.counter_offset_beacon = offset;
|
||||
+
|
||||
+ if (tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
|
||||
+ if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) !=
|
||||
+ sizeof(u16)) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
|
||||
+ if (offset >= params.beacon_color_change.probe_resp_len) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (params.beacon_color_change.probe_resp[offset] !=
|
||||
+ params.count) {
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ params.counter_offset_presp = offset;
|
||||
+ }
|
||||
+
|
||||
+ wdev_lock(wdev);
|
||||
+ err = rdev_color_change(rdev, dev, ¶ms);
|
||||
+ wdev_unlock(wdev);
|
||||
+
|
||||
+out:
|
||||
+ kfree(tb);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
#define NL80211_FLAG_NEED_WIPHY 0x01
|
||||
#define NL80211_FLAG_NEED_NETDEV 0x02
|
||||
#define NL80211_FLAG_NEED_RTNL 0x04
|
||||
@@ -15758,6 +15862,14 @@ static const struct genl_small_ops nl802
|
||||
.internal_flags = NL80211_FLAG_NEED_WIPHY |
|
||||
NL80211_FLAG_NEED_RTNL,
|
||||
},
|
||||
+ {
|
||||
+ .cmd = NL80211_CMD_COLOR_CHANGE_REQUEST,
|
||||
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
+ .doit = nl80211_color_change,
|
||||
+ .flags = GENL_UNS_ADMIN_PERM,
|
||||
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
|
||||
+ NL80211_FLAG_NEED_RTNL,
|
||||
+ },
|
||||
};
|
||||
|
||||
static struct genl_family nl80211_fam __genl_ro_after_init = {
|
||||
@@ -17384,6 +17496,51 @@ void cfg80211_ch_switch_started_notify(s
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
|
||||
|
||||
+int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp,
|
||||
+ enum nl80211_commands cmd, u8 count,
|
||||
+ u64 color_bitmap)
|
||||
+{
|
||||
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
+ struct wiphy *wiphy = wdev->wiphy;
|
||||
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
+ struct sk_buff *msg;
|
||||
+ void *hdr;
|
||||
+
|
||||
+ ASSERT_WDEV_LOCK(wdev);
|
||||
+
|
||||
+ trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap);
|
||||
+
|
||||
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
|
||||
+ if (!msg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
|
||||
+ if (!hdr)
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ if (cmd == NL80211_CMD_COLOR_CHANGE_STARTED &&
|
||||
+ nla_put_u32(msg, NL80211_ATTR_COLOR_CHANGE_COUNT, count))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ if (cmd == NL80211_CMD_OBSS_COLOR_COLLISION &&
|
||||
+ nla_put_u64_64bit(msg, NL80211_ATTR_OBSS_COLOR_BITMAP,
|
||||
+ color_bitmap, NL80211_ATTR_PAD))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ genlmsg_end(msg, hdr);
|
||||
+
|
||||
+ return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
|
||||
+ msg, 0, NL80211_MCGRP_MLME, gfp);
|
||||
+
|
||||
+nla_put_failure:
|
||||
+ nlmsg_free(msg);
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+EXPORT_SYMBOL(cfg80211_bss_color_notify);
|
||||
+
|
||||
void
|
||||
nl80211_radar_notify(struct cfg80211_registered_device *rdev,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
--- a/net/wireless/rdev-ops.h
|
||||
+++ b/net/wireless/rdev-ops.h
|
||||
@@ -1368,4 +1368,17 @@ static inline int rdev_set_sar_specs(str
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static inline int rdev_color_change(struct cfg80211_registered_device *rdev,
|
||||
+ struct net_device *dev,
|
||||
+ struct cfg80211_color_change_settings *params)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ trace_rdev_color_change(&rdev->wiphy, dev, params);
|
||||
+ ret = rdev->ops->color_change(&rdev->wiphy, dev, params);
|
||||
+ trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
#endif /* __CFG80211_RDEV_OPS */
|
||||
--- a/net/wireless/trace.h
|
||||
+++ b/net/wireless/trace.h
|
||||
@@ -3570,6 +3570,52 @@ TRACE_EVENT(rdev_set_sar_specs,
|
||||
WIPHY_PR_ARG, __entry->type, __entry->num)
|
||||
);
|
||||
|
||||
+TRACE_EVENT(rdev_color_change,
|
||||
+ TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
+ struct cfg80211_color_change_settings *params),
|
||||
+ TP_ARGS(wiphy, netdev, params),
|
||||
+ TP_STRUCT__entry(
|
||||
+ WIPHY_ENTRY
|
||||
+ NETDEV_ENTRY
|
||||
+ __field(u8, count)
|
||||
+ __field(u16, bcn_ofs)
|
||||
+ __field(u16, pres_ofs)
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ WIPHY_ASSIGN;
|
||||
+ NETDEV_ASSIGN;
|
||||
+ __entry->count = params->count;
|
||||
+ __entry->bcn_ofs = params->counter_offset_beacon;
|
||||
+ __entry->pres_ofs = params->counter_offset_presp;
|
||||
+ ),
|
||||
+ TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT
|
||||
+ ", count: %u",
|
||||
+ WIPHY_PR_ARG, NETDEV_PR_ARG,
|
||||
+ __entry->count)
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(cfg80211_bss_color_notify,
|
||||
+ TP_PROTO(struct net_device *netdev,
|
||||
+ enum nl80211_commands cmd,
|
||||
+ u8 count, u64 color_bitmap),
|
||||
+ TP_ARGS(netdev, cmd, count, color_bitmap),
|
||||
+ TP_STRUCT__entry(
|
||||
+ NETDEV_ENTRY
|
||||
+ __field(enum nl80211_bss_scan_width, cmd)
|
||||
+ __field(u8, count)
|
||||
+ __field(u64, color_bitmap)
|
||||
+ ),
|
||||
+ TP_fast_assign(
|
||||
+ NETDEV_ASSIGN;
|
||||
+ __entry->cmd = cmd;
|
||||
+ __entry->count = count;
|
||||
+ __entry->color_bitmap = color_bitmap;
|
||||
+ ),
|
||||
+ TP_printk(NETDEV_PR_FMT ", cmd: %x, count: %u, bitmap: %llx",
|
||||
+ NETDEV_PR_ARG, __entry->cmd, __entry->count,
|
||||
+ __entry->color_bitmap)
|
||||
+);
|
||||
+
|
||||
#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -0,0 +1,524 @@
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Fri, 2 Jul 2021 19:44:08 +0200
|
||||
Subject: [PATCH] mac80211: add support for BSS color change
|
||||
|
||||
The color change announcement is very similar to how CSA works where
|
||||
we have an IE that includes a counter. When the counter hits 0, the new
|
||||
color is applied via an updated beacon.
|
||||
|
||||
This patch makes the CSA counter functionality reusable, rather than
|
||||
implementing it again. This also allows for future reuse incase support
|
||||
for other counter IEs gets added.
|
||||
|
||||
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
Link: https://lore.kernel.org/r/057c1e67b82bee561ea44ce6a45a8462d3da6995.1625247619.git.lorenzo@kernel.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -1710,6 +1710,10 @@ enum ieee80211_offload_flags {
|
||||
* protected by fq->lock.
|
||||
* @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see
|
||||
* &enum ieee80211_offload_flags.
|
||||
+ * @color_change_active: marks whether a color change is ongoing. Internally it is
|
||||
+ * write-protected by sdata_lock and local->mtx so holding either is fine
|
||||
+ * for read access.
|
||||
+ * @color_change_color: the bss color that will be used after the change.
|
||||
*/
|
||||
struct ieee80211_vif {
|
||||
enum nl80211_iftype type;
|
||||
@@ -1738,6 +1742,9 @@ struct ieee80211_vif {
|
||||
|
||||
bool txqs_stopped[IEEE80211_NUM_ACS];
|
||||
|
||||
+ bool color_change_active;
|
||||
+ u8 color_change_color;
|
||||
+
|
||||
/* must be last */
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
@@ -4982,6 +4989,16 @@ void ieee80211_csa_finish(struct ieee802
|
||||
bool ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif);
|
||||
|
||||
/**
|
||||
+ * ieee80211_color_change_finish - notify mac80211 about color change
|
||||
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
+ *
|
||||
+ * After a color change announcement was scheduled and the counter in this
|
||||
+ * announcement hits 1, this function must be called by the driver to
|
||||
+ * notify mac80211 that the color can be changed
|
||||
+ */
|
||||
+void ieee80211_color_change_finish(struct ieee80211_vif *vif);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_proberesp_get - retrieve a Probe Response template
|
||||
* @hw: pointer obtained from ieee80211_alloc_hw().
|
||||
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
@@ -6726,6 +6743,18 @@ ieee80211_get_unsol_bcast_probe_resp_tmp
|
||||
struct ieee80211_vif *vif);
|
||||
|
||||
/**
|
||||
+ * ieeee80211_obss_color_collision_notify - notify userland about a BSS color
|
||||
+ * collision.
|
||||
+ *
|
||||
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
+ * @color_bitmap: a 64 bit bitmap representing the colors that the local BSS is
|
||||
+ * aware of.
|
||||
+ */
|
||||
+void
|
||||
+ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
+ u64 color_bitmap);
|
||||
+
|
||||
+/**
|
||||
* ieee80211_is_tx_data - check if frame is a data frame
|
||||
*
|
||||
* The function is used to check if a frame is a data frame. Frames with
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -827,9 +827,11 @@ static int ieee80211_set_monitor_channel
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
|
||||
- const u8 *resp, size_t resp_len,
|
||||
- const struct ieee80211_csa_settings *csa)
|
||||
+static int
|
||||
+ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
|
||||
+ const u8 *resp, size_t resp_len,
|
||||
+ const struct ieee80211_csa_settings *csa,
|
||||
+ const struct ieee80211_color_change_settings *cca)
|
||||
{
|
||||
struct probe_resp *new, *old;
|
||||
|
||||
@@ -849,6 +851,8 @@ static int ieee80211_set_probe_resp(stru
|
||||
memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_presp,
|
||||
csa->n_counter_offsets_presp *
|
||||
sizeof(new->cntdwn_counter_offsets[0]));
|
||||
+ else if (cca)
|
||||
+ new->cntdwn_counter_offsets[0] = cca->counter_offset_presp;
|
||||
|
||||
rcu_assign_pointer(sdata->u.ap.probe_resp, new);
|
||||
if (old)
|
||||
@@ -954,7 +958,8 @@ static int ieee80211_set_ftm_responder_p
|
||||
|
||||
static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_beacon_data *params,
|
||||
- const struct ieee80211_csa_settings *csa)
|
||||
+ const struct ieee80211_csa_settings *csa,
|
||||
+ const struct ieee80211_color_change_settings *cca)
|
||||
{
|
||||
struct beacon_data *new, *old;
|
||||
int new_head_len, new_tail_len;
|
||||
@@ -1003,6 +1008,9 @@ static int ieee80211_assign_beacon(struc
|
||||
memcpy(new->cntdwn_counter_offsets, csa->counter_offsets_beacon,
|
||||
csa->n_counter_offsets_beacon *
|
||||
sizeof(new->cntdwn_counter_offsets[0]));
|
||||
+ } else if (cca) {
|
||||
+ new->cntdwn_current_counter = cca->count;
|
||||
+ new->cntdwn_counter_offsets[0] = cca->counter_offset_beacon;
|
||||
}
|
||||
|
||||
/* copy in head */
|
||||
@@ -1019,7 +1027,7 @@ static int ieee80211_assign_beacon(struc
|
||||
memcpy(new->tail, old->tail, new_tail_len);
|
||||
|
||||
err = ieee80211_set_probe_resp(sdata, params->probe_resp,
|
||||
- params->probe_resp_len, csa);
|
||||
+ params->probe_resp_len, csa, cca);
|
||||
if (err < 0) {
|
||||
kfree(new);
|
||||
return err;
|
||||
@@ -1176,7 +1184,7 @@ static int ieee80211_start_ap(struct wip
|
||||
if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL))
|
||||
sdata->vif.bss_conf.beacon_tx_rate = params->beacon_rate;
|
||||
|
||||
- err = ieee80211_assign_beacon(sdata, ¶ms->beacon, NULL);
|
||||
+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon, NULL, NULL);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
changed |= err;
|
||||
@@ -1231,17 +1239,17 @@ static int ieee80211_change_beacon(struc
|
||||
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
- /* don't allow changing the beacon while CSA is in place - offset
|
||||
+ /* don't allow changing the beacon while a countdown is in place - offset
|
||||
* of channel switch counter may change
|
||||
*/
|
||||
- if (sdata->vif.csa_active)
|
||||
+ if (sdata->vif.csa_active || sdata->vif.color_change_active)
|
||||
return -EBUSY;
|
||||
|
||||
old = sdata_dereference(sdata->u.ap.beacon, sdata);
|
||||
if (!old)
|
||||
return -ENOENT;
|
||||
|
||||
- err = ieee80211_assign_beacon(sdata, params, NULL);
|
||||
+ err = ieee80211_assign_beacon(sdata, params, NULL, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
ieee80211_bss_info_change_notify(sdata, err);
|
||||
@@ -3174,7 +3182,7 @@ static int ieee80211_set_after_csa_beaco
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
|
||||
- NULL);
|
||||
+ NULL, NULL);
|
||||
kfree(sdata->u.ap.next_beacon);
|
||||
sdata->u.ap.next_beacon = NULL;
|
||||
|
||||
@@ -3340,7 +3348,7 @@ static int ieee80211_set_csa_beacon(stru
|
||||
csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
|
||||
csa.count = params->count;
|
||||
|
||||
- err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa);
|
||||
+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa, NULL);
|
||||
if (err < 0) {
|
||||
kfree(sdata->u.ap.next_beacon);
|
||||
return err;
|
||||
@@ -3428,6 +3436,15 @@ static int ieee80211_set_csa_beacon(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata)
|
||||
+{
|
||||
+ sdata->vif.color_change_active = false;
|
||||
+ kfree(sdata->u.ap.next_beacon);
|
||||
+ sdata->u.ap.next_beacon = NULL;
|
||||
+
|
||||
+ cfg80211_color_change_aborted_notify(sdata->dev);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
__ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_csa_settings *params)
|
||||
@@ -3496,6 +3513,10 @@ __ieee80211_channel_switch(struct wiphy
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ /* if there is a color change in progress, abort it */
|
||||
+ if (sdata->vif.color_change_active)
|
||||
+ ieee80211_color_change_abort(sdata);
|
||||
+
|
||||
err = ieee80211_set_csa_beacon(sdata, params, &changed);
|
||||
if (err) {
|
||||
ieee80211_vif_unreserve_chanctx(sdata);
|
||||
@@ -4147,6 +4168,196 @@ static int ieee80211_set_sar_specs(struc
|
||||
return local->ops->set_sar_specs(&local->hw, sar);
|
||||
}
|
||||
|
||||
+static int
|
||||
+ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
+ u32 *changed)
|
||||
+{
|
||||
+ switch (sdata->vif.type) {
|
||||
+ case NL80211_IFTYPE_AP: {
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
|
||||
+ NULL, NULL);
|
||||
+ kfree(sdata->u.ap.next_beacon);
|
||||
+ sdata->u.ap.next_beacon = NULL;
|
||||
+
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ *changed |= ret;
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ WARN_ON_ONCE(1);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct cfg80211_color_change_settings *params,
|
||||
+ u32 *changed)
|
||||
+{
|
||||
+ struct ieee80211_color_change_settings color_change = {};
|
||||
+ int err;
|
||||
+
|
||||
+ switch (sdata->vif.type) {
|
||||
+ case NL80211_IFTYPE_AP:
|
||||
+ sdata->u.ap.next_beacon =
|
||||
+ cfg80211_beacon_dup(¶ms->beacon_next);
|
||||
+ if (!sdata->u.ap.next_beacon)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (params->count <= 1)
|
||||
+ break;
|
||||
+
|
||||
+ color_change.counter_offset_beacon =
|
||||
+ params->counter_offset_beacon;
|
||||
+ color_change.counter_offset_presp =
|
||||
+ params->counter_offset_presp;
|
||||
+ color_change.count = params->count;
|
||||
+
|
||||
+ err = ieee80211_assign_beacon(sdata, ¶ms->beacon_color_change,
|
||||
+ NULL, &color_change);
|
||||
+ if (err < 0) {
|
||||
+ kfree(sdata->u.ap.next_beacon);
|
||||
+ return err;
|
||||
+ }
|
||||
+ *changed |= err;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_color_change_bss_config_notify(struct ieee80211_sub_if_data *sdata,
|
||||
+ u8 color, int enable, u32 changed)
|
||||
+{
|
||||
+ sdata->vif.bss_conf.he_bss_color.color = color;
|
||||
+ sdata->vif.bss_conf.he_bss_color.enabled = enable;
|
||||
+ changed |= BSS_CHANGED_HE_BSS_COLOR;
|
||||
+
|
||||
+ ieee80211_bss_info_change_notify(sdata, changed);
|
||||
+}
|
||||
+
|
||||
+static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata)
|
||||
+{
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ u32 changed = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ sdata_assert_lock(sdata);
|
||||
+ lockdep_assert_held(&local->mtx);
|
||||
+
|
||||
+ sdata->vif.color_change_active = false;
|
||||
+
|
||||
+ err = ieee80211_set_after_color_change_beacon(sdata, &changed);
|
||||
+ if (err) {
|
||||
+ cfg80211_color_change_aborted_notify(sdata->dev);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ ieee80211_color_change_bss_config_notify(sdata,
|
||||
+ sdata->vif.color_change_color,
|
||||
+ 1, changed);
|
||||
+ cfg80211_color_change_notify(sdata->dev);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void ieee80211_color_change_finalize_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata =
|
||||
+ container_of(work, struct ieee80211_sub_if_data,
|
||||
+ color_change_finalize_work);
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+
|
||||
+ sdata_lock(sdata);
|
||||
+ mutex_lock(&local->mtx);
|
||||
+
|
||||
+ /* AP might have been stopped while waiting for the lock. */
|
||||
+ if (!sdata->vif.color_change_active)
|
||||
+ goto unlock;
|
||||
+
|
||||
+ if (!ieee80211_sdata_running(sdata))
|
||||
+ goto unlock;
|
||||
+
|
||||
+ ieee80211_color_change_finalize(sdata);
|
||||
+
|
||||
+unlock:
|
||||
+ mutex_unlock(&local->mtx);
|
||||
+ sdata_unlock(sdata);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_color_change_finish(struct ieee80211_vif *vif)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
+
|
||||
+ ieee80211_queue_work(&sdata->local->hw,
|
||||
+ &sdata->color_change_finalize_work);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ieee80211_color_change_finish);
|
||||
+
|
||||
+void
|
||||
+ieeee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
+ u64 color_bitmap)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
+
|
||||
+ if (sdata->vif.color_change_active || sdata->vif.csa_active)
|
||||
+ return;
|
||||
+
|
||||
+ cfg80211_obss_color_collision_notify(sdata->dev, color_bitmap);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(ieeee80211_obss_color_collision_notify);
|
||||
+
|
||||
+static int
|
||||
+ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,
|
||||
+ struct cfg80211_color_change_settings *params)
|
||||
+{
|
||||
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ u32 changed = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ sdata_assert_lock(sdata);
|
||||
+
|
||||
+ mutex_lock(&local->mtx);
|
||||
+
|
||||
+ /* don't allow another color change if one is already active or if csa
|
||||
+ * is active
|
||||
+ */
|
||||
+ if (sdata->vif.color_change_active || sdata->vif.csa_active) {
|
||||
+ err = -EBUSY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ err = ieee80211_set_color_change_beacon(sdata, params, &changed);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+
|
||||
+ sdata->vif.color_change_active = true;
|
||||
+ sdata->vif.color_change_color = params->color;
|
||||
+
|
||||
+ cfg80211_color_change_started_notify(sdata->dev, params->count);
|
||||
+
|
||||
+ if (changed)
|
||||
+ ieee80211_color_change_bss_config_notify(sdata, 0, 0, changed);
|
||||
+ else
|
||||
+ /* if the beacon didn't change, we can finalize immediately */
|
||||
+ ieee80211_color_change_finalize(sdata);
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&local->mtx);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
const struct cfg80211_ops mac80211_config_ops = {
|
||||
.add_virtual_intf = ieee80211_add_iface,
|
||||
.del_virtual_intf = ieee80211_del_iface,
|
||||
@@ -4251,4 +4462,5 @@ const struct cfg80211_ops mac80211_confi
|
||||
.set_tid_config = ieee80211_set_tid_config,
|
||||
.reset_tid_config = ieee80211_reset_tid_config,
|
||||
.set_sar_specs = ieee80211_set_sar_specs,
|
||||
+ .color_change = ieee80211_color_change,
|
||||
};
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -248,6 +248,12 @@ struct ieee80211_csa_settings {
|
||||
u8 count;
|
||||
};
|
||||
|
||||
+struct ieee80211_color_change_settings {
|
||||
+ u16 counter_offset_beacon;
|
||||
+ u16 counter_offset_presp;
|
||||
+ u8 count;
|
||||
+};
|
||||
+
|
||||
struct beacon_data {
|
||||
u8 *head, *tail;
|
||||
int head_len, tail_len;
|
||||
@@ -932,6 +938,8 @@ struct ieee80211_sub_if_data {
|
||||
bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
|
||||
struct cfg80211_chan_def csa_chandef;
|
||||
|
||||
+ struct work_struct color_change_finalize_work;
|
||||
+
|
||||
struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */
|
||||
struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */
|
||||
|
||||
@@ -1900,6 +1908,9 @@ void ieee80211_csa_finalize_work(struct
|
||||
int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_csa_settings *params);
|
||||
|
||||
+/* color change handling */
|
||||
+void ieee80211_color_change_finalize_work(struct work_struct *work);
|
||||
+
|
||||
/* interface handling */
|
||||
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
|
||||
NETIF_F_HW_CSUM | NETIF_F_SG | \
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -465,6 +465,7 @@ static void ieee80211_do_stop(struct iee
|
||||
sdata_unlock(sdata);
|
||||
|
||||
cancel_work_sync(&sdata->csa_finalize_work);
|
||||
+ cancel_work_sync(&sdata->color_change_finalize_work);
|
||||
|
||||
cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
|
||||
|
||||
@@ -1639,6 +1640,7 @@ static void ieee80211_setup_sdata(struct
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
|
||||
INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
|
||||
+ INIT_WORK(&sdata->color_change_finalize_work, ieee80211_color_change_finalize_work);
|
||||
INIT_LIST_HEAD(&sdata->assigned_chanctx_list);
|
||||
INIT_LIST_HEAD(&sdata->reserved_chanctx_list);
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -4790,11 +4790,11 @@ static int ieee80211_beacon_add_tim(stru
|
||||
static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata,
|
||||
struct beacon_data *beacon)
|
||||
{
|
||||
+ u8 *beacon_data, count, max_count = 1;
|
||||
struct probe_resp *resp;
|
||||
- u8 *beacon_data;
|
||||
size_t beacon_data_len;
|
||||
+ u16 *bcn_offsets;
|
||||
int i;
|
||||
- u8 count = beacon->cntdwn_current_counter;
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
@@ -4814,21 +4814,27 @@ static void ieee80211_set_beacon_cntdwn(
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
- for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; ++i) {
|
||||
- resp = rcu_dereference(sdata->u.ap.probe_resp);
|
||||
+ resp = rcu_dereference(sdata->u.ap.probe_resp);
|
||||
|
||||
- if (beacon->cntdwn_counter_offsets[i]) {
|
||||
- if (WARN_ON_ONCE(beacon->cntdwn_counter_offsets[i] >=
|
||||
- beacon_data_len)) {
|
||||
+ bcn_offsets = beacon->cntdwn_counter_offsets;
|
||||
+ count = beacon->cntdwn_current_counter;
|
||||
+ if (sdata->vif.csa_active)
|
||||
+ max_count = IEEE80211_MAX_CNTDWN_COUNTERS_NUM;
|
||||
+
|
||||
+ for (i = 0; i < max_count; ++i) {
|
||||
+ if (bcn_offsets[i]) {
|
||||
+ if (WARN_ON_ONCE(bcn_offsets[i] >= beacon_data_len)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
-
|
||||
- beacon_data[beacon->cntdwn_counter_offsets[i]] = count;
|
||||
+ beacon_data[bcn_offsets[i]] = count;
|
||||
}
|
||||
|
||||
- if (sdata->vif.type == NL80211_IFTYPE_AP && resp)
|
||||
- resp->data[resp->cntdwn_counter_offsets[i]] = count;
|
||||
+ if (sdata->vif.type == NL80211_IFTYPE_AP && resp) {
|
||||
+ u16 *resp_offsets = resp->cntdwn_counter_offsets;
|
||||
+
|
||||
+ resp->data[resp_offsets[i]] = count;
|
||||
+ }
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
@@ -5038,6 +5044,7 @@ __ieee80211_beacon_get(struct ieee80211_
|
||||
if (offs) {
|
||||
offs->tim_offset = beacon->head_len;
|
||||
offs->tim_length = skb->len - beacon->head_len;
|
||||
+ offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0];
|
||||
|
||||
/* for AP the csa offsets are from tail */
|
||||
csa_off_base = skb->len;
|
@ -0,0 +1,112 @@
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 23 Aug 2021 20:02:38 +0200
|
||||
Subject: [PATCH] ieee80211: add TWT element definitions
|
||||
|
||||
Introduce TWT definitions and TWT Information element structure
|
||||
in ieee80211.h
|
||||
|
||||
Tested-by: Peter Chiu <chui-hao.chiu@mediatek.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://lore.kernel.org/r/71d8b581fe4b5abc5b92f8d77ac2de3e2f7591b6.1629741512.git.lorenzo@kernel.org
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -1088,6 +1088,48 @@ struct ieee80211_ext {
|
||||
} u;
|
||||
} __packed __aligned(2);
|
||||
|
||||
+#define IEEE80211_TWT_CONTROL_NDP BIT(0)
|
||||
+#define IEEE80211_TWT_CONTROL_RESP_MODE BIT(1)
|
||||
+#define IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST BIT(3)
|
||||
+#define IEEE80211_TWT_CONTROL_RX_DISABLED BIT(4)
|
||||
+#define IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT BIT(5)
|
||||
+
|
||||
+#define IEEE80211_TWT_REQTYPE_REQUEST BIT(0)
|
||||
+#define IEEE80211_TWT_REQTYPE_SETUP_CMD GENMASK(3, 1)
|
||||
+#define IEEE80211_TWT_REQTYPE_TRIGGER BIT(4)
|
||||
+#define IEEE80211_TWT_REQTYPE_IMPLICIT BIT(5)
|
||||
+#define IEEE80211_TWT_REQTYPE_FLOWTYPE BIT(6)
|
||||
+#define IEEE80211_TWT_REQTYPE_FLOWID GENMASK(9, 7)
|
||||
+#define IEEE80211_TWT_REQTYPE_WAKE_INT_EXP GENMASK(14, 10)
|
||||
+#define IEEE80211_TWT_REQTYPE_PROTECTION BIT(15)
|
||||
+
|
||||
+enum ieee80211_twt_setup_cmd {
|
||||
+ TWT_SETUP_CMD_REQUEST,
|
||||
+ TWT_SETUP_CMD_SUGGEST,
|
||||
+ TWT_SETUP_CMD_DEMAND,
|
||||
+ TWT_SETUP_CMD_GROUPING,
|
||||
+ TWT_SETUP_CMD_ACCEPT,
|
||||
+ TWT_SETUP_CMD_ALTERNATE,
|
||||
+ TWT_SETUP_CMD_DICTATE,
|
||||
+ TWT_SETUP_CMD_REJECT,
|
||||
+};
|
||||
+
|
||||
+struct ieee80211_twt_params {
|
||||
+ __le16 req_type;
|
||||
+ __le64 twt;
|
||||
+ u8 min_twt_dur;
|
||||
+ __le16 mantissa;
|
||||
+ u8 channel;
|
||||
+} __packed;
|
||||
+
|
||||
+struct ieee80211_twt_setup {
|
||||
+ u8 dialog_token;
|
||||
+ u8 element_id;
|
||||
+ u8 length;
|
||||
+ u8 control;
|
||||
+ u8 params[];
|
||||
+} __packed;
|
||||
+
|
||||
struct ieee80211_mgmt {
|
||||
__le16 frame_control;
|
||||
__le16 duration;
|
||||
@@ -1252,6 +1294,10 @@ struct ieee80211_mgmt {
|
||||
__le16 toa_error;
|
||||
u8 variable[0];
|
||||
} __packed ftm;
|
||||
+ struct {
|
||||
+ u8 action_code;
|
||||
+ u8 variable[];
|
||||
+ } __packed s1g;
|
||||
} u;
|
||||
} __packed action;
|
||||
} u;
|
||||
@@ -2880,6 +2926,7 @@ enum ieee80211_eid {
|
||||
WLAN_EID_AID_RESPONSE = 211,
|
||||
WLAN_EID_S1G_BCN_COMPAT = 213,
|
||||
WLAN_EID_S1G_SHORT_BCN_INTERVAL = 214,
|
||||
+ WLAN_EID_S1G_TWT = 216,
|
||||
WLAN_EID_S1G_CAPABILITIES = 217,
|
||||
WLAN_EID_VENDOR_SPECIFIC = 221,
|
||||
WLAN_EID_QOS_PARAMETER = 222,
|
||||
@@ -2948,6 +2995,7 @@ enum ieee80211_category {
|
||||
WLAN_CATEGORY_FST = 18,
|
||||
WLAN_CATEGORY_UNPROT_DMG = 20,
|
||||
WLAN_CATEGORY_VHT = 21,
|
||||
+ WLAN_CATEGORY_S1G = 22,
|
||||
WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
|
||||
WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
|
||||
};
|
||||
@@ -3021,6 +3069,20 @@ enum ieee80211_key_len {
|
||||
WLAN_KEY_LEN_BIP_GMAC_256 = 32,
|
||||
};
|
||||
|
||||
+enum ieee80211_s1g_actioncode {
|
||||
+ WLAN_S1G_AID_SWITCH_REQUEST,
|
||||
+ WLAN_S1G_AID_SWITCH_RESPONSE,
|
||||
+ WLAN_S1G_SYNC_CONTROL,
|
||||
+ WLAN_S1G_STA_INFO_ANNOUNCE,
|
||||
+ WLAN_S1G_EDCA_PARAM_SET,
|
||||
+ WLAN_S1G_EL_OPERATION,
|
||||
+ WLAN_S1G_TWT_SETUP,
|
||||
+ WLAN_S1G_TWT_TEARDOWN,
|
||||
+ WLAN_S1G_SECT_GROUP_ID_LIST,
|
||||
+ WLAN_S1G_SECT_ID_FEEDBACK,
|
||||
+ WLAN_S1G_TWT_INFORMATION = 11,
|
||||
+};
|
||||
+
|
||||
#define IEEE80211_WEP_IV_LEN 4
|
||||
#define IEEE80211_WEP_ICV_LEN 4
|
||||
#define IEEE80211_CCMP_HDR_LEN 8
|
@ -0,0 +1,576 @@
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 23 Aug 2021 20:02:39 +0200
|
||||
Subject: [PATCH] mac80211: introduce individual TWT support in AP mode
|
||||
|
||||
Introduce TWT action frames parsing support to mac80211.
|
||||
Currently just individual TWT agreement are support in AP mode.
|
||||
Whenever the AP receives a TWT action frame from an associated client,
|
||||
after performing sanity checks, it will notify the underlay driver with
|
||||
requested parameters in order to check if they are supported and if there
|
||||
is enough room for a new agreement. The driver is expected to set the
|
||||
agreement result and report it to mac80211.
|
||||
|
||||
Drivers supporting this have two new callbacks:
|
||||
- add_twt_setup (mandatory)
|
||||
- twt_teardown_request (optional)
|
||||
|
||||
mac80211 will send an action frame reply according to the result
|
||||
reported by the driver.
|
||||
|
||||
Tested-by: Peter Chiu <chui-hao.chiu@mediatek.com>
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://lore.kernel.org/r/257512f2e22ba42b9f2624942a128dd8f141de4b.1629741512.git.lorenzo@kernel.org
|
||||
[use le16p_replace_bits(), minor cleanups, use (void *) casts,
|
||||
fix to use ieee80211_get_he_iftype_cap() correctly]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/include/net/mac80211.h
|
||||
+++ b/include/net/mac80211.h
|
||||
@@ -4219,6 +4219,11 @@ struct ieee80211_ops {
|
||||
void (*sta_set_decap_offload)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, bool enabled);
|
||||
+ void (*add_twt_setup)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt);
|
||||
+ void (*twt_teardown_request)(struct ieee80211_hw *hw,
|
||||
+ struct ieee80211_sta *sta, u8 flowid);
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/net/mac80211/driver-ops.h
|
||||
+++ b/net/mac80211/driver-ops.h
|
||||
@@ -1429,4 +1429,40 @@ static inline void drv_sta_set_decap_off
|
||||
trace_drv_return_void(local);
|
||||
}
|
||||
|
||||
+static inline void drv_add_twt_setup(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt)
|
||||
+{
|
||||
+ struct ieee80211_twt_params *twt_agrt;
|
||||
+
|
||||
+ might_sleep();
|
||||
+
|
||||
+ if (!check_sdata_in_driver(sdata))
|
||||
+ return;
|
||||
+
|
||||
+ twt_agrt = (void *)twt->params;
|
||||
+
|
||||
+ trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
|
||||
+ local->ops->add_twt_setup(&local->hw, sta, twt);
|
||||
+ trace_drv_return_void(local);
|
||||
+}
|
||||
+
|
||||
+static inline void drv_twt_teardown_request(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sub_if_data *sdata,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ u8 flowid)
|
||||
+{
|
||||
+ might_sleep();
|
||||
+ if (!check_sdata_in_driver(sdata))
|
||||
+ return;
|
||||
+
|
||||
+ if (!local->ops->twt_teardown_request)
|
||||
+ return;
|
||||
+
|
||||
+ trace_drv_twt_teardown_request(local, sta, flowid);
|
||||
+ local->ops->twt_teardown_request(&local->hw, sta, flowid);
|
||||
+ trace_drv_return_void(local);
|
||||
+}
|
||||
+
|
||||
#endif /* __MAC80211_DRIVER_OPS */
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -954,6 +954,7 @@ struct ieee80211_sub_if_data {
|
||||
|
||||
struct work_struct work;
|
||||
struct sk_buff_head skb_queue;
|
||||
+ struct sk_buff_head status_queue;
|
||||
|
||||
u8 needed_rx_chains;
|
||||
enum ieee80211_smps_mode smps_mode;
|
||||
@@ -2093,6 +2094,11 @@ ieee80211_he_op_ie_to_bss_conf(struct ie
|
||||
|
||||
/* S1G */
|
||||
void ieee80211_s1g_sta_rate_init(struct sta_info *sta);
|
||||
+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb);
|
||||
+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb);
|
||||
+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb);
|
||||
|
||||
/* Spectrum management */
|
||||
void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
|
||||
--- a/net/mac80211/iface.c
|
||||
+++ b/net/mac80211/iface.c
|
||||
@@ -563,6 +563,7 @@ static void ieee80211_do_stop(struct iee
|
||||
*/
|
||||
ieee80211_free_keys(sdata, true);
|
||||
skb_queue_purge(&sdata->skb_queue);
|
||||
+ skb_queue_purge(&sdata->status_queue);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
|
||||
@@ -1070,6 +1071,7 @@ int ieee80211_add_virtual_monitor(struct
|
||||
}
|
||||
|
||||
skb_queue_head_init(&sdata->skb_queue);
|
||||
+ skb_queue_head_init(&sdata->status_queue);
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
|
||||
return 0;
|
||||
@@ -1442,6 +1444,24 @@ static void ieee80211_if_setup_no_queue(
|
||||
#endif
|
||||
}
|
||||
|
||||
+static void ieee80211_iface_process_status(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
+
|
||||
+ if (ieee80211_is_action(mgmt->frame_control) &&
|
||||
+ mgmt->u.action.category == WLAN_CATEGORY_S1G) {
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_status_twt_action(sdata, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void ieee80211_iface_work(struct work_struct *work)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata =
|
||||
@@ -1519,6 +1539,16 @@ static void ieee80211_iface_work(struct
|
||||
WARN_ON(1);
|
||||
break;
|
||||
}
|
||||
+ } else if (ieee80211_is_action(mgmt->frame_control) &&
|
||||
+ mgmt->u.action.category == WLAN_CATEGORY_S1G) {
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_rx_twt_action(sdata, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
} else if (ieee80211_is_ext(mgmt->frame_control)) {
|
||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_sta_rx_queued_ext(sdata, skb);
|
||||
@@ -1574,6 +1604,12 @@ static void ieee80211_iface_work(struct
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
+ /* process status queue */
|
||||
+ while ((skb = skb_dequeue(&sdata->status_queue))) {
|
||||
+ ieee80211_iface_process_status(sdata, skb);
|
||||
+ kfree_skb(skb);
|
||||
+ }
|
||||
+
|
||||
/* then other type-dependent work */
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
@@ -1637,6 +1673,7 @@ static void ieee80211_setup_sdata(struct
|
||||
}
|
||||
|
||||
skb_queue_head_init(&sdata->skb_queue);
|
||||
+ skb_queue_head_init(&sdata->status_queue);
|
||||
INIT_WORK(&sdata->work, ieee80211_iface_work);
|
||||
INIT_WORK(&sdata->recalc_smps, ieee80211_recalc_smps_work);
|
||||
INIT_WORK(&sdata->csa_finalize_work, ieee80211_csa_finalize_work);
|
||||
--- a/net/mac80211/rx.c
|
||||
+++ b/net/mac80211/rx.c
|
||||
@@ -3210,6 +3210,68 @@ ieee80211_rx_h_mgmt_check(struct ieee802
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+ieee80211_process_rx_twt_action(struct ieee80211_rx_data *rx)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)rx->skb->data;
|
||||
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||||
+ struct ieee80211_sub_if_data *sdata = rx->sdata;
|
||||
+ const struct ieee80211_sta_he_cap *hecap;
|
||||
+ struct ieee80211_supported_band *sband;
|
||||
+
|
||||
+ /* TWT actions are only supported in AP for the moment */
|
||||
+ if (sdata->vif.type != NL80211_IFTYPE_AP)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!rx->local->ops->add_twt_setup)
|
||||
+ return false;
|
||||
+
|
||||
+ sband = rx->local->hw.wiphy->bands[status->band];
|
||||
+ hecap = ieee80211_get_he_iftype_cap(sband,
|
||||
+ ieee80211_vif_type_p2p(&sdata->vif));
|
||||
+ if (!hecap)
|
||||
+ return false;
|
||||
+
|
||||
+ if (!(hecap->he_cap_elem.mac_cap_info[0] &
|
||||
+ IEEE80211_HE_MAC_CAP0_TWT_RES))
|
||||
+ return false;
|
||||
+
|
||||
+ if (!rx->sta)
|
||||
+ return false;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP: {
|
||||
+ struct ieee80211_twt_setup *twt;
|
||||
+
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
|
||||
+ 1 + /* action code */
|
||||
+ sizeof(struct ieee80211_twt_setup) +
|
||||
+ 2 /* TWT req_type agrt */)
|
||||
+ break;
|
||||
+
|
||||
+ twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ if (twt->element_id != WLAN_EID_S1G_TWT)
|
||||
+ break;
|
||||
+
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE +
|
||||
+ 4 + /* action code + token + tlv */
|
||||
+ twt->length)
|
||||
+ break;
|
||||
+
|
||||
+ return true; /* queue the frame */
|
||||
+ }
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE + 2)
|
||||
+ break;
|
||||
+
|
||||
+ return true; /* queue the frame */
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static ieee80211_rx_result debug_noinline
|
||||
ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
||||
{
|
||||
@@ -3489,6 +3551,17 @@ ieee80211_rx_h_action(struct ieee80211_r
|
||||
!mesh_path_sel_is_hwmp(sdata))
|
||||
break;
|
||||
goto queue;
|
||||
+ case WLAN_CATEGORY_S1G:
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ if (ieee80211_process_rx_twt_action(rx))
|
||||
+ goto queue;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
|
||||
return RX_CONTINUE;
|
||||
--- a/net/mac80211/s1g.c
|
||||
+++ b/net/mac80211/s1g.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <linux/ieee80211.h>
|
||||
#include <net/mac80211.h>
|
||||
#include "ieee80211_i.h"
|
||||
+#include "driver-ops.h"
|
||||
|
||||
void ieee80211_s1g_sta_rate_init(struct sta_info *sta)
|
||||
{
|
||||
@@ -14,3 +15,182 @@ void ieee80211_s1g_sta_rate_init(struct
|
||||
sta->rx_stats.last_rate =
|
||||
STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_S1G);
|
||||
}
|
||||
+
|
||||
+bool ieee80211_s1g_is_twt_setup(struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+
|
||||
+ if (likely(!ieee80211_is_action(mgmt->frame_control)))
|
||||
+ return false;
|
||||
+
|
||||
+ if (likely(mgmt->u.action.category != WLAN_CATEGORY_S1G))
|
||||
+ return false;
|
||||
+
|
||||
+ return mgmt->u.action.u.s1g.action_code == WLAN_S1G_TWT_SETUP;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_send_twt_setup(struct ieee80211_sub_if_data *sdata, const u8 *da,
|
||||
+ const u8 *bssid, struct ieee80211_twt_setup *twt)
|
||||
+{
|
||||
+ int len = IEEE80211_MIN_ACTION_SIZE + 4 + twt->length;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_mgmt *mgmt;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom + len);
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||
+ mgmt = skb_put_zero(skb, len);
|
||||
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
+ IEEE80211_STYPE_ACTION);
|
||||
+ memcpy(mgmt->da, da, ETH_ALEN);
|
||||
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
||||
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
|
||||
+
|
||||
+ mgmt->u.action.category = WLAN_CATEGORY_S1G;
|
||||
+ mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_SETUP;
|
||||
+ memcpy(mgmt->u.action.u.s1g.variable, twt, 3 + twt->length);
|
||||
+
|
||||
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
||||
+ IEEE80211_TX_INTFL_MLME_CONN_TX |
|
||||
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ ieee80211_tx_skb(sdata, skb);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_send_twt_teardown(struct ieee80211_sub_if_data *sdata,
|
||||
+ const u8 *da, const u8 *bssid, u8 flowid)
|
||||
+{
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct ieee80211_mgmt *mgmt;
|
||||
+ struct sk_buff *skb;
|
||||
+ u8 *id;
|
||||
+
|
||||
+ skb = dev_alloc_skb(local->hw.extra_tx_headroom +
|
||||
+ IEEE80211_MIN_ACTION_SIZE + 2);
|
||||
+ if (!skb)
|
||||
+ return;
|
||||
+
|
||||
+ skb_reserve(skb, local->hw.extra_tx_headroom);
|
||||
+ mgmt = skb_put_zero(skb, IEEE80211_MIN_ACTION_SIZE + 2);
|
||||
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
|
||||
+ IEEE80211_STYPE_ACTION);
|
||||
+ memcpy(mgmt->da, da, ETH_ALEN);
|
||||
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
|
||||
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
|
||||
+
|
||||
+ mgmt->u.action.category = WLAN_CATEGORY_S1G;
|
||||
+ mgmt->u.action.u.s1g.action_code = WLAN_S1G_TWT_TEARDOWN;
|
||||
+ id = (u8 *)mgmt->u.action.u.s1g.variable;
|
||||
+ *id = flowid;
|
||||
+
|
||||
+ IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
||||
+ IEEE80211_TX_CTL_REQ_TX_STATUS;
|
||||
+ ieee80211_tx_skb(sdata, skb);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_rx_twt_setup(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
|
||||
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
|
||||
+
|
||||
+ twt_agrt->req_type &= cpu_to_le16(~IEEE80211_TWT_REQTYPE_REQUEST);
|
||||
+
|
||||
+ /* broadcast TWT not supported yet */
|
||||
+ if (twt->control & IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST) {
|
||||
+ le16p_replace_bits(&twt_agrt->req_type,
|
||||
+ TWT_SETUP_CMD_REJECT,
|
||||
+ IEEE80211_TWT_REQTYPE_SETUP_CMD);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ drv_add_twt_setup(sdata->local, sdata, &sta->sta, twt);
|
||||
+out:
|
||||
+ ieee80211_s1g_send_twt_setup(sdata, mgmt->sa, sdata->vif.addr, twt);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_rx_twt_teardown(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+
|
||||
+ drv_twt_teardown_request(sdata->local, sdata, &sta->sta,
|
||||
+ mgmt->u.action.u.s1g.variable[0]);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ieee80211_s1g_tx_twt_setup_fail(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sta_info *sta, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_twt_setup *twt = (void *)mgmt->u.action.u.s1g.variable;
|
||||
+ struct ieee80211_twt_params *twt_agrt = (void *)twt->params;
|
||||
+ u8 flowid = le16_get_bits(twt_agrt->req_type,
|
||||
+ IEEE80211_TWT_REQTYPE_FLOWID);
|
||||
+
|
||||
+ drv_twt_teardown_request(sdata->local, sdata, &sta->sta, flowid);
|
||||
+
|
||||
+ ieee80211_s1g_send_twt_teardown(sdata, mgmt->sa, sdata->vif.addr,
|
||||
+ flowid);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ mutex_lock(&local->sta_mtx);
|
||||
+
|
||||
+ sta = sta_info_get_bss(sdata, mgmt->sa);
|
||||
+ if (!sta)
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ ieee80211_s1g_rx_twt_setup(sdata, sta, skb);
|
||||
+ break;
|
||||
+ case WLAN_S1G_TWT_TEARDOWN:
|
||||
+ ieee80211_s1g_rx_twt_teardown(sdata, sta, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&local->sta_mtx);
|
||||
+}
|
||||
+
|
||||
+void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
|
||||
+ struct sk_buff *skb)
|
||||
+{
|
||||
+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
|
||||
+ struct ieee80211_local *local = sdata->local;
|
||||
+ struct sta_info *sta;
|
||||
+
|
||||
+ mutex_lock(&local->sta_mtx);
|
||||
+
|
||||
+ sta = sta_info_get_bss(sdata, mgmt->da);
|
||||
+ if (!sta)
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (mgmt->u.action.u.s1g.action_code) {
|
||||
+ case WLAN_S1G_TWT_SETUP:
|
||||
+ /* process failed twt setup frames */
|
||||
+ ieee80211_s1g_tx_twt_setup_fail(sdata, sta, skb);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&local->sta_mtx);
|
||||
+}
|
||||
--- a/net/mac80211/status.c
|
||||
+++ b/net/mac80211/status.c
|
||||
@@ -705,13 +705,26 @@ static void ieee80211_report_used_skb(st
|
||||
/* Check to see if packet is a TDLS teardown packet */
|
||||
if (ieee80211_is_data(hdr->frame_control) &&
|
||||
(ieee80211_get_tdls_action(skb, hdr_size) ==
|
||||
- WLAN_TDLS_TEARDOWN))
|
||||
+ WLAN_TDLS_TEARDOWN)) {
|
||||
ieee80211_tdls_td_tx_handle(local, sdata, skb,
|
||||
info->flags);
|
||||
- else
|
||||
+ } else if (ieee80211_s1g_is_twt_setup(skb)) {
|
||||
+ if (!acked) {
|
||||
+ struct sk_buff *qskb;
|
||||
+
|
||||
+ qskb = skb_clone(skb, GFP_ATOMIC);
|
||||
+ if (qskb) {
|
||||
+ skb_queue_tail(&sdata->status_queue,
|
||||
+ qskb);
|
||||
+ ieee80211_queue_work(&local->hw,
|
||||
+ &sdata->work);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
ieee80211_mgd_conn_tx_status(sdata,
|
||||
hdr->frame_control,
|
||||
acked);
|
||||
+ }
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
--- a/net/mac80211/trace.h
|
||||
+++ b/net/mac80211/trace.h
|
||||
@@ -2804,6 +2804,73 @@ DEFINE_EVENT(sta_flag_evt, drv_sta_set_d
|
||||
TP_ARGS(local, sdata, sta, enabled)
|
||||
);
|
||||
|
||||
+TRACE_EVENT(drv_add_twt_setup,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sta *sta,
|
||||
+ struct ieee80211_twt_setup *twt,
|
||||
+ struct ieee80211_twt_params *twt_agrt),
|
||||
+
|
||||
+ TP_ARGS(local, sta, twt, twt_agrt),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ LOCAL_ENTRY
|
||||
+ STA_ENTRY
|
||||
+ __field(u8, dialog_token)
|
||||
+ __field(u8, control)
|
||||
+ __field(__le16, req_type)
|
||||
+ __field(__le64, twt)
|
||||
+ __field(u8, duration)
|
||||
+ __field(__le16, mantissa)
|
||||
+ __field(u8, channel)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ LOCAL_ASSIGN;
|
||||
+ STA_ASSIGN;
|
||||
+ __entry->dialog_token = twt->dialog_token;
|
||||
+ __entry->control = twt->control;
|
||||
+ __entry->req_type = twt_agrt->req_type;
|
||||
+ __entry->twt = twt_agrt->twt;
|
||||
+ __entry->duration = twt_agrt->min_twt_dur;
|
||||
+ __entry->mantissa = twt_agrt->mantissa;
|
||||
+ __entry->channel = twt_agrt->channel;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ LOCAL_PR_FMT STA_PR_FMT
|
||||
+ " token:%d control:0x%02x req_type:0x%04x"
|
||||
+ " twt:%llu duration:%d mantissa:%d channel:%d",
|
||||
+ LOCAL_PR_ARG, STA_PR_ARG, __entry->dialog_token,
|
||||
+ __entry->control, le16_to_cpu(__entry->req_type),
|
||||
+ le64_to_cpu(__entry->twt), __entry->duration,
|
||||
+ le16_to_cpu(__entry->mantissa), __entry->channel
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
+TRACE_EVENT(drv_twt_teardown_request,
|
||||
+ TP_PROTO(struct ieee80211_local *local,
|
||||
+ struct ieee80211_sta *sta, u8 flowid),
|
||||
+
|
||||
+ TP_ARGS(local, sta, flowid),
|
||||
+
|
||||
+ TP_STRUCT__entry(
|
||||
+ LOCAL_ENTRY
|
||||
+ STA_ENTRY
|
||||
+ __field(u8, flowid)
|
||||
+ ),
|
||||
+
|
||||
+ TP_fast_assign(
|
||||
+ LOCAL_ASSIGN;
|
||||
+ STA_ASSIGN;
|
||||
+ __entry->flowid = flowid;
|
||||
+ ),
|
||||
+
|
||||
+ TP_printk(
|
||||
+ LOCAL_PR_FMT STA_PR_FMT " flowid:%d",
|
||||
+ LOCAL_PR_ARG, STA_PR_ARG, __entry->flowid
|
||||
+ )
|
||||
+);
|
||||
+
|
||||
#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
@ -0,0 +1,196 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 9 Apr 2021 12:40:17 +0300
|
||||
Subject: [PATCH] wireless: align some HE capabilities with the spec
|
||||
|
||||
Some names were changed, align that with the spec as of
|
||||
802.11ax-D6.1.
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210409123755.b1e5fbab0d8c.I3eb6076cb0714ec6aec6b8f9dee613ce4a05d825@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -3627,7 +3627,7 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
IEEE80211_HE_MAC_CAP4_BQR;
|
||||
he_cap_elem->mac_cap_info[4] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION |
|
||||
+ m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION |
|
||||
IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU |
|
||||
IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING |
|
||||
IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX;
|
||||
@@ -3637,7 +3637,7 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
|
||||
he_cap_elem->phy_cap_info[2] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA |
|
||||
+ m = IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK;
|
||||
he_cap_elem->phy_cap_info[3] &= ~m;
|
||||
@@ -3649,13 +3649,13 @@ ath11k_mac_filter_he_cap_mesh(struct iee
|
||||
he_cap_elem->phy_cap_info[5] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;
|
||||
he_cap_elem->phy_cap_info[6] &= ~m;
|
||||
|
||||
- m = IEEE80211_HE_PHY_CAP7_SRP_BASED_SR |
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ m = IEEE80211_HE_PHY_CAP7_PSR_BASED_SR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;
|
||||
he_cap_elem->phy_cap_info[7] &= ~m;
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
@@ -307,8 +307,8 @@ mt7915_set_stream_he_txbf_caps(struct ie
|
||||
IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
|
||||
elem->phy_cap_info[5] &= ~c;
|
||||
|
||||
- c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
|
||||
+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
|
||||
elem->phy_cap_info[6] &= ~c;
|
||||
|
||||
elem->phy_cap_info[7] &= ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;
|
||||
@@ -348,8 +348,8 @@ mt7915_set_stream_he_txbf_caps(struct ie
|
||||
c = (nss - 1) | (max_t(int, mcs->tx_mcs_160, 1) << 3);
|
||||
elem->phy_cap_info[5] |= c;
|
||||
|
||||
- c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
- IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
|
||||
+ c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
|
||||
+ IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB;
|
||||
elem->phy_cap_info[6] |= c;
|
||||
}
|
||||
|
||||
@@ -484,7 +484,7 @@ mt7915_init_he_caps(struct mt7915_phy *p
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
|
||||
he_cap_elem->phy_cap_info[7] |=
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI;
|
||||
he_cap_elem->phy_cap_info[8] |=
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -2065,7 +2065,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
#define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01
|
||||
#define IEEE80211_HE_MAC_CAP4_QTP 0x02
|
||||
#define IEEE80211_HE_MAC_CAP4_BQR 0x04
|
||||
-#define IEEE80211_HE_MAC_CAP4_SRP_RESP 0x08
|
||||
+#define IEEE80211_HE_MAC_CAP4_PSR_RESP 0x08
|
||||
#define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10
|
||||
#define IEEE80211_HE_MAC_CAP4_OPS 0x20
|
||||
#define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x40
|
||||
@@ -2076,7 +2076,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
|
||||
#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 0x01
|
||||
#define IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B41 0x02
|
||||
-#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION 0x04
|
||||
+#define IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECTIVE_TRANSMISSION 0x04
|
||||
#define IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU 0x08
|
||||
#define IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX 0x10
|
||||
#define IEEE80211_HE_MAC_CAP5_HE_DYNAMIC_SM_PS 0x20
|
||||
@@ -2134,7 +2134,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK 0x18
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00
|
||||
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_2 0x20
|
||||
-#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
|
||||
+#define IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU 0x40
|
||||
#define IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER 0x80
|
||||
|
||||
#define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x01
|
||||
@@ -2181,15 +2181,15 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
|
||||
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x01
|
||||
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x02
|
||||
-#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x04
|
||||
-#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x08
|
||||
+#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB 0x04
|
||||
+#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB 0x08
|
||||
#define IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB 0x10
|
||||
#define IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE 0x20
|
||||
#define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 0x40
|
||||
#define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x80
|
||||
|
||||
-#define IEEE80211_HE_PHY_CAP7_SRP_BASED_SR 0x01
|
||||
-#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR 0x02
|
||||
+#define IEEE80211_HE_PHY_CAP7_PSR_BASED_SR 0x01
|
||||
+#define IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP 0x02
|
||||
#define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x04
|
||||
#define IEEE80211_HE_PHY_CAP7_MAX_NC_1 0x08
|
||||
#define IEEE80211_HE_PHY_CAP7_MAX_NC_2 0x10
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -732,15 +732,15 @@ static ssize_t sta_he_capa_read(struct f
|
||||
PFLAG(MAC, 4, BSRP_BQRP_A_MPDU_AGG, "BSRP-BQRP-A-MPDU-AGG");
|
||||
PFLAG(MAC, 4, QTP, "QTP");
|
||||
PFLAG(MAC, 4, BQR, "BQR");
|
||||
- PFLAG(MAC, 4, SRP_RESP, "SRP-RESP");
|
||||
+ PFLAG(MAC, 4, PSR_RESP, "PSR-RESP");
|
||||
PFLAG(MAC, 4, NDP_FB_REP, "NDP-FB-REP");
|
||||
PFLAG(MAC, 4, OPS, "OPS");
|
||||
PFLAG(MAC, 4, AMDSU_IN_AMPDU, "AMSDU-IN-AMPDU");
|
||||
|
||||
PRINT("MULTI-TID-AGG-TX-QOS-%d", ((cap[5] << 1) | (cap[4] >> 7)) & 0x7);
|
||||
|
||||
- PFLAG(MAC, 5, SUBCHAN_SELECVITE_TRANSMISSION,
|
||||
- "SUBCHAN-SELECVITE-TRANSMISSION");
|
||||
+ PFLAG(MAC, 5, SUBCHAN_SELECTIVE_TRANSMISSION,
|
||||
+ "SUBCHAN-SELECTIVE-TRANSMISSION");
|
||||
PFLAG(MAC, 5, UL_2x996_TONE_RU, "UL-2x996-TONE-RU");
|
||||
PFLAG(MAC, 5, OM_CTRL_UL_MU_DATA_DIS_RX, "OM-CTRL-UL-MU-DATA-DIS-RX");
|
||||
PFLAG(MAC, 5, HE_DYNAMIC_SM_PS, "HE-DYNAMIC-SM-PS");
|
||||
@@ -832,8 +832,8 @@ static ssize_t sta_he_capa_read(struct f
|
||||
|
||||
PFLAG(PHY, 3, DCM_MAX_RX_NSS_1, "DCM-MAX-RX-NSS-1");
|
||||
PFLAG(PHY, 3, DCM_MAX_RX_NSS_2, "DCM-MAX-RX-NSS-2");
|
||||
- PFLAG(PHY, 3, RX_HE_MU_PPDU_FROM_NON_AP_STA,
|
||||
- "RX-HE-MU-PPDU-FROM-NON-AP-STA");
|
||||
+ PFLAG(PHY, 3, RX_PARTIAL_BW_SU_IN_20MHZ_MU,
|
||||
+ "RX-PARTIAL-BW-SU-IN-20MHZ-MU");
|
||||
PFLAG(PHY, 3, SU_BEAMFORMER, "SU-BEAMFORMER");
|
||||
|
||||
PFLAG(PHY, 4, SU_BEAMFORMEE, "SU-BEAMFORMEE");
|
||||
@@ -853,16 +853,17 @@ static ssize_t sta_he_capa_read(struct f
|
||||
|
||||
PFLAG(PHY, 6, CODEBOOK_SIZE_42_SU, "CODEBOOK-SIZE-42-SU");
|
||||
PFLAG(PHY, 6, CODEBOOK_SIZE_75_MU, "CODEBOOK-SIZE-75-MU");
|
||||
- PFLAG(PHY, 6, TRIG_SU_BEAMFORMER_FB, "TRIG-SU-BEAMFORMER-FB");
|
||||
- PFLAG(PHY, 6, TRIG_MU_BEAMFORMER_FB, "TRIG-MU-BEAMFORMER-FB");
|
||||
+ PFLAG(PHY, 6, TRIG_SU_BEAMFORMING_FB, "TRIG-SU-BEAMFORMING-FB");
|
||||
+ PFLAG(PHY, 6, TRIG_MU_BEAMFORMING_PARTIAL_BW_FB,
|
||||
+ "MU-BEAMFORMING-PARTIAL-BW-FB");
|
||||
PFLAG(PHY, 6, TRIG_CQI_FB, "TRIG-CQI-FB");
|
||||
PFLAG(PHY, 6, PARTIAL_BW_EXT_RANGE, "PARTIAL-BW-EXT-RANGE");
|
||||
PFLAG(PHY, 6, PARTIAL_BANDWIDTH_DL_MUMIMO,
|
||||
"PARTIAL-BANDWIDTH-DL-MUMIMO");
|
||||
PFLAG(PHY, 6, PPE_THRESHOLD_PRESENT, "PPE-THRESHOLD-PRESENT");
|
||||
|
||||
- PFLAG(PHY, 7, SRP_BASED_SR, "SRP-BASED-SR");
|
||||
- PFLAG(PHY, 7, POWER_BOOST_FACTOR_AR, "POWER-BOOST-FACTOR-AR");
|
||||
+ PFLAG(PHY, 7, PSR_BASED_SR, "PSR-BASED-SR");
|
||||
+ PFLAG(PHY, 7, POWER_BOOST_FACTOR_SUPP, "POWER-BOOST-FACTOR-SUPP");
|
||||
PFLAG(PHY, 7, HE_SU_MU_PPDU_4XLTF_AND_08_US_GI,
|
||||
"HE-SU-MU-PPDU-4XLTF-AND-08-US-GI");
|
||||
PFLAG_RANGE(PHY, 7, MAX_NC, 0, 1, 1, "MAX-NC-%d");
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
@@ -631,7 +631,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
.phy_cap_info[6] =
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT,
|
||||
.phy_cap_info[7] =
|
||||
- IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
+ IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_SUPP |
|
||||
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP7_MAX_NC_1,
|
||||
.phy_cap_info[8] =
|
@ -0,0 +1,113 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 9 Apr 2021 12:40:24 +0300
|
||||
Subject: [PATCH] wireless: fix spelling of A-MSDU in HE capabilities
|
||||
|
||||
In the HE capabilities, spell A-MSDU correctly, not "A-MDSU".
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210409123755.9e6ff1af1181.If6868bc6902ccd9a95c74c78f716c4b41473ef14@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
@@ -598,7 +598,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
.mac_cap_info[4] =
|
||||
- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU |
|
||||
+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
|
||||
IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
|
||||
.mac_cap_info[5] =
|
||||
IEEE80211_HE_MAC_CAP5_MULTI_TID_AGG_TX_QOS_B40 |
|
||||
@@ -682,7 +682,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
.mac_cap_info[4] =
|
||||
- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.mac_cap_info[5] =
|
||||
IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU,
|
||||
.phy_cap_info[0] =
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
@@ -427,7 +427,7 @@ mt7915_init_he_caps(struct mt7915_phy *p
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED;
|
||||
he_cap_elem->mac_cap_info[4] =
|
||||
- IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU;
|
||||
+ IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;
|
||||
|
||||
if (band == NL80211_BAND_2GHZ)
|
||||
he_cap_elem->phy_cap_info[0] =
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
|
||||
@@ -1353,7 +1353,7 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *sk
|
||||
if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
|
||||
cap |= STA_REC_HE_CAP_OM;
|
||||
|
||||
- if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU)
|
||||
+ if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU)
|
||||
cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU;
|
||||
|
||||
if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -2068,7 +2068,7 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
#define IEEE80211_HE_MAC_CAP4_PSR_RESP 0x08
|
||||
#define IEEE80211_HE_MAC_CAP4_NDP_FB_REP 0x10
|
||||
#define IEEE80211_HE_MAC_CAP4_OPS 0x20
|
||||
-#define IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU 0x40
|
||||
+#define IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU 0x40
|
||||
/* Multi TID agg TX is split between byte #4 and #5
|
||||
* The value is a combination of B39,B40,B41
|
||||
*/
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -735,7 +735,7 @@ static ssize_t sta_he_capa_read(struct f
|
||||
PFLAG(MAC, 4, PSR_RESP, "PSR-RESP");
|
||||
PFLAG(MAC, 4, NDP_FB_REP, "NDP-FB-REP");
|
||||
PFLAG(MAC, 4, OPS, "OPS");
|
||||
- PFLAG(MAC, 4, AMDSU_IN_AMPDU, "AMSDU-IN-AMPDU");
|
||||
+ PFLAG(MAC, 4, AMSDU_IN_AMPDU, "AMSDU-IN-AMPDU");
|
||||
|
||||
PRINT("MULTI-TID-AGG-TX-QOS-%d", ((cap[5] << 1) | (cap[4] >> 7)) & 0x7);
|
||||
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -2748,7 +2748,7 @@ static const struct ieee80211_sband_ifty
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
|
||||
@@ -2792,7 +2792,7 @@ static const struct ieee80211_sband_ifty
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
|
||||
@@ -2838,7 +2838,7 @@ static const struct ieee80211_sband_ifty
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
|
||||
@@ -2886,7 +2886,7 @@ static const struct ieee80211_sband_ifty
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
- .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU,
|
||||
+ .mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
|
@ -0,0 +1,148 @@
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Fri, 9 Apr 2021 12:40:20 +0300
|
||||
Subject: [PATCH] wireless: align HE capabilities A-MPDU Length Exponent
|
||||
Extension
|
||||
|
||||
The A-MPDU length exponent extension is defined differently in
|
||||
802.11ax D6.1, align with that.
|
||||
|
||||
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
|
||||
Link: https://lore.kernel.org/r/iwlwifi.20210409123755.c2a257d3e2df.I3455245d388c52c61dace7e7958dbed7e807cfb6@changeid
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -1290,9 +1290,8 @@ static void ath11k_peer_assoc_h_he(struc
|
||||
* request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu
|
||||
* length.
|
||||
*/
|
||||
- ampdu_factor = (he_cap->he_cap_elem.mac_cap_info[3] &
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >>
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT;
|
||||
+ ampdu_factor = u8_get_bits(he_cap->he_cap_elem.mac_cap_info[3],
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK);
|
||||
|
||||
if (ampdu_factor) {
|
||||
if (sta->vht_cap.vht_supported)
|
||||
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
|
||||
@@ -596,7 +596,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU |
|
||||
IEEE80211_HE_MAC_CAP4_MULTI_TID_AGG_TX_QOS_B39,
|
||||
@@ -680,7 +680,7 @@ static struct ieee80211_sband_iftype_dat
|
||||
IEEE80211_HE_MAC_CAP2_BSR,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2,
|
||||
.mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.mac_cap_info[5] =
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -2747,7 +2747,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
@@ -2791,7 +2791,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[1] =
|
||||
IEEE80211_HE_PHY_CAP1_PREAMBLE_PUNC_RX_MASK |
|
||||
@@ -2837,7 +2837,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
@@ -2885,7 +2885,7 @@ static const struct ieee80211_sband_ifty
|
||||
IEEE80211_HE_MAC_CAP2_ACK_EN,
|
||||
.mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2,
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3,
|
||||
.mac_cap_info[4] = IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU,
|
||||
.phy_cap_info[0] =
|
||||
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
|
||||
@@ -425,7 +425,7 @@ mt7915_init_he_caps(struct mt7915_phy *p
|
||||
IEEE80211_HE_MAC_CAP0_HTC_HE;
|
||||
he_cap_elem->mac_cap_info[3] =
|
||||
IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
|
||||
- IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED;
|
||||
+ IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3;
|
||||
he_cap_elem->mac_cap_info[4] =
|
||||
IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU;
|
||||
|
||||
--- a/include/linux/ieee80211.h
|
||||
+++ b/include/linux/ieee80211.h
|
||||
@@ -2051,17 +2051,15 @@ int ieee80211_get_vht_max_nss(struct iee
|
||||
* A-MDPU Length Exponent field in the HT capabilities, VHT capabilities and the
|
||||
* same field in the HE capabilities.
|
||||
*/
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT 0x00
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1 0x08
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2 0x10
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED 0x18
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0 0x00
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1 0x08
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2 0x10
|
||||
+#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3 0x18
|
||||
#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK 0x18
|
||||
#define IEEE80211_HE_MAC_CAP3_AMSDU_FRAG 0x20
|
||||
#define IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED 0x40
|
||||
#define IEEE80211_HE_MAC_CAP3_RX_CTRL_FRAME_TO_MULTIBSS 0x80
|
||||
|
||||
-#define IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_SHIFT 3
|
||||
-
|
||||
#define IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG 0x01
|
||||
#define IEEE80211_HE_MAC_CAP4_QTP 0x02
|
||||
#define IEEE80211_HE_MAC_CAP4_BQR 0x04
|
||||
--- a/net/mac80211/debugfs_sta.c
|
||||
+++ b/net/mac80211/debugfs_sta.c
|
||||
@@ -711,17 +711,17 @@ static ssize_t sta_he_capa_read(struct f
|
||||
PFLAG(MAC, 3, OFDMA_RA, "OFDMA-RA");
|
||||
|
||||
switch (cap[3] & IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) {
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_USE_VHT:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-USE-VHT");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_0:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-USE-EXT-0");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_1:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-VHT-1");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_1:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-1");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_VHT_2:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-VHT-2");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_2:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-2");
|
||||
break;
|
||||
- case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED:
|
||||
- PRINT("MAX-AMPDU-LEN-EXP-RESERVED");
|
||||
+ case IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_EXT_3:
|
||||
+ PRINT("MAX-AMPDU-LEN-EXP-VHT-EXT-3");
|
||||
break;
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 22 Nov 2021 21:39:38 +0100
|
||||
Subject: [PATCH] mac80211: fix rate control for retransmitted frames
|
||||
|
||||
Since retransmission clears info->control, rate control needs to be called
|
||||
again, otherwise the driver might crash due to invalid rates.
|
||||
|
||||
Cc: stable@vger.kernel.org # 5.14+
|
||||
Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi>
|
||||
Reported-by: Robert W <rwbugreport@lost-in-the-void.net>
|
||||
Fixes: 03c3911d2d67 ("mac80211: call ieee80211_tx_h_rate_ctrl() when dequeue")
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -1835,15 +1835,15 @@ static int invoke_tx_handlers_late(struc
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
|
||||
ieee80211_tx_result res = TX_CONTINUE;
|
||||
|
||||
+ if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
||||
+ CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
+
|
||||
if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) {
|
||||
__skb_queue_tail(&tx->skbs, tx->skb);
|
||||
tx->skb = NULL;
|
||||
goto txh_done;
|
||||
}
|
||||
|
||||
- if (!ieee80211_hw_check(&tx->local->hw, HAS_RATE_CONTROL))
|
||||
- CALL_TXH(ieee80211_tx_h_rate_ctrl);
|
||||
-
|
||||
CALL_TXH(ieee80211_tx_h_michael_mic_add);
|
||||
CALL_TXH(ieee80211_tx_h_sequence);
|
||||
CALL_TXH(ieee80211_tx_h_fragment);
|
@ -1,6 +1,6 @@
|
||||
--- a/include/net/cfg80211.h
|
||||
+++ b/include/net/cfg80211.h
|
||||
@@ -3745,6 +3745,7 @@ struct mgmt_frame_regs {
|
||||
@@ -3814,6 +3814,7 @@ struct mgmt_frame_regs {
|
||||
* (as advertised by the nl80211 feature flag.)
|
||||
* @get_tx_power: store the current TX power into the dbm variable;
|
||||
* return 0 if successful
|
||||
@ -8,7 +8,7 @@
|
||||
*
|
||||
* @set_wds_peer: set the WDS peer for a WDS interface
|
||||
*
|
||||
@@ -4067,6 +4068,7 @@ struct cfg80211_ops {
|
||||
@@ -4138,6 +4139,7 @@ struct cfg80211_ops {
|
||||
enum nl80211_tx_power_setting type, int mbm);
|
||||
int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
int *dbm);
|
||||
@ -36,9 +36,9 @@
|
||||
u8 ps_dtim_period;
|
||||
--- a/include/uapi/linux/nl80211.h
|
||||
+++ b/include/uapi/linux/nl80211.h
|
||||
@@ -2560,6 +2560,9 @@ enum nl80211_commands {
|
||||
* disassoc events to indicate that an immediate reconnect to the AP
|
||||
* is desired.
|
||||
@@ -2593,6 +2593,9 @@ enum nl80211_commands {
|
||||
* @NL80211_ATTR_COLOR_CHANGE_ELEMS: Nested set of attributes containing the IE
|
||||
* information for the time while performing a color switch.
|
||||
*
|
||||
+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
|
||||
+ * transmit power to stay within regulatory limits. u32, dBi.
|
||||
@ -46,9 +46,9 @@
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@@ -3057,6 +3060,8 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_DISABLE_HE,
|
||||
@@ -3096,6 +3099,8 @@ enum nl80211_attrs {
|
||||
NL80211_ATTR_COLOR_CHANGE_COLOR,
|
||||
NL80211_ATTR_COLOR_CHANGE_ELEMS,
|
||||
|
||||
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
|
||||
+
|
||||
@ -57,7 +57,7 @@
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
--- a/net/mac80211/cfg.c
|
||||
+++ b/net/mac80211/cfg.c
|
||||
@@ -2728,6 +2728,19 @@ static int ieee80211_get_tx_power(struct
|
||||
@@ -2769,6 +2769,19 @@ static int ieee80211_get_tx_power(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *addr)
|
||||
{
|
||||
@@ -4158,6 +4171,7 @@ const struct cfg80211_ops mac80211_confi
|
||||
@@ -4413,6 +4426,7 @@ const struct cfg80211_ops mac80211_confi
|
||||
.set_wiphy_params = ieee80211_set_wiphy_params,
|
||||
.set_tx_power = ieee80211_set_tx_power,
|
||||
.get_tx_power = ieee80211_get_tx_power,
|
||||
@ -87,7 +87,7 @@
|
||||
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1390,6 +1390,7 @@ struct ieee80211_local {
|
||||
@@ -1435,6 +1435,7 @@ struct ieee80211_local {
|
||||
int dynamic_ps_forced_timeout;
|
||||
|
||||
int user_power_level; /* in dBm, for all interfaces */
|
||||
@ -129,15 +129,15 @@
|
||||
local->hw.max_mtu = IEEE80211_MAX_DATA_LEN;
|
||||
--- a/net/wireless/nl80211.c
|
||||
+++ b/net/wireless/nl80211.c
|
||||
@@ -740,6 +740,7 @@ static const struct nla_policy nl80211_p
|
||||
NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
|
||||
NL80211_SAE_PWE_BOTH),
|
||||
[NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
|
||||
@@ -757,6 +757,7 @@ static const struct nla_policy nl80211_p
|
||||
[NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
|
||||
+ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@@ -3248,6 +3249,20 @@ static int nl80211_set_wiphy(struct sk_b
|
||||
@@ -3322,6 +3323,20 @@ static int nl80211_set_wiphy(struct sk_b
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
|
@ -8,11 +8,12 @@ PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=2021-06-06
|
||||
PKG_SOURCE_VERSION:=22b690334c0f49b11534cc2e331c9d5e17c4a0bc
|
||||
PKG_MIRROR_HASH:=ff5e563935919d2e40c1e7254ef3bc06f7ecc5e69f8ddd12903e8f5de942d630
|
||||
PKG_SOURCE_DATE:=2021-11-23
|
||||
PKG_SOURCE_VERSION:=99225b985cbcab4707589f1fa313436f4bf1e368
|
||||
PKG_MIRROR_HASH:=6444c7d49d778c7621b03f0f201ce41f6dc9ac00dedb29c66478360b4fd60492
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_USE_NINJA:=0
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
PKG_CONFIG_DEPENDS += \
|
||||
@ -151,6 +152,14 @@ define KernelPackage/mt76-connac
|
||||
FILES:= $(PKG_BUILD_DIR)/mt76-connac-lib.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/mt76-sdio
|
||||
$(KernelPackage/mt76-default)
|
||||
TITLE:=MediaTek MT7615/MT79xx SDIO driver common code
|
||||
HIDDEN:=1
|
||||
DEPENDS+=+kmod-mt76-core +kmod-mmc
|
||||
FILES:= $(PKG_BUILD_DIR)/mt76-sdio.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/mt7615-common
|
||||
$(KernelPackage/mt76-default)
|
||||
TITLE:=MediaTek MT7615 wireless driver common code
|
||||
@ -195,9 +204,8 @@ endef
|
||||
define KernelPackage/mt7663s
|
||||
$(KernelPackage/mt76-default)
|
||||
TITLE:=MediaTek MT7663s wireless driver
|
||||
DEPENDS+=+kmod-mmc +kmod-mt7615-common +kmod-mt7663-usb-sdio
|
||||
DEPENDS+=+kmod-mt76-sdio +kmod-mt7615-common +kmod-mt7663-usb-sdio
|
||||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/mt76-sdio.ko \
|
||||
$(PKG_BUILD_DIR)/mt7615/mt7663s.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mt7663s)
|
||||
endef
|
||||
@ -218,10 +226,25 @@ define KernelPackage/mt7915e
|
||||
AUTOLOAD:=$(call AutoProbe,mt7915e)
|
||||
endef
|
||||
|
||||
define KernelPackage/mt7921-common
|
||||
TITLE:=MediaTek MT7615 wireless driver common code
|
||||
HIDDEN:=1
|
||||
DEPENDS+=@PCI_SUPPORT +kmod-mt76-core +kmod-mt76-connac
|
||||
FILES:= $(PKG_BUILD_DIR)/mt7921/mt7921-common.ko
|
||||
endef
|
||||
|
||||
define KernelPackage/mt7921s
|
||||
$(KernelPackage/mt76-default)
|
||||
TITLE:=MediaTek MT7921s wireless driver
|
||||
DEPENDS+=@PCI_SUPPORT +kmod-mt76-connac +kmod-mt76-sdio +kmod-mt7921-common
|
||||
FILES:= $(PKG_BUILD_DIR)/mt7921/mt7921s.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mt7921s)
|
||||
endef
|
||||
|
||||
define KernelPackage/mt7921e
|
||||
$(KernelPackage/mt76-default)
|
||||
TITLE:=MediaTek MT7921e wireless driver
|
||||
DEPENDS+=@PCI_SUPPORT +kmod-mt76-connac
|
||||
DEPENDS+=@PCI_SUPPORT +kmod-mt76-connac +kmod-mt7921-common
|
||||
FILES:= $(PKG_BUILD_DIR)/mt7921/mt7921e.ko
|
||||
AUTOLOAD:=$(call AutoProbe,mt7921e)
|
||||
endef
|
||||
@ -287,6 +310,9 @@ endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt76-connac
|
||||
PKG_MAKE_FLAGS += CONFIG_MT76_CONNAC_LIB=m
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt76-sdio
|
||||
PKG_MAKE_FLAGS += CONFIG_MT76_SDIO=m
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt7615-common
|
||||
PKG_MAKE_FLAGS += CONFIG_MT7615_COMMON=m
|
||||
endif
|
||||
@ -301,7 +327,6 @@ ifdef CONFIG_PACKAGE_kmod-mt7663-usb-sdio
|
||||
PKG_MAKE_FLAGS += CONFIG_MT7663_USB_SDIO_COMMON=m
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt7663s
|
||||
PKG_MAKE_FLAGS += CONFIG_MT76_SDIO=m
|
||||
PKG_MAKE_FLAGS += CONFIG_MT7663S=m
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt7663u
|
||||
@ -310,6 +335,12 @@ endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt7915e
|
||||
PKG_MAKE_FLAGS += CONFIG_MT7915E=m
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt7921-common
|
||||
PKG_MAKE_FLAGS += CONFIG_MT7921_COMMON=m
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt7921s
|
||||
PKG_MAKE_FLAGS += CONFIG_MT7921S=m
|
||||
endif
|
||||
ifdef CONFIG_PACKAGE_kmod-mt7921e
|
||||
PKG_MAKE_FLAGS += CONFIG_MT7921E=m
|
||||
endif
|
||||
@ -432,6 +463,7 @@ $(eval $(call KernelPackage,mt76x2u))
|
||||
$(eval $(call KernelPackage,mt76x2))
|
||||
$(eval $(call KernelPackage,mt7603))
|
||||
$(eval $(call KernelPackage,mt76-connac))
|
||||
$(eval $(call KernelPackage,mt76-sdio))
|
||||
$(eval $(call KernelPackage,mt7615-common))
|
||||
$(eval $(call KernelPackage,mt7615-firmware))
|
||||
$(eval $(call KernelPackage,mt7615e))
|
||||
@ -441,6 +473,8 @@ $(eval $(call KernelPackage,mt7663-usb-sdio))
|
||||
$(eval $(call KernelPackage,mt7663u))
|
||||
$(eval $(call KernelPackage,mt7663s))
|
||||
$(eval $(call KernelPackage,mt7915e))
|
||||
$(eval $(call KernelPackage,mt7921-common))
|
||||
$(eval $(call KernelPackage,mt7921s))
|
||||
$(eval $(call KernelPackage,mt7921e))
|
||||
$(eval $(call KernelPackage,mt76))
|
||||
$(eval $(call BuildPackage,mt76-test))
|
||||
|
@ -0,0 +1,26 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 23 Nov 2021 17:01:45 +0100
|
||||
Subject: [PATCH] Revert "of: net: pass the dst buffer to of_get_mac_address()"
|
||||
|
||||
This reverts commit 4932c5d80153c336c77dbe8d7af9f8fdd879d01f.
|
||||
---
|
||||
|
||||
--- a/eeprom.c
|
||||
+++ b/eeprom.c
|
||||
@@ -105,9 +105,15 @@ mt76_eeprom_override(struct mt76_phy *ph
|
||||
{
|
||||
struct mt76_dev *dev = phy->dev;
|
||||
|
||||
+#ifdef CONFIG_OF
|
||||
struct device_node *np = dev->dev->of_node;
|
||||
+ const u8 *mac = NULL;
|
||||
|
||||
- of_get_mac_address(np, phy->macaddr);
|
||||
+ if (np)
|
||||
+ mac = of_get_mac_address(np);
|
||||
+ if (!IS_ERR_OR_NULL(mac))
|
||||
+ ether_addr_copy(phy->macaddr, mac);
|
||||
+#endif
|
||||
|
||||
if (!is_valid_ether_addr(phy->macaddr)) {
|
||||
eth_random_addr(phy->macaddr);
|
@ -5,9 +5,9 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
|
||||
PKG_SOURCE_DATE:=2021-11-27
|
||||
PKG_SOURCE_VERSION:=a68e80513abb73cc76b94b5d70d0813344fa7cd7
|
||||
PKG_MIRROR_HASH:=4f2eff7a0bd4e9b278d220a4361e8948b582feab59eeedcc5eb120678aa72d0d
|
||||
PKG_SOURCE_DATE:=2021-10-30
|
||||
PKG_SOURCE_VERSION:=8f82742ca4f47f459284f3a07323d04da72ea5f6
|
||||
PKG_MIRROR_HASH:=5e519bb1aec9bb30782213f32f19f12e874c909e42826618dd4332ded816d2fe
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
@ -7,7 +7,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=hostapd
|
||||
PKG_RELEASE:=35
|
||||
PKG_RELEASE:=37
|
||||
|
||||
PKG_SOURCE_URL:=http://w1.fi/hostap.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
|
@ -384,7 +384,7 @@ CONFIG_TLS=internal
|
||||
#CONFIG_OWE=y
|
||||
|
||||
# Airtime policy support
|
||||
#CONFIG_AIRTIME_POLICY=y
|
||||
CONFIG_AIRTIME_POLICY=y
|
||||
|
||||
# Override default value for the wpa_disable_eapol_key_retries configuration
|
||||
# parameter. See that parameter in hostapd.conf for more details.
|
||||
|
@ -91,6 +91,7 @@ hostapd_add_log_config() {
|
||||
hostapd_common_add_device_config() {
|
||||
config_add_array basic_rate
|
||||
config_add_array supported_rates
|
||||
config_add_string beacon_rate
|
||||
|
||||
config_add_string country country3
|
||||
config_add_boolean country_ie doth
|
||||
@ -100,6 +101,7 @@ hostapd_common_add_device_config() {
|
||||
config_add_boolean legacy_rates
|
||||
config_add_int cell_density
|
||||
config_add_boolean vendor_vht
|
||||
config_add_int rts_threshold
|
||||
|
||||
config_add_string acs_chan_bias
|
||||
config_add_array hostapd_options
|
||||
@ -116,7 +118,8 @@ hostapd_prepare_device_config() {
|
||||
local base_cfg=
|
||||
|
||||
json_get_vars country country3 country_ie beacon_int:100 dtim_period:2 doth require_mode legacy_rates \
|
||||
acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density vendor_vht
|
||||
acs_chan_bias local_pwr_constraint spectrum_mgmt_required airtime_mode cell_density vendor_vht \
|
||||
rts_threshold beacon_rate
|
||||
|
||||
hostapd_set_log_options base_cfg
|
||||
|
||||
@ -209,9 +212,11 @@ hostapd_prepare_device_config() {
|
||||
hostapd_add_rate brlist "$br"
|
||||
done
|
||||
|
||||
[ -n "$beacon_rate" ] && append base_cfg "beacon_rate=$beacon_rate" "$N"
|
||||
[ -n "$rlist" ] && append base_cfg "supported_rates=$rlist" "$N"
|
||||
[ -n "$brlist" ] && append base_cfg "basic_rates=$brlist" "$N"
|
||||
append base_cfg "beacon_int=$beacon_int" "$N"
|
||||
[ -n "$rts_threshold" ] && append base_cfg "rts_threshold=$rts_threshold" "$N"
|
||||
append base_cfg "dtim_period=$dtim_period" "$N"
|
||||
[ "$airtime_mode" -gt 0 ] && append base_cfg "airtime_mode=$airtime_mode" "$N"
|
||||
|
||||
@ -271,7 +276,7 @@ hostapd_common_add_bss_config() {
|
||||
config_add_array domain_match domain_match2 domain_suffix_match domain_suffix_match2
|
||||
config_add_string ieee80211w_mgmt_cipher
|
||||
|
||||
config_add_int dynamic_vlan vlan_naming
|
||||
config_add_int dynamic_vlan vlan_naming vlan_no_bridge
|
||||
config_add_string vlan_tagged_interface vlan_bridge
|
||||
config_add_string vlan_file
|
||||
|
||||
@ -289,6 +294,7 @@ hostapd_common_add_bss_config() {
|
||||
config_add_boolean wnm_sleep_mode wnm_sleep_mode_no_keys bss_transition
|
||||
config_add_int time_advertisement
|
||||
config_add_string time_zone
|
||||
config_add_string vendor_elements
|
||||
|
||||
config_add_boolean ieee80211k rrm_neighbor_report rrm_beacon_report
|
||||
|
||||
@ -321,7 +327,7 @@ hostapd_common_add_bss_config() {
|
||||
config_add_int iw_ipaddr_type_availability iw_gas_address3
|
||||
config_add_string iw_hessid iw_network_auth_type iw_qos_map_set
|
||||
config_add_array iw_roaming_consortium iw_domain_name iw_anqp_3gpp_cell_net iw_nai_realm
|
||||
config_add_array iw_anqp_elem
|
||||
config_add_array iw_anqp_elem iw_venue_name iw_venue_url
|
||||
|
||||
config_add_boolean hs20 disable_dgaf osen
|
||||
config_add_int anqp_domain_id
|
||||
@ -332,12 +338,21 @@ hostapd_common_add_bss_config() {
|
||||
config_add_array hs20_conn_capab
|
||||
config_add_string osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp
|
||||
|
||||
config_add_string hs20_t_c_server_url
|
||||
|
||||
config_add_array airtime_sta_weight
|
||||
config_add_int airtime_bss_weight airtime_bss_limit
|
||||
|
||||
config_add_boolean multicast_to_unicast per_sta_vif
|
||||
|
||||
config_add_array hostapd_bss_options
|
||||
|
||||
config_add_boolean request_cui
|
||||
config_add_array radius_auth_req_attr
|
||||
config_add_array radius_acct_req_attr
|
||||
|
||||
config_add_int eap_server
|
||||
config_add_string eap_user_file ca_cert server_cert private_key private_key_passwd server_id
|
||||
}
|
||||
|
||||
hostapd_set_vlan_file() {
|
||||
@ -401,10 +416,22 @@ append_iw_nai_realm() {
|
||||
[ -n "$1" ] && append bss_conf "nai_realm=$1" "$N"
|
||||
}
|
||||
|
||||
append_iw_venue_name() {
|
||||
append bss_conf "venue_name=$1" "$N"
|
||||
}
|
||||
|
||||
append_iw_venue_url() {
|
||||
append bss_conf "venue_url=$1" "$N"
|
||||
}
|
||||
|
||||
append_hs20_oper_friendly_name() {
|
||||
append bss_conf "hs20_oper_friendly_name=$1" "$N"
|
||||
}
|
||||
|
||||
append_osu_provider_friendly_name() {
|
||||
append bss_conf "osu_friendly_name=$1" "$N"
|
||||
}
|
||||
|
||||
append_osu_provider_service_desc() {
|
||||
append bss_conf "osu_service_desc=$1" "$N"
|
||||
}
|
||||
@ -452,6 +479,7 @@ append_osu_provider() {
|
||||
append bss_conf "osu_method_list=$osu_method_list" "$N"
|
||||
|
||||
config_list_foreach "$1" osu_service_desc append_osu_provider_service_desc
|
||||
config_list_foreach "$1" osu_friendly_name append_osu_friendly_name
|
||||
config_list_foreach "$1" osu_icon append_osu_icon
|
||||
|
||||
append bss_conf "$N"
|
||||
@ -461,6 +489,14 @@ append_hs20_conn_capab() {
|
||||
[ -n "$1" ] && append bss_conf "hs20_conn_capab=$1" "$N"
|
||||
}
|
||||
|
||||
append_radius_acct_req_attr() {
|
||||
append bss_conf "radius_acct_req_attr=$1" "$N"
|
||||
}
|
||||
|
||||
append_radius_auth_req_attr() {
|
||||
append bss_conf "radius_auth_req_attr=$1" "$N"
|
||||
}
|
||||
|
||||
append_airtime_sta_weight() {
|
||||
[ -n "$1" ] && append bss_conf "airtime_sta_weight=$1" "$N"
|
||||
}
|
||||
@ -487,7 +523,9 @@ hostapd_set_bss_options() {
|
||||
bss_load_update_period chan_util_avg_period sae_require_mfp \
|
||||
multi_ap multi_ap_backhaul_ssid multi_ap_backhaul_key skip_inactivity_poll \
|
||||
airtime_bss_weight airtime_bss_limit airtime_sta_weight \
|
||||
multicast_to_unicast per_sta_vif
|
||||
multicast_to_unicast per_sta_vif \
|
||||
eap_server eap_user_file ca_cert server_cert private_key private_key_passwd server_id \
|
||||
vendor_elements
|
||||
|
||||
set_default isolate 0
|
||||
set_default maxassoc 0
|
||||
@ -508,6 +546,7 @@ hostapd_set_bss_options() {
|
||||
set_default multi_ap 0
|
||||
set_default airtime_bss_weight 0
|
||||
set_default airtime_bss_limit 0
|
||||
set_default eap_server 0
|
||||
|
||||
append bss_conf "ctrl_interface=/var/run/hostapd"
|
||||
if [ "$isolate" -gt 0 ]; then
|
||||
@ -534,6 +573,7 @@ hostapd_set_bss_options() {
|
||||
append bss_conf "uapsd_advertisement_enabled=$uapsd" "$N"
|
||||
append bss_conf "utf8_ssid=$utf8_ssid" "$N"
|
||||
append bss_conf "multi_ap=$multi_ap" "$N"
|
||||
[ -n "$vendor_elements" ] && append bss_conf "vendor_elements=$vendor_elements" "$N"
|
||||
|
||||
[ "$tdls_prohibit" -gt 0 ] && append bss_conf "tdls_prohibit=$tdls_prohibit" "$N"
|
||||
|
||||
@ -552,6 +592,7 @@ hostapd_set_bss_options() {
|
||||
append bss_conf "acct_server_shared_secret=$acct_secret" "$N"
|
||||
[ -n "$acct_interval" ] && \
|
||||
append bss_conf "radius_acct_interim_interval=$acct_interval" "$N"
|
||||
json_for_each_item append_radius_acct_req_attr radius_acct_req_attr
|
||||
}
|
||||
|
||||
case "$auth_type" in
|
||||
@ -606,7 +647,7 @@ hostapd_set_bss_options() {
|
||||
auth_server auth_secret auth_port \
|
||||
dae_client dae_secret dae_port \
|
||||
ownip radius_client_addr \
|
||||
eap_reauth_period
|
||||
eap_reauth_period request_cui
|
||||
|
||||
# radius can provide VLAN ID for clients
|
||||
vlan_possible=1
|
||||
@ -618,18 +659,22 @@ hostapd_set_bss_options() {
|
||||
|
||||
set_default auth_port 1812
|
||||
set_default dae_port 3799
|
||||
set_default request_cui 0
|
||||
|
||||
[ "$eap_server" -eq 0 ] && {
|
||||
append bss_conf "auth_server_addr=$auth_server" "$N"
|
||||
append bss_conf "auth_server_port=$auth_port" "$N"
|
||||
append bss_conf "auth_server_shared_secret=$auth_secret" "$N"
|
||||
}
|
||||
|
||||
append bss_conf "auth_server_addr=$auth_server" "$N"
|
||||
append bss_conf "auth_server_port=$auth_port" "$N"
|
||||
append bss_conf "auth_server_shared_secret=$auth_secret" "$N"
|
||||
|
||||
[ "$request_cui" -gt 0 ] && append bss_conf "radius_request_cui=$request_cui" "$N"
|
||||
[ -n "$eap_reauth_period" ] && append bss_conf "eap_reauth_period=$eap_reauth_period" "$N"
|
||||
|
||||
[ -n "$dae_client" -a -n "$dae_secret" ] && {
|
||||
append bss_conf "radius_das_port=$dae_port" "$N"
|
||||
append bss_conf "radius_das_client=$dae_client $dae_secret" "$N"
|
||||
}
|
||||
json_for_each_item append_radius_auth_req_attr radius_auth_req_attr
|
||||
|
||||
[ -n "$ownip" ] && append bss_conf "own_ip_addr=$ownip" "$N"
|
||||
[ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N"
|
||||
@ -701,7 +746,8 @@ hostapd_set_bss_options() {
|
||||
}
|
||||
|
||||
append bss_conf "ssid=$ssid" "$N"
|
||||
[ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
|
||||
[ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge${N}wds_bridge=" "$N"
|
||||
[ -n "$network_ifname" ] && append bss_conf "snoop_iface=$network_ifname" "$N"
|
||||
[ -n "$iapp_interface" ] && {
|
||||
local ifname
|
||||
network_get_device ifname "$iapp_interface" || ifname="$iapp_interface"
|
||||
@ -742,7 +788,7 @@ hostapd_set_bss_options() {
|
||||
append bss_conf "ftm_responder=1" "$N"
|
||||
[ "$stationary_ap" -eq "1" ] && append bss_conf "stationary_ap=1" "$N"
|
||||
[ -n "$lci" ] && append bss_conf "lci=$lci" "$N"
|
||||
[ -n "$civic" ] && append bss_conf "lci=$civic" "$N"
|
||||
[ -n "$civic" ] && append bss_conf "civic=$civic" "$N"
|
||||
}
|
||||
fi
|
||||
|
||||
@ -766,6 +812,7 @@ hostapd_set_bss_options() {
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "$network_ifname" ] && append bss_conf "ft_iface=$network_ifname" "$N"
|
||||
append bss_conf "mobility_domain=$mobility_domain" "$N"
|
||||
append bss_conf "ft_psk_generate_local=$ft_psk_generate_local" "$N"
|
||||
append bss_conf "ft_over_ds=$ft_over_ds" "$N"
|
||||
@ -780,6 +827,13 @@ hostapd_set_bss_options() {
|
||||
set_default r0_key_lifetime 10000
|
||||
set_default pmk_r1_push 0
|
||||
|
||||
[ -n "$r0kh" -a -n "$r1kh" ] || {
|
||||
key=`echo -n "$mobility_domain/$auth_secret" | md5sum | awk '{print $1}'`
|
||||
|
||||
set_default r0kh "ff:ff:ff:ff:ff:ff,*,$key"
|
||||
set_default r1kh "00:00:00:00:00:00,00:00:00:00:00:00,$key"
|
||||
}
|
||||
|
||||
[ -n "$r1_key_holder" ] && append bss_conf "r1_key_holder=$r1_key_holder" "$N"
|
||||
append bss_conf "r0_key_lifetime=$r0_key_lifetime" "$N"
|
||||
append bss_conf "pmk_r1_push=$pmk_r1_push" "$N"
|
||||
@ -865,13 +919,17 @@ hostapd_set_bss_options() {
|
||||
}
|
||||
|
||||
[ -n "$vlan_possible" -a -n "$dynamic_vlan" ] && {
|
||||
json_get_vars vlan_naming vlan_tagged_interface vlan_bridge vlan_file
|
||||
json_get_vars vlan_naming vlan_tagged_interface vlan_bridge vlan_file vlan_no_bridge
|
||||
set_default vlan_naming 1
|
||||
[ -z "$vlan_file" ] && set_default vlan_file /var/run/hostapd-$ifname.vlan
|
||||
append bss_conf "dynamic_vlan=$dynamic_vlan" "$N"
|
||||
append bss_conf "vlan_naming=$vlan_naming" "$N"
|
||||
[ -n "$vlan_bridge" ] && \
|
||||
if [ -n "$vlan_bridge" ]; then
|
||||
append bss_conf "vlan_bridge=$vlan_bridge" "$N"
|
||||
else
|
||||
set_default vlan_no_bridge 1
|
||||
fi
|
||||
append bss_conf "vlan_no_bridge=$vlan_no_bridge" "$N"
|
||||
[ -n "$vlan_tagged_interface" ] && \
|
||||
append bss_conf "vlan_tagged_interface=$vlan_tagged_interface" "$N"
|
||||
[ -n "$vlan_file" ] && {
|
||||
@ -884,6 +942,7 @@ hostapd_set_bss_options() {
|
||||
json_get_vars iw_hessid iw_venue_group iw_venue_type iw_network_auth_type
|
||||
json_get_vars iw_roaming_consortium iw_domain_name iw_anqp_3gpp_cell_net iw_nai_realm
|
||||
json_get_vars iw_anqp_elem iw_qos_map_set iw_ipaddr_type_availability iw_gas_address3
|
||||
json_get_vars iw_venue_name iw_venue_url
|
||||
|
||||
set_default iw_enabled 0
|
||||
if [ "$iw_enabled" = "1" ]; then
|
||||
@ -907,11 +966,12 @@ hostapd_set_bss_options() {
|
||||
[ -n "$iw_network_auth_type" ] && \
|
||||
append bss_conf "network_auth_type=$iw_network_auth_type" "$N"
|
||||
[ -n "$iw_gas_address3" ] && append bss_conf "gas_address3=$iw_gas_address3" "$N"
|
||||
[ -n "$iw_qos_map_set" ] && append bss_conf "qos_map_set=$iw_qos_map_set" "$N"
|
||||
|
||||
json_for_each_item append_iw_roaming_consortium iw_roaming_consortium
|
||||
json_for_each_item append_iw_anqp_elem iw_anqp_elem
|
||||
json_for_each_item append_iw_nai_realm iw_nai_realm
|
||||
json_for_each_item append_iw_venue_name iw_venue_name
|
||||
json_for_each_item append_iw_venue_url iw_venue_url
|
||||
|
||||
iw_domain_name_conf=
|
||||
json_for_each_item append_iw_domain_name iw_domain_name
|
||||
@ -924,11 +984,19 @@ hostapd_set_bss_options() {
|
||||
append bss_conf "anqp_3gpp_cell_net=$iw_anqp_3gpp_cell_net_conf" "$N"
|
||||
fi
|
||||
|
||||
set_default iw_qos_map_set 0,0,2,16,1,1,255,255,18,22,24,38,40,40,44,46,48,56
|
||||
case "$iw_qos_map_set" in
|
||||
*,*);;
|
||||
*) iw_qos_map_set="";;
|
||||
esac
|
||||
[ -n "$iw_qos_map_set" ] && append bss_conf "qos_map_set=$iw_qos_map_set" "$N"
|
||||
|
||||
local hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \
|
||||
osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp
|
||||
osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp \
|
||||
hs20_t_c_server_url
|
||||
json_get_vars hs20 disable_dgaf osen anqp_domain_id hs20_deauth_req_timeout \
|
||||
osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp
|
||||
osu_ssid hs20_wan_metrics hs20_operating_class hs20_t_c_filename hs20_t_c_timestamp \
|
||||
hs20_t_c_server_url
|
||||
|
||||
set_default hs20 0
|
||||
set_default disable_dgaf $hs20
|
||||
@ -947,12 +1015,23 @@ hostapd_set_bss_options() {
|
||||
[ -n "$hs20_operating_class" ] && append bss_conf "hs20_operating_class=$hs20_operating_class" "$N"
|
||||
[ -n "$hs20_t_c_filename" ] && append bss_conf "hs20_t_c_filename=$hs20_t_c_filename" "$N"
|
||||
[ -n "$hs20_t_c_timestamp" ] && append bss_conf "hs20_t_c_timestamp=$hs20_t_c_timestamp" "$N"
|
||||
json_for_each_item append_hs20_conn_capab hs20_conn_capab
|
||||
[ -n "$hs20_t_c_server_url" ] && append bss_conf "hs20_t_c_server_url=$hs20_t_c_server_url" "$N"
|
||||
json_for_each_item append_hs20_oper_friendly_name hs20_oper_friendly_name
|
||||
json_for_each_item append_hs20_conn_capab hs20_conn_capab
|
||||
json_for_each_item append_osu_provider osu_provider
|
||||
json_for_each_item append_operator_icon operator_icon
|
||||
fi
|
||||
|
||||
if [ "$eap_server" = "1" ]; then
|
||||
append bss_conf "eap_server=1" "$N"
|
||||
[ -n "$eap_user_file" ] && append bss_conf "eap_user_file=$eap_user_file" "$N"
|
||||
[ -n "$ca_cert" ] && append bss_conf "ca_cert=$ca_cert" "$N"
|
||||
[ -n "$server_cert" ] && append bss_conf "server_cert=$server_cert" "$N"
|
||||
[ -n "$private_key" ] && append bss_conf "private_key=$private_key" "$N"
|
||||
[ -n "$private_key_passwd" ] && append bss_conf "private_key_passwd=$private_key_passwd" "$N"
|
||||
[ -n "$server_id" ] && append bss_conf "server_id=$server_id" "$N"
|
||||
fi
|
||||
|
||||
set_default multicast_to_unicast 0
|
||||
if [ "$multicast_to_unicast" -gt 0 ]; then
|
||||
append bss_conf "multicast_to_unicast=$multicast_to_unicast" "$N"
|
||||
@ -1081,16 +1160,16 @@ wpa_supplicant_set_fixed_freq() {
|
||||
append network_data "frequency=$freq" "$N$T"
|
||||
case "$htmode" in
|
||||
NOHT) append network_data "disable_ht=1" "$N$T";;
|
||||
HT20|VHT20) append network_data "disable_ht40=1" "$N$T";;
|
||||
HT40*|VHT40*|VHT80*|VHT160*) append network_data "ht40=1" "$N$T";;
|
||||
HE20|HT20|VHT20) append network_data "disable_ht40=1" "$N$T";;
|
||||
HT40*|VHT40|VHT80|VHT160|HE40|HE80|HE160) append network_data "ht40=1" "$N$T";;
|
||||
esac
|
||||
case "$htmode" in
|
||||
VHT*) append network_data "vht=1" "$N$T";;
|
||||
esac
|
||||
case "$htmode" in
|
||||
VHT80) append network_data "max_oper_chwidth=1" "$N$T";;
|
||||
VHT160) append network_data "max_oper_chwidth=2" "$N$T";;
|
||||
VHT20|VHT40) append network_data "max_oper_chwidth=0" "$N$T";;
|
||||
HE80|VHT80) append network_data "max_oper_chwidth=1" "$N$T";;
|
||||
HE160|VHT160) append network_data "max_oper_chwidth=2" "$N$T";;
|
||||
HE20|HE40|VHT20|VHT40) append network_data "max_oper_chwidth=0" "$N$T";;
|
||||
*) append network_data "disable_vht=1" "$N$T";;
|
||||
esac
|
||||
}
|
||||
|
@ -18,8 +18,6 @@ Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
src/drivers/driver_nl80211.c | 23 +++++++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
|
||||
index 72189da24..011a15e68 100644
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -617,6 +617,7 @@ struct wiphy_idx_data {
|
||||
@ -30,7 +28,7 @@ index 72189da24..011a15e68 100644
|
||||
};
|
||||
|
||||
|
||||
@@ -639,6 +640,9 @@ static int netdev_info_handler(struct nl_msg *msg, void *arg)
|
||||
@@ -639,6 +640,9 @@ static int netdev_info_handler(struct nl
|
||||
os_memcpy(info->macaddr, nla_data(tb[NL80211_ATTR_MAC]),
|
||||
ETH_ALEN);
|
||||
|
||||
@ -40,7 +38,7 @@ index 72189da24..011a15e68 100644
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
@@ -691,6 +695,20 @@ static int nl80211_get_macaddr(struct i802_bss *bss)
|
||||
@@ -691,6 +695,20 @@ static int nl80211_get_macaddr(struct i8
|
||||
}
|
||||
|
||||
|
||||
@ -61,7 +59,7 @@ index 72189da24..011a15e68 100644
|
||||
static int nl80211_register_beacons(struct wpa_driver_nl80211_data *drv,
|
||||
struct nl80211_wiphy_data *w)
|
||||
{
|
||||
@@ -11482,6 +11500,11 @@ static int nl80211_set_4addr_mode(void *priv, const char *bridge_ifname,
|
||||
@@ -11508,6 +11526,11 @@ static int nl80211_set_4addr_mode(void *
|
||||
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||
msg = NULL;
|
||||
@ -73,6 +71,3 @@ index 72189da24..011a15e68 100644
|
||||
if (!ret) {
|
||||
if (bridge_ifname[0] && val &&
|
||||
i802_check_bridge(drv, bss, bridge_ifname, bss->ifname) < 0)
|
||||
--
|
||||
2.29.2
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 28 Jul 2021 05:43:29 +0200
|
||||
Subject: [PATCH] ndisc_snoop: call dl_list_del before freeing ipv6 addresses
|
||||
|
||||
Fixes a segmentation fault on sta disconnect
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/src/ap/ndisc_snoop.c
|
||||
+++ b/src/ap/ndisc_snoop.c
|
||||
@@ -61,6 +61,7 @@ void sta_ip6addr_del(struct hostapd_data
|
||||
dl_list_for_each_safe(ip6addr, prev, &sta->ip6addr, struct ip6addr,
|
||||
list) {
|
||||
hostapd_drv_br_delete_ip_neigh(hapd, 6, (u8 *) &ip6addr->addr);
|
||||
+ dl_list_del(&ip6addr->list);
|
||||
os_free(ip6addr);
|
||||
}
|
||||
}
|
@ -0,0 +1,275 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Wed, 28 Jul 2021 05:49:46 +0200
|
||||
Subject: [PATCH] driver_nl80211: rewrite neigh code to not depend on
|
||||
libnl3-route
|
||||
|
||||
Removes an unnecessary dependency and also makes the code smaller
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -16,9 +16,6 @@
|
||||
#include <net/if.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
-#include <netlink/route/neighbour.h>
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/errqueue.h>
|
||||
@@ -4965,26 +4962,29 @@ fail:
|
||||
|
||||
static void rtnl_neigh_delete_fdb_entry(struct i802_bss *bss, const u8 *addr)
|
||||
{
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
- struct rtnl_neigh *rn;
|
||||
- struct nl_addr *nl_addr;
|
||||
+ struct ndmsg nhdr = {
|
||||
+ .ndm_state = NUD_PERMANENT,
|
||||
+ .ndm_ifindex = bss->ifindex,
|
||||
+ .ndm_family = AF_BRIDGE,
|
||||
+ };
|
||||
+ struct nl_msg *msg;
|
||||
int err;
|
||||
|
||||
- rn = rtnl_neigh_alloc();
|
||||
- if (!rn)
|
||||
+ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE);
|
||||
+ if (!msg)
|
||||
return;
|
||||
|
||||
- rtnl_neigh_set_family(rn, AF_BRIDGE);
|
||||
- rtnl_neigh_set_ifindex(rn, bss->ifindex);
|
||||
- nl_addr = nl_addr_build(AF_BRIDGE, (void *) addr, ETH_ALEN);
|
||||
- if (!nl_addr) {
|
||||
- rtnl_neigh_put(rn);
|
||||
- return;
|
||||
- }
|
||||
- rtnl_neigh_set_lladdr(rn, nl_addr);
|
||||
+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
|
||||
+ goto errout;
|
||||
+
|
||||
+ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr))
|
||||
+ goto errout;
|
||||
+
|
||||
+ if (nl_send_auto_complete(drv->rtnl_sk, msg) < 0)
|
||||
+ goto errout;
|
||||
|
||||
- err = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
|
||||
+ err = nl_wait_for_ack(drv->rtnl_sk);
|
||||
if (err < 0) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: bridge FDB entry delete for "
|
||||
MACSTR " ifindex=%d failed: %s", MAC2STR(addr),
|
||||
@@ -4994,9 +4994,8 @@ static void rtnl_neigh_delete_fdb_entry(
|
||||
MACSTR, MAC2STR(addr));
|
||||
}
|
||||
|
||||
- nl_addr_put(nl_addr);
|
||||
- rtnl_neigh_put(rn);
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
+errout:
|
||||
+ nlmsg_free(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -7337,7 +7336,6 @@ static void *i802_init(struct hostapd_da
|
||||
(params->num_bridge == 0 || !params->bridge[0]))
|
||||
add_ifidx(drv, br_ifindex, drv->ifindex);
|
||||
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
if (bss->added_if_into_bridge || bss->already_in_bridge) {
|
||||
int err;
|
||||
|
||||
@@ -7354,7 +7352,6 @@ static void *i802_init(struct hostapd_da
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
|
||||
if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
@@ -10238,13 +10235,14 @@ static int wpa_driver_br_add_ip_neigh(vo
|
||||
const u8 *ipaddr, int prefixlen,
|
||||
const u8 *addr)
|
||||
{
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
struct i802_bss *bss = priv;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
- struct rtnl_neigh *rn;
|
||||
- struct nl_addr *nl_ipaddr = NULL;
|
||||
- struct nl_addr *nl_lladdr = NULL;
|
||||
- int family, addrsize;
|
||||
+ struct ndmsg nhdr = {
|
||||
+ .ndm_state = NUD_PERMANENT,
|
||||
+ .ndm_ifindex = bss->br_ifindex,
|
||||
+ };
|
||||
+ struct nl_msg *msg;
|
||||
+ int addrsize;
|
||||
int res;
|
||||
|
||||
if (!ipaddr || prefixlen == 0 || !addr)
|
||||
@@ -10263,85 +10261,66 @@ static int wpa_driver_br_add_ip_neigh(vo
|
||||
}
|
||||
|
||||
if (version == 4) {
|
||||
- family = AF_INET;
|
||||
+ nhdr.ndm_family = AF_INET;
|
||||
addrsize = 4;
|
||||
} else if (version == 6) {
|
||||
- family = AF_INET6;
|
||||
+ nhdr.ndm_family = AF_INET6;
|
||||
addrsize = 16;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- rn = rtnl_neigh_alloc();
|
||||
- if (rn == NULL)
|
||||
+ msg = nlmsg_alloc_simple(RTM_NEWNEIGH, NLM_F_CREATE);
|
||||
+ if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
- /* set the destination ip address for neigh */
|
||||
- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
|
||||
- if (nl_ipaddr == NULL) {
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
|
||||
- res = -ENOMEM;
|
||||
+ res = -ENOMEM;
|
||||
+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
|
||||
goto errout;
|
||||
- }
|
||||
- nl_addr_set_prefixlen(nl_ipaddr, prefixlen);
|
||||
- res = rtnl_neigh_set_dst(rn, nl_ipaddr);
|
||||
- if (res) {
|
||||
- wpa_printf(MSG_DEBUG,
|
||||
- "nl80211: neigh set destination addr failed");
|
||||
+
|
||||
+ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr))
|
||||
goto errout;
|
||||
- }
|
||||
|
||||
- /* set the corresponding lladdr for neigh */
|
||||
- nl_lladdr = nl_addr_build(AF_BRIDGE, (u8 *) addr, ETH_ALEN);
|
||||
- if (nl_lladdr == NULL) {
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: neigh set lladdr failed");
|
||||
- res = -ENOMEM;
|
||||
+ if (nla_put(msg, NDA_LLADDR, ETH_ALEN, (void *)addr))
|
||||
goto errout;
|
||||
- }
|
||||
- rtnl_neigh_set_lladdr(rn, nl_lladdr);
|
||||
|
||||
- rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
|
||||
- rtnl_neigh_set_state(rn, NUD_PERMANENT);
|
||||
+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
|
||||
+ if (res < 0)
|
||||
+ goto errout;
|
||||
|
||||
- res = rtnl_neigh_add(drv->rtnl_sk, rn, NLM_F_CREATE);
|
||||
+ res = nl_wait_for_ack(drv->rtnl_sk);
|
||||
if (res) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Adding bridge ip neigh failed: %s",
|
||||
nl_geterror(res));
|
||||
}
|
||||
errout:
|
||||
- if (nl_lladdr)
|
||||
- nl_addr_put(nl_lladdr);
|
||||
- if (nl_ipaddr)
|
||||
- nl_addr_put(nl_ipaddr);
|
||||
- if (rn)
|
||||
- rtnl_neigh_put(rn);
|
||||
+ nlmsg_free(msg);
|
||||
return res;
|
||||
-#else /* CONFIG_LIBNL3_ROUTE */
|
||||
- return -1;
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
}
|
||||
|
||||
|
||||
static int wpa_driver_br_delete_ip_neigh(void *priv, u8 version,
|
||||
const u8 *ipaddr)
|
||||
{
|
||||
-#ifdef CONFIG_LIBNL3_ROUTE
|
||||
struct i802_bss *bss = priv;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
- struct rtnl_neigh *rn;
|
||||
- struct nl_addr *nl_ipaddr;
|
||||
- int family, addrsize;
|
||||
+ struct ndmsg nhdr = {
|
||||
+ .ndm_state = NUD_PERMANENT,
|
||||
+ .ndm_ifindex = bss->br_ifindex,
|
||||
+ };
|
||||
+ struct nl_msg *msg;
|
||||
+ int addrsize;
|
||||
int res;
|
||||
|
||||
if (!ipaddr)
|
||||
return -EINVAL;
|
||||
|
||||
if (version == 4) {
|
||||
- family = AF_INET;
|
||||
+ nhdr.ndm_family = AF_INET;
|
||||
addrsize = 4;
|
||||
} else if (version == 6) {
|
||||
- family = AF_INET6;
|
||||
+ nhdr.ndm_family = AF_INET6;
|
||||
addrsize = 16;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
@@ -10359,41 +10338,30 @@ static int wpa_driver_br_delete_ip_neigh
|
||||
return -1;
|
||||
}
|
||||
|
||||
- rn = rtnl_neigh_alloc();
|
||||
- if (rn == NULL)
|
||||
+ msg = nlmsg_alloc_simple(RTM_DELNEIGH, NLM_F_CREATE);
|
||||
+ if (!msg)
|
||||
return -ENOMEM;
|
||||
|
||||
- /* set the destination ip address for neigh */
|
||||
- nl_ipaddr = nl_addr_build(family, (void *) ipaddr, addrsize);
|
||||
- if (nl_ipaddr == NULL) {
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: nl_ipaddr build failed");
|
||||
- res = -ENOMEM;
|
||||
+ res = -ENOMEM;
|
||||
+ if (nlmsg_append(msg, &nhdr, sizeof(nhdr), NLMSG_ALIGNTO) < 0)
|
||||
goto errout;
|
||||
- }
|
||||
- res = rtnl_neigh_set_dst(rn, nl_ipaddr);
|
||||
- if (res) {
|
||||
- wpa_printf(MSG_DEBUG,
|
||||
- "nl80211: neigh set destination addr failed");
|
||||
+
|
||||
+ if (nla_put(msg, NDA_DST, addrsize, (void *)ipaddr))
|
||||
goto errout;
|
||||
- }
|
||||
|
||||
- rtnl_neigh_set_ifindex(rn, bss->br_ifindex);
|
||||
+ res = nl_send_auto_complete(drv->rtnl_sk, msg);
|
||||
+ if (res < 0)
|
||||
+ goto errout;
|
||||
|
||||
- res = rtnl_neigh_delete(drv->rtnl_sk, rn, 0);
|
||||
+ res = nl_wait_for_ack(drv->rtnl_sk);
|
||||
if (res) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Deleting bridge ip neigh failed: %s",
|
||||
nl_geterror(res));
|
||||
}
|
||||
errout:
|
||||
- if (nl_ipaddr)
|
||||
- nl_addr_put(nl_ipaddr);
|
||||
- if (rn)
|
||||
- rtnl_neigh_put(rn);
|
||||
+ nlmsg_free(msg);
|
||||
return res;
|
||||
-#else /* CONFIG_LIBNL3_ROUTE */
|
||||
- return -1;
|
||||
-#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Mon, 18 Feb 2019 12:57:11 +0100
|
||||
Subject: [PATCH] mesh: allow processing authentication frames in blocked state
|
||||
|
||||
If authentication fails repeatedly e.g. because of a weak signal, the link
|
||||
can end up in blocked state. If one of the nodes tries to establish a link
|
||||
again before it is unblocked on the other side, it will block the link to
|
||||
that other side. The same happens on the other side when it unblocks the
|
||||
link. In that scenario, the link never recovers on its own.
|
||||
|
||||
To fix this, allow restarting authentication even if the link is in blocked
|
||||
state, but don't initiate the attempt until the blocked period is over.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -2527,15 +2527,6 @@ static void handle_auth(struct hostapd_d
|
||||
seq_ctrl);
|
||||
return;
|
||||
}
|
||||
-#ifdef CONFIG_MESH
|
||||
- if ((hapd->conf->mesh & MESH_ENABLED) &&
|
||||
- sta->plink_state == PLINK_BLOCKED) {
|
||||
- wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
|
||||
- " is blocked - drop Authentication frame",
|
||||
- MAC2STR(mgmt->sa));
|
||||
- return;
|
||||
- }
|
||||
-#endif /* CONFIG_MESH */
|
||||
} else {
|
||||
#ifdef CONFIG_MESH
|
||||
if (hapd->conf->mesh & MESH_ENABLED) {
|
@ -59,7 +59,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -10023,6 +10023,9 @@ static int nl80211_put_mesh_config(struc
|
||||
@@ -10038,6 +10038,9 @@ static int nl80211_put_mesh_config(struc
|
||||
if (((params->flags & WPA_DRIVER_MESH_CONF_FLAG_AUTO_PLINKS) &&
|
||||
nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
|
||||
params->auto_plinks)) ||
|
||||
|
@ -63,7 +63,7 @@ Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
|
||||
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -4878,6 +4878,28 @@ static int handle_action(struct hostapd_
|
||||
@@ -4869,6 +4869,28 @@ static int handle_action(struct hostapd_
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
|
||||
|
||||
/**
|
||||
* ieee802_11_mgmt - process incoming IEEE 802.11 management frames
|
||||
@@ -4969,6 +4991,9 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||
@@ -4960,6 +4982,9 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||
if (hapd->iconf->track_sta_max_num)
|
||||
sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
|
||||
|
||||
|
@ -231,7 +231,7 @@
|
||||
os_memset(&global, 0, sizeof(global));
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -4581,8 +4581,8 @@ static void wpas_event_unprot_beacon(str
|
||||
@@ -4579,8 +4579,8 @@ static void wpas_event_unprot_beacon(str
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +242,7 @@
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = ctx;
|
||||
int resched;
|
||||
@@ -5400,7 +5400,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
@@ -5398,7 +5398,7 @@ void wpa_supplicant_event(void *ctx, enu
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -4646,7 +4646,7 @@ static int nl80211_set_channel(struct i8
|
||||
@@ -4661,7 +4661,7 @@ static int nl80211_set_channel(struct i8
|
||||
freq->freq, freq->ht_enabled, freq->vht_enabled, freq->he_enabled,
|
||||
freq->bandwidth, freq->center_freq1, freq->center_freq2);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -2788,10 +2788,15 @@ static int wpa_driver_nl80211_del_beacon
|
||||
@@ -2803,10 +2803,15 @@ static int wpa_driver_nl80211_del_beacon
|
||||
struct nl_msg *msg;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
return send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -5261,7 +5266,7 @@ static void nl80211_teardown_ap(struct i
|
||||
@@ -5278,7 +5283,7 @@ static void nl80211_teardown_ap(struct i
|
||||
nl80211_mgmt_unsubscribe(bss, "AP teardown");
|
||||
|
||||
nl80211_put_wiphy_data_ap(bss);
|
||||
@ -27,7 +27,7 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -7679,8 +7684,6 @@ static int wpa_driver_nl80211_if_remove(
|
||||
@@ -7694,8 +7699,6 @@ static int wpa_driver_nl80211_if_remove(
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: First BSS - reassign context");
|
||||
nl80211_teardown_ap(bss);
|
||||
@ -36,7 +36,7 @@
|
||||
nl80211_destroy_bss(bss);
|
||||
if (!bss->added_if)
|
||||
i802_set_iface_flags(bss, 0);
|
||||
@@ -8074,7 +8077,6 @@ static int wpa_driver_nl80211_deinit_ap(
|
||||
@@ -8089,7 +8092,6 @@ static int wpa_driver_nl80211_deinit_ap(
|
||||
if (!is_ap_interface(drv->nlmode))
|
||||
return -1;
|
||||
wpa_driver_nl80211_del_beacon(bss);
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
/*
|
||||
* If the P2P GO interface was dynamically added, then it is
|
||||
@@ -8094,7 +8096,6 @@ static int wpa_driver_nl80211_stop_ap(vo
|
||||
@@ -8109,7 +8111,6 @@ static int wpa_driver_nl80211_stop_ap(vo
|
||||
if (!is_ap_interface(drv->nlmode))
|
||||
return -1;
|
||||
wpa_driver_nl80211_del_beacon(bss);
|
||||
|
@ -274,7 +274,7 @@
|
||||
if (ieee802_11_build_ap_params(hapd, ¶ms) < 0)
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -4581,6 +4581,60 @@ static void wpas_event_unprot_beacon(str
|
||||
@@ -4579,6 +4579,60 @@ static void wpas_event_unprot_beacon(str
|
||||
}
|
||||
|
||||
|
||||
@ -335,7 +335,7 @@
|
||||
void supplicant_event(void *ctx, enum wpa_event_type event,
|
||||
union wpa_event_data *data)
|
||||
{
|
||||
@@ -4883,8 +4937,10 @@ void supplicant_event(void *ctx, enum wp
|
||||
@@ -4881,8 +4935,10 @@ void supplicant_event(void *ctx, enum wp
|
||||
channel_width_to_string(data->ch_switch.ch_width),
|
||||
data->ch_switch.cf1,
|
||||
data->ch_switch.cf2);
|
||||
|
@ -10,7 +10,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -5584,7 +5584,7 @@ static int wpa_driver_nl80211_ibss(struc
|
||||
@@ -5601,7 +5601,7 @@ static int wpa_driver_nl80211_ibss(struc
|
||||
struct wpa_driver_associate_params *params)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
@ -19,7 +19,7 @@ Signed-hostap: Antonio Quartulli <ordex@autistici.org>
|
||||
int count = 0;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
|
||||
@@ -5611,6 +5611,37 @@ retry:
|
||||
@@ -5628,6 +5628,37 @@ retry:
|
||||
nl80211_put_beacon_int(msg, params->beacon_int))
|
||||
goto fail;
|
||||
|
||||
|
@ -29,7 +29,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
|
||||
struct wpa_driver_set_key_params {
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -10043,6 +10043,18 @@ static int nl80211_put_mesh_id(struct nl
|
||||
@@ -10058,6 +10058,18 @@ static int nl80211_put_mesh_id(struct nl
|
||||
}
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ Tested-by: Simon Wunderlich <simon.wunderlich@openmesh.com>
|
||||
static int nl80211_put_mesh_config(struct nl_msg *msg,
|
||||
struct wpa_driver_mesh_bss_params *params)
|
||||
{
|
||||
@@ -10104,6 +10116,7 @@ static int nl80211_join_mesh(struct i802
|
||||
@@ -10119,6 +10131,7 @@ static int nl80211_join_mesh(struct i802
|
||||
nl80211_put_basic_rates(msg, params->basic_rates) ||
|
||||
nl80211_put_mesh_id(msg, params->meshid, params->meshid_len) ||
|
||||
nl80211_put_beacon_int(msg, params->beacon_int) ||
|
||||
|
@ -126,7 +126,7 @@
|
||||
if (res == HOSTAPD_ACL_PENDING)
|
||||
return;
|
||||
|
||||
@@ -4166,7 +4178,7 @@ static void handle_assoc(struct hostapd_
|
||||
@@ -4157,7 +4169,7 @@ static void handle_assoc(struct hostapd_
|
||||
int resp = WLAN_STATUS_SUCCESS;
|
||||
u16 reply_res;
|
||||
const u8 *pos;
|
||||
@ -135,7 +135,7 @@
|
||||
struct sta_info *sta;
|
||||
u8 *tmp = NULL;
|
||||
#ifdef CONFIG_FILS
|
||||
@@ -4379,6 +4391,11 @@ static void handle_assoc(struct hostapd_
|
||||
@@ -4370,6 +4382,11 @@ static void handle_assoc(struct hostapd_
|
||||
left = res;
|
||||
}
|
||||
#endif /* CONFIG_FILS */
|
||||
@ -147,9 +147,9 @@
|
||||
|
||||
/* followed by SSID and Supported rates; and HT capabilities if 802.11n
|
||||
* is used */
|
||||
@@ -4543,6 +4560,14 @@ static void handle_assoc(struct hostapd_
|
||||
pos, left, rssi, omit_rsnxe);
|
||||
os_free(tmp);
|
||||
@@ -4468,6 +4485,14 @@ static void handle_assoc(struct hostapd_
|
||||
}
|
||||
#endif /* CONFIG_FILS */
|
||||
|
||||
+ ubus_resp = hostapd_ubus_handle_event(hapd, &req);
|
||||
+ if (ubus_resp) {
|
||||
@ -159,10 +159,10 @@
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fail:
|
||||
|
||||
/*
|
||||
* Remove the station in case tranmission of a success response fails
|
||||
* (the STA was added associated to the driver) or if the station was
|
||||
@@ -4570,6 +4595,7 @@ static void handle_disassoc(struct hosta
|
||||
@@ -4561,6 +4586,7 @@ static void handle_disassoc(struct hosta
|
||||
wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
|
||||
MAC2STR(mgmt->sa),
|
||||
le_to_host16(mgmt->u.disassoc.reason_code));
|
||||
@ -170,7 +170,7 @@
|
||||
|
||||
sta = ap_get_sta(hapd, mgmt->sa);
|
||||
if (sta == NULL) {
|
||||
@@ -4636,6 +4662,8 @@ static void handle_deauth(struct hostapd
|
||||
@@ -4627,6 +4653,8 @@ static void handle_deauth(struct hostapd
|
||||
" reason_code=%d",
|
||||
MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
|
||||
|
||||
@ -235,22 +235,22 @@
|
||||
wpabuf_free(sta->p2p_ie);
|
||||
--- a/src/ap/sta_info.c
|
||||
+++ b/src/ap/sta_info.c
|
||||
@@ -424,6 +424,7 @@ void ap_handle_timer(void *eloop_ctx, vo
|
||||
@@ -423,6 +423,7 @@ void ap_handle_timer(void *eloop_ctx, vo
|
||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO, "deauthenticated due to "
|
||||
"local deauth request");
|
||||
ap_free_sta(hapd, sta);
|
||||
+ hostapd_ubus_notify(hapd, "local-deauth", sta->addr);
|
||||
ap_free_sta(hapd, sta);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -579,6 +580,7 @@ skip_poll:
|
||||
@@ -578,6 +579,7 @@ skip_poll:
|
||||
mlme_deauthenticate_indication(
|
||||
hapd, sta,
|
||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
ap_free_sta(hapd, sta);
|
||||
+ hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr);
|
||||
ap_free_sta(hapd, sta);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1294,6 +1296,7 @@ void ap_sta_set_authorized(struct hostap
|
||||
buf, ip_addr, keyid_buf);
|
||||
} else {
|
||||
|
@ -174,7 +174,7 @@
|
||||
hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -4493,6 +4493,9 @@ static int wpa_driver_nl80211_set_ap(voi
|
||||
@@ -4508,6 +4508,9 @@ static int wpa_driver_nl80211_set_ap(voi
|
||||
if (ret) {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
|
||||
ret, strerror(-ret));
|
||||
|
@ -0,0 +1,33 @@
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -115,6 +115,7 @@ struct hostapd_ssid {
|
||||
#define DYNAMIC_VLAN_OPTIONAL 1
|
||||
#define DYNAMIC_VLAN_REQUIRED 2
|
||||
int dynamic_vlan;
|
||||
+ int vlan_no_bridge;
|
||||
#define DYNAMIC_VLAN_NAMING_WITHOUT_DEVICE 0
|
||||
#define DYNAMIC_VLAN_NAMING_WITH_DEVICE 1
|
||||
#define DYNAMIC_VLAN_NAMING_END 2
|
||||
--- a/src/ap/vlan_full.c
|
||||
+++ b/src/ap/vlan_full.c
|
||||
@@ -466,6 +466,9 @@ void vlan_newlink(const char *ifname, st
|
||||
|
||||
wpa_printf(MSG_DEBUG, "VLAN: vlan_newlink(%s)", ifname);
|
||||
|
||||
+ if (hapd->conf->ssid.vlan_no_bridge)
|
||||
+ return;
|
||||
+
|
||||
for (vlan = hapd->conf->vlan; vlan; vlan = vlan->next) {
|
||||
if (vlan->configured ||
|
||||
os_strcmp(ifname, vlan->ifname) != 0)
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -3400,6 +3400,8 @@ static int hostapd_config_fill(struct ho
|
||||
#ifndef CONFIG_NO_VLAN
|
||||
} else if (os_strcmp(buf, "dynamic_vlan") == 0) {
|
||||
bss->ssid.dynamic_vlan = atoi(pos);
|
||||
+ } else if (os_strcmp(buf, "vlan_no_bridge") == 0) {
|
||||
+ bss->ssid.vlan_no_bridge = atoi(pos);
|
||||
} else if (os_strcmp(buf, "per_sta_vif") == 0) {
|
||||
bss->ssid.per_sta_vif = atoi(pos);
|
||||
} else if (os_strcmp(buf, "vlan_file") == 0) {
|
@ -0,0 +1,22 @@
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -2405,6 +2405,8 @@ static int hostapd_config_fill(struct ho
|
||||
sizeof(conf->bss[0]->iface));
|
||||
} else if (os_strcmp(buf, "bridge") == 0) {
|
||||
os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
|
||||
+ if (!bss->wds_bridge[0])
|
||||
+ os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
|
||||
} else if (os_strcmp(buf, "vlan_bridge") == 0) {
|
||||
os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
|
||||
} else if (os_strcmp(buf, "wds_bridge") == 0) {
|
||||
--- a/src/ap/ap_drv_ops.c
|
||||
+++ b/src/ap/ap_drv_ops.c
|
||||
@@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d
|
||||
return -1;
|
||||
if (hapd->conf->wds_bridge[0])
|
||||
bridge = hapd->conf->wds_bridge;
|
||||
- else if (hapd->conf->bridge[0])
|
||||
- bridge = hapd->conf->bridge;
|
||||
return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
|
||||
bridge, ifname_wds);
|
||||
}
|
38
package/network/services/hostapd/patches/730-ft_iface.patch
Normal file
38
package/network/services/hostapd/patches/730-ft_iface.patch
Normal file
@ -0,0 +1,38 @@
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -3069,6 +3069,8 @@ static int hostapd_config_fill(struct ho
|
||||
wpa_printf(MSG_INFO,
|
||||
"Line %d: Obsolete peerkey parameter ignored", line);
|
||||
#ifdef CONFIG_IEEE80211R_AP
|
||||
+ } else if (os_strcmp(buf, "ft_iface") == 0) {
|
||||
+ os_strlcpy(bss->ft_iface, pos, sizeof(bss->ft_iface));
|
||||
} else if (os_strcmp(buf, "mobility_domain") == 0) {
|
||||
if (os_strlen(pos) != 2 * MOBILITY_DOMAIN_ID_LEN ||
|
||||
hexstr2bin(pos, bss->mobility_domain,
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -284,6 +284,7 @@ struct airtime_sta_weight {
|
||||
struct hostapd_bss_config {
|
||||
char iface[IFNAMSIZ + 1];
|
||||
char bridge[IFNAMSIZ + 1];
|
||||
+ char ft_iface[IFNAMSIZ + 1];
|
||||
char vlan_bridge[IFNAMSIZ + 1];
|
||||
char wds_bridge[IFNAMSIZ + 1];
|
||||
|
||||
--- a/src/ap/wpa_auth_glue.c
|
||||
+++ b/src/ap/wpa_auth_glue.c
|
||||
@@ -1511,8 +1511,12 @@ int hostapd_setup_wpa(struct hostapd_dat
|
||||
wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) {
|
||||
const char *ft_iface;
|
||||
|
||||
- ft_iface = hapd->conf->bridge[0] ? hapd->conf->bridge :
|
||||
- hapd->conf->iface;
|
||||
+ if (hapd->conf->ft_iface[0])
|
||||
+ ft_iface = hapd->conf->ft_iface;
|
||||
+ else if (hapd->conf->bridge[0])
|
||||
+ ft_iface = hapd->conf->bridge;
|
||||
+ else
|
||||
+ ft_iface = hapd->conf->iface;
|
||||
hapd->l2 = l2_packet_init(ft_iface, NULL, ETH_P_RRB,
|
||||
hostapd_rrb_receive, hapd, 1);
|
||||
if (!hapd->l2) {
|
@ -0,0 +1,66 @@
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -285,6 +285,7 @@ struct hostapd_bss_config {
|
||||
char iface[IFNAMSIZ + 1];
|
||||
char bridge[IFNAMSIZ + 1];
|
||||
char ft_iface[IFNAMSIZ + 1];
|
||||
+ char snoop_iface[IFNAMSIZ + 1];
|
||||
char vlan_bridge[IFNAMSIZ + 1];
|
||||
char wds_bridge[IFNAMSIZ + 1];
|
||||
|
||||
--- a/src/ap/x_snoop.c
|
||||
+++ b/src/ap/x_snoop.c
|
||||
@@ -31,14 +31,16 @@ int x_snoop_init(struct hostapd_data *ha
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE,
|
||||
+ if (!conf->snoop_iface[0] &&
|
||||
+ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_HAIRPIN_MODE,
|
||||
1)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"x_snoop: Failed to enable hairpin_mode on the bridge port");
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) {
|
||||
+ if (!conf->snoop_iface[0] &&
|
||||
+ hostapd_drv_br_port_set_attr(hapd, DRV_BR_PORT_ATTR_PROXYARP, 1)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"x_snoop: Failed to enable proxyarp on the bridge port");
|
||||
return -1;
|
||||
@@ -52,7 +54,8 @@ int x_snoop_init(struct hostapd_data *ha
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPV6
|
||||
- if (hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) {
|
||||
+ if (!conf->snoop_iface[0] &&
|
||||
+ hostapd_drv_br_set_net_param(hapd, DRV_BR_MULTICAST_SNOOPING, 1)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"x_snoop: Failed to enable multicast snooping on the bridge");
|
||||
return -1;
|
||||
@@ -71,8 +74,12 @@ x_snoop_get_l2_packet(struct hostapd_dat
|
||||
{
|
||||
struct hostapd_bss_config *conf = hapd->conf;
|
||||
struct l2_packet_data *l2;
|
||||
+ const char *ifname = conf->bridge;
|
||||
|
||||
- l2 = l2_packet_init(conf->bridge, NULL, ETH_P_ALL, handler, hapd, 1);
|
||||
+ if (conf->snoop_iface[0])
|
||||
+ ifname = conf->snoop_iface;
|
||||
+
|
||||
+ l2 = l2_packet_init(ifname, NULL, ETH_P_ALL, handler, hapd, 1);
|
||||
if (l2 == NULL) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"x_snoop: Failed to initialize L2 packet processing %s",
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -2407,6 +2407,8 @@ static int hostapd_config_fill(struct ho
|
||||
os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
|
||||
if (!bss->wds_bridge[0])
|
||||
os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
|
||||
+ } else if (os_strcmp(buf, "snoop_iface") == 0) {
|
||||
+ os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface));
|
||||
} else if (os_strcmp(buf, "vlan_bridge") == 0) {
|
||||
os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
|
||||
} else if (os_strcmp(buf, "wds_bridge") == 0) {
|
@ -0,0 +1,112 @@
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -1711,6 +1711,8 @@ static int parse_anqp_elem(struct hostap
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#endif /* CONFIG_INTERWORKING */
|
||||
+
|
||||
|
||||
static int parse_qos_map_set(struct hostapd_bss_config *bss,
|
||||
char *buf, int line)
|
||||
@@ -1752,8 +1754,6 @@ static int parse_qos_map_set(struct host
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#endif /* CONFIG_INTERWORKING */
|
||||
-
|
||||
|
||||
#ifdef CONFIG_HS20
|
||||
static int hs20_parse_conn_capab(struct hostapd_bss_config *bss, char *buf,
|
||||
@@ -4050,10 +4050,10 @@ static int hostapd_config_fill(struct ho
|
||||
bss->gas_frag_limit = val;
|
||||
} else if (os_strcmp(buf, "gas_comeback_delay") == 0) {
|
||||
bss->gas_comeback_delay = atoi(pos);
|
||||
+#endif /* CONFIG_INTERWORKING */
|
||||
} else if (os_strcmp(buf, "qos_map_set") == 0) {
|
||||
if (parse_qos_map_set(bss, pos, line) < 0)
|
||||
return 1;
|
||||
-#endif /* CONFIG_INTERWORKING */
|
||||
#ifdef CONFIG_RADIUS_TEST
|
||||
} else if (os_strcmp(buf, "dump_msk_file") == 0) {
|
||||
os_free(bss->dump_msk_file);
|
||||
--- a/src/ap/hostapd.c
|
||||
+++ b/src/ap/hostapd.c
|
||||
@@ -1386,6 +1386,7 @@ static int hostapd_setup_bss(struct host
|
||||
wpa_printf(MSG_ERROR, "GAS server initialization failed");
|
||||
return -1;
|
||||
}
|
||||
+#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
if (conf->qos_map_set_len &&
|
||||
hostapd_drv_set_qos_map(hapd, conf->qos_map_set,
|
||||
@@ -1393,7 +1394,6 @@ static int hostapd_setup_bss(struct host
|
||||
wpa_printf(MSG_ERROR, "Failed to initialize QoS Map");
|
||||
return -1;
|
||||
}
|
||||
-#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
if (conf->bss_load_update_period && bss_load_update_init(hapd)) {
|
||||
wpa_printf(MSG_ERROR, "BSS Load initialization failed");
|
||||
--- a/src/ap/drv_callbacks.c
|
||||
+++ b/src/ap/drv_callbacks.c
|
||||
@@ -245,12 +245,10 @@ int hostapd_notif_assoc(struct hostapd_d
|
||||
}
|
||||
#endif /* NEED_AP_MLME */
|
||||
|
||||
-#ifdef CONFIG_INTERWORKING
|
||||
if (elems.ext_capab && elems.ext_capab_len > 4) {
|
||||
if (elems.ext_capab[4] & 0x01)
|
||||
sta->qos_map_enabled = 1;
|
||||
}
|
||||
-#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
#ifdef CONFIG_HS20
|
||||
wpabuf_free(sta->hs20_ie);
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -2875,13 +2875,11 @@ static u16 copy_supp_rates(struct hostap
|
||||
static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
const u8 *ext_capab_ie, size_t ext_capab_ie_len)
|
||||
{
|
||||
-#ifdef CONFIG_INTERWORKING
|
||||
/* check for QoS Map support */
|
||||
if (ext_capab_ie_len >= 5) {
|
||||
if (ext_capab_ie[4] & 0x01)
|
||||
sta->qos_map_enabled = 1;
|
||||
}
|
||||
-#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
if (ext_capab_ie_len > 0) {
|
||||
sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2));
|
||||
--- a/wpa_supplicant/events.c
|
||||
+++ b/wpa_supplicant/events.c
|
||||
@@ -2500,8 +2500,6 @@ void wnm_bss_keep_alive_deinit(struct wp
|
||||
}
|
||||
|
||||
|
||||
-#ifdef CONFIG_INTERWORKING
|
||||
-
|
||||
static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map,
|
||||
size_t len)
|
||||
{
|
||||
@@ -2534,8 +2532,6 @@ static void interworking_process_assoc_r
|
||||
}
|
||||
}
|
||||
|
||||
-#endif /* CONFIG_INTERWORKING */
|
||||
-
|
||||
|
||||
static void multi_ap_process_assoc_resp(struct wpa_supplicant *wpa_s,
|
||||
const u8 *ies, size_t ies_len)
|
||||
@@ -2669,10 +2665,8 @@ static int wpa_supplicant_event_associnf
|
||||
wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len);
|
||||
#endif /* CONFIG_WNM */
|
||||
-#ifdef CONFIG_INTERWORKING
|
||||
interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len);
|
||||
-#endif /* CONFIG_INTERWORKING */
|
||||
if (wpa_s->hw_capab == CAPAB_VHT &&
|
||||
get_ie(data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len, WLAN_EID_VHT_CAP))
|
@ -14,11 +14,9 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
src/crypto/crypto_wolfssl.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
|
||||
index 2e4bf8962..ed2528159 100644
|
||||
--- a/src/crypto/crypto_wolfssl.c
|
||||
+++ b/src/crypto/crypto_wolfssl.c
|
||||
@@ -1303,6 +1303,7 @@ int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R,
|
||||
@@ -1303,6 +1303,7 @@ int ecc_projective_add_point(ecc_point *
|
||||
|
||||
struct crypto_ec {
|
||||
ecc_key key;
|
||||
@ -26,7 +24,7 @@ index 2e4bf8962..ed2528159 100644
|
||||
mp_int a;
|
||||
mp_int prime;
|
||||
mp_int order;
|
||||
@@ -1357,6 +1358,8 @@ struct crypto_ec * crypto_ec_init(int group)
|
||||
@@ -1357,6 +1358,8 @@ struct crypto_ec * crypto_ec_init(int gr
|
||||
return NULL;
|
||||
|
||||
if (wc_ecc_init(&e->key) != 0 ||
|
||||
@ -35,7 +33,7 @@ index 2e4bf8962..ed2528159 100644
|
||||
wc_ecc_set_curve(&e->key, 0, curve_id) != 0 ||
|
||||
mp_init(&e->a) != MP_OKAY ||
|
||||
mp_init(&e->prime) != MP_OKAY ||
|
||||
@@ -1388,6 +1391,7 @@ void crypto_ec_deinit(struct crypto_ec* e)
|
||||
@@ -1388,6 +1391,7 @@ void crypto_ec_deinit(struct crypto_ec*
|
||||
mp_clear(&e->order);
|
||||
mp_clear(&e->prime);
|
||||
mp_clear(&e->a);
|
||||
@ -43,6 +41,3 @@ index 2e4bf8962..ed2528159 100644
|
||||
wc_ecc_free(&e->key);
|
||||
os_free(e);
|
||||
}
|
||||
--
|
||||
2.31.1
|
||||
|
||||
|
@ -20,27 +20,50 @@
|
||||
*
|
||||
* @NL80211_CMD_SET_MULTICAST_TO_UNICAST: Configure if this AP should perform
|
||||
* multicast to unicast conversion. When enabled, all multicast packets
|
||||
@@ -1177,6 +1181,10 @@
|
||||
@@ -1177,6 +1181,25 @@
|
||||
* includes the contents of the frame. %NL80211_ATTR_ACK flag is included
|
||||
* if the recipient acknowledged the frame.
|
||||
*
|
||||
+ * @NL80211_CMD_SET_SAR_SPECS: SAR power limitation configuration is
|
||||
+ * passed using %NL80211_ATTR_SAR_SPEC. %NL80211_ATTR_WIPHY is used to
|
||||
+ * specify the wiphy index to be applied to.
|
||||
+ *
|
||||
+ * @NL80211_CMD_OBSS_COLOR_COLLISION: This notification is sent out whenever
|
||||
+ * mac80211/drv detects a bss color collision.
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_REQUEST: This command is used to indicate that
|
||||
+ * userspace wants to change the BSS color.
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_STARTED: Notify userland, that a color change has
|
||||
+ * started
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_ABORTED: Notify userland, that the color change has
|
||||
+ * been aborted
|
||||
+ *
|
||||
+ * @NL80211_CMD_COLOR_CHANGE_COMPLETED: Notify userland that the color change
|
||||
+ * has completed
|
||||
+ *
|
||||
* @NL80211_CMD_MAX: highest used command number
|
||||
* @__NL80211_CMD_AFTER_LAST: internal use
|
||||
*/
|
||||
@@ -1407,6 +1415,8 @@ enum nl80211_commands {
|
||||
@@ -1407,6 +1430,16 @@ enum nl80211_commands {
|
||||
|
||||
NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS,
|
||||
|
||||
+ NL80211_CMD_SET_SAR_SPECS,
|
||||
+
|
||||
+ NL80211_CMD_OBSS_COLOR_COLLISION,
|
||||
+
|
||||
+ NL80211_CMD_COLOR_CHANGE_REQUEST,
|
||||
+
|
||||
+ NL80211_CMD_COLOR_CHANGE_STARTED,
|
||||
+ NL80211_CMD_COLOR_CHANGE_ABORTED,
|
||||
+ NL80211_CMD_COLOR_CHANGE_COMPLETED,
|
||||
+
|
||||
/* add new commands above here */
|
||||
|
||||
/* used to define NL80211_CMD_MAX below */
|
||||
@@ -1750,8 +1760,9 @@ enum nl80211_commands {
|
||||
@@ -1750,8 +1783,9 @@ enum nl80211_commands {
|
||||
* specify just a single bitrate, which is to be used for the beacon.
|
||||
* The driver must also specify support for this with the extended
|
||||
* features NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
|
||||
@ -52,7 +75,7 @@
|
||||
*
|
||||
* @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain
|
||||
* at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME.
|
||||
@@ -1955,8 +1966,15 @@ enum nl80211_commands {
|
||||
@@ -1955,8 +1989,15 @@ enum nl80211_commands {
|
||||
* @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire
|
||||
* probe-response frame. The DA field in the 802.11 header is zero-ed out,
|
||||
* to be filled by the FW.
|
||||
@ -70,7 +93,7 @@
|
||||
* @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the
|
||||
* ATTR_HT_CAPABILITY to which attention should be paid.
|
||||
* Currently, only mac80211 NICs support this feature.
|
||||
@@ -2077,7 +2095,8 @@ enum nl80211_commands {
|
||||
@@ -2077,7 +2118,8 @@ enum nl80211_commands {
|
||||
* until the channel switch event.
|
||||
* @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission
|
||||
* must be blocked on the current channel (before the channel switch
|
||||
@ -80,7 +103,7 @@
|
||||
* @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
|
||||
* for the time while performing a channel switch.
|
||||
* @NL80211_ATTR_CNTDWN_OFFS_BEACON: An array of offsets (u16) to the channel
|
||||
@@ -2527,6 +2546,23 @@ enum nl80211_commands {
|
||||
@@ -2527,6 +2569,33 @@ enum nl80211_commands {
|
||||
* override mask. Used with NL80211_ATTR_S1G_CAPABILITY in
|
||||
* NL80211_CMD_ASSOCIATE or NL80211_CMD_CONNECT.
|
||||
*
|
||||
@ -98,13 +121,23 @@
|
||||
+ * disassoc events to indicate that an immediate reconnect to the AP
|
||||
+ * is desired.
|
||||
+ *
|
||||
+ * @NL80211_ATTR_OBSS_COLOR_BITMAP: bitmap of the u64 BSS colors for the
|
||||
+ * %NL80211_CMD_OBSS_COLOR_COLLISION event.
|
||||
+ *
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_COUNT: u8 attribute specifying the number of TBTT's
|
||||
+ * until the color switch event.
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_COLOR: u8 attribute specifying the color that we are
|
||||
+ * switching to
|
||||
+ * @NL80211_ATTR_COLOR_CHANGE_ELEMS: Nested set of attributes containing the IE
|
||||
+ * information for the time while performing a color switch.
|
||||
+ *
|
||||
+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
|
||||
+ * transmit power to stay within regulatory limits. u32, dBi.
|
||||
+ *
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@@ -3016,6 +3052,16 @@ enum nl80211_attrs {
|
||||
@@ -3016,6 +3085,22 @@ enum nl80211_attrs {
|
||||
NL80211_ATTR_S1G_CAPABILITY,
|
||||
NL80211_ATTR_S1G_CAPABILITY_MASK,
|
||||
|
||||
@ -116,12 +149,18 @@
|
||||
+
|
||||
+ NL80211_ATTR_DISABLE_HE,
|
||||
+
|
||||
+ NL80211_ATTR_OBSS_COLOR_BITMAP,
|
||||
+
|
||||
+ NL80211_ATTR_COLOR_CHANGE_COUNT,
|
||||
+ NL80211_ATTR_COLOR_CHANGE_COLOR,
|
||||
+ NL80211_ATTR_COLOR_CHANGE_ELEMS,
|
||||
+
|
||||
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
|
||||
+
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
@@ -5896,6 +5942,19 @@ enum nl80211_feature_flags {
|
||||
@@ -5896,6 +5981,22 @@ enum nl80211_feature_flags {
|
||||
* @NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP: Driver/device supports
|
||||
* unsolicited broadcast probe response transmission
|
||||
*
|
||||
@ -137,11 +176,14 @@
|
||||
+ * @NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE: Device supports management
|
||||
+ * frame protection for all management frames exchanged during the
|
||||
+ * negotiation and range measurement procedure.
|
||||
+ *
|
||||
+ * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision
|
||||
+ * detection and change announcemnts.
|
||||
+ *
|
||||
* @NUM_NL80211_EXT_FEATURES: number of extended features.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
|
||||
*/
|
||||
@@ -5956,6 +6015,10 @@ enum nl80211_ext_feature_index {
|
||||
@@ -5956,6 +6057,11 @@ enum nl80211_ext_feature_index {
|
||||
NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
|
||||
NL80211_EXT_FEATURE_FILS_DISCOVERY,
|
||||
NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
|
||||
@ -149,10 +191,11 @@
|
||||
+ NL80211_EXT_FEATURE_SECURE_LTF,
|
||||
+ NL80211_EXT_FEATURE_SECURE_RTT,
|
||||
+ NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
|
||||
+ NL80211_EXT_FEATURE_BSS_COLOR,
|
||||
|
||||
/* add new features before the definition below */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
@@ -6253,11 +6316,13 @@ struct nl80211_vendor_cmd_info {
|
||||
@@ -6253,11 +6359,13 @@ struct nl80211_vendor_cmd_info {
|
||||
* @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
|
||||
* @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
|
||||
* @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
|
||||
@ -166,7 +209,7 @@
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -6849,6 +6914,9 @@ enum nl80211_peer_measurement_ftm_capa {
|
||||
@@ -6849,6 +6957,9 @@ enum nl80211_peer_measurement_ftm_capa {
|
||||
* if neither %NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED nor
|
||||
* %NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED is set, EDCA based
|
||||
* ranging will be used.
|
||||
@ -176,7 +219,7 @@
|
||||
*
|
||||
* @NUM_NL80211_PMSR_FTM_REQ_ATTR: internal
|
||||
* @NL80211_PMSR_FTM_REQ_ATTR_MAX: highest attribute number
|
||||
@@ -6867,6 +6935,7 @@ enum nl80211_peer_measurement_ftm_req {
|
||||
@@ -6867,6 +6978,7 @@ enum nl80211_peer_measurement_ftm_req {
|
||||
NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC,
|
||||
NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED,
|
||||
NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED,
|
||||
@ -184,7 +227,7 @@
|
||||
|
||||
/* keep last */
|
||||
NUM_NL80211_PMSR_FTM_REQ_ATTR,
|
||||
@@ -7124,4 +7193,115 @@ enum nl80211_unsol_bcast_probe_resp_attr
|
||||
@@ -7124,4 +7236,115 @@ enum nl80211_unsol_bcast_probe_resp_attr
|
||||
NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX =
|
||||
__NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_LAST - 1
|
||||
};
|
||||
|
@ -187,23 +187,29 @@
|
||||
};
|
||||
|
||||
static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data,
|
||||
@@ -2326,6 +2331,7 @@ void print_ies(unsigned char *ie, int ie
|
||||
ieprinters[ie[0]].flags & BIT(ptype)) {
|
||||
print_ie(&ieprinters[ie[0]],
|
||||
ie[0], ie[1], ie + 2, &ie_buffer);
|
||||
@@ -2080,8 +2085,10 @@ static void print_wifi_wps(const uint8_t
|
||||
|
||||
static const struct ie_print wifiprinters[] = {
|
||||
[1] = { "WPA", print_wifi_wpa, 2, 255, BIT(PRINT_SCAN), },
|
||||
+#ifdef IW_FULL
|
||||
} else if (ie[0] == 221 /* vendor */) {
|
||||
print_vendor(ie[1], ie + 2, unknown, ptype);
|
||||
} else if (ie[0] == 255 /* extension */) {
|
||||
@@ -2337,6 +2343,7 @@ void print_ies(unsigned char *ie, int ie
|
||||
for (i=0; i<ie[1]; i++)
|
||||
printf(" %.2x", ie[2+i]);
|
||||
printf("\n");
|
||||
[2] = { "WMM", print_wifi_wmm, 1, 255, BIT(PRINT_SCAN), },
|
||||
[4] = { "WPS", print_wifi_wps, 0, 255, BIT(PRINT_SCAN), },
|
||||
+#endif
|
||||
}
|
||||
ielen -= ie[1] + 2;
|
||||
ie += ie[1] + 2;
|
||||
@@ -2377,6 +2384,7 @@ static void print_capa_non_dmg(__u16 cap
|
||||
};
|
||||
|
||||
static inline void print_p2p(const uint8_t type, uint8_t len,
|
||||
@@ -2244,6 +2251,10 @@ static void print_vendor(unsigned char l
|
||||
return;
|
||||
}
|
||||
|
||||
+#ifdef IW_FULL
|
||||
+ return;
|
||||
+#endif
|
||||
+
|
||||
if (len >= 4 && memcmp(data, wfa_oui, 3) == 0) {
|
||||
if (data[3] < ARRAY_SIZE(wfa_printers) &&
|
||||
wfa_printers[data[3]].name &&
|
||||
@@ -2377,6 +2388,7 @@ static void print_capa_non_dmg(__u16 cap
|
||||
printf(" ESS");
|
||||
if (capa & WLAN_CAPABILITY_IBSS)
|
||||
printf(" IBSS");
|
||||
@ -211,7 +217,7 @@
|
||||
if (capa & WLAN_CAPABILITY_CF_POLLABLE)
|
||||
printf(" CfPollable");
|
||||
if (capa & WLAN_CAPABILITY_CF_POLL_REQUEST)
|
||||
@@ -2405,6 +2413,7 @@ static void print_capa_non_dmg(__u16 cap
|
||||
@@ -2405,6 +2417,7 @@ static void print_capa_non_dmg(__u16 cap
|
||||
printf(" DelayedBACK");
|
||||
if (capa & WLAN_CAPABILITY_IMM_BACK)
|
||||
printf(" ImmediateBACK");
|
||||
@ -219,7 +225,7 @@
|
||||
}
|
||||
|
||||
static int print_bss_handler(struct nl_msg *msg, void *arg)
|
||||
@@ -2489,8 +2498,10 @@ static int print_bss_handler(struct nl_m
|
||||
@@ -2489,8 +2502,10 @@ static int print_bss_handler(struct nl_m
|
||||
if (bss[NL80211_BSS_FREQUENCY]) {
|
||||
int freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
|
||||
printf("\tfreq: %d\n", freq);
|
||||
@ -230,7 +236,7 @@
|
||||
}
|
||||
if (bss[NL80211_BSS_BEACON_INTERVAL])
|
||||
printf("\tbeacon interval: %d TUs\n",
|
||||
@@ -2684,6 +2695,7 @@ static int handle_stop_sched_scan(struct
|
||||
@@ -2684,6 +2699,7 @@ static int handle_stop_sched_scan(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -238,7 +244,7 @@
|
||||
COMMAND(scan, sched_start,
|
||||
SCHED_SCAN_OPTIONS,
|
||||
NL80211_CMD_START_SCHED_SCAN, 0, CIB_NETDEV, handle_start_sched_scan,
|
||||
@@ -2694,3 +2706,4 @@ COMMAND(scan, sched_start,
|
||||
@@ -2694,3 +2710,4 @@ COMMAND(scan, sched_start,
|
||||
COMMAND(scan, sched_stop, "",
|
||||
NL80211_CMD_STOP_SCHED_SCAN, 0, CIB_NETDEV, handle_stop_sched_scan,
|
||||
"Stop an ongoing scheduled scan.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user