Netdev List
 help / color / mirror / Atom feed
* [PATCH] slip: sl_alloc(): remove unused parameter "dev_t line"
From: Marc Kleine-Budde @ 2017-12-08 11:18 UTC (permalink / raw)
  To: netdev; +Cc: kernel, David Miller, Marc Kleine-Budde

The first and only parameter of sl_alloc() is unused, so remove it.

Fixes: 5342b77c4123 slip: ("Clean up create and destroy")
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
 drivers/net/slip/slip.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index cc63102ca96e..8940417c30e5 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -731,7 +731,7 @@ static void sl_sync(void)
 
 
 /* Find a free SLIP channel, and link in this `tty' line. */
-static struct slip *sl_alloc(dev_t line)
+static struct slip *sl_alloc(void)
 {
 	int i;
 	char name[IFNAMSIZ];
@@ -809,7 +809,7 @@ static int slip_open(struct tty_struct *tty)
 
 	/* OK.  Find a free SLIP channel to use. */
 	err = -ENFILE;
-	sl = sl_alloc(tty_devnum(tty));
+	sl = sl_alloc();
 	if (sl == NULL)
 		goto err_exit;
 
-- 
2.15.0

^ permalink raw reply related

* [PATCH net v3] net: phy: meson-gxl: detect LPA corruption
From: Jerome Brunet @ 2017-12-08 11:08 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli
  Cc: Jerome Brunet, Kevin Hilman, netdev, linux-arm-kernel,
	linux-amlogic, linux-kernel

The purpose of this change is to fix the incorrect detection of the link
partner (LP) advertised capabilities which sometimes happens with this PHY
(roughly 1 time in a dozen)

This issue may cause the link to be negotiated at 10Mbps/Full or
10Mbps/Half when 100MBps/Full is actually possible. In some case, the link
is even completely broken and no communication is possible.

To detect the corruption, we must look for a magic undocumented bit in the
WOL bank (hint given by the SoC vendor kernel) but this is not enough to
cover all cases. We also have to look at the LPA ack. If the LP supports
Aneg but did not ack our base code when aneg is completed, we assume
something went wrong.

The detection of a corrupted LPA triggers a restart of the aneg process.
This solves the problem but may take up to 6 retries to complete.

Fixes: 7334b3e47aee ("net: phy: Add Meson GXL Internal PHY driver")
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---

I suppose this patch probably seems a bit hacky, especially the part
about the link partner acknowledge. I'm trying to figure out if the
value in MII_LPA makes sense but I don't have such a deep knowledge
of the ethernet spec.

To me, it does not makes sense for the LP to support ANEG (Bit 1 in
MII_EXPENSION), the aneg to have successfully complete and, at the
same time, LP does not ACK our base code word, which we should have
sent during this aneg.

If you think this may have unintended consequences or if you have
an idea to do this differently, feel free to let me know.

This fix has been tested on the libretech-cc and khadas VIM

The v2 [0] had dependencies on other changes which were not fixes.
This v3 is re-implementation of v2 without the dependencies to be
merged as a fix and easily backportable.

All the ugly phy_write() with hexadecimal values will go away when
then clean-up gets through.

[0]: https://lkml.kernel.org/r/20171207142715.32578-6-jbrunet@baylibre.com

 drivers/net/phy/meson-gxl.c | 74 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 1ea69b7585d9..700007dd4be5 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -22,6 +22,7 @@
 #include <linux/ethtool.h>
 #include <linux/phy.h>
 #include <linux/netdevice.h>
+#include <linux/bitfield.h>
 
 static int meson_gxl_config_init(struct phy_device *phydev)
 {
@@ -50,6 +51,77 @@ static int meson_gxl_config_init(struct phy_device *phydev)
 	return 0;
 }
 
+/* This function is provided to cope with the possible failures of this phy
+ * during aneg process. When aneg fails, the PHY reports that aneg is done
+ * but the value found in MII_LPA is wrong:
+ *  - Early failures: MII_LPA is just 0x0001. if MII_EXPANSION reports that
+ *    the link partner (LP) supports aneg but the LP never acked our base
+ *    code word, it is likely that we never sent it to begin with.
+ *  - Late failures: MII_LPA is filled with a value which seems to make sense
+ *    but it actually is not what the LP is advertising. It seems that we
+ *    can detect this using a magic bit in the WOL bank (reg 12 - bit 12).
+ *    If this particular bit is not set when aneg is reported being done,
+ *    it means MII_LPA is likely to be wrong.
+ *
+ * In both case, forcing a restart of the aneg process solve the problem.
+ * When this failure happens, the first retry is usually successful but,
+ * in some cases, it may take up to 6 retries to get a decent result
+ */
+int meson_gxl_read_status(struct phy_device *phydev)
+{
+	int ret, wol, lpa, exp;
+
+	if (phydev->autoneg == AUTONEG_ENABLE) {
+		ret = genphy_aneg_done(phydev);
+		if (ret < 0)
+			return ret;
+		else if (!ret)
+			goto read_status_continue;
+
+		/* Need to access WOL bank, make sure the access is open */
+		ret = phy_write(phydev, 0x14, 0x0000);
+		if (ret)
+			return ret;
+		ret = phy_write(phydev, 0x14, 0x0400);
+		if (ret)
+			return ret;
+		ret = phy_write(phydev, 0x14, 0x0000);
+		if (ret)
+			return ret;
+		ret = phy_write(phydev, 0x14, 0x0400);
+		if (ret)
+			return ret;
+
+		/* Request LPI_STATUS WOL register */
+		ret = phy_write(phydev, 0x14, 0x8D80);
+		if (ret)
+			return ret;
+
+		/* Read LPI_STATUS value */
+		wol = phy_read(phydev, 0x15);
+		if (wol < 0)
+			return wol;
+
+		lpa = phy_read(phydev, MII_LPA);
+		if (lpa < 0)
+			return lpa;
+
+		exp = phy_read(phydev, MII_EXPANSION);
+		if (exp < 0)
+			return exp;
+
+		if (!(wol & BIT(12)) ||
+		    ((exp & EXPANSION_NWAY) && !(lpa & LPA_LPACK))) {
+			/* Looks like aneg failed after all */
+			phydev_dbg(phydev, "LPA corruption - aneg restart\n");
+			return genphy_restart_aneg(phydev);
+		}
+	}
+
+read_status_continue:
+	return genphy_read_status(phydev);
+}
+
 static struct phy_driver meson_gxl_phy[] = {
 	{
 		.phy_id		= 0x01814400,
@@ -60,7 +132,7 @@ static struct phy_driver meson_gxl_phy[] = {
 		.config_init	= meson_gxl_config_init,
 		.config_aneg	= genphy_config_aneg,
 		.aneg_done      = genphy_aneg_done,
-		.read_status	= genphy_read_status,
+		.read_status	= meson_gxl_read_status,
 		.suspend        = genphy_suspend,
 		.resume         = genphy_resume,
 	},
-- 
2.14.3

^ permalink raw reply related

* Re: [PATCH v5 net-next] net/tcp: trace all TCP/IP state transition with tcp_set_state tracepoint
From: Marcelo Ricardo Leitner @ 2017-12-08 11:03 UTC (permalink / raw)
  To: Yafang Shao
  Cc: David Miller, Song Liu, Alexey Kuznetsov, yoshfuji,
	Steven Rostedt, Brendan Gregg, netdev, LKML
In-Reply-To: <CALOAHbBbo+ueVt7Wu=wAvgrfFjg7LVHfo4W_hhv_d7pQzeY9+Q@mail.gmail.com>

On Fri, Dec 08, 2017 at 11:40:23AM +0800, Yafang Shao wrote:
> It will looks like these,
> 
>     if (sk->sk_protocol == IPPROTO_TCP)
>         __tcp_set_state(newsk, TCP_SYN_RECV);
>     else
>         newsk->sk_state = TCP_SYN_RECV;
> 
> 
>     if (sk->sk_protocol == IPPROTO_TCP)
>           __tcp_set_state(sk, TCP_CLOSE);
>     else
>           sk->sk_state = TCP_CLOSE;
> 
>     if (sk->sk_protocol == IPPROTO_TCP)
>           tcp_state_store(sk,  state);
>     else
>           sk_state_store(sk, state);
> 
> 
> Some redundant code.
> 
> IMO, put these similar code into a wrapper is more nice.

Agreed. Hmpf, looks like one way or another, we have to add the sk_
functions to do such check, and then the tcp_* won't help much.

I'm okay with this v5 then, can't see a better way around it.

  Marcelo

^ permalink raw reply

* Re: [PATCH net 3/3] hv_netvsc: Fix the default receive buffer size
From: Dan Carpenter @ 2017-12-08 10:44 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: devel, haiyangz, sthemmin, netdev
In-Reply-To: <20171208001055.24670-4-sthemmin@microsoft.com>

On Thu, Dec 07, 2017 at 04:10:55PM -0800, Stephen Hemminger wrote:
> From: Haiyang Zhang <haiyangz@microsoft.com>
> 
> The intended size is 16 MB, and the default slot size is 1728.
> So, NETVSC_DEFAULT_RX should be 16*1024*1024 / 1728 = 9709.
> 
> Fixes: 5023a6db73196 ("netvsc: increase default receive buffer size")
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
> ---
>  drivers/net/hyperv/netvsc_drv.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
> index dc70de674ca9..edfcde5d3621 100644
> --- a/drivers/net/hyperv/netvsc_drv.c
> +++ b/drivers/net/hyperv/netvsc_drv.c
> @@ -50,7 +50,7 @@
>  #define NETVSC_MIN_TX_SECTIONS	10
>  #define NETVSC_DEFAULT_TX	192	/* ~1M */
>  #define NETVSC_MIN_RX_SECTIONS	10	/* ~64K */
> -#define NETVSC_DEFAULT_RX	10485   /* Max ~16M */
> +#define NETVSC_DEFAULT_RX	9709    /* ~16M */

How does this bug look like to the user?  Memory corruption?

It's weird to me reviewing this code that the default sizes are
stored in netvsc_drv.c and the max sizes are stored in hyperv_net.h.
Could we move these to hyperv_net.h?  We could write it like:
#define NETVSC_DEFAULT_RX ((16 * 1024 * 1024) / NETVSC_RECV_SECTION_SIZE)

16MB is sort of a weird default because it's larger than the 15MB
allowed for legacy versions, but it's smaller than the 32MB you'd want
for the current versions.

regards,
dan carpenter

^ permalink raw reply

* [PATCH net-next v4 2/2] net: thunderx: add timestamping support
From: Aleksey Makarov @ 2017-12-08 10:34 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, Goutham, Sunil,
	Radoslaw Biernacki, Aleksey Makarov, Robert Richter, David Daney,
	Richard Cochran, Sunil Goutham
In-Reply-To: <20171208103442.19354-1-aleksey.makarov@cavium.com>

From: Sunil Goutham <sgoutham@cavium.com>

This adds timestamping support for both receive and transmit
paths. On the receive side no filters are supported i.e either
all pkts will get a timestamp appended infront of the packet or none.
On the transmit side HW doesn't support timestamp insertion but
only generates a separate CQE with transmitted packet's timestamp.
Also HW supports only one packet at a time for timestamping on the
transmit side.

Signed-off-by: Sunil Goutham <sgoutham@cavium.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov@cavium.com>
---
 drivers/net/ethernet/cavium/Kconfig                |   1 +
 drivers/net/ethernet/cavium/thunder/nic.h          |  15 ++
 drivers/net/ethernet/cavium/thunder/nic_main.c     |  58 ++++++-
 drivers/net/ethernet/cavium/thunder/nic_reg.h      |   1 +
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    |  29 +++-
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 173 ++++++++++++++++++++-
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c |  26 ++++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  29 ++++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h  |   4 +
 9 files changed, 330 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig
index 2380e9834007..d163c5bdbbcb 100644
--- a/drivers/net/ethernet/cavium/Kconfig
+++ b/drivers/net/ethernet/cavium/Kconfig
@@ -27,6 +27,7 @@ config THUNDER_NIC_PF
 
 config THUNDER_NIC_VF
 	tristate "Thunder Virtual function driver"
+	select CAVIUM_PTP
 	depends on 64BIT
 	---help---
 	  This driver supports Thunder's NIC virtual function
diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 4a02e618e318..204b234beb9d 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -263,6 +263,8 @@ struct nicvf_drv_stats {
 	struct u64_stats_sync   syncp;
 };
 
+struct cavium_ptp;
+
 struct nicvf {
 	struct nicvf		*pnicvf;
 	struct net_device	*netdev;
@@ -312,6 +314,12 @@ struct nicvf {
 	struct tasklet_struct	qs_err_task;
 	struct work_struct	reset_task;
 
+	/* PTP timestamp */
+	struct cavium_ptp	*ptp_clock;
+	bool			hw_rx_tstamp;
+	struct sk_buff		*ptp_skb;
+	atomic_t		tx_ptp_skbs;
+
 	/* Interrupt coalescing settings */
 	u32			cq_coalesce_usecs;
 	u32			msg_enable;
@@ -371,6 +379,7 @@ struct nicvf {
 #define	NIC_MBOX_MSG_LOOPBACK		0x16	/* Set interface in loopback */
 #define	NIC_MBOX_MSG_RESET_STAT_COUNTER 0x17	/* Reset statistics counters */
 #define	NIC_MBOX_MSG_PFC		0x18	/* Pause frame control */
+#define	NIC_MBOX_MSG_PTP_CFG		0x19	/* HW packet timestamp */
 #define	NIC_MBOX_MSG_CFG_DONE		0xF0	/* VF configuration done */
 #define	NIC_MBOX_MSG_SHUTDOWN		0xF1	/* VF is being shutdown */
 
@@ -521,6 +530,11 @@ struct pfc {
 	u8    fc_tx;
 };
 
+struct set_ptp {
+	u8    msg;
+	bool  enable;
+};
+
 /* 128 bit shared memory between PF and each VF */
 union nic_mbx {
 	struct { u8 msg; }	msg;
@@ -540,6 +554,7 @@ union nic_mbx {
 	struct set_loopback	lbk;
 	struct reset_stat_cfg	reset_stat;
 	struct pfc		pfc;
+	struct set_ptp		ptp;
 };
 
 #define NIC_NODE_ID_MASK	0x03
diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
index 8f1dd55b3e08..4c1c5414a162 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
@@ -426,13 +426,22 @@ static void nic_init_hw(struct nicpf *nic)
 	/* Enable backpressure */
 	nic_reg_write(nic, NIC_PF_BP_CFG, (1ULL << 6) | 0x03);
 
-	/* TNS and TNS bypass modes are present only on 88xx */
+	/* TNS and TNS bypass modes are present only on 88xx
+	 * Also offset of this CSR has changed in 81xx and 83xx.
+	 */
 	if (nic->pdev->subsystem_device == PCI_SUBSYS_DEVID_88XX_NIC_PF) {
 		/* Disable TNS mode on both interfaces */
 		nic_reg_write(nic, NIC_PF_INTF_0_1_SEND_CFG,
-			      (NIC_TNS_BYPASS_MODE << 7) | BGX0_BLOCK);
+			      (NIC_TNS_BYPASS_MODE << 7) |
+			      BGX0_BLOCK | (1ULL << 16));
 		nic_reg_write(nic, NIC_PF_INTF_0_1_SEND_CFG | (1 << 8),
-			      (NIC_TNS_BYPASS_MODE << 7) | BGX1_BLOCK);
+			      (NIC_TNS_BYPASS_MODE << 7) |
+			      BGX1_BLOCK | (1ULL << 16));
+	} else {
+		/* Configure timestamp generation timeout to 10us */
+		for (i = 0; i < nic->hw->bgx_cnt; i++)
+			nic_reg_write(nic, NIC_PF_INTFX_SEND_CFG | (i << 3),
+				      (1ULL << 16));
 	}
 
 	nic_reg_write(nic, NIC_PF_INTF_0_1_BP_CFG,
@@ -880,6 +889,46 @@ static void nic_pause_frame(struct nicpf *nic, int vf, struct pfc *cfg)
 	}
 }
 
+/* Enable or disable HW timestamping by BGX for pkts received on a LMAC */
+static void nic_config_timestamp(struct nicpf *nic, int vf, struct set_ptp *ptp)
+{
+	struct pkind_cfg *pkind;
+	u8 lmac, bgx_idx;
+	u64 pkind_val, pkind_idx;
+
+	if (vf >= nic->num_vf_en)
+		return;
+
+	bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
+
+	pkind_idx = lmac + bgx_idx * MAX_LMAC_PER_BGX;
+	pkind_val = nic_reg_read(nic, NIC_PF_PKIND_0_15_CFG | (pkind_idx << 3));
+	pkind = (struct pkind_cfg *)&pkind_val;
+
+	if (ptp->enable && !pkind->hdr_sl) {
+		/* Skiplen to exclude 8byte timestamp while parsing pkt
+		 * If not configured, will result in L2 errors.
+		 */
+		pkind->hdr_sl = 4;
+		/* Adjust max packet length allowed */
+		pkind->maxlen += (pkind->hdr_sl * 2);
+		bgx_config_timestamping(nic->node, bgx_idx, lmac, true);
+		nic_reg_write(nic,
+			      NIC_PF_RX_ETYPE_0_7 | (1 << 3),
+			      (ETYPE_ALG_ENDPARSE << 16) | ETH_P_1588);
+	} else if (!ptp->enable && pkind->hdr_sl) {
+		pkind->maxlen -= (pkind->hdr_sl * 2);
+		pkind->hdr_sl = 0;
+		bgx_config_timestamping(nic->node, bgx_idx, lmac, false);
+		nic_reg_write(nic,
+			      NIC_PF_RX_ETYPE_0_7 | (1 << 3),
+			      (1ULL << 16) | ETH_P_8021Q); /* reset value */
+	}
+
+	nic_reg_write(nic, NIC_PF_PKIND_0_15_CFG | (pkind_idx << 3), pkind_val);
+}
+
 /* Interrupt handler to handle mailbox messages from VFs */
 static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 {
@@ -1022,6 +1071,9 @@ static void nic_handle_mbx_intr(struct nicpf *nic, int vf)
 	case NIC_MBOX_MSG_PFC:
 		nic_pause_frame(nic, vf, &mbx.pfc);
 		goto unlock;
+	case NIC_MBOX_MSG_PTP_CFG:
+		nic_config_timestamp(nic, vf, &mbx.ptp);
+		break;
 	default:
 		dev_err(&nic->pdev->dev,
 			"Invalid msg from VF%d, msg 0x%x\n", vf, mbx.msg.msg);
diff --git a/drivers/net/ethernet/cavium/thunder/nic_reg.h b/drivers/net/ethernet/cavium/thunder/nic_reg.h
index 80d46337cf29..a16c48a1ebb2 100644
--- a/drivers/net/ethernet/cavium/thunder/nic_reg.h
+++ b/drivers/net/ethernet/cavium/thunder/nic_reg.h
@@ -99,6 +99,7 @@
 #define   NIC_PF_ECC3_DBE_INT_W1S		(0x2708)
 #define   NIC_PF_ECC3_DBE_ENA_W1C		(0x2710)
 #define   NIC_PF_ECC3_DBE_ENA_W1S		(0x2718)
+#define   NIC_PF_INTFX_SEND_CFG			(0x4000)
 #define   NIC_PF_MCAM_0_191_ENA			(0x100000)
 #define   NIC_PF_MCAM_0_191_M_0_5_DATA		(0x110000)
 #define   NIC_PF_MCAM_CTRL			(0x120000)
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
index b9ece9cbf98b..ed9f10bdf41e 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_ethtool.c
@@ -9,12 +9,14 @@
 /* ETHTOOL Support for VNIC_VF Device*/
 
 #include <linux/pci.h>
+#include <linux/net_tstamp.h>
 
 #include "nic_reg.h"
 #include "nic.h"
 #include "nicvf_queues.h"
 #include "q_struct.h"
 #include "thunder_bgx.h"
+#include "../common/cavium_ptp.h"
 
 #define DRV_NAME	"thunder-nicvf"
 #define DRV_VERSION     "1.0"
@@ -824,6 +826,31 @@ static int nicvf_set_pauseparam(struct net_device *dev,
 	return 0;
 }
 
+static int nicvf_get_ts_info(struct net_device *netdev,
+			     struct ethtool_ts_info *info)
+{
+	struct nicvf *nic = netdev_priv(netdev);
+
+	if (!nic->ptp_clock)
+		return ethtool_op_get_ts_info(netdev, info);
+
+	info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE |
+				SOF_TIMESTAMPING_RX_SOFTWARE |
+				SOF_TIMESTAMPING_SOFTWARE |
+				SOF_TIMESTAMPING_TX_HARDWARE |
+				SOF_TIMESTAMPING_RX_HARDWARE |
+				SOF_TIMESTAMPING_RAW_HARDWARE;
+
+	info->phc_index = cavium_ptp_clock_index(nic->ptp_clock);
+
+	info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
+
+	info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+			   (1 << HWTSTAMP_FILTER_ALL);
+
+	return 0;
+}
+
 static const struct ethtool_ops nicvf_ethtool_ops = {
 	.get_link		= nicvf_get_link,
 	.get_drvinfo		= nicvf_get_drvinfo,
@@ -847,7 +874,7 @@ static const struct ethtool_ops nicvf_ethtool_ops = {
 	.set_channels		= nicvf_set_channels,
 	.get_pauseparam         = nicvf_get_pauseparam,
 	.set_pauseparam         = nicvf_set_pauseparam,
-	.get_ts_info		= ethtool_op_get_ts_info,
+	.get_ts_info		= nicvf_get_ts_info,
 	.get_link_ksettings	= nicvf_get_link_ksettings,
 };
 
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 52b3a6044f85..8e3338f31e54 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -20,11 +20,13 @@
 #include <linux/bpf.h>
 #include <linux/bpf_trace.h>
 #include <linux/filter.h>
+#include <linux/net_tstamp.h>
 
 #include "nic_reg.h"
 #include "nic.h"
 #include "nicvf_queues.h"
 #include "thunder_bgx.h"
+#include "../common/cavium_ptp.h"
 
 #define DRV_NAME	"thunder-nicvf"
 #define DRV_VERSION	"1.0"
@@ -601,6 +603,44 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog,
 	return false;
 }
 
+static void nicvf_snd_ptp_handler(struct net_device *netdev,
+				  struct cqe_send_t *cqe_tx)
+{
+	struct nicvf *nic = netdev_priv(netdev);
+	struct skb_shared_hwtstamps ts;
+	u64 ns;
+
+	nic = nic->pnicvf;
+
+	/* Sync for 'ptp_skb' */
+	smp_rmb();
+
+	/* New timestamp request can be queued now */
+	atomic_set(&nic->tx_ptp_skbs, 0);
+
+	/* Check for timestamp requested skb */
+	if (!nic->ptp_skb)
+		return;
+
+	/* Check if timestamping is timedout, which is set to 10us */
+	if (cqe_tx->send_status == CQ_TX_ERROP_TSTMP_TIMEOUT ||
+	    cqe_tx->send_status == CQ_TX_ERROP_TSTMP_CONFLICT)
+		goto no_tstamp;
+
+	/* Get the timestamp */
+	memset(&ts, 0, sizeof(ts));
+	ns = cavium_ptp_tstamp2time(nic->ptp_clock, cqe_tx->ptp_timestamp);
+	ts.hwtstamp = ns_to_ktime(ns);
+	skb_tstamp_tx(nic->ptp_skb, &ts);
+
+no_tstamp:
+	/* Free the original skb */
+	dev_kfree_skb_any(nic->ptp_skb);
+	nic->ptp_skb = NULL;
+	/* Sync 'ptp_skb' */
+	smp_wmb();
+}
+
 static void nicvf_snd_pkt_handler(struct net_device *netdev,
 				  struct cqe_send_t *cqe_tx,
 				  int budget, int *subdesc_cnt,
@@ -657,7 +697,12 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev,
 		prefetch(skb);
 		(*tx_pkts)++;
 		*tx_bytes += skb->len;
-		napi_consume_skb(skb, budget);
+		/* If timestamp is requested for this skb, don't free it */
+		if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS &&
+		    !nic->pnicvf->ptp_skb)
+			nic->pnicvf->ptp_skb = skb;
+		else
+			napi_consume_skb(skb, budget);
 		sq->skbuff[cqe_tx->sqe_ptr] = (u64)NULL;
 	} else {
 		/* In case of SW TSO on 88xx, only last segment will have
@@ -696,6 +741,21 @@ static inline void nicvf_set_rxhash(struct net_device *netdev,
 	skb_set_hash(skb, hash, hash_type);
 }
 
+static inline void nicvf_set_rxtstamp(struct nicvf *nic, struct sk_buff *skb)
+{
+	u64 ns;
+
+	if (!nic->ptp_clock || !nic->hw_rx_tstamp)
+		return;
+
+	/* The first 8 bytes is the timestamp */
+	ns = cavium_ptp_tstamp2time(nic->ptp_clock,
+				    be64_to_cpu(*(__be64 *)skb->data));
+	skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);
+
+	__skb_pull(skb, 8);
+}
+
 static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 				  struct napi_struct *napi,
 				  struct cqe_rx_t *cqe_rx, struct snd_queue *sq)
@@ -746,6 +806,7 @@ static void nicvf_rcv_pkt_handler(struct net_device *netdev,
 		return;
 	}
 
+	nicvf_set_rxtstamp(nic, skb);
 	nicvf_set_rxhash(netdev, cqe_rx, skb);
 
 	skb_record_rx_queue(skb, rq_idx);
@@ -820,10 +881,12 @@ static int nicvf_cq_intr_handler(struct net_device *netdev, u8 cq_idx,
 					      &tx_pkts, &tx_bytes);
 			tx_done++;
 		break;
+		case CQE_TYPE_SEND_PTP:
+			nicvf_snd_ptp_handler(netdev, (void *)cq_desc);
+		break;
 		case CQE_TYPE_INVALID:
 		case CQE_TYPE_RX_SPLIT:
 		case CQE_TYPE_RX_TCP:
-		case CQE_TYPE_SEND_PTP:
 			/* Ignore for now */
 		break;
 		}
@@ -1319,12 +1382,28 @@ int nicvf_stop(struct net_device *netdev)
 
 	nicvf_free_cq_poll(nic);
 
+	/* Free any pending SKB saved to receive timestamp */
+	if (nic->ptp_skb) {
+		dev_kfree_skb_any(nic->ptp_skb);
+		nic->ptp_skb = NULL;
+	}
+
 	/* Clear multiqset info */
 	nic->pnicvf = nic;
 
 	return 0;
 }
 
