Skip to content

Commit

Permalink
Merge branch 'Add-ENETC-PTP-clock-driver'
Browse files Browse the repository at this point in the history
Yangbo Lu says:

====================
Add ENETC PTP clock driver

There is same QorIQ 1588 timer IP block on the new ENETC Ethernet
controller with eTSEC/DPAA Ethernet controllers. However it's
different endianness (little-endian) and using PCI driver.

To support ENETC PTP driver, ptp_qoriq driver needed to be
reworked to make functions global for reusing, to add little-
endian support, to add ENETC memory map support, and to add
ENETC dependency for ptp_qoriq driver.

In addition, although ENETC PTP driver is a PCI driver, the dts
node still could be used. Currently the ls1028a dtsi which is
the only platform by now using ENETC is not complete, so there
is still dependency for ENETC PTP node upstreaming. This will
be done in the near future. The hardware timestamping support
for ENETC is done but needs to be reworked with new method in
internal git tree, and will be sent out soon.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Feb 12, 2019
2 parents 4ea7b0c + 74abc07 commit a263f99
Show file tree
Hide file tree
Showing 13 changed files with 486 additions and 258 deletions.
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/ptp/ptp-qoriq.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Clock Properties:
- fsl,max-adj Maximum frequency adjustment in parts per billion.
- fsl,extts-fifo The presence of this property indicates hardware
support for the external trigger stamp FIFO.
- little-endian The presence of this property indicates the 1588 timer
IP block is little-endian mode. The default endian mode
is big-endian.

These properties set the operational parameters for the PTP
clock. You must choose these carefully for the clock to work right.
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -6104,6 +6104,7 @@ FREESCALE QORIQ PTP CLOCK DRIVER
M: Yangbo Lu <yangbo.lu@nxp.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/freescale/enetc/enetc_ptp.c
F: drivers/ptp/ptp_qoriq.c
F: drivers/ptp/ptp_qoriq_debugfs.c
F: include/linux/fsl/ptp_qoriq.h
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ static int dpaa_get_ts_info(struct net_device *net_dev,
struct device_node *mac_node = dev->of_node;
struct device_node *fman_node = NULL, *ptp_node = NULL;
struct platform_device *ptp_dev = NULL;
struct qoriq_ptp *ptp = NULL;
struct ptp_qoriq *ptp = NULL;

info->phc_index = -1;

Expand Down
12 changes: 12 additions & 0 deletions drivers/net/ethernet/freescale/enetc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,15 @@ config FSL_ENETC_VF
virtual function (VF) devices enabled by the ENETC PF driver.

If compiled as module (M), the module name is fsl-enetc-vf.

config FSL_ENETC_PTP_CLOCK
tristate "ENETC PTP clock driver"
depends on PTP_1588_CLOCK_QORIQ && (FSL_ENETC || FSL_ENETC_VF)
default y
help
This driver adds support for using the ENETC 1588 timer
as a PTP clock. This clock is only useful if your PTP
programs are getting hardware time stamps on the PTP Ethernet
packets using the SO_TIMESTAMPING API.

If compiled as module (M), the module name is fsl-enetc-ptp.
3 changes: 3 additions & 0 deletions drivers/net/ethernet/freescale/enetc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ fsl-enetc-vf-$(CONFIG_FSL_ENETC_VF) += enetc.o enetc_cbdr.o \
enetc_ethtool.o
fsl-enetc-vf-objs := enetc_vf.o $(fsl-enetc-vf-y)
endif

obj-$(CONFIG_FSL_ENETC_PTP_CLOCK) += fsl-enetc-ptp.o
fsl-enetc-ptp-$(CONFIG_FSL_ENETC_PTP_CLOCK) += enetc_ptp.o
5 changes: 3 additions & 2 deletions drivers/net/ethernet/freescale/enetc/enetc_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
#include <linux/bitops.h>

/* ENETC device IDs */
#define ENETC_DEV_ID_PF 0xe100
#define ENETC_DEV_ID_VF 0xef00
#define ENETC_DEV_ID_PF 0xe100
#define ENETC_DEV_ID_VF 0xef00
#define ENETC_DEV_ID_PTP 0xee02

/* ENETC register block BAR */
#define ENETC_BAR_REGS 0
Expand Down
144 changes: 144 additions & 0 deletions drivers/net/ethernet/freescale/enetc/enetc_ptp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/* Copyright 2019 NXP */

#include <linux/module.h>
#include <linux/of.h>
#include <linux/fsl/ptp_qoriq.h>

#include "enetc.h"

static struct ptp_clock_info enetc_ptp_caps = {
.owner = THIS_MODULE,
.name = "ENETC PTP clock",
.max_adj = 512000,
.n_alarm = 0,
.n_ext_ts = 2,
.n_per_out = 0,
.n_pins = 0,
.pps = 1,
.adjfine = ptp_qoriq_adjfine,
.adjtime = ptp_qoriq_adjtime,
.gettime64 = ptp_qoriq_gettime,
.settime64 = ptp_qoriq_settime,
.enable = ptp_qoriq_enable,
};

static int enetc_ptp_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct ptp_qoriq *ptp_qoriq;
void __iomem *base;
int err, len, n;

if (pdev->dev.of_node && !of_device_is_available(pdev->dev.of_node)) {
dev_info(&pdev->dev, "device is disabled, skipping\n");
return -ENODEV;
}

err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev, "device enable failed\n");
return err;
}

/* set up for high or low dma */
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
if (err) {
err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (err) {
dev_err(&pdev->dev,
"DMA configuration failed: 0x%x\n", err);
goto err_dma;
}
}

err = pci_request_mem_regions(pdev, KBUILD_MODNAME);
if (err) {
dev_err(&pdev->dev, "pci_request_regions failed err=%d\n", err);
goto err_pci_mem_reg;
}

pci_set_master(pdev);

ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL);
if (!ptp_qoriq) {
err = -ENOMEM;
goto err_alloc_ptp;
}

len = pci_resource_len(pdev, ENETC_BAR_REGS);

base = ioremap(pci_resource_start(pdev, ENETC_BAR_REGS), len);
if (!base) {
err = -ENXIO;
dev_err(&pdev->dev, "ioremap() failed\n");
goto err_ioremap;
}

/* Allocate 1 interrupt */
n = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
if (n != 1) {
err = -EPERM;
goto err_irq;
}

ptp_qoriq->irq = pci_irq_vector(pdev, 0);

err = request_irq(ptp_qoriq->irq, ptp_qoriq_isr, 0, DRIVER, ptp_qoriq);
if (err) {
dev_err(&pdev->dev, "request_irq() failed!\n");
goto err_irq;
}

ptp_qoriq->dev = &pdev->dev;

err = ptp_qoriq_init(ptp_qoriq, base, enetc_ptp_caps);
if (err)
goto err_no_clock;

pci_set_drvdata(pdev, ptp_qoriq);

return 0;

err_no_clock:
free_irq(ptp_qoriq->irq, ptp_qoriq);
err_irq:
iounmap(base);
err_ioremap:
kfree(ptp_qoriq);
err_alloc_ptp:
pci_release_mem_regions(pdev);
err_pci_mem_reg:
err_dma:
pci_disable_device(pdev);

return err;
}

static void enetc_ptp_remove(struct pci_dev *pdev)
{
struct ptp_qoriq *ptp_qoriq = pci_get_drvdata(pdev);

ptp_qoriq_free(ptp_qoriq);
kfree(ptp_qoriq);

pci_release_mem_regions(pdev);
pci_disable_device(pdev);
}

static const struct pci_device_id enetc_ptp_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PTP) },
{ 0, } /* End of table. */
};
MODULE_DEVICE_TABLE(pci, enetc_ptp_id_table);

static struct pci_driver enetc_ptp_driver = {
.name = KBUILD_MODNAME,
.id_table = enetc_ptp_id_table,
.probe = enetc_ptp_probe,
.remove = enetc_ptp_remove,
};
module_pci_driver(enetc_ptp_driver);

MODULE_DESCRIPTION("ENETC PTP clock driver");
MODULE_LICENSE("Dual BSD/GPL");
2 changes: 1 addition & 1 deletion drivers/net/ethernet/freescale/gianfar_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1492,7 +1492,7 @@ static int gfar_get_ts_info(struct net_device *dev,
struct gfar_private *priv = netdev_priv(dev);
struct platform_device *ptp_dev;
struct device_node *ptp_node;
struct qoriq_ptp *ptp = NULL;
struct ptp_qoriq *ptp = NULL;

info->phc_index = -1;

Expand Down
22 changes: 20 additions & 2 deletions drivers/net/ethernet/mellanox/mlx4/en_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,16 +617,29 @@ static int get_fixed_ipv6_csum(__wsum hw_checksum, struct sk_buff *skb,
}
#endif

#define short_frame(size) ((size) <= ETH_ZLEN + ETH_FCS_LEN)

/* We reach this function only after checking that any of
* the (IPv4 | IPv6) bits are set in cqe->status.
*/
static int check_csum(struct mlx4_cqe *cqe, struct sk_buff *skb, void *va,
netdev_features_t dev_features)
{
__wsum hw_checksum = 0;
void *hdr;

/* CQE csum doesn't cover padding octets in short ethernet
* frames. And the pad field is appended prior to calculating
* and appending the FCS field.
*
* Detecting these padded frames requires to verify and parse
* IP headers, so we simply force all those small frames to skip
* checksum complete.
*/
if (short_frame(skb->len))
return -EINVAL;

void *hdr = (u8 *)va + sizeof(struct ethhdr);

hdr = (u8 *)va + sizeof(struct ethhdr);
hw_checksum = csum_unfold((__force __sum16)cqe->checksum);

if (cqe->vlan_my_qpn & cpu_to_be32(MLX4_CQE_CVLAN_PRESENT_MASK) &&
Expand Down Expand Up @@ -819,6 +832,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
skb_record_rx_queue(skb, cq_ring);

if (likely(dev->features & NETIF_F_RXCSUM)) {
/* TODO: For IP non TCP/UDP packets when csum complete is
* not an option (not supported or any other reason) we can
* actually check cqe IPOK status bit and report
* CHECKSUM_UNNECESSARY rather than CHECKSUM_NONE
*/
if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_TCP |
MLX4_CQE_STATUS_UDP)) &&
(cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
Expand Down
2 changes: 1 addition & 1 deletion drivers/ptp/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ config PTP_1588_CLOCK_DTE

config PTP_1588_CLOCK_QORIQ
tristate "Freescale QorIQ 1588 timer as PTP clock"
depends on GIANFAR || FSL_DPAA_ETH
depends on GIANFAR || FSL_DPAA_ETH || FSL_ENETC || FSL_ENETC_VF
depends on PTP_1588_CLOCK
default y
help
Expand Down
Loading

0 comments on commit a263f99

Please sign in to comment.