Commit 35d37709 authored by David S. Miller's avatar David S. Miller

Merge branch '1GbE' of https://github.com/anguy11/next-queue

Tony Nguyen says:

====================
1GbE Intel Wired LAN Driver Updates 2020-09-28

This series contains updates to igb, igc, and e1000e drivers.

Sven Auhagen adds XDP support for igb.

Gal Hammer allows for 82576 to display part number string correctly for
igb.

Sasha adds device IDs for i221 and i226 parts. Exposes LPI counters and
removes unused fields in structures for igc. He also adds Meteor Lake
support for e1000e.

For igc, Andre renames IGC_TSYNCTXCTL_VALID to IGC_TSYNCTXCTL_TXTT_0 to
match the datasheet and adds a warning if it's not set when expected.
Removes the PTP Tx timestamp check in igc_ptp_tx_work() as it's already
checked in the watchdog_task. Cleans up some code by removing invalid error
bits, renaming a bit to match datasheet naming, and removing a, now
unneeded, macro.

Vinicius makes changes for igc PTP: removes calling SYSTIMR to latch timer
value, stores PTP time before a reset, and rejects schedules with times in
the future.

v2: Remove 'inline' from igb_xdp_tx_queue_mapping() and igb_rx_offset()
for patch 1
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents bcbf1be0 cc23f4f0
......@@ -895,6 +895,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
mask |= BIT(18);
break;
default:
......@@ -1560,6 +1561,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
fext_nvm11 = er32(FEXTNVM11);
fext_nvm11 &= ~E1000_FEXTNVM11_DISABLE_MULR_FIX;
ew32(FEXTNVM11, fext_nvm11);
......
......@@ -102,6 +102,10 @@ struct e1000_hw;
#define E1000_DEV_ID_PCH_ADP_I219_V16 0x1A1F
#define E1000_DEV_ID_PCH_ADP_I219_LM17 0x1A1C
#define E1000_DEV_ID_PCH_ADP_I219_V17 0x1A1D
#define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A
#define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B
#define E1000_DEV_ID_PCH_MTP_I219_LM19 0x550C
#define E1000_DEV_ID_PCH_MTP_I219_V19 0x550D
#define E1000_REVISION_4 4
......@@ -127,6 +131,7 @@ enum e1000_mac_type {
e1000_pch_cnp,
e1000_pch_tgp,
e1000_pch_adp,
e1000_pch_mtp,
};
enum e1000_media_type {
......
......@@ -320,6 +320,7 @@ static s32 e1000_init_phy_workarounds_pchlan(struct e1000_hw *hw)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
if (e1000_phy_is_accessible_pchlan(hw))
break;
......@@ -464,6 +465,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
/* In case the PHY needs to be in mdio slow mode,
* set slow mode and try to get the PHY id again.
*/
......@@ -708,6 +710,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
case e1000_pchlan:
/* check management mode */
mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
......@@ -1648,6 +1651,7 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
rc = e1000_init_phy_params_pchlan(hw);
break;
default:
......@@ -2102,6 +2106,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
break;
default:
......@@ -3145,6 +3150,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
bank1_offset = nvm->flash_bank_size;
act_offset = E1000_ICH_NVM_SIG_WORD;
......@@ -4090,6 +4096,7 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
word = NVM_COMPAT;
valid_csum_mask = NVM_COMPAT_VALID_CSUM;
break;
......
......@@ -3587,6 +3587,7 @@ s32 e1000e_get_base_timinca(struct e1000_adapter *adapter, u32 *timinca)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) {
/* Stable 24MHz frequency */
incperiod = INCPERIOD_24MHZ;
......@@ -4104,6 +4105,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
fc->refresh_time = 0xFFFF;
fc->pause_time = 0xFFFF;
......@@ -7877,6 +7879,10 @@ static const struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V16), board_pch_cnp },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM17), board_pch_cnp },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_cnp },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_cnp },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_cnp },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_cnp },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_cnp },
{ 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
};
......
......@@ -297,6 +297,7 @@ void e1000e_ptp_init(struct e1000_adapter *adapter)
case e1000_pch_cnp:
case e1000_pch_tgp:
case e1000_pch_adp:
case e1000_pch_mtp:
if ((hw->mac.type < e1000_pch_lpt) ||
(er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) {
adapter->ptp_clock_info.max_adj = 24000000 - 1;
......
......@@ -19,6 +19,8 @@
#include <linux/pci.h>
#include <linux/mdio.h>
#include <net/xdp.h>
struct igb_adapter;
#define E1000_PCS_CFG_IGN_SD 1
......@@ -79,6 +81,12 @@ struct igb_adapter;
#define IGB_I210_RX_LATENCY_100 2213
#define IGB_I210_RX_LATENCY_1000 448
/* XDP */
#define IGB_XDP_PASS 0
#define IGB_XDP_CONSUMED BIT(0)
#define IGB_XDP_TX BIT(1)
#define IGB_XDP_REDIR BIT(2)
struct vf_data_storage {
unsigned char vf_mac_addresses[ETH_ALEN];
u16 vf_mc_hashes[IGB_MAX_VF_MC_ENTRIES];
......@@ -132,17 +140,62 @@ struct vf_mac_filter {
/* Supported Rx Buffer Sizes */
#define IGB_RXBUFFER_256 256
#define IGB_RXBUFFER_1536 1536
#define IGB_RXBUFFER_2048 2048
#define IGB_RXBUFFER_3072 3072
#define IGB_RX_HDR_LEN IGB_RXBUFFER_256
#define IGB_TS_HDR_LEN 16
#define IGB_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
/* Attempt to maximize the headroom available for incoming frames. We
* use a 2K buffer for receives and need 1536/1534 to store the data for
* the frame. This leaves us with 512 bytes of room. From that we need
* to deduct the space needed for the shared info and the padding needed
* to IP align the frame.
*
* Note: For cache line sizes 256 or larger this value is going to end
* up negative. In these cases we should fall back to the 3K
* buffers.
*/
#if (PAGE_SIZE < 8192)
#define IGB_MAX_FRAME_BUILD_SKB \
(SKB_WITH_OVERHEAD(IGB_RXBUFFER_2048) - IGB_SKB_PAD - IGB_TS_HDR_LEN)
#define IGB_MAX_FRAME_BUILD_SKB (IGB_RXBUFFER_1536 - NET_IP_ALIGN)
#define IGB_2K_TOO_SMALL_WITH_PADDING \
((NET_SKB_PAD + IGB_TS_HDR_LEN + IGB_RXBUFFER_1536) > SKB_WITH_OVERHEAD(IGB_RXBUFFER_2048))
static inline int igb_compute_pad(int rx_buf_len)
{
int page_size, pad_size;
page_size = ALIGN(rx_buf_len, PAGE_SIZE / 2);
pad_size = SKB_WITH_OVERHEAD(page_size) - rx_buf_len;
return pad_size;
}
static inline int igb_skb_pad(void)
{
int rx_buf_len;
/* If a 2K buffer cannot handle a standard Ethernet frame then
* optimize padding for a 3K buffer instead of a 1.5K buffer.
*
* For a 3K buffer we need to add enough padding to allow for
* tailroom due to NET_IP_ALIGN possibly shifting us out of
* cache-line alignment.
*/
if (IGB_2K_TOO_SMALL_WITH_PADDING)
rx_buf_len = IGB_RXBUFFER_3072 + SKB_DATA_ALIGN(NET_IP_ALIGN);
else
rx_buf_len = IGB_RXBUFFER_1536;
/* if needed make room for NET_IP_ALIGN */
rx_buf_len -= NET_IP_ALIGN;
return igb_compute_pad(rx_buf_len);
}
#define IGB_SKB_PAD igb_skb_pad()
#else
#define IGB_MAX_FRAME_BUILD_SKB (IGB_RXBUFFER_2048 - IGB_TS_HDR_LEN)
#define IGB_SKB_PAD (NET_SKB_PAD + NET_IP_ALIGN)
#endif
/* How many Rx Buffers do we bundle into one write to the hardware ? */
......@@ -194,13 +247,22 @@ enum igb_tx_flags {
#define IGB_SFF_ADDRESSING_MODE 0x4
#define IGB_SFF_8472_UNSUP 0x00
enum igb_tx_buf_type {
IGB_TYPE_SKB = 0,
IGB_TYPE_XDP,
};
/* wrapper around a pointer to a socket buffer,
* so a DMA handle can be stored along with the buffer
*/
struct igb_tx_buffer {
union e1000_adv_tx_desc *next_to_watch;
unsigned long time_stamp;
enum igb_tx_buf_type type;
union {
struct sk_buff *skb;
struct xdp_frame *xdpf;
};
unsigned int bytecount;
u16 gso_segs;
__be16 protocol;
......@@ -248,6 +310,7 @@ struct igb_ring_container {
struct igb_ring {
struct igb_q_vector *q_vector; /* backlink to q_vector */
struct net_device *netdev; /* back pointer to net_device */
struct bpf_prog *xdp_prog;
struct device *dev; /* device pointer for dma mapping */
union { /* array of buffer info structs */
struct igb_tx_buffer *tx_buffer_info;
......@@ -288,6 +351,7 @@ struct igb_ring {
struct u64_stats_sync rx_syncp;
};
};
struct xdp_rxq_info xdp_rxq;
} ____cacheline_internodealigned_in_smp;
struct igb_q_vector {
......@@ -339,7 +403,7 @@ static inline unsigned int igb_rx_bufsz(struct igb_ring *ring)
return IGB_RXBUFFER_3072;
if (ring_uses_build_skb(ring))
return IGB_MAX_FRAME_BUILD_SKB + IGB_TS_HDR_LEN;
return IGB_MAX_FRAME_BUILD_SKB;
#endif
return IGB_RXBUFFER_2048;
}
......@@ -467,6 +531,7 @@ struct igb_adapter {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
struct net_device *netdev;
struct bpf_prog *xdp_prog;
unsigned long state;
unsigned int flags;
......@@ -643,6 +708,9 @@ enum igb_boards {
extern char igb_driver_name[];
int igb_xmit_xdp_ring(struct igb_adapter *adapter,
struct igb_ring *ring,
struct xdp_frame *xdpf);
int igb_open(struct net_device *netdev);
int igb_close(struct net_device *netdev);
int igb_up(struct igb_adapter *);
......
......@@ -961,6 +961,10 @@ static int igb_set_ringparam(struct net_device *netdev,
memcpy(&temp_ring[i], adapter->rx_ring[i],
sizeof(struct igb_ring));
/* Clear copied XDP RX-queue info */
memset(&temp_ring[i].xdp_rxq, 0,
sizeof(temp_ring[i].xdp_rxq));
temp_ring[i].count = new_rx_count;
err = igb_setup_rx_resources(&temp_ring[i]);
if (err) {
......
This diff is collapsed.
......@@ -215,6 +215,8 @@ struct igc_adapter {
spinlock_t tmreg_lock;
struct cyclecounter cc;
struct timecounter tc;
struct timespec64 prev_ptp_time; /* Pre-reset PTP clock */
ktime_t ptp_reset_start; /* Reset time in clock mono */
};
void igc_up(struct igc_adapter *adapter);
......@@ -548,6 +550,7 @@ void igc_ptp_rx_pktstamp(struct igc_q_vector *q_vector, void *va,
int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr);
int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr);
void igc_ptp_tx_hang(struct igc_adapter *adapter);
void igc_ptp_read(struct igc_adapter *adapter, struct timespec64 *ts);
#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))
......
......@@ -215,6 +215,11 @@ static s32 igc_get_invariants_base(struct igc_hw *hw)
case IGC_DEV_ID_I225_K2:
case IGC_DEV_ID_I225_LMVP:
case IGC_DEV_ID_I225_IT:
case IGC_DEV_ID_I226_LM:
case IGC_DEV_ID_I226_V:
case IGC_DEV_ID_I226_IT:
case IGC_DEV_ID_I221_V:
case IGC_DEV_ID_I226_BLANK_NVM:
case IGC_DEV_ID_I225_BLANK_NVM:
mac->type = igc_i225;
break;
......
......@@ -324,22 +324,10 @@
/* Advanced Receive Descriptor bit definitions */
#define IGC_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */
#define IGC_RXDEXT_STATERR_CE 0x01000000
#define IGC_RXDEXT_STATERR_SE 0x02000000
#define IGC_RXDEXT_STATERR_SEQ 0x04000000
#define IGC_RXDEXT_STATERR_CXE 0x10000000
#define IGC_RXDEXT_STATERR_TCPE 0x20000000
#define IGC_RXDEXT_STATERR_L4E 0x20000000
#define IGC_RXDEXT_STATERR_IPE 0x40000000
#define IGC_RXDEXT_STATERR_RXE 0x80000000
/* Same mask, but for extended and packet split descriptors */
#define IGC_RXDEXT_ERR_FRAME_ERR_MASK ( \
IGC_RXDEXT_STATERR_CE | \
IGC_RXDEXT_STATERR_SE | \
IGC_RXDEXT_STATERR_SEQ | \
IGC_RXDEXT_STATERR_CXE | \
IGC_RXDEXT_STATERR_RXE)
#define IGC_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define IGC_MRQC_RSS_FIELD_IPV4 0x00020000
#define IGC_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
......@@ -409,7 +397,7 @@
#define IGC_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
/* Time Sync Transmit Control bit definitions */
#define IGC_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
#define IGC_TSYNCTXCTL_TXTT_0 0x00000001 /* Tx timestamp reg 0 valid */
#define IGC_TSYNCTXCTL_ENABLED 0x00000010 /* enable Tx timestamping */
#define IGC_TSYNCTXCTL_MAX_ALLOWED_DLY_MASK 0x0000F000 /* max delay */
#define IGC_TSYNCTXCTL_SYNC_COMP_ERR 0x20000000 /* sync err */
......
......@@ -321,6 +321,9 @@ static void igc_ethtool_get_regs(struct net_device *netdev,
for (i = 0; i < 8; i++)
regs_buff[205 + i] = rd32(IGC_ETQF(i));
regs_buff[213] = adapter->stats.tlpic;
regs_buff[214] = adapter->stats.rlpic;
}
static void igc_ethtool_get_wol(struct net_device *netdev,
......
......@@ -24,6 +24,11 @@
#define IGC_DEV_ID_I225_K2 0x3101
#define IGC_DEV_ID_I225_LMVP 0x5502
#define IGC_DEV_ID_I225_IT 0x0D9F
#define IGC_DEV_ID_I226_LM 0x125B
#define IGC_DEV_ID_I226_V 0x125C
#define IGC_DEV_ID_I226_IT 0x125D
#define IGC_DEV_ID_I221_V 0x125E
#define IGC_DEV_ID_I226_BLANK_NVM 0x125F
#define IGC_DEV_ID_I225_BLANK_NVM 0x15FD
/* Function pointers for the MAC. */
......@@ -125,9 +130,6 @@ struct igc_nvm_info {
struct igc_nvm_operations ops;
enum igc_nvm_type type;
u32 flash_bank_size;
u32 flash_base_addr;
u16 word_size;
u16 delay_usec;
u16 address_bits;
......@@ -153,7 +155,6 @@ struct igc_phy_info {
u8 mdix;
bool is_mdix;
bool reset_disable;
bool speed_downgraded;
bool autoneg_wait_to_complete;
};
......@@ -239,6 +240,8 @@ struct igc_hw_stats {
u64 prc511;
u64 prc1023;
u64 prc1522;
u64 tlpic;
u64 rlpic;
u64 gprc;
u64 bprc;
u64 mprc;
......
......@@ -47,6 +47,11 @@ static const struct pci_device_id igc_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_K2), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_LMVP), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_IT), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I226_LM), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I226_V), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I226_IT), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I221_V), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I226_BLANK_NVM), board_base },
{ PCI_VDEVICE(INTEL, IGC_DEV_ID_I225_BLANK_NVM), board_base },
/* required last entry */
{0, }
......@@ -1428,7 +1433,7 @@ static void igc_rx_checksum(struct igc_ring *ring,
/* TCP/UDP checksum error bit is set */
if (igc_test_staterr(rx_desc,
IGC_RXDEXT_STATERR_TCPE |
IGC_RXDEXT_STATERR_L4E |
IGC_RXDEXT_STATERR_IPE)) {
/* work around errata with sctp packets where the TCPE aka
* L4E bit is set incorrectly on 64 byte (60 byte w/o crc)
......@@ -1737,8 +1742,7 @@ static bool igc_cleanup_headers(struct igc_ring *rx_ring,
union igc_adv_rx_desc *rx_desc,
struct sk_buff *skb)
{
if (unlikely((igc_test_staterr(rx_desc,
IGC_RXDEXT_ERR_FRAME_ERR_MASK)))) {
if (unlikely(igc_test_staterr(rx_desc, IGC_RXDEXT_STATERR_RXE))) {
struct net_device *netdev = rx_ring->netdev;
if (!(netdev->features & NETIF_F_RXALL)) {
......@@ -3679,6 +3683,8 @@ void igc_update_stats(struct igc_adapter *adapter)
adapter->stats.prc511 += rd32(IGC_PRC511);
adapter->stats.prc1023 += rd32(IGC_PRC1023);
adapter->stats.prc1522 += rd32(IGC_PRC1522);
adapter->stats.tlpic += rd32(IGC_TLPIC);
adapter->stats.rlpic += rd32(IGC_RLPIC);
mpc = rd32(IGC_MPC);
adapter->stats.mpc += mpc;
......@@ -3772,6 +3778,8 @@ void igc_down(struct igc_adapter *adapter)
set_bit(__IGC_DOWN, &adapter->state);
igc_ptp_suspend(adapter);
/* disable receives in the hardware */
rctl = rd32(IGC_RCTL);
wr32(IGC_RCTL, rctl & ~IGC_RCTL_EN);
......@@ -4694,14 +4702,35 @@ static int igc_save_launchtime_params(struct igc_adapter *adapter, int queue,
return 0;
}
static bool validate_schedule(const struct tc_taprio_qopt_offload *qopt)
static bool is_base_time_past(ktime_t base_time, const struct timespec64 *now)
{
struct timespec64 b;
b = ktime_to_timespec64(base_time);
return timespec64_compare(now, &b) > 0;
}
static bool validate_schedule(struct igc_adapter *adapter,
const struct tc_taprio_qopt_offload *qopt)
{
int queue_uses[IGC_MAX_TX_QUEUES] = { };
struct timespec64 now;
size_t n;
if (qopt->cycle_time_extension)
return false;
igc_ptp_read(adapter, &now);
/* If we program the controller's BASET registers with a time
* in the future, it will hold all the packets until that
* time, causing a lot of TX Hangs, so to avoid that, we
* reject schedules that would start in the future.
*/
if (!is_base_time_past(qopt->base_time, &now))
return false;
for (n = 0; n < qopt->num_entries; n++) {
const struct tc_taprio_sched_entry *e;
int i;
......@@ -4756,7 +4785,7 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
if (adapter->base_time)
return -EALREADY;
if (!validate_schedule(qopt))
if (!validate_schedule(adapter, qopt))
return -EINVAL;
adapter->cycle_time = qopt->cycle_time;
......
......@@ -8,6 +8,7 @@
#include <linux/pci.h>
#include <linux/ptp_classify.h>
#include <linux/clocksource.h>
#include <linux/ktime.h>
#define INCVALUE_MASK 0x7fffffff
#define ISGN 0x80000000
......@@ -16,17 +17,12 @@
#define IGC_PTP_TX_TIMEOUT (HZ * 15)
/* SYSTIM read access for I225 */
static void igc_ptp_read_i225(struct igc_adapter *adapter,
struct timespec64 *ts)
void igc_ptp_read(struct igc_adapter *adapter, struct timespec64 *ts)
{
struct igc_hw *hw = &adapter->hw;
u32 sec, nsec;
/* The timestamp latches on lowest register read. For I210/I211, the
* lowest register is SYSTIMR. Since we only need to provide nanosecond
* resolution, we can ignore it.
*/
rd32(IGC_SYSTIMR);
/* The timestamp is latched when SYSTIML is read. */
nsec = rd32(IGC_SYSTIML);
sec = rd32(IGC_SYSTIMH);
......@@ -39,9 +35,6 @@ static void igc_ptp_write_i225(struct igc_adapter *adapter,
{
struct igc_hw *hw = &adapter->hw;
/* Writing the SYSTIMR register is not necessary as it only
* provides sub-nanosecond resolution.
*/
wr32(IGC_SYSTIML, ts->tv_nsec);
wr32(IGC_SYSTIMH, ts->tv_sec);
}
......@@ -81,7 +74,7 @@ static int igc_ptp_adjtime_i225(struct ptp_clock_info *ptp, s64 delta)
spin_lock_irqsave(&igc->tmreg_lock, flags);
igc_ptp_read_i225(igc, &now);
igc_ptp_read(igc, &now);
now = timespec64_add(now, then);
igc_ptp_write_i225(igc, (const struct timespec64 *)&now);
......@@ -102,10 +95,9 @@ static int igc_ptp_gettimex64_i225(struct ptp_clock_info *ptp,
spin_lock_irqsave(&igc->tmreg_lock, flags);
ptp_read_system_prets(sts);
rd32(IGC_SYSTIMR);
ptp_read_system_postts(sts);
ts->tv_nsec = rd32(IGC_SYSTIML);
ts->tv_sec = rd32(IGC_SYSTIMH);
ptp_read_system_postts(sts);
spin_unlock_irqrestore(&igc->tmreg_lock, flags);
......@@ -422,18 +414,11 @@ static void igc_ptp_tx_work(struct work_struct *work)
if (!test_bit(__IGC_PTP_TX_IN_PROGRESS, &adapter->state))
return;
if (time_is_before_jiffies(adapter->ptp_tx_start +
IGC_PTP_TX_TIMEOUT)) {
igc_ptp_tx_timeout(adapter);
tsynctxctl = rd32(IGC_TSYNCTXCTL);
if (WARN_ON_ONCE(!(tsynctxctl & IGC_TSYNCTXCTL_TXTT_0)))
return;
}
tsynctxctl = rd32(IGC_TSYNCTXCTL);
if (tsynctxctl & IGC_TSYNCTXCTL_VALID)
igc_ptp_tx_hwtstamp(adapter);
else
/* reschedule to check later */
schedule_work(&adapter->ptp_tx_work);
}
/**
......@@ -515,6 +500,9 @@ void igc_ptp_init(struct igc_adapter *adapter)
adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
adapter->prev_ptp_time = ktime_to_timespec64(ktime_get_real());
adapter->ptp_reset_start = ktime_get();
adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
&adapter->pdev->dev);
if (IS_ERR(adapter->ptp_clock)) {
......@@ -526,6 +514,24 @@ void igc_ptp_init(struct igc_adapter *adapter)
}
}
static void igc_ptp_time_save(struct igc_adapter *adapter)
{
igc_ptp_read(adapter, &adapter->prev_ptp_time);
adapter->ptp_reset_start = ktime_get();
}
static void igc_ptp_time_restore(struct igc_adapter *adapter)
{
struct timespec64 ts = adapter->prev_ptp_time;
ktime_t delta;
delta = ktime_sub(ktime_get(), adapter->ptp_reset_start);
timespec64_add_ns(&ts, ktime_to_ns(delta));
igc_ptp_write_i225(adapter, &ts);
}
/**
* igc_ptp_suspend - Disable PTP work items and prepare for suspend
* @adapter: Board private structure
......@@ -542,6 +548,8 @@ void igc_ptp_suspend(struct igc_adapter *adapter)
dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL;
clear_bit_unlock(__IGC_PTP_TX_IN_PROGRESS, &adapter->state);
igc_ptp_time_save(adapter);
}
/**
......@@ -591,9 +599,7 @@ void igc_ptp_reset(struct igc_adapter *adapter)
/* Re-initialize the timer. */
if (hw->mac.type == igc_i225) {
struct timespec64 ts64 = ktime_to_timespec64(ktime_get_real());
igc_ptp_write_i225(adapter, &ts64);
igc_ptp_time_restore(adapter);
} else {
timecounter_init(&adapter->tc, &adapter->cc,
ktime_to_ns(ktime_get_real()));
......
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