ipq50xx: add CIF WF-198 support

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2024-02-14 12:57:42 +01:00
parent 01adebbd6f
commit 460050a114
65 changed files with 12567 additions and 764 deletions

View File

@@ -19,7 +19,7 @@ define Package/ath12k-wifi-default
SUBMENU:=ath12k Board-Specific Overrides
SECTION:=firmware
CATEGORY:=Firmware
DEPENDS:=@TARGET_qcn9274
DEPENDS:=@(TARGET_qcn9274||TARGET_ipq53xx)
TITLE:=Custom Board
endef
@@ -33,4 +33,15 @@ define Package/ath12k-wifi-qcom-qcn9274/install
$(INSTALL_DATA) ./board-2.bin.QCN9274 $(1)/lib/firmware/ath12k/QCN9274/hw1.0/board-2.bin
endef
define Package/ath12k-wifi-cig-wf198
$(call Package/ath12k-wifi-default)
TITLE:=board.bin for CIG WF198
endef
define Package/ath12k-wifi-cig-wf198/install
$(INSTALL_DIR) $(1)/lib/firmware/ath12k/QCN92XX/hw1.0
$(INSTALL_DATA) ./board-cig-wf198.bin.qcn9224 $(1)/lib/firmware/ath12k/QCN92XX/hw1.0/board.bin
endef
$(eval $(call BuildPackage,ath12k-wifi-qcom-qcn9274))
$(eval $(call BuildPackage,ath12k-wifi-cig-wf198))

Binary file not shown.

View File

@@ -8,7 +8,7 @@ PKG_NAME:=hostapd
PKG_VERSION:=2023-02-21-ath12.3-cs
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
PKG_HASH:=639140658012286453c9f4a8d92d70efa0bbfc23d71ddea0496cf3dc90e39c80
PKG_HASH:=6153bacd614d9bb2dfba634dd698a698e37c043e08543a0802903718238a12fa
PKG_SOURCE_URL:=@KERNEL/software/utils/dtc
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>

View File

@@ -0,0 +1,28 @@
include $(TOPDIR)/rules.mk
ARCH:=aarch64
BOARD:=ipq53xx
BOARDNAME:=Qualcomm Technologies, Inc IPQ53xx
FEATURES:=ubifs squashfs fpu ramdisk nand pcie usbgadget
CPU_TYPE:=cortex-a73
CPU_SUBTYPE:=neon-vfpv4
MAINTAINER:=John Crispin <blogic@openwrt.org>
SUBTARGETS:=generic
KERNELNAME:=zImage Image dtbs
KERNEL_PATCHVER:=5.4
KERNEL_NAME_SUFFIX=-qsdk-b2d40c94fad765a48c03f492d669aeecbbb9b617
include $(INCLUDE_DIR)/target.mk
DEFAULT_PACKAGES += \
uboot-envtools kmod-leds-gpio kmod-gpio-button-hotplug kmod-button-hotplug \
kmod-usb3 swconfig kmod-qca-nss-dp \
kmod-usb-phy-ipq5018 kmod-usb-dwc3-qcom-internal \
kmod-qca-nss-ppe kmod-qca-ssdk-nohnat kmod-qca-psdk \
kmod-gpio-button-hotplug iwinfo uboot-envtools swconfig \
kmod-ath11k-ahb \
kmod-ath12k ath12k-firmware-qcn92xx wpad-openssl \
-procd-ujail
$(eval $(call BuildTarget))

View File

@@ -0,0 +1,21 @@
#!/bin/sh
. /lib/functions/uci-defaults.sh
ipq95xx_setup_interfaces()
{
local board="$1"
case "$board" in
qcom,ipq9574-ap-al02-c4)
ucidef_set_interfaces_lan_wan "eth1 eth2 eth3 eth4 eth5" "eth0"
;;
esac
}
board_config_update
board=$(board_name)
ipq95xx_setup_interfaces $board
board_config_flush
exit 0

View File

@@ -0,0 +1,41 @@
#!/bin/sh
export >> /tmp/foo
[ -e /lib/firmware/$FIRMWARE ] && exit 0
. /lib/functions.sh
. /lib/functions/system.sh
caldata_die() {
echo "caldata: " "$*"
exit 1
}
caldata_extract() {
local part=$1
local offset=$(($2))
local count=$(($3))
local mtd
mtd=$(find_mtd_chardev $part)
[ -n "$mtd" ] || caldata_die "no mtd device found for partition $part"
dd if=$mtd of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
caldata_die "failed to extract calibration data from $mtd"
}
board=$(board_name)
case "$FIRMWARE" in
ath11k/IPQ9574/hw1.0/caldata.bin)
case "$board" in
qcom,ipq9574-ap-al02-c15)
caldata_extract "0:ART" 0x1000 0x20000
;;
esac
;;
*)
exit 1
;;
esac

View File

@@ -0,0 +1,48 @@
#!/bin/sh
export >> /tmp/foo
[ -e /lib/firmware/$FIRMWARE ] && exit 0
. /lib/functions.sh
. /lib/functions/system.sh
caldata_die() {
echo "caldata: " "$*"
exit 1
}
caldata_extract() {
local part=$1
local offset=$(($2))
local count=$(($3))
local mtd
mtd=$(find_mtd_chardev $part)
[ -n "$mtd" ] || caldata_die "no mtd device found for partition $part"
dd if=$mtd of=/lib/firmware/$FIRMWARE iflag=skip_bytes bs=$count skip=$offset count=1 2>/dev/null || \
caldata_die "failed to extract calibration data from $mtd"
}
board=$(board_name)
case "$FIRMWARE" in
ath12k/IPQ5332/hw1.0/caldata.bin)
case "$board" in
cig,wf198)
caldata_extract "0:ART" 0x1000 0x20000
;;
esac
;;
ath12k/QCN92XX/hw1.0/cal-pci-0001:01:00.0.bin)
case "$board" in
cig,wf198)
caldata_extract "0:ART" 0x58800 0x2d000
;;
esac
;;
*)
exit 1
;;
esac

View File

@@ -0,0 +1,392 @@
# Copyright (C) 2014 OpenWrt.org
#
. /lib/functions.sh
# 'kernel' partition or UBI volume on NAND contains the kernel
CI_KERNPART="${CI_KERNPART:-kernel}"
# 'ubi' partition on NAND contains UBI
CI_UBIPART="${CI_UBIPART:-ubi}"
# 'rootfs' UBI volume on NAND contains the rootfs
CI_ROOTPART="${CI_ROOTPART:-rootfs}"
# ipq807x qsdk kernel misbehaves
CI_IPQ807X=0
# update BOOTCONFIG partitions (rotate rootfs/rootfs_1)
CI_BOOTCFG=0
# update uboot-env if upgrade suceeded
CI_FWSETENV=
ubi_mknod() {
local dir="$1"
local dev="/dev/$(basename $dir)"
[ -e "$dev" ] && return 0
local devid="$(cat $dir/dev)"
local major="${devid%%:*}"
local minor="${devid##*:}"
mknod "$dev" c $major $minor
}
nand_find_volume() {
local ubidevdir ubivoldir
ubidevdir="/sys/devices/virtual/ubi/$1"
[ ! -d "$ubidevdir" ] && return 1
for ubivoldir in $ubidevdir/${1}_*; do
[ ! -d "$ubivoldir" ] && continue
if [ "$( cat $ubivoldir/name )" = "$2" ]; then
basename $ubivoldir
ubi_mknod "$ubivoldir"
return 0
fi
done
}
nand_find_ubi() {
local ubidevdir ubidev mtdnum
mtdnum="$( find_mtd_index $1 )"
[ ! "$mtdnum" ] && return 1
for ubidevdir in /sys/devices/virtual/ubi/ubi*; do
[ ! -d "$ubidevdir" ] && continue
cmtdnum="$( cat $ubidevdir/mtd_num )"
[ ! "$mtdnum" ] && continue
if [ "$mtdnum" = "$cmtdnum" ]; then
ubidev=$( basename $ubidevdir )
ubi_mknod "$ubidevdir"
echo $ubidev
return 0
fi
done
}
nand_get_magic_long() {
dd if="$1" skip=$2 bs=4 count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
}
get_magic_long_tar() {
( tar xf $1 $2 -O | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2> /dev/null
}
identify_magic() {
local magic=$1
case "$magic" in
"55424923")
echo "ubi"
;;
"31181006")
echo "ubifs"
;;
"68737173")
echo "squashfs"
;;
"d00dfeed")
echo "fit"
;;
"4349"*)
echo "combined"
;;
*)
echo "unknown $magic"
;;
esac
}
identify() {
identify_magic $(nand_get_magic_long "$1" "${2:-0}")
}
identify_tar() {
identify_magic $(get_magic_long_tar "$1" "$2")
}
nand_restore_config() {
sync
local ubidev=$( nand_find_ubi $CI_UBIPART )
local ubivol="$( nand_find_volume $ubidev rootfs_data )"
[ ! "$ubivol" ] &&
ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
mkdir /tmp/new_root
if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then
echo "mounting ubifs $ubivol failed"
rmdir /tmp/new_root
return 1
fi
mv "$1" "/tmp/new_root/$BACKUP_FILE"
umount /tmp/new_root
sync
rmdir /tmp/new_root
}
nand_upgrade_prepare_ubi() {
local rootfs_length="$1"
local rootfs_type="$2"
local rootfs_data_max="$(fw_printenv -n rootfs_data_max 2>/dev/null)"
[ -n "$rootfs_data_max" ] && rootfs_data_max=$(printf %d "$rootfs_data_max")
local kernel_length="$3"
local has_env="${4:-0}"
[ -n "$rootfs_length" -o -n "$kernel_length" ] || return 1
local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
if [ ! "$mtdnum" ]; then
echo "cannot find ubi mtd partition $CI_UBIPART"
return 1
fi
[ "$CI_IPQ807X" = 1 ] && ubidetach -f -m $mtdnum
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
if [ ! "$ubidev" ]; then
ubiattach -m "$mtdnum"
sync
ubidev="$( nand_find_ubi "$CI_UBIPART" )"
fi
if [ ! "$ubidev" ]; then
ubiformat /dev/mtd$mtdnum -y
ubiattach -m "$mtdnum"
sync
ubidev="$( nand_find_ubi "$CI_UBIPART" )"
[ "$has_env" -gt 0 ] && {
ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB
ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB
}
fi
local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
local data_ubivol="$( nand_find_volume $ubidev rootfs_data )"
local ubiblk ubiblkvol
for ubiblk in /dev/ubiblock*_? ; do
[ -e "$ubiblk" ] || continue
echo "removing ubiblock${ubiblk:13}"
ubiblkvol=ubi${ubiblk:13}
if ! ubiblock -r /dev/$ubiblkvol; then
echo "cannot remove $ubiblk"
return 1
fi
done
# kill volumes
[ "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_KERNPART || true
[ "$root_ubivol" -a "$root_ubivol" != "$kern_ubivol" ] && ubirmvol /dev/$ubidev -N $CI_ROOTPART || true
[ "$data_ubivol" ] && ubirmvol /dev/$ubidev -N rootfs_data || true
# update kernel
if [ -n "$kernel_length" ]; then
if ! ubimkvol /dev/$ubidev -N $CI_KERNPART -s $kernel_length; then
echo "cannot create kernel volume"
return 1;
fi
fi
# update rootfs
if [ -n "$rootfs_length" ]; then
local rootfs_size_param
if [ "$rootfs_type" = "ubifs" ]; then
rootfs_size_param="-m"
else
rootfs_size_param="-s $rootfs_length"
fi
if ! ubimkvol /dev/$ubidev -N $CI_ROOTPART $rootfs_size_param; then
echo "cannot create rootfs volume"
return 1;
fi
fi
# create rootfs_data for non-ubifs rootfs
if [ "$rootfs_type" != "ubifs" ]; then
local availeb=$(cat /sys/devices/virtual/ubi/$ubidev/avail_eraseblocks)
local ebsize=$(cat /sys/devices/virtual/ubi/$ubidev/eraseblock_size)
local avail_size=$(( $availeb * $ebsize ))
local rootfs_data_size_param="-m"
if [ -n "$rootfs_data_max" ] &&
[ "$rootfs_data_max" != "0" ] &&
[ "$rootfs_data_max" -le "$avail_size" ]; then
rootfs_data_size_param="-s $rootfs_data_max"
fi
if ! ubimkvol /dev/$ubidev -N rootfs_data $rootfs_data_size_param; then
echo "cannot initialize rootfs_data volume"
return 1
fi
fi
sync
return 0
}
nand_qca_update_bootconfig() {
local primary="0"
local mtdnum
local part
[ -f /proc/boot_info/rootfs/primaryboot ] || return
[ -f /proc/boot_info/getbinary_bootconfig ] || return
[ "$(cat /proc/boot_info/rootfs/primaryboot)" = "0" ] && primary="1"
echo "$primary" > /proc/boot_info/rootfs/primaryboot 2>/dev/null
for part in "0:BOOTCONFIG" "0:BOOTCONFIG1"; do
mtdnum="$(find_mtd_index "$part")"
[ -c "/dev/mtd${mtdnum}" ] && {
mtd -qq write /proc/boot_info/getbinary_bootconfig \
"/dev/mtd${mtdnum}" 2>/dev/null &&\
echo "partition '$part' updated"
}
done
}
nand_do_upgrade_success() {
local conf_tar="/tmp/sysupgrade.tgz"
sync
[ "$CI_BOOTCFG" = 1 ] && nand_qca_update_bootconfig
[ -n "$CI_FWSETENV" ] && fw_setenv $CI_FWSETENV
[ -f "$conf_tar" ] && nand_restore_config "$conf_tar"
echo "sysupgrade successful"
umount -a
sleep 5
reboot -f
}
# Flash the UBI image to MTD partition
nand_upgrade_ubinized() {
local ubi_file="$1"
local mtdnum="$(find_mtd_index "$CI_UBIPART")"
[ ! "$mtdnum" ] && {
CI_UBIPART="rootfs"
mtdnum="$(find_mtd_index "$CI_UBIPART")"
}
if [ ! "$mtdnum" ]; then
echo "cannot find mtd device $CI_UBIPART"
umount -a
reboot -f
fi
local mtddev="/dev/mtd${mtdnum}"
ubidetach -p "${mtddev}" || true
sync
ubiformat "${mtddev}" -y -f "${ubi_file}"
ubiattach -p "${mtddev}"
nand_do_upgrade_success
}
# Write the UBIFS image to UBI volume
nand_upgrade_ubifs() {
local rootfs_length=$( (cat $1 | wc -c) 2> /dev/null)
nand_upgrade_prepare_ubi "$rootfs_length" "ubifs" "" ""
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
local root_ubivol="$(nand_find_volume $ubidev $CI_ROOTPART)"
ubiupdatevol /dev/$root_ubivol -s $rootfs_length $1
nand_do_upgrade_success
}
nand_upgrade_fit() {
local fit_file="$1"
local fit_length="$(wc -c < "$fit_file")"
nand_upgrade_prepare_ubi "" "" "$fit_length" "1"
local fit_ubidev="$(nand_find_ubi "$CI_UBIPART")"
local fit_ubivol="$(nand_find_volume $fit_ubidev "$CI_KERNPART")"
ubiupdatevol /dev/$fit_ubivol -s $fit_length $fit_file
nand_do_upgrade_success
}
nand_upgrade_tar() {
local tar_file="$1"
local kernel_mtd="$(find_mtd_index $CI_KERNPART)"
local board_dir=$(tar tf "$tar_file" | grep -m 1 '^sysupgrade-.*/$')
board_dir=${board_dir%/}
kernel_length=$( (tar xf "$tar_file" ${board_dir}/kernel -O | wc -c) 2> /dev/null)
local has_rootfs=0
local rootfs_length
local rootfs_type
tar tf "$tar_file" ${board_dir}/root 1>/dev/null 2>/dev/null && has_rootfs=1
[ "$has_rootfs" = "1" ] && {
rootfs_length=$( (tar xf "$tar_file" ${board_dir}/root -O | wc -c) 2> /dev/null)
rootfs_type="$(identify_tar "$tar_file" ${board_dir}/root)"
}
local has_kernel=1
local has_env=0
[ "$CI_IPQ807X" = 0 -a "$kernel_length" != 0 -a -n "$kernel_mtd" ] && {
tar xf $tar_file ${board_dir}/kernel -O | mtd write - $CI_KERNPART
}
[ "$CI_IPQ807X" = 0 ] && {
[ "$kernel_length" = 0 -o ! -z "$kernel_mtd" ] && has_kernel=
}
nand_upgrade_prepare_ubi "$rootfs_length" "$rootfs_type" "${has_kernel:+$kernel_length}" "$has_env"
local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
[ "$has_kernel" = "1" ] && {
local kern_ubivol="$( nand_find_volume $ubidev $CI_KERNPART )"
tar xf "$tar_file" ${board_dir}/kernel -O | \
ubiupdatevol /dev/$kern_ubivol -s $kernel_length -
}
[ "$has_rootfs" = "1" ] && {
local root_ubivol="$( nand_find_volume $ubidev $CI_ROOTPART )"
tar xf "$tar_file" ${board_dir}/root -O | \
ubiupdatevol /dev/$root_ubivol -s $rootfs_length -
}
nand_do_upgrade_success
}
# Recognize type of passed file and start the upgrade process
nand_do_upgrade() {
local file_type=$(identify $1)
[ ! "$( find_mtd_index "$CI_UBIPART" )" ] && CI_UBIPART="rootfs"
case "$file_type" in
"fit") nand_upgrade_fit $1;;
"ubi") nand_upgrade_ubinized $1;;
"ubifs") nand_upgrade_ubifs $1;;
*) nand_upgrade_tar $1;;
esac
}
# Check if passed file is a valid one for NAND sysupgrade. Currently it accepts
# 3 types of files:
# 1) UBI - should contain an ubinized image, header is checked for the proper
# MAGIC
# 2) UBIFS - should contain UBIFS partition that will replace "rootfs" volume,
# header is checked for the proper MAGIC
# 3) TAR - archive has to include "sysupgrade-BOARD" directory with a non-empty
# "CONTROL" file (at this point its content isn't verified)
#
# You usually want to call this function in platform_check_image.
#
# $(1): board name, used in case of passing TAR file
# $(2): file to be checked
nand_do_platform_check() {
local board_name="$1"
local tar_file="$2"
local control_length=$( (tar xf $tar_file sysupgrade-$board_name/CONTROL -O | wc -c) 2> /dev/null)
local file_type="$(identify $2)"
[ "$control_length" = 0 -a "$file_type" != "ubi" -a "$file_type" != "ubifs" -a "$file_type" != "fit" ] && {
echo "Invalid sysupgrade file."
return 1
}
return 0
}

View File

@@ -0,0 +1,24 @@
. /lib/functions/system.sh
RAMFS_COPY_BIN='fw_printenv fw_setenv'
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
platform_check_image() {
local magic_long="$(get_magic_long "$1")"
[ "$magic_long" = "73797375" ] && return 0
return 1
}
platform_do_upgrade() {
CI_UBIPART="rootfs"
CI_ROOTPART="ubi_rootfs"
CI_IPQ807X=1
board=$(board_name)
case $board in
qcom,ipq9574-ap-al02-c4|\
qcom,ipq9574-ap-al02-c15)
nand_upgrade_tar "$1"
;;
esac
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,479 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
* IPQ5332 AP-MI01.6 board device tree source
*
* Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
/dts-v1/;
#include "ipq5332.dtsi"
#ifdef __IPQ_MEM_PROFILE_512_MB__
#include "ipq5332-512MB-memory.dtsi"
#else
#include "ipq5332-default-memory.dtsi"
#endif
/ {
#address-cells = <0x2>;
#size-cells = <0x2>;
model = "CIG WF198";
compatible = "cig,wf198", "qcom,ipq5332-ap-mi01.6", "qcom,ipq5332";
interrupt-parent = <&intc>;
aliases {
serial0 = &blsp1_uart0;
serial1 = &blsp1_uart1;
ethernet0 = "/soc/dp1";
ethernet1 = "/soc/dp2";
};
chosen {
stdout-path = "serial0";
};
soc {
pinctrl@1000000 {
spi_0_pins: spi0-pinmux {
spi_clock {
pins = "gpio14";
function = "blsp0_spi";
drive-strength = <2>;
bias-pull-down;
};
spi_mosi {
pins = "gpio15";
function = "blsp0_spi";
drive-strength = <2>;
bias-pull-down;
};
spi_miso {
pins = "gpio16";
function = "blsp0_spi";
drive-strength = <2>;
bias-pull-down;
};
spi_cs {
pins = "gpio17";
function = "blsp0_spi";
drive-strength = <2>;
bias-pull-up;
};
};
serial_0_pins: serial0-pinmux {
pins = "gpio18", "gpio19";
function = "blsp0_uart0";
drive-strength = <8>;
bias-pull-up;
};
serial_1_pins: serial1-pinmux {
pins = "gpio33", "gpio34", "gpio35", "gpio36";
function = "blsp1_uart2";
drive-strength = <8>;
bias-pull-up;
};
i2c_1_pins: i2c-1-pinmux {
pins = "gpio29", "gpio30";
function = "blsp1_i2c0";
drive-strength = <8>;
bias-pull-up;
};
mdio1_pins: mdio1_pinmux {
mux_0 {
pins = "gpio27";
function = "mdc1";
drive-strength = <8>;
bias-disable;
};
mux_1 {
pins = "gpio28";
function = "mdio1";
drive-strength = <8>;
bias-pull-up;
};
};
pwm_pins: pwm_pinmux {
/*mux_1 {
pins = "gpio26";
function = "pwm2";
drive-strength = <8>;
};*/
mux_2 {
pins = "gpio30";
function = "pwm1";
drive-strength = <8>;
};
mux_3 {
pins = "gpio45";
function = "pwm0";
drive-strength = <8>;
};
};
/*audio_pins_pri: audio_pinmux_pri {
mux_1 {
pins = "gpio29";
function = "audio_pri";
drive-strength = <8>;
bias-pull-down;
};
mux_2 {
pins = "gpio30";
function = "audio_pri";
drive-strength = <8>;
bias-pull-down;
};
mux_3 {
pins = "gpio31";
function = "audio_pri";
drive-strength = <4>;
bias-pull-down;
};
mux_4 {
pins = "gpio32";
function = "audio_pri";
drive-strength = <4>;
bias-pull-down;
};
};*/
spi_2_pins: spi-2-pins {
pins = "gpio33", "gpio34", "gpio35", "gpio36";
function = "blsp2_spi0";
drive-strength = <8>;
bias-pull-down;
};
button_pins: button_pins {
rst_button {
pins = "gpio17";
function = "gpio";
drive-strength = <8>;
bias-pull-up;
};
};
};
dp1 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <2>;
reg = <0x3a504000 0x4000>;
qcom,mactype = <1>;
local-mac-address = [000000000000];
mdio-bus = <&mdio>;
qcom,phy-mdio-addr = <12>;
qcom,link-poll = <1>;
phy-mode = "sgmii";
};
dp2 {
device_type = "network";
compatible = "qcom,nss-dp";
qcom,id = <1>;
reg = <0x3a500000 0x4000>;
qcom,mactype = <1>;
local-mac-address = [000000000000];
mdio-bus = <&mdio>;
qcom,phy-mdio-addr = <8>;
qcom,link-poll = <1>;
phy-mode = "sgmii";
qcom,ppe-offload-disabled = <1>;
qcom,is_switch_connected = <1>;
};
pwm: pwm {
pinctrl-0 = <&pwm_pins>;
pinctrl-names = "default";
used-pwm-indices = <1>, <1>, <1>, <1>;
dft-pwm-status = <0>, <1>, <1>, <0>;
#pwm-cells = <2>;
status = "ok";
};
mdio:mdio@90000 {
status = "ok";
pinctrl-0 = <&mdio1_pins>;
pinctrl-names = "default";
/*gpio51 for manhattan reset*/
phy-reset-gpio = <&tlmm 14 0 &tlmm 20 0>;
phyaddr_fixup = <0xC90F018>;
uniphyaddr_fixup = <0xC90F014>;
mdio_clk_fixup; /* MDIO clock sequence fix up flag */
phy0: ethernet-phy@0 {
reg = <8>;
reset-gpios = <&tlmm 14 GPIO_ACTIVE_LOW>;
compatible ="ethernet-phy-ieee802.3-c45";
};
phy1: ethernet-phy@1 {
reg = <12>;
reset-gpios = <&tlmm 20 GPIO_ACTIVE_LOW>;
};
};
/*pcm: pcm@0xA3C0000{
pinctrl-0 = <&audio_pins_pri>;
pinctrl-names = "primary";
status = "disabled";
};*/
ess-instance {
num_devices = <0x1>;
ess-switch@3a000000 {
switch_cpu_bmp = <0x1>; /* cpu port bitmap */
switch_lan_bmp = <0x2>; /* lan port bitmap */
switch_wan_bmp = <0x4>; /* wan port bitmap */
switch_mac_mode = <0xd>; /* mac mode for uniphy instance0*/
switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/
switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/
qcom,port_phyinfo {
port@0 {
port_id = <1>;
phy_address = <8>;
mdiobus = <&mdio>;
ethernet-phy-ieee802.3-c45;
};
port@1 {
port_id = <2>;
phy_address = <12>;
mdiobus = <&mdio>;
};
};
};
};
/* EDMA host driver configuration for the board */
edma@3ab00000 {
qcom,txdesc-ring-start = <4>; /* Tx desc ring start ID */
qcom,txdesc-rings = <12>; /* Total number of Tx desc rings to be provisioned */
qcom,txcmpl-ring-start = <4>; /* Tx complete ring start ID */
qcom,txcmpl-rings = <12>; /* Total number of Tx complete rings to be provisioned */
qcom,rxfill-ring-start = <4>; /* Rx fill ring start ID */
qcom,rxfill-rings = <4>; /* Total number of Rx fill rings to be provisioned */
qcom,rxdesc-ring-start = <12>; /* Rx desc ring start ID */
qcom,rxdesc-rings = <4>; /* Total number of Rx desc rings to be provisioned */
qcom,rx-page-mode = <0>; /* Rx fill ring page mode */
qcom,tx-map-priority-level = <1>; /* Tx priority level per port */
qcom,rx-map-priority-level = <1>; /* Rx priority level per core */
qcom,ppeds-num = <2>; /* Number of PPEDS nodes */
/* PPE-DS node format: <Rx-fill Tx-cmpl Rx Tx Queue-base Queue-count> */
qcom,ppeds-map = <1 1 1 1 32 8>, /* PPEDS Node#0 ring and queue map */
<2 2 2 2 40 8>; /* PPEDS Node#1 ring and queue map */
qcom,txdesc-map = <8 9 10 11>, /* Port0 per-core Tx ring map */
<12 13 14 15>, /* Port1 per-core Tx ring map */
<4 5 6 7>; /* used only for packets from vp*/
qcom,txdesc-fc-grp-map = <1 2>; /* Per GMAC flow control group map */
qcom,rxfill-map = <4 5 6 7>; /* Per-core Rx fill ring map */
qcom,rxdesc-map = <12 13 14 15>; /* Per-core Rx desc ring map */
qcom,rx-queue-start = <0>; /* Rx queue start */
qcom,rx-ring-queue-map = <0 8 16 24>, /* Priority 0 queues per-core Rx ring map */
<1 9 17 25>, /* Priority 1 queues per-core Rx ring map */
<2 10 18 26>, /* Priority 2 queues per-core Rx ring map */
<3 11 19 27>, /* Priority 3 queues per-core Rx ring map */
<4 12 20 28>, /* Priority 4 queues per-core Rx ring map */
<5 13 21 29>, /* Priority 5 queues per-core Rx ring map */
<6 14 22 30>, /* Priority 6 queues per-core Rx ring map */
<7 15 23 31>; /* Priority 7 queues per-core Rx ring map */
interrupts = <0 163 4>, /* Tx complete ring id #4 IRQ info */
<0 164 4>, /* Tx complete ring id #5 IRQ info */
<0 165 4>, /* Tx complete ring id #6 IRQ info */
<0 166 4>, /* Tx complete ring id #7 IRQ info */
<0 167 4>, /* Tx complete ring id #8 IRQ info */
<0 168 4>, /* Tx complete ring id #9 IRQ info */
<0 169 4>, /* Tx complete ring id #10 IRQ info */
<0 170 4>, /* Tx complete ring id #11 IRQ info */
<0 171 4>, /* Tx complete ring id #12 IRQ info */
<0 172 4>, /* Tx complete ring id #13 IRQ info */
<0 173 4>, /* Tx complete ring id #14 IRQ info */
<0 174 4>, /* Tx complete ring id #15 IRQ info */
<0 139 4>, /* Rx desc ring id #12 IRQ info */
<0 140 4>, /* Rx desc ring id #13 IRQ info */
<0 141 4>, /* Rx desc ring id #14 IRQ info */
<0 142 4>, /* Rx desc ring id #15 IRQ info */
<0 191 4>, /* Misc error IRQ info */
<0 160 4>, /* PPEDS Node #1(TxComp ring id #1) TxComplete IRQ info */
<0 128 4>, /* PPEDS Node #1(Rx Desc ring id #1) Rx Desc IRQ info */
<0 152 4>, /* PPEDS Node #1(RxFill Desc ring id #1) Rx Fill IRQ info */
<0 161 4>, /* PPEDS Node #2(TxComp ring id #2) TxComplete IRQ info */
<0 129 4>, /* PPEDS Node #2(Rx Desc ring id #2) Rx Desc IRQ info */
<0 153 4>; /* PPEDS Node #2(RxFill Desc ring id #2) Rx Fill IRQ info */
};
serial@78af000 {
pinctrl-0 = <&serial_0_pins>;
pinctrl-names = "default";
status = "ok";
};
serial@78b0000 {
pinctrl-0 = <&serial_1_pins>;
pinctrl-names = "default";
status = "ok";
};
spi@78b5000 {
pinctrl-0 = <&spi_0_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "ok";
m25p80@0 {
compatible = "n25q128a11";
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
spi-max-frequency = <50000000>;
};
};
spi_2: spi@78b7000 {
pinctrl-0 = <&spi_2_pins>;
pinctrl-names = "default";
cs-select = <0>;
status = "disabled";
};
i2c_1: i2c@78b6000 {
pinctrl-0 = <&i2c_1_pins>;
pinctrl-names = "default";
};
dma@7984000 {
status = "ok";
};
nand: nand@79b0000 {
pinctrl-0 = <&qspi_nand_pins>;
pinctrl-names = "default";
status = "ok";
};
usb3@8A00000 {
status = "ok";
qcom,multiplexed-phy;
};
ssuniphy_0: ssuniphy@4b0000 {
status = "ok";
};
hs_m31phy_0: hs_m31phy@7b000 {
status = "ok";
};
pcie1_phy_x2: phy_x2@4b1000 {
status = "ok";
};
gpio_keys {
compatible = "gpio-keys";
pinctrl-0 = <&button_pins>;
pinctrl-names = "default";
button@1 {
label = "rst";
linux,code = <KEY_RESTART>;
gpios = <&tlmm 17 GPIO_ACTIVE_LOW>;
linux,input-type = <1>;
debounce-interval = <60>;
};
};
pwmleds {
compatible = "pwm-leds";
led1 {
label = "led1";
pwms = <&pwm 0 10000>;
max-brightness = <255>;
};
led2 {
label = "led2";
pwms = <&pwm 1 10000>;
max-brightness = <255>;
};
led3 {
label = "led3";
pwms = <&pwm 2 10000>;
max-brightness = <255>;
};
led4 {
label = "led4";
pwms = <&pwm 3 10000>;
max-brightness = <255>;
};
};
wsi: wsi {
id = <0>;
num_chip = <2>;
};
pcie1: pcie@18000000 {
status = "ok";
pcie1_rp {
reg = <0 0 0 0 0>;
qcom,mhi@1 {
reg = <0 0 0 0 0>;
qti,disable-rddm-prealloc;
qti,rddm-seg-len = <0x1000>;
#if defined(__CNSS2__)
qrtr_node_id = <0x31>;
memory-region = <0>, <&mhi_region1>;
#else
memory-region = <&qcn9224_pcie1>;
qcom,board_id = <0x1019>;
qcom,wsi = <&wsi>;
#endif
};
};
};
};
};
&wifi0 {
qcom,rproc = <&q6_wcss_pd1>;
qcom,rproc_rpd = <&q6v5_wcss>;
qcom,multipd_arch;
qcom,userpd-subsys-name = "q6v5_wcss_userpd1";
#if defined(__CNSS2__)
mem-region = <&q6_region>;
#else
memory-region = <&q6_region>;
qcom,wsi = <&wsi>;
#endif
qcom,board_id = <0x16>;
status = "ok";
};
&mhi_region1 {
status = "ok";
};
&qcn9224_pcie1 {
status = "ok";
};
/* QCN9224 5G+6G */
&wifi2 {
hremote_node = <&qcn9224_pcie1>;
board_id = <0x1019>;
status = "ok";
};

