| .. | .. | 
|---|
 | 1 | +/* SPDX-License-Identifier: GPL-2.0-only */  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 | 3 |   * Copyright (C) 2014 Felix Fietkau <nbd@nbd.name> | 
|---|
| 3 | 4 |   * Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com> | 
|---|
| 4 |  | - *  | 
|---|
| 5 |  | - * This program is free software; you can redistribute it and/or modify  | 
|---|
| 6 |  | - * it under the terms of the GNU General Public License version 2  | 
|---|
| 7 |  | - * as published by the Free Software Foundation  | 
|---|
| 8 |  | - *  | 
|---|
| 9 |  | - * This program is distributed in the hope that it will be useful,  | 
|---|
| 10 |  | - * but WITHOUT ANY WARRANTY; without even the implied warranty of  | 
|---|
| 11 |  | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  | 
|---|
| 12 |  | - * GNU General Public License for more details.  | 
|---|
| 13 | 5 |   */ | 
|---|
| 14 | 6 |   | 
|---|
| 15 | 7 |  #ifndef _LINUX_BITFIELD_H | 
|---|
| .. | .. | 
|---|
| 49 | 41 |   | 
|---|
| 50 | 42 |  #define __bf_shf(x) (__builtin_ffsll(x) - 1) | 
|---|
| 51 | 43 |   | 
|---|
 | 44 | +#define __scalar_type_to_unsigned_cases(type)				\  | 
|---|
 | 45 | +		unsigned type:	(unsigned type)0,			\  | 
|---|
 | 46 | +		signed type:	(unsigned type)0  | 
|---|
 | 47 | +  | 
|---|
 | 48 | +#define __unsigned_scalar_typeof(x) typeof(				\  | 
|---|
 | 49 | +		_Generic((x),						\  | 
|---|
 | 50 | +			char:	(unsigned char)0,			\  | 
|---|
 | 51 | +			__scalar_type_to_unsigned_cases(char),		\  | 
|---|
 | 52 | +			__scalar_type_to_unsigned_cases(short),		\  | 
|---|
 | 53 | +			__scalar_type_to_unsigned_cases(int),		\  | 
|---|
 | 54 | +			__scalar_type_to_unsigned_cases(long),		\  | 
|---|
 | 55 | +			__scalar_type_to_unsigned_cases(long long),	\  | 
|---|
 | 56 | +			default: (x)))  | 
|---|
 | 57 | +  | 
|---|
 | 58 | +#define __bf_cast_unsigned(type, x)	((__unsigned_scalar_typeof(type))(x))  | 
|---|
 | 59 | +  | 
|---|
| 52 | 60 |  #define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx)			\ | 
|---|
| 53 | 61 |  	({								\ | 
|---|
| 54 | 62 |  		BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask),		\ | 
|---|
| .. | .. | 
|---|
| 57 | 65 |  		BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ?		\ | 
|---|
| 58 | 66 |  				 ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ | 
|---|
| 59 | 67 |  				 _pfx "value too large for the field"); \ | 
|---|
| 60 |  | -		BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull,		\  | 
|---|
 | 68 | +		BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) >	\  | 
|---|
 | 69 | +				 __bf_cast_unsigned(_reg, ~0ull),	\  | 
|---|
| 61 | 70 |  				 _pfx "type of reg too small for mask"); \ | 
|---|
| 62 | 71 |  		__BUILD_BUG_ON_NOT_POWER_OF_2((_mask) +			\ | 
|---|
| 63 | 72 |  					      (1ULL << __bf_shf(_mask))); \ | 
|---|
 | 73 | +	})  | 
|---|
 | 74 | +  | 
|---|
 | 75 | +/**  | 
|---|
 | 76 | + * FIELD_MAX() - produce the maximum value representable by a field  | 
|---|
 | 77 | + * @_mask: shifted mask defining the field's length and position  | 
|---|
 | 78 | + *  | 
|---|
 | 79 | + * FIELD_MAX() returns the maximum value that can be held in the field  | 
|---|
 | 80 | + * specified by @_mask.  | 
|---|
 | 81 | + */  | 
|---|
 | 82 | +#define FIELD_MAX(_mask)						\  | 
|---|
 | 83 | +	({								\  | 
|---|
 | 84 | +		__BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_MAX: ");	\  | 
|---|
 | 85 | +		(typeof(_mask))((_mask) >> __bf_shf(_mask));		\  | 
|---|
| 64 | 86 |  	}) | 
|---|
| 65 | 87 |   | 
|---|
| 66 | 88 |  /** | 
|---|
| .. | .. | 
|---|
| 118 | 140 |  { | 
|---|
| 119 | 141 |  	return field / field_multiplier(field); | 
|---|
| 120 | 142 |  } | 
|---|
 | 143 | +#define field_max(field)	((typeof(field))field_mask(field))  | 
|---|
| 121 | 144 |  #define ____MAKE_OP(type,base,to,from)					\ | 
|---|
| 122 | 145 |  static __always_inline __##type type##_encode_bits(base v, base field)	\ | 
|---|
| 123 | 146 |  {									\ | 
|---|