mac80211: backport new register bitfield macros
[openwrt/staging/chunkeey.git] / package / kernel / mac80211 / patches / 006-add-basic-register-field-manipulation-macros.patch
1 From: Jakub Kicinski <jakub.kicinski@netronome.com>
2 Date: Wed, 31 Aug 2016 12:46:44 +0100
3 Subject: [PATCH] add basic register-field manipulation macros
4
5 Common approach to accessing register fields is to define
6 structures or sets of macros containing mask and shift pair.
7 Operations on the register are then performed as follows:
8
9 field = (reg >> shift) & mask;
10
11 reg &= ~(mask << shift);
12 reg |= (field & mask) << shift;
13
14 Defining shift and mask separately is tedious. Ivo van Doorn
15 came up with an idea of computing them at compilation time
16 based on a single shifted mask (later refined by Felix) which
17 can be used like this:
18
19 #define REG_FIELD 0x000ff000
20
21 field = FIELD_GET(REG_FIELD, reg);
22
23 reg &= ~REG_FIELD;
24 reg |= FIELD_PREP(REG_FIELD, field);
25
26 FIELD_{GET,PREP} macros take care of finding out what the
27 appropriate shift is based on compilation time ffs operation.
28
29 GENMASK can be used to define registers (which is usually
30 less error-prone and easier to match with datasheets).
31
32 This approach is the most convenient I've seen so to limit code
33 multiplication let's move the macros to a global header file.
34 Attempts to use static inlines instead of macros failed due
35 to false positive triggering of BUILD_BUG_ON()s, especially with
36 GCC < 6.0.
37
38 Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
39 Reviewed-by: Dinan Gunawardena <dinan.gunawardena@netronome.com>
40 ---
41 create mode 100644 include/linux/bitfield.h
42
43 --- /dev/null
44 +++ b/include/linux/bitfield.h
45 @@ -0,0 +1,100 @@
46 +/*
47 + * Copyright (C) 2014 Felix Fietkau <nbd@nbd.name>
48 + * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
49 + *
50 + * This program is free software; you can redistribute it and/or modify
51 + * it under the terms of the GNU General Public License version 2
52 + * as published by the Free Software Foundation
53 + *
54 + * This program is distributed in the hope that it will be useful,
55 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
56 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57 + * GNU General Public License for more details.
58 + */
59 +
60 +#ifndef _LINUX_BITFIELD_H
61 +#define _LINUX_BITFIELD_H
62 +
63 +#include <linux/bug.h>
64 +
65 +#ifdef __CHECKER__
66 +#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
67 +#else
68 +#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) \
69 + BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
70 +#endif
71 +
72 +/*
73 + * Bitfield access macros
74 + *
75 + * FIELD_{GET,PREP} macros take as first parameter shifted mask
76 + * from which they extract the base mask and shift amount.
77 + * Mask must be a compilation time constant.
78 + *
79 + * Example:
80 + *
81 + * #define REG_FIELD_A GENMASK(6, 0)
82 + * #define REG_FIELD_B BIT(7)
83 + * #define REG_FIELD_C GENMASK(15, 8)
84 + * #define REG_FIELD_D GENMASK(31, 16)
85 + *
86 + * Get:
87 + * a = FIELD_GET(REG_FIELD_A, reg);
88 + * b = FIELD_GET(REG_FIELD_B, reg);
89 + *
90 + * Set:
91 + * reg = FIELD_PREP(REG_FIELD_A, 1) |
92 + * FIELD_PREP(REG_FIELD_B, 0) |
93 + * FIELD_PREP(REG_FIELD_C, c) |
94 + * FIELD_PREP(REG_FIELD_D, 0x40);
95 + *
96 + * Modify:
97 + * reg &= ~REG_FIELD_C;
98 + * reg |= FIELD_PREP(REG_FIELD_C, c);
99 + */
100 +
101 +#define __bf_shf(x) (__builtin_ffsll(x) - 1)
102 +
103 +#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
104 + ({ \
105 + BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
106 + _pfx "mask is not constant"); \
107 + BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \
108 + BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \
109 + ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
110 + _pfx "value too large for the field"); \
111 + BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \
112 + _pfx "type of reg too small for mask"); \
113 + __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
114 + (1ULL << __bf_shf(_mask))); \
115 + })
116 +
117 +/**
118 + * FIELD_PREP() - prepare a bitfield element
119 + * @_mask: shifted mask defining the field's length and position
120 + * @_val: value to put in the field
121 + *
122 + * FIELD_PREP() masks and shifts up the value. The result should
123 + * be combined with other fields of the bitfield using logical OR.
124 + */
125 +#define FIELD_PREP(_mask, _val) \
126 + ({ \
127 + __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \
128 + ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \
129 + })
130 +
131 +/**
132 + * FIELD_GET() - extract a bitfield element
133 + * @_mask: shifted mask defining the field's length and position
134 + * @_reg: 32bit value of entire bitfield
135 + *
136 + * FIELD_GET() extracts the field specified by @_mask from the
137 + * bitfield passed in as @_reg by masking and shifting it down.
138 + */
139 +#define FIELD_GET(_mask, _reg) \
140 + ({ \
141 + __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
142 + (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
143 + })
144 +
145 +#endif