+static int nicvf_config_hw_rx_tstamp(struct nicvf *nic, bool enable)
+{
+	union nic_mbx mbx = {};
+
+	mbx.ptp.msg = NIC_MBOX_MSG_PTP_CFG;
+	mbx.ptp.enable = enable;
+
+	return nicvf_send_msg_to_pf(nic, &mbx);
+}
+
 static int nicvf_update_hw_max_frs(struct nicvf *nic, int mtu)
 {
 	union nic_mbx mbx = {};
@@ -1394,6 +1473,12 @@ int nicvf_open(struct net_device *netdev)
 	if (nic->sqs_mode)
 		nicvf_get_primary_vf_struct(nic);
 
+	/* Configure PTP timestamp */
+	if (nic->ptp_clock)
+		nicvf_config_hw_rx_tstamp(nic, nic->hw_rx_tstamp);
+	atomic_set(&nic->tx_ptp_skbs, 0);
+	nic->ptp_skb = NULL;
+
 	/* Configure receive side scaling and MTU */
 	if (!nic->sqs_mode) {
 		nicvf_rss_init(nic);
@@ -1820,6 +1905,77 @@ static void nicvf_xdp_flush(struct net_device *dev)
 	return;
 }
 
+static int nicvf_config_hwtstamp(struct net_device *netdev, struct ifreq *ifr)
+{
+	struct hwtstamp_config config;
+	struct nicvf *nic = netdev_priv(netdev);
+
+	if (!nic->ptp_clock)
+		return -ENODEV;
+
+	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	/* reserved for future extensions */
+	if (config.flags)
+		return -EINVAL;
+
+	switch (config.tx_type) {
+	case HWTSTAMP_TX_OFF:
+	case HWTSTAMP_TX_ON:
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		nic->hw_rx_tstamp = false;
+		break;
+	case HWTSTAMP_FILTER_ALL:
+	case HWTSTAMP_FILTER_SOME:
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+		nic->hw_rx_tstamp = true;
+		config.rx_filter = HWTSTAMP_FILTER_ALL;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	if (netif_running(netdev)) {
+		if (nic->hw_rx_tstamp)
+			nicvf_config_hw_rx_tstamp(nic, true);
+		else
+			nicvf_config_hw_rx_tstamp(nic, false);
+	}
+
+	if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
+		return -EFAULT;
+
+	return 0;
+}
+
+static int nicvf_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
+{
+	switch (cmd) {
+	case SIOCSHWTSTAMP:
+		return nicvf_config_hwtstamp(netdev, req);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 static const struct net_device_ops nicvf_netdev_ops = {
 	.ndo_open		= nicvf_open,
 	.ndo_stop		= nicvf_stop,
@@ -1833,6 +1989,7 @@ static const struct net_device_ops nicvf_netdev_ops = {
 	.ndo_bpf		= nicvf_xdp,
 	.ndo_xdp_xmit		= nicvf_xdp_xmit,
 	.ndo_xdp_flush          = nicvf_xdp_flush,
+	.ndo_do_ioctl           = nicvf_ioctl,
 };
 
 static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -1842,6 +1999,16 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct nicvf *nic;
 	int    err, qcount;
 	u16    sdevid;
+	struct cavium_ptp *ptp_clock;
+
+	ptp_clock = cavium_ptp_get();
+	if (IS_ERR(ptp_clock)) {
+		if (PTR_ERR(ptp_clock) == -ENODEV)
+			/* In virtualized environment we proceed without ptp */
+			ptp_clock = NULL;
+		else
+			return PTR_ERR(ptp_clock);
+	}
 
 	err = pci_enable_device(pdev);
 	if (err) {
@@ -1896,6 +2063,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	 */
 	if (!nic->t88)
 		nic->max_queues *= 2;
+	nic->ptp_clock = ptp_clock;
 
 	/* MAP VF's configuration registers */
 	nic->reg_base = pcim_iomap(pdev, PCI_CFG_REG_BAR_NUM, 0);
@@ -2009,6 +2177,7 @@ static void nicvf_remove(struct pci_dev *pdev)
 	pci_set_drvdata(pdev, NULL);
 	if (nic->drv_stats)
 		free_percpu(nic->drv_stats);
+	cavium_ptp_put(nic->ptp_clock);
 	free_netdev(netdev);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
index 095c18aeb8d5..9a999c62d6ba 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c
@@ -978,6 +978,9 @@ void nicvf_qset_config(struct nicvf *nic, bool enable)
 		qs_cfg->be = 1;
 #endif
 		qs_cfg->vnic = qs->vnic_id;
+		/* Enable Tx timestamping capability */
+		if (nic->ptp_clock)
+			qs_cfg->send_tstmp_ena = 1;
 	}
 	nicvf_send_msg_to_pf(nic, &mbx);
 }
@@ -1383,6 +1386,29 @@ nicvf_sq_add_hdr_subdesc(struct nicvf *nic, struct snd_queue *sq, int qentry,
 		hdr->inner_l3_offset = skb_network_offset(skb) - 2;
 		this_cpu_inc(nic->pnicvf->drv_stats->tx_tso);
 	}
+
+	/* Check if timestamp is requested */
+	if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
+		skb_tx_timestamp(skb);
+		return;
+	}
+
+	/* Tx timestamping not supported along with TSO, so ignore request */
+	if (skb_shinfo(skb)->gso_size)
+		return;
+
+	/* HW supports only a single outstanding packet to timestamp */
+	if (!atomic_add_unless(&nic->pnicvf->tx_ptp_skbs, 1, 1))
+		return;
+
+	/* Mark the SKB for later reference */
+	skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+
+	/* Finally enable timestamp generation
+	 * Since 'post_cqe' is also set, two CQEs will be posted
+	 * for this packet i.e CQE_TYPE_SEND and CQE_TYPE_SEND_PTP.
+	 */
+	hdr->tstmp = 1;
 }
 
 /* SQ GATHER subdescriptor
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
index 5e5c4d7796b8..0f23999c5bcf 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c
@@ -245,6 +245,35 @@ void bgx_lmac_rx_tx_enable(int node, int bgx_idx, int lmacid, bool enable)
 }
 EXPORT_SYMBOL(bgx_lmac_rx_tx_enable);
 
+/* Enables or disables timestamp insertion by BGX for Rx packets */
+void bgx_config_timestamping(int node, int bgx_idx, int lmacid, bool enable)
+{
+	struct bgx *bgx = get_bgx(node, bgx_idx);
+	struct lmac *lmac;
+	u64 csr_offset, cfg;
+
+	if (!bgx)
+		return;
+
+	lmac = &bgx->lmac[lmacid];
+
+	if (lmac->lmac_type == BGX_MODE_SGMII ||
+	    lmac->lmac_type == BGX_MODE_QSGMII ||
+	    lmac->lmac_type == BGX_MODE_RGMII)
+		csr_offset = BGX_GMP_GMI_RXX_FRM_CTL;
+	else
+		csr_offset = BGX_SMUX_RX_FRM_CTL;
+
+	cfg = bgx_reg_read(bgx, lmacid, csr_offset);
+
+	if (enable)
+		cfg |= BGX_PKT_RX_PTP_EN;
+	else
+		cfg &= ~BGX_PKT_RX_PTP_EN;
+	bgx_reg_write(bgx, lmacid, csr_offset, cfg);
+}
+EXPORT_SYMBOL(bgx_config_timestamping);
+
 void bgx_lmac_get_pfc(int node, int bgx_idx, int lmacid, void *pause)
 {
 	struct pfc *pfc = (struct pfc *)pause;
diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
index 23acdc5ab896..5a7567d31138 100644
--- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
+++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.h
@@ -122,6 +122,8 @@
 #define  SPU_DBG_CTL_AN_NONCE_MCT_DIS		BIT_ULL(29)
 
 #define BGX_SMUX_RX_INT			0x20000
+#define BGX_SMUX_RX_FRM_CTL		0x20020
+#define  BGX_PKT_RX_PTP_EN			BIT_ULL(12)
 #define BGX_SMUX_RX_JABBER		0x20030
 #define BGX_SMUX_RX_CTL			0x20048
 #define  SMU_RX_CTL_STATUS			(3ull << 0)
@@ -172,6 +174,7 @@
 #define  GMI_PORT_CFG_SPEED_MSB			BIT_ULL(8)
 #define  GMI_PORT_CFG_RX_IDLE			BIT_ULL(12)
 #define  GMI_PORT_CFG_TX_IDLE			BIT_ULL(13)
+#define BGX_GMP_GMI_RXX_FRM_CTL		0x38028
 #define BGX_GMP_GMI_RXX_JABBER		0x38038
 #define BGX_GMP_GMI_TXX_THRESH		0x38210
 #define BGX_GMP_GMI_TXX_APPEND		0x38218
@@ -223,6 +226,7 @@ void bgx_set_lmac_mac(int node, int bgx_idx, int lmacid, const u8 *mac);
 void bgx_get_lmac_link_state(int node, int bgx_idx, int lmacid, void *status);
 void bgx_lmac_internal_loopback(int node, int bgx_idx,
 				int lmac_idx, bool enable);
+void bgx_config_timestamping(int node, int bgx_idx, int lmacid, bool enable);
 void bgx_lmac_get_pfc(int node, int bgx_idx, int lmacid, void *pause);
 void bgx_lmac_set_pfc(int node, int bgx_idx, int lmacid, void *pause);
 
-- 
2.15.1

^ permalink raw reply related

* [PATCH net-next v4 0/2] net: thunderx: add support for PTP clock
From: Aleksey Makarov @ 2017-12-08 10:34 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, Goutham, Sunil,
	Radoslaw Biernacki, Aleksey Makarov, Robert Richter, David Daney,
	Richard Cochran

This series adds support for IEEE 1588 Precision Time Protocol
to Cavium ethernet driver.

The first patch adds support for the Precision Time Protocol Clocks and
Timestamping coprocessor (PTP) found on Cavium processors.
It registers a new PTP clock in the PTP core and provides functions
to use the counter in BGX, TNS, GTI, and NIC blocks.

The second patch introduces support for the PTP protocol to the
Cavium ThunderX ethernet driver.

v4:
- use IS_ENABLED. This fixes compilation of the ptp as a module (David Miller)
- select PTP_1588_CLOCK, not depend on it.  This fixes a build warning.
- change u64 to __be64.  This fixes the sparse warning
  "warning: cast to restricted __be64"
- make nicvf_config_hwtstamp() static. This fixes the sparse warning
  "warning: symbol 'nicvf_config_hwtstamp' was not declared. Should it be static?"

v3: https://lkml.kernel.org/r/20171206133100.26436-1-aleksey.makarov@cavium.com
- rebase to net-next

v2: https://lkml.kernel.org/r/20171117134909.8954-1-aleksey.makarov@cavium.com
- use readq()/writeq() in place of cavium_ptp_reg_read()/cavium_ptp_reg_write(),
  don't use readq_relaxed()/writeq_relaxed() (David Daney)

v1: https://lkml.kernel.org/r/20171107190704.15458-1-aleksey.makarov@cavium.com

Radoslaw Biernacki (1):
  net: add support for Cavium PTP coprocessor

Sunil Goutham (1):
  net: thunderx: add timestamping support

 drivers/net/ethernet/cavium/Kconfig                |  13 +
 drivers/net/ethernet/cavium/Makefile               |   1 +
 drivers/net/ethernet/cavium/common/Makefile        |   1 +
 drivers/net/ethernet/cavium/common/cavium_ptp.c    | 334 +++++++++++++++++++++
 drivers/net/ethernet/cavium/common/cavium_ptp.h    |  78 +++++
 drivers/net/ethernet/cavium/thunder/nic.h          |  15 +
 drivers/net/ethernet/cavium/thunder/nic_main.c     |  58 +++-
 drivers/net/ethernet/cavium/thunder/nic_reg.h      |   1 +
 .../net/ethernet/cavium/thunder/nicvf_ethtool.c    |  29 +-
 drivers/net/ethernet/cavium/thunder/nicvf_main.c   | 173 ++++++++++-
 drivers/net/ethernet/cavium/thunder/nicvf_queues.c |  26 ++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.c  |  29 ++
 drivers/net/ethernet/cavium/thunder/thunder_bgx.h  |   4 +
 13 files changed, 756 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/ethernet/cavium/common/Makefile
 create mode 100644 drivers/net/ethernet/cavium/common/cavium_ptp.c
 create mode 100644 drivers/net/ethernet/cavium/common/cavium_ptp.h

-- 
2.15.1

^ permalink raw reply

* [PATCH net-next v4 1/2] net: add support for Cavium PTP coprocessor
From: Aleksey Makarov @ 2017-12-08 10:34 UTC (permalink / raw)
  To: netdev
  Cc: linux-arm-kernel, linux-kernel, Goutham, Sunil,
	Radoslaw Biernacki, Aleksey Makarov, Robert Richter, David Daney,
	Richard Cochran
In-Reply-To: <20171208103442.19354-1-aleksey.makarov@cavium.com>

From: Radoslaw Biernacki <rad@semihalf.com>

This patch adds support for the Precision Time Protocol
Clocks and Timestamping hardware found on Cavium ThunderX
processors.

Signed-off-by: Radoslaw Biernacki <rad@semihalf.com>
Signed-off-by: Aleksey Makarov <aleksey.makarov@cavium.com>
---
 drivers/net/ethernet/cavium/Kconfig             |  12 +
 drivers/net/ethernet/cavium/Makefile            |   1 +
 drivers/net/ethernet/cavium/common/Makefile     |   1 +
 drivers/net/ethernet/cavium/common/cavium_ptp.c | 334 ++++++++++++++++++++++++
 drivers/net/ethernet/cavium/common/cavium_ptp.h |  78 ++++++
 5 files changed, 426 insertions(+)
 create mode 100644 drivers/net/ethernet/cavium/common/Makefile
 create mode 100644 drivers/net/ethernet/cavium/common/cavium_ptp.c
 create mode 100644 drivers/net/ethernet/cavium/common/cavium_ptp.h

diff --git a/drivers/net/ethernet/cavium/Kconfig b/drivers/net/ethernet/cavium/Kconfig
index 63be75eb34d2..2380e9834007 100644
--- a/drivers/net/ethernet/cavium/Kconfig
+++ b/drivers/net/ethernet/cavium/Kconfig
@@ -50,6 +50,18 @@ config	THUNDER_NIC_RGX
 	  This driver supports configuring XCV block of RGX interface
 	  present on CN81XX chip.
 
+config CAVIUM_PTP
+	tristate "Cavium PTP coprocessor as PTP clock"
+	depends on 64BIT
+	select PTP_1588_CLOCK
+	default y
+	---help---
+	  This driver adds support for the Precision Time Protocol Clocks and
+	  Timestamping coprocessor (PTP) found on Cavium processors.
+	  PTP provides timestamping mechanism that is suitable for use in IEEE 1588
+	  Precision Time Protocol or other purposes.  Timestamps can be used in
+	  BGX, TNS, GTI, and NIC blocks.
+
 config LIQUIDIO
 	tristate "Cavium LiquidIO support"
 	depends on 64BIT
diff --git a/drivers/net/ethernet/cavium/Makefile b/drivers/net/ethernet/cavium/Makefile
index 872da9f7c31a..946bba84e81d 100644
--- a/drivers/net/ethernet/cavium/Makefile
+++ b/drivers/net/ethernet/cavium/Makefile
@@ -1,6 +1,7 @@
 #
 # Makefile for the Cavium ethernet device drivers.
 #
+obj-$(CONFIG_NET_VENDOR_CAVIUM) += common/
 obj-$(CONFIG_NET_VENDOR_CAVIUM) += thunder/
 obj-$(CONFIG_NET_VENDOR_CAVIUM) += liquidio/
 obj-$(CONFIG_NET_VENDOR_CAVIUM) += octeon/
diff --git a/drivers/net/ethernet/cavium/common/Makefile b/drivers/net/ethernet/cavium/common/Makefile
new file mode 100644
index 000000000000..dd8561b8060b
--- /dev/null
+++ b/drivers/net/ethernet/cavium/common/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_CAVIUM_PTP) += cavium_ptp.o
diff --git a/drivers/net/ethernet/cavium/common/cavium_ptp.c b/drivers/net/ethernet/cavium/common/cavium_ptp.c
new file mode 100644
index 000000000000..f4c738db27fd
--- /dev/null
+++ b/drivers/net/ethernet/cavium/common/cavium_ptp.c
@@ -0,0 +1,334 @@
+/*
+ * cavium_ptp.c - PTP 1588 clock on Cavium hardware
+ *
+ * Copyright (c) 2003-2015, 2017 Cavium, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium, Inc. for more information
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/timecounter.h>
+#include <linux/pci.h>
+
+#include "cavium_ptp.h"
+
+#define DRV_NAME	"Cavium PTP Driver"
+
+#define PCI_DEVICE_ID_CAVIUM_PTP	0xA00C
+#define PCI_DEVICE_ID_CAVIUM_RST	0xA00E
+
+#define PCI_PTP_BAR_NO	0
+#define PCI_RST_BAR_NO	0
+
+#define PTP_CLOCK_CFG		0xF00ULL
+#define  PTP_CLOCK_CFG_PTP_EN	BIT(0)
+#define PTP_CLOCK_LO		0xF08ULL
+#define PTP_CLOCK_HI		0xF10ULL
+#define PTP_CLOCK_COMP		0xF18ULL
+
+#define RST_BOOT	0x1600ULL
+#define CLOCK_BASE_RATE	50000000ULL
+
+static u64 ptp_cavium_clock_get(void)
+{
+	struct pci_dev *pdev;
+	void __iomem *base;
+	u64 ret = CLOCK_BASE_RATE * 16;
+
+	pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
+			      PCI_DEVICE_ID_CAVIUM_RST, NULL);
+	if (!pdev)
+		goto error;
+
+	base = pci_ioremap_bar(pdev, PCI_RST_BAR_NO);
+	if (!base)
+		goto error_put_pdev;
+
+	ret = CLOCK_BASE_RATE * ((readq(base + RST_BOOT) >> 33) & 0x3f);
+
+	iounmap(base);
+
+error_put_pdev:
+	pci_dev_put(pdev);
+
+error:
+	return ret;
+}
+
+struct cavium_ptp *cavium_ptp_get(void)
+{
+	struct cavium_ptp *ptp;
+	struct pci_dev *pdev;
+
+	pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
+			      PCI_DEVICE_ID_CAVIUM_PTP, NULL);
+	if (!pdev)
+		return ERR_PTR(-ENODEV);
+
+	ptp = pci_get_drvdata(pdev);
+	if (!ptp) {
+		pci_dev_put(pdev);
+		ptp = ERR_PTR(-EPROBE_DEFER);
+	}
+
+	return ptp;
+}
+EXPORT_SYMBOL(cavium_ptp_get);
+
+void cavium_ptp_put(struct cavium_ptp *ptp)
+{
+	pci_dev_put(ptp->pdev);
+}
+EXPORT_SYMBOL(cavium_ptp_put);
+
+/**
+ * cavium_ptp_adjfreq() - Adjust ptp frequency
+ * @ptp: PTP clock info
+ * @ppb: how much to adjust by, in parts-per-billion
+ */
+static int cavium_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
+{
+	struct cavium_ptp *clock =
+		container_of(ptp_info, struct cavium_ptp, ptp_info);
+	unsigned long flags;
+	u64 comp;
+	u64 adj;
+	bool neg_adj = false;
+
+	if (ppb < 0) {
+		neg_adj = true;
+		ppb = -ppb;
+	}
+
+	/* The hardware adds the clock compensation value to the PTP clock
+	 * on every coprocessor clock cycle. Typical convention is that it
+	 * represent number of nanosecond betwen each cycle. In this
+	 * convention compensation value is in 64 bit fixed-point
+	 * representation where upper 32 bits are number of nanoseconds
+	 * and lower is fractions of nanosecond.
+	 * The ppb represent the ratio in "parts per bilion" by which the
+	 * compensation value should be corrected.
+	 * To calculate new compenstation value we use 64bit fixed point
+	 * arithmetic on following formula comp = tbase + tbase * ppb / 1G
+	 * where tbase is the basic compensation value calculated initialy
+	 * in cavium_ptp_init() -> tbase = 1/Hz. Then we use endian
+	 * independent structure definition to write data to PTP register.
+	 */
+	comp = ((u64)1000000000ull << 32) / clock->clock_rate;
+	adj = comp * ppb;
+	adj = div_u64(adj, 1000000000ull);
+	comp = neg_adj ? comp - adj : comp + adj;
+
+	spin_lock_irqsave(&clock->spin_lock, flags);
+	writeq(comp, clock->reg_base + PTP_CLOCK_COMP);
+	spin_unlock_irqrestore(&clock->spin_lock, flags);
+
+	return 0;
+}
+
+/**
+ * cavium_ptp_adjtime() - Adjust ptp time
+ * @ptp:   PTP clock info
+ * @delta: how much to adjust by, in nanosecs
+ */
+static int cavium_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
+{
+	struct cavium_ptp *clock =
+		container_of(ptp_info, struct cavium_ptp, ptp_info);
+	unsigned long flags;
+
+	spin_lock_irqsave(&clock->spin_lock, flags);
+	timecounter_adjtime(&clock->time_counter, delta);
+	spin_unlock_irqrestore(&clock->spin_lock, flags);
+
+	/* Sync, for network driver to get latest value */
+	smp_mb();
+
+	return 0;
+}
+
+/**
+ * cavium_ptp_gettime() - Get hardware clock time with adjustment
+ * @ptp: PTP clock info
+ * @ts:  timespec
+ */
+static int cavium_ptp_gettime(struct ptp_clock_info *ptp_info,
+			      struct timespec64 *ts)
+{
+	struct cavium_ptp *clock =
+		container_of(ptp_info, struct cavium_ptp, ptp_info);
+	unsigned long flags;
+	u64 nsec;
+
+	spin_lock_irqsave(&clock->spin_lock, flags);
+	nsec = timecounter_read(&clock->time_counter);
+	spin_unlock_irqrestore(&clock->spin_lock, flags);
+
+	*ts = ns_to_timespec64(nsec);
+
+	return 0;
+}
+
+/**
+ * cavium_ptp_settime() - Set hardware clock time. Reset adjustment
+ * @ptp: PTP clock info
+ * @ts:  timespec
+ */
+static int cavium_ptp_settime(struct ptp_clock_info *ptp_info,
+			      const struct timespec64 *ts)
+{
+	struct cavium_ptp *clock =
+		container_of(ptp_info, struct cavium_ptp, ptp_info);
+	unsigned long flags;
+	u64 nsec;
+
+	nsec = timespec64_to_ns(ts);
+
+	spin_lock_irqsave(&clock->spin_lock, flags);
+	timecounter_init(&clock->time_counter, &clock->cycle_counter, nsec);
+	spin_unlock_irqrestore(&clock->spin_lock, flags);
+
+	return 0;
+}
+
+/**
+ * cavium_ptp_enable() - Check if PTP is enabled
+ * @ptp: PTP clock info
+ * @rq:  request
+ * @on:  is it on
+ */
+static int cavium_ptp_enable(struct ptp_clock_info *ptp_info,
+			     struct ptp_clock_request *rq, int on)
+{
+	return -EOPNOTSUPP;
+}
+
+static u64 cavium_ptp_cc_read(const struct cyclecounter *cc)
+{
+	struct cavium_ptp *clock =
+		container_of(cc, struct cavium_ptp, cycle_counter);
+
+	return readq(clock->reg_base + PTP_CLOCK_HI);
+}
+
+static int cavium_ptp_probe(struct pci_dev *pdev,
+			    const struct pci_device_id *ent)
+{
+	struct device *dev = &pdev->dev;
+	struct cavium_ptp *clock;
+	struct cyclecounter *cc;
+	u64 clock_cfg;
+	u64 clock_comp;
+	int err;
+
+	clock = devm_kzalloc(dev, sizeof(*clock), GFP_KERNEL);
+	if (!clock)
+		return -ENOMEM;
+
+	clock->pdev = pdev;
+
+	err = pcim_enable_device(pdev);
+	if (err)
+		return err;
+
+	err = pcim_iomap_regions(pdev, 1 << PCI_PTP_BAR_NO, pci_name(pdev));
+	if (err)
+		return err;
+
+	clock->reg_base = pcim_iomap_table(pdev)[PCI_PTP_BAR_NO];
+
+	spin_lock_init(&clock->spin_lock);
+
+	cc = &clock->cycle_counter;
+	cc->read = cavium_ptp_cc_read;
+	cc->mask = CYCLECOUNTER_MASK(64);
+	cc->mult = 1;
+	cc->shift = 0;
+
+	timecounter_init(&clock->time_counter, &clock->cycle_counter,
+			 ktime_to_ns(ktime_get_real()));
+
+	clock->clock_rate = ptp_cavium_clock_get();
+
+	clock->ptp_info = (struct ptp_clock_info) {
+		.owner		= THIS_MODULE,
+		.name		= "ThunderX PTP",
+		.max_adj	= 1000000000ull,
+		.n_ext_ts	= 0,
+		.n_pins		= 0,
+		.pps		= 0,
+		.adjfreq	= cavium_ptp_adjfreq,
+		.adjtime	= cavium_ptp_adjtime,
+		.gettime64	= cavium_ptp_gettime,
+		.settime64	= cavium_ptp_settime,
+		.enable		= cavium_ptp_enable,
+	};
+
+	clock_cfg = readq(clock->reg_base + PTP_CLOCK_CFG);
+	clock_cfg |= PTP_CLOCK_CFG_PTP_EN;
+	writeq(clock_cfg, clock->reg_base + PTP_CLOCK_CFG);
+
+	clock_comp = ((u64)1000000000ull << 32) / clock->clock_rate;
+	writeq(clock_comp, clock->reg_base + PTP_CLOCK_COMP);
+
+	clock->ptp_clock = ptp_clock_register(&clock->ptp_info, dev);
+	if (IS_ERR(clock->ptp_clock)) {
+		clock_cfg = readq(clock->reg_base + PTP_CLOCK_CFG);
+		clock_cfg &= ~PTP_CLOCK_CFG_PTP_EN;
+		writeq(clock_cfg, clock->reg_base + PTP_CLOCK_CFG);
+		return PTR_ERR(clock->ptp_clock);
+	}
+
+	pci_set_drvdata(pdev, clock);
+	return 0;
+}
+
+static void cavium_ptp_remove(struct pci_dev *pdev)
+{
+	struct cavium_ptp *clock = pci_get_drvdata(pdev);
+	u64 clock_cfg;
+
+	pci_set_drvdata(pdev, NULL);
+
+	ptp_clock_unregister(clock->ptp_clock);
+
+	clock_cfg = readq(clock->reg_base + PTP_CLOCK_CFG);
+	clock_cfg &= ~PTP_CLOCK_CFG_PTP_EN;
+	writeq(clock_cfg, clock->reg_base + PTP_CLOCK_CFG);
+}
+
+static const struct pci_device_id cavium_ptp_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_CAVIUM_PTP) },
+	{ 0, }
+};
+
+static struct pci_driver cavium_ptp_driver = {
+	.name = DRV_NAME,
+	.id_table = cavium_ptp_id_table,
+	.probe = cavium_ptp_probe,
+	.remove = cavium_ptp_remove,
+};
+
+static int __init cavium_ptp_init_module(void)
+{
+	return pci_register_driver(&cavium_ptp_driver);
+}
+
+static void __exit cavium_ptp_cleanup_module(void)
+{
+	pci_unregister_driver(&cavium_ptp_driver);
+}
+
+module_init(cavium_ptp_init_module);
+module_exit(cavium_ptp_cleanup_module);
+
+MODULE_DESCRIPTION(DRV_NAME);
+MODULE_AUTHOR("Cavium Networks <support@cavium.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(pci, cavium_ptp_id_table);
diff --git a/drivers/net/ethernet/cavium/common/cavium_ptp.h b/drivers/net/ethernet/cavium/common/cavium_ptp.h
new file mode 100644
index 000000000000..0f6fe2b6e2ca
--- /dev/null
+++ b/drivers/net/ethernet/cavium/common/cavium_ptp.h
@@ -0,0 +1,78 @@
+/*
+ * cavium_ptp.h - PTP 1588 clock on Cavium hardware
+ *
+ * Copyright (c) 2003-2015, 2017 Cavium, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium, Inc. for more information
+ */
+
+#ifndef CAVIUM_PTP_H
+#define CAVIUM_PTP_H
+
+#include <linux/ptp_clock_kernel.h>
+#include <linux/timecounter.h>
+
+struct cavium_ptp {
+	struct pci_dev *pdev;
+
+	/* Serialize access to cycle_counter, time_counter and hw_registers */
+	spinlock_t spin_lock;
+	struct cyclecounter cycle_counter;
+	struct timecounter time_counter;
+	void __iomem *reg_base;
+
+	u32 clock_rate;
+
+	struct ptp_clock_info ptp_info;
+	struct ptp_clock *ptp_clock;
+};
+
+#if IS_ENABLED(CONFIG_CAVIUM_PTP)
+
+struct cavium_ptp *cavium_ptp_get(void);
+void cavium_ptp_put(struct cavium_ptp *ptp);
+
+static inline u64 cavium_ptp_tstamp2time(struct cavium_ptp *ptp, u64 tstamp)
+{
+	unsigned long flags;
+	u64 ret;
+
+	spin_lock_irqsave(&ptp->spin_lock, flags);
+	ret = timecounter_cyc2time(&ptp->time_counter, tstamp);
+	spin_unlock_irqrestore(&ptp->spin_lock, flags);
+
+	return ret;
+}
+
+static inline int cavium_ptp_clock_index(struct cavium_ptp *clock)
+{
+	return ptp_clock_index(clock->ptp_clock);
+}
+
+#else
+
+static inline struct cavium_ptp *cavium_ptp_get(void)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void cavium_ptp_put(struct cavium_ptp *ptp) {}
+
+static inline u64 cavium_ptp_tstamp2time(struct cavium_ptp *ptp, u64 tstamp)
+{
+	return 0;
+}
+
+static inline int cavium_ptp_clock_index(struct cavium_ptp *clock)
+{
+	return -1;
+}
+
+#endif
+
+#endif
-- 
2.15.1

^ permalink raw reply related

* Re: Linux 4.14 - regression: broken tun/tap / bridge network with virtio - bisected
From: Andreas Hartmann @ 2017-12-08 10:31 UTC (permalink / raw)
  To: Michal Kubecek; +Cc: Jason Wang, David Miller, netdev
In-Reply-To: <20171208084751.tom4auppogz4lanz@unicorn.suse.cz>

On 12/08/2017 at 09:47 AM Michal Kubecek wrote:
> On Fri, Dec 08, 2017 at 08:21:16AM +0100, Andreas Hartmann wrote:
>>
>> Thanks for this hint - I'm not using xdp. Therefore I rechecked my
>> bisect and detected a mistake. The rebisect now leads to
>>
>>
>>
>> [v2,RFC,11/13] net: Remove all references to SKB_GSO_UDP. [1]
>>
>>
>>
>> For the repeated bisect, I switched back to the original qemu 2.6.2
>> (instead of 2.10.1), because problems can be seen reliably with 2.6.2.
>>
>> All my VMs are using virtio_net. BTW: I couldn't see the problems
>> (sometimes, the VM couldn't be stopped at all) if all my VMs are using
>> e1000 as interface instead.
>>
>> This finding now matches pretty much the responsible UDP-package which
>> caused the stall. I already mentioned it here [2].
>>
>> To prove it, I reverted from the patch series "[PATCH v2 RFC 0/13]
>> Remove UDP Fragmentation Offload support" [3]
>>
>> 11/13 [v2,RFC,11/13] net: Remove all references to SKB_GSO_UDP. [4]
>> 12/13 [v2,RFC,12/13] inet: Remove software UFO fragmenting code. [5]
>> 13/13 [v2,RFC,13/13] net: Kill NETIF_F_UFO and SKB_GSO_UDP. [6]
>>
>> and applied it to Linux 4.14.4. It compiled fine and is running fine.
>> The vnet doesn't die anymore. Yet, I can't say if the qemu stop hangs
>> are gone, too.
>>
>> Obviously, there is something broken with the new UDP handling. Could
>> you please analyze this problem? I could test some more patches ... .
> 
> Any chance your VMs were live migrated from pre-4.14 host kernel?

No - the VMs are not live migrated. They are always running on the same
host - either with kernel < 4.14 or with kernel 4.14.x.

> If
> this is the case, you should try commit 0c19f846d582 ("net: accept UFO
> datagrams from tuntap and packet"). 

It doesn't apply to 4.14.4

> Or disabling UFO in the guest should
> work around the issue.

ethtool -K ethX ufo off for each device / bridge in VM.

Yes, this seems to work. I'll wait and see if the non stoppable
qemu-problem on shutdown will remain.


When will there be a fix for 4.14? It is clearly a regression. Is it
possible / a good idea to just remove the complete patch series "Remove
UDP Fragmentation Offload support"?


Thanks,
Andreas

^ permalink raw reply

* Re: [PATCH v2 net-next 4/4] bpftool: implement cgroup bpf operations
From: Quentin Monnet @ 2017-12-08 10:34 UTC (permalink / raw)
  To: Roman Gushchin, netdev
  Cc: linux-kernel, kernel-team, ast, daniel, jakub.kicinski, kafai,
	David Ahern
In-Reply-To: <20171207183909.16240-5-guro@fb.com>

2017-12-07 18:39 UTC+0000 ~ Roman Gushchin <guro@fb.com>
> This patch adds basic cgroup bpf operations to bpftool:
> cgroup list, attach and detach commands.
> 
> Usage is described in the corresponding man pages,
> and examples are provided.
> 
> Syntax:
> $ bpftool cgroup list CGROUP
> $ bpftool cgroup attach CGROUP ATTACH_TYPE PROG [ATTACH_FLAGS]
> $ bpftool cgroup detach CGROUP ATTACH_TYPE PROG
> 
> Signed-off-by: Roman Gushchin <guro@fb.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
> Cc: Martin KaFai Lau <kafai@fb.com>
> Cc: Quentin Monnet <quentin.monnet@netronome.com>
> Cc: David Ahern <dsahern@gmail.com>
> ---
>  tools/bpf/bpftool/Documentation/bpftool-cgroup.rst |  92 +++++++
>  tools/bpf/bpftool/Documentation/bpftool-map.rst    |   2 +-
>  tools/bpf/bpftool/Documentation/bpftool-prog.rst   |   2 +-
>  tools/bpf/bpftool/Documentation/bpftool.rst        |   6 +-
>  tools/bpf/bpftool/cgroup.c                         | 305 +++++++++++++++++++++
>  tools/bpf/bpftool/main.c                           |   3 +-
>  tools/bpf/bpftool/main.h                           |   1 +
>  7 files changed, 406 insertions(+), 5 deletions(-)
>  create mode 100644 tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
>  create mode 100644 tools/bpf/bpftool/cgroup.c
> 
> diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
> new file mode 100644
> index 000000000000..61ded613aee1
> --- /dev/null
> +++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst
> @@ -0,0 +1,92 @@
> +================
> +bpftool-cgroup
> +================
> +-------------------------------------------------------------------------------
> +tool for inspection and simple manipulation of eBPF progs
> +-------------------------------------------------------------------------------
> +
> +:Manual section: 8
> +
> +SYNOPSIS
> +========
> +
> +	**bpftool** [*OPTIONS*] **cgroup** *COMMAND*
> +
> +	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } }
> +
> +	*COMMANDS* :=
> +	{ **list** | **attach** | **detach** | **help** }
> +
> +MAP COMMANDS
> +=============
> +
> +|	**bpftool** **cgroup list** *CGROUP*
> +|	**bpftool** **cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*]
> +|	**bpftool** **cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG*
> +|	**bpftool** **cgroup help**
> +|
> +|	*PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }

