mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 22:44:27 -05:00 
			
		
		
		
	Backport FIELD_PREP_CONST patch needed for at803x backport patches to correctly compile and work. This MACRO is needed to treat values derived from FIELD_PREP usage as const to be used by switch case or other needed usage. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
		
			
				
	
	
		
			59 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From e2192de59e457aef8d1f055a452131f0b3e5d097 Mon Sep 17 00:00:00 2001
 | 
						|
From: Johannes Berg <johannes.berg@intel.com>
 | 
						|
Date: Wed, 18 Jan 2023 14:26:53 +0100
 | 
						|
Subject: [PATCH] bitfield: add FIELD_PREP_CONST()
 | 
						|
 | 
						|
Neither FIELD_PREP() nor *_encode_bits() can be used
 | 
						|
in constant contexts (such as initializers), but we
 | 
						|
don't want to define shift constants for all masks
 | 
						|
just for use in initializers, and having checks that
 | 
						|
the values fit is also useful.
 | 
						|
 | 
						|
Therefore, add FIELD_PREP_CONST() which is a smaller
 | 
						|
version of FIELD_PREP() that can only take constant
 | 
						|
arguments and has less friendly (but not less strict)
 | 
						|
error checks, and expands to a constant value.
 | 
						|
 | 
						|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 | 
						|
Link: https://lore.kernel.org/r/20230118142652.53f20593504b.Iaeea0aee77a6493d70e573b4aa55c91c00e01e4b@changeid
 | 
						|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
 | 
						|
---
 | 
						|
 include/linux/bitfield.h | 26 ++++++++++++++++++++++++++
 | 
						|
 1 file changed, 26 insertions(+)
 | 
						|
 | 
						|
--- a/include/linux/bitfield.h
 | 
						|
+++ b/include/linux/bitfield.h
 | 
						|
@@ -115,6 +115,32 @@
 | 
						|
 		((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask);	\
 | 
						|
 	})
 | 
						|
 
 | 
						|
+#define __BF_CHECK_POW2(n)	BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0)
 | 
						|
+
 | 
						|
+/**
 | 
						|
+ * FIELD_PREP_CONST() - prepare a constant bitfield element
 | 
						|
+ * @_mask: shifted mask defining the field's length and position
 | 
						|
+ * @_val:  value to put in the field
 | 
						|
+ *
 | 
						|
+ * FIELD_PREP_CONST() masks and shifts up the value.  The result should
 | 
						|
+ * be combined with other fields of the bitfield using logical OR.
 | 
						|
+ *
 | 
						|
+ * Unlike FIELD_PREP() this is a constant expression and can therefore
 | 
						|
+ * be used in initializers. Error checking is less comfortable for this
 | 
						|
+ * version, and non-constant masks cannot be used.
 | 
						|
+ */
 | 
						|
+#define FIELD_PREP_CONST(_mask, _val)					\
 | 
						|
+	(								\
 | 
						|
+		/* mask must be non-zero */				\
 | 
						|
+		BUILD_BUG_ON_ZERO((_mask) == 0) +			\
 | 
						|
+		/* check if value fits */				\
 | 
						|
+		BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \
 | 
						|
+		/* check if mask is contiguous */			\
 | 
						|
+		__BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) +	\
 | 
						|
+		/* and create the value */				\
 | 
						|
+		(((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask))	\
 | 
						|
+	)
 | 
						|
+
 | 
						|
 /**
 | 
						|
  * FIELD_GET() - extract a bitfield element
 | 
						|
  * @_mask: shifted mask defining the field's length and position
 |