* [PATCH v3 2/2] net: phy: adin: implement Energy Detect Powerdown mode via phy-tunable
From: Alexandru Ardelean @ 2019-09-09 13:12 UTC (permalink / raw)
To: netdev, devicetree, linux-kernel
Cc: davem, robh+dt, mark.rutland, f.fainelli, hkallweit1, andrew,
Alexandru Ardelean
In-Reply-To: <20190909131251.3634-1-alexandru.ardelean@analog.com>
This driver becomes the first user of the kernel's `ETHTOOL_PHY_EDPD`
phy-tunable feature.
EDPD is also enabled by default on PHY config_init, but can be disabled via
the phy-tunable control.
When enabling EDPD, it's also a good idea (for the ADIN PHYs) to enable TX
periodic pulses, so that in case the other PHY is also on EDPD mode, there
is no lock-up situation where both sides are waiting for the other to
transmit.
Via the phy-tunable control, TX pulses can be disabled if specifying 0
`tx-interval` via ethtool.
The ADIN PHY supports only fixed 1 second intervals; they cannot be
configured. That is why the acceptable values are 1,
ETHTOOL_PHY_EDPD_DFLT_TX_INTERVAL and ETHTOOL_PHY_EDPD_NO_TX (which
disables TX pulses).
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
drivers/net/phy/adin.c | 61 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
index 4dec83df048d..5f5f73a58122 100644
--- a/drivers/net/phy/adin.c
+++ b/drivers/net/phy/adin.c
@@ -26,6 +26,11 @@
#define ADIN1300_RX_ERR_CNT 0x0014
+#define ADIN1300_PHY_CTRL_STATUS2 0x0015
+#define ADIN1300_NRG_PD_EN BIT(3)
+#define ADIN1300_NRG_PD_TX_EN BIT(2)
+#define ADIN1300_NRG_PD_STATUS BIT(1)
+
#define ADIN1300_PHY_CTRL2 0x0016
#define ADIN1300_DOWNSPEED_AN_100_EN BIT(11)
#define ADIN1300_DOWNSPEED_AN_10_EN BIT(10)
@@ -328,12 +333,62 @@ static int adin_set_downshift(struct phy_device *phydev, u8 cnt)
ADIN1300_DOWNSPEEDS_EN);
}
+static int adin_get_edpd(struct phy_device *phydev, u16 *tx_interval)
+{
+ int val;
+
+ val = phy_read(phydev, ADIN1300_PHY_CTRL_STATUS2);
+ if (val < 0)
+ return val;
+
+ if (ADIN1300_NRG_PD_EN & val) {
+ if (val & ADIN1300_NRG_PD_TX_EN)
+ /* default is 1 second */
+ *tx_interval = ETHTOOL_PHY_EDPD_DFLT_TX_INTERVAL;
+ else
+ *tx_interval = ETHTOOL_PHY_EDPD_NO_TX;
+ } else {
+ *tx_interval = ETHTOOL_PHY_EDPD_DISABLE;
+ }
+
+ return 0;
+}
+
+static int adin_set_edpd(struct phy_device *phydev, u16 tx_interval)
+{
+ u16 val;
+
+ if (tx_interval == ETHTOOL_PHY_EDPD_DISABLE)
+ return phy_clear_bits(phydev, ADIN1300_PHY_CTRL_STATUS2,
+ (ADIN1300_NRG_PD_EN | ADIN1300_NRG_PD_TX_EN));
+
+ val = ADIN1300_NRG_PD_EN;
+
+ switch (tx_interval) {
+ case 1: /* second */
+ /* fallthrough */
+ case ETHTOOL_PHY_EDPD_DFLT_TX_INTERVAL:
+ val |= ADIN1300_NRG_PD_TX_EN;
+ /* fallthrough */
+ case ETHTOOL_PHY_EDPD_NO_TX:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return phy_modify(phydev, ADIN1300_PHY_CTRL_STATUS2,
+ (ADIN1300_NRG_PD_EN | ADIN1300_NRG_PD_TX_EN),
+ val);
+}
+
static int adin_get_tunable(struct phy_device *phydev,
struct ethtool_tunable *tuna, void *data)
{
switch (tuna->id) {
case ETHTOOL_PHY_DOWNSHIFT:
return adin_get_downshift(phydev, data);
+ case ETHTOOL_PHY_EDPD:
+ return adin_get_edpd(phydev, data);
default:
return -EOPNOTSUPP;
}
@@ -345,6 +400,8 @@ static int adin_set_tunable(struct phy_device *phydev,
switch (tuna->id) {
case ETHTOOL_PHY_DOWNSHIFT:
return adin_set_downshift(phydev, *(const u8 *)data);
+ case ETHTOOL_PHY_EDPD:
+ return adin_set_edpd(phydev, *(const u16 *)data);
default:
return -EOPNOTSUPP;
}
@@ -368,6 +425,10 @@ static int adin_config_init(struct phy_device *phydev)
if (rc < 0)
return rc;
+ rc = adin_set_edpd(phydev, 1);
+ if (rc < 0)
+ return rc;
+
phydev_dbg(phydev, "PHY is using mode '%s'\n",
phy_modes(phydev->interface));
--
2.20.1
^ permalink raw reply related
* Re: [PATCH net-next 1/3] net: dsa: microchip: add KSZ9477 I2C driver
From: George McCollister @ 2019-09-09 12:54 UTC (permalink / raw)
To: Marek Vasut
Cc: netdev, Woojung Huh, Andrew Lunn, Florian Fainelli, Tristram Ha,
David S. Miller, open list
In-Reply-To: <b1e98d5e-50b7-1f2f-6874-9515fcf2b540@denx.de>
On Fri, Sep 6, 2019 at 4:42 PM Marek Vasut <marex@denx.de> wrote:
>
> On 9/6/19 11:30 PM, George McCollister wrote:
>
> [...]
>
> > --- /dev/null
> > +++ b/drivers/net/dsa/microchip/ksz9477_i2c.c
> > @@ -0,0 +1,100 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Microchip KSZ9477 series register access through I2C
> > + *
> > + * Copyright (C) 2018-2019 Microchip Technology Inc.
>
> Doesn't the copyright need update ?
I figured it wasn't necessary since you didn't update the copyright in
ksz9477_spi.c when you converted it to use regmap and made other
changes.
You're suggesting I add my copyright below this one, correct?
>
> > + */
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/regmap.h>
> > +#include <linux/i2c.h>
>
> Please keep the headers sorted.
Ack. Moving linux/i2c.h before linux/kernel.h in v2.
>
> > +#include "ksz_common.h"
> > +
> > +KSZ_REGMAP_TABLE(ksz9477, not_used, 16, 0, 0);
> > +
>
> The rest looks good.
>
> [...]
>
> --
> Best regards,
> Marek Vasut
^ permalink raw reply
* Re: [PATCH v1 net-next 00/15] tc-taprio offload for SJA1105 DSA
From: Joergen Andreasen @ 2019-09-09 12:36 UTC (permalink / raw)
To: Andrew Lunn
Cc: Vladimir Oltean, David Miller, f.fainelli, vivien.didelot,
vinicius.gomes, vedang.patel, richardcochran, weifeng.voon, jiri,
m-karicheri2, Jose.Abreu, ilias.apalodimas, jhs, xiyou.wangcong,
kurt.kanzenbach, netdev
In-Reply-To: <20190908204224.GA2730@lunn.ch>
The 09/08/2019 22:42, Andrew Lunn wrote:
> On Sun, Sep 08, 2019 at 12:07:27PM +0100, Vladimir Oltean wrote:
> > I think Richard has been there when the taprio, etf qdiscs, SO_TXTIME
> > were first defined and developed:
> > https://patchwork.ozlabs.org/cover/808504/
> > I expect he is capable of delivering a competent review of the entire
> > series, possibly way more competent than my patch set itself.
> >
> > The reason why I'm not splitting it up is because I lose around 10 ns
> > of synchronization offset when using the hardware-corrected PTPCLKVAL
> > clock for timestamping rather than the PTPTSCLK free-running counter.
>
> Hi Vladimir
>
> I'm not suggesting anything is wrong with your concept, when i say
> split it up. It is more than when somebody sees 15 patches, they
> decide they don't have the time at the moment, and put it off until
> later. And often later never happens. If however they see a smaller
> number of patches, they think that yes they have time now, and do the
> review.
>
> So if you are struggling to get something reviewed, make it more
> appealing for the reviewer. Salami tactics.
>
> Andrew
I vote for splitting it up.
I don't know enough about PTP and taprio/qdisc to review the entire series
but the interface presented in patch 09/15 fits well with our future TSN
switches.
Joergen Andreasen, Microchip
^ permalink raw reply
* [PATCH net-next 2/2] net: stmmac: Support enhanced addressing mode for DWMAC 4.10
From: Thierry Reding @ 2019-09-09 12:36 UTC (permalink / raw)
To: David S . Miller
Cc: Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu, Jon Hunter,
Bitan Biswas, netdev, linux-tegra
In-Reply-To: <20190909123627.29928-1-thierry.reding@gmail.com>
From: Thierry Reding <treding@nvidia.com>
The address width of the controller can be read from hardware feature
registers much like on XGMAC. Add support for parsing the ADDR64 field
so that the DMA mask can be set accordingly.
This avoids getting swiotlb involved for DMA on Tegra186 and later.
Also make sure that the upper 32 bits of the DMA address are written to
the DMA descriptors when enhanced addressing mode is used.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 1 +
.../ethernet/stmicro/stmmac/dwmac4_descs.c | 4 ++--
.../net/ethernet/stmicro/stmmac/dwmac4_dma.c | 20 +++++++++++++++++++
.../net/ethernet/stmicro/stmmac/dwmac4_dma.h | 1 +
4 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index 2ed11a581d80..f634fa09dffc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -183,6 +183,7 @@ enum power_event {
#define GMAC_HW_HASH_TB_SZ GENMASK(25, 24)
#define GMAC_HW_FEAT_AVSEL BIT(20)
#define GMAC_HW_TSOEN BIT(18)
+#define GMAC_HW_ADDR64 GENMASK(15, 14)
#define GMAC_HW_TXFIFOSIZE GENMASK(10, 6)
#define GMAC_HW_RXFIFOSIZE GENMASK(4, 0)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
index dbde23e7e169..d546041d2fcd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
@@ -431,8 +431,8 @@ static void dwmac4_get_addr(struct dma_desc *p, unsigned int *addr)
static void dwmac4_set_addr(struct dma_desc *p, dma_addr_t addr)
{
- p->des0 = cpu_to_le32(addr);
- p->des1 = 0;
+ p->des0 = cpu_to_le32(lower_32_bits(addr));
+ p->des1 = cpu_to_le32(upper_32_bits(addr));
}
static void dwmac4_clear(struct dma_desc *p)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index 3ed5508586ef..23dfbd0efc37 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -132,6 +132,9 @@ static void dwmac4_dma_init(void __iomem *ioaddr,
if (dma_cfg->aal)
value |= DMA_SYS_BUS_AAL;
+ if (dma_cfg->eame)
+ value |= DMA_SYS_BUS_EAME;
+
writel(value, ioaddr + DMA_SYS_BUS_MODE);
}
@@ -354,6 +357,23 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
dma_cap->hash_tb_sz = (hw_cap & GMAC_HW_HASH_TB_SZ) >> 24;
dma_cap->av = (hw_cap & GMAC_HW_FEAT_AVSEL) >> 20;
dma_cap->tsoen = (hw_cap & GMAC_HW_TSOEN) >> 18;
+
+ dma_cap->addr64 = (hw_cap & GMAC_HW_ADDR64) >> 14;
+ switch (dma_cap->addr64) {
+ case 0:
+ dma_cap->addr64 = 32;
+ break;
+ case 1:
+ dma_cap->addr64 = 40;
+ break;
+ case 2:
+ dma_cap->addr64 = 48;
+ break;
+ default:
+ dma_cap->addr64 = 32;
+ break;
+ }
+
/* RX and TX FIFO sizes are encoded as log2(n / 128). Undo that by
* shifting and store the sizes in bytes.
*/
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
index b66da0237d2a..d00776db20d6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -65,6 +65,7 @@
#define DMA_SYS_BUS_MB BIT(14)
#define DMA_AXI_1KBBE BIT(13)
#define DMA_SYS_BUS_AAL BIT(12)
+#define DMA_SYS_BUS_EAME BIT(11)
#define DMA_AXI_BLEN256 BIT(7)
#define DMA_AXI_BLEN128 BIT(6)
#define DMA_AXI_BLEN64 BIT(5)
--
2.23.0
^ permalink raw reply related
* [PATCH net-next 1/2] net: stmmac: Only enable enhanced addressing mode when needed
From: Thierry Reding @ 2019-09-09 12:36 UTC (permalink / raw)
To: David S . Miller
Cc: Giuseppe Cavallaro, Alexandre Torgue, Jose Abreu, Jon Hunter,
Bitan Biswas, netdev, linux-tegra
From: Thierry Reding <treding@nvidia.com>
Enhanced addressing mode is only required when more than 32 bits need to
be addressed. Add a DMA configuration parameter to enable this mode only
when needed.
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 5 ++++-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++++++
include/linux/stmmac.h | 1 +
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
index 64956465c030..3e00fd8befcf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -27,7 +27,10 @@ static void dwxgmac2_dma_init(void __iomem *ioaddr,
if (dma_cfg->aal)
value |= XGMAC_AAL;
- writel(value | XGMAC_EAME, ioaddr + XGMAC_DMA_SYSBUS_MODE);
+ if (dma_cfg->eame)
+ value |= XGMAC_EAME;
+
+ writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
}
static void dwxgmac2_dma_init_chan(void __iomem *ioaddr,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 06ccd216ae90..ecd461207dbc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4497,6 +4497,12 @@ int stmmac_dvr_probe(struct device *device,
if (!ret) {
dev_info(priv->device, "Using %d bits DMA width\n",
priv->dma_cap.addr64);
+
+ /*
+ * If more than 32 bits can be addressed, make sure to
+ * enable enhanced addressing mode.
+ */
+ priv->plat->dma_cfg->eame = true;
} else {
ret = dma_set_mask_and_coherent(device, DMA_BIT_MASK(32));
if (ret) {
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 7ad7ae35cf88..d300ac907c76 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -92,6 +92,7 @@ struct stmmac_dma_cfg {
int fixed_burst;
int mixed_burst;
bool aal;
+ bool eame;
};
#define AXI_BLEN 7
--
2.23.0
^ permalink raw reply related
* Re: [PATCH 0/2] Revert and rework on the metadata accelreation
From: Michael S. Tsirkin @ 2019-09-09 12:15 UTC (permalink / raw)
To: Jason Wang
Cc: David Miller, jgg, kvm, virtualization, netdev, linux-kernel,
aarcange, jglisse, linux-mm
In-Reply-To: <bb9ae371-58b7-b7fc-b728-b5c5f55d3a91@redhat.com>
On Mon, Sep 09, 2019 at 03:18:01PM +0800, Jason Wang wrote:
>
> On 2019/9/6 下午9:15, David Miller wrote:
> > From: Jason Wang <jasowang@redhat.com>
> > Date: Fri, 6 Sep 2019 18:02:35 +0800
> >
> > > On 2019/9/5 下午9:59, Jason Gunthorpe wrote:
> > > > I think you should apply the revert this cycle and rebase the other
> > > > patch for next..
> > > >
> > > > Jason
> > > Yes, the plan is to revert in this release cycle.
> > Then you should reset patch #1 all by itself targetting 'net'.
>
>
> Thanks for the reminding. I want the patch to go through Michael's vhost
> tree, that's why I don't put 'net' prefix. For next time, maybe I can use
> "vhost" as a prefix for classification?
That's fine by me.
--
MST
^ permalink raw reply
* Re: VRF Issue Since kernel 5
From: Alexis Bauvin @ 2019-09-09 12:01 UTC (permalink / raw)
To: Gowen; +Cc: netdev@vger.kernel.org
In-Reply-To: <CWLP265MB1554B902B7F3B43E6E75FD0DFDB70@CWLP265MB1554.GBRP265.PROD.OUTLOOK.COM>
Hi,
I guess all routing from the management VRF itself is working correctly (i.e. cURLing
an IP from this VRF or digging any DNS), and it is your route leakage that’s at fault.
Could you try swapping the local and l3mdev rules?
`ip rule del pref 0; ip rule add from all lookup local pref 1001`
I faced security issues and behavioral weirdnesses from the default kernel rule ordering
regarding the default vrf.
Alexis
> Le 9 sept. 2019 à 12:53, Gowen <gowen@potatocomputing.co.uk> a écrit :
>
> Hi Alexis,
>
> Admin@NETM06:~$ sysctl net.ipv4.tcp_l3mdev_accept
> net.ipv4.tcp_l3mdev_accept = 1
>
> Admin@NETM06:~$ sudo ip vrf exec mgmt-vrf curl kernel.org
> curl: (6) Could not resolve host: kernel.org
>
> the failure to resolve is the same with all DNS lookups from any process I've run
>
> The route is there from the guide I originally used, I can't remember the purpose but I know I don't need it - I've removed it now and no change
>
> Admin@NETM06:~$ ip rule show
> 0: from all lookup local
> 1000: from all lookup [l3mdev-table]
> 32766: from all lookup main
> 32767: from all lookup default
>
> I could switch the VRFs over, but this is a test-box and i have prod boxes on this as well so not so keen on that if I can avoid it.
>
> From what I can speculate, because the TCP return traffic is met with an RST, it looks like it may be something to do with iptables - but even if I set the policy to ACCEPT and flush all the rules, the behaviour remains the same.
>
> Is it possible that the TCP stack isn't aware of the session (as is mapped to wrong VRF internally or something to that effect) and is therefore sending the RST?
>
> Gareth
> From: Alexis Bauvin <abauvin@online.net>
> Sent: 09 September 2019 10:28
> To: Gowen <gowen@potatocomputing.co.uk>
> Cc: netdev@vger.kernel.org <netdev@vger.kernel.org>
> Subject: Re: VRF Issue Since kernel 5
>
> Hi,
>
> There has been some changes regarding VRF isolation in Linux 5 IIRC, namely proper
> isolation of the default VRF.
>
> Some things you may try:
>
> - looking at the l3mdev_accept sysctls (e.g. `net.ipv4.tcp_l3mdev_accept`)
> - querying stuff from the management vrf through `ip vrf exec vrf-mgmt <stuff>`
> e.g. `ip vrf exec vrf-mgmt curl kernel.org`
> `ip vrf exec vrf-mgmt dig @1.1.1.1 kernel.org`
> - reversing your logic: default VRF is your management one, the other one is for your
> other boxes
>
> Also, your `unreachable default metric 4278198272` route looks odd to me.
>
> What are your routing rules? (`ip rule`)
>
> Alexis
>
> > Le 9 sept. 2019 à 09:46, Gowen <gowen@potatocomputing.co.uk> a écrit :
> >
> > Hi there,
> >
> > Dave A said this was the mailer to send this to:
> >
> >
> > I’ve been using my management interface in a VRF for several months now and it’s worked perfectly – I’ve been able to update/upgrade the packages just fine and iptables works excellently with it – exactly as I needed.
> >
> >
> > Since Kernel 5 though I am no longer able to update – but the issue is quite a curious one as some traffic appears to be fine (DNS lookups use VRF correctly) but others don’t (updating/upgrading the packages)
> >
> >
> > I have on this device 2 interfaces:
> > Eth0 for management – inbound SSH, DNS, updates/upgrades
> > Eth1 for managing other boxes (ansible using SSH)
> >
> >
> > Link and addr info shown below:
> >
> >
> > Admin@NETM06:~$ ip link show
> > 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
> > link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
> > 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master mgmt-vrf state UP mode DEFAULT group default qlen 1000
> > link/ether 00:22:48:07:cc:ad brd ff:ff:ff:ff:ff:ff
> > 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
> > link/ether 00:22:48:07:c9:6c brd ff:ff:ff:ff:ff:ff
> > 4: mgmt-vrf: <NOARP,MASTER,UP,LOWER_UP> mtu 65536 qdisc noqueue state UP mode DEFAULT group default qlen 1000
> > link/ether 8a:f6:26:65:02:5a brd ff:ff:ff:ff:ff:ff
> >
> >
> > Admin@NETM06:~$ ip addr
> > 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
> > link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
> > inet 127.0.0.1/8 scope host lo
> > valid_lft forever preferred_lft forever
> > inet6 ::1/128 scope host
> > valid_lft forever preferred_lft forever
> > 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master mgmt-vrf state UP group default qlen 1000
> > link/ether 00:22:48:07:cc:ad brd ff:ff:ff:ff:ff:ff
> > inet 10.24.12.10/24 brd 10.24.12.255 scope global eth0
> > valid_lft forever preferred_lft forever
> > inet6 fe80::222:48ff:fe07:ccad/64 scope link
> > valid_lft forever preferred_lft forever
> > 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
> > link/ether 00:22:48:07:c9:6c brd ff:ff:ff:ff:ff:ff
> > inet 10.24.12.9/24 brd 10.24.12.255 scope global eth1
> > valid_lft forever preferred_lft forever
> > inet6 fe80::222:48ff:fe07:c96c/64 scope link
> > valid_lft forever preferred_lft forever
> > 4: mgmt-vrf: <NOARP,MASTER,UP,LOWER_UP> mtu 65536 qdisc noqueue state UP group default qlen 1000
> > link/ether 8a:f6:26:65:02:5a brd ff:ff:ff:ff:ff:ff
> >
> >
> >
> > the production traffic is all in the 10.0.0.0/8 network (eth1 global VRF) except for a few subnets (DNS) which are routed out eth0 (mgmt-vrf)
> >
> >
> > Admin@NETM06:~$ ip route show
> > default via 10.24.12.1 dev eth0
> > 10.0.0.0/8 via 10.24.12.1 dev eth1
> > 10.24.12.0/24 dev eth1 proto kernel scope link src 10.24.12.9
> > 10.24.65.0/24 via 10.24.12.1 dev eth0
> > 10.25.65.0/24 via 10.24.12.1 dev eth0
> > 10.26.0.0/21 via 10.24.12.1 dev eth0
> > 10.26.64.0/21 via 10.24.12.1 dev eth0
> >
> >
> > Admin@NETM06:~$ ip route show vrf mgmt-vrf
> > default via 10.24.12.1 dev eth0
> > unreachable default metric 4278198272
> > 10.24.12.0/24 dev eth0 proto kernel scope link src 10.24.12.10
> > 10.24.65.0/24 via 10.24.12.1 dev eth0
> > 10.25.65.0/24 via 10.24.12.1 dev eth0
> > 10.26.0.0/21 via 10.24.12.1 dev eth0
> > 10.26.64.0/21 via 10.24.12.1 dev eth0
> >
> >
> >
> > The strange activity occurs when I enter the command “sudo apt update” as I can resolve the DNS request (10.24.65.203 or 10.24.64.203, verified with tcpdump) out eth0 but for the actual update traffic there is no activity:
> >
> >
> > sudo tcpdump -i eth0 '(host 10.24.65.203 or host 10.25.65.203) and port 53' -n
> > <OUTPUT OMITTED FOR BREVITY>
> > 10:06:05.268735 IP 10.24.12.10.39963 > 10.24.65.203.53: 48798+ [1au] A? security.ubuntu.com. (48)
> > <OUTPUT OMITTED FOR BREVITY>
> > 10:06:05.284403 IP 10.24.65.203.53 > 10.24.12.10.39963: 48798 13/0/1 A 91.189.91.23, A 91.189.88.24, A 91.189.91.26, A 91.189.88.162, A 91.189.88.149, A 91.189.91.24, A 91.189.88.173, A 91.189.88.177, A 91.189.88.31, A 91.189.91.14, A 91.189.88.176, A 91.189.88.175, A 91.189.88.174 (256)
> >
> >
> >
> > You can see that the update traffic is returned but is not accepted by the stack and a RST is sent
> >
> >
> > Admin@NETM06:~$ sudo tcpdump -i eth0 '(not host 168.63.129.16 and port 80)' -n
> > tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> > listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
> > 10:17:12.690658 IP 10.24.12.10.40216 > 91.189.88.175.80: Flags [S], seq 2279624826, win 64240, options [mss 1460,sackOK,TS val 2029365856 ecr 0,nop,wscale 7], length 0
> > 10:17:12.691929 IP 10.24.12.10.52362 > 91.189.95.83.80: Flags [S], seq 1465797256, win 64240, options [mss 1460,sackOK,TS val 3833463674 ecr 0,nop,wscale 7], length 0
> > 10:17:12.696270 IP 91.189.88.175.80 > 10.24.12.10.40216: Flags [S.], seq 968450722, ack 2279624827, win 28960, options [mss 1418,sackOK,TS val 81957103 ecr 2029365856,nop,wscale 7], length 0
> > 10:17:12.696301 IP 10.24.12.10.40216 > 91.189.88.175.80: Flags [R], seq 2279624827, win 0, length 0
> > 10:17:12.697884 IP 91.189.95.83.80 > 10.24.12.10.52362: Flags [S.], seq 4148330738, ack 1465797257, win 28960, options [mss 1418,sackOK,TS val 2257624414 ecr 3833463674,nop,wscale 8], length 0
> > 10:17:12.697909 IP 10.24.12.10.52362 > 91.189.95.83.80: Flags [R], seq 1465797257, win 0, length 0
> >
> >
> >
> >
> > I can emulate the DNS lookup using netcat in the vrf:
> >
> >
> > sudo ip vrf exec mgmt-vrf nc -u 10.24.65.203 53
> >
> >
> > then interactively enter the binary for a www.google.co.uk request:
> >
> >
> > 0035624be394010000010000000000010377777706676f6f676c6502636f02756b00000100010000290200000000000000
> >
> >
> > This returns as expected:
> >
> >
> > 00624be394010000010000000000010377777706676f6f676c6502636f02756b00000100010000290200000000000000
> >
> >
> > I can run:
> >
> >
> > Admin@NETM06:~$ host www.google.co.uk
> > www.google.co.uk has address 172.217.169.3
> > www.google.co.uk has IPv6 address 2a00:1450:4009:80d::2003
> >
> >
> > but I get a timeout for:
> >
> >
> > sudo ip vrf exec mgmt-vrf host www.google.co.uk
> > ;; connection timed out; no servers could be reached
> >
> >
> >
> > However I can take a repo address and vrf exec to it on port 80:
> >
> >
> > Admin@NETM06:~$ sudo ip vrf exec mgmt-vrf nc 91.189.91.23 80
> > hello
> > HTTP/1.1 400 Bad Request
> > <OUTPUT OMITTED>
> >
> > My iptables rule:
> >
> >
> > sudo iptables -Z
> > Admin@NETM06:~$ sudo iptables -L -v
> > Chain INPUT (policy DROP 16 packets, 3592 bytes)
> > pkts bytes target prot opt in out source destination
> > 44 2360 ACCEPT tcp -- any any anywhere anywhere tcp spt:http ctstate RELATED,ESTABLISHED
> > 83 10243 ACCEPT udp -- any any anywhere anywhere udp spt:domain ctstate RELATED,ESTABLISHED
> >
> >
> >
> > I cannot find out why the update isn’t working. Any help greatly appreciated
> >
> >
> > Kind Regards,
> >
> >
> > Gareth
^ permalink raw reply
* Re: [RFC PATCH 3/3] Enable ptp_kvm for arm64
From: Marc Zyngier @ 2019-09-09 11:24 UTC (permalink / raw)
To: Jianyong Wu (Arm Technology China)
Cc: netdev@vger.kernel.org, pbonzini@redhat.com,
sean.j.christopherson@intel.com, richardcochran@gmail.com,
Mark Rutland, Will Deacon, Suzuki Poulose,
linux-kernel@vger.kernel.org, Steve Capper,
Kaly Xin (Arm Technology China), Justin He (Arm Technology China)
In-Reply-To: <HE1PR0801MB16768BE47D3D1F0662DDC3C7F4B70@HE1PR0801MB1676.eurprd08.prod.outlook.com>
On Mon, 09 Sep 2019 11:17:24 +0100,
"Jianyong Wu (Arm Technology China)" <Jianyong.Wu@arm.com> wrote:
Hi Jianyoung,
[...]
> > > > I'm definitely not keen on exposing the internals of the arch_timer
> > > > driver to random subsystems. Furthermore, you seem to expect that
> > > > the guest kernel will only use the arch timer as a clocksource, and
> > > > nothing really guarantees that (in which case
> > get_device_system_crosststamp will fail).
> > > >
> > > The code here is really ugly, I need a better solution to offer a
> > > clock source For the guest.
> > >
> > > > It looks to me that we'd be better off exposing a core timekeeping
> > > > API that populates a struct system_counterval_t based on the
> > > > *current* timekeeper monotonic clocksource. This would simplify the
> > > > split between generic and arch-specific code.
> > > >
> > > I think it really necessary.
> > >
> > > > Whether or not tglx will be happy with the idea is another problem,
> > > > but I'm certainly not taking any change to the arch timer code based on
> > this.
> > > >
> > > I can have a try, but the detail is not clear for me now.
> >
> > Something along those lines:
> >
> > From 5f1c061e55c691d64012bc7c1490a1a8c4432c67 Mon Sep 17 00:00:00 2001
> > From: Marc Zyngier <maz@kernel.org>
> > Date: Sat, 7 Sep 2019 10:11:49 +0100
> > Subject: [PATCH] timekeeping: Expose API allowing retrival of current
> > clocksource and counter value
> >
> > Signed-off-by: Marc Zyngier <maz@kernel.org>
> > ---
> > include/linux/timekeeping.h | 5 +++++
> > kernel/time/timekeeping.c | 12 ++++++++++++
> > 2 files changed, 17 insertions(+)
> >
> > diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index
> > b27e2ffa96c1..6df26a913711 100644
> > --- a/include/linux/timekeeping.h
> > +++ b/include/linux/timekeeping.h
> > @@ -275,6 +275,11 @@ extern int get_device_system_crosststamp(
> > struct system_time_snapshot *history,
> > struct system_device_crosststamp *xtstamp);
> >
> > +/*
> > + * Obtain current monotonic clock and its counter value */ extern void
> > +get_current_counterval(struct system_counterval_t *sc);
> > +
> > /*
> > * Simultaneously snapshot realtime and monotonic raw clocks
> > */
> > diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index
> > d911c8470149..de689bbd3808 100644
> > --- a/kernel/time/timekeeping.c
> > +++ b/kernel/time/timekeeping.c
> > @@ -1098,6 +1098,18 @@ static bool cycle_between(u64 before, u64 test,
> > u64 after)
> > return false;
> > }
> >
> > +/**
> > + * get_current_counterval - Snapshot the current clocksource and counter
> > value
> > + * @sc: Pointer to a struct containing the current clocksource and its
> > value
> > + */
> > +void get_current_counterval(struct system_counterval_t *sc) {
> > + struct timekeeper *tk = &tk_core.timekeeper;
> > +
> > + sc->cs = READ_ONCE(tk->tkr_mono.clock);
> > + sc->cycles = sc->cs->read(sc->cs);
> > +}
> > +
> > /**
> > * get_device_system_crosststamp - Synchronously capture system/device
> > timestamp
> > * @get_time_fn: Callback to get simultaneous device time and
> >
> > which should do the right thing.
> >
> It is a good news for me. These code is indeed what I need! So
> what's your plan about this patch? Is there any problem with you if
> I include these code into my patch ?
Just add this patch as part of your series (I'll try to write an
actual commit log for that).
[...]
> > > > Other questions: how does this works with VM migration? Specially
> > > > when moving from a hypervisor that supports the feature to one that
> > doesn't?
> > > >
> > > I think it won't solve the problem generated by VM migration and only
> > > for VMs in a single machine. Ptp_kvm only works for VMs in the same
> > > machine. But using ptp (not ptp_kvm) clock, all the machines in a low
> > > latency network environment can keep time sync in high precision, Then
> > > VMs move from one machine to another will obtain a high precision time
> > > sync.
> >
> > That's a problem. Migration must be possible from one host to another, even
> > if that means temporarily loosing some (or a lot of) precision. The service
> > must be discoverable from userspace on the host so that the MVV can decie
> > whether a migration is possible or not.
> >
> Don't worry, things will be not that bad. ptp_kvm will not trouble
> the VM migration. This ptp_kvm is one clocksource of the clock pool
> for chrony. Chrony will choose the highest precision clock from the
> pool. If host does not support ptp_kvm, the ptp_kvm will not be
> chosen as the clocksouce of chrony. We have roughly the same logic
> of implementation of ptp_kvm with x86, and ptp_kvm works well in
> x86. so I think that will be the case for arm64.
>
> Maybe I miss your point, I have no idea of MVV and can't get related
> info from google. Also I'm not clear of your last words of how to
> decide VM migration is possible?
Sorry. s/MVV/VMM/. Basically userspace, such as QEMU.
Here's an example: The guest runs on a PTP aware host, starts using
the PTP service and uses HVC calls to get its clock. We now migrate
the guest to a non PTP-aware host. The hypercalls are now going to
fail unexpectedly. Is that something that is acceptable? I don't think
it is. Once you've allowed a guest to use a service, this service
should be preserved. I'd be more confident if we gave to userspace the
indication that the hypervisor supports PTP. Userspace can then decide
whether to perform migration or not.
Thanks,
M.
--
Jazz is not dead, it just smells funny.
^ permalink raw reply
* Re: [PATCH] rtl8xxxu: add bluetooth co-existence support for single antenna
From: Jes Sorensen @ 2019-09-09 11:13 UTC (permalink / raw)
To: Chris Chiu, kvalo, davem; +Cc: linux-wireless, netdev, linux-kernel, linux
In-Reply-To: <20190903053735.85957-1-chiu@endlessm.com>
On 9/3/19 1:37 AM, Chris Chiu wrote:
> The RTL8723BU suffers the wifi disconnection problem while bluetooth
> device connected. While wifi is doing tx/rx, the bluetooth will scan
> without results. This is due to the wifi and bluetooth share the same
> single antenna for RF communication and they need to have a mechanism
> to collaborate.
>
> BT information is provided via the packet sent from co-processor to
> host (C2H). It contains the status of BT but the rtl8723bu_handle_c2h
> dose not really handle it. And there's no bluetooth coexistence
> mechanism to deal with it.
>
> This commit adds a workqueue to set the tdma configurations and
> coefficient table per the parsed bluetooth link status and given
> wifi connection state. The tdma/coef table comes from the vendor
> driver code of the RTL8192EU and RTL8723BU. However, this commit is
> only for single antenna scenario which RTL8192EU is default dual
> antenna. The rtl8xxxu_parse_rxdesc24 which invokes the handle_c2h
> is only for 8723b and 8192e so the mechanism is expected to work
> on both chips with single antenna. Note RTL8192EU dual antenna is
> not supported.
I am pretty excited to see this! It always bugged me the bluetooth
driver was allowed to be applied breaking the existing wifi driver.
Except for some cosmetic stuff, I am all happy with this.
> Signed-off-by: Chris Chiu <chiu@endlessm.com>
> ---
> .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 37 +++
> .../realtek/rtl8xxxu/rtl8xxxu_8723b.c | 2 -
> .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 243 +++++++++++++++++-
> 3 files changed, 275 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> index 582c2a346cec..22e95b11bfbb 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> +
> +struct rtl8xxxu_btcoex {
> + u8 bt_status;
> + bool bt_busy;
> + bool has_sco;
> + bool has_a2dp;
> + bool has_hid;
> + bool has_pan;
> + bool hid_only;
> + bool a2dp_only;
> + bool c2h_bt_inquiry;
> +};
bool is large, maybe just use flags or u8's for this? Not a big deal though.
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> index a6f358b9e447..4f72c2d14d44 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> + if (!btcoex->has_a2dp &&
> + !btcoex->has_sco &&
> + !btcoex->has_pan &&
> + btcoex->has_hid)
This should all fit in one line - 80 characters
> + btcoex->hid_only = true;
> + else
> + btcoex->hid_only = false;
> +
> + if (!btcoex->has_sco &&
> + !btcoex->has_pan &&
> + !btcoex->has_hid &&
> + btcoex->has_a2dp)
Ditto
> +static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
> +{
> + struct rtl8xxxu_priv *priv;
> + struct rtl8723bu_c2h *c2h;
> + struct ieee80211_vif *vif;
> + struct device *dev;
> + struct sk_buff *skb = NULL;
> + unsigned long flags;
> + int len;
> + u8 bt_info = 0;
> + struct rtl8xxxu_btcoex *btcoex;
> +
> + priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work);
> + vif = priv->vif;
> + btcoex = &priv->bt_coex;
> + dev = &priv->udev->dev;
> +
> + if (priv->rf_paths > 1)
> + goto out;
> +
> + while (!skb_queue_empty(&priv->c2hcmd_queue)) {
> + spin_lock_irqsave(&priv->c2hcmd_lock, flags);
> + skb = __skb_dequeue(&priv->c2hcmd_queue);
> + spin_unlock_irqrestore(&priv->c2hcmd_lock, flags);
> +
> + c2h = (struct rtl8723bu_c2h *)skb->data;
> + len = skb->len - 2;
> +
> + switch (c2h->id) {
> + case C2H_8723B_BT_INFO:
> + bt_info = c2h->bt_info.bt_info;
> +
> + rtl8723bu_update_bt_link_info(priv, bt_info);
> +
> + if (btcoex->c2h_bt_inquiry) {
> + if (vif && !vif->bss_conf.assoc) {
> + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0);
> + rtl8723bu_set_coex_with_type(priv, 0);
> + } else if (btcoex->has_sco ||
> + btcoex->has_hid ||
> + btcoex->has_a2dp) {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + } else if (btcoex->has_pan) {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x3f, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + } else {
> + rtl8723bu_set_ps_tdma(priv, 0x8, 0x0, 0x0, 0x0, 0x0);
> + rtl8723bu_set_coex_with_type(priv, 7);
> + }
> +
> + return;
> + }
Kernel code is 80 characters wide - maybe create a btcoex helper
function for this?
> +
> + if (vif && vif->bss_conf.assoc) {
> + u32 val32 = 0;
> + u32 high_prio_tx = 0, high_prio_rx = 0;
> +
> + val32 = rtl8xxxu_read32(priv, 0x770);
> + high_prio_tx = val32 & 0x0000ffff;
> + high_prio_rx = (val32 & 0xffff0000) >> 16;
> +
> + if (btcoex->bt_busy) {
> + if (btcoex->hid_only) {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x20, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 5);
> + } else if (btcoex->a2dp_only) {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + } else if ((btcoex->has_a2dp &&
> + btcoex->has_pan) ||
> + (btcoex->has_hid &&
> + btcoex->has_a2dp &&
> + btcoex->has_pan)) {
> + rtl8723bu_set_ps_tdma(priv, 0x51, 0x21, 0x3, 0x10, 0x10);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + } else if (btcoex->has_hid &&
> + btcoex->has_a2dp) {
> + rtl8723bu_set_ps_tdma(priv, 0x51, 0x21, 0x3, 0x10, 0x10);
> + rtl8723bu_set_coex_with_type(priv, 3);
> + } else {
> + rtl8723bu_set_ps_tdma(priv, 0x61, 0x35, 0x3, 0x11, 0x11);
> + rtl8723bu_set_coex_with_type(priv, 4);
> + }
Same here
Otherwise, thanks for digging into this, it's really great to see!
Cheers,
Jes
^ permalink raw reply
* Re: [PATCH 1/2] net: phy: dp83867: Add documentation for SGMII mode type
From: Vitaly Gaiduk @ 2019-09-09 11:07 UTC (permalink / raw)
To: Andrew Lunn
Cc: davem@davemloft.net, robh+dt@kernel.org, f.fainelli@gmail.com,
Mark Rutland, netdev@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Trent Piepho
In-Reply-To: <20190908085417.GA28580@lunn.ch>
I've done required changes. Sorry for HTML in previous mail I sent it
from mobile app which has not disabling HTML.
Vitaly.
^ permalink raw reply
* [PATCH v2 1/2] net: phy: dp83867: Add documentation for SGMII mode type
From: Vitaly Gaiduk @ 2019-09-09 11:02 UTC (permalink / raw)
To: davem, robh+dt, f.fainelli
Cc: Vitaly Gaiduk, Mark Rutland, Andrew Lunn, Trent Piepho, netdev,
devicetree, linux-kernel
In-Reply-To: <1568026945-3857-1-git-send-email-vitaly.gaiduk@cloudbear.ru>
Add documentation of ti,sgmii-ref-clock-output-enable
which can be used to select SGMII mode type (4 or 6-wire).
Signed-off-by: Vitaly Gaiduk <vitaly.gaiduk@cloudbear.ru>
---
Changes in v2:
- renamed ti,sgmii-type to ti,sgmii-ref-clock-output-enable
and extended description
Documentation/devicetree/bindings/net/ti,dp83867.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/ti,dp83867.txt b/Documentation/devicetree/bindings/net/ti,dp83867.txt
index db6aa3f..c98c682 100644
--- a/Documentation/devicetree/bindings/net/ti,dp83867.txt
+++ b/Documentation/devicetree/bindings/net/ti,dp83867.txt
@@ -37,6 +37,10 @@ Optional property:
for applicable values. The CLK_OUT pin can also
be disabled by this property. When omitted, the
PHY's default will be left as is.
+ - ti,sgmii-ref-clock-output-enable - This denotes the fact which
+ SGMII configuration is used (4 or 6-wire modes).
+ Some MACs work with differential SGMII clock.
+ See data manual for details.
Note: ti,min-output-impedance and ti,max-output-impedance are mutually
exclusive. When both properties are present ti,max-output-impedance
--
2.7.4
^ permalink raw reply related
* [PATCH v2 2/2] net: phy: dp83867: Add SGMII mode type switching
From: Vitaly Gaiduk @ 2019-09-09 11:02 UTC (permalink / raw)
To: davem, robh+dt, f.fainelli
Cc: Vitaly Gaiduk, Mark Rutland, Andrew Lunn, Heiner Kallweit,
Trent Piepho, netdev, devicetree, linux-kernel
In-Reply-To: <1567700761-14195-2-git-send-email-vitaly.gaiduk@cloudbear.ru>
This patch adds ability to switch beetween two PHY SGMII modes.
Some hardware, for example, FPGA IP designs may use 6-wire mode
which enables differential SGMII clock to MAC.
Signed-off-by: Vitaly Gaiduk <vitaly.gaiduk@cloudbear.ru>
---
Changes in v2:
- changed variable sgmii_type name to sgmii_ref_clk_en
drivers/net/phy/dp83867.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 1f1ecee..cd6260e 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -37,6 +37,7 @@
#define DP83867_STRAP_STS2 0x006f
#define DP83867_RGMIIDCTL 0x0086
#define DP83867_IO_MUX_CFG 0x0170
+#define DP83867_SGMIICTL 0x00D3
#define DP83867_10M_SGMII_CFG 0x016F
#define DP83867_10M_SGMII_RATE_ADAPT_MASK BIT(7)
@@ -61,6 +62,9 @@
#define DP83867_RGMII_TX_CLK_DELAY_EN BIT(1)
#define DP83867_RGMII_RX_CLK_DELAY_EN BIT(0)
+/* SGMIICTL bits */
+#define DP83867_SGMII_TYPE BIT(14)
+
/* STRAP_STS1 bits */
#define DP83867_STRAP_STS1_RESERVED BIT(11)
@@ -109,6 +113,7 @@ struct dp83867_private {
bool rxctrl_strap_quirk;
bool set_clk_output;
u32 clk_output_sel;
+ bool sgmii_ref_clk_en;
};
static int dp83867_ack_interrupt(struct phy_device *phydev)
@@ -197,6 +202,9 @@ static int dp83867_of_init(struct phy_device *phydev)
dp83867->rxctrl_strap_quirk = of_property_read_bool(of_node,
"ti,dp83867-rxctrl-strap-quirk");
+ dp83867->sgmii_ref_clk_en = of_property_read_bool(of_node,
+ "ti,sgmii-ref-clock-output-enable");
+
/* Existing behavior was to use default pin strapping delay in rgmii
* mode, but rgmii should have meant no delay. Warn existing users.
*/
@@ -389,6 +397,14 @@ static int dp83867_config_init(struct phy_device *phydev)
if (ret)
return ret;
+
+ /* SGMII type is set to 4-wire mode by default */
+ if (dp83867->sgmii_ref_clk_en) {
+ /* Switch on 6-wire mode */
+ val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL);
+ val |= DP83867_SGMII_TYPE;
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val);
+ }
}
/* Enable Interrupt output INT_OE in CFG3 register */
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] NET: m_can: split into core library and platform adaptation
From: Felipe Balbi @ 2019-09-09 10:59 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde; +Cc: netdev, davem, Felipe Balbi
A future patch will add PCI-based m_can driver. This patch makes that
a lot simpler.
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
drivers/net/can/m_can/Kconfig | 10 +
drivers/net/can/m_can/Makefile | 1 +
drivers/net/can/m_can/m_can.c | 707 ++-----------------------
drivers/net/can/m_can/m_can.h | 420 +++++++++++++++
drivers/net/can/m_can/m_can_platform.c | 306 +++++++++++
5 files changed, 778 insertions(+), 666 deletions(-)
create mode 100644 drivers/net/can/m_can/m_can.h
create mode 100644 drivers/net/can/m_can/m_can_platform.c
diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig
index ec4b2e117f66..fba73338bc38 100644
--- a/drivers/net/can/m_can/Kconfig
+++ b/drivers/net/can/m_can/Kconfig
@@ -4,3 +4,13 @@ config CAN_M_CAN
tristate "Bosch M_CAN devices"
---help---
Say Y here if you want to support for Bosch M_CAN controller.
+
+if CAN_M_CAN
+
+config CAN_M_CAN_PLATFORM
+ tristate "Generic Platform Bus based M_CAN driver"
+ ---help---
+ Say Y here if you want to support Bosch M_CAN controller connected
+ to the platform bus.
+
+endif
diff --git a/drivers/net/can/m_can/Makefile b/drivers/net/can/m_can/Makefile
index 599ae69cb4a1..ac568be3de98 100644
--- a/drivers/net/can/m_can/Makefile
+++ b/drivers/net/can/m_can/Makefile
@@ -4,3 +4,4 @@
#
obj-$(CONFIG_CAN_M_CAN) += m_can.o
+obj-$(CONFIG_CAN_M_CAN_PLATFORM) += m_can_platform.o
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index deb274a19ba0..eabd3777908b 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -13,402 +13,19 @@
* warranty of any kind, whether express or implied.
*/
-#include <linux/clk.h>
#include <linux/delay.h>
-#include <linux/interrupt.h>
+#include <linux/device.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/iopoll.h>
#include <linux/can/dev.h>
-#include <linux/pinctrl/consumer.h>
-
-/* napi related */
-#define M_CAN_NAPI_WEIGHT 64
-
-/* message ram configuration data length */
-#define MRAM_CFG_LEN 8
-
-/* registers definition */
-enum m_can_reg {
- M_CAN_CREL = 0x0,
- M_CAN_ENDN = 0x4,
- M_CAN_CUST = 0x8,
- M_CAN_DBTP = 0xc,
- M_CAN_TEST = 0x10,
- M_CAN_RWD = 0x14,
- M_CAN_CCCR = 0x18,
- M_CAN_NBTP = 0x1c,
- M_CAN_TSCC = 0x20,
- M_CAN_TSCV = 0x24,
- M_CAN_TOCC = 0x28,
- M_CAN_TOCV = 0x2c,
- M_CAN_ECR = 0x40,
- M_CAN_PSR = 0x44,
-/* TDCR Register only available for version >=3.1.x */
- M_CAN_TDCR = 0x48,
- M_CAN_IR = 0x50,
- M_CAN_IE = 0x54,
- M_CAN_ILS = 0x58,
- M_CAN_ILE = 0x5c,
- M_CAN_GFC = 0x80,
- M_CAN_SIDFC = 0x84,
- M_CAN_XIDFC = 0x88,
- M_CAN_XIDAM = 0x90,
- M_CAN_HPMS = 0x94,
- M_CAN_NDAT1 = 0x98,
- M_CAN_NDAT2 = 0x9c,
- M_CAN_RXF0C = 0xa0,
- M_CAN_RXF0S = 0xa4,
- M_CAN_RXF0A = 0xa8,
- M_CAN_RXBC = 0xac,
- M_CAN_RXF1C = 0xb0,
- M_CAN_RXF1S = 0xb4,
- M_CAN_RXF1A = 0xb8,
- M_CAN_RXESC = 0xbc,
- M_CAN_TXBC = 0xc0,
- M_CAN_TXFQS = 0xc4,
- M_CAN_TXESC = 0xc8,
- M_CAN_TXBRP = 0xcc,
- M_CAN_TXBAR = 0xd0,
- M_CAN_TXBCR = 0xd4,
- M_CAN_TXBTO = 0xd8,
- M_CAN_TXBCF = 0xdc,
- M_CAN_TXBTIE = 0xe0,
- M_CAN_TXBCIE = 0xe4,
- M_CAN_TXEFC = 0xf0,
- M_CAN_TXEFS = 0xf4,
- M_CAN_TXEFA = 0xf8,
-};
-
-/* m_can lec values */
-enum m_can_lec_type {
- LEC_NO_ERROR = 0,
- LEC_STUFF_ERROR,
- LEC_FORM_ERROR,
- LEC_ACK_ERROR,
- LEC_BIT1_ERROR,
- LEC_BIT0_ERROR,
- LEC_CRC_ERROR,
- LEC_UNUSED,
-};
-
-enum m_can_mram_cfg {
- MRAM_SIDF = 0,
- MRAM_XIDF,
- MRAM_RXF0,
- MRAM_RXF1,
- MRAM_RXB,
- MRAM_TXE,
- MRAM_TXB,
- MRAM_CFG_NUM,
-};
-
-/* Core Release Register (CREL) */
-#define CREL_REL_SHIFT 28
-#define CREL_REL_MASK (0xF << CREL_REL_SHIFT)
-#define CREL_STEP_SHIFT 24
-#define CREL_STEP_MASK (0xF << CREL_STEP_SHIFT)
-#define CREL_SUBSTEP_SHIFT 20
-#define CREL_SUBSTEP_MASK (0xF << CREL_SUBSTEP_SHIFT)
-
-/* Data Bit Timing & Prescaler Register (DBTP) */
-#define DBTP_TDC BIT(23)
-#define DBTP_DBRP_SHIFT 16
-#define DBTP_DBRP_MASK (0x1f << DBTP_DBRP_SHIFT)
-#define DBTP_DTSEG1_SHIFT 8
-#define DBTP_DTSEG1_MASK (0x1f << DBTP_DTSEG1_SHIFT)
-#define DBTP_DTSEG2_SHIFT 4
-#define DBTP_DTSEG2_MASK (0xf << DBTP_DTSEG2_SHIFT)
-#define DBTP_DSJW_SHIFT 0
-#define DBTP_DSJW_MASK (0xf << DBTP_DSJW_SHIFT)
-
-/* Transmitter Delay Compensation Register (TDCR) */
-#define TDCR_TDCO_SHIFT 8
-#define TDCR_TDCO_MASK (0x7F << TDCR_TDCO_SHIFT)
-#define TDCR_TDCF_SHIFT 0
-#define TDCR_TDCF_MASK (0x7F << TDCR_TDCF_SHIFT)
-
-/* Test Register (TEST) */
-#define TEST_LBCK BIT(4)
-
-/* CC Control Register(CCCR) */
-#define CCCR_CMR_MASK 0x3
-#define CCCR_CMR_SHIFT 10
-#define CCCR_CMR_CANFD 0x1
-#define CCCR_CMR_CANFD_BRS 0x2
-#define CCCR_CMR_CAN 0x3
-#define CCCR_CME_MASK 0x3
-#define CCCR_CME_SHIFT 8
-#define CCCR_CME_CAN 0
-#define CCCR_CME_CANFD 0x1
-#define CCCR_CME_CANFD_BRS 0x2
-#define CCCR_TXP BIT(14)
-#define CCCR_TEST BIT(7)
-#define CCCR_MON BIT(5)
-#define CCCR_CSR BIT(4)
-#define CCCR_CSA BIT(3)
-#define CCCR_ASM BIT(2)
-#define CCCR_CCE BIT(1)
-#define CCCR_INIT BIT(0)
-#define CCCR_CANFD 0x10
-/* for version >=3.1.x */
-#define CCCR_EFBI BIT(13)
-#define CCCR_PXHD BIT(12)
-#define CCCR_BRSE BIT(9)
-#define CCCR_FDOE BIT(8)
-/* only for version >=3.2.x */
-#define CCCR_NISO BIT(15)
-
-/* Nominal Bit Timing & Prescaler Register (NBTP) */
-#define NBTP_NSJW_SHIFT 25
-#define NBTP_NSJW_MASK (0x7f << NBTP_NSJW_SHIFT)
-#define NBTP_NBRP_SHIFT 16
-#define NBTP_NBRP_MASK (0x1ff << NBTP_NBRP_SHIFT)
-#define NBTP_NTSEG1_SHIFT 8
-#define NBTP_NTSEG1_MASK (0xff << NBTP_NTSEG1_SHIFT)
-#define NBTP_NTSEG2_SHIFT 0
-#define NBTP_NTSEG2_MASK (0x7f << NBTP_NTSEG2_SHIFT)
-
-/* Error Counter Register(ECR) */
-#define ECR_RP BIT(15)
-#define ECR_REC_SHIFT 8
-#define ECR_REC_MASK (0x7f << ECR_REC_SHIFT)
-#define ECR_TEC_SHIFT 0
-#define ECR_TEC_MASK 0xff
-
-/* Protocol Status Register(PSR) */
-#define PSR_BO BIT(7)
-#define PSR_EW BIT(6)
-#define PSR_EP BIT(5)
-#define PSR_LEC_MASK 0x7
-
-/* Interrupt Register(IR) */
-#define IR_ALL_INT 0xffffffff
-
-/* Renamed bits for versions > 3.1.x */
-#define IR_ARA BIT(29)
-#define IR_PED BIT(28)
-#define IR_PEA BIT(27)
-
-/* Bits for version 3.0.x */
-#define IR_STE BIT(31)
-#define IR_FOE BIT(30)
-#define IR_ACKE BIT(29)
-#define IR_BE BIT(28)
-#define IR_CRCE BIT(27)
-#define IR_WDI BIT(26)
-#define IR_BO BIT(25)
-#define IR_EW BIT(24)
-#define IR_EP BIT(23)
-#define IR_ELO BIT(22)
-#define IR_BEU BIT(21)
-#define IR_BEC BIT(20)
-#define IR_DRX BIT(19)
-#define IR_TOO BIT(18)
-#define IR_MRAF BIT(17)
-#define IR_TSW BIT(16)
-#define IR_TEFL BIT(15)
-#define IR_TEFF BIT(14)
-#define IR_TEFW BIT(13)
-#define IR_TEFN BIT(12)
-#define IR_TFE BIT(11)
-#define IR_TCF BIT(10)
-#define IR_TC BIT(9)
-#define IR_HPM BIT(8)
-#define IR_RF1L BIT(7)
-#define IR_RF1F BIT(6)
-#define IR_RF1W BIT(5)
-#define IR_RF1N BIT(4)
-#define IR_RF0L BIT(3)
-#define IR_RF0F BIT(2)
-#define IR_RF0W BIT(1)
-#define IR_RF0N BIT(0)
-#define IR_ERR_STATE (IR_BO | IR_EW | IR_EP)
-
-/* Interrupts for version 3.0.x */
-#define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE)
-#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_ELO | IR_BEU | \
- IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
- IR_RF1L | IR_RF0L)
-#define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X)
-/* Interrupts for version >= 3.1.x */
-#define IR_ERR_LEC_31X (IR_PED | IR_PEA)
-#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_ELO | IR_BEU | \
- IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
- IR_RF1L | IR_RF0L)
-#define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X)
-
-/* Interrupt Line Select (ILS) */
-#define ILS_ALL_INT0 0x0
-#define ILS_ALL_INT1 0xFFFFFFFF
-
-/* Interrupt Line Enable (ILE) */
-#define ILE_EINT1 BIT(1)
-#define ILE_EINT0 BIT(0)
-
-/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */
-#define RXFC_FWM_SHIFT 24
-#define RXFC_FWM_MASK (0x7f << RXFC_FWM_SHIFT)
-#define RXFC_FS_SHIFT 16
-#define RXFC_FS_MASK (0x7f << RXFC_FS_SHIFT)
-
-/* Rx FIFO 0/1 Status (RXF0S/RXF1S) */
-#define RXFS_RFL BIT(25)
-#define RXFS_FF BIT(24)
-#define RXFS_FPI_SHIFT 16
-#define RXFS_FPI_MASK 0x3f0000
-#define RXFS_FGI_SHIFT 8
-#define RXFS_FGI_MASK 0x3f00
-#define RXFS_FFL_MASK 0x7f
-
-/* Rx Buffer / FIFO Element Size Configuration (RXESC) */
-#define M_CAN_RXESC_8BYTES 0x0
-#define M_CAN_RXESC_64BYTES 0x777
-
-/* Tx Buffer Configuration(TXBC) */
-#define TXBC_NDTB_SHIFT 16
-#define TXBC_NDTB_MASK (0x3f << TXBC_NDTB_SHIFT)
-#define TXBC_TFQS_SHIFT 24
-#define TXBC_TFQS_MASK (0x3f << TXBC_TFQS_SHIFT)
-
-/* Tx FIFO/Queue Status (TXFQS) */
-#define TXFQS_TFQF BIT(21)
-#define TXFQS_TFQPI_SHIFT 16
-#define TXFQS_TFQPI_MASK (0x1f << TXFQS_TFQPI_SHIFT)
-#define TXFQS_TFGI_SHIFT 8
-#define TXFQS_TFGI_MASK (0x1f << TXFQS_TFGI_SHIFT)
-#define TXFQS_TFFL_SHIFT 0
-#define TXFQS_TFFL_MASK (0x3f << TXFQS_TFFL_SHIFT)
-
-/* Tx Buffer Element Size Configuration(TXESC) */
-#define TXESC_TBDS_8BYTES 0x0
-#define TXESC_TBDS_64BYTES 0x7
-
-/* Tx Event FIFO Configuration (TXEFC) */
-#define TXEFC_EFS_SHIFT 16
-#define TXEFC_EFS_MASK (0x3f << TXEFC_EFS_SHIFT)
-
-/* Tx Event FIFO Status (TXEFS) */
-#define TXEFS_TEFL BIT(25)
-#define TXEFS_EFF BIT(24)
-#define TXEFS_EFGI_SHIFT 8
-#define TXEFS_EFGI_MASK (0x1f << TXEFS_EFGI_SHIFT)
-#define TXEFS_EFFL_SHIFT 0
-#define TXEFS_EFFL_MASK (0x3f << TXEFS_EFFL_SHIFT)
-
-/* Tx Event FIFO Acknowledge (TXEFA) */
-#define TXEFA_EFAI_SHIFT 0
-#define TXEFA_EFAI_MASK (0x1f << TXEFA_EFAI_SHIFT)
-
-/* Message RAM Configuration (in bytes) */
-#define SIDF_ELEMENT_SIZE 4
-#define XIDF_ELEMENT_SIZE 8
-#define RXF0_ELEMENT_SIZE 72
-#define RXF1_ELEMENT_SIZE 72
-#define RXB_ELEMENT_SIZE 72
-#define TXE_ELEMENT_SIZE 8
-#define TXB_ELEMENT_SIZE 72
-
-/* Message RAM Elements */
-#define M_CAN_FIFO_ID 0x0
-#define M_CAN_FIFO_DLC 0x4
-#define M_CAN_FIFO_DATA(n) (0x8 + ((n) << 2))
-
-/* Rx Buffer Element */
-/* R0 */
-#define RX_BUF_ESI BIT(31)
-#define RX_BUF_XTD BIT(30)
-#define RX_BUF_RTR BIT(29)
-/* R1 */
-#define RX_BUF_ANMF BIT(31)
-#define RX_BUF_FDF BIT(21)
-#define RX_BUF_BRS BIT(20)
-
-/* Tx Buffer Element */
-/* T0 */
-#define TX_BUF_ESI BIT(31)
-#define TX_BUF_XTD BIT(30)
-#define TX_BUF_RTR BIT(29)
-/* T1 */
-#define TX_BUF_EFC BIT(23)
-#define TX_BUF_FDF BIT(21)
-#define TX_BUF_BRS BIT(20)
-#define TX_BUF_MM_SHIFT 24
-#define TX_BUF_MM_MASK (0xff << TX_BUF_MM_SHIFT)
-
-/* Tx event FIFO Element */
-/* E1 */
-#define TX_EVENT_MM_SHIFT TX_BUF_MM_SHIFT
-#define TX_EVENT_MM_MASK (0xff << TX_EVENT_MM_SHIFT)
-
-/* address offset and element number for each FIFO/Buffer in the Message RAM */
-struct mram_cfg {
- u16 off;
- u8 num;
-};
-
-/* m_can private data structure */
-struct m_can_priv {
- struct can_priv can; /* must be the first member */
- struct napi_struct napi;
- struct net_device *dev;
- struct device *device;
- struct clk *hclk;
- struct clk *cclk;
- void __iomem *base;
- u32 irqstatus;
- int version;
-
- /* message ram configuration */
- void __iomem *mram_base;
- struct mram_cfg mcfg[MRAM_CFG_NUM];
-};
-
-static inline u32 m_can_read(const struct m_can_priv *priv, enum m_can_reg reg)
-{
- return readl(priv->base + reg);
-}
-
-static inline void m_can_write(const struct m_can_priv *priv,
- enum m_can_reg reg, u32 val)
-{
- writel(val, priv->base + reg);
-}
-static inline u32 m_can_fifo_read(const struct m_can_priv *priv,
- u32 fgi, unsigned int offset)
-{
- return readl(priv->mram_base + priv->mcfg[MRAM_RXF0].off +
- fgi * RXF0_ELEMENT_SIZE + offset);
-}
+#include "m_can.h"
-static inline void m_can_fifo_write(const struct m_can_priv *priv,
- u32 fpi, unsigned int offset, u32 val)
-{
- writel(val, priv->mram_base + priv->mcfg[MRAM_TXB].off +
- fpi * TXB_ELEMENT_SIZE + offset);
-}
-
-static inline u32 m_can_txe_fifo_read(const struct m_can_priv *priv,
- u32 fgi,
- u32 offset) {
- return readl(priv->mram_base + priv->mcfg[MRAM_TXE].off +
- fgi * TXE_ELEMENT_SIZE + offset);
-}
-
-static inline bool m_can_tx_fifo_full(const struct m_can_priv *priv)
-{
- return !!(m_can_read(priv, M_CAN_TXFQS) & TXFQS_TFQF);
-}
-
-static inline void m_can_config_endisable(const struct m_can_priv *priv,
- bool enable)
+void m_can_config_endisable(const struct m_can_priv *priv, bool enable)
{
u32 cccr = m_can_read(priv, M_CAN_CCCR);
u32 timeout = 10;
@@ -437,17 +54,20 @@ static inline void m_can_config_endisable(const struct m_can_priv *priv,
udelay(1);
}
}
+EXPORT_SYMBOL_GPL(m_can_config_endisable);
-static inline void m_can_enable_all_interrupts(const struct m_can_priv *priv)
+void m_can_enable_all_interrupts(const struct m_can_priv *priv)
{
/* Only interrupt line 0 is used in this driver */
m_can_write(priv, M_CAN_ILE, ILE_EINT0);
}
+EXPORT_SYMBOL_GPL(m_can_enable_all_interrupts);
-static inline void m_can_disable_all_interrupts(const struct m_can_priv *priv)
+void m_can_disable_all_interrupts(const struct m_can_priv *priv)
{
m_can_write(priv, M_CAN_ILE, 0x0);
}
+EXPORT_SYMBOL_GPL(m_can_disable_all_interrupts);
static void m_can_read_fifo(struct net_device *dev, u32 rxfs)
{
@@ -629,7 +249,7 @@ static int __m_can_get_berr_counter(const struct net_device *dev,
return 0;
}
-static int m_can_clk_start(struct m_can_priv *priv)
+int m_can_clk_start(struct m_can_priv *priv)
{
int err;
@@ -641,11 +261,13 @@ static int m_can_clk_start(struct m_can_priv *priv)
return 0;
}
+EXPORT_SYMBOL_GPL(m_can_clk_start);
-static void m_can_clk_stop(struct m_can_priv *priv)
+void m_can_clk_stop(struct m_can_priv *priv)
{
pm_runtime_put_sync(priv->device);
}
+EXPORT_SYMBOL_GPL(m_can_clk_stop);
static int m_can_get_berr_counter(const struct net_device *dev,
struct can_berr_counter *bec)
@@ -1178,7 +800,7 @@ static void m_can_chip_config(struct net_device *dev)
m_can_config_endisable(priv, false);
}
-static void m_can_start(struct net_device *dev)
+void m_can_start(struct net_device *dev)
{
struct m_can_priv *priv = netdev_priv(dev);
@@ -1189,6 +811,7 @@ static void m_can_start(struct net_device *dev)
m_can_enable_all_interrupts(priv);
}
+EXPORT_SYMBOL_GPL(m_can_start);
static int m_can_set_mode(struct net_device *dev, enum can_mode mode)
{
@@ -1263,7 +886,7 @@ static bool m_can_niso_supported(const struct m_can_priv *priv)
return !niso_timeout;
}
-static int m_can_dev_setup(struct platform_device *pdev, struct net_device *dev,
+int m_can_dev_setup(struct device *dev, struct net_device *net,
void __iomem *addr)
{
struct m_can_priv *priv;
@@ -1272,17 +895,17 @@ static int m_can_dev_setup(struct platform_device *pdev, struct net_device *dev,
m_can_version = m_can_check_core_release(addr);
/* return if unsupported version */
if (!m_can_version) {
- dev_err(&pdev->dev, "Unsupported version number: %2d",
+ dev_err(dev, "Unsupported version number: %2d",
m_can_version);
return -EINVAL;
}
- priv = netdev_priv(dev);
- netif_napi_add(dev, &priv->napi, m_can_poll, M_CAN_NAPI_WEIGHT);
+ priv = netdev_priv(net);
+ netif_napi_add(net, &priv->napi, m_can_poll, M_CAN_NAPI_WEIGHT);
/* Shared properties of all M_CAN versions */
priv->version = m_can_version;
- priv->dev = dev;
+ priv->dev = net;
priv->base = addr;
priv->can.do_set_mode = m_can_set_mode;
priv->can.do_get_berr_counter = m_can_get_berr_counter;
@@ -1297,14 +920,14 @@ static int m_can_dev_setup(struct platform_device *pdev, struct net_device *dev,
switch (priv->version) {
case 30:
/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.x */
- can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
+ can_set_static_ctrlmode(net, CAN_CTRLMODE_FD_NON_ISO);
priv->can.bittiming_const = &m_can_bittiming_const_30X;
priv->can.data_bittiming_const =
&m_can_data_bittiming_const_30X;
break;
case 31:
/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.1.x */
- can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
+ can_set_static_ctrlmode(net, CAN_CTRLMODE_FD_NON_ISO);
priv->can.bittiming_const = &m_can_bittiming_const_31X;
priv->can.data_bittiming_const =
&m_can_data_bittiming_const_31X;
@@ -1318,13 +941,14 @@ static int m_can_dev_setup(struct platform_device *pdev, struct net_device *dev,
: 0);
break;
default:
- dev_err(&pdev->dev, "Unsupported version number: %2d",
+ dev_err(dev, "Unsupported version number: %2d",
priv->version);
return -EINVAL;
}
return 0;
}
+EXPORT_SYMBOL_GPL(m_can_dev_setup);
static int m_can_open(struct net_device *dev)
{
@@ -1366,7 +990,7 @@ static int m_can_open(struct net_device *dev)
return err;
}
-static void m_can_stop(struct net_device *dev)
+void m_can_stop(struct net_device *dev)
{
struct m_can_priv *priv = netdev_priv(dev);
@@ -1376,6 +1000,7 @@ static void m_can_stop(struct net_device *dev)
/* set the state as STOPPED */
priv->can.state = CAN_STATE_STOPPED;
}
+EXPORT_SYMBOL_GPL(m_can_stop);
static int m_can_close(struct net_device *dev)
{
@@ -1528,15 +1153,16 @@ static const struct net_device_ops m_can_netdev_ops = {
.ndo_change_mtu = can_change_mtu,
};
-static int register_m_can_dev(struct net_device *dev)
+int register_m_can_dev(struct net_device *dev)
{
dev->flags |= IFF_ECHO; /* we support local echo */
dev->netdev_ops = &m_can_netdev_ops;
return register_candev(dev);
}
+EXPORT_SYMBOL_GPL(register_m_can_dev);
-static void m_can_init_ram(struct m_can_priv *priv)
+void m_can_init_ram(struct m_can_priv *priv)
{
int end, i, start;
@@ -1549,283 +1175,32 @@ static void m_can_init_ram(struct m_can_priv *priv)
for (i = start; i < end; i += 4)
writel(0x0, priv->mram_base + i);
}
+EXPORT_SYMBOL_GPL(m_can_init_ram);
-static void m_can_of_parse_mram(struct m_can_priv *priv,
- const u32 *mram_config_vals)
+void unregister_m_can_dev(struct net_device *dev)
{
- priv->mcfg[MRAM_SIDF].off = mram_config_vals[0];
- priv->mcfg[MRAM_SIDF].num = mram_config_vals[1];
- priv->mcfg[MRAM_XIDF].off = priv->mcfg[MRAM_SIDF].off +
- priv->mcfg[MRAM_SIDF].num * SIDF_ELEMENT_SIZE;
- priv->mcfg[MRAM_XIDF].num = mram_config_vals[2];
- priv->mcfg[MRAM_RXF0].off = priv->mcfg[MRAM_XIDF].off +
- priv->mcfg[MRAM_XIDF].num * XIDF_ELEMENT_SIZE;
- priv->mcfg[MRAM_RXF0].num = mram_config_vals[3] &
- (RXFC_FS_MASK >> RXFC_FS_SHIFT);
- priv->mcfg[MRAM_RXF1].off = priv->mcfg[MRAM_RXF0].off +
- priv->mcfg[MRAM_RXF0].num * RXF0_ELEMENT_SIZE;
- priv->mcfg[MRAM_RXF1].num = mram_config_vals[4] &
- (RXFC_FS_MASK >> RXFC_FS_SHIFT);
- priv->mcfg[MRAM_RXB].off = priv->mcfg[MRAM_RXF1].off +
- priv->mcfg[MRAM_RXF1].num * RXF1_ELEMENT_SIZE;
- priv->mcfg[MRAM_RXB].num = mram_config_vals[5];
- priv->mcfg[MRAM_TXE].off = priv->mcfg[MRAM_RXB].off +
- priv->mcfg[MRAM_RXB].num * RXB_ELEMENT_SIZE;
- priv->mcfg[MRAM_TXE].num = mram_config_vals[6];
- priv->mcfg[MRAM_TXB].off = priv->mcfg[MRAM_TXE].off +
- priv->mcfg[MRAM_TXE].num * TXE_ELEMENT_SIZE;
- priv->mcfg[MRAM_TXB].num = mram_config_vals[7] &
- (TXBC_NDTB_MASK >> TXBC_NDTB_SHIFT);
-
- dev_dbg(priv->device,
- "mram_base %p sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n",
- priv->mram_base,
- priv->mcfg[MRAM_SIDF].off, priv->mcfg[MRAM_SIDF].num,
- priv->mcfg[MRAM_XIDF].off, priv->mcfg[MRAM_XIDF].num,
- priv->mcfg[MRAM_RXF0].off, priv->mcfg[MRAM_RXF0].num,
- priv->mcfg[MRAM_RXF1].off, priv->mcfg[MRAM_RXF1].num,
- priv->mcfg[MRAM_RXB].off, priv->mcfg[MRAM_RXB].num,
- priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
- priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);
-
- m_can_init_ram(priv);
+ unregister_candev(dev);
}
+EXPORT_SYMBOL_GPL(unregister_m_can_dev);
-static int m_can_plat_probe(struct platform_device *pdev)
+struct net_device *alloc_m_can_dev(u32 tx_fifo_size)
{
- struct net_device *dev;
+ struct net_device *net;
struct m_can_priv *priv;
- struct resource *res;
- void __iomem *addr;
- void __iomem *mram_addr;
- struct clk *hclk, *cclk;
- int irq, ret;
- struct device_node *np;
- u32 mram_config_vals[MRAM_CFG_LEN];
- u32 tx_fifo_size;
-
- np = pdev->dev.of_node;
-
- hclk = devm_clk_get(&pdev->dev, "hclk");
- cclk = devm_clk_get(&pdev->dev, "cclk");
-
- if (IS_ERR(hclk) || IS_ERR(cclk)) {
- dev_err(&pdev->dev, "no clock found\n");
- ret = -ENODEV;
- goto failed_ret;
- }
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "m_can");
- addr = devm_ioremap_resource(&pdev->dev, res);
- irq = platform_get_irq_byname(pdev, "int0");
-
- if (IS_ERR(addr) || irq < 0) {
- ret = -EINVAL;
- goto failed_ret;
- }
-
- /* message ram could be shared */
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram");
- if (!res) {
- ret = -ENODEV;
- goto failed_ret;
- }
-
- mram_addr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
- if (!mram_addr) {
- ret = -ENOMEM;
- goto failed_ret;
- }
-
- /* get message ram configuration */
- ret = of_property_read_u32_array(np, "bosch,mram-cfg",
- mram_config_vals,
- sizeof(mram_config_vals) / 4);
- if (ret) {
- dev_err(&pdev->dev, "Could not get Message RAM configuration.");
- goto failed_ret;
- }
-
- /* Get TX FIFO size
- * Defines the total amount of echo buffers for loopback
- */
- tx_fifo_size = mram_config_vals[7];
-
- /* allocate the m_can device */
- dev = alloc_candev(sizeof(*priv), tx_fifo_size);
- if (!dev) {
- ret = -ENOMEM;
- goto failed_ret;
- }
-
- priv = netdev_priv(dev);
- dev->irq = irq;
- priv->device = &pdev->dev;
- priv->hclk = hclk;
- priv->cclk = cclk;
- priv->can.clock.freq = clk_get_rate(cclk);
- priv->mram_base = mram_addr;
-
- platform_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- /* Enable clocks. Necessary to read Core Release in order to determine
- * M_CAN version
- */
- pm_runtime_enable(&pdev->dev);
- ret = m_can_clk_start(priv);
- if (ret)
- goto pm_runtime_fail;
-
- ret = m_can_dev_setup(pdev, dev, addr);
- if (ret)
- goto clk_disable;
-
- ret = register_m_can_dev(dev);
- if (ret) {
- dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
- KBUILD_MODNAME, ret);
- goto clk_disable;
- }
-
- m_can_of_parse_mram(priv, mram_config_vals);
-
- devm_can_led_init(dev);
-
- of_can_transceiver(dev);
-
- dev_info(&pdev->dev, "%s device registered (irq=%d, version=%d)\n",
- KBUILD_MODNAME, dev->irq, priv->version);
-
- /* Probe finished
- * Stop clocks. They will be reactivated once the M_CAN device is opened
- */
-clk_disable:
- m_can_clk_stop(priv);
-pm_runtime_fail:
- if (ret) {
- pm_runtime_disable(&pdev->dev);
- free_candev(dev);
- }
-failed_ret:
- return ret;
-}
-
-static __maybe_unused int m_can_suspend(struct device *dev)
-{
- struct net_device *ndev = dev_get_drvdata(dev);
- struct m_can_priv *priv = netdev_priv(ndev);
-
- if (netif_running(ndev)) {
- netif_stop_queue(ndev);
- netif_device_detach(ndev);
- m_can_stop(ndev);
- m_can_clk_stop(priv);
- }
-
- pinctrl_pm_select_sleep_state(dev);
-
- priv->can.state = CAN_STATE_SLEEPING;
-
- return 0;
-}
-
-static __maybe_unused int m_can_resume(struct device *dev)
-{
- struct net_device *ndev = dev_get_drvdata(dev);
- struct m_can_priv *priv = netdev_priv(ndev);
-
- pinctrl_pm_select_default_state(dev);
- priv->can.state = CAN_STATE_ERROR_ACTIVE;
-
- if (netif_running(ndev)) {
- int ret;
+ net = alloc_candev(sizeof(*priv), tx_fifo_size);
+ if (!net)
+ return NULL;
- ret = m_can_clk_start(priv);
- if (ret)
- return ret;
-
- m_can_init_ram(priv);
- m_can_start(ndev);
- netif_device_attach(ndev);
- netif_start_queue(ndev);
- }
-
- return 0;
+ return net;
}
+EXPORT_SYMBOL_GPL(alloc_m_can_dev);
-static void unregister_m_can_dev(struct net_device *dev)
+void free_m_can_dev(struct net_device *dev)
{
- unregister_candev(dev);
-}
-
-static int m_can_plat_remove(struct platform_device *pdev)
-{
- struct net_device *dev = platform_get_drvdata(pdev);
-
- unregister_m_can_dev(dev);
-
- pm_runtime_disable(&pdev->dev);
-
- platform_set_drvdata(pdev, NULL);
-
free_candev(dev);
-
- return 0;
-}
-
-static int __maybe_unused m_can_runtime_suspend(struct device *dev)
-{
- struct net_device *ndev = dev_get_drvdata(dev);
- struct m_can_priv *priv = netdev_priv(ndev);
-
- clk_disable_unprepare(priv->cclk);
- clk_disable_unprepare(priv->hclk);
-
- return 0;
-}
-
-static int __maybe_unused m_can_runtime_resume(struct device *dev)
-{
- struct net_device *ndev = dev_get_drvdata(dev);
- struct m_can_priv *priv = netdev_priv(ndev);
- int err;
-
- err = clk_prepare_enable(priv->hclk);
- if (err)
- return err;
-
- err = clk_prepare_enable(priv->cclk);
- if (err)
- clk_disable_unprepare(priv->hclk);
-
- return err;
}
-
-static const struct dev_pm_ops m_can_pmops = {
- SET_RUNTIME_PM_OPS(m_can_runtime_suspend,
- m_can_runtime_resume, NULL)
- SET_SYSTEM_SLEEP_PM_OPS(m_can_suspend, m_can_resume)
-};
-
-static const struct of_device_id m_can_of_table[] = {
- { .compatible = "bosch,m_can", .data = NULL },
- { /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, m_can_of_table);
-
-static struct platform_driver m_can_plat_driver = {
- .driver = {
- .name = KBUILD_MODNAME,
- .of_match_table = m_can_of_table,
- .pm = &m_can_pmops,
- },
- .probe = m_can_plat_probe,
- .remove = m_can_plat_remove,
-};
-
-module_platform_driver(m_can_plat_driver);
+EXPORT_SYMBOL_GPL(free_m_can_dev);
MODULE_AUTHOR("Dong Aisheng <b29396@freescale.com>");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/m_can/m_can.h b/drivers/net/can/m_can/m_can.h
new file mode 100644
index 000000000000..e40ff64ac819
--- /dev/null
+++ b/drivers/net/can/m_can/m_can.h
@@ -0,0 +1,420 @@
+/*
+ * CAN bus driver for Bosch M_CAN controller
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Dong Aisheng <b29396@freescale.com>
+ *
+ * Bosch M_CAN user manual can be obtained from:
+ * http://www.bosch-semiconductors.de/media/pdf_1/ipmodules_1/m_can/
+ * mcan_users_manual_v302.pdf
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __M_CAN_H
+#define __M_CAN_H
+
+#include <linux/can/dev.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+
+/* napi related */
+#define M_CAN_NAPI_WEIGHT 64
+
+/* message ram configuration data length */
+#define MRAM_CFG_LEN 8
+
+/* registers definition */
+enum m_can_reg {
+ M_CAN_CREL = 0x0,
+ M_CAN_ENDN = 0x4,
+ M_CAN_CUST = 0x8,
+ M_CAN_DBTP = 0xc,
+ M_CAN_TEST = 0x10,
+ M_CAN_RWD = 0x14,
+ M_CAN_CCCR = 0x18,
+ M_CAN_NBTP = 0x1c,
+ M_CAN_TSCC = 0x20,
+ M_CAN_TSCV = 0x24,
+ M_CAN_TOCC = 0x28,
+ M_CAN_TOCV = 0x2c,
+ M_CAN_ECR = 0x40,
+ M_CAN_PSR = 0x44,
+/* TDCR Register only available for version >=3.1.x */
+ M_CAN_TDCR = 0x48,
+ M_CAN_IR = 0x50,
+ M_CAN_IE = 0x54,
+ M_CAN_ILS = 0x58,
+ M_CAN_ILE = 0x5c,
+ M_CAN_GFC = 0x80,
+ M_CAN_SIDFC = 0x84,
+ M_CAN_XIDFC = 0x88,
+ M_CAN_XIDAM = 0x90,
+ M_CAN_HPMS = 0x94,
+ M_CAN_NDAT1 = 0x98,
+ M_CAN_NDAT2 = 0x9c,
+ M_CAN_RXF0C = 0xa0,
+ M_CAN_RXF0S = 0xa4,
+ M_CAN_RXF0A = 0xa8,
+ M_CAN_RXBC = 0xac,
+ M_CAN_RXF1C = 0xb0,
+ M_CAN_RXF1S = 0xb4,
+ M_CAN_RXF1A = 0xb8,
+ M_CAN_RXESC = 0xbc,
+ M_CAN_TXBC = 0xc0,
+ M_CAN_TXFQS = 0xc4,
+ M_CAN_TXESC = 0xc8,
+ M_CAN_TXBRP = 0xcc,
+ M_CAN_TXBAR = 0xd0,
+ M_CAN_TXBCR = 0xd4,
+ M_CAN_TXBTO = 0xd8,
+ M_CAN_TXBCF = 0xdc,
+ M_CAN_TXBTIE = 0xe0,
+ M_CAN_TXBCIE = 0xe4,
+ M_CAN_TXEFC = 0xf0,
+ M_CAN_TXEFS = 0xf4,
+ M_CAN_TXEFA = 0xf8,
+};
+
+/* m_can lec values */
+enum m_can_lec_type {
+ LEC_NO_ERROR = 0,
+ LEC_STUFF_ERROR,
+ LEC_FORM_ERROR,
+ LEC_ACK_ERROR,
+ LEC_BIT1_ERROR,
+ LEC_BIT0_ERROR,
+ LEC_CRC_ERROR,
+ LEC_UNUSED,
+};
+
+enum m_can_mram_cfg {
+ MRAM_SIDF = 0,
+ MRAM_XIDF,
+ MRAM_RXF0,
+ MRAM_RXF1,
+ MRAM_RXB,
+ MRAM_TXE,
+ MRAM_TXB,
+ MRAM_CFG_NUM,
+};
+
+/* Core Release Register (CREL) */
+#define CREL_REL_SHIFT 28
+#define CREL_REL_MASK (0xF << CREL_REL_SHIFT)
+#define CREL_STEP_SHIFT 24
+#define CREL_STEP_MASK (0xF << CREL_STEP_SHIFT)
+#define CREL_SUBSTEP_SHIFT 20
+#define CREL_SUBSTEP_MASK (0xF << CREL_SUBSTEP_SHIFT)
+
+/* Data Bit Timing & Prescaler Register (DBTP) */
+#define DBTP_TDC BIT(23)
+#define DBTP_DBRP_SHIFT 16
+#define DBTP_DBRP_MASK (0x1f << DBTP_DBRP_SHIFT)
+#define DBTP_DTSEG1_SHIFT 8
+#define DBTP_DTSEG1_MASK (0x1f << DBTP_DTSEG1_SHIFT)
+#define DBTP_DTSEG2_SHIFT 4
+#define DBTP_DTSEG2_MASK (0xf << DBTP_DTSEG2_SHIFT)
+#define DBTP_DSJW_SHIFT 0
+#define DBTP_DSJW_MASK (0xf << DBTP_DSJW_SHIFT)
+
+/* Transmitter Delay Compensation Register (TDCR) */
+#define TDCR_TDCO_SHIFT 8
+#define TDCR_TDCO_MASK (0x7F << TDCR_TDCO_SHIFT)
+#define TDCR_TDCF_SHIFT 0
+#define TDCR_TDCF_MASK (0x7F << TDCR_TDCF_SHIFT)
+
+/* Test Register (TEST) */
+#define TEST_LBCK BIT(4)
+
+/* CC Control Register(CCCR) */
+#define CCCR_CMR_MASK 0x3
+#define CCCR_CMR_SHIFT 10
+#define CCCR_CMR_CANFD 0x1
+#define CCCR_CMR_CANFD_BRS 0x2
+#define CCCR_CMR_CAN 0x3
+#define CCCR_CME_MASK 0x3
+#define CCCR_CME_SHIFT 8
+#define CCCR_CME_CAN 0
+#define CCCR_CME_CANFD 0x1
+#define CCCR_CME_CANFD_BRS 0x2
+#define CCCR_TXP BIT(14)
+#define CCCR_TEST BIT(7)
+#define CCCR_MON BIT(5)
+#define CCCR_CSR BIT(4)
+#define CCCR_CSA BIT(3)
+#define CCCR_ASM BIT(2)
+#define CCCR_CCE BIT(1)
+#define CCCR_INIT BIT(0)
+#define CCCR_CANFD 0x10
+/* for version >=3.1.x */
+#define CCCR_EFBI BIT(13)
+#define CCCR_PXHD BIT(12)
+#define CCCR_BRSE BIT(9)
+#define CCCR_FDOE BIT(8)
+/* only for version >=3.2.x */
+#define CCCR_NISO BIT(15)
+
+/* Nominal Bit Timing & Prescaler Register (NBTP) */
+#define NBTP_NSJW_SHIFT 25
+#define NBTP_NSJW_MASK (0x7f << NBTP_NSJW_SHIFT)
+#define NBTP_NBRP_SHIFT 16
+#define NBTP_NBRP_MASK (0x1ff << NBTP_NBRP_SHIFT)
+#define NBTP_NTSEG1_SHIFT 8
+#define NBTP_NTSEG1_MASK (0xff << NBTP_NTSEG1_SHIFT)
+#define NBTP_NTSEG2_SHIFT 0
+#define NBTP_NTSEG2_MASK (0x7f << NBTP_NTSEG2_SHIFT)
+
+/* Error Counter Register(ECR) */
+#define ECR_RP BIT(15)
+#define ECR_REC_SHIFT 8
+#define ECR_REC_MASK (0x7f << ECR_REC_SHIFT)
+#define ECR_TEC_SHIFT 0
+#define ECR_TEC_MASK 0xff
+
+/* Protocol Status Register(PSR) */
+#define PSR_BO BIT(7)
+#define PSR_EW BIT(6)
+#define PSR_EP BIT(5)
+#define PSR_LEC_MASK 0x7
+
+/* Interrupt Register(IR) */
+#define IR_ALL_INT 0xffffffff
+
+/* Renamed bits for versions > 3.1.x */
+#define IR_ARA BIT(29)
+#define IR_PED BIT(28)
+#define IR_PEA BIT(27)
+
+/* Bits for version 3.0.x */
+#define IR_STE BIT(31)
+#define IR_FOE BIT(30)
+#define IR_ACKE BIT(29)
+#define IR_BE BIT(28)
+#define IR_CRCE BIT(27)
+#define IR_WDI BIT(26)
+#define IR_BO BIT(25)
+#define IR_EW BIT(24)
+#define IR_EP BIT(23)
+#define IR_ELO BIT(22)
+#define IR_BEU BIT(21)
+#define IR_BEC BIT(20)
+#define IR_DRX BIT(19)
+#define IR_TOO BIT(18)
+#define IR_MRAF BIT(17)
+#define IR_TSW BIT(16)
+#define IR_TEFL BIT(15)
+#define IR_TEFF BIT(14)
+#define IR_TEFW BIT(13)
+#define IR_TEFN BIT(12)
+#define IR_TFE BIT(11)
+#define IR_TCF BIT(10)
+#define IR_TC BIT(9)
+#define IR_HPM BIT(8)
+#define IR_RF1L BIT(7)
+#define IR_RF1F BIT(6)
+#define IR_RF1W BIT(5)
+#define IR_RF1N BIT(4)
+#define IR_RF0L BIT(3)
+#define IR_RF0F BIT(2)
+#define IR_RF0W BIT(1)
+#define IR_RF0N BIT(0)
+#define IR_ERR_STATE (IR_BO | IR_EW | IR_EP)
+
+/* Interrupts for version 3.0.x */
+#define IR_ERR_LEC_30X (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE)
+#define IR_ERR_BUS_30X (IR_ERR_LEC_30X | IR_WDI | IR_ELO | IR_BEU | \
+ IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
+ IR_RF1L | IR_RF0L)
+#define IR_ERR_ALL_30X (IR_ERR_STATE | IR_ERR_BUS_30X)
+/* Interrupts for version >= 3.1.x */
+#define IR_ERR_LEC_31X (IR_PED | IR_PEA)
+#define IR_ERR_BUS_31X (IR_ERR_LEC_31X | IR_WDI | IR_ELO | IR_BEU | \
+ IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \
+ IR_RF1L | IR_RF0L)
+#define IR_ERR_ALL_31X (IR_ERR_STATE | IR_ERR_BUS_31X)
+
+/* Interrupt Line Select (ILS) */
+#define ILS_ALL_INT0 0x0
+#define ILS_ALL_INT1 0xFFFFFFFF
+
+/* Interrupt Line Enable (ILE) */
+#define ILE_EINT1 BIT(1)
+#define ILE_EINT0 BIT(0)
+
+/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */
+#define RXFC_FWM_SHIFT 24
+#define RXFC_FWM_MASK (0x7f << RXFC_FWM_SHIFT)
+#define RXFC_FS_SHIFT 16
+#define RXFC_FS_MASK (0x7f << RXFC_FS_SHIFT)
+
+/* Rx FIFO 0/1 Status (RXF0S/RXF1S) */
+#define RXFS_RFL BIT(25)
+#define RXFS_FF BIT(24)
+#define RXFS_FPI_SHIFT 16
+#define RXFS_FPI_MASK 0x3f0000
+#define RXFS_FGI_SHIFT 8
+#define RXFS_FGI_MASK 0x3f00
+#define RXFS_FFL_MASK 0x7f
+
+/* Rx Buffer / FIFO Element Size Configuration (RXESC) */
+#define M_CAN_RXESC_8BYTES 0x0
+#define M_CAN_RXESC_64BYTES 0x777
+
+/* Tx Buffer Configuration(TXBC) */
+#define TXBC_NDTB_SHIFT 16
+#define TXBC_NDTB_MASK (0x3f << TXBC_NDTB_SHIFT)
+#define TXBC_TFQS_SHIFT 24
+#define TXBC_TFQS_MASK (0x3f << TXBC_TFQS_SHIFT)
+
+/* Tx FIFO/Queue Status (TXFQS) */
+#define TXFQS_TFQF BIT(21)
+#define TXFQS_TFQPI_SHIFT 16
+#define TXFQS_TFQPI_MASK (0x1f << TXFQS_TFQPI_SHIFT)
+#define TXFQS_TFGI_SHIFT 8
+#define TXFQS_TFGI_MASK (0x1f << TXFQS_TFGI_SHIFT)
+#define TXFQS_TFFL_SHIFT 0
+#define TXFQS_TFFL_MASK (0x3f << TXFQS_TFFL_SHIFT)
+
+/* Tx Buffer Element Size Configuration(TXESC) */
+#define TXESC_TBDS_8BYTES 0x0
+#define TXESC_TBDS_64BYTES 0x7
+
+/* Tx Event FIFO Configuration (TXEFC) */
+#define TXEFC_EFS_SHIFT 16
+#define TXEFC_EFS_MASK (0x3f << TXEFC_EFS_SHIFT)
+
+/* Tx Event FIFO Status (TXEFS) */
+#define TXEFS_TEFL BIT(25)
+#define TXEFS_EFF BIT(24)
+#define TXEFS_EFGI_SHIFT 8
+#define TXEFS_EFGI_MASK (0x1f << TXEFS_EFGI_SHIFT)
+#define TXEFS_EFFL_SHIFT 0
+#define TXEFS_EFFL_MASK (0x3f << TXEFS_EFFL_SHIFT)
+
+/* Tx Event FIFO Acknowledge (TXEFA) */
+#define TXEFA_EFAI_SHIFT 0
+#define TXEFA_EFAI_MASK (0x1f << TXEFA_EFAI_SHIFT)
+
+/* Message RAM Configuration (in bytes) */
+#define SIDF_ELEMENT_SIZE 4
+#define XIDF_ELEMENT_SIZE 8
+#define RXF0_ELEMENT_SIZE 72
+#define RXF1_ELEMENT_SIZE 72
+#define RXB_ELEMENT_SIZE 72
+#define TXE_ELEMENT_SIZE 8
+#define TXB_ELEMENT_SIZE 72
+
+/* Message RAM Elements */
+#define M_CAN_FIFO_ID 0x0
+#define M_CAN_FIFO_DLC 0x4
+#define M_CAN_FIFO_DATA(n) (0x8 + ((n) << 2))
+
+/* Rx Buffer Element */
+/* R0 */
+#define RX_BUF_ESI BIT(31)
+#define RX_BUF_XTD BIT(30)
+#define RX_BUF_RTR BIT(29)
+/* R1 */
+#define RX_BUF_ANMF BIT(31)
+#define RX_BUF_FDF BIT(21)
+#define RX_BUF_BRS BIT(20)
+
+/* Tx Buffer Element */
+/* T0 */
+#define TX_BUF_ESI BIT(31)
+#define TX_BUF_XTD BIT(30)
+#define TX_BUF_RTR BIT(29)
+/* T1 */
+#define TX_BUF_EFC BIT(23)
+#define TX_BUF_FDF BIT(21)
+#define TX_BUF_BRS BIT(20)
+#define TX_BUF_MM_SHIFT 24
+#define TX_BUF_MM_MASK (0xff << TX_BUF_MM_SHIFT)
+
+/* Tx event FIFO Element */
+/* E1 */
+#define TX_EVENT_MM_SHIFT TX_BUF_MM_SHIFT
+#define TX_EVENT_MM_MASK (0xff << TX_EVENT_MM_SHIFT)
+
+/* address offset and element number for each FIFO/Buffer in the Message RAM */
+struct mram_cfg {
+ u16 off;
+ u8 num;
+};
+
+/* m_can private data structure */
+struct m_can_priv {
+ struct can_priv can; /* must be the first member */
+ struct napi_struct napi;
+ struct net_device *dev;
+ struct device *device;
+ struct clk *hclk;
+ struct clk *cclk;
+ void __iomem *base;
+ u32 irqstatus;
+ int version;
+
+ /* message ram configuration */
+ void __iomem *mram_base;
+ struct mram_cfg mcfg[MRAM_CFG_NUM];
+};
+
+static inline u32 m_can_read(const struct m_can_priv *priv, enum m_can_reg reg)
+{
+ return readl(priv->base + reg);
+}
+
+static inline void m_can_write(const struct m_can_priv *priv,
+ enum m_can_reg reg, u32 val)
+{
+ writel(val, priv->base + reg);
+}
+
+static inline u32 m_can_fifo_read(const struct m_can_priv *priv,
+ u32 fgi, unsigned int offset)
+{
+ return readl(priv->mram_base + priv->mcfg[MRAM_RXF0].off +
+ fgi * RXF0_ELEMENT_SIZE + offset);
+}
+
+static inline void m_can_fifo_write(const struct m_can_priv *priv,
+ u32 fpi, unsigned int offset, u32 val)
+{
+ writel(val, priv->mram_base + priv->mcfg[MRAM_TXB].off +
+ fpi * TXB_ELEMENT_SIZE + offset);
+}
+
+static inline u32 m_can_txe_fifo_read(const struct m_can_priv *priv,
+ u32 fgi,
+ u32 offset) {
+ return readl(priv->mram_base + priv->mcfg[MRAM_TXE].off +
+ fgi * TXE_ELEMENT_SIZE + offset);
+}
+
+static inline bool m_can_tx_fifo_full(const struct m_can_priv *priv)
+{
+ return !!(m_can_read(priv, M_CAN_TXFQS) & TXFQS_TFQF);
+}
+
+extern int register_m_can_dev(struct net_device *dev);
+extern void unregister_m_can_dev(struct net_device *dev);
+extern void m_can_config_endisable(const struct m_can_priv *priv, bool enable);
+extern void m_can_enable_all_interrupts(const struct m_can_priv *priv);
+extern void m_can_disable_all_interrupts(const struct m_can_priv *priv);
+extern struct net_device *alloc_m_can_dev(u32 tx_fifo_size);
+extern void free_m_can_dev(struct net_device *dev);
+extern int m_can_clk_start(struct m_can_priv *priv);
+extern void m_can_clk_stop(struct m_can_priv *priv);
+extern int m_can_dev_setup(struct device *dev, struct net_device *net,
+ void __iomem *addr);
+extern void m_can_start(struct net_device *dev);
+extern void m_can_stop(struct net_device *dev);
+extern void m_can_init_ram(struct m_can_priv *priv);
+
+#endif
diff --git a/drivers/net/can/m_can/m_can_platform.c b/drivers/net/can/m_can/m_can_platform.c
new file mode 100644
index 000000000000..f69f502c9265
--- /dev/null
+++ b/drivers/net/can/m_can/m_can_platform.c
@@ -0,0 +1,306 @@
+/*
+ * CAN bus driver for Bosch M_CAN controller
+ *
+ * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Dong Aisheng <b29396@freescale.com>
+ *
+ * Bosch M_CAN user manual can be obtained from:
+ * http://www.bosch-semiconductors.de/media/pdf_1/ipmodules_1/m_can/
+ * mcan_users_manual_v302.pdf
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/iopoll.h>
+#include <linux/can/dev.h>
+#include <linux/pinctrl/consumer.h>
+
+#include "m_can.h"
+
+static void m_can_of_parse_mram(struct m_can_priv *priv, const u32 *mram_config_vals)
+{
+ priv->mcfg[MRAM_SIDF].off = mram_config_vals[0];
+ priv->mcfg[MRAM_SIDF].num = mram_config_vals[1];
+ priv->mcfg[MRAM_XIDF].off = priv->mcfg[MRAM_SIDF].off +
+ priv->mcfg[MRAM_SIDF].num * SIDF_ELEMENT_SIZE;
+ priv->mcfg[MRAM_XIDF].num = mram_config_vals[2];
+ priv->mcfg[MRAM_RXF0].off = priv->mcfg[MRAM_XIDF].off +
+ priv->mcfg[MRAM_XIDF].num * XIDF_ELEMENT_SIZE;
+ priv->mcfg[MRAM_RXF0].num = mram_config_vals[3] &
+ (RXFC_FS_MASK >> RXFC_FS_SHIFT);
+ priv->mcfg[MRAM_RXF1].off = priv->mcfg[MRAM_RXF0].off +
+ priv->mcfg[MRAM_RXF0].num * RXF0_ELEMENT_SIZE;
+ priv->mcfg[MRAM_RXF1].num = mram_config_vals[4] &
+ (RXFC_FS_MASK >> RXFC_FS_SHIFT);
+ priv->mcfg[MRAM_RXB].off = priv->mcfg[MRAM_RXF1].off +
+ priv->mcfg[MRAM_RXF1].num * RXF1_ELEMENT_SIZE;
+ priv->mcfg[MRAM_RXB].num = mram_config_vals[5];
+ priv->mcfg[MRAM_TXE].off = priv->mcfg[MRAM_RXB].off +
+ priv->mcfg[MRAM_RXB].num * RXB_ELEMENT_SIZE;
+ priv->mcfg[MRAM_TXE].num = mram_config_vals[6];
+ priv->mcfg[MRAM_TXB].off = priv->mcfg[MRAM_TXE].off +
+ priv->mcfg[MRAM_TXE].num * TXE_ELEMENT_SIZE;
+ priv->mcfg[MRAM_TXB].num = mram_config_vals[7] &
+ (TXBC_NDTB_MASK >> TXBC_NDTB_SHIFT);
+
+ dev_dbg(priv->device,
+ "mram_base %p sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n",
+ priv->mram_base,
+ priv->mcfg[MRAM_SIDF].off, priv->mcfg[MRAM_SIDF].num,
+ priv->mcfg[MRAM_XIDF].off, priv->mcfg[MRAM_XIDF].num,
+ priv->mcfg[MRAM_RXF0].off, priv->mcfg[MRAM_RXF0].num,
+ priv->mcfg[MRAM_RXF1].off, priv->mcfg[MRAM_RXF1].num,
+ priv->mcfg[MRAM_RXB].off, priv->mcfg[MRAM_RXB].num,
+ priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
+ priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);
+
+ m_can_init_ram(priv);
+}
+
+static int m_can_plat_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct m_can_priv *priv;
+ struct resource *res;
+ void __iomem *addr;
+ void __iomem *mram_addr;
+ struct clk *hclk, *cclk;
+ int irq, ret;
+ struct device_node *np;
+ u32 mram_config_vals[MRAM_CFG_LEN];
+ u32 tx_fifo_size;
+
+ np = pdev->dev.of_node;
+
+ hclk = devm_clk_get(&pdev->dev, "hclk");
+ cclk = devm_clk_get(&pdev->dev, "cclk");
+
+ if (IS_ERR(hclk) || IS_ERR(cclk)) {
+ dev_err(&pdev->dev, "no clock found\n");
+ ret = -ENODEV;
+ goto failed_ret;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "m_can");
+ addr = devm_ioremap_resource(&pdev->dev, res);
+ irq = platform_get_irq_byname(pdev, "int0");
+
+ if (IS_ERR(addr) || irq < 0) {
+ ret = -EINVAL;
+ goto failed_ret;
+ }
+
+ /* message ram could be shared */
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram");
+ if (!res) {
+ ret = -ENODEV;
+ goto failed_ret;
+ }
+
+ mram_addr = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!mram_addr) {
+ ret = -ENOMEM;
+ goto failed_ret;
+ }
+
+ /* get message ram configuration */
+ ret = of_property_read_u32_array(np, "bosch,mram-cfg",
+ mram_config_vals,
+ sizeof(mram_config_vals) / 4);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not get Message RAM configuration.");
+ goto failed_ret;
+ }
+
+ /* Get TX FIFO size
+ * Defines the total amount of echo buffers for loopback
+ */
+ tx_fifo_size = mram_config_vals[7];
+
+ /* allocate the m_can device */
+ dev = alloc_m_can_dev(tx_fifo_size);
+ if (!dev) {
+ ret = -ENOMEM;
+ goto failed_ret;
+ }
+
+ priv = netdev_priv(dev);
+ dev->irq = irq;
+ priv->device = &pdev->dev;
+ priv->hclk = hclk;
+ priv->cclk = cclk;
+ priv->can.clock.freq = clk_get_rate(cclk);
+ priv->mram_base = mram_addr;
+
+ platform_set_drvdata(pdev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ /* Enable clocks. Necessary to read Core Release in order to determine
+ * M_CAN version
+ */
+ pm_runtime_enable(&pdev->dev);
+ ret = m_can_clk_start(priv);
+ if (ret)
+ goto pm_runtime_fail;
+
+ ret = m_can_dev_setup(&pdev->dev, dev, addr);
+ if (ret)
+ goto clk_disable;
+
+ ret = register_m_can_dev(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+ KBUILD_MODNAME, ret);
+ goto clk_disable;
+ }
+
+ m_can_of_parse_mram(priv, mram_config_vals);
+
+ devm_can_led_init(dev);
+
+ of_can_transceiver(dev);
+
+ dev_info(&pdev->dev, "%s device registered (irq=%d, version=%d)\n",
+ KBUILD_MODNAME, dev->irq, priv->version);
+
+ /* Probe finished
+ * Stop clocks. They will be reactivated once the M_CAN device is opened
+ */
+clk_disable:
+ m_can_clk_stop(priv);
+pm_runtime_fail:
+ if (ret) {
+ pm_runtime_disable(&pdev->dev);
+ free_m_can_dev(dev);
+ }
+failed_ret:
+ return ret;
+}
+
+static __maybe_unused int m_can_suspend(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct m_can_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ netif_stop_queue(ndev);
+ netif_device_detach(ndev);
+ m_can_stop(ndev);
+ m_can_clk_stop(priv);
+ }
+
+ pinctrl_pm_select_sleep_state(dev);
+
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ return 0;
+}
+
+static __maybe_unused int m_can_resume(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct m_can_priv *priv = netdev_priv(ndev);
+
+ pinctrl_pm_select_default_state(dev);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_running(ndev)) {
+ int ret;
+
+ ret = m_can_clk_start(priv);
+ if (ret)
+ return ret;
+
+ m_can_init_ram(priv);
+ m_can_start(ndev);
+ netif_device_attach(ndev);
+ netif_start_queue(ndev);
+ }
+
+ return 0;
+}
+
+static int m_can_plat_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+
+ unregister_m_can_dev(dev);
+
+ pm_runtime_disable(&pdev->dev);
+
+ platform_set_drvdata(pdev, NULL);
+
+ free_m_can_dev(dev);
+
+ return 0;
+}
+
+static int __maybe_unused m_can_runtime_suspend(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct m_can_priv *priv = netdev_priv(ndev);
+
+ clk_disable_unprepare(priv->cclk);
+ clk_disable_unprepare(priv->hclk);
+
+ return 0;
+}
+
+static int __maybe_unused m_can_runtime_resume(struct device *dev)
+{
+ struct net_device *ndev = dev_get_drvdata(dev);
+ struct m_can_priv *priv = netdev_priv(ndev);
+ int err;
+
+ err = clk_prepare_enable(priv->hclk);
+ if (err)
+ return err;
+
+ err = clk_prepare_enable(priv->cclk);
+ if (err)
+ clk_disable_unprepare(priv->hclk);
+
+ return err;
+}
+
+static const struct dev_pm_ops m_can_pmops = {
+ SET_RUNTIME_PM_OPS(m_can_runtime_suspend,
+ m_can_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(m_can_suspend, m_can_resume)
+};
+
+static const struct of_device_id m_can_of_table[] = {
+ { .compatible = "bosch,m_can", .data = NULL },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, m_can_of_table);
+
+static struct platform_driver m_can_plat_driver = {
+ .driver = {
+ .name = KBUILD_MODNAME,
+ .of_match_table = m_can_of_table,
+ .pm = &m_can_pmops,
+ },
+ .probe = m_can_plat_probe,
+ .remove = m_can_plat_remove,
+};
+
+module_platform_driver(m_can_plat_driver);
+
+MODULE_AUTHOR("Dong Aisheng <b29396@freescale.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CAN bus driver for Bosch M_CAN controller");
--
2.23.0
^ permalink raw reply related
* [PATCH 2/2] NET: m_can: add PCI glue driver
From: Felipe Balbi @ 2019-09-09 10:59 UTC (permalink / raw)
To: Wolfgang Grandegger, Marc Kleine-Budde; +Cc: netdev, davem, Felipe Balbi
In-Reply-To: <20190909105953.36504-1-felipe.balbi@linux.intel.com>
Some intel platforms support an MCAN controller attached to the PCI
bus. This minimal driver adds support for those.
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
drivers/net/can/m_can/Kconfig | 7 +
drivers/net/can/m_can/Makefile | 1 +
drivers/net/can/m_can/m_can_pci.c | 222 ++++++++++++++++++++++++++++++
3 files changed, 230 insertions(+)
create mode 100644 drivers/net/can/m_can/m_can_pci.c
diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig
index fba73338bc38..c7fbea72491c 100644
--- a/drivers/net/can/m_can/Kconfig
+++ b/drivers/net/can/m_can/Kconfig
@@ -13,4 +13,11 @@ config CAN_M_CAN_PLATFORM
Say Y here if you want to support Bosch M_CAN controller connected
to the platform bus.
+config CAN_M_CAN_PCI
+ tristate "Generic PCI Bus based M_CAN driver"
+ depends on PCI
+ ---help---
+ Say Y here if you want to support Bosch M_CAN controller connected
+ to the pci bus.
+
endif
diff --git a/drivers/net/can/m_can/Makefile b/drivers/net/can/m_can/Makefile
index ac568be3de98..104de5cb6d79 100644
--- a/drivers/net/can/m_can/Makefile
+++ b/drivers/net/can/m_can/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_CAN_M_CAN) += m_can.o
obj-$(CONFIG_CAN_M_CAN_PLATFORM) += m_can_platform.o
+obj-$(CONFIG_CAN_M_CAN_PCI) += m_can_pci.o
diff --git a/drivers/net/can/m_can/m_can_pci.c b/drivers/net/can/m_can/m_can_pci.c
new file mode 100644
index 000000000000..fc6dfc334d34
--- /dev/null
+++ b/drivers/net/can/m_can/m_can_pci.c
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * m_can_pci.c - PCI Specific M_CAN Glue
+ *
+ * Copyright (C) 2018 Intel Corporation - https://www.intel.com
+ * Author: Felipe Balbi <felipe.balbi@linux.intel.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/can/dev.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/pm_runtime.h>
+
+#include "m_can.h"
+
+#define PCI_DEVICE_ID_INTEL_EHL_1 0x4bc1
+#define PCI_DEVICE_ID_INTEL_EHL_2 0x4bc2
+
+#define M_CAN_PCI_MMIO_BAR 0
+#define M_CAN_MRAM_OFFSET 0x800
+
+#define M_CAN_CLOCK_FREQ_EHL 100000000
+
+static void m_can_init_mram_conf(struct m_can_priv *priv)
+{
+ priv->mcfg[MRAM_SIDF].off = 0;
+ priv->mcfg[MRAM_SIDF].num = 128;
+ priv->mcfg[MRAM_XIDF].off = priv->mcfg[MRAM_SIDF].off +
+ priv->mcfg[MRAM_SIDF].num * SIDF_ELEMENT_SIZE;
+ priv->mcfg[MRAM_XIDF].num = 64;
+ priv->mcfg[MRAM_RXF0].off = priv->mcfg[MRAM_XIDF].off +
+ priv->mcfg[MRAM_XIDF].num * XIDF_ELEMENT_SIZE;
+ priv->mcfg[MRAM_RXF0].num = 64 &
+ (RXFC_FS_MASK >> RXFC_FS_SHIFT);
+ priv->mcfg[MRAM_RXF1].off = priv->mcfg[MRAM_RXF0].off +
+ priv->mcfg[MRAM_RXF0].num * RXF0_ELEMENT_SIZE;
+ priv->mcfg[MRAM_RXF1].num = 0 &
+ (RXFC_FS_MASK >> RXFC_FS_SHIFT);
+ priv->mcfg[MRAM_RXB].off = priv->mcfg[MRAM_RXF1].off +
+ priv->mcfg[MRAM_RXF1].num * RXF1_ELEMENT_SIZE;
+ priv->mcfg[MRAM_RXB].num = 64;
+ priv->mcfg[MRAM_TXE].off = priv->mcfg[MRAM_RXB].off +
+ priv->mcfg[MRAM_RXB].num * RXB_ELEMENT_SIZE;
+ priv->mcfg[MRAM_TXE].num = 0;
+ priv->mcfg[MRAM_TXB].off = priv->mcfg[MRAM_TXE].off +
+ priv->mcfg[MRAM_TXE].num * TXE_ELEMENT_SIZE;
+ priv->mcfg[MRAM_TXB].num = 16 &
+ (TXBC_NDTB_MASK >> TXBC_NDTB_SHIFT);
+
+ dev_dbg(priv->device,
+ "mram_base %p sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n",
+ priv->mram_base,
+ priv->mcfg[MRAM_SIDF].off, priv->mcfg[MRAM_SIDF].num,
+ priv->mcfg[MRAM_XIDF].off, priv->mcfg[MRAM_XIDF].num,
+ priv->mcfg[MRAM_RXF0].off, priv->mcfg[MRAM_RXF0].num,
+ priv->mcfg[MRAM_RXF1].off, priv->mcfg[MRAM_RXF1].num,
+ priv->mcfg[MRAM_RXB].off, priv->mcfg[MRAM_RXB].num,
+ priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num,
+ priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num);
+
+ m_can_init_ram(priv);
+}
+
+static int m_can_pci_probe(struct pci_dev *pci,
+ const struct pci_device_id *id)
+{
+ struct m_can_priv *priv;
+ struct net_device *net;
+ struct device *dev;
+ void __iomem *base;
+ int ret;
+
+ ret = pcim_enable_device(pci);
+ if (ret)
+ return ret;
+
+ pci_set_master(pci);
+
+ ret = pcim_iomap_regions(pci, BIT(M_CAN_PCI_MMIO_BAR), pci_name(pci));
+ if (ret)
+ return ret;
+
+ dev = &pci->dev;
+
+ base = pcim_iomap_table(pci)[M_CAN_PCI_MMIO_BAR];
+
+ if (!base) {
+ dev_err(dev, "failed to map BARs\n");
+ return -ENOMEM;
+ }
+
+ net = alloc_m_can_dev(1);
+ if (!net)
+ return -ENOMEM;
+
+ ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_ALL_TYPES);
+ if (ret < 0)
+ return ret;
+
+ priv = netdev_priv(net);
+ net->irq = pci_irq_vector(pci, 0);
+ priv->device = dev;
+ priv->can.clock.freq = id->driver_data;
+ priv->mram_base = base + M_CAN_MRAM_OFFSET;
+
+ pci_set_drvdata(pci, net);
+ SET_NETDEV_DEV(net, dev);
+
+ ret = m_can_dev_setup(dev, net, base);
+ if (ret)
+ goto err;
+
+ ret = register_m_can_dev(net);
+ if (ret)
+ goto err;
+
+ m_can_init_mram_conf(priv);
+ devm_can_led_init(net);
+
+ pm_runtime_set_autosuspend_delay(dev, 1000);
+ pm_runtime_use_autosuspend(dev);
+ pm_runtime_put_noidle(dev);
+ pm_runtime_allow(dev);
+
+ return 0;
+
+err:
+ pm_runtime_disable(&pci->dev);
+ pci_free_irq_vectors(pci);
+ return ret;
+}
+
+static void m_can_pci_remove(struct pci_dev *pci)
+{
+ struct net_device *dev = pci_get_drvdata(pci);
+
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_get_noresume(&pci->dev);
+
+ pci_free_irq_vectors(pci);
+ unregister_m_can_dev(dev);
+ free_m_can_dev(dev);
+}
+
+static __maybe_unused int m_can_pci_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+ struct net_device *ndev = pci_get_drvdata(pdev);
+ struct m_can_priv *priv = netdev_priv(ndev);
+
+ if (netif_running(ndev)) {
+ netif_stop_queue(ndev);
+ netif_device_detach(ndev);
+ m_can_stop(ndev);
+ m_can_clk_stop(priv);
+ }
+
+ priv->can.state = CAN_STATE_SLEEPING;
+
+ return 0;
+}
+
+static __maybe_unused int m_can_pci_resume(struct device *dev)
+{
+ struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
+ struct net_device *ndev = pci_get_drvdata(pdev);
+ struct m_can_priv *priv = netdev_priv(ndev);
+
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_running(ndev)) {
+ int ret;
+
+ ret = m_can_clk_start(priv);
+ if (ret)
+ return ret;
+
+ m_can_init_ram(priv);
+ m_can_start(ndev);
+ netif_device_attach(ndev);
+ netif_start_queue(ndev);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops m_can_pci_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(m_can_pci_suspend, m_can_pci_resume)
+};
+
+static const struct pci_device_id m_can_pci_id_table[] = {
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_EHL_1),
+ M_CAN_CLOCK_FREQ_EHL, },
+
+ { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_EHL_2),
+ M_CAN_CLOCK_FREQ_EHL, },
+
+ { } /* Terminating Entry */
+};
+MODULE_DEVICE_TABLE(pci, m_can_pci_id_table);
+
+static struct pci_driver m_can_pci_driver = {
+ .name = "m_can_pci",
+ .probe = m_can_pci_probe,
+ .remove = m_can_pci_remove,
+ .id_table = m_can_pci_id_table,
+ .driver = {
+ .pm = &m_can_pci_pm_ops,
+ }
+};
+
+MODULE_AUTHOR("Felipe Balbi <felipe.balbi@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("CAN bus driver for Bosch M_CAN controller on PCI bus");
+
+module_pci_driver(m_can_pci_driver);
--
2.23.0
^ permalink raw reply related
* Re: [PATCH] ncsi-netlink: support sending NC-SI commands over Netlink interface
From: Brad Bishop @ 2019-09-09 10:46 UTC (permalink / raw)
To: Ben Wei
Cc: Terry Duncan, sam@mendozajonas.com, davem@davemloft.net,
netdev@vger.kernel.org, openbmc@lists.ozlabs.org,
Justin.Lee1@Dell.com
In-Reply-To: <CH2PR15MB3686CCC22840AD848796D6CAA3BD0@CH2PR15MB3686.namprd15.prod.outlook.com>
>> Do you have plans to upstream your yocto recipe for this repo?
>
> Yes I sure can upstream the recipe file. I had to make local changes to
> build ncsi-netlink for my BMC platform.
> Is there a group I may submit my recipe to?
Hi Ben
Can you try meta-openembedded? If they will not take it, I’m happy to host
a recipe for this in meta-phosphor.
In case you have not submitted a patch to meta-openembedded before... the
correct mailing list is openembedded-devel:
https://www.openembedded.org/wiki/How_to_submit_a_patch_to_OpenEmbedded
thx - brad
^ permalink raw reply
* RE: [RFC PATCH 3/3] Enable ptp_kvm for arm64
From: Jianyong Wu (Arm Technology China) @ 2019-09-09 10:17 UTC (permalink / raw)
To: Marc Zyngier
Cc: netdev@vger.kernel.org, pbonzini@redhat.com,
sean.j.christopherson@intel.com, richardcochran@gmail.com,
Mark Rutland, Will Deacon, Suzuki Poulose,
linux-kernel@vger.kernel.org, Steve Capper,
Kaly Xin (Arm Technology China), Justin He (Arm Technology China)
In-Reply-To: <86h85osbzz.wl-maz@kernel.org>
Hi Marc,
> -----Original Message-----
> From: Marc Zyngier <maz@kernel.org>
> Sent: Saturday, September 7, 2019 5:16 PM
> To: Jianyong Wu (Arm Technology China) <Jianyong.Wu@arm.com>
> Cc: netdev@vger.kernel.org; pbonzini@redhat.com;
> sean.j.christopherson@intel.com; richardcochran@gmail.com; Mark Rutland
> <Mark.Rutland@arm.com>; Will Deacon <Will.Deacon@arm.com>; Suzuki
> Poulose <Suzuki.Poulose@arm.com>; linux-kernel@vger.kernel.org; Steve
> Capper <Steve.Capper@arm.com>; Kaly Xin (Arm Technology China)
> <Kaly.Xin@arm.com>; Justin He (Arm Technology China)
> <Justin.He@arm.com>
> Subject: Re: [RFC PATCH 3/3] Enable ptp_kvm for arm64
>
> On Fri, 06 Sep 2019 12:58:15 +0100,
> "Jianyong Wu (Arm Technology China)" <Jianyong.Wu@arm.com> wrote:
> >
> > Hi Marc,
> >
> > Very sorry to have missed this comments.
> >
> > > -----Original Message-----
> > > From: Marc Zyngier <maz@kernel.org>
> > > Sent: Thursday, August 29, 2019 6:33 PM
> > > To: Jianyong Wu (Arm Technology China) <Jianyong.Wu@arm.com>;
> > > netdev@vger.kernel.org; pbonzini@redhat.com;
> > > sean.j.christopherson@intel.com; richardcochran@gmail.com; Mark
> > > Rutland <Mark.Rutland@arm.com>; Will Deacon
> <Will.Deacon@arm.com>;
> > > Suzuki Poulose <Suzuki.Poulose@arm.com>
> > > Cc: linux-kernel@vger.kernel.org; Steve Capper
> > > <Steve.Capper@arm.com>; Kaly Xin (Arm Technology China)
> > > <Kaly.Xin@arm.com>; Justin He (Arm Technology China)
> > > <Justin.He@arm.com>
> > > Subject: Re: [RFC PATCH 3/3] Enable ptp_kvm for arm64
> > >
> > > On 29/08/2019 07:39, Jianyong Wu wrote:
> > > > Currently in arm64 virtualization environment, there is no
> > > > mechanism to keep time sync between guest and host. Time in guest
> > > > will drift compared with host after boot up as they may both use
> > > > third party time sources to correct their time respectively. The
> > > > time deviation will be in order of milliseconds but some scenarios
> > > > ask for higher time precision, like in cloud envirenment, we want
> > > > all the VMs running in the host aquire the same level accuracy from
> host clock.
> > > >
> > > > Use of kvm ptp clock, which choose the host clock source clock as
> > > > a reference clock to sync time clock between guest and host has
> > > > been adopted by x86 which makes the time sync order from
> > > > milliseconds to
> > > nanoseconds.
> > > >
> > > > This patch enable kvm ptp on arm64 and we get the similar clock
> > > > drift as found with x86 with kvm ptp.
> > > >
> > > > Test result comparison between with kvm ptp and without it in
> > > > arm64 are as follows. This test derived from the result of command
> > > > 'chronyc sources'. we should take more cure of the last sample
> > > > column which shows the offset between the local clock and the
> > > > source at the last
> > > measurement.
> > > >
> > > > no kvm ptp in guest:
> > > > MS Name/IP address Stratum Poll Reach LastRx Last sample
> > > >
> > >
> ==========================================================
> > > ==============
> > > > ^* dns1.synet.edu.cn 2 6 377 13 +1040us[+1581us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 21 +1040us[+1581us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 29 +1040us[+1581us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 37 +1040us[+1581us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 45 +1040us[+1581us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 53 +1040us[+1581us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 61 +1040us[+1581us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 4 -130us[ +796us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 12 -130us[ +796us] +/- 21ms
> > > > ^* dns1.synet.edu.cn 2 6 377 20 -130us[ +796us] +/- 21ms
> > > >
> > > > in host:
> > > > MS Name/IP address Stratum Poll Reach LastRx Last sample
> > > >
> > >
> ==========================================================
> > > ==============
> > > > ^* 120.25.115.20 2 7 377 72 -470us[ -603us] +/- 18ms
> > > > ^* 120.25.115.20 2 7 377 92 -470us[ -603us] +/- 18ms
> > > > ^* 120.25.115.20 2 7 377 112 -470us[ -603us] +/- 18ms
> > > > ^* 120.25.115.20 2 7 377 2 +872ns[-6808ns] +/- 17ms
> > > > ^* 120.25.115.20 2 7 377 22 +872ns[-6808ns] +/- 17ms
> > > > ^* 120.25.115.20 2 7 377 43 +872ns[-6808ns] +/- 17ms
> > > > ^* 120.25.115.20 2 7 377 63 +872ns[-6808ns] +/- 17ms
> > > > ^* 120.25.115.20 2 7 377 83 +872ns[-6808ns] +/- 17ms
> > > > ^* 120.25.115.20 2 7 377 103 +872ns[-6808ns] +/- 17ms
> > > > ^* 120.25.115.20 2 7 377 123 +872ns[-6808ns] +/- 17ms
> > > >
> > > > The dns1.synet.edu.cn is the network reference clock for guest and
> > > > 120.25.115.20 is the network reference clock for host. we can't
> > > > get the clock error between guest and host directly, but a roughly
> > > > estimated value will be in order of hundreds of us to ms.
> > > >
> > > > with kvm ptp in guest:
> > > > chrony has been disabled in host to remove the disturb by network
> clock.
> > >
> > > Is that a realistic use case? Why should the host not use NTP?
> > >
> >
> > Not really, NTP will change the the host clock which will contaminate
> > the data of sync between Host and guest. But in reality, we will keep NTP
> online.
> >
> > > >
> > > > MS Name/IP address Stratum Poll Reach LastRx Last sample
> > > >
> > >
> ==========================================================
> > > ==============
> > > > * PHC0 0 3 377 8 -7ns[ +1ns] +/- 3ns
> > > > * PHC0 0 3 377 8 +1ns[ +16ns] +/- 3ns
> > > > * PHC0 0 3 377 6 -4ns[ -0ns] +/- 6ns
> > > > * PHC0 0 3 377 6 -8ns[ -12ns] +/- 5ns
> > > > * PHC0 0 3 377 5 +2ns[ +4ns] +/- 4ns
> > > > * PHC0 0 3 377 13 +2ns[ +4ns] +/- 4ns
> > > > * PHC0 0 3 377 12 -4ns[ -6ns] +/- 4ns
> > > > * PHC0 0 3 377 11 -8ns[ -11ns] +/- 6ns
> > > > * PHC0 0 3 377 10 -14ns[ -20ns] +/- 4ns
> > > > * PHC0 0 3 377 8 +4ns[ +5ns] +/- 4ns
> > > >
> > > > The PHC0 is the ptp clock which choose the host clock as its
> > > > source clock. So we can be sure to say that the clock error
> > > > between host and guest is in order of ns.
> > > >
> > > > Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
> > > > ---
> > > > arch/arm64/include/asm/arch_timer.h | 3 ++
> > > > arch/arm64/kvm/arch_ptp_kvm.c | 76
> > > ++++++++++++++++++++++++++++
> > > > drivers/clocksource/arm_arch_timer.c | 6 ++-
> > > > drivers/ptp/Kconfig | 2 +-
> > > > include/linux/arm-smccc.h | 14 +++++
> > > > virt/kvm/arm/psci.c | 17 +++++++
> > > > 6 files changed, 115 insertions(+), 3 deletions(-) create mode
> > > > 100644 arch/arm64/kvm/arch_ptp_kvm.c
> > >
> > > Please split this patch into two parts: the hypervisor code in a
> > > patch and the guest code in another patch. Having both of them together
> is confusing.
> > >
> > Ok, really better.
> >
> > > >
> > > > diff --git a/arch/arm64/include/asm/arch_timer.h
> > > > b/arch/arm64/include/asm/arch_timer.h
> > > > index 6756178c27db..880576a814b6 100644
> > > > --- a/arch/arm64/include/asm/arch_timer.h
> > > > +++ b/arch/arm64/include/asm/arch_timer.h
> > > > @@ -229,4 +229,7 @@ static inline int arch_timer_arch_init(void)
> > > > return 0;
> > > > }
> > > >
> > > > +extern struct clocksource clocksource_counter; extern u64
> > > > +arch_counter_read(struct clocksource *cs);
> > >
> > > I'm definitely not keen on exposing the internals of the arch_timer
> > > driver to random subsystems. Furthermore, you seem to expect that
> > > the guest kernel will only use the arch timer as a clocksource, and
> > > nothing really guarantees that (in which case
> get_device_system_crosststamp will fail).
> > >
> > The code here is really ugly, I need a better solution to offer a
> > clock source For the guest.
> >
> > > It looks to me that we'd be better off exposing a core timekeeping
> > > API that populates a struct system_counterval_t based on the
> > > *current* timekeeper monotonic clocksource. This would simplify the
> > > split between generic and arch-specific code.
> > >
> > I think it really necessary.
> >
> > > Whether or not tglx will be happy with the idea is another problem,
> > > but I'm certainly not taking any change to the arch timer code based on
> this.
> > >
> > I can have a try, but the detail is not clear for me now.
>
> Something along those lines:
>
> From 5f1c061e55c691d64012bc7c1490a1a8c4432c67 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <maz@kernel.org>
> Date: Sat, 7 Sep 2019 10:11:49 +0100
> Subject: [PATCH] timekeeping: Expose API allowing retrival of current
> clocksource and counter value
>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
> include/linux/timekeeping.h | 5 +++++
> kernel/time/timekeeping.c | 12 ++++++++++++
> 2 files changed, 17 insertions(+)
>
> diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h index
> b27e2ffa96c1..6df26a913711 100644
> --- a/include/linux/timekeeping.h
> +++ b/include/linux/timekeeping.h
> @@ -275,6 +275,11 @@ extern int get_device_system_crosststamp(
> struct system_time_snapshot *history,
> struct system_device_crosststamp *xtstamp);
>
> +/*
> + * Obtain current monotonic clock and its counter value */ extern void
> +get_current_counterval(struct system_counterval_t *sc);
> +
> /*
> * Simultaneously snapshot realtime and monotonic raw clocks
> */
> diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index
> d911c8470149..de689bbd3808 100644
> --- a/kernel/time/timekeeping.c
> +++ b/kernel/time/timekeeping.c
> @@ -1098,6 +1098,18 @@ static bool cycle_between(u64 before, u64 test,
> u64 after)
> return false;
> }
>
> +/**
> + * get_current_counterval - Snapshot the current clocksource and counter
> value
> + * @sc: Pointer to a struct containing the current clocksource and its
> value
> + */
> +void get_current_counterval(struct system_counterval_t *sc) {
> + struct timekeeper *tk = &tk_core.timekeeper;
> +
> + sc->cs = READ_ONCE(tk->tkr_mono.clock);
> + sc->cycles = sc->cs->read(sc->cs);
> +}
> +
> /**
> * get_device_system_crosststamp - Synchronously capture system/device
> timestamp
> * @get_time_fn: Callback to get simultaneous device time and
>
> which should do the right thing.
>
It is a good news for me. These code is indeed what I need!
So what's your plan about this patch? Is there any problem with you if I include these code
into my patch ?
> >
> > > > +
> > > > #endif
> > > > diff --git a/arch/arm64/kvm/arch_ptp_kvm.c
> > > > b/arch/arm64/kvm/arch_ptp_kvm.c
> > >
> > > We don't put non-hypervisor in arch/arm64/kvm. Please move it back
> > > to drivers/ptp (as well as its x86 counterpart), and just link the two parts
> there.
> > > This should also allow this to be enabled for 32bit guests.
> > >
> > Err, sorry, what's mean of "link the two parts there"? should I add
> > another two file update driver/ptp/ Both for arm64 and x86 to contains
> > these arch-specific code or pack them all into ptp_kvm.c?
>
> What I'm suggesting is that you have 3 files:
>
> drivers/ptp/ptp_kvm.c
> drivers/ptp/ptp_kvm_x86.c
> drivers/ptp/ptp_kvm_arm.c
>
> and let the Makefile combine them.
>
> [...]
>
it is what I want to do at the beginning of drafting these patches.
> > > Other questions: how does this works with VM migration? Specially
> > > when moving from a hypervisor that supports the feature to one that
> doesn't?
> > >
> > I think it won't solve the problem generated by VM migration and only
> > for VMs in a single machine. Ptp_kvm only works for VMs in the same
> > machine. But using ptp (not ptp_kvm) clock, all the machines in a low
> > latency network environment can keep time sync in high precision, Then
> > VMs move from one machine to another will obtain a high precision time
> > sync.
>
> That's a problem. Migration must be possible from one host to another, even
> if that means temporarily loosing some (or a lot of) precision. The service
> must be discoverable from userspace on the host so that the MVV can decie
> whether a migration is possible or not.
>
Don't worry, things will be not that bad.
ptp_kvm will not trouble the VM migration. This ptp_kvm is one clocksource of the clock pool for
chrony. Chrony will choose the highest precision clock from the pool. If host does not support
ptp_kvm, the ptp_kvm will not be chosen as the clocksouce of chrony.
We have roughly the same logic of implementation of ptp_kvm with x86, and ptp_kvm works well in x86.
so I think that will be the case for arm64.
Maybe I miss your point, I have no idea of MVV and can't get related info from google.
Also I'm not clear of your last words of how to decide VM migration is possible?
Thanks
Jianyong Wu
> Thanks,
>
> M.
>
> --
> Jazz is not dead, it just smells funny.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.
^ permalink raw reply
* Re: [PATCH v2 0/4] Deterministic SPI latency with NXP DSPI driver
From: Mark Brown @ 2019-09-09 10:06 UTC (permalink / raw)
To: Vladimir Oltean
Cc: h.feurstein, mlichvar, richardcochran, andrew, f.fainelli,
linux-spi, netdev
In-Reply-To: <20190905010114.26718-1-olteanv@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 773 bytes --]
On Thu, Sep 05, 2019 at 04:01:10AM +0300, Vladimir Oltean wrote:
> This patchset proposes an interface from the SPI subsystem for
> software timestamping SPI transfers. There is a default implementation
> provided in the core, as well as a mechanism for SPI slave drivers to
> check which byte was in fact timestamped post-facto. The patchset also
> adds the first user of this interface (the NXP DSPI driver in TCFQ mode).
I think this is about as good as we're going to get but we're
very near the merge window now so I'll leave this until after the
merge window is done in case there's more review comments before
applying. I need to reread the implementation code a bit as
well, it looked fine on a first scan through but it's possible I
might spot something later.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: net/dst_cache.c: preemption bug in net/dst_cache.c
From: Xin Long @ 2019-09-09 9:48 UTC (permalink / raw)
To: Bharath Vedartham
Cc: davem, Greg Kroah-Hartman, allison, tglx, network dev, LKML,
Jon Maloy
In-Reply-To: <20190822195132.GA2100@bharath12345-Inspiron-5559>
On Fri, Aug 23, 2019 at 3:58 PM Bharath Vedartham <linux.bhar@gmail.com> wrote:
>
> Hi all,
>
> I just want to bring attention to the syzbot bug [1]
>
> Even though syzbot claims the bug to be in net/tipc, I feel it is in
> net/dst_cache.c. Please correct me if I am wrong.
>
> This bug is being triggered a lot of times by syzbot since the day it
> was reported. Also given that this is core networking code, I felt it
> was important to bring this to attention.
>
> It looks like preemption needs to be disabled before using this_cpu_ptr
> or maybe we would be better of using a get_cpu_var and put_cpu_var combo
> here.
b->media->send_msg (tipc_udp_send_msg)
-> tipc_udp_xmit() -> dst_cache_get()
send_msg() is always called under the protection of rcu_read_lock(), which
already disabled preemption. If not, there must be some unbalanced calls of
disable/enable preemption elsewhere.
Agree that this could be a serious issue, do you have any reproducer for this?
Thanks.
>
> [1] https://syzkaller.appspot.com/bug?id=dc6352b92862eb79373fe03fdf9af5928753e057
>
> Thank you
> Bharath
^ permalink raw reply
* Re: WARNING in hso_free_net_device
From: Oliver Neukum @ 2019-09-09 9:47 UTC (permalink / raw)
To: Hui Peng, Andrey Konovalov
Cc: David S. Miller, syzkaller-bugs, alexios.zavras, Thomas Gleixner,
Greg Kroah-Hartman, Mathias Payer, Stephen Hemminger, rfontana,
syzbot+44d53c7255bb1aea22d2, LKML, USB list, netdev
In-Reply-To: <02ef64cc-5053-e6da-fc59-9970f48064c5@gmail.com>
Am Donnerstag, den 05.09.2019, 22:05 -0400 schrieb Hui Peng:
>
> On 9/5/2019 7:24 AM, Andrey Konovalov wrote:
> > On Thu, Sep 5, 2019 at 4:20 AM Hui Peng <benquike@gmail.com> wrote:
> > >
> > > Can you guys have a look at the attached patch?
> >
> > Let's try it:
> >
> > #syz test: https://github.com/google/kasan.git eea39f24
> >
> > FYI: there are two more reports coming from this driver, which might
> > (or might not) have the same root cause. One of them has a suggested
> > fix by Oliver.
> >
> > https://syzkaller.appspot.com/bug?extid=67b2bd0e34f952d0321e
> > https://syzkaller.appspot.com/bug?extid=93f2f45b19519b289613
> >
>
> I think they are different, though similar.
> This one is resulted from unregistering a network device.
> These 2 are resulted from unregistering a tty device.
Hi,
looks like it. That may indeed be the issue.
Please try to have syzbot test your patch and we will
know more.
Regards
Oliver
^ permalink raw reply
* Re: VRF Issue Since kernel 5
From: Alexis Bauvin @ 2019-09-09 9:28 UTC (permalink / raw)
To: Gowen; +Cc: netdev@vger.kernel.org
In-Reply-To: <CWLP265MB1554308A1373D9ECE68CB854FDB70@CWLP265MB1554.GBRP265.PROD.OUTLOOK.COM>
Hi,
There has been some changes regarding VRF isolation in Linux 5 IIRC, namely proper
isolation of the default VRF.
Some things you may try:
- looking at the l3mdev_accept sysctls (e.g. `net.ipv4.tcp_l3mdev_accept`)
- querying stuff from the management vrf through `ip vrf exec vrf-mgmt <stuff>`
e.g. `ip vrf exec vrf-mgmt curl kernel.org`
`ip vrf exec vrf-mgmt dig @1.1.1.1 kernel.org`
- reversing your logic: default VRF is your management one, the other one is for your
other boxes
Also, your `unreachable default metric 4278198272` route looks odd to me.
What are your routing rules? (`ip rule`)
Alexis
> Le 9 sept. 2019 à 09:46, Gowen <gowen@potatocomputing.co.uk> a écrit :
>
> Hi there,
>
> Dave A said this was the mailer to send this to:
>
>
> I’ve been using my management interface in a VRF for several months now and it’s worked perfectly – I’ve been able to update/upgrade the packages just fine and iptables works excellently with it – exactly as I needed.
>
>
> Since Kernel 5 though I am no longer able to update – but the issue is quite a curious one as some traffic appears to be fine (DNS lookups use VRF correctly) but others don’t (updating/upgrading the packages)
>
>
> I have on this device 2 interfaces:
> Eth0 for management – inbound SSH, DNS, updates/upgrades
> Eth1 for managing other boxes (ansible using SSH)
>
>
> Link and addr info shown below:
>
>
> Admin@NETM06:~$ ip link show
> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
> link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master mgmt-vrf state UP mode DEFAULT group default qlen 1000
> link/ether 00:22:48:07:cc:ad brd ff:ff:ff:ff:ff:ff
> 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
> link/ether 00:22:48:07:c9:6c brd ff:ff:ff:ff:ff:ff
> 4: mgmt-vrf: <NOARP,MASTER,UP,LOWER_UP> mtu 65536 qdisc noqueue state UP mode DEFAULT group default qlen 1000
> link/ether 8a:f6:26:65:02:5a brd ff:ff:ff:ff:ff:ff
>
>
> Admin@NETM06:~$ ip addr
> 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
> link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
> inet 127.0.0.1/8 scope host lo
> valid_lft forever preferred_lft forever
> inet6 ::1/128 scope host
> valid_lft forever preferred_lft forever
> 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master mgmt-vrf state UP group default qlen 1000
> link/ether 00:22:48:07:cc:ad brd ff:ff:ff:ff:ff:ff
> inet 10.24.12.10/24 brd 10.24.12.255 scope global eth0
> valid_lft forever preferred_lft forever
> inet6 fe80::222:48ff:fe07:ccad/64 scope link
> valid_lft forever preferred_lft forever
> 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
> link/ether 00:22:48:07:c9:6c brd ff:ff:ff:ff:ff:ff
> inet 10.24.12.9/24 brd 10.24.12.255 scope global eth1
> valid_lft forever preferred_lft forever
> inet6 fe80::222:48ff:fe07:c96c/64 scope link
> valid_lft forever preferred_lft forever
> 4: mgmt-vrf: <NOARP,MASTER,UP,LOWER_UP> mtu 65536 qdisc noqueue state UP group default qlen 1000
> link/ether 8a:f6:26:65:02:5a brd ff:ff:ff:ff:ff:ff
>
>
>
> the production traffic is all in the 10.0.0.0/8 network (eth1 global VRF) except for a few subnets (DNS) which are routed out eth0 (mgmt-vrf)
>
>
> Admin@NETM06:~$ ip route show
> default via 10.24.12.1 dev eth0
> 10.0.0.0/8 via 10.24.12.1 dev eth1
> 10.24.12.0/24 dev eth1 proto kernel scope link src 10.24.12.9
> 10.24.65.0/24 via 10.24.12.1 dev eth0
> 10.25.65.0/24 via 10.24.12.1 dev eth0
> 10.26.0.0/21 via 10.24.12.1 dev eth0
> 10.26.64.0/21 via 10.24.12.1 dev eth0
>
>
> Admin@NETM06:~$ ip route show vrf mgmt-vrf
> default via 10.24.12.1 dev eth0
> unreachable default metric 4278198272
> 10.24.12.0/24 dev eth0 proto kernel scope link src 10.24.12.10
> 10.24.65.0/24 via 10.24.12.1 dev eth0
> 10.25.65.0/24 via 10.24.12.1 dev eth0
> 10.26.0.0/21 via 10.24.12.1 dev eth0
> 10.26.64.0/21 via 10.24.12.1 dev eth0
>
>
>
> The strange activity occurs when I enter the command “sudo apt update” as I can resolve the DNS request (10.24.65.203 or 10.24.64.203, verified with tcpdump) out eth0 but for the actual update traffic there is no activity:
>
>
> sudo tcpdump -i eth0 '(host 10.24.65.203 or host 10.25.65.203) and port 53' -n
> <OUTPUT OMITTED FOR BREVITY>
> 10:06:05.268735 IP 10.24.12.10.39963 > 10.24.65.203.53: 48798+ [1au] A? security.ubuntu.com. (48)
> <OUTPUT OMITTED FOR BREVITY>
> 10:06:05.284403 IP 10.24.65.203.53 > 10.24.12.10.39963: 48798 13/0/1 A 91.189.91.23, A 91.189.88.24, A 91.189.91.26, A 91.189.88.162, A 91.189.88.149, A 91.189.91.24, A 91.189.88.173, A 91.189.88.177, A 91.189.88.31, A 91.189.91.14, A 91.189.88.176, A 91.189.88.175, A 91.189.88.174 (256)
>
>
>
> You can see that the update traffic is returned but is not accepted by the stack and a RST is sent
>
>
> Admin@NETM06:~$ sudo tcpdump -i eth0 '(not host 168.63.129.16 and port 80)' -n
> tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
> listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
> 10:17:12.690658 IP 10.24.12.10.40216 > 91.189.88.175.80: Flags [S], seq 2279624826, win 64240, options [mss 1460,sackOK,TS val 2029365856 ecr 0,nop,wscale 7], length 0
> 10:17:12.691929 IP 10.24.12.10.52362 > 91.189.95.83.80: Flags [S], seq 1465797256, win 64240, options [mss 1460,sackOK,TS val 3833463674 ecr 0,nop,wscale 7], length 0
> 10:17:12.696270 IP 91.189.88.175.80 > 10.24.12.10.40216: Flags [S.], seq 968450722, ack 2279624827, win 28960, options [mss 1418,sackOK,TS val 81957103 ecr 2029365856,nop,wscale 7], length 0
> 10:17:12.696301 IP 10.24.12.10.40216 > 91.189.88.175.80: Flags [R], seq 2279624827, win 0, length 0
> 10:17:12.697884 IP 91.189.95.83.80 > 10.24.12.10.52362: Flags [S.], seq 4148330738, ack 1465797257, win 28960, options [mss 1418,sackOK,TS val 2257624414 ecr 3833463674,nop,wscale 8], length 0
> 10:17:12.697909 IP 10.24.12.10.52362 > 91.189.95.83.80: Flags [R], seq 1465797257, win 0, length 0
>
>
>
>
> I can emulate the DNS lookup using netcat in the vrf:
>
>
> sudo ip vrf exec mgmt-vrf nc -u 10.24.65.203 53
>
>
> then interactively enter the binary for a www.google.co.uk request:
>
>
> 0035624be394010000010000000000010377777706676f6f676c6502636f02756b00000100010000290200000000000000
>
>
> This returns as expected:
>
>
> 00624be394010000010000000000010377777706676f6f676c6502636f02756b00000100010000290200000000000000
>
>
> I can run:
>
>
> Admin@NETM06:~$ host www.google.co.uk
> www.google.co.uk has address 172.217.169.3
> www.google.co.uk has IPv6 address 2a00:1450:4009:80d::2003
>
>
> but I get a timeout for:
>
>
> sudo ip vrf exec mgmt-vrf host www.google.co.uk
> ;; connection timed out; no servers could be reached
>
>
>
> However I can take a repo address and vrf exec to it on port 80:
>
>
> Admin@NETM06:~$ sudo ip vrf exec mgmt-vrf nc 91.189.91.23 80
> hello
> HTTP/1.1 400 Bad Request
> <OUTPUT OMITTED>
>
> My iptables rule:
>
>
> sudo iptables -Z
> Admin@NETM06:~$ sudo iptables -L -v
> Chain INPUT (policy DROP 16 packets, 3592 bytes)
> pkts bytes target prot opt in out source destination
> 44 2360 ACCEPT tcp -- any any anywhere anywhere tcp spt:http ctstate RELATED,ESTABLISHED
> 83 10243 ACCEPT udp -- any any anywhere anywhere udp spt:domain ctstate RELATED,ESTABLISHED
>
>
>
> I cannot find out why the update isn’t working. Any help greatly appreciated
>
>
> Kind Regards,
>
>
> Gareth
^ permalink raw reply
* Re: [PATCH] net: stmmac: socfpga: re-use the `interface` parameter from platform data
From: Ardelean, Alexandru @ 2019-09-09 8:53 UTC (permalink / raw)
To: lkp@intel.com
Cc: davem@davemloft.net, linux-stm32@st-md-mailman.stormreply.com,
joabreu@synopsys.com, linux-kernel@vger.kernel.org,
kbuild-all@01.org, netdev@vger.kernel.org,
alexandre.torgue@st.com, peppe.cavallaro@st.com,
linux-arm-kernel@lists.infradead.org, mcoquelin.stm32@gmail.com
In-Reply-To: <201909072036.v1rX0Vwh%lkp@intel.com>
On Sat, 2019-09-07 at 20:54 +0800, kbuild test robot wrote:
> [External]
>
> Hi Alexandru,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on linus/master]
Hmm, this error should be expectable I guess: I applied this on net-next/master.
Alex
> [cannot apply to v5.3-rc7 next-20190904]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Alexandru-Ardelean/net-stmmac-socfpga-re-use-the-interface-parameter-from-platform-data/20190907-190627
> config: sparc64-allmodconfig (attached as .config)
> compiler: sparc64-linux-gcc (GCC) 7.4.0
> reproduce:
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # save the attached .config to linux build tree
> GCC_VERSION=7.4.0 make.cross ARCH=sparc64
>
> If you fix the issue, kindly add following tag
> Reported-by: kbuild test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
> In file included from include/linux/dma-mapping.h:7:0,
> from include/linux/skbuff.h:30,
> from include/linux/if_ether.h:19,
> from include/uapi/linux/ethtool.h:19,
> from include/linux/ethtool.h:18,
> from include/linux/phy.h:16,
> from drivers/net//ethernet/stmicro/stmmac/dwmac-socfpga.c:11:
> drivers/net//ethernet/stmicro/stmmac/dwmac-socfpga.c: In function 'socfpga_gen5_set_phy_mode':
> > > drivers/net//ethernet/stmicro/stmmac/dwmac-socfpga.c:264:44: error: 'phymode' undeclared (first use in this
> > > function); did you mean 'phy_modes'?
> dev_err(dwmac->dev, "bad phy mode %d\n", phymode);
> ^
> include/linux/device.h:1499:32: note: in definition of macro 'dev_err'
> _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__)
> ^~~~~~~~~~~
> drivers/net//ethernet/stmicro/stmmac/dwmac-socfpga.c:264:44: note: each undeclared identifier is reported only once
> for each function it appears in
> dev_err(dwmac->dev, "bad phy mode %d\n", phymode);
> ^
> include/linux/device.h:1499:32: note: in definition of macro 'dev_err'
> _dev_err(dev, dev_fmt(fmt), ##__VA_ARGS__)
> ^~~~~~~~~~~
> drivers/net//ethernet/stmicro/stmmac/dwmac-socfpga.c: In function 'socfpga_gen10_set_phy_mode':
> drivers/net//ethernet/stmicro/stmmac/dwmac-socfpga.c:340:6: error: 'phymode' undeclared (first use in this
> function); did you mean 'phy_modes'?
> phymode == PHY_INTERFACE_MODE_MII ||
> ^~~~~~~
> phy_modes
>
> vim +264 drivers/net//ethernet/stmicro/stmmac/dwmac-socfpga.c
>
> 40ae25505fe834 Dinh Nguyen 2019-06-05 255
> 40ae25505fe834 Dinh Nguyen 2019-06-05 256 static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
> 40ae25505fe834 Dinh Nguyen 2019-06-05 257 {
> 40ae25505fe834 Dinh Nguyen 2019-06-05 258 struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
> 40ae25505fe834 Dinh Nguyen 2019-06-05 259 u32 reg_offset = dwmac->reg_offset;
> 40ae25505fe834 Dinh Nguyen 2019-06-05 260 u32 reg_shift = dwmac->reg_shift;
> 40ae25505fe834 Dinh Nguyen 2019-06-05 261 u32 ctrl, val, module;
> 40ae25505fe834 Dinh Nguyen 2019-06-05 262
> 6169afbe4a340b Alexandru Ardelean 2019-09-06 263 if (socfpga_set_phy_mode_common(dwmac, &val)) {
> 801d233b7302ee Dinh Nguyen 2014-03-26 @264 dev_err(dwmac->dev, "bad phy mode %d\n", phymode);
> 801d233b7302ee Dinh Nguyen 2014-03-26 265 return -EINVAL;
> 801d233b7302ee Dinh Nguyen 2014-03-26 266 }
> 801d233b7302ee Dinh Nguyen 2014-03-26 267
> b4834c86e11baf Ley Foon Tan 2014-08-20 268 /* Overwrite val to GMII if splitter core is enabled. The
> phymode here
> b4834c86e11baf Ley Foon Tan 2014-08-20 269 * is the actual phy mode on phy hardware, but phy interface
> from
> b4834c86e11baf Ley Foon Tan 2014-08-20 270 * EMAC core is GMII.
> b4834c86e11baf Ley Foon Tan 2014-08-20 271 */
> b4834c86e11baf Ley Foon Tan 2014-08-20 272 if (dwmac->splitter_base)
> b4834c86e11baf Ley Foon Tan 2014-08-20 273 val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
> b4834c86e11baf Ley Foon Tan 2014-08-20 274
> 70cb136f773083 Joachim Eastwood 2016-05-01 275 /* Assert reset to the enet controller before changing the phy
> mode */
> bc8a2d9bcbf1ca Dinh Nguyen 2018-06-19 276 reset_control_assert(dwmac->stmmac_ocp_rst);
> 70cb136f773083 Joachim Eastwood 2016-05-01 277 reset_control_assert(dwmac->stmmac_rst);
> 70cb136f773083 Joachim Eastwood 2016-05-01 278
> 801d233b7302ee Dinh Nguyen 2014-03-26 279 regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
> 801d233b7302ee Dinh Nguyen 2014-03-26 280 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
> 801d233b7302ee Dinh Nguyen 2014-03-26 281 ctrl |= val << reg_shift;
> 801d233b7302ee Dinh Nguyen 2014-03-26 282
> 013dae5dbc07aa Stephan Gatzka 2017-08-22 283 if (dwmac->f2h_ptp_ref_clk ||
> 013dae5dbc07aa Stephan Gatzka 2017-08-22 284 phymode == PHY_INTERFACE_MODE_MII ||
> 013dae5dbc07aa Stephan Gatzka 2017-08-22 285 phymode == PHY_INTERFACE_MODE_GMII ||
> 013dae5dbc07aa Stephan Gatzka 2017-08-22 286 phymode == PHY_INTERFACE_MODE_SGMII) {
> 43569814fa35b2 Phil Reid 2015-12-14 287 ctrl |= SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK <<
> (reg_shift / 2);
> 734e00fa02eff5 Phil Reid 2016-04-07 288 regmap_read(sys_mgr_base_addr,
> SYSMGR_FPGAGRP_MODULE_REG,
> 734e00fa02eff5 Phil Reid 2016-04-07 289 &module);
> 734e00fa02eff5 Phil Reid 2016-04-07 290 module |= (SYSMGR_FPGAGRP_MODULE_EMAC << (reg_shift /
> 2));
> 734e00fa02eff5 Phil Reid 2016-04-07 291 regmap_write(sys_mgr_base_addr,
> SYSMGR_FPGAGRP_MODULE_REG,
> 734e00fa02eff5 Phil Reid 2016-04-07 292 module);
> 734e00fa02eff5 Phil Reid 2016-04-07 293 } else {
> 43569814fa35b2 Phil Reid 2015-12-14 294 ctrl &= ~(SYSMGR_EMACGRP_CTRL_PTP_REF_CLK_MASK <<
> (reg_shift / 2));
> 734e00fa02eff5 Phil Reid 2016-04-07 295 }
> 43569814fa35b2 Phil Reid 2015-12-14 296
> 801d233b7302ee Dinh Nguyen 2014-03-26 297 regmap_write(sys_mgr_base_addr, reg_offset, ctrl);
> 734e00fa02eff5 Phil Reid 2016-04-07 298
> 70cb136f773083 Joachim Eastwood 2016-05-01 299 /* Deassert reset for the phy configuration to be sampled by
> 70cb136f773083 Joachim Eastwood 2016-05-01 300 * the enet controller, and operation to start in requested mode
> 70cb136f773083 Joachim Eastwood 2016-05-01 301 */
> bc8a2d9bcbf1ca Dinh Nguyen 2018-06-19 302 reset_control_deassert(dwmac->stmmac_ocp_rst);
> 70cb136f773083 Joachim Eastwood 2016-05-01 303 reset_control_deassert(dwmac->stmmac_rst);
> fb3bbdb859891e Tien Hock Loh 2016-07-07 304 if (phymode == PHY_INTERFACE_MODE_SGMII) {
> fb3bbdb859891e Tien Hock Loh 2016-07-07 305 if (tse_pcs_init(dwmac->pcs.tse_pcs_base, &dwmac->pcs)
> != 0) {
> fb3bbdb859891e Tien Hock Loh 2016-07-07 306 dev_err(dwmac->dev, "Unable to initialize TSE
> PCS");
> fb3bbdb859891e Tien Hock Loh 2016-07-07 307 return -EINVAL;
> fb3bbdb859891e Tien Hock Loh 2016-07-07 308 }
> fb3bbdb859891e Tien Hock Loh 2016-07-07 309 }
> 70cb136f773083 Joachim Eastwood 2016-05-01 310
> 801d233b7302ee Dinh Nguyen 2014-03-26 311 return 0;
> 801d233b7302ee Dinh Nguyen 2014-03-26 312 }
> 801d233b7302ee Dinh Nguyen 2014-03-26 313
>
> :::::: The code at line 264 was first introduced by commit
> :::::: 801d233b7302eeab94750427a623c10c044cb0ca net: stmmac: Add SOCFPGA glue driver
>
> :::::: TO: Dinh Nguyen <dinguyen@altera.com>
> :::::: CC: David S. Miller <davem@davemloft.net>
>
> ---
> 0-DAY kernel test infrastructure Open Source Technology Center
> https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply
* [PATCHv2 ipsec-next] xfrm: remove the unnecessary .net_exit for xfrmi
From: Xin Long @ 2019-09-09 8:30 UTC (permalink / raw)
To: network dev; +Cc: davem, steffen.klassert
The xfrm_if(s) on each netns can be deleted when its xfrmi dev is
deleted. xfrmi dev's removal can happen when:
a. netns is being removed and all xfrmi devs will be deleted.
b. rtnl_link_unregister(&xfrmi_link_ops) in xfrmi_fini() when
xfrm_interface.ko is being unloaded.
So there's no need to use xfrmi_exit_net() to clean any xfrm_if up.
v1->v2:
- Fix some changelog.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/xfrm/xfrm_interface.c | 23 -----------------------
1 file changed, 23 deletions(-)
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c
index 74868f9..faa0518 100644
--- a/net/xfrm/xfrm_interface.c
+++ b/net/xfrm/xfrm_interface.c
@@ -738,30 +738,7 @@ static struct rtnl_link_ops xfrmi_link_ops __read_mostly = {
.get_link_net = xfrmi_get_link_net,
};
-static void __net_exit xfrmi_destroy_interfaces(struct xfrmi_net *xfrmn)
-{
- struct xfrm_if *xi;
- LIST_HEAD(list);
-
- xi = rtnl_dereference(xfrmn->xfrmi[0]);
- if (!xi)
- return;
-
- unregister_netdevice_queue(xi->dev, &list);
- unregister_netdevice_many(&list);
-}
-
-static void __net_exit xfrmi_exit_net(struct net *net)
-{
- struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id);
-
- rtnl_lock();
- xfrmi_destroy_interfaces(xfrmn);
- rtnl_unlock();
-}
-
static struct pernet_operations xfrmi_net_ops = {
- .exit = xfrmi_exit_net,
.id = &xfrmi_net_id,
.size = sizeof(struct xfrmi_net),
};
--
2.1.0
^ permalink raw reply related
* [PATCH v3 1/2] PTP: introduce new versions of IOCTLs
From: Felipe Balbi @ 2019-09-09 7:59 UTC (permalink / raw)
To: Richard Cochran; +Cc: Christopher S Hall, netdev, linux-kernel, Felipe Balbi
The current version of the IOCTL have a small problem which prevents us
from extending the API by making use of reserved fields. In these new
IOCTLs, we are now making sure that flags and rsv fields are zero which
will allow us to extend the API in the future.
Reviewed-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
Changes since v2:
- Define PTP_{PEROUT,EXTTS}_VALID_FLAGS
- Fix comment above PTP_*_FLAGS
-
Changes since v1:
- Add a blank line after memset()
- Move memset(req) to the three places where it's needed
- Fix the accidental removal of GETFUNC and SETFUNC
drivers/ptp/ptp_chardev.c | 63 ++++++++++++++++++++++++++++++++++
include/uapi/linux/ptp_clock.h | 24 ++++++++++++-
2 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index 18ffe449efdf..9c18476d8d10 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -126,7 +126,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
switch (cmd) {
case PTP_CLOCK_GETCAPS:
+ case PTP_CLOCK_GETCAPS2:
memset(&caps, 0, sizeof(caps));
+
caps.max_adj = ptp->info->max_adj;
caps.n_alarm = ptp->info->n_alarm;
caps.n_ext_ts = ptp->info->n_ext_ts;
@@ -139,11 +141,24 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;
case PTP_EXTTS_REQUEST:
+ case PTP_EXTTS_REQUEST2:
+ memset(&req, 0, sizeof(req));
+
if (copy_from_user(&req.extts, (void __user *)arg,
sizeof(req.extts))) {
err = -EFAULT;
break;
}
+ if (((req.extts.flags & ~PTP_EXTTS_VALID_FLAGS) ||
+ req.extts.rsv[0] || req.extts.rsv[1]) &&
+ cmd == PTP_EXTTS_REQUEST2) {
+ err = -EINVAL;
+ break;
+ } else if (cmd == PTP_EXTTS_REQUEST) {
+ req.extts.flags &= ~PTP_EXTTS_VALID_FLAGS;
+ req.extts.rsv[0] = 0;
+ req.extts.rsv[1] = 0;
+ }
if (req.extts.index >= ops->n_ext_ts) {
err = -EINVAL;
break;
@@ -154,11 +169,27 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;
case PTP_PEROUT_REQUEST:
+ case PTP_PEROUT_REQUEST2:
+ memset(&req, 0, sizeof(req));
+
if (copy_from_user(&req.perout, (void __user *)arg,
sizeof(req.perout))) {
err = -EFAULT;
break;
}
+ if (((req.perout.flags & ~PTP_PEROUT_VALID_FLAGS) ||
+ req.perout.rsv[0] || req.perout.rsv[1] ||
+ req.perout.rsv[2] || req.perout.rsv[3]) &&
+ cmd == PTP_PEROUT_REQUEST2) {
+ err = -EINVAL;
+ break;
+ } else if (cmd == PTP_PEROUT_REQUEST) {
+ req.perout.flags &= ~PTP_PEROUT_VALID_FLAGS;
+ req.perout.rsv[0] = 0;
+ req.perout.rsv[1] = 0;
+ req.perout.rsv[2] = 0;
+ req.perout.rsv[3] = 0;
+ }
if (req.perout.index >= ops->n_per_out) {
err = -EINVAL;
break;
@@ -169,6 +200,9 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;
case PTP_ENABLE_PPS:
+ case PTP_ENABLE_PPS2:
+ memset(&req, 0, sizeof(req));
+
if (!capable(CAP_SYS_TIME))
return -EPERM;
req.type = PTP_CLK_REQ_PPS;
@@ -177,6 +211,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;
case PTP_SYS_OFFSET_PRECISE:
+ case PTP_SYS_OFFSET_PRECISE2:
if (!ptp->info->getcrosststamp) {
err = -EOPNOTSUPP;
break;
@@ -201,6 +236,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;
case PTP_SYS_OFFSET_EXTENDED:
+ case PTP_SYS_OFFSET_EXTENDED2:
if (!ptp->info->gettimex64) {
err = -EOPNOTSUPP;
break;
@@ -232,6 +268,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;
case PTP_SYS_OFFSET:
+ case PTP_SYS_OFFSET2:
sysoff = memdup_user((void __user *)arg, sizeof(*sysoff));
if (IS_ERR(sysoff)) {
err = PTR_ERR(sysoff);
@@ -266,10 +303,23 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;
case PTP_PIN_GETFUNC:
+ case PTP_PIN_GETFUNC2:
if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
err = -EFAULT;
break;
}
+ if ((pd.rsv[0] || pd.rsv[1] || pd.rsv[2]
+ || pd.rsv[3] || pd.rsv[4])
+ && cmd == PTP_PIN_GETFUNC2) {
+ err = -EINVAL;
+ break;
+ } else if (cmd == PTP_PIN_GETFUNC) {
+ pd.rsv[0] = 0;
+ pd.rsv[1] = 0;
+ pd.rsv[2] = 0;
+ pd.rsv[3] = 0;
+ pd.rsv[4] = 0;
+ }
pin_index = pd.index;
if (pin_index >= ops->n_pins) {
err = -EINVAL;
@@ -285,10 +335,23 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
break;
case PTP_PIN_SETFUNC:
+ case PTP_PIN_SETFUNC2:
if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
err = -EFAULT;
break;
}
+ if ((pd.rsv[0] || pd.rsv[1] || pd.rsv[2]
+ || pd.rsv[3] || pd.rsv[4])
+ && cmd == PTP_PIN_SETFUNC2) {
+ err = -EINVAL;
+ break;
+ } else if (cmd == PTP_PIN_SETFUNC) {
+ pd.rsv[0] = 0;
+ pd.rsv[1] = 0;
+ pd.rsv[2] = 0;
+ pd.rsv[3] = 0;
+ pd.rsv[4] = 0;
+ }
pin_index = pd.index;
if (pin_index >= ops->n_pins) {
err = -EINVAL;
diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h
index 1bc794ad957a..12911785991b 100644
--- a/include/uapi/linux/ptp_clock.h
+++ b/include/uapi/linux/ptp_clock.h
@@ -25,10 +25,20 @@
#include <linux/ioctl.h>
#include <linux/types.h>
-/* PTP_xxx bits, for the flags field within the request structures. */
+/*
+ * Bits of the ptp_extts_request.flags field:
+ */
#define PTP_ENABLE_FEATURE (1<<0)
#define PTP_RISING_EDGE (1<<1)
#define PTP_FALLING_EDGE (1<<2)
+#define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | \
+ PTP_RISING_EDGE | \
+ PTP_FALLING_EDGE)
+
+/*
+ * Bits of the ptp_perout_request.flags field:
+ */
+#define PTP_PEROUT_VALID_FLAGS (~0)
/*
* struct ptp_clock_time - represents a time value
@@ -149,6 +159,18 @@ struct ptp_pin_desc {
#define PTP_SYS_OFFSET_EXTENDED \
_IOWR(PTP_CLK_MAGIC, 9, struct ptp_sys_offset_extended)
+#define PTP_CLOCK_GETCAPS2 _IOR(PTP_CLK_MAGIC, 10, struct ptp_clock_caps)
+#define PTP_EXTTS_REQUEST2 _IOW(PTP_CLK_MAGIC, 11, struct ptp_extts_request)
+#define PTP_PEROUT_REQUEST2 _IOW(PTP_CLK_MAGIC, 12, struct ptp_perout_request)
+#define PTP_ENABLE_PPS2 _IOW(PTP_CLK_MAGIC, 13, int)
+#define PTP_SYS_OFFSET2 _IOW(PTP_CLK_MAGIC, 14, struct ptp_sys_offset)
+#define PTP_PIN_GETFUNC2 _IOWR(PTP_CLK_MAGIC, 15, struct ptp_pin_desc)
+#define PTP_PIN_SETFUNC2 _IOW(PTP_CLK_MAGIC, 16, struct ptp_pin_desc)
+#define PTP_SYS_OFFSET_PRECISE2 \
+ _IOWR(PTP_CLK_MAGIC, 17, struct ptp_sys_offset_precise)
+#define PTP_SYS_OFFSET_EXTENDED2 \
+ _IOWR(PTP_CLK_MAGIC, 18, struct ptp_sys_offset_extended)
+
struct ptp_extts_event {
struct ptp_clock_time t; /* Time event occured. */
unsigned int index; /* Which channel produced the event. */
--
2.23.0
^ permalink raw reply related
* [PATCH v3 2/2] PTP: add support for one-shot output
From: Felipe Balbi @ 2019-09-09 7:59 UTC (permalink / raw)
To: Richard Cochran; +Cc: Christopher S Hall, netdev, linux-kernel, Felipe Balbi
In-Reply-To: <20190909075940.12843-1-felipe.balbi@linux.intel.com>
Some controllers allow for a one-shot output pulse, in contrast to
periodic output. Now that we have extensible versions of our IOCTLs, we
can finally make use of the 'flags' field to pass a bit telling driver
that if we want one-shot pulse output.
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
Changes since v2:
- Add _PEROUT_ to bit macro
Changes since v1:
- remove comment from .flags field
include/uapi/linux/ptp_clock.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h
index 12911785991b..cbdc0d97b471 100644
--- a/include/uapi/linux/ptp_clock.h
+++ b/include/uapi/linux/ptp_clock.h
@@ -38,8 +38,8 @@
/*
* Bits of the ptp_perout_request.flags field:
*/
-#define PTP_PEROUT_VALID_FLAGS (~0)
-
+#define PTP_PEROUT_ONE_SHOT (1<<0)
+#define PTP_PEROUT_VALID_FLAGS (~PTP_PEROUT_ONE_SHOT)
/*
* struct ptp_clock_time - represents a time value
*
@@ -77,7 +77,7 @@ struct ptp_perout_request {
struct ptp_clock_time start; /* Absolute start time. */
struct ptp_clock_time period; /* Desired period, zero means disable. */
unsigned int index; /* Which channel to configure. */
- unsigned int flags; /* Reserved for future use. */
+ unsigned int flags;
unsigned int rsv[4]; /* Reserved for future use. */
};
--
2.23.0
^ permalink raw reply related
* [PATCH net-next 5/5] sctp: add spt_pathcpthld in struct sctp_paddrthlds
From: Xin Long @ 2019-09-09 7:56 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
In-Reply-To: <cover.1568015756.git.lucien.xin@gmail.com>
Section 7.2 of rfc7829: "Peer Address Thresholds (SCTP_PEER_ADDR_THLDS)
Socket Option" extends 'struct sctp_paddrthlds' with 'spt_pathcpthld'
added to allow a user to change ps_retrans per sock/asoc/transport, as
other 2 paddrthlds: pf_retrans, pathmaxrxt.
Note that ps_retrans is not allowed to be greater than pf_retrans.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/uapi/linux/sctp.h | 1 +
net/sctp/socket.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index a15cc28..dfd81e1 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -1069,6 +1069,7 @@ struct sctp_paddrthlds {
struct sockaddr_storage spt_address;
__u16 spt_pathmaxrxt;
__u16 spt_pathpfthld;
+ __u16 spt_pathcpthld;
};
/*
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5e2098b..5b9774d 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3954,6 +3954,9 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
sizeof(struct sctp_paddrthlds)))
return -EFAULT;
+ if (val.spt_pathpfthld > val.spt_pathcpthld)
+ return -EINVAL;
+
if (!sctp_is_any(sk, (const union sctp_addr *)&val.spt_address)) {
trans = sctp_addr_id2transport(sk, &val.spt_address,
val.spt_assoc_id);
@@ -3963,6 +3966,7 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
if (val.spt_pathmaxrxt)
trans->pathmaxrxt = val.spt_pathmaxrxt;
trans->pf_retrans = val.spt_pathpfthld;
+ trans->ps_retrans = val.spt_pathcpthld;
return 0;
}
@@ -3978,17 +3982,20 @@ static int sctp_setsockopt_paddr_thresholds(struct sock *sk,
if (val.spt_pathmaxrxt)
trans->pathmaxrxt = val.spt_pathmaxrxt;
trans->pf_retrans = val.spt_pathpfthld;
+ trans->ps_retrans = val.spt_pathcpthld;
}
if (val.spt_pathmaxrxt)
asoc->pathmaxrxt = val.spt_pathmaxrxt;
asoc->pf_retrans = val.spt_pathpfthld;
+ asoc->ps_retrans = val.spt_pathcpthld;
} else {
struct sctp_sock *sp = sctp_sk(sk);
if (val.spt_pathmaxrxt)
sp->pathmaxrxt = val.spt_pathmaxrxt;
sp->pf_retrans = val.spt_pathpfthld;
+ sp->ps_retrans = val.spt_pathcpthld;
}
return 0;
@@ -7232,6 +7239,7 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
if (!trans)
return -ENOENT;
+ val.spt_pathcpthld = trans->ps_retrans;
val.spt_pathmaxrxt = trans->pathmaxrxt;
val.spt_pathpfthld = trans->pf_retrans;
@@ -7244,11 +7252,13 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
return -EINVAL;
if (asoc) {
+ val.spt_pathcpthld = asoc->ps_retrans;
val.spt_pathpfthld = asoc->pf_retrans;
val.spt_pathmaxrxt = asoc->pathmaxrxt;
} else {
struct sctp_sock *sp = sctp_sk(sk);
+ val.spt_pathcpthld = sp->ps_retrans;
val.spt_pathpfthld = sp->pf_retrans;
val.spt_pathmaxrxt = sp->pathmaxrxt;
}
--
2.1.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox