forked from luck/tmp_suning_uos_patched
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net
Jeff Kirsher says: ==================== Intel Wired LAN Driver Updates This series contains updates to e1000e, igb, ixgbe and i40e. Most notably are Jakub's patches to clean up the Rx time stamping code for ixgbe and the fix up of debug messages with proper termination. Jesse's i40e patch fixes an issue reported by Eric Dumazet that the i40e driver was allowing the hardware to replicate the PSH flag on all segments of a TSO operation. With this fix, we are now configuring the CWR bit to only be set in the first packet of a TSO and we enable TSO_ECN in order to advertise to the stack that we do the right thing on the wire. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
647401d5ac
drivers/net/ethernet/intel
|
@ -1165,7 +1165,7 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work)
|
|||
dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
|
||||
adapter->tx_hwtstamp_skb = NULL;
|
||||
adapter->tx_hwtstamp_timeouts++;
|
||||
e_warn("clearing Tx timestamp hang");
|
||||
e_warn("clearing Tx timestamp hang\n");
|
||||
} else {
|
||||
/* reschedule to check later */
|
||||
schedule_work(&adapter->tx_hwtstamp_work);
|
||||
|
@ -5687,7 +5687,7 @@ struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
|
|||
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
{
|
||||
struct e1000_adapter *adapter = netdev_priv(netdev);
|
||||
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
|
||||
int max_frame = new_mtu + VLAN_HLEN + ETH_HLEN + ETH_FCS_LEN;
|
||||
|
||||
/* Jumbo frame support */
|
||||
if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
|
||||
|
@ -6235,6 +6235,7 @@ static int __e1000_resume(struct pci_dev *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int e1000e_pm_thaw(struct device *dev)
|
||||
{
|
||||
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
|
||||
|
@ -6255,7 +6256,6 @@ static int e1000e_pm_thaw(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int e1000e_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
|
|
@ -4271,6 +4271,14 @@ static int i40e_open(struct net_device *netdev)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
/* configure global TSO hardware offload settings */
|
||||
wr32(&pf->hw, I40E_GLLAN_TSOMSK_F, be32_to_cpu(TCP_FLAG_PSH |
|
||||
TCP_FLAG_FIN) >> 16);
|
||||
wr32(&pf->hw, I40E_GLLAN_TSOMSK_M, be32_to_cpu(TCP_FLAG_PSH |
|
||||
TCP_FLAG_FIN |
|
||||
TCP_FLAG_CWR) >> 16);
|
||||
wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16);
|
||||
|
||||
#ifdef CONFIG_I40E_VXLAN
|
||||
vxlan_get_rx_port(netdev);
|
||||
#endif
|
||||
|
@ -6712,6 +6720,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
|
|||
NETIF_F_HW_VLAN_CTAG_FILTER |
|
||||
NETIF_F_IPV6_CSUM |
|
||||
NETIF_F_TSO |
|
||||
NETIF_F_TSO_ECN |
|
||||
NETIF_F_TSO6 |
|
||||
NETIF_F_RXCSUM |
|
||||
NETIF_F_NTUPLE |
|
||||
|
|
|
@ -160,7 +160,7 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
|
|||
udelay(5);
|
||||
}
|
||||
if (ret_code == I40E_ERR_TIMEOUT)
|
||||
hw_dbg(hw, "Done bit in GLNVM_SRCTL not set");
|
||||
hw_dbg(hw, "Done bit in GLNVM_SRCTL not set\n");
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
|
|
|
@ -239,7 +239,7 @@ static void i40e_ptp_tx_work(struct work_struct *work)
|
|||
dev_kfree_skb_any(pf->ptp_tx_skb);
|
||||
pf->ptp_tx_skb = NULL;
|
||||
pf->tx_hwtstamp_timeouts++;
|
||||
dev_warn(&pf->pdev->dev, "clearing Tx timestamp hang");
|
||||
dev_warn(&pf->pdev->dev, "clearing Tx timestamp hang\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -321,7 +321,7 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi)
|
|||
pf->last_rx_ptp_check = jiffies;
|
||||
pf->rx_hwtstamp_cleared++;
|
||||
dev_warn(&vsi->back->pdev->dev,
|
||||
"%s: clearing Rx timestamp hang",
|
||||
"%s: clearing Rx timestamp hang\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -418,7 +418,7 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
|
|||
}
|
||||
break;
|
||||
default:
|
||||
dev_info(&pf->pdev->dev, "Could not specify spec type %d",
|
||||
dev_info(&pf->pdev->dev, "Could not specify spec type %d\n",
|
||||
input->flow_type);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
@ -478,7 +478,7 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
|
|||
pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT;
|
||||
}
|
||||
} else {
|
||||
dev_info(&pdev->dev, "FD filter programming error");
|
||||
dev_info(&pdev->dev, "FD filter programming error\n");
|
||||
}
|
||||
} else if (error ==
|
||||
(0x1 << I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) {
|
||||
|
@ -1713,9 +1713,11 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
|
|||
I40E_TX_FLAGS_VLAN_PRIO_SHIFT;
|
||||
if (tx_flags & I40E_TX_FLAGS_SW_VLAN) {
|
||||
struct vlan_ethhdr *vhdr;
|
||||
if (skb_header_cloned(skb) &&
|
||||
pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
|
||||
return -ENOMEM;
|
||||
int rc;
|
||||
|
||||
rc = skb_cow_head(skb, 0);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
vhdr = (struct vlan_ethhdr *)skb->data;
|
||||
vhdr->h_vlan_TCI = htons(tx_flags >>
|
||||
I40E_TX_FLAGS_VLAN_SHIFT);
|
||||
|
@ -1743,20 +1745,18 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
|
|||
u64 *cd_type_cmd_tso_mss, u32 *cd_tunneling)
|
||||
{
|
||||
u32 cd_cmd, cd_tso_len, cd_mss;
|
||||
struct ipv6hdr *ipv6h;
|
||||
struct tcphdr *tcph;
|
||||
struct iphdr *iph;
|
||||
u32 l4len;
|
||||
int err;
|
||||
struct ipv6hdr *ipv6h;
|
||||
|
||||
if (!skb_is_gso(skb))
|
||||
return 0;
|
||||
|
||||
if (skb_header_cloned(skb)) {
|
||||
err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
err = skb_cow_head(skb, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (protocol == htons(ETH_P_IP)) {
|
||||
iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
|
||||
|
|
|
@ -365,7 +365,7 @@ static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
|
|||
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
|
||||
if (word_address == address) {
|
||||
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
|
||||
hw_dbg("Read INVM Word 0x%02x = %x",
|
||||
hw_dbg("Read INVM Word 0x%02x = %x\n",
|
||||
address, *data);
|
||||
status = E1000_SUCCESS;
|
||||
break;
|
||||
|
|
|
@ -929,11 +929,10 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
|||
*/
|
||||
if (hw->fc.requested_mode == e1000_fc_full) {
|
||||
hw->fc.current_mode = e1000_fc_full;
|
||||
hw_dbg("Flow Control = FULL.\r\n");
|
||||
hw_dbg("Flow Control = FULL.\n");
|
||||
} else {
|
||||
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||
hw_dbg("Flow Control = "
|
||||
"RX PAUSE frames only.\r\n");
|
||||
hw_dbg("Flow Control = RX PAUSE frames only.\n");
|
||||
}
|
||||
}
|
||||
/* For receiving PAUSE frames ONLY.
|
||||
|
@ -948,7 +947,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
|||
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
|
||||
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
|
||||
hw->fc.current_mode = e1000_fc_tx_pause;
|
||||
hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
|
||||
hw_dbg("Flow Control = TX PAUSE frames only.\n");
|
||||
}
|
||||
/* For transmitting PAUSE frames ONLY.
|
||||
*
|
||||
|
@ -962,7 +961,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
|||
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
|
||||
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
|
||||
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||
hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
|
||||
hw_dbg("Flow Control = RX PAUSE frames only.\n");
|
||||
}
|
||||
/* Per the IEEE spec, at this point flow control should be
|
||||
* disabled. However, we want to consider that we could
|
||||
|
@ -988,10 +987,10 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
|
|||
(hw->fc.requested_mode == e1000_fc_tx_pause) ||
|
||||
(hw->fc.strict_ieee)) {
|
||||
hw->fc.current_mode = e1000_fc_none;
|
||||
hw_dbg("Flow Control = NONE.\r\n");
|
||||
hw_dbg("Flow Control = NONE.\n");
|
||||
} else {
|
||||
hw->fc.current_mode = e1000_fc_rx_pause;
|
||||
hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
|
||||
hw_dbg("Flow Control = RX PAUSE frames only.\n");
|
||||
}
|
||||
|
||||
/* Now we need to do one last check... If we auto-
|
||||
|
|
|
@ -5193,8 +5193,10 @@ void igb_update_stats(struct igb_adapter *adapter,
|
|||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < adapter->num_rx_queues; i++) {
|
||||
u32 rqdpc = rd32(E1000_RQDPC(i));
|
||||
struct igb_ring *ring = adapter->rx_ring[i];
|
||||
u32 rqdpc = rd32(E1000_RQDPC(i));
|
||||
if (hw->mac.type >= e1000_i210)
|
||||
wr32(E1000_RQDPC(i), 0);
|
||||
|
||||
if (rqdpc) {
|
||||
ring->rx_stats.drops += rqdpc;
|
||||
|
|
|
@ -389,7 +389,7 @@ static void igb_ptp_tx_work(struct work_struct *work)
|
|||
adapter->ptp_tx_skb = NULL;
|
||||
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
|
||||
adapter->tx_hwtstamp_timeouts++;
|
||||
dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang");
|
||||
dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -451,7 +451,7 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter)
|
|||
rd32(E1000_RXSTMPH);
|
||||
adapter->last_rx_ptp_check = jiffies;
|
||||
adapter->rx_hwtstamp_cleared++;
|
||||
dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang");
|
||||
dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -256,7 +256,6 @@ struct ixgbe_ring {
|
|||
struct ixgbe_tx_buffer *tx_buffer_info;
|
||||
struct ixgbe_rx_buffer *rx_buffer_info;
|
||||
};
|
||||
unsigned long last_rx_timestamp;
|
||||
unsigned long state;
|
||||
u8 __iomem *tail;
|
||||
dma_addr_t dma; /* phys. address of descriptor ring */
|
||||
|
@ -770,6 +769,7 @@ struct ixgbe_adapter {
|
|||
unsigned long ptp_tx_start;
|
||||
unsigned long last_overflow_check;
|
||||
unsigned long last_rx_ptp_check;
|
||||
unsigned long last_rx_timestamp;
|
||||
spinlock_t tmreg_lock;
|
||||
struct cyclecounter cc;
|
||||
struct timecounter tc;
|
||||
|
@ -944,24 +944,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter);
|
|||
void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
|
||||
void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
|
||||
void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
|
||||
void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
|
||||
struct sk_buff *skb);
|
||||
static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
|
||||
union ixgbe_adv_rx_desc *rx_desc,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
|
||||
return;
|
||||
|
||||
__ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb);
|
||||
|
||||
/*
|
||||
* Update the last_rx_timestamp timer in order to enable watchdog check
|
||||
* for error case of latched timestamp on a dropped packet.
|
||||
*/
|
||||
rx_ring->last_rx_timestamp = jiffies;
|
||||
}
|
||||
|
||||
void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb);
|
||||
int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
|
||||
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
|
||||
void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
|
||||
|
|
|
@ -1195,7 +1195,7 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
|
|||
*/
|
||||
hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
|
||||
|
||||
hw_dbg(hw, "Detected EEPROM page size = %d words.",
|
||||
hw_dbg(hw, "Detected EEPROM page size = %d words.\n",
|
||||
hw->eeprom.word_page_size);
|
||||
out:
|
||||
return status;
|
||||
|
|
|
@ -1664,7 +1664,8 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
|
|||
|
||||
ixgbe_rx_checksum(rx_ring, rx_desc, skb);
|
||||
|
||||
ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
|
||||
if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
|
||||
ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector->adapter, skb);
|
||||
|
||||
if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
|
||||
ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {
|
||||
|
|
|
@ -536,7 +536,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
|
|||
|
||||
if (time_out == max_time_out) {
|
||||
status = IXGBE_ERR_LINK_SETUP;
|
||||
hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out");
|
||||
hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out\n");
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -745,7 +745,7 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw)
|
|||
|
||||
if (time_out == max_time_out) {
|
||||
status = IXGBE_ERR_LINK_SETUP;
|
||||
hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out");
|
||||
hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out\n");
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -1175,7 +1175,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
|
|||
status = 0;
|
||||
} else {
|
||||
if (hw->allow_unsupported_sfp) {
|
||||
e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.");
|
||||
e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n");
|
||||
status = 0;
|
||||
} else {
|
||||
hw_dbg(hw,
|
||||
|
|
|
@ -435,10 +435,8 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter)
|
|||
void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
struct ixgbe_ring *rx_ring;
|
||||
u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
|
||||
unsigned long rx_event;
|
||||
int n;
|
||||
|
||||
/* if we don't have a valid timestamp in the registers, just update the
|
||||
* timeout counter and exit
|
||||
|
@ -450,18 +448,15 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)
|
|||
|
||||
/* determine the most recent watchdog or rx_timestamp event */
|
||||
rx_event = adapter->last_rx_ptp_check;
|
||||
for (n = 0; n < adapter->num_rx_queues; n++) {
|
||||
rx_ring = adapter->rx_ring[n];
|
||||
if (time_after(rx_ring->last_rx_timestamp, rx_event))
|
||||
rx_event = rx_ring->last_rx_timestamp;
|
||||
}
|
||||
if (time_after(adapter->last_rx_timestamp, rx_event))
|
||||
rx_event = adapter->last_rx_timestamp;
|
||||
|
||||
/* only need to read the high RXSTMP register to clear the lock */
|
||||
if (time_is_before_jiffies(rx_event + 5*HZ)) {
|
||||
IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
|
||||
adapter->last_rx_ptp_check = jiffies;
|
||||
|
||||
e_warn(drv, "clearing RX Timestamp hang");
|
||||
e_warn(drv, "clearing RX Timestamp hang\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -517,7 +512,7 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work)
|
|||
dev_kfree_skb_any(adapter->ptp_tx_skb);
|
||||
adapter->ptp_tx_skb = NULL;
|
||||
clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
|
||||
e_warn(drv, "clearing Tx Timestamp hang");
|
||||
e_warn(drv, "clearing Tx Timestamp hang\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -530,35 +525,22 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
/**
|
||||
* __ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
|
||||
* @q_vector: structure containing interrupt and ring information
|
||||
* ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
|
||||
* @adapter: pointer to adapter struct
|
||||
* @skb: particular skb to send timestamp with
|
||||
*
|
||||
* if the timestamp is valid, we convert it into the timecounter ns
|
||||
* value, then store that result into the shhwtstamps structure which
|
||||
* is passed up the network stack
|
||||
*/
|
||||
void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
|
||||
struct sk_buff *skb)
|
||||
void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb)
|
||||
{
|
||||
struct ixgbe_adapter *adapter;
|
||||
struct ixgbe_hw *hw;
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
struct skb_shared_hwtstamps *shhwtstamps;
|
||||
u64 regval = 0, ns;
|
||||
u32 tsyncrxctl;
|
||||
unsigned long flags;
|
||||
|
||||
/* we cannot process timestamps on a ring without a q_vector */
|
||||
if (!q_vector || !q_vector->adapter)
|
||||
return;
|
||||
|
||||
adapter = q_vector->adapter;
|
||||
hw = &adapter->hw;
|
||||
|
||||
/*
|
||||
* Read the tsyncrxctl register afterwards in order to prevent taking an
|
||||
* I/O hit on every packet.
|
||||
*/
|
||||
tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
|
||||
if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
|
||||
return;
|
||||
|
@ -566,13 +548,17 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
|
|||
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
|
||||
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
|
||||
|
||||
|
||||
spin_lock_irqsave(&adapter->tmreg_lock, flags);
|
||||
ns = timecounter_cyc2time(&adapter->tc, regval);
|
||||
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
|
||||
|
||||
shhwtstamps = skb_hwtstamps(skb);
|
||||
shhwtstamps->hwtstamp = ns_to_ktime(ns);
|
||||
|
||||
/* Update the last_rx_timestamp timer in order to enable watchdog check
|
||||
* for error case of latched timestamp on a dropped packet.
|
||||
*/
|
||||
adapter->last_rx_timestamp = jiffies;
|
||||
}
|
||||
|
||||
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
|
||||
|
|
Loading…
Reference in New Issue
Block a user