Skip to content

Commit 77a7811

Browse files
jacob-kelleranguy11
authored andcommitted
ice: enable receive hardware timestamping
Add SIOCGHWTSTAMP and SIOCSHWTSTAMP ioctl handlers to respond to requests to enable timestamping support. If the request is for enabling Rx timestamps, set a bit in the Rx descriptors to indicate that receive timestamps should be reported. Hardware captures receive timestamps in the PHY which only captures part of the timer, and reports only 40 bits into the Rx descriptor. The upper 32 bits represent the contents of GLTSYN_TIME_L at the point of packet reception, while the lower 8 bits represent the upper 8 bits of GLTSYN_TIME_0. The networking and PTP stack expect 64 bit timestamps in nanoseconds. To support this, implement some logic to extend the timestamps by using the full PHC time. If the Rx timestamp was captured prior to the PHC time, then the real timestamp is PHC - (lower_32_bits(PHC) - timestamp) If the Rx timestamp was captured after the PHC time, then the real timestamp is PHC + (timestamp - lower_32_bits(PHC)) These calculations are correct as long as neither the PHC timestamp nor the Rx timestamps are more than 2^32-1 nanseconds old. Further, we can detect when the Rx timestamp is before or after the PHC as long as the PHC timestamp is no more than 2^31-1 nanoseconds old. In that case, we calculate the delta between the lower 32 bits of the PHC and the Rx timestamp. If it's larger than 2^31-1 then the Rx timestamp must have been captured in the past. If it's smaller, then the Rx timestamp must have been captured after PHC time. Add an ice_ptp_extend_32b_ts function that relies on a cached copy of the PHC time and implements this algorithm to calculate the proper upper 32bits of the Rx timestamps. Cache the PHC time periodically in all of the Rx rings. This enables each Rx ring to simply call the extension function with a recent copy of the PHC time. By ensuring that the PHC time is kept up to date periodically, we ensure this algorithm doesn't use stale data and produce incorrect results. To cache the time, introduce a kworker and a kwork item to periodically store the Rx time. It might seem like we should use the .do_aux_work interface of the PTP clock. This doesn't work because all PFs must cache this time, but only one PF owns the PTP clock device. Thus, the ice driver will manage its own kthread instead of relying on the PTP do_aux_work handler. With this change, the driver can now report Rx timestamps on all incoming packets. Signed-off-by: Jacob Keller <[email protected]> Tested-by: Tony Brelinski <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 67569a7 commit 77a7811

File tree

9 files changed

+410
-6
lines changed

9 files changed

+410
-6
lines changed

drivers/net/ethernet/intel/ice/ice_base.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,9 +393,10 @@ static int ice_setup_rx_ctx(struct ice_ring *ring)
393393
* of same priority
394394
*/
395395
if (vsi->type != ICE_VSI_VF)
396-
ice_write_qrxflxp_cntxt(hw, pf_q, rxdid, 0x3);
396+
ice_write_qrxflxp_cntxt(hw, pf_q, rxdid, 0x3, true);
397397
else
398-
ice_write_qrxflxp_cntxt(hw, pf_q, ICE_RXDID_LEGACY_1, 0x3);
398+
ice_write_qrxflxp_cntxt(hw, pf_q, ICE_RXDID_LEGACY_1, 0x3,
399+
false);
399400

400401
/* Absolute queue number out of 2K needs to be passed */
401402
err = ice_write_rxq_ctx(hw, &rlan_ctx, pf_q);

drivers/net/ethernet/intel/ice/ice_ethtool.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3204,13 +3204,16 @@ ice_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
32043204
if (!test_bit(ICE_FLAG_PTP, pf->flags))
32053205
return ethtool_op_get_ts_info(dev, info);
32063206

3207-
info->so_timestamping = SOF_TIMESTAMPING_SOFTWARE;
3207+
info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
3208+
SOF_TIMESTAMPING_SOFTWARE |
3209+
SOF_TIMESTAMPING_RX_HARDWARE |
3210+
SOF_TIMESTAMPING_RAW_HARDWARE;
32083211

