forked from mirrors/linux
		
	ethtool: Add forced speed to supported link modes maps
The need to map Ethtool forced speeds to Ethtool supported link modes is
common among drivers. To support this, add a common structure for forced
speed maps and a function to init them.  This is solution was originally
introduced in commit 1d4e4ecccb ("qede: populate supported link modes
maps on module init") for qede driver.
ethtool_forced_speed_maps_init() should be called during driver init
with an array of struct ethtool_forced_speed_map to populate the mapping.
Definitions for maps themselves are left in the driver code, as the sets
of supported link modes may vary between the devices.
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Pawel Chmielewski <pawel.chmielewski@intel.com>
Signed-off-by: Paul Greenwalt <paul.greenwalt@intel.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									a0a8602247
								
							
						
					
					
						commit
						26c5334d34
					
				
					 2 changed files with 52 additions and 14 deletions
				
			
		|  | @ -13,6 +13,7 @@ | |||
| #ifndef _LINUX_ETHTOOL_H | ||||
| #define _LINUX_ETHTOOL_H | ||||
| 
 | ||||
| #include <linux/linkmode.h> | ||||
| #include <linux/bitmap.h> | ||||
| #include <linux/compat.h> | ||||
| #include <linux/if_ether.h> | ||||
|  | @ -1052,4 +1053,40 @@ static inline int ethtool_mm_frag_size_min_to_add(u32 val_min, u32 *val_add, | |||
|  * next string. | ||||
|  */ | ||||
| extern __printf(2, 3) void ethtool_sprintf(u8 **data, const char *fmt, ...); | ||||
| 
 | ||||
| /* Link mode to forced speed capabilities maps */ | ||||
| struct ethtool_forced_speed_map { | ||||
| 	u32		speed; | ||||
| 	__ETHTOOL_DECLARE_LINK_MODE_MASK(caps); | ||||
| 
 | ||||
| 	const u32	*cap_arr; | ||||
| 	u32		arr_size; | ||||
| }; | ||||
| 
 | ||||
| #define ETHTOOL_FORCED_SPEED_MAP(prefix, value)				\ | ||||
| {									\ | ||||
| 	.speed		= SPEED_##value,				\ | ||||
| 	.cap_arr	= prefix##_##value,				\ | ||||
| 	.arr_size	= ARRAY_SIZE(prefix##_##value),			\ | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * ethtool_forced_speed_maps_init | ||||
|  * @maps: Pointer to an array of Ethtool forced speed map | ||||
|  * @size: Array size | ||||
|  * | ||||
|  * Initialize an array of Ethtool forced speed map to Ethtool link modes. This | ||||
|  * should be called during driver module init. | ||||
|  */ | ||||
| static inline void | ||||
| ethtool_forced_speed_maps_init(struct ethtool_forced_speed_map *maps, u32 size) | ||||
| { | ||||
| 	for (u32 i = 0; i < size; i++) { | ||||
| 		struct ethtool_forced_speed_map *map = &maps[i]; | ||||
| 
 | ||||
| 		linkmode_set_bit_array(map->cap_arr, map->arr_size, map->caps); | ||||
| 		map->cap_arr = NULL; | ||||
| 		map->arr_size = 0; | ||||
| 	} | ||||
| } | ||||
| #endif /* _LINUX_ETHTOOL_H */ | ||||
|  |  | |||
|  | @ -2,6 +2,21 @@ | |||
| #define __LINKMODE_H | ||||
| 
 | ||||
| #include <linux/bitmap.h> | ||||
| 
 | ||||
| static inline void linkmode_set_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	__set_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline void linkmode_set_bit_array(const int *array, int array_size, | ||||
| 					  unsigned long *addr) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < array_size; i++) | ||||
| 		linkmode_set_bit(array[i], addr); | ||||
| } | ||||
| 
 | ||||
| #include <linux/ethtool.h> | ||||
| #include <uapi/linux/ethtool.h> | ||||
| 
 | ||||
|  | @ -38,20 +53,6 @@ static inline int linkmode_andnot(unsigned long *dst, const unsigned long *src1, | |||
| 	return bitmap_andnot(dst, src1, src2,  __ETHTOOL_LINK_MODE_MASK_NBITS); | ||||
| } | ||||
| 
 | ||||
| static inline void linkmode_set_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	__set_bit(nr, addr); | ||||
| } | ||||
| 
 | ||||
| static inline void linkmode_set_bit_array(const int *array, int array_size, | ||||
| 					  unsigned long *addr) | ||||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < array_size; i++) | ||||
| 		linkmode_set_bit(array[i], addr); | ||||
| } | ||||
| 
 | ||||
| static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr) | ||||
| { | ||||
| 	__clear_bit(nr, addr); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Paul Greenwalt
						Paul Greenwalt