diff options
author | Michał Mirosław <mirq-linux@rere.qmqm.pl> | 2011-02-15 11:59:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-17 17:16:33 -0500 |
commit | 5455c6998d34dc983a8693500e4dffefc3682dc5 (patch) | |
tree | b765aecf6d33d8c550cde78368ccc8654951ec07 /include | |
parent | 0a417704777ed29d0e8c72b7274a328e61248e75 (diff) |
net: Introduce new feature setting ops
This introduces a new framework to handle device features setting.
It consists of:
- new fields in struct net_device:
+ hw_features - features that hw/driver supports toggling
+ wanted_features - features that user wants enabled, when possible
- new netdev_ops:
+ feat = ndo_fix_features(dev, feat) - API checking constraints for
enabling features or their combinations
+ ndo_set_features(dev) - API updating hardware state to match
changed dev->features
- new ethtool commands:
+ ETHTOOL_GFEATURES/ETHTOOL_SFEATURES: get/set dev->wanted_features
and trigger device reconfiguration if resulting dev->features
changed
+ ETHTOOL_GSTRINGS(ETH_SS_FEATURES): get feature bits names (meaning)
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/ethtool.h | 85 | ||||
-rw-r--r-- | include/linux/netdevice.h | 37 |
2 files changed, 120 insertions, 2 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 1908929204a9..806e716bb4fb 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -251,6 +251,7 @@ enum ethtool_stringset { | |||
251 | ETH_SS_STATS, | 251 | ETH_SS_STATS, |
252 | ETH_SS_PRIV_FLAGS, | 252 | ETH_SS_PRIV_FLAGS, |
253 | ETH_SS_NTUPLE_FILTERS, | 253 | ETH_SS_NTUPLE_FILTERS, |
254 | ETH_SS_FEATURES, | ||
254 | }; | 255 | }; |
255 | 256 | ||
256 | /* for passing string sets for data tagging */ | 257 | /* for passing string sets for data tagging */ |
@@ -523,6 +524,87 @@ struct ethtool_flash { | |||
523 | char data[ETHTOOL_FLASH_MAX_FILENAME]; | 524 | char data[ETHTOOL_FLASH_MAX_FILENAME]; |
524 | }; | 525 | }; |
525 | 526 | ||
527 | /* for returning and changing feature sets */ | ||
528 | |||
529 | /** | ||
530 | * struct ethtool_get_features_block - block with state of 32 features | ||
531 | * @available: mask of changeable features | ||
532 | * @requested: mask of features requested to be enabled if possible | ||
533 | * @active: mask of currently enabled features | ||
534 | * @never_changed: mask of features not changeable for any device | ||
535 | */ | ||
536 | struct ethtool_get_features_block { | ||
537 | __u32 available; | ||
538 | __u32 requested; | ||
539 | __u32 active; | ||
540 | __u32 never_changed; | ||
541 | }; | ||
542 | |||
543 | /** | ||
544 | * struct ethtool_gfeatures - command to get state of device's features | ||
545 | * @cmd: command number = %ETHTOOL_GFEATURES | ||
546 | * @size: in: number of elements in the features[] array; | ||
547 | * out: number of elements in features[] needed to hold all features | ||
548 | * @features: state of features | ||
549 | */ | ||
550 | struct ethtool_gfeatures { | ||
551 | __u32 cmd; | ||
552 | __u32 size; | ||
553 | struct ethtool_get_features_block features[0]; | ||
554 | }; | ||
555 | |||
556 | /** | ||
557 | * struct ethtool_set_features_block - block with request for 32 features | ||
558 | * @valid: mask of features to be changed | ||
559 | * @requested: values of features to be changed | ||
560 | */ | ||
561 | struct ethtool_set_features_block { | ||
562 | __u32 valid; | ||
563 | __u32 requested; | ||
564 | }; | ||
565 | |||
566 | /** | ||
567 | * struct ethtool_sfeatures - command to request change in device's features | ||
568 | * @cmd: command number = %ETHTOOL_SFEATURES | ||
569 | * @size: array size of the features[] array | ||
570 | * @features: feature change masks | ||
571 | */ | ||
572 | struct ethtool_sfeatures { | ||
573 | __u32 cmd; | ||
574 | __u32 size; | ||
575 | struct ethtool_set_features_block features[0]; | ||
576 | }; | ||
577 | |||
578 | /* | ||
579 | * %ETHTOOL_SFEATURES changes features present in features[].valid to the | ||
580 | * values of corresponding bits in features[].requested. Bits in .requested | ||
581 | * not set in .valid or not changeable are ignored. | ||
582 | * | ||
583 | * Returns %EINVAL when .valid contains undefined or never-changable bits | ||
584 | * or size is not equal to required number of features words (32-bit blocks). | ||
585 | * Returns >= 0 if request was completed; bits set in the value mean: | ||
586 | * %ETHTOOL_F_UNSUPPORTED - there were bits set in .valid that are not | ||
587 | * changeable (not present in %ETHTOOL_GFEATURES' features[].available) | ||
588 | * those bits were ignored. | ||
589 | * %ETHTOOL_F_WISH - some or all changes requested were recorded but the | ||
590 | * resulting state of bits masked by .valid is not equal to .requested. | ||
591 | * Probably there are other device-specific constraints on some features | ||
592 | * in the set. When %ETHTOOL_F_UNSUPPORTED is set, .valid is considered | ||
593 | * here as though ignored bits were cleared. | ||
594 | * | ||
595 | * Meaning of bits in the masks are obtained by %ETHTOOL_GSSET_INFO (number of | ||
596 | * bits in the arrays - always multiple of 32) and %ETHTOOL_GSTRINGS commands | ||
597 | * for ETH_SS_FEATURES string set. First entry in the table corresponds to least | ||
598 | * significant bit in features[0] fields. Empty strings mark undefined features. | ||
599 | */ | ||
600 | enum ethtool_sfeatures_retval_bits { | ||
601 | ETHTOOL_F_UNSUPPORTED__BIT, | ||
602 | ETHTOOL_F_WISH__BIT, | ||
603 | }; | ||
604 | |||
605 | #define ETHTOOL_F_UNSUPPORTED (1 << ETHTOOL_F_UNSUPPORTED__BIT) | ||
606 | #define ETHTOOL_F_WISH (1 << ETHTOOL_F_WISH__BIT) | ||
607 | |||
526 | #ifdef __KERNEL__ | 608 | #ifdef __KERNEL__ |
527 | 609 | ||
528 | #include <linux/rculist.h> | 610 | #include <linux/rculist.h> |
@@ -744,6 +826,9 @@ struct ethtool_ops { | |||
744 | #define ETHTOOL_GRXFHINDIR 0x00000038 /* Get RX flow hash indir'n table */ | 826 | #define ETHTOOL_GRXFHINDIR 0x00000038 /* Get RX flow hash indir'n table */ |
745 | #define ETHTOOL_SRXFHINDIR 0x00000039 /* Set RX flow hash indir'n table */ | 827 | #define ETHTOOL_SRXFHINDIR 0x00000039 /* Set RX flow hash indir'n table */ |
746 | 828 | ||
829 | #define ETHTOOL_GFEATURES 0x0000003a /* Get device offload settings */ | ||
830 | #define ETHTOOL_SFEATURES 0x0000003b /* Change device offload settings */ | ||
831 | |||
747 | /* compatibility with older code */ | 832 | /* compatibility with older code */ |
748 | #define SPARC_ETH_GSET ETHTOOL_GSET | 833 | #define SPARC_ETH_GSET ETHTOOL_GSET |
749 | #define SPARC_ETH_SSET ETHTOOL_SSET | 834 | #define SPARC_ETH_SSET ETHTOOL_SSET |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index dede3fdbb4be..85f67e225f60 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -791,6 +791,18 @@ struct netdev_tc_txq { | |||
791 | * | 791 | * |
792 | * int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev); | 792 | * int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev); |
793 | * Called to release previously enslaved netdev. | 793 | * Called to release previously enslaved netdev. |
794 | * | ||
795 | * Feature/offload setting functions. | ||
796 | * u32 (*ndo_fix_features)(struct net_device *dev, u32 features); | ||
797 | * Adjusts the requested feature flags according to device-specific | ||
798 | * constraints, and returns the resulting flags. Must not modify | ||
799 | * the device state. | ||
800 | * | ||
801 | * int (*ndo_set_features)(struct net_device *dev, u32 features); | ||
802 | * Called to update device configuration to new features. Passed | ||
803 | * feature set might be less than what was returned by ndo_fix_features()). | ||
804 | * Must return >0 or -errno if it changed dev->features itself. | ||
805 | * | ||
794 | */ | 806 | */ |
795 | #define HAVE_NET_DEVICE_OPS | 807 | #define HAVE_NET_DEVICE_OPS |
796 | struct net_device_ops { | 808 | struct net_device_ops { |
@@ -874,6 +886,10 @@ struct net_device_ops { | |||
874 | struct net_device *slave_dev); | 886 | struct net_device *slave_dev); |
875 | int (*ndo_del_slave)(struct net_device *dev, | 887 | int (*ndo_del_slave)(struct net_device *dev, |
876 | struct net_device *slave_dev); | 888 | struct net_device *slave_dev); |
889 | u32 (*ndo_fix_features)(struct net_device *dev, | ||
890 | u32 features); | ||
891 | int (*ndo_set_features)(struct net_device *dev, | ||
892 | u32 features); | ||
877 | }; | 893 | }; |
878 | 894 | ||
879 | /* | 895 | /* |
@@ -925,12 +941,18 @@ struct net_device { | |||
925 | struct list_head napi_list; | 941 | struct list_head napi_list; |
926 | struct list_head unreg_list; | 942 | struct list_head unreg_list; |
927 | 943 | ||
928 | /* Net device features */ | 944 | /* currently active device features */ |
929 | u32 features; | 945 | u32 features; |
930 | 946 | /* user-changeable features */ | |
947 | u32 hw_features; | ||
948 | /* user-requested features */ | ||
949 | u32 wanted_features; | ||
931 | /* VLAN feature mask */ | 950 | /* VLAN feature mask */ |
932 | u32 vlan_features; | 951 | u32 vlan_features; |
933 | 952 | ||
953 | /* Net device feature bits; if you change something, | ||
954 | * also update netdev_features_strings[] in ethtool.c */ | ||
955 | |||
934 | #define NETIF_F_SG 1 /* Scatter/gather IO. */ | 956 | #define NETIF_F_SG 1 /* Scatter/gather IO. */ |
935 | #define NETIF_F_IP_CSUM 2 /* Can checksum TCP/UDP over IPv4. */ | 957 | #define NETIF_F_IP_CSUM 2 /* Can checksum TCP/UDP over IPv4. */ |
936 | #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ | 958 | #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ |
@@ -966,6 +988,12 @@ struct net_device { | |||
966 | #define NETIF_F_TSO6 (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT) | 988 | #define NETIF_F_TSO6 (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT) |
967 | #define NETIF_F_FSO (SKB_GSO_FCOE << NETIF_F_GSO_SHIFT) | 989 | #define NETIF_F_FSO (SKB_GSO_FCOE << NETIF_F_GSO_SHIFT) |
968 | 990 | ||
991 | /* Features valid for ethtool to change */ | ||
992 | /* = all defined minus driver/device-class-related */ | ||
993 | #define NETIF_F_NEVER_CHANGE (NETIF_F_HIGHDMA | NETIF_F_VLAN_CHALLENGED | \ | ||
994 | NETIF_F_LLTX | NETIF_F_NETNS_LOCAL) | ||
995 | #define NETIF_F_ETHTOOL_BITS (0x1f3fffff & ~NETIF_F_NEVER_CHANGE) | ||
996 | |||
969 | /* List of features with software fallbacks. */ | 997 | /* List of features with software fallbacks. */ |
970 | #define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \ | 998 | #define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | \ |
971 | NETIF_F_TSO6 | NETIF_F_UFO) | 999 | NETIF_F_TSO6 | NETIF_F_UFO) |
@@ -2428,8 +2456,13 @@ extern char *netdev_drivername(const struct net_device *dev, char *buffer, int l | |||
2428 | 2456 | ||
2429 | extern void linkwatch_run_queue(void); | 2457 | extern void linkwatch_run_queue(void); |
2430 | 2458 | ||
2459 | static inline u32 netdev_get_wanted_features(struct net_device *dev) | ||
2460 | { | ||
2461 | return (dev->features & ~dev->hw_features) | dev->wanted_features; | ||
2462 | } | ||
2431 | u32 netdev_increment_features(u32 all, u32 one, u32 mask); | 2463 | u32 netdev_increment_features(u32 all, u32 one, u32 mask); |
2432 | u32 netdev_fix_features(struct net_device *dev, u32 features); | 2464 | u32 netdev_fix_features(struct net_device *dev, u32 features); |
2465 | void netdev_update_features(struct net_device *dev); | ||
2433 | 2466 | ||
2434 | void netif_stacked_transfer_operstate(const struct net_device *rootdev, | 2467 | void netif_stacked_transfer_operstate(const struct net_device *rootdev, |
2435 | struct net_device *dev); | 2468 | struct net_device *dev); |