linux/drivers/net/ethernet/freescale
Vladimir Oltean 29d98f54a4 net: enetc: allow hardware timestamping on TX queues with tc-etf enabled
The txtime is passed to the driver in skb->skb_mstamp_ns, which is
actually in a union with skb->tstamp (the place where software
timestamps are kept).

Since commit b50a5c70ff ("net: allow simultaneous SW and HW transmit
timestamping"), __sock_recv_timestamp has some logic for making sure
that the two calls to skb_tstamp_tx:

skb_tx_timestamp(skb) # Software timestamp in the driver
-> skb_tstamp_tx(skb, NULL)

and

skb_tstamp_tx(skb, &shhwtstamps) # Hardware timestamp in the driver

will both do the right thing and in a race-free manner, meaning that
skb_tx_timestamp will deliver a cmsg with the software timestamp only,
and skb_tstamp_tx with a non-NULL hwtstamps argument will deliver a cmsg
with the hardware timestamp only.

Why are races even possible? Well, because although the software timestamp
skb->tstamp is private per skb, the hardware timestamp skb_hwtstamps(skb)
lives in skb_shinfo(skb), an area which is shared between skbs and their
clones. And skb_tstamp_tx works by cloning the packets when timestamping
them, therefore attempting to perform hardware timestamping on an skb's
clone will also change the hardware timestamp of the original skb. And
the original skb might have been yet again cloned for software
timestamping, at an earlier stage.

So the logic in __sock_recv_timestamp can't be as simple as saying
"does this skb have a hardware timestamp? if yes I'll send the hardware
timestamp to the socket, otherwise I'll send the software timestamp",
precisely because the hardware timestamp is shared.
Instead, it's quite the other way around: __sock_recv_timestamp says
"does this skb have a software timestamp? if yes, I'll send the software
timestamp, otherwise the hardware one". This works because the software
timestamp is not shared with clones.

But that means we have a problem when we attempt hardware timestamping
with skbs that don't have the skb->tstamp == 0. __sock_recv_timestamp
will say "oh, yeah, this must be some sort of odd clone" and will not
deliver the hardware timestamp to the socket. And this is exactly what
is happening when we have txtime enabled on the socket: as mentioned,
that is put in a union with skb->tstamp, so it is quite easy to mistake
it.

Do what other drivers do (intel igb/igc) and write zero to skb->tstamp
before taking the hardware timestamp. It's of no use to us now (we're
already on the TX confirmation path).

Fixes: 0d08c9ec7d ("enetc: add support time specific departure base on the qos etf")
Cc: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-03-08 12:03:42 -08:00
..
dpaa dpaa_eth: fix the access method for the dpaa_napi_portal 2021-02-22 17:54:39 -08:00
dpaa2 Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2021-02-16 17:51:13 -08:00
enetc net: enetc: allow hardware timestamping on TX queues with tc-etf enabled 2021-03-08 12:03:42 -08:00
fman fsl/fman: Add MII mode support. 2021-01-12 20:03:49 -08:00
fs_enet net: ethernet: fs_enet: Add missing MODULE_LICENSE 2021-01-05 16:56:35 -08:00
fec_main.c net: fec: Silence M5272 build warnings 2021-02-02 19:02:26 -08:00
fec_mpc52xx_phy.c
fec_mpc52xx.c net: fec_mpc52xx: Replace in_interrupt() usage 2020-09-29 14:02:54 -07:00
fec_mpc52xx.h
fec_ptp.c net: fec: ptp: avoid register access when ipg clock is disabled 2021-02-26 15:45:18 -08:00
fec.h net: fec: Fix temporary RMII clock reset on link up 2021-01-26 18:24:39 -08:00
fsl_pq_mdio.c net: freescale: convert comma to semicolon 2020-12-09 16:23:08 -08:00
gianfar_ethtool.c net: gianfar: reject unsupported coalescing params 2020-03-12 11:32:35 -07:00
gianfar.c gianfar: fix jumbo packets+napi+rx overrun crash 2021-03-05 13:13:32 -08:00
gianfar.h net/freescale: Clean drivers from static versions 2020-03-03 17:54:55 -08:00
Kconfig ethernet: select CONFIG_CRC32 as needed 2020-12-04 14:42:21 -08:00
Makefile net: dsa: felix: fix link error 2020-01-08 16:05:54 -08:00
ucc_geth_ethtool.c net/freescale: Don't set zero if FW not-available in ucc_geth 2020-03-03 17:54:55 -08:00
ucc_geth.c ethernet: ucc_geth: simplify rx/tx allocations 2021-01-21 12:19:56 -08:00
ucc_geth.h ethernet: ucc_geth: simplify rx/tx allocations 2021-01-21 12:19:56 -08:00
xgmac_mdio.c net/fsl: quieten expected MDIO access failures 2020-09-24 20:13:26 -07:00