Could you please give the different possible values for ATTACH_TYPE and
ATTACH_FLAGS, and provide some documentation for the flags?

> +
> +DESCRIPTION
> +===========
> +	**bpftool cgroup list** *CGROUP*
> +		  List all programs attached to the cgroup *CGROUP*.
> +
> +		  Output will start with program ID followed by attach type,
> +		  attach flags and program name.
> +
> +	**bpftool cgroup attach** *CGROUP* *ATTACH_TYPE* *PROG* [*ATTACH_FLAGS*]
> +		  Attach program *PROG* to the cgroup *CGROUP* with attach type
> +		  *ATTACH_TYPE* and optional *ATTACH_FLAGS*.
> +
> +	**bpftool cgroup detach** *CGROUP* *ATTACH_TYPE* *PROG*
> +		  Detach *PROG* from the cgroup *CGROUP* and attach type
> +		  *ATTACH_TYPE*.
> +
> +	**bpftool prog help**
> +		  Print short help message.

[…]

> diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c
> new file mode 100644
> index 000000000000..88d67f74313f
> --- /dev/null
> +++ b/tools/bpf/bpftool/cgroup.c
> @@ -0,0 +1,305 @@
> +/*
> + * Copyright (C) 2017 Facebook
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + *
> + * Author: Roman Gushchin <guro@fb.com>
> + */
> +