View File

@@ -0,0 +1,72 @@
# CONFIG_32BIT is not set
CONFIG_64BIT=y
# CONFIG_ACPI is not set
# CONFIG_ARCH_BCM_IPROC is not set
# CONFIG_ARCH_EXYNOS7 is not set
CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
# CONFIG_ARCH_LAYERSCAPE is not set
CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
# CONFIG_ARCH_SEATTLE is not set
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_SPARSEMEM_DEFAULT=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
# CONFIG_ARCH_SPRD is not set
# CONFIG_ARCH_STRATIX10 is not set
# CONFIG_ARCH_THUNDER is not set
CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
CONFIG_ARCH_WANT_FRAME_POINTERS=y
CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y
# CONFIG_ARCH_XGENE is not set
# CONFIG_ARCH_ZYNQMP is not set
CONFIG_ARM64=y
# CONFIG_ARM64_16K_PAGES is not set
CONFIG_ARM64_4K_PAGES=y
# CONFIG_ARM64_64K_PAGES is not set
# CONFIG_ARM64_CRYPTO is not set
# CONFIG_ARM64_ERRATUM_819472 is not set
# CONFIG_ARM64_ERRATUM_824069 is not set
# CONFIG_ARM64_ERRATUM_826319 is not set
# CONFIG_ARM64_ERRATUM_827319 is not set
# CONFIG_ARM64_ERRATUM_832075 is not set
# CONFIG_ARM64_ERRATUM_843419 is not set
# CONFIG_ARM64_ERRATUM_845719 is not set
CONFIG_ARM64_HW_AFDBM=y
# CONFIG_ARM64_LSE_ATOMICS is not set
CONFIG_ARM64_PAN=y
# CONFIG_ARM64_PTDUMP is not set
# CONFIG_ARM64_RANDOMIZE_TEXT_OFFSET is not set
CONFIG_ARM64_VA_BITS=39
CONFIG_ARM64_VA_BITS_39=y
# CONFIG_ARM64_VA_BITS_48 is not set
# CONFIG_ARMV8_DEPRECATED is not set
# CONFIG_CAVIUM_ERRATUM_22375 is not set
# CONFIG_CAVIUM_ERRATUM_23154 is not set
# CONFIG_CAVIUM_ERRATUM_27456 is not set
# CONFIG_COMMON_CLK_VERSATILE is not set
CONFIG_COMMON_CLK_XGENE=y
CONFIG_COMPAT=y
CONFIG_COMPAT_BINFMT_ELF=y
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
# CONFIG_DEBUG_ALIGN_RODATA is not set
CONFIG_FRAME_WARN=2048
# CONFIG_GPIO_XGENE is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_I2C_CADENCE is not set
# CONFIG_KASAN is not set
# CONFIG_KVM is not set
# CONFIG_NET_VENDOR_CAVIUM is not set
# CONFIG_PCI_HISI is not set
CONFIG_PHYS_ADDR_T_64BIT=y
# CONFIG_PHY_XGENE is not set
# CONFIG_POWER_RESET_XGENE is not set
CONFIG_QCOM_SCM_64=y
# CONFIG_RTC_DRV_EFI is not set
CONFIG_SPARSEMEM=y
CONFIG_SPARSEMEM_EXTREME=y
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_VIRTUALIZATION=y
CONFIG_ARM64_CRYPTO=y
CONFIG_CRYPTO_AES_ARM64_CE=y

View File

@@ -0,0 +1,12 @@
SUBTARGET:=generic
BOARDNAME:=QTI IPQ53xx(64bit) based boards
CPU_TYPE:=cortex-a53
KERNELNAME:=Image dtbs
DEFAULT_PACKAGES += \
sysupgrade-helper
define Target/Description
Build images for IPQ53xx 64 bit system.
endef

View File

@@ -0,0 +1,26 @@
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$(IMG_PREFIX_EXTRA)$(BOARD)
# default all platform image(fit) build
define Device/Default
PROFILES = Default $$(DEVICE_NAME)
FILESYSTEMS := squashfs
DEVICE_DTS_DIR := $(DTS_DIR)/qcom
KERNEL_IN_UBI := 1
ROOTFSNAME_IN_UBI := ubi_rootfs
BLOCKSIZE := 128k
PAGESIZE := 2048
IMAGES := sysupgrade.tar nand-factory.bin
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand
KERNEL_NAME := Image
KERNEL = kernel-bin | gzip | fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
#KERNEL_INITRAMFS = kernel-bin | gzip | fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
KERNEL_INITRAMFS = kernel-bin | fit none $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb
endef
include ipq53xx.mk
$(eval $(call BuildImage))

View File

@@ -0,0 +1,13 @@
KERNEL_LOADADDR := 0x40080000
define Device/cig_wf198
DEVICE_TITLE := CIG WF198
DEVICE_DTS := ipq5332-cig-wf198
DEVICE_DTS_CONFIG := config@mi01.6
IMAGES := sysupgrade.tar nand-factory.bin nand-factory.ubi
IMAGE/sysupgrade.tar := sysupgrade-tar | append-metadata
IMAGE/nand-factory.bin := append-ubi | qsdk-ipq-factory-nand
IMAGE/nand-factory.ubi := append-ubi
DEVICE_PACKAGES := ath12k-wifi-cig-wf198
endef
TARGET_DEVICES += cig_wf198

View File

@@ -0,0 +1,6 @@
CONFIG_ARCH_IPQ9574=y
CONFIG_ARCH_MMAP_RND_BITS=8
CONFIG_PCIE_DW_PLAT=y
# CONFIG_USB_QCOM_DIAG_BRIDGE is not set
CONFIG_VMSPLIT_1G=y
# CONFIG_VMSPLIT_3G is not set

View File

@@ -0,0 +1,13 @@
ARCH:=arm
SUBTARGET:=ipq95xx_32
BOARDNAME:=QTI IPQ95xx(32bit) based boards
CPU_TYPE:=cortex-a7
DEFAULT_PACKAGES += \
uboot-2016-ipq9574 -uboot-2016-ipq95xx_tiny -lk-ipq95xx \
fwupgrade-tools
define Target/Description
Build firmware image for IPQ95xx SoC devices.
endef

View File

@@ -0,0 +1,61 @@
define KernelPackage/usb-dwc3-internal
TITLE:=DWC3 USB controller driver
DEPENDS:=+USB_GADGET_SUPPORT:kmod-usb-gadget
KCONFIG:= \
CONFIG_USB_DWC3 \
CONFIG_USB_DWC3_HOST=n \
CONFIG_USB_DWC3_GADGET=n \
CONFIG_USB_DWC3_DUAL_ROLE=y \
CONFIG_EXTCON=y \
CONFIG_USB_DWC3_DEBUG=n \
CONFIG_USB_DWC3_VERBOSE=n
FILES:= $(LINUX_DIR)/drivers/usb/dwc3/dwc3.ko
AUTOLOAD:=$(call AutoLoad,84,dwc3)
$(call AddPlatformDepends/usb)
endef
define KernelPackage/usb-dwc3-internal/description
This driver provides support for the Dual Role SuperSpeed
USB Controller based on the Synopsys DesignWare USB3 IP Core
endef
$(eval $(call KernelPackage,usb-dwc3-internal))
define KernelPackage/usb-dwc3-qcom-internal
TITLE:=DWC3 QTI USB driver
DEPENDS:=@!LINUX_4_14 @(TARGET_ipq40xx||TARGET_ipq806x||TARGET_ipq807x||TARGET_ipq60xx||TARGET_ipq95xx||TARGET_ipq50xx||TARGET_ipq53xx) +kmod-usb-dwc3-internal
KCONFIG:= CONFIG_USB_DWC3_QCOM
FILES:= $(LINUX_DIR)/drivers/usb/dwc3/dwc3-qcom.ko
AUTOLOAD:=$(call AutoLoad,83,dwc3-qcom)
$(call AddPlatformDepends/usb)
endef
define KernelPackage/usb-dwc3-qcom-internal/description
Some QTI SoCs use DesignWare Core IP for USB2/3 functionality.
This driver also handles Qscratch wrapper which is needed for
peripheral mode support.
endef
$(eval $(call KernelPackage,usb-dwc3-qcom-internal))
define KernelPackage/usb-phy-ipq807x
TITLE:=DWC3 USB QTI PHY drivers for IPQ807x based targets
DEPENDS:=@TARGET_ipq||TARGET_ipq807x||TARGET_ipq95xx||TARGET_ipq60xx
KCONFIG:= \
CONFIG_PHY_QCOM_QUSB2 \
CONFIG_PHY_QCOM_QMP=y \
CONFIG_USB_QCOM_QUSB_PHY \
CONFIG_USB_QCOM_QMP_PHY
FILES:= \
$(LINUX_DIR)/drivers/phy/qualcomm/phy-qcom-qusb2.ko@ge5.4 \
$(LINUX_DIR)/drivers/usb/phy/phy-msm-qusb.ko@le4.4 \
$(LINUX_DIR)/drivers/usb/phy/phy-msm-ssusb-qmp.ko@le4.4
AUTOLOAD:=$(call AutoLoad,85,phy-qcom-qusb2 phy-msm-qusb phy-msm-ssusb-qmp)
$(call AddPlatformDepends/usb)
endef
define KernelPackage/usb-phy-ipq807x/description
Support for USB PHY drivers in IPQ807x based SoCs.
endef
$(eval $(call KernelPackage,usb-phy-ipq807x))

View File

@@ -0,0 +1,13 @@
Index: linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d/net/ipv6/ip6mr.c
===================================================================
--- linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d.orig/net/ipv6/ip6mr.c
+++ linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d/net/ipv6/ip6mr.c
@@ -105,7 +105,7 @@ static ip6mr_mfc_event_offload_callback_
#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
#define ip6mr_for_each_table(mrt, net) \
- list_for_each_entry_rcu(mrt, &net->ipv6.mr_tables, list)
+ list_for_each_entry_rcu(mrt, &net->ipv6.mr6_tables, list)
static struct mr_table *ip6mr_mr_table_iter(struct net *net,
struct mr_table *mrt)

View File

@@ -0,0 +1,24 @@
Index: linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/arch/arm64/boot/dts/qcom/ipq6018.dtsi
===================================================================
--- linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452.orig/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -1882,6 +1882,7 @@
qti,scm_restart_reason {
compatible = "qti_ipq6018,scm_restart_reason";
+ dload_status = <1>;
};
ctx_save: ctx-save {
Index: linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/arch/arm64/boot/dts/qcom/ipq9574.dtsi
===================================================================
--- linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452.orig/arch/arm64/boot/dts/qcom/ipq9574.dtsi
+++ linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -3678,6 +3678,7 @@
qti,scm_restart_reason {
compatible = "qti_ipq9574,scm_restart_reason";
+ dload_status = <1>;
};
qti,gadget_diag@0 {

View File

@@ -0,0 +1,173 @@
From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001
From: John Crispin <blogic@openwrt.org>
Date: Tue, 12 Aug 2014 20:49:27 +0200
Subject: [PATCH 24/53] GPIO: add named gpio exports
Signed-off-by: John Crispin <blogic@openwrt.org>
---
drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++
drivers/gpio/gpiolib-sysfs.c | 10 +++++-
include/asm-generic/gpio.h | 6 ++++
include/linux/gpio/consumer.h | 8 +++++
4 files changed, 91 insertions(+), 1 deletion(-)
Index: linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/drivers/gpio/gpiolib-of.c
===================================================================
--- linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452.orig/drivers/gpio/gpiolib-of.c
+++ linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/drivers/gpio/gpiolib-of.c
@@ -19,6 +19,8 @@
#include <linux/pinctrl/pinctrl.h>
#include <linux/slab.h>
#include <linux/gpio/machine.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
#include "gpiolib.h"
#include "gpiolib-of.h"
@@ -917,3 +919,68 @@ void of_gpiochip_remove(struct gpio_chip
{
of_node_put(chip->of_node);
}
+
+static struct of_device_id gpio_export_ids[] = {
+ { .compatible = "gpio-export" },
+ { /* sentinel */ }
+};
+
+static int of_gpio_export_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *cnp;
+ u32 val;
+ int nb = 0;
+
+ for_each_child_of_node(np, cnp) {
+ const char *name = NULL;
+ int gpio;
+ bool dmc;
+ int max_gpio = 1;
+ int i;
+
+ of_property_read_string(cnp, "gpio-export,name", &name);
+
+ if (!name)
+ max_gpio = of_gpio_count(cnp);
+
+ for (i = 0; i < max_gpio; i++) {
+ unsigned flags = 0;
+ enum of_gpio_flags of_flags;
+
+ gpio = of_get_gpio_flags(cnp, i, &of_flags);
+ if (!gpio_is_valid(gpio))
+ return gpio;
+
+ if (of_flags == OF_GPIO_ACTIVE_LOW)
+ flags |= GPIOF_ACTIVE_LOW;
+
+ if (!of_property_read_u32(cnp, "gpio-export,output", &val))
+ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+ else
+ flags |= GPIOF_IN;
+
+ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np)))
+ continue;
+
+ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change");
+ gpio_export_with_name(gpio, dmc, name);
+ nb++;
+ }
+ }
+
+ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb);
+
+ return 0;
+}
+
+static struct platform_driver gpio_export_driver = {
+ .driver = {
+ .name = "gpio-export",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(gpio_export_ids),
+ },
+ .probe = of_gpio_export_probe,
+};
+
+module_platform_driver(gpio_export_driver);
Index: linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/drivers/gpio/gpiolib-sysfs.c
===================================================================
--- linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452.orig/drivers/gpio/gpiolib-sysfs.c
+++ linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/drivers/gpio/gpiolib-sysfs.c
@@ -571,7 +571,7 @@ static struct class gpio_class = {
*
* Returns zero on success, else an error.
*/
-int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name)
{
struct gpio_chip *chip;
struct gpio_device *gdev;
@@ -633,6 +633,8 @@ int gpiod_export(struct gpio_desc *desc,
offset = gpio_chip_hwgpio(desc);
if (chip->names && chip->names[offset])
ioname = chip->names[offset];
+ if (name)
+ ioname = name;
dev = device_create_with_groups(&gpio_class, &gdev->dev,
MKDEV(0, 0), data, gpio_groups,
@@ -654,6 +656,12 @@ err_unlock:
gpiod_dbg(desc, "%s: status %d\n", __func__, status);
return status;
}
+EXPORT_SYMBOL_GPL(__gpiod_export);
+
+int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
+{
+ return __gpiod_export(desc, direction_may_change, NULL);
+}
EXPORT_SYMBOL_GPL(gpiod_export);
static int match_export(struct device *dev, const void *desc)
Index: linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/include/asm-generic/gpio.h
===================================================================
--- linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452.orig/include/asm-generic/gpio.h
+++ linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/include/asm-generic/gpio.h
@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g
return gpiod_export(gpio_to_desc(gpio), direction_may_change);
}
+int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
+static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name)
+{
+ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name);
+}
+
static inline int gpio_export_link(struct device *dev, const char *name,
unsigned gpio)
{
Index: linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/include/linux/gpio/consumer.h
===================================================================
--- linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452.orig/include/linux/gpio/consumer.h
+++ linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/include/linux/gpio/consumer.h
@@ -668,6 +668,7 @@ static inline void devm_acpi_dev_remove_
#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
+int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name);
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
int gpiod_export_link(struct device *dev, const char *name,
struct gpio_desc *desc);
@@ -675,6 +676,13 @@ void gpiod_unexport(struct gpio_desc *de
#else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */
+static inline int _gpiod_export(struct gpio_desc *desc,
+ bool direction_may_change,
+ const char *name)
+{
+ return -ENOSYS;
+}
+
static inline int gpiod_export(struct gpio_desc *desc,
bool direction_may_change)
{

View File

@@ -0,0 +1,151 @@
From: Maxim Mikityanskiy <maximmi@nvidia.com>
Date: Tue, 30 Nov 2021 20:16:07 +0200
Subject: [PATCH] bpf: Fix the off-by-two error in range markings
commit 2fa7d94afc1afbb4d702760c058dc2d7ed30f226 upstream.
The first commit cited below attempts to fix the off-by-one error that
appeared in some comparisons with an open range. Due to this error,
arithmetically equivalent pieces of code could get different verdicts
from the verifier, for example (pseudocode):
// 1. Passes the verifier:
if (data + 8 > data_end)
return early
read *(u64 *)data, i.e. [data; data+7]
// 2. Rejected by the verifier (should still pass):
if (data + 7 >= data_end)
return early
read *(u64 *)data, i.e. [data; data+7]
The attempted fix, however, shifts the range by one in a wrong
direction, so the bug not only remains, but also such piece of code
starts failing in the verifier:
// 3. Rejected by the verifier, but the check is stricter than in #1.
if (data + 8 >= data_end)
return early
read *(u64 *)data, i.e. [data; data+7]
The change performed by that fix converted an off-by-one bug into
off-by-two. The second commit cited below added the BPF selftests
written to ensure than code chunks like #3 are rejected, however,
they should be accepted.
This commit fixes the off-by-two error by adjusting new_range in the
right direction and fixes the tests by changing the range into the
one that should actually fail.
Fixes: fb2a311a31d3 ("bpf: fix off by one for range markings with L{T, E} patterns")
Fixes: b37242c773b2 ("bpf: add test cases to bpf selftests to cover all access tests")
Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20211130181607.593149-1-maximmi@nvidia.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Index: linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/tools/testing/selftests/bpf/verifier/xdp_direct_packet_access.c
===================================================================
--- linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452.orig/tools/testing/selftests/bpf/verifier/xdp_direct_packet_access.c
+++ linux-5.4.213-qsdk-f2ee796db820cd8261889849f043c9c816196452/tools/testing/selftests/bpf/verifier/xdp_direct_packet_access.c
@@ -202,10 +202,10 @@
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
offsetof(struct xdp_md, data_end)),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
- BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
@@ -293,10 +293,10 @@
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
offsetof(struct xdp_md, data_end)),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
- BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
@@ -469,9 +469,9 @@
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
offsetof(struct xdp_md, data_end)),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
- BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
@@ -740,9 +740,9 @@
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
offsetof(struct xdp_md, data_end)),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
- BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
@@ -918,10 +918,10 @@
offsetof(struct xdp_md, data_meta)),
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
- BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
@@ -1009,10 +1009,10 @@
offsetof(struct xdp_md, data_meta)),
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
- BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
@@ -1185,9 +1185,9 @@
offsetof(struct xdp_md, data_meta)),
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
- BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},
@@ -1456,9 +1456,9 @@
offsetof(struct xdp_md, data_meta)),
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
- BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
- BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
},

View File

