@@ -702,6 +702,22 @@ func isFeatureBitSet(blocks [MAX_FEATURE_BLOCKS]ethtoolGetFeaturesBlock, index u
702702 return (blocks )[index / 32 ].active & (1 << (index % 32 )) != 0
703703}
704704
705+ type FeatureState struct {
706+ Available bool
707+ Requested bool
708+ Active bool
709+ NeverChanged bool
710+ }
711+
712+ func getFeatureStateBits (blocks [MAX_FEATURE_BLOCKS ]ethtoolGetFeaturesBlock , index uint ) FeatureState {
713+ return FeatureState {
714+ Available : (blocks )[index / 32 ].available & (1 << (index % 32 )) != 0 ,
715+ Requested : (blocks )[index / 32 ].requested & (1 << (index % 32 )) != 0 ,
716+ Active : (blocks )[index / 32 ].active & (1 << (index % 32 )) != 0 ,
717+ NeverChanged : (blocks )[index / 32 ].never_changed & (1 << (index % 32 )) != 0 ,
718+ }
719+ }
720+
705721func setFeatureBit (blocks * [MAX_FEATURE_BLOCKS ]ethtoolSetFeaturesBlock , index uint , value bool ) {
706722 blockIndex , bitIndex := index / 32 , index % 32
707723
@@ -790,6 +806,36 @@ func (e *Ethtool) Features(intf string) (map[string]bool, error) {
790806 return result , nil
791807}
792808
809+ // FeaturesWithState retrieves features of the given interface name,
810+ // with extra flags to explain if they can be enabled
811+ func (e * Ethtool ) FeaturesWithState (intf string ) (map [string ]FeatureState , error ) {
812+ names , err := e .FeatureNames (intf )
813+ if err != nil {
814+ return nil , err
815+ }
816+
817+ length := uint32 (len (names ))
818+ if length == 0 {
819+ return map [string ]FeatureState {}, nil
820+ }
821+
822+ features := ethtoolGfeatures {
823+ cmd : ETHTOOL_GFEATURES ,
824+ size : (length + 32 - 1 ) / 32 ,
825+ }
826+
827+ if err := e .ioctl (intf , uintptr (unsafe .Pointer (& features ))); err != nil {
828+ return nil , err
829+ }
830+
831+ var result = make (map [string ]FeatureState , length )
832+ for key , index := range names {
833+ result [key ] = getFeatureStateBits (features .blocks , index )
834+ }
835+
836+ return result , nil
837+ }
838+
793839// Change requests a change in the given device's features.
794840func (e * Ethtool ) Change (intf string , config map [string ]bool ) error {
795841 names , err := e .FeatureNames (intf )
0 commit comments