|
|
1.1 root 1: #ifndef _MLX_BITOPS_H
2: #define _MLX_BITOPS_H
3:
4: /*
5: * Copyright (C) 2007 Michael Brown <[email protected]>.
6: *
7: * This program is free software; you can redistribute it and/or
8: * modify it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation; either version 2 of the
10: * License, or any later version.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: * General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public License
18: * along with this program; if not, write to the Free Software
19: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20: */
21:
22: FILE_LICENCE ( GPL2_OR_LATER );
23:
24: /**
25: * @file
26: *
27: * Mellanox bit operations
28: *
29: */
30:
31: /* Datatype used to represent a bit in the Mellanox autogenerated headers */
32: typedef unsigned char pseudo_bit_t;
33:
34: /**
35: * Wrapper structure for pseudo_bit_t structures
36: *
37: * This structure provides a wrapper around the autogenerated
38: * pseudo_bit_t structures. It has the correct size, and also
39: * encapsulates type information about the underlying pseudo_bit_t
40: * structure, which allows the MLX_FILL etc. macros to work without
41: * requiring explicit type information.
42: */
43: #define MLX_DECLARE_STRUCT( _structure ) \
44: _structure { \
45: union { \
46: uint8_t bytes[ sizeof ( struct _structure ## _st ) / 8 ]; \
47: uint32_t dwords[ sizeof ( struct _structure ## _st ) / 32 ]; \
48: struct _structure ## _st *dummy[0]; \
49: } __attribute__ (( packed )) u; \
50: } __attribute__ (( packed ))
51:
52: /** Get pseudo_bit_t structure type from wrapper structure pointer */
53: #define MLX_PSEUDO_STRUCT( _ptr ) \
54: typeof ( *((_ptr)->u.dummy[0]) )
55:
56: /** Bit offset of a field within a pseudo_bit_t structure */
57: #define MLX_BIT_OFFSET( _structure_st, _field ) \
58: offsetof ( _structure_st, _field )
59:
60: /** Dword offset of a field within a pseudo_bit_t structure */
61: #define MLX_DWORD_OFFSET( _structure_st, _field ) \
62: ( MLX_BIT_OFFSET ( _structure_st, _field ) / 32 )
63:
64: /** Dword bit offset of a field within a pseudo_bit_t structure
65: *
66: * Yes, using mod-32 would work, but would lose the check for the
67: * error of specifying a mismatched field name and dword index.
68: */
69: #define MLX_DWORD_BIT_OFFSET( _structure_st, _index, _field ) \
70: ( MLX_BIT_OFFSET ( _structure_st, _field ) - ( 32 * (_index) ) )
71:
72: /** Bit width of a field within a pseudo_bit_t structure */
73: #define MLX_BIT_WIDTH( _structure_st, _field ) \
74: sizeof ( ( ( _structure_st * ) NULL )->_field )
75:
76: /** Bit mask for a field within a pseudo_bit_t structure */
77: #define MLX_BIT_MASK( _structure_st, _field ) \
78: ( ( ~( ( uint32_t ) 0 ) ) >> \
79: ( 32 - MLX_BIT_WIDTH ( _structure_st, _field ) ) )
80:
81: /*
82: * Assemble native-endian dword from named fields and values
83: *
84: */
85:
86: #define MLX_ASSEMBLE_1( _structure_st, _index, _field, _value ) \
87: ( (_value) << MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) )
88:
89: #define MLX_ASSEMBLE_2( _structure_st, _index, _field, _value, ... ) \
90: ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) | \
91: MLX_ASSEMBLE_1 ( _structure_st, _index, __VA_ARGS__ ) )
92:
93: #define MLX_ASSEMBLE_3( _structure_st, _index, _field, _value, ... ) \
94: ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) | \
95: MLX_ASSEMBLE_2 ( _structure_st, _index, __VA_ARGS__ ) )
96:
97: #define MLX_ASSEMBLE_4( _structure_st, _index, _field, _value, ... ) \
98: ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) | \
99: MLX_ASSEMBLE_3 ( _structure_st, _index, __VA_ARGS__ ) )
100:
101: #define MLX_ASSEMBLE_5( _structure_st, _index, _field, _value, ... ) \
102: ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) | \
103: MLX_ASSEMBLE_4 ( _structure_st, _index, __VA_ARGS__ ) )
104:
105: #define MLX_ASSEMBLE_6( _structure_st, _index, _field, _value, ... ) \
106: ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) | \
107: MLX_ASSEMBLE_5 ( _structure_st, _index, __VA_ARGS__ ) )
108:
109: #define MLX_ASSEMBLE_7( _structure_st, _index, _field, _value, ... ) \
110: ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) | \
111: MLX_ASSEMBLE_6 ( _structure_st, _index, __VA_ARGS__ ) )
112:
113: #define MLX_ASSEMBLE_8( _structure_st, _index, _field, _value, ... ) \
114: ( MLX_ASSEMBLE_1 ( _structure_st, _index, _field, _value ) | \
115: MLX_ASSEMBLE_7 ( _structure_st, _index, __VA_ARGS__ ) )
116:
117: /*
118: * Build native-endian (positive) dword bitmasks from named fields
119: *
120: */
121:
122: #define MLX_MASK_1( _structure_st, _index, _field ) \
123: ( MLX_BIT_MASK ( _structure_st, _field ) << \
124: MLX_DWORD_BIT_OFFSET ( _structure_st, _index, _field ) )
125:
126: #define MLX_MASK_2( _structure_st, _index, _field, ... ) \
127: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \
128: MLX_MASK_1 ( _structure_st, _index, __VA_ARGS__ ) )
129:
130: #define MLX_MASK_3( _structure_st, _index, _field, ... ) \
131: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \
132: MLX_MASK_2 ( _structure_st, _index, __VA_ARGS__ ) )
133:
134: #define MLX_MASK_4( _structure_st, _index, _field, ... ) \
135: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \
136: MLX_MASK_3 ( _structure_st, _index, __VA_ARGS__ ) )
137:
138: #define MLX_MASK_5( _structure_st, _index, _field, ... ) \
139: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \
140: MLX_MASK_4 ( _structure_st, _index, __VA_ARGS__ ) )
141:
142: #define MLX_MASK_6( _structure_st, _index, _field, ... ) \
143: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \
144: MLX_MASK_5 ( _structure_st, _index, __VA_ARGS__ ) )
145:
146: #define MLX_MASK_7( _structure_st, _index, _field, ... ) \
147: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \
148: MLX_MASK_6 ( _structure_st, _index, __VA_ARGS__ ) )
149:
150: #define MLX_MASK_8( _structure_st, _index, _field, ... ) \
151: ( MLX_MASK_1 ( _structure_st, _index, _field ) | \
152: MLX_MASK_7 ( _structure_st, _index, __VA_ARGS__ ) )
153:
154: /*
155: * Populate big-endian dwords from named fields and values
156: *
157: */
158:
159: #define MLX_FILL( _ptr, _index, _assembled ) \
160: do { \
161: uint32_t *__ptr = &(_ptr)->u.dwords[(_index)]; \
162: uint32_t __assembled = (_assembled); \
163: *__ptr = cpu_to_be32 ( __assembled ); \
164: } while ( 0 )
165:
166: #define MLX_FILL_1( _ptr, _index, ... ) \
167: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ),\
168: _index, __VA_ARGS__ ) )
169:
170: #define MLX_FILL_2( _ptr, _index, ... ) \
171: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_2 ( MLX_PSEUDO_STRUCT ( _ptr ),\
172: _index, __VA_ARGS__ ) )
173:
174: #define MLX_FILL_3( _ptr, _index, ... ) \
175: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_3 ( MLX_PSEUDO_STRUCT ( _ptr ),\
176: _index, __VA_ARGS__ ) )
177:
178: #define MLX_FILL_4( _ptr, _index, ... ) \
179: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_4 ( MLX_PSEUDO_STRUCT ( _ptr ),\
180: _index, __VA_ARGS__ ) )
181:
182: #define MLX_FILL_5( _ptr, _index, ... ) \
183: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_5 ( MLX_PSEUDO_STRUCT ( _ptr ),\
184: _index, __VA_ARGS__ ) )
185:
186: #define MLX_FILL_6( _ptr, _index, ... ) \
187: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_6 ( MLX_PSEUDO_STRUCT ( _ptr ),\
188: _index, __VA_ARGS__ ) )
189:
190: #define MLX_FILL_7( _ptr, _index, ... ) \
191: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_7 ( MLX_PSEUDO_STRUCT ( _ptr ),\
192: _index, __VA_ARGS__ ) )
193:
194: #define MLX_FILL_8( _ptr, _index, ... ) \
195: MLX_FILL ( _ptr, _index, MLX_ASSEMBLE_8 ( MLX_PSEUDO_STRUCT ( _ptr ),\
196: _index, __VA_ARGS__ ) )
197:
198: /*
199: * Modify big-endian dword using named field and value
200: *
201: */
202:
203: #define MLX_SET( _ptr, _field, _value ) \
204: do { \
205: unsigned int __index = \
206: MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
207: uint32_t *__ptr = &(_ptr)->u.dwords[__index]; \
208: uint32_t __value = be32_to_cpu ( *__ptr ); \
209: __value &= ~( MLX_MASK_1 ( MLX_PSEUDO_STRUCT ( _ptr ), \
210: __index, _field ) ); \
211: __value |= MLX_ASSEMBLE_1 ( MLX_PSEUDO_STRUCT ( _ptr ), \
212: __index, _field, _value ); \
213: *__ptr = cpu_to_be32 ( __value ); \
214: } while ( 0 )
215:
216: /*
217: * Extract value of named field
218: *
219: */
220:
221: #define MLX_GET( _ptr, _field ) \
222: ( { \
223: unsigned int __index = \
224: MLX_DWORD_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
225: uint32_t *__ptr = &(_ptr)->u.dwords[__index]; \
226: uint32_t __value = be32_to_cpu ( *__ptr ); \
227: __value >>= \
228: MLX_DWORD_BIT_OFFSET ( MLX_PSEUDO_STRUCT ( _ptr ), \
229: __index, _field ); \
230: __value &= \
231: MLX_BIT_MASK ( MLX_PSEUDO_STRUCT ( _ptr ), _field ); \
232: __value; \
233: } )
234:
235: /*
236: * Fill high dword of physical address, if necessary
237: *
238: */
239: #define MLX_FILL_H( _structure_st, _index, _field, _address ) do { \
240: if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) { \
241: MLX_FILL_1 ( _structure_st, _index, _field, \
242: ( ( ( uint64_t ) (_address) ) >> 32 ) ); \
243: } } while ( 0 )
244:
245: #endif /* _MLX_BITOPS_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.