[…]

> +static int do_detach(int argc, char **argv)
> +{
> +	int prog_fd, cgroup_fd;
> +	enum bpf_attach_type attach_type;
> +	int ret = -1;
> +
> +	if (argc < 4) {
> +		p_err("too few parameters for cgroup detach\n");
> +		goto exit;
> +	}
> +
> +	cgroup_fd = open(argv[0], O_RDONLY);
> +	if (cgroup_fd < 0) {
> +		p_err("can't open cgroup %s\n", argv[1]);
> +		goto exit;
> +	}
> +
> +	attach_type = parse_attach_type(argv[1]);
> +	if (attach_type == __MAX_BPF_ATTACH_TYPE) {
> +		p_err("invalid attach type");
> +		goto exit_cgroup;
> +	}
> +
> +	argc -= 2;
> +	argv = &argv[2];
> +	prog_fd = prog_parse_fd(&argc, &argv);
> +	if (prog_fd < 0)
> +		goto exit_cgroup;
> +
> +	if (bpf_prog_detach2(prog_fd, cgroup_fd, attach_type)) {
> +		p_err("failed to attach program");

Failed to *detach* instead of “attach”.

> +		goto exit_prog;
> +	}
> +
> +	if (json_output)
> +		jsonw_null(json_wtr);
> +
> +	ret = 0;
> +
> +exit_prog:
> +	close(prog_fd);
> +exit_cgroup:
> +	close(cgroup_fd);
> +exit:
> +	return ret;
> +}

