netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC][PATCH] new byteorder primitives - ..._{replace,get}_bits()
Date: Mon, 11 Dec 2017 15:54:22 +0000	[thread overview]
Message-ID: <20171211155422.GA12326@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20171211053803.GW21978@ZenIV.linux.org.uk>

A lot of drivers are open-coding the "replace these bits in __be32 with
the following value" kind of primitives.  Let's add them to byteorder.h.

Primitives:
	{be,le}{16,32,64}_replace_bits(old, v, bit, nbits)
	{be,le}{16,32,64}_get_bits(val, bit, nbits)

Essentially, it gives helpers for work with bitfields in fixed-endian.
Suppose we have e.g. a little-endian 32bit value with fixed layout;
expressing that as a bitfield would go like
	struct foo {
		unsigned foo:4;		/* bits 0..3 */
		unsigned :2;
		unsigned bar:12;	/* bits 6..17 */
		unsigned baz:14;	/* bits 18..31 */
	}
Even for host-endian it doesn't work all that well - you end up with
ifdefs in structure definition and generated code stinks.  For fixed-endian
it gets really painful, and people tend to use explicit shift-and-mask
kind of macros for accessing the fields (and often enough get the
endianness conversions wrong, at that).  With these primitives

struct foo v		<=>	__le32 v
v.foo = i ? 1 : 2	<=>	v = le32_replace_bits(v, i ? 1 : 2, 0, 4)
f(4 + v.baz)		<=>	f(4 + le32_get_bits(v, 18, 14))

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
index 451aaa0786ae..d8f169a7104a 100644
--- a/include/linux/byteorder/generic.h
+++ b/include/linux/byteorder/generic.h
@@ -187,4 +187,26 @@ static inline void be32_to_cpu_array(u32 *dst, const __be32 *src, size_t len)
 		dst[i] = be32_to_cpu(src[i]);
 }
 
+#define ____MASK(bit, nbits) ((((1ULL << ((nbits) - 1)) << 1) - 1) << (bit))
+#define ____MAKE_OP(type,base)						\
+static inline __##type type##_replace_bits(__##type old,		\
+					base val, int bit, int nbits)	\
+{									\
+	__##type mask = cpu_to_##type(____MASK(bit, nbits));		\
+	return (old & ~mask) | (cpu_to_##type(val << bit) & mask);	\
+}									\
+static inline base type##_get_bits(__##type val, int bit, int nbits)	\
+{									\
+	return (type##_to_cpu(val) >> bit) & ____MASK(0, nbits);	\
+}
+
+____MAKE_OP(le16,u16)
+____MAKE_OP(le32,u32)
+____MAKE_OP(le64,u64)
+____MAKE_OP(be16,u16)
+____MAKE_OP(be32,u32)
+____MAKE_OP(be64,u64)
+#undef ____MAKE_OP
+#undef ____MASK
+
 #endif /* _LINUX_BYTEORDER_GENERIC_H */

  parent reply	other threads:[~2017-12-11 15:54 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-10  4:53 [RFC][PATCH] apparent big-endian bugs in dwc-xlgmac Al Viro
2017-12-11  4:33 ` Jie Deng
2017-12-11  5:05   ` Al Viro
2017-12-11  5:38     ` Al Viro
2017-12-11  6:46       ` Jie Deng
2017-12-11 15:54       ` Al Viro [this message]
2017-12-12  4:02         ` [RFC][PATCH] new byteorder primitives - ..._{replace,get}_bits() Jakub Kicinski
2017-12-12  6:20           ` Al Viro
2017-12-12 19:45             ` Al Viro
2017-12-12 20:04               ` Jakub Kicinski
2017-12-12 23:48                 ` Al Viro
2017-12-12 23:59                   ` Jakub Kicinski
2017-12-13  0:36                     ` Al Viro
2017-12-13  1:04                       ` Jakub Kicinski
2017-12-13  1:30                         ` Al Viro
2017-12-13  1:35                           ` Jakub Kicinski
2017-12-13  1:51                             ` Al Viro
2017-12-13  2:44                               ` Jakub Kicinski
2017-12-13 14:22                                 ` Al Viro
2017-12-13 17:45                                   ` Al Viro
2017-12-15  2:33                                     ` [RFC][PATCH] Add primitives for manipulating bitfields both in host- and fixed-endian Al Viro
2017-12-15  5:07                                       ` Jakub Kicinski
2017-12-15  5:34                                         ` Al Viro
2017-12-15 16:48                                           ` [RFC][PATCH v2] " Al Viro
2017-12-13 19:04                                   ` [RFC][PATCH] new byteorder primitives - ..._{replace,get}_bits() Jakub Kicinski
2017-12-11  6:18     ` [RFC][PATCH] apparent big-endian bugs in dwc-xlgmac Jie Deng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171211155422.GA12326@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).