提交 1bc693e1 编写于 作者: D David S. Miller

Merge branch 'intel-next'

Aaron Brown says:

====================
Mark updates ixgbe for LER / adapter removal.  He restores the HW
address in the recovery path so the device is not perpetually removed,
fixes up some removed state ethtool results and adds checks related to
config space access.

Jacob adds support for the new SIOCGHWTSTAMP ioctl.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -765,6 +765,7 @@ struct ixgbe_adapter { ...@@ -765,6 +765,7 @@ struct ixgbe_adapter {
struct ptp_clock_info ptp_caps; struct ptp_clock_info ptp_caps;
struct work_struct ptp_tx_work; struct work_struct ptp_tx_work;
struct sk_buff *ptp_tx_skb; struct sk_buff *ptp_tx_skb;
struct hwtstamp_config tstamp_config;
unsigned long ptp_tx_start; unsigned long ptp_tx_start;
unsigned long last_overflow_check; unsigned long last_overflow_check;
unsigned long last_rx_ptp_check; unsigned long last_rx_ptp_check;
...@@ -957,8 +958,8 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring, ...@@ -957,8 +958,8 @@ static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
rx_ring->last_rx_timestamp = jiffies; rx_ring->last_rx_timestamp = jiffies;
} }
int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, struct ifreq *ifr, int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
int cmd); int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr);
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2014 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -61,6 +61,9 @@ static void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw) ...@@ -61,6 +61,9 @@ static void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR); u32 gcr = IXGBE_READ_REG(hw, IXGBE_GCR);
u16 pcie_devctl2; u16 pcie_devctl2;
if (ixgbe_removed(hw->hw_addr))
return;
/* only take action if timeout value is defaulted to 0 */ /* only take action if timeout value is defaulted to 0 */
if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK) if (gcr & IXGBE_GCR_CMPL_TMOUT_MASK)
goto out; goto out;
...@@ -79,8 +82,9 @@ static void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw) ...@@ -79,8 +82,9 @@ static void ixgbe_set_pcie_completion_timeout(struct ixgbe_hw *hw)
* directly in order to set the completion timeout value for * directly in order to set the completion timeout value for
* 16ms to 55ms * 16ms to 55ms
*/ */
pci_read_config_word(adapter->pdev, pcie_devctl2 = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_DEVICE_CONTROL2);
IXGBE_PCI_DEVICE_CONTROL2, &pcie_devctl2); if (ixgbe_removed(hw->hw_addr))
return;
pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms; pcie_devctl2 |= IXGBE_PCI_DEVICE_CONTROL2_16ms;
pci_write_config_word(adapter->pdev, pci_write_config_word(adapter->pdev,
IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2); IXGBE_PCI_DEVICE_CONTROL2, pcie_devctl2);
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2014 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -2487,7 +2487,6 @@ static u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw) ...@@ -2487,7 +2487,6 @@ static u32 ixgbe_pcie_timeout_poll(struct ixgbe_hw *hw)
**/ **/
static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
{ {
struct ixgbe_adapter *adapter = hw->back;
s32 status = 0; s32 status = 0;
u32 i, poll; u32 i, poll;
u16 value; u16 value;
...@@ -2496,7 +2495,8 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) ...@@ -2496,7 +2495,8 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS); IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS);
/* Exit if master requests are blocked */ /* Exit if master requests are blocked */
if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) ||
ixgbe_removed(hw->hw_addr))
goto out; goto out;
/* Poll for master request bit to clear */ /* Poll for master request bit to clear */
...@@ -2524,8 +2524,9 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) ...@@ -2524,8 +2524,9 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
poll = ixgbe_pcie_timeout_poll(hw); poll = ixgbe_pcie_timeout_poll(hw);
for (i = 0; i < poll; i++) { for (i = 0; i < poll; i++) {
udelay(100); udelay(100);
pci_read_config_word(adapter->pdev, IXGBE_PCI_DEVICE_STATUS, value = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_DEVICE_STATUS);
&value); if (ixgbe_removed(hw->hw_addr))
goto out;
if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING)) if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
goto out; goto out;
} }
...@@ -2867,7 +2868,6 @@ s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr) ...@@ -2867,7 +2868,6 @@ s32 ixgbe_get_san_mac_addr_generic(struct ixgbe_hw *hw, u8 *san_mac_addr)
**/ **/
u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
{ {
struct ixgbe_adapter *adapter = hw->back;
u16 msix_count = 1; u16 msix_count = 1;
u16 max_msix_count; u16 max_msix_count;
u16 pcie_offset; u16 pcie_offset;
...@@ -2886,7 +2886,9 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) ...@@ -2886,7 +2886,9 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
return msix_count; return msix_count;
} }
pci_read_config_word(adapter->pdev, pcie_offset, &msix_count); msix_count = ixgbe_read_pci_cfg_word(hw, pcie_offset);
if (ixgbe_removed(hw->hw_addr))
msix_count = 0;
msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK; msix_count &= IXGBE_PCIE_MSIX_TBL_SZ_MASK;
/* MSI-X count is zero-based in HW */ /* MSI-X count is zero-based in HW */
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2014 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -128,6 +128,10 @@ s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw); ...@@ -128,6 +128,10 @@ s32 ixgbe_get_thermal_sensor_data_generic(struct ixgbe_hw *hw);
s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw); s32 ixgbe_init_thermal_sensor_thresh_generic(struct ixgbe_hw *hw);
#define IXGBE_FAILED_READ_REG 0xffffffffU #define IXGBE_FAILED_READ_REG 0xffffffffU
#define IXGBE_FAILED_READ_CFG_DWORD 0xffffffffU
#define IXGBE_FAILED_READ_CFG_WORD 0xffffU
u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg);
static inline bool ixgbe_removed(void __iomem *addr) static inline bool ixgbe_removed(void __iomem *addr)
{ {
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2014 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -1247,6 +1247,11 @@ static int ixgbe_link_test(struct ixgbe_adapter *adapter, u64 *data) ...@@ -1247,6 +1247,11 @@ static int ixgbe_link_test(struct ixgbe_adapter *adapter, u64 *data)
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
bool link_up; bool link_up;
u32 link_speed = 0; u32 link_speed = 0;
if (ixgbe_removed(hw->hw_addr)) {
*data = 1;
return 1;
}
*data = 0; *data = 0;
hw->mac.ops.check_link(hw, &link_speed, &link_up, true); hw->mac.ops.check_link(hw, &link_speed, &link_up, true);
...@@ -1969,6 +1974,7 @@ static void ixgbe_diag_test(struct net_device *netdev, ...@@ -1969,6 +1974,7 @@ static void ixgbe_diag_test(struct net_device *netdev,
data[1] = 1; data[1] = 1;
data[2] = 1; data[2] = 1;
data[3] = 1; data[3] = 1;
data[4] = 1;
eth_test->flags |= ETH_TEST_FL_FAILED; eth_test->flags |= ETH_TEST_FL_FAILED;
return; return;
} }
...@@ -1988,6 +1994,7 @@ static void ixgbe_diag_test(struct net_device *netdev, ...@@ -1988,6 +1994,7 @@ static void ixgbe_diag_test(struct net_device *netdev,
data[1] = 1; data[1] = 1;
data[2] = 1; data[2] = 1;
data[3] = 1; data[3] = 1;
data[4] = 1;
eth_test->flags |= ETH_TEST_FL_FAILED; eth_test->flags |= ETH_TEST_FL_FAILED;
clear_bit(__IXGBE_TESTING, clear_bit(__IXGBE_TESTING,
&adapter->state); &adapter->state);
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2014 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -67,7 +67,7 @@ static char ixgbe_default_device_descr[] = ...@@ -67,7 +67,7 @@ static char ixgbe_default_device_descr[] =
#define DRV_VERSION "3.19.1-k" #define DRV_VERSION "3.19.1-k"
const char ixgbe_driver_version[] = DRV_VERSION; const char ixgbe_driver_version[] = DRV_VERSION;
static const char ixgbe_copyright[] = static const char ixgbe_copyright[] =
"Copyright (c) 1999-2013 Intel Corporation."; "Copyright (c) 1999-2014 Intel Corporation.";
static const struct ixgbe_info *ixgbe_info_tbl[] = { static const struct ixgbe_info *ixgbe_info_tbl[] = {
[board_82598] = &ixgbe_82598_info, [board_82598] = &ixgbe_82598_info,
...@@ -151,6 +151,8 @@ MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver"); ...@@ -151,6 +151,8 @@ MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev);
static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter, static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter,
u32 reg, u16 *value) u32 reg, u16 *value)
{ {
...@@ -169,6 +171,9 @@ static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter, ...@@ -169,6 +171,9 @@ static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter,
return -1; return -1;
pcie_capability_read_word(parent_dev, reg, value); pcie_capability_read_word(parent_dev, reg, value);
if (*value == IXGBE_FAILED_READ_CFG_WORD &&
ixgbe_check_cfg_remove(&adapter->hw, parent_dev))
return -1;
return 0; return 0;
} }
...@@ -313,6 +318,48 @@ void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg) ...@@ -313,6 +318,48 @@ void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
ixgbe_remove_adapter(hw); ixgbe_remove_adapter(hw);
} }
static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev)
{
u16 value;
pci_read_config_word(pdev, PCI_VENDOR_ID, &value);
if (value == IXGBE_FAILED_READ_CFG_WORD) {
ixgbe_remove_adapter(hw);
return true;
}
return false;
}
u16 ixgbe_read_pci_cfg_word(struct ixgbe_hw *hw, u32 reg)
{
struct ixgbe_adapter *adapter = hw->back;
u16 value;
if (ixgbe_removed(hw->hw_addr))
return IXGBE_FAILED_READ_CFG_WORD;
pci_read_config_word(adapter->pdev, reg, &value);
if (value == IXGBE_FAILED_READ_CFG_WORD &&
ixgbe_check_cfg_remove(hw, adapter->pdev))
return IXGBE_FAILED_READ_CFG_WORD;
return value;
}
#ifdef CONFIG_PCI_IOV
static u32 ixgbe_read_pci_cfg_dword(struct ixgbe_hw *hw, u32 reg)
{
struct ixgbe_adapter *adapter = hw->back;
u32 value;
if (ixgbe_removed(hw->hw_addr))
return IXGBE_FAILED_READ_CFG_DWORD;
pci_read_config_dword(adapter->pdev, reg, &value);
if (value == IXGBE_FAILED_READ_CFG_DWORD &&
ixgbe_check_cfg_remove(hw, adapter->pdev))
return IXGBE_FAILED_READ_CFG_DWORD;
return value;
}
#endif /* CONFIG_PCI_IOV */
static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter) static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter)
{ {
BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state)); BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state));
...@@ -5508,6 +5555,7 @@ static int ixgbe_resume(struct pci_dev *pdev) ...@@ -5508,6 +5555,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
u32 err; u32 err;
adapter->hw.hw_addr = adapter->io_addr;
pci_set_power_state(pdev, PCI_D0); pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev); pci_restore_state(pdev);
/* /*
...@@ -7149,7 +7197,9 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) ...@@ -7149,7 +7197,9 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
switch (cmd) { switch (cmd) {
case SIOCSHWTSTAMP: case SIOCSHWTSTAMP:
return ixgbe_ptp_hwtstamp_ioctl(adapter, req, cmd); return ixgbe_ptp_set_ts_config(adapter, req);
case SIOCGHWTSTAMP:
return ixgbe_ptp_get_ts_config(adapter, req);
default: default:
return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd); return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
} }
...@@ -8338,6 +8388,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, ...@@ -8338,6 +8388,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
struct ixgbe_hw *hw = &adapter->hw;
struct pci_dev *bdev, *vfdev; struct pci_dev *bdev, *vfdev;
u32 dw0, dw1, dw2, dw3; u32 dw0, dw1, dw2, dw3;
int vf, pos; int vf, pos;
...@@ -8358,10 +8409,12 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, ...@@ -8358,10 +8409,12 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
if (!pos) if (!pos)
goto skip_bad_vf_detection; goto skip_bad_vf_detection;
pci_read_config_dword(bdev, pos + PCI_ERR_HEADER_LOG, &dw0); dw0 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG);
pci_read_config_dword(bdev, pos + PCI_ERR_HEADER_LOG + 4, &dw1); dw1 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 4);
pci_read_config_dword(bdev, pos + PCI_ERR_HEADER_LOG + 8, &dw2); dw2 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 8);
pci_read_config_dword(bdev, pos + PCI_ERR_HEADER_LOG + 12, &dw3); dw3 = ixgbe_read_pci_cfg_dword(hw, pos + PCI_ERR_HEADER_LOG + 12);
if (ixgbe_removed(hw->hw_addr))
goto skip_bad_vf_detection;
req_id = dw1 >> 16; req_id = dw1 >> 16;
/* On the 82599 if bit 7 of the requestor ID is set then it's a VF */ /* On the 82599 if bit 7 of the requestor ID is set then it's a VF */
...@@ -8453,6 +8506,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) ...@@ -8453,6 +8506,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
e_err(probe, "Cannot re-enable PCI device after reset.\n"); e_err(probe, "Cannot re-enable PCI device after reset.\n");
result = PCI_ERS_RESULT_DISCONNECT; result = PCI_ERS_RESULT_DISCONNECT;
} else { } else {
adapter->hw.hw_addr = adapter->io_addr;
pci_set_master(pdev); pci_set_master(pdev);
pci_restore_state(pdev); pci_restore_state(pdev);
pci_save_state(pdev); pci_save_state(pdev);
......
...@@ -576,14 +576,21 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, ...@@ -576,14 +576,21 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
shhwtstamps->hwtstamp = ns_to_ktime(ns); shhwtstamps->hwtstamp = ns_to_ktime(ns);
} }
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
{
struct hwtstamp_config *config = &adapter->tstamp_config;
return copy_to_user(ifr->ifr_data, config,
sizeof(*config)) ? -EFAULT : 0;
}
/** /**
* ixgbe_ptp_hwtstamp_ioctl - control hardware time stamping * ixgbe_ptp_set_ts_config - control hardware time stamping
* @adapter: pointer to adapter struct * @adapter: pointer to adapter struct
* @ifreq: ioctl data * @ifreq: ioctl data
* @cmd: particular ioctl requested
* *
* Outgoing time stamping can be enabled and disabled. Play nice and * Outgoing time stamping can be enabled and disabled. Play nice and
* disable it when requested, although it shouldn't case any overhead * disable it when requested, although it shouldn't cause any overhead
* when no packet needs it. At most one packet in the queue may be * when no packet needs it. At most one packet in the queue may be
* marked for time stamping, otherwise it would be impossible to tell * marked for time stamping, otherwise it would be impossible to tell
* for sure to which packet the hardware time stamp belongs. * for sure to which packet the hardware time stamp belongs.
...@@ -599,8 +606,7 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, ...@@ -599,8 +606,7 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
* Event mode. This more accurately tells the user what the hardware is going * Event mode. This more accurately tells the user what the hardware is going
* to do anyways. * to do anyways.
*/ */
int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
struct ifreq *ifr, int cmd)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
struct hwtstamp_config config; struct hwtstamp_config config;
...@@ -702,6 +708,10 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter, ...@@ -702,6 +708,10 @@ int ixgbe_ptp_hwtstamp_ioctl(struct ixgbe_adapter *adapter,
regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH); regval = IXGBE_READ_REG(hw, IXGBE_TXSTMPH);
regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH); regval = IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
/* save these settings for future reference */
memcpy(&adapter->tstamp_config, &config,
sizeof(adapter->tstamp_config));
return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0; -EFAULT : 0;
} }
...@@ -809,6 +819,9 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter) ...@@ -809,6 +819,9 @@ void ixgbe_ptp_reset(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000); IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0x00000000);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
/* Reset the saved tstamp_config */
memset(&adapter->tstamp_config, 0, sizeof(adapter->tstamp_config));
ixgbe_ptp_start_cyclecounter(adapter); ixgbe_ptp_start_cyclecounter(adapter);
spin_lock_irqsave(&adapter->tmreg_lock, flags); spin_lock_irqsave(&adapter->tmreg_lock, flags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册