|
11 | 11 | #define _LINUX_NETDEV_FEATURES_H
|
12 | 12 |
|
13 | 13 | #include <linux/types.h>
|
| 14 | +#include <asm/byteorder.h> |
14 | 15 |
|
15 | 16 | typedef u64 netdev_features_t;
|
16 | 17 |
|
@@ -154,8 +155,26 @@ enum {
|
154 | 155 | #define NETIF_F_HW_TLS_TX __NETIF_F(HW_TLS_TX)
|
155 | 156 | #define NETIF_F_HW_TLS_RX __NETIF_F(HW_TLS_RX)
|
156 | 157 |
|
157 |
| -#define for_each_netdev_feature(mask_addr, bit) \ |
158 |
| - for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT) |
| 158 | +/* Finds the next feature with the highest number of the range of start till 0. |
| 159 | + */ |
| 160 | +static inline int find_next_netdev_feature(u64 feature, unsigned long start) |
| 161 | +{ |
| 162 | + /* like BITMAP_LAST_WORD_MASK() for u64 |
| 163 | + * this sets the most significant 64 - start to 0. |
| 164 | + */ |
| 165 | + feature &= ~0ULL >> (-start & ((sizeof(feature) * 8) - 1)); |
| 166 | + |
| 167 | + return fls64(feature) - 1; |
| 168 | +} |
| 169 | + |
| 170 | +/* This goes for the MSB to the LSB through the set feature bits, |
| 171 | + * mask_addr should be a u64 and bit an int |
| 172 | + */ |
| 173 | +#define for_each_netdev_feature(mask_addr, bit) \ |
| 174 | + for ((bit) = find_next_netdev_feature((mask_addr), \ |
| 175 | + NETDEV_FEATURE_COUNT); \ |
| 176 | + (bit) >= 0; \ |
| 177 | + (bit) = find_next_netdev_feature((mask_addr), (bit) - 1)) |
159 | 178 |
|
160 | 179 | /* Features valid for ethtool to change */
|
161 | 180 | /* = all defined minus driver/device-class-related */
|
|
0 commit comments