@@ -0,0 +1,38 @@
From: Nathan Chancellor <natechancellor@gmail.com>
Date: Mon, 6 Apr 2020 20:09:27 -0700
Subject: [PATCH] kernel/extable.c: use address-of operator on section symbols
Clang warns:
../kernel/extable.c:37:52: warning: array comparison always evaluates to
a constant [-Wtautological-compare]
if (main_extable_sort_needed && __stop___ex_table > __start___ex_table) {
^
1 warning generated.
These are not true arrays, they are linker defined symbols, which are just
addresses. Using the address of operator silences the warning and does
not change the resulting assembly with either clang/ld.lld or gcc/ld
(tested with diff + objdump -Dr).
Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Link: https://github.com/ClangBuiltLinux/linux/issues/892
Link: http://lkml.kernel.org/r/20200219202036.45702-1-natechancellor@gmail.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
--- a/kernel/extable.c
+++ b/kernel/extable.c
@@ -34,7 +34,8 @@ u32 __initdata __visible main_extable_so
/* Sort the kernel's built-in exception table */
void __init sort_main_extable(void)
{
- if (main_extable_sort_needed && __stop___ex_table > __start___ex_table) {
+ if (main_extable_sort_needed &&
+ &__stop___ex_table > &__start___ex_table) {
pr_notice("Sorting __ex_table...\n");
sort_extable(__start___ex_table, __stop___ex_table);
}

View File

@@ -0,0 +1,14 @@
--- a/drivers/bus/mhi/test/mhitest_pci.c
+++ b/drivers/bus/mhi/test/mhitest_pci.c
@@ -547,11 +547,6 @@ int mhitest_pci_register_mhi(struct mhit
mplat->mhi_ctrl = mhi_ctrl;
dev_set_drvdata(&pci_dev->dev, mplat);
mhi_ctrl->cntrl_dev = &pci_dev->dev;
-
- if (!mplat->fw_name) {
- MHITEST_ERR("fw_name is NULLL\n");
- return -EINVAL;
- }
mhi_ctrl->fw_image = mplat->fw_name;
mhi_ctrl->regs = mplat->bar;

View File

@@ -0,0 +1,14 @@
Index: linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d/net/bridge/br_arp_nd_proxy.c
===================================================================
--- linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d.orig/net/bridge/br_arp_nd_proxy.c
+++ linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d/net/bridge/br_arp_nd_proxy.c
@@ -198,7 +198,8 @@ void br_do_proxy_suppress_arp(struct sk_
if ((p && (p->flags & BR_PROXYARP)) ||
(f->dst && (f->dst->flags & (BR_PROXYARP_WIFI |
- BR_NEIGH_SUPPRESS)))) {
+ BR_NEIGH_SUPPRESS))
+ && memcmp(sha, n->ha, 6))) {
if (!vid)
br_arp_send(br, p, skb->dev, sip, tip,
sha, n->ha, sha, 0, 0);

View File

@@ -0,0 +1,15 @@
Index: linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d/drivers/soc/qcom/ctx-save.c
===================================================================
--- linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d.orig/drivers/soc/qcom/ctx-save.c
+++ linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d/drivers/soc/qcom/ctx-save.c
@@ -1509,8 +1509,8 @@ static int ctx_save_probe(struct platfor
#ifdef CONFIG_QCA_MINIDUMP
ret = register_module_notifier(&wlan_module_exit_nb);
- if (ret)
- dev_err(&pdev->dev, "Failed to register WLAN module exit notifier\n");
+ if (ret)
+ dev_err(&pdev->dev, "Failed to register WLAN module exit notifier\n");
ret = atomic_notifier_chain_register(&panic_notifier_list,
&wlan_panic_nb);

View File

@@ -0,0 +1,49 @@
Index: linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d/arch/arm64/boot/dts/qcom/ipq6018-memory.dtsi
===================================================================
--- linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d.orig/arch/arm64/boot/dts/qcom/ipq6018-memory.dtsi
+++ linux-5.4.164-qsdk-26349818b464f8c7b52d59ce73579d9f3dd6bd5d/arch/arm64/boot/dts/qcom/ipq6018-memory.dtsi
@@ -132,6 +132,14 @@
reg = <0x0 0x4d400000 0x0 0x100000>;
};
+ ramoops@4d500000 {
+ compatible = "ramoops";
+ reg = <0x0 0x4d500000 0x0 0x100000>;
+ record-size = <0x1000>;
+ console-size = <0x1000>;
+ pmsg-size = <0x1000>;
+ };
+
rpm_msg_ram: rpm_msg_ram@0x60000 {
no-map;
reg = <0x0 0x60000 0x0 0x6000>;
@@ -256,6 +264,14 @@
reg = <0x0 0x4e300000 0x0 0x100000>;
};
+ ramoops@4e400000 {
+ compatible = "ramoops";
+ reg = <0x0 0x4e400000 0x0 0x100000>;
+ record-size = <0x1000>;
+ console-size = <0x1000>;
+ pmsg-size = <0x1000>;
+ };
+
rpm_msg_ram: rpm_msg_ram@0x60000 {
no-map;
reg = <0x0 0x60000 0x0 0x6000>;
@@ -383,6 +399,14 @@
reg = <0x0 0x50100000 0x0 0x100000>;
};
+ ramoops@50200000 {
+ compatible = "ramoops";
+ reg = <0x0 0x50200000 0x0 0x100000>;
+ record-size = <0x1000>;
+ console-size = <0x1000>;
+ pmsg-size = <0x1000>;
+ };
+
rpm_msg_ram: rpm_msg_ram@0x60000 {
no-map;
reg = <0x0 0x60000 0x0 0x6000>;

View File

@@ -0,0 +1,136 @@
From: Andy Ren <andy.ren@getcruise.com>
Date: Mon, 7 Nov 2022 09:42:42 -0800
Subject: [PATCH] net/core: Allow live renaming when an interface is up
Allow a network interface to be renamed when the interface
is up.
As described in the netconsole documentation [1], when netconsole is
used as a built-in, it will bring up the specified interface as soon as
possible. As a result, user space will not be able to rename the
interface since the kernel disallows renaming of interfaces that are
administratively up unless the 'IFF_LIVE_RENAME_OK' private flag was set
by the kernel.
The original solution [2] to this problem was to add a new parameter to
the netconsole configuration parameters that allows renaming of
the interface used by netconsole while it is administratively up.
However, during the discussion that followed, it became apparent that we
have no reason to keep the current restriction and instead we should
allow user space to rename interfaces regardless of their administrative
state:
1. The restriction was put in place over 20 years ago when renaming was
only possible via IOCTL and before rtnetlink started notifying user
space about such changes like it does today.
2. The 'IFF_LIVE_RENAME_OK' flag was added over 3 years ago in version
5.2 and no regressions were reported.
3. In-kernel listeners to 'NETDEV_CHANGENAME' do not seem to care about
the administrative state of interface.
Therefore, allow user space to rename running interfaces by removing the
restriction and the associated 'IFF_LIVE_RENAME_OK' flag. Help in
possible triage by emitting a message to the kernel log that an
interface was renamed while UP.
[1] https://www.kernel.org/doc/Documentation/networking/netconsole.rst
[2] https://lore.kernel.org/netdev/20221102002420.2613004-1-andy.ren@getcruise.com/
Signed-off-by: Andy Ren <andy.ren@getcruise.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1503,7 +1503,6 @@ struct net_device_ops {
* @IFF_FAILOVER: device is a failover master device
* @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device
* @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device
- * @IFF_LIVE_RENAME_OK: rename is allowed while device is up and running
*/
enum netdev_priv_flags {
IFF_802_1Q_VLAN = 1<<0,
@@ -1536,7 +1535,7 @@ enum netdev_priv_flags {
IFF_FAILOVER = 1<<27,
IFF_FAILOVER_SLAVE = 1<<28,
IFF_L3MDEV_RX_HANDLER = 1<<29,
- IFF_LIVE_RENAME_OK = 1<<30,
+ /* was IFF_LIVE_RENAME_OK */
IFF_NO_IP_ALIGN = 1<<31,
};
@@ -1595,7 +1594,6 @@ enum netdev_priv_flags_ext {
#define IFF_FAILOVER IFF_FAILOVER
#define IFF_FAILOVER_SLAVE IFF_FAILOVER_SLAVE
#define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER
-#define IFF_LIVE_RENAME_OK IFF_LIVE_RENAME_OK
#define IFF_NO_IP_ALIGN IFF_NO_IP_ALIGN
/* Specifies the type of the struct net_device::ml_priv pointer */
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1093,22 +1093,6 @@ int dev_change_name(struct net_device *d
net = dev_net(dev);
- /* Some auto-enslaved devices e.g. failover slaves are
- * special, as userspace might rename the device after
- * the interface had been brought up and running since
- * the point kernel initiated auto-enslavement. Allow
- * live name change even when these slave devices are
- * up and running.
- *
- * Typically, users of these auto-enslaving devices
- * don't actually care about slave name change, as
- * they are supposed to operate on master interface
- * directly.
- */
- if (dev->flags & IFF_UP &&
- likely(!(dev->priv_flags & IFF_LIVE_RENAME_OK)))
- return -EBUSY;
-
down_write(&devnet_rename_sem);
if (strncmp(newname, dev->name, IFNAMSIZ) == 0) {
@@ -1125,7 +1109,8 @@ int dev_change_name(struct net_device *d
}
if (oldname[0] && !strchr(oldname, '%'))
- netdev_info(dev, "renamed from %s\n", oldname);
+ netdev_info(dev, "renamed from %s%s\n", oldname,
+ dev->flags & IFF_UP ? " (while UP)" : "");
old_assign_type = dev->name_assign_type;
dev->name_assign_type = NET_NAME_RENAMED;
--- a/net/core/failover.c
+++ b/net/core/failover.c
@@ -80,14 +80,14 @@ static int failover_slave_register(struc
goto err_upper_link;
}
- slave_dev->priv_flags |= (IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
+ slave_dev->priv_flags |= IFF_FAILOVER_SLAVE;
if (fops && fops->slave_register &&
!fops->slave_register(slave_dev, failover_dev))
return NOTIFY_OK;
netdev_upper_dev_unlink(slave_dev, failover_dev);
- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
err_upper_link:
netdev_rx_handler_unregister(slave_dev);
done:
@@ -121,7 +121,7 @@ int failover_slave_unregister(struct net
netdev_rx_handler_unregister(slave_dev);
netdev_upper_dev_unlink(slave_dev, failover_dev);
- slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK);
+ slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE;
if (fops && fops->slave_unregister &&
!fops->slave_unregister(slave_dev, failover_dev))

View File

@@ -0,0 +1,10 @@
define Profile/Default
NAME:=Default Profile (minimum package set)
PACKAGES:=
endef
define Profile/Default/Description
Default package set compatible with most boards.
endef
$(eval $(call Profile,Default))

View File

@@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=iw
PKG_VERSION:=5.16
PKG_VERSION:=5.19
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=https://www.kernel.org/pub/software/network/iw
PKG_HASH:=4c44e42762f903f9094ba5a598998c800a97a62afd6fd31ec1e0a799e308659c
PKG_HASH:=f167bbe947dd53bb9ebc0c1dcef5db6ad73ac1d6084f2c6f9376c5c360cc4d4e
PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
PKG_LICENSE:=GPL-2.0

View File

@@ -1,8 +1,8 @@
--- a/nl80211.h
+++ b/nl80211.h
@@ -2639,6 +2639,9 @@ enum nl80211_commands {
* Mandatory parameter for the transmitting interface to enable MBSSID.
* Optional for the non-transmitting interfaces.
@@ -2663,6 +2663,9 @@ enum nl80211_commands {
* association request when used with NL80211_CMD_NEW_STATION). Can be set
* only if %NL80211_STA_FLAG_WME is set.
*
+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
+ * transmit power to stay within regulatory limits. u32, dBi.
@@ -10,20 +10,26 @@
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3145,6 +3148,20 @@ enum nl80211_attrs {
NL80211_ATTR_MBSSID_CONFIG,
NL80211_ATTR_MBSSID_ELEMS,
@@ -3177,6 +3180,26 @@ enum nl80211_attrs {
NL80211_ATTR_DISABLE_EHT,
+ NL80211_ATTR_MLO_LINKS,
+ NL80211_ATTR_MLO_LINK_ID,
+ NL80211_ATTR_MLD_ADDR,
+
+ NL80211_ATTR_MLO_SUPPORT,
+
+ NL80211_ATTR_MAX_NUM_AKM_SUITES,
+
+ NL80211_ATTR_EML_CAPABILITY,
+ NL80211_ATTR_MLD_CAPA_AND_OPS,
+
+ NL80211_ATTR_TX_HW_TIMESTAMP,
+ NL80211_ATTR_RX_HW_TIMESTAMP,
+
+ NL80211_ATTR_HE_MUEDCA_PARAMS,
+
+ NL80211_ATTR_MULTIPLE_BSSID_PARENT,
+ NL80211_ATTR_MULTIPLE_BSSID_INDEX,
+ NL80211_ATTR_MULTIPLE_BSSID_COUNT,
+ NL80211_ATTR_MULTIPLE_BSSID_IES,
+ NL80211_ATTR_MULTIPLE_BSSID_EMA,
+
+ NL80211_ATTR_RNR_OFFSETS,
+
+ NL80211_ATTR_BEACON_TX_MODE,
+
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,

View File

@@ -1,40 +0,0 @@
Add channel attribure support for nl80211 message
---
info.c | 9 +++++++--
nl80211.h | 1 +
2 files changed, 8 insertions(+), 2 deletions(-)
--- a/info.c
+++ b/info.c
@@ -183,13 +183,18 @@ static int print_phy_handler(struct nl_m
band_had_freq = true;
}
nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) {
- uint32_t freq;
+ uint32_t freq,channel;
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq),
nla_len(nl_freq), freq_policy);
if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
continue;
freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
- printf("\t\t\t* %d MHz [%d]", freq, ieee80211_frequency_to_channel(freq));
+ if (tb_freq[NL80211_FREQUENCY_ATTR_CHANNEL])
+ channel = nla_get_u16(tb_freq[NL80211_FREQUENCY_ATTR_CHANNEL]);
+ else
+ channel = ieee80211_frequency_to_channel(freq);
+ printf("\t\t\t* %d MHz [%d]", freq, channel);
+
if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] &&
!tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
--- a/nl80211.h
+++ b/nl80211.h
@@ -3802,6 +3802,7 @@ enum nl80211_frequency_attr {
NL80211_FREQUENCY_ATTR_NO_20MHZ,
NL80211_FREQUENCY_ATTR_NO_10MHZ,
NL80211_FREQUENCY_ATTR_WMM,
+ NL80211_FREQUENCY_ATTR_CHANNEL,
NL80211_FREQUENCY_ATTR_NO_HE,
NL80211_FREQUENCY_ATTR_OFFSET,
NL80211_FREQUENCY_ATTR_1MHZ,

View File

@@ -1,90 +0,0 @@
From 72be4bb967e8081d4864619ff2afaad77e1956e2 Mon Sep 17 00:00:00 2001
From: Vikram Kandukuri <quic_vikram@quicinc.com>
Date: Wed, 20 Oct 2021 23:10:53 +0530
Subject: [PATCH] iw: Add MLO support in interface creation
Add MLO support in interface creation and add support to get
MLD mac address in dev info.
Signed-off-by: Vikram Kandukuri <quic_vikram@quicinc.com>
---
interface.c | 27 ++++++++++++++++++++++++++-
nl80211.h | 3 +++
2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/interface.c b/interface.c
index 57e2fe4..88b30e9 100644
--- a/interface.c
+++ b/interface.c
@@ -236,7 +236,9 @@ static int handle_interface_add(struct nl80211_state *state,
enum nl80211_iftype type;
int tpset;
unsigned char mac_addr[ETH_ALEN];
- int found_mac = 0;
+ unsigned char mld_mac_addr[ETH_ALEN];
+ int found_mac = 0, found_mld_mac = 0;
+ char mac_temp[20];
if (argc < 1)
return 1;
@@ -287,6 +289,18 @@ try_another:
fprintf(stderr, "flags error\n");
return 2;
}
+ } else if (strcmp(argv[0], "mld_addr") == 0) {
+ argc--;
+ argv++;
+ if (mac_addr_a2n(mld_mac_addr, argv[0])) {
+ fprintf(stderr, "Invalid MAC address\n");
+ return 2;
+ }
+ argc--;
+ argv++;
+ found_mld_mac = 1;
+ mac_addr_n2a(mac_temp, mld_mac_addr);
+ goto try_another;
} else {
return 1;
}
@@ -302,6 +316,10 @@ try_another:
if (found_mac)
NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
+ if (found_mld_mac)
+ NLA_PUT(msg, NL80211_ATTR_MLD_MAC, ETH_ALEN, mld_mac_addr);
+
+
return 0;
nla_put_failure:
return -ENOBUFS;
@@ -399,6 +417,13 @@ static int print_iface_handler(struct nl_msg *msg, void *arg)
mac_addr_n2a(mac_addr, nla_data(tb_msg[NL80211_ATTR_MAC]));
printf("%s\taddr %s\n", indent, mac_addr);
}
+
+ if (tb_msg[NL80211_ATTR_MLD_MAC]) {
+ char mld_mac_addr[20];
+ mac_addr_n2a(mld_mac_addr, nla_data(tb_msg[NL80211_ATTR_MLD_MAC]));
+ printf("%s\tmld_addr %s\n", indent, mld_mac_addr);
+ }
+
if (tb_msg[NL80211_ATTR_SSID]) {
printf("%s\tssid ", indent);
print_ssid_escaped(nla_len(tb_msg[NL80211_ATTR_SSID]),
diff --git a/nl80211.h b/nl80211.h
index 174851b..5654aca 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -3047,6 +3047,9 @@ enum nl80211_attrs {
NL80211_ATTR_WIPHY_ANTENNA_GAIN,
+ NL80211_ATTR_MLD_MAC=352,
+ NL80211_ATTR_MLD_REFERENCE=353,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
--
2.7.4

View File

@@ -13,34 +13,33 @@ Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
--- a/nl80211.h
+++ b/nl80211.h
@@ -3139,6 +3139,8 @@ enum nl80211_attrs {
@@ -1481,6 +1481,17 @@ enum nl80211_commands {
NL80211_ATTR_DISABLE_HE,
NL80211_CMD_ASSOC_COMEBACK,
+ NL80211_ATTR_HE_MUEDCA_PARAMS,
+ NL80211_CMD_ADD_LINK,
+ NL80211_CMD_REMOVE_LINK,
+
NL80211_ATTR_OBSS_COLOR_BITMAP,
+ NL80211_CMD_ADD_LINK_STA,
+ NL80211_CMD_MODIFY_LINK_STA,
+ NL80211_CMD_REMOVE_LINK_STA,
+
+ NL80211_CMD_UPDATE_HE_MUEDCA_PARAMS,
+
+ NL80211_CMD_AWGN_DETECT,
+
/* add new commands above here */
NL80211_ATTR_COLOR_CHANGE_COUNT,
@@ -3148,15 +3150,9 @@ enum nl80211_attrs {
NL80211_ATTR_MBSSID_CONFIG,
NL80211_ATTR_MBSSID_ELEMS,
/* used to define NL80211_CMD_MAX below */
@@ -3193,6 +3204,7 @@ enum nl80211_attrs {
- NL80211_ATTR_HE_MUEDCA_PARAMS,
-
- NL80211_ATTR_MULTIPLE_BSSID_PARENT,
- NL80211_ATTR_MULTIPLE_BSSID_INDEX,
- NL80211_ATTR_MULTIPLE_BSSID_COUNT,
- NL80211_ATTR_MULTIPLE_BSSID_IES,
- NL80211_ATTR_MULTIPLE_BSSID_EMA,
+ NL80211_ATTR_RADAR_BACKGROUND,
NL80211_ATTR_TX_HW_TIMESTAMP,
NL80211_ATTR_RX_HW_TIMESTAMP,
+ NL80211_ATTR_TD_BITMAP,
- NL80211_ATTR_RNR_OFFSETS,
+ NL80211_ATTR_AP_SETTINGS_FLAGS,
NL80211_ATTR_HE_MUEDCA_PARAMS,
NL80211_ATTR_BEACON_TX_MODE,
@@ -3164,6 +3160,20 @@ enum nl80211_attrs {
@@ -3202,6 +3214,18 @@ enum nl80211_attrs {
NL80211_ATTR_STA_MGMT_RTS_CTS_CONFIG,
@@ -50,44 +49,16 @@ Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
+
+ NL80211_ATTR_EMA_RNR_ELEMS,
+
+ NL80211_ATTR_EHT_CAPABILITY = NL80211_ATTR_MBSSID_ELEMS + 15,
+
+ NL80211_ATTR_DISABLE_EHT,
+
+ NL80211_ATTR_RU_PUNCT_SUPP_BW,
+
+ NL80211_ATTR_RU_PUNCT_SUPP_HE,
+
+ NL80211_ATTR_RU_PUNCT_BITMAP,
+
NL80211_ATTR_MLD_MAC=352,
NL80211_ATTR_MLD_REFERENCE=353,
/* add attributes here, update the policy in nl80211.c */
@@ -3429,6 +3439,13 @@ enum nl80211_he_ru_alloc {
* @NL80211_RATE_INFO_HE_DCM: HE DCM value (u8, 0/1)
* @NL80211_RATE_INFO_RU_ALLOC: HE RU allocation, if not present then
* non-OFDMA was used (u8, see &enum nl80211_he_ru_alloc)
+ * @NL80211_RATE_INFO_320_MHZ_WIDTH: 320 MHz bitrate
+ * @NL80211_RATE_INFO_EHT_MCS: EHT MCS index (u8, 0-15)
+ * @NL80211_RATE_INFO_EHT_NSS: EHT NSS value (u8, 1-8)
+ * @NL80211_RATE_INFO_EHT_GI: EHT guard interval identifier
+ * (u8, see &enum nl80211_eht_gi)
+ * @NL80211_RATE_INFO_EHT_RU_ALLOC: EHT RU allocation, if not present then
+ * non-OFDMA was used (u8, see &enum nl80211_eht_ru_alloc)
* @__NL80211_RATE_INFO_AFTER_LAST: internal use
*/
enum nl80211_rate_info {
@@ -3450,6 +3467,11 @@ enum nl80211_rate_info {
NL80211_RATE_INFO_HE_GI,
NL80211_RATE_INFO_HE_DCM,
NL80211_RATE_INFO_HE_RU_ALLOC,
+ NL80211_RATE_INFO_320_MHZ_WIDTH,
+ NL80211_RATE_INFO_EHT_MCS,
+ NL80211_RATE_INFO_EHT_NSS,
+ NL80211_RATE_INFO_EHT_GI,
+ NL80211_RATE_INFO_EHT_RU_ALLOC,
/* keep last */
__NL80211_RATE_INFO_AFTER_LAST,
@@ -3746,6 +3768,8 @@ enum nl80211_mpath_info {
__NL80211_ATTR_AFTER_LAST,
@@ -3845,6 +3869,8 @@ enum nl80211_mpath_info {
NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1
};
@@ -96,7 +67,7 @@ Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
/**
* enum nl80211_band_iftype_attr - Interface type data attributes
*
@@ -4954,6 +4978,11 @@ enum nl80211_key_attributes {
@@ -5074,6 +5100,11 @@ enum nl80211_key_attributes {
* see &struct nl80211_txrate_he
* @NL80211_TXRATE_HE_GI: configure HE GI, 0.8us, 1.6us and 3.2us.
* @NL80211_TXRATE_HE_LTF: configure HE LTF, 1XLTF, 2XLTF and 4XLTF.
@@ -108,7 +79,7 @@ Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
* @__NL80211_TXRATE_AFTER_LAST: internal
* @NL80211_TXRATE_MAX: highest TX rate attribute
*/
@@ -4967,6 +4996,9 @@ enum nl80211_tx_rate_attributes {
@@ -5087,6 +5118,9 @@ enum nl80211_tx_rate_attributes {
NL80211_TXRATE_HE_GI,
NL80211_TXRATE_HE_LTF,
NL80211_TXRATE_HE_UL,
@@ -118,7 +89,7 @@ Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
/* keep last */
__NL80211_TXRATE_AFTER_LAST,
@@ -5000,6 +5032,38 @@ enum nl80211_txrate_gi {
@@ -5120,6 +5154,26 @@ enum nl80211_txrate_gi {
};
/**
@@ -130,18 +101,6 @@ Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
+};
+
+/**
+ * enum nl80211_eht_gi - EHT guard interval
+ * @NL80211_RATE_INFO_EHT_GI_0_8: 0.8 usec
+ * @NL80211_RATE_INFO_EHT_GI_1_6: 1.6 usec
+ * @NL80211_RATE_INFO_EHT_GI_3_2: 3.2 usec
+ */
+enum nl80211_eht_gi {
+ NL80211_RATE_INFO_EHT_GI_0_8,
+ NL80211_RATE_INFO_EHT_GI_1_6,
+ NL80211_RATE_INFO_EHT_GI_3_2,
+};
+
+/**
+ * enum nl80211_eht_ltf - EHT long training field
+ * @NL80211_RATE_INFO_EHT_1xLTF: 3.2 usec
+ * @NL80211_RATE_INFO_EHT_2xLTF: 6.4 usec

View File

@@ -356,25 +356,3 @@ Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
NL80211_CMD_SET_TX_BITRATE_MASK, 0, CIB_NETDEV, handle_bitrates,
"Sets up the specified rate masks.\n"
"Not passing any arguments would clear the existing mask (if any).");
--- a/station.c
+++ b/station.c
@@ -259,6 +259,19 @@ void parse_bitrate(struct nlattr *bitrat
if (rinfo[NL80211_RATE_INFO_HE_RU_ALLOC])
pos += snprintf(pos, buflen - (pos - buf),
" HE-RU-ALLOC %d", nla_get_u8(rinfo[NL80211_RATE_INFO_HE_RU_ALLOC]));
+ if (rinfo[NL80211_RATE_INFO_EHT_MCS])
+ pos += snprintf(pos, buflen - (pos - buf),
+ " EHT-MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_EHT_MCS]));
+ if (rinfo[NL80211_RATE_INFO_EHT_NSS])
+ pos += snprintf(pos, buflen - (pos - buf),
+ " EHT-NSS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_EHT_NSS]));
+ if (rinfo[NL80211_RATE_INFO_EHT_GI])
+ pos += snprintf(pos, buflen - (pos - buf),
+ " EHT-GI %d", nla_get_u8(rinfo[NL80211_RATE_INFO_EHT_GI]));
+ if (rinfo[NL80211_RATE_INFO_EHT_RU_ALLOC])
+ pos += snprintf(pos, buflen - (pos - buf),
+ " EHT-RU-ALLOC %d", nla_get_u8(rinfo[NL80211_RATE_INFO_EHT_RU_ALLOC]));
+
}
static char *get_chain_signal(struct nlattr *attr_list)

View File

@@ -15,10 +15,8 @@ Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
util.c | 36 +++++++++++++++++++++++++++++++++++-
5 files changed, 47 insertions(+), 4 deletions(-)
Index: iw-5.16/event.c
===================================================================
--- iw-5.16.orig/event.c
+++ iw-5.16/event.c
--- a/event.c
+++ b/event.c
@@ -856,6 +856,9 @@ static void parse_ch_switch_notify(struc
case NL80211_CHAN_WIDTH_160:
printf("\"160 MHz\"");
@@ -29,20 +27,9 @@ Index: iw-5.16/event.c
case NL80211_CHAN_WIDTH_5:
printf("\"5 MHz\"");
break;
Index: iw-5.16/interface.c
===================================================================
--- iw-5.16.orig/interface.c
+++ iw-5.16/interface.c
@@ -376,6 +376,8 @@ char *channel_width_name(enum nl80211_ch
return "80+80 MHz";
case NL80211_CHAN_WIDTH_160:
return "160 MHz";
+ case NL80211_CHAN_WIDTH_320:
+ return "320 MHz";
case NL80211_CHAN_WIDTH_5:
return "5 MHz";
case NL80211_CHAN_WIDTH_10:
@@ -766,11 +768,11 @@ static int handle_chan(struct nl80211_st
--- a/interface.c
+++ b/interface.c
@@ -743,11 +743,11 @@ static int handle_chan(struct nl80211_st
SECTION(switch);
COMMAND(switch, freq,
@@ -57,10 +44,8 @@ Index: iw-5.16/interface.c
NL80211_CMD_CHANNEL_SWITCH, 0, CIB_NETDEV, handle_chan,
"Switch the operating channel by sending a channel switch announcement (CSA)."
"6GHz channels expects '6G' in argument. Defaults to 5GHz or 2GHz channels");
Index: iw-5.16/measurements.c
===================================================================
--- iw-5.16.orig/measurements.c
+++ iw-5.16/measurements.c
--- a/measurements.c
+++ b/measurements.c
@@ -189,6 +189,7 @@ static int parse_ftm_target(struct nl_ms
case NL80211_CHAN_WIDTH_160:
preamble = NL80211_PREAMBLE_VHT;
@@ -69,31 +54,8 @@ Index: iw-5.16/measurements.c
default:
return HANDLER_RET_USAGE;
}
Index: iw-5.16/nl80211.h
===================================================================
--- iw-5.16.orig/nl80211.h
+++ iw-5.16/nl80211.h
@@ -4677,6 +4677,8 @@ enum nl80211_key_mode {
* and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well
* @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
* attribute must be provided as well
+ * @NL80211_CHAN_WIDTH_320: 320 MHz channel, the %NL80211_ATTR_CENTER_FREQ1
+ * attribute must be provided as well
* @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel
* @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel
* @NL80211_CHAN_WIDTH_1: 1 MHz OFDM channel
@@ -4699,6 +4701,7 @@ enum nl80211_chan_width {
NL80211_CHAN_WIDTH_4,
NL80211_CHAN_WIDTH_8,
NL80211_CHAN_WIDTH_16,
+ NL80211_CHAN_WIDTH_320,
};
/**
Index: iw-5.16/util.c
===================================================================
--- iw-5.16.orig/util.c
+++ iw-5.16/util.c
--- a/util.c
+++ b/util.c
@@ -473,6 +473,7 @@ enum nl80211_chan_width str_to_bw(const
{ .name = "80", .val = NL80211_CHAN_WIDTH_80, },
{ .name = "80+80", .val = NL80211_CHAN_WIDTH_80P80, },
@@ -102,15 +64,7 @@ Index: iw-5.16/util.c
};
unsigned int i;
@@ -510,6 +511,7 @@ static int parse_freqs(struct chandef *c
case NL80211_CHAN_WIDTH_40:
case NL80211_CHAN_WIDTH_80:
case NL80211_CHAN_WIDTH_160:
+ case NL80211_CHAN_WIDTH_320:
need_cf1 = true;
break;
case NL80211_CHAN_WIDTH_1:
@@ -580,12 +582,12 @@ static int parse_freqs(struct chandef *c
@@ -581,12 +582,12 @@ static int parse_freqs(struct chandef *c
* user by giving "NOHT" instead.
*
* The working specifier if chan is set are:
@@ -126,8 +80,8 @@ Index: iw-5.16/util.c
*
* If the mode/channel width is not given the NOHT is assumed.
*
@@ -628,6 +630,10 @@ int parse_freqchan(struct chandef *chand
.width = NL80211_CHAN_WIDTH_160,
@@ -633,6 +634,10 @@ int parse_freqchan(struct chandef *chand
.width = NL80211_CHAN_WIDTH_320,
.freq1_diff = 0,
.chantype = -1 },
+ { .name = "320MHz",
@@ -137,7 +91,7 @@ Index: iw-5.16/util.c
};
const struct chanmode *chanmode_selected = NULL;
unsigned int freq;
@@ -1308,12 +1314,16 @@ void iw_hexdump(const char *prefix, cons
@@ -1697,13 +1702,16 @@ void iw_hexdump(const char *prefix, cons
int get_cf1(const struct chanmode *chanmode, unsigned long freq)
{
@@ -147,17 +101,17 @@ Index: iw-5.16/util.c
5955, 6035, 6115, 6195, 6275, 6355,
6435, 6515, 6595, 6675, 6755, 6835,
6195, 6995 };
unsigned int vht160[] = { 5180, 5500 };
+ unsigned int eht320_1[] = { 5955, 6275, 6595 };
+ unsigned int eht320_2[] = { 6115, 6435, 6755 };
+ unsigned int eht320_1diff, eht320_2diff;
+
unsigned int bw160[] = { 5180, 5500, 5955, 6115, 6275, 6435,
6595, 6755, 6915 };
+ unsigned int eht320_1[] = { 5955, 6275, 6595 };
+ unsigned int eht320_2[] = { 6115, 6435, 6755 };
+ unsigned int eht320_1diff, eht320_2diff;
switch (chanmode->width) {
case NL80211_CHAN_WIDTH_80:
@@ -1340,6 +1350,31 @@ int get_cf1(const struct chanmode *chanm
@@ -1730,6 +1738,31 @@ int get_cf1(const struct chanmode *chanm
cf1 = vht160[j] + 70;
cf1 = bw160[j] + 70;
break;
+ case NL80211_CHAN_WIDTH_320:
+ /* setup center_freq1 */
@@ -187,10 +141,8 @@ Index: iw-5.16/util.c
default:
cf1 = freq + chanmode->freq1_diff;
break;
Index: iw-5.16/phy.c
===================================================================
--- iw-5.16.orig/phy.c
+++ iw-5.16/phy.c
--- a/phy.c
+++ b/phy.c
@@ -199,14 +199,14 @@ static int handle_freq(struct nl80211_st
}

View File

@@ -1,279 +0,0 @@
From 9acc984a8790de84105011c2cf98bf5b5a0164f7 Mon Sep 17 00:00:00 2001
From: Muna Sinada <quic_msinada@quicinc.com>
Date: Wed, 26 Jan 2022 14:23:01 -0800
Subject: [PATCH] iw: Add EHT Capability Information
Add EHT capability information that is printed out in "iw phy"
commands.
Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
---
info.c | 4 +-
iw.h | 3 +
scan.c | 8 +++
util.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 220 insertions(+), 1 deletion(-)
--- a/info.c
+++ b/info.c
@@ -174,8 +174,10 @@ static int print_phy_handler(struct nl_m
struct nlattr *nl_iftype;
int rem_band;
- nla_for_each_nested(nl_iftype, tb_band[NL80211_BAND_ATTR_IFTYPE_DATA], rem_band)
+ nla_for_each_nested(nl_iftype, tb_band[NL80211_BAND_ATTR_IFTYPE_DATA], rem_band) {
print_he_info(nl_iftype);
+ print_eht_info(nl_iftype);
+ }
}
if (tb_band[NL80211_BAND_ATTR_FREQS]) {
if (!band_had_freq) {
--- a/iw.h
+++ b/iw.h
@@ -233,6 +233,9 @@ void print_ht_capability(__u16 cap);
void print_vht_info(__u32 capa, const __u8 *mcs);
void print_he_capability(const uint8_t *ie, int len);
void print_he_info(struct nlattr *nl_iftype);
+void print_eht_capability(const uint8_t *ie, int len);
+void print_eht_info(struct nlattr *nl_iftype);
+
char *channel_width_name(enum nl80211_chan_width width);
const char *iftype_name(enum nl80211_iftype iftype);
--- a/scan.c
+++ b/scan.c
@@ -2322,8 +2322,16 @@ static void print_he_capa(const uint8_t
print_he_capability(data, len);
}
+static void print_eht_capa(const uint8_t type, uint8_t len, const uint8_t *data,
+ const struct print_ies_data *ie_buffer)
+{
+ printf("\n");
+ print_eht_capability(data, len);
+}
+
static const struct ie_print ext_printers[] = {
[35] = { "HE capabilities", print_he_capa, 21, 54, BIT(PRINT_SCAN), },
+ [108] = { "EHT capabilities", print_eht_capa, 13, 62, BIT(PRINT_SCAN), },
};
static void print_extension(unsigned char len, unsigned char *ie,
--- a/util.c
+++ b/util.c
@@ -1187,6 +1187,121 @@ static void __print_he_capa(const __u16
}
}
+static void __print_eht_capa(const __u16 *mac_cap,
+ const __u16 *phy_cap,
+ const __u8 *mcs_set, size_t mcs_len,
+ const __u8 *ppet, int ppet_len,
+ bool indent)
+{
+ int i;
+ const char *pre = indent ? "\t" : "";
+
+ #define PRINT_EHT_CAP(_var, _idx, _bit, _str) \
+ do { \
+ if (_var[_idx] & BIT(_bit)) \
+ printf("%s\t\t\t" _str "\n", pre); \
+ } while (0)
+
+ #define PRINT_EHT_CAP_MASK(_var, _idx, _shift, _mask, _str) \
+ do { \
+ if ((_var[_idx] >> _shift) & _mask) \
+ printf("%s\t\t\t" _str ": %d\n", pre, (_var[_idx] >> _shift) & _mask); \
+ } while (0)
+
+ #define PRINT_EHT_MAC_CAP(...) PRINT_EHT_CAP(mac_cap, __VA_ARGS__)
+ #define PRINT_EHT_MAC_CAP_MASK(...) PRINT_EHT_CAP_MASK(mac_cap, __VA_ARGS__)
+ #define PRINT_EHT_PHY_CAP(...) PRINT_EHT_CAP(phy_cap, __VA_ARGS__)
+ #define PRINT_EHT_PHY_CAP0(_idx, _bit, ...) PRINT_EHT_CAP(phy_cap, _idx, _bit + 8, __VA_ARGS__)
+ #define PRINT_EHT_PHY_CAP_MASK(...) PRINT_EHT_CAP_MASK(phy_cap, __VA_ARGS__)
+
+ printf("%s\t\tEHT MAC Capabilities (0x", pre);
+ for (i = 0; i < 2; i++)
+ printf("%04x", mac_cap[i]);
+ printf("):\n");
+
+ PRINT_EHT_MAC_CAP(0, 0, "NSEP Priority Access Support");
+ PRINT_EHT_MAC_CAP(0, 1, "EHT OM Control Support");
+ PRINT_EHT_MAC_CAP(0, 2, "Triggered TXOP Sharing Mode 1 Support");
+ PRINT_EHT_MAC_CAP(0, 3, "Triggered TXOP Sharing Mode 2 Support");
+ PRINT_EHT_MAC_CAP(0, 4, "Restrived TWT Support");
+ PRINT_EHT_MAC_CAP(0, 5, "SCS Traffic Description Support");
+ PRINT_EHT_MAC_CAP_MASK(0, 6, 0x7, "Maximum MPDU Length");
+
+ printf("%s\t\tEHT PHY Capabilities: (0x", pre);
+ for (i = 0; i < 8; i++)
+ printf("%02x", ((__u8 *)phy_cap)[i + 1]);
+ printf("):\n");
+
+ PRINT_EHT_PHY_CAP0(0, 1, "320 MHz in 6 GHz Support");
+ PRINT_EHT_PHY_CAP0(0, 2, "242-tone RU in BW Wider Than 20 MHz Support");
+ PRINT_EHT_PHY_CAP0(0, 3, "NDP With 4x EHT-LTF and 3.2us GI");
+ PRINT_EHT_PHY_CAP0(0, 4, "Partial Bandwidth UL MU-MIMO");
+ PRINT_EHT_PHY_CAP0(0, 5, "SU Beamformer");
+ PRINT_EHT_PHY_CAP0(0, 6, "SU Beamformee");
+ PRINT_EHT_PHY_CAP_MASK(0, 7, 0x7, "Beamformee STS <= 80Mhz");
+ PRINT_EHT_PHY_CAP_MASK(0, 10, 0x7, "Beamformee STS = 160Mhz");
+ PRINT_EHT_PHY_CAP_MASK(0, 13, 0x7, "Beamformee STS = 320Mhz");
+ PRINT_EHT_PHY_CAP_MASK(1, 0, 0x7, "Sounding Dimensions <= 80Mhz");
+ PRINT_EHT_PHY_CAP_MASK(1, 3, 0x7, "Sounding Dimensions = 160Mhz");
+ PRINT_EHT_PHY_CAP_MASK(1, 6, 0x7, "Sounding Dimensions = 320Mhz");
+ PRINT_EHT_PHY_CAP(1, 9, "Ng = 16 SU Feedback");
+ PRINT_EHT_PHY_CAP(1, 10, "Ng = 16 MU Feedback");
+ PRINT_EHT_PHY_CAP(1, 11, "Codebook Size SU Feedback");
+ PRINT_EHT_PHY_CAP(1, 12, "Codebook Size MU Feedback");
+ PRINT_EHT_PHY_CAP(1, 13, "Triggered SU Beamforming Feedback");
+ PRINT_EHT_PHY_CAP(1, 14, "Triggered MU Beamforming Partial BW Feedback");
+ PRINT_EHT_PHY_CAP(1, 15, "Triggered CQI Feedback");
+ PRINT_EHT_PHY_CAP(2, 0, "Partial Bandwidth DL MU-MIMO");
+ PRINT_EHT_PHY_CAP(2, 1, "EHT PSR-based SR Support");
+ PRINT_EHT_PHY_CAP(2, 2, "Power Boost Factor Support");
+ PRINT_EHT_PHY_CAP(2, 3, "EHT MU PPDU With 4x EHT-LTF and 0.8us GI");
+ PRINT_EHT_PHY_CAP_MASK(2, 4, 0xf, "Max Nc");
+ PRINT_EHT_PHY_CAP(2, 8, "Non-Triggered CQI Feedback");
+ PRINT_EHT_PHY_CAP(2, 9, "TX 1024-QAM and 4096-QAM");
+ PRINT_EHT_PHY_CAP(2, 10, "RX 1024-QAM and 4096-QAM");
+ PRINT_EHT_PHY_CAP(2, 11, "PPE Thresholds Present");
+ PRINT_EHT_PHY_CAP_MASK(2, 12, 0x3, "Common Nominal Packet Padding");
+ PRINT_EHT_PHY_CAP(2, 14, "Extra EHT-LTFs Rx Support");
+ PRINT_EHT_PHY_CAP_MASK(2, 0, 0x7, "Max Number of Supported EHT-LTFs");
+ PRINT_EHT_PHY_CAP_MASK(3, 3, 0xf, "MCS 15 Support");
+ PRINT_EHT_PHY_CAP(3, 7, "EHT DUP (MCS 14) in 6 GHz Support");
+ PRINT_EHT_PHY_CAP(3, 8, "20 MHz Operating STA Recieving NDP With Wider BW");
+ PRINT_EHT_PHY_CAP(3, 9, "Non-OFDMA UL MU-MIMO <= 80Mhz");
+ PRINT_EHT_PHY_CAP(3, 10, "Non-OFDMA UL MU-MIMO = 160Mhz");
+ PRINT_EHT_PHY_CAP(3, 11, "Non-OFDMA UL MU-MIMO = 320Mhz");
+ PRINT_EHT_PHY_CAP(3, 12, "MU Beamformer <= 80Mhz");
+ PRINT_EHT_PHY_CAP(3, 13, "MU Beamformer = 160Mhz");
+ PRINT_EHT_PHY_CAP(3, 14, "MU Beamformer <= 320Mhz");
+ PRINT_EHT_PHY_CAP(3, 15, "TB Sounding Feedback Rate Limit");
+
+ char *bw[] = { "<= 80", "160", "360" };
+ for (i = 0; i < 3; i++) {
+ int j;
+
+ printf("%s\t\tEHT TX/RX MCS and NSS set %s MHz\n", pre, bw[i]);
+
+ for(j = 7; j >= 0; j--) {
+ printf("%s\t\t\t%d streams: ", pre, j + 1);
+ if (mcs_set[i * 3] >= j)
+ printf("MCS 0-13\n");
+ else if (mcs_set[(i * 3) + 1] >= j)
+ printf("MCS 0-11\n");
+ else if (mcs_set[(i * 3) + 2] >= j)
+ printf("MCS 0-9\n");
+ else
+ printf("not supported\n");
+ }
+ }
+
+ if (ppet_len) {
+ printf("%s\t\tEHT PPE Threshold ", pre);
+ for (i = 0; i < ppet_len; i++)
+ if (ppet[i])
+ printf("0x%02x ", ppet[i]);
+ printf("\n");
+ }
+}
+
void print_iftype_list(const char *name, const char *pfx, struct nlattr *attr)
{
struct nlattr *ift;
@@ -1293,6 +1408,80 @@ void print_he_capability(const uint8_t *
__print_he_capa(mac_cap, phy_cap - 1, mcs_set, mcs_len, NULL, 0, false);
}
+void print_eht_info(struct nlattr *nl_iftype)
+{
+ struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
+ __u16 mac_cap[1] = { 0 };
+ __u16 phy_cap[4] = { 0 };
+ __u8 mcs_set[9] = { 0 };
+ __u8 ppet[62] = { 0 };
+ size_t len;
+ int mcs_len = 0, ppet_len = 0;
+
+ nla_parse(tb, NL80211_BAND_IFTYPE_ATTR_MAX,
+ nla_data(nl_iftype), nla_len(nl_iftype), NULL);
+
+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]) {
+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]);
+ if (len > sizeof(mac_cap))
+ len = sizeof(mac_cap);
+ memcpy(mac_cap,
+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC]),
+ len);
+ }
+
+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]) {
+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]);
+
+ if (len > sizeof(phy_cap) - 1)
+ len = sizeof(phy_cap) - 1;
+ memcpy(&((__u8 *)phy_cap)[1],
+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]),
+ len);
+ }
+
+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]) {
+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]);
+ if (len > sizeof(mcs_set))
+ len = sizeof(mcs_set);
+ memcpy(mcs_set,
+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET]),
+ len);
+ mcs_len = len;
+ }
+
+ if (tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]) {
+ len = nla_len(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]);
+ if (len > sizeof(ppet))
+ len = sizeof(ppet);
+ memcpy(ppet,
+ nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE]),
+ len);
+ ppet_len = len;
+ }
+
+ __print_eht_capa(mac_cap, phy_cap, mcs_set, mcs_len, ppet, ppet_len,
+ true);
+}
+
+void print_eht_capability(const uint8_t *ie, int len)
+{
+ const void *mac_cap, *phy_cap, *mcs_set;
+ int mcs_len;
+ int i = 0;
+
+ mac_cap = &ie[i];
+ i += 2;
+
+ phy_cap = &ie[i];
+ i += 8;
+
+ mcs_set = &ie[i];
+ mcs_len = len - i;
+
+ __print_eht_capa(mac_cap, phy_cap - 1, mcs_set, mcs_len, NULL, 0, false);
+}
+
void iw_hexdump(const char *prefix, const __u8 *buf, size_t size)
{
size_t i;
--- a/nl80211.h
+++ b/nl80211.h
@@ -3786,6 +3786,10 @@ enum nl80211_band_iftype_attr {
NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET,
+ NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE,
/* keep last */
__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,

View File

@@ -13,11 +13,9 @@ Signed-off-by: Sivashankari Madhavan <quic_sivamadh@quicinc.com>
nl80211.h | 5 ++++-
2 files changed, 36 insertions(+), 1 deletion(-)
Index: iw-5.16/interface.c
===================================================================
--- iw-5.16.orig/interface.c
+++ iw-5.16/interface.c
@@ -1220,3 +1220,34 @@ COMMAND(set, tidconf, "[peer <MAC addres
--- a/interface.c
+++ b/interface.c
@@ -1222,3 +1222,52 @@ COMMAND(set, tidconf, "[peer <MAC addres
" $ iw dev wlan0 set tidconf peer xx:xx:xx:xx:xx:xx tids 0x2 bitrates auto\n"
" $ iw dev wlan0 set tidconf peer xx:xx:xx:xx:xx:xx tids 0x2 bitrates limit legacy-5 ht-mcs-5 vht-mcs-5 he-mcs-5 2:3\n"
);
@@ -27,36 +25,52 @@ Index: iw-5.16/interface.c
+ int argc, char **argv,
+ enum id_input id)
+{
+ char *end;
+ uint8_t ap_ps = 0;
+ char *end;
+ uint8_t ap_ps = 0;
+ int i = 0;
+
+ if (argc > 1)
+ return 1;
+ if (argc == 3) {
+ if (!strcmp(argv[0], "-l")) {
+ unsigned int link_id;
+
+ ap_ps = strtol(argv[0], &end, 10);
+ link_id = strtol(argv[1], &end, 10);
+ if (*end)
+ return 1;
+ if (link_id < MAX_MLD_LINK) {
+ NLA_PUT_U8(msg, NL80211_ATTR_MLO_LINK_ID,
+ link_id);
+ i = 2;
+ }
+ } else {
+ printf("Invalid parameter: %s\n", argv[0]);
+ return 1;
+ }
+ } else {
+ if (argc != 1)
+ return 1;
+ }
+
+ if (*end){
+ return 2;
+ }
+ ap_ps = strtol(argv[i], &end, 10);
+
+ if (ap_ps > 1)
+ if (*end)
+ return 2;
+
+ if (ap_ps > 1)
+ return -EINVAL;
+
+ NLA_PUT_U8(msg, NL80211_ATTR_AP_PS, ap_ps);
+ NLA_PUT_U8(msg, NL80211_ATTR_AP_PS, ap_ps);
+
+ return 0;
+ return 0;
+
+nla_put_failure:
+ return -ENOBUFS;
+ return -ENOBUFS;
+}
+
+COMMAND(set, ap_ps, "<Enable[1]/Disable[0]>",
+COMMAND(set, ap_ps, "[-l] <link id> <Enable[1]/Disable[0]>",
+ NL80211_CMD_UPDATE_AP, 0, CIB_NETDEV, handle_interface_ap_ps, NULL);
Index: iw-5.16/nl80211.h
===================================================================
--- iw-5.16.orig/nl80211.h
+++ iw-5.16/nl80211.h
@@ -1255,7 +1255,8 @@ enum nl80211_commands {
--- a/nl80211.h
+++ b/nl80211.h
@@ -1260,7 +1260,8 @@ enum nl80211_commands {
NL80211_CMD_DEL_KEY,
NL80211_CMD_GET_BEACON,
@@ -66,12 +80,22 @@ Index: iw-5.16/nl80211.h
NL80211_CMD_START_AP,
NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP,
NL80211_CMD_STOP_AP,
@@ -3170,6 +3171,8 @@ enum nl80211_attrs {
NL80211_ATTR_RU_PUNCT_SUPP_HE,
@@ -3225,6 +3226,8 @@ enum nl80211_attrs {
NL80211_ATTR_RU_PUNCT_BITMAP,
+ NL80211_ATTR_AP_PS,
+
NL80211_ATTR_MLD_MAC=352,
NL80211_ATTR_MLD_REFERENCE=353,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
--- a/iw.h
+++ b/iw.h
@@ -41,6 +41,7 @@ enum nlmsgerr_attrs {
#define ETH_ALEN 6
#define VHT_MUMIMO_GROUP_LEN 24
+#define MAX_MLD_LINK 15
/* libnl 1.x compatibility code */
#if !defined(CONFIG_LIBNL20) && !defined(CONFIG_LIBNL30)

View File

@@ -32,11 +32,9 @@ Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
reg.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/nl80211.h b/nl80211.h
index 95d2121..9bc5122 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -3858,6 +3858,20 @@ enum nl80211_band_attr {
@@ -3935,6 +3935,20 @@ enum nl80211_band_attr {
#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
@@ -57,7 +55,7 @@ index 95d2121..9bc5122 100644
/**
* enum nl80211_wmm_rule - regulatory wmm rule
*
@@ -4083,6 +4097,10 @@ enum nl80211_reg_type {
@@ -4165,6 +4179,10 @@ enum nl80211_reg_type {
* a given frequency range. The value is in mBm (100 * dBm).
* @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
* If not present or 0 default CAC time will be used.
@@ -68,7 +66,7 @@ index 95d2121..9bc5122 100644
* @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
* currently defined
* @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
@@ -4100,6 +4118,10 @@ enum nl80211_reg_rule_attr {
@@ -4182,6 +4200,10 @@ enum nl80211_reg_rule_attr {
NL80211_ATTR_DFS_CAC_TIME,
@@ -79,27 +77,25 @@ index 95d2121..9bc5122 100644
/* keep last */
__NL80211_REG_RULE_ATTR_AFTER_LAST,
NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
@@ -4181,6 +4203,7 @@ enum nl80211_sched_scan_match_attr {
* @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
@@ -4264,6 +4286,7 @@ enum nl80211_sched_scan_match_attr {
* @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
* @NL80211_RRF_NO_HE: HE operation not allowed
* @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed
+ * @NL80211_RRF_PSD: channels has power spectral density value
*/
enum nl80211_reg_rule_flags {
NL80211_RRF_NO_OFDM = 1<<0,
@@ -4199,6 +4222,7 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_NO_80MHZ = 1<<15,
@@ -4283,6 +4306,7 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_NO_160MHZ = 1<<16,
NL80211_RRF_NO_HE = 1<<17,
+ NL80211_RRF_PSD = 1<<18,
NL80211_RRF_NO_320MHZ = 1<<18,
+ NL80211_RRF_PSD = 1<<19,
};
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
diff --git a/reg.c b/reg.c
index feb347a..36f8192 100644
--- a/reg.c
+++ b/reg.c
@@ -111,6 +111,34 @@ COMMAND(reg, set, "<ISO/IEC 3166-1 alpha2>",
@@ -111,6 +111,34 @@ COMMAND(reg, set, "<ISO/IEC 3166-1 alpha
NL80211_CMD_REQ_SET_REG, 0, CIB_NONE, handle_reg_set,
"Notify the kernel about the current regulatory domain.");
@@ -134,7 +130,7 @@ index feb347a..36f8192 100644
static int print_reg_handler(struct nl_msg *msg, void *arg)
{
#define PARSE_FLAG(nl_flag, string_value) do { \
@@ -132,6 +160,8 @@ static int print_reg_handler(struct nl_msg *msg, void *arg)
@@ -132,6 +160,8 @@ static int print_reg_handler(struct nl_m
[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
[NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
[NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
@@ -143,7 +139,7 @@ index feb347a..36f8192 100644
};
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
@@ -164,6 +194,7 @@ static int print_reg_handler(struct nl_msg *msg, void *arg)
@@ -164,6 +194,7 @@ static int print_reg_handler(struct nl_m
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule) {
struct nlattr *tb_rule[NL80211_REG_RULE_ATTR_MAX + 1];
@@ -151,7 +147,7 @@ index feb347a..36f8192 100644
__u32 flags, start_freq_khz, end_freq_khz, max_bw_khz, max_ant_gain_mbi, max_eirp_mbm;
nla_parse(tb_rule, NL80211_REG_RULE_ATTR_MAX, nla_data(nl_rule), nla_len(nl_rule), reg_rule_policy);
@@ -196,6 +227,15 @@ static int print_reg_handler(struct nl_msg *msg, void *arg)
@@ -196,6 +227,15 @@ static int print_reg_handler(struct nl_m
continue;
}
@@ -167,6 +163,3 @@ index feb347a..36f8192 100644
/* Sync this output format to match that of dbparse.py from wireless-regdb.git */
PARSE_FLAG(NL80211_RRF_NO_OFDM, "NO-OFDM");
PARSE_FLAG(NL80211_RRF_NO_CCK, "NO-CCK");
--
2.17.1

View File

@@ -1,74 +0,0 @@
From 13cead1431549600e6f25013894217ad659513f5 Mon Sep 17 00:00:00 2001
From: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Date: Mon, 29 Aug 2022 10:12:16 +0530
Subject: [PATCH] iw: fix wrong information display for EHT PHY CAPABILITY in iw phy# info
Currently, EHT PHY capability information that is received from kernel
is stored from 9th bit of phy_cap and first 8 bit is zero,
when we are printing information, then first 8 bit of phy_cap
is checking with 8 bit of actual information.
Hence EHT PHY capability display wrong information in iw phy# info
Fix it by storing kernel information from index zero of phy_cap.
Fixes: a6de65ec ("iw: Add EHT Capability Information")
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
---
util.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
--- a/util.c
+++ b/util.c
@@ -1226,7 +1226,6 @@ static void __print_eht_capa(const __u16
#define PRINT_EHT_MAC_CAP(...) PRINT_EHT_CAP(mac_cap, __VA_ARGS__)
#define PRINT_EHT_MAC_CAP_MASK(...) PRINT_EHT_CAP_MASK(mac_cap, __VA_ARGS__)
#define PRINT_EHT_PHY_CAP(...) PRINT_EHT_CAP(phy_cap, __VA_ARGS__)
- #define PRINT_EHT_PHY_CAP0(_idx, _bit, ...) PRINT_EHT_CAP(phy_cap, _idx, _bit + 8, __VA_ARGS__)
#define PRINT_EHT_PHY_CAP_MASK(...) PRINT_EHT_CAP_MASK(phy_cap, __VA_ARGS__)
printf("%s\t\tEHT MAC Capabilities (0x", pre);
@@ -1243,16 +1242,16 @@ static void __print_eht_capa(const __u16
PRINT_EHT_MAC_CAP_MASK(0, 6, 0x7, "Maximum MPDU Length");
printf("%s\t\tEHT PHY Capabilities: (0x", pre);
- for (i = 0; i < 8; i++)
- printf("%02x", ((__u8 *)phy_cap)[i + 1]);
+ for (i = 0; i < 9; i++)
+ printf("%02x", ((__u8 *)phy_cap)[i]);
printf("):\n");
- PRINT_EHT_PHY_CAP0(0, 1, "320 MHz in 6 GHz Support");
- PRINT_EHT_PHY_CAP0(0, 2, "242-tone RU in BW Wider Than 20 MHz Support");
- PRINT_EHT_PHY_CAP0(0, 3, "NDP With 4x EHT-LTF and 3.2us GI");
- PRINT_EHT_PHY_CAP0(0, 4, "Partial Bandwidth UL MU-MIMO");
- PRINT_EHT_PHY_CAP0(0, 5, "SU Beamformer");
- PRINT_EHT_PHY_CAP0(0, 6, "SU Beamformee");
+ PRINT_EHT_PHY_CAP(0, 1, "320 MHz in 6 GHz Support");
+ PRINT_EHT_PHY_CAP(0, 2, "242-tone RU in BW Wider Than 20 MHz Support");
+ PRINT_EHT_PHY_CAP(0, 3, "NDP With 4x EHT-LTF and 3.2us GI");
+ PRINT_EHT_PHY_CAP(0, 4, "Partial Bandwidth UL MU-MIMO");
+ PRINT_EHT_PHY_CAP(0, 5, "SU Beamformer");
+ PRINT_EHT_PHY_CAP(0, 6, "SU Beamformee");
PRINT_EHT_PHY_CAP_MASK(0, 7, 0x7, "Beamformee STS <= 80Mhz");
PRINT_EHT_PHY_CAP_MASK(0, 10, 0x7, "Beamformee STS = 160Mhz");
PRINT_EHT_PHY_CAP_MASK(0, 13, 0x7, "Beamformee STS = 320Mhz");
@@ -1427,7 +1426,7 @@ void print_eht_info(struct nlattr *nl_if
{
struct nlattr *tb[NL80211_BAND_IFTYPE_ATTR_MAX + 1];
__u16 mac_cap[1] = { 0 };
- __u16 phy_cap[4] = { 0 };
+ __u16 phy_cap[5] = { 0 };
__u8 mcs_set[9] = { 0 };
__u8 ppet[62] = { 0 };
size_t len;
@@ -1450,7 +1449,7 @@ void print_eht_info(struct nlattr *nl_if
if (len > sizeof(phy_cap) - 1)
len = sizeof(phy_cap) - 1;
- memcpy(&((__u8 *)phy_cap)[1],
+ memcpy(&((__u8 *)phy_cap)[0],
nla_data(tb[NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY]),
len);
}

View File

@@ -18,8 +18,6 @@ Signed-off-by: Avula Sri Charan <quic_asrichar@quicinc.com>
util.c | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/sar.c b/sar.c
index 95e36e4..e7f8a9f 100644
--- a/sar.c
+++ b/sar.c
@@ -14,9 +14,10 @@
@@ -34,28 +32,3 @@ index 95e36e4..e7f8a9f 100644
static int set_sar_specs(struct nl80211_state *state,
struct nl_msg *msg,
int argc, char **argv,
diff --git a/util.c b/util.c
index 48735ab..036f162 100644
--- a/util.c
+++ b/util.c
@@ -1210,7 +1210,8 @@ static void __print_eht_capa(const __u16 *mac_cap,
{
int i;
const char *pre = indent ? "\t" : "";
-
+ char *bw[] = { "<= 80", "160", "360" };
+
#define PRINT_EHT_CAP(_var, _idx, _bit, _str) \
do { \
if (_var[_idx] & BIT(_bit)) \
@@ -1288,7 +1289,6 @@ static void __print_eht_capa(const __u16 *mac_cap,
PRINT_EHT_PHY_CAP(3, 14, "MU Beamformer <= 320Mhz");
PRINT_EHT_PHY_CAP(3, 15, "TB Sounding Feedback Rate Limit");
- char *bw[] = { "<= 80", "160", "360" };
for (i = 0; i < 3; i++) {
int j;
--
2.17.1

View File

@@ -0,0 +1,132 @@
From 953c7b5bcaaafa711833d3592c5ec8bd8e72fa68 Mon Sep 17 00:00:00 2001
From: Harshitha Prem <quic_hprem@quicinc.com>
Date: Wed, 12 Oct 2022 16:39:33 +0530
Subject: [PATCH] iw: Add support for background CAC
Changes are made to support following CLIs:
iw dev <wlanX> cac trigger channel <channel> [6G] [width] [bgcac]
iw dev <wlanX> cac stop
---
nl80211.h | 1 +
phy.c | 28 +++++++++++++++++++++++-----
2 files changed, 24 insertions(+), 5 deletions(-)
--- a/nl80211.h
+++ b/nl80211.h
@@ -1493,6 +1493,7 @@ enum nl80211_commands {
NL80211_CMD_AWGN_DETECT,
+ NL80211_CMD_STOP_BGRADAR_DETECT,
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
--- a/phy.c
+++ b/phy.c
@@ -282,15 +282,37 @@ static int handle_cac_trigger(struct nl8
enum id_input id)
{
struct chandef chandef;
- int res;
+ int res, count, index = 0;
if (argc < 2)
return 1;
- if (strcmp(argv[0], "channel") == 0) {
- res = parse_freqchan(&chandef, true, argc - 1, argv + 1, NULL);
- } else if (strcmp(argv[0], "freq") == 0) {
- res = parse_freqchan(&chandef, false, argc - 1, argv + 1, NULL);
+ if (!strcmp(argv[0], "-l")) {
+ unsigned int link_id;
+ char *endptr;
+
+ link_id = strtol(argv[1], &endptr, 10);
+
+ if (*endptr)
+ return 1;
+
+ if (link_id <= MAX_MLD_LINK) {
+ NLA_PUT_U8(msg, NL80211_ATTR_MLO_LINK_ID,
+ link_id);
+ index = 2;
+ }
+ }
+
+ if (strcmp(argv[argc - 1], "bgcac") == 0) {
+ NLA_PUT_FLAG(msg, NL80211_ATTR_RADAR_BACKGROUND);
+ count = argc - index - 2;
+ } else
+ count = argc - index - 1;
+
+ if (strcmp(argv[index], "channel") == 0) {
+ res = parse_freqchan(&chandef, true, count, argv + index + 1, NULL);
+ } else if (strcmp(argv[index], "freq") == 0) {
+ res = parse_freqchan(&chandef, false, count, argv + index + 1, NULL);
} else {
return 1;
}
@@ -299,6 +321,10 @@ static int handle_cac_trigger(struct nl8
return res;
return put_chandef(msg, &chandef);
+
+nla_put_failure:
+ return -ENOBUFS;
+
}
static int no_seq_check(struct nl_msg *msg, void *arg)
@@ -374,9 +400,9 @@ TOPLEVEL(cac, "channel <channel> [6G] [N
"freq <control freq> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
0, 0, CIB_NETDEV, handle_cac, NULL);
COMMAND(cac, trigger,
- "channel <channel> [6G] [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
- "freq <frequency> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz]\n"
- "freq <frequency> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]]",
+ "[-l] <link id> channel <channel> [6G] [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz] [bgcac]\n"
+ "freq <frequency> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz] [bgcac]\n"
+ "freq <frequency> [5|10|20|40|80|80+80|160] [<center1_freq> [<center2_freq>]] [bgcac]",
NL80211_CMD_RADAR_DETECT, 0, CIB_NETDEV, handle_cac_trigger,
"Start or trigger a channel availability check (CAC) looking to look for\n"
"radars on the given channel.");
@@ -882,3 +908,39 @@ static int handle_get_txq(struct nl80211
COMMAND(get, txq, "",
NL80211_CMD_GET_WIPHY, 0, CIB_PHY, handle_get_txq,
"Get TXQ parameters.");
+
+static int handle_cac_stop(struct nl80211_state *state,
+ struct nl_msg *msg,
+ int argc, char **argv,
+ enum id_input id)
+{
+ if (argc > 0) {
+ if (!strcmp(argv[0], "-l")) {
+ unsigned int link_id;
+ char *endptr;
+
+ if (argc != 2)
+ return 1;
+
+ link_id = strtol(argv[1], &endptr, 10);
+
+ if (*endptr)
+ return 1;
+
+ if (link_id <= MAX_MLD_LINK) {
+ NLA_PUT_U8(msg, NL80211_ATTR_MLO_LINK_ID,
+ link_id);
+ }
+ }
+ }
+
+ return 0;
+
+nla_put_failure:
+ return -ENOBUFS;
+}
+
+COMMAND(cac, stop, "[-l] <link id>",
+ NL80211_CMD_STOP_BGRADAR_DETECT, 0, CIB_NETDEV, handle_cac_stop,
+ "Stop the ongoing background CAC");
+

View File

@@ -1,26 +0,0 @@
From dd072e8e639554298b9d1205540cc4555efef1dd Mon Sep 17 00:00:00 2001
From: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
Date: Fri, 4 Nov 2022 00:22:17 +0530
Subject: [PATCH] iw: print handler to display 320MHz bitrate
This patch adds handler to print tx/rx bitrates
for 320MHz
Signed-off-by: Ramya Gnanasekar <quic_rgnanase@quicinc.com>
diff --git a/station.c b/station.c
index 970e8a5..5618200 100644
--- a/station.c
+++ b/station.c
@@ -239,6 +239,8 @@ void parse_bitrate(struct nlattr *bitrate_attr, char *buf, int buflen)
pos += snprintf(pos, buflen - (pos - buf), " 80P80MHz");
if (rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
pos += snprintf(pos, buflen - (pos - buf), " 160MHz");
+ if (rinfo[NL80211_RATE_INFO_320_MHZ_WIDTH])
+ pos += snprintf(pos, buflen - (pos - buf), " 320MHz");
if (rinfo[NL80211_RATE_INFO_SHORT_GI])
pos += snprintf(pos, buflen - (pos - buf), " short GI");
if (rinfo[NL80211_RATE_INFO_VHT_NSS])
--
2.17.1

View File

@@ -0,0 +1,128 @@
From acf2137f1b10a7ab8613258e420c74770c72f6cd Mon Sep 17 00:00:00 2001
From: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Date: Fri, 18 Nov 2022 17:52:41 +0530
Subject: [PATCH] iw: add link information for iw dev
print link address, channel, and tx power information for each link.
for MLO iw dev will display
phy#3
Interface wlan0
ifindex 34
wdev 0x30000000a
addr 00:03:7f:12:dc:dc
ssid OpenWrt
type AP
link 0:
addr 00:03:7f:12:dc:dc
channel 11 (2462 MHz), width: 20 MHz, center1: 2462 MHz
txpower 28.00 dBm
link 1:
addr 00:03:7f:12:dd:dd
channel 36 (5180 MHz), width: 80 MHz, center1: 5210 MHz
txpower 28.00 dBm
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
---
interface.c | 103 ++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 75 insertions(+), 28 deletions(-)
--- a/interface.c
+++ b/interface.c
@@ -387,10 +387,40 @@ char *channel_width_name(enum nl80211_ch
}
}
+static void print_channel_txpower(struct nlattr *tb_msg[], const char *space)
+{
+ if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
+ uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);
+ printf("\t\t%schannel %d (%d MHz)", space,
+ ieee80211_frequency_to_channel(freq), freq);
+ if (tb_msg[NL80211_ATTR_CHANNEL_WIDTH]) {
+ printf(", width: %s",
+ channel_width_name(nla_get_u32(tb_msg[NL80211_ATTR_CHANNEL_WIDTH])));
+ if (tb_msg[NL80211_ATTR_CENTER_FREQ1])
+ printf(", center1: %d MHz",
+ nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ1]));
+ if (tb_msg[NL80211_ATTR_CENTER_FREQ2])
+ printf(", center2: %d MHz",
+ nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ2]));
+ } else if (tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
+ enum nl80211_channel_type channel_type;
+ channel_type = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
+ printf(" %s", channel_type_name(channel_type));
+ }
+ printf("\n");
+ }
+ if (tb_msg[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]) {
+ int32_t txp = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]);
+ printf("\t\t%stxpower %d.%.2d dBm\n", space,
+ txp / 100, txp % 100);
+ }
+}
+
static int print_iface_handler(struct nl_msg *msg, void *arg)
{
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
+ struct nlattr *attrs, *link[NL80211_ATTR_MAX + 1];
unsigned int *wiphy = arg;
const char *indent = "";
@@ -436,38 +466,24 @@ static int print_iface_handler(struct nl
printf("%s\ttype %s\n", indent, iftype_name(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE])));
if (!wiphy && tb_msg[NL80211_ATTR_WIPHY])
printf("%s\twiphy %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]));
- if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) {
- uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]);
-
- printf("%s\tchannel %d (%d MHz)", indent,
- ieee80211_frequency_to_channel(freq), freq);
-
- if (tb_msg[NL80211_ATTR_CHANNEL_WIDTH]) {
- printf(", width: %s",
- channel_width_name(nla_get_u32(tb_msg[NL80211_ATTR_CHANNEL_WIDTH])));
- if (tb_msg[NL80211_ATTR_CENTER_FREQ1])
- printf(", center1: %d MHz",
- nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ1]));
- if (tb_msg[NL80211_ATTR_CENTER_FREQ2])
- printf(", center2: %d MHz",
- nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ2]));
- } else if (tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
- enum nl80211_channel_type channel_type;
-
- channel_type = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
- printf(" %s", channel_type_name(channel_type));
- }
-
- printf("\n");
+ if (tb_msg[NL80211_ATTR_MLO_LINKS]) {
+ int ret = 0;
+ nla_for_each_nested(attrs, tb_msg[NL80211_ATTR_MLO_LINKS], ret) {
+ nla_parse_nested(link, NL80211_ATTR_MAX, attrs, NULL);
+ if (link[NL80211_ATTR_MLO_LINK_ID]) {
+ printf("%s\tlink %d:\n", indent,
+ nla_get_u8(link[NL80211_ATTR_MLO_LINK_ID]));
+ if (link[NL80211_ATTR_MAC]) {
+ char link_addr[20];
+ mac_addr_n2a(link_addr, nla_data(link[NL80211_ATTR_MAC]));
+ printf("%s\t addr %s\n", indent, link_addr);
+ }
+ print_channel_txpower(link, " ");
+ }
+ }
+ } else {
+ print_channel_txpower(tb_msg, "");
}
-
- if (tb_msg[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]) {
- int32_t txp = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_TX_POWER_LEVEL]);
-
- printf("%s\ttxpower %d.%.2d dBm\n",
- indent, txp / 100, txp % 100);
- }
-
if (tb_msg[NL80211_ATTR_TXQ_STATS]) {
char buf[150];
parse_txq_stats(buf, sizeof(buf), tb_msg[NL80211_ATTR_TXQ_STATS], 1, -1, indent);

View File

@@ -0,0 +1,85 @@
From 21b83739d21aa8d995f004b35a8b14a26598ac47 Mon Sep 17 00:00:00 2001
From: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Date: Thu, 24 Nov 2022 10:35:40 +0530
Subject: [PATCH] iw: display link id for iw wlan# station dump
print associated link id for each interface.
for MLO iw wlan# station dump will display
Station 00:7a:f6:22:12:3e (on wlan0 - link0, link1)
inactive time: 16160 ms
rx bytes: 2984
rx packets: 5
tx bytes: 858
tx packets: 0
tx retries: 0
tx failed: 0
rx drop misc: 0
signal: -43 dBm
tx bitrate: 6.0 MBit/s
tx duration: 1366 us
rx duration: 0 us
authorized: no
authenticated: no
associated: no
WMM/WME: no
DTIM period: 0
beacon interval:0
short preamble: yes
short slot time:yes
connected time: 294 seconds
associated at [boottime]: 18411.885s
associated at: 1668599688499 ms
current time: 1668599982613 ms
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
---
station.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/station.c
+++ b/station.c
@@ -307,6 +307,7 @@ static int print_sta_handler(struct nl_m
struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
+ struct nlattr *attrs, *link[NL80211_ATTR_MAX + 1];
char mac_addr[20], state_name[10], dev[20];
struct nl80211_sta_flag_update *sta_flags;
static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
@@ -376,7 +377,24 @@ static int print_sta_handler(struct nl_m
mac_addr_n2a(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
- printf("Station %s (on %s)", mac_addr, dev);
+ if (tb[NL80211_ATTR_MLO_LINKS]) {
+ int ret = 0, offset = 0;
+ const char *indent = "";
+ char link_buf[MLD_MAX_LINK_BUF_SIZE];
+ nla_for_each_nested(attrs, tb[NL80211_ATTR_MLO_LINKS], ret) {
+ nla_parse_nested(link, NL80211_ATTR_MAX, attrs, NULL);
+ if (link[NL80211_ATTR_MLO_LINK_ID]) {
+ offset += snprintf(link_buf + offset,
+ MLD_MAX_LINK_BUF_SIZE - offset,
+ "%slink%d", indent,
+ nla_get_u8(link[NL80211_ATTR_MLO_LINK_ID]));
+ indent = ", ";
+ }
+ }
+ printf("Station %s (on %s - %s)", mac_addr, dev, link_buf);
+ } else {
+ printf("Station %s (on %s)", mac_addr, dev);
+ }
if (sinfo[NL80211_STA_INFO_INACTIVE_TIME])
printf("\n\tinactive time:\t%u ms",
--- a/iw.h
+++ b/iw.h
@@ -41,6 +41,7 @@ enum nlmsgerr_attrs {
#define ETH_ALEN 6
#define VHT_MUMIMO_GROUP_LEN 24
+#define MLD_MAX_LINK_BUF_SIZE 100
#define MAX_MLD_LINK 15
/* libnl 1.x compatibility code */

View File

@@ -0,0 +1,97 @@
From ae070708333cb4a08fde17590523d2adff401852 Mon Sep 17 00:00:00 2001
From: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Date: Tue, 17 Jan 2023 11:44:47 +0530
Subject: [PATCH] iw: add support set txpower command for each link
Add support for set tx power by link id in multi-link operation.
Command:
iw wlan0 set txpower -l <link id> <auto|fixed|limit> [<tx power in mBm>]
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
---
phy.c | 43 +++++++++++++++++++++++++++++++++----------
1 files changed, 34 insertions(+), 10 deletions(-)
--- a/phy.c
+++ b/phy.c
@@ -666,20 +666,43 @@ static int handle_txpower(struct nl80211
enum id_input id)
{
enum nl80211_tx_power_setting type;
- int mbm;
+ int mbm, i, max_argc;
/* get the required args */
- if (argc != 1 && argc != 2)
- return 1;
+ if (argc == 3 || argc == 4) {
+ max_argc = 4;
- if (!strcmp(argv[0], "auto"))
+ if (!strcmp(argv[0], "-l")) {
+ unsigned int link_id;
+ char *endptr;
+
+ link_id = strtol(argv[1], &endptr, 10);
+ if (*endptr)
+ return 1;
+ if (link_id <= MAX_MLD_LINK) {
+ NLA_PUT_U8(msg, NL80211_ATTR_MLO_LINK_ID,
+ link_id);
+ i = 2;
+ }
+ } else {
+ printf("Invalid parameter: %s\n", argv[0]);
+ return 1;
+ }
+ } else {
+ if (argc != 1 && argc != 2)
+ return 1;
+ max_argc = 2;
+ i = 0;
+ }
+
+ if (!strcmp(argv[i], "auto"))
type = NL80211_TX_POWER_AUTOMATIC;
- else if (!strcmp(argv[0], "fixed"))
+ else if (!strcmp(argv[i], "fixed"))
type = NL80211_TX_POWER_FIXED;
- else if (!strcmp(argv[0], "limit"))
+ else if (!strcmp(argv[i], "limit"))
type = NL80211_TX_POWER_LIMITED;
else {
- printf("Invalid parameter: %s\n", argv[0]);
+ printf("Invalid parameter: %s\n", argv[i]);
return 2;
}
@@ -687,16 +710,16 @@ static int handle_txpower(struct nl80211
if (type != NL80211_TX_POWER_AUTOMATIC) {
char *endptr;
- if (argc != 2) {
+ if (argc != max_argc) {
printf("Missing TX power level argument.\n");
return 2;
}
- mbm = strtol(argv[1], &endptr, 10);
+ mbm = strtol(argv[++i], &endptr, 10);
if (*endptr)
return 2;
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, mbm);
- } else if (argc != 1)
+ } else if (argc != max_argc-1)
return 1;
return 0;
@@ -707,7 +730,7 @@ static int handle_txpower(struct nl80211
COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]",
NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_txpower,
"Specify transmit power level and setting type.");
-COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]",
+COMMAND(set, txpower, "[-l] <link id> <auto|fixed|limit> [<tx power in mBm>]",
NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_txpower,
"Specify transmit power level and setting type.");

View File

@@ -0,0 +1,57 @@
From 07d07d8f7f6c2b7f648d22d06db772e0ad006cf6 Mon Sep 17 00:00:00 2001
From: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Date: Thu, 12 Jan 2023 16:36:37 +0530
Subject: [PATCH] iw: add support set bitrate command for each link
Add support for set bit rate by link id in multi-link operation.
command:
iw dev wlanX set bitrates -l <link_id> eht-mcs-<6/5/2.4>
<NSS:MCS0-MCS7/MCS9/MCS11/MCS13>
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
---
bitrate.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/bitrate.c b/bitrate.c
index 571ebb4..24752be 100644
--- a/bitrate.c
+++ b/bitrate.c
@@ -199,7 +199,7 @@ int set_bitrates(struct nl_msg *msg,
enum nl80211_attrs attr)
{
struct nlattr *nl_rates, *nl_band;
- int i, ret = 0;
+ int i, index, ret = 0;
bool have_legacy_24 = false, have_legacy_5 = false;
uint8_t legacy_24[32], legacy_5[32];
int n_legacy_24 = 0, n_legacy_5 = 0;
@@ -266,7 +266,23 @@ int set_bitrates(struct nl_msg *msg,
S_EHT_LTF,
} parser_state = S_NONE;
- for (i = 0; i < argc; i++) {
+ if (!strcmp(argv[0], "-l")) {
+ unsigned int link_id;
+ char *endptr;
+
+ link_id = strtol(argv[1], &endptr, 10);
+ if (*endptr)
+ return 1;
+ if (link_id <= MAX_MLD_LINK) {
+ NLA_PUT_U8(msg, NL80211_ATTR_MLO_LINK_ID,
+ link_id);
+ index = 2;
+ }
+ } else {
+ index = 0;
+ }
+
+ for (i = index; i < argc; i++) {
char *end;
double tmpd;
long tmpl;
--
2.17.1

View File

@@ -0,0 +1,75 @@
From f253847b35ea0d11526f27d7f4d931beab87d59f Mon Sep 17 00:00:00 2001
From: Aaradhana Sahu <quic_aarasahu@quicinc.com>
Date: Fri, 10 Feb 2023 15:47:48 +0530
Subject: [PATCH] iw: add support for rts threshold command for MLO
Add support for set rts threshold command according to
each link id for multi-link operation.
command:
iw dev wlan# set rts -l <link_id> <rts threshold|off>
Signed-off-by: Aaradhana Sahu <quic_aarasahu@quicinc.com>
---
phy.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
--- a/phy.c
+++ b/phy.c
@@ -444,19 +444,40 @@ static int handle_rts(struct nl80211_sta
int argc, char **argv,
enum id_input id)
{
- unsigned int rts;
+ unsigned int rts, link_id;
+ int index = 0;
+ char *endptr;
- if (argc != 1)
+ if (!argc) {
return 1;
+ } else if (argc == 3) {
+ if (!strcmp(argv[0], "-l")) {
+ link_id = strtol(argv[1], &endptr, 10);
+
+ if (*endptr)
+ return 1;
+
+ if (link_id <= MAX_MLD_LINK) {
+ NLA_PUT_U8(msg, NL80211_ATTR_MLO_LINK_ID,
+ link_id);
+ index = 2;
+ }
+ } else {
+ printf("Invalid parameter: %s\n", argv[0]);
+ return 1;
+ }
+ }
- if (strcmp("off", argv[0]) == 0)
+ if (strcmp("off", argv[index]) == 0) {
rts = -1;
- else {
+ } else {
char *end;
- if (!*argv[0])
+ if (!*argv[index])
return 1;
- rts = strtoul(argv[0], &end, 10);
+
+ rts = strtoul(argv[index], &end, 10);
+
if (*end != '\0')
return 1;
}
@@ -470,6 +491,9 @@ static int handle_rts(struct nl80211_sta
COMMAND(set, rts, "<rts threshold|off>",
NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_rts,
"Set rts threshold.");
+COMMAND(set, rts, "[-l] <link_id> <rts threshold|off>",
+ NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_rts,
+ "Set rts threshold.");
static int handle_retry(struct nl80211_state *state,
struct nl_msg *msg,

View File

@@ -0,0 +1,281 @@
From 9c263bc61d802fab30b3529ebdaace86f564e8f0 Mon Sep 17 00:00:00 2001
From: Harshitha Prem <quic_hprem@quicinc.com>
Date: Fri, 4 Nov 2022 18:51:54 +0530
Subject: [PATCH] iw: interface combination changes
print multi_hw channels
print multi_hw interface combinations
Signed-off-by: Harshitha Prem <quic_hprem@quicinc.com>
---
info.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-
nl80211.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 170 insertions(+), 2 deletions(-)
--- a/info.c
+++ b/info.c
@@ -390,7 +390,6 @@ next:
if (tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
unsigned char coverage;
-
coverage = nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
/* See handle_distance() for an explanation where the '450' comes from */
printf("\tCoverage class: %d (up to %dm)\n", coverage, 450 * coverage);
@@ -436,6 +435,7 @@ next:
struct nlattr *nl_combi;
int rem_combi;
bool have_combinations = false;
+ bool have_combinations_per_hw = false;
nla_for_each_nested(nl_combi, tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS], rem_combi) {
static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = {
@@ -444,6 +444,7 @@ next:
[NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG },
[NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 },
+ [NL80211_IFACE_COMB_PER_HW_COMB] = { .type = NLA_NESTED },
};
struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB];
static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = {
@@ -452,7 +453,15 @@ next:
};
struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT];
struct nlattr *nl_limit;
- int err, rem_limit;
+ static struct nla_policy iface_comb_per_hw_policy[NUM_NL80211_IFACE_COMB_PER_HW_COMB] = {
+ [NL80211_IFACE_COMB_PER_HW_COMB_HW_IDX] = { .type = NLA_U8 },
+ [NL80211_IFACE_COMB_PER_HW_COMB_LIMITS] = { .type = NLA_NESTED },
+ [NL80211_IFACE_COMB_PER_HW_COMB_MAXIMUM] = { .type = NLA_U16 },
+ [NL80211_IFACE_COMB_PER_HW_COMB_NUM_CHANNELS] = { .type = NLA_U32 },
+ };
+ struct nlattr *tb_per_hw[NUM_NL80211_IFACE_COMB_PER_HW_COMB];
+ struct nlattr *nl_per_hw;
+ int err, rem_limit, rem_per_hw;
bool comma = false;
if (!have_combinations) {
@@ -512,6 +521,43 @@ next:
}
}
printf("\n");
+
+ if (!tb_comb[NL80211_IFACE_COMB_PER_HW_COMB])
+ goto broken_combination;
+
+ nla_for_each_nested(nl_per_hw, tb_comb[NL80211_IFACE_COMB_PER_HW_COMB], rem_per_hw) {
+ comma = false;
+ if (!have_combinations_per_hw) {
+ printf("\tvalid interface combo per hw:");
+ have_combinations_per_hw = true;
+ }
+
+ err = nla_parse_nested(tb_per_hw, MAX_NL80211_IFACE_COMB_PER_HW_COMB,
+ nl_per_hw, iface_comb_per_hw_policy);
+ if (err || !tb_per_hw[NL80211_IFACE_COMB_PER_HW_COMB_HW_IDX]) {
+ printf("<failed to parse> at %d %d\n", __LINE__, err);
+ goto broken_combination;
+ }
+ printf("\n\t\thw_idx %d:\n\t\t\t max num of iface: %d, #channels <= %d,",
+ nla_get_u8(tb_per_hw[NL80211_IFACE_COMB_PER_HW_COMB_HW_IDX]),
+ nla_get_u32(tb_per_hw[NL80211_IFACE_COMB_PER_HW_COMB_MAXIMUM]),
+ nla_get_u16(tb_per_hw[NL80211_IFACE_COMB_NUM_CHANNELS]));
+ nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS], rem_limit) {
+ err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT,
+ nl_limit, iface_limit_policy);
+ if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) {
+ printf("<failed to parse> at %d %d\n", __LINE__, err);
+ goto broken_combination;
+ }
+ if (comma)
+ printf(", ");
+ comma = true;
+ printf("#{ ");
+ print_iftype_line(tb_limit[NL80211_IFACE_LIMIT_TYPES]);
+ printf(" } <= %u", nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX]));
+ }
+ }
+ printf("\n");
broken_combination:
;
}
@@ -762,6 +808,49 @@ broken_combination:
printf("\tMaximum associated stations in AP mode: %u\n",
nla_get_u16(tb_msg[NL80211_ATTR_MAX_AP_ASSOC_STA]));
+ if (tb_msg[NL80211_ATTR_MULTI_HW_MACS]) {
+ struct nlattr *tb_hw[NL80211_MULTI_HW_MAC_ATTR_MAX + 1];
+ struct nlattr *tb_freq[NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_MAX + 1];
+ struct nlattr *nl_hw_macs;
+ struct nlattr *nl_freq_list;
+ int rem_hw_macs, rem_freq_list;
+
+ nla_for_each_nested(nl_hw_macs, tb_msg[NL80211_ATTR_MULTI_HW_MACS],
+ rem_hw_macs) {
+ nla_parse(tb_hw, NL80211_MULTI_HW_MAC_ATTR_MAX,
+ nla_data(nl_hw_macs), nla_len(nl_hw_macs),
+ NULL);
+
+ if (tb_hw[NL80211_MULTI_HW_MAC_ATTR_IDX]) {
+ uint8_t hw_idx;
+ hw_idx = nla_get_u8(tb_hw[NL80211_MULTI_HW_MAC_ATTR_IDX]);
+ printf("\n\thw_idx %d channel list:\n", hw_idx);
+ }
+ if (tb_hw[NL80211_MULTI_HW_MAC_ATTR_CHAN_LIST]) {
+ uint8_t count = 0;
+ printf("\t\t");
+ nla_for_each_nested(nl_freq_list,
+ tb_hw[NL80211_MULTI_HW_MAC_ATTR_CHAN_LIST],
+ rem_freq_list) {
+ if (count == 20) {
+ printf("\n\t\t");
+ count = 0;
+ }
+ nla_parse(tb_freq, NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_MAX,
+ nla_data(nl_freq_list), nla_len(nl_freq_list),
+ NULL);
+ if (tb_freq[NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_FREQ]) {
+ uint32_t freq;
+ freq = nla_get_u32(tb_freq[NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_FREQ]);
+ printf("%d ",ieee80211_frequency_to_channel(freq));
+ count++;
+ }
+ }
+ }
+ }
+ printf("\n");
+ }
+
return NL_SKIP;
}
--- a/nl80211.h
+++ b/nl80211.h
@@ -3217,6 +3217,8 @@ enum nl80211_attrs {
NL80211_ATTR_AP_PS,
+ NL80211_ATTR_MULTI_HW_MACS,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -5826,6 +5828,10 @@ enum nl80211_iface_limit_attrs {
* @NL80211_IFACE_COMB_BI_MIN_GCD: u32 attribute specifying the minimum GCD of
* different beacon intervals supported by all the interface combinations
* in this group (if not present, all beacon intervals be identical).
+ * @NL80211_IFACE_COMB_PER_HW_COMB: nested attribute specifying the interface
+ * combination for each underlying hardware when multiple hardware are
+ * registered under a single wiphy,
+ * see &enum nl80211_if_combination_per_hw_comb_attrs.
* @NUM_NL80211_IFACE_COMB: number of attributes
* @MAX_NL80211_IFACE_COMB: highest attribute number
*
@@ -5841,6 +5847,16 @@ enum nl80211_iface_limit_attrs {
*
* numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4
* => allows a STA plus three P2P interfaces
+ * When describing per-hw combinations, the first possibility can
+ * further include the finer capabilities like below
+ * hw_chan_idx = 0, numbers = [ #{STA} <= 1, #{AP} <= 1 ],
+ * channels = 1, max = 2
+ * => allows a STA plus an AP interface on the underlying hw mac
+ * advertised at index 0 in wiphy @hw_chans array.
+ * hw_chan_idx = 1, numbers = [ #{STA} <= 1, #{AP} <= 2 ],
+ * channels = 1, max = 3
+ * => allows a STA plus two AP interfaces on the underlying hw mac
+ * advertised at index 1 in wiphy @hw_chans array.
*
* The list of these four possibilities could completely be contained
* within the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute to indicate
@@ -5861,12 +5877,43 @@ enum nl80211_if_combination_attrs {
NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
NL80211_IFACE_COMB_BI_MIN_GCD,
-
+ NL80211_IFACE_COMB_PER_HW_COMB,
/* keep last */
NUM_NL80211_IFACE_COMB,
MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1
};
+/**
+ * enum nl80211_if_combination_per_hw_comb_attrs - per-hw iface combination
+ * attributes with multi-hw radios
+ *
+ * @NL80211_IFACE_COMB_PER_HW_COMB_UNSPEC: (reserved)
+ * @NL80211_IFACE_COMB_PER_HW_COMB_HW_IDX: u8 attribute specifying the index
+ * to the wiphy @hw_chans list for which the iface combination is being
+ * described.
+ * @NL80211_IFACE_COMB_PER_HW_COMB_LIMITS: nested attribute containing the
+ * limits for the given interface types, see
+ * &enum nl80211_iface_limit_attrs.
+ * @NL80211_IFACE_COMB_PER_HW_COMB_MAXIMUM: u32 attribute giving the maximum
+ * number of interfaces that can be created in this group. This number
+ * does not apply to the interfaces purely managed in software.
+ * @NL80211_IFACE_COMB_PER_HW_COMB_NUM_CHANNELS: u32 attribute specifying the
+ * number of different channels that can be used in this group.
+ * @NUM_NL80211_IFACE_COMB_PER_HW_COMB: number of attributes
+ * @MAX_NL80211_IFACE_COMB_PER_HW_COMB: highest attribute number
+ */
+enum nl80211_if_combination_per_hw_comb_attrs {
+ NL80211_IFACE_COMB_PER_HW_COMB_UNSPEC,
+ NL80211_IFACE_COMB_PER_HW_COMB_HW_IDX,
+ NL80211_IFACE_COMB_PER_HW_COMB_LIMITS,
+ NL80211_IFACE_COMB_PER_HW_COMB_MAXIMUM,
+ NL80211_IFACE_COMB_PER_HW_COMB_NUM_CHANNELS,
+
+ /* keep last */
+ NUM_NL80211_IFACE_COMB_PER_HW_COMB,
+ MAX_NL80211_IFACE_COMB_PER_HW_COMB =
+ NUM_NL80211_IFACE_COMB_PER_HW_COMB - 1
+};
/**
* enum nl80211_plink_state - state of a mesh peer link finite state machine
@@ -7766,4 +7813,45 @@ enum nl80211_ap_settings_flags {
NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1,
};
+/**
+ * nl80211_multi_hw_mac_attrs - multi-hw mac attributes
+ *
+ * @NL80211_MULTI_HW_MAC_ATTR_INVALID: invalid
+ * @NL80211_MULTI_HW_MAC_ATTR_IDX: (u8) array index in wiphy @hw_chans to refer an
+ * underlying hw mac for which the supported channel list is advertised.
+ * @NL80211_MULTI_HW_MAC_ATTR_CHAN_LIST: nested attribute specifying list of
+ * supported channels, see &enum nl80211_multi_hw_mac_chan_list_attrs
+ * @__NL80211_MULTI_HW_MAC_ATTR_LAST: internal use
+ * @NL80211_MULTI_HW_MAC_ATTR_MAX: maximum multi-hw mac attribute
+ */
+enum nl80211_multi_hw_mac_attrs {
+ __NL80211_MULTI_HW_MAC_ATTR_INVALID,
+
+ NL80211_MULTI_HW_MAC_ATTR_IDX,
+ NL80211_MULTI_HW_MAC_ATTR_CHAN_LIST,
+
+ /* keep last */
+ __NL80211_MULTI_HW_MAC_ATTR_LAST,
+ NL80211_MULTI_HW_MAC_ATTR_MAX =
+ __NL80211_MULTI_HW_MAC_ATTR_LAST - 1
+};
+
+/**
+ * nl80211_multi_hw_mac_chan_list_attrs - channel attributes for multi-hw
+ *
+ * @__NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_INVALID: invalid
+ * @NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_FREQ: channel center frequency in MHz
+ * @__NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_LAST: internal use
+ * @NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_MAX: maximum channel attribute
+ */
+enum nl80211_multi_hw_mac_chan_list_attrs {
+ __NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_INVALID,
+
+ NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_FREQ,
+
+ /* keep last */
+ __NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_LAST,
+ NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_MAX =
+ __NL80211_MULTI_HW_MAC_CHAN_LIST_ATTR_LAST - 1
+};
#endif /* __LINUX_NL80211_H */

View File

@@ -0,0 +1,61 @@
From c9d3ed710064b8db1757ccc5fac03d3eb9a1a97a Mon Sep 17 00:00:00 2001
From: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
Date: Thu, 26 Jan 2023 17:59:07 +0530
Subject: [PATCH] iw: sync NL Attribute and Ext Feature with RRM changes
Due to RRM link measurement changes new NL Attribute and NL extended
feature are added in kernel. The NL attributes and extended feature
are:
NL80211_ATTR_WIPHY_MAX_TX_POWER_LEVEL
NL80211_EXT_FEATURE_TX_POWER_REPORTING
Add this NL changes in iw to sync NL attribute and NL extended
feature with kernel changes.
The below NL Attributes are used in iw. Thus sync will make the
below attributes not impacted after the RRM chnages.
NL80211_ATTR_RU_PUNCT_BITMAP
NL80211_ATTR_AP_PS
NL80211_ATTR_MULTI_HW_MACS
Signed-off-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
---
info.c | 3 +++
nl80211.h | 15 +++++++++++++++
2 files changed, 18 insertions(+)
--- a/info.c
+++ b/info.c
@@ -167,7 +167,9 @@ static void ext_feat_print(enum nl80211_
"support for MFP in range measurement negotiation/procedure");
ext_feat_case(BSS_COLOR, "BSS coloring support");
ext_feat_case(FILS_CRYPTO_OFFLOAD, "FILS crypto offload");
+ ext_feat_case(WIDE_BAND_SCAN, "wide band scan support");
ext_feat_case(RADAR_BACKGROUND, "Radar background support");
+ ext_feat_case(STA_MGMT_RTS_CTS, "station management RTS CTS support");
}
}
--- a/nl80211.h
+++ b/nl80211.h
@@ -6397,6 +6397,9 @@ enum nl80211_feature_flags {
* @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC
* detection.
*
+ * @NL80211_EXT_FEATURE_WIDE_BAND_SCAN: Driver/device supports wide band scan
+ * on a frequency along with its corresponding phymode (40Mhz, 80Mhz)
+ *
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
*/
@@ -6463,7 +6466,9 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
NL80211_EXT_FEATURE_BSS_COLOR,
NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD,
+ NL80211_EXT_FEATURE_WIDE_BAND_SCAN,
NL80211_EXT_FEATURE_RADAR_BACKGROUND,
+ NL80211_EXT_FEATURE_STA_MGMT_RTS_CTS,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,

View File

@@ -0,0 +1,395 @@
From 8fea084fa76f76159bcc110699eb5a91854e6f19 Mon Sep 17 00:00:00 2001
From: Nagarajan Maran <quic_nmaran@quicinc.com>
Date: Thu, 10 Nov 2022 18:52:12 +0530
Subject: [PATCH] iw: add support for sawf
Add configure, disable and view support for SAWF service classes.
Below is the command to configure a service class
- iw phy <phyname> service_class create <service_id> <app_name>
[min_tput <min_thruput_rate>] [max_tput <max_thruput_rate>]
[burst_size <burst_size>] [service_interval <service_interval>]
[delay_bound <delay_bound>] [msdu_ttl <msdu_ttl>] [priority <priority>]
[tid <tid>] [msdu_loss <msdu_rate_loss>]
Below is the command to disable a service class
- iw phy <phyname> service_class delete <service_id>
Below is the command to view a specific service class
- iw phy <phyname> service_class view <service_id>
Below is the command to view all service classes
- iw phy <phyname> service_class view
Signed-off-by: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
Co-Developed-by: Nagarajan Maran <quic_nmaran@quicinc.com>
Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
---
iw.h | 17 +++++
sawf.c | 215 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 232 insertions(+)
create mode 100644 sawf.c
--- a/iw.h
+++ b/iw.h
@@ -69,6 +69,12 @@ enum id_input {
II_WDEV,
};
+enum qca_nl80211_vendor_subcmds {
+ QCA_NL80211_VENDOR_SUBCMD_ROAM_EVENTS = 203,
+ QCA_NL80211_VENDOR_SUBCMD_SVC_CREATE = 204,
+ QCA_NL80211_VENDOR_SUBCMD_SVC_DISABLE = 205,
+ QCA_NL80211_VENDOR_SUBCMD_SVC_VIEW = 206,
+};
/* Attributes for data used by
* QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION and
* QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_CONFIGURATION subcommands.
@@ -82,6 +88,26 @@ enum qca_wlan_vendor_attr_config {
QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST - 1,
};
+enum qca_wlan_vendor_sawf_attr_config {
+ QCA_WLAN_VENDOR_ATTR_SAWF_SERVICE_CLASSES = 1,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_ID,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_APP_NAME,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MIN_TP,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MAX_TP,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_BURST_SIZE,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_INTERVAL,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_DELAY_BOUND,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_TTL,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_PRIO,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_TID,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_AFTER_LAST,
+ QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_MAX =
+ QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_AFTER_LAST - 1,
+};
+
#define HANDLER_RET_USAGE 1
#define HANDLER_RET_DONE 3
--- /dev/null
+++ b/sawf.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include <arpa/inet.h>
+
+#include "nl80211.h"
+#include "iw.h"
+
+#define OUI_QCA 0x001374
+#define MAX_OPTIONAL_STRINGS 9
+#define MAX_STRING_SIZE 60
+#define MAX_RANGE(type) pow(2, 8 * sizeof(type)) - 1
+#define SVC_CREATE_MIN_ARGUMENTS 2
+#define SVC_CREATE_MAX_ARGUMENTS 20
+#define SVC_DISABLE_MAX_ARGUMENTS 1
+#define SVC_VIEW_MAX_ARGUMENTS 1
+#define APP_NAME_MAX_BYTES 64
+
+struct sawf_disable_param {
+ uint8_t svc_id;
+};
+
+SECTION(service_class);
+
+static int handle_service_class_create(struct nl80211_state *state,
+ struct nl_msg *msg, int argc,
+ char **argv, enum id_input id)
+{
+ struct nlattr *service_class;
+ char app_name[APP_NAME_MAX_BYTES];
+ int parsed = 0, param_count;
+ char *end;
+ unsigned long value;
+ char service_check[MAX_OPTIONAL_STRINGS][MAX_STRING_SIZE] = {"min_tput",
+ "max_tput",
+ "burst_size",
+ "service_interval",
+ "delay_bound",
+ "msdu_ttl",
+ "priority",
+ "tid",
+ "msdu_loss"};
+
+ if (argc < SVC_CREATE_MIN_ARGUMENTS || argc > SVC_CREATE_MAX_ARGUMENTS ||
+ (argc % SVC_CREATE_MIN_ARGUMENTS) != 0)
+ goto err;
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SVC_CREATE);
+
+ service_class = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!service_class)
+ return -ENOBUFS;
+
+ errno = 0;
+ value = strtoul(argv[0], &end, 10);
+ if (*end != '\0' || value > MAX_RANGE(uint8_t) || errno == ERANGE)
+ goto err;
+
+ strlcpy(app_name, argv[1], APP_NAME_MAX_BYTES);
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_ID, value);
+ nla_put(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_APP_NAME, sizeof(app_name), app_name);
+
+ parsed += 2;
+
+ for (errno = 0; parsed < argc; parsed += 2, errno = 0) {
+ value = strtoul(argv[parsed + 1], &end, 10);
+ if (*end != '\0' || value > MAX_RANGE(uint32_t) || errno == ERANGE)
+ goto err;
+
+ for (param_count = 0; param_count < MAX_OPTIONAL_STRINGS;
+ param_count++) {
+ if (!strcmp(argv[parsed], service_check[param_count]))
+ break;
+ }
+
+ if (param_count == MAX_OPTIONAL_STRINGS)
+ goto err;
+
+ switch (param_count + QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MIN_TP) {
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MIN_TP:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MIN_TP, value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MAX_TP:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MAX_TP, value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_BURST_SIZE:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_BURST_SIZE, value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_INTERVAL:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_INTERVAL, value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_DELAY_BOUND:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_DELAY_BOUND,
+ value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_TTL:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_TTL, value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_PRIO:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_PRIO, value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_TID:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_TID, value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS,
+ value);
+ break;
+ }
+ }
+
+ nla_nest_end(msg, service_class);
+ return 0;
+err:
+ printf("Invalid SAWF service class command format: Usage\n");
+ printf("\t iw phy <phyname> service_class create <service_id> <app_name> ");
+ printf("[min_tput <min_thruput_rate>] [max_tput <max_thruput_rate>] ");
+ printf("[burst_size <burst_size>] [service_interval <service_interval>] ");
+ printf("[delay_bound <delay_bound>] [msdu_ttl <msdu_ttl>] ");
+ printf("[priority <priority>] [tid <tid>] [msdu_loss <msdu_rate_loss>]\n");
+
+ return -EINVAL;
+}
+
+COMMAND(service_class, create, "<service_id> <app_name> [min_tput <min_thruput_rate>]"
+ " [max_tput <max_thruput_rate>] [burst_size <burst_size>]"
+ " [service_interval <service_interval>] [delay_bound <delay_bound>]"
+ " [msdu_ttl <msdu_ttl>] [priority <priority>] [tid <tid>]"
+ " [msdu_loss <msdu_rate_loss>]", NL80211_CMD_VENDOR, 0, CIB_PHY,
+ handle_service_class_create, ".");
+
+static int handle_service_class_disable(struct nl80211_state *state,
+ struct nl_msg *msg, int argc,
+ char **argv, enum id_input id)
+{
+ struct nlattr *service_class;
+ unsigned long value;
+ char *end;
+
+ if (argc != SVC_DISABLE_MAX_ARGUMENTS)
+ goto err;
+
+ errno = 0;
+ value = strtoul(argv[0], &end, 10);
+ if (*end != '\0' || value > MAX_RANGE(uint8_t) || errno == ERANGE)
+ goto err;
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SVC_DISABLE);
+
+ service_class = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!service_class)
+ return -ENOBUFS;
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_ID, value);
+
+ nla_nest_end(msg, service_class);
+ return 0;
+
+err:
+ printf("Invalid SAWF service class command format: Usage\n");
+ printf("\t iw phy <phyname> service_class disable <service_id>\n");
+ return -EINVAL;
+}
+
+COMMAND(service_class, disable, "<service_id>", NL80211_CMD_VENDOR, 0, CIB_PHY,
+ handle_service_class_disable, ".");
+
+static int print_sawf_service_classes(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
+ struct nlattr *sawf_service_classes;
+ struct nlattr *sawf_service_class;
+ struct nlattr *attrs[QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_MAX + 1];
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ int sawf_service_classes_len = 0;
+ char *app_name = NULL;
+ static struct nla_policy sawf_policy[QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_MAX + 1] = {
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_ID] = {.type = NLA_U8},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_APP_NAME] = {.type = NLA_STRING},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MIN_TP] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MAX_TP] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_BURST_SIZE] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_INTERVAL] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_DELAY_BOUND] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_TTL] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_PRIO] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_TID] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS] = {.type = NLA_U32},
+ };
+
+ nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL);
+
+ if (tb_msg[NL80211_ATTR_VENDOR_DATA]) {
+ sawf_service_classes = nla_data(tb_msg[NL80211_ATTR_VENDOR_DATA]);
+ sawf_service_classes_len = nla_len(tb_msg[NL80211_ATTR_VENDOR_DATA]);
+ }
+ else
+ return NL_SKIP;
+
+ if (nla_type(sawf_service_classes) != QCA_WLAN_VENDOR_ATTR_SAWF_SERVICE_CLASSES )
+ return NL_SKIP;
+
+ nla_for_each_nested(sawf_service_class, sawf_service_classes,
+ sawf_service_classes_len) {
+ nla_parse_nested(attrs,
+ QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_MAX,
+ sawf_service_class, sawf_policy);
+
+ printf("***********************************\n");
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_ID])
+ printf("Service ID\t: %u\n",
+ nla_get_u8(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_ID]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_APP_NAME]) {
+ app_name = nla_data(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_APP_NAME]);
+ printf("App Name\t: %s\n", app_name);
+ }
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MIN_TP])
+ printf("Min throughput\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MIN_TP]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MAX_TP])
+ printf("Max throughput\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MAX_TP]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_BURST_SIZE])
+ printf("Burst Size\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_BURST_SIZE]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_INTERVAL])
+ printf("Service Interval: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_INTERVAL]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_DELAY_BOUND])
+ printf("Delay Bound\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_DELAY_BOUND]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_TTL])
+ printf("MSDU TTL\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_TTL]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_PRIO])
+ printf("Priority\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_PRIO]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_TID])
+ printf("TID\t\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_TID]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS])
+ printf("MSDU Loss Rate\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS]));
+ }
+ return NL_SKIP;
+}
+
+static int handle_service_class_dump(struct nl80211_state *state,
+ struct nl_msg *msg, int argc,
+ char **argv, enum id_input id)
+{
+ struct nlattr *service_class;
+ unsigned long value = 0;
+ char *end;
+
+ if (argc > SVC_VIEW_MAX_ARGUMENTS) {
+ goto err;
+ }
+ else if (argc == SVC_VIEW_MAX_ARGUMENTS) {
+ errno = 0;
+ value = strtoul(argv[0], &end, 10);
+ if (*end != '\0' || value > MAX_RANGE(uint8_t) || errno == ERANGE)
+ goto err;
+ }
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SVC_VIEW);
+
+ service_class = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!service_class)
+ return -ENOBUFS;
+
+ if (argc)
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_ID, value);
+
+ nla_nest_end(msg, service_class);
+
+ register_handler(print_sawf_service_classes, NULL);
+ return 0;
+err:
+ printf("Invalid SAWF service class command format: Usage\n");
+ printf("\t iw phy <phyname> service_class view [<service_id>]\n");
+ return -EINVAL;
+}
+
+COMMAND(service_class, view, "[<service_id>]", NL80211_CMD_VENDOR, NLM_F_DUMP, CIB_PHY,
+ handle_service_class_dump, ".");

View File

@@ -0,0 +1,197 @@
From 98e3c7c11e335d9f63bdf7377ba2ebfa6cc251b0 Mon Sep 17 00:00:00 2001
From: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
Date: Mon, 20 Mar 2023 14:00:30 +0530
Subject: [PATCH] iw: add support to add/del multi chan support for monitor
The below command helps to add multiple channels to monitor interface
iw dev mon0 add channel 11
iw dev mon0 add channel 36
iw dev mon0 add channel 49 6G
Similarly channel can be deleted from the monitor interface
iw dev mon0 del channel 36
The same is done for set freq command and added add freq and del freq
Signed-off-by: Karthikeyan Kathirvel <quic_kathirve@quicinc.com>
---
iw.h | 1 +
nl80211.h | 16 +++++++++
phy.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 119 insertions(+), 2 deletions(-)
diff --git a/iw.h b/iw.h
index d01b85b70df8..972df0c32fc8 100644
--- a/iw.h
+++ b/iw.h
@@ -324,6 +324,7 @@ DECLARE_SECTION(reg);
DECLARE_SECTION(roc);
DECLARE_SECTION(scan);
DECLARE_SECTION(set);
+DECLARE_SECTION(add);
DECLARE_SECTION(station);
DECLARE_SECTION(survey);
DECLARE_SECTION(switch);
diff --git a/nl80211.h b/nl80211.h
index 2d9a3d65afe8..f336ff4139dc 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -2683,6 +2683,16 @@ enum nl80211_commands {
* the operating channel as per device capability, policy and regulatory
* authority in signed mBm units.
*
+ * @NL80211_ATTR_RADAR_BITMAP: (u16) RADAR bitmap where the lowest bit
+ * corresponds to the lowest 20MHZ channel. Each bit set to 1
+ * indicates that radar is detected in that sub-channel.
+ *
+ * @NL80211_ATTR_ADD_MULTI_CHAN: Add channel to the radio, this is used
+ * for monitor interface (u32).
+ *
+ * @NL80211_ATTR_DEL_MULTI_CHAN: Delete channel from the radio, this is used
+ * for monitor interface (u32).
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3237,6 +3247,12 @@ enum nl80211_attrs {
NL80211_ATTR_MULTI_HW_MACS,
+ NL80211_ATTR_RADAR_BITMAP,
+
+ NL80211_ATTR_EHT_240MHZ_CAPABILITY,
+
+ NL80211_ATTR_ADD_MULTI_CHAN,
+ NL80211_ATTR_DEL_MULTI_CHAN,
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
diff --git a/phy.c b/phy.c
index e935c27af2ee..23cd45318dbd 100644
--- a/phy.c
+++ b/phy.c
@@ -15,6 +15,8 @@
#include "nl80211.h"
#include "iw.h"
+SECTION(add);
+
struct channels_ctx {
int last_band;
bool width_40;
@@ -209,6 +211,59 @@ COMMAND(set, freq,
"<control freq> [5|10|20|40|80|80+80|160|320] [<center1_freq> [<center2_freq>]] [ru-puncturing-bitmap <bitmap>]",
NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_freq, NULL);
+static int handle_add_freq(struct nl80211_state *state, struct nl_msg *msg,
+ int argc, char **argv,
+ enum id_input id)
+{
+ struct chandef chandef;
+ int res;
+
+ res = parse_freqchan(&chandef, false, argc, argv, NULL);
+ if (res)
+ return res;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_ADD_MULTI_CHAN, true);
+
+ return put_chandef(msg, &chandef);
+ nla_put_failure:
+ return -ENOBUFS;
+}
+
+COMMAND(add, freq,
+ "<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz|320MHz]\n"
+ "<control freq> [5|10|20|40|80|80+80|160|320] [<center1_freq> [<center2_freq>]]",
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_add_freq,
+ "Set frequency/channel the hardware is using, including HT\n"
+ "configuration.");
+COMMAND(add, freq,
+ "<freq> [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz|320MHz]\n"
+ "<control freq> [5|10|20|40|80|80+80|160|320] [<center1_freq> [<center2_freq>]]",
+ NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_add_freq, NULL);
+
+static int handle_del_freq(struct nl80211_state *state, struct nl_msg *msg,
+ int argc, char **argv,
+ enum id_input id)
+{
+ struct chandef chandef;
+ int res;
+
+ res = parse_freqchan(&chandef, false, argc, argv, NULL);
+ if (res)
+ return res;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_DEL_MULTI_CHAN, true);
+
+ return put_chandef(msg, &chandef);
+ nla_put_failure:
+ return -ENOBUFS;
+}
+
+COMMAND(del, freq, "<freq>\n",
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_del_freq,
+ "del frequency/channel the hardware is using\n");
+COMMAND(del, freq, "<freq>\n",
+ NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_del_freq, NULL);
+
static int handle_chan(struct nl80211_state *state, struct nl_msg *msg,
int argc, char **argv,
enum id_input id)
@@ -227,6 +282,52 @@ COMMAND(set, channel, "<channel> [6G] [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|16
COMMAND(set, channel, "<channel> [6G] [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz|320MHz] [6G] [ru-puncturing-bitmap <bitmap>]",
NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_chan, NULL);
+static int handle_add_chan(struct nl80211_state *state, struct nl_msg *msg,
+ int argc, char **argv,
+ enum id_input id)
+{
+ struct chandef chandef;
+ int res;
+
+ res = parse_freqchan(&chandef, true, argc, argv, NULL);
+ if (res)
+ return res;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_ADD_MULTI_CHAN, true);
+
+ return put_chandef(msg, &chandef);
+
+ nla_put_failure:
+ return -ENOBUFS;
+}
+COMMAND(add, channel, "<channel> [6G] [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz|320MHz]",
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_add_chan, NULL);
+COMMAND(add, channel, "<channel> [6G] [NOHT|HT20|HT40+|HT40-|5MHz|10MHz|80MHz|160MHz|320MHz] [6G]",
+ NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_add_chan, NULL);
+
+static int handle_del_chan(struct nl80211_state *state, struct nl_msg *msg,
+ int argc, char **argv,
+ enum id_input id)
+{
+ struct chandef chandef;
+ int res;
+
+ res = parse_freqchan(&chandef, true, argc, argv, NULL);
+ if (res)
+ return res;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_DEL_MULTI_CHAN, true);
+
+ return put_chandef(msg, &chandef);
+
+ nla_put_failure:
+ return -ENOBUFS;
+}
+COMMAND(del, channel, "<channel> [6G]",
+ NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_del_chan, NULL);
+COMMAND(del, channel, "<channel> [6G]",
+ NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_del_chan, NULL);
+
struct cac_event {
int ret;
--
2.38.0

View File

@@ -0,0 +1,115 @@
From 1898807476c589bf140d7cf9690f172e9c97ab18 Mon Sep 17 00:00:00 2001
From: Sivashankari Madhavan <quic_sivamadh@quicinc.com>
Date: Fri, 5 May 2023 10:34:40 +0530
Subject: [PATCH] iw: Add support for link specific station dump fields display
While connecting the AP with a station in SLO/MLO mode observe
the Dtim period and Beacon Interval as 0 in the station dump.
During the start AP, these fields are updated in the specific
link config. But when setting the station info, it's referring
to the sdata bss config. Due to this, observing the issue.
Fix it by updating these fields with corresponding link config data
per active link.
Signed-off-by: Sivashankari Madhavan <quic_sivamadh@quicinc.com>
---
nl80211.h | 8 ++++++++
station.c | 51 +++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 51 insertions(+), 8 deletions(-)
Index: iw-5.19/station.c
===================================================================
--- iw-5.19.orig/station.c
+++ iw-5.19/station.c
@@ -148,9 +148,11 @@ static void parse_tid_stats(struct nlatt
printf("\n\tTXQs:%s", txqbuf);
}
-static void parse_bss_param(struct nlattr *bss_param_attr)
+static void parse_bss_param(struct nlattr *bss_param_attr,
+ struct nlattr *tb[NL80211_ATTR_MAX + 1])
{
struct nlattr *bss_param_info[NL80211_STA_BSS_PARAM_MAX + 1], *info;
+ struct nlattr *attrs;
static struct nla_policy bss_poilcy[NL80211_STA_BSS_PARAM_MAX + 1] = {
[NL80211_STA_BSS_PARAM_CTS_PROT] = { .type = NLA_FLAG },
[NL80211_STA_BSS_PARAM_SHORT_PREAMBLE] = { .type = NLA_FLAG },
@@ -159,17 +161,58 @@ static void parse_bss_param(struct nlatt
[NL80211_STA_BSS_PARAM_BEACON_INTERVAL] = { .type = NLA_U16 },
};
- if (nla_parse_nested(bss_param_info, NL80211_STA_BSS_PARAM_MAX,
- bss_param_attr, bss_poilcy)) {
- printf("failed to parse nested bss param attributes!");
+ if (tb[NL80211_ATTR_MLO_LINKS]) {
+ int ret = 0, dtim_offset = 0, beacon_int_offset = 0;
+ const char *dtim_indent = "", *beacon_int_indent = "";
+ char dtim_buf[MLD_MAX_LINK_BUF_SIZE],
+ beacon_int_buf[MLD_MAX_LINK_BUF_SIZE];
+
+ nla_for_each_nested(attrs, bss_param_attr, ret) {
+ if (nla_parse_nested(bss_param_info,
+ NL80211_STA_BSS_PARAM_MAX,
+ attrs, bss_poilcy)) {
+ printf("\nFailed to parse nested bss param attributes!\n");
+ }
+
+ info = bss_param_info[NL80211_STA_BSS_PARAM_DTIM_PERIOD];
+
+ if (info) {
+ dtim_offset += snprintf(dtim_buf + dtim_offset,
+ MLD_MAX_LINK_BUF_SIZE - dtim_offset,
+ "%s%u", dtim_indent,
+ nla_get_u8(info));
+ dtim_indent = ", ";
+ }
+
+ info = bss_param_info[NL80211_STA_BSS_PARAM_BEACON_INTERVAL];
+
+ if (info) {
+ beacon_int_offset += snprintf(beacon_int_buf + beacon_int_offset,
+ MLD_MAX_LINK_BUF_SIZE - beacon_int_offset,
+ "%s%u", beacon_int_indent,
+ nla_get_u16(info));
+ beacon_int_indent = ", ";
+ }
+ }
+
+ printf("\n\tDTIM period:\t%s",dtim_buf);
+
+ printf("\n\tbeacon interval:%s",beacon_int_buf);
+ } else {
+ if (nla_parse_nested(bss_param_info,
+ NL80211_STA_BSS_PARAM_MAX,
+ bss_param_attr, bss_poilcy)) {
+ printf("\nFailed to parse nested bss param attributes!\n");
+ }
+
+ info = bss_param_info[NL80211_STA_BSS_PARAM_DTIM_PERIOD];
+ if (info)
+ printf("\n\tDTIM period:\t%u", nla_get_u8(info));
+ info = bss_param_info[NL80211_STA_BSS_PARAM_BEACON_INTERVAL];
+ if (info)
+ printf("\n\tbeacon interval:%u", nla_get_u16(info));
}
- info = bss_param_info[NL80211_STA_BSS_PARAM_DTIM_PERIOD];
- if (info)
- printf("\n\tDTIM period:\t%u", nla_get_u8(info));
- info = bss_param_info[NL80211_STA_BSS_PARAM_BEACON_INTERVAL];
- if (info)
- printf("\n\tbeacon interval:%u", nla_get_u16(info));
info = bss_param_info[NL80211_STA_BSS_PARAM_CTS_PROT];
if (info) {
printf("\n\tCTS protection:");
@@ -622,7 +665,7 @@ static int print_sta_handler(struct nl_m
!strcmp((char *)arg, "-v"))
parse_tid_stats(sinfo[NL80211_STA_INFO_TID_STATS]);
if (sinfo[NL80211_STA_INFO_BSS_PARAM])
- parse_bss_param(sinfo[NL80211_STA_INFO_BSS_PARAM]);
+ parse_bss_param(sinfo[NL80211_STA_INFO_BSS_PARAM], tb);
if (sinfo[NL80211_STA_INFO_CONNECTED_TIME])
printf("\n\tconnected time:\t%u seconds",
nla_get_u32(sinfo[NL80211_STA_INFO_CONNECTED_TIME]));

View File

@@ -0,0 +1,210 @@
From 5ea22f07b7cac4ac9776151476fa8906ce7b10a8 Mon Sep 17 00:00:00 2001
From: Ganesh Babu Jothiram <quic_gjothira@quicinc.com>
Date: Mon, 3 Apr 2023 02:12:30 +0530
Subject: [PATCH] iw: add support for default msduq map
Below is the command for default msduq map.
- iw dev <devname> defqmap map <service_id> <peer_macaddr>
Below is the command for default msduq unmap and reports.
- iw dev <devname> defqmap unmap <service_id> <peer_macaddr>
Below is the command for default msduq map reports.
- iw dev <devname> defqmap report <peer_macaddr>o
The above commands will map/unmap the specificed service class ID to use
default MSDUQ of TID.
The TID value is obtaied from the service class parameter.
Signed-off-by: Ganesh Babu Jothiram <quic_gjothira@quicinc.com>
---
defqmap.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
iw.h | 13 +++++
2 files changed, 167 insertions(+)
create mode 100644 defqmap.c
diff --git a/defqmap.c b/defqmap.c
new file mode 100644
index 0000000..d8964b3
--- /dev/null
+++ b/defqmap.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include <arpa/inet.h>
+
+#include "nl80211.h"
+#include "iw.h"
+#define MAC_ADDR_LEN 18
+#define SAWF_SVC_ID_INVALID 0xFF
+#define MAX_RANGE(type) (pow(2, 8 * sizeof(type)) - 1)
+#define OUI_QCA 0x001374
+
+SECTION(defqmap);
+
+static int handle_default_q_map_req(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *defqmap_attr;
+ char *end;
+ unsigned long value;
+ char macaddr[MAC_ADDR_LEN] = {0};
+
+ if (argc < 2 || argc > 2 || (argc%2) != 0)
+ goto err;
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP);
+
+ defqmap_attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!defqmap_attr)
+ return -ENOBUFS;
+
+ errno = 0;
+ value = strtoul(argv[0], &end, 10);
+ if (*end != '\0' || value > MAX_RANGE(uint8_t) || errno == ERANGE)
+ goto err;
+
+ strlcpy(macaddr, argv[1], MAC_ADDR_LEN);
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_SVC_ID, value);
+ nla_put(msg, QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_MAC_ADDR, MAC_ADDR_LEN, macaddr);
+
+ nla_nest_end(msg, defqmap_attr);
+ return 0;
+err:
+ return -EINVAL;
+}
+
+COMMAND(defqmap, map, "<service_id> <macaddr>", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_default_q_map_req, ".");
+
+static int handle_default_q_unmap_req(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *defqmap_attr;
+ char *end;
+ unsigned long value;
+ char macaddr[MAC_ADDR_LEN] = {0};
+
+ if (argc < 2 || argc > 2 || (argc%2) != 0)
+ goto err;
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_UNMAP);
+
+ defqmap_attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!defqmap_attr)
+ return -ENOBUFS;
+
+ errno = 0;
+ value = strtoul(argv[0], &end, 10);
+ if (*end != '\0' || value > MAX_RANGE(uint8_t) || errno == ERANGE)
+ goto err;
+
+ strlcpy(macaddr, argv[1], MAC_ADDR_LEN);
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_SVC_ID, value);
+ nla_put(msg, QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_MAC_ADDR, MAC_ADDR_LEN, macaddr);
+
+ nla_nest_end(msg, defqmap_attr);
+ return 0;
+err:
+ return -EINVAL;
+}
+
+COMMAND(defqmap, unmap, "<service_id> <macaddr>", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_default_q_unmap_req, ".");
+
+
+static int handle_default_q_map_report(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *defqmap_attr;
+ char macaddr[MAC_ADDR_LEN] = {0};
+
+ if (argc < 1 || argc > 1)
+ goto err;
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP_REP);
+
+ defqmap_attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!defqmap_attr)
+ return -ENOBUFS;
+
+ errno = 0;
+ strlcpy(macaddr, argv[0], MAC_ADDR_LEN);
+
+ nla_put(msg, QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_MAC_ADDR, MAC_ADDR_LEN, macaddr);
+
+ nla_nest_end(msg, defqmap_attr);
+ return 0;
+err:
+ return -EINVAL;
+}
+
+COMMAND(defqmap, report, "<macaddr>", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_default_q_map_report, ".");
diff --git a/iw.h b/iw.h
index 494919f..1b327c3 100644
--- a/iw.h
+++ b/iw.h
@@ -74,6 +74,9 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_SVC_CREATE = 204,
QCA_NL80211_VENDOR_SUBCMD_SVC_DISABLE = 205,
QCA_NL80211_VENDOR_SUBCMD_SVC_VIEW = 206,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP = 207,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_UNMAP = 208,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP_REP = 209
};
/* Attributes for data used by
* QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION and
@@ -88,6 +91,16 @@ enum qca_wlan_vendor_attr_config {
QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST - 1,
};
+enum ath12k_vendor_attr_sawf_def_q_map {
+ QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_SVC_ID = 1,
+ QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_MAC_ADDR = 2,
+
+ QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_MAX =
+ QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_AFTER_LAST - 1,
+};
+
enum qca_wlan_vendor_sawf_attr_config {
QCA_WLAN_VENDOR_ATTR_SAWF_SERVICE_CLASSES = 1,
QCA_WLAN_VENDOR_ATTR_SAWF_SVC_ID,
--
2.17.1

View File

@@ -0,0 +1,184 @@
From d5b3cb26d97cca6bbd816087aa292d5ed46b6b7f Mon Sep 17 00:00:00 2001
From: Ganesh Babu Jothiram <quic_gjothira@quicinc.com>
Date: Mon, 3 Apr 2023 16:33:24 +0530
Subject: [PATCH] iw: sawf: add uplink configuration parameters in the service
class
configuration structure.
add uplink configuration related parameters into service class structure and
update service class configure, and view to extend support for uplink configuration.
Below is the command to configure a service class
- iw phy <phyname> service_class create <service_id> <app_name>
[min_tput <min_thruput_rate>] [max_tput <max_thruput_rate>]
[burst_size <burst_size>] [service_interval <service_interval>]
[delay_bound <delay_bound>] [msdu_ttl <msdu_ttl>] [priority <priority>]
[tid <tid>] [msdu_loss <msdu_rate_loss>] [ul_service_interval <ul_service_interval>]
[ul_min_tput <ul_min_tput>] [ul_max_latency <ul_max_latency>]
[ul_burst_size <ul_burst_size>] [ul_ofdma_disable <ul_ofdma_disable>]
[ul_mu_mimo_disable <ul_mu_mimo_disable>]
Below is the command to disable a service class
- iw phy <phyname> service_class delete <service_id>
Below is the command to view a specific service class
- iw phy <phyname> service_class view <service_id>
Below is the command to view all service classes
- iw phy <phyname> service_class view
Signed-off-by: Ganesh Babu Jothiram <quic_gjothira@quicinc.com>
---
iw.h | 6 +++++
sawf.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
2 files changed, 74 insertions(+), 4 deletions(-)
diff --git a/iw.h b/iw.h
index 1b327c3..64769d7 100644
--- a/iw.h
+++ b/iw.h
@@ -114,6 +114,12 @@ enum qca_wlan_vendor_sawf_attr_config {
QCA_WLAN_VENDOR_ATTR_SAWF_SVC_PRIO,
QCA_WLAN_VENDOR_ATTR_SAWF_SVC_TID,
QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_SVC_INTERVAL,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MIN_TPUT,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MAX_LATENCY,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_BURST_SIZE,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_OFDMA_DISABLE,
+ QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MU_MIMO_DISABLE,
/* keep last */
QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_AFTER_LAST,
diff --git a/sawf.c b/sawf.c
index da88e52..2fe2be0 100644
--- a/sawf.c
+++ b/sawf.c
@@ -31,11 +31,11 @@
#include "iw.h"
#define OUI_QCA 0x001374
-#define MAX_OPTIONAL_STRINGS 9
+#define MAX_OPTIONAL_STRINGS 15
#define MAX_STRING_SIZE 60
#define MAX_RANGE(type) pow(2, 8 * sizeof(type)) - 1
#define SVC_CREATE_MIN_ARGUMENTS 2
-#define SVC_CREATE_MAX_ARGUMENTS 20
+#define SVC_CREATE_MAX_ARGUMENTS 32
#define SVC_DISABLE_MAX_ARGUMENTS 1
#define SVC_VIEW_MAX_ARGUMENTS 1
#define APP_NAME_MAX_BYTES 64
@@ -63,7 +63,13 @@ static int handle_service_class_create(struct nl80211_state *state,
"msdu_ttl",
"priority",
"tid",
- "msdu_loss"};
+ "msdu_loss",
+ "ul_service_interval",
+ "ul_min_tput",
+ "ul_max_latency",
+ "ul_burst_size",
+ "ul_ofdma_disable",
+ "ul_mu_mimo_disable"};
if (argc < SVC_CREATE_MIN_ARGUMENTS || argc > SVC_CREATE_MAX_ARGUMENTS ||
(argc % SVC_CREATE_MIN_ARGUMENTS) != 0)
@@ -133,6 +139,30 @@ static int handle_service_class_create(struct nl80211_state *state,
nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS,
value);
break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_SVC_INTERVAL:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_SVC_INTERVAL,
+ value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MIN_TPUT:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MIN_TPUT,
+ value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MAX_LATENCY:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MAX_LATENCY,
+ value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_BURST_SIZE:
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_BURST_SIZE,
+ value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_OFDMA_DISABLE:
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_OFDMA_DISABLE,
+ value);
+ break;
+ case QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MU_MIMO_DISABLE:
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MU_MIMO_DISABLE,
+ value);
+ break;
}
}
@@ -145,6 +175,12 @@ err:
printf("[burst_size <burst_size>] [service_interval <service_interval>] ");
printf("[delay_bound <delay_bound>] [msdu_ttl <msdu_ttl>] ");
printf("[priority <priority>] [tid <tid>] [msdu_loss <msdu_rate_loss>]\n");
+ printf("[ul_service_interval <ul_service_interval>]\n");
+ printf("[ul_min_tput <ul_min_tput>]\n");
+ printf("[ul_max_latency <ul_max_latency>]\n");
+ printf("[ul_burst_size <ul_burst_size>]\n");
+ printf("[ul_ofdma_disable <ul_ofdma_disable>]\n");
+ printf("[ul_mu_mimo_disable <ul_mu_mimo_disable>]\n");
return -EINVAL;
}
@@ -153,7 +189,11 @@ COMMAND(service_class, create, "<service_id> <app_name> [min_tput <min_thruput_r
" [max_tput <max_thruput_rate>] [burst_size <burst_size>]"
" [service_interval <service_interval>] [delay_bound <delay_bound>]"
" [msdu_ttl <msdu_ttl>] [priority <priority>] [tid <tid>]"
- " [msdu_loss <msdu_rate_loss>]", NL80211_CMD_VENDOR, 0, CIB_PHY,
+ " [msdu_loss <msdu_rate_loss>] [ul_service_interval <ul_service_interval>]"
+ " [ul_min_tput <ul_min_tput>] [ul_max_latency <ul_max_latency>]"
+ " [ul_burst_size <ul_burst_size>] [ul_ofdma_disable <ul_ofdma_disable>]"
+ " [ul_mu_mimo_disable <ul_mu_mimo_disable>]", NL80211_CMD_VENDOR, 0, CIB_PHY,
+
handle_service_class_create, ".");
static int handle_service_class_disable(struct nl80211_state *state,
@@ -215,6 +255,12 @@ static int print_sawf_service_classes(struct nl_msg *msg, void *arg)
[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_PRIO] = {.type = NLA_U32},
[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_TID] = {.type = NLA_U32},
[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_SVC_INTERVAL] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MIN_TPUT] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MAX_LATENCY] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_BURST_SIZE] = {.type = NLA_U32},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_OFDMA_DISABLE] = {.type = NLA_U8},
+ [QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MU_MIMO_DISABLE] = {.type = NLA_U8},
};
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
@@ -271,6 +317,24 @@ static int print_sawf_service_classes(struct nl_msg *msg, void *arg)
if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS])
printf("MSDU Loss Rate\t: %u\n",
nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_MSDU_RATE_LOSS]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_SVC_INTERVAL])
+ printf("UL service interval\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_SVC_INTERVAL]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MIN_TPUT])
+ printf("UL min throughput\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MIN_TPUT]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MAX_LATENCY])
+ printf("UL max latency\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MAX_LATENCY]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_BURST_SIZE])
+ printf("UL burst size\t: %u\n",
+ nla_get_u32(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_BURST_SIZE]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_OFDMA_DISABLE])
+ printf("UL ofdma disable\t: %u\n",
+ nla_get_u8(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_OFDMA_DISABLE]));
+ if (attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MU_MIMO_DISABLE])
+ printf("UL mu mimo disable\t: %u\n",
+ nla_get_u8(attrs[QCA_WLAN_VENDOR_ATTR_SAWF_SVC_UL_MU_MIMO_DISABLE]));
}
return NL_SKIP;
}
--
2.17.1

View File

@@ -0,0 +1,428 @@
From 6dd3cb94e051d1ebe923ff854aa666dea719a30f Mon Sep 17 00:00:00 2001
From: Mahendran P <quic_mahep@quicinc.com>
Date: Mon, 29 May 2023 10:34:24 +0530
Subject: [PATCH] iw: add support to configure telemetry
Add sla samples configuration, sla thershold configuration and sla detection configuration
Below is the command to configure sla samples configuration
- iw phy <phyname> telemetry sla_samples_cfg <moving_avg_pkt> <moving_avg_window> <sla_num_pkt> <sla_time_sec>
Below is the command to configure sla thershold
- iw phy <phyname> telemetry sla_thershold <service_id> <min_throughput_rate> <max_throughput_rate> <burst_size> <service_interval> <delay_bound> <msdu_ttl> <msdu_rate_loss>
Below is the command to configure sla detection
- iw phy <phyname> telemetry sla_detection_cfg <detection_option> <min_throughput_rate> <max_throughput_rate> <burst_size> <service_interval> <delay_bound> <msdu_ttl> <msdu_rate_loss>
Signed-off-by: Mahendran P <quic_mahep@quicinc.com>
---
iw.h | 52 +++++++++-
telemetry.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 323 insertions(+), 1 deletion(-)
create mode 100644 telemetry.c
--- a/iw.h
+++ b/iw.h
@@ -76,7 +76,11 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_SVC_VIEW = 206,
QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP = 207,
QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_UNMAP = 208,
- QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP_REP = 209
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP_REP = 209,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_THERSHOLD_CFG = 210,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_SAMPLES_COLLECTION_CFG = 211,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_BREACH_DETECTION_CFG = 212
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_SLA_BREACH = 214,
};
/* Attributes for data used by
* QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION and
@@ -127,6 +131,82 @@ enum qca_wlan_vendor_sawf_attr_config {
QCA_WLAN_VENDOR_SAWF_ATTR_CONFIG_AFTER_LAST - 1,
};
+enum qca_wlan_vendor_attr_telemetry_sawf_sla_samples_config {
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_MOVING_AVG_PKT = 1,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_MOVING_AVG_WIN,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_NUM_PKT,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_TIME_SEC,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_SAMPLES_CFG_ATTR_AFTER_LAST,
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_SAMPLES_CFG_ATTR_CONFIG_MAX =
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_SAMPLES_CFG_ATTR_AFTER_LAST - 1,
+};
+
+enum qca_wlan_vendor_attr_telemetry_sawf_sla_detect_config {
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECTION_PARAM = 1,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MIN_TP,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MAX_TP,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_BURST_SIZE,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_INTERVAL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_DELAY_BOUND,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MSDU_TTL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MSDU_RATE_LOSS,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_DETECT_AFTER_LAST,
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_DETECT_ATTR_CONFIG_MAX =
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_DETECT_AFTER_LAST - 1,
+
+};
+
+enum qca_wlan_vendor_attr_telemetry_sawf_sla_thershold_config {
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_SVC_ID = 1,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MIN_TP,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MAX_TP,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_BURST_SIZE,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_INTERVAL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_DELAY_BOUND,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MSDU_TTL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MSDU_RATE_LOSS,
+
+ /* keep last */
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_THERSHOLD_CFG_AFTER_LAST,
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_THERSHOLD_CFG_ATTR_CONFIG_MAX =
+ QCA_WLAN_VENDOR_TELEMETRY_SLA_THERSHOLD_CFG_AFTER_LAST - 1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_sawf_sla_params - This enum defines
+ * attributes required for QCA_NL80211_VENDOR_SUBCMD_SAWF_SLA_BREACH
+ * Used to send sla clear event to driver.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_SLA_PEER_MAC: Unsigned 8-bit array
+ * of size 6, representing peer mac address.
+ * @QCA_WLAN_VENDOR_ATTR_SLA_SVC_ID: Unsigned 8-bit representing service ID
+ * @QCA_WLAN_VENDOR_ATTR_SLA_PARAM: Unsigned 8-bit indicaing service class
+ * from qca_vendor_attr_sla_param_type
+ * @QCA_WLAN_VENDOR_ATTR_SLA_PEER_MLD_MAC: Unsigned 8-bit array
+ * of size 6, representing peer mld mac address. Filled only for ML capable
+ * peers
+ * @QCA_WLAN_VENDOR_ATTR_SLA_AC: Unsigned 8-bit representing AC for breach
+ *
+ */
+enum qca_wlan_vendor_attr_sawf_sla_params {
+ QCA_WLAN_VENDOR_ATTR_SLA_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_SLA_PEER_MAC = 1,
+ QCA_WLAN_VENDOR_ATTR_SLA_SVC_ID = 2,
+ QCA_WLAN_VENDOR_ATTR_SLA_PARAM = 3,
+ QCA_WLAN_VENDOR_ATTR_SLA_SET_CLEAR = 4,
+ QCA_WLAN_VENDOR_ATTR_SLA_PEER_MLD_MAC = 5,
+ QCA_WLAN_VENDOR_ATTR_SLA_AC = 6,
+
+ /* Keep last */
+ QCA_WLAN_VENDOR_ATTR_SLA_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_SLA_MAX =
+ QCA_WLAN_VENDOR_ATTR_SLA_AFTER_LAST - 1
+};
+
#define HANDLER_RET_USAGE 1
#define HANDLER_RET_DONE 3
--- /dev/null
+++ b/telemetry.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include <arpa/inet.h>
+
+#include "nl80211.h"
+#include "iw.h"
+
+#define OUI_QCA 0x001374
+#define MAX_OPTIONAL_STRINGS 15
+#define MAX_STRING_SIZE 60
+#define MAX_RANGE(type) pow(2, 8 * sizeof(type)) - 1
+#define SVC_CREATE_MIN_ARGUMENTS 2
+#define SVC_CREATE_MAX_ARGUMENTS 32
+#define SVC_DISABLE_MAX_ARGUMENTS 1
+#define SVC_VIEW_MAX_ARGUMENTS 1
+#define APP_NAME_MAX_BYTES 64
+#define streq(a, b) (strcmp((a), (b)) == 0)
+
+#define TELEMETRY_SLA_SAMPLES_CONFIG_NUM_OF_PARAMS 4
+#define TELEMETRY_SLA_THERSHOLD_CONFIG_NUM_OF_PARAMS 8
+#define TELEMETRY_SLA_DETECTION_CONFIG_NUM_OF_PARAMS 8
+
+struct telemetry_sawf_generic_param {
+ uint32_t moving_avg_pkt;
+ uint32_t moving_avg_win;
+ uint32_t sla_num_pkt;
+ uint32_t sla_time_sec;
+};
+
+struct telemetry_sawf_sla_thershold {
+ uint8_t svc_id;
+ uint32_t min_throughput_rate;
+ uint32_t max_throughput_rate;
+ uint32_t burst_size;
+ uint32_t service_interval;
+ uint32_t delay_bound;
+ uint32_t msdu_ttl;
+ uint32_t msdu_rate_loss;
+};
+
+enum telemetry_sawf_sla_detect {
+ SLA_DETECT_NUM_PACKET,
+ SLA_DETECT_PER_SECOND,
+ SLA_DETECT_MOV_AVG,
+ SLA_DETECT_NUM_SECOND,
+ SLA_DETECT_MAX,
+};
+
+struct telemetry_sawf_sla_detect_param {
+ enum telemetry_sawf_sla_detect sla_detect;
+ uint32_t min_throughput_rate;
+ uint32_t max_throughput_rate;
+ uint32_t burst_size;
+ uint32_t service_interval;
+ uint32_t delay_bound;
+ uint32_t msdu_ttl;
+ uint32_t msdu_rate_loss;
+};
+
+
+SECTION(telemetry);
+
+static int handle_telemetry_sawf_sla_samples_colletion_cfg
+ (struct nl80211_state *state, struct nl_msg *msg,
+ int argc, char **argv, enum id_input id)
+{
+ struct nlattr *telemetry_cfg;
+ char *end;
+ struct telemetry_sawf_generic_param telemetry_param;
+
+ if (argc != TELEMETRY_SLA_SAMPLES_CONFIG_NUM_OF_PARAMS)
+ goto err;
+
+ telemetry_param.moving_avg_pkt = strtoul(argv[0], &end, 10);
+ telemetry_param.moving_avg_win = strtoul(argv[1], &end, 10);
+ telemetry_param.sla_num_pkt = strtoul(argv[2], &end, 10);
+ telemetry_param.sla_time_sec = strtoul(argv[3], &end, 10);
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_SAMPLES_COLLECTION_CFG);
+
+ telemetry_cfg = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!telemetry_cfg)
+ return -ENOBUFS;
+
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_MOVING_AVG_PKT,
+ telemetry_param.moving_avg_pkt);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_MOVING_AVG_WIN,
+ telemetry_param.moving_avg_win);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_NUM_PKT,
+ telemetry_param.sla_num_pkt);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_TIME_SEC,
+ telemetry_param.sla_time_sec);
+
+ nla_nest_end(msg, telemetry_cfg);
+
+ return 0;
+
+err:
+ printf("invalid telemetry sla samples configuration command format: Usage\n");
+ printf("\t iw phy <phyname> telemetry sla_samples_cfg <moving_avg_pkt> <moving_avg_window> <sla_num_pkt> <sla_time_sec>\n");
+ return -EINVAL;
+}
+
+COMMAND(telemetry, sla_samples_cfg, "<moving_avg_pkt> <moving_avg_window>"
+"<sla_num_pkt> <sla_time_sec>", NL80211_CMD_VENDOR, 0, CIB_PHY,
+handle_telemetry_sawf_sla_samples_colletion_cfg, ".");
+
+static int handle_telemetry_sawf_sla_thershold_cfg(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *telemetry_cfg;
+ char *end;
+ struct telemetry_sawf_sla_thershold sla_thershold_cfg;
+
+ if (argc != TELEMETRY_SLA_THERSHOLD_CONFIG_NUM_OF_PARAMS)
+ goto err;
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_THERSHOLD_CFG);
+
+ telemetry_cfg = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!telemetry_cfg)
+ return -ENOBUFS;
+
+ sla_thershold_cfg.svc_id = strtoul(argv[0], &end, 10);
+ sla_thershold_cfg.min_throughput_rate = strtoul(argv[1], &end, 10);
+ sla_thershold_cfg.max_throughput_rate = strtoul(argv[2], &end, 10);
+ sla_thershold_cfg.burst_size = strtoul(argv[3], &end, 10);
+ sla_thershold_cfg.service_interval = strtoul(argv[4], &end, 10);
+ sla_thershold_cfg.delay_bound = strtoul(argv[5], &end, 10);
+ sla_thershold_cfg.msdu_ttl = strtoul(argv[6], &end, 10);
+ sla_thershold_cfg.msdu_rate_loss = strtoul(argv[7], &end, 10);
+
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_SVC_ID,
+ sla_thershold_cfg.svc_id);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MIN_TP,
+ sla_thershold_cfg.min_throughput_rate);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MAX_TP,
+ sla_thershold_cfg.max_throughput_rate);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_BURST_SIZE,
+ sla_thershold_cfg.burst_size);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_INTERVAL,
+ sla_thershold_cfg.service_interval);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_DELAY_BOUND,
+ sla_thershold_cfg.delay_bound);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MSDU_TTL,
+ sla_thershold_cfg.msdu_ttl);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_THERSHOLD_MSDU_RATE_LOSS,
+ sla_thershold_cfg.msdu_rate_loss);
+ nla_nest_end(msg, telemetry_cfg);
+ return 0;
+
+err:
+ printf("invalid telemetry sla thershold configuration command format: Usage\n");
+ printf("\t iw phy <phyname> telemetry sla_thershold <service_id> ");
+ printf(" <min_throughput_rate> <max_throughput_rate> <burst_size> <service_interval> ");
+ printf(" <delay_bound> <msdu_ttl> <msdu_rate_loss> \n");
+ return -EINVAL;
+}
+
+COMMAND(telemetry, sla_thershold, "<service_id> <min_throughput_rate> <max_throughput_rate>"
+"<burst_size> <service_interval> <delay_bound> <msdu_ttl> <msdu_rate_loss>", NL80211_CMD_VENDOR, 0,
+CIB_PHY, handle_telemetry_sawf_sla_thershold_cfg, ".");
+
+
+static int handle_telemetry_sawf_sla_detection_cfg(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *telemetry_cfg;
+ char *end;
+ struct telemetry_sawf_sla_detect_param telemetry_param;
+
+ if (argc != TELEMETRY_SLA_DETECTION_CONFIG_NUM_OF_PARAMS)
+ goto err;
+
+ if (streq(argv[0], "num_packet"))
+ telemetry_param.sla_detect = SLA_DETECT_NUM_PACKET;
+
+ if (streq(argv[0], "per_second"))
+ telemetry_param.sla_detect = SLA_DETECT_PER_SECOND;
+
+ if (streq(argv[0], "moving_avg"))
+ telemetry_param.sla_detect = SLA_DETECT_MOV_AVG;
+
+ if (streq(argv[0], "num_second"))
+ telemetry_param.sla_detect = SLA_DETECT_NUM_SECOND;
+
+ telemetry_param.min_throughput_rate = strtoul(argv[1], &end, 10);
+ telemetry_param.max_throughput_rate = strtoul(argv[2], &end, 10);
+ telemetry_param.burst_size = strtoul(argv[3], &end, 10);
+ telemetry_param.service_interval = strtoul(argv[4], &end, 10);
+ telemetry_param.delay_bound = strtoul(argv[5], &end, 10);
+ telemetry_param.msdu_ttl = strtoul(argv[6], &end, 10);
+ telemetry_param.msdu_rate_loss = strtoul(argv[7], &end, 10);
+
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_BREACH_DETECTION_CFG);
+
+ telemetry_cfg = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!telemetry_cfg)
+ return -ENOBUFS;
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECTION_PARAM,
+ telemetry_param.sla_detect);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MIN_TP,
+ telemetry_param.min_throughput_rate);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MAX_TP,
+ telemetry_param.max_throughput_rate);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_BURST_SIZE,
+ telemetry_param.burst_size);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_INTERVAL,
+ telemetry_param.service_interval);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_DELAY_BOUND,
+ telemetry_param.delay_bound);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MSDU_TTL,
+ telemetry_param.msdu_ttl);
+ nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRY_SLA_DETECT_MSDU_RATE_LOSS,
+ telemetry_param.msdu_rate_loss);
+ nla_nest_end(msg, telemetry_cfg);
+
+ return 0;
+
+err:
+ printf("invalid telemetry sla breach detection configuration command format: Usage\n");
+ printf("\t iw phy <phyname> telemetry sla_detection_cfg <detection_option> <min_throughput_rate> <max_throughput_rate> <burst_size> <service_interval> <delay_bound> <msdu_ttl> <msdu_rate_loss>\n");
+ return -EINVAL;
+}
+
+COMMAND(telemetry, sla_detection_cfg, "<detection_option> <min_throughput_rate>"
+"<max_throughput_rate> <burst_size> <service_interval> <delay_bound> <msdu_ttl>"
+"<msdu_rate_loss>", NL80211_CMD_VENDOR, 0, CIB_PHY,
+handle_telemetry_sawf_sla_detection_cfg, ".");
+
+#define TELEMETRY_SLA_CLEAR_STATS_MAX_ARG 1
+#define MAC_ADDR_LEN 18
+
+static int handle_telemetry_sla_clear_stats(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *sla_clear;
+ unsigned char mac_addr[MAC_ADDR_LEN];
+
+ if (argc != TELEMETRY_SLA_CLEAR_STATS_MAX_ARG)
+ goto err;
+
+ if (mac_addr_a2n(mac_addr, argv[0])) {
+ printf("Invalid MAC address\n");
+ return -EINVAL;
+ }
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_SLA_BREACH);
+
+ sla_clear = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!sla_clear)
+ return -ENOBUFS;
+
+ if (nla_put(msg, QCA_WLAN_VENDOR_ATTR_SLA_PEER_MAC,
+ ETH_ALEN, mac_addr))
+ return -ENOBUFS;
+
+ nla_nest_end(msg, sla_clear);
+ return NL_OK;
+err:
+ printf("Invalid telemetry sla clear stats, command format: Usage\n");
+ printf("\t iw dev <devname> telemetry sla_clear_stats <peer_mac>\n");
+ return NL_STOP;
+}
+COMMAND(telemetry, sla_clear_stats, "<peer_mac>", NL80211_CMD_VENDOR, 0, CIB_NETDEV,
+ handle_telemetry_sla_clear_stats, ".");

