Commit c8c3d7e2 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to e1000e, igb, i40e and i40evf

Anjali provides i40e fix to remove the ATR filter on RST as well as FIN
packets.  Cleans up add_del_fdir() because it was used and implemented
only for the add, so change the name and drop a parameter.  Adds the
ability to drop a flow if we wanted to and adds a flow director
message level to be used for flow director specific messages.

Mitch fixes an issue on i40evf where the Tx watchdog handler was causing
an oops when sending an admin queue message to request a reset because
the admin queue functions use spinlocks.

Greg provides a change to i40e to make the alloc and free queue vector
calls orthogonal.

Shannon fixes i40e to verify the eeprom checksum and firmware CRC status
bits, and shutdown the driver if they fail.  This change stops the
processing of traffic, but does not kill the PF netdev so that the
NVMUpdate process still has a chance at fixing the image.  Also provides
a fix to make sure the VSI has a netdev before trying to use it in
the debugfs netdev_ops commands.

Jakub Kicinski provides patches for e1000e and igb to fix a number issues
found in the PTP code.

v2:
- drop patch 11 "i40e: Add a fallback debug flow for the driver" from the
  series based on feedback from David Miller
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2405e8f6 ed4420a3
......@@ -262,6 +262,7 @@ struct e1000_adapter {
u32 tx_head_addr;
u32 tx_fifo_size;
u32 tx_dma_failed;
u32 tx_hwtstamp_timeouts;
/* Rx */
bool (*clean_rx) (struct e1000_ring *ring, int *work_done,
......@@ -334,6 +335,7 @@ struct e1000_adapter {
struct hwtstamp_config hwtstamp_config;
struct delayed_work systim_overflow_work;
struct sk_buff *tx_hwtstamp_skb;
unsigned long tx_hwtstamp_start;
struct work_struct tx_hwtstamp_work;
spinlock_t systim_lock; /* protects SYSTIML/H regsters */
struct cyclecounter cc;
......
......@@ -104,6 +104,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
E1000_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
E1000_STAT("uncorr_ecc_errors", uncorr_errors),
E1000_STAT("corr_ecc_errors", corr_errors),
E1000_STAT("tx_hwtstamp_timeouts", tx_hwtstamp_timeouts),
};
#define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats)
......
......@@ -1148,9 +1148,6 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work)
tx_hwtstamp_work);
struct e1000_hw *hw = &adapter->hw;
if (!adapter->tx_hwtstamp_skb)
return;
if (er32(TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID) {
struct skb_shared_hwtstamps shhwtstamps;
u64 txstmp;
......@@ -1163,6 +1160,12 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work)
skb_tstamp_tx(adapter->tx_hwtstamp_skb, &shhwtstamps);
dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
adapter->tx_hwtstamp_skb = NULL;
} else if (time_after(jiffies, adapter->tx_hwtstamp_start
+ adapter->tx_timeout_factor * HZ)) {
dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
adapter->tx_hwtstamp_skb = NULL;
adapter->tx_hwtstamp_timeouts++;
e_warn("clearing Tx timestamp hang");
} else {
/* reschedule to check later */
schedule_work(&adapter->tx_hwtstamp_work);
......@@ -5567,6 +5570,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
tx_flags |= E1000_TX_FLAGS_HWTSTAMP;
adapter->tx_hwtstamp_skb = skb_get(skb);
adapter->tx_hwtstamp_start = jiffies;
schedule_work(&adapter->tx_hwtstamp_work);
} else {
skb_tx_timestamp(skb);
......
......@@ -136,6 +136,7 @@ enum i40e_state_t {
__I40E_EMP_RESET_REQUESTED,
__I40E_FILTER_OVERFLOW_PROMISC,
__I40E_SUSPENDED,
__I40E_BAD_EEPROM,
};
enum i40e_interrupt_policy {
......
......@@ -2087,9 +2087,13 @@ static ssize_t i40e_dbg_netdev_ops_write(struct file *filp,
if (!vsi) {
dev_info(&pf->pdev->dev,
"tx_timeout: VSI %d not found\n", vsi_seid);
goto netdev_ops_write_done;
}
if (rtnl_trylock()) {
} else if (!vsi->netdev) {
dev_info(&pf->pdev->dev, "tx_timeout: no netdev for VSI %d\n",
vsi_seid);
} else if (test_bit(__I40E_DOWN, &vsi->state)) {
dev_info(&pf->pdev->dev, "tx_timeout: VSI %d not UP\n",
vsi_seid);
} else if (rtnl_trylock()) {
vsi->netdev->netdev_ops->ndo_tx_timeout(vsi->netdev);
rtnl_unlock();
dev_info(&pf->pdev->dev, "tx_timeout called\n");
......@@ -2108,9 +2112,10 @@ static ssize_t i40e_dbg_netdev_ops_write(struct file *filp,
if (!vsi) {
dev_info(&pf->pdev->dev,
"change_mtu: VSI %d not found\n", vsi_seid);
goto netdev_ops_write_done;
}
if (rtnl_trylock()) {
} else if (!vsi->netdev) {
dev_info(&pf->pdev->dev, "change_mtu: no netdev for VSI %d\n",
vsi_seid);
} else if (rtnl_trylock()) {
vsi->netdev->netdev_ops->ndo_change_mtu(vsi->netdev,
mtu);
rtnl_unlock();
......@@ -2129,9 +2134,10 @@ static ssize_t i40e_dbg_netdev_ops_write(struct file *filp,
if (!vsi) {
dev_info(&pf->pdev->dev,
"set_rx_mode: VSI %d not found\n", vsi_seid);
goto netdev_ops_write_done;
}
if (rtnl_trylock()) {
} else if (!vsi->netdev) {
dev_info(&pf->pdev->dev, "set_rx_mode: no netdev for VSI %d\n",
vsi_seid);
} else if (rtnl_trylock()) {
vsi->netdev->netdev_ops->ndo_set_rx_mode(vsi->netdev);
rtnl_unlock();
dev_info(&pf->pdev->dev, "set_rx_mode called\n");
......@@ -2149,11 +2155,14 @@ static ssize_t i40e_dbg_netdev_ops_write(struct file *filp,
if (!vsi) {
dev_info(&pf->pdev->dev, "napi: VSI %d not found\n",
vsi_seid);
goto netdev_ops_write_done;
} else if (!vsi->netdev) {
dev_info(&pf->pdev->dev, "napi: no netdev for VSI %d\n",
vsi_seid);
} else {
for (i = 0; i < vsi->num_q_vectors; i++)
napi_schedule(&vsi->q_vectors[i]->napi);
dev_info(&pf->pdev->dev, "napi called\n");
}
for (i = 0; i < vsi->num_q_vectors; i++)
napi_schedule(&vsi->q_vectors[i]->napi);
dev_info(&pf->pdev->dev, "napi called\n");
} else {
dev_info(&pf->pdev->dev, "unknown command '%s'\n",
i40e_dbg_netdev_ops_buf);
......
......@@ -62,8 +62,8 @@ static const struct i40e_stats i40e_gstrings_net_stats[] = {
I40E_NETDEV_STAT(rx_crc_errors),
};
static int i40e_add_del_fdir_ethtool(struct i40e_vsi *vsi,
struct ethtool_rxnfc *cmd, bool add);
static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
struct ethtool_rxnfc *cmd);
/* These PF_STATs might look like duplicates of some NETDEV_STATs,
* but they are separate. This device supports Virtualization, and
......@@ -1470,16 +1470,15 @@ static int i40e_del_fdir_entry(struct i40e_vsi *vsi,
}
/**
* i40e_add_del_fdir_ethtool - Add/Remove Flow Director filters
* i40e_add_fdir_ethtool - Add/Remove Flow Director filters
* @vsi: pointer to the targeted VSI
* @cmd: command to get or set RX flow classification rules
* @add: true adds a filter, false removes it
*
* Add/Remove Flow Director filters for a specific flow spec based on their
* protocol. Returns 0 if the filters were successfully added or removed.
* Add Flow Director filters for a specific flow spec based on their
* protocol. Returns 0 if the filters were successfully added.
**/
static int i40e_add_del_fdir_ethtool(struct i40e_vsi *vsi,
struct ethtool_rxnfc *cmd, bool add)
static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
struct ethtool_rxnfc *cmd)
{
struct ethtool_rx_flow_spec *fsp;
struct i40e_fdir_filter *input;
......@@ -1494,7 +1493,7 @@ static int i40e_add_del_fdir_ethtool(struct i40e_vsi *vsi,
if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
return -EOPNOTSUPP;
if (add && (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED))
if (pf->auto_disable_flags & I40E_FLAG_FD_SB_ENABLED)
return -ENOSPC;
fsp = (struct ethtool_rx_flow_spec *)&cmd->fs;
......@@ -1504,7 +1503,7 @@ static int i40e_add_del_fdir_ethtool(struct i40e_vsi *vsi,
return -EINVAL;
}
if ((fsp->ring_cookie >= vsi->num_queue_pairs) && add)
if (fsp->ring_cookie >= vsi->num_queue_pairs)
return -EINVAL;
input = kzalloc(sizeof(*input), GFP_KERNEL);
......@@ -1514,11 +1513,16 @@ static int i40e_add_del_fdir_ethtool(struct i40e_vsi *vsi,
input->fd_id = fsp->location;
if (fsp->ring_cookie == RX_CLS_FLOW_DISC)
input->dest_ctl = I40E_FILTER_PROGRAM_DESC_DEST_DROP_PACKET;
else
input->dest_ctl =
I40E_FILTER_PROGRAM_DESC_DEST_DIRECT_PACKET_QINDEX;
input->q_index = fsp->ring_cookie;
input->flex_off = 0;
input->pctype = 0;
input->dest_vsi = vsi->id;
input->dest_ctl = I40E_FILTER_PROGRAM_DESC_DEST_DIRECT_PACKET_QINDEX;
input->fd_status = I40E_FILTER_PROGRAM_DESC_FD_STATUS_FD_ID;
input->cnt_index = 0;
input->flow_type = fsp->flow_type;
......@@ -1528,16 +1532,11 @@ static int i40e_add_del_fdir_ethtool(struct i40e_vsi *vsi,
input->src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src;
input->dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst;
ret = i40e_add_del_fdir(vsi, input, add);
if (ret) {
ret = i40e_add_del_fdir(vsi, input, true);
if (ret)
kfree(input);
return ret;
}
if (!ret && add)
i40e_update_ethtool_fdir_entry(vsi, input, fsp->location, NULL);
else
kfree(input);
i40e_update_ethtool_fdir_entry(vsi, input, fsp->location, NULL);
return ret;
}
......@@ -1561,7 +1560,7 @@ static int i40e_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
ret = i40e_set_rss_hash_opt(pf, cmd);
break;
case ETHTOOL_SRXCLSRLINS:
ret = i40e_add_del_fdir_ethtool(vsi, cmd, true);
ret = i40e_add_fdir_ethtool(vsi, cmd);
break;
case ETHTOOL_SRXCLSRLDEL:
ret = i40e_del_fdir_entry(vsi, cmd);
......
......@@ -26,6 +26,7 @@
/* Local includes */
#include "i40e.h"
#include "i40e_diag.h"
#ifdef CONFIG_I40E_VXLAN
#include <net/vxlan.h>
#endif
......@@ -2877,12 +2878,14 @@ static irqreturn_t i40e_intr(int irq, void *data)
val = rd32(hw, I40E_GLGEN_RSTAT);
val = (val & I40E_GLGEN_RSTAT_RESET_TYPE_MASK)
>> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT;
if (val == I40E_RESET_CORER)
if (val == I40E_RESET_CORER) {
pf->corer_count++;
else if (val == I40E_RESET_GLOBR)
} else if (val == I40E_RESET_GLOBR) {
pf->globr_count++;
else if (val == I40E_RESET_EMPR)
} else if (val == I40E_RESET_EMPR) {
pf->empr_count++;
set_bit(__I40E_EMP_RESET_REQUESTED, &pf->state);
}
}
if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK) {
......@@ -4257,8 +4260,9 @@ static int i40e_open(struct net_device *netdev)
struct i40e_pf *pf = vsi->back;
int err;
/* disallow open during test */
if (test_bit(__I40E_TESTING, &pf->state))
/* disallow open during test or if eeprom is broken */
if (test_bit(__I40E_TESTING, &pf->state) ||
test_bit(__I40E_BAD_EEPROM, &pf->state))
return -EBUSY;
netif_carrier_off(netdev);
......@@ -5077,6 +5081,31 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
kfree(event.msg_buf);
}
/**
* i40e_verify_eeprom - make sure eeprom is good to use
* @pf: board private structure
**/
static void i40e_verify_eeprom(struct i40e_pf *pf)
{
int err;
err = i40e_diag_eeprom_test(&pf->hw);
if (err) {
/* retry in case of garbage read */
err = i40e_diag_eeprom_test(&pf->hw);
if (err) {
dev_info(&pf->pdev->dev, "eeprom check failed (%d), Tx/Rx traffic disabled\n",
err);
set_bit(__I40E_BAD_EEPROM, &pf->state);
}
}
if (!err && test_bit(__I40E_BAD_EEPROM, &pf->state)) {
dev_info(&pf->pdev->dev, "eeprom check passed, Tx/Rx traffic enabled\n");
clear_bit(__I40E_BAD_EEPROM, &pf->state);
}
}
/**
* i40e_reconstitute_veb - rebuild the VEB and anything connected to it
* @veb: pointer to the VEB instance
......@@ -5386,6 +5415,12 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
goto end_core_reset;
}
/* re-verify the eeprom if we just had an EMP reset */
if (test_bit(__I40E_EMP_RESET_REQUESTED, &pf->state)) {
clear_bit(__I40E_EMP_RESET_REQUESTED, &pf->state);
i40e_verify_eeprom(pf);
}
ret = i40e_get_capabilities(pf);
if (ret) {
dev_info(&pf->pdev->dev, "i40e_get_capabilities failed, %d\n",
......@@ -6111,13 +6146,13 @@ static int i40e_init_msix(struct i40e_pf *pf)
}
/**
* i40e_alloc_q_vector - Allocate memory for a single interrupt vector
* i40e_vsi_alloc_q_vector - Allocate memory for a single interrupt vector
* @vsi: the VSI being configured
* @v_idx: index of the vector in the vsi struct
*
* We allocate one q_vector. If allocation fails we return -ENOMEM.
**/
static int i40e_alloc_q_vector(struct i40e_vsi *vsi, int v_idx)
static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx)
{
struct i40e_q_vector *q_vector;
......@@ -6143,13 +6178,13 @@ static int i40e_alloc_q_vector(struct i40e_vsi *vsi, int v_idx)
}
/**
* i40e_alloc_q_vectors - Allocate memory for interrupt vectors
* i40e_vsi_alloc_q_vectors - Allocate memory for interrupt vectors
* @vsi: the VSI being configured
*
* We allocate one q_vector per queue interrupt. If allocation fails we
* return -ENOMEM.
**/
static int i40e_alloc_q_vectors(struct i40e_vsi *vsi)
static int i40e_vsi_alloc_q_vectors(struct i40e_vsi *vsi)
{
struct i40e_pf *pf = vsi->back;
int v_idx, num_q_vectors;
......@@ -6164,7 +6199,7 @@ static int i40e_alloc_q_vectors(struct i40e_vsi *vsi)
return -EINVAL;
for (v_idx = 0; v_idx < num_q_vectors; v_idx++) {
err = i40e_alloc_q_vector(vsi, v_idx);
err = i40e_vsi_alloc_q_vector(vsi, v_idx);
if (err)
goto err_out;
}
......@@ -7020,7 +7055,7 @@ static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi)
return -EEXIST;
}
ret = i40e_alloc_q_vectors(vsi);
ret = i40e_vsi_alloc_q_vectors(vsi);
if (ret) {
dev_info(&pf->pdev->dev,
"failed to allocate %d q_vector for VSI %d, ret=%d\n",
......@@ -8157,6 +8192,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_pf_reset;
}
i40e_verify_eeprom(pf);
i40e_clear_pxe_mode(hw);
err = i40e_get_capabilities(pf);
if (err)
......@@ -8258,7 +8295,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* prep for VF support */
if ((pf->flags & I40E_FLAG_SRIOV_ENABLED) &&
(pf->flags & I40E_FLAG_MSIX_ENABLED)) {
(pf->flags & I40E_FLAG_MSIX_ENABLED) &&
!test_bit(__I40E_BAD_EEPROM, &pf->state)) {
u32 val;
/* disable link interrupts for VFs */
......
......@@ -482,8 +482,9 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
}
} else if (error ==
(0x1 << I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) {
netdev_info(rx_ring->vsi->netdev, "ntuple filter loc = %d, could not be removed\n",
rx_desc->wb.qword0.hi_dword.fd_id);
if (I40E_DEBUG_FD & pf->hw.debug_mask)
dev_info(&pdev->dev, "ntuple filter loc = %d, could not be removed\n",
rx_desc->wb.qword0.hi_dword.fd_id);
}
}
......@@ -1624,8 +1625,11 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
tx_ring->atr_count++;
/* sample on all syn/fin packets or once every atr sample rate */
if (!th->fin && !th->syn && (tx_ring->atr_count < tx_ring->atr_sample_rate))
/* sample on all syn/fin/rst packets or once every atr sample rate */
if (!th->fin &&
!th->syn &&
!th->rst &&
(tx_ring->atr_count < tx_ring->atr_sample_rate))
return;
tx_ring->atr_count = 0;
......@@ -1649,7 +1653,7 @@ static void i40e_atr(struct i40e_ring *tx_ring, struct sk_buff *skb,
dtype_cmd = I40E_TX_DESC_DTYPE_FILTER_PROG;
dtype_cmd |= th->fin ?
dtype_cmd |= (th->fin || th->rst) ?
(I40E_FILTER_PROGRAM_DESC_PCMD_REMOVE <<
I40E_TXD_FLTR_QW1_PCMD_SHIFT) :
(I40E_FILTER_PROGRAM_DESC_PCMD_ADD_UPDATE <<
......
......@@ -91,6 +91,7 @@ enum i40e_debug_mask {
I40E_DEBUG_FLOW = 0x00000200,
I40E_DEBUG_DCB = 0x00000400,
I40E_DEBUG_DIAG = 0x00000800,
I40E_DEBUG_FD = 0x00001000,
I40E_DEBUG_AQ_MESSAGE = 0x01000000,
I40E_DEBUG_AQ_DESCRIPTOR = 0x02000000,
......
......@@ -67,7 +67,7 @@ extern struct i40e_rx_ptype_decoded i40evf_ptype_lookup[];
static inline struct i40e_rx_ptype_decoded decode_rx_desc_ptype(u8 ptype)
{
return i40evf_ptype_lookup[ptype];
return i40evf_ptype_lookup[ptype];
}
/* prototype for functions used for SW locks */
......
......@@ -88,6 +88,7 @@ enum i40e_debug_mask {
I40E_DEBUG_FLOW = 0x00000200,
I40E_DEBUG_DCB = 0x00000400,
I40E_DEBUG_DIAG = 0x00000800,
I40E_DEBUG_FD = 0x00001000,
I40E_DEBUG_AQ_MESSAGE = 0x01000000,
I40E_DEBUG_AQ_DESCRIPTOR = 0x02000000,
......
......@@ -211,6 +211,7 @@ struct i40evf_adapter {
#define I40EVF_FLAG_NEED_LINK_UPDATE (u32)(1 << 7)
#define I40EVF_FLAG_PF_COMMS_FAILED (u32)(1 << 8)
#define I40EVF_FLAG_RESET_PENDING (u32)(1 << 9)
#define I40EVF_FLAG_RESET_NEEDED (u32)(1 << 10)
/* duplcates for common code */
#define I40E_FLAG_FDIR_ATR_ENABLED 0
#define I40E_FLAG_DCB_ENABLED 0
......
......@@ -169,9 +169,7 @@ static void i40evf_tx_timeout(struct net_device *netdev)
adapter->tx_timeout_count++;
dev_info(&adapter->pdev->dev, "TX timeout detected.\n");
if (!(adapter->flags & I40EVF_FLAG_RESET_PENDING)) {
dev_info(&adapter->pdev->dev, "Requesting reset from PF\n");
i40evf_request_reset(adapter);
adapter->flags |= I40EVF_FLAG_RESET_PENDING;
adapter->flags |= I40EVF_FLAG_RESET_NEEDED;
schedule_work(&adapter->reset_task);
}
}
......@@ -1484,6 +1482,12 @@ static void i40evf_reset_task(struct work_struct *work)
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section))
udelay(500);
if (adapter->flags & I40EVF_FLAG_RESET_NEEDED) {
dev_info(&adapter->pdev->dev, "Requesting reset from PF\n");
i40evf_request_reset(adapter);
}
/* poll until we see the reset actually happen */
for (i = 0; i < I40EVF_RESET_WAIT_COUNT; i++) {
rstat_val = rd32(hw, I40E_VFGEN_RSTAT) &
......
......@@ -492,7 +492,8 @@ struct igb_adapter {
enum e1000_state_t {
__IGB_TESTING,
__IGB_RESETTING,
__IGB_DOWN
__IGB_DOWN,
__IGB_PTP_TX_IN_PROGRESS,
};
enum igb_boards {
......
......@@ -4980,12 +4980,11 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
first->bytecount = skb->len;
first->gso_segs = 1;
skb_tx_timestamp(skb);
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
if (!(adapter->ptp_tx_skb)) {
if (!test_and_set_bit_lock(__IGB_PTP_TX_IN_PROGRESS,
&adapter->state)) {
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
tx_flags |= IGB_TX_FLAGS_TSTAMP;
......@@ -4996,6 +4995,8 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
}
}
skb_tx_timestamp(skb);
if (vlan_tx_tag_present(skb)) {
tx_flags |= IGB_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
......
......@@ -387,6 +387,7 @@ static void igb_ptp_tx_work(struct work_struct *work)
IGB_PTP_TX_TIMEOUT)) {
dev_kfree_skb_any(adapter->ptp_tx_skb);
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");
return;
......@@ -480,6 +481,7 @@ static void igb_ptp_tx_hwtstamp(struct igb_adapter *adapter)
skb_tstamp_tx(adapter->ptp_tx_skb, &shhwtstamps);
dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL;
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
}
/**
......@@ -857,6 +859,7 @@ void igb_ptp_stop(struct igb_adapter *adapter)
if (adapter->ptp_tx_skb) {
dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL;
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
}
if (adapter->ptp_clock) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment