diff options
author | Reece R. Pollack | 2014-11-26 16:22:16 -0600 |
---|---|---|
committer | Reece R. Pollack | 2014-11-26 16:22:16 -0600 |
commit | 450d2f8dd9f26e88e336455524694dac5d99e278 (patch) | |
tree | 8802a9c0a98ec08ad3c54da964aec86b7ea30a77 | |
parent | ee76a14c6ba05c2b9b3761b795cde36e13e00491 (diff) | |
parent | 016670db48e47d3809a65c7ad61fcf5a565c74ae (diff) | |
download | linux-v3.10.10/master.tar.gz linux-v3.10.10/master.tar.xz linux-v3.10.10/master.zip |
Merge branch 'master/rebuild/24-drivers-net' into master/masterK2_LINUX_03.10.10_14.12v3.10.10/master
-rw-r--r-- | drivers/net/ethernet/ti/keystone_pa2.c | 421 |
1 files changed, 0 insertions, 421 deletions
diff --git a/drivers/net/ethernet/ti/keystone_pa2.c b/drivers/net/ethernet/ti/keystone_pa2.c index 81abfdd4e42..aa92fc2f055 100644 --- a/drivers/net/ethernet/ti/keystone_pa2.c +++ b/drivers/net/ethernet/ti/keystone_pa2.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/highmem.h> | 27 | #include <linux/highmem.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/dmaengine.h> | 29 | #include <linux/dmaengine.h> |
30 | #include <linux/net_tstamp.h> | ||
31 | #include <linux/dma-mapping.h> | 30 | #include <linux/dma-mapping.h> |
32 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
33 | #include <linux/byteorder/generic.h> | 32 | #include <linux/byteorder/generic.h> |
@@ -1007,12 +1006,6 @@ struct pa2_lut_entry { | |||
1007 | struct netcp_addr *naddr; | 1006 | struct netcp_addr *naddr; |
1008 | }; | 1007 | }; |
1009 | 1008 | ||
1010 | struct pa2_timestamp_info { | ||
1011 | u32 mult; | ||
1012 | u32 shift; | ||
1013 | u64 system_offset; | ||
1014 | }; | ||
1015 | |||
1016 | struct pa2_intf { | 1009 | struct pa2_intf { |
1017 | struct pa2_device *pa_device; | 1010 | struct pa2_device *pa_device; |
1018 | struct net_device *net_device; | 1011 | struct net_device *net_device; |
@@ -1021,9 +1014,6 @@ struct pa2_intf { | |||
1021 | unsigned data_queue_num; | 1014 | unsigned data_queue_num; |
1022 | u32 saved_ss_state; | 1015 | u32 saved_ss_state; |
1023 | char tx_chan_name[24]; | 1016 | char tx_chan_name[24]; |
1024 | |||
1025 | bool tx_timestamp_enable; | ||
1026 | bool rx_timestamp_enable; | ||
1027 | }; | 1017 | }; |
1028 | 1018 | ||
1029 | struct pa2_device { | 1019 | struct pa2_device { |
@@ -1036,8 +1026,6 @@ struct pa2_device { | |||
1036 | unsigned cmd_flow_num; | 1026 | unsigned cmd_flow_num; |
1037 | unsigned cmd_queue_num; | 1027 | unsigned cmd_queue_num; |
1038 | 1028 | ||
1039 | struct pa2_timestamp_info timestamp_info; | ||
1040 | |||
1041 | struct pa2_mailbox_regs __iomem *reg_mailbox; | 1029 | struct pa2_mailbox_regs __iomem *reg_mailbox; |
1042 | struct pa2_ra_bridge_regs __iomem *reg_ra_bridge; | 1030 | struct pa2_ra_bridge_regs __iomem *reg_ra_bridge; |
1043 | struct pa2_thread_mapper_regs __iomem *reg_thread_mapper; | 1031 | struct pa2_thread_mapper_regs __iomem *reg_thread_mapper; |
@@ -1069,8 +1057,6 @@ struct pa2_device { | |||
1069 | struct pa2_lut_entry *lut; | 1057 | struct pa2_lut_entry *lut; |
1070 | u32 lut_size; | 1058 | u32 lut_size; |
1071 | 1059 | ||
1072 | u32 ts_not_req; | ||
1073 | int force_no_hwtstamp; | ||
1074 | const char *pdsp_fw[PA2_NUM_PDSPS]; | 1060 | const char *pdsp_fw[PA2_NUM_PDSPS]; |
1075 | }; | 1061 | }; |
1076 | 1062 | ||
@@ -1430,122 +1416,6 @@ static int pa2_conv_routing_info(struct pa2_frm_forward *fwd_info, | |||
1430 | return PA2_OK; | 1416 | return PA2_OK; |
1431 | } | 1417 | } |
1432 | 1418 | ||
1433 | |||
1434 | /* | ||
1435 | * Convert a raw PA timer count to nanoseconds | ||
1436 | */ | ||
1437 | static inline u64 tstamp_raw_to_ns(struct pa2_device *pa_dev, u64 raw) | ||
1438 | { | ||
1439 | return (raw * pa_dev->timestamp_info.mult) | ||
1440 | >> pa_dev->timestamp_info.shift; | ||
1441 | } | ||
1442 | |||
1443 | static u64 pa2_to_sys_time(struct pa2_device *pa_dev, u64 pa_ticks) | ||
1444 | { | ||
1445 | s64 temp; | ||
1446 | u64 result; | ||
1447 | |||
1448 | /* we need to compute difference from wallclock | ||
1449 | * to time from boot dynamically since | ||
1450 | * it will change whenever absolute time is adjusted by | ||
1451 | * protocols above (ntp, ptpv2) | ||
1452 | */ | ||
1453 | |||
1454 | temp = ktime_to_ns(ktime_get_monotonic_offset()); | ||
1455 | result = (u64)((s64)pa_dev->timestamp_info.system_offset - temp + | ||
1456 | (s64)tstamp_raw_to_ns(pa_dev, pa_ticks)); | ||
1457 | |||
1458 | return result; | ||
1459 | } | ||
1460 | |||
1461 | static inline u64 tstamp_get_raw(struct pa2_device *pa_dev) | ||
1462 | { | ||
1463 | struct pa2_ppu_cp_timer_regs __iomem *timer_reg = | ||
1464 | pa_dev->ppu[PA2_INGRESS0_PDSP0].cp_timer; | ||
1465 | u32 low, high, high2; | ||
1466 | u64 raw; | ||
1467 | int count; | ||
1468 | |||
1469 | count = 0; | ||
1470 | do { | ||
1471 | high = __raw_readl(pa_dev->pa_sram + | ||
1472 | PA2_SYS_TIMESTAMP_ADDR_OFFSET); | ||
1473 | low = __raw_readl(&timer_reg->timer_value); | ||
1474 | high2 = __raw_readl(pa_dev->pa_sram + | ||
1475 | PA2_SYS_TIMESTAMP_ADDR_OFFSET); | ||
1476 | } while ((high != high2) && (++count < 32)); | ||
1477 | |||
1478 | raw = (((u64)high) << 16) | (u64)(0x0000ffff - (low & 0x0000ffff)); | ||
1479 | |||
1480 | return raw; | ||
1481 | } | ||
1482 | |||
1483 | /* | ||
1484 | * calibrate the PA timer to the system time | ||
1485 | * ktime_get gives montonic time | ||
1486 | * ktime_to_ns converts ktime to ns | ||
1487 | * this needs to be called before doing conversions | ||
1488 | */ | ||
1489 | static void pa2_calibrate_with_system_timer(struct pa2_device *pa_dev) | ||
1490 | { | ||
1491 | ktime_t ktime1, ktime2; | ||
1492 | u64 pa_ticks; | ||
1493 | u64 pa_ns; | ||
1494 | u64 sys_ns1, sys_ns2; | ||
1495 | |||
1496 | /* Get the two values with minimum delay between */ | ||
1497 | ktime1 = ktime_get(); | ||
1498 | pa_ticks = tstamp_get_raw(pa_dev); | ||
1499 | ktime2 = ktime_get(); | ||
1500 | |||
1501 | /* Convert both values to nanoseconds */ | ||
1502 | sys_ns1 = ktime_to_ns(ktime1); | ||
1503 | pa_ns = tstamp_raw_to_ns(pa_dev, pa_ticks); | ||
1504 | sys_ns2 = ktime_to_ns(ktime2); | ||
1505 | |||
1506 | /* compute offset */ | ||
1507 | pa_dev->timestamp_info.system_offset = sys_ns1 + | ||
1508 | ((sys_ns2 - sys_ns1) / 2) - pa_ns; | ||
1509 | } | ||
1510 | |||
1511 | static int pa2_config_timer(struct pa2_device *pa_dev, | ||
1512 | enum pa2_timerstamp_scaler_factor factor) | ||
1513 | { | ||
1514 | unsigned long pa_rate; | ||
1515 | u64 max_sec; | ||
1516 | struct pa2_ppu_cp_timer_regs __iomem *timer_reg = | ||
1517 | pa_dev->ppu[PA2_INGRESS0_PDSP0].cp_timer; | ||
1518 | |||
1519 | /* Start PDSP timer at a prescaler of divide by 2 */ | ||
1520 | __raw_writel(0xffff, &timer_reg->timer_load); | ||
1521 | __raw_writel((PA2_SS_TIMER_CNTRL_REG_GO | | ||
1522 | PA2_SS_TIMER_CNTRL_REG_MODE | | ||
1523 | PA2_SS_TIMER_CNTRL_REG_PSE | | ||
1524 | (factor << PA2_SS_TIMER_CNTRL_REG_PRESCALE_SHIFT)), | ||
1525 | &timer_reg->timer_control); | ||
1526 | |||
1527 | /* calculate the multiplier/shift to | ||
1528 | * convert PA counter ticks to ns. */ | ||
1529 | pa_rate = clk_get_rate(pa_dev->clk) / 2; | ||
1530 | |||
1531 | max_sec = ((1ULL << 48) - 1) + (pa_rate - 1); | ||
1532 | do_div(max_sec, pa_rate); | ||
1533 | |||
1534 | clocks_calc_mult_shift(&pa_dev->timestamp_info.mult, | ||
1535 | &pa_dev->timestamp_info.shift, pa_rate, | ||
1536 | NSEC_PER_SEC, max_sec); | ||
1537 | |||
1538 | dev_info(pa_dev->dev, "pa_clk_rate(%lu HZ),mult(%u),shift(%u)\n", | ||
1539 | pa_rate, pa_dev->timestamp_info.mult, | ||
1540 | pa_dev->timestamp_info.shift); | ||
1541 | |||
1542 | pa_dev->timestamp_info.system_offset = 0; | ||
1543 | |||
1544 | pa2_calibrate_with_system_timer(pa_dev); | ||
1545 | |||
1546 | return 0; | ||
1547 | } | ||
1548 | |||
1549 | static void pa2_get_version(struct pa2_device *pa_dev) | 1419 | static void pa2_get_version(struct pa2_device *pa_dev) |
1550 | { | 1420 | { |
1551 | u32 version, i; | 1421 | u32 version, i; |
@@ -1742,130 +1612,6 @@ static int pa2_submit_tx_packet(struct pa2_packet *p_info) | |||
1742 | 1612 | ||
1743 | #define PA2_CONTEXT_MASK 0xffff0000 | 1613 | #define PA2_CONTEXT_MASK 0xffff0000 |
1744 | #define PA2_CONTEXT_CONFIG 0xdead0000 | 1614 | #define PA2_CONTEXT_CONFIG 0xdead0000 |
1745 | #define PA2_CONTEXT_TSTAMP 0xbeef0000 | ||
1746 | |||
1747 | #define TSTAMP_TIMEOUT (HZ * 5) /* 5 seconds (arbitrary) */ | ||
1748 | |||
1749 | struct tstamp_pending { | ||
1750 | struct list_head list; | ||
1751 | u32 context; | ||
1752 | struct sock *sock; | ||
1753 | struct sk_buff *skb; | ||
1754 | struct pa2_device *pa_dev; | ||
1755 | struct timer_list timeout; | ||
1756 | }; | ||
1757 | |||
1758 | static spinlock_t tstamp_lock; | ||
1759 | static atomic_t tstamp_sequence = ATOMIC_INIT(0); | ||
1760 | static struct list_head tstamp_pending = LIST_HEAD_INIT(tstamp_pending); | ||
1761 | |||
1762 | static struct tstamp_pending *tstamp_remove_pending(u32 context) | ||
1763 | { | ||
1764 | struct tstamp_pending *pend; | ||
1765 | |||
1766 | spin_lock(&tstamp_lock); | ||
1767 | list_for_each_entry(pend, &tstamp_pending, list) { | ||
1768 | if (pend->context == context) { | ||
1769 | del_timer(&pend->timeout); | ||
1770 | list_del(&pend->list); | ||
1771 | spin_unlock(&tstamp_lock); | ||
1772 | return pend; | ||
1773 | } | ||
1774 | } | ||
1775 | spin_unlock(&tstamp_lock); | ||
1776 | |||
1777 | return NULL; | ||
1778 | } | ||
1779 | |||
1780 | static void tstamp_complete(u32, struct pa2_packet *); | ||
1781 | |||
1782 | static void tstamp_purge_pending(struct pa2_device *pa_dev) | ||
1783 | { | ||
1784 | struct tstamp_pending *pend; | ||
1785 | int found; | ||
1786 | |||
1787 | /* This is ugly and inefficient, but very rarely executed */ | ||
1788 | do { | ||
1789 | found = 0; | ||
1790 | |||
1791 | spin_lock(&tstamp_lock); | ||
1792 | list_for_each_entry(pend, &tstamp_pending, list) { | ||
1793 | if (pend->pa_dev == pa_dev) { | ||
1794 | found = 1; | ||
1795 | break; | ||
1796 | } | ||
1797 | } | ||
1798 | spin_unlock(&tstamp_lock); | ||
1799 | |||
1800 | if (found) | ||
1801 | tstamp_complete(pend->context, NULL); | ||
1802 | } while (found); | ||
1803 | } | ||
1804 | |||
1805 | static void tstamp_timeout(unsigned long context) | ||
1806 | { | ||
1807 | tstamp_complete((u32)context, NULL); | ||
1808 | } | ||
1809 | |||
1810 | static int tstamp_add_pending(struct tstamp_pending *pend) | ||
1811 | { | ||
1812 | init_timer(&pend->timeout); | ||
1813 | pend->timeout.expires = jiffies + TSTAMP_TIMEOUT; | ||
1814 | pend->timeout.function = tstamp_timeout; | ||
1815 | pend->timeout.data = (unsigned long)pend->context; | ||
1816 | |||
1817 | spin_lock(&tstamp_lock); | ||
1818 | add_timer(&pend->timeout); | ||
1819 | list_add_tail(&pend->list, &tstamp_pending); | ||
1820 | spin_unlock(&tstamp_lock); | ||
1821 | |||
1822 | return 0; | ||
1823 | } | ||
1824 | |||
1825 | static void tstamp_complete(u32 context, struct pa2_packet *p_info) | ||
1826 | { | ||
1827 | struct tstamp_pending *pend; | ||
1828 | struct sock_exterr_skb *serr; | ||
1829 | struct sk_buff *skb; | ||
1830 | struct skb_shared_hwtstamps *sh_hw_tstamps; | ||
1831 | u64 tx_timestamp; | ||
1832 | u64 sys_time; | ||
1833 | int err; | ||
1834 | |||
1835 | pend = tstamp_remove_pending(context); | ||
1836 | if (!pend) | ||
1837 | return; | ||
1838 | |||
1839 | |||
1840 | skb = pend->skb; | ||
1841 | if (!p_info) { | ||
1842 | dev_warn(pend->pa_dev->dev, "Timestamp completion timeout\n"); | ||
1843 | kfree_skb(skb); | ||
1844 | } else { | ||
1845 | tx_timestamp = p_info->epib[0]; | ||
1846 | tx_timestamp |= ((u64)(p_info->epib[2] & 0x0000ffff)) << 32; | ||
1847 | |||
1848 | sys_time = pa2_to_sys_time(pend->pa_dev, tx_timestamp); | ||
1849 | |||
1850 | sh_hw_tstamps = skb_hwtstamps(skb); | ||
1851 | memset(sh_hw_tstamps, 0, sizeof(*sh_hw_tstamps)); | ||
1852 | sh_hw_tstamps->hwtstamp = | ||
1853 | ns_to_ktime(tstamp_raw_to_ns(pend->pa_dev, | ||
1854 | tx_timestamp)); | ||
1855 | sh_hw_tstamps->syststamp = ns_to_ktime(sys_time); | ||
1856 | |||
1857 | serr = SKB_EXT_ERR(skb); | ||
1858 | memset(serr, 0, sizeof(*serr)); | ||
1859 | serr->ee.ee_errno = ENOMSG; | ||
1860 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; | ||
1861 | |||
1862 | err = sock_queue_err_skb(pend->sock, skb); | ||
1863 | if (err) | ||
1864 | kfree_skb(skb); | ||
1865 | } | ||
1866 | |||
1867 | kfree(pend); | ||
1868 | } | ||
1869 | 1615 | ||
1870 | static void pa2_rx_complete(void *param) | 1616 | static void pa2_rx_complete(void *param) |
1871 | { | 1617 | { |
@@ -1897,10 +1643,6 @@ static void pa2_rx_complete(void *param) | |||
1897 | dev_dbg(pa_dev->dev, "command response complete\n"); | 1643 | dev_dbg(pa_dev->dev, "command response complete\n"); |
1898 | break; | 1644 | break; |
1899 | 1645 | ||
1900 | case PA2_CONTEXT_TSTAMP: | ||
1901 | tstamp_complete(p_info->epib[1], p_info); | ||
1902 | break; | ||
1903 | |||
1904 | default: | 1646 | default: |
1905 | dev_warn(pa_dev->dev, "bad response context, got 0x%08x\n", | 1647 | dev_warn(pa_dev->dev, "bad response context, got 0x%08x\n", |
1906 | p_info->epib[1]); | 1648 | p_info->epib[1]); |
@@ -2333,28 +2075,6 @@ static inline int pa2_fmtcmd_next_route(struct netcp_packet *p_info, | |||
2333 | return sizeof(*nr); | 2075 | return sizeof(*nr); |
2334 | } | 2076 | } |
2335 | 2077 | ||
2336 | static inline int pa2_fmtcmd_tx_timestamp(struct netcp_packet *p_info, | ||
2337 | const struct pa2_cmd_tx_timestamp *tx_ts) | ||
2338 | { | ||
2339 | struct pasaho2_report_timestamp *rt_info; | ||
2340 | int size; | ||
2341 | |||
2342 | size = sizeof(*rt_info); | ||
2343 | rt_info = | ||
2344 | (struct pasaho2_report_timestamp *)netcp_push_psdata(p_info, | ||
2345 | size); | ||
2346 | if (!rt_info) | ||
2347 | return -ENOMEM; | ||
2348 | |||
2349 | rt_info->word0 = 0; | ||
2350 | PASAHO2_SET_CMDID(rt_info, PASAHO2_PAMOD_REPORT_TIMESTAMP); | ||
2351 | PASAHO2_SET_REPORT_FLOW(rt_info, (u8)tx_ts->flow_id); | ||
2352 | PASAHO2_SET_REPORT_QUEUE(rt_info, tx_ts->dest_queue); | ||
2353 | rt_info->sw_info0 = tx_ts->sw_info0; | ||
2354 | |||
2355 | return size; | ||
2356 | } | ||
2357 | |||
2358 | static inline int pa2_fmtcmd_align(struct netcp_packet *p_info, | 2078 | static inline int pa2_fmtcmd_align(struct netcp_packet *p_info, |
2359 | const unsigned bytes) | 2079 | const unsigned bytes) |
2360 | { | 2080 | { |
@@ -2412,11 +2132,8 @@ static int pa2_tx_hook(int order, void *data, struct netcp_packet *p_info) | |||
2412 | struct pa2_device *pa_dev = pa_intf->pa_device; | 2132 | struct pa2_device *pa_dev = pa_intf->pa_device; |
2413 | struct netcp_priv *netcp_priv = netdev_priv(pa_intf->net_device); | 2133 | struct netcp_priv *netcp_priv = netdev_priv(pa_intf->net_device); |
2414 | struct sk_buff *skb = p_info->skb; | 2134 | struct sk_buff *skb = p_info->skb; |
2415 | struct sock *sk = skb->sk; | ||
2416 | struct pa2_cmd_tx_timestamp tx_ts; | ||
2417 | int size, total = 0; | 2135 | int size, total = 0; |
2418 | u8 ps_flags = 0; | 2136 | u8 ps_flags = 0; |
2419 | struct tstamp_pending *pend; | ||
2420 | 2137 | ||
2421 | if (pa_dev->multi_if) { | 2138 | if (pa_dev->multi_if) { |
2422 | if (likely(skb->mark == 0) || | 2139 | if (likely(skb->mark == 0) || |
@@ -2439,50 +2156,6 @@ static int pa2_tx_hook(int order, void *data, struct netcp_packet *p_info) | |||
2439 | return size; | 2156 | return size; |
2440 | total += size; | 2157 | total += size; |
2441 | 2158 | ||
2442 | /* If TX Timestamp required, request it */ | ||
2443 | if (unlikely(pa_intf->tx_timestamp_enable && | ||
2444 | !pa_dev->force_no_hwtstamp && | ||
2445 | sk && | ||
2446 | (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && | ||
2447 | !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))) { | ||
2448 | pend = kzalloc(sizeof(*pend), GFP_ATOMIC); | ||
2449 | if (pend) { | ||
2450 | void *saved_sp; | ||
2451 | if (!atomic_inc_not_zero(&sk->sk_refcnt)) | ||
2452 | return -ENODEV; | ||
2453 | |||
2454 | /* The SA module may have reused skb->sp */ | ||
2455 | saved_sp = skb->sp; | ||
2456 | skb->sp = NULL; | ||
2457 | pend->skb = skb_clone(skb, GFP_ATOMIC); | ||
2458 | skb->sp = saved_sp; | ||
2459 | |||
2460 | if (!pend->skb) { | ||
2461 | sock_put(sk); | ||
2462 | kfree(pend); | ||
2463 | return -ENOMEM; | ||
2464 | } else { | ||
2465 | pend->sock = sk; | ||
2466 | pend->pa_dev = pa_dev; | ||
2467 | pend->context = PA2_CONTEXT_TSTAMP | | ||
2468 | (~PA2_CONTEXT_MASK & | ||
2469 | atomic_inc_return(&tstamp_sequence)); | ||
2470 | tstamp_add_pending(pend); | ||
2471 | |||
2472 | memset(&tx_ts, 0, sizeof(tx_ts)); | ||
2473 | tx_ts.dest_queue = pa_dev->cmd_queue_num; | ||
2474 | tx_ts.flow_id = pa_dev->cmd_flow_num; | ||
2475 | tx_ts.sw_info0 = pend->context; | ||
2476 | |||
2477 | size = pa2_fmtcmd_tx_timestamp(p_info, | ||
2478 | &tx_ts); | ||
2479 | if (unlikely(size < 0)) | ||
2480 | return size; | ||
2481 | total += size; | ||
2482 | } | ||
2483 | } | ||
2484 | } | ||
2485 | |||
2486 | /* If checksum offload required, request it */ | 2159 | /* If checksum offload required, request it */ |
2487 | if ((skb->ip_summed == CHECKSUM_PARTIAL) && | 2160 | if ((skb->ip_summed == CHECKSUM_PARTIAL) && |
2488 | (pa_dev->csum_offload == CSUM_OFFLOAD_HARD)) { | 2161 | (pa_dev->csum_offload == CSUM_OFFLOAD_HARD)) { |
@@ -2687,40 +2360,6 @@ static int pa2_txhook_softcsum(int order, void *data, | |||
2687 | } | 2360 | } |
2688 | 2361 | ||
2689 | 2362 | ||
2690 | static int pa2_rx_timestamp(int order, void *data, struct netcp_packet *p_info) | ||
2691 | { | ||
2692 | struct pa2_intf *pa_intf = data; | ||
2693 | struct pa2_device *pa_dev = pa_intf->pa_device; | ||
2694 | struct sk_buff *skb = p_info->skb; | ||
2695 | struct skb_shared_hwtstamps *sh_hw_tstamps; | ||
2696 | u64 rx_timestamp; | ||
2697 | u64 sys_time; | ||
2698 | |||
2699 | if (pa_dev->force_no_hwtstamp) | ||
2700 | return 0; | ||
2701 | |||
2702 | if (!pa_intf->rx_timestamp_enable) | ||
2703 | return 0; | ||
2704 | |||
2705 | if (p_info->rxtstamp_complete) | ||
2706 | return 0; | ||
2707 | |||
2708 | rx_timestamp = p_info->epib[0]; | ||
2709 | rx_timestamp |= ((u64)(p_info->psdata[5] & 0x0000ffff)) << 32; | ||
2710 | |||
2711 | sys_time = pa2_to_sys_time(pa_dev, rx_timestamp); | ||
2712 | |||
2713 | sh_hw_tstamps = skb_hwtstamps(skb); | ||
2714 | memset(sh_hw_tstamps, 0, sizeof(*sh_hw_tstamps)); | ||
2715 | sh_hw_tstamps->hwtstamp = ns_to_ktime(tstamp_raw_to_ns(pa_dev, | ||
2716 | rx_timestamp)); | ||
2717 | sh_hw_tstamps->syststamp = ns_to_ktime(sys_time); | ||
2718 | |||
2719 | p_info->rxtstamp_complete = true; | ||
2720 | |||
2721 | return 0; | ||
2722 | } | ||
2723 | |||
2724 | static int pa2_close(void *intf_priv, struct net_device *ndev) | 2363 | static int pa2_close(void *intf_priv, struct net_device *ndev) |
2725 | { | 2364 | { |
2726 | struct pa2_intf *pa_intf = intf_priv; | 2365 | struct pa2_intf *pa_intf = intf_priv; |
@@ -2733,10 +2372,6 @@ static int pa2_close(void *intf_priv, struct net_device *ndev) | |||
2733 | netcp_unregister_txhook(netcp_priv, pa_dev->txhook_softcsum, | 2372 | netcp_unregister_txhook(netcp_priv, pa_dev->txhook_softcsum, |
2734 | pa2_txhook_softcsum, intf_priv); | 2373 | pa2_txhook_softcsum, intf_priv); |
2735 | 2374 | ||
2736 | if (!pa_dev->force_no_hwtstamp) | ||
2737 | netcp_unregister_rxhook(netcp_priv, pa_dev->rxhook_order, | ||
2738 | pa2_rx_timestamp, intf_priv); | ||
2739 | |||
2740 | netcp_txpipe_close(&pa_intf->tx_pipe); | 2375 | netcp_txpipe_close(&pa_intf->tx_pipe); |
2741 | 2376 | ||
2742 | /* De-Configure the streaming switch */ | 2377 | /* De-Configure the streaming switch */ |
@@ -2765,8 +2400,6 @@ static int pa2_close(void *intf_priv, struct net_device *ndev) | |||
2765 | pa_dev->rx_channel = NULL; | 2400 | pa_dev->rx_channel = NULL; |
2766 | } | 2401 | } |
2767 | 2402 | ||
2768 | tstamp_purge_pending(pa_dev); | ||
2769 | |||
2770 | if (pa_dev->clk) { | 2403 | if (pa_dev->clk) { |
2771 | clk_disable_unprepare(pa_dev->clk); | 2404 | clk_disable_unprepare(pa_dev->clk); |
2772 | clk_put(pa_dev->clk); | 2405 | clk_put(pa_dev->clk); |
@@ -2869,8 +2502,6 @@ static int pa2_open(void *intf_priv, struct net_device *ndev) | |||
2869 | 2502 | ||
2870 | pa2_get_version(pa_dev); | 2503 | pa2_get_version(pa_dev); |
2871 | 2504 | ||
2872 | pa2_config_timer(pa_dev, PA2_TIMESTAMP_SCALER_FACTOR_2); | ||
2873 | |||
2874 | dma_cap_zero(mask); | 2505 | dma_cap_zero(mask); |
2875 | dma_cap_set(DMA_SLAVE, mask); | 2506 | dma_cap_set(DMA_SLAVE, mask); |
2876 | 2507 | ||
@@ -2974,10 +2605,6 @@ static int pa2_open(void *intf_priv, struct net_device *ndev) | |||
2974 | netcp_register_txhook(netcp_priv, pa_dev->txhook_softcsum, | 2605 | netcp_register_txhook(netcp_priv, pa_dev->txhook_softcsum, |
2975 | pa2_txhook_softcsum, intf_priv); | 2606 | pa2_txhook_softcsum, intf_priv); |
2976 | 2607 | ||
2977 | if (!pa_dev->force_no_hwtstamp) | ||
2978 | netcp_register_rxhook(netcp_priv, pa_dev->rxhook_order, | ||
2979 | pa2_rx_timestamp, intf_priv); | ||
2980 | |||
2981 | return 0; | 2608 | return 0; |
2982 | 2609 | ||
2983 | fail: | 2610 | fail: |
@@ -3095,50 +2722,8 @@ static int pa2_del_addr(void *intf_priv, struct netcp_addr *naddr) | |||
3095 | return 0; | 2722 | return 0; |
3096 | } | 2723 | } |
3097 | 2724 | ||
3098 | static int pa2_hwtstamp_ioctl(struct pa2_intf *pa_intf, | ||
3099 | struct ifreq *ifr, int cmd) | ||
3100 | { | ||
3101 | struct hwtstamp_config cfg; | ||
3102 | |||
3103 | if (pa_intf->pa_device->force_no_hwtstamp) | ||
3104 | return -EOPNOTSUPP; | ||
3105 | |||
3106 | if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) | ||
3107 | return -EFAULT; | ||
3108 | |||
3109 | if (cfg.flags) | ||
3110 | return -EINVAL; | ||
3111 | |||
3112 | switch (cfg.tx_type) { | ||
3113 | case HWTSTAMP_TX_OFF: | ||
3114 | pa_intf->tx_timestamp_enable = false; | ||
3115 | break; | ||
3116 | case HWTSTAMP_TX_ON: | ||
3117 | pa_intf->tx_timestamp_enable = true; | ||
3118 | break; | ||
3119 | default: | ||
3120 | return -ERANGE; | ||
3121 | } | ||
3122 | |||
3123 | switch (cfg.rx_filter) { | ||
3124 | case HWTSTAMP_FILTER_NONE: | ||
3125 | pa_intf->rx_timestamp_enable = false; | ||
3126 | break; | ||
3127 | default: | ||
3128 | pa_intf->rx_timestamp_enable = true; | ||
3129 | break; | ||
3130 | } | ||
3131 | |||
3132 | return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; | ||
3133 | } | ||
3134 | |||
3135 | static int pa2_ioctl(void *intf_priv, struct ifreq *req, int cmd) | 2725 | static int pa2_ioctl(void *intf_priv, struct ifreq *req, int cmd) |
3136 | { | 2726 | { |
3137 | struct pa2_intf *pa_intf = intf_priv; | ||
3138 | |||
3139 | if (cmd == SIOCSHWTSTAMP) | ||
3140 | return pa2_hwtstamp_ioctl(pa_intf, req, cmd); | ||
3141 | |||
3142 | return -EOPNOTSUPP; | 2727 | return -EOPNOTSUPP; |
3143 | } | 2728 | } |
3144 | 2729 | ||
@@ -3495,11 +3080,6 @@ static int pa2_probe(struct netcp_device *netcp_device, | |||
3495 | return -ENODEV; | 3080 | return -ENODEV; |
3496 | } | 3081 | } |
3497 | 3082 | ||
3498 | if (of_find_property(node, "force_no_hwtstamp", NULL)) { | ||
3499 | pa_dev->force_no_hwtstamp = 1; | ||
3500 | dev_warn(dev, "***** No PA timestamping *****\n"); | ||
3501 | } | ||
3502 | |||
3503 | prange = devm_kzalloc(dev, len, GFP_KERNEL); | 3083 | prange = devm_kzalloc(dev, len, GFP_KERNEL); |
3504 | if (!prange) { | 3084 | if (!prange) { |
3505 | dev_err(dev, "memory alloc failed at PA lut entry range\n"); | 3085 | dev_err(dev, "memory alloc failed at PA lut entry range\n"); |
@@ -3542,7 +3122,6 @@ static int pa2_probe(struct netcp_device *netcp_device, | |||
3542 | devm_kfree(pa_dev->dev, prange); | 3122 | devm_kfree(pa_dev->dev, prange); |
3543 | 3123 | ||
3544 | spin_lock_init(&pa_dev->lock); | 3124 | spin_lock_init(&pa_dev->lock); |
3545 | spin_lock_init(&tstamp_lock); | ||
3546 | 3125 | ||
3547 | return 0; | 3126 | return 0; |
3548 | 3127 | ||