[…]

Very nice work on this v2, thanks a lot!
Quentin

^ permalink raw reply

* Re: [PATCH v2 net-next 3/4] bpftool: implement prog load command
From: Quentin Monnet @ 2017-12-08 10:33 UTC (permalink / raw)
  To: Roman Gushchin, netdev
  Cc: linux-kernel, kernel-team, ast, daniel, jakub.kicinski, kafai,
	David Ahern
In-Reply-To: <20171207183909.16240-4-guro@fb.com>

2017-12-07 18:39 UTC+0000 ~ Roman Gushchin <guro@fb.com>
> Add the prog load command to load a bpf program from a specified
> binary file and pin it to bpffs.
> 
> Usage description and examples are given in the corresponding man
> page.
> 
> Syntax:
> $ bpftool prog load SOURCE_FILE FILE
> 
> FILE is a non-existing file on bpffs.
> 
> Signed-off-by: Roman Gushchin <guro@fb.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
> Cc: Martin KaFai Lau <kafai@fb.com>
> Cc: Quentin Monnet <quentin.monnet@netronome.com>
> Cc: David Ahern <dsahern@gmail.com>
> ---
>  tools/bpf/bpftool/Documentation/bpftool-prog.rst | 10 +++-
>  tools/bpf/bpftool/Documentation/bpftool.rst      |  2 +-
>  tools/bpf/bpftool/common.c                       | 71 +++++++++++++-----------
>  tools/bpf/bpftool/main.h                         |  1 +
>  tools/bpf/bpftool/prog.c                         | 31 ++++++++++-
>  5 files changed, 81 insertions(+), 34 deletions(-)
> 
> diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
> index 36e8d1c3c40d..827b415f8ab6 100644
> --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst
> +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst
> @@ -15,7 +15,7 @@ SYNOPSIS
>  	*OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-f** | **--bpffs** } }
>  
>  	*COMMANDS* :=
> -	{ **show** | **dump xlated** | **dump jited** | **pin** | **help** }
> +	{ **show** | **dump xlated** | **dump jited** | **pin** | **load** | **help** }
>  
>  MAP COMMANDS
>  =============
> @@ -24,6 +24,7 @@ MAP COMMANDS
>  |	**bpftool** **prog dump xlated** *PROG* [{**file** *FILE* | **opcodes**}]
>  |	**bpftool** **prog dump jited**  *PROG* [{**file** *FILE* | **opcodes**}]
>  |	**bpftool** **prog pin** *PROG* *FILE*
> +|	**bpftool** **prog load** *SRC* *FILE*
>  |	**bpftool** **prog help**
>  |
>  |	*PROG* := { **id** *PROG_ID* | **pinned** *FILE* | **tag** *PROG_TAG* }
> @@ -57,6 +58,11 @@ DESCRIPTION
>  
>  		  Note: *FILE* must be located in *bpffs* mount.
>  
> +	**bpftool prog load** *SRC* *FILE*
> +		  Load bpf program from binary *SRC* and pin as *FILE*.
> +
> +		  Note: *FILE* must be located in *bpffs* mount.
> +
>  	**bpftool prog help**
>  		  Print short help message.
>  
> @@ -126,8 +132,10 @@ EXAMPLES
>  |
>  | **# mount -t bpf none /sys/fs/bpf/**
>  | **# bpftool prog pin id 10 /sys/fs/bpf/prog**
> +| **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2**
>  | **# ls -l /sys/fs/bpf/**
>  |   -rw------- 1 root root 0 Jul 22 01:43 prog
> +|   -rw------- 1 root root 0 Dec 07 17:23 prog2

