--- /dev/null
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (C) 2007-2019 B.A.T.M.A.N. contributors:
+#
+# Marek Lindner, Simon Wunderlich
+
+#
+# B.A.T.M.A.N meshing protocol
+#
+
+config BATMAN_ADV_BATMAN_V
+ bool "B.A.T.M.A.N. V protocol"
+ depends on PACKAGE_kmod-batman-adv
+ default y
+ help
+ This option enables the B.A.T.M.A.N. V protocol, the successor
+ of the currently used B.A.T.M.A.N. IV protocol. The main
+ changes include splitting of the OGM protocol into a neighbor
+ discovery protocol (Echo Location Protocol, ELP) and a new OGM
+ Protocol OGMv2 for flooding protocol information through the
+ network, as well as a throughput based metric.
+ B.A.T.M.A.N. V is currently considered experimental and not
+ compatible to B.A.T.M.A.N. IV networks.
+
+config BATMAN_ADV_BLA
+ bool "Bridge Loop Avoidance"
+ depends on PACKAGE_kmod-batman-adv
+ select PACKAGE_kmod-lib-crc16
+ default y
+ help
+ This option enables BLA (Bridge Loop Avoidance), a mechanism
+ to avoid Ethernet frames looping when mesh nodes are connected
+ to both the same LAN and the same mesh. If you will never use
+ more than one mesh node in the same LAN, you can safely remove
+ this feature and save some space.
+
+config BATMAN_ADV_DAT
+ bool "Distributed ARP Table"
+ depends on PACKAGE_kmod-batman-adv
+ default y
+ help
+ This option enables DAT (Distributed ARP Table), a DHT based
+ mechanism that increases ARP reliability on sparse wireless
+ mesh networks. If you think that your network does not need
+ this option you can safely remove it and save some space.
+
+config BATMAN_ADV_MCAST
+ bool "Multicast optimisation"
+ depends on PACKAGE_kmod-batman-adv
+ default y
+ help
+ This option enables the multicast optimisation which aims to
+ reduce the air overhead while improving the reliability of
+ multicast messages.
+
+config BATMAN_ADV_DEBUG
+ bool "B.A.T.M.A.N. debugging"
+ depends on PACKAGE_kmod-batman-adv
+ help
+ This is an option for use by developers; most people should
+ say N here. This enables compilation of support for
+ outputting debugging information to the debugfs log or tracing
+ buffer. The output is controlled via the batadv netdev specific
+ log_level setting.
+
+config BATMAN_ADV_TRACING
+ bool "B.A.T.M.A.N. tracing support"
+ depends on PACKAGE_kmod-batman-adv
+ select KERNEL_FTRACE
+ select KERNEL_ENABLE_DEFAULT_TRACERS
+ help
+ This is an option for use by developers; most people should
+ say N here. Select this option to gather traces like the debug
+ messages using the generic tracing infrastructure of the kernel.
+ BATMAN_ADV_DEBUG must also be selected to get trace events for
+ batadv_dbg.
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=batman-adv
+PKG_VERSION:=2026.2
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
+PKG_HASH:=4e17fced2c80945e22609be87534481733ff1b5d17050de4e4f323c171418135
+PKG_EXTMOD_SUBDIRS:=net/batman-adv
+
+PKG_MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
+PKG_LICENSE:=GPL-2.0-only MIT
+PKG_LICENSE_FILES:=LICENSES/preferred/GPL-2.0 LICENSES/preferred/MIT
+
+PKG_BUILD_PARALLEL:=1
+
+STAMP_CONFIGURED_DEPENDS:=$(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h
+
+PKG_CONFIG_DEPENDS += \
+ CONFIG_BATMAN_ADV_BATMAN_V \
+ CONFIG_BATMAN_ADV_BLA \
+ CONFIG_BATMAN_ADV_DAT \
+ CONFIG_BATMAN_ADV_MCAST \
+ CONFIG_BATMAN_ADV_DEBUG \
+ CONFIG_BATMAN_ADV_TRACING
+
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/package.mk
+
+define KernelPackage/batman-adv
+ SUBMENU:=Network Support
+ TITLE:=B.A.T.M.A.N. Adv
+ URL:=https://www.open-mesh.org/
+ DEPENDS:=+BATMAN_ADV_BLA:kmod-lib-crc16 +LINUX_6_12:kmod-lib-crc32c +kmod-cfg80211 +batctl
+ FILES:=$(PKG_BUILD_DIR)/net/batman-adv/batman-adv.$(LINUX_KMOD_SUFFIX)
+ AUTOLOAD:=$(call AutoProbe,batman-adv)
+endef
+
+define KernelPackage/batman-adv/description
+ B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
+ a routing protocol for multi-hop ad-hoc mesh networks. The
+ networks may be wired or wireless. See
+ https://www.open-mesh.org/ for more information and user space
+ tools. This package builds version $(PKG_VERSION) of the kernel
+ module.
+endef
+
+define KernelPackage/batman-adv/config
+ source "$(SOURCE)/Config.in"
+endef
+
+define Package/kmod-batman-adv/conffiles
+/etc/config/batman-adv
+endef
+
+PKG_MAKE_FLAGS:= \
+ CONFIG_BATMAN_ADV=m \
+ CONFIG_BATMAN_ADV_DEBUG=$(if $(CONFIG_BATMAN_ADV_DEBUG),y,n) \
+ CONFIG_BATMAN_ADV_BLA=$(if $(CONFIG_BATMAN_ADV_BLA),y,n) \
+ CONFIG_BATMAN_ADV_DAT=$(if $(CONFIG_BATMAN_ADV_DAT),y,n) \
+ CONFIG_BATMAN_ADV_MCAST=$(if $(CONFIG_BATMAN_ADV_MCAST),y,n) \
+ CONFIG_BATMAN_ADV_BATMAN_V=$(if $(CONFIG_BATMAN_ADV_BATMAN_V),y,n) \
+ CONFIG_BATMAN_ADV_TRACING=$(if $(CONFIG_BATMAN_ADV_TRACING),y,n) \
+
+NOSTDINC_FLAGS := \
+ $(KERNEL_NOSTDINC_FLAGS) \
+ -I$(PKG_BUILD_DIR)/include/ \
+ -I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
+ -I$(STAGING_DIR)/usr/include/mac80211-backport \
+ -I$(STAGING_DIR)/usr/include/mac80211/uapi \
+ -I$(STAGING_DIR)/usr/include/mac80211 \
+ -include backport/autoconf.h \
+ -include backport/backport.h \
+ -include $(PKG_BUILD_DIR)/compat-hacks.h \
+ -DBATADV_SOURCE_VERSION=\\\"$(PKG_VERSION)-openwrt-$(PKG_RELEASE)\\\"
+
+NOSTDINC_FLAGS += \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(PKG_MAKE_FLAGS)))) \
+ $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(PKG_MAKE_FLAGS)))) \
+
+define Build/Compile
+ +$(KERNEL_MAKE) $(PKG_JOBS) \
+ $(PKG_MAKE_FLAGS) \
+ M="$(PKG_BUILD_DIR)/net/batman-adv" \
+ NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
+ modules
+endef
+
+define KernelPackage/batman-adv/install
+ $(CP) ./files/. $(1)/
+endef
+
+$(eval $(call KernelPackage,batman-adv))
--- /dev/null
+#!/bin/sh
+
+# This UCI-Defaults script will split the batadv proto network interfaces
+# in batadv_hardif and batadv proto. The configuration options from
+# /etc/config/batman-adv will be moved to the latter.
+
+. /lib/functions.sh
+
+proto_batadv_to_batadv_hardif() {
+ local section="$1"
+ local proto
+ local mesh
+ local routing_algo
+
+ config_get proto "${section}" proto
+ config_get mesh "${section}" mesh
+ config_get routing_algo "${section}" routing_algo
+
+ if [ -z "$mesh" -o "${proto}" != "batadv" ]; then
+ continue
+ fi
+
+ uci set network."${section}".proto="batadv_hardif"
+ uci rename network."${section}".mesh="master"
+ uci delete network."${section}".routing_algo
+
+ # create new section or adjust existing one
+ uci set network."${mesh}"=interface
+ uci set network."${mesh}".proto=batadv
+ [ -n "${routing_algo}" ] && uci set network."${mesh}".routing_algo="${routing_algo}"
+}
+
+mv_batadv_config_section() {
+ local section="$1"
+ local aggregated_ogms
+ local ap_isolation
+ local bonding
+ local bridge_loop_avoidance
+ local distributed_arp_table
+ local fragmentation
+ local gw_bandwidth
+ local gw_mode
+ local gw_sel_class
+ local hop_penalty
+ local isolation_mark
+ local log_level
+ local multicast_mode
+ local orig_interval
+
+ config_get aggregated_ogms "${section}" aggregated_ogms
+ config_get ap_isolation "${section}" ap_isolation
+ config_get bonding "${section}" bonding
+ config_get bridge_loop_avoidance "${section}" bridge_loop_avoidance
+ config_get distributed_arp_table "${section}" distributed_arp_table
+ config_get fragmentation "${section}" fragmentation
+ config_get gw_bandwidth "${section}" gw_bandwidth
+ config_get gw_mode "${section}" gw_mode
+ config_get gw_sel_class "${section}" gw_sel_class
+ config_get hop_penalty "${section}" hop_penalty
+ config_get isolation_mark "${section}" isolation_mark
+ config_get log_level "${section}" log_level
+ config_get multicast_mode "${section}" multicast_mode
+ config_get orig_interval "${section}" orig_interval
+
+ # update section in case it exists
+ [ -n "${aggregated_ogms}" ] && uci set network."${section}".aggregated_ogms="${aggregated_ogms}"
+ [ -n "${ap_isolation}" ] && uci set network."${section}".ap_isolation="${ap_isolation}"
+ [ -n "${bonding}" ] && uci set network."${section}".bonding="${bonding}"
+ [ -n "${bridge_loop_avoidance}" ] && uci set network."${section}".bridge_loop_avoidance="${bridge_loop_avoidance}"
+ [ -n "${distributed_arp_table}" ] && uci set network."${section}".distributed_arp_table="${distributed_arp_table}"
+ [ -n "${fragmentation}" ] && uci set network."${section}".fragmentation="${fragmentation}"
+ [ -n "${gw_bandwidth}" ] && uci set network."${section}".gw_bandwidth="${gw_bandwidth}"
+ [ -n "${gw_mode}" ] && uci set network."${section}".gw_mode="${gw_mode}"
+ [ -n "${gw_sel_class}" ] && uci set network."${section}".gw_sel_class="${gw_sel_class}"
+ [ -n "${hop_penalty}" ] && uci set network."${section}".hop_penalty="${hop_penalty}"
+ [ -n "${isolation_mark}" ] && uci set network."${section}".isolation_mark="${isolation_mark}"
+ [ -n "${log_level}" ] && uci set network."${section}".log_level="${log_level}"
+ [ -n "${multicast_mode}" ] && uci set network."${section}".multicast_mode="${multicast_mode}"
+ [ -n "${orig_interval}" ] && uci set network."${section}".orig_interval="${orig_interval}"
+}
+
+if [ -f /etc/config/batman-adv ]; then
+ config_load network
+ config_foreach proto_batadv_to_batadv_hardif 'interface'
+ uci commit network
+
+ config_load batman-adv
+ config_foreach mv_batadv_config_section 'mesh'
+ uci commit network
+
+ rm -f /etc/config/batman-adv
+fi
+
+exit 0
--- /dev/null
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_batadv_init_config() {
+ no_device=1
+ available=1
+
+ proto_config_add_boolean 'aggregated_ogms:bool'
+ proto_config_add_boolean 'ap_isolation:bool'
+ proto_config_add_boolean 'bonding:bool'
+ proto_config_add_boolean 'bridge_loop_avoidance:bool'
+ proto_config_add_boolean 'distributed_arp_table:bool'
+ proto_config_add_boolean 'fragmentation:bool'
+ proto_config_add_string 'gw_bandwidth'
+ proto_config_add_string 'gw_mode'
+ proto_config_add_int 'gw_sel_class'
+ proto_config_add_int 'hop_penalty'
+ proto_config_add_string 'isolation_mark'
+ proto_config_add_string 'log_level'
+ proto_config_add_int 'multicast_fanout'
+ proto_config_add_boolean 'multicast_mode:bool'
+ proto_config_add_int 'orig_interval'
+ proto_config_add_string 'routing_algo'
+}
+
+proto_batadv_setup() {
+ local config="$1"
+ local iface="$config"
+
+ local aggregated_ogms
+ local ap_isolation
+ local bonding
+ local bridge_loop_avoidance
+ local distributed_arp_table
+ local fragmentation
+ local gw_bandwidth
+ local gw_mode
+ local gw_sel_class
+ local hop_penalty
+ local isolation_mark
+ local log_level
+ local multicast_fanout
+ local multicast_mode
+ local orig_interval
+ local routing_algo
+
+ json_get_vars aggregated_ogms
+ json_get_vars ap_isolation
+ json_get_vars bonding
+ json_get_vars bridge_loop_avoidance
+ json_get_vars distributed_arp_table
+ json_get_vars fragmentation
+ json_get_vars gw_bandwidth
+ json_get_vars gw_mode
+ json_get_vars gw_sel_class
+ json_get_vars hop_penalty
+ json_get_vars isolation_mark
+ json_get_vars log_level
+ json_get_vars multicast_fanout
+ json_get_vars multicast_mode
+ json_get_vars orig_interval
+ json_get_vars routing_algo
+
+ set_default routing_algo 'BATMAN_IV'
+
+ batctl routing_algo "$routing_algo"
+ batctl meshif "$iface" interface create
+
+ [ -n "$aggregated_ogms" ] && batctl meshif "$iface" aggregation "$aggregated_ogms"
+ [ -n "$ap_isolation" ] && batctl meshif "$iface" ap_isolation "$ap_isolation"
+ [ -n "$bonding" ] && batctl meshif "$iface" bonding "$bonding"
+ [ -n "$bridge_loop_avoidance" ] && batctl meshif "$iface" bridge_loop_avoidance "$bridge_loop_avoidance" 2>&-
+ [ -n "$distributed_arp_table" ] && batctl meshif "$iface" distributed_arp_table "$distributed_arp_table" 2>&-
+ [ -n "$fragmentation" ] && batctl meshif "$iface" fragmentation "$fragmentation"
+
+ case "$gw_mode" in
+ server)
+ if [ -n "$gw_bandwidth" ]; then
+ batctl meshif "$iface" gw_mode "server" "$gw_bandwidth"
+ else
+ batctl meshif "$iface" gw_mode "server"
+ fi
+ ;;
+ client)
+ if [ -n "$gw_sel_class" ]; then
+ batctl meshif "$iface" gw_mode "client" "$gw_sel_class"
+ else
+ batctl meshif "$iface" gw_mode "client"
+ fi
+ ;;
+ *)
+ batctl meshif "$iface" gw_mode "off"
+ ;;
+ esac
+
+ [ -n "$hop_penalty" ] && batctl meshif "$iface" hop_penalty "$hop_penalty"
+ [ -n "$isolation_mark" ] && batctl meshif "$iface" isolation_mark "$isolation_mark"
+ [ -n "$multicast_fanout" ] && batctl meshif "$iface" multicast_fanout "$multicast_fanout"
+ [ -n "$multicast_mode" ] && batctl meshif "$iface" multicast_mode "$multicast_mode" 2>&-
+ [ -n "$log_level" ] && batctl meshif "$iface" loglevel "$log_level" 2>&-
+ [ -n "$orig_interval" ] && batctl meshif "$iface" orig_interval "$orig_interval"
+
+ proto_init_update "$iface" 1
+ proto_send_update "$config"
+}
+
+proto_batadv_teardown() {
+ local config="$1"
+ local iface="$config"
+
+ batctl meshif "$iface" interface destroy
+}
+
+add_protocol batadv
--- /dev/null
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_batadv_hardif_init_config() {
+ proto_config_add_int 'elp_interval'
+ proto_config_add_int 'hop_penalty'
+ proto_config_add_string "master"
+ proto_config_add_string 'throughput_override'
+}
+
+proto_batadv_hardif_setup() {
+ local config="$1"
+ local iface="$2"
+
+ local elp_interval
+ local hop_penalty
+ local master
+ local throughput_override
+
+ json_get_vars elp_interval
+ json_get_vars hop_penalty
+ json_get_vars master
+ json_get_vars throughput_override
+
+ ( proto_add_host_dependency "$config" '' "$master" )
+
+ batctl meshif "$master" interface -M add "$iface"
+
+ [ -n "$elp_interval" ] && batctl hardif "$iface" elp_interval "$elp_interval"
+ [ -n "$hop_penalty" ] && batctl hardif "$iface" hop_penalty "$hop_penalty"
+ [ -n "$throughput_override" ] && batctl hardif "$iface" throughput_override "$throughput_override"
+
+ proto_init_update "$iface" 1
+ proto_send_update "$config"
+}
+
+proto_batadv_hardif_teardown() {
+ local config="$1"
+ local iface="$2"
+
+ local master
+
+ json_get_vars master
+
+ batctl meshif "$master" interface -M del "$iface" || true
+}
+
+add_protocol batadv_hardif
--- /dev/null
+#!/bin/sh
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+proto_batadv_vlan_init_config() {
+ proto_config_add_boolean 'ap_isolation:bool'
+}
+
+proto_batadv_vlan_setup() {
+ local config="$1"
+ local iface="$2"
+
+ # batadv_vlan options
+ local ap_isolation
+
+ json_get_vars ap_isolation
+
+ batctl vlan "$iface" ap_isolation "${ap_isolation:-0}"
+ proto_init_update "$iface" 1
+ proto_send_update "$config"
+}
+
+proto_batadv_vlan_teardown() {
+ local cfg="$1"
+}
+
+add_protocol batadv_vlan
--- /dev/null
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
+Date: Thu, 6 Apr 2023 18:05:50 -0500
+Subject: fix batadv_is_cfg80211_netdev
+
+Replace CONFIG_CFG80211 with CPTCFG_CFG80211, which is the correct
+macro to use when building under backports.
+
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -320,8 +320,7 @@ static bool batadv_is_cfg80211_netdev(st
+ {
+ if (!net_device)
+ return false;
+-
+-#if IS_ENABLED(CONFIG_CFG80211)
++#if IS_ENABLED(CPTCFG_CFG80211)
+ /* cfg80211 drivers have to set ieee80211_ptr */
+ if (net_device->ieee80211_ptr)
+ return true;
--- /dev/null
+/* Please avoid adding hacks here - instead add it to mac80211/backports.git */
+
+#undef CONFIG_MODULE_STRIPPED
+
+#include <linux/version.h> /* LINUX_VERSION_CODE */
+#include <linux/types.h>
+
+#if LINUX_VERSION_IS_LESS(6, 15, 0)
+#include <linux/crc32c.h>
+#endif /* LINUX_VERSION_IS_LESS(6, 15, 0) */
+
+#if LINUX_VERSION_IS_LESS(6, 16, 0)
+
+#define timer_container_of(var, callback_timer, timer_fieldname) \
+ from_timer(var, callback_timer, timer_fieldname)
+
+#endif /* LINUX_VERSION_IS_LESS(6, 16, 0) */
+
+#if LINUX_VERSION_IS_LESS(6, 16, 0) || !defined(CONFIG_NET_CRC32C)
+
+#include <linux/skbuff.h>
+#include <linux/crc32.h>
+
+static inline u32 batadv_skb_crc32c(struct sk_buff *skb, int offset,
+ int len, u32 crc)
+{
+ unsigned int to = offset + len;
+ unsigned int consumed = 0;
+ struct skb_seq_state st;
+ unsigned int l;
+ const u8 *data;
+
+ if (len <= 0)
+ return crc;
+
+ skb_prepare_seq_read(skb, offset, to, &st);
+ while ((l = skb_seq_read(consumed, &data, &st)) != 0) {
+ crc = crc32c(crc, data, l);
+ consumed += l;
+ }
+
+ return crc;
+}
+
+#define skb_crc32c batadv_skb_crc32c
+
+#endif /* LINUX_VERSION_IS_LESS(6, 16, 0) || !defined(CONFIG_NET_CRC32C) */
+
+#if LINUX_VERSION_IS_LESS(7, 0, 0) && \
+ !(LINUX_VERSION_IS_GEQ(6, 18, 33) && LINUX_VERSION_IS_LESS(6, 19, 0))
+
+#define kzalloc_obj(P, GFP) \
+ kzalloc(sizeof(P), GFP)
+
+#define kmalloc_obj(P, GFP) \
+ kmalloc(sizeof(P), GFP)
+
+#define kmalloc_objs(P, COUNT, GFP) \
+ kmalloc_array((COUNT), sizeof(P), GFP)
+
+#endif /* < KERNEL_VERSION(7, 0, 0) */
+
+/* <DECLARE_EWMA> */
+
+#include <linux/version.h>
+#include_next <linux/average.h>
+
+#include <linux/bug.h>
+
+#ifdef DECLARE_EWMA
+#undef DECLARE_EWMA
+#endif /* DECLARE_EWMA */
+
+/*
+ * Exponentially weighted moving average (EWMA)
+ *
+ * This implements a fixed-precision EWMA algorithm, with both the
+ * precision and fall-off coefficient determined at compile-time
+ * and built into the generated helper funtions.
+ *
+ * The first argument to the macro is the name that will be used
+ * for the struct and helper functions.
+ *
+ * The second argument, the precision, expresses how many bits are
+ * used for the fractional part of the fixed-precision values.
+ *
+ * The third argument, the weight reciprocal, determines how the
+ * new values will be weighed vs. the old state, new values will
+ * get weight 1/weight_rcp and old values 1-1/weight_rcp. Note
+ * that this parameter must be a power of two for efficiency.
+ */
+
+#define DECLARE_EWMA(name, _precision, _weight_rcp) \
+ struct ewma_##name { \
+ unsigned long internal; \
+ }; \
+ static inline void ewma_##name##_init(struct ewma_##name *e) \
+ { \
+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
+ /* \
+ * Even if you want to feed it just 0/1 you should have \
+ * some bits for the non-fractional part... \
+ */ \
+ BUILD_BUG_ON((_precision) > 30); \
+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
+ e->internal = 0; \
+ } \
+ static inline unsigned long \
+ ewma_##name##_read(struct ewma_##name *e) \
+ { \
+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
+ BUILD_BUG_ON((_precision) > 30); \
+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
+ return e->internal >> (_precision); \
+ } \
+ static inline void ewma_##name##_add(struct ewma_##name *e, \
+ unsigned long val) \
+ { \
+ unsigned long internal = READ_ONCE(e->internal); \
+ unsigned long weight_rcp = ilog2(_weight_rcp); \
+ unsigned long precision = _precision; \
+ \
+ BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
+ BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
+ BUILD_BUG_ON((_precision) > 30); \
+ BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
+ \
+ WRITE_ONCE(e->internal, internal ? \
+ (((internal << weight_rcp) - internal) + \
+ (val << precision)) >> weight_rcp : \
+ (val << precision)); \
+ }
+
+/* </DECLARE_EWMA> */