forked from luck/tmp_suning_uos_patched
igb: check timestamp validity
[ Upstream commit f0a03a026857d6c7766eb7d5835edbf5523ca15c ] Add a couple of checks to make sure timestamping is on and that the timestamp value from DMA is valid. This avoids any functional issues that could come from a misinterpreted time stamp. One of the functions changed doesn't need a return value added because there was no value in checking from the calling locations. While here, fix a couple of reverse christmas tree issues next to the code being changed. Fixes:f56e7bba22
("igb: Pull timestamp from fragment before adding it to skb") Fixes:9cbc948b5a
("igb: add XDP support") Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Tested-by: Dave Switzer <david.switzer@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
421e0d7310
commit
2330d46db0
|
@ -748,8 +748,8 @@ void igb_ptp_suspend(struct igb_adapter *adapter);
|
|||
void igb_ptp_rx_hang(struct igb_adapter *adapter);
|
||||
void igb_ptp_tx_hang(struct igb_adapter *adapter);
|
||||
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb);
|
||||
void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
|
||||
struct sk_buff *skb);
|
||||
int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
|
||||
struct sk_buff *skb);
|
||||
int igb_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
|
||||
int igb_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
|
||||
void igb_set_flag_queue_pairs(struct igb_adapter *, const u32);
|
||||
|
|
|
@ -8319,9 +8319,10 @@ static struct sk_buff *igb_construct_skb(struct igb_ring *rx_ring,
|
|||
return NULL;
|
||||
|
||||
if (unlikely(igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP))) {
|
||||
igb_ptp_rx_pktstamp(rx_ring->q_vector, xdp->data, skb);
|
||||
xdp->data += IGB_TS_HDR_LEN;
|
||||
size -= IGB_TS_HDR_LEN;
|
||||
if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, xdp->data, skb)) {
|
||||
xdp->data += IGB_TS_HDR_LEN;
|
||||
size -= IGB_TS_HDR_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine available headroom for copy */
|
||||
|
@ -8382,8 +8383,8 @@ static struct sk_buff *igb_build_skb(struct igb_ring *rx_ring,
|
|||
|
||||
/* pull timestamp out of packet data */
|
||||
if (igb_test_staterr(rx_desc, E1000_RXDADV_STAT_TSIP)) {
|
||||
igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb);
|
||||
__skb_pull(skb, IGB_TS_HDR_LEN);
|
||||
if (!igb_ptp_rx_pktstamp(rx_ring->q_vector, skb->data, skb))
|
||||
__skb_pull(skb, IGB_TS_HDR_LEN);
|
||||
}
|
||||
|
||||
/* update buffer offset */
|
||||
|
|
|
@ -856,6 +856,9 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)
|
|||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
#define IGB_RET_PTP_DISABLED 1
|
||||
#define IGB_RET_PTP_INVALID 2
|
||||
|
||||
/**
|
||||
* igb_ptp_rx_pktstamp - retrieve Rx per packet timestamp
|
||||
* @q_vector: Pointer to interrupt specific structure
|
||||
|
@ -864,19 +867,29 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)
|
|||
*
|
||||
* This function is meant to retrieve a timestamp from the first buffer of an
|
||||
* incoming frame. The value is stored in little endian format starting on
|
||||
* byte 8.
|
||||
* byte 8
|
||||
*
|
||||
* Returns: 0 if success, nonzero if failure
|
||||
**/
|
||||
void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
|
||||
struct sk_buff *skb)
|
||||
int igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
__le64 *regval = (__le64 *)va;
|
||||
struct igb_adapter *adapter = q_vector->adapter;
|
||||
__le64 *regval = (__le64 *)va;
|
||||
int adjust = 0;
|
||||
|
||||
if (!(adapter->ptp_flags & IGB_PTP_ENABLED))
|
||||
return IGB_RET_PTP_DISABLED;
|
||||
|
||||
/* The timestamp is recorded in little endian format.
|
||||
* DWORD: 0 1 2 3
|
||||
* Field: Reserved Reserved SYSTIML SYSTIMH
|
||||
*/
|
||||
|
||||
/* check reserved dwords are zero, be/le doesn't matter for zero */
|
||||
if (regval[0])
|
||||
return IGB_RET_PTP_INVALID;
|
||||
|
||||
igb_ptp_systim_to_hwtstamp(adapter, skb_hwtstamps(skb),
|
||||
le64_to_cpu(regval[1]));
|
||||
|
||||
|
@ -896,6 +909,8 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
|
|||
}
|
||||
skb_hwtstamps(skb)->hwtstamp =
|
||||
ktime_sub_ns(skb_hwtstamps(skb)->hwtstamp, adjust);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -906,13 +921,15 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, void *va,
|
|||
* This function is meant to retrieve a timestamp from the internal registers
|
||||
* of the adapter and store it in the skb.
|
||||
**/
|
||||
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector,
|
||||
struct sk_buff *skb)
|
||||
void igb_ptp_rx_rgtstamp(struct igb_q_vector *q_vector, struct sk_buff *skb)
|
||||
{
|
||||
struct igb_adapter *adapter = q_vector->adapter;
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u64 regval;
|
||||
int adjust = 0;
|
||||
u64 regval;
|
||||
|
||||
if (!(adapter->ptp_flags & IGB_PTP_ENABLED))
|
||||
return;
|
||||
|
||||
/* If this bit is set, then the RX registers contain the time stamp. No
|
||||
* other packet will be time stamped until we read these registers, so
|
||||
|
|
Loading…
Reference in New Issue
Block a user