View File

@@ -0,0 +1,147 @@
From 741fa523d6dd195195a9b7514a9583699f43ba3a Mon Sep 17 00:00:00 2001
From: Nagarajan Maran <quic_nmaran@quicinc.com>
Date: Wed, 7 Jun 2023 12:26:25 +0530
Subject: [PATCH] iw: Add support to handle streaming stats in target.
Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
---
iw.h | 13 +++++++-
sawf_stats.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 1 deletion(-)
create mode 100644 sawf_stats.c
--- a/iw.h
+++ b/iw.h
@@ -79,7 +79,8 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_SAWF_DEF_Q_MAP_REP = 209,
QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_THERSHOLD_CFG = 210,
QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_SAMPLES_COLLECTION_CFG = 211,
- QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_BREACH_DETECTION_CFG = 212
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_BREACH_DETECTION_CFG = 212,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_STREAMING_STATS = 213,
QCA_NL80211_VENDOR_SUBCMD_SAWF_SLA_BREACH = 214,
};
/* Attributes for data used by
@@ -95,6 +96,17 @@ enum qca_wlan_vendor_attr_config {
QCA_WLAN_VENDOR_ATTR_CONFIG_AFTER_LAST - 1,
};
+enum ath12k_vendor_attr_sawf_streaming {
+ QCA_WLAN_VENDOR_ATTR_SAWF_STREAMING_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_SAWF_STREAMING_BASIC_STATS = 1,
+ QCA_WLAN_VENDOR_ATTR_SAWF_STREAMING_EXTND_STATS = 2,
+ QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID = 3,
+ /* keep last */
+ QCA_WLAN_VENDOR_ATTR_SAWF_STREAMING_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_SAWF_STREAMING_MAX =
+ QCA_WLAN_VENDOR_ATTR_SAWF_STREAMING_AFTER_LAST - 1,
+};
+
enum ath12k_vendor_attr_sawf_def_q_map {
QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_INVALID = 0,
QCA_WLAN_VENDOR_ATTR_SAWF_DEF_Q_MAP_SVC_ID = 1,
--- /dev/null
+++ b/sawf_stats.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include <arpa/inet.h>
+
+#include "nl80211.h"
+#include "iw.h"
+
+#define OUI_QCA 0x001374
+#define STREAMING_STATS_MIN_ARGUMENTS 1
+#define STREAMING_STATS_MAX_ARGUMENTS 3
+#define STREAMING_STATS_MAX_VALUE 3
+#define STREAMING_STATS_BASIC_EN_EXTND_DIS 1
+#define STREAMING_STATS_BASIC_DIS_EXTND_EN 2
+
+
+SECTION(streaming_stats);
+
+static int handle_streaming_stats(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *stats;
+ unsigned long value;
+ uint8_t basic_stats = 0, extnd_stats = 0, link_id;
+ char *end;
+
+ if (argc < STREAMING_STATS_MIN_ARGUMENTS ||
+ argc > STREAMING_STATS_MAX_ARGUMENTS)
+ goto err;
+
+ errno = 0;
+ value = strtoul(argv[0], &end, 10);
+ if (*end != '\0' || value > STREAMING_STATS_MAX_VALUE || errno == ERANGE)
+ goto err;
+ argc--;
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_SAWF_STREAMING_STATS);
+
+ stats = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!stats)
+ return -ENOBUFS;
+
+ if (value & STREAMING_STATS_BASIC_EN_EXTND_DIS)
+ basic_stats = 1;
+ if (value & STREAMING_STATS_BASIC_DIS_EXTND_EN)
+ extnd_stats = 1;
+
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_STREAMING_BASIC_STATS, basic_stats);
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_SAWF_STREAMING_EXTND_STATS, extnd_stats);
+
+ if (argc) {
+ argc--;
+ if (!strcmp(argv[1], "-l") || !argc)
+ goto err;
+ errno = 0;
+ link_id = strtoul(argv[2], &end, 10);
+ if (*end != '\0' || value > MAX_MLD_LINK || errno == ERANGE) {
+ goto err;
+ }
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_MLO_LINK_ID, link_id);
+ }
+
+ nla_nest_end(msg, stats);
+ return 0;
+
+err:
+ printf("Invalid SAWF streaming stats command format: Usage\n");
+ printf("iw dev <devname> streaming_stats configure <value> [-l <link_id>]\n");
+ printf("\t value: 0 - Disable both Basic and Extended stats\n");
+ printf("\t value: 1 - Enable Basic and Disable Extended stats\n");
+ printf("\t value: 2 - Disable Basic and Enable Extended stats\n");
+ printf("\t value: 3 - Enable both Basic and Extended stats\n");
+ return -EINVAL;
+}
+
+COMMAND(streaming_stats, handle, "<value> [-l <link_id>]", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_streaming_stats, ".");

View File

@@ -0,0 +1,815 @@
From 581b7eb9fb63e21a277e71799756f6f629581ebf Mon Sep 17 00:00:00 2001
From: Nagarajan Maran <quic_nmaran@quicinc.com>
Date: Thu, 8 Jun 2023 18:30:49 +0530
Subject: [PATCH] iw: Add support to get SAWF stats
Signed-off-by: Nagarajan Maran <quic_nmaran@quicinc.com>
---
iw.h | 1 +
sawf_stats.c | 398 ++++++++++++++++++++++++++++++++++++++++++++++++++-
sawf_stats.h | 367 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 764 insertions(+), 2 deletions(-)
create mode 100644 sawf_stats.h
--- a/sawf_stats.c
+++ b/sawf_stats.c
@@ -28,6 +28,7 @@
#include "nl80211.h"
#include "iw.h"
+#include "sawf_stats.h"
#define OUI_QCA 0x001374
#define STREAMING_STATS_MIN_ARGUMENTS 1
@@ -35,7 +36,7 @@
#define STREAMING_STATS_MAX_VALUE 3
#define STREAMING_STATS_BASIC_EN_EXTND_DIS 1
#define STREAMING_STATS_BASIC_DIS_EXTND_EN 2
-
+#define MAX_RANGE(type) pow(2, 8 * sizeof(type)) - 1
SECTION(streaming_stats);
@@ -100,3 +101,401 @@ err:
}
COMMAND(streaming_stats, handle, "<value> [-l <link_id>]", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_streaming_stats, ".");
+
+SECTION(sawf_stats);
+#define MAC_ADDR_LEN 18
+#define TELEMETRY_GET_STATS_MIN_ARG 3
+#define TELEMETRY_GET_STATS_MAX_ARG 4
+#define SAWFDELAY_STATS 0x00400000
+#define SAWFTX_STATS 0x00800000
+
+const char *stats_if_hw_tx_comp_delay_bucket[DELAY_BUCKET_MAX + 1] = {
+ "0 to 250 us", "250 to 500 us",
+ "500 to 750 us", "750 to 1000 us",
+ "1000 to 1500 us", "1500 to 2000 us",
+ "2000 to 2500 us", "2500 to 5000 us",
+ "5000 to 6000 us", "6000 to 7000 ms",
+ "7000 to 8000 us", "8000 to 9000 us", "9000+ us"
+};
+
+static void print_hist_stats(struct delay_hist_stats *hstats,
+ enum hist_types hist_type)
+{
+ uint8_t index = 0;
+ uint64_t count = 0;
+
+ for (index = 0; index < HIST_BUCKET_MAX; index++) {
+ count = hstats->hist.freq[index];
+ if (!count)
+ continue;
+ if (index > DELAY_BUCKET_MAX) {
+ printf("%s: Packets = %" PRIu64 "\n",
+ "Invalid index", count);
+ continue;
+ }
+ switch (hist_type) {
+ case HIST_TYPE_HW_TX_COMP_DELAY:
+ printf("%s: Packets = %" PRIu64 "\n",
+ stats_if_hw_tx_comp_delay_bucket[index],
+ count);
+ break;
+ default:
+ break;
+ }
+ }
+
+ printf("Min = %d\n", hstats->min);
+ printf("Max = %d\n", hstats->max);
+ printf("Avg = %d\n", hstats->avg);
+}
+
+static void print_telemetry_delay_stats(struct telemetry_sawf_delay_stat *delay_stats)
+{
+ printf("\nDelay Bins\n");
+
+ print_hist_stats(&delay_stats->delay_hist,
+ HIST_TYPE_HW_TX_COMP_DELAY);
+
+ printf("NwDelay Moving average = %u\n",
+ delay_stats->nwdelay_avg);
+ printf("SwDelay Moving average = %u\n",
+ delay_stats->swdelay_avg);
+ printf("HwDelay Moving average = %u\n",
+ delay_stats->hwdelay_avg);
+ printf("Delay bound success = %" PRIu64 "\n",
+ delay_stats->delay_bound_success);
+ printf("Delay bound failure = %" PRIu64 "\n",
+ delay_stats->delay_bound_failure);
+
+ return;
+}
+
+static void print_telemetry_tx_stats(struct telemetry_sawf_tx_stat *tx_stats)
+{
+ printf("Tx_info_success_num = %u\n",
+ tx_stats->tx_success.num_pkts);
+ printf("Tx_info_success_bytes = %" PRIu64 "\n",
+ tx_stats->tx_success.bytes);
+ printf("Tx_info_ingress_num = %u\n",
+ tx_stats->tx_ingress.num_pkts);
+ printf("Tx_info_ingress_bytes = %" PRIu64 "\n",
+ tx_stats->tx_ingress.bytes);
+ printf("Tx_info_Throughput = %u\n",
+ tx_stats->throughput);
+ printf("Tx_info_ingress_rate = %u\n",
+ tx_stats->ingress_rate);
+
+ printf("Tx_info_drop_num = %u\n",
+ tx_stats->dropped.fw_rem.num_pkts);
+ printf("Tx_info_drop_bytes = %" PRIu64 "\n",
+ tx_stats->dropped.fw_rem.bytes);
+ printf("Tx_info_drop_fw_rem_notx = %u\n",
+ tx_stats->dropped.fw_rem_notx);
+ printf("Tx_info_drop_Tx_fw_rem_tx = %u\n",
+ tx_stats->dropped.fw_rem_tx);
+ printf("Tx_info_drop_Tx_age_out = %u\n",
+ tx_stats->dropped.age_out);
+
+ printf("Tx_info_drop_fw_reason1 = %u\n",
+ tx_stats->dropped.fw_reason1);
+ printf("Tx_info_drop_fw_reason2 = %u\n",
+ tx_stats->dropped.fw_reason2);
+ printf("Tx_info_drop_fw_reason3 = %u\n",
+ tx_stats->dropped.fw_reason3);
+ printf("Tx_info_tx_failed = %u\n",
+ tx_stats->tx_failed);
+ printf("Tx_info_queue_depth = %u\n",
+ tx_stats->queue_depth);
+ printf("Service_intvl_success_cnt = %" PRIu64 "\n",
+ tx_stats->svc_intval_stats.success_cnt);
+ printf("Service_intvl_failure_cnt = %" PRIu64 "\n",
+ tx_stats->svc_intval_stats.failure_cnt);
+ printf("Burst_size_success_cnt = %" PRIu64 "\n",
+ tx_stats->burst_size_stats.success_cnt);
+ printf("Burst_size_failure_cnt = %" PRIu64 "\n",
+ tx_stats->burst_size_stats.failure_cnt);
+}
+
+static int error_stats_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
+ void *arg)
+{
+ struct unified_stats *telemetry_stats = (struct unified_stats*)arg;
+
+ telemetry_stats->err = EINVAL;
+ return NL_STOP;
+}
+
+static void print_sawf_stats(struct unified_stats *telemetry_stats,
+ uint8_t svc_id)
+{
+ int tid, q_id;
+ struct telemetry_sawfdelay_stats *delay_stats = telemetry_stats->feat[STATS_FEAT_SAWFDELAY];
+ struct telemetry_sawftx_stats *tx_stats = telemetry_stats->feat[STATS_FEAT_SAWFTX];
+ struct telemetry_sawf_tx_stat *sawftx_stats;
+ struct telemetry_sawf_delay_stat *sawfdelay_stats;
+
+ if(tx_stats) {
+ if (!svc_id) {
+ for (tid = 0; tid < MAX_TID; tid++) {
+ for (q_id = 0; q_id < MAX_SAWF_Q; q_id++) {
+ sawftx_stats = &tx_stats->tx[tid][q_id];
+ printf("----TIDX: %d---- ", tid);
+ printf("----QUEUE: %d----\n", q_id);
+ print_telemetry_tx_stats(sawftx_stats);
+ }
+ }
+ } else {
+ sawftx_stats = &tx_stats->tx[0][0];
+ printf("----TIDX: %d---- ", tx_stats->tid);
+ printf("----QUEUE: %d----\n", tx_stats->msduq);
+ print_telemetry_tx_stats(sawftx_stats);
+ }
+ }
+
+ if(delay_stats) {
+ if (!svc_id) {
+ for (tid = 0; tid < MAX_TID; tid++) {
+ for (q_id = 0; q_id < MAX_SAWF_Q; q_id++) {
+ sawfdelay_stats = &delay_stats->delay[tid][q_id];
+ printf("----TIDX: %d---- ", tid);
+ printf("----QUEUE: %d----\n", q_id);
+ print_telemetry_delay_stats(sawfdelay_stats);
+ }
+ }
+ } else {
+ sawfdelay_stats = &delay_stats->delay[0][0];
+ printf("----TIDX: %d---- ", delay_stats->tid);
+ printf("----QUEUE: %d----\n", delay_stats->msduq);
+ print_telemetry_delay_stats(sawfdelay_stats);
+ }
+ }
+}
+
+static int complete_telemetry_stats(struct nl_msg *msg, void *arg)
+{
+ struct unified_stats *telemetry_stats = (struct unified_stats*)arg;
+
+ telemetry_stats->err = 0;
+ return NL_OK;
+}
+
+static int print_telemetry_stats(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
+ struct nlattr *stats[QCA_WLAN_VENDOR_ATTR_TELEMETRIC_MAX + 1];
+ struct nlattr *feat[QCA_WLAN_VENDOR_ATTR_FEAT_MAX + 1];
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+ static struct nla_policy stats_policy[QCA_WLAN_VENDOR_ATTR_STATS_MAX + 1] = {
+ [QCA_WLAN_VENDOR_ATTR_STATS_LEVEL] = { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_STATS_OBJECT] = { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_STATS_OBJ_ID] = { .type = NLA_UNSPEC },
+ [QCA_WLAN_VENDOR_ATTR_STATS_PARENT_IF] = { .type = NLA_UNSPEC },
+ [QCA_WLAN_VENDOR_ATTR_STATS_TYPE] = { .type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_STATS_RECURSIVE] = { .type = NLA_NESTED },
+ [QCA_WLAN_VENDOR_ATTR_STATS_MULTI_REPLY] = { .type = NLA_FLAG },
+ [QCA_WLAN_VENDOR_ATTR_STATS_SERVICEID] = { .type = NLA_U8 },
+ };
+ struct telemetry_sawfdelay_stats *delay_stats;
+ struct telemetry_sawftx_stats *tx_stats;
+ static int filled_buf_len_delay, filled_buf_len_tx;
+ struct unified_stats *telemetry_stats = (struct unified_stats*)arg;
+ size_t len;
+
+ nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL);
+
+ if (tb_msg[NL80211_ATTR_VENDOR_DATA])
+ nla_parse_nested(stats, QCA_WLAN_VENDOR_ATTR_STATS_MAX,
+ tb_msg[NL80211_ATTR_VENDOR_DATA], stats_policy);
+ else
+ return NL_STOP;
+
+ if (!stats[QCA_WLAN_VENDOR_ATTR_STATS_LEVEL] ||
+ !stats[QCA_WLAN_VENDOR_ATTR_STATS_OBJECT] ||
+ !stats[QCA_WLAN_VENDOR_ATTR_STATS_OBJ_ID] ||
+ !stats[QCA_WLAN_VENDOR_ATTR_STATS_TYPE] ||
+ !stats[QCA_WLAN_VENDOR_ATTR_STATS_RECURSIVE] ||
+ !stats[QCA_WLAN_VENDOR_ATTR_STATS_SERVICEID]) {
+ printf("SAWF STATS: Invalid data received\n");
+ return NL_SKIP;
+ }
+
+ if (stats[QCA_WLAN_VENDOR_ATTR_STATS_MULTI_REPLY]) {
+ delay_stats = telemetry_stats->feat[STATS_FEAT_SAWFDELAY];
+ tx_stats = telemetry_stats->feat[STATS_FEAT_SAWFTX];
+ } else {
+ filled_buf_len_delay = 0;
+ filled_buf_len_tx = 0;
+ delay_stats = NULL;
+ tx_stats = NULL;
+ }
+
+ nla_parse_nested(feat, QCA_WLAN_VENDOR_ATTR_FEAT_MAX,
+ stats[QCA_WLAN_VENDOR_ATTR_STATS_RECURSIVE], NULL);
+
+ if (feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFDELAY]) {
+ if (!delay_stats) {
+ void *temp_delay;
+ temp_delay = malloc(sizeof(struct telemetry_sawfdelay_stats));
+ if (!temp_delay)
+ return NL_STOP;
+ len = nla_len(feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFDELAY]);
+ memcpy((uint8_t *)temp_delay, nla_data(feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFDELAY]),
+ len);
+ delay_stats = temp_delay;
+ filled_buf_len_delay += len;
+ } else {
+ len = nla_len(feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFDELAY]);
+ memcpy((uint8_t *)delay_stats + filled_buf_len_delay,
+ nla_data(feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFDELAY]),
+ len);
+ filled_buf_len_delay += len;
+ }
+ telemetry_stats->feat[STATS_FEAT_SAWFDELAY] = delay_stats;
+ }
+
+ if (feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFTX]) {
+ if (!tx_stats) {
+ void *temp_tx;
+ temp_tx = malloc(sizeof(struct telemetry_sawftx_stats));
+ if (!temp_tx)
+ return NL_STOP;
+ len = nla_len(feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFTX]);
+ memcpy((uint8_t *)temp_tx, nla_data(feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFTX]),
+ len);
+ tx_stats = temp_tx;
+ filled_buf_len_tx += len;
+ } else {
+ len = nla_len(feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFTX]);
+ memcpy((uint8_t *)tx_stats + filled_buf_len_tx,
+ nla_data(feat[QCA_WLAN_VENDOR_ATTR_FEAT_SAWFTX]),
+ len);
+ filled_buf_len_tx += len;
+ }
+ telemetry_stats->feat[STATS_FEAT_SAWFTX] = tx_stats;
+ }
+
+ return NL_OK;
+}
+
+static void free_unified_stats(struct unified_stats *telemetry_stats)
+{
+ int i;
+
+ for (i = 0; i < STATS_FEAT_MAX; i++) {
+ if (telemetry_stats->feat[i])
+ free(telemetry_stats->feat[i]);
+ telemetry_stats->feat[i] = NULL;
+ }
+ free(telemetry_stats);
+}
+
+static int handle_sawf_stats(struct nl80211_state *state,
+ struct nl_msg *msg, int argc, char **argv,
+ enum id_input id)
+{
+ struct nlattr *telemetry;
+ unsigned char mac_addr[MAC_ADDR_LEN];
+ unsigned long stats = 0;
+ uint8_t value;
+ int ret;
+ struct nl_cb *cb;
+ struct unified_stats *telemetry_stats;
+ char *end;
+
+ if (argc < TELEMETRY_GET_STATS_MIN_ARG || argc > TELEMETRY_GET_STATS_MAX_ARG)
+ goto err;
+
+ if (mac_addr_a2n(mac_addr, argv[0])) {
+ printf("Invalid MAC address\n");
+ return -EINVAL;
+ }
+ argc--;
+ argv++;
+
+ if (!strcmp("svc_id", argv[0])) {
+ argc--;
+ argv++;
+ errno = 0;
+ value = strtoul(argv[0], &end, 10);
+ if (*end != '\0' || value > MAX_RANGE(uint8_t) || errno == ERANGE)
+ goto err;
+
+ argc--;
+ argv++;
+ } else {
+ goto err;
+ }
+
+ if (!argc)
+ goto err;
+
+ while (argc) {
+ if (!strcmp("sawfdelay",argv[0]))
+ stats |= SAWFDELAY_STATS;
+ else if (!strcmp("sawftx",argv[0]))
+ stats |= SAWFTX_STATS;
+ else
+ goto err;
+ argc--;
+ argv++;
+ }
+
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA);
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_GETSTATS);
+
+ telemetry = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+ if (!telemetry)
+ return -ENOBUFS;
+
+ if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRIC_LEVEL,
+ STATS_LVL_ADVANCE) ||
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRIC_OBJECT,
+ STATS_OBJ_STA) ||
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRIC_TYPE,
+ STATS_TYPE_DATA) ||
+ nla_put_u64(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRIC_FEATURE_FLAG,
+ stats) ||
+ nla_put(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRIC_STA_MAC,
+ ETH_ALEN, mac_addr) ||
+ nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRIC_SERVICEID,
+ value) ||
+ nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TELEMETRIC_AGGREGATE))
+ return -ENOBUFS;
+
+ nla_nest_end(msg, telemetry);
+ telemetry_stats = malloc(sizeof(struct unified_stats));
+ if (!telemetry_stats)
+ return NL_SKIP;
+
+ memset(telemetry_stats, 0, sizeof(struct unified_stats));
+
+ ret = nl_send_auto_complete(state->nl_sock, msg);
+ if (ret < 0)
+ goto unified_stats_free;
+
+ telemetry_stats->err = -1;
+
+ cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
+ nl_cb_err(cb, NL_CB_CUSTOM, error_stats_handler, telemetry_stats);
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_telemetry_stats, telemetry_stats);
+ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, complete_telemetry_stats, telemetry_stats);
+
+ while (telemetry_stats->err < 0)
+ nl_recvmsgs(state->nl_sock, cb);
+
+ if (telemetry_stats->err != EINVAL)
+ print_sawf_stats(telemetry_stats, value);
+ nl_cb_put(cb); // free the cb
+
+unified_stats_free:
+ free_unified_stats(telemetry_stats);
+ return HANDLER_RET_DONE;
+err:
+ printf("Invalid SAWF stats get command, format: Usage\n");
+ printf("iw dev <devname> sawf_stats get <sta_mac> [svc_id <service_id>] ");
+ printf("<[sawftx] [sawfdelay]>\n");
+ return HANDLER_RET_DONE;
+}
+COMMAND(sawf_stats, get, "<sta_mac> svc_id <service_id> <[sawftx] [sawfdelay]>", NL80211_CMD_VENDOR, 0, CIB_NETDEV, handle_sawf_stats, ".");
--- /dev/null
+++ b/sawf_stats.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * enum qca_wlan_vendor_attr_telemetric: Defines attributes to be used in
+ * request message of QCA_NL80211_VENDOR_SUBCMD_TELEMETRIC_DATA vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TELEMETRIC_LEVEL: Defines stats levels like Basic or
+ * Advance or Debug.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TELEMETRIC_OBJECT: Defines stats objects like STA or
+ * VAP or Radio or SoC.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TELEMETRIC_TYPE: Defines stats types like Data or
+ * control.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TELEMETRIC_AGGREGATE: Defines aggregation flag for
+ * driver agrregation.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TELEMETRIC_FEATURE_FLAG: Defines feature flags for
+ * which stats is requested.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TELEMETRIC_STA_MAC: Defines STA MAC Address if the
+ * request is for particular STA object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TELEMETRIC_SERVICEID: Defines serviceid for sawf stats.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_TELEMETRIC_MAX: Defines maximum attribute counts to be
+ * used in QCA_NL80211_VENDOR_SUBCMD_TELEMETRIC_DATA vendor command request.
+ */
+enum qca_wlan_vendor_attr_telemetric {
+ QCA_WLAN_VENDOR_TELEMETRY_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_LEVEL,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_OBJECT,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_TYPE,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_AGGREGATE,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_FEATURE_FLAG,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_STA_MAC,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_SERVICEID,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_MLD_LINK,
+
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_MAX =
+ QCA_WLAN_VENDOR_ATTR_TELEMETRIC_AFTER_LAST -1,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_stats: Defines attributes to be used in response of
+ * QCA_NL80211_VENDOR_SUBCMD_TELEMETRIC_DATA vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_STATS_LEVEL: Used for stats levels like Basic or
+ * Advance or Debug.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_STATS_OBJECT: Required (u8)
+ * Used with the command, carrying stats, to specify for which stats_object_e.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_STATS_OBJ_ID: Used for Object ID like for STA MAC
+ * address or for VAP or Radio or SoC respective interface name.
+ *
+ * QCA_WLAN_VENDOR_ATTR_STATS_SERVICEID: Used for sawf levels stats like per
+ * peer or per peer per serviceclass.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_STATS_PARENT_IF: Used for Parent Object interface name
+ * like for STA VAP name, for VAP Radio interface name and for Radio SoC
+ * interface name.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_STATS_TYPE: Used for stats types like Data or
+ * control.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_STATS_RECURSIVE: Required (NESTED Flag)
+ * Used with the command to specify the nested stats.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_STATS_MULTI_REPLY: Set this flag if current reply
+ * messageis holding data from previous reply.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_STATS_MAX: Defines maximum attriutes can be used in
+ * QCA_NL80211_VENDOR_SUBCMD_TELEMETRIC_DATA vendor command response.
+ */
+
+enum qca_wlan_vendor_attr_stats {
+ QCA_WLAN_VENDOR_ATTR_STATS_LEVEL = 1,
+ QCA_WLAN_VENDOR_ATTR_STATS_OBJECT,
+ QCA_WLAN_VENDOR_ATTR_STATS_OBJ_ID,
+ QCA_WLAN_VENDOR_ATTR_STATS_SERVICEID,
+ QCA_WLAN_VENDOR_ATTR_STATS_PARENT_IF,
+ QCA_WLAN_VENDOR_ATTR_STATS_TYPE,
+ QCA_WLAN_VENDOR_ATTR_STATS_RECURSIVE,
+ QCA_WLAN_VENDOR_ATTR_STATS_MULTI_REPLY,
+ QCA_WLAN_VENDOR_ATTR_STATS_MAX,
+};
+
+/**
+ * enum qca_wlan_vendor_attr_feat: Defines nested attributes to be used in
+ * response of QCA_NL80211_VENDOR_SUBCMD_TELEMETRIC_DATA vendor command.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_ME: Used for Multicast Enhancement stats for a
+ * particular stats object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_RX: Used for Rx stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_TX: Used for Tx stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_AST: Used for AST stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_CFR: Used for CFR stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_FWD: Used for BSS stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_RAW: Used for RAW mode stats for a particular
+ * object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_TSO: Used for TSO stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_TWT: Used for TWT stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_VOW: Used for VOW stats for a particular object.
+*
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_WDI: Used for WDI stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_WMI: Used for WMI stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_IGMP: Used for IGMP stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_LINK: Used for Link related stats for a particular
+ * object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_MESH: Used for Mesh related stats for a particular
+ * object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_RATE: Used for Rate stats for a particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_NAWDS: Used for NAWDS related stats for a
+ * particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_DELAY: Used for DELAY related stats for a
+ * particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_JITTER: Used for JITTER related stats for a
+ * particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_TXCAP: Used for TXCAP realted stats for a
+ * particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_MONITOR: Used for MONITOR realted stats for a
+ * particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_SAWFDELAY: Used for SAWFDELAY related stats for a
+ * particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_SAWFTX: Used for SAWFTX related stats for a
+ * particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_DETER: Used for DETERMINISTIC related stats for a
+ * particular object.
+ *
+ * @QCA_WLAN_VENDOR_ATTR_FEAT_MAX: Defines Maximum count of feature attributes.
+ */
+enum qca_wlan_vendor_attr_feat {
+ QCA_WLAN_VENDOR_ATTR_FEAT_ME = 1,
+ QCA_WLAN_VENDOR_ATTR_FEAT_RX,
+ QCA_WLAN_VENDOR_ATTR_FEAT_TX,
+ QCA_WLAN_VENDOR_ATTR_FEAT_AST,
+ QCA_WLAN_VENDOR_ATTR_FEAT_CFR,
+ QCA_WLAN_VENDOR_ATTR_FEAT_FWD,
+ QCA_WLAN_VENDOR_ATTR_FEAT_RAW,
+ QCA_WLAN_VENDOR_ATTR_FEAT_TSO,
+ QCA_WLAN_VENDOR_ATTR_FEAT_TWT,
+ QCA_WLAN_VENDOR_ATTR_FEAT_VOW,
+ QCA_WLAN_VENDOR_ATTR_FEAT_WDI,
+ QCA_WLAN_VENDOR_ATTR_FEAT_WMI,
+ QCA_WLAN_VENDOR_ATTR_FEAT_IGMP,
+ QCA_WLAN_VENDOR_ATTR_FEAT_LINK,
+ QCA_WLAN_VENDOR_ATTR_FEAT_MESH,
+ QCA_WLAN_VENDOR_ATTR_FEAT_RATE,
+ QCA_WLAN_VENDOR_ATTR_FEAT_NAWDS,
+ QCA_WLAN_VENDOR_ATTR_FEAT_DELAY,
+ QCA_WLAN_VENDOR_ATTR_FEAT_JITTER,
+ QCA_WLAN_VENDOR_ATTR_FEAT_TXCAP,
+ QCA_WLAN_VENDOR_ATTR_FEAT_MONITOR,
+ QCA_WLAN_VENDOR_ATTR_FEAT_SAWFDELAY,
+ QCA_WLAN_VENDOR_ATTR_FEAT_SAWFTX,
+ QCA_WLAN_VENDOR_ATTR_FEAT_DETER,
+ /**
+ * New attribute must be add before this.
+ * Also define the corresponding feature
+ * index in stats_feat_index_e.
+ */
+ QCA_WLAN_VENDOR_ATTR_FEAT_MAX,
+};
+
+/**
+ * enum stats_level: Defines detailing levels
+ * @STATS_LVL_BASIC: Very minimal stats data
+ * @STATS_LVL_ADVANCE: Mostly feature specific stats data
+ * @STATS_LVL_DEBUG: Stats data for debug purpose
+ * @STATS_LVL_MAX: Max supported Stats levels
+ */
+enum stats_level {
+ STATS_LVL_BASIC,
+ STATS_LVL_ADVANCE,
+ STATS_LVL_DEBUG,
+ STATS_LVL_MAX = STATS_LVL_DEBUG,
+};
+
+/**
+ * enum stats_object: Defines the Stats specific to object
+ * @STATS_OBJ_STA: Stats for station/peer associated to AP
+ * @STATS_OBJ_VAP: Stats for VAP
+ * @STATS_OBJ_MLD: Stats for MLD group
+ * @STATS_OBJ_RADIO: Stats for particular Radio
+ * @STATS_OBJ_AP: Stats for SoC
+ * @STATS_OBJ_MAX: Max supported objects
+ */
+enum stats_object {
+ STATS_OBJ_STA,
+ STATS_OBJ_VAP,
+ STATS_OBJ_MLD,
+ STATS_OBJ_RADIO,
+ STATS_OBJ_AP,
+ STATS_OBJ_MAX = STATS_OBJ_AP,
+};
+
+/**
+ * enum stats_type: Defines the Stats for specific category
+ * @STATS_TYPE_DATA: Stats for Data frames
+ * @STATS_TYPE_CTRL: Stats for Control/Management frames
+ * @STATS_TYPE_MAX: Max supported types
+ */
+enum stats_type {
+ STATS_TYPE_DATA,
+ STATS_TYPE_CTRL,
+ STATS_TYPE_MAX = STATS_TYPE_CTRL,
+};
+
+#define MAX_TID 8
+#define MAX_Q 8
+#define MAX_SAWF_Q 2
+
+struct sawf_fw_mpdu_stats {
+ uint64_t success_cnt;
+ uint64_t failure_cnt;
+};
+
+struct dp_pkt_info {
+ uint32_t num_pkts;
+ uint64_t bytes;
+};
+
+struct telemetry_sawf_tx_stat {
+ struct dp_pkt_info tx_success;
+ struct dp_pkt_info tx_ingress;
+ struct {
+ struct dp_pkt_info fw_rem;
+ uint32_t fw_rem_notx;
+ uint32_t fw_rem_tx;
+ uint32_t age_out;
+ uint32_t fw_reason1;
+ uint32_t fw_reason2;
+ uint32_t fw_reason3;
+ } dropped;
+ struct sawf_fw_mpdu_stats svc_intval_stats;
+ struct sawf_fw_mpdu_stats burst_size_stats;
+ uint32_t tx_failed;
+ uint32_t queue_depth;
+ uint32_t throughput;
+ uint32_t ingress_rate;
+};
+
+struct telemetry_sawftx_stats {
+ struct telemetry_sawf_tx_stat tx[MAX_TID][MAX_Q];
+ uint8_t tid;
+ uint8_t msduq;
+};
+
+enum stats_if_hist_bucket_index {
+ HIST_BUCKET_0,
+ HIST_BUCKET_1,
+ HIST_BUCKET_2,
+ HIST_BUCKET_3,
+ HIST_BUCKET_4,
+ HIST_BUCKET_5,
+ HIST_BUCKET_6,
+ HIST_BUCKET_7,
+ HIST_BUCKET_8,
+ HIST_BUCKET_9,
+ HIST_BUCKET_10,
+ HIST_BUCKET_11,
+ HIST_BUCKET_12,
+ HIST_BUCKET_MAX,
+};
+
+enum stats_if_delay_bucket_index {
+ DELAY_BUCKET_0,
+ DELAY_BUCKET_1,
+ DELAY_BUCKET_2,
+ DELAY_BUCKET_3,
+ DELAY_BUCKET_4,
+ DELAY_BUCKET_5,
+ DELAY_BUCKET_6,
+ DELAY_BUCKET_7,
+ DELAY_BUCKET_8,
+ DELAY_BUCKET_9,
+ DELAY_BUCKET_10,
+ DELAY_BUCKET_11,
+ DELAY_BUCKET_12,
+ DELAY_BUCKET_MAX,
+};
+
+enum hist_types {
+ HIST_TYPE_SW_ENQEUE_DELAY,
+ HIST_TYPE_HW_COMP_DELAY,
+ HIST_TYPE_REAP_STACK,
+ HIST_TYPE_HW_TX_COMP_DELAY,
+ HIST_TYPE_MAX,
+};
+
+struct hist_bucket {
+ enum hist_types hist_type;
+ uint64_t freq[HIST_BUCKET_MAX];
+};
+
+struct delay_hist_stats {
+ struct hist_bucket hist;
+ int32_t max;
+ int32_t min;
+ int32_t avg;
+};
+
+struct telemetry_sawf_delay_stat {
+ struct delay_hist_stats delay_hist;
+ uint8_t cur_win;
+ uint32_t nwdelay_avg;
+ uint32_t swdelay_avg;
+ uint32_t hwdelay_avg;
+ uint64_t delay_bound_success;
+ uint64_t delay_bound_failure;
+};
+
+struct telemetry_sawfdelay_stats {
+ struct telemetry_sawf_delay_stat delay[MAX_TID][MAX_Q];
+ uint8_t tid;
+ uint8_t msduq;
+};
+
+enum stats_feat {
+ STATS_FEAT_SAWFDELAY = 0,
+ STATS_FEAT_SAWFTX = 1,
+ STATS_FEAT_MAX = 2,
+};
+
+struct unified_stats {
+ void *feat[STATS_FEAT_MAX];
+ int err;
+};
+
--- a/iw.h
+++ b/iw.h
@@ -82,6 +82,7 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_SLA_BREACH_DETECTION_CFG = 212,
QCA_NL80211_VENDOR_SUBCMD_SAWF_STREAMING_STATS = 213,
QCA_NL80211_VENDOR_SUBCMD_SAWF_SLA_BREACH = 214,
+ QCA_NL80211_VENDOR_SUBCMD_TELEMETRY_GETSTATS = 334,
};
/* Attributes for data used by
* QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION and

View File

@@ -0,0 +1,35 @@
From 465bf0b889b8718318b636763464d0dd78c088c8 Mon Sep 17 00:00:00 2001
From: Arulanbu Balusamy <quic_abalusam@quicinc.com>
Date: Sat, 8 Jul 2023 23:13:36 +0530
Subject: [PATCH] event.c: format specifier modify in printf statement
The variable declares in long long int but exist format specifier is unsigned
long int. So modify the format specifier by declaring local variable.
Signed-off-by: Arulanbu Balusamy <quic_abalusam@quicinc.com>
---
event.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/event.c
+++ b/event.c
@@ -929,7 +929,7 @@
#endif
if (args->time || args->reltime || args->ctime) {
- unsigned long long usecs, previous;
+ unsigned long long usecs, previous, tvusec;
previous = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec;
gettimeofday(&args->ts, NULL);
@@ -949,7 +949,8 @@
memset(buf, 0, 255);
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
- printf("[%s.%06lu]: ", buf, args->ts.tv_usec);
+ tvusec=args->ts.tv_usec;
+ printf("[%s.%06llu]: ", buf, tvusec);
} else {
printf("%llu.%06llu: ", usecs/1000000, usecs % 1000000);
}

View File

@@ -0,0 +1,49 @@
From 2f37eaa39c6fb845c181281d5708b3413cf29b79 Mon Sep 17 00:00:00 2001
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
Date: Wed, 6 Sep 2023 11:10:35 +0530
Subject: [PATCH] iw: print NO-EHT flags for reg get command
If a reg rule is marked with NO-EHT flag, print "NO-EHT" while
displaying the reg rules via reg get command.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
nl80211.h | 2 ++
reg.c | 1 +
2 files changed, 3 insertions(+)
diff --git a/nl80211.h b/nl80211.h
index f3f456094989..db431b13776d 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -4344,6 +4344,7 @@ enum nl80211_sched_scan_match_attr {
* @NL80211_RRF_NO_HE: HE operation not allowed
* @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed
* @NL80211_RRF_PSD: channels has power spectral density value
+ * @NL80211_RRF_NO_EHT: EHT operation not allowed
*/
enum nl80211_reg_rule_flags {
NL80211_RRF_NO_OFDM = 1<<0,
@@ -4364,6 +4365,7 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_NO_HE = 1<<17,
NL80211_RRF_NO_320MHZ = 1<<18,
NL80211_RRF_PSD = 1<<19,
+ NL80211_RRF_NO_EHT = 1<<20,
};
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
diff --git a/reg.c b/reg.c
index 1ff4fe998a18..2c3bffb95486 100644
--- a/reg.c
+++ b/reg.c
@@ -251,6 +251,7 @@ static int print_reg_handler(struct nl_msg *msg, void *arg)
PARSE_FLAG(NL80211_RRF_NO_160MHZ, "NO-160MHZ");
PARSE_FLAG(NL80211_RRF_NO_HE, "NO-HE");
PARSE_FLAG(NL80211_RRF_NO_320MHZ, "NO-320MHZ");
+ PARSE_FLAG(NL80211_RRF_NO_EHT, "NO-EHT");
/* Kernels that support NO_IR always turn on both flags */
if ((flags & NL80211_RRF_NO_IR) && (flags & __NL80211_RRF_NO_IBSS)) {
--
2.17.1

View File

@@ -64,7 +64,7 @@ config-$(call config_package,ath10k) += ATH10K ATH10K_PCI
config-$(call config_package,ath11k) += ATH11K ATH11K_AHB ATH11K_SPECTRAL ATH11K_DEBUG ATH11K_CFR
config-$(call config_package,ath11k-pci) += ATH11K_PCI
config-$(call config_package,ath12k) += ATH12K
config-y += ATH12K_SPECTRAL
config-y += ATH12K_SPECTRAL ATH12K_AHB
#ifeq ($(CONFIG_KERNEL_IPQ_MEM_PROFILE),512)
config-y += ATH11K_MEM_PROFILE_512M
@@ -289,7 +289,7 @@ define KernelPackage/ath11k
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11ax wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath11k
DEPENDS+= @TARGET_ipq95xx +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT \
DEPENDS+= @(TARGET_ipq95xx||TARGET_ipq53xx) +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT \
+@DRIVER_11AX_SUPPORT
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath11k/ath11k.ko
@@ -324,7 +324,7 @@ define KernelPackage/ath12k
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11be wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath12k
DEPENDS+= @TARGET_ipq95xx +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT \
DEPENDS+= @(TARGET_ipq95xx||TARGET_ipq53xx) +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT \
+@DRIVER_11AX_SUPPORT
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath12k/ath12k.ko

View File

@@ -0,0 +1,13 @@
Index: backports-20220822-5.4.213-ef7197996efe/drivers/net/wireless/ath/ath12k/qmi.c
===================================================================
--- backports-20220822-5.4.213-ef7197996efe.orig/drivers/net/wireless/ath/ath12k/qmi.c
+++ backports-20220822-5.4.213-ef7197996efe/drivers/net/wireless/ath/ath12k/qmi.c
@@ -24,7 +24,7 @@
#define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08
#define ATH12K_QMI_MAX_CHUNK_SIZE 2097152
-bool ath12k_cold_boot_cal = 1;
+bool ath12k_cold_boot_cal = 0;
module_param_named(cold_boot_cal, ath12k_cold_boot_cal, bool, 0644);
MODULE_PARM_DESC(cold_boot_cal,
"Decrease the channel switch time but increase the driver load time (Default: true)");

View File

@@ -0,0 +1,31 @@
Index: backports-20220822-5.4.213-ef7197996efe/drivers/net/wireless/ath/ath12k/core.c
===================================================================
--- backports-20220822-5.4.213-ef7197996efe.orig/drivers/net/wireless/ath/ath12k/core.c
+++ backports-20220822-5.4.213-ef7197996efe/drivers/net/wireless/ath/ath12k/core.c
@@ -48,7 +48,7 @@ unsigned int ath12k_ftm_mode;
module_param_named(ftm_mode, ath12k_ftm_mode, uint, 0444);
MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode");
-unsigned int ath12k_mlo_capable = true;
+unsigned int ath12k_mlo_capable = false;
module_param_named(mlo_capable, ath12k_mlo_capable, uint, 0644);
MODULE_PARM_DESC(mlo_capable, "mlo capable: 0-disable, 1-enable");
@@ -474,7 +474,7 @@ const struct firmware *ath12k_core_firmw
ath12k_core_create_firmware_path(ab, file, path, sizeof(path));
- ret = request_firmware_direct(&fw, path, ab->dev);
+ ret = request_firmware(&fw, path, ab->dev);
if (ret)
return ERR_PTR(ret);
@@ -734,6 +734,8 @@ int ath12k_core_fetch_bdf(struct ath12k_
ab->bd_api = 1;
ret = ath12k_core_fetch_board_data_api_1(ab, bd, ATH12K_DEFAULT_BOARD_FILE);
+ if (!ret)
+ goto success;
if (ret) {
ath12k_err(ab, "failed to fetch board-2.bin from %s\n",
ab->hw_params->fw.dir);

File diff suppressed because it is too large Load Diff

13
profiles/cig_wf198.yml Normal file
View File

@@ -0,0 +1,13 @@
---
profile: cig_wf198
target: ipq53xx
subtarget: generic
description: Build image for the CIG WF198
image: bin/targets/ipq60xx/generic/openwrt-ipq60xx-edgecore_eap101-squashfs-sysupgrade.tar
feeds:
- name: ipq95xx
path: ../../feeds/ipq95xx
packages:
- ipq53xx
diffconfig: |
CONFIG_KERNEL_IPQ_MEM_PROFILE=0