Nit: would you mind using a date closer to the first one? Just from a
reader's point of view it might look strange to see the files apparently
created with two successive commands having such a difference between
their creation times.

>  
>  **# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes**
>  
> diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst
> index 926c03d5a8da..f547a0c0aa34 100644
> --- a/tools/bpf/bpftool/Documentation/bpftool.rst
> +++ b/tools/bpf/bpftool/Documentation/bpftool.rst
> @@ -26,7 +26,7 @@ SYNOPSIS
>  	| **pin** | **help** }
>  
>  	*PROG-COMMANDS* := { **show** | **dump jited** | **dump xlated** | **pin**
> -	| **help** }
> +	| **load** | **help** }
>  
>  DESCRIPTION
>  ===========

[…]

> diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
> index ad619b96c276..bac5d81e2ff0 100644
> --- a/tools/bpf/bpftool/prog.c
> +++ b/tools/bpf/bpftool/prog.c
> @@ -45,6 +45,7 @@
>  #include <sys/stat.h>
>  
>  #include <bpf.h>
> +#include <libbpf.h>
>  
>  #include "main.h"
>  #include "disasm.h"
> @@ -635,6 +636,32 @@ static int do_pin(int argc, char **argv)
>  	return err;
>  }
>  
> +static int do_load(int argc, char **argv)
> +{
> +	struct bpf_object *obj;
> +	int prog_fd;
> +
> +	if (argc != 2) {
> +		usage();
> +		return -1;
> +	}

No need to return here, usage() exits from the program.

> +
> +	if (bpf_prog_load(argv[0], BPF_PROG_TYPE_UNSPEC, &obj, &prog_fd)) {
> +		p_err("failed to load program\n");
> +		return -1;
> +	}
> +
> +	if (do_pin_fd(prog_fd, argv[1])) {
> +		p_err("failed to pin program\n");
> +		return -1;
> +	}
> +
> +	if (json_output)
> +		jsonw_null(json_wtr);
> +
> +	return 0;
> +}
> +
>  static int do_help(int argc, char **argv)
>  {
>  	if (json_output) {
> @@ -647,13 +674,14 @@ static int do_help(int argc, char **argv)
>  		"       %s %s dump xlated PROG [{ file FILE | opcodes }]\n"
>  		"       %s %s dump jited  PROG [{ file FILE | opcodes }]\n"
>  		"       %s %s pin   PROG FILE\n"
> +		"       %s %s load  SRC  FILE\n"
>  		"       %s %s help\n"
>  		"\n"
>  		"       " HELP_SPEC_PROGRAM "\n"
>  		"       " HELP_SPEC_OPTIONS "\n"
>  		"",
>  		bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2],
> -		bin_name, argv[-2], bin_name, argv[-2]);
> +		bin_name, argv[-2], bin_name, argv[-2], bin_name, argv[-2]);
>  
>  	return 0;
>  }
> @@ -663,6 +691,7 @@ static const struct cmd cmds[] = {
>  	{ "help",	do_help },
>  	{ "dump",	do_dump },
>  	{ "pin",	do_pin },
> +	{ "load",	do_load },
>  	{ 0 }
>  };
>  
> 

^ permalink raw reply

* Re: [PATCH v2 net-next 1/4] libbpf: add ability to guess program type based on section name
From: Quentin Monnet @ 2017-12-08 10:33 UTC (permalink / raw)
  To: Roman Gushchin, netdev
  Cc: linux-kernel, kernel-team, ast, daniel, jakub.kicinski, kafai,
	David Ahern
In-Reply-To: <20171207183909.16240-2-guro@fb.com>

2017-12-07 18:39 UTC+0000 ~ Roman Gushchin <guro@fb.com>
> The bpf_prog_load() function will guess program type if it's not
> specified explicitly. This functionality will be used to implement
> loading of different programs without asking a user to specify
> the program type. In first order it will be used by bpftool.
> 
> Signed-off-by: Roman Gushchin <guro@fb.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: Jakub Kicinski <jakub.kicinski@netronome.com>
> Cc: Martin KaFai Lau <kafai@fb.com>
> Cc: Quentin Monnet <quentin.monnet@netronome.com>
> Cc: David Ahern <dsahern@gmail.com>
> ---
>  tools/lib/bpf/libbpf.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
> 
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 5aa45f89da93..205b7822fa0a 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -1721,6 +1721,45 @@ BPF_PROG_TYPE_FNS(tracepoint, BPF_PROG_TYPE_TRACEPOINT);
>  BPF_PROG_TYPE_FNS(xdp, BPF_PROG_TYPE_XDP);
>  BPF_PROG_TYPE_FNS(perf_event, BPF_PROG_TYPE_PERF_EVENT);
>  
> +#define BPF_PROG_SEC(string, type) { string, sizeof(string), type }
> +static const struct {
> +	const char *sec;
> +	size_t len;
> +	enum bpf_prog_type prog_type;
> +} section_names[] = {
> +	BPF_PROG_SEC("socket",		BPF_PROG_TYPE_SOCKET_FILTER),
> +	BPF_PROG_SEC("kprobe/",		BPF_PROG_TYPE_KPROBE),
> +	BPF_PROG_SEC("kretprobe/",	BPF_PROG_TYPE_KPROBE),
> +	BPF_PROG_SEC("tracepoint/",	BPF_PROG_TYPE_TRACEPOINT),
> +	BPF_PROG_SEC("xdp",		BPF_PROG_TYPE_XDP),
> +	BPF_PROG_SEC("perf_event",	BPF_PROG_TYPE_PERF_EVENT),
> +	BPF_PROG_SEC("cgroup/skb",	BPF_PROG_TYPE_CGROUP_SKB),
> +	BPF_PROG_SEC("cgroup/sock",	BPF_PROG_TYPE_CGROUP_SOCK),
> +	BPF_PROG_SEC("cgroup/dev",	BPF_PROG_TYPE_CGROUP_DEVICE),
> +	BPF_PROG_SEC("sockops",		BPF_PROG_TYPE_SOCK_OPS),
> +	BPF_PROG_SEC("sk_skb",		BPF_PROG_TYPE_SK_SKB),
> +};
> +#undef BPF_PROG_SEC
> +
> +static enum bpf_prog_type bpf_program__guess_type(struct bpf_program *prog)
> +{
> +	int i;
> +
> +	if (!prog->section_name)
> +		goto err;
> +
> +	for (i = 0; i < ARRAY_SIZE(section_names); i++)
> +		if (strncmp(prog->section_name, section_names[i].sec,
> +			    section_names[i].len) == 0)
> +			return section_names[i].prog_type;
> +
> +err:
> +	pr_warning("failed to guess program type based on section name %s\n",
> +		   prog->section_name);
> +
> +	return BPF_PROG_TYPE_UNSPEC;
> +}
> +
>  int bpf_map__fd(struct bpf_map *map)
>  {
>  	return map ? map->fd : -EINVAL;
> @@ -1832,6 +1871,18 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
>  		return -ENOENT;
>  	}
>  
> +	/*
> +	 * If type is not specified, try to guess it based on
> +	 * section name.
> +	 */
> +	if (type == BPF_PROG_TYPE_UNSPEC) {
> +		type = bpf_program__guess_type(prog);
> +		if (type == BPF_PROG_TYPE_UNSPEC) {
> +			bpf_object__close(obj);
> +			return -EINVAL;
> +		}
> +	}
> +
>  	bpf_program__set_type(prog, type);
>  	err = bpf_object__load(obj);
>  	if (err) {
> 

Looks good to me, nice to avoid the hard-coded string lengths :). Thanks
for the changes!

Quentin

^ permalink raw reply

* Re: [PATCH net 1/3] hv_netvsc: Correct the max receive buffer size
From: Dan Carpenter @ 2017-12-08 10:33 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: devel, haiyangz, sthemmin, netdev
In-Reply-To: <20171208001055.24670-2-sthemmin@microsoft.com>

On Thu, Dec 07, 2017 at 04:10:53PM -0800, Stephen Hemminger wrote:
> From: Haiyang Zhang <haiyangz@microsoft.com>
> 
> It should be 31 MB on recent host versions.
> 
> Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>

This is very vague.  What does "recent" mean in this context?  There are
also some unrelated white space changes here which make the patch harder
to read.

This patch kind of makes the bug fixed by patch 2 even worse because
before the receive buffer was capped at around 16MB and now we can set
the receive buffer to 31MB.  It might make sense to fold the two
patches together.

Is patch 2 a memory corruption bug?  The changelog doesn't really say
what the user visible effects of the bug are.  Basically if you make the
buffer too small then it's a performance issue but if you make it too
large what happens?  It's not clear to me.

regards,
dan carpenter

^ permalink raw reply

* Re: [PATCH v3 24/33] nds32: Device tree support
From: Mark Rutland @ 2017-12-08 10:27 UTC (permalink / raw)
  To: Greentime Hu
  Cc: greentime, linux-kernel, arnd, linux-arch, tglx, jason,
	marc.zyngier, robh+dt, netdev, deanbo422, devicetree, viro,
	dhowells, will.deacon, daniel.lezcano, linux-serial,
	geert.uytterhoeven, linus.walleij, greg, Vincent Chen
In-Reply-To: <c1083b6f603aeeb13c72c501214e82549404fa5c.1512723245.git.green.hu@gmail.com>

On Fri, Dec 08, 2017 at 05:12:07PM +0800, Greentime Hu wrote:
> +	timer0: timer@98400000 {
> +		compatible = "andestech,atftmr010";
> +		reg = <0x98400000 0x1000>;
> +		interrupts = <19>;
> +		clocks = <&clk_pll>;
> +		clock-names = "apb_pclk";
> +		cycle-count-offset = <0x20>;
> +	};

Looking through the series, I can't find a binding or driver for this
timer, either.

Does timekeeping work with this series, or are additional patches
necessary?

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH v3 24/33] nds32: Device tree support
From: Mark Rutland @ 2017-12-08 10:23 UTC (permalink / raw)
  To: Greentime Hu
  Cc: greentime, linux-kernel, arnd, linux-arch, tglx, jason,
	marc.zyngier, robh+dt, netdev, deanbo422, devicetree, viro,
	dhowells, will.deacon, daniel.lezcano, linux-serial,
	geert.uytterhoeven, linus.walleij, greg, Vincent Chen
In-Reply-To: <c1083b6f603aeeb13c72c501214e82549404fa5c.1512723245.git.green.hu@gmail.com>

On Fri, Dec 08, 2017 at 05:12:07PM +0800, Greentime Hu wrote:
> +	timer0: timer@f0400000 {
> +		compatible = "andestech,atcpit100";
> +		reg = <0xf0400000 0x1000>;
> +		interrupts = <2>;
> +		clocks = <&clk_pll>;
> +		clock-names = "apb_pclk";
> +		cycle-count-offset = <0x38>;
> +		cycle-count-down;
> +	};

The cover leter mentioned the atcpit100 driver had been removed, but the
node is still here, and the vdso code seems to look for this node.

This binding needs documentation.

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH v3 17/33] nds32: VDSO support
From: Mark Rutland @ 2017-12-08 10:21 UTC (permalink / raw)
  To: Greentime Hu
  Cc: greentime, linux-kernel, arnd, linux-arch, tglx, jason,
	marc.zyngier, robh+dt, netdev, deanbo422, devicetree, viro,
	dhowells, will.deacon, daniel.lezcano, linux-serial,
	geert.uytterhoeven, linus.walleij, greg, Vincent Chen
In-Reply-To: <921ccfa97c4c13f12c7b22b9554f52dcce51f87e.1512723245.git.green.hu@gmail.com>

On Fri, Dec 08, 2017 at 05:12:00PM +0800, Greentime Hu wrote:
> From: Greentime Hu <greentime@andestech.com>
> 
> This patch adds VDSO support. The VDSO code is currently used for
> sys_rt_sigreturn() and optimised gettimeofday() (using the SoC timer counter).

[...]

> +static int grab_timer_node_info(void)
> +{
> +	struct device_node *timer_node;
> +
> +	timer_node = of_find_node_by_name(NULL, "timer");

Please use a compatible string, rather than matching the timer by name.

It's plausible that you have multiple nodes called "timer" in the DT,
under different parent nodes, and this might not be the device you
think it is. I see your dt in patch 24 has two timer nodes.

It would be best if your clocksource driver exposed some stuct that you
looked at here, so that you're guaranteed to user the same device.

> +	of_property_read_u32(timer_node, "cycle-count-offset",
> +			     &vdso_data->cycle_count_offset);
> +	vdso_data->cycle_count_down =
> +	    of_property_read_bool(timer_node, "cycle-count-down");

... and then you'd only need to parse these in one place, too.

IIUC these are proeprties for the atcpit device, which has no
documentation or driver in this series.

So I'm rather confused as to what's going on here.

> +	return of_address_to_resource(timer_node, 0, &timer_res);
> +}

> +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
> +{

> +	/*Map timer to user space */
> +	vdso_base += PAGE_SIZE;
> +	prot = __pgprot(_PAGE_V | _PAGE_M_UR_KR | _PAGE_D |
> +			_PAGE_G | _PAGE_C_DEV);
> +	ret = io_remap_pfn_range(vma, vdso_base, timer_res.start >> PAGE_SHIFT,
> +				 PAGE_SIZE, prot);
> +	if (ret)
> +		goto up_fail;

Maybe this is fine, but it looks a bit suspicious.

Is it safe to map IO memory to a userspace process like this?

In general that isn't safe, since userspace could access other registers
(if those exist), perform accesses that change the state of hardware, or
make unsupported access types (e.g. unaligned, atomic) that result in
errors the kernel can't handle.

Does none of that apply here?

Thanks,
Mark.

^ permalink raw reply

* Re: [PATCH nf-next RFC,v2 6/6] netfilter: nft_flow_offload: add ndo hooks for hardware offload
From: Florian Westphal @ 2017-12-08 10:18 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: netfilter-devel, netdev, f.fainelli, simon.horman, ronye, jiri,
	nbd, john, kubakici, fw
In-Reply-To: <20171207124501.24325-7-pablo@netfilter.org>

Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> The software flow table garbage collector skips entries that resides in
> the hardware, so the hardware will be responsible for releasing this
> flow table entry too via flow_offload_dead(). In the next garbage
> collector run, this removes the entries both in the software and
> hardware flow table from user context.
> 
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> @Florian: I still owe you one here, you mentioned about inmediate schedule
> of the workqueue thread, and I need to revisit this, the quick patch I made
> is hitting splats when calling queue_delayed_work() from packet path, this
> may be my fault though.

OK. IIRC I had suggested to just use schedule_work() instead.
In most cases (assuming system is busy) the workqueue will already be
pending anyway.

> diff --git a/net/netfilter/nf_flow_table.c b/net/netfilter/nf_flow_table.c
> index ff27dad268c3..c578c3aec0e0 100644
> --- a/net/netfilter/nf_flow_table.c
> +++ b/net/netfilter/nf_flow_table.c
> @@ -212,6 +212,21 @@ int nf_flow_table_iterate(struct nf_flowtable *flow_table,
>  }
>  EXPORT_SYMBOL_GPL(nf_flow_table_iterate);
>  
> +static void flow_offload_hw_del(struct flow_offload *flow)
> +{
> +	struct net_device *indev;
> +	int ret, ifindex;
> +
> +	rtnl_lock();
> +	ifindex = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.iifidx;
> +	indev = __dev_get_by_index(&init_net, ifindex);

I think this should pass struct net * as arg to flow_offload_hw_del.

> +	if (WARN_ON(!indev))
> +		return;
> +
> +	ret = indev->netdev_ops->ndo_flow_offload(FLOW_OFFLOAD_DEL, flow);
> +	rtnl_unlock();
> +}

Please no rtnl lock unless absolutely needed.
Seems this could even avoid the mutex completely by using
dev_get_by_index + dev_put.

> +static int do_flow_offload(struct flow_offload *flow)
> +{
> +	struct net_device *indev;
> +	int ret, ifindex;
> +
> +	rtnl_lock();
> +	ifindex = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.iifidx;
> +	indev = __dev_get_by_index(&init_net, ifindex);

likewise.

> +#define FLOW_HW_WORK_TIMEOUT	msecs_to_jiffies(100)
> +
> +static struct delayed_work nft_flow_offload_dwork;

I would go with struct work and no delay at all.

^ permalink raw reply

* [PATCH iproute v2] tc: util: Don't call NEXT_ARG_FWD() in __parse_action_control()
From: Michal Privoznik @ 2017-12-08 10:18 UTC (permalink / raw)
  To: netdev; +Cc: jiri, stephen

Not all callers want parse_action_control*() to advance the
arguments. For instance act_parse_police() does the argument
advancing itself.

Fixes: e67aba559581 ("tc: actions: add helpers to parse and print control actions")
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
---

Technically, even though this implements different approach, it is v2 of:

http://www.spinics.net/lists/netdev/msg468479.html

 tc/m_bpf.c        |  1 +
 tc/m_connmark.c   |  1 +
 tc/m_csum.c       |  1 +
 tc/m_gact.c       | 10 +++++-----
 tc/m_ife.c        |  1 +
 tc/m_mirred.c     |  4 +++-
 tc/m_nat.c        |  1 +
 tc/m_pedit.c      |  1 +
 tc/m_sample.c     |  1 +
 tc/m_skbedit.c    |  1 +
 tc/m_skbmod.c     |  1 +
 tc/m_tunnel_key.c |  1 +
 tc/m_vlan.c       |  1 +
 tc/tc_util.c      |  1 -
 14 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/tc/m_bpf.c b/tc/m_bpf.c
index 1c1f71cd..576f69cc 100644
--- a/tc/m_bpf.c
+++ b/tc/m_bpf.c
@@ -129,6 +129,7 @@ opt_bpf:
 
 	parse_action_control_dflt(&argc, &argv, &parm.action,
 				  false, TC_ACT_PIPE);
+	NEXT_ARG_FWD();
 
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
diff --git a/tc/m_connmark.c b/tc/m_connmark.c
index 37d71854..47c7a8c2 100644
--- a/tc/m_connmark.c
+++ b/tc/m_connmark.c
@@ -82,6 +82,7 @@ parse_connmark(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 	}
 
 	parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_PIPE);
+	NEXT_ARG_FWD();
 
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
diff --git a/tc/m_csum.c b/tc/m_csum.c
index 7b156734..e1352c08 100644
--- a/tc/m_csum.c
+++ b/tc/m_csum.c
@@ -124,6 +124,7 @@ parse_csum(struct action_util *a, int *argc_p,
 	}
 
 	parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK);
+	NEXT_ARG_FWD();
 
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
diff --git a/tc/m_gact.c b/tc/m_gact.c
index e7d91dab..b30b0420 100644
--- a/tc/m_gact.c
+++ b/tc/m_gact.c
@@ -87,14 +87,13 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
 	if (argc < 0)
 		return -1;
 
