aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/tg3.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2012-12-03 14:36:57 -0500
committerDavid S. Miller <davem@davemloft.net>2012-12-04 12:58:49 -0500
commitbe947307b5b61fabbd76194d02617f9d2653176d (patch)
tree63f6548d072b3ffd603ce3d7870bf3442ed9572e /drivers/net/ethernet/broadcom/tg3.c
parent357630668a638418d542d0e331c90c01a091a3f1 (diff)
tg3: PTP - Add header definitions, initialization and hw access functions.
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> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c61
1 files changed, 57 insertions, 4 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index a4a5e2d329e4..32ffb5416674 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -54,6 +54,9 @@
54#include <asm/byteorder.h> 54#include <asm/byteorder.h>
55#include <linux/uaccess.h> 55#include <linux/uaccess.h>
56 56
57#include <uapi/linux/net_tstamp.h>
58#include <linux/ptp_clock_kernel.h>
59
57#ifdef CONFIG_SPARC 60#ifdef CONFIG_SPARC
58#include <asm/idprom.h> 61#include <asm/idprom.h>
59#include <asm/prom.h> 62#include <asm/prom.h>
@@ -5516,6 +5519,45 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset)
5516 return err; 5519 return err;
5517} 5520}
5518 5521
5522/* tp->lock must be held */
5523static void tg3_refclk_write(struct tg3 *tp, u64 newval)
5524{
5525 tw32(TG3_EAV_REF_CLCK_CTL, TG3_EAV_REF_CLCK_CTL_STOP);
5526 tw32(TG3_EAV_REF_CLCK_LSB, newval & 0xffffffff);
5527 tw32(TG3_EAV_REF_CLCK_MSB, newval >> 32);
5528 tw32_f(TG3_EAV_REF_CLCK_CTL, TG3_EAV_REF_CLCK_CTL_RESUME);
5529}
5530
5531/* tp->lock must be held */
5532static void tg3_ptp_init(struct tg3 *tp)
5533{
5534 if (!tg3_flag(tp, PTP_CAPABLE))
5535 return;
5536
5537 /* Initialize the hardware clock to the system time. */
5538 tg3_refclk_write(tp, ktime_to_ns(ktime_get_real()));
5539 tp->ptp_adjust = 0;
5540}
5541
5542/* tp->lock must be held */
5543static void tg3_ptp_resume(struct tg3 *tp)
5544{
5545 if (!tg3_flag(tp, PTP_CAPABLE))
5546 return;
5547
5548 tg3_refclk_write(tp, ktime_to_ns(ktime_get_real()) + tp->ptp_adjust);
5549 tp->ptp_adjust = 0;
5550}
5551
5552static void tg3_ptp_fini(struct tg3 *tp)
5553{
5554 if (!tg3_flag(tp, PTP_CAPABLE) || !tp->ptp_clock)
5555 return;
5556
5557 tp->ptp_clock = NULL;
5558 tp->ptp_adjust = 0;
5559}
5560
5519static inline int tg3_irq_sync(struct tg3 *tp) 5561static inline int tg3_irq_sync(struct tg3 *tp)
5520{ 5562{
5521 return tp->irq_sync; 5563 return tp->irq_sync;
@@ -6528,6 +6570,8 @@ static inline void tg3_netif_stop(struct tg3 *tp)
6528/* tp->lock must be held */ 6570/* tp->lock must be held */
6529static inline void tg3_netif_start(struct tg3 *tp) 6571static inline void tg3_netif_start(struct tg3 *tp)
6530{ 6572{
6573 tg3_ptp_resume(tp);
6574
6531 /* NOTE: unconditional netif_tx_wake_all_queues is only 6575 /* NOTE: unconditional netif_tx_wake_all_queues is only
6532 * appropriate so long as all callers are assured to 6576 * appropriate so long as all callers are assured to
6533 * have free tx slots (such as after tg3_init_hw) 6577 * have free tx slots (such as after tg3_init_hw)
@@ -10365,7 +10409,8 @@ static void tg3_ints_fini(struct tg3 *tp)
10365 tg3_flag_clear(tp, ENABLE_TSS); 10409 tg3_flag_clear(tp, ENABLE_TSS);
10366} 10410}
10367 10411
10368static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq) 10412static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq,
10413 bool init)
10369{ 10414{
10370 struct net_device *dev = tp->dev; 10415 struct net_device *dev = tp->dev;
10371 int i, err; 10416 int i, err;
@@ -10444,6 +10489,12 @@ static int tg3_start(struct tg3 *tp, bool reset_phy, bool test_irq)
10444 tg3_flag_set(tp, INIT_COMPLETE); 10489 tg3_flag_set(tp, INIT_COMPLETE);
10445 tg3_enable_ints(tp); 10490 tg3_enable_ints(tp);
10446 10491
10492 if (init)
10493 tg3_ptp_init(tp);
10494 else
10495 tg3_ptp_resume(tp);
10496
10497
10447 tg3_full_unlock(tp); 10498 tg3_full_unlock(tp);
10448 10499
10449 netif_tx_start_all_queues(dev); 10500 netif_tx_start_all_queues(dev);
@@ -10541,11 +10592,12 @@ static int tg3_open(struct net_device *dev)
10541 10592
10542 tg3_full_unlock(tp); 10593 tg3_full_unlock(tp);
10543 10594
10544 err = tg3_start(tp, true, true); 10595 err = tg3_start(tp, true, true, true);
10545 if (err) { 10596 if (err) {
10546 tg3_frob_aux_power(tp, false); 10597 tg3_frob_aux_power(tp, false);
10547 pci_set_power_state(tp->pdev, PCI_D3hot); 10598 pci_set_power_state(tp->pdev, PCI_D3hot);
10548 } 10599 }
10600
10549 return err; 10601 return err;
10550} 10602}
10551 10603
@@ -10553,6 +10605,8 @@ static int tg3_close(struct net_device *dev)
10553{ 10605{
10554 struct tg3 *tp = netdev_priv(dev); 10606 struct tg3 *tp = netdev_priv(dev);
10555 10607
10608 tg3_ptp_fini(tp);
10609
10556 tg3_stop(tp); 10610 tg3_stop(tp);
10557 10611
10558 /* Clear stats across close / open calls */ 10612 /* Clear stats across close / open calls */
@@ -11455,7 +11509,7 @@ static int tg3_set_channels(struct net_device *dev,
11455 11509
11456 tg3_carrier_off(tp); 11510 tg3_carrier_off(tp);
11457 11511
11458 tg3_start(tp, true, false); 11512 tg3_start(tp, true, false, false);
11459 11513
11460 return 0; 11514 return 0;
11461} 11515}
@@ -12508,7 +12562,6 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest,
12508 } 12562 }
12509 12563
12510 tg3_full_lock(tp, irq_sync); 12564 tg3_full_lock(tp, irq_sync);
12511
12512 tg3_halt(tp, RESET_KIND_SUSPEND, 1); 12565 tg3_halt(tp, RESET_KIND_SUSPEND, 1);
12513 err = tg3_nvram_lock(tp); 12566 err = tg3_nvram_lock(tp);
12514 tg3_halt_cpu(tp, RX_CPU_BASE); 12567 tg3_halt_cpu(tp, RX_CPU_BASE);