Skip to content

Commit

Permalink
igc: Add basic skeleton for PTP
Browse files Browse the repository at this point in the history
This allows the creation of the /dev/ptpX device for i225, and reading
and writing the time.

Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
vcgomes authored and Jeff Kirsher committed Jan 6, 2020
1 parent df2c2ba commit 5f29580
Show file tree
Hide file tree
Showing 6 changed files with 439 additions and 1 deletion.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/igc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
obj-$(CONFIG_IGC) += igc.o

igc-objs := igc_main.o igc_mac.o igc_i225.o igc_base.o igc_nvm.o igc_phy.o \
igc_ethtool.o
igc_ethtool.o igc_ptp.o
26 changes: 26 additions & 0 deletions drivers/net/ethernet/intel/igc/igc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <linux/vmalloc.h>
#include <linux/ethtool.h>
#include <linux/sctp.h>
#include <linux/ptp_clock_kernel.h>
#include <linux/timecounter.h>
#include <linux/net_tstamp.h>

#include "igc_hw.h"

Expand Down Expand Up @@ -45,11 +48,15 @@ extern char igc_driver_version[];
#define IGC_REGS_LEN 740
#define IGC_RETA_SIZE 128

/* flags controlling PTP/1588 function */
#define IGC_PTP_ENABLED BIT(0)

/* Interrupt defines */
#define IGC_START_ITR 648 /* ~6000 ints/sec */
#define IGC_FLAG_HAS_MSI BIT(0)
#define IGC_FLAG_QUEUE_PAIRS BIT(3)
#define IGC_FLAG_DMAC BIT(4)
#define IGC_FLAG_PTP BIT(8)
#define IGC_FLAG_NEED_LINK_UPDATE BIT(9)
#define IGC_FLAG_MEDIA_RESET BIT(10)
#define IGC_FLAG_MAS_ENABLE BIT(12)
Expand Down Expand Up @@ -432,6 +439,20 @@ struct igc_adapter {

unsigned long link_check_timeout;
struct igc_info ei;

struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
struct work_struct ptp_tx_work;
struct sk_buff *ptp_tx_skb;
struct hwtstamp_config tstamp_config;
unsigned long ptp_tx_start;
unsigned long last_rx_ptp_check;
unsigned long last_rx_timestamp;
unsigned int ptp_flags;
/* System time value lock */
spinlock_t tmreg_lock;
struct cyclecounter cc;
struct timecounter tc;
};

/* igc_desc_unused - calculate if we have unused descriptors */
Expand Down Expand Up @@ -515,6 +536,11 @@ int igc_add_filter(struct igc_adapter *adapter,
int igc_erase_filter(struct igc_adapter *adapter,
struct igc_nfc_filter *input);

void igc_ptp_init(struct igc_adapter *adapter);
void igc_ptp_reset(struct igc_adapter *adapter);
void igc_ptp_stop(struct igc_adapter *adapter);
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);
#define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring))

#define IGC_TXD_DCMD (IGC_ADVTXD_DCMD_EOP | IGC_ADVTXD_DCMD_RS)
Expand Down
12 changes: 12 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@
#define IGC_ICR_RXDMT0 BIT(4) /* Rx desc min. threshold (0) */
#define IGC_ICR_RXO BIT(6) /* Rx overrun */
#define IGC_ICR_RXT0 BIT(7) /* Rx timer intr (ring 0) */
#define IGC_ICR_TS BIT(19) /* Time Sync Interrupt */
#define IGC_ICR_DRSTA BIT(30) /* Device Reset Asserted */

/* If this bit asserted, the driver should claim the interrupt */
Expand All @@ -240,6 +241,7 @@
#define IGC_IMS_DRSTA IGC_ICR_DRSTA /* Device Reset Asserted */
#define IGC_IMS_RXT0 IGC_ICR_RXT0 /* Rx timer intr */
#define IGC_IMS_RXDMT0 IGC_ICR_RXDMT0 /* Rx desc min. threshold */
#define IGC_IMS_TS IGC_ICR_TS /* Time Sync Interrupt */

#define IGC_QVECTOR_MASK 0x7FFC /* Q-vector mask */
#define IGC_ITR_VAL_MASK 0x04 /* ITR value mask */
Expand Down Expand Up @@ -355,6 +357,16 @@
#define I225_RXPBSIZE_DEFAULT 0x000000A2 /* RXPBSIZE default */
#define I225_TXPBSIZE_DEFAULT 0x04000014 /* TXPBSIZE default */

/* Time Sync Interrupt Causes */
#define IGC_TSICR_SYS_WRAP BIT(0) /* SYSTIM Wrap around. */
#define IGC_TSICR_TXTS BIT(1) /* Transmit Timestamp. */
#define IGC_TSICR_TT0 BIT(3) /* Target Time 0 Trigger. */
#define IGC_TSICR_TT1 BIT(4) /* Target Time 1 Trigger. */
#define IGC_TSICR_AUTT0 BIT(5) /* Auxiliary Timestamp 0 Taken. */
#define IGC_TSICR_AUTT1 BIT(6) /* Auxiliary Timestamp 1 Taken. */

#define IGC_TSICR_INTERRUPTS IGC_TSICR_TXTS

/* Receive Checksum Control */
#define IGC_RXCSUM_CRCOFL 0x00000800 /* CRC32 offload enable */
#define IGC_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
Expand Down
27 changes: 27 additions & 0 deletions drivers/net/ethernet/intel/igc/igc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ void igc_reset(struct igc_adapter *adapter)
if (!netif_running(adapter->netdev))
igc_power_down_link(adapter);

/* Re-enable PTP, where applicable. */
igc_ptp_reset(adapter);

igc_get_phy_info(hw);
}

Expand Down Expand Up @@ -4277,6 +4280,24 @@ static int igc_close(struct net_device *netdev)
return 0;
}

/**
* igc_ioctl - Access the hwtstamp interface
* @netdev: network interface device structure
* @ifreq: interface request data
* @cmd: ioctl command
**/
static int igc_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
case SIOCGHWTSTAMP:
return igc_ptp_get_ts_config(netdev, ifr);
case SIOCSHWTSTAMP:
return igc_ptp_set_ts_config(netdev, ifr);
default:
return -EOPNOTSUPP;
}
}

static const struct net_device_ops igc_netdev_ops = {
.ndo_open = igc_open,
.ndo_stop = igc_close,
Expand All @@ -4288,6 +4309,7 @@ static const struct net_device_ops igc_netdev_ops = {
.ndo_fix_features = igc_fix_features,
.ndo_set_features = igc_set_features,
.ndo_features_check = igc_features_check,
.ndo_do_ioctl = igc_ioctl,
};

/* PCIe configuration access */
Expand Down Expand Up @@ -4588,6 +4610,9 @@ static int igc_probe(struct pci_dev *pdev,
/* carrier off reporting is important to ethtool even BEFORE open */
netif_carrier_off(netdev);

/* do hw tstamp init after resetting */
igc_ptp_init(adapter);

/* Check if Media Autosense is enabled */
adapter->ei = *ei;

Expand Down Expand Up @@ -4629,6 +4654,8 @@ static void igc_remove(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct igc_adapter *adapter = netdev_priv(netdev);

igc_ptp_stop(adapter);

set_bit(__IGC_DOWN, &adapter->state);

del_timer_sync(&adapter->watchdog_timer);
Expand Down
Loading

0 comments on commit 5f29580

Please sign in to comment.