-
-	if (matches(*argv, "gact") == 0) {
-		argc--;
-		argv++;
-	} else if (parse_action_control(&argc, &argv, &p.action, false) == -1) {
+	if (matches(*argv, "gact") != 0 &&
+		parse_action_control(&argc, &argv, &p.action, false) == -1) {
 		usage();	/* does not return */
 	}
 
+	NEXT_ARG_FWD();
+
 #ifdef CONFIG_GACT_PROB
 	if (argc > 0) {
 		if (matches(*argv, "random") == 0) {
@@ -114,6 +113,7 @@ parse_gact(struct action_util *a, int *argc_p, char ***argv_p,
 			if (parse_action_control(&argc, &argv,
 						 &pp.paction, false) == -1)
 				usage();
+			NEXT_ARG_FWD();
 			if (get_u16(&pp.pval, *argv, 10)) {
 				fprintf(stderr,
 					"Illegal probability val 0x%x\n",
diff --git a/tc/m_ife.c b/tc/m_ife.c
index 205efc9f..4647f6a6 100644
--- a/tc/m_ife.c
+++ b/tc/m_ife.c
@@ -159,6 +159,7 @@ static int parse_ife(struct action_util *a, int *argc_p, char ***argv_p,
 
 	parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE);
 
+	NEXT_ARG_FWD();
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
 			NEXT_ARG();
diff --git a/tc/m_mirred.c b/tc/m_mirred.c
index 3870d3a4..aa7ce6d9 100644
--- a/tc/m_mirred.c
+++ b/tc/m_mirred.c
@@ -202,8 +202,10 @@ parse_direction(struct action_util *a, int *argc_p, char ***argv_p,
 	}
 
 
-	if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR)
+	if (p.eaction == TCA_EGRESS_MIRROR || p.eaction == TCA_INGRESS_MIRROR) {
 		parse_action_control(&argc, &argv, &p.action, false);
+		NEXT_ARG_FWD();
+	}
 
 	if (argc) {
 		if (iok && matches(*argv, "index") == 0) {
diff --git a/tc/m_nat.c b/tc/m_nat.c
index 1e4ff51f..f5de4d4c 100644
--- a/tc/m_nat.c
+++ b/tc/m_nat.c
@@ -116,6 +116,7 @@ parse_nat(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct
 
 	parse_action_control_dflt(&argc, &argv, &sel.action, false, TC_ACT_OK);
 
+	NEXT_ARG_FWD();
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
 			NEXT_ARG();
diff --git a/tc/m_pedit.c b/tc/m_pedit.c
index 26549eee..dc57f14a 100644
--- a/tc/m_pedit.c
+++ b/tc/m_pedit.c
@@ -672,6 +672,7 @@ int parse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 
 	parse_action_control_dflt(&argc, &argv, &sel.sel.action, false, TC_ACT_OK);
 
+	NEXT_ARG_FWD();
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
 			NEXT_ARG();
diff --git a/tc/m_sample.c b/tc/m_sample.c
index ff5ee6bd..31774c0e 100644
--- a/tc/m_sample.c
+++ b/tc/m_sample.c
@@ -100,6 +100,7 @@ static int parse_sample(struct action_util *a, int *argc_p, char ***argv_p,
 
 	parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE);
 
+	NEXT_ARG_FWD();
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
 			NEXT_ARG();
diff --git a/tc/m_skbedit.c b/tc/m_skbedit.c
index aa374fcb..c41a7bb0 100644
--- a/tc/m_skbedit.c
+++ b/tc/m_skbedit.c
@@ -123,6 +123,7 @@ parse_skbedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 	parse_action_control_dflt(&argc, &argv, &sel.action,
 				  false, TC_ACT_PIPE);
 
+	NEXT_ARG_FWD();
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
 			NEXT_ARG();
diff --git a/tc/m_skbmod.c b/tc/m_skbmod.c
index 561b73fb..bc268dfd 100644
--- a/tc/m_skbmod.c
+++ b/tc/m_skbmod.c
@@ -124,6 +124,7 @@ static int parse_skbmod(struct action_util *a, int *argc_p, char ***argv_p,
 
 	parse_action_control_dflt(&argc, &argv, &p.action, false, TC_ACT_PIPE);
 
+	NEXT_ARG_FWD();
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
 			NEXT_ARG();
diff --git a/tc/m_tunnel_key.c b/tc/m_tunnel_key.c
index 1cdd0356..2dc91879 100644
--- a/tc/m_tunnel_key.c
+++ b/tc/m_tunnel_key.c
@@ -175,6 +175,7 @@ static int parse_tunnel_key(struct action_util *a, int *argc_p, char ***argv_p,
 	parse_action_control_dflt(&argc, &argv, &parm.action,
 				  false, TC_ACT_PIPE);
 
+	NEXT_ARG_FWD();
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
 			NEXT_ARG();
diff --git a/tc/m_vlan.c b/tc/m_vlan.c
index 161759fd..edae0d1e 100644
--- a/tc/m_vlan.c
+++ b/tc/m_vlan.c
@@ -131,6 +131,7 @@ static int parse_vlan(struct action_util *a, int *argc_p, char ***argv_p,
 	parse_action_control_dflt(&argc, &argv, &parm.action,
 				  false, TC_ACT_PIPE);
 
+	NEXT_ARG_FWD();
 	if (argc) {
 		if (matches(*argv, "index") == 0) {
 			NEXT_ARG();
diff --git a/tc/tc_util.c b/tc/tc_util.c
index 18879056..ee9a70aa 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -586,7 +586,6 @@ static int __parse_action_control(int *argc_p, char ***argv_p, int *result_p,
 		}
 		result |= jump_cnt;
 	}
-	NEXT_ARG_FWD();
 	*argc_p = argc;
 	*argv_p = argv;
 	*result_p = result;
-- 
2.13.6

^ permalink raw reply related

* From Precious
From: preciouskazim1@myself.com @ 2017-12-08 10:12 UTC (permalink / raw)


Hello dear,
My name is Precious, I saw your profile  and I became interested in
you, I would also like to know more about you, please contact me with
this email address so that I can give you a so that you know who I am,
because I have something very important to tell you.
Precious.

^ permalink raw reply

* Re: [PATCH nf-next RFC,v2 4/6] netfilter: flow table support for IPv4
From: Florian Westphal @ 2017-12-08 10:04 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: netfilter-devel, netdev, f.fainelli, simon.horman, ronye, jiri,
	nbd, john, kubakici, fw
In-Reply-To: <20171207124501.24325-5-pablo@netfilter.org>

Pablo Neira Ayuso <pablo@netfilter.org> wrote:
> This patch adds the IPv4 flow table type, that implements the datapath
> flow table to forward IPv4 traffic. Rationale is:
> 
> 1) Look up for the packet in the flow table, from the ingress hook.
> 2) If there's a hit, decrement ttl and pass it on to the neighbour layer
>    for transmission.
> 3) If there's a miss, packet is passed up to the classic forwarding
>    path.

Is there a plan to also handle zone IDs in future?

I't going to be messy for sure since we'd need to tell HW how to do
the zone mapping.  Perhaps only support a builtin list, e.g.
vlan id == zone...?

Don't yet see how it could be done in a generic way as the mappings can
be arbitrarily complex.

Right now afaics one could install one flow table per zone and map
this in nft, but then we still miss the part that tells the hardware
how the zone identifier was derived.

> +static bool ip_has_options(unsigned int thoff)
> +{
> +	return thoff > sizeof(struct iphdr);

I'd use
	thoff != sizeof(...)

to catch case where ihl is < struct iphdr.

> +nf_flow_offload_hook(void *priv, struct sk_buff *skb,
> +		     const struct nf_hook_state *state)
> +{
> +	struct flow_offload_tuple_rhash *tuplehash;
> +	struct nf_flowtable *flow_table = priv;
> +	struct flow_offload_tuple tuple = {};
> +	union nf_inet_addr nexthop;
> +	struct flow_offload *flow;
> +	struct net_device *outdev;
> +	struct iphdr *iph;
> +
> +	if (nf_flow_tuple_ip(skb, &tuple) < 0)
> +		return NF_ACCEPT;
> +
> +	tuplehash = flow_offload_lookup(flow_table, &tuple);
> +	if (tuplehash == NULL)
> +		return NF_ACCEPT;
> +
> +	outdev = dev_get_by_index_rcu(&init_net, tuplehash->tuple.oifidx);

state->net ?

^ permalink raw reply

* Re: [PATCH net 2/4] net: aquantia: Fix hardware DMA stream overload on large MRRS
From: Igor Russkikh @ 2017-12-08  9:56 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, darcari, pavel.belous, Nadezhda.Krupnina, simon.edelhaus
In-Reply-To: <20171207.142331.906125407031062563.davem@davemloft.net>

Hi David!

>> +#define pci_reg_control6_adr 0x1014u
>> +
> CPP macros, especially those which define register numbers or bit
> valus, should never use lowercase.  They should always use uppercase
> names.
>
> This is a coding style convention we use in the entire kernel which
> makes it easy to visually see whether something is a bonafide C
> symbol or a CPP macro.

Totally agree on that. I honestly not aware of the history why it was done in lowercase.
I'm now preparing a set of commits for new hardware revisions support, I can queue this task there as well.

Or, if you prefer, I may add this low to uppercase conversion patch into this patchset and resubmit.

BR, Igor

^ permalink raw reply

* Re: [PATCH v4.1] phylib: Add device reset GPIO support
From: Geert Uytterhoeven @ 2017-12-08  9:53 UTC (permalink / raw)
  To: Sergei Shtylyov
  Cc: Geert Uytterhoeven, David S . Miller, Andrew Lunn,
	Florian Fainelli, Simon Horman, Magnus Damm, Rob Herring,
	Mark Rutland, Nicolas Ferre, Richard Leitner,
	netdev@vger.kernel.org, devicetree@vger.kernel.org, Linux-Renesas,
	linux-kernel@vger.kernel.org
In-Reply-To: <69fe9a6d-4039-6f80-b80d-7dc0de31e5bf@cogentembedded.com>

Hi Sergei,

On Thu, Dec 7, 2017 at 6:20 PM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> On 12/04/2017 03:35 PM, Geert Uytterhoeven wrote:
>> From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>> The PHY devices sometimes do have their reset signal (maybe even power
>> supply?) tied to some GPIO and sometimes it also does happen that a boot
>> loader does not leave it deasserted. So far this issue has been attacked
>> from (as I believe) a wrong angle: by teaching the MAC driver to
>> manipulate
>> the GPIO in question; that solution, when applied to the device trees, led
>> to adding the PHY reset GPIO properties to the MAC device node, with one
>> exception: Cadence MACB driver which could handle the "reset-gpios" prop
>> in a PHY device subnode. I believe that the correct approach is to teach
>> the 'phylib' to get the MDIO device reset GPIO from the device tree node
>> corresponding to this device -- which this patch is doing...
>>
>> Note that I had to modify the AT803x PHY driver as it would stop working
>> otherwise -- it made use of the reset GPIO for its own purposes...
>>
>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
>> Acked-by: Rob Herring <robh@kernel.org>
>> [geert: Propagate actual errors from fwnode_get_named_gpiod()]
>> [geert: Avoid destroying initial setup]
>> [geert: Consolidate GPIO descriptor acquiring code]
>> Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
> [...]
>>
>> diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
>> index 2df7b62c1a36811e..8f8b7747c54bc478 100644
>> --- a/drivers/net/phy/mdio_bus.c
>> +++ b/drivers/net/phy/mdio_bus.c
>
> [...]
>>
>> @@ -48,9 +49,26 @@
>>     int mdiobus_register_device(struct mdio_device *mdiodev)
>>   {
>> +       struct gpio_desc *gpiod = NULL;
>> +
>>         if (mdiodev->bus->mdio_map[mdiodev->addr])
>>                 return -EBUSY;
>>   +     /* Deassert the optional reset signal */
>
>
>    Umm, but why deassert it here for such a short time?

That's a consequence of moving it from drivers/of/of_mdio.c to here.
Not that it was deasserted that much longer in drivers/of/of_mdio.c, though...

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply

* Re: [PATCH v5 2/2] sock: Move the socket inuse to namespace.
From: Tonghao Zhang @ 2017-12-08  9:52 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David Miller, Cong Wang, Eric Dumazet, Willem de Bruijn,
	Linux Kernel Network Developers
In-Reply-To: <1512711658.25033.23.camel@gmail.com>

On Fri, Dec 8, 2017 at 1:40 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Fri, 2017-12-08 at 13:28 +0800, Tonghao Zhang wrote:
>> On Fri, Dec 8, 2017 at 1:20 AM, Eric Dumazet <eric.dumazet@gmail.com>
>> wrote:
>> > On Thu, 2017-12-07 at 08:45 -0800, Tonghao Zhang wrote:
>> > > In some case, we want to know how many sockets are in use in
>> > > different _net_ namespaces. It's a key resource metric.
>> > >
>> >
>> > ...
>> >
>> > > +static void sock_inuse_add(struct net *net, int val)
>> > > +{
>> > > +     if (net->core.prot_inuse)
>> > > +             this_cpu_add(*net->core.sock_inuse, val);
>> > > +}
>> >
>> > This is very confusing.
>> >
>> > Why testing net->core.prot_inuse for NULL is needed at all ?
>> >
>> > Why not testing net->core.sock_inuse instead ?
>> >
>>
>> Hi Eric and Cong, oh it's a typo. it's net->core.sock_inuse there.
>> Why
>> we should check the net->core.sock_inuse
>> Now show you the code:
>>
>> cleanup_net will call all of the network namespace exit methods,
>> rcu_barrier, and then remove the _net_ namespace.
>>
>> cleanup_net:
>>     list_for_each_entry_reverse(ops, &pernet_list, list)
>>          ops_exit_list(ops, &net_exit_list);
>>
>>     rcu_barrier(); /* for netlink sock, the ‘deferred_put_nlk_sk’
>> will
>> be called. But sock_inuse has been released. */
>
>
> Thats would be a bug.
>
> Please find another way, but we want ultimately to check that before
> net->core.sock_inuse is freed, folding the inuse count on all cpus is
> 0, to make sure we do not have a bug somewhere.

Yes, I am aware of this issue even we will destroy the network namespace.
By the way, we can counter the socket-inuse in sock_alloc or sock_release.
In this way, we have to hold the network namespace again(via
get_net()) while sock
may hold it.

what do you think of this idea?

> We should not have to test if net->core.sock_inuse is NULL or not from
> sock_inuse_add(). Pointer must be there all the time.
>
> The freeing should only happen once we are sure sock_inuse_add() can
> not be called anymore.
>
>>
>>
>>     /* Finally it is safe to free my network namespace structure */
>>     list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {}
>>
>>
>>
>> Release the netlink sock created in kernel(not hold the _net_
>> namespace):
>>
>> netlink_release
>>        call_rcu(&nlk->rcu, deferred_put_nlk_sk);
>>
>> deferred_put_nlk_sk
>>        sk_free(sk);
>>
>>
>> I may add a comment for sock_inuse_add in v6.
>
>

^ permalink raw reply

* Re: [PATCH net 3/4] net: aquantia: Improve and fix statistics on device
From: Igor Russkikh @ 2017-12-08  9:43 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: David S . Miller, netdev, David Arcari, Pavel Belous,
	Nadezhda Krupnina, Simon Edelhaus
In-Reply-To: <20171207190830.GB7240@lunn.ch>

Hi Andrew,

>> 1) Device hardware provides only 32bit counters. Using these directly
>> causes byte counters to overflow soon. A separate nic level structure
>> with 64 bit counters is now used to collect incrementally all the stats
>> and report these counters to ethtool stats and ndev stats.
>>
>> 2) ndev stats were filled from ring counters. These sometimes incorrectly
>> calculate byte and packet amounts when using LRO/LSO and jumboframes.
>> Fill ndev counters from hardware makes them precise.
>>
>> 3) Fill in multicast counter in ndev stats from hardware counter
>>
>> 4) Improve link state and statistics check interval callback: reduce normal
>> timeout from 2 secs to 1 sec. If link is down, reduce it to 500msec. This
>> speeds up link detection.
>>
>> 5) Reset driver level statistics to zero on initialization
>>
>> 6) Fix typo in ethtool statistics names
> Hi Igor
>
> This list suggests there should actually be 6 patches, not one.
>
1,2 and 3 are tightly linked and are difficult to separate.

4, 5 and 6 are small, agree I can split them.

BR, Igor

^ permalink raw reply

* [PATCH v3 29/33] dt-bindings: nds32 CPU Bindings
From: Greentime Hu @ 2017-12-08  9:12 UTC (permalink / raw)
  To: greentime, linux-kernel, arnd, linux-arch, tglx, jason,
	marc.zyngier, robh+dt, netdev, deanbo422, devicetree, viro,
	dhowells, will.deacon, daniel.lezcano, linux-serial,
	geert.uytterhoeven, linus.walleij, mark.rutland, greg
  Cc: green.hu, Vincent Chen, Rick Chen, Zong Li
In-Reply-To: <cover.1512723245.git.green.hu@gmail.com>

From: Greentime Hu <greentime@andestech.com>

This patch adds nds32 CPU binding documents.

Signed-off-by: Vincent Chen <vincentc@andestech.com>
Signed-off-by: Rick Chen <rick@andestech.com>
Signed-off-by: Zong Li <zong@andestech.com>
Signed-off-by: Greentime Hu <greentime@andestech.com>
---
 Documentation/devicetree/bindings/nds32/cpus.txt |   37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nds32/cpus.txt

diff --git a/Documentation/devicetree/bindings/nds32/cpus.txt b/Documentation/devicetree/bindings/nds32/cpus.txt
new file mode 100644
index 0000000..9a52937
--- /dev/null
+++ b/Documentation/devicetree/bindings/nds32/cpus.txt
@@ -0,0 +1,37 @@
+* Andestech Processor Binding
+
+This binding specifies what properties must be available in the device tree
+representation of a Andestech Processor Core, which is the root node in the
+tree.
+
+Required properties:
+
+	- compatible:
+		Usage: required
+		Value type: <string>
+		Definition: should be one of:
+			"andestech,n13"
+			"andestech,n15"
+			"andestech,d15"
+			"andestech,n10"
+			"andestech,d10"
+			"andestech,nds32v3"
+	- device_type
+		Usage: required
+		Value type: <string>
+		Definition: must be "cpu"
+	- reg: Contains CPU index.
+	- clock-frequency: Contains the clock frequency for CPU, in Hz.
+
+* Examples
+
+/ {
+	cpus {
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "andestech,n13", "andestech,nds32v3";
+			reg = <0x0>;
+			clock-frequency = <60000000>
+		};
+	};
+};
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 26/33] nds32: defconfig
From: Greentime Hu @ 2017-12-08  9:12 UTC (permalink / raw)
  To: greentime, linux-kernel, arnd, linux-arch, tglx, jason,
	marc.zyngier, robh+dt, netdev, deanbo422, devicetree, viro,
	dhowells, will.deacon, daniel.lezcano, linux-serial,
	geert.uytterhoeven, linus.walleij, mark.rutland, greg
  Cc: green.hu, Vincent Chen
In-Reply-To: <cover.1512723245.git.green.hu@gmail.com>

From: Greentime Hu <greentime@andestech.com>

This patch adds nds32 defconfig.

Signed-off-by: Vincent Chen <vincentc@andestech.com>
Signed-off-by: Greentime Hu <greentime@andestech.com>
---
 arch/nds32/configs/defconfig |  108 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)
 create mode 100644 arch/nds32/configs/defconfig

diff --git a/arch/nds32/configs/defconfig b/arch/nds32/configs/defconfig
new file mode 100644
index 0000000..069ebe6
--- /dev/null
+++ b/arch/nds32/configs/defconfig
@@ -0,0 +1,108 @@
+CONFIG_CROSS_COMPILE="nds32le-linux-"
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_USER_NS=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_CACHE_L2 is not set
+CONFIG_VMSPLIT_3G_OPT=y
+CONFIG_PREEMPT=y
+# CONFIG_COMPACTION is not set
+CONFIG_HZ_100=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_FTMAC100=y
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_RC_CORE is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_A4TECH is not set
+# CONFIG_HID_APPLE is not set
+# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CHERRY is not set
+# CONFIG_HID_CHICONY is not set
+# CONFIG_HID_CYPRESS is not set
+# CONFIG_HID_EZKEY is not set
+# CONFIG_HID_ITE is not set
+# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_CLKSRC_ATCPIT100=y
+CONFIG_GENERIC_PHY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_ENCRYPTION=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_USE_LEGACY_DNS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_DWARF4=y
+CONFIG_GDB_SCRIPTS=y
+CONFIG_READABLE_ASM=y
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_SECTION_MISMATCH=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_STACKTRACE=y
+CONFIG_RCU_CPU_STALL_TIMEOUT=300
+# CONFIG_CRYPTO_HW is not set
-- 
1.7.9.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox