diff --git a/include/image-commands.mk b/include/image-commands.mk index 6fe2890a1a..6b4bc4945c 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -4,7 +4,7 @@ IMAGE_KERNEL = $(word 1,$^) IMAGE_ROOTFS = $(word 2,$^) define ModelNameLimit16 -$(shell expr substr "$(word 2, $(subst _, ,$(1)))" 1 16) +$(shell printf %.16s "$(word 2, $(subst _, ,$(1)))") endef define rootfs_align diff --git a/package/base-files/files/lib/functions/system.sh b/package/base-files/files/lib/functions/system.sh index 22eb00c515..29de2e5dd6 100644 --- a/package/base-files/files/lib/functions/system.sh +++ b/package/base-files/files/lib/functions/system.sh @@ -283,3 +283,7 @@ macaddr_canonicalize() { printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${canon// / 0x} 2>/dev/null } + +dt_is_enabled() { + grep -q okay "/proc/device-tree/$1/status" +} diff --git a/package/base-files/files/lib/functions/uci-defaults.sh b/package/base-files/files/lib/functions/uci-defaults.sh index 86f16b5125..a37e8cf824 100644 --- a/package/base-files/files/lib/functions/uci-defaults.sh +++ b/package/base-files/files/lib/functions/uci-defaults.sh @@ -646,6 +646,21 @@ ucidef_set_ntpserver() { json_select .. } +ucidef_add_wlan() { + local path="$1"; shift + + ucidef_wlan_idx=${ucidef_wlan_idx:-0} + + json_select_object wlan + json_select_object "wl$ucidef_wlan_idx" + json_add_string path "$path" + json_add_fields "$@" + json_select .. + json_select .. + + ucidef_wlan_idx="$((ucidef_wlan_idx + 1))" +} + board_config_update() { json_init [ -f ${CFG} ] && json_load "$(cat ${CFG})" diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index 8d10158140..638967b837 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -51,6 +51,8 @@ drv_mac80211_init_device_config() { rx_antenna_pattern \ tx_antenna_pattern \ he_spr_sr_control \ + he_spr_psr_enabled \ + he_bss_color_enabled \ he_twt_required config_add_int \ beamformer_antennas \ @@ -414,12 +416,14 @@ mac80211_hostapd_setup_base() { if [ "$enable_ax" != "0" ]; then json_get_vars \ he_su_beamformer:1 \ - he_su_beamformee:0 \ + he_su_beamformee:1 \ 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_spr_sr_control:3 \ + he_spr_psr_enabled:0 \ + he_spr_non_srg_obss_pd_max_offset:0 \ + he_bss_color:128 \ + he_bss_color_enabled:1 he_phy_cap=$(iw phy "$phy" info | sed -n '/HE Iftypes: AP/,$p' | awk -F "[()]" '/HE PHY Capabilities/ { print $2 }' | head -1) he_phy_cap=${he_phy_cap:2} @@ -432,17 +436,25 @@ mac80211_hostapd_setup_base() { append base_cfg "he_oper_centr_freq_seg0_idx=$vht_center_seg0" "$N" } - set_default he_bss_color 128 - append base_cfg "he_bss_color=$he_bss_color" "$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_spr_psr_enabled:${he_phy_cap:14:2}:0x1:$he_spr_psr_enabled \ 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" + if [ "$he_bss_color_enabled" -gt 0 ]; then + append base_cfg "he_bss_color=$he_bss_color" "$N" + [ "$he_spr_non_srg_obss_pd_max_offset" -gt 0 ] && { \ + append base_cfg "he_spr_non_srg_obss_pd_max_offset=$he_spr_non_srg_obss_pd_max_offset" "$N" + he_spr_sr_control=$((he_spr_sr_control | (1 << 2))) + } + [ "$he_spr_psr_enabled" -gt 0 ] || he_spr_sr_control=$((he_spr_sr_control | (1 << 0))) + append base_cfg "he_spr_sr_control=$he_spr_sr_control" "$N" + else + append base_cfg "he_bss_color_disabled=1" "$N" + fi + append base_cfg "he_default_pe_duration=4" "$N" append base_cfg "he_rts_threshold=1023" "$N" @@ -569,15 +581,77 @@ mac80211_generate_mac() { $(( (0x$6 + $id) % 0x100 )) } +get_board_phy_name() ( + local path="$1" + local fallback_phy="" + + __check_phy() { + local val="$1" + local key="$2" + local ref_path="$3" + + json_select "$key" + json_get_values path + json_select .. + + [ "${ref_path%+*}" = "$path" ] && fallback_phy=$key + [ "$ref_path" = "$path" ] || return 0 + + echo "$key" + exit + } + + json_load_file /etc/board.json + json_for_each_item __check_phy wlan "$path" + [ -n "$fallback_phy" ] && echo "${fallback_phy}.${path##*+}" +) + +rename_board_phy_by_path() { + local path="$1" + + local new_phy="$(get_board_phy_name "$path")" + [ -z "$new_phy" -o "$new_phy" = "$phy" ] && return + + iw "$phy" set name "$new_phy" && phy="$new_phy" +} + +rename_board_phy_by_name() ( + local phy="$1" + local suffix="${phy##*.}" + [ "$suffix" = "$phy" ] && suffix= + + json_load_file /etc/board.json + json_select wlan + json_select "${phy%.*}" || return 0 + json_get_values path + + prev_phy="$(iwinfo nl80211 phyname "path=$path${suffix:++$suffix}")" + [ -n "$prev_phy" ] || return 0 + + [ "$prev_phy" = "$phy" ] && return 0 + + iw "$prev_phy" set name "$phy" +) + find_phy() { - [ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0 + [ -n "$phy" ] && { + rename_board_phy_by_name "$phy" + [ -d /sys/class/ieee80211/$phy ] && return 0 + } [ -n "$path" ] && { phy="$(iwinfo nl80211 phyname "path=$path")" - [ -n "$phy" ] && return 0 + [ -n "$phy" ] && { + rename_board_phy_by_path "$path" + return 0 + } } [ -n "$macaddr" ] && { for phy in $(ls /sys/class/ieee80211 2>/dev/null); do - grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && return 0 + grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && { + path="$(iwinfo nl80211 path "$phy")" + rename_board_phy_by_path "$path" + return 0 + } done } return 1 @@ -655,13 +729,28 @@ mac80211_iw_interface_add() { return $rc } +mac80211_set_ifname() { + local phy="$1" + local prefix="$2" + eval "ifname=\"$phy-$prefix\${idx_$prefix:-0}\"; idx_$prefix=\$((\${idx_$prefix:-0 } + 1))" +} + mac80211_prepare_vif() { json_select config json_get_vars ifname mode ssid wds powersave macaddr enable wpa_psk_file vlan_file - [ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}" - if_idx=$((${if_idx:-0} + 1)) + [ -n "$ifname" ] || { + local prefix; + + case "$mode" in + ap|sta|mesh) prefix=$mode;; + adhoc) prefix=ibss;; + monitor) prefix=mon;; + esac + + mac80211_set_ifname "$phy" "$prefix" + } set_default wds 0 set_default powersave 0 diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh index 656a05b1f7..6e8b60aded 100644 --- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh +++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh @@ -2,60 +2,48 @@ append DRIVERS "mac80211" -lookup_phy() { - [ -n "$phy" ] && { - [ -d /sys/class/ieee80211/$phy ] && return - } - - local devpath - config_get devpath "$device" path - [ -n "$devpath" ] && { - phy="$(iwinfo nl80211 phyname "path=$devpath")" - [ -n "$phy" ] && return - } - - local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')" - [ -n "$macaddr" ] && { - for _phy in /sys/class/ieee80211/*; do - [ -e "$_phy" ] || continue - - [ "$macaddr" = "$(cat ${_phy}/macaddress)" ] || continue - phy="${_phy##*/}" - return - done - } - phy= - return -} - -find_mac80211_phy() { +check_mac80211_device() { local device="$1" + local path="$2" + local macaddr="$3" + [ -n "$found" ] && return 0 + + phy_path= config_get phy "$device" phy - lookup_phy - [ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || { - echo "PHY for wifi device $1 not found" - return 1 + json_select wlan + [ -n "$phy" ] && case "$phy" in + phy*) + [ -d /sys/class/ieee80211/$phy ] && \ + phy_path="$(iwinfo nl80211 path "$dev")" + ;; + *) + if json_is_a "$phy" object; then + json_select "$phy" + json_get_var phy_path path + json_select .. + elif json_is_a "${phy%.*}" object; then + json_select "${phy%.*}" + json_get_var phy_path path + json_select .. + phy_path="$phy_path+${phy##*.}" + fi + ;; + esac + json_select .. + [ -n "$phy_path" ] || config_get phy_path "$device" path + [ -n "$path" -a "$phy_path" = "$path" ] && { + found=1 + return 0 } - config_set "$device" phy "$phy" - config_get macaddr "$device" macaddr - [ -z "$macaddr" ] && { - config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)" - } + config_get dev_macaddr "$device" macaddr + + [ -n "$macaddr" -a "$dev_macaddr" = "$macaddr" ] && found=1 return 0 } -check_mac80211_device() { - config_get phy "$1" phy - [ -z "$phy" ] && { - find_mac80211_phy "$1" >/dev/null || return 0 - config_get phy "$1" phy - } - [ "$phy" = "$dev" ] && found=1 -} - __get_band_defaults() { local phy="$1" @@ -135,24 +123,41 @@ get_band_defaults() { done } +check_devidx() { + case "$1" in + radio[0-9]*) + local idx="${1#radio}" + [ "$devidx" -ge "${1#radio}" ] && devidx=$((idx + 1)) + ;; + esac +} + +check_board_phy() { + local name="$2" + + json_select "$name" + json_get_var phy_path path + json_select .. + + if [ "$path" = "$phy_path" ]; then + board_dev="$name" + elif [ "${path%+*}" = "$phy_path" ]; then + fallback_board_dev="$name.${path#*+}" + fi +} + detect_mac80211() { devidx=0 config_load wireless - while :; do - config_get type "radio$devidx" type - [ -n "$type" ] || break - devidx=$(($devidx + 1)) - done + config_foreach check_devidx wifi-device + + json_load_file /etc/board.json for _dev in /sys/class/ieee80211/*; do [ -e "$_dev" ] || continue dev="${_dev##*/}" - found=0 - config_foreach check_mac80211_device wifi-device - [ "$found" -gt 0 ] && continue - mode_band="" channel="" htmode="" @@ -161,32 +166,50 @@ detect_mac80211() { get_band_defaults "$dev" path="$(iwinfo nl80211 path "$dev")" - if [ -n "$path" ]; then - dev_id="set wireless.radio${devidx}.path='$path'" - else - dev_id="set wireless.radio${devidx}.macaddr=$(cat /sys/class/ieee80211/${dev}/macaddress)" - fi + macaddr="$(cat /sys/class/ieee80211/${dev}/macaddress)" + board_dev= + fallback_board_dev= + json_for_each_item check_board_phy wlan + [ -n "$board_dev" ] || board_dev="$fallback_board_dev" + [ -n "$board_dev" ] && dev="$board_dev" + + found= + config_foreach check_mac80211_device wifi-device "$path" "$macaddr" + [ -n "$found" ] && continue + + name="radio${devidx}" + devidx=$(($devidx + 1)) + case "$dev" in + phy*) + if [ -n "$path" ]; then + dev_id="set wireless.${name}.path='$path'" + else + dev_id="set wireless.${name}.macaddr='$macaddr'" + fi + ;; + *) + dev_id="set wireless.${name}.phy='$dev'" + ;; + esac uci -q batch <<-EOF - set wireless.radio${devidx}=wifi-device - set wireless.radio${devidx}.type=mac80211 + set wireless.${name}=wifi-device + set wireless.${name}.type=mac80211 ${dev_id} - set wireless.radio${devidx}.channel=${channel} - set wireless.radio${devidx}.band=${mode_band} - set wireless.radio${devidx}.htmode=$htmode - set wireless.radio${devidx}.country=US - set wireless.radio${devidx}.disabled=0 +< set wireless.${name}.channel=${channel} + set wireless.${name}.band=${mode_band} + set wireless.${name}.htmode=$htmode + set wireless.${name}.country=US + set wireless.${name}.disabled=0 - set wireless.default_radio${devidx}=wifi-iface - set wireless.default_radio${devidx}.device=radio${devidx} - set wireless.default_radio${devidx}.network=lan - set wireless.default_radio${devidx}.mode=ap - set wireless.default_radio${devidx}.ssid=OpenWrt - set wireless.default_radio${devidx}.encryption=none - set wireless.default_radio${devidx}.iw_qos_map_set=none + set wireless.default_${name}=wifi-iface + set wireless.default_${name}.device=${name} + set wireless.default_${name}.network=lan + set wireless.default_${name}.mode=ap + set wireless.default_${name}.ssid=OpenWrt + set wireless.default_${name}.encryption=none + set wireless.default_${name}.iw_qos_map_set=none EOF uci -q commit wireless - - devidx=$(($devidx + 1)) done } diff --git a/package/kernel/mac80211/patches/subsys/346-mac80211-mesh-clean-up-rx_bcn_presp-API.patch b/package/kernel/mac80211/patches/subsys/346-mac80211-mesh-clean-up-rx_bcn_presp-API.patch new file mode 100644 index 0000000000..3fa70b05fd --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/346-mac80211-mesh-clean-up-rx_bcn_presp-API.patch @@ -0,0 +1,110 @@ +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:07 +0200 +Subject: [PATCH] mac80211: mesh: clean up rx_bcn_presp API + +commit a5b983c6073140b624f64e79fea6d33c3e4315a0 upstream. + +We currently pass the entire elements to the rx_bcn_presp() +method, but only need mesh_config. Additionally, we use the +length of the elements to calculate back the entire frame's +length, but that's confusing - just pass the length of the +frame instead. + +Link: https://lore.kernel.org/r/20210920154009.a18ed3d2da6c.I1824b773a0fbae4453e1433c184678ca14e8df45@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -645,10 +645,9 @@ struct ieee80211_if_ocb { + */ + struct ieee802_11_elems; + struct ieee80211_mesh_sync_ops { +- void (*rx_bcn_presp)(struct ieee80211_sub_if_data *sdata, +- u16 stype, +- struct ieee80211_mgmt *mgmt, +- struct ieee802_11_elems *elems, ++ void (*rx_bcn_presp)(struct ieee80211_sub_if_data *sdata, u16 stype, ++ struct ieee80211_mgmt *mgmt, unsigned int len, ++ const struct ieee80211_meshconf_ie *mesh_cfg, + struct ieee80211_rx_status *rx_status); + + /* should be called with beacon_data under RCU read lock */ +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -1354,8 +1354,8 @@ static void ieee80211_mesh_rx_bcn_presp( + } + + if (ifmsh->sync_ops) +- ifmsh->sync_ops->rx_bcn_presp(sdata, +- stype, mgmt, &elems, rx_status); ++ ifmsh->sync_ops->rx_bcn_presp(sdata, stype, mgmt, len, ++ elems.mesh_config, rx_status); + } + + int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) +--- a/net/mac80211/mesh_sync.c ++++ b/net/mac80211/mesh_sync.c +@@ -3,6 +3,7 @@ + * Copyright 2011-2012, Pavel Zubarev + * Copyright 2011-2012, Marco Porsch + * Copyright 2011-2012, cozybit Inc. ++ * Copyright (C) 2021 Intel Corporation + */ + + #include "ieee80211_i.h" +@@ -35,12 +36,12 @@ struct sync_method { + /** + * mesh_peer_tbtt_adjusting - check if an mp is currently adjusting its TBTT + * +- * @ie: information elements of a management frame from the mesh peer ++ * @cfg: mesh config element from the mesh peer (or %NULL) + */ +-static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie) ++static bool mesh_peer_tbtt_adjusting(const struct ieee80211_meshconf_ie *cfg) + { +- return (ie->mesh_config->meshconf_cap & +- IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0; ++ return cfg && ++ (cfg->meshconf_cap & IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING); + } + + void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata) +@@ -76,11 +77,11 @@ void mesh_sync_adjust_tsf(struct ieee802 + } + } + +-static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, +- u16 stype, +- struct ieee80211_mgmt *mgmt, +- struct ieee802_11_elems *elems, +- struct ieee80211_rx_status *rx_status) ++static void ++mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, u16 stype, ++ struct ieee80211_mgmt *mgmt, unsigned int len, ++ const struct ieee80211_meshconf_ie *mesh_cfg, ++ struct ieee80211_rx_status *rx_status) + { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; + struct ieee80211_local *local = sdata->local; +@@ -101,10 +102,7 @@ static void mesh_sync_offset_rx_bcn_pres + */ + if (ieee80211_have_rx_timestamp(rx_status)) + t_r = ieee80211_calculate_rx_timestamp(local, rx_status, +- 24 + 12 + +- elems->total_len + +- FCS_LEN, +- 24); ++ len + FCS_LEN, 24); + else + t_r = drv_get_tsf(local, sdata); + +@@ -119,7 +117,7 @@ static void mesh_sync_offset_rx_bcn_pres + * dot11MeshNbrOffsetMaxNeighbor non-peer non-MBSS neighbors + */ + +- if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { ++ if (mesh_peer_tbtt_adjusting(mesh_cfg)) { + msync_dbg(sdata, "STA %pM : is adjusting TBTT\n", + sta->sta.addr); + goto no_sync; diff --git a/package/kernel/mac80211/patches/subsys/347-mac80211-move-CRC-into-struct-ieee802_11_elems.patch b/package/kernel/mac80211/patches/subsys/347-mac80211-move-CRC-into-struct-ieee802_11_elems.patch new file mode 100644 index 0000000000..e44aac5cba --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/347-mac80211-move-CRC-into-struct-ieee802_11_elems.patch @@ -0,0 +1,82 @@ +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:08 +0200 +Subject: [PATCH] mac80211: move CRC into struct ieee802_11_elems + +commit c6e37ed498f958254b5459253199e816b6bfc52f upstream. + +We're currently returning this value, but to prepare for +returning the allocated structure, move it into there. + +Link: https://lore.kernel.org/r/20210920154009.479b8ebf999d.If0d4ba75ee38998dc3eeae25058aa748efcb2fc9@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1530,6 +1530,7 @@ struct ieee80211_csa_ie { + struct ieee802_11_elems { + const u8 *ie_start; + size_t total_len; ++ u32 crc; + + /* pointers to IEs */ + const struct ieee80211_tdls_lnkie *lnk_id; +@@ -2089,10 +2090,10 @@ static inline void ieee80211_tx_skb(stru + ieee80211_tx_skb_tid(sdata, skb, 7); + } + +-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, +- u8 *bss_bssid); ++void 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, ++ u8 *bss_bssid); + static inline void ieee802_11_parse_elems(const u8 *start, size_t len, + bool action, + struct ieee802_11_elems *elems, +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -4102,10 +4102,11 @@ static void ieee80211_rx_mgmt_beacon(str + */ + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) + ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); +- ncrc = ieee802_11_parse_elems_crc(variable, +- len - baselen, false, &elems, +- care_about_ies, ncrc, +- mgmt->bssid, bssid); ++ ieee802_11_parse_elems_crc(variable, ++ len - baselen, false, &elems, ++ care_about_ies, ncrc, ++ mgmt->bssid, bssid); ++ ncrc = elems.crc; + + if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) && + ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) { +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1469,10 +1469,10 @@ static size_t ieee802_11_find_bssid_prof + return found ? profile_len : 0; + } + +-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, +- u8 *bss_bssid) ++void 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, ++ u8 *bss_bssid) + { + const struct element *non_inherit = NULL; + u8 *nontransmitted_profile; +@@ -1524,7 +1524,7 @@ u32 ieee802_11_parse_elems_crc(const u8 + + kfree(nontransmitted_profile); + +- return crc; ++ elems->crc = crc; + } + + void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/subsys/348-mac80211-mlme-find-auth-challenge-directly.patch b/package/kernel/mac80211/patches/subsys/348-mac80211-mlme-find-auth-challenge-directly.patch new file mode 100644 index 0000000000..3432c25a91 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/348-mac80211-mlme-find-auth-challenge-directly.patch @@ -0,0 +1,80 @@ +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:09 +0200 +Subject: [PATCH] mac80211: mlme: find auth challenge directly + +commit 49a765d6785e99157ff5091cc37485732496864e upstream. + +There's no need to parse all elements etc. just to find the +authentication challenge - use cfg80211_find_elem() instead. +This also allows us to remove WLAN_EID_CHALLENGE handling +from the element parsing entirely. + +Link: https://lore.kernel.org/r/20210920154009.45f9b3a15722.Ice3159ffad03a007d6154cbf1fb3a8c48489e86f@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1540,7 +1540,6 @@ struct ieee802_11_elems { + const u8 *supp_rates; + const u8 *ds_params; + const struct ieee80211_tim_ie *tim; +- const u8 *challenge; + const u8 *rsn; + const u8 *rsnx; + const u8 *erp_info; +@@ -1594,7 +1593,6 @@ struct ieee802_11_elems { + u8 ssid_len; + u8 supp_rates_len; + u8 tim_len; +- u8 challenge_len; + u8 rsn_len; + u8 rsnx_len; + u8 ext_supp_rates_len; +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -2889,17 +2889,17 @@ static void ieee80211_auth_challenge(str + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data; ++ const struct element *challenge; + u8 *pos; +- struct ieee802_11_elems elems; + u32 tx_flags = 0; + struct ieee80211_prep_tx_info info = { + .subtype = IEEE80211_STYPE_AUTH, + }; + + pos = mgmt->u.auth.variable; +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems, +- mgmt->bssid, auth_data->bss->bssid); +- if (!elems.challenge) ++ challenge = cfg80211_find_elem(WLAN_EID_CHALLENGE, pos, ++ len - (pos - (u8 *)mgmt)); ++ if (!challenge) + return; + auth_data->expected_transaction = 4; + drv_mgd_prepare_tx(sdata->local, sdata, &info); +@@ -2907,7 +2907,8 @@ static void ieee80211_auth_challenge(str + tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | + IEEE80211_TX_INTFL_MLME_CONN_TX; + ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0, +- elems.challenge - 2, elems.challenge_len + 2, ++ (void *)challenge, ++ challenge->datalen + sizeof(*challenge), + auth_data->bss->bssid, auth_data->bss->bssid, + auth_data->key, auth_data->key_len, + auth_data->key_idx, tx_flags); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1120,10 +1120,6 @@ _ieee802_11_parse_elems_crc(const u8 *st + } else + elem_parse_failed = true; + break; +- case WLAN_EID_CHALLENGE: +- elems->challenge = pos; +- elems->challenge_len = elen; +- break; + case WLAN_EID_VENDOR_SPECIFIC: + if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && + pos[2] == 0xf2) { diff --git a/package/kernel/mac80211/patches/subsys/349-mac80211-always-allocate-struct-ieee802_11_elems.patch b/package/kernel/mac80211/patches/subsys/349-mac80211-always-allocate-struct-ieee802_11_elems.patch new file mode 100644 index 0000000000..75655279a9 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/349-mac80211-always-allocate-struct-ieee802_11_elems.patch @@ -0,0 +1,1143 @@ +From: Johannes Berg +Date: Mon, 20 Sep 2021 15:40:10 +0200 +Subject: [PATCH] mac80211: always allocate struct ieee802_11_elems + +As the 802.11 spec evolves, we need to parse more and more +elements. This is causing the struct to grow, and we can no +longer get away with putting it on the stack. + +Change the API to always dynamically allocate and return an +allocated pointer that must be kfree()d later. + +As an alternative, I contemplated a scheme whereby we'd say +in the code which elements we needed, e.g. + + DECLARE_ELEMENT_PARSER(elems, + SUPPORTED_CHANNELS, + CHANNEL_SWITCH, + EXT(KEY_DELIVERY)); + + ieee802_11_parse_elems(..., &elems, ...); + +and while I think this is possible and will save us a lot +since most individual places only care about a small subset +of the elements, it ended up being a bit more work since a +lot of places do the parsing and then pass the struct to +other functions, sometimes with multiple levels. + +Link: https://lore.kernel.org/r/20210920154009.26caff6b5998.I05ae58768e990e611aee8eca8abefd9d7bc15e05@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -478,7 +478,7 @@ void ieee80211_process_addba_request(str + size_t len) + { + u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num; +- struct ieee802_11_elems elems = { }; ++ struct ieee802_11_elems *elems = NULL; + u8 dialog_token; + int ies_len; + +@@ -496,16 +496,17 @@ void ieee80211_process_addba_request(str + ies_len = len - offsetof(struct ieee80211_mgmt, + u.action.u.addba_req.variable); + if (ies_len) { +- ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); +- if (elems.parse_error) ++ elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, ++ ies_len, true, mgmt->bssid, NULL); ++ if (!elems || elems->parse_error) + return; + } + + __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, + start_seq_num, ba_policy, tid, + buf_size, true, false, +- elems.addba_ext_ie); ++ elems ? elems->addba_ext_ie : NULL); ++ kfree(elems); + } + + void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -9,7 +9,7 @@ + * Copyright 2009, Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright(c) 2016 Intel Deutschland GmbH +- * Copyright(c) 2018-2020 Intel Corporation ++ * Copyright(c) 2018-2021 Intel Corporation + */ + + #include +@@ -1589,7 +1589,7 @@ void ieee80211_rx_mgmt_probe_beacon(stru + struct ieee80211_rx_status *rx_status) + { + size_t baselen; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + + BUILD_BUG_ON(offsetof(typeof(mgmt->u.probe_resp), variable) != + offsetof(typeof(mgmt->u.beacon), variable)); +@@ -1602,10 +1602,14 @@ void ieee80211_rx_mgmt_probe_beacon(stru + if (baselen > len) + return; + +- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, +- false, &elems, mgmt->bssid, NULL); +- +- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); ++ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable, ++ len - baselen, false, ++ mgmt->bssid, NULL); ++ ++ if (elems) { ++ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, elems); ++ kfree(elems); ++ } + } + + void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, +@@ -1614,7 +1618,7 @@ void ieee80211_ibss_rx_queued_mgmt(struc + struct ieee80211_rx_status *rx_status; + struct ieee80211_mgmt *mgmt; + u16 fc; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + int ies_len; + + rx_status = IEEE80211_SKB_RXCB(skb); +@@ -1651,15 +1655,16 @@ void ieee80211_ibss_rx_queued_mgmt(struc + if (ies_len < 0) + break; + +- ieee802_11_parse_elems( ++ elems = ieee802_11_parse_elems( + mgmt->u.action.u.chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len, +- rx_status, &elems); ++ rx_status, elems); ++ kfree(elems); + break; + } + } +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -2088,18 +2088,18 @@ static inline void ieee80211_tx_skb(stru + ieee80211_tx_skb_tid(sdata, skb, 7); + } + +-void 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, +- u8 *bss_bssid); +-static inline void ieee802_11_parse_elems(const u8 *start, size_t len, +- bool action, +- struct ieee802_11_elems *elems, +- u8 *transmitter_bssid, +- u8 *bss_bssid) ++struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, ++ bool action, ++ u64 filter, u32 crc, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid); ++static inline struct ieee802_11_elems * ++ieee802_11_parse_elems(const u8 *start, size_t len, bool action, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid) + { +- ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0, +- transmitter_bssid, bss_bssid); ++ return ieee802_11_parse_elems_crc(start, len, action, 0, 0, ++ transmitter_bssid, bss_bssid); + } + + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -1247,7 +1247,7 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + struct sk_buff *presp; + struct beacon_data *bcn; + struct ieee80211_mgmt *hdr; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *pos; + +@@ -1256,22 +1256,24 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + if (baselen > len) + return; + +- ieee802_11_parse_elems(pos, len - baselen, false, &elems, mgmt->bssid, +- NULL); +- +- if (!elems.mesh_id) ++ elems = ieee802_11_parse_elems(pos, len - baselen, false, mgmt->bssid, ++ NULL); ++ if (!elems) + return; + ++ if (!elems->mesh_id) ++ goto free; ++ + /* 802.11-2012 10.1.4.3.2 */ + if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) && + !is_broadcast_ether_addr(mgmt->da)) || +- elems.ssid_len != 0) +- return; ++ elems->ssid_len != 0) ++ goto free; + +- if (elems.mesh_id_len != 0 && +- (elems.mesh_id_len != ifmsh->mesh_id_len || +- memcmp(elems.mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len))) +- return; ++ if (elems->mesh_id_len != 0 && ++ (elems->mesh_id_len != ifmsh->mesh_id_len || ++ memcmp(elems->mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len))) ++ goto free; + + rcu_read_lock(); + bcn = rcu_dereference(ifmsh->beacon); +@@ -1295,6 +1297,8 @@ ieee80211_mesh_rx_probe_req(struct ieee8 + ieee80211_tx_skb(sdata, presp); + out: + rcu_read_unlock(); ++free: ++ kfree(elems); + } + + static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, +@@ -1305,7 +1309,7 @@ static void ieee80211_mesh_rx_bcn_presp( + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct ieee80211_channel *channel; + size_t baselen; + int freq; +@@ -1320,42 +1324,47 @@ static void ieee80211_mesh_rx_bcn_presp( + if (baselen > len) + return; + +- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, +- false, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable, ++ len - baselen, ++ false, mgmt->bssid, NULL); ++ if (!elems) ++ return; + + /* ignore non-mesh or secure / unsecure mismatch */ +- if ((!elems.mesh_id || !elems.mesh_config) || +- (elems.rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || +- (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) +- return; ++ if ((!elems->mesh_id || !elems->mesh_config) || ++ (elems->rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) || ++ (!elems->rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE)) ++ goto free; + +- if (elems.ds_params) +- freq = ieee80211_channel_to_frequency(elems.ds_params[0], band); ++ if (elems->ds_params) ++ freq = ieee80211_channel_to_frequency(elems->ds_params[0], band); + else + freq = rx_status->freq; + + channel = ieee80211_get_channel(local->hw.wiphy, freq); + + if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) +- return; ++ goto free; + +- if (mesh_matches_local(sdata, &elems)) { ++ if (mesh_matches_local(sdata, elems)) { + mpl_dbg(sdata, "rssi_threshold=%d,rx_status->signal=%d\n", + sdata->u.mesh.mshcfg.rssi_threshold, rx_status->signal); + if (!sdata->u.mesh.user_mpm || + sdata->u.mesh.mshcfg.rssi_threshold == 0 || + sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal) +- mesh_neighbour_update(sdata, mgmt->sa, &elems, ++ mesh_neighbour_update(sdata, mgmt->sa, elems, + rx_status); + + if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT && + !sdata->vif.csa_active) +- ieee80211_mesh_process_chnswitch(sdata, &elems, true); ++ ieee80211_mesh_process_chnswitch(sdata, elems, true); + } + + if (ifmsh->sync_ops) + ifmsh->sync_ops->rx_bcn_presp(sdata, stype, mgmt, len, +- elems.mesh_config, rx_status); ++ elems->mesh_config, rx_status); ++free: ++ kfree(elems); + } + + int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata) +@@ -1447,7 +1456,7 @@ static void mesh_rx_csa_frame(struct iee + struct ieee80211_mgmt *mgmt, size_t len) + { + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + u16 pre_value; + bool fwd_csa = true; + size_t baselen; +@@ -1460,33 +1469,37 @@ static void mesh_rx_csa_frame(struct iee + pos = mgmt->u.action.u.chan_switch.variable; + baselen = offsetof(struct ieee80211_mgmt, + u.action.u.chan_switch.variable); +- ieee802_11_parse_elems(pos, len - baselen, true, &elems, +- mgmt->bssid, NULL); +- +- if (!mesh_matches_local(sdata, &elems)) ++ elems = ieee802_11_parse_elems(pos, len - baselen, true, ++ mgmt->bssid, NULL); ++ if (!elems) + return; + +- ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; ++ if (!mesh_matches_local(sdata, elems)) ++ goto free; ++ ++ ifmsh->chsw_ttl = elems->mesh_chansw_params_ie->mesh_ttl; + if (!--ifmsh->chsw_ttl) + fwd_csa = false; + +- pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); ++ pre_value = le16_to_cpu(elems->mesh_chansw_params_ie->mesh_pre_value); + if (ifmsh->pre_value >= pre_value) +- return; ++ goto free; + + ifmsh->pre_value = pre_value; + + if (!sdata->vif.csa_active && +- !ieee80211_mesh_process_chnswitch(sdata, &elems, false)) { ++ !ieee80211_mesh_process_chnswitch(sdata, elems, false)) { + mcsa_dbg(sdata, "Failed to process CSA action frame"); +- return; ++ goto free; + } + + /* forward or re-broadcast the CSA frame */ + if (fwd_csa) { +- if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0) ++ if (mesh_fwd_csa_frame(sdata, mgmt, len, elems) < 0) + mcsa_dbg(sdata, "Failed to forward the CSA frame"); + } ++free: ++ kfree(elems); + } + + static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2008, 2009 open80211s Ltd. +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + * Author: Luis Carlos Cobo + */ + +@@ -908,7 +908,7 @@ static void hwmp_rann_frame_process(stru + void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, + struct ieee80211_mgmt *mgmt, size_t len) + { +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u32 path_metric; + struct sta_info *sta; +@@ -926,37 +926,41 @@ void mesh_rx_path_sel_frame(struct ieee8 + rcu_read_unlock(); + + baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; +- ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, +- len - baselen, false, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, ++ len - baselen, false, mgmt->bssid, NULL); ++ if (!elems) ++ return; + +- if (elems.preq) { +- if (elems.preq_len != 37) ++ if (elems->preq) { ++ if (elems->preq_len != 37) + /* Right now we support just 1 destination and no AE */ +- return; +- path_metric = hwmp_route_info_get(sdata, mgmt, elems.preq, ++ goto free; ++ path_metric = hwmp_route_info_get(sdata, mgmt, elems->preq, + MPATH_PREQ); + if (path_metric) +- hwmp_preq_frame_process(sdata, mgmt, elems.preq, ++ hwmp_preq_frame_process(sdata, mgmt, elems->preq, + path_metric); + } +- if (elems.prep) { +- if (elems.prep_len != 31) ++ if (elems->prep) { ++ if (elems->prep_len != 31) + /* Right now we support no AE */ +- return; +- path_metric = hwmp_route_info_get(sdata, mgmt, elems.prep, ++ goto free; ++ path_metric = hwmp_route_info_get(sdata, mgmt, elems->prep, + MPATH_PREP); + if (path_metric) +- hwmp_prep_frame_process(sdata, mgmt, elems.prep, ++ hwmp_prep_frame_process(sdata, mgmt, elems->prep, + path_metric); + } +- if (elems.perr) { +- if (elems.perr_len != 15) ++ if (elems->perr) { ++ if (elems->perr_len != 15) + /* Right now we support only one destination per PERR */ +- return; +- hwmp_perr_frame_process(sdata, mgmt, elems.perr); ++ goto free; ++ hwmp_perr_frame_process(sdata, mgmt, elems->perr); + } +- if (elems.rann) +- hwmp_rann_frame_process(sdata, mgmt, elems.rann); ++ if (elems->rann) ++ hwmp_rann_frame_process(sdata, mgmt, elems->rann); ++free: ++ kfree(elems); + } + + /** +--- a/net/mac80211/mesh_plink.c ++++ b/net/mac80211/mesh_plink.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2008, 2009 open80211s Ltd. +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + * Author: Luis Carlos Cobo + */ + #include +@@ -1200,7 +1200,7 @@ void mesh_rx_plink_frame(struct ieee8021 + struct ieee80211_mgmt *mgmt, size_t len, + struct ieee80211_rx_status *rx_status) + { +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *baseaddr; + +@@ -1228,7 +1228,8 @@ void mesh_rx_plink_frame(struct ieee8021 + if (baselen > len) + return; + } +- ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems, +- mgmt->bssid, NULL); +- mesh_process_plink_frame(sdata, mgmt, &elems, rx_status); ++ elems = ieee802_11_parse_elems(baseaddr, len - baselen, true, ++ mgmt->bssid, NULL); ++ mesh_process_plink_frame(sdata, mgmt, elems, rx_status); ++ kfree(elems); + } +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3317,8 +3317,11 @@ static bool ieee80211_assoc_success(stru + aid = 0; /* TODO */ + } + capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, elems, +- mgmt->bssid, assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, ++ mgmt->bssid, assoc_data->bss->bssid); ++ ++ if (!elems) ++ return false; + + if (elems->aid_resp) + aid = le16_to_cpu(elems->aid_resp->aid); +@@ -3340,7 +3343,8 @@ static bool ieee80211_assoc_success(stru + + if (!is_s1g && !elems->supp_rates) { + sdata_info(sdata, "no SuppRates element in AssocResp\n"); +- return false; ++ ret = false; ++ goto out; + } + + sdata->vif.bss_conf.aid = aid; +@@ -3362,7 +3366,7 @@ static bool ieee80211_assoc_success(stru + (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) && + (!elems->vht_cap_elem || !elems->vht_operation)))) { + const struct cfg80211_bss_ies *ies; +- struct ieee802_11_elems bss_elems; ++ struct ieee802_11_elems *bss_elems; + + rcu_read_lock(); + ies = rcu_dereference(cbss->ies); +@@ -3373,13 +3377,17 @@ static bool ieee80211_assoc_success(stru + if (!bss_ies) + return false; + +- ieee802_11_parse_elems(bss_ies->data, bss_ies->len, +- false, &bss_elems, +- mgmt->bssid, +- assoc_data->bss->bssid); ++ bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len, ++ false, mgmt->bssid, ++ assoc_data->bss->bssid); ++ if (!bss_elems) { ++ ret = false; ++ goto out; ++ } ++ + if (assoc_data->wmm && +- !elems->wmm_param && bss_elems.wmm_param) { +- elems->wmm_param = bss_elems.wmm_param; ++ !elems->wmm_param && bss_elems->wmm_param) { ++ elems->wmm_param = bss_elems->wmm_param; + sdata_info(sdata, + "AP bug: WMM param missing from AssocResp\n"); + } +@@ -3388,30 +3396,32 @@ static bool ieee80211_assoc_success(stru + * Also check if we requested HT/VHT, otherwise the AP doesn't + * have to include the IEs in the (re)association response. + */ +- if (!elems->ht_cap_elem && bss_elems.ht_cap_elem && ++ if (!elems->ht_cap_elem && bss_elems->ht_cap_elem && + !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { +- elems->ht_cap_elem = bss_elems.ht_cap_elem; ++ elems->ht_cap_elem = bss_elems->ht_cap_elem; + sdata_info(sdata, + "AP bug: HT capability missing from AssocResp\n"); + } +- if (!elems->ht_operation && bss_elems.ht_operation && ++ if (!elems->ht_operation && bss_elems->ht_operation && + !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) { +- elems->ht_operation = bss_elems.ht_operation; ++ elems->ht_operation = bss_elems->ht_operation; + sdata_info(sdata, + "AP bug: HT operation missing from AssocResp\n"); + } +- if (!elems->vht_cap_elem && bss_elems.vht_cap_elem && ++ if (!elems->vht_cap_elem && bss_elems->vht_cap_elem && + !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { +- elems->vht_cap_elem = bss_elems.vht_cap_elem; ++ elems->vht_cap_elem = bss_elems->vht_cap_elem; + sdata_info(sdata, + "AP bug: VHT capa missing from AssocResp\n"); + } +- if (!elems->vht_operation && bss_elems.vht_operation && ++ if (!elems->vht_operation && bss_elems->vht_operation && + !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) { +- elems->vht_operation = bss_elems.vht_operation; ++ elems->vht_operation = bss_elems->vht_operation; + sdata_info(sdata, + "AP bug: VHT operation missing from AssocResp\n"); + } ++ ++ kfree(bss_elems); + } + + /* +@@ -3662,6 +3672,7 @@ static bool ieee80211_assoc_success(stru + + ret = true; + out: ++ kfree(elems); + kfree(bss_ies); + return ret; + } +@@ -3673,7 +3684,7 @@ static void ieee80211_rx_mgmt_assoc_resp + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; + u16 capab_info, status_code, aid; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + int ac, uapsd_queues = -1; + u8 *pos; + bool reassoc; +@@ -3730,14 +3741,16 @@ static void ieee80211_rx_mgmt_assoc_resp + fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0) + return; + +- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems, +- mgmt->bssid, assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, ++ mgmt->bssid, assoc_data->bss->bssid); ++ if (!elems) ++ goto notify_driver; + + if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY && +- elems.timeout_int && +- elems.timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) { ++ elems->timeout_int && ++ elems->timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) { + u32 tu, ms; +- tu = le32_to_cpu(elems.timeout_int->value); ++ tu = le32_to_cpu(elems->timeout_int->value); + ms = tu * 1024 / 1000; + sdata_info(sdata, + "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", +@@ -3757,7 +3770,7 @@ static void ieee80211_rx_mgmt_assoc_resp + event.u.mlme.reason = status_code; + drv_event_callback(sdata->local, sdata, &event); + } else { +- if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, &elems)) { ++ if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, elems)) { + /* oops -- internal error -- send timeout for now */ + ieee80211_destroy_assoc_data(sdata, false, false); + cfg80211_assoc_timeout(sdata->dev, cbss); +@@ -3787,6 +3800,7 @@ static void ieee80211_rx_mgmt_assoc_resp + ifmgd->assoc_req_ies, ifmgd->assoc_req_ies_len); + notify_driver: + drv_mgd_complete_tx(sdata->local, sdata, &info); ++ kfree(elems); + } + + static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, +@@ -3991,7 +4005,7 @@ static void ieee80211_rx_mgmt_beacon(str + struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; + struct ieee80211_mgmt *mgmt = (void *) hdr; + size_t baselen; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct ieee80211_local *local = sdata->local; + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_channel *chan; +@@ -4037,15 +4051,16 @@ static void ieee80211_rx_mgmt_beacon(str + + if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon && + ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->bss)) { +- ieee802_11_parse_elems(variable, +- len - baselen, false, &elems, +- bssid, +- ifmgd->assoc_data->bss->bssid); ++ elems = ieee802_11_parse_elems(variable, len - baselen, false, ++ bssid, ++ ifmgd->assoc_data->bss->bssid); ++ if (!elems) ++ return; + + ieee80211_rx_bss_info(sdata, mgmt, len, rx_status); + +- if (elems.dtim_period) +- ifmgd->dtim_period = elems.dtim_period; ++ if (elems->dtim_period) ++ ifmgd->dtim_period = elems->dtim_period; + ifmgd->have_beacon = true; + ifmgd->assoc_data->need_beacon = false; + if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) { +@@ -4053,17 +4068,17 @@ static void ieee80211_rx_mgmt_beacon(str + le64_to_cpu(mgmt->u.beacon.timestamp); + sdata->vif.bss_conf.sync_device_ts = + rx_status->device_timestamp; +- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count; ++ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count; + } + +- if (elems.mbssid_config_ie) ++ if (elems->mbssid_config_ie) + bss_conf->profile_periodicity = +- elems.mbssid_config_ie->profile_periodicity; ++ elems->mbssid_config_ie->profile_periodicity; + else + bss_conf->profile_periodicity = 0; + +- if (elems.ext_capab_len >= 11 && +- (elems.ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT)) ++ if (elems->ext_capab_len >= 11 && ++ (elems->ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT)) + bss_conf->ema_ap = true; + else + bss_conf->ema_ap = false; +@@ -4072,6 +4087,7 @@ static void ieee80211_rx_mgmt_beacon(str + ifmgd->assoc_data->timeout = jiffies; + ifmgd->assoc_data->timeout_started = true; + run_again(sdata, ifmgd->assoc_data->timeout); ++ kfree(elems); + return; + } + +@@ -4103,14 +4119,15 @@ static void ieee80211_rx_mgmt_beacon(str + */ + if (!ieee80211_is_s1g_beacon(hdr->frame_control)) + ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); +- ieee802_11_parse_elems_crc(variable, +- len - baselen, false, &elems, +- care_about_ies, ncrc, +- mgmt->bssid, bssid); +- ncrc = elems.crc; ++ elems = ieee802_11_parse_elems_crc(variable, len - baselen, ++ false, care_about_ies, ncrc, ++ mgmt->bssid, bssid); ++ if (!elems) ++ return; ++ ncrc = elems->crc; + + if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) && +- ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) { ++ ieee80211_check_tim(elems->tim, elems->tim_len, bss_conf->aid)) { + if (local->hw.conf.dynamic_ps_timeout > 0) { + if (local->hw.conf.flags & IEEE80211_CONF_PS) { + local->hw.conf.flags &= ~IEEE80211_CONF_PS; +@@ -4180,12 +4197,12 @@ static void ieee80211_rx_mgmt_beacon(str + le64_to_cpu(mgmt->u.beacon.timestamp); + sdata->vif.bss_conf.sync_device_ts = + rx_status->device_timestamp; +- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count; ++ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count; + } + + if ((ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) || + ieee80211_is_s1g_short_beacon(mgmt->frame_control)) +- return; ++ goto free; + ifmgd->beacon_crc = ncrc; + ifmgd->beacon_crc_valid = true; + +@@ -4193,12 +4210,12 @@ static void ieee80211_rx_mgmt_beacon(str + + ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, + rx_status->device_timestamp, +- &elems, true); ++ elems, true); + + if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) && +- ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, +- elems.wmm_param_len, +- elems.mu_edca_param_set)) ++ ieee80211_sta_wmm_params(local, sdata, elems->wmm_param, ++ elems->wmm_param_len, ++ elems->mu_edca_param_set)) + changed |= BSS_CHANGED_QOS; + + /* +@@ -4207,7 +4224,7 @@ static void ieee80211_rx_mgmt_beacon(str + */ + if (!ifmgd->have_beacon) { + /* a few bogus AP send dtim_period = 0 or no TIM IE */ +- bss_conf->dtim_period = elems.dtim_period ?: 1; ++ bss_conf->dtim_period = elems->dtim_period ?: 1; + + changed |= BSS_CHANGED_BEACON_INFO; + ifmgd->have_beacon = true; +@@ -4219,9 +4236,9 @@ static void ieee80211_rx_mgmt_beacon(str + ieee80211_recalc_ps_vif(sdata); + } + +- if (elems.erp_info) { ++ if (elems->erp_info) { + erp_valid = true; +- erp_value = elems.erp_info[0]; ++ erp_value = elems->erp_info[0]; + } else { + erp_valid = false; + } +@@ -4234,12 +4251,12 @@ static void ieee80211_rx_mgmt_beacon(str + mutex_lock(&local->sta_mtx); + sta = sta_info_get(sdata, bssid); + +- changed |= ieee80211_recalc_twt_req(sdata, sta, &elems); ++ changed |= ieee80211_recalc_twt_req(sdata, sta, elems); + +- if (ieee80211_config_bw(sdata, sta, elems.ht_cap_elem, +- elems.vht_cap_elem, elems.ht_operation, +- elems.vht_operation, elems.he_operation, +- elems.s1g_oper, bssid, &changed)) { ++ if (ieee80211_config_bw(sdata, sta, elems->ht_cap_elem, ++ elems->vht_cap_elem, elems->ht_operation, ++ elems->vht_operation, elems->he_operation, ++ elems->s1g_oper, bssid, &changed)) { + mutex_unlock(&local->sta_mtx); + sdata_info(sdata, + "failed to follow AP %pM bandwidth change, disconnect\n", +@@ -4251,21 +4268,23 @@ static void ieee80211_rx_mgmt_beacon(str + sizeof(deauth_buf), true, + WLAN_REASON_DEAUTH_LEAVING, + false); +- return; ++ goto free; + } + +- if (sta && elems.opmode_notif) +- ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif, ++ if (sta && elems->opmode_notif) ++ ieee80211_vht_handle_opmode(sdata, sta, *elems->opmode_notif, + rx_status->band); + mutex_unlock(&local->sta_mtx); + + changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt, +- elems.country_elem, +- elems.country_elem_len, +- elems.pwr_constr_elem, +- elems.cisco_dtpc_elem); ++ elems->country_elem, ++ elems->country_elem_len, ++ elems->pwr_constr_elem, ++ elems->cisco_dtpc_elem); + + ieee80211_bss_info_change_notify(sdata, changed); ++free: ++ kfree(elems); + } + + void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata, +@@ -4294,7 +4313,6 @@ void ieee80211_sta_rx_queued_mgmt(struct + struct ieee80211_rx_status *rx_status; + struct ieee80211_mgmt *mgmt; + u16 fc; +- struct ieee802_11_elems elems; + int ies_len; + + rx_status = (struct ieee80211_rx_status *) skb->cb; +@@ -4326,6 +4344,8 @@ void ieee80211_sta_rx_queued_mgmt(struct + break; + case IEEE80211_STYPE_ACTION: + if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { ++ struct ieee802_11_elems *elems; ++ + ies_len = skb->len - + offsetof(struct ieee80211_mgmt, + u.action.u.chan_switch.variable); +@@ -4334,18 +4354,21 @@ void ieee80211_sta_rx_queued_mgmt(struct + break; + + /* CSA IE cannot be overridden, no need for BSSID */ +- ieee802_11_parse_elems( +- mgmt->u.action.u.chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems( ++ mgmt->u.action.u.chan_switch.variable, ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + ieee80211_sta_process_chanswitch(sdata, + rx_status->mactime, + rx_status->device_timestamp, +- &elems, false); ++ elems, false); ++ kfree(elems); + } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { ++ struct ieee802_11_elems *elems; ++ + ies_len = skb->len - + offsetof(struct ieee80211_mgmt, + u.action.u.ext_chan_switch.variable); +@@ -4357,21 +4380,22 @@ void ieee80211_sta_rx_queued_mgmt(struct + * extended CSA IE can't be overridden, no need for + * BSSID + */ +- ieee802_11_parse_elems( +- mgmt->u.action.u.ext_chan_switch.variable, +- ies_len, true, &elems, mgmt->bssid, NULL); ++ elems = ieee802_11_parse_elems( ++ mgmt->u.action.u.ext_chan_switch.variable, ++ ies_len, true, mgmt->bssid, NULL); + +- if (elems.parse_error) ++ if (!elems || elems->parse_error) + break; + + /* for the handling code pretend this was also an IE */ +- elems.ext_chansw_ie = ++ elems->ext_chansw_ie = + &mgmt->u.action.u.ext_chan_switch.data; + + ieee80211_sta_process_chanswitch(sdata, + rx_status->mactime, + rx_status->device_timestamp, +- &elems, false); ++ elems, false); ++ kfree(elems); + } + break; + } +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -9,7 +9,7 @@ + * Copyright 2007, Michael Wu + * Copyright 2013-2015 Intel Mobile Communications GmbH + * Copyright 2016-2017 Intel Deutschland GmbH +- * Copyright (C) 2018-2020 Intel Corporation ++ * Copyright (C) 2018-2021 Intel Corporation + */ + + #include +@@ -155,7 +155,7 @@ ieee80211_bss_info_update(struct ieee802 + }; + bool signal_valid; + struct ieee80211_sub_if_data *scan_sdata; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + size_t baselen; + u8 *elements; + +@@ -209,8 +209,10 @@ ieee80211_bss_info_update(struct ieee802 + if (baselen > len) + return NULL; + +- ieee802_11_parse_elems(elements, len - baselen, false, &elems, +- mgmt->bssid, cbss->bssid); ++ elems = ieee802_11_parse_elems(elements, len - baselen, false, ++ mgmt->bssid, cbss->bssid); ++ if (!elems) ++ return NULL; + + /* In case the signal is invalid update the status */ + signal_valid = channel == cbss->channel; +@@ -218,15 +220,17 @@ ieee80211_bss_info_update(struct ieee802 + rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + + bss = (void *)cbss->priv; +- ieee80211_update_bss_from_elems(local, bss, &elems, rx_status, beacon); ++ ieee80211_update_bss_from_elems(local, bss, elems, rx_status, beacon); + + list_for_each_entry(non_tx_cbss, &cbss->nontrans_list, nontrans_list) { + non_tx_bss = (void *)non_tx_cbss->priv; + +- ieee80211_update_bss_from_elems(local, non_tx_bss, &elems, ++ ieee80211_update_bss_from_elems(local, non_tx_bss, elems, + rx_status, beacon); + } + ++ kfree(elems); ++ + return bss; + } + +--- a/net/mac80211/tdls.c ++++ b/net/mac80211/tdls.c +@@ -6,7 +6,7 @@ + * Copyright 2014, Intel Corporation + * Copyright 2014 Intel Mobile Communications GmbH + * Copyright 2015 - 2016 Intel Deutschland GmbH +- * Copyright (C) 2019 Intel Corporation ++ * Copyright (C) 2019, 2021 Intel Corporation + */ + + #include +@@ -1684,7 +1684,7 @@ ieee80211_process_tdls_channel_switch_re + struct sk_buff *skb) + { + struct ieee80211_local *local = sdata->local; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems = NULL; + struct sta_info *sta; + struct ieee80211_tdls_data *tf = (void *)skb->data; + bool local_initiator; +@@ -1718,16 +1718,20 @@ ieee80211_process_tdls_channel_switch_re + goto call_drv; + } + +- ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, +- skb->len - baselen, false, &elems, +- NULL, NULL); +- if (elems.parse_error) { ++ elems = ieee802_11_parse_elems(tf->u.chan_switch_resp.variable, ++ skb->len - baselen, false, NULL, NULL); ++ if (!elems) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ if (elems->parse_error) { + tdls_dbg(sdata, "Invalid IEs in TDLS channel switch resp\n"); + ret = -EINVAL; + goto out; + } + +- if (!elems.ch_sw_timing || !elems.lnk_id) { ++ if (!elems->ch_sw_timing || !elems->lnk_id) { + tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n"); + ret = -EINVAL; + goto out; +@@ -1735,15 +1739,15 @@ ieee80211_process_tdls_channel_switch_re + + /* validate the initiator is set correctly */ + local_initiator = +- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); ++ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); + if (local_initiator == sta->sta.tdls_initiator) { + tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); + ret = -EINVAL; + goto out; + } + +- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time); +- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout); ++ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); ++ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); + + params.tmpl_skb = + ieee80211_tdls_ch_sw_resp_tmpl_get(sta, ¶ms.ch_sw_tm_ie); +@@ -1763,6 +1767,7 @@ call_drv: + out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(params.tmpl_skb); ++ kfree(elems); + return ret; + } + +@@ -1771,7 +1776,7 @@ ieee80211_process_tdls_channel_switch_re + struct sk_buff *skb) + { + struct ieee80211_local *local = sdata->local; +- struct ieee802_11_elems elems; ++ struct ieee802_11_elems *elems; + struct cfg80211_chan_def chandef; + struct ieee80211_channel *chan; + enum nl80211_channel_type chan_type; +@@ -1831,22 +1836,27 @@ ieee80211_process_tdls_channel_switch_re + return -EINVAL; + } + +- ieee802_11_parse_elems(tf->u.chan_switch_req.variable, +- skb->len - baselen, false, &elems, NULL, NULL); +- if (elems.parse_error) { ++ elems = ieee802_11_parse_elems(tf->u.chan_switch_req.variable, ++ skb->len - baselen, false, NULL, NULL); ++ if (!elems) ++ return -ENOMEM; ++ ++ if (elems->parse_error) { + tdls_dbg(sdata, "Invalid IEs in TDLS channel switch req\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + +- if (!elems.ch_sw_timing || !elems.lnk_id) { ++ if (!elems->ch_sw_timing || !elems->lnk_id) { + tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + +- if (!elems.sec_chan_offs) { ++ if (!elems->sec_chan_offs) { + chan_type = NL80211_CHAN_HT20; + } else { +- switch (elems.sec_chan_offs->sec_chan_offs) { ++ switch (elems->sec_chan_offs->sec_chan_offs) { + case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: + chan_type = NL80211_CHAN_HT40PLUS; + break; +@@ -1865,7 +1875,8 @@ ieee80211_process_tdls_channel_switch_re + if (!cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &chandef, + sdata->wdev.iftype)) { + tdls_dbg(sdata, "TDLS chan switch to forbidden channel\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto free; + } + + mutex_lock(&local->sta_mtx); +@@ -1881,7 +1892,7 @@ ieee80211_process_tdls_channel_switch_re + + /* validate the initiator is set correctly */ + local_initiator = +- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); ++ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN); + if (local_initiator == sta->sta.tdls_initiator) { + tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n"); + ret = -EINVAL; +@@ -1889,16 +1900,16 @@ ieee80211_process_tdls_channel_switch_re + } + + /* peer should have known better */ +- if (!sta->sta.ht_cap.ht_supported && elems.sec_chan_offs && +- elems.sec_chan_offs->sec_chan_offs) { ++ if (!sta->sta.ht_cap.ht_supported && elems->sec_chan_offs && ++ elems->sec_chan_offs->sec_chan_offs) { + tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n"); + ret = -ENOTSUPP; + goto out; + } + + params.chandef = &chandef; +- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time); +- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout); ++ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time); ++ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout); + + params.tmpl_skb = + ieee80211_tdls_ch_sw_resp_tmpl_get(sta, +@@ -1917,6 +1928,8 @@ ieee80211_process_tdls_channel_switch_re + out: + mutex_unlock(&local->sta_mtx); + dev_kfree_skb_any(params.tmpl_skb); ++free: ++ kfree(elems); + return ret; + } + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1399,8 +1399,8 @@ _ieee802_11_parse_elems_crc(const u8 *st + + static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, + struct ieee802_11_elems *elems, +- u8 *transmitter_bssid, +- u8 *bss_bssid, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid, + u8 *nontransmitted_profile) + { + const struct element *elem, *sub; +@@ -1465,16 +1465,20 @@ static size_t ieee802_11_find_bssid_prof + return found ? profile_len : 0; + } + +-void 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, +- u8 *bss_bssid) ++struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len, ++ bool action, u64 filter, ++ u32 crc, ++ const u8 *transmitter_bssid, ++ const u8 *bss_bssid) + { ++ struct ieee802_11_elems *elems; + const struct element *non_inherit = NULL; + u8 *nontransmitted_profile; + int nontransmitted_profile_len = 0; + +- memset(elems, 0, sizeof(*elems)); ++ elems = kzalloc(sizeof(*elems), GFP_ATOMIC); ++ if (!elems) ++ return NULL; + elems->ie_start = start; + elems->total_len = len; + +@@ -1521,6 +1525,8 @@ void ieee802_11_parse_elems_crc(const u8 + kfree(nontransmitted_profile); + + elems->crc = crc; ++ ++ return elems; + } + + void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/subsys/350-mac80211-fix-memory-leaks-with-element-parsing.patch b/package/kernel/mac80211/patches/subsys/350-mac80211-fix-memory-leaks-with-element-parsing.patch new file mode 100644 index 0000000000..f4906e8c03 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/350-mac80211-fix-memory-leaks-with-element-parsing.patch @@ -0,0 +1,115 @@ +From: Johannes Berg +Date: Fri, 1 Oct 2021 21:11:08 +0200 +Subject: [PATCH] mac80211: fix memory leaks with element parsing + +commit 8223ac199a3849257e86ec27865dc63f034b1cf1 upstream. + +My previous commit 5d24828d05f3 ("mac80211: always allocate +struct ieee802_11_elems") had a few bugs and leaked the new +allocated struct in a few error cases, fix that. + +Fixes: 5d24828d05f3 ("mac80211: always allocate struct ieee802_11_elems") +Signed-off-by: Johannes Berg +Link: https://lore.kernel.org/r/20211001211108.9839928e42e0.Ib81ca187d3d3af7ed1bfeac2e00d08a4637c8025@changeid +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -499,13 +499,14 @@ void ieee80211_process_addba_request(str + elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable, + ies_len, true, mgmt->bssid, NULL); + if (!elems || elems->parse_error) +- return; ++ goto free; + } + + __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, + start_seq_num, ba_policy, tid, + buf_size, true, false, + elems ? elems->addba_ext_ie : NULL); ++free: + kfree(elems); + } + +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -1659,11 +1659,11 @@ void ieee80211_ibss_rx_queued_mgmt(struc + mgmt->u.action.u.chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; +- +- ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len, +- rx_status, elems); ++ if (elems && !elems->parse_error) ++ ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, ++ skb->len, ++ rx_status, ++ elems); + kfree(elems); + break; + } +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -3374,8 +3374,10 @@ static bool ieee80211_assoc_success(stru + bss_ies = kmemdup(ies, sizeof(*ies) + ies->len, + GFP_ATOMIC); + rcu_read_unlock(); +- if (!bss_ies) +- return false; ++ if (!bss_ies) { ++ ret = false; ++ goto out; ++ } + + bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len, + false, mgmt->bssid, +@@ -4358,13 +4360,11 @@ void ieee80211_sta_rx_queued_mgmt(struct + mgmt->u.action.u.chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; +- +- ieee80211_sta_process_chanswitch(sdata, +- rx_status->mactime, +- rx_status->device_timestamp, +- elems, false); ++ if (elems && !elems->parse_error) ++ ieee80211_sta_process_chanswitch(sdata, ++ rx_status->mactime, ++ rx_status->device_timestamp, ++ elems, false); + kfree(elems); + } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { + struct ieee802_11_elems *elems; +@@ -4384,17 +4384,17 @@ void ieee80211_sta_rx_queued_mgmt(struct + mgmt->u.action.u.ext_chan_switch.variable, + ies_len, true, mgmt->bssid, NULL); + +- if (!elems || elems->parse_error) +- break; ++ if (elems && !elems->parse_error) { ++ /* for the handling code pretend it was an IE */ ++ elems->ext_chansw_ie = ++ &mgmt->u.action.u.ext_chan_switch.data; ++ ++ ieee80211_sta_process_chanswitch(sdata, ++ rx_status->mactime, ++ rx_status->device_timestamp, ++ elems, false); ++ } + +- /* for the handling code pretend this was also an IE */ +- elems->ext_chansw_ie = +- &mgmt->u.action.u.ext_chan_switch.data; +- +- ieee80211_sta_process_chanswitch(sdata, +- rx_status->mactime, +- rx_status->device_timestamp, +- elems, false); + kfree(elems); + } + break; diff --git a/package/kernel/mac80211/patches/subsys/351-wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch b/package/kernel/mac80211/patches/subsys/351-wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch new file mode 100644 index 0000000000..9e1f781367 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/351-wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch @@ -0,0 +1,41 @@ +From: Johannes Berg +Date: Wed, 28 Sep 2022 21:56:15 +0200 +Subject: [PATCH] wifi: cfg80211: fix u8 overflow in + cfg80211_update_notlisted_nontrans() + +commit aebe9f4639b13a1f4e9a6b42cdd2e38c617b442d upstream. + +In the copy code of the elements, we do the following calculation +to reach the end of the MBSSID element: + + /* copy the IEs after MBSSID */ + cpy_len = mbssid[1] + 2; + +This looks fine, however, cpy_len is a u8, the same as mbssid[1], +so the addition of two can overflow. In this case the subsequent +memcpy() will overflow the allocated buffer, since it copies 256 +bytes too much due to the way the allocation and memcpy() sizes +are calculated. + +Fix this by using size_t for the cpy_len variable. + +This fixes CVE-2022-41674. + +Reported-by: Soenke Huster +Tested-by: Soenke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2238,7 +2238,7 @@ cfg80211_update_notlisted_nontrans(struc + size_t new_ie_len; + struct cfg80211_bss_ies *new_ies; + const struct cfg80211_bss_ies *old; +- u8 cpy_len; ++ size_t cpy_len; + + lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock); + diff --git a/package/kernel/mac80211/patches/subsys/352-wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch b/package/kernel/mac80211/patches/subsys/352-wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch new file mode 100644 index 0000000000..4c8e05e9ba --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/352-wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch @@ -0,0 +1,47 @@ +From: Johannes Berg +Date: Wed, 28 Sep 2022 22:01:37 +0200 +Subject: [PATCH] wifi: cfg80211/mac80211: reject bad MBSSID elements + +commit 8f033d2becc24aa6bfd2a5c104407963560caabc upstream + +Per spec, the maximum value for the MaxBSSID ('n') indicator is 8, +and the minimum is 1 since a multiple BSSID set with just one BSSID +doesn't make sense (the # of BSSIDs is limited by 2^n). + +Limit this in the parsing in both cfg80211 and mac80211, rejecting +any elements with an invalid value. + +This fixes potentially bad shifts in the processing of these inside +the cfg80211_gen_new_bssid() function later. + +I found this during the investigation of CVE-2022-41674 fixed by the +previous patch. + +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Fixes: 78ac51f81532 ("mac80211: support multi-bssid") +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1413,6 +1413,8 @@ static size_t ieee802_11_find_bssid_prof + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) { + if (elem->datalen < 2) + continue; ++ if (elem->data[0] < 1 || elem->data[0] > 8) ++ continue; + + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 new_bssid[ETH_ALEN]; +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -2103,6 +2103,8 @@ static void cfg80211_parse_mbssid_data(s + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) { + if (elem->datalen < 4) + continue; ++ if (elem->data[0] < 1 || (int)elem->data[0] > 8) ++ continue; + for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 profile_len; + diff --git a/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch b/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch new file mode 100644 index 0000000000..6e97150e90 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch @@ -0,0 +1,94 @@ +From: Johannes Berg +Date: Wed, 28 Sep 2022 22:07:15 +0200 +Subject: [PATCH] wifi: mac80211: fix MBSSID parsing use-after-free + +commit ff05d4b45dd89b922578dac497dcabf57cf771c6 + +When we parse a multi-BSSID element, we might point some +element pointers into the allocated nontransmitted_profile. +However, we free this before returning, causing UAF when the +relevant pointers in the parsed elements are accessed. + +Fix this by not allocating the scratch buffer separately but +as part of the returned structure instead, that way, there +are no lifetime issues with it. + +The scratch buffer introduction as part of the returned data +here is taken from MLO feature work done by Ilan. + +This fixes CVE-2022-42719. + +Fixes: 5023b14cf4df ("mac80211: support profile split between elements") +Co-developed-by: Ilan Peer +Signed-off-by: Ilan Peer +Reviewed-by: Kees Cook +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1611,6 +1611,14 @@ struct ieee802_11_elems { + + /* whether a parse error occurred while retrieving these elements */ + bool parse_error; ++ ++ /* ++ * scratch buffer that can be used for various element parsing related ++ * tasks, e.g., element de-fragmentation etc. ++ */ ++ size_t scratch_len; ++ u8 *scratch_pos; ++ u8 scratch[]; + }; + + static inline struct ieee80211_local *hw_to_local( +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1478,24 +1478,25 @@ struct ieee802_11_elems *ieee802_11_pars + u8 *nontransmitted_profile; + int nontransmitted_profile_len = 0; + +- elems = kzalloc(sizeof(*elems), GFP_ATOMIC); ++ elems = kzalloc(sizeof(*elems) + len, GFP_ATOMIC); + if (!elems) + return NULL; + elems->ie_start = start; + elems->total_len = len; + +- nontransmitted_profile = kmalloc(len, GFP_ATOMIC); +- if (nontransmitted_profile) { +- nontransmitted_profile_len = +- ieee802_11_find_bssid_profile(start, len, elems, +- transmitter_bssid, +- bss_bssid, +- nontransmitted_profile); +- non_inherit = +- cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, +- nontransmitted_profile, +- nontransmitted_profile_len); +- } ++ elems->scratch_len = len; ++ elems->scratch_pos = elems->scratch; ++ ++ nontransmitted_profile = elems->scratch_pos; ++ nontransmitted_profile_len = ++ ieee802_11_find_bssid_profile(start, len, elems, ++ transmitter_bssid, ++ bss_bssid, ++ nontransmitted_profile); ++ non_inherit = ++ cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, ++ nontransmitted_profile, ++ nontransmitted_profile_len); + + crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter, + crc, non_inherit); +@@ -1524,8 +1525,6 @@ struct ieee802_11_elems *ieee802_11_pars + offsetofend(struct ieee80211_bssid_index, dtim_count)) + elems->dtim_count = elems->bssid_index->dtim_count; + +- kfree(nontransmitted_profile); +- + elems->crc = crc; + + return elems; diff --git a/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-ensure-length-byte-is-present-before-a.patch b/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-ensure-length-byte-is-present-before-a.patch new file mode 100644 index 0000000000..da94840dac --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-ensure-length-byte-is-present-before-a.patch @@ -0,0 +1,41 @@ +From: Johannes Berg +Date: Thu, 29 Sep 2022 21:50:44 +0200 +Subject: [PATCH] wifi: cfg80211: ensure length byte is present before + access + +commit 567e14e39e8f8c6997a1378bc3be615afca86063 upstream. + +When iterating the elements here, ensure the length byte is +present before checking it to see if the entire element will +fit into the buffer. + +Longer term, we should rewrite this code using the type-safe +element iteration macros that check all of this. + +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Reported-by: Soenke Huster +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -304,7 +304,8 @@ static size_t cfg80211_gen_new_ie(const + tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen); + tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie; + +- while (tmp_old + tmp_old[1] + 2 - ie <= ielen) { ++ while (tmp_old + 2 - ie <= ielen && ++ tmp_old + tmp_old[1] + 2 - ie <= ielen) { + if (tmp_old[0] == 0) { + tmp_old++; + continue; +@@ -364,7 +365,8 @@ static size_t cfg80211_gen_new_ie(const + * copied to new ie, skip ssid, capability, bssid-index ie + */ + tmp_new = sub_copy; +- while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { ++ while (tmp_new + 2 - sub_copy <= subie_len && ++ tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { + if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP || + tmp_new[0] == WLAN_EID_SSID)) { + memcpy(pos, tmp_new, tmp_new[1] + 2); diff --git a/package/kernel/mac80211/patches/subsys/355-wifi-cfg80211-fix-BSS-refcounting-bugs.patch b/package/kernel/mac80211/patches/subsys/355-wifi-cfg80211-fix-BSS-refcounting-bugs.patch new file mode 100644 index 0000000000..4680e1e815 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/355-wifi-cfg80211-fix-BSS-refcounting-bugs.patch @@ -0,0 +1,87 @@ +From: Johannes Berg +Date: Fri, 30 Sep 2022 23:44:23 +0200 +Subject: [PATCH] wifi: cfg80211: fix BSS refcounting bugs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 0b7808818cb9df6680f98996b8e9a439fa7bcc2f upstream. + +There are multiple refcounting bugs related to multi-BSSID: + - In bss_ref_get(), if the BSS has a hidden_beacon_bss, then + the bss pointer is overwritten before checking for the + transmitted BSS, which is clearly wrong. Fix this by using + the bss_from_pub() macro. + + - In cfg80211_bss_update() we copy the transmitted_bss pointer + from tmp into new, but then if we release new, we'll unref + it erroneously. We already set the pointer and ref it, but + need to NULL it since it was copied from the tmp data. + + - In cfg80211_inform_single_bss_data(), if adding to the non- + transmitted list fails, we unlink the BSS and yet still we + return it, but this results in returning an entry without + a reference. We shouldn't return it anyway if it was broken + enough to not get added there. + +This fixes CVE-2022-42720. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: a3584f56de1c ("cfg80211: Properly track transmitting and non-transmitting BSS") +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cf + lockdep_assert_held(&rdev->bss_lock); + + bss->refcount++; +- if (bss->pub.hidden_beacon_bss) { +- bss = container_of(bss->pub.hidden_beacon_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } +- if (bss->pub.transmitted_bss) { +- bss = container_of(bss->pub.transmitted_bss, +- struct cfg80211_internal_bss, +- pub); +- bss->refcount++; +- } ++ ++ if (bss->pub.hidden_beacon_bss) ++ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++; ++ ++ if (bss->pub.transmitted_bss) ++ bss_from_pub(bss->pub.transmitted_bss)->refcount++; + } + + static inline void bss_ref_put(struct cfg80211_registered_device *rdev, +@@ -1743,6 +1737,8 @@ cfg80211_bss_update(struct cfg80211_regi + new->refcount = 1; + INIT_LIST_HEAD(&new->hidden_list); + INIT_LIST_HEAD(&new->pub.nontrans_list); ++ /* we'll set this later if it was non-NULL */ ++ new->pub.transmitted_bss = NULL; + + if (rcu_access_pointer(tmp->pub.proberesp_ies)) { + hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN); +@@ -1983,10 +1979,15 @@ cfg80211_inform_single_bss_data(struct w + spin_lock_bh(&rdev->bss_lock); + if (cfg80211_add_nontrans_list(non_tx_data->tx_bss, + &res->pub)) { +- if (__cfg80211_unlink_bss(rdev, res)) ++ if (__cfg80211_unlink_bss(rdev, res)) { + rdev->bss_generation++; ++ res = NULL; ++ } + } + spin_unlock_bh(&rdev->bss_lock); ++ ++ if (!res) ++ return NULL; + } + + trace_cfg80211_return_bss(&res->pub); diff --git a/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch b/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch new file mode 100644 index 0000000000..db0e51edc2 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch @@ -0,0 +1,48 @@ +From: Johannes Berg +Date: Sat, 1 Oct 2022 00:01:44 +0200 +Subject: [PATCH] wifi: cfg80211: avoid nontransmitted BSS list + corruption +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit bcca852027e5878aec911a347407ecc88d6fff7f upstream. + +If a non-transmitted BSS shares enough information (both +SSID and BSSID!) with another non-transmitted BSS of a +different AP, then we can find and update it, and then +try to add it to the non-transmitted BSS list. We do a +search for it on the transmitted BSS, but if it's not +there (but belongs to another transmitted BSS), the list +gets corrupted. + +Since this is an erroneous situation, simply fail the +list insertion in this case and free the non-transmitted +BSS. + +This fixes CVE-2022-42721. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -425,6 +425,15 @@ cfg80211_add_nontrans_list(struct cfg802 + + rcu_read_unlock(); + ++ /* ++ * This is a bit weird - it's not on the list, but already on another ++ * one! The only way that could happen is if there's some BSSID/SSID ++ * shared by multiple APs in their multi-BSSID profiles, potentially ++ * with hidden SSID mixed in ... ignore it. ++ */ ++ if (!list_empty(&nontrans_bss->nontrans_list)) ++ return -EINVAL; ++ + /* add to the list */ + list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list); + return 0; diff --git a/package/kernel/mac80211/patches/subsys/357-wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch b/package/kernel/mac80211/patches/subsys/357-wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch new file mode 100644 index 0000000000..ed834ff296 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/357-wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch @@ -0,0 +1,31 @@ +From: Johannes Berg +Date: Wed, 5 Oct 2022 15:10:09 +0200 +Subject: [PATCH] wifi: mac80211_hwsim: avoid mac80211 warning on bad + rate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 1833b6f46d7e2830251a063935ab464256defe22 upstream. + +If the tool on the other side (e.g. wmediumd) gets confused +about the rate, we hit a warning in mac80211. Silence that +by effectively duplicating the check here and dropping the +frame silently (in mac80211 it's dropped with the warning). + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Signed-off-by: Johannes Berg +--- + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -3760,6 +3760,8 @@ static int hwsim_cloned_frame_received_n + + rx_status.band = channel->band; + rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); ++ if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates) ++ goto out; + rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); + + hdr = (void *)skb->data; diff --git a/package/kernel/mac80211/patches/subsys/358-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch b/package/kernel/mac80211/patches/subsys/358-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch new file mode 100644 index 0000000000..44b8729977 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/358-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch @@ -0,0 +1,52 @@ +From: Johannes Berg +Date: Wed, 5 Oct 2022 21:24:10 +0200 +Subject: [PATCH] wifi: mac80211: fix crash in beacon protection for + P2P-device +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit b2d03cabe2b2e150ff5a381731ea0355459be09f upstream. + +If beacon protection is active but the beacon cannot be +decrypted or is otherwise malformed, we call the cfg80211 +API to report this to userspace, but that uses a netdev +pointer, which isn't present for P2P-Device. Fix this to +call it only conditionally to ensure cfg80211 won't crash +in the case of P2P-Device. + +This fixes CVE-2022-42722. + +Reported-by: Sönke Huster +Fixes: 9eaf183af741 ("mac80211: Report beacon protection failures to user space") +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1986,10 +1986,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_ + + if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS || + mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS + +- NUM_DEFAULT_BEACON_KEYS) { +- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, +- skb->data, +- skb->len); ++ NUM_DEFAULT_BEACON_KEYS) { ++ if (rx->sdata->dev) ++ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, ++ skb->data, ++ skb->len); + return RX_DROP_MONITOR; /* unexpected BIP keyidx */ + } + +@@ -2137,7 +2138,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_ + /* either the frame has been decrypted or will be dropped */ + status->flag |= RX_FLAG_DECRYPTED; + +- if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE)) ++ if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE && ++ rx->sdata->dev)) + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, + skb->data, skb->len); + diff --git a/package/kernel/mac80211/patches/subsys/359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch b/package/kernel/mac80211/patches/subsys/359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch new file mode 100644 index 0000000000..c689fac854 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch @@ -0,0 +1,85 @@ +From: Johannes Berg +Date: Wed, 5 Oct 2022 23:11:43 +0200 +Subject: [PATCH] wifi: cfg80211: update hidden BSSes to avoid WARN_ON +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit c90b93b5b782891ebfda49d4e5da36632fefd5d1 upstream. + +When updating beacon elements in a non-transmitted BSS, +also update the hidden sub-entries to the same beacon +elements, so that a future update through other paths +won't trigger a WARN_ON(). + +The warning is triggered because the beacon elements in +the hidden BSSes that are children of the BSS should +always be the same as in the parent. + +Reported-by: Sönke Huster +Tested-by: Sönke Huster +Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning") +Signed-off-by: Johannes Berg +--- + +--- a/net/wireless/scan.c ++++ b/net/wireless/scan.c +@@ -1609,6 +1609,23 @@ struct cfg80211_non_tx_bss { + u8 bssid_index; + }; + ++static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known, ++ const struct cfg80211_bss_ies *new_ies, ++ const struct cfg80211_bss_ies *old_ies) ++{ ++ struct cfg80211_internal_bss *bss; ++ ++ /* Assign beacon IEs to all sub entries */ ++ list_for_each_entry(bss, &known->hidden_list, hidden_list) { ++ const struct cfg80211_bss_ies *ies; ++ ++ ies = rcu_access_pointer(bss->pub.beacon_ies); ++ WARN_ON(ies != old_ies); ++ ++ rcu_assign_pointer(bss->pub.beacon_ies, new_ies); ++ } ++} ++ + static bool + cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, + struct cfg80211_internal_bss *known, +@@ -1632,7 +1649,6 @@ cfg80211_update_known_bss(struct cfg8021 + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); + } else if (rcu_access_pointer(new->pub.beacon_ies)) { + const struct cfg80211_bss_ies *old; +- struct cfg80211_internal_bss *bss; + + if (known->pub.hidden_beacon_bss && + !list_empty(&known->hidden_list)) { +@@ -1660,16 +1676,7 @@ cfg80211_update_known_bss(struct cfg8021 + if (old == rcu_access_pointer(known->pub.ies)) + rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies); + +- /* Assign beacon IEs to all sub entries */ +- list_for_each_entry(bss, &known->hidden_list, hidden_list) { +- const struct cfg80211_bss_ies *ies; +- +- ies = rcu_access_pointer(bss->pub.beacon_ies); +- WARN_ON(ies != old); +- +- rcu_assign_pointer(bss->pub.beacon_ies, +- new->pub.beacon_ies); +- } ++ cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old); + + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); +@@ -2319,6 +2326,8 @@ cfg80211_update_notlisted_nontrans(struc + } else { + old = rcu_access_pointer(nontrans_bss->beacon_ies); + rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies); ++ cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss), ++ new_ies, old); + rcu_assign_pointer(nontrans_bss->ies, new_ies); + if (old) + kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); diff --git a/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch index 0e58b61602..50b6b94fbf 100644 --- a/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch +++ b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch @@ -29,7 +29,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c -@@ -461,16 +461,19 @@ static void __ieee80211_scan_completed(s +@@ -465,16 +465,19 @@ static void __ieee80211_scan_completed(s scan_req = rcu_dereference_protected(local->scan_req, lockdep_is_held(&local->mtx)); diff --git a/package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch b/package/kernel/mac80211/patches/subsys/363-bss-color-collision.patch similarity index 96% rename from package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch rename to package/kernel/mac80211/patches/subsys/363-bss-color-collision.patch index 1e3486accd..edee4b3ee0 100644 --- a/package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch +++ b/package/kernel/mac80211/patches/subsys/363-bss-color-collision.patch @@ -56,7 +56,7 @@ Signed-off-by: Johannes Berg --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -3180,6 +3180,49 @@ static void ieee80211_process_sa_query_r +@@ -3182,6 +3182,49 @@ static void ieee80211_process_sa_query_r ieee80211_tx_skb(sdata, skb); } @@ -106,7 +106,7 @@ Signed-off-by: Johannes Berg static ieee80211_rx_result debug_noinline ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) { -@@ -3205,6 +3248,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802 +@@ -3207,6 +3250,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802 !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { int sig = 0; diff --git a/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch b/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch new file mode 100644 index 0000000000..d133ed91eb --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch @@ -0,0 +1,513 @@ +From: Felix Fietkau +Date: Sun, 9 Oct 2022 20:15:46 +0200 +Subject: [PATCH] mac80211: add support for restricting netdev features per vif + +This can be used to selectively disable feature flags for checksum offload, +scatter/gather or GSO by changing vif->netdev_features. +Removing features from vif->netdev_features does not affect the netdev +features themselves, but instead fixes up skbs in the tx path so that the +offloads are not needed in the driver. + +Aside from making it easier to deal with vif type based hardware limitations, +this also makes it possible to optimize performance on hardware without native +GSO support by declaring GSO support in hw->netdev_features and removing it +from vif->netdev_features. This allows mac80211 to handle GSO segmentation +after the sta lookup, but before itxq enqueue, thus reducing the number of +unnecessary sta lookups, as well as some other per-packet processing. + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/fq_impl.h ++++ b/include/net/fq_impl.h +@@ -200,6 +200,7 @@ static void fq_tin_enqueue(struct fq *fq + fq_skb_free_t free_func) + { + struct fq_flow *flow; ++ struct sk_buff *next; + bool oom; + + lockdep_assert_held(&fq->lock); +@@ -214,11 +215,15 @@ static void fq_tin_enqueue(struct fq *fq + } + + flow->tin = tin; +- flow->backlog += skb->len; +- tin->backlog_bytes += skb->len; +- tin->backlog_packets++; +- fq->memory_usage += skb->truesize; +- fq->backlog++; ++ skb_list_walk_safe(skb, skb, next) { ++ skb_mark_not_on_list(skb); ++ flow->backlog += skb->len; ++ tin->backlog_bytes += skb->len; ++ tin->backlog_packets++; ++ fq->memory_usage += skb->truesize; ++ fq->backlog++; ++ __skb_queue_tail(&flow->queue, skb); ++ } + + if (list_empty(&flow->flowchain)) { + flow->deficit = fq->quantum; +@@ -226,7 +231,6 @@ static void fq_tin_enqueue(struct fq *fq + &tin->new_flows); + } + +- __skb_queue_tail(&flow->queue, skb); + oom = (fq->memory_usage > fq->memory_limit); + while (fq->backlog > fq->limit || oom) { + flow = fq_find_fattest_flow(fq); +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1685,6 +1685,10 @@ enum ieee80211_offload_flags { + * write-protected by sdata_lock and local->mtx so holding either is fine + * for read access. + * @mu_mimo_owner: indicates interface owns MU-MIMO capability ++ * @netdev_features: tx netdev features supported by the hardware for this ++ * vif. mac80211 initializes this to hw->netdev_features, and the driver ++ * can mask out specific tx features. mac80211 will handle software fixup ++ * for masked offloads (GSO, CSUM) + * @driver_flags: flags/capabilities the driver has for this interface, + * these need to be set (or cleared) when the interface is added + * or, if supported by the driver, the interface type is changed +@@ -1736,6 +1740,7 @@ struct ieee80211_vif { + + struct ieee80211_chanctx_conf __rcu *chanctx_conf; + ++ netdev_features_t netdev_features; + u32 driver_flags; + u32 offload_flags; + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -2209,6 +2209,7 @@ int ieee80211_if_add(struct ieee80211_lo + ndev->features |= local->hw.netdev_features; + ndev->hw_features |= ndev->features & + MAC80211_SUPPORTED_FEATURES_TX; ++ sdata->vif.netdev_features = local->hw.netdev_features; + + netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1310,7 +1310,11 @@ static struct txq_info *ieee80211_get_tx + + static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) + { +- IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); ++ struct sk_buff *next; ++ codel_time_t now = codel_get_time(); ++ ++ skb_list_walk_safe(skb, skb, next) ++ IEEE80211_SKB_CB(skb)->control.enqueue_time = now; + } + + static u32 codel_skb_len_func(const struct sk_buff *skb) +@@ -3499,47 +3503,71 @@ ieee80211_xmit_fast_finish(struct ieee80 + return TX_CONTINUE; + } + +-static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, +- struct sta_info *sta, +- struct ieee80211_fast_tx *fast_tx, +- struct sk_buff *skb) ++static netdev_features_t ++ieee80211_sdata_netdev_features(struct ieee80211_sub_if_data *sdata) + { +- struct ieee80211_local *local = sdata->local; +- u16 ethertype = (skb->data[12] << 8) | skb->data[13]; +- int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); +- int hw_headroom = sdata->local->hw.extra_tx_headroom; +- struct ethhdr eth; +- struct ieee80211_tx_info *info; +- struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; +- struct ieee80211_tx_data tx; +- ieee80211_tx_result r; +- struct tid_ampdu_tx *tid_tx = NULL; +- u8 tid = IEEE80211_NUM_TIDS; ++ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) ++ return sdata->vif.netdev_features; + +- /* control port protocol needs a lot of special handling */ +- if (cpu_to_be16(ethertype) == sdata->control_port_protocol) +- return false; ++ if (!sdata->bss) ++ return 0; + +- /* only RFC 1042 SNAP */ +- if (ethertype < ETH_P_802_3_MIN) +- return false; ++ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); ++ return sdata->vif.netdev_features; ++} + +- /* don't handle TX status request here either */ +- if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) +- return false; ++static struct sk_buff * ++ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features) ++{ ++ if (skb_is_gso(skb)) { ++ struct sk_buff *segs; + +- if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { +- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; +- tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); +- if (tid_tx) { +- if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) +- return false; +- if (tid_tx->timeout) +- tid_tx->last_tx = jiffies; +- } ++ segs = skb_gso_segment(skb, features); ++ if (!segs) ++ return skb; ++ if (IS_ERR(segs)) ++ goto free; ++ ++ consume_skb(skb); ++ return segs; ++ } ++ ++ if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) ++ goto free; ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ int ofs = skb_checksum_start_offset(skb); ++ ++ if (skb->encapsulation) ++ skb_set_inner_transport_header(skb, ofs); ++ else ++ skb_set_transport_header(skb, ofs); ++ ++ if (skb_csum_hwoffload_help(skb, features)) ++ goto free; + } + +- /* after this point (skb is modified) we cannot return false */ ++ skb_mark_not_on_list(skb); ++ return skb; ++ ++free: ++ kfree_skb(skb); ++ return NULL; ++} ++ ++static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, ++ struct ieee80211_fast_tx *fast_tx, ++ struct sk_buff *skb, u8 tid, bool ampdu) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; ++ struct ieee80211_tx_info *info; ++ struct ieee80211_tx_data tx; ++ ieee80211_tx_result r; ++ int hw_headroom = sdata->local->hw.extra_tx_headroom; ++ int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); ++ struct ethhdr eth; + + if (skb_shared(skb)) { + struct sk_buff *tmp_skb = skb; +@@ -3548,12 +3576,12 @@ static bool ieee80211_xmit_fast(struct i + kfree_skb(tmp_skb); + + if (!skb) +- return true; ++ return; + } + + if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) && + ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb)) +- return true; ++ return; + + /* will not be crypto-handled beyond what we do here, so use false + * as the may-encrypt argument for the resize to not account for +@@ -3562,10 +3590,8 @@ static bool ieee80211_xmit_fast(struct i + if (unlikely(ieee80211_skb_resize(sdata, skb, + max_t(int, extra_head + hw_headroom - + skb_headroom(skb), 0), +- ENCRYPT_NO))) { +- kfree_skb(skb); +- return true; +- } ++ ENCRYPT_NO))) ++ goto free; + + memcpy(ð, skb->data, ETH_HLEN - 2); + hdr = skb_push(skb, extra_head); +@@ -3579,7 +3605,7 @@ static bool ieee80211_xmit_fast(struct i + info->control.vif = &sdata->vif; + info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | + IEEE80211_TX_CTL_DONTFRAG | +- (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); ++ (ampdu ? IEEE80211_TX_CTL_AMPDU : 0); + info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT; + + #ifdef CPTCFG_MAC80211_DEBUGFS +@@ -3601,16 +3627,14 @@ static bool ieee80211_xmit_fast(struct i + tx.key = fast_tx->key; + + if (ieee80211_queue_skb(local, sdata, sta, skb)) +- return true; ++ return; + + tx.skb = skb; + r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, + fast_tx->key, &tx); + tx.skb = NULL; +- if (r == TX_DROP) { +- kfree_skb(skb); +- return true; +- } ++ if (r == TX_DROP) ++ goto free; + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + sdata = container_of(sdata->bss, +@@ -3618,6 +3642,55 @@ static bool ieee80211_xmit_fast(struct i + + __skb_queue_tail(&tx.skbs, skb); + ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false); ++ return; ++ ++free: ++ kfree_skb(skb); ++} ++ ++static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, ++ struct ieee80211_fast_tx *fast_tx, ++ struct sk_buff *skb) ++{ ++ u16 ethertype = (skb->data[12] << 8) | skb->data[13]; ++ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; ++ struct tid_ampdu_tx *tid_tx = NULL; ++ struct sk_buff *next; ++ u8 tid = IEEE80211_NUM_TIDS; ++ ++ /* control port protocol needs a lot of special handling */ ++ if (cpu_to_be16(ethertype) == sdata->control_port_protocol) ++ return false; ++ ++ /* only RFC 1042 SNAP */ ++ if (ethertype < ETH_P_802_3_MIN) ++ return false; ++ ++ /* don't handle TX status request here either */ ++ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) ++ return false; ++ ++ if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { ++ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; ++ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); ++ if (tid_tx) { ++ if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) ++ return false; ++ if (tid_tx->timeout) ++ tid_tx->last_tx = jiffies; ++ } ++ } ++ ++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); ++ if (!skb) ++ return true; ++ ++ skb_list_walk_safe(skb, skb, next) { ++ skb_mark_not_on_list(skb); ++ __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx); ++ } ++ + return true; + } + +@@ -4123,31 +4196,14 @@ void __ieee80211_subif_start_xmit(struct + goto out; + } + +- if (skb_is_gso(skb)) { +- struct sk_buff *segs; +- +- segs = skb_gso_segment(skb, 0); +- if (IS_ERR(segs)) { +- goto out_free; +- } else if (segs) { +- consume_skb(skb); +- skb = segs; +- } +- } else { +- /* we cannot process non-linear frames on this path */ +- if (skb_linearize(skb)) +- goto out_free; +- +- /* the frame could be fragmented, software-encrypted, and other +- * things so we cannot really handle checksum offload with it - +- * fix it up in software before we handle anything else. +- */ +- if (skb->ip_summed == CHECKSUM_PARTIAL) { +- skb_set_transport_header(skb, +- skb_checksum_start_offset(skb)); +- if (skb_checksum_help(skb)) +- goto out_free; +- } ++ /* the frame could be fragmented, software-encrypted, and other ++ * things so we cannot really handle checksum or GSO offload. ++ * fix it up in software before we handle anything else. ++ */ ++ skb = ieee80211_tx_skb_fixup(skb, 0); ++ if (!skb) { ++ len = 0; ++ goto out; + } + + skb_list_walk_safe(skb, skb, next) { +@@ -4310,9 +4366,11 @@ netdev_tx_t ieee80211_subif_start_xmit(s + return NETDEV_TX_OK; + } + +-static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, +- struct sk_buff *skb, struct sta_info *sta, +- bool txpending) ++ ++ ++static bool __ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, struct sta_info *sta, ++ bool txpending) + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_tx_control control = {}; +@@ -4321,14 +4379,6 @@ static bool ieee80211_tx_8023(struct iee + unsigned long flags; + int q = info->hw_queue; + +- if (sta) +- sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift); +- +- ieee80211_tpt_led_trig_tx(local, skb->len); +- +- if (ieee80211_queue_skb(local, sdata, sta, skb)) +- return true; +- + spin_lock_irqsave(&local->queue_stop_reason_lock, flags); + + if (local->queue_stop_reasons[q] || +@@ -4355,27 +4405,50 @@ static bool ieee80211_tx_8023(struct iee + return true; + } + ++static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, struct sta_info *sta, ++ bool txpending) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct sk_buff *next; ++ bool ret = true; ++ ++ if (ieee80211_queue_skb(local, sdata, sta, skb)) ++ return true; ++ ++ skb_list_walk_safe(skb, skb, next) { ++ skb_mark_not_on_list(skb); ++ if (!__ieee80211_tx_8023(sdata, skb, sta, txpending)) ++ ret = false; ++ } ++ ++ return ret; ++} ++ + static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, + struct net_device *dev, struct sta_info *sta, + struct ieee80211_key *key, struct sk_buff *skb) + { +- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); ++ struct ieee80211_tx_info *info; + struct ieee80211_local *local = sdata->local; + struct tid_ampdu_tx *tid_tx; ++ struct sk_buff *seg, *next; ++ unsigned int skbs = 0, len = 0; ++ u16 queue; + u8 tid; + + if (local->ops->wake_tx_queue) { +- u16 queue = __ieee80211_select_queue(sdata, sta, skb); ++ queue = __ieee80211_select_queue(sdata, sta, skb); + skb_set_queue_mapping(skb, queue); + skb_get_hash(skb); ++ } else { ++ queue = skb_get_queue_mapping(skb); + } + + if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && + test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) + goto out_free; + +- memset(info, 0, sizeof(*info)); +- + ieee80211_aggr_check(sdata, sta, skb); + + tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; +@@ -4387,22 +4460,20 @@ static void ieee80211_8023_xmit(struct i + return; + } + +- info->flags |= IEEE80211_TX_CTL_AMPDU; + if (tid_tx->timeout) + tid_tx->last_tx = jiffies; + } + +- if (unlikely(skb->sk && +- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) +- info->ack_frame_id = ieee80211_store_ack_skb(local, skb, +- &info->flags, NULL); ++ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); ++ if (!skb) ++ return; + +- info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; ++ info = IEEE80211_SKB_CB(skb); ++ memset(info, 0, sizeof(*info)); ++ if (tid_tx) ++ info->flags |= IEEE80211_TX_CTL_AMPDU; + +- dev_sw_netstats_tx_add(dev, 1, skb->len); +- +- sta->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; +- sta->tx_stats.packets[skb_get_queue_mapping(skb)]++; ++ info->hw_queue = sdata->vif.hw_queue[queue]; + + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + sdata = container_of(sdata->bss, +@@ -4414,6 +4485,24 @@ static void ieee80211_8023_xmit(struct i + if (key) + info->control.hw_key = &key->conf; + ++ skb_list_walk_safe(skb, seg, next) { ++ skbs++; ++ len += seg->len; ++ if (seg != skb) ++ memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); ++ } ++ ++ if (unlikely(skb->sk && ++ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) ++ info->ack_frame_id = ieee80211_store_ack_skb(local, skb, ++ &info->flags, NULL); ++ ++ dev_sw_netstats_tx_add(dev, skbs, len); ++ sta->tx_stats.packets[queue] += skbs; ++ sta->tx_stats.bytes[queue] += len; ++ ++ ieee80211_tpt_led_trig_tx(local, len); ++ + ieee80211_tx_8023(sdata, skb, sta, false); + + return; +@@ -4455,6 +4544,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 + key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) + goto skip_offload; + ++ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); + ieee80211_8023_xmit(sdata, dev, sta, key, skb); + goto out; + diff --git a/package/libs/libubox/Makefile b/package/libs/libubox/Makefile index 9ad4c30595..e19a97cbba 100644 --- a/package/libs/libubox/Makefile +++ b/package/libs/libubox/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/libubox.git -PKG_MIRROR_HASH:=cf48d00ed0ea74d53f2043eb9f9dc52834c0b214f258201cf22dfff7dd6c6e40 -PKG_SOURCE_DATE:=2022-05-15 -PKG_SOURCE_VERSION:=d2223ef9da7172a84d1508733dc58840e1381e3c +PKG_MIRROR_HASH:=400bef38b8c0f382e4e595a50bb52dfbdb8da820eb80f3447b9bd7be3f5499a5 +PKG_SOURCE_DATE:=2022-09-27 +PKG_SOURCE_VERSION:=ea56013409d5823001b47a9bba6f74055a6d76a5 PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE)) CMAKE_INSTALL:=1 diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 85281f4197..b7b8343892 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -2019,6 +2019,7 @@ void hostapd_ubus_notify_beacon_report( blobmsg_add_macaddr(&b, "bssid", rep->bssid); blobmsg_add_u16(&b, "antenna-id", rep->antenna_id); blobmsg_add_u16(&b, "parent-tsf", rep->parent_tsf); + blobmsg_add_u16(&b, "rep-mode", rep_mode); ubus_notify(ctx, &hapd->ubus.obj, "beacon-report", b.head, -1); } diff --git a/package/network/utils/iwinfo/Makefile b/package/network/utils/iwinfo/Makefile index 9d17e0343a..686b3cef8d 100644 --- a/package/network/utils/iwinfo/Makefile +++ b/package/network/utils/iwinfo/Makefile @@ -11,9 +11,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git -PKG_SOURCE_DATE:=2022-09-22 -PKG_SOURCE_VERSION:=4a43b0d40ba50a21de1d47e7bf0f759be9cf646a -PKG_MIRROR_HASH:=4df2c5ac8cb60e4df06a4ef9a87c3a5196f0a8739ee39e6a2587c15527612250 +PKG_SOURCE_DATE:=2022-10-14 +PKG_SOURCE_VERSION:=0496c722f1d798789d9280d9e357f87b920349eb +PKG_MIRROR_HASH:=6dcbb79b3ebcad3f013a162ee1b18535a05afe9be9bf578cf62d9cf0b210f9df PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=GPL-2.0 diff --git a/target/linux/airoha/generic/target.mk b/target/linux/airoha/generic/target.mk new file mode 100644 index 0000000000..f5cb1fb19b --- /dev/null +++ b/target/linux/airoha/generic/target.mk @@ -0,0 +1 @@ +BOARDNAME:=Generic diff --git a/target/linux/archs38/config-5.10 b/target/linux/archs38/config-5.10 index 1460d35535..442f741328 100644 --- a/target/linux/archs38/config-5.10 +++ b/target/linux/archs38/config-5.10 @@ -152,8 +152,6 @@ CONFIG_IIO_ST_SENSORS_I2C=y CONFIG_IIO_ST_SENSORS_SPI=y CONFIG_IIO_TRIGGER=y CONFIG_IIO_TRIGGERED_BUFFER=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_IRQCHIP=y CONFIG_IRQ_DOMAIN=y diff --git a/target/linux/bcm27xx/bcm2708/config-5.15 b/target/linux/bcm27xx/bcm2708/config-5.15 index 9f2c6f266f..6fde682ffd 100644 --- a/target/linux/bcm27xx/bcm2708/config-5.15 +++ b/target/linux/bcm27xx/bcm2708/config-5.15 @@ -199,8 +199,6 @@ CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_BRCMSTB is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set diff --git a/target/linux/bcm27xx/bcm2709/config-5.15 b/target/linux/bcm27xx/bcm2709/config-5.15 index 7a01f594e2..63e3b3bdbb 100644 --- a/target/linux/bcm27xx/bcm2709/config-5.15 +++ b/target/linux/bcm27xx/bcm2709/config-5.15 @@ -252,8 +252,6 @@ CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_BRCMSTB is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set diff --git a/target/linux/bcm27xx/bcm2710/config-5.15 b/target/linux/bcm27xx/bcm2710/config-5.15 index 308a9246cc..2f1b82484e 100644 --- a/target/linux/bcm27xx/bcm2710/config-5.15 +++ b/target/linux/bcm27xx/bcm2710/config-5.15 @@ -249,8 +249,6 @@ CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_BRCMSTB is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y diff --git a/target/linux/bcm27xx/bcm2711/config-5.15 b/target/linux/bcm27xx/bcm2711/config-5.15 index e9e50ea26d..61ced4508a 100644 --- a/target/linux/bcm27xx/bcm2711/config-5.15 +++ b/target/linux/bcm27xx/bcm2711/config-5.15 @@ -256,8 +256,6 @@ CONFIG_I2C=y # CONFIG_I2C_BCM2708 is not set CONFIG_I2C_BOARDINFO=y # CONFIG_I2C_BRCMSTB is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INPUT=y CONFIG_INPUT_MOUSEDEV=y diff --git a/target/linux/bcm53xx/patches-5.10/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch b/target/linux/bcm53xx/patches-5.10/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch new file mode 100644 index 0000000000..8d15abf915 --- /dev/null +++ b/target/linux/bcm53xx/patches-5.10/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch @@ -0,0 +1,32 @@ +From e492f69e4da879db7b3e9a2290e5b6620f1335b5 Mon Sep 17 00:00:00 2001 +From: Aleksey Nasibulin +Date: Thu, 13 Oct 2022 08:16:51 +0000 +Subject: [PATCH] ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys + EA6500 V2 + +Linksys ea6500-v2 have 256MB of ram. Currently we only use 128MB. +Expand the definition to use all the available RAM. + +Fixes: 03e96644d7a8 ("ARM: dts: BCM5301X: Add basic DT for Linksys EA6500 V2") +Signed-off-by: Aleksey Nasibulin +--- + arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +index f1412ba83def..0454423fe166 100644 +--- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts ++++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +@@ -19,7 +19,8 @@ chosen { + + memory@0 { + device_type = "memory"; +- reg = <0x00000000 0x08000000>; ++ reg = <0x00000000 0x08000000>, ++ <0x88000000 0x08000000>; + }; + + gpio-keys { +-- +2.30.2 + diff --git a/target/linux/bcm53xx/patches-5.15/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch b/target/linux/bcm53xx/patches-5.15/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch new file mode 100644 index 0000000000..8d15abf915 --- /dev/null +++ b/target/linux/bcm53xx/patches-5.15/315-ARM-dts-BCM5301X-Extend-RAM-to-full-256MB-for-Linksy.patch @@ -0,0 +1,32 @@ +From e492f69e4da879db7b3e9a2290e5b6620f1335b5 Mon Sep 17 00:00:00 2001 +From: Aleksey Nasibulin +Date: Thu, 13 Oct 2022 08:16:51 +0000 +Subject: [PATCH] ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys + EA6500 V2 + +Linksys ea6500-v2 have 256MB of ram. Currently we only use 128MB. +Expand the definition to use all the available RAM. + +Fixes: 03e96644d7a8 ("ARM: dts: BCM5301X: Add basic DT for Linksys EA6500 V2") +Signed-off-by: Aleksey Nasibulin +--- + arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +index f1412ba83def..0454423fe166 100644 +--- a/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts ++++ b/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +@@ -19,7 +19,8 @@ chosen { + + memory@0 { + device_type = "memory"; +- reg = <0x00000000 0x08000000>; ++ reg = <0x00000000 0x08000000>, ++ <0x88000000 0x08000000>; + }; + + gpio-keys { +-- +2.30.2 + diff --git a/target/linux/generic/backport-5.10/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch b/target/linux/generic/backport-5.10/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch new file mode 100644 index 0000000000..dd8a1b445d --- /dev/null +++ b/target/linux/generic/backport-5.10/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch @@ -0,0 +1,73 @@ +From 2fd7e7f9317d3048a14026816d081b08ba98ea8e Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Tue, 8 Mar 2022 22:56:13 +0100 +Subject: [PATCH 1/3] Kbuild: use -Wdeclaration-after-statement + +The kernel is moving from using `-std=gnu89` to `-std=gnu11`, permitting +the use of additional C11 features such as for-loop initial declarations. + +One contentious aspect of C99 is that it permits mixed declarations and +code, and for now at least, it seems preferable to enforce that +declarations must come first. + +These warnings were already enabled in the kernel itself, but not +for KBUILD_USERCFLAGS or the compat VDSO on arch/arm64, which uses +a separate set of CFLAGS. + +This patch fixes an existing violation in modpost.c, which is not +reported because of the missing flag in KBUILD_USERCFLAGS: + +| scripts/mod/modpost.c: In function ‘match’: +| scripts/mod/modpost.c:837:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] +| 837 | const char *endp = p + strlen(p) - 1; +| | ^~~~~ + +Signed-off-by: Mark Rutland +[arnd: don't add a duplicate flag to the default set, update changelog] +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Tested-by: Sedat Dilek # LLVM/Clang v13.0.0 (x86-64) +Signed-off-by: Masahiro Yamada +--- + Makefile | 3 ++- + arch/arm64/kernel/vdso32/Makefile | 1 + + scripts/mod/modpost.c | 4 +++- + 3 files changed, 6 insertions(+), 2 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -416,7 +416,8 @@ HOSTCXX = g++ + endif + + export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ +- -O2 -fomit-frame-pointer -std=gnu89 ++ -O2 -fomit-frame-pointer -std=gnu89 \ ++ -Wdeclaration-after-statement + export KBUILD_USERLDFLAGS := + + KBUILD_HOSTCFLAGS := $(KBUILD_USERCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) +--- a/arch/arm64/kernel/vdso32/Makefile ++++ b/arch/arm64/kernel/vdso32/Makefile +@@ -76,6 +76,7 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-pr + -fno-strict-aliasing -fno-common \ + -Werror-implicit-function-declaration \ + -Wno-format-security \ ++ -Wdeclaration-after-statement \ + -std=gnu89 + VDSO_CFLAGS += -O2 + # Some useful compiler-dependent flags from top-level Makefile +--- a/scripts/mod/modpost.c ++++ b/scripts/mod/modpost.c +@@ -844,8 +844,10 @@ static int match(const char *sym, const + { + const char *p; + while (*pat) { ++ const char *endp; ++ + p = *pat++; +- const char *endp = p + strlen(p) - 1; ++ endp = p + strlen(p) - 1; + + /* "*foo*" */ + if (*p == '*' && *endp == '*') { diff --git a/target/linux/generic/backport-5.10/005-v5.17-02-Kbuild-move-to-std-gnu11.patch b/target/linux/generic/backport-5.10/005-v5.17-02-Kbuild-move-to-std-gnu11.patch new file mode 100644 index 0000000000..7938fe5026 --- /dev/null +++ b/target/linux/generic/backport-5.10/005-v5.17-02-Kbuild-move-to-std-gnu11.patch @@ -0,0 +1,60 @@ +From b810c8e719ea082e47c7a8f7cf878bc84fa2455d Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Mar 2022 22:56:14 +0100 +Subject: [PATCH 2/3] Kbuild: move to -std=gnu11 + +During a patch discussion, Linus brought up the option of changing +the C standard version from gnu89 to gnu99, which allows using variable +declaration inside of a for() loop. While the C99, C11 and later standards +introduce many other features, most of these are already available in +gnu89 as GNU extensions as well. + +An earlier attempt to do this when gcc-5 started defaulting to +-std=gnu11 failed because at the time that caused warnings about +designated initializers with older compilers. Now that gcc-5.1 is +the minimum compiler version used for building kernels, that is no +longer a concern. Similarly, the behavior of 'inline' functions changes +between gnu89 using gnu_inline behavior and gnu11 using standard c99+ +behavior, but this was taken care of by defining 'inline' to include +__attribute__((gnu_inline)) in order to allow building with clang a +while ago. + +Nathan Chancellor reported a new -Wdeclaration-after-statement +warning that appears in a system header on arm, this still needs a +workaround. + +The differences between gnu99, gnu11, gnu1x and gnu17 are fairly +minimal and mainly impact warnings at the -Wpedantic level that the +kernel never enables. Between these, gnu11 is the newest version +that is supported by all supported compiler versions, though it is +only the default on gcc-5, while all other supported versions of +gcc or clang default to gnu1x/gnu17. + +Link: https://lore.kernel.org/lkml/CAHk-=wiyCH7xeHcmiFJ-YgXUy2Jaj7pnkdKpcovt8fYbVFW3TA@mail.gmail.com/ +Link: https://github.com/ClangBuiltLinux/linux/issues/1603 +Suggested-by: Linus Torvalds +Acked-by: Marco Elver +Acked-by: Jani Nikula +Acked-by: David Sterba +Tested-by: Sedat Dilek +Reviewed-by: Alex Shi +Reviewed-by: Nick Desaulniers +Reviewed-by: Miguel Ojeda +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Signed-off-by: Masahiro Yamada +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Makefile ++++ b/Makefile +@@ -498,7 +498,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror + -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ + -Werror=implicit-function-declaration -Werror=implicit-int \ + -Werror=return-type -Wno-format-security \ +- -std=gnu89 ++ -std=gnu11 + KBUILD_CPPFLAGS := -D__KERNEL__ + KBUILD_AFLAGS_KERNEL := + KBUILD_CFLAGS_KERNEL := diff --git a/target/linux/generic/backport-5.10/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch b/target/linux/generic/backport-5.10/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch new file mode 100644 index 0000000000..34b5b653ae --- /dev/null +++ b/target/linux/generic/backport-5.10/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch @@ -0,0 +1,42 @@ +From 40337d6f3d677aee7ad3052ae662d3f53dd4d5cb Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Mar 2022 22:56:15 +0100 +Subject: [PATCH 3/3] Kbuild: use -std=gnu11 for KBUILD_USERCFLAGS + +As we change the C language standard for the kernel from gnu89 to +gnu11, it makes sense to also update the version for user space +compilation. + +Some users have older native compilers than what they use for +kernel builds, so I considered using gnu99 as the default version +for wider compatibility with gcc-4.6 and earlier. + +However, testing with older compilers showed that we already require +HOSTCC version 5.1 as well because a lot of host tools include +linux/compiler.h that uses __has_attribute(): + + CC tools/objtool/exec-cmd.o +In file included from tools/include/linux/compiler_types.h:36:0, + from tools/include/linux/compiler.h:5, + from exec-cmd.c:2: +tools/include/linux/compiler-gcc.h:19:5: error: "__has_attribute" is not defined [-Werror=undef] + +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Tested-by: Sedat Dilek +Signed-off-by: Masahiro Yamada +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Makefile ++++ b/Makefile +@@ -416,7 +416,7 @@ HOSTCXX = g++ + endif + + export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ +- -O2 -fomit-frame-pointer -std=gnu89 \ ++ -O2 -fomit-frame-pointer -std=gnu11 \ + -Wdeclaration-after-statement + export KBUILD_USERLDFLAGS := diff --git a/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch b/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch new file mode 100644 index 0000000000..141a7a18c5 --- /dev/null +++ b/target/linux/generic/backport-5.15/005-v5.17-01-Kbuild-use-Wdeclaration-after-statement.patch @@ -0,0 +1,81 @@ +From 2fd7e7f9317d3048a14026816d081b08ba98ea8e Mon Sep 17 00:00:00 2001 +From: Mark Rutland +Date: Tue, 8 Mar 2022 22:56:13 +0100 +Subject: [PATCH 1/3] Kbuild: use -Wdeclaration-after-statement + +The kernel is moving from using `-std=gnu89` to `-std=gnu11`, permitting +the use of additional C11 features such as for-loop initial declarations. + +One contentious aspect of C99 is that it permits mixed declarations and +code, and for now at least, it seems preferable to enforce that +declarations must come first. + +These warnings were already enabled in the kernel itself, but not +for KBUILD_USERCFLAGS or the compat VDSO on arch/arm64, which uses +a separate set of CFLAGS. + +This patch fixes an existing violation in modpost.c, which is not +reported because of the missing flag in KBUILD_USERCFLAGS: + +| scripts/mod/modpost.c: In function ‘match’: +| scripts/mod/modpost.c:837:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] +| 837 | const char *endp = p + strlen(p) - 1; +| | ^~~~~ + +Signed-off-by: Mark Rutland +[arnd: don't add a duplicate flag to the default set, update changelog] +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Tested-by: Sedat Dilek # LLVM/Clang v13.0.0 (x86-64) +Signed-off-by: Masahiro Yamada +--- + Makefile | 3 ++- + arch/arm64/kernel/vdso32/Makefile | 1 + + scripts/mod/modpost.c | 4 +++- + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/Makefile b/Makefile +index b9e0b5c604af..cfe400032f96 100644 +--- a/Makefile ++++ b/Makefile +@@ -416,7 +416,8 @@ HOSTCXX = g++ + endif + + export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ +- -O2 -fomit-frame-pointer -std=gnu89 ++ -O2 -fomit-frame-pointer -std=gnu89 \ ++ -Wdeclaration-after-statement + export KBUILD_USERLDFLAGS := + + KBUILD_HOSTCFLAGS := $(KBUILD_USERCFLAGS) $(HOST_LFS_CFLAGS) $(HOSTCFLAGS) +diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile +index abad38c576e1..33cd7ed3f94f 100644 +--- a/arch/arm64/kernel/vdso32/Makefile ++++ b/arch/arm64/kernel/vdso32/Makefile +@@ -76,6 +76,7 @@ VDSO_CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -fno-common \ + -Werror-implicit-function-declaration \ + -Wno-format-security \ ++ -Wdeclaration-after-statement \ + -std=gnu89 + VDSO_CFLAGS += -O2 + # Some useful compiler-dependent flags from top-level Makefile +diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c +index 3c27a177b28b..d2b17ed27e6e 100644 +--- a/scripts/mod/modpost.c ++++ b/scripts/mod/modpost.c +@@ -844,8 +844,10 @@ static int match(const char *sym, const char * const pat[]) + { + const char *p; + while (*pat) { ++ const char *endp; ++ + p = *pat++; +- const char *endp = p + strlen(p) - 1; ++ endp = p + strlen(p) - 1; + + /* "*foo*" */ + if (*p == '*' && *endp == '*') { +-- +2.37.2 diff --git a/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch b/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch new file mode 100644 index 0000000000..79bda0cd7e --- /dev/null +++ b/target/linux/generic/backport-5.15/005-v5.17-02-Kbuild-move-to-std-gnu11.patch @@ -0,0 +1,64 @@ +From b810c8e719ea082e47c7a8f7cf878bc84fa2455d Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Mar 2022 22:56:14 +0100 +Subject: [PATCH 2/3] Kbuild: move to -std=gnu11 + +During a patch discussion, Linus brought up the option of changing +the C standard version from gnu89 to gnu99, which allows using variable +declaration inside of a for() loop. While the C99, C11 and later standards +introduce many other features, most of these are already available in +gnu89 as GNU extensions as well. + +An earlier attempt to do this when gcc-5 started defaulting to +-std=gnu11 failed because at the time that caused warnings about +designated initializers with older compilers. Now that gcc-5.1 is +the minimum compiler version used for building kernels, that is no +longer a concern. Similarly, the behavior of 'inline' functions changes +between gnu89 using gnu_inline behavior and gnu11 using standard c99+ +behavior, but this was taken care of by defining 'inline' to include +__attribute__((gnu_inline)) in order to allow building with clang a +while ago. + +Nathan Chancellor reported a new -Wdeclaration-after-statement +warning that appears in a system header on arm, this still needs a +workaround. + +The differences between gnu99, gnu11, gnu1x and gnu17 are fairly +minimal and mainly impact warnings at the -Wpedantic level that the +kernel never enables. Between these, gnu11 is the newest version +that is supported by all supported compiler versions, though it is +only the default on gcc-5, while all other supported versions of +gcc or clang default to gnu1x/gnu17. + +Link: https://lore.kernel.org/lkml/CAHk-=wiyCH7xeHcmiFJ-YgXUy2Jaj7pnkdKpcovt8fYbVFW3TA@mail.gmail.com/ +Link: https://github.com/ClangBuiltLinux/linux/issues/1603 +Suggested-by: Linus Torvalds +Acked-by: Marco Elver +Acked-by: Jani Nikula +Acked-by: David Sterba +Tested-by: Sedat Dilek +Reviewed-by: Alex Shi +Reviewed-by: Nick Desaulniers +Reviewed-by: Miguel Ojeda +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Signed-off-by: Masahiro Yamada +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index cfe400032f96..fe86758acaaa 100644 +--- a/Makefile ++++ b/Makefile +@@ -498,7 +498,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \ + -fno-strict-aliasing -fno-common -fshort-wchar -fno-PIE \ + -Werror=implicit-function-declaration -Werror=implicit-int \ + -Werror=return-type -Wno-format-security \ +- -std=gnu89 ++ -std=gnu11 + KBUILD_CPPFLAGS := -D__KERNEL__ + KBUILD_AFLAGS_KERNEL := + KBUILD_CFLAGS_KERNEL := +-- +2.37.2 diff --git a/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch b/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch new file mode 100644 index 0000000000..f60daa3800 --- /dev/null +++ b/target/linux/generic/backport-5.15/005-v5.17-03-Kbuild-use-std-gnu11-for-KBUILD_USERCFLAGS.patch @@ -0,0 +1,47 @@ +From 40337d6f3d677aee7ad3052ae662d3f53dd4d5cb Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 8 Mar 2022 22:56:15 +0100 +Subject: [PATCH 3/3] Kbuild: use -std=gnu11 for KBUILD_USERCFLAGS + +As we change the C language standard for the kernel from gnu89 to +gnu11, it makes sense to also update the version for user space +compilation. + +Some users have older native compilers than what they use for +kernel builds, so I considered using gnu99 as the default version +for wider compatibility with gcc-4.6 and earlier. + +However, testing with older compilers showed that we already require +HOSTCC version 5.1 as well because a lot of host tools include +linux/compiler.h that uses __has_attribute(): + + CC tools/objtool/exec-cmd.o +In file included from tools/include/linux/compiler_types.h:36:0, + from tools/include/linux/compiler.h:5, + from exec-cmd.c:2: +tools/include/linux/compiler-gcc.h:19:5: error: "__has_attribute" is not defined [-Werror=undef] + +Signed-off-by: Arnd Bergmann +Reviewed-by: Nathan Chancellor +Reviewed-by: Nick Desaulniers +Tested-by: Sedat Dilek +Signed-off-by: Masahiro Yamada +--- + Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile b/Makefile +index fe86758acaaa..e569fccfb009 100644 +--- a/Makefile ++++ b/Makefile +@@ -416,7 +416,7 @@ HOSTCXX = g++ + endif + + export KBUILD_USERCFLAGS := -Wall -Wmissing-prototypes -Wstrict-prototypes \ +- -O2 -fomit-frame-pointer -std=gnu89 \ ++ -O2 -fomit-frame-pointer -std=gnu11 \ + -Wdeclaration-after-statement + export KBUILD_USERLDFLAGS := + +-- +2.37.2 diff --git a/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch b/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch new file mode 100644 index 0000000000..e706874a6a --- /dev/null +++ b/target/linux/generic/backport-5.15/776-v6.1-01-net-dsa-qca8k-fix-inband-mgmt-for-big-endian-systems.patch @@ -0,0 +1,163 @@ +From a2550d3ce53c68f54042bc5e468c4d07491ffe0e Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 12 Oct 2022 19:18:36 +0200 +Subject: [PATCH 1/2] net: dsa: qca8k: fix inband mgmt for big-endian systems + +The header and the data of the skb for the inband mgmt requires +to be in little-endian. This is problematic for big-endian system +as the mgmt header is written in the cpu byte order. + +Fix this by converting each value for the mgmt header and data to +little-endian, and convert to cpu byte order the mgmt header and +data sent by the switch. + +Fixes: 5950c7c0a68c ("net: dsa: qca8k: add support for mgmt read/write in Ethernet packet") +Tested-by: Pawel Dembicki +Tested-by: Lech Perczak +Signed-off-by: Christian Marangi +Reviewed-by: Lech Perczak +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 63 ++++++++++++++++++++++++-------- + include/linux/dsa/tag_qca.h | 6 +-- + 2 files changed, 50 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c +index 5669c92c93f7..644338ca0510 100644 +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb) + struct qca8k_mgmt_eth_data *mgmt_eth_data; + struct qca8k_priv *priv = ds->priv; + struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ u32 command; + u8 len, cmd; ++ int i; + + mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb); + mgmt_eth_data = &priv->mgmt_eth_data; + +- cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command); +- len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command); ++ command = get_unaligned_le32(&mgmt_ethhdr->command); ++ cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command); ++ len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command); + + /* Make sure the seq match the requested packet */ +- if (mgmt_ethhdr->seq == mgmt_eth_data->seq) ++ if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq) + mgmt_eth_data->ack = true; + + if (cmd == MDIO_READ) { +- mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data; ++ u32 *val = mgmt_eth_data->data; ++ ++ *val = get_unaligned_le32(&mgmt_ethhdr->mdio_data); + + /* Get the rest of the 12 byte of data. + * The read/write function will extract the requested data. + */ +- if (len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(mgmt_eth_data->data + 1, skb->data, +- QCA_HDR_MGMT_DATA2_LEN); ++ if (len > QCA_HDR_MGMT_DATA1_LEN) { ++ __le32 *data2 = (__le32 *)skb->data; ++ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, ++ len - QCA_HDR_MGMT_DATA1_LEN); ++ ++ val++; ++ ++ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { ++ *val = get_unaligned_le32(data2); ++ val++; ++ data2++; ++ } ++ } + } + + complete(&mgmt_eth_data->rw_done); +@@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * + struct qca_mgmt_ethhdr *mgmt_ethhdr; + unsigned int real_len; + struct sk_buff *skb; +- u32 *data2; ++ __le32 *data2; ++ u32 command; + u16 hdr; ++ int i; + + skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN); + if (!skb) +@@ -199,20 +216,32 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * + hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0)); + hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG); + +- mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); +- mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, ++ command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg); ++ command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len); ++ command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd); ++ command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE, + QCA_HDR_MGMT_CHECK_CODE_VAL); + ++ put_unaligned_le32(command, &mgmt_ethhdr->command); ++ + if (cmd == MDIO_WRITE) +- mgmt_ethhdr->mdio_data = *val; ++ put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data); + + mgmt_ethhdr->hdr = htons(hdr); + + data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN); +- if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) +- memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN); ++ if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) { ++ int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN, ++ len - QCA_HDR_MGMT_DATA1_LEN); ++ ++ val++; ++ ++ for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) { ++ put_unaligned_le32(*val, data2); ++ data2++; ++ val++; ++ } ++ } + + return skb; + } +@@ -220,9 +249,11 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 * + static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num) + { + struct qca_mgmt_ethhdr *mgmt_ethhdr; ++ u32 seq; + ++ seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); + mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data; +- mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num); ++ put_unaligned_le32(seq, &mgmt_ethhdr->seq); + } + + static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len) +diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h +index 50be7cbd93a5..0e176da1e43f 100644 +--- a/include/linux/dsa/tag_qca.h ++++ b/include/linux/dsa/tag_qca.h +@@ -61,9 +61,9 @@ struct sk_buff; + + /* Special struct emulating a Ethernet header */ + struct qca_mgmt_ethhdr { +- u32 command; /* command bit 31:0 */ +- u32 seq; /* seq 63:32 */ +- u32 mdio_data; /* first 4byte mdio */ ++ __le32 command; /* command bit 31:0 */ ++ __le32 seq; /* seq 63:32 */ ++ __le32 mdio_data; /* first 4byte mdio */ + __be16 hdr; /* qca hdr */ + } __packed; + +-- +2.37.2 + diff --git a/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch b/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch new file mode 100644 index 0000000000..93c0bb85b5 --- /dev/null +++ b/target/linux/generic/backport-5.15/776-v6.1-02-net-dsa-qca8k-fix-ethtool-autocast-mib-for-big-endia.patch @@ -0,0 +1,88 @@ +From 0d4636f7d72df3179b20a2d32b647881917a5e2a Mon Sep 17 00:00:00 2001 +From: Christian Marangi +Date: Wed, 12 Oct 2022 19:18:37 +0200 +Subject: [PATCH 2/2] net: dsa: qca8k: fix ethtool autocast mib for big-endian + systems + +The switch sends autocast mib in little-endian. This is problematic for +big-endian system as the values needs to be converted. + +Fix this by converting each mib value to cpu byte order. + +Fixes: 5c957c7ca78c ("net: dsa: qca8k: add support for mib autocast in Ethernet packet") +Tested-by: Pawel Dembicki +Tested-by: Lech Perczak +Signed-off-by: Christian Marangi +Signed-off-by: David S. Miller +--- + drivers/net/dsa/qca/qca8k-8xxx.c | 20 ++++++++------------ + include/linux/dsa/tag_qca.h | 2 +- + 2 files changed, 9 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c +index 644338ca0510..c5c3b4e92f28 100644 +--- a/drivers/net/dsa/qca/qca8k-8xxx.c ++++ b/drivers/net/dsa/qca/qca8k-8xxx.c +@@ -1518,9 +1518,9 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk + struct qca8k_priv *priv = ds->priv; + const struct qca8k_mib_desc *mib; + struct mib_ethhdr *mib_ethhdr; +- int i, mib_len, offset = 0; +- u64 *data; ++ __le32 *data2; + u8 port; ++ int i; + + mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb); + mib_eth_data = &priv->mib_eth_data; +@@ -1532,28 +1532,24 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk + if (port != mib_eth_data->req_port) + goto exit; + +- data = mib_eth_data->data; ++ data2 = (__le32 *)skb->data; + + for (i = 0; i < priv->info->mib_count; i++) { + mib = &ar8327_mib[i]; + + /* First 3 mib are present in the skb head */ + if (i < 3) { +- data[i] = mib_ethhdr->data[i]; ++ mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i); + continue; + } + +- mib_len = sizeof(uint32_t); +- + /* Some mib are 64 bit wide */ + if (mib->size == 2) +- mib_len = sizeof(uint64_t); +- +- /* Copy the mib value from packet to the */ +- memcpy(data + i, skb->data + offset, mib_len); ++ mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2); ++ else ++ mib_eth_data->data[i] = get_unaligned_le32(data2); + +- /* Set the offset for the next mib */ +- offset += mib_len; ++ data2 += mib->size; + } + + exit: +diff --git a/include/linux/dsa/tag_qca.h b/include/linux/dsa/tag_qca.h +index 0e176da1e43f..b1b5720d89a5 100644 +--- a/include/linux/dsa/tag_qca.h ++++ b/include/linux/dsa/tag_qca.h +@@ -73,7 +73,7 @@ enum mdio_cmd { + }; + + struct mib_ethhdr { +- u32 data[3]; /* first 3 mib counter */ ++ __le32 data[3]; /* first 3 mib counter */ + __be16 hdr; /* qca hdr */ + } __packed; + +-- +2.37.2 + diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 index 60a0d4ad6b..e9c4b9fa4b 100644 --- a/target/linux/generic/config-5.15 +++ b/target/linux/generic/config-5.15 @@ -3200,6 +3200,11 @@ CONFIG_LLC=y CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set # CONFIG_LOCKD is not set +CONFIG_LOCKDEP_BITS=15 +CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12 +CONFIG_LOCKDEP_CHAINS_BITS=16 +CONFIG_LOCKDEP_STACK_TRACE_BITS=19 +CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14 CONFIG_LOCKDEP_SUPPORT=y CONFIG_LOCKD_V4=y # CONFIG_LOCKUP_DETECTOR is not set diff --git a/target/linux/layerscape/armv7/config-5.10 b/target/linux/layerscape/armv7/config-5.10 index 52bd032905..8c0e5b6ffe 100644 --- a/target/linux/layerscape/armv7/config-5.10 +++ b/target/linux/layerscape/armv7/config-5.10 @@ -292,8 +292,6 @@ CONFIG_I2C_SLAVE_EEPROM=y CONFIG_I2C_XILINX=y CONFIG_ICPLUS_PHY=y CONFIG_ICS932S401=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_IMX2_WDT=y # CONFIG_IMX7ULP_WDT is not set # CONFIG_IMX8MM_THERMAL is not set diff --git a/target/linux/layerscape/armv8_64b/config-5.10 b/target/linux/layerscape/armv8_64b/config-5.10 index c480b71006..0d4afa9809 100644 --- a/target/linux/layerscape/armv8_64b/config-5.10 +++ b/target/linux/layerscape/armv8_64b/config-5.10 @@ -381,8 +381,6 @@ CONFIG_I2C_MUX_PCA954x=y CONFIG_I2C_RK3X=y CONFIG_I2C_SLAVE=y # CONFIG_I2C_SLAVE_TESTUNIT is not set -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_IMX2_WDT=y CONFIG_INET_DIAG=y diff --git a/target/linux/mediatek/filogic/config-5.15 b/target/linux/mediatek/filogic/config-5.15 index d17522924e..0867316afd 100644 --- a/target/linux/mediatek/filogic/config-5.15 +++ b/target/linux/mediatek/filogic/config-5.15 @@ -184,8 +184,6 @@ CONFIG_I2C_CHARDEV=y CONFIG_I2C_MT65XX=y CONFIG_ICPLUS_PHY=y CONFIG_IIO=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INITRAMFS_SOURCE="" CONFIG_IO_URING=y diff --git a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network index e76792164d..7781fcd435 100644 --- a/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/mt7622/base-files/etc/board.d/02_network @@ -34,6 +34,17 @@ mediatek_setup_interfaces() esac } +DEV_PATH_WMAC=platform/18000000.wmac +DEV_PATH_PCIE0=1a143000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0 +DEV_PATH_PCIE1=1a145000.pcie/pci0001:00/0001:00:01.0/0001:01:00.0 + +mediatek_setup_wlan() +{ + dt_is_enabled wmac@18000000 && ucidef_add_wlan $DEV_PATH_WMAC + dt_is_enabled pcie@1a143000 && ucidef_add_wlan $DEV_PATH_PCIE0 + dt_is_enabled pcie@1a145000 && ucidef_add_wlan $DEV_PATH_PCIE1 +} + mediatek_setup_macs() { local board="$1" @@ -60,6 +71,7 @@ board_config_update board=$(board_name) mediatek_setup_interfaces $board mediatek_setup_macs $board +mediatek_setup_wlan $board board_config_flush exit 0 diff --git a/target/linux/mediatek/mt7622/config-5.15 b/target/linux/mediatek/mt7622/config-5.15 index 675abfb85c..13bc77bb98 100644 --- a/target/linux/mediatek/mt7622/config-5.15 +++ b/target/linux/mediatek/mt7622/config-5.15 @@ -73,7 +73,7 @@ CONFIG_COMMON_CLK_MT7622_ETHSYS=y CONFIG_COMMON_CLK_MT7622_HIFSYS=y # CONFIG_COMMON_CLK_MT7986 is not set # CONFIG_COMMON_CLK_MT8173 is not set -CONFIG_COMMON_CLK_MT8183=y +# CONFIG_COMMON_CLK_MT8183 is not set # CONFIG_COMMON_CLK_MT8183_AUDIOSYS is not set # CONFIG_COMMON_CLK_MT8183_CAMSYS is not set # CONFIG_COMMON_CLK_MT8183_IMGSYS is not set @@ -85,7 +85,7 @@ CONFIG_COMMON_CLK_MT8183=y # CONFIG_COMMON_CLK_MT8183_MMSYS is not set # CONFIG_COMMON_CLK_MT8183_VDECSYS is not set # CONFIG_COMMON_CLK_MT8183_VENCSYS is not set -CONFIG_COMMON_CLK_MT8516=y +# CONFIG_COMMON_CLK_MT8516 is not set # CONFIG_COMMON_CLK_MT8516_AUDSYS is not set CONFIG_COMPAT=y CONFIG_COMPAT_32BIT_TIME=y @@ -146,7 +146,6 @@ CONFIG_DCACHE_WORD_ACCESS=y CONFIG_DEBUG_MISC=y CONFIG_DIMLIB=y CONFIG_DMADEVICES=y -CONFIG_DMATEST=y CONFIG_DMA_DIRECT_REMAP=y CONFIG_DMA_ENGINE=y CONFIG_DMA_ENGINE_RAID=y @@ -211,12 +210,8 @@ CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MT65XX=y CONFIG_ICPLUS_PHY=y -CONFIG_IIO=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_INITRAMFS_SOURCE="" -CONFIG_IO_URING=y # CONFIG_IR_MTK is not set CONFIG_IRQCHIP=y CONFIG_IRQ_DOMAIN=y diff --git a/target/linux/mediatek/patches-5.15/193-dts-mt7623-thermal_zone_fix.patch b/target/linux/mediatek/patches-5.15/193-dts-mt7623-thermal_zone_fix.patch new file mode 100644 index 0000000000..1cfb53d620 --- /dev/null +++ b/target/linux/mediatek/patches-5.15/193-dts-mt7623-thermal_zone_fix.patch @@ -0,0 +1,48 @@ +From 824d56e753a588fcfd650db1822e34a02a48bb77 Mon Sep 17 00:00:00 2001 +From: Bruno Umuarama +Date: Thu, 13 Oct 2022 21:18:21 +0000 +Subject: [PATCH] mediatek: mt7623: fix thermal zone +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Raising the temperatures for passive and active trips. @VA1DER +proposed at issue 9396 to remove passive trip. This commit relates to +his suggestion. + +Without this patch. the CPU will be throttled all the way down to 98MHz +if the temperature rises even a degree above the trip point, and it was +further discovered that if the internal temperature of the device is +above the first trip point temperature when it boots then it will start +in a throttled state and even +$ echo disabled > /sys/class/thermal/thermal_zone0/mode +will have no effect. + +The patch increases the passive trip point and active cooling map. The +throttling temperature will then be at 77°C and 82°C, which is still a +low enough temperature for ARM devices to not be in the real danger +zone, and gives some operational headroom. + +Signed-off-by: Bruno Umuarama +--- + arch/arm/boot/dts/mt7623.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -160,13 +160,13 @@ + + trips { + cpu_passive: cpu-passive { +- temperature = <57000>; ++ temperature = <77000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu_active: cpu-active { +- temperature = <67000>; ++ temperature = <82000>; + hysteresis = <2000>; + type = "active"; + }; diff --git a/target/linux/omap/config-5.10 b/target/linux/omap/config-5.10 index 28736f67ed..c03ff8a6d9 100644 --- a/target/linux/omap/config-5.10 +++ b/target/linux/omap/config-5.10 @@ -274,8 +274,6 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_OMAP=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y diff --git a/target/linux/omap/config-5.15 b/target/linux/omap/config-5.15 index c35a20acda..7b0dd7c908 100644 --- a/target/linux/omap/config-5.15 +++ b/target/linux/omap/config-5.15 @@ -277,8 +277,6 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_OMAP=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y diff --git a/target/linux/zynq/config-5.10 b/target/linux/zynq/config-5.10 index 228b710ec1..767ee677f6 100644 --- a/target/linux/zynq/config-5.10 +++ b/target/linux/zynq/config-5.10 @@ -246,8 +246,6 @@ CONFIG_IIO_BUFFER=y CONFIG_IIO_KFIFO_BUF=y CONFIG_IIO_TRIGGER=y CONFIG_IIO_TRIGGERED_BUFFER=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" CONFIG_INPUT=y CONFIG_INPUT_EVDEV=y