* [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start(). @ 2012-12-04 5:36 Michael Chan 2012-12-04 5:36 ` [PATCH 2/5 net-next v2] tg3: PTP - Add header definitions, initialization and hw access functions Michael Chan ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Michael Chan @ 2012-12-04 5:36 UTC (permalink / raw) To: davem; +Cc: netdev, nsujir, richardcochran From: Nithin Nayak Sujir <nsujir@broadcom.com> Every caller holds tp->lock when calling tg3_netif_start() except tg3_io_resume(). Fix it so that it is all consistent. The subsequent PTP patches add tg3_ptp_resume() to tg3_netif_start() and the tp->lock is required. Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> --- drivers/net/ethernet/broadcom/tg3.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 5cc976d..41a2dbd 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -6525,6 +6525,7 @@ static inline void tg3_netif_stop(struct tg3 *tp) netif_tx_disable(tp->dev); } +/* tp->lock must be held */ static inline void tg3_netif_start(struct tg3 *tp) { /* NOTE: unconditional netif_tx_wake_all_queues is only @@ -16598,8 +16599,8 @@ static void tg3_io_resume(struct pci_dev *pdev) tg3_full_lock(tp, 0); tg3_flag_set(tp, INIT_COMPLETE); err = tg3_restart_hw(tp, 1); - tg3_full_unlock(tp); if (err) { + tg3_full_unlock(tp); netdev_err(netdev, "Cannot restart hardware after reset.\n"); goto done; } @@ -16610,6 +16611,8 @@ static void tg3_io_resume(struct pci_dev *pdev) tg3_netif_start(tp); + tg3_full_unlock(tp); + tg3_phy_start(tp); done: -- 1.7.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/5 net-next v2] tg3: PTP - Add header definitions, initialization and hw access functions. 2012-12-04 5:36 [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start() Michael Chan @ 2012-12-04 5:36 ` Michael Chan 2012-12-04 5:36 ` [PATCH 3/5 net-next v2] tg3: PTP - Implement the ptp api and ethtool functions Michael Chan 2012-12-04 8:48 ` [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start() Richard Cochran 2012-12-04 18:02 ` David Miller 2 siblings, 1 reply; 7+ messages in thread From: Michael Chan @ 2012-12-04 5:36 UTC (permalink / raw) To: davem; +Cc: netdev, nsujir, richardcochran From: Matt Carlson <mcarlson@broadcom.com> This patch adds code to write the reference clock. If a chip reset is performed, the hwclock is reinitialized with the adjusted kernel time Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Cc: Richard Cochran <richardcochran@gmail.com> --- drivers/net/ethernet/broadcom/Kconfig | 1 + drivers/net/ethernet/broadcom/tg3.c | 61 ++++++++++++++++++++++++++++++-- drivers/net/ethernet/broadcom/tg3.h | 60 ++++++++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 4bd416b..f552673 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -102,6 +102,7 @@ config TIGON3 depends on PCI select PHYLIB select HWMON + select PTP_1588_CLOCK ---help--- This driver supports Broadcom Tigon3 based gigabit Ethernet cards. diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 41a2dbd..6922596 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -54,6 +54,9 @@ #include <asm/byteorder.h> #include <linux/uaccess.h> +#include <uapi/linux/net_tstamp.h> +#include <linux/ptp_clock_kernel.h> + #ifdef CONFIG_SPARC #include <asm/idprom.h> #include <asm/prom.h> @@ -5516,6 +5519,45 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) return err; } +/* tp->lock must be held */ +static void tg3_refclk_write(struct tg3 *tp, u64 newval) +{ + tw32(TG3_EAV_REF_CLCK_CTL, TG3_EAV_REF_CLCK_CTL_STOP); + tw32(TG3_EAV_REF_CLCK_LSB, newval & 0xffffffff); + tw32(TG3_EAV_REF_CLCK_MSB, newval >> 32); + tw32_f(TG3_EAV_REF_CLCK_CTL, TG3_EAV_REF_CLCK_CTL_RESUME); +} + +/* tp->lock must be held */ +static void tg3_ptp_init(struct tg3 *tp) +{ + if (!tg3_flag(tp, PTP_CAPABLE)) + return; + + /* Initialize the hardware clock to the system time. */ + tg3_refclk_write(tp, ktime_to_ns(ktime_get_real())); + tp->ptp_adjust = 0; +} + +/* tp->lock must be held */ +static void tg3_ptp_resume(struct tg3 *tp) +{ + if (!tg3_flag(tp, PTP_CAPABLE)) + return; + + tg3_refclk_write(tp, ktime_to_ns(ktime_get_real()) + tp->ptp_adjust); + tp->ptp_adjust = 0; +} + +static void tg3_ptp_fini(struct tg3 *tp) +{ + if (!tg3_flag(tp, PTP_CAPABLE) || !tp->ptp_clock) + return; + + tp->ptp_clock = NULL; + tp->ptp_adjust = 0; +} + static inline int tg3_irq_sync(struct tg3 *tp) { return tp->irq_sync; @@ -6528,6 +6570,8 @@ static inline void tg3_netif_stop(struct tg3 *tp) /* tp->lock must be held */ static inline void tg3_netif_start(struct tg3 *tp) { + tg3_ptp_resume(tp); + /* NOTE: unconditional netif_tx_wake_all_queues is only * appropriate so long as all callers are assured to * have free tx slots (such as after tg3_init_hw) @@ -10365,7 +10409,8 @@ static void tg3_ints_fini(struct tg3 *tp) tg3_flag_clear(tp, ENABLE_TSS); } -static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq) +static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq, + bool init) { struct net_device *dev = tp->dev; int i, err; @@ -10444,6 +10489,12 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq) tg3_flag_set(tp, INIT_COMPLETE); tg3_enable_ints(tp); + if (init) + tg3_ptp_init(tp); + else + tg3_ptp_resume(tp); + + tg3_full_unlock(tp); netif_tx_start_all_queues(dev); @@ -10541,11 +10592,12 @@ static int tg3_open(struct net_device *dev) tg3_full_unlock(tp); - err = tg3_start(tp, true, true); + err = tg3_start(tp, true, true, true); if (err) { tg3_frob_aux_power(tp, false); pci_set_power_state(tp->pdev, PCI_D3hot); } + return err; } @@ -10553,6 +10605,8 @@ static int tg3_close(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); + tg3_ptp_fini(tp); + tg3_stop(tp); /* Clear stats across close / open calls */ @@ -11455,7 +11509,7 @@ static int tg3_set_channels(struct net_device *dev, tg3_carrier_off(tp); - tg3_start(tp, true, false); + tg3_start(tp, true, false, false); return 0; } @@ -12508,7 +12562,6 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, } tg3_full_lock(tp, irq_sync); - tg3_halt(tp, RESET_KIND_SUSPEND, 1); err = tg3_nvram_lock(tp); tg3_halt_cpu(tp, RX_CPU_BASE); diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h index 4534804..d330e81 100644 --- a/drivers/net/ethernet/broadcom/tg3.h +++ b/drivers/net/ethernet/broadcom/tg3.h @@ -772,7 +772,10 @@ #define SG_DIG_MAC_ACK_STATUS 0x00000004 #define SG_DIG_AUTONEG_COMPLETE 0x00000002 #define SG_DIG_AUTONEG_ERROR 0x00000001 -/* 0x5b8 --> 0x600 unused */ +#define TG3_TX_TSTAMP_LSB 0x000005c0 +#define TG3_TX_TSTAMP_MSB 0x000005c4 +#define TG3_TSTAMP_MASK 0x7fffffffffffffff +/* 0x5c8 --> 0x600 unused */ #define MAC_TX_MAC_STATE_BASE 0x00000600 /* 16 bytes */ #define MAC_RX_MAC_STATE_BASE 0x00000610 /* 20 bytes */ /* 0x624 --> 0x670 unused */ @@ -789,7 +792,36 @@ #define MAC_RSS_HASH_KEY_7 0x0000068c #define MAC_RSS_HASH_KEY_8 0x00000690 #define MAC_RSS_HASH_KEY_9 0x00000694 -/* 0x698 --> 0x800 unused */ +/* 0x698 --> 0x6b0 unused */ + +#define TG3_RX_TSTAMP_LSB 0x000006b0 +#define TG3_RX_TSTAMP_MSB 0x000006b4 +/* 0x6b8 --> 0x6c8 unused */ + +#define TG3_RX_PTP_CTL 0x000006c8 +#define TG3_RX_PTP_CTL_SYNC_EVNT 0x00000001 +#define TG3_RX_PTP_CTL_DELAY_REQ 0x00000002 +#define TG3_RX_PTP_CTL_PDLAY_REQ 0x00000004 +#define TG3_RX_PTP_CTL_PDLAY_RES 0x00000008 +#define TG3_RX_PTP_CTL_ALL_V1_EVENTS (TG3_RX_PTP_CTL_SYNC_EVNT | \ + TG3_RX_PTP_CTL_DELAY_REQ) +#define TG3_RX_PTP_CTL_ALL_V2_EVENTS (TG3_RX_PTP_CTL_SYNC_EVNT | \ + TG3_RX_PTP_CTL_DELAY_REQ | \ + TG3_RX_PTP_CTL_PDLAY_REQ | \ + TG3_RX_PTP_CTL_PDLAY_RES) +#define TG3_RX_PTP_CTL_FOLLOW_UP 0x00000100 +#define TG3_RX_PTP_CTL_DELAY_RES 0x00000200 +#define TG3_RX_PTP_CTL_PDRES_FLW_UP 0x00000400 +#define TG3_RX_PTP_CTL_ANNOUNCE 0x00000800 +#define TG3_RX_PTP_CTL_SIGNALING 0x00001000 +#define TG3_RX_PTP_CTL_MANAGEMENT 0x00002000 +#define TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN 0x00800000 +#define TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN 0x01000000 +#define TG3_RX_PTP_CTL_RX_PTP_V2_EN (TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | \ + TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN) +#define TG3_RX_PTP_CTL_RX_PTP_V1_EN 0x02000000 +#define TG3_RX_PTP_CTL_HWTS_INTERLOCK 0x04000000 +/* 0x6cc --> 0x800 unused */ #define MAC_TX_STATS_OCTETS 0x00000800 #define MAC_TX_STATS_RESV1 0x00000804 @@ -1669,6 +1701,7 @@ #define GRC_MODE_HOST_STACKUP 0x00010000 #define GRC_MODE_HOST_SENDBDS 0x00020000 #define GRC_MODE_HTX2B_ENABLE 0x00040000 +#define GRC_MODE_TIME_SYNC_ENABLE 0x00080000 #define GRC_MODE_NO_TX_PHDR_CSUM 0x00100000 #define GRC_MODE_NVRAM_WR_ENABLE 0x00200000 #define GRC_MODE_PCIE_TL_SEL 0x00000000 @@ -1771,7 +1804,17 @@ #define GRC_VCPU_EXT_CTRL_DISABLE_WOL 0x20000000 #define GRC_FASTBOOT_PC 0x00006894 /* 5752, 5755, 5787 */ -/* 0x6c00 --> 0x7000 unused */ +#define TG3_EAV_REF_CLCK_LSB 0x00006900 +#define TG3_EAV_REF_CLCK_MSB 0x00006904 +#define TG3_EAV_REF_CLCK_CTL 0x00006908 +#define TG3_EAV_REF_CLCK_CTL_STOP 0x00000002 +#define TG3_EAV_REF_CLCK_CTL_RESUME 0x00000004 +#define TG3_EAV_REF_CLK_CORRECT_CTL 0x00006928 +#define TG3_EAV_REF_CLK_CORRECT_EN (1 << 31) +#define TG3_EAV_REF_CLK_CORRECT_NEG (1 << 30) + +#define TG3_EAV_REF_CLK_CORRECT_MASK 0xffffff +/* 0x690c --> 0x7000 unused */ /* NVRAM Control registers */ #define NVRAM_CMD 0x00007000 @@ -2439,6 +2482,7 @@ struct tg3_tx_buffer_desc { #define TXD_FLAG_IP_FRAG 0x0008 #define TXD_FLAG_JMB_PKT 0x0008 #define TXD_FLAG_IP_FRAG_END 0x0010 +#define TXD_FLAG_HWTSTAMP 0x0020 #define TXD_FLAG_VLAN 0x0040 #define TXD_FLAG_COAL_NOW 0x0080 #define TXD_FLAG_CPU_PRE_DMA 0x0100 @@ -2480,6 +2524,9 @@ struct tg3_rx_buffer_desc { #define RXD_FLAG_IP_CSUM 0x1000 #define RXD_FLAG_TCPUDP_CSUM 0x2000 #define RXD_FLAG_IS_TCP 0x4000 +#define RXD_FLAG_PTPSTAT_MASK 0x0210 +#define RXD_FLAG_PTPSTAT_PTPV1 0x0010 +#define RXD_FLAG_PTPSTAT_PTPV2 0x0200 u32 ip_tcp_csum; #define RXD_IPCSUM_MASK 0xffff0000 @@ -2970,9 +3017,11 @@ enum TG3_FLAGS { TG3_FLAG_USE_JUMBO_BDFLAG, TG3_FLAG_L1PLLPD_EN, TG3_FLAG_APE_HAS_NCSI, + TG3_FLAG_TX_TSTAMP_EN, TG3_FLAG_4K_FIFO_LIMIT, TG3_FLAG_5719_RDMA_BUG, TG3_FLAG_RESET_TASK_PENDING, + TG3_FLAG_PTP_CAPABLE, TG3_FLAG_5705_PLUS, TG3_FLAG_IS_5788, TG3_FLAG_5750_PLUS, @@ -3041,6 +3090,10 @@ struct tg3 { u32 coal_now; u32 msg_enable; + struct ptp_clock_info ptp_info; + struct ptp_clock *ptp_clock; + s64 ptp_adjust; + /* begin "tx thread" cacheline section */ void (*write32_tx_mbox) (struct tg3 *, u32, u32); @@ -3108,6 +3161,7 @@ struct tg3 { u32 dma_rwctrl; u32 coalesce_mode; u32 pwrmgmt_thresh; + u32 rxptpctl; /* PCI block */ u32 pci_chip_rev_id; -- 1.7.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/5 net-next v2] tg3: PTP - Implement the ptp api and ethtool functions 2012-12-04 5:36 ` [PATCH 2/5 net-next v2] tg3: PTP - Add header definitions, initialization and hw access functions Michael Chan @ 2012-12-04 5:36 ` Michael Chan 2012-12-04 5:36 ` [PATCH 4/5 net-next v2] tg3: PTP - Add the hardware timestamp ioctl Michael Chan 0 siblings, 1 reply; 7+ messages in thread From: Michael Chan @ 2012-12-04 5:36 UTC (permalink / raw) To: davem; +Cc: netdev, nsujir, richardcochran From: Matt Carlson <mcarlson@broadcom.com> This patch adds the ptp_caps structure, ptp api implementation, reference clock read and register/unregister functions. All the basic clock operations as described in Documentation/ptp/ptp.txt are supported. Frequency adjustment is performed using hardware with a 24 bit accumulator and a programmable correction value. On each clk, the correction value gets added to the accumulator and when it overflows, the time counter is incremented/decremented and the accumulator reset. So conversion from ppb to correction value is ppb * (1 << 24) / 1000000000 [Re-organized to put the ptp_clock_info struct declaration in one patch, added ptp_clock_info.name, and added locking to tg3_ptp_adjtime() based on input from Richard Cochran.] Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Cc: Richard Cochran <richardcochran@gmail.com> --- drivers/net/ethernet/broadcom/tg3.c | 146 ++++++++++++++++++++++++++++++++++- 1 files changed, 145 insertions(+), 1 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 6922596..58af2a1 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -5520,6 +5520,13 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) } /* tp->lock must be held */ +static u64 tg3_refclk_read(struct tg3 *tp) +{ + u64 stamp = tr32(TG3_EAV_REF_CLCK_LSB); + return stamp | (u64)tr32(TG3_EAV_REF_CLCK_MSB) << 32; +} + +/* tp->lock must be held */ static void tg3_refclk_write(struct tg3 *tp, u64 newval) { tw32(TG3_EAV_REF_CLCK_CTL, TG3_EAV_REF_CLCK_CTL_STOP); @@ -5528,6 +5535,134 @@ static void tg3_refclk_write(struct tg3 *tp, u64 newval) tw32_f(TG3_EAV_REF_CLCK_CTL, TG3_EAV_REF_CLCK_CTL_RESUME); } +static inline void tg3_full_lock(struct tg3 *tp, int irq_sync); +static inline void tg3_full_unlock(struct tg3 *tp); +static int tg3_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info) +{ + struct tg3 *tp = netdev_priv(dev); + + info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + + if (tp->ptp_clock) + info->phc_index = ptp_clock_index(tp->ptp_clock); + else + info->phc_index = -1; + + info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); + + info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) | + (1 << HWTSTAMP_FILTER_PTP_V1_L4_EVENT) | + (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | + (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT); + return 0; +} + +static int tg3_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb) +{ + struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); + bool neg_adj = false; + u32 correction = 0; + + if (ppb < 0) { + neg_adj = true; + ppb = -ppb; + } + + /* Frequency adjustment is performed using hardware with a 24 bit + * accumulator and a programmable correction value. On each clk, the + * correction value gets added to the accumulator and when it + * overflows, the time counter is incremented/decremented. + * + * So conversion from ppb to correction value is + * ppb * (1 << 24) / 1000000000 + */ + correction = div_u64((u64)ppb * (1 << 24), 1000000000ULL) & + TG3_EAV_REF_CLK_CORRECT_MASK; + + tg3_full_lock(tp, 0); + + if (correction) + tw32(TG3_EAV_REF_CLK_CORRECT_CTL, + TG3_EAV_REF_CLK_CORRECT_EN | + (neg_adj ? TG3_EAV_REF_CLK_CORRECT_NEG : 0) | correction); + else + tw32(TG3_EAV_REF_CLK_CORRECT_CTL, 0); + + tg3_full_unlock(tp); + + return 0; +} + +static int tg3_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); + + tg3_full_lock(tp, 0); + tp->ptp_adjust += delta; + tg3_full_unlock(tp); + + return 0; +} + +static int tg3_ptp_gettime(struct ptp_clock_info *ptp, struct timespec *ts) +{ + u64 ns; + u32 remainder; + struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); + + tg3_full_lock(tp, 0); + ns = tg3_refclk_read(tp); + ns += tp->ptp_adjust; + tg3_full_unlock(tp); + + ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder); + ts->tv_nsec = remainder; + + return 0; +} + +static int tg3_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec *ts) +{ + u64 ns; + struct tg3 *tp = container_of(ptp, struct tg3, ptp_info); + + ns = timespec_to_ns(ts); + + tg3_full_lock(tp, 0); + tg3_refclk_write(tp, ns); + tp->ptp_adjust = 0; + tg3_full_unlock(tp); + + return 0; +} + +static int tg3_ptp_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + return -EOPNOTSUPP; +} + +static const struct ptp_clock_info tg3_ptp_caps = { + .owner = THIS_MODULE, + .name = "tg3 clock", + .max_adj = 250000000, + .n_alarm = 0, + .n_ext_ts = 0, + .n_per_out = 0, + .pps = 0, + .adjfreq = tg3_ptp_adjfreq, + .adjtime = tg3_ptp_adjtime, + .gettime = tg3_ptp_gettime, + .settime = tg3_ptp_settime, + .enable = tg3_ptp_enable, +}; + /* tp->lock must be held */ static void tg3_ptp_init(struct tg3 *tp) { @@ -5537,6 +5672,7 @@ static void tg3_ptp_init(struct tg3 *tp) /* Initialize the hardware clock to the system time. */ tg3_refclk_write(tp, ktime_to_ns(ktime_get_real())); tp->ptp_adjust = 0; + tp->ptp_info = tg3_ptp_caps; } /* tp->lock must be held */ @@ -5554,6 +5690,7 @@ static void tg3_ptp_fini(struct tg3 *tp) if (!tg3_flag(tp, PTP_CAPABLE) || !tp->ptp_clock) return; + ptp_clock_unregister(tp->ptp_clock); tp->ptp_clock = NULL; tp->ptp_adjust = 0; } @@ -10598,6 +10735,13 @@ static int tg3_open(struct net_device *dev) pci_set_power_state(tp->pdev, PCI_D3hot); } + if (tg3_flag(tp, PTP_CAPABLE)) { + tp->ptp_clock = ptp_clock_register(&tp->ptp_info, + &tp->pdev->dev); + if (IS_ERR(tp->ptp_clock)) + tp->ptp_clock = NULL; + } + return err; } @@ -12767,7 +12911,7 @@ static const struct ethtool_ops tg3_ethtool_ops = { .set_rxfh_indir = tg3_set_rxfh_indir, .get_channels = tg3_get_channels, .set_channels = tg3_set_channels, - .get_ts_info = ethtool_op_get_ts_info, + .get_ts_info = tg3_get_ts_info, }; static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, -- 1.7.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/5 net-next v2] tg3: PTP - Add the hardware timestamp ioctl 2012-12-04 5:36 ` [PATCH 3/5 net-next v2] tg3: PTP - Implement the ptp api and ethtool functions Michael Chan @ 2012-12-04 5:36 ` Michael Chan 2012-12-04 5:37 ` [PATCH 5/5 net-next v2] tg3: PTP - Enable the timestamping feature in hardware and fill skb tx/rx timestamps Michael Chan 0 siblings, 1 reply; 7+ messages in thread From: Michael Chan @ 2012-12-04 5:36 UTC (permalink / raw) To: davem; +Cc: netdev, nsujir, richardcochran From: Matt Carlson <mcarlson@broadcom.com> This patch implements the SIOCSHWTSTAMP ioctl as described in Documentation/networking/timestamping.txt [Removed HWTSTAMP_FILTER_ALL handling by returning -ERANGE based on input from Richard Cochran.] Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Cc: Richard Cochran <richardcochran@gmail.com> --- drivers/net/ethernet/broadcom/tg3.c | 93 +++++++++++++++++++++++++++++++++++ 1 files changed, 93 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 58af2a1..dddb21e 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -12760,6 +12760,96 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, } +static int tg3_hwtstamp_ioctl(struct net_device *dev, + struct ifreq *ifr, int cmd) +{ + struct tg3 *tp = netdev_priv(dev); + struct hwtstamp_config stmpconf; + + if (!tg3_flag(tp, PTP_CAPABLE)) + return -EINVAL; + + if (copy_from_user(&stmpconf, ifr->ifr_data, sizeof(stmpconf))) + return -EFAULT; + + if (stmpconf.flags) + return -EINVAL; + + switch (stmpconf.tx_type) { + case HWTSTAMP_TX_ON: + tg3_flag_set(tp, TX_TSTAMP_EN); + break; + case HWTSTAMP_TX_OFF: + tg3_flag_clear(tp, TX_TSTAMP_EN); + break; + default: + return -ERANGE; + } + + switch (stmpconf.rx_filter) { + case HWTSTAMP_FILTER_NONE: + tp->rxptpctl = 0; + break; + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | + TG3_RX_PTP_CTL_ALL_V1_EVENTS; + break; + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | + TG3_RX_PTP_CTL_SYNC_EVNT; + break; + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V1_EN | + TG3_RX_PTP_CTL_DELAY_REQ; + break; + case HWTSTAMP_FILTER_PTP_V2_EVENT: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | + TG3_RX_PTP_CTL_ALL_V2_EVENTS; + break; + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | + TG3_RX_PTP_CTL_ALL_V2_EVENTS; + break; + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | + TG3_RX_PTP_CTL_ALL_V2_EVENTS; + break; + case HWTSTAMP_FILTER_PTP_V2_SYNC: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | + TG3_RX_PTP_CTL_SYNC_EVNT; + break; + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | + TG3_RX_PTP_CTL_SYNC_EVNT; + break; + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | + TG3_RX_PTP_CTL_SYNC_EVNT; + break; + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_EN | + TG3_RX_PTP_CTL_DELAY_REQ; + break; + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L2_EN | + TG3_RX_PTP_CTL_DELAY_REQ; + break; + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + tp->rxptpctl = TG3_RX_PTP_CTL_RX_PTP_V2_L4_EN | + TG3_RX_PTP_CTL_DELAY_REQ; + break; + default: + return -ERANGE; + } + + if (netif_running(dev) && tp->rxptpctl) + tw32(TG3_RX_PTP_CTL, + tp->rxptpctl | TG3_RX_PTP_CTL_HWTS_INTERLOCK); + + return copy_to_user(ifr->ifr_data, &stmpconf, sizeof(stmpconf)) ? + -EFAULT : 0; +} + static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = if_mii(ifr); @@ -12810,6 +12900,9 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return err; + case SIOCSHWTSTAMP: + return tg3_hwtstamp_ioctl(dev, ifr, cmd); + default: /* do nothing */ break; -- 1.7.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/5 net-next v2] tg3: PTP - Enable the timestamping feature in hardware and fill skb tx/rx timestamps 2012-12-04 5:36 ` [PATCH 4/5 net-next v2] tg3: PTP - Add the hardware timestamp ioctl Michael Chan @ 2012-12-04 5:37 ` Michael Chan 0 siblings, 0 replies; 7+ messages in thread From: Michael Chan @ 2012-12-04 5:37 UTC (permalink / raw) To: davem; +Cc: netdev, nsujir, richardcochran From: Matt Carlson <mcarlson@broadcom.com> This patch implements the hardware timestamping as described in Documentation/networking/timestamping.txt Update version to 3.128. Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com> Signed-off-by: Michael Chan <mchan@broadcom.com> Cc: Richard Cochran <richardcochran@gmail.com> --- drivers/net/ethernet/broadcom/tg3.c | 57 +++++++++++++++++++++++++++++++--- 1 files changed, 52 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index dddb21e..23918ce 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -93,10 +93,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits) #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 127 +#define TG3_MIN_NUM 128 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "November 14, 2012" +#define DRV_MODULE_RELDATE "December 03, 2012" #define RESET_KIND_SHUTDOWN 0 #define RESET_KIND_INIT 1 @@ -5663,6 +5663,14 @@ static const struct ptp_clock_info tg3_ptp_caps = { .enable = tg3_ptp_enable, }; +static void tg3_hwclock_to_timestamp(struct tg3 *tp, u64 hwclock, + struct skb_shared_hwtstamps *timestamp) +{ + memset(timestamp, 0, sizeof(struct skb_shared_hwtstamps)); + timestamp->hwtstamp = ns_to_ktime((hwclock & TG3_TSTAMP_MASK) + + tp->ptp_adjust); +} + /* tp->lock must be held */ static void tg3_ptp_init(struct tg3 *tp) { @@ -5875,6 +5883,16 @@ static void tg3_tx(struct tg3_napi *tnapi) return; } + if (tnapi->tx_ring[sw_idx].len_flags & TXD_FLAG_HWTSTAMP) { + struct skb_shared_hwtstamps timestamp; + u64 hwclock = tr32(TG3_TX_TSTAMP_LSB); + hwclock |= (u64)tr32(TG3_TX_TSTAMP_MSB) << 32; + + tg3_hwclock_to_timestamp(tp, hwclock, ×tamp); + + skb_tstamp_tx(skb, ×tamp); + } + pci_unmap_single(tp->pdev, dma_unmap_addr(ri, mapping), skb_headlen(skb), @@ -6142,6 +6160,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) dma_addr_t dma_addr; u32 opaque_key, desc_idx, *post_ptr; u8 *data; + u64 tstamp = 0; desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; @@ -6176,6 +6195,14 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - ETH_FCS_LEN; + if ((desc->type_flags & RXD_FLAG_PTPSTAT_MASK) == + RXD_FLAG_PTPSTAT_PTPV1 || + (desc->type_flags & RXD_FLAG_PTPSTAT_MASK) == + RXD_FLAG_PTPSTAT_PTPV2) { + tstamp = tr32(TG3_RX_TSTAMP_LSB); + tstamp |= (u64)tr32(TG3_RX_TSTAMP_MSB) << 32; + } + if (len > TG3_RX_COPY_THRESH(tp)) { int skb_size; unsigned int frag_size; @@ -6219,6 +6246,10 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) } skb_put(skb, len); + if (tstamp) + tg3_hwclock_to_timestamp(tp, tstamp, + skb_hwtstamps(skb)); + if ((tp->dev->features & NETIF_F_RXCSUM) && (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) && (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK) @@ -7276,6 +7307,12 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) vlan = vlan_tx_tag_get(skb); } + if ((unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) && + tg3_flag(tp, TX_TSTAMP_EN)) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + base_flags |= TXD_FLAG_HWTSTAMP; + } + len = skb_headlen(skb); mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE); @@ -9144,9 +9181,15 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) */ tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM; - tw32(GRC_MODE, - tp->grc_mode | - (GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP)); + val = GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP; + if (tp->rxptpctl) + tw32(TG3_RX_PTP_CTL, + tp->rxptpctl | TG3_RX_PTP_CTL_HWTS_INTERLOCK); + + if (tg3_flag(tp, PTP_CAPABLE)) + val |= GRC_MODE_TIME_SYNC_ENABLE; + + tw32(GRC_MODE, tp->grc_mode | val); /* Setup the timer prescalar register. Clock is always 66Mhz. */ val = tr32(GRC_MISC_CFG); @@ -16564,6 +16607,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) + tg3_flag_set(tp, PTP_CAPABLE); + if (tg3_flag(tp, 5717_PLUS)) { /* Resume a low-power mode */ tg3_frob_aux_power(tp, false); -- 1.7.1 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start(). 2012-12-04 5:36 [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start() Michael Chan 2012-12-04 5:36 ` [PATCH 2/5 net-next v2] tg3: PTP - Add header definitions, initialization and hw access functions Michael Chan @ 2012-12-04 8:48 ` Richard Cochran 2012-12-04 18:02 ` David Miller 2 siblings, 0 replies; 7+ messages in thread From: Richard Cochran @ 2012-12-04 8:48 UTC (permalink / raw) To: Michael Chan; +Cc: davem, netdev, nsujir On Mon, Dec 03, 2012 at 09:36:56PM -0800, Michael Chan wrote: > From: Nithin Nayak Sujir <nsujir@broadcom.com> > > Every caller holds tp->lock when calling tg3_netif_start() except > tg3_io_resume(). Fix it so that it is all consistent. The subsequent > PTP patches add tg3_ptp_resume() to tg3_netif_start() and the tp->lock > is required. > > Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com> > Signed-off-by: Michael Chan <mchan@broadcom.com> This series looks good to me now. Acked-by: Richard Cochran <richardcochran@gmail.com> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start(). 2012-12-04 5:36 [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start() Michael Chan 2012-12-04 5:36 ` [PATCH 2/5 net-next v2] tg3: PTP - Add header definitions, initialization and hw access functions Michael Chan 2012-12-04 8:48 ` [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start() Richard Cochran @ 2012-12-04 18:02 ` David Miller 2 siblings, 0 replies; 7+ messages in thread From: David Miller @ 2012-12-04 18:02 UTC (permalink / raw) To: mchan; +Cc: netdev, nsujir, richardcochran All 5 patches applied, thanks. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-12-04 18:02 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-12-04 5:36 [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start() Michael Chan 2012-12-04 5:36 ` [PATCH 2/5 net-next v2] tg3: PTP - Add header definitions, initialization and hw access functions Michael Chan 2012-12-04 5:36 ` [PATCH 3/5 net-next v2] tg3: PTP - Implement the ptp api and ethtool functions Michael Chan 2012-12-04 5:36 ` [PATCH 4/5 net-next v2] tg3: PTP - Add the hardware timestamp ioctl Michael Chan 2012-12-04 5:37 ` [PATCH 5/5 net-next v2] tg3: PTP - Enable the timestamping feature in hardware and fill skb tx/rx timestamps Michael Chan 2012-12-04 8:48 ` [PATCH 1/5 net-next v2] tg3: Fix inconsistent locking for tg3_netif_start() Richard Cochran 2012-12-04 18:02 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).