32093212
info->phc_index = ice_get_ptp_clock_index(pf);
32103213

32113214
info->tx_types = BIT(HWTSTAMP_TX_OFF);
32123215

3213-
info->rx_filters = BIT(HWTSTAMP_FILTER_NONE);
3216+
info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
32143217

32153218
return 0;
32163219
}

drivers/net/ethernet/intel/ice/ice_lib.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1675,9 +1675,11 @@ void ice_vsi_cfg_frame_size(struct ice_vsi *vsi)
16751675
* @pf_q: index of the Rx queue in the PF's queue space
16761676
* @rxdid: flexible descriptor RXDID
16771677
* @prio: priority for the RXDID for this queue
1678+
* @ena_ts: true to enable timestamp and false to disable timestamp
16781679
*/
16791680
void
1680-
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio)
1681+
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio,
1682+
bool ena_ts)
16811683
{
16821684
int regval = rd32(hw, QRXFLXP_CNTXT(pf_q));
16831685

@@ -1692,6 +1694,10 @@ ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio)
16921694
regval |= (prio << QRXFLXP_CNTXT_RXDID_PRIO_S) &
16931695
QRXFLXP_CNTXT_RXDID_PRIO_M;
16941696

1697+
if (ena_ts)
1698+
/* Enable TimeSync on this queue */
1699+
regval |= QRXFLXP_CNTXT_TS_M;
1700+
16951701
wr32(hw, QRXFLXP_CNTXT(pf_q), regval);
16961702
}
16971703

drivers/net/ethernet/intel/ice/ice_lib.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ bool ice_is_reset_in_progress(unsigned long *state);
8080
int ice_wait_for_reset(struct ice_pf *pf, unsigned long timeout);
8181

8282
void
83-
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio);
83+
ice_write_qrxflxp_cntxt(struct ice_hw *hw, u16 pf_q, u32 rxdid, u32 prio,
84+
bool ena_ts);
8485

8586
void ice_vsi_dis_irq(struct ice_vsi *vsi);
8687

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6519,6 +6519,27 @@ static int ice_change_mtu(struct net_device *netdev, int new_mtu)
65196519
return err;
65206520
}
65216521

6522+
/**
6523+
* ice_do_ioctl - Access the hwtstamp interface
6524+
* @netdev: network interface device structure
6525+
* @ifr: interface request data
6526+
* @cmd: ioctl command
6527+
*/
6528+
static int ice_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
6529+
{
6530+
struct ice_netdev_priv *np = netdev_priv(netdev);
6531+
struct ice_pf *pf = np->vsi->back;
6532+
6533+
switch (cmd) {
6534+
case SIOCGHWTSTAMP:
6535+
return ice_ptp_get_ts_config(pf, ifr);
6536+
case SIOCSHWTSTAMP:
6537+
return ice_ptp_set_ts_config(pf, ifr);
6538+
default:
6539+
return -EOPNOTSUPP;
6540+
}
6541+
}
6542+
65226543
/**
65236544
* ice_aq_str - convert AQ err code to a string
65246545
* @aq_err: the AQ error code to convert
@@ -7169,6 +7190,7 @@ static const struct net_device_ops ice_netdev_ops = {
71697190
.ndo_change_mtu = ice_change_mtu,
71707191
.ndo_get_stats64 = ice_get_stats64,
71717192
.ndo_set_tx_maxrate = ice_set_tx_maxrate,
7193+
.ndo_do_ioctl = ice_do_ioctl,
71727194
.ndo_set_vf_spoofchk = ice_set_vf_spoofchk,
71737195
.ndo_set_vf_mac = ice_set_vf_mac,
71747196
.ndo_get_vf_config = ice_get_vf_cfg,

0 commit comments

Comments
 (0)