Merge 267e31750a ("Merge branch 'phy-listing-link_topology-tracking'") into android-mainline

Steps on the way to 6.10-rc1

Resolves merge conflicts in:
	include/trace/events/rpcgss.h
	net/core/dev.c

Change-Id: I5583f92563983ee27432e07e1bc7fb194a6a45fc
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman
2024-07-29 07:03:30 +00:00
69 changed files with 907 additions and 150 deletions
+1 -1
View File
@@ -158,7 +158,7 @@ properties:
type: &attr-type
enum: [ unused, pad, flag, binary,
uint, sint, u8, u16, u32, u64, s32, s64,
string, nest, array-nest, nest-type-value ]
string, nest, indexed-array, nest-type-value ]
doc:
description: Documentation of the attribute.
type: string
+1 -1
View File
@@ -201,7 +201,7 @@ properties:
description: The netlink attribute type
enum: [ unused, pad, flag, binary, bitfield32,
uint, sint, u8, u16, u32, u64, s32, s64,
string, nest, array-nest, nest-type-value ]
string, nest, indexed-array, nest-type-value ]
doc:
description: Documentation of the attribute.
type: string
+1 -1
View File
@@ -124,7 +124,7 @@ properties:
type: &attr-type
enum: [ unused, pad, flag, binary,
uint, sint, u8, u16, u32, u64, s32, s64,
string, nest, array-nest, nest-type-value ]
string, nest, indexed-array, nest-type-value ]
doc:
description: Documentation of the attribute.
type: string
+1 -1
View File
@@ -222,7 +222,7 @@ properties:
description: The netlink attribute type
enum: [ unused, pad, flag, binary, bitfield32,
u8, u16, u32, u64, s8, s16, s32, s64,
string, nest, array-nest, nest-type-value,
string, nest, indexed-array, nest-type-value,
sub-message ]
doc:
description: Documentation of the attribute.
+17 -1
View File
@@ -18,7 +18,6 @@ definitions:
entries: []
-
name: header-flags
enum-name:
type: flags
entries: [ compact-bitsets, omit-reply, stats ]
@@ -565,6 +564,18 @@ attribute-sets:
-
name: tx-lpi-timer
type: u32
-
name: ts-stat
attributes:
-
name: tx-pkts
type: uint
-
name: tx-lost
type: uint
-
name: tx-err
type: uint
-
name: tsinfo
attributes:
@@ -587,6 +598,10 @@ attribute-sets:
-
name: phc-index
type: u32
-
name: stats
type: nest
nested-attributes: ts-stat
-
name: cable-result
attributes:
@@ -1394,6 +1409,7 @@ operations:
- tx-types
- rx-filters
- phc-index
- stats
dump: *tsinfo-get-op
-
name: cable-test-act
+4 -2
View File
@@ -65,11 +65,13 @@ attribute-sets:
type: u32
-
name: ops
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: op-attrs
-
name: mcast-groups
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: mcast-group-attrs
-
name: policy
+2 -1
View File
@@ -1696,7 +1696,8 @@ attribute-sets:
type: binary
-
name: hw-s-info
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: hw-s-info-one
-
name: l3-stats
+14 -7
View File
@@ -1988,7 +1988,8 @@ attribute-sets:
nested-attributes: tc-ematch-attrs
-
name: act
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: tc-act-attrs
-
name: police
@@ -2128,7 +2129,8 @@ attribute-sets:
type: u32
-
name: tin-stats
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: tc-cake-tin-stats-attrs
-
name: deficit
@@ -2348,7 +2350,8 @@ attribute-sets:
type: string
-
name: act
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: tc-act-attrs
-
name: key-eth-dst
@@ -2849,7 +2852,8 @@ attribute-sets:
type: string
-
name: act
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: tc-act-attrs
-
name: mask
@@ -3002,7 +3006,8 @@ attribute-sets:
type: u32
-
name: act
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: tc-act-attrs
-
name: flags
@@ -3375,7 +3380,8 @@ attribute-sets:
nested-attributes: tc-police-attrs
-
name: act
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: tc-act-attrs
-
name: tc-taprio-attrs
@@ -3593,7 +3599,8 @@ attribute-sets:
nested-attributes: tc-police-attrs
-
name: act
type: array-nest
type: indexed-array
sub-type: nest
nested-attributes: tc-act-attrs
-
name: indev
@@ -300,6 +300,11 @@ the software port.
in the beginning of the queue. This is a normal condition.
- Informative
* - `tx[i]_timestamps`
- Transmitted packets that were hardware timestamped at the device's DMA
layer.
- Informative
* - `tx[i]_added_vlan_packets`
- The number of packets sent where vlan tag insertion was offloaded to the
hardware.
@@ -702,6 +707,12 @@ the software port.
the device typically ensures not posting the CQE.
- Error
* - `ptp_cq[i]_lost_cqe`
- Number of times a CQE is expected to not be delivered on the PTP
timestamping CQE by the device due to a time delta elapsing. If such a
CQE is somehow delivered, `ptp_cq[i]_late_cqe` is incremented.
- Error
.. [#ring_global] The corresponding ring and global counters do not share the
same name (i.e. do not follow the common naming scheme).
@@ -57,6 +57,7 @@ Structure of this header is
``ETHTOOL_A_HEADER_DEV_INDEX`` u32 device ifindex
``ETHTOOL_A_HEADER_DEV_NAME`` string device name
``ETHTOOL_A_HEADER_FLAGS`` u32 flags common for all requests
``ETHTOOL_A_HEADER_PHY_INDEX`` u32 phy device index
============================== ====== =============================
``ETHTOOL_A_HEADER_DEV_INDEX`` and ``ETHTOOL_A_HEADER_DEV_NAME`` identify the
@@ -81,6 +82,12 @@ the behaviour is backward compatible, i.e. requests from old clients not aware
of the flag should be interpreted the way the client expects. A client must
not set flags it does not understand.
``ETHTOOL_A_HEADER_PHY_INDEX`` identifies the Ethernet PHY the message relates to.
As there are numerous commands that are related to PHY configuration, and because
there may be more than one PHY on the link, the PHY index can be passed in the
request for the commands that needs it. It is, however, not mandatory, and if it
is not passed for commands that target a PHY, the net_device.phydev pointer
is used.
Bit sets
========
@@ -1237,12 +1244,21 @@ Kernel response contents:
``ETHTOOL_A_TSINFO_TX_TYPES`` bitset supported Tx types
``ETHTOOL_A_TSINFO_RX_FILTERS`` bitset supported Rx filters
``ETHTOOL_A_TSINFO_PHC_INDEX`` u32 PTP hw clock index
``ETHTOOL_A_TSINFO_STATS`` nested HW timestamping statistics
===================================== ====== ==========================
``ETHTOOL_A_TSINFO_PHC_INDEX`` is absent if there is no associated PHC (there
is no special value for this case). The bitset attributes are omitted if they
would be empty (no bit set).
Additional hardware timestamping statistics response contents:
===================================== ====== ===================================
``ETHTOOL_A_TS_STAT_TX_PKTS`` u64 Packets with Tx HW timestamps
``ETHTOOL_A_TS_STAT_TX_LOST`` u64 Tx HW timestamp not arrived count
``ETHTOOL_A_TS_STAT_TX_ERR`` u64 HW error request Tx timestamp count
===================================== ====== ===================================
CABLE_TEST
==========
@@ -46,10 +46,16 @@ For reference the ``multi-attr`` array may look like this::
where ``ARRAY-ATTR`` is the array entry type.
array-nest
~~~~~~~~~~
indexed-array
~~~~~~~~~~~~~
``array-nest`` creates the following structure::
``indexed-array`` wraps the entire array in an extra attribute (hence
limiting its size to 64kB). The ``ENTRY`` nests are special and have the
index of the entry as their type instead of normal attribute type.
A ``sub-type`` is needed to describe what type in the ``ENTRY``. A ``nest``
``sub-type`` means there are nest arrays in the ``ENTRY``, with the structure
looks like::
[SOME-OTHER-ATTR]
[ARRAY-ATTR]
@@ -60,9 +66,13 @@ array-nest
[MEMBER1]
[MEMBER2]
It wraps the entire array in an extra attribute (hence limiting its size
to 64kB). The ``ENTRY`` nests are special and have the index of the entry
as their type instead of normal attribute type.
Other ``sub-type`` like ``u32`` means there is only one member as described
in ``sub-type`` in the ``ENTRY``. The structure looks like::
[SOME-OTHER-ATTR]
[ARRAY-ATTR]
[ENTRY u32]
[ENTRY u32]
type-value
~~~~~~~~~~
+2
View File
@@ -8062,6 +8062,8 @@ F: include/linux/mii.h
F: include/linux/of_net.h
F: include/linux/phy.h
F: include/linux/phy_fixed.h
F: include/linux/phy_link_topology.h
F: include/linux/phy_link_topology_core.h
F: include/linux/phylib_stubs.h
F: include/linux/platform_data/mdio-bcm-unimac.h
F: include/linux/platform_data/mdio-gpio.h
+2 -1
View File
@@ -2,4 +2,5 @@
# Makefile for the CAPI subsystem used by BT_CMTP
obj-$(CONFIG_BT_CMTP) += kernelcapi.o
kernelcapi-y := kcapi.o capiutil.o capi.o kcapi_proc.o
kernelcapi-y := kcapi.o capiutil.o capi.o
kernelcapi-$(CONFIG_PROC_FS) += kcapi_proc.o
+5 -2
View File
@@ -917,13 +917,16 @@ int __init kcapi_init(void)
return err;
}
kcapi_proc_init();
if (IS_ENABLED(CONFIG_PROC_FS))
kcapi_proc_init();
return 0;
}
void kcapi_exit(void)
{
kcapi_proc_exit();
if (IS_ENABLED(CONFIG_PROC_FS))
kcapi_proc_exit();
cdebug_exit();
destroy_workqueue(kcapi_wq);
-3
View File
@@ -31,9 +31,6 @@
Setting to > 1512 effectively disables this feature. */
static int rx_copybreak = 200;
/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
static const int mtu = 1500;
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static int max_interrupt_work = 20;
@@ -538,7 +538,6 @@ static const struct xgbe_version_data xgbe_v1 = {
.tx_tstamp_workaround = 1,
};
#ifdef CONFIG_ACPI
static const struct acpi_device_id xgbe_acpi_match[] = {
{ .id = "AMDI8001",
.driver_data = (kernel_ulong_t)&xgbe_v1 },
@@ -546,9 +545,7 @@ static const struct acpi_device_id xgbe_acpi_match[] = {
};
MODULE_DEVICE_TABLE(acpi, xgbe_acpi_match);
#endif
#ifdef CONFIG_OF
static const struct of_device_id xgbe_of_match[] = {
{ .compatible = "amd,xgbe-seattle-v1a",
.data = &xgbe_v1 },
@@ -556,7 +553,6 @@ static const struct of_device_id xgbe_of_match[] = {
};
MODULE_DEVICE_TABLE(of, xgbe_of_match);
#endif
static SIMPLE_DEV_PM_OPS(xgbe_platform_pm_ops,
xgbe_platform_suspend, xgbe_platform_resume);
@@ -564,12 +560,8 @@ static SIMPLE_DEV_PM_OPS(xgbe_platform_pm_ops,
static struct platform_driver xgbe_driver = {
.driver = {
.name = XGBE_DRV_NAME,
#ifdef CONFIG_ACPI
.acpi_match_table = xgbe_acpi_match,
#endif
#ifdef CONFIG_OF
.of_match_table = xgbe_of_match,
#endif
.pm = &xgbe_platform_pm_ops,
},
.probe = xgbe_platform_probe,
@@ -131,7 +131,7 @@ static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts,
if (!tmo_us)
tmo_us = BNXT_PTP_QTS_TIMEOUT;
tmo_us = min(tmo_us, BNXT_PTP_QTS_MAX_TMO_US);
req->ts_req_timeout = cpu_to_le16(txts_tmo);
req->ts_req_timeout = cpu_to_le16(tmo_us);
}
resp = hwrm_req_hold(bp, req);
@@ -1143,7 +1143,6 @@ void mlx5e_close_drop_rq(struct mlx5e_rq *drop_rq);
int mlx5e_create_tis(struct mlx5_core_dev *mdev, void *in, u32 *tisn);
void mlx5e_destroy_tis(struct mlx5_core_dev *mdev, u32 tisn);
int mlx5e_update_nic_rx(struct mlx5e_priv *priv);
void mlx5e_update_carrier(struct mlx5e_priv *priv);
int mlx5e_close(struct net_device *netdev);
int mlx5e_open(struct net_device *netdev);
@@ -1180,23 +1179,12 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
struct ethtool_coalesce *coal,
struct kernel_ethtool_coalesce *kernel_coal,
struct netlink_ext_ack *extack);
int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
struct ethtool_link_ksettings *link_ksettings);
int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
const struct ethtool_link_ksettings *link_ksettings);
int mlx5e_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh);
int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack);
u32 mlx5e_ethtool_get_rxfh_key_size(struct mlx5e_priv *priv);
u32 mlx5e_ethtool_get_rxfh_indir_size(struct mlx5e_priv *priv);
int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
struct ethtool_ts_info *info);
int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
struct ethtool_flash *flash);
void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
struct ethtool_pauseparam *pauseparam);
int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
struct ethtool_pauseparam *pauseparam);
/* mlx5e generic netdev management API */
static inline bool
@@ -292,10 +292,15 @@ enum mlx5e_fec_supported_link_mode {
MLX5E_FEC_SUPPORTED_LINK_MODE_100G_2X,
MLX5E_FEC_SUPPORTED_LINK_MODE_200G_4X,
MLX5E_FEC_SUPPORTED_LINK_MODE_400G_8X,
MLX5E_FEC_SUPPORTED_LINK_MODE_100G_1X,
MLX5E_FEC_SUPPORTED_LINK_MODE_200G_2X,
MLX5E_FEC_SUPPORTED_LINK_MODE_400G_4X,
MLX5E_FEC_SUPPORTED_LINK_MODE_800G_8X,
MLX5E_MAX_FEC_SUPPORTED_LINK_MODE,
};
#define MLX5E_FEC_FIRST_50G_PER_LANE_MODE MLX5E_FEC_SUPPORTED_LINK_MODE_50G_1X
#define MLX5E_FEC_FIRST_100G_PER_LANE_MODE MLX5E_FEC_SUPPORTED_LINK_MODE_100G_1X
#define MLX5E_FEC_OVERRIDE_ADMIN_POLICY(buf, policy, write, link) \
do { \
@@ -308,6 +313,17 @@ enum mlx5e_fec_supported_link_mode {
*_policy = MLX5_GET(pplm_reg, _buf, fec_override_admin_##link); \
} while (0)
/* Returns true if FEC can be set for a given link mode. */
static bool mlx5e_is_fec_supported_link_mode(struct mlx5_core_dev *dev,
enum mlx5e_fec_supported_link_mode link_mode)
{
return link_mode < MLX5E_FEC_FIRST_50G_PER_LANE_MODE ||
(link_mode < MLX5E_FEC_FIRST_100G_PER_LANE_MODE &&
MLX5_CAP_PCAM_FEATURE(dev, fec_50G_per_lane_in_pplm)) ||
(link_mode >= MLX5E_FEC_FIRST_100G_PER_LANE_MODE &&
MLX5_CAP_PCAM_FEATURE(dev, fec_100G_per_lane_in_pplm));
}
/* get/set FEC admin field for a given speed */
static int mlx5e_fec_admin_field(u32 *pplm, u16 *fec_policy, bool write,
enum mlx5e_fec_supported_link_mode link_mode)
@@ -340,6 +356,18 @@ static int mlx5e_fec_admin_field(u32 *pplm, u16 *fec_policy, bool write,
case MLX5E_FEC_SUPPORTED_LINK_MODE_400G_8X:
MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 400g_8x);
break;
case MLX5E_FEC_SUPPORTED_LINK_MODE_100G_1X:
MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 100g_1x);
break;
case MLX5E_FEC_SUPPORTED_LINK_MODE_200G_2X:
MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 200g_2x);
break;
case MLX5E_FEC_SUPPORTED_LINK_MODE_400G_4X:
MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 400g_4x);
break;
case MLX5E_FEC_SUPPORTED_LINK_MODE_800G_8X:
MLX5E_FEC_OVERRIDE_ADMIN_POLICY(pplm, *fec_policy, write, 800g_8x);
break;
default:
return -EINVAL;
}
@@ -381,6 +409,18 @@ static int mlx5e_get_fec_cap_field(u32 *pplm, u16 *fec_cap,
case MLX5E_FEC_SUPPORTED_LINK_MODE_400G_8X:
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 400g_8x);
break;
case MLX5E_FEC_SUPPORTED_LINK_MODE_100G_1X:
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 100g_1x);
break;
case MLX5E_FEC_SUPPORTED_LINK_MODE_200G_2X:
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 200g_2x);
break;
case MLX5E_FEC_SUPPORTED_LINK_MODE_400G_4X:
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 400g_4x);
break;
case MLX5E_FEC_SUPPORTED_LINK_MODE_800G_8X:
*fec_cap = MLX5E_GET_FEC_OVERRIDE_CAP(pplm, 800g_8x);
break;
default:
return -EINVAL;
}
@@ -389,7 +429,6 @@ static int mlx5e_get_fec_cap_field(u32 *pplm, u16 *fec_cap,
bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy)
{
bool fec_50g_per_lane = MLX5_CAP_PCAM_FEATURE(dev, fec_50G_per_lane_in_pplm);
u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {};
u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
int sz = MLX5_ST_SZ_BYTES(pplm_reg);
@@ -407,7 +446,7 @@ bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy)
for (i = 0; i < MLX5E_MAX_FEC_SUPPORTED_LINK_MODE; i++) {
u16 fec_caps;
if (i >= MLX5E_FEC_FIRST_50G_PER_LANE_MODE && !fec_50g_per_lane)
if (!mlx5e_is_fec_supported_link_mode(dev, i))
break;
mlx5e_get_fec_cap_field(out, &fec_caps, i);
@@ -420,7 +459,6 @@ bool mlx5e_fec_in_caps(struct mlx5_core_dev *dev, int fec_policy)
int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active,
u16 *fec_configured_mode)
{
bool fec_50g_per_lane = MLX5_CAP_PCAM_FEATURE(dev, fec_50G_per_lane_in_pplm);
u32 out[MLX5_ST_SZ_DW(pplm_reg)] = {};
u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
int sz = MLX5_ST_SZ_BYTES(pplm_reg);
@@ -445,7 +483,7 @@ int mlx5e_get_fec_mode(struct mlx5_core_dev *dev, u32 *fec_mode_active,
*fec_configured_mode = 0;
for (i = 0; i < MLX5E_MAX_FEC_SUPPORTED_LINK_MODE; i++) {
if (i >= MLX5E_FEC_FIRST_50G_PER_LANE_MODE && !fec_50g_per_lane)
if (!mlx5e_is_fec_supported_link_mode(dev, i))
break;
mlx5e_fec_admin_field(out, fec_configured_mode, 0, i);
@@ -489,13 +527,13 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u16 fec_policy)
u16 conf_fec = fec_policy;
u16 fec_caps = 0;
if (i >= MLX5E_FEC_FIRST_50G_PER_LANE_MODE && !fec_50g_per_lane)
if (!mlx5e_is_fec_supported_link_mode(dev, i))
break;
/* RS fec in ethtool is mapped to MLX5E_FEC_RS_528_514
* to link modes up to 25G per lane and to
* MLX5E_FEC_RS_544_514 in the new link modes based on
* 50 G per lane
* 50G or 100G per lane
*/
if (conf_fec == (1 << MLX5E_FEC_RS_528_514) &&
i >= MLX5E_FEC_FIRST_50G_PER_LANE_MODE)
@@ -169,6 +169,7 @@ static void mlx5e_ptpsq_mark_ts_cqes_undelivered(struct mlx5e_ptpsq *ptpsq,
WARN_ON_ONCE(!pos->inuse);
pos->inuse = false;
list_del(&pos->entry);
ptpsq->cq_stats->lost_cqe++;
}
spin_unlock_bh(&cqe_list->tracker_list_lock);
}
@@ -1024,8 +1024,8 @@ static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp,
ptys2ethtool_adver_link(lp_advertising, eth_proto_lp, ext);
}
int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
struct ethtool_link_ksettings *link_ksettings)
static int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
struct ethtool_link_ksettings *link_ksettings)
{
struct mlx5_core_dev *mdev = priv->mdev;
u32 out[MLX5_ST_SZ_DW(ptys_reg)] = {};
@@ -1195,8 +1195,8 @@ static bool ext_requested(u8 autoneg, const unsigned long *adver, bool ext_suppo
return autoneg == AUTONEG_ENABLE ? ext_link_mode : ext_supported;
}
int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
const struct ethtool_link_ksettings *link_ksettings)
static int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
const struct ethtool_link_ksettings *link_ksettings)
{
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5_port_eth_proto eproto;
@@ -1296,7 +1296,7 @@ static u32 mlx5e_get_rxfh_indir_size(struct net_device *netdev)
return mlx5e_ethtool_get_rxfh_indir_size(priv);
}
int mlx5e_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
static int mlx5e_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
u32 rss_context = rxfh->rss_context;
@@ -1309,8 +1309,8 @@ int mlx5e_get_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh)
return err;
}
int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
static int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
struct mlx5e_priv *priv = netdev_priv(dev);
u32 *rss_context = &rxfh->rss_context;
@@ -1452,8 +1452,8 @@ static void mlx5e_get_pause_stats(struct net_device *netdev,
mlx5e_stats_pause_get(priv, pause_stats);
}
void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
struct ethtool_pauseparam *pauseparam)
static void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
struct ethtool_pauseparam *pauseparam)
{
struct mlx5_core_dev *mdev = priv->mdev;
int err;
@@ -1474,8 +1474,8 @@ static void mlx5e_get_pauseparam(struct net_device *netdev,
mlx5e_ethtool_get_pauseparam(priv, pauseparam);
}
int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
struct ethtool_pauseparam *pauseparam)
static int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
struct ethtool_pauseparam *pauseparam)
{
struct mlx5_core_dev *mdev = priv->mdev;
int err;
@@ -2428,6 +2428,14 @@ static void mlx5e_get_rmon_stats(struct net_device *netdev,
mlx5e_stats_rmon_get(priv, rmon_stats, ranges);
}
static void mlx5e_get_ts_stats(struct net_device *netdev,
struct ethtool_ts_stats *ts_stats)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
mlx5e_stats_ts_get(priv, ts_stats);
}
const struct ethtool_ops mlx5e_ethtool_ops = {
.cap_rss_ctx_supported = true,
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
@@ -2477,5 +2485,6 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
.get_eth_mac_stats = mlx5e_get_eth_mac_stats,
.get_eth_ctrl_stats = mlx5e_get_eth_ctrl_stats,
.get_rmon_stats = mlx5e_get_rmon_stats,
.get_ts_stats = mlx5e_get_ts_stats,
.get_link_ext_stats = mlx5e_get_link_ext_stats
};
@@ -5562,7 +5562,7 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv)
mlx5e_ipsec_cleanup(priv);
}
int mlx5e_update_nic_rx(struct mlx5e_priv *priv)
static int mlx5e_update_nic_rx(struct mlx5e_priv *priv)
{
return mlx5e_refresh_tirs(priv, false, false);
}
@@ -1172,6 +1172,51 @@ void mlx5e_stats_rmon_get(struct mlx5e_priv *priv,
*ranges = mlx5e_rmon_ranges;
}
void mlx5e_stats_ts_get(struct mlx5e_priv *priv,
struct ethtool_ts_stats *ts_stats)
{
int i, j;
mutex_lock(&priv->state_lock);
if (priv->tx_ptp_opened) {
struct mlx5e_ptp *ptp = priv->channels.ptp;
ts_stats->pkts = 0;
ts_stats->err = 0;
ts_stats->lost = 0;
/* Aggregate stats across all TCs */
for (i = 0; i < ptp->num_tc; i++) {
struct mlx5e_ptp_cq_stats *stats =
ptp->ptpsq[i].cq_stats;
ts_stats->pkts += stats->cqe;
ts_stats->err += stats->abort + stats->err_cqe +
stats->late_cqe;
ts_stats->lost += stats->lost_cqe;
}
} else {
/* DMA layer will always successfully timestamp packets. Other
* counters do not make sense for this layer.
*/
ts_stats->pkts = 0;
/* Aggregate stats across all SQs */
for (j = 0; j < priv->channels.num; j++) {
struct mlx5e_channel *c = priv->channels.c[j];
for (i = 0; i < c->num_tc; i++) {
struct mlx5e_sq_stats *stats = c->sq[i].stats;
ts_stats->pkts += stats->timestamps;
}
}
}
mutex_unlock(&priv->state_lock);
}
#define PPORT_PHY_STATISTICAL_OFF(c) \
MLX5_BYTE_OFF(ppcnt_reg, \
counter_set.phys_layer_statistical_cntrs.c##_high)
@@ -2066,6 +2111,7 @@ static const struct counter_desc sq_stats_desc[] = {
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, added_vlan_packets) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, nop) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, timestamps) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, mpwqe_blks) },
{ MLX5E_DECLARE_TX_STAT(struct mlx5e_sq_stats, mpwqe_pkts) },
#ifdef CONFIG_MLX5_EN_TLS
@@ -2178,6 +2224,7 @@ static const struct counter_desc ptp_cq_stats_desc[] = {
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, abort) },
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, abort_abs_diff_ns) },
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, late_cqe) },
{ MLX5E_DECLARE_PTP_CQ_STAT(struct mlx5e_ptp_cq_stats, lost_cqe) },
};
static const struct counter_desc ptp_rq_stats_desc[] = {
@@ -2217,6 +2264,7 @@ static const struct counter_desc qos_sq_stats_desc[] = {
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, csum_partial_inner) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, added_vlan_packets) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, nop) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, timestamps) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, mpwqe_blks) },
{ MLX5E_DECLARE_QOS_TX_STAT(struct mlx5e_sq_stats, mpwqe_pkts) },
#ifdef CONFIG_MLX5_EN_TLS
@@ -128,6 +128,8 @@ void mlx5e_stats_eth_ctrl_get(struct mlx5e_priv *priv,
void mlx5e_stats_rmon_get(struct mlx5e_priv *priv,
struct ethtool_rmon_stats *rmon,
const struct ethtool_rmon_hist_range **ranges);
void mlx5e_stats_ts_get(struct mlx5e_priv *priv,
struct ethtool_ts_stats *ts_stats);
void mlx5e_get_link_ext_stats(struct net_device *dev,
struct ethtool_link_ext_stats *stats);
@@ -431,6 +433,7 @@ struct mlx5e_sq_stats {
u64 stopped;
u64 dropped;
u64 recover;
u64 timestamps;
/* dirtied @completion */
u64 cqes ____cacheline_aligned_in_smp;
u64 wake;
@@ -463,6 +466,7 @@ struct mlx5e_ptp_cq_stats {
u64 abort;
u64 abort_abs_diff_ns;
u64 late_cqe;
u64 lost_cqe;
};
struct mlx5e_rep_stats {
@@ -749,11 +749,13 @@ static void mlx5e_consume_skb(struct mlx5e_txqsq *sq, struct sk_buff *skb,
u64 ts = get_cqe_ts(cqe);
hwts.hwtstamp = mlx5e_cqe_ts_to_ns(sq->ptp_cyc2time, sq->clock, ts);
if (sq->ptpsq)
if (sq->ptpsq) {
mlx5e_skb_cb_hwtstamp_handler(skb, MLX5E_SKB_CB_CQE_HWTSTAMP,
hwts.hwtstamp, sq->ptpsq->cq_stats);
else
} else {
skb_tstamp_tx(skb, &hwts);
sq->stats->timestamps++;
}
}
napi_consume_skb(skb, napi_budget);
+1 -1
View File
@@ -2,7 +2,7 @@
# Makefile for Linux PHY drivers
libphy-y := phy.o phy-c45.o phy-core.o phy_device.o \
linkmode.o
linkmode.o phy_link_topology.o
mdio-bus-y += mdio_bus.o mdio_device.o
ifdef CONFIG_MDIO_DEVICE
+2
View File
@@ -553,6 +553,8 @@ static const struct sfp_upstream_ops sfp_phy_ops = {
.link_down = mv2222_sfp_link_down,
.attach = phy_sfp_attach,
.detach = phy_sfp_detach,
.connect_phy = phy_sfp_connect_phy,
.disconnect_phy = phy_sfp_disconnect_phy,
};
static int mv2222_probe(struct phy_device *phydev)
+95
View File
@@ -281,6 +281,7 @@
#define MII_VCT_TXPINS 0x1A
#define MII_VCT_RXPINS 0x1B
#define MII_VCT_SR 0x1C
#define MII_VCT_TXPINS_ENVCT BIT(15)
#define MII_VCT_TXRXPINS_VCTTST GENMASK(14, 13)
#define MII_VCT_TXRXPINS_VCTTST_SHIFT 13
@@ -2623,6 +2624,92 @@ static int m88e3082_vct_cable_test_get_status(struct phy_device *phydev,
return 0;
}
static int m88e1111_vct_cable_test_start(struct phy_device *phydev)
{
int ret;
ret = marvell_cable_test_start_common(phydev);
if (ret)
return ret;
/* It needs some magic workarounds described in VCT manual for this PHY.
*/
ret = phy_write(phydev, 29, 0x0018);
if (ret < 0)
return ret;
ret = phy_write(phydev, 30, 0x00c2);
if (ret < 0)
return ret;
ret = phy_write(phydev, 30, 0x00ca);
if (ret < 0)
return ret;
ret = phy_write(phydev, 30, 0x00c2);
if (ret < 0)
return ret;
ret = phy_write_paged(phydev, MII_MARVELL_COPPER_PAGE, MII_VCT_SR,
MII_VCT_TXPINS_ENVCT);
if (ret < 0)
return ret;
ret = phy_write(phydev, 29, 0x0018);
if (ret < 0)
return ret;
ret = phy_write(phydev, 30, 0x0042);
if (ret < 0)
return ret;
return 0;
}
static u32 m88e1111_vct_distrfln_2_cm(u8 distrfln)
{
if (distrfln < 36)
return 0;
/* Original function for meters: y = 0.8018x - 28.751 */
return (8018 * distrfln - 287510) / 100;
}
static int m88e1111_vct_cable_test_get_status(struct phy_device *phydev,
bool *finished)
{
u8 vcttst_res, distrfln;
int ret, result;
*finished = false;
/* Each pair use one page: A-0, B-1, C-2, D-3 */
for (u8 i = 0; i < 4; i++) {
ret = phy_read_paged(phydev, i, MII_VCT_SR);
if (ret < 0)
return ret;
else if (i == 0 && ret & MII_VCT_TXPINS_ENVCT)
return 0;
distrfln = ret & MII_VCT_TXRXPINS_DISTRFLN;
vcttst_res = (ret & MII_VCT_TXRXPINS_VCTTST) >>
MII_VCT_TXRXPINS_VCTTST_SHIFT;
result = m88e3082_vct_cable_test_report_trans(vcttst_res,
distrfln);
ethnl_cable_test_result(phydev, i, result);
if (distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
u32 cm = m88e1111_vct_distrfln_2_cm(distrfln);
ethnl_cable_test_fault_length(phydev, i, cm);
}
}
*finished = true;
return 0;
}
#ifdef CONFIG_HWMON
struct marvell_hwmon_ops {
int (*config)(struct phy_device *phydev);
@@ -3463,6 +3550,8 @@ static const struct sfp_upstream_ops m88e1510_sfp_ops = {
.module_remove = m88e1510_sfp_remove,
.attach = phy_sfp_attach,
.detach = phy_sfp_detach,
.connect_phy = phy_sfp_connect_phy,
.disconnect_phy = phy_sfp_disconnect_phy,
};
static int m88e1510_probe(struct phy_device *phydev)
@@ -3534,6 +3623,7 @@ static struct phy_driver marvell_drivers[] = {
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "Marvell 88E1111",
/* PHY_GBIT_FEATURES */
.flags = PHY_POLL_CABLE_TEST,
.probe = marvell_probe,
.config_init = m88e1111gbe_config_init,
.config_aneg = m88e1111_config_aneg,
@@ -3549,6 +3639,8 @@ static struct phy_driver marvell_drivers[] = {
.get_stats = marvell_get_stats,
.get_tunable = m88e1111_get_tunable,
.set_tunable = m88e1111_set_tunable,
.cable_test_start = m88e1111_vct_cable_test_start,
.cable_test_get_status = m88e1111_vct_cable_test_get_status,
},
{
.phy_id = MARVELL_PHY_ID_88E1111_FINISAR,
@@ -3642,6 +3734,7 @@ static struct phy_driver marvell_drivers[] = {
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "Marvell 88E1145",
/* PHY_GBIT_FEATURES */
.flags = PHY_POLL_CABLE_TEST,
.probe = marvell_probe,
.config_init = m88e1145_config_init,
.config_aneg = m88e1101_config_aneg,
@@ -3656,6 +3749,8 @@ static struct phy_driver marvell_drivers[] = {
.get_stats = marvell_get_stats,
.get_tunable = m88e1111_get_tunable,
.set_tunable = m88e1111_set_tunable,
.cable_test_start = m88e1111_vct_cable_test_start,
.cable_test_get_status = m88e1111_vct_cable_test_get_status,
},
{
.phy_id = MARVELL_PHY_ID_88E1149R,
+2
View File
@@ -503,6 +503,8 @@ static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
static const struct sfp_upstream_ops mv3310_sfp_ops = {
.attach = phy_sfp_attach,
.detach = phy_sfp_detach,
.connect_phy = phy_sfp_connect_phy,
.disconnect_phy = phy_sfp_disconnect_phy,
.module_insert = mv3310_sfp_insert,
};
+55
View File
@@ -29,6 +29,7 @@
#include <linux/phy.h>
#include <linux/phylib_stubs.h>
#include <linux/phy_led_triggers.h>
#include <linux/phy_link_topology.h>
#include <linux/pse-pd/pse.h>
#include <linux/property.h>
#include <linux/rtnetlink.h>
@@ -276,6 +277,14 @@ static void phy_mdio_device_remove(struct mdio_device *mdiodev)
static struct phy_driver genphy_driver;
static struct phy_link_topology *phy_get_link_topology(struct phy_device *phydev)
{
if (phydev->attached_dev)
return phydev->attached_dev->link_topo;
return NULL;
}
static LIST_HEAD(phy_fixup_list);
static DEFINE_MUTEX(phy_fixup_lock);
@@ -1369,6 +1378,46 @@ phy_standalone_show(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RO(phy_standalone);
/**
* phy_sfp_connect_phy - Connect the SFP module's PHY to the upstream PHY
* @upstream: pointer to the upstream phy device
* @phy: pointer to the SFP module's phy device
*
* This helper allows keeping track of PHY devices on the link. It adds the
* SFP module's phy to the phy namespace of the upstream phy
*/
int phy_sfp_connect_phy(void *upstream, struct phy_device *phy)
{
struct phy_device *phydev = upstream;
struct phy_link_topology *topo = phy_get_link_topology(phydev);
if (topo)
return phy_link_topo_add_phy(topo, phy, PHY_UPSTREAM_PHY, phydev);
return 0;
}
EXPORT_SYMBOL(phy_sfp_connect_phy);
/**
* phy_sfp_disconnect_phy - Disconnect the SFP module's PHY from the upstream PHY
* @upstream: pointer to the upstream phy device
* @phy: pointer to the SFP module's phy device
*
* This helper allows keeping track of PHY devices on the link. It removes the
* SFP module's phy to the phy namespace of the upstream phy. As the module phy
* will be destroyed, re-inserting the same module will add a new phy with a
* new index.
*/
void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy)
{
struct phy_device *phydev = upstream;
struct phy_link_topology *topo = phy_get_link_topology(phydev);
if (topo)
phy_link_topo_del_phy(topo, phy);
}
EXPORT_SYMBOL(phy_sfp_disconnect_phy);
/**
* phy_sfp_attach - attach the SFP bus to the PHY upstream network device
* @upstream: pointer to the phy device
@@ -1511,6 +1560,11 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
if (phydev->sfp_bus_attached)
dev->sfp_bus = phydev->sfp_bus;
err = phy_link_topo_add_phy(dev->link_topo, phydev,
PHY_UPSTREAM_MAC, dev);
if (err)
goto error;
}
/* Some Ethernet drivers try to connect to a PHY device before
@@ -1938,6 +1992,7 @@ void phy_detach(struct phy_device *phydev)
if (dev) {
phydev->attached_dev->phydev = NULL;
phydev->attached_dev = NULL;
phy_link_topo_del_phy(dev->link_topo, phydev);
}
phydev->phylink = NULL;
+105
View File
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Infrastructure to handle all PHY devices connected to a given netdev,
* either directly or indirectly attached.
*
* Copyright (c) 2023 Maxime Chevallier<maxime.chevallier@bootlin.com>
*/
#include <linux/phy_link_topology.h>
#include <linux/netdevice.h>
#include <linux/phy.h>
#include <linux/rtnetlink.h>
#include <linux/xarray.h>
struct phy_link_topology *phy_link_topo_create(struct net_device *dev)
{
struct phy_link_topology *topo;
topo = kzalloc(sizeof(*topo), GFP_KERNEL);
if (!topo)
return ERR_PTR(-ENOMEM);
xa_init_flags(&topo->phys, XA_FLAGS_ALLOC1);
topo->next_phy_index = 1;
return topo;
}
void phy_link_topo_destroy(struct phy_link_topology *topo)
{
if (!topo)
return;
xa_destroy(&topo->phys);
kfree(topo);
}
int phy_link_topo_add_phy(struct phy_link_topology *topo,
struct phy_device *phy,
enum phy_upstream upt, void *upstream)
{
struct phy_device_node *pdn;
int ret;
pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
if (!pdn)
return -ENOMEM;
pdn->phy = phy;
switch (upt) {
case PHY_UPSTREAM_MAC:
pdn->upstream.netdev = (struct net_device *)upstream;
if (phy_on_sfp(phy))
pdn->parent_sfp_bus = pdn->upstream.netdev->sfp_bus;
break;
case PHY_UPSTREAM_PHY:
pdn->upstream.phydev = (struct phy_device *)upstream;
if (phy_on_sfp(phy))
pdn->parent_sfp_bus = pdn->upstream.phydev->sfp_bus;
break;
default:
ret = -EINVAL;
goto err;
}
pdn->upstream_type = upt;
/* Attempt to re-use a previously allocated phy_index */
if (phy->phyindex) {
ret = xa_insert(&topo->phys, phy->phyindex, pdn, GFP_KERNEL);
/* Errors could be either -ENOMEM or -EBUSY. If the phy has an
* index, and there's another entry at the same index, this is
* unexpected and we still error-out
*/
if (ret)
goto err;
return 0;
}
ret = xa_alloc_cyclic(&topo->phys, &phy->phyindex, pdn, xa_limit_32b,
&topo->next_phy_index, GFP_KERNEL);
if (ret)
goto err;
return 0;
err:
kfree(pdn);
return ret;
}
EXPORT_SYMBOL_GPL(phy_link_topo_add_phy);
void phy_link_topo_del_phy(struct phy_link_topology *topo,
struct phy_device *phy)
{
struct phy_device_node *pdn = xa_erase(&topo->phys, phy->phyindex);
/* We delete the PHY from the topology, however we don't re-set the
* phy->phyindex field. If the PHY isn't gone, we can re-assign it the
* same index next time it's added back to the topology
*/
kfree(pdn);
}
EXPORT_SYMBOL_GPL(phy_link_topo_del_phy);
+2 -1
View File
@@ -3408,7 +3408,8 @@ static int phylink_sfp_connect_phy(void *upstream, struct phy_device *phy)
return ret;
}
static void phylink_sfp_disconnect_phy(void *upstream)
static void phylink_sfp_disconnect_phy(void *upstream,
struct phy_device *phydev)
{
phylink_disconnect_phy(upstream);
}
+2
View File
@@ -770,6 +770,8 @@ static const struct sfp_upstream_ops at8031_sfp_ops = {
.attach = phy_sfp_attach,
.detach = phy_sfp_detach,
.module_insert = at8031_sfp_insert,
.connect_phy = phy_sfp_connect_phy,
.disconnect_phy = phy_sfp_disconnect_phy,
};
static int at8031_parse_dt(struct phy_device *phydev)
+2
View File
@@ -699,6 +699,8 @@ static const struct sfp_upstream_ops qca807x_sfp_ops = {
.detach = phy_sfp_detach,
.module_insert = qca807x_sfp_insert,
.module_remove = qca807x_sfp_remove,
.connect_phy = phy_sfp_connect_phy,
.disconnect_phy = phy_sfp_disconnect_phy,
};
static int qca807x_probe(struct phy_device *phydev)
+13 -2
View File
@@ -486,7 +486,7 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
bus->socket_ops->stop(bus->sfp);
bus->socket_ops->detach(bus->sfp);
if (bus->phydev && ops && ops->disconnect_phy)
ops->disconnect_phy(bus->upstream);
ops->disconnect_phy(bus->upstream, bus->phydev);
}
bus->registered = false;
}
@@ -742,7 +742,7 @@ void sfp_remove_phy(struct sfp_bus *bus)
const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
if (ops && ops->disconnect_phy)
ops->disconnect_phy(bus->upstream);
ops->disconnect_phy(bus->upstream, bus->phydev);
bus->phydev = NULL;
}
EXPORT_SYMBOL_GPL(sfp_remove_phy);
@@ -859,3 +859,14 @@ void sfp_unregister_socket(struct sfp_bus *bus)
sfp_bus_put(bus);
}
EXPORT_SYMBOL_GPL(sfp_unregister_socket);
const char *sfp_get_name(struct sfp_bus *bus)
{
ASSERT_RTNL();
if (bus->sfp_dev)
return dev_name(bus->sfp_dev);
return NULL;
}
EXPORT_SYMBOL_GPL(sfp_get_name);
+26 -1
View File
@@ -480,6 +480,26 @@ struct ethtool_rmon_stats {
);
};
/**
* struct ethtool_ts_stats - HW timestamping statistics
* @pkts: Number of packets successfully timestamped by the hardware.
* @lost: Number of hardware timestamping requests where the timestamping
* information from the hardware never arrived for submission with
* the skb.
* @err: Number of arbitrary timestamp generation error events that the
* hardware encountered, exclusive of @lost statistics. Cases such
* as resource exhaustion, unavailability, firmware errors, and
* detected illogical timestamp values not submitted with the skb
* are inclusive to this counter.
*/
struct ethtool_ts_stats {
struct_group(tx_stats,
u64 pkts;
u64 lost;
u64 err;
);
};
#define ETH_MODULE_EEPROM_PAGE_LEN 128
#define ETH_MODULE_MAX_I2C_ADDRESS 0x7f
@@ -755,7 +775,10 @@ struct ethtool_rxfh_param {
* @get_ts_info: Get the time stamping and PTP hardware clock capabilities.
* It may be called with RCU, or rtnl or reference on the device.
* Drivers supporting transmit time stamps in software should set this to
* ethtool_op_get_ts_info().
* ethtool_op_get_ts_info(). Drivers must not zero statistics which they
* don't report. The stats structure is initialized to ETHTOOL_STAT_NOT_SET
* indicating driver does not report statistics.
* @get_ts_stats: Query the device hardware timestamping statistics.
* @get_module_info: Get the size and type of the eeprom contained within
* a plug-in module.
* @get_module_eeprom: Get the eeprom information from the plug-in module
@@ -898,6 +921,8 @@ struct ethtool_ops {
struct ethtool_dump *, void *);
int (*set_dump)(struct net_device *, struct ethtool_dump *);
int (*get_ts_info)(struct net_device *, struct ethtool_ts_info *);
void (*get_ts_stats)(struct net_device *dev,
struct ethtool_ts_stats *ts_stats);
int (*get_module_info)(struct net_device *,
struct ethtool_modinfo *);
int (*get_module_eeprom)(struct net_device *,
+18 -2
View File
@@ -9817,7 +9817,21 @@ struct mlx5_ifc_pplm_reg_bits {
u8 fec_override_admin_100g_2x[0x10];
u8 fec_override_admin_50g_1x[0x10];
u8 reserved_at_140[0x140];
u8 fec_override_cap_800g_8x[0x10];
u8 fec_override_cap_400g_4x[0x10];
u8 fec_override_cap_200g_2x[0x10];
u8 fec_override_cap_100g_1x[0x10];
u8 reserved_at_180[0xa0];
u8 fec_override_admin_800g_8x[0x10];
u8 fec_override_admin_400g_4x[0x10];
u8 fec_override_admin_200g_2x[0x10];
u8 fec_override_admin_100g_1x[0x10];
u8 reserved_at_260[0x20];
};
struct mlx5_ifc_ppcnt_reg_bits {
@@ -10189,7 +10203,9 @@ struct mlx5_ifc_mtutc_reg_bits {
};
struct mlx5_ifc_pcam_enhanced_features_bits {
u8 reserved_at_0[0x68];
u8 reserved_at_0[0x48];
u8 fec_100G_per_lane_in_pplm[0x1];
u8 reserved_at_49[0x1f];
u8 fec_50G_per_lane_in_pplm[0x1];
u8 reserved_at_69[0x4];
u8 rx_icrc_encapsulated_counter[0x1];
+3 -1
View File
@@ -40,7 +40,6 @@
#include <net/dcbnl.h>
#endif
#include <net/netprio_cgroup.h>
#include <linux/netdev_features.h>
#include <linux/neighbour.h>
#include <uapi/linux/netdevice.h>
@@ -52,6 +51,7 @@
#include <net/net_trackers.h>
#include <net/net_debug.h>
#include <net/dropreason-core.h>
#include <linux/phy_link_topology_core.h>
struct netpoll_info;
struct device;
@@ -1974,6 +1974,7 @@ enum netdev_reg_state {
* @fcoe_ddp_xid: Max exchange id for FCoE LRO by ddp
*
* @priomap: XXX: need comments on this one
* @link_topo: Physical link topology tracking attached PHYs
* @phydev: Physical device may attach itself
* for hardware timestamping
* @sfp_bus: attached &struct sfp_bus structure.
@@ -2362,6 +2363,7 @@ struct net_device {
#if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
struct netprio_map __rcu *priomap;
#endif
struct phy_link_topology *link_topo;
struct phy_device *phydev;
struct sfp_bus *sfp_bus;
struct lock_class_key *qdisc_tx_busylock;
+6
View File
@@ -550,6 +550,9 @@ struct macsec_ops;
* @drv: Pointer to the driver for this PHY instance
* @devlink: Create a link between phy dev and mac dev, if the external phy
* used by current mac interface is managed by another mac interface.
* @phyindex: Unique id across the phy's parent tree of phys to address the PHY
* from userspace, similar to ifindex. A zero index means the PHY
* wasn't assigned an id yet.
* @phy_id: UID for this device found during discovery
* @c45_ids: 802.3-c45 Device Identifiers if is_c45.
* @is_c45: Set to true if this PHY uses clause 45 addressing.
@@ -650,6 +653,7 @@ struct phy_device {
struct device_link *devlink;
u32 phyindex;
u32 phy_id;
struct phy_c45_device_ids c45_ids;
@@ -1754,6 +1758,8 @@ int phy_suspend(struct phy_device *phydev);
int phy_resume(struct phy_device *phydev);
int __phy_resume(struct phy_device *phydev);
int phy_loopback(struct phy_device *phydev, bool enable);
int phy_sfp_connect_phy(void *upstream, struct phy_device *phy);
void phy_sfp_disconnect_phy(void *upstream, struct phy_device *phy);
void phy_sfp_attach(void *upstream, struct sfp_bus *bus);
void phy_sfp_detach(void *upstream, struct sfp_bus *bus);
int phy_sfp_probe(struct phy_device *phydev,
+72
View File
@@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* PHY device list allow maintaining a list of PHY devices that are
* part of a netdevice's link topology. PHYs can for example be chained,
* as is the case when using a PHY that exposes an SFP module, on which an
* SFP transceiver that embeds a PHY is connected.
*
* This list can then be used by userspace to leverage individual PHY
* capabilities.
*/
#ifndef __PHY_LINK_TOPOLOGY_H
#define __PHY_LINK_TOPOLOGY_H
#include <linux/ethtool.h>
#include <linux/phy_link_topology_core.h>
struct xarray;
struct phy_device;
struct net_device;
struct sfp_bus;
struct phy_device_node {
enum phy_upstream upstream_type;
union {
struct net_device *netdev;
struct phy_device *phydev;
} upstream;
struct sfp_bus *parent_sfp_bus;
struct phy_device *phy;
};
struct phy_link_topology {
struct xarray phys;
u32 next_phy_index;
};
static inline struct phy_device *
phy_link_topo_get_phy(struct phy_link_topology *topo, u32 phyindex)
{
struct phy_device_node *pdn = xa_load(&topo->phys, phyindex);
if (pdn)
return pdn->phy;
return NULL;
}
#if IS_REACHABLE(CONFIG_PHYLIB)
int phy_link_topo_add_phy(struct phy_link_topology *topo,
struct phy_device *phy,
enum phy_upstream upt, void *upstream);
void phy_link_topo_del_phy(struct phy_link_topology *lt, struct phy_device *phy);
#else
static inline int phy_link_topo_add_phy(struct phy_link_topology *topo,
struct phy_device *phy,
enum phy_upstream upt, void *upstream)
{
return 0;
}
static inline void phy_link_topo_del_phy(struct phy_link_topology *topo,
struct phy_device *phy)
{
}
#endif
#endif /* __PHY_LINK_TOPOLOGY_H */
+25
View File
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PHY_LINK_TOPOLOGY_CORE_H
#define __PHY_LINK_TOPOLOGY_CORE_H
struct phy_link_topology;
#if IS_REACHABLE(CONFIG_PHYLIB)
struct phy_link_topology *phy_link_topo_create(struct net_device *dev);
void phy_link_topo_destroy(struct phy_link_topology *topo);
#else
static inline struct phy_link_topology *phy_link_topo_create(struct net_device *dev)
{
return NULL;
}
static inline void phy_link_topo_destroy(struct phy_link_topology *topo)
{
}
#endif
#endif /* __PHY_LINK_TOPOLOGY_CORE_H */
+7 -1
View File
@@ -544,7 +544,7 @@ struct sfp_upstream_ops {
void (*link_down)(void *priv);
void (*link_up)(void *priv);
int (*connect_phy)(void *priv, struct phy_device *);
void (*disconnect_phy)(void *priv);
void (*disconnect_phy)(void *priv, struct phy_device *);
};
#if IS_ENABLED(CONFIG_SFP)
@@ -570,6 +570,7 @@ struct sfp_bus *sfp_bus_find_fwnode(const struct fwnode_handle *fwnode);
int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
const struct sfp_upstream_ops *ops);
void sfp_bus_del_upstream(struct sfp_bus *bus);
const char *sfp_get_name(struct sfp_bus *bus);
#else
static inline int sfp_parse_port(struct sfp_bus *bus,
const struct sfp_eeprom_id *id,
@@ -648,6 +649,11 @@ static inline int sfp_bus_add_upstream(struct sfp_bus *bus, void *upstream,
static inline void sfp_bus_del_upstream(struct sfp_bus *bus)
{
}
static inline const char *sfp_get_name(struct sfp_bus *bus)
{
return NULL;
}
#endif
#endif
+12 -3
View File
@@ -998,7 +998,7 @@ struct sk_buff {
#ifdef CONFIG_NETFILTER_SKIP_EGRESS
__u8 nf_skip_egress:1;
#endif
#ifdef CONFIG_TLS_DEVICE
#ifdef CONFIG_SKB_DECRYPTED
__u8 decrypted:1;
#endif
__u8 slow_gro:1;
@@ -1621,17 +1621,26 @@ static inline void skb_copy_hash(struct sk_buff *to, const struct sk_buff *from)
static inline int skb_cmp_decrypted(const struct sk_buff *skb1,
const struct sk_buff *skb2)
{
#ifdef CONFIG_TLS_DEVICE
#ifdef CONFIG_SKB_DECRYPTED
return skb2->decrypted - skb1->decrypted;
#else
return 0;
#endif
}
static inline bool skb_is_decrypted(const struct sk_buff *skb)
{
#ifdef CONFIG_SKB_DECRYPTED
return skb->decrypted;
#else
return false;
#endif
}
static inline void skb_copy_decrypted(struct sk_buff *to,
const struct sk_buff *from)
{
#ifdef CONFIG_TLS_DEVICE
#ifdef CONFIG_SKB_DECRYPTED
to->decrypted = from->decrypted;
#endif
}
+12 -2
View File
@@ -41,7 +41,8 @@
* nlmsg_get_pos() return current position in message
* nlmsg_trim() trim part of message
* nlmsg_cancel() cancel message construction
* nlmsg_free() free a netlink message
* nlmsg_consume() free a netlink message (expected)
* nlmsg_free() free a netlink message (drop)
*
* Message Sending:
* nlmsg_multicast() multicast message to several groups
@@ -1082,7 +1083,7 @@ static inline void nlmsg_cancel(struct sk_buff *skb, struct nlmsghdr *nlh)
}
/**
* nlmsg_free - free a netlink message
* nlmsg_free - drop a netlink message
* @skb: socket buffer of netlink message
*/
static inline void nlmsg_free(struct sk_buff *skb)
@@ -1090,6 +1091,15 @@ static inline void nlmsg_free(struct sk_buff *skb)
kfree_skb(skb);
}
/**
* nlmsg_consume - free a netlink message
* @skb: socket buffer of netlink message
*/
static inline void nlmsg_consume(struct sk_buff *skb)
{
consume_skb(skb);
}
/**
* nlmsg_multicast_filtered - multicast a netlink message with filter function
* @sk: netlink socket to spread messages to
+1 -3
View File
@@ -2837,12 +2837,10 @@ static inline struct sk_buff *sk_validate_xmit_skb(struct sk_buff *skb,
if (sk && sk_fullsock(sk) && sk->sk_validate_xmit_skb) {
skb = sk->sk_validate_xmit_skb(sk, dev, skb);
#ifdef CONFIG_TLS_DEVICE
} else if (unlikely(skb->decrypted)) {
} else if (unlikely(skb_is_decrypted(skb))) {
pr_warn_ratelimited("unencrypted skb with no associated socket - dropping\n");
kfree_skb(skb);
skb = NULL;
#endif
}
#endif
+1 -1
View File
@@ -25,7 +25,7 @@ TRACE_EVENT_CONDITION(mdio_access,
),
TP_fast_assign(
strncpy(__entry->busid, bus->id, MII_BUS_ID_SIZE);
strscpy(__entry->busid, bus->id, MII_BUS_ID_SIZE);
__entry->read = read;
__entry->addr = addr;
__entry->regnum = regnum;
+1 -1
View File
@@ -110,7 +110,7 @@ TRACE_EVENT(sock_exceed_buf_limit,
),
TP_fast_assign(
strncpy(__entry->name, prot->name, 32);
strscpy(__entry->name, prot->name, 32);
__entry->sysctl_mem[0] = READ_ONCE(prot->sysctl_mem[0]);
__entry->sysctl_mem[1] = READ_ONCE(prot->sysctl_mem[1]);
__entry->sysctl_mem[2] = READ_ONCE(prot->sysctl_mem[2]);
+16
View File
@@ -2268,4 +2268,20 @@ struct ethtool_link_settings {
* __u32 map_lp_advertising[link_mode_masks_nwords];
*/
};
/**
* enum phy_upstream - Represents the upstream component a given PHY device
* is connected to, as in what is on the other end of the MII bus. Most PHYs
* will be attached to an Ethernet MAC controller, but in some cases, there's
* an intermediate PHY used as a media-converter, which will driver another
* MII interface as its output.
* @PHY_UPSTREAM_MAC: Upstream component is a MAC (a switch port,
* or ethernet controller)
* @PHY_UPSTREAM_PHY: Upstream component is a PHY (likely a media converter)
*/
enum phy_upstream {
PHY_UPSTREAM_MAC,
PHY_UPSTREAM_PHY,
};
#endif /* _UAPI_LINUX_ETHTOOL_H */
+20 -6
View File
@@ -117,12 +117,11 @@ enum {
/* request header */
/* use compact bitsets in reply */
#define ETHTOOL_FLAG_COMPACT_BITSETS (1 << 0)
/* provide optional reply for SET or ACT requests */
#define ETHTOOL_FLAG_OMIT_REPLY (1 << 1)
/* request statistics, if supported by the driver */
#define ETHTOOL_FLAG_STATS (1 << 2)
enum ethtool_header_flags {
ETHTOOL_FLAG_COMPACT_BITSETS = 1 << 0, /* use compact bitsets in reply */
ETHTOOL_FLAG_OMIT_REPLY = 1 << 1, /* provide optional reply for SET or ACT requests */
ETHTOOL_FLAG_STATS = 1 << 2, /* request statistics, if supported by the driver */
};
#define ETHTOOL_FLAG_ALL (ETHTOOL_FLAG_COMPACT_BITSETS | \
ETHTOOL_FLAG_OMIT_REPLY | \
@@ -133,6 +132,7 @@ enum {
ETHTOOL_A_HEADER_DEV_INDEX, /* u32 */
ETHTOOL_A_HEADER_DEV_NAME, /* string */
ETHTOOL_A_HEADER_FLAGS, /* u32 - ETHTOOL_FLAG_* */
ETHTOOL_A_HEADER_PHY_INDEX, /* u32 */
/* add new constants above here */
__ETHTOOL_A_HEADER_CNT,
@@ -478,12 +478,26 @@ enum {
ETHTOOL_A_TSINFO_TX_TYPES, /* bitset */
ETHTOOL_A_TSINFO_RX_FILTERS, /* bitset */
ETHTOOL_A_TSINFO_PHC_INDEX, /* u32 */
ETHTOOL_A_TSINFO_STATS, /* nest - _A_TSINFO_STAT */
/* add new constants above here */
__ETHTOOL_A_TSINFO_CNT,
ETHTOOL_A_TSINFO_MAX = (__ETHTOOL_A_TSINFO_CNT - 1)
};
enum {
ETHTOOL_A_TS_STAT_UNSPEC,
ETHTOOL_A_TS_STAT_TX_PKTS, /* u64 */
ETHTOOL_A_TS_STAT_TX_LOST, /* u64 */
ETHTOOL_A_TS_STAT_TX_ERR, /* u64 */
/* add new constants above here */
__ETHTOOL_A_TS_STAT_CNT,
ETHTOOL_A_TS_STAT_MAX = (__ETHTOOL_A_TS_STAT_CNT - 1)
};
/* PHC VCLOCKS */
enum {
+3
View File
@@ -60,6 +60,9 @@ config NET_XGRESS
config NET_REDIRECT
bool
config SKB_DECRYPTED
bool
config SKB_EXTENSIONS
bool
+9
View File
@@ -159,6 +159,7 @@
#include <net/page_pool/helpers.h>
#include <net/rps.h>
#include <trace/hooks/net.h>
#include <linux/phy_link_topology_core.h>
#include "dev.h"
#include "net-sysfs.h"
@@ -10975,6 +10976,12 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
#ifdef CONFIG_NET_SCHED
hash_init(dev->qdisc_hash);
#endif
dev->link_topo = phy_link_topo_create(dev);
if (IS_ERR(dev->link_topo)) {
dev->link_topo = NULL;
goto free_all;
}
dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM;
setup(dev);
@@ -11063,6 +11070,8 @@ void free_netdev(struct net_device *dev)
free_percpu(dev->xdp_bulkq);
dev->xdp_bulkq = NULL;
phy_link_topo_destroy(dev->link_topo);
/* Compatibility with error handling in drivers */
if (dev->reg_state == NETREG_UNINITIALIZED) {
netdev_freemem(dev);
+2 -3
View File
@@ -2526,13 +2526,12 @@ EXPORT_SYMBOL(skb_set_owner_w);
static bool can_skb_orphan_partial(const struct sk_buff *skb)
{
#ifdef CONFIG_TLS_DEVICE
/* Drivers depend on in-order delivery for crypto offload,
* partial orphan breaks out-of-order-OK logic.
*/
if (skb->decrypted)
if (skb_is_decrypted(skb))
return false;
#endif
return (skb->destructor == sock_wfree ||
(IS_ENABLED(CONFIG_INET) && skb->destructor == tcp_wfree));
}
+1 -1
View File
@@ -1214,7 +1214,7 @@ static void __devlink_compat_running_version(struct devlink *devlink,
}
}
free_msg:
nlmsg_free(msg);
nlmsg_consume(msg);
}
void devlink_compat_running_version(struct devlink *devlink,
+46 -2
View File
@@ -4,6 +4,7 @@
#include <linux/ethtool_netlink.h>
#include <linux/pm_runtime.h>
#include "netlink.h"
#include <linux/phy_link_topology.h>
static struct genl_family ethtool_genl_family;
@@ -30,6 +31,24 @@ const struct nla_policy ethnl_header_policy_stats[] = {
ETHTOOL_FLAGS_STATS),
};
const struct nla_policy ethnl_header_policy_phy[] = {
[ETHTOOL_A_HEADER_DEV_INDEX] = { .type = NLA_U32 },
[ETHTOOL_A_HEADER_DEV_NAME] = { .type = NLA_NUL_STRING,
.len = ALTIFNAMSIZ - 1 },
[ETHTOOL_A_HEADER_FLAGS] = NLA_POLICY_MASK(NLA_U32,
ETHTOOL_FLAGS_BASIC),
[ETHTOOL_A_HEADER_PHY_INDEX] = NLA_POLICY_MIN(NLA_U32, 1),
};
const struct nla_policy ethnl_header_policy_phy_stats[] = {
[ETHTOOL_A_HEADER_DEV_INDEX] = { .type = NLA_U32 },
[ETHTOOL_A_HEADER_DEV_NAME] = { .type = NLA_NUL_STRING,
.len = ALTIFNAMSIZ - 1 },
[ETHTOOL_A_HEADER_FLAGS] = NLA_POLICY_MASK(NLA_U32,
ETHTOOL_FLAGS_STATS),
[ETHTOOL_A_HEADER_PHY_INDEX] = NLA_POLICY_MIN(NLA_U32, 1),
};
int ethnl_ops_begin(struct net_device *dev)
{
int ret;
@@ -89,8 +108,9 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
const struct nlattr *header, struct net *net,
struct netlink_ext_ack *extack, bool require_dev)
{
struct nlattr *tb[ARRAY_SIZE(ethnl_header_policy)];
struct nlattr *tb[ARRAY_SIZE(ethnl_header_policy_phy)];
const struct nlattr *devname_attr;
struct phy_device *phydev = NULL;
struct net_device *dev = NULL;
u32 flags = 0;
int ret;
@@ -104,7 +124,7 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
/* No validation here, command policy should have a nested policy set
* for the header, therefore validation should have already been done.
*/
ret = nla_parse_nested(tb, ARRAY_SIZE(ethnl_header_policy) - 1, header,
ret = nla_parse_nested(tb, ARRAY_SIZE(ethnl_header_policy_phy) - 1, header,
NULL, extack);
if (ret < 0)
return ret;
@@ -145,6 +165,30 @@ int ethnl_parse_header_dev_get(struct ethnl_req_info *req_info,
return -EINVAL;
}
if (dev) {
if (tb[ETHTOOL_A_HEADER_PHY_INDEX]) {
struct nlattr *phy_id;
phy_id = tb[ETHTOOL_A_HEADER_PHY_INDEX];
phydev = phy_link_topo_get_phy(dev->link_topo,
nla_get_u32(phy_id));
if (!phydev) {
NL_SET_BAD_ATTR(extack, phy_id);
return -ENODEV;
}
} else {
/* If we need a PHY but no phy index is specified, fallback
* to dev->phydev
*/
phydev = dev->phydev;
}
} else if (tb[ETHTOOL_A_HEADER_PHY_INDEX]) {
NL_SET_ERR_MSG_ATTR(extack, header,
"can't target a PHY without a netdev");
return -EINVAL;
}
req_info->phydev = phydev;
req_info->dev = dev;
req_info->flags = flags;
return 0;
+5
View File
@@ -250,6 +250,7 @@ static inline unsigned int ethnl_reply_header_size(void)
* @dev: network device the request is for (may be null)
* @dev_tracker: refcount tracker for @dev reference
* @flags: request flags common for all request types
* @phydev: phy_device connected to @dev this request is for (may be null)
*
* This is a common base for request specific structures holding data from
* parsed userspace request. These always embed struct ethnl_req_info at
@@ -259,6 +260,7 @@ struct ethnl_req_info {
struct net_device *dev;
netdevice_tracker dev_tracker;
u32 flags;
struct phy_device *phydev;
};
static inline void ethnl_parse_header_dev_put(struct ethnl_req_info *req_info)
@@ -395,9 +397,12 @@ extern const struct ethnl_request_ops ethnl_rss_request_ops;
extern const struct ethnl_request_ops ethnl_plca_cfg_request_ops;
extern const struct ethnl_request_ops ethnl_plca_status_request_ops;
extern const struct ethnl_request_ops ethnl_mm_request_ops;
extern const struct ethnl_request_ops ethnl_phy_request_ops;
extern const struct nla_policy ethnl_header_policy[ETHTOOL_A_HEADER_FLAGS + 1];
extern const struct nla_policy ethnl_header_policy_stats[ETHTOOL_A_HEADER_FLAGS + 1];
extern const struct nla_policy ethnl_header_policy_phy[ETHTOOL_A_HEADER_PHY_INDEX + 1];
extern const struct nla_policy ethnl_header_policy_phy_stats[ETHTOOL_A_HEADER_PHY_INDEX + 1];
extern const struct nla_policy ethnl_strset_get_policy[ETHTOOL_A_STRSET_COUNTS_ONLY + 1];
extern const struct nla_policy ethnl_linkinfo_get_policy[ETHTOOL_A_LINKINFO_HEADER + 1];
extern const struct nla_policy ethnl_linkinfo_set_policy[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL + 1];
+51 -1
View File
@@ -13,14 +13,18 @@ struct tsinfo_req_info {
struct tsinfo_reply_data {
struct ethnl_reply_data base;
struct ethtool_ts_info ts_info;
struct ethtool_ts_stats stats;
};
#define TSINFO_REPDATA(__reply_base) \
container_of(__reply_base, struct tsinfo_reply_data, base)
#define ETHTOOL_TS_STAT_CNT \
(__ETHTOOL_A_TS_STAT_CNT - (ETHTOOL_A_TS_STAT_UNSPEC + 1))
const struct nla_policy ethnl_tsinfo_get_policy[] = {
[ETHTOOL_A_TSINFO_HEADER] =
NLA_POLICY_NESTED(ethnl_header_policy),
NLA_POLICY_NESTED(ethnl_header_policy_stats),
};
static int tsinfo_prepare_data(const struct ethnl_req_info *req_base,
@@ -34,6 +38,12 @@ static int tsinfo_prepare_data(const struct ethnl_req_info *req_base,
ret = ethnl_ops_begin(dev);
if (ret < 0)
return ret;
if (req_base->flags & ETHTOOL_FLAG_STATS &&
dev->ethtool_ops->get_ts_stats) {
ethtool_stats_init((u64 *)&data->stats,
sizeof(data->stats) / sizeof(u64));
dev->ethtool_ops->get_ts_stats(dev, &data->stats);
}
ret = __ethtool_get_ts_info(dev, &data->ts_info);
ethnl_ops_complete(dev);
@@ -79,10 +89,47 @@ static int tsinfo_reply_size(const struct ethnl_req_info *req_base,
}
if (ts_info->phc_index >= 0)
len += nla_total_size(sizeof(u32)); /* _TSINFO_PHC_INDEX */
if (req_base->flags & ETHTOOL_FLAG_STATS)
len += nla_total_size(0) + /* _TSINFO_STATS */
nla_total_size_64bit(sizeof(u64)) * ETHTOOL_TS_STAT_CNT;
return len;
}
static int tsinfo_put_stat(struct sk_buff *skb, u64 val, u16 attrtype)
{
if (val == ETHTOOL_STAT_NOT_SET)
return 0;
if (nla_put_uint(skb, attrtype, val))
return -EMSGSIZE;
return 0;
}
static int tsinfo_put_stats(struct sk_buff *skb,
const struct ethtool_ts_stats *stats)
{
struct nlattr *nest;
nest = nla_nest_start(skb, ETHTOOL_A_TSINFO_STATS);
if (!nest)
return -EMSGSIZE;
if (tsinfo_put_stat(skb, stats->tx_stats.pkts,
ETHTOOL_A_TS_STAT_TX_PKTS) ||
tsinfo_put_stat(skb, stats->tx_stats.lost,
ETHTOOL_A_TS_STAT_TX_LOST) ||
tsinfo_put_stat(skb, stats->tx_stats.err,
ETHTOOL_A_TS_STAT_TX_ERR))
goto err_cancel;
nla_nest_end(skb, nest);
return 0;
err_cancel:
nla_nest_cancel(skb, nest);
return -EMSGSIZE;
}
static int tsinfo_fill_reply(struct sk_buff *skb,
const struct ethnl_req_info *req_base,
const struct ethnl_reply_data *reply_base)
@@ -119,6 +166,9 @@ static int tsinfo_fill_reply(struct sk_buff *skb,
if (ts_info->phc_index >= 0 &&
nla_put_u32(skb, ETHTOOL_A_TSINFO_PHC_INDEX, ts_info->phc_index))
return -EMSGSIZE;
if (req_base->flags & ETHTOOL_FLAG_STATS &&
tsinfo_put_stats(skb, &data->stats))
return -EMSGSIZE;
return 0;
}
+2 -1
View File
@@ -462,7 +462,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb)
}
/* Try to redo what tcp_v4_send_synack did. */
req->rsk_window_clamp = tp->window_clamp ? :dst_metric(&rt->dst, RTAX_WINDOW);
req->rsk_window_clamp = READ_ONCE(tp->window_clamp) ? :
dst_metric(&rt->dst, RTAX_WINDOW);
/* limit the window selection if the user enforce a smaller rx buffer */
full_space = tcp_full_space(sk);
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
+4 -4
View File
@@ -1721,7 +1721,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val)
space = tcp_space_from_win(sk, val);
if (space > sk->sk_rcvbuf) {
WRITE_ONCE(sk->sk_rcvbuf, space);
tcp_sk(sk)->window_clamp = val;
WRITE_ONCE(tcp_sk(sk)->window_clamp, val);
}
return 0;
}
@@ -3379,7 +3379,7 @@ int tcp_set_window_clamp(struct sock *sk, int val)
if (!val) {
if (sk->sk_state != TCP_CLOSE)
return -EINVAL;
tp->window_clamp = 0;
WRITE_ONCE(tp->window_clamp, 0);
} else {
u32 new_rcv_ssthresh, old_window_clamp = tp->window_clamp;
u32 new_window_clamp = val < SOCK_MIN_RCVBUF / 2 ?
@@ -3388,7 +3388,7 @@ int tcp_set_window_clamp(struct sock *sk, int val)
if (new_window_clamp == old_window_clamp)
return 0;
tp->window_clamp = new_window_clamp;
WRITE_ONCE(tp->window_clamp, new_window_clamp);
if (new_window_clamp < old_window_clamp) {
/* need to apply the reserved mem provisioning only
* when shrinking the window clamp
@@ -4057,7 +4057,7 @@ int do_tcp_getsockopt(struct sock *sk, int level,
TCP_RTO_MAX / HZ);
break;
case TCP_WINDOW_CLAMP:
val = tp->window_clamp;
val = READ_ONCE(tp->window_clamp);
break;
case TCP_INFO: {
struct tcp_info info;
+13 -16
View File
@@ -563,19 +563,20 @@ static void tcp_init_buffer_space(struct sock *sk)
maxwin = tcp_full_space(sk);
if (tp->window_clamp >= maxwin) {
tp->window_clamp = maxwin;
WRITE_ONCE(tp->window_clamp, maxwin);
if (tcp_app_win && maxwin > 4 * tp->advmss)
tp->window_clamp = max(maxwin -
(maxwin >> tcp_app_win),
4 * tp->advmss);
WRITE_ONCE(tp->window_clamp,
max(maxwin - (maxwin >> tcp_app_win),
4 * tp->advmss));
}
/* Force reservation of one segment. */
if (tcp_app_win &&
tp->window_clamp > 2 * tp->advmss &&
tp->window_clamp + tp->advmss > maxwin)
tp->window_clamp = max(2 * tp->advmss, maxwin - tp->advmss);
WRITE_ONCE(tp->window_clamp,
max(2 * tp->advmss, maxwin - tp->advmss));
tp->rcv_ssthresh = min(tp->rcv_ssthresh, tp->window_clamp);
tp->snd_cwnd_stamp = tcp_jiffies32;
@@ -773,7 +774,8 @@ void tcp_rcv_space_adjust(struct sock *sk)
WRITE_ONCE(sk->sk_rcvbuf, rcvbuf);
/* Make the window clamp follow along. */
tp->window_clamp = tcp_win_from_space(sk, rcvbuf);
WRITE_ONCE(tp->window_clamp,
tcp_win_from_space(sk, rcvbuf));
}
}
tp->rcvq_space.space = copied;
@@ -4803,10 +4805,8 @@ static bool tcp_try_coalesce(struct sock *sk,
if (!mptcp_skb_can_collapse(to, from))
return false;
#ifdef CONFIG_TLS_DEVICE
if (from->decrypted != to->decrypted)
if (skb_cmp_decrypted(from, to))
return false;
#endif
if (!skb_try_coalesce(to, from, fragstolen, &delta))
return false;
@@ -5375,9 +5375,7 @@ restart:
break;
memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
#ifdef CONFIG_TLS_DEVICE
nskb->decrypted = skb->decrypted;
#endif
skb_copy_decrypted(nskb, skb);
TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
if (list)
__skb_queue_before(list, skb, nskb);
@@ -5407,10 +5405,8 @@ restart:
!mptcp_skb_can_collapse(nskb, skb) ||
(TCP_SKB_CB(skb)->tcp_flags & (TCPHDR_SYN | TCPHDR_FIN)))
goto end;
#ifdef CONFIG_TLS_DEVICE
if (skb->decrypted != nskb->decrypted)
if (skb_cmp_decrypted(skb, nskb))
goto end;
#endif
}
}
}
@@ -6426,7 +6422,8 @@ consume:
if (!tp->rx_opt.wscale_ok) {
tp->rx_opt.snd_wscale = tp->rx_opt.rcv_wscale = 0;
tp->window_clamp = min(tp->window_clamp, 65535U);
WRITE_ONCE(tp->window_clamp,
min(tp->window_clamp, 65535U));
}
if (tp->rx_opt.saw_tstamp) {
+1 -3
View File
@@ -2050,10 +2050,8 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
TCP_SKB_CB(skb)->tcp_flags) & TCPHDR_ACK) ||
((TCP_SKB_CB(tail)->tcp_flags ^
TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_ECE | TCPHDR_CWR)) ||
#ifdef CONFIG_TLS_DEVICE
tail->decrypted != skb->decrypted ||
#endif
!mptcp_skb_can_collapse(tail, skb) ||
skb_cmp_decrypted(tail, skb) ||
thtail->doff != th->doff ||
memcmp(thtail + 1, th + 1, hdrlen - sizeof(*th)))
goto no_coalesce;
+1 -3
View File
@@ -265,9 +265,7 @@ found:
flush |= (len - 1) >= mss;
flush |= (ntohl(th2->seq) + skb_gro_len(p)) ^ ntohl(th->seq);
#ifdef CONFIG_TLS_DEVICE
flush |= p->decrypted ^ skb->decrypted;
#endif
flush |= skb_cmp_decrypted(p, skb);
if (flush || skb_gro_receive(p, skb)) {
mss = 1;
+10 -8
View File
@@ -203,16 +203,17 @@ static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt)
* This MUST be enforced by all callers.
*/
void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss,
__u32 *rcv_wnd, __u32 *window_clamp,
__u32 *rcv_wnd, __u32 *__window_clamp,
int wscale_ok, __u8 *rcv_wscale,
__u32 init_rcv_wnd)
{
unsigned int space = (__space < 0 ? 0 : __space);
u32 window_clamp = READ_ONCE(*__window_clamp);
/* If no clamp set the clamp to the max possible scaled window */
if (*window_clamp == 0)
(*window_clamp) = (U16_MAX << TCP_MAX_WSCALE);
space = min(*window_clamp, space);
if (window_clamp == 0)
window_clamp = (U16_MAX << TCP_MAX_WSCALE);
space = min(window_clamp, space);
/* Quantize space offering to a multiple of mss if possible. */
if (space > mss)
@@ -239,12 +240,13 @@ void tcp_select_initial_window(const struct sock *sk, int __space, __u32 mss,
/* Set window scaling on max possible window */
space = max_t(u32, space, READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_rmem[2]));
space = max_t(u32, space, READ_ONCE(sysctl_rmem_max));
space = min_t(u32, space, *window_clamp);
space = min_t(u32, space, window_clamp);
*rcv_wscale = clamp_t(int, ilog2(space) - 15,
0, TCP_MAX_WSCALE);
}
/* Set the clamp no higher than max representable value */
(*window_clamp) = min_t(__u32, U16_MAX << (*rcv_wscale), *window_clamp);
WRITE_ONCE(*__window_clamp,
min_t(__u32, U16_MAX << (*rcv_wscale), window_clamp));
}
EXPORT_SYMBOL(tcp_select_initial_window);
@@ -3857,7 +3859,7 @@ static void tcp_connect_init(struct sock *sk)
tcp_ca_dst_init(sk, dst);
if (!tp->window_clamp)
tp->window_clamp = dst_metric(dst, RTAX_WINDOW);
WRITE_ONCE(tp->window_clamp, dst_metric(dst, RTAX_WINDOW));
tp->advmss = tcp_mss_clamp(tp, dst_metric_advmss(dst));
tcp_initialize_rcv_mss(sk);
@@ -3865,7 +3867,7 @@ static void tcp_connect_init(struct sock *sk)
/* limit the window selection if the user enforce a smaller rx buffer */
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
(tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0))
tp->window_clamp = tcp_full_space(sk);
WRITE_ONCE(tp->window_clamp, tcp_full_space(sk));
rcv_wnd = tcp_rwnd_init_bpf(sk);
if (rcv_wnd == 0)
+1 -1
View File
@@ -246,7 +246,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
}
}
req->rsk_window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
req->rsk_window_clamp = READ_ONCE(tp->window_clamp) ? :dst_metric(dst, RTAX_WINDOW);
/* limit the window selection if the user enforce a smaller rx buffer */
full_space = tcp_full_space(sk);
if (sk->sk_userlocks & SOCK_RCVBUF_LOCK &&
+1 -1
View File
@@ -2056,7 +2056,7 @@ static void mptcp_rcv_space_adjust(struct mptcp_sock *msk, int copied)
ssk = mptcp_subflow_tcp_sock(subflow);
slow = lock_sock_fast(ssk);
WRITE_ONCE(ssk->sk_rcvbuf, rcvbuf);
tcp_sk(ssk)->window_clamp = window_clamp;
WRITE_ONCE(tcp_sk(ssk)->window_clamp, window_clamp);
tcp_cleanup_rbuf(ssk, 1);
unlock_sock_fast(ssk, slow);
}
+1 -1
View File
@@ -1523,7 +1523,7 @@ int mptcp_set_rcvlowat(struct sock *sk, int val)
slow = lock_sock_fast(ssk);
WRITE_ONCE(ssk->sk_rcvbuf, space);
tcp_sk(ssk)->window_clamp = val;
WRITE_ONCE(tcp_sk(ssk)->window_clamp, val);
unlock_sock_fast(ssk, slow);
}
return 0;
+1
View File
@@ -20,6 +20,7 @@ config TLS
config TLS_DEVICE
bool "Transport Layer Security HW offload"
depends on TLS
select SKB_DECRYPTED
select SOCK_VALIDATE_XMIT
select SOCK_RX_QUEUE_MAPPING
default n
+10 -1
View File
@@ -324,7 +324,13 @@ def main():
return
if args.show_time_stamping:
tsinfo = dumpit(ynl, args, 'tsinfo-get')
req = {
'header': {
'flags': 'stats',
},
}
tsinfo = dumpit(ynl, args, 'tsinfo-get', req)
print(f'Time stamping parameters for {args.device}:')
@@ -338,6 +344,9 @@ def main():
print('Hardware Receive Filter Modes:')
[print(f'\t{v}') for v in bits_to_dict(tsinfo['rx-filters'])]
print('Statistics:')
[print(f'\t{k}: {v}') for k, v in tsinfo['stats'].items()]
return
print(f'Settings for {args.device}:')
+18 -5
View File
@@ -632,15 +632,28 @@ class YnlFamily(SpecFamily):
decoded = self._formatted_string(decoded, attr_spec.display_hint)
return decoded
def _decode_array_nest(self, attr, attr_spec):
def _decode_array_attr(self, attr, attr_spec):
decoded = []
offset = 0
while offset < len(attr.raw):
item = NlAttr(attr.raw, offset)
offset += item.full_len
subattrs = self._decode(NlAttrs(item.raw), attr_spec['nested-attributes'])
decoded.append({ item.type: subattrs })
if attr_spec["sub-type"] == 'nest':
subattrs = self._decode(NlAttrs(item.raw), attr_spec['nested-attributes'])
decoded.append({ item.type: subattrs })
elif attr_spec["sub-type"] == 'binary':
subattrs = item.as_bin()
if attr_spec.display_hint:
subattrs = self._formatted_string(subattrs, attr_spec.display_hint)
decoded.append(subattrs)
elif attr_spec["sub-type"] in NlAttr.type_formats:
subattrs = item.as_scalar(attr_spec['sub-type'], attr_spec.byte_order)
if attr_spec.display_hint:
subattrs = self._formatted_string(subattrs, attr_spec.display_hint)
decoded.append(subattrs)
else:
raise Exception(f'Unknown {attr_spec["sub-type"]} with name {attr_spec["name"]}')
return decoded
def _decode_nest_type_value(self, attr, attr_spec):
@@ -734,8 +747,8 @@ class YnlFamily(SpecFamily):
decoded = attr.as_scalar(attr_spec['type'], attr_spec.byte_order)
if 'enum' in attr_spec:
decoded = self._decode_enum(decoded, attr_spec)
elif attr_spec["type"] == 'array-nest':
decoded = self._decode_array_nest(attr, attr_spec)
elif attr_spec["type"] == 'indexed-array':
decoded = self._decode_array_attr(attr, attr_spec)
elif attr_spec["type"] == 'bitfield32':
value, selector = struct.unpack("II", attr.raw)
if 'enum' in attr_spec:
+12 -6
View File
@@ -841,8 +841,11 @@ class AttrSet(SpecAttrSet):
t = TypeBitfield32(self.family, self, elem, value)
elif elem['type'] == 'nest':
t = TypeNest(self.family, self, elem, value)
elif elem['type'] == 'array-nest':
t = TypeArrayNest(self.family, self, elem, value)
elif elem['type'] == 'indexed-array' and 'sub-type' in elem:
if elem["sub-type"] == 'nest':
t = TypeArrayNest(self.family, self, elem, value)
else:
raise Exception(f'new_attr: unsupported sub-type {elem["sub-type"]}')
elif elem['type'] == 'nest-type-value':
t = TypeNestTypeValue(self.family, self, elem, value)
else:
@@ -1055,7 +1058,7 @@ class Family(SpecFamily):
if nested in self.root_sets:
raise Exception("Inheriting members to a space used as root not supported")
inherit.update(set(spec['type-value']))
elif spec['type'] == 'array-nest':
elif spec['type'] == 'indexed-array':
inherit.add('idx')
self.pure_nested_structs[nested].set_inherited(inherit)
@@ -1619,9 +1622,12 @@ def _multi_parse(ri, struct, init_lines, local_vars):
multi_attrs = set()
needs_parg = False
for arg, aspec in struct.member_list():
if aspec['type'] == 'array-nest':
local_vars.append(f'const struct nlattr *attr_{aspec.c_name};')
array_nests.add(arg)
if aspec['type'] == 'indexed-array' and 'sub-type' in aspec:
if aspec["sub-type"] == 'nest':
local_vars.append(f'const struct nlattr *attr_{aspec.c_name};')
array_nests.add(arg)
else:
raise Exception(f'Not supported sub-type {aspec["sub-type"]}')
if 'multi-attr' in aspec:
multi_attrs.add(arg)
needs_parg |= 'nested-attributes' in aspec