History

net: ethtool: Add support for tsconfig command to get/set hwtstamp config

Introduce support for ETHTOOL_MSG_TSCONFIG_GET/SET ethtool netlink socket to read and configure hwtstamp configuration of a PHC provider. Note that simultaneous hwtstamp isn't supported; configuring a new one disables the previous setting.

Kory Maincent committed 1 year ago

Commit 6e9e2ee1 parent b9e3f7d10 files · +655 −26Browse files

Unified · Split

10 files
  1. Documentation/netlink/specs/ethtool.yaml +56 −0
  2. Documentation/networking/ethtool-netlink.rst +75 −0
  3. Documentation/networking/timestamping.rst +24 −14
  4. include/uapi/linux/ethtool_netlink_generated.h +16 −0
  5. net/ethtool/Makefile +1 −1
  6. net/ethtool/common.c +17 −10
  7. net/ethtool/common.h +1 −1
  8. net/ethtool/netlink.c +18 −0
  9. net/ethtool/netlink.h +3 −0
  10. net/ethtool/tsconfig.c +444 −0
Documentation/netlink/specs/ethtool.yaml+56−0
@@ -1489,6 +1489,33 @@ attribute-sets: · 1488 unmodified lines
1489 -1489 -
1490 name: downstream-sfp-name1490 name: downstream-sfp-name
1491 type: string1491 type: string
1492 -
1493 name: tsconfig
1494 attr-cnt-name: __ethtool-a-tsconfig-cnt
1495 attributes:
1496 -
1497 name: unspec
1498 type: unused
1499 value: 0
1500 -
1501 name: header
1502 type: nest
1503 nested-attributes: header
1504 -
1505 name: hwtstamp-provider
1506 type: nest
1507 nested-attributes: ts-hwtstamp-provider
1508 -
1509 name: tx-types
1510 type: nest
1511 nested-attributes: bitset
1512 -
1513 name: rx-filters
1514 type: nest
1515 nested-attributes: bitset
1516 -
1517 name: hwtstamp-flags
1518 type: u32
1492 1519
1493operations:1520operations:
1494 enum-model: directional1521 enum-model: directional
@@ -2314,3 +2341,32 @@ operations: · 819 unmodified lines
2314 name: phy-ntf2341 name: phy-ntf
2315 doc: Notification for change in PHY devices.2342 doc: Notification for change in PHY devices.
2316 notify: phy-get2343 notify: phy-get
2344 -
2345 name: tsconfig-get
2346 doc: Get hwtstamp config.
2347
2348 attribute-set: tsconfig
2349
2350 do: &tsconfig-get-op
2351 request:
2352 attributes:
2353 - header
2354 reply:
2355 attributes: &tsconfig
2356 - header
2357 - hwtstamp-provider
2358 - tx-types
2359 - rx-filters
2360 - hwtstamp-flags
2361 dump: *tsconfig-get-op
2362 -
2363 name: tsconfig-set
2364 doc: Set hwtstamp config.
2365
2366 attribute-set: tsconfig
2367
2368 do:
2369 request:
2370 attributes: *tsconfig
2371 reply:
2372 attributes: *tsconfig
Documentation/networking/ethtool-netlink.rst+75−0
@@ -237,6 +237,8 @@ Userspace to kernel: · 236 unmodified lines
237 ``ETHTOOL_MSG_MM_SET`` set MAC merge layer parameters237 ``ETHTOOL_MSG_MM_SET`` set MAC merge layer parameters
238 ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT`` flash transceiver module firmware238 ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT`` flash transceiver module firmware
239 ``ETHTOOL_MSG_PHY_GET`` get Ethernet PHY information239 ``ETHTOOL_MSG_PHY_GET`` get Ethernet PHY information
240 ``ETHTOOL_MSG_TSCONFIG_GET`` get hw timestamping configuration
241 ``ETHTOOL_MSG_TSCONFIG_SET`` set hw timestamping configuration
240 ===================================== =================================242 ===================================== =================================
241 243
242Kernel to userspace:244Kernel to userspace:
@@ -286,6 +288,8 @@ Kernel to userspace: · 43 unmodified lines
286 ``ETHTOOL_MSG_MODULE_FW_FLASH_NTF`` transceiver module flash updates288 ``ETHTOOL_MSG_MODULE_FW_FLASH_NTF`` transceiver module flash updates
287 ``ETHTOOL_MSG_PHY_GET_REPLY`` Ethernet PHY information289 ``ETHTOOL_MSG_PHY_GET_REPLY`` Ethernet PHY information
288 ``ETHTOOL_MSG_PHY_NTF`` Ethernet PHY information change290 ``ETHTOOL_MSG_PHY_NTF`` Ethernet PHY information change
291 ``ETHTOOL_MSG_TSCONFIG_GET_REPLY`` hw timestamping configuration
292 ``ETHTOOL_MSG_TSCONFIG_SET_REPLY`` new hw timestamping configuration
289 ======================================== =================================293 ======================================== =================================
290 294
291``GET`` requests are sent by userspace applications to retrieve device295``GET`` requests are sent by userspace applications to retrieve device
@@ -2244,6 +2248,75 @@ Kernel response contents: · 1952 unmodified lines
2244When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is2248When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is
2245another PHY.2249another PHY.
2246 2250
2251TSCONFIG_GET
2252============
2253
2254Retrieves the information about the current hardware timestamping source and
2255configuration.
2256
2257It is similar to the deprecated ``SIOCGHWTSTAMP`` ioctl request.
2258
2259Request contents:
2260
2261 ==================================== ====== ==========================
2262 ``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
2263 ==================================== ====== ==========================
2264
2265Kernel response contents:
2266
2267 ======================================== ====== ============================
2268 ``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
2269 ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
2270 ``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
2271 ``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
2272 ``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
2273 ======================================== ====== ============================
2274
2275When set the ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` attribute identifies the
2276source of the hw timestamping provider. It is composed by
2277``ETHTOOL_A_TS_HWTSTAMP_PROVIDER_INDEX`` attribute which describe the index of
2278the PTP device and ``ETHTOOL_A_TS_HWTSTAMP_PROVIDER_QUALIFIER`` which describe
2279the qualifier of the timestamp.
2280
2281When set the ``ETHTOOL_A_TSCONFIG_TX_TYPES``, ``ETHTOOL_A_TSCONFIG_RX_FILTERS``
2282and the ``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` attributes identify the Tx
2283type, the Rx filter and the flags configured for the current hw timestamping
2284provider. The attributes are propagated to the driver through the following
2285structure:
2286
2287.. kernel-doc:: include/linux/net_tstamp.h
2288 :identifiers: kernel_hwtstamp_config
2289
2290TSCONFIG_SET
2291============
2292
2293Set the information about the current hardware timestamping source and
2294configuration.
2295
2296It is similar to the deprecated ``SIOCSHWTSTAMP`` ioctl request.
2297
2298Request contents:
2299
2300 ======================================== ====== ============================
2301 ``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
2302 ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
2303 ``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
2304 ``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
2305 ``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
2306 ======================================== ====== ============================
2307
2308Kernel response contents:
2309
2310 ======================================== ====== ============================
2311 ``ETHTOOL_A_TSCONFIG_HEADER`` nested request header
2312 ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` nested PTP hw clock provider
2313 ``ETHTOOL_A_TSCONFIG_TX_TYPES`` bitset hwtstamp Tx type
2314 ``ETHTOOL_A_TSCONFIG_RX_FILTERS`` bitset hwtstamp Rx filter
2315 ``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` u32 hwtstamp flags
2316 ======================================== ====== ============================
2317
2318For a description of each attribute, see ``TSCONFIG_GET``.
2319
2247Request translation2320Request translation
2248===================2321===================
2249 2322
@@ -2352,4 +2425,6 @@ are netlink only. · 102 unmodified lines
2352 n/a ``ETHTOOL_MSG_MM_SET``2425 n/a ``ETHTOOL_MSG_MM_SET``
2353 n/a ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT``2426 n/a ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT``
2354 n/a ``ETHTOOL_MSG_PHY_GET``2427 n/a ``ETHTOOL_MSG_PHY_GET``
2428 ``SIOCGHWTSTAMP`` ``ETHTOOL_MSG_TSCONFIG_GET``
2429 ``SIOCSHWTSTAMP`` ``ETHTOOL_MSG_TSCONFIG_SET``
2355 =================================== =====================================2430 =================================== =====================================
Documentation/networking/timestamping.rst+24−14
@@ -525,8 +525,8 @@ implicitly defined. ts[0] holds a software timestamp if set, ts[1] · 524 unmodified lines
525is again deprecated and ts[2] holds a hardware timestamp if set.525is again deprecated and ts[2] holds a hardware timestamp if set.
526 526
527 527
5283. Hardware Timestamping configuration: SIOCSHWTSTAMP and SIOCGHWTSTAMP5283. Hardware Timestamping configuration: ETHTOOL_MSG_TSCONFIG_SET/GET
529=======================================================================529====================================================================
530 530
531Hardware time stamping must also be initialized for each device driver531Hardware time stamping must also be initialized for each device driver
532that is expected to do hardware time stamping. The parameter is defined in532that is expected to do hardware time stamping. The parameter is defined in
@@ -539,12 +539,14 @@ include/uapi/linux/net_tstamp.h as:: · 6 unmodified lines
539 };539 };
540 540
541Desired behavior is passed into the kernel and to a specific device by541Desired behavior is passed into the kernel and to a specific device by
542calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose542calling the tsconfig netlink socket ``ETHTOOL_MSG_TSCONFIG_SET``.
543ifr_data points to a struct hwtstamp_config. The tx_type and543The ``ETHTOOL_A_TSCONFIG_TX_TYPES``, ``ETHTOOL_A_TSCONFIG_RX_FILTERS`` and
544rx_filter are hints to the driver what it is expected to do. If544``ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS`` netlink attributes are then used to set
545the requested fine-grained filtering for incoming packets is not545the struct hwtstamp_config accordingly.
546supported, the driver may time stamp more than just the requested types546
547of packets.547The ``ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER`` netlink nested attribute is used
548to select the source of the hardware time stamping. It is composed of an index
549for the device source and a qualifier for the type of time stamping.
548 550
549Drivers are free to use a more permissive configuration than the requested551Drivers are free to use a more permissive configuration than the requested
550configuration. It is expected that drivers should only implement directly the552configuration. It is expected that drivers should only implement directly the
@@ -563,9 +565,16 @@ Only a processes with admin rights may change the configuration. User · 12 unmodified lines
563space is responsible to ensure that multiple processes don't interfere565space is responsible to ensure that multiple processes don't interfere
564with each other and that the settings are reset.566with each other and that the settings are reset.
565 567
566Any process can read the actual configuration by passing this568Any process can read the actual configuration by requesting tsconfig netlink
567structure to ioctl(SIOCGHWTSTAMP) in the same way. However, this has569socket ``ETHTOOL_MSG_TSCONFIG_GET``.
568not been implemented in all drivers.570
571The legacy configuration is the use of the ioctl(SIOCSHWTSTAMP) with a pointer
572to a struct ifreq whose ifr_data points to a struct hwtstamp_config.
573The tx_type and rx_filter are hints to the driver what it is expected to do.
574If the requested fine-grained filtering for incoming packets is not
575supported, the driver may time stamp more than just the requested types
576of packets. ioctl(SIOCGHWTSTAMP) is used in the same way as the
577ioctl(SIOCSHWTSTAMP). However, this has not been implemented in all drivers.
569 578
570::579::
571 580
@@ -610,9 +619,10 @@ not been implemented in all drivers. · 38 unmodified lines
610--------------------------------------------------------619--------------------------------------------------------
611 620
612A driver which supports hardware time stamping must support the621A driver which supports hardware time stamping must support the
613SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with622ndo_hwtstamp_set NDO or the legacy SIOCSHWTSTAMP ioctl and update the
614the actual values as described in the section on SIOCSHWTSTAMP. It623supplied struct hwtstamp_config with the actual values as described in
615should also support SIOCGHWTSTAMP.624the section on SIOCSHWTSTAMP. It should also support ndo_hwtstamp_get or
625the legacy SIOCGHWTSTAMP.
616 626
617Time stamps for received packets must be stored in the skb. To get a pointer627Time stamps for received packets must be stored in the skb. To get a pointer
618to the shared time stamp structure of the skb call skb_hwtstamps(). Then628to the shared time stamp structure of the skb call skb_hwtstamps(). Then
include/uapi/linux/ethtool_netlink_generated.h+16−0
@@ -694,6 +694,18 @@ enum { · 693 unmodified lines
694 ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1)694 ETHTOOL_A_PHY_MAX = (__ETHTOOL_A_PHY_CNT - 1)
695};695};
696 696
697enum {
698 ETHTOOL_A_TSCONFIG_UNSPEC,
699 ETHTOOL_A_TSCONFIG_HEADER,
700 ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER,
701 ETHTOOL_A_TSCONFIG_TX_TYPES,
702 ETHTOOL_A_TSCONFIG_RX_FILTERS,
703 ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS,
704
705 __ETHTOOL_A_TSCONFIG_CNT,
706 ETHTOOL_A_TSCONFIG_MAX = (__ETHTOOL_A_TSCONFIG_CNT - 1)
707};
708
697enum {709enum {
698 ETHTOOL_MSG_USER_NONE = 0,710 ETHTOOL_MSG_USER_NONE = 0,
699 ETHTOOL_MSG_STRSET_GET = 1,711 ETHTOOL_MSG_STRSET_GET = 1,
@@ -741,6 +753,8 @@ enum { · 41 unmodified lines
741 ETHTOOL_MSG_MM_SET,753 ETHTOOL_MSG_MM_SET,
742 ETHTOOL_MSG_MODULE_FW_FLASH_ACT,754 ETHTOOL_MSG_MODULE_FW_FLASH_ACT,
743 ETHTOOL_MSG_PHY_GET,755 ETHTOOL_MSG_PHY_GET,
756 ETHTOOL_MSG_TSCONFIG_GET,
757 ETHTOOL_MSG_TSCONFIG_SET,
744 758
745 __ETHTOOL_MSG_USER_CNT,759 __ETHTOOL_MSG_USER_CNT,
746 ETHTOOL_MSG_USER_MAX = (__ETHTOOL_MSG_USER_CNT - 1)760 ETHTOOL_MSG_USER_MAX = (__ETHTOOL_MSG_USER_CNT - 1)
@@ -794,6 +808,8 @@ enum { · 47 unmodified lines
794 ETHTOOL_MSG_MODULE_FW_FLASH_NTF,808 ETHTOOL_MSG_MODULE_FW_FLASH_NTF,
795 ETHTOOL_MSG_PHY_GET_REPLY,809 ETHTOOL_MSG_PHY_GET_REPLY,
796 ETHTOOL_MSG_PHY_NTF,810 ETHTOOL_MSG_PHY_NTF,
811 ETHTOOL_MSG_TSCONFIG_GET_REPLY,
812 ETHTOOL_MSG_TSCONFIG_SET_REPLY,
797 813
798 __ETHTOOL_MSG_KERNEL_CNT,814 __ETHTOOL_MSG_KERNEL_CNT,
799 ETHTOOL_MSG_KERNEL_MAX = (__ETHTOOL_MSG_KERNEL_CNT - 1)815 ETHTOOL_MSG_KERNEL_MAX = (__ETHTOOL_MSG_KERNEL_CNT - 1)
net/ethtool/Makefile+1−1
@@ -9,4 +9,4 @@ ethtool_nl-y := netlink.o bitset.o strset.o linkinfo.o linkmodes.o rss.o \ · 8 unmodified lines
9 channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \9 channels.o coalesce.o pause.o eee.o tsinfo.o cabletest.o \
10 tunnels.o fec.o eeprom.o stats.o phc_vclocks.o mm.o \10 tunnels.o fec.o eeprom.o stats.o phc_vclocks.o mm.o \
11 module.o cmis_fw_update.o cmis_cdb.o pse-pd.o plca.o mm.o \11 module.o cmis_fw_update.o cmis_cdb.o pse-pd.o plca.o mm.o \
12 phy.o12 phy.o tsconfig.o
net/ethtool/common.c+17−10
@@ -797,7 +797,7 @@ int ethtool_net_get_ts_info_by_phc(struct net_device *dev, · 796 unmodified lines
797 return -ENODEV;797 return -ENODEV;
798}798}
799 799
800int800struct phy_device *
801ethtool_phy_get_ts_info_by_phc(struct net_device *dev,801ethtool_phy_get_ts_info_by_phc(struct net_device *dev,
802 struct kernel_ethtool_ts_info *info,802 struct kernel_ethtool_ts_info *info,
803 struct hwtstamp_provider_desc *hwprov_desc)803 struct hwtstamp_provider_desc *hwprov_desc)
@@ -806,7 +806,7 @@ ethtool_phy_get_ts_info_by_phc(struct net_device *dev, · 2 unmodified lines
806 806
807 /* Only precise qualifier is supported in phydev */807 /* Only precise qualifier is supported in phydev */
808 if (hwprov_desc->qualifier != HWTSTAMP_PROVIDER_QUALIFIER_PRECISE)808 if (hwprov_desc->qualifier != HWTSTAMP_PROVIDER_QUALIFIER_PRECISE)
809 return -ENODEV;809 return ERR_PTR(-ENODEV);
810 810
811 /* Look in the phy topology */811 /* Look in the phy topology */
812 if (dev->link_topo) {812 if (dev->link_topo) {
@@ -820,12 +820,12 @@ ethtool_phy_get_ts_info_by_phc(struct net_device *dev, · 7 unmodified lines
820 ethtool_init_tsinfo(info);820 ethtool_init_tsinfo(info);
821 err = phy_ts_info(pdn->phy, info);821 err = phy_ts_info(pdn->phy, info);
822 if (err)822 if (err)
823 return err;823 return ERR_PTR(err);
824 824
825 if (info->phc_index == hwprov_desc->index)825 if (info->phc_index == hwprov_desc->index)
826 return 0;826 return pdn->phy;
827 }827 }
828 return -ENODEV;828 return ERR_PTR(-ENODEV);
829 }829 }
830 830
831 /* Look on the dev->phydev */831 /* Look on the dev->phydev */
@@ -833,13 +833,13 @@ ethtool_phy_get_ts_info_by_phc(struct net_device *dev, · 1 unmodified line
833 ethtool_init_tsinfo(info);833 ethtool_init_tsinfo(info);
834 err = phy_ts_info(dev->phydev, info);834 err = phy_ts_info(dev->phydev, info);
835 if (err)835 if (err)
836 return err;836 return ERR_PTR(err);
837 837
838 if (info->phc_index == hwprov_desc->index)838 if (info->phc_index == hwprov_desc->index)
839 return 0;839 return dev->phydev;
840 }840 }
841 841
842 return -ENODEV;842 return ERR_PTR(-ENODEV);
843}843}
844 844
845int ethtool_get_ts_info_by_phc(struct net_device *dev,845int ethtool_get_ts_info_by_phc(struct net_device *dev,
@@ -849,8 +849,15 @@ int ethtool_get_ts_info_by_phc(struct net_device *dev, · 3 unmodified lines
849 int err;849 int err;
850 850
851 err = ethtool_net_get_ts_info_by_phc(dev, info, hwprov_desc);851 err = ethtool_net_get_ts_info_by_phc(dev, info, hwprov_desc);
852 if (err == -ENODEV)852 if (err == -ENODEV) {
853 err = ethtool_phy_get_ts_info_by_phc(dev, info, hwprov_desc);853 struct phy_device *phy;
854
855 phy = ethtool_phy_get_ts_info_by_phc(dev, info, hwprov_desc);
856 if (IS_ERR(phy))
857 err = PTR_ERR(phy);
858 else
859 err = 0;
860 }
854 861
855 info->so_timestamping |= SOF_TIMESTAMPING_RX_SOFTWARE |862 info->so_timestamping |= SOF_TIMESTAMPING_RX_SOFTWARE |
856 SOF_TIMESTAMPING_SOFTWARE;863 SOF_TIMESTAMPING_SOFTWARE;
net/ethtool/common.h+1−1
@@ -56,7 +56,7 @@ int ethtool_get_ts_info_by_phc(struct net_device *dev, · 55 unmodified lines
56int ethtool_net_get_ts_info_by_phc(struct net_device *dev,56int ethtool_net_get_ts_info_by_phc(struct net_device *dev,
57 struct kernel_ethtool_ts_info *info,57 struct kernel_ethtool_ts_info *info,
58 struct hwtstamp_provider_desc *hwprov_desc);58 struct hwtstamp_provider_desc *hwprov_desc);
59int59struct phy_device *
60ethtool_phy_get_ts_info_by_phc(struct net_device *dev,60ethtool_phy_get_ts_info_by_phc(struct net_device *dev,
61 struct kernel_ethtool_ts_info *info,61 struct kernel_ethtool_ts_info *info,
62 struct hwtstamp_provider_desc *hwprov_desc);62 struct hwtstamp_provider_desc *hwprov_desc);
net/ethtool/netlink.c+18−0
@@ -394,6 +394,8 @@ ethnl_default_requests[__ETHTOOL_MSG_USER_CNT] = { · 393 unmodified lines
394 [ETHTOOL_MSG_PLCA_GET_STATUS] = &ethnl_plca_status_request_ops,394 [ETHTOOL_MSG_PLCA_GET_STATUS] = &ethnl_plca_status_request_ops,
395 [ETHTOOL_MSG_MM_GET] = &ethnl_mm_request_ops,395 [ETHTOOL_MSG_MM_GET] = &ethnl_mm_request_ops,
396 [ETHTOOL_MSG_MM_SET] = &ethnl_mm_request_ops,396 [ETHTOOL_MSG_MM_SET] = &ethnl_mm_request_ops,
397 [ETHTOOL_MSG_TSCONFIG_GET] = &ethnl_tsconfig_request_ops,
398 [ETHTOOL_MSG_TSCONFIG_SET] = &ethnl_tsconfig_request_ops,
397};399};
398 400
399static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)401static struct ethnl_dump_ctx *ethnl_dump_context(struct netlink_callback *cb)
@@ -1243,6 +1245,22 @@ static const struct genl_ops ethtool_genl_ops[] = { · 843 unmodified lines
1243 .policy = ethnl_phy_get_policy,1245 .policy = ethnl_phy_get_policy,
1244 .maxattr = ARRAY_SIZE(ethnl_phy_get_policy) - 1,1246 .maxattr = ARRAY_SIZE(ethnl_phy_get_policy) - 1,
1245 },1247 },
1248 {
1249 .cmd = ETHTOOL_MSG_TSCONFIG_GET,
1250 .doit = ethnl_default_doit,
1251 .start = ethnl_default_start,
1252 .dumpit = ethnl_default_dumpit,
1253 .done = ethnl_default_done,
1254 .policy = ethnl_tsconfig_get_policy,
1255 .maxattr = ARRAY_SIZE(ethnl_tsconfig_get_policy) - 1,
1256 },
1257 {
1258 .cmd = ETHTOOL_MSG_TSCONFIG_SET,
1259 .flags = GENL_UNS_ADMIN_PERM,
1260 .doit = ethnl_default_set_doit,
1261 .policy = ethnl_tsconfig_set_policy,
1262 .maxattr = ARRAY_SIZE(ethnl_tsconfig_set_policy) - 1,
1263 },
1246};1264};
1247 1265
1248static const struct genl_multicast_group ethtool_nl_mcgrps[] = {1266static const struct genl_multicast_group ethtool_nl_mcgrps[] = {
net/ethtool/netlink.h+3−0
@@ -435,6 +435,7 @@ extern const struct ethnl_request_ops ethnl_plca_cfg_request_ops; · 434 unmodified lines
435extern const struct ethnl_request_ops ethnl_plca_status_request_ops;435extern const struct ethnl_request_ops ethnl_plca_status_request_ops;
436extern const struct ethnl_request_ops ethnl_mm_request_ops;436extern const struct ethnl_request_ops ethnl_mm_request_ops;
437extern const struct ethnl_request_ops ethnl_phy_request_ops;437extern const struct ethnl_request_ops ethnl_phy_request_ops;
438extern const struct ethnl_request_ops ethnl_tsconfig_request_ops;
438 439
439extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];440extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
440extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];441extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
@@ -485,6 +486,8 @@ extern const struct nla_policy ethnl_mm_get_policy[ETHTOOL_A_MM_HEADER + 1]; · 44 unmodified lines
485extern const struct nla_policy ethnl_mm_set_policy[ETHTOOL_A_MM_MAX + 1];486extern const struct nla_policy ethnl_mm_set_policy[ETHTOOL_A_MM_MAX + 1];
486extern const struct nla_policy ethnl_module_fw_flash_act_policy[ETHTOOL_A_MODULE_FW_FLASH_PASSWORD + 1];487extern const struct nla_policy ethnl_module_fw_flash_act_policy[ETHTOOL_A_MODULE_FW_FLASH_PASSWORD + 1];
487extern const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1];488extern const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1];
489extern const struct nla_policy ethnl_tsconfig_get_policy[ETHTOOL_A_TSCONFIG_HEADER + 1];
490extern const struct nla_policy ethnl_tsconfig_set_policy[ETHTOOL_A_TSCONFIG_MAX + 1];
488 491
489int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);492int ethnl_set_features(struct sk_buff *skb, struct genl_info *info);
490int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);493int ethnl_act_cable_test(struct sk_buff *skb, struct genl_info *info);
net/ethtool/tsconfig.c+444−0
@@ -0,0 +1,444 @@
1// SPDX-License-Identifier: GPL-2.0-only
2
3#include <linux/net_tstamp.h>
4#include <linux/ptp_clock_kernel.h>
5
6#include "netlink.h"
7#include "common.h"
8#include "bitset.h"
9#include "../core/dev.h"
10#include "ts.h"
11
12struct tsconfig_req_info {
13 struct ethnl_req_info base;
14};
15
16struct tsconfig_reply_data {
17 struct ethnl_reply_data base;
18 struct hwtstamp_provider_desc hwprov_desc;
19 struct {
20 u32 tx_type;
21 u32 rx_filter;
22 u32 flags;
23 } hwtst_config;
24};
25
26#define TSCONFIG_REPDATA(__reply_base) \
27 container_of(__reply_base, struct tsconfig_reply_data, base)
28
29const struct nla_policy ethnl_tsconfig_get_policy[ETHTOOL_A_TSCONFIG_HEADER + 1] = {
30 [ETHTOOL_A_TSCONFIG_HEADER] =
31 NLA_POLICY_NESTED(ethnl_header_policy),
32};
33
34static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,
35 struct ethnl_reply_data *reply_base,
36 const struct genl_info *info)
37{
38 struct tsconfig_reply_data *data = TSCONFIG_REPDATA(reply_base);
39 struct hwtstamp_provider *hwprov = NULL;
40 struct net_device *dev = reply_base->dev;
41 struct kernel_hwtstamp_config cfg = {};
42 int ret;
43
44 if (!dev->netdev_ops->ndo_hwtstamp_get)
45 return -EOPNOTSUPP;
46
47 ret = ethnl_ops_begin(dev);
48 if (ret < 0)
49 return ret;
50
51 ret = dev_get_hwtstamp_phylib(dev, &cfg);
52 if (ret)
53 goto out;
54
55 data->hwtst_config.tx_type = BIT(cfg.tx_type);
56 data->hwtst_config.rx_filter = BIT(cfg.rx_filter);
57 data->hwtst_config.flags = BIT(cfg.flags);
58
59 data->hwprov_desc.index = -1;
60 hwprov = rtnl_dereference(dev->hwprov);
61 if (hwprov) {
62 data->hwprov_desc.index = hwprov->desc.index;
63 data->hwprov_desc.qualifier = hwprov->desc.qualifier;
64 } else {
65 struct kernel_ethtool_ts_info ts_info = {};
66
67 ts_info.phc_index = -1;
68 ret = __ethtool_get_ts_info(dev, &ts_info);
69 if (ret)
70 goto out;
71
72 if (ts_info.phc_index == -1)
73 return -ENODEV;
74
75 data->hwprov_desc.index = ts_info.phc_index;
76 data->hwprov_desc.qualifier = ts_info.phc_qualifier;
77 }
78
79out:
80 ethnl_ops_complete(dev);
81 return ret;
82}
83
84static int tsconfig_reply_size(const struct ethnl_req_info *req_base,
85 const struct ethnl_reply_data *reply_base)
86{
87 const struct tsconfig_reply_data *data = TSCONFIG_REPDATA(reply_base);
88 bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
89 int len = 0;
90 int ret;
91
92 BUILD_BUG_ON(__HWTSTAMP_TX_CNT > 32);
93 BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT > 32);
94
95 if (data->hwtst_config.flags)
96 /* _TSCONFIG_HWTSTAMP_FLAGS */
97 len += nla_total_size(sizeof(u32));
98
99 if (data->hwtst_config.tx_type) {
100 ret = ethnl_bitset32_size(&data->hwtst_config.tx_type,
101 NULL, __HWTSTAMP_TX_CNT,
102 ts_tx_type_names, compact);
103 if (ret < 0)
104 return ret;
105 len += ret; /* _TSCONFIG_TX_TYPES */
106 }
107 if (data->hwtst_config.rx_filter) {
108 ret = ethnl_bitset32_size(&data->hwtst_config.rx_filter,
109 NULL, __HWTSTAMP_FILTER_CNT,
110 ts_rx_filter_names, compact);
111 if (ret < 0)
112 return ret;
113 len += ret; /* _TSCONFIG_RX_FILTERS */
114 }
115
116 if (data->hwprov_desc.index >= 0)
117 /* _TSCONFIG_HWTSTAMP_PROVIDER */
118 len += nla_total_size(0) +
119 2 * nla_total_size(sizeof(u32));
120
121 return len;
122}
123
124static int tsconfig_fill_reply(struct sk_buff *skb,
125 const struct ethnl_req_info *req_base,
126 const struct ethnl_reply_data *reply_base)
127{
128 const struct tsconfig_reply_data *data = TSCONFIG_REPDATA(reply_base);
129 bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
130 int ret;
131
132 if (data->hwtst_config.flags) {
133 ret = nla_put_u32(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS,
134 data->hwtst_config.flags);
135 if (ret < 0)
136 return ret;
137 }
138
139 if (data->hwtst_config.tx_type) {
140 ret = ethnl_put_bitset32(skb, ETHTOOL_A_TSCONFIG_TX_TYPES,
141 &data->hwtst_config.tx_type, NULL,
142 __HWTSTAMP_TX_CNT,
143 ts_tx_type_names, compact);
144 if (ret < 0)
145 return ret;
146 }
147
148 if (data->hwtst_config.rx_filter) {
149 ret = ethnl_put_bitset32(skb, ETHTOOL_A_TSCONFIG_RX_FILTERS,
150 &data->hwtst_config.rx_filter,
151 NULL, __HWTSTAMP_FILTER_CNT,
152 ts_rx_filter_names, compact);
153 if (ret < 0)
154 return ret;
155 }
156
157 if (data->hwprov_desc.index >= 0) {
158 struct nlattr *nest;
159
160 nest = nla_nest_start(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER);
161 if (!nest)
162 return -EMSGSIZE;
163
164 if (nla_put_u32(skb, ETHTOOL_A_TS_HWTSTAMP_PROVIDER_INDEX,
165 data->hwprov_desc.index) ||
166 nla_put_u32(skb,
167 ETHTOOL_A_TS_HWTSTAMP_PROVIDER_QUALIFIER,
168 data->hwprov_desc.qualifier)) {
169 nla_nest_cancel(skb, nest);
170 return -EMSGSIZE;
171 }
172
173 nla_nest_end(skb, nest);
174 }
175 return 0;
176}
177
178/* TSCONFIG_SET */
179const struct nla_policy ethnl_tsconfig_set_policy[ETHTOOL_A_TSCONFIG_MAX + 1] = {
180 [ETHTOOL_A_TSCONFIG_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
181 [ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER] =
182 NLA_POLICY_NESTED(ethnl_ts_hwtst_prov_policy),
183 [ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS] = { .type = NLA_U32 },
184 [ETHTOOL_A_TSCONFIG_RX_FILTERS] = { .type = NLA_NESTED },
185 [ETHTOOL_A_TSCONFIG_TX_TYPES] = { .type = NLA_NESTED },
186};
187
188static int tsconfig_send_reply(struct net_device *dev, struct genl_info *info)
189{
190 struct tsconfig_reply_data *reply_data;
191 struct tsconfig_req_info *req_info;
192 struct sk_buff *rskb;
193 void *reply_payload;
194 int reply_len = 0;
195 int ret;
196
197 req_info = kzalloc(sizeof(*req_info), GFP_KERNEL);
198 if (!req_info)
199 return -ENOMEM;
200 reply_data = kmalloc(sizeof(*reply_data), GFP_KERNEL);
201 if (!reply_data) {
202 kfree(req_info);
203 return -ENOMEM;
204 }
205
206 ASSERT_RTNL();
207 reply_data->base.dev = dev;
208 ret = tsconfig_prepare_data(&req_info->base, &reply_data->base, info);
209 if (ret < 0)
210 goto err_cleanup;
211
212 ret = tsconfig_reply_size(&req_info->base, &reply_data->base);
213 if (ret < 0)
214 goto err_cleanup;
215
216 reply_len = ret + ethnl_reply_header_size();
217 rskb = ethnl_reply_init(reply_len, dev, ETHTOOL_MSG_TSCONFIG_SET_REPLY,
218 ETHTOOL_A_TSCONFIG_HEADER, info, &reply_payload);
219 if (!rskb)
220 goto err_cleanup;
221
222 ret = tsconfig_fill_reply(rskb, &req_info->base, &reply_data->base);
223 if (ret < 0)
224 goto err_cleanup;
225
226 genlmsg_end(rskb, reply_payload);
227 ret = genlmsg_reply(rskb, info);
228
229err_cleanup:
230 kfree(reply_data);
231 kfree(req_info);
232 return ret;
233}
234
235static int ethnl_set_tsconfig_validate(struct ethnl_req_info *req_base,
236 struct genl_info *info)
237{
238 const struct net_device_ops *ops = req_base->dev->netdev_ops;
239
240 if (!ops->ndo_hwtstamp_set || !ops->ndo_hwtstamp_get)
241 return -EOPNOTSUPP;
242
243 return 1;
244}
245
246static struct hwtstamp_provider *
247tsconfig_set_hwprov_from_desc(struct net_device *dev,
248 struct genl_info *info,
249 struct hwtstamp_provider_desc *hwprov_desc)
250{
251 struct kernel_ethtool_ts_info ts_info;
252 struct hwtstamp_provider *hwprov;
253 struct nlattr **tb = info->attrs;
254 struct phy_device *phy = NULL;
255 enum hwtstamp_source source;
256 int ret;
257
258 ret = ethtool_net_get_ts_info_by_phc(dev, &ts_info, hwprov_desc);
259 if (!ret) {
260 /* Found */
261 source = HWTSTAMP_SOURCE_NETDEV;
262 } else {
263 phy = ethtool_phy_get_ts_info_by_phc(dev, &ts_info, hwprov_desc);
264 if (IS_ERR(phy)) {
265 if (PTR_ERR(phy) == -ENODEV)
266 NL_SET_ERR_MSG_ATTR(info->extack,
267 tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER],
268 "phc not in this net device topology");
269 return ERR_CAST(phy);
270 }
271
272 source = HWTSTAMP_SOURCE_PHYLIB;
273 }
274
275 hwprov = kzalloc(sizeof(*hwprov), GFP_KERNEL);
276 if (!hwprov)
277 return ERR_PTR(-ENOMEM);
278
279 hwprov->desc.index = hwprov_desc->index;
280 hwprov->desc.qualifier = hwprov_desc->qualifier;
281 hwprov->source = source;
282 hwprov->phydev = phy;
283
284 return hwprov;
285}
286
287static int ethnl_set_tsconfig(struct ethnl_req_info *req_base,
288 struct genl_info *info)
289{
290 struct kernel_hwtstamp_config hwtst_config = {0};
291 bool hwprov_mod = false, config_mod = false;
292 struct hwtstamp_provider *hwprov = NULL;
293 struct net_device *dev = req_base->dev;
294 struct nlattr **tb = info->attrs;
295 int ret;
296
297 BUILD_BUG_ON(__HWTSTAMP_TX_CNT >= 32);
298 BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT >= 32);
299
300 if (!netif_device_present(dev))
301 return -ENODEV;
302
303 if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER]) {
304 struct hwtstamp_provider_desc __hwprov_desc = {.index = -1};
305 struct hwtstamp_provider *__hwprov;
306
307 __hwprov = rtnl_dereference(dev->hwprov);
308 if (__hwprov) {
309 __hwprov_desc.index = __hwprov->desc.index;
310 __hwprov_desc.qualifier = __hwprov->desc.qualifier;
311 }
312
313 ret = ts_parse_hwtst_provider(tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER],
314 &__hwprov_desc, info->extack,
315 &hwprov_mod);
316 if (ret < 0)
317 return ret;
318
319 if (hwprov_mod) {
320 hwprov = tsconfig_set_hwprov_from_desc(dev, info,
321 &__hwprov_desc);
322 if (IS_ERR(hwprov))
323 return PTR_ERR(hwprov);
324 }
325 }
326
327 /* Get current hwtstamp config if we are not changing the
328 * hwtstamp source. It will be zeroed in the other case.
329 */
330 if (!hwprov_mod) {
331 ret = dev_get_hwtstamp_phylib(dev, &hwtst_config);
332 if (ret < 0 && ret != -EOPNOTSUPP)
333 goto err_free_hwprov;
334 }
335
336 /* Get the hwtstamp config from netlink */
337 if (tb[ETHTOOL_A_TSCONFIG_TX_TYPES]) {
338 u32 req_tx_type;
339
340 req_tx_type = BIT(hwtst_config.tx_type);
341 ret = ethnl_update_bitset32(&req_tx_type,
342 __HWTSTAMP_TX_CNT,
343 tb[ETHTOOL_A_TSCONFIG_TX_TYPES],
344 ts_tx_type_names, info->extack,
345 &config_mod);
346 if (ret < 0)
347 goto err_free_hwprov;
348
349 /* Select only one tx type at a time */
350 if (ffs(req_tx_type) != fls(req_tx_type)) {
351 ret = -EINVAL;
352 goto err_free_hwprov;
353 }
354
355 hwtst_config.tx_type = ffs(req_tx_type) - 1;
356 }
357
358 if (tb[ETHTOOL_A_TSCONFIG_RX_FILTERS]) {
359 u32 req_rx_filter;
360
361 req_rx_filter = BIT(hwtst_config.rx_filter);
362 ret = ethnl_update_bitset32(&req_rx_filter,
363 __HWTSTAMP_FILTER_CNT,
364 tb[ETHTOOL_A_TSCONFIG_RX_FILTERS],
365 ts_rx_filter_names, info->extack,
366 &config_mod);
367 if (ret < 0)
368 goto err_free_hwprov;
369
370 /* Select only one rx filter at a time */
371 if (ffs(req_rx_filter) != fls(req_rx_filter)) {
372 ret = -EINVAL;
373 goto err_free_hwprov;
374 }
375
376 hwtst_config.rx_filter = ffs(req_rx_filter) - 1;
377 }
378
379 if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS]) {
380 ethnl_update_u32(&hwtst_config.flags,
381 tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS],
382 &config_mod);
383 }
384
385 ret = net_hwtstamp_validate(&hwtst_config);
386 if (ret)
387 goto err_free_hwprov;
388
389 if (hwprov_mod) {
390 struct kernel_hwtstamp_config zero_config = {0};
391 struct hwtstamp_provider *__hwprov;
392
393 /* Disable current time stamping if we try to enable
394 * another one
395 */
396 ret = dev_set_hwtstamp_phylib(dev, &zero_config, info->extack);
397 if (ret < 0)
398 goto err_free_hwprov;
399
400 /* Change the selected hwtstamp source */
401 __hwprov = rcu_replace_pointer_rtnl(dev->hwprov, hwprov);
402 if (__hwprov)
403 kfree_rcu(__hwprov, rcu_head);
404 }
405
406 if (config_mod) {
407 ret = dev_set_hwtstamp_phylib(dev, &hwtst_config,
408 info->extack);
409 if (ret < 0)
410 return ret;
411 }
412
413 if (hwprov_mod || config_mod) {
414 ret = tsconfig_send_reply(dev, info);
415 if (ret && ret != -EOPNOTSUPP) {
416 NL_SET_ERR_MSG(info->extack,
417 "error while reading the new configuration set");
418 return ret;
419 }
420 }
421
422 /* tsconfig has no notification */
423 return 0;
424
425err_free_hwprov:
426 kfree(hwprov);
427
428 return ret;
429}
430
431const struct ethnl_request_ops ethnl_tsconfig_request_ops = {
432 .request_cmd = ETHTOOL_MSG_TSCONFIG_GET,
433 .reply_cmd = ETHTOOL_MSG_TSCONFIG_GET_REPLY,
434 .hdr_attr = ETHTOOL_A_TSCONFIG_HEADER,
435 .req_info_size = sizeof(struct tsconfig_req_info),
436 .reply_data_size = sizeof(struct tsconfig_reply_data),
437
438 .prepare_data = tsconfig_prepare_data,
439 .reply_size = tsconfig_reply_size,
440 .fill_reply = tsconfig_fill_reply,
441
442 .set_validate = ethnl_set_tsconfig_validate,
443 .set = ethnl_set_tsconfig,
444};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t