Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 7/7] net/mlx4_core: Support more than 64 VFs
From: Or Gerlitz @ 2014-11-13 12:45 UTC (permalink / raw)
  To: David S. Miller
  Cc: netdev, Matan Barak, Amir Vadai, Jack Morgenstein, Or Gerlitz
In-Reply-To: <1415882733-3084-1-git-send-email-ogerlitz@mellanox.com>

From: Matan Barak <matanb@mellanox.com>

We now allow up to 126 VFs. Note though that certain firmware
versions only allow up to 80 VFs. Moreover, old HCAs only support 64 VFs.
In these cases, we limit the maximum number of VFs to 64.

Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx4/fw.c   |    5 ++++-
 drivers/net/ethernet/mellanox/mlx4/main.c |   24 ++++++++++++++++++++++++
 include/linux/mlx4/device.h               |    5 +++--
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index d2f594f..4251f81 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -143,7 +143,8 @@ static void dump_dev_cap_flags2(struct mlx4_dev *dev, u64 flags)
 		[14] = "Ethernet protocol control support",
 		[15] = "Ethernet Backplane autoneg support",
 		[16] = "CONFIG DEV support",
-		[17] = "Asymmetric EQs support"
+		[17] = "Asymmetric EQs support",
+		[18] = "More than 80 VFs support"
 	};
 	int i;
 
@@ -860,6 +861,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 		dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_VLAN_CONTROL;
 	if (field32 & (1 << 20))
 		dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_FSM;
+	if (field32 & (1 << 21))
+		dev_cap->flags2 |= MLX4_DEV_CAP_FLAG2_80_VFS;
 
 	if (dev->flags & MLX4_FLAG_OLD_PORT_CMDS) {
 		for (i = 1; i <= dev_cap->num_ports; ++i) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index ebb2790..3044f9e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2373,6 +2373,24 @@ disable_sriov:
 	return dev_flags & ~MLX4_FLAG_MASTER;
 }
 
+enum {
+	MLX4_DEV_CAP_CHECK_NUM_VFS_ABOVE_64 = -1,
+};
+
+static int mlx4_check_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap,
+			      int *nvfs)
+{
+	int requested_vfs = nvfs[0] + nvfs[1] + nvfs[2];
+	/* Checking for 64 VFs as a limitation of CX2 */
+	if (!(dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_80_VFS) &&
+	    requested_vfs >= 64) {
+		mlx4_err(dev, "Requested %d VFs, but FW does not support more than 64\n",
+			 requested_vfs);
+		return MLX4_DEV_CAP_CHECK_NUM_VFS_ABOVE_64;
+	}
+	return 0;
+}
+
 static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data,
 			 int total_vfs, int *nvfs, struct mlx4_priv *priv)
 {
@@ -2484,6 +2502,9 @@ slave_start:
 				goto err_fw;
 			}
 
+			if (mlx4_check_dev_cap(dev, dev_cap, nvfs))
+				goto err_fw;
+
 			if (!(dev_cap->flags2 & MLX4_DEV_CAP_FLAG2_SYS_EQS)) {
 				u64 dev_flags = mlx4_enable_sriov(dev, pdev, total_vfs,
 								  existing_vfs);
@@ -2512,6 +2533,9 @@ slave_start:
 				mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n");
 				goto err_fw;
 			}
+
+			if (mlx4_check_dev_cap(dev, dev_cap, nvfs))
+				goto err_fw;
 		}
 	}
 
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h
index 1c560eb..cf09e65 100644
--- a/include/linux/mlx4/device.h
+++ b/include/linux/mlx4/device.h
@@ -95,7 +95,7 @@ enum {
 
 enum {
 	MLX4_MAX_NUM_PF		= 16,
-	MLX4_MAX_NUM_VF		= 64,
+	MLX4_MAX_NUM_VF		= 126,
 	MLX4_MAX_NUM_VF_P_PORT  = 64,
 	MLX4_MFUNC_MAX		= 80,
 	MLX4_MAX_EQ_NUM		= 1024,
@@ -190,7 +190,8 @@ enum {
 	MLX4_DEV_CAP_FLAG2_ETH_PROT_CTRL        = 1LL <<  14,
 	MLX4_DEV_CAP_FLAG2_ETH_BACKPL_AN_REP	= 1LL <<  15,
 	MLX4_DEV_CAP_FLAG2_CONFIG_DEV		= 1LL <<  16,
-	MLX4_DEV_CAP_FLAG2_SYS_EQS		= 1LL <<  17
+	MLX4_DEV_CAP_FLAG2_SYS_EQS		= 1LL <<  17,
+	MLX4_DEV_CAP_FLAG2_80_VFS		= 1LL <<  18
 };
 
 enum {
-- 
1.7.1

^ permalink raw reply related

* Re: arm64 allmodconfig failures in nft_reject_bridge.c
From: Mark Brown @ 2014-11-13 12:51 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: David S. Miller, Guenter Roeck, Patrick McHardy, Jozsef Kadlecsik,
	Stephen Hemminger, linaro-kernel, kernel-build-reports,
	netfilter-devel, coreteam, bridge, netdev
In-Reply-To: <20141113114357.GA7857@salvia>

[-- Attachment #1: Type: text/plain, Size: 450 bytes --]

On Thu, Nov 13, 2014 at 12:43:57PM +0100, Pablo Neira Ayuso wrote:

> I can see this in David's tree:

> http://git.kernel.org/cgit/linux/kernel/git/davem/net.git/commit/?id=c1207c049b204b0a96535dc5416aee331b51e0e1

> I think this was reported by when -rc4 was already out, so you'll see
> this by -rc5.

The fix predates -rc4 (sent on the 2nd, committed on the 3rd, -rc4 was
on the 9th), I'd been expecting to see it turn up there or shortly
after.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply

* Re: [PATCH v5 6/8] net: can: c_can: Disable pins when CAN interface is down
From: Marc Kleine-Budde @ 2014-11-13 12:56 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
	sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <54636BD0.2010208@ti.com>

[-- Attachment #1: Type: text/plain, Size: 4856 bytes --]

On 11/12/2014 03:16 PM, Roger Quadros wrote:
> DRA7 CAN IP suffers from a problem which causes it to be prevented
> from fully turning OFF (i.e. stuck in transition) if the module was
> disabled while there was traffic on the CAN_RX line.
> 
> To work around this issue we select the SLEEP pin state by default
> on probe and use the DEFAULT pin state on CAN up and back to the
> SLEEP pin state on CAN down.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  drivers/net/can/c_can/c_can.c          | 21 +++++++++++++++++++++
>  drivers/net/can/c_can/c_can.h          |  1 +
>  drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
>  3 files changed, 42 insertions(+)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 8e78bb4..a950eea 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -35,6 +35,7 @@
>  #include <linux/list.h>
>  #include <linux/io.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/pinctrl/consumer.h>
>  
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
> @@ -587,6 +588,21 @@ static int c_can_chip_config(struct net_device *dev)
>  	return c_can_set_bittiming(dev);
>  }
>  
> +/*
> + * Selects the pinctrl state specified in the name.
> + */
> +static void c_can_pinctrl_select_state(struct c_can_priv *priv,
> +				      const char *name)
> +{
> +	if (!IS_ERR(priv->pinctrl)) {

What happens if priv->pinctrl is NULL? This is probably the case with
the c_can_pci driver.

> +		struct pinctrl_state *s;
> +
> +		s = pinctrl_lookup_state(priv->pinctrl, name);
> +		if (!IS_ERR(s))
> +			pinctrl_select_state(priv->pinctrl, s);
> +	}
> +}
> +
>  static int c_can_start(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
> @@ -603,6 +619,8 @@ static int c_can_start(struct net_device *dev)
>  
>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>  
> +	/* activate pins */
> +	c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT);
>  	return 0;
>  }
>  
> @@ -611,6 +629,9 @@ static void c_can_stop(struct net_device *dev)
>  	struct c_can_priv *priv = netdev_priv(dev);
>  
>  	c_can_irq_control(priv, false);
> +
> +	/* deactivate pins */
> +	c_can_pinctrl_select_state(priv, PINCTRL_STATE_SLEEP);
>  	priv->can.state = CAN_STATE_STOPPED;
>  }
>  
> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
> index c6715ca..3cedf48 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -210,6 +210,7 @@ struct c_can_priv {
>  	u32 comm_rcv_high;
>  	u32 rxmasked;
>  	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
> +	struct pinctrl *pinctrl;
>  };
>  
>  struct net_device *alloc_c_can_dev(void);
> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
> index b838c6b..71b9063 100644
> --- a/drivers/net/can/c_can/c_can_platform.c
> +++ b/drivers/net/can/c_can/c_can_platform.c
> @@ -34,6 +34,7 @@
>  #include <linux/of_device.h>
>  #include <linux/mfd/syscon.h>
>  #include <linux/regmap.h>
> +#include <linux/pinctrl/consumer.h>
>  
>  #include <linux/can/dev.h>
>  
> @@ -230,6 +231,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  	struct clk *clk;
>  	const struct c_can_driver_data *drvdata;
>  	struct device_node *np = pdev->dev.of_node;
> +	struct pinctrl *pinctrl;
>  
>  	match = of_match_device(c_can_of_table, &pdev->dev);
>  	if (match) {
> @@ -241,6 +243,23 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> +	pinctrl = devm_pinctrl_get(&pdev->dev);
> +	if (!IS_ERR(pinctrl)) {
> +		struct pinctrl_state *s;
> +
> +		/* Deactivate pins to prevent DRA7 DCAN IP from being
> +		 * stuck in transition when module is disabled.
> +		 * Pins are activated in c_can_start() and deactivated
> +		 * in c_can_stop()
> +		 */
> +		s = pinctrl_lookup_state(pinctrl, PINCTRL_STATE_SLEEP);
> +		if (!IS_ERR(s))
> +			pinctrl_select_state(pinctrl, s);
> +	} else {
> +		dev_warn(&pdev->dev,
> +			 "failed to get pinctrl\n");
> +	}

Can you move the initial setting into c_can.c, register_c_can_dev()
should be a good candidate.

> +
>  	/* get the appropriate clk */
>  	clk = devm_clk_get(&pdev->dev, NULL);
>  	if (IS_ERR(clk)) {
> @@ -270,6 +289,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
>  	}
>  
>  	priv = netdev_priv(dev);
> +	priv->pinctrl = pinctrl;
>  
>  	switch (drvdata->id) {
>  	case BOSCH_C_CAN:
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCH v4 4/8] net: can: c_can: Add syscon/regmap RAMINIT mechanism
From: Marc Kleine-Budde @ 2014-11-13 12:58 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
	sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <54649F66.8090305@ti.com>

[-- Attachment #1: Type: text/plain, Size: 1003 bytes --]

On 11/13/2014 01:09 PM, Roger Quadros wrote:
>> What about the existing device trees that don't have the syscon-raminit
>> phandle? We can either keep the existing init routines or create regmap
>> in the platform driver an use the new ones.
> 
> There is only one user
> arch/arm/boot/dts/am33xx.dtsi
> 
> The can nodes are disabled there and no other board file is enabling that node.
> So there is no breakage as such and not worth the hassle to maintain the old routine.
> 
> I will be sending the corresponding dts changes today which Tony will take as we don't see
> any DT binding changes.

Alright then (I'll give your email to $CUSTOMERS complaining ;) ), this
whole series will go into 3.19.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCH v5 6/8] net: can: c_can: Disable pins when CAN interface is down
From: Roger Quadros @ 2014-11-13 13:04 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
	sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <5464AA61.4080606@pengutronix.de>

On 11/13/2014 02:56 PM, Marc Kleine-Budde wrote:
> On 11/12/2014 03:16 PM, Roger Quadros wrote:
>> DRA7 CAN IP suffers from a problem which causes it to be prevented
>> from fully turning OFF (i.e. stuck in transition) if the module was
>> disabled while there was traffic on the CAN_RX line.
>>
>> To work around this issue we select the SLEEP pin state by default
>> on probe and use the DEFAULT pin state on CAN up and back to the
>> SLEEP pin state on CAN down.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  drivers/net/can/c_can/c_can.c          | 21 +++++++++++++++++++++
>>  drivers/net/can/c_can/c_can.h          |  1 +
>>  drivers/net/can/c_can/c_can_platform.c | 20 ++++++++++++++++++++
>>  3 files changed, 42 insertions(+)
>>
>> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
>> index 8e78bb4..a950eea 100644
>> --- a/drivers/net/can/c_can/c_can.c
>> +++ b/drivers/net/can/c_can/c_can.c
>> @@ -35,6 +35,7 @@
>>  #include <linux/list.h>
>>  #include <linux/io.h>
>>  #include <linux/pm_runtime.h>
>> +#include <linux/pinctrl/consumer.h>
>>  
>>  #include <linux/can.h>
>>  #include <linux/can/dev.h>
>> @@ -587,6 +588,21 @@ static int c_can_chip_config(struct net_device *dev)
>>  	return c_can_set_bittiming(dev);
>>  }
>>  
>> +/*
>> + * Selects the pinctrl state specified in the name.
>> + */
>> +static void c_can_pinctrl_select_state(struct c_can_priv *priv,
>> +				      const char *name)
>> +{
>> +	if (!IS_ERR(priv->pinctrl)) {
> 
> What happens if priv->pinctrl is NULL? This is probably the case with
> the c_can_pci driver.

There will be a NULL pointer dereference error. :(

> 
>> +		struct pinctrl_state *s;
>> +
>> +		s = pinctrl_lookup_state(priv->pinctrl, name);
>> +		if (!IS_ERR(s))
>> +			pinctrl_select_state(priv->pinctrl, s);
>> +	}
>> +}
>> +
>>  static int c_can_start(struct net_device *dev)
>>  {
>>  	struct c_can_priv *priv = netdev_priv(dev);
>> @@ -603,6 +619,8 @@ static int c_can_start(struct net_device *dev)
>>  
>>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>>  
>> +	/* activate pins */
>> +	c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT);
>>  	return 0;
>>  }
>>  
>> @@ -611,6 +629,9 @@ static void c_can_stop(struct net_device *dev)
>>  	struct c_can_priv *priv = netdev_priv(dev);
>>  
>>  	c_can_irq_control(priv, false);
>> +
>> +	/* deactivate pins */
>> +	c_can_pinctrl_select_state(priv, PINCTRL_STATE_SLEEP);
>>  	priv->can.state = CAN_STATE_STOPPED;
>>  }
>>  
>> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
>> index c6715ca..3cedf48 100644
>> --- a/drivers/net/can/c_can/c_can.h
>> +++ b/drivers/net/can/c_can/c_can.h
>> @@ -210,6 +210,7 @@ struct c_can_priv {
>>  	u32 comm_rcv_high;
>>  	u32 rxmasked;
>>  	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
>> +	struct pinctrl *pinctrl;
>>  };
>>  
>>  struct net_device *alloc_c_can_dev(void);
>> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
>> index b838c6b..71b9063 100644
>> --- a/drivers/net/can/c_can/c_can_platform.c
>> +++ b/drivers/net/can/c_can/c_can_platform.c
>> @@ -34,6 +34,7 @@
>>  #include <linux/of_device.h>
>>  #include <linux/mfd/syscon.h>
>>  #include <linux/regmap.h>
>> +#include <linux/pinctrl/consumer.h>
>>  
>>  #include <linux/can/dev.h>
>>  
>> @@ -230,6 +231,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
>>  	struct clk *clk;
>>  	const struct c_can_driver_data *drvdata;
>>  	struct device_node *np = pdev->dev.of_node;
>> +	struct pinctrl *pinctrl;
>>  
>>  	match = of_match_device(c_can_of_table, &pdev->dev);
>>  	if (match) {
>> @@ -241,6 +243,23 @@ static int c_can_plat_probe(struct platform_device *pdev)
>>  		return -ENODEV;
>>  	}
>>  
>> +	pinctrl = devm_pinctrl_get(&pdev->dev);
>> +	if (!IS_ERR(pinctrl)) {
>> +		struct pinctrl_state *s;
>> +
>> +		/* Deactivate pins to prevent DRA7 DCAN IP from being
>> +		 * stuck in transition when module is disabled.
>> +		 * Pins are activated in c_can_start() and deactivated
>> +		 * in c_can_stop()
>> +		 */
>> +		s = pinctrl_lookup_state(pinctrl, PINCTRL_STATE_SLEEP);
>> +		if (!IS_ERR(s))
>> +			pinctrl_select_state(pinctrl, s);
>> +	} else {
>> +		dev_warn(&pdev->dev,
>> +			 "failed to get pinctrl\n");
>> +	}
> 
> Can you move the initial setting into c_can.c, register_c_can_dev()
> should be a good candidate.

OK. This should also address the NULL pointer issue you pointed out earlier with c_can_pci.

cheers,
-roger


> 
>> +
>>  	/* get the appropriate clk */
>>  	clk = devm_clk_get(&pdev->dev, NULL);
>>  	if (IS_ERR(clk)) {
>> @@ -270,6 +289,7 @@ static int c_can_plat_probe(struct platform_device *pdev)
>>  	}
>>  
>>  	priv = netdev_priv(dev);
>> +	priv->pinctrl = pinctrl;
>>  
>>  	switch (drvdata->id) {
>>  	case BOSCH_C_CAN:
>>
> 
> Marc
> 

^ permalink raw reply

* Re: [PATCH v4 4/8] net: can: c_can: Add syscon/regmap RAMINIT mechanism
From: Roger Quadros @ 2014-11-13 13:07 UTC (permalink / raw)
  To: Marc Kleine-Budde, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
	sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <5464A79F.1070304@pengutronix.de>

On 11/13/2014 02:44 PM, Marc Kleine-Budde wrote:
> On 11/07/2014 03:49 PM, Roger Quadros wrote:
>> Some TI SoCs like DRA7 have a RAMINIT register specification
>> different from the other AMxx SoCs and as expected by the
>> existing driver.
>>
>> To add more insanity, this register is shared with other
>> IPs like DSS, PCIe and PWM.
>>
>> Provides a more generic mechanism to specify the RAMINIT
>> register location and START/DONE bit position and use the
>> syscon/regmap framework to access the register.
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  .../devicetree/bindings/net/can/c_can.txt          |   3 +
>>  drivers/net/can/c_can/c_can.h                      |  11 +-
>>  drivers/net/can/c_can/c_can_platform.c             | 112 ++++++++++++++-------
>>  3 files changed, 86 insertions(+), 40 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/net/can/c_can.txt b/Documentation/devicetree/bindings/net/can/c_can.txt
>> index 8f1ae81..a3ca3ee 100644
>> --- a/Documentation/devicetree/bindings/net/can/c_can.txt
>> +++ b/Documentation/devicetree/bindings/net/can/c_can.txt
>> @@ -12,6 +12,9 @@ Required properties:
>>  Optional properties:
>>  - ti,hwmods		: Must be "d_can<n>" or "c_can<n>", n being the
>>  			  instance number
>> +- syscon-raminit	: Handle to system control region that contains the
>> +			  RAMINIT register, register offset to the RAMINIT
>> +			  register and the CAN instance number (0 offset).
>>  
>>  Note: "ti,hwmods" field is used to fetch the base address and irq
>>  resources from TI, omap hwmod data base during device registration.
>> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
>> index 3c305a1..0e17c7b 100644
>> --- a/drivers/net/can/c_can/c_can.h
>> +++ b/drivers/net/can/c_can/c_can.h
>> @@ -179,6 +179,14 @@ struct c_can_driver_data {
>>  	bool raminit_pulse;	/* If set, sets and clears START bit (pulse) */
>>  };
>>  
>> +/* Out of band RAMINIT register access via syscon regmap */
>> +struct c_can_raminit {
>> +	struct regmap *syscon;	/* for raminit ctrl. reg. access */
>> +	unsigned int reg;	/* register index within syscon */
>> +	u8 start_bit;
>> +	u8 done_bit;
>> +};
>> +
>>  /* c_can private data structure */
>>  struct c_can_priv {
>>  	struct can_priv can;	/* must be the first member */
>> @@ -196,8 +204,7 @@ struct c_can_priv {
>>  	const u16 *regs;
>>  	void *priv;		/* for board-specific data */
>>  	enum c_can_dev_id type;
>> -	u32 __iomem *raminit_ctrlreg;
>> -	int instance;
>> +	struct c_can_raminit raminit_sys;	/* RAMINIT via syscon regmap */
>>  	void (*raminit) (const struct c_can_priv *priv, bool enable);
>>  	u32 comm_rcv_high;
>>  	u32 rxmasked;
>> diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
>> index 20deb67..3776483 100644
>> --- a/drivers/net/can/c_can/c_can_platform.c
>> +++ b/drivers/net/can/c_can/c_can_platform.c
>> @@ -32,14 +32,13 @@
>>  #include <linux/clk.h>
>>  #include <linux/of.h>
>>  #include <linux/of_device.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/regmap.h>
>>  
>>  #include <linux/can/dev.h>
>>  
>>  #include "c_can.h"
>>  
>> -#define CAN_RAMINIT_START_MASK(i)	(0x001 << (i))
>> -#define CAN_RAMINIT_DONE_MASK(i)	(0x100 << (i))
>> -#define CAN_RAMINIT_ALL_MASK(i)		(0x101 << (i))
>>  #define DCAN_RAM_INIT_BIT		(1 << 3)
>>  static DEFINE_SPINLOCK(raminit_lock);
>>  /*
>> @@ -72,47 +71,61 @@ static void c_can_plat_write_reg_aligned_to_32bit(const struct c_can_priv *priv,
>>  	writew(val, priv->base + 2 * priv->regs[index]);
>>  }
>>  
>> -static void c_can_hw_raminit_wait_ti(const struct c_can_priv *priv, u32 mask,
>> -				  u32 val)
>> +static void c_can_hw_raminit_wait_syscon(const struct c_can_priv *priv,
>> +					 u32 mask, u32 val)
>>  {
>>  	int timeout = 0;
>> +	const struct c_can_raminit *raminit = &priv->raminit_sys;
>> +	u32 ctrl;
>> +
>>  	/* We look only at the bits of our instance. */
>>  	val &= mask;
>> -	while ((readl(priv->raminit_ctrlreg) & mask) != val) {
>> +	do {
>>  		udelay(1);
>>  		timeout++;
>>  
>> +		regmap_read(raminit->syscon, raminit->reg, &ctrl);
>>  		if (timeout == 1000) {
>>  			dev_err(&priv->dev->dev, "%s: time out\n", __func__);
>>  			break;
>>  		}
>> -	}
>> +	} while ((ctrl & mask) != val);
>>  }
>>  
>> -static void c_can_hw_raminit_ti(const struct c_can_priv *priv, bool enable)
>> +static void c_can_hw_raminit_syscon(const struct c_can_priv *priv, bool enable)
>>  {
>> -	u32 mask = CAN_RAMINIT_ALL_MASK(priv->instance);
>> +	u32 mask;
>>  	u32 ctrl;
>> +	const struct c_can_raminit *raminit = &priv->raminit_sys;
>> +	u8 start_bit, done_bit;
>> +
>> +	start_bit = raminit->start_bit;
>> +	done_bit = raminit->done_bit;
>>  
>>  	spin_lock(&raminit_lock);
>>  
>> -	ctrl = readl(priv->raminit_ctrlreg);
>> +	mask = 1 << start_bit | 1 << done_bit;
>> +	regmap_read(raminit->syscon, raminit->reg, &ctrl);
>> +
>>  	/* We clear the done and start bit first. The start bit is
>>  	 * looking at the 0 -> transition, but is not self clearing;
>>  	 * And we clear the init done bit as well.
>> +	 * NOTE: DONE must be written with 1 to clear it.
>>  	 */
>> -	ctrl &= ~CAN_RAMINIT_START_MASK(priv->instance);
>> -	ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
>> -	writel(ctrl, priv->raminit_ctrlreg);
>> -	ctrl &= ~CAN_RAMINIT_DONE_MASK(priv->instance);
>> -	c_can_hw_raminit_wait_ti(priv, mask, ctrl);
>> +	ctrl &= ~(1 << start_bit);
>> +	ctrl |= 1 << done_bit;
>> +	regmap_write(raminit->syscon, raminit->reg, ctrl);
>> +
>> +	ctrl &= ~(1 << done_bit);
>> +	c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
>>  
>>  	if (enable) {
>>  		/* Set start bit and wait for the done bit. */
>> -		ctrl |= CAN_RAMINIT_START_MASK(priv->instance);
>> -		writel(ctrl, priv->raminit_ctrlreg);
>> -		ctrl |= CAN_RAMINIT_DONE_MASK(priv->instance);
>> -		c_can_hw_raminit_wait_ti(priv, mask, ctrl);
>> +		ctrl |= 1 << start_bit;
>> +		regmap_write(raminit->syscon, raminit->reg, ctrl);
>> +
>> +		ctrl |= 1 << done_bit;
>> +		c_can_hw_raminit_wait_syscon(priv, mask, ctrl);
>>  	}
>>  	spin_unlock(&raminit_lock);
>>  }
>> @@ -206,10 +219,11 @@ static int c_can_plat_probe(struct platform_device *pdev)
>>  	struct net_device *dev;
>>  	struct c_can_priv *priv;
>>  	const struct of_device_id *match;
>> -	struct resource *mem, *res;
>> +	struct resource *mem;
>>  	int irq;
>>  	struct clk *clk;
>>  	const struct c_can_driver_data *drvdata;
>> +	struct device_node *np = pdev->dev.of_node;
>>  
>>  	match = of_match_device(c_can_of_table, &pdev->dev);
>>  	if (match) {
>> @@ -278,27 +292,49 @@ static int c_can_plat_probe(struct platform_device *pdev)
>>  		priv->read_reg32 = d_can_plat_read_reg32;
>>  		priv->write_reg32 = d_can_plat_write_reg32;
>>  
>> -		if (pdev->dev.of_node)
>> -			priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
>> -		else
>> -			priv->instance = pdev->id;
>> -
>> -		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>> -		/* Not all D_CAN modules have a separate register for the D_CAN
>> -		 * RAM initialization. Use default RAM init bit in D_CAN module
>> -		 * if not specified in DT.
>> +		/* Check if we need custom RAMINIT via syscon. Mostly for TI
>> +		 * platforms. Only supported with DT boot.
>>  		 */
>> -		if (!res) {
>> +		if (np && of_property_read_bool(np, "syscon-raminit")) {
>> +			u32 id;
>> +			struct c_can_raminit *raminit = &priv->raminit_sys;
>> +
>> +			ret = -EINVAL;
>> +			raminit->syscon = syscon_regmap_lookup_by_phandle(np,
>> +									  "syscon-raminit");
> 
> You should return PTR_ERR() here, as it it might be -EPROBE_DEFER

Good catch.

> 
>> +			if (IS_ERR(raminit->syscon)) {
>> +				dev_err(&pdev->dev,
>> +					"couldn't get syscon regmap for RAMINIT\n");
>> +				goto exit_free_device;
>> +			}
> 
> ...and maybe remove this error message completely.

OK.

cheers,
-roger


^ permalink raw reply

* Partnership Proposal
From: Ronald @ 2014-11-13  8:55 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 163 bytes --]

Partnership Proposal: Please read attachment for details. If you are
interested, reply me through this email: ronthwala@admin.in.th
My regards,
Mr. Ronald Thwala.

[-- Attachment #2: RONALD.pdf --]
[-- Type: application/pdf, Size: 3771 bytes --]

^ permalink raw reply

* Re: [PATCH nf] netfilter: conntrack: fix race in __nf_conntrack_confirm against get_next_corpse
From: Jörg Marx @ 2014-11-13 14:33 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: Jesper Dangaard Brouer, programme110, netfilter-devel,
	Florian Westphal, netdev, Patrick McHardy
In-Reply-To: <20141113120826.GA8224@salvia>

On 13.11.2014 13:08, Pablo Neira Ayuso wrote:

>> For me there is little difference in choosing DROP or ACCEPT as verdict.
>> > The packet/skb belongs to a formerly allowed connection, most likely
>> > this connection is still allowed (but the conntrack hash entry is about
>> > to be removed due to userspace is flushing the conntrack table).
> __nf_conntrack_confirm() is only called for the first packet that we
> see in a flow. If you just invoked the flush command once (which
> should be the common case), then this is likely to be the first packet
> of the flow (unless you already called flush anytime soon in the
> past).
Yes, you are right. As far as I remember it was very hard to trigger
that critical moment, when the first packet triggered the insertion into
the hash table. But the test and production systems showed this strange
behaviour, that no traffic was allowed to flow for exactly 600 seconds.

> 
>> > To minimize the impact (lost packets -> retransmit) I decided to allow
>> > the skb in flight, so were is no lost packet at this place.
> I understand your original motivation was to be conservative.
Yes.

> 
>> > When the connection is not allowed anymore (but was allowed up to now,
>> > because the hash entry exists), the impact is one last packet 'slipping
>> > through'.
Feel free to change the verdict, IMHO it doesn't matter at all as long
as the hash table is in a consistent state. The higher protocol layers
will deal with the missing packet.

> The general policy in conntrack is to not drop packets, but in this
> case we'll leave things in inconsistent state (ie. we will likely
> receive a reply packet in response to the original packet that has no
> conntrack yet).
Under heavy load this can happen anyway I guess?

Thanks and best regards
Jörg

-- 
Dipl.-Inform.
Jörg Marx
Bereichsleiter
Entwicklung Client- & Netzwerksicherheit
Geschäftsbereich Public Sector
secunet Security Networks AG
Ammonstr. 74
D-01067 Dresden, Germany 
Telefon +49 201 54 54-3517
Telefax +49 201 54 54-1323
joerg.marx@secunet.com
www.secunet.com

secunet Security Networks AG
Kronprinzenstr. 30
45128 Essen, Germany 
Amtsgericht Essen HRB 13615

Vorstand: Dr. Rainer Baumgart (Vors.), Thomas Pleines
Aufsichtsratsvorsitzender: Dr. Peter Zattler
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] inetdevice: fixed signed integer overflow
From: Vincent Benayoun @ 2014-11-13 15:04 UTC (permalink / raw)
  To: "David S. Miller", Jiri Pirko, Julian Anastasov,
	Nicolas Dichtel
  Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org

>From f25ff0f2645f9763552147d480f86973b7041e26 Mon Sep 17 00:00:00 2001
From: Vincent BENAYOUN <vincent.benayoun@trust-in-soft.com>
Date: Thu, 13 Nov 2014 13:47:26 +0100
Subject: [PATCH] inetdevice: fixed signed integer overflow

There could be a signed overflow in the following code.

The expression, (32-logmask) is comprised between 0 and 31 included.
It may be equal to 31.
In such a case the left shift will produce a signed integer overflow.
According to the C99 Standard, this is an undefined behavior.
A simple fix is to replace the signed int 1 with the unsigned int 1U.

Best Regards,
Vincent Benayoun
R&D engineer @ TrustInSoft

Signed-off-by: Vincent BENAYOUN <vincent.benayoun@trust-in-soft.com>
---
 include/linux/inetdevice.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 0068708..0a21fbe 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -242,7 +242,7 @@ static inline void in_dev_put(struct in_device *idev)
 static __inline__ __be32 inet_make_mask(int logmask)
 {
 	if (logmask)
-		return htonl(~((1<<(32-logmask))-1));
+		return htonl(~((1U<<(32-logmask))-1));
 	return 0;
 }
 
-- 
1.9.1

^ permalink raw reply related

* Re: Device Tree Binding for Marvell DSA Switch on imx28 board over Mdio Interface
From: Oliver Graute @ 2014-11-13 15:15 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: netdev
In-Reply-To: <5463B2AC.6090904@gmail.com>

Hello Florian,

On Wed, Nov 12, 2014 at 8:19 PM, Florian Fainelli <f.fainelli@gmail.com> wrote:
> On 11/12/2014 05:07 AM, Oliver Graute wrote:
>> Hello,
>>
>> how do I specify the DSA node and the MDIO node in the Device Tree
>> Binding to integrate a Marvell 88e6071 switch with a imx28 board?
>>
>> On my board the Marvell switch 88e6071 is connected via phy1 (on a
>> imx28 PCB) to phy5 on the Marvell switch (on a Switch PCB). All phys
>> are connected via the same MDIO Bus.
>>
>> I enabled the Marvell DSA Support Driver, Gianfar Ethernet Driver and
>> Freescale PQ MDIO Driver in the Kernel (I' am not sure if this is the
>> right choice for imx28 fec ethernet controller is it?)
>>

I changed my DeviceTree according to your proposal. Now I got a ENODEV 19
in dsa_of_probe. Because  of_find_device_by_node(ethernet) is returning 0.
Is my ethernet setting still wrong?

dsa@0 {
        compatible = "marvell,dsa";
        #address-cells = <2>;
        #size-cells = <0>;

        interrupts = <10>;
        dsa,ethernet = <&eth1>;
        dsa,mii-bus = <&mdio_bus>;

        switch@0 {
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <5 0>;   /* MDIO address 5, switch 0 in tree */

            port@0 {
                reg = <0>;
                label = "lan1";
                phy-handle = <&ethphy1>;
            };

            port@1 {
                reg = <1>;
                label = "lan2";
            };

            port@2 {
                reg = <2>;
                label = "lan3";
            };

            port@3 {
                reg = <3>;
                label = "lan4";
            };

            port@4 {
                reg = <4>;
                label = "lan5";
            };

            port@5 {
                reg = <5>;
                label = "cpu";
            };

        };
    };

eth1: eth1 {
    status = "okay";
    ethernet1-port@1 {
        phy-handle = <&ethphy1>;

        fixed-link {
                speed = <1000>;
                full-duplex;
            };
    };
};

mdio_bus: mdio@800f0040 {
        #address-cells = <1>;
        #size-cells = <0>;
        device_type = "mdio";
        //compatible = "fsl,gianfar-mdio";
        compatible = "fsl,mpc875-fec-mdio", "fsl,pq1-fec-mdio";
        reg = <0x800f0040 0x188>;
        status = "okay";

         ethphy0: ethernet-phy@0 {
                compatible = "fsl,gianfar-mdio";
                device_type = "network";
                model = "FEC";
                reg = <0x00>;

         };

         ethphy1: ethernet-phy@1 {
                 compatible = "fsl,gianfar-mdio";
                 device_type = "network";
                 model = "FEC";
                 reg = <0x01>;
                };
                 //reg = <0xff>; */ /* No PHY attached */
                 //speed = <1000>;
                 //duple = <1>;
       };

modprobe dsa_core
[  151.720180] !!!!!enter dsa_init_module!!!!!
[  151.724713] !!!!Enter dsa Probe!!!!!
[  151.728321] Distributed Switch Architecture driver version 0.1
[  151.739026] !!!!!Enter dsa_of_probe!!!!!
[  151.744515] !!!!!mdio->name=mdio mdio->type=mdio
mdio->full_name=/mdio@800f0040 !!!!!
[  151.753559] !!!!!np->name=dsa np->type=<NULL> np->full_name=/dsa@0 !!!!!
[  151.761419] !!!!before of_mdio_find_bus!!!!!
[  151.765732] !!!!!enter of_mdio_find_bus!!!!!
[  151.772418] !!!!!!enter class_find_device!!!!!
[  151.776908] !!!!!!enter class_dev_iter_init!!!!!
[  151.783512] !!!!!!iter->type->name=(null) !!!!!
[  151.788085] !!!!!!leave class_dev_iter_init!!!!!
[  151.794439] !!!!!enter of_mdio_bus_match!!!!!
[  151.798845] !!!!!enter of_mdio_bus_match!!!!!
[  151.804967] !!!!!enter of_mdio_bus_match!!!!!
[  151.809381] !!!!!!leave class_find_device return dev=!!!!!
[  151.816668] !!!!Leave of_mdio_find_bus !!!!!
[  151.822057] !!!!before of_parse_phandle dsa,ethernet!!!!!
[  151.827553] !!!!before of find_device_by_node!!!!!
[  151.834819] !!!!!ethernet->name=eth1 ethernet->type=<NULL>
ethernet->full_name=/eth1 !!!!!
[  151.844540] !!!!! enter of_find_device_by_node !!!!!
[  151.850692] !!!!! Leave of_find_device_by_node dev=0 !!!!!
[  151.856221] !!!! return  of_find-device_by_node =19 !!!!!
[  151.863419] dsa_of_probe returns=-19
[  151.873509] !!!!!leave dsa_init_module!!!!!


Best Regards,

Oliver

^ permalink raw reply

* [PATCH v5 6/8] net: can: c_can: Disable pins when CAN interface is down
From: Roger Quadros @ 2014-11-13 15:23 UTC (permalink / raw)
  To: wg, mkl
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
	sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <1415371762-29885-7-git-send-email-rogerq@ti.com>

DRA7 CAN IP suffers from a problem which causes it to be prevented
from fully turning OFF (i.e. stuck in transition) if the module was
disabled while there was traffic on the CAN_RX line.

To work around this issue we select the SLEEP pin state by default
on probe and use the DEFAULT pin state on CAN up and back to the
SLEEP pin state on CAN down.

Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/net/can/c_can/c_can.c | 37 +++++++++++++++++++++++++++++++++++++
 drivers/net/can/c_can/c_can.h |  1 +
 2 files changed, 38 insertions(+)

diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index 8e78bb4..c80cb3d 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -35,6 +35,7 @@
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/pm_runtime.h>
+#include <linux/pinctrl/consumer.h>
 
 #include <linux/can.h>
 #include <linux/can/dev.h>
@@ -587,6 +588,21 @@ static int c_can_chip_config(struct net_device *dev)
 	return c_can_set_bittiming(dev);
 }
 
+/*
+ * Selects the pinctrl state specified in the name.
+ */
+static void c_can_pinctrl_select_state(struct c_can_priv *priv,
+				      const char *name)
+{
+	if (!IS_ERR(priv->pinctrl)) {
+		struct pinctrl_state *s;
+
+		s = pinctrl_lookup_state(priv->pinctrl, name);
+		if (!IS_ERR(s))
+			pinctrl_select_state(priv->pinctrl, s);
+	}
+}
+
 static int c_can_start(struct net_device *dev)
 {
 	struct c_can_priv *priv = netdev_priv(dev);
@@ -603,6 +619,8 @@ static int c_can_start(struct net_device *dev)
 
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
 
+	/* activate pins */
+	c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT);
 	return 0;
 }
 
@@ -611,6 +629,9 @@ static void c_can_stop(struct net_device *dev)
 	struct c_can_priv *priv = netdev_priv(dev);
 
 	c_can_irq_control(priv, false);
+
+	/* deactivate pins */
+	c_can_pinctrl_select_state(priv, PINCTRL_STATE_SLEEP);
 	priv->can.state = CAN_STATE_STOPPED;
 }
 
@@ -1244,6 +1265,22 @@ int register_c_can_dev(struct net_device *dev)
 	struct c_can_priv *priv = netdev_priv(dev);
 	int err;
 
+	priv->pinctrl = devm_pinctrl_get(dev->dev.parent);
+	if (!IS_ERR(priv->pinctrl)) {
+		struct pinctrl_state *s;
+
+		/* Deactivate pins to prevent DRA7 DCAN IP from being
+		 * stuck in transition when module is disabled.
+		 * Pins are activated in c_can_start() and deactivated
+		 * in c_can_stop()
+		 */
+		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_SLEEP);
+		if (!IS_ERR(s))
+			pinctrl_select_state(priv->pinctrl, s);
+	} else {
+		netdev_dbg(dev, "failed to get pinctrl\n");
+	}
+
 	c_can_pm_runtime_enable(priv);
 
 	dev->flags |= IFF_ECHO;	/* we support local echo */
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
index c6715ca..3cedf48 100644
--- a/drivers/net/can/c_can/c_can.h
+++ b/drivers/net/can/c_can/c_can.h
@@ -210,6 +210,7 @@ struct c_can_priv {
 	u32 comm_rcv_high;
 	u32 rxmasked;
 	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
+	struct pinctrl *pinctrl;
 };
 
 struct net_device *alloc_c_can_dev(void);
-- 
1.8.3.2

^ permalink raw reply related

* Re: [PATCH v5 6/8] net: can: c_can: Disable pins when CAN interface is down
From: Marc Kleine-Budde @ 2014-11-13 16:03 UTC (permalink / raw)
  To: Roger Quadros, wg
  Cc: wsa, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar, nm,
	sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <5464CCFF.5010004@ti.com>

[-- Attachment #1: Type: text/plain, Size: 4251 bytes --]

On 11/13/2014 04:23 PM, Roger Quadros wrote:
> DRA7 CAN IP suffers from a problem which causes it to be prevented
> from fully turning OFF (i.e. stuck in transition) if the module was
> disabled while there was traffic on the CAN_RX line.
> 
> To work around this issue we select the SLEEP pin state by default
> on probe and use the DEFAULT pin state on CAN up and back to the
> SLEEP pin state on CAN down.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> ---
>  drivers/net/can/c_can/c_can.c | 37 +++++++++++++++++++++++++++++++++++++
>  drivers/net/can/c_can/c_can.h |  1 +
>  2 files changed, 38 insertions(+)
> 
> diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
> index 8e78bb4..c80cb3d 100644
> --- a/drivers/net/can/c_can/c_can.c
> +++ b/drivers/net/can/c_can/c_can.c
> @@ -35,6 +35,7 @@
>  #include <linux/list.h>
>  #include <linux/io.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/pinctrl/consumer.h>
>  
>  #include <linux/can.h>
>  #include <linux/can/dev.h>
> @@ -587,6 +588,21 @@ static int c_can_chip_config(struct net_device *dev)
>  	return c_can_set_bittiming(dev);
>  }
>  
> +/*
> + * Selects the pinctrl state specified in the name.
> + */
> +static void c_can_pinctrl_select_state(struct c_can_priv *priv,
> +				      const char *name)
> +{
> +	if (!IS_ERR(priv->pinctrl)) {
> +		struct pinctrl_state *s;
> +
> +		s = pinctrl_lookup_state(priv->pinctrl, name);
> +		if (!IS_ERR(s))
> +			pinctrl_select_state(priv->pinctrl, s);
> +	}
> +}
> +
>  static int c_can_start(struct net_device *dev)
>  {
>  	struct c_can_priv *priv = netdev_priv(dev);
> @@ -603,6 +619,8 @@ static int c_can_start(struct net_device *dev)
>  
>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
>  
> +	/* activate pins */
> +	c_can_pinctrl_select_state(priv, PINCTRL_STATE_DEFAULT);
>  	return 0;
>  }
>  
> @@ -611,6 +629,9 @@ static void c_can_stop(struct net_device *dev)
>  	struct c_can_priv *priv = netdev_priv(dev);
>  
>  	c_can_irq_control(priv, false);
> +
> +	/* deactivate pins */
> +	c_can_pinctrl_select_state(priv, PINCTRL_STATE_SLEEP);
>  	priv->can.state = CAN_STATE_STOPPED;
>  }
>  
> @@ -1244,6 +1265,22 @@ int register_c_can_dev(struct net_device *dev)
>  	struct c_can_priv *priv = netdev_priv(dev);
>  	int err;
>  
> +	priv->pinctrl = devm_pinctrl_get(dev->dev.parent);

What's dev->dev.parent?
Ah, this is set by SET_NETDEV_DEV(dev, &pdev->dev); Good work!

I thought we had to set priv->pinctrl in the platform.c.

> +	if (!IS_ERR(priv->pinctrl)) {
> +		struct pinctrl_state *s;
> +
> +		/* Deactivate pins to prevent DRA7 DCAN IP from being
> +		 * stuck in transition when module is disabled.
> +		 * Pins are activated in c_can_start() and deactivated
> +		 * in c_can_stop()
> +		 */
> +		s = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_SLEEP);
> +		if (!IS_ERR(s))
> +			pinctrl_select_state(priv->pinctrl, s);
> +	} else {
> +		netdev_dbg(dev, "failed to get pinctrl\n");
> +	}
> +
The above can be replace by this?

	c_can_pinctrl_select_state(priv, PINCTRL_STATE_SLEEP)

Then we don't have the worrying looking error message if there isn't any
pinctrl, e.g. for the PCI driver with pinctrl enabled in the Kernel.

I just stumbled over pinctrl_pm_select_sleep_state(), is it possible to
integrate this into runtime pm?

http://lxr.free-electrons.com/source/drivers/pinctrl/core.c#L1282

>  	c_can_pm_runtime_enable(priv);
>  
>  	dev->flags |= IFF_ECHO;	/* we support local echo */
> diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h
> index c6715ca..3cedf48 100644
> --- a/drivers/net/can/c_can/c_can.h
> +++ b/drivers/net/can/c_can/c_can.h
> @@ -210,6 +210,7 @@ struct c_can_priv {
>  	u32 comm_rcv_high;
>  	u32 rxmasked;
>  	u32 dlc[C_CAN_MSG_OBJ_TX_NUM];
> +	struct pinctrl *pinctrl;
>  };
>  
>  struct net_device *alloc_c_can_dev(void);
> 

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCH v4 8/8] net: can: c_can: Add support for TI am3352 DCAN
From: Wolfram Sang @ 2014-11-13 16:06 UTC (permalink / raw)
  To: Roger Quadros
  Cc: wg, mkl, tony, tglx, mugunthanvnm, george.cherian, balbi, nsekhar,
	nm, sergei.shtylyov, linux-omap, linux-can, netdev
In-Reply-To: <1415371762-29885-9-git-send-email-rogerq@ti.com>

[-- Attachment #1: Type: text/plain, Size: 260 bytes --]

On Fri, Nov 07, 2014 at 04:49:22PM +0200, Roger Quadros wrote:
> AM3352 SoC has 2 DCAN modules. Add compatible id and
> raminit driver data for am3352 DCAN.
> 
> Signed-off-by: Roger Quadros <rogerq@ti.com>

Acked-by: Wolfram Sang <wsa@the-dreams.de>


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* [net-next PATCH 0/4] Clean up intel driver page reuse Rx code
From: Alexander Duyck @ 2014-11-13 16:18 UTC (permalink / raw)
  To: netdev; +Cc: jeffrey.t.kirsher

This patch series cleans up the page reuse and Rx path so that all of the
fixes that have been applied to any one driver are now in place for igb,
fm10k, and ixgbe.  It occured to me that fm10k was missing the pfmemalloc
bits, and ixgbe was missing some logic that reduced the number of writes
needed as well as the pfmemalloc fix.

In addition ixgbe was carrying around some mostly-dead code that was
wrapping a call to writel.  I removed it since it masked the fact that
ixgbe was missing the mmiowb it was supposed to have between the tail write
and the Tx queue lock release to prevent the MMIO access from racing
between CPUs.

Also one change made to all 3 drivers is that we now only overwrite 3 of
the 4 DWORDs in the Rx descriptor after allocation.  The last DWORD
contains the upper 32 bits of the header address on fetch, and the length
and vlan on writeback.  Since we are no longer using header split we don't
need to clear it prior to descriptor fetch as it is unused so we can save
ourselves a cycle on 32b systems by just leaving it untouched.

---

Alexander Duyck (4):
      igb: Clean-up page reuse code
      fm10k: Clean-up page reuse code
      ixgbe: Clean-up page reuse code
      ixgbe: Remove tail write abstraction and add missing barrier


 drivers/net/ethernet/intel/fm10k/fm10k_main.c |   34 ++++---
 drivers/net/ethernet/intel/igb/igb_main.c     |   35 +++----
 drivers/net/ethernet/intel/ixgbe/ixgbe.h      |    5 -
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  118 ++++++++++++-------------
 4 files changed, 89 insertions(+), 103 deletions(-)

--

^ permalink raw reply

* [net-next PATCH 2/4] fm10k: Clean-up page reuse code
From: Alexander Duyck @ 2014-11-13 16:18 UTC (permalink / raw)
  To: netdev; +Cc: Matthew Vick, jeffrey.t.kirsher
In-Reply-To: <20141113161148.2790.22082.stgit@ahduyck-vm-fedora20>

This patch cleans up the page reuse code getting it into a state where all
the workarounds needed are in place as well as cleaning up a few minor
oversights such as using __free_pages instead of put_page to drop a locally
allocated page.

It also cleans up how we clear the descriptor status bits.  Previously they
were zeroed as a part of clearing the hdr_addr.  However the hdr_addr is a
64 bit field and 64 bit writes can be a bit more expensive on on 32 bit
systems.  Since we are no longer using the header split feature the upper
32 bits of the address no longer need to be cleared.  As a result we can
just clear the status bits and leave the length and VLAN fields as-is which
should provide more information in debugging.

Cc: Matthew Vick <matthew.vick@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
 drivers/net/ethernet/intel/fm10k/fm10k_main.c |   34 +++++++++++++------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
index 73457ed..8c8deec 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c
@@ -97,7 +97,6 @@ static bool fm10k_alloc_mapped_page(struct fm10k_ring *rx_ring,
 	 */
 	if (dma_mapping_error(rx_ring->dev, dma)) {
 		__free_page(page);
-		bi->page = NULL;
 
 		rx_ring->rx_stats.alloc_failed++;
 		return false;
@@ -147,8 +146,8 @@ void fm10k_alloc_rx_buffers(struct fm10k_ring *rx_ring, u16 cleaned_count)
 			i -= rx_ring->count;
 		}
 
-		/* clear the hdr_addr for the next_to_use descriptor */
-		rx_desc->q.hdr_addr = 0;
+		/* clear the status bits for the next_to_use descriptor */
+		rx_desc->d.staterr = 0;
 
 		cleaned_count--;
 	} while (cleaned_count);
@@ -194,7 +193,7 @@ static void fm10k_reuse_rx_page(struct fm10k_ring *rx_ring,
 	rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
 
 	/* transfer page from old buffer to new buffer */
-	memcpy(new_buff, old_buff, sizeof(struct fm10k_rx_buffer));
+	*new_buff = *old_buff;
 
 	/* sync the buffer for use by the device */
 	dma_sync_single_range_for_device(rx_ring->dev, old_buff->dma,
@@ -203,12 +202,17 @@ static void fm10k_reuse_rx_page(struct fm10k_ring *rx_ring,
 					 DMA_FROM_DEVICE);
 }
 
+static inline bool fm10k_page_is_reserved(struct page *page)
+{
+	return (page_to_nid(page) != numa_mem_id()) || page->pfmemalloc;
+}
+
 static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer,
 				    struct page *page,
 				    unsigned int truesize)
 {
 	/* avoid re-using remote pages */
-	if (unlikely(page_to_nid(page) != numa_mem_id()))
+	if (unlikely(fm10k_page_is_reserved(page)))
 		return false;
 
 #if (PAGE_SIZE < 8192)
@@ -218,22 +222,19 @@ static bool fm10k_can_reuse_rx_page(struct fm10k_rx_buffer *rx_buffer,
 
 	/* flip page offset to other buffer */
 	rx_buffer->page_offset ^= FM10K_RX_BUFSZ;
-
-	/* Even if we own the page, we are not allowed to use atomic_set()
-	 * This would break get_page_unless_zero() users.
-	 */
-	atomic_inc(&page->_count);
 #else
 	/* move offset up to the next cache line */
 	rx_buffer->page_offset += truesize;
 
 	if (rx_buffer->page_offset > (PAGE_SIZE - FM10K_RX_BUFSZ))
 		return false;
-
-	/* bump ref count on page before it is given to the stack */
-	get_page(page);
 #endif
 
+	/* Even if we own the page, we are not allowed to use atomic_set()
+	 * This would break get_page_unless_zero() users.
+	 */
+	atomic_inc(&page->_count);
+
 	return true;
 }
 
@@ -270,12 +271,12 @@ static bool fm10k_add_rx_frag(struct fm10k_ring *rx_ring,
 
 		memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long)));
 
-		/* we can reuse buffer as-is, just make sure it is local */
-		if (likely(page_to_nid(page) == numa_mem_id()))
+		/* page is not reserved, we can reuse buffer as-is */
+		if (likely(!fm10k_page_is_reserved(page)))
 			return true;
 
 		/* this page cannot be reused so discard it */
-		put_page(page);
+		__free_page(page);
 		return false;
 	}
 
@@ -293,7 +294,6 @@ static struct sk_buff *fm10k_fetch_rx_buffer(struct fm10k_ring *rx_ring,
 	struct page *page;
 
 	rx_buffer = &rx_ring->rx_buffer[rx_ring->next_to_clean];
-
 	page = rx_buffer->page;
 	prefetchw(page);
 

^ permalink raw reply related

* [net-next PATCH 1/4] igb: Clean-up page reuse code
From: Alexander Duyck @ 2014-11-13 16:18 UTC (permalink / raw)
  To: netdev; +Cc: jeffrey.t.kirsher
In-Reply-To: <20141113161148.2790.22082.stgit@ahduyck-vm-fedora20>

This patch cleans up the page reuse code getting it into a state where all
the workarounds needed are in place as well as cleaning up a few minor
oversights such as using __free_pages instead of put_page to drop a locally
allocated page.

It also cleans up how we clear the descriptor status bits.  Previously they
were zeroed as a part of clearing the hdr_addr.  However the hdr_addr is a
64 bit field and 64 bit writes can be a bit more expensive on on 32 bit
systems.  Since we are no longer using the header split feature the upper
32 bits of the address no longer need to be cleared.  As a result we can
just clear the status bits and leave the length and VLAN fields as-is which
should provide more information in debugging.

Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
 drivers/net/ethernet/intel/igb/igb_main.c |   35 +++++++++++++----------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 1e35fae..ade207d 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -6529,15 +6529,17 @@ static void igb_reuse_rx_page(struct igb_ring *rx_ring,
 					 DMA_FROM_DEVICE);
 }
 
+static inline bool igb_page_is_reserved(struct page *page)
+{
+	return (page_to_nid(page) != numa_mem_id()) || page->pfmemalloc;
+}
+
 static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
 				  struct page *page,
 				  unsigned int truesize)
 {
 	/* avoid re-using remote pages */
-	if (unlikely(page_to_nid(page) != numa_node_id()))
-		return false;
-
-	if (unlikely(page->pfmemalloc))
+	if (unlikely(igb_page_is_reserved(page)))
 		return false;
 
 #if (PAGE_SIZE < 8192)
@@ -6547,22 +6549,19 @@ static bool igb_can_reuse_rx_page(struct igb_rx_buffer *rx_buffer,
 
 	/* flip page offset to other buffer */
 	rx_buffer->page_offset ^= IGB_RX_BUFSZ;
-
-	/* Even if we own the page, we are not allowed to use atomic_set()
-	 * This would break get_page_unless_zero() users.
-	 */
-	atomic_inc(&page->_count);
 #else
 	/* move offset up to the next cache line */
 	rx_buffer->page_offset += truesize;
 
 	if (rx_buffer->page_offset > (PAGE_SIZE - IGB_RX_BUFSZ))
 		return false;
-
-	/* bump ref count on page before it is given to the stack */
-	get_page(page);
 #endif
 
+	/* Even if we own the page, we are not allowed to use atomic_set()
+	 * This would break get_page_unless_zero() users.
+	 */
+	atomic_inc(&page->_count);
+
 	return true;
 }
 
@@ -6605,13 +6604,12 @@ static bool igb_add_rx_frag(struct igb_ring *rx_ring,
 
 		memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long)));
 
-		/* we can reuse buffer as-is, just make sure it is local */
-		if (likely((page_to_nid(page) == numa_node_id()) &&
-			   !page->pfmemalloc))
+		/* page is not reserved, we can reuse buffer as-is */
+		if (likely(!igb_page_is_reserved(page)))
 			return true;
 
 		/* this page cannot be reused so discard it */
-		put_page(page);
+		__free_page(page);
 		return false;
 	}
 
@@ -6629,7 +6627,6 @@ static struct sk_buff *igb_fetch_rx_buffer(struct igb_ring *rx_ring,
 	struct page *page;
 
 	rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean];
-
 	page = rx_buffer->page;
 	prefetchw(page);
 
@@ -7050,8 +7047,8 @@ void igb_alloc_rx_buffers(struct igb_ring *rx_ring, u16 cleaned_count)
 			i -= rx_ring->count;
 		}
 
-		/* clear the hdr_addr for the next_to_use descriptor */
-		rx_desc->read.hdr_addr = 0;
+		/* clear the status bits for the next_to_use descriptor */
+		rx_desc->wb.upper.status_error = 0;
 
 		cleaned_count--;
 	} while (cleaned_count);

^ permalink raw reply related

* [net-next PATCH 3/4] ixgbe: Clean-up page reuse code
From: Alexander Duyck @ 2014-11-13 16:18 UTC (permalink / raw)
  To: netdev; +Cc: Don Skidmore, jeffrey.t.kirsher
In-Reply-To: <20141113161148.2790.22082.stgit@ahduyck-vm-fedora20>

This patch cleans up the page reuse code getting it into a state where all
the workarounds needed are in place as well as cleaning up a few minor
oversights such as using __free_pages instead of put_page to drop a locally
allocated page.

It also cleans up how we clear the descriptor status bits.  Previously they
were zeroed as a part of clearing the hdr_addr.  However the hdr_addr is a
64 bit field and 64 bit writes can be a bit more expensive on on 32 bit
systems.  Since we are no longer using the header split feature the upper
32 bits of the address no longer need to be cleared.  As a result we can
just clear the status bits and leave the length and VLAN fields as-is which
should provide more information in debugging.


Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |   78 ++++++++++++-------------
 1 file changed, 36 insertions(+), 42 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index f5fcba4..a72c852 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1436,20 +1436,17 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring,
 				    struct ixgbe_rx_buffer *bi)
 {
 	struct page *page = bi->page;
-	dma_addr_t dma = bi->dma;
+	dma_addr_t dma;
 
 	/* since we are recycling buffers we should seldom need to alloc */
-	if (likely(dma))
+	if (likely(page))
 		return true;
 
 	/* alloc new page for storage */
-	if (likely(!page)) {
-		page = dev_alloc_pages(ixgbe_rx_pg_order(rx_ring));
-		if (unlikely(!page)) {
-			rx_ring->rx_stats.alloc_rx_page_failed++;
-			return false;
-		}
-		bi->page = page;
+	page = dev_alloc_pages(ixgbe_rx_pg_order(rx_ring));
+	if (unlikely(!page)) {
+		rx_ring->rx_stats.alloc_rx_page_failed++;
+		return false;
 	}
 
 	/* map page for use */
@@ -1462,13 +1459,13 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring,
 	 */
 	if (dma_mapping_error(rx_ring->dev, dma)) {
 		__free_pages(page, ixgbe_rx_pg_order(rx_ring));
-		bi->page = NULL;
 
 		rx_ring->rx_stats.alloc_rx_page_failed++;
 		return false;
 	}
 
 	bi->dma = dma;
+	bi->page = page;
 	bi->page_offset = 0;
 
 	return true;
@@ -1512,8 +1509,8 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count)
 			i -= rx_ring->count;
 		}
 
-		/* clear the hdr_addr for the next_to_use descriptor */
-		rx_desc->read.hdr_addr = 0;
+		/* clear the status bits for the next_to_use descriptor */
+		rx_desc->wb.upper.status_error = 0;
 
 		cleaned_count--;
 	} while (cleaned_count);
@@ -1798,9 +1795,7 @@ static void ixgbe_reuse_rx_page(struct ixgbe_ring *rx_ring,
 	rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
 
 	/* transfer page from old buffer to new buffer */
-	new_buff->page = old_buff->page;
-	new_buff->dma = old_buff->dma;
-	new_buff->page_offset = old_buff->page_offset;
+	*new_buff = *old_buff;
 
 	/* sync the buffer for use by the device */
 	dma_sync_single_range_for_device(rx_ring->dev, new_buff->dma,
@@ -1809,6 +1804,11 @@ static void ixgbe_reuse_rx_page(struct ixgbe_ring *rx_ring,
 					 DMA_FROM_DEVICE);
 }
 
+static inline bool ixgbe_page_is_reserved(struct page *page)
+{
+	return (page_to_nid(page) != numa_mem_id()) || page->pfmemalloc;
+}
+
 /**
  * ixgbe_add_rx_frag - Add contents of Rx buffer to sk_buff
  * @rx_ring: rx descriptor ring to transact packets on
@@ -1844,12 +1844,12 @@ static bool ixgbe_add_rx_frag(struct ixgbe_ring *rx_ring,
 
 		memcpy(__skb_put(skb, size), va, ALIGN(size, sizeof(long)));
 
-		/* we can reuse buffer as-is, just make sure it is local */
-		if (likely(page_to_nid(page) == numa_node_id()))
+		/* page is not reserved, we can reuse buffer as-is */
+		if (likely(!ixgbe_page_is_reserved(page)))
 			return true;
 
 		/* this page cannot be reused so discard it */
-		put_page(page);
+		__free_pages(page, ixgbe_rx_pg_order(rx_ring));
 		return false;
 	}
 
@@ -1857,7 +1857,7 @@ static bool ixgbe_add_rx_frag(struct ixgbe_ring *rx_ring,
 			rx_buffer->page_offset, size, truesize);
 
 	/* avoid re-using remote pages */
-	if (unlikely(page_to_nid(page) != numa_node_id()))
+	if (unlikely(ixgbe_page_is_reserved(page)))
 		return false;
 
 #if (PAGE_SIZE < 8192)
@@ -1867,22 +1867,19 @@ static bool ixgbe_add_rx_frag(struct ixgbe_ring *rx_ring,
 
 	/* flip page offset to other buffer */
 	rx_buffer->page_offset ^= truesize;
-
-	/* Even if we own the page, we are not allowed to use atomic_set()
-	 * This would break get_page_unless_zero() users.
-	 */
-	atomic_inc(&page->_count);
 #else
 	/* move offset up to the next cache line */
 	rx_buffer->page_offset += truesize;
 
 	if (rx_buffer->page_offset > last_offset)
 		return false;
-
-	/* bump ref count on page before it is given to the stack */
-	get_page(page);
 #endif
 
+	/* Even if we own the page, we are not allowed to use atomic_set()
+	 * This would break get_page_unless_zero() users.
+	 */
+	atomic_inc(&page->_count);
+
 	return true;
 }
 
@@ -1945,6 +1942,8 @@ dma_sync:
 					      rx_buffer->page_offset,
 					      ixgbe_rx_bufsz(rx_ring),
 					      DMA_FROM_DEVICE);
+
+		rx_buffer->skb = NULL;
 	}
 
 	/* pull page into skb */
@@ -1962,8 +1961,6 @@ dma_sync:
 	}
 
 	/* clear contents of buffer_info */
-	rx_buffer->skb = NULL;
-	rx_buffer->dma = 0;
 	rx_buffer->page = NULL;
 
 	return skb;
@@ -4345,29 +4342,26 @@ static void ixgbe_clean_rx_ring(struct ixgbe_ring *rx_ring)
 
 	/* Free all the Rx ring sk_buffs */
 	for (i = 0; i < rx_ring->count; i++) {
-		struct ixgbe_rx_buffer *rx_buffer;
+		struct ixgbe_rx_buffer *rx_buffer = &rx_ring->rx_buffer_info[i];
 
-		rx_buffer = &rx_ring->rx_buffer_info[i];
 		if (rx_buffer->skb) {
 			struct sk_buff *skb = rx_buffer->skb;
-			if (IXGBE_CB(skb)->page_released) {
+			if (IXGBE_CB(skb)->page_released)
 				dma_unmap_page(dev,
 					       IXGBE_CB(skb)->dma,
 					       ixgbe_rx_bufsz(rx_ring),
 					       DMA_FROM_DEVICE);
-				IXGBE_CB(skb)->page_released = false;
-			}
 			dev_kfree_skb(skb);
 			rx_buffer->skb = NULL;
 		}
-		if (rx_buffer->dma)
-			dma_unmap_page(dev, rx_buffer->dma,
-				       ixgbe_rx_pg_size(rx_ring),
-				       DMA_FROM_DEVICE);
-		rx_buffer->dma = 0;
-		if (rx_buffer->page)
-			__free_pages(rx_buffer->page,
-				     ixgbe_rx_pg_order(rx_ring));
+
+		if (!rx_buffer->page)
+			continue;
+
+		dma_unmap_page(dev, rx_buffer->dma,
+			       ixgbe_rx_pg_size(rx_ring), DMA_FROM_DEVICE);
+		__free_pages(rx_buffer->page, ixgbe_rx_pg_order(rx_ring));
+
 		rx_buffer->page = NULL;
 	}
 

^ permalink raw reply related

* [net-next PATCH 4/4] ixgbe: Remove tail write abstraction and add missing barrier
From: Alexander Duyck @ 2014-11-13 16:18 UTC (permalink / raw)
  To: netdev; +Cc: Don Skidmore, jeffrey.t.kirsher
In-Reply-To: <20141113161148.2790.22082.stgit@ahduyck-vm-fedora20>

This change cleans up the tail writes for the ixgbe descriptor queues.  The
current implementation had me confused as I wasn't sure if it was still
making use of the suprise remove logic or not.

It also adds the mmiowb which is needed on ia64, mips, and a couple other
architectures in order to synchronize the MMIO writes with the Tx queue
_xmit_lock spinlock.

Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Alexander Duyck <alexander.h.duyck@redhat.com>
---
 drivers/net/ethernet/intel/ixgbe/ixgbe.h      |    5 ---
 drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |   40 +++++++++++++------------
 2 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5032a60..86fa607 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -553,11 +553,6 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
 	return ((ntc > ntu) ? 0 : ring->count) + ntc - ntu - 1;
 }
 
-static inline void ixgbe_write_tail(struct ixgbe_ring *ring, u32 value)
-{
-	writel(value, ring->tail);
-}
-
 #define IXGBE_RX_DESC(R, i)	    \
 	(&(((union ixgbe_adv_rx_desc *)((R)->desc))[i]))
 #define IXGBE_TX_DESC(R, i)	    \
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index a72c852..6b29dfe 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1416,22 +1416,6 @@ static inline void ixgbe_rx_checksum(struct ixgbe_ring *ring,
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 }
 
-static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val)
-{
-	rx_ring->next_to_use = val;
-
-	/* update next to alloc since we have filled the ring */
-	rx_ring->next_to_alloc = val;
-	/*
-	 * Force memory writes to complete before letting h/w
-	 * know there are new descriptors to fetch.  (Only
-	 * applicable for weak-ordered memory model archs,
-	 * such as IA-64).
-	 */
-	wmb();
-	ixgbe_write_tail(rx_ring, val);
-}
-
 static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring,
 				    struct ixgbe_rx_buffer *bi)
 {
@@ -1517,8 +1501,20 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count)
 
 	i += rx_ring->count;
 
-	if (rx_ring->next_to_use != i)
-		ixgbe_release_rx_desc(rx_ring, i);
+	if (rx_ring->next_to_use != i) {
+		rx_ring->next_to_use = i;
+
+		/* update next to alloc since we have filled the ring */
+		rx_ring->next_to_alloc = i;
+
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64).
+		 */
+		wmb();
+		writel(i, rx_ring->tail);
+	}
 }
 
 static void ixgbe_set_rsc_gso_size(struct ixgbe_ring *ring,
@@ -6955,8 +6951,12 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
 	ixgbe_maybe_stop_tx(tx_ring, DESC_NEEDED);
 
 	if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
-		/* notify HW of packet */
-		ixgbe_write_tail(tx_ring, i);
+		writel(i, tx_ring->tail);
+
+		/* we need this if more than one processor can write to our tail
+		 * at a time, it synchronizes IO on IA64/Altix systems
+		 */
+		mmiowb();
 	}
 
 	return;

^ permalink raw reply related

* CitiBank Project
From: Jin.Zhang @ 2014-11-13 16:23 UTC (permalink / raw)
  To: netdev

Dear Attorney,

This is to inquire if your law firm handles Purchase and Sale Agreements in your area in the United States.

Regards,
Anthony Miyamoto
President & CEO
MIYAMOTO Industrial Co. Ltd.
6-4-10
NANKO-NAKA, SUMINOE-KU,
OSAKA, JAPAN 559-0033

^ permalink raw reply

* CitiBank Project
From: Jin.Zhang @ 2014-11-13 16:34 UTC (permalink / raw)
  To: netdev

Dear Attorney,

This is to inquire if your law firm handles Purchase and Sale Agreements in your area in the United States.

Regards,
Anthony Miyamoto
President & CEO
MIYAMOTO Industrial Co. Ltd.
6-4-10
NANKO-NAKA, SUMINOE-KU,
OSAKA, JAPAN 559-0033

^ permalink raw reply

* [PATCH net v3] vxlan: Do not reuse sockets for a different address family
From: Marcelo Ricardo Leitner @ 2014-11-13 16:43 UTC (permalink / raw)
  To: netdev; +Cc: stephen, sergei.shtylyov

Currently, we only match against local port number in order to reuse
socket. But if this new vxlan wants an IPv6 socket and a IPv4 one bound
to that port, vxlan will reuse an IPv4 socket as IPv6 and a panic will
follow. The following steps reproduce it:

   # ip link add vxlan6 type vxlan id 42 group 229.10.10.10 \
       srcport 5000 6000 dev eth0
   # ip link add vxlan7 type vxlan id 43 group ff0e::110 \
       srcport 5000 6000 dev eth0
   # ip link set vxlan6 up
   # ip link set vxlan7 up
   <panic>

[    4.187481] BUG: unable to handle kernel NULL pointer dereference at 0000000000000058
...
[    4.188076] Call Trace:
[    4.188085]  [<ffffffff81667c4a>] ? ipv6_sock_mc_join+0x3a/0x630
[    4.188098]  [<ffffffffa05a6ad6>] vxlan_igmp_join+0x66/0xd0 [vxlan]
[    4.188113]  [<ffffffff810a3430>] process_one_work+0x220/0x710
[    4.188125]  [<ffffffff810a33c4>] ? process_one_work+0x1b4/0x710
[    4.188138]  [<ffffffff810a3a3b>] worker_thread+0x11b/0x3a0
[    4.188149]  [<ffffffff810a3920>] ? process_one_work+0x710/0x710

So address family must also match in order to reuse a socket.

Reported-by: Jean-Tsung Hsiao <jhsiao@redhat.com>
Signed-off-by: Marcelo Ricardo Leitner <mleitner@redhat.com>
---
 drivers/net/vxlan.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 0ab411461d2ec2a0f57930a663f2e89842632a92..7ef7b0ead33c464bf5314c048d32127fe54335e1 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -275,13 +275,15 @@ static inline struct vxlan_rdst *first_remote_rtnl(struct vxlan_fdb *fdb)
 	return list_first_entry(&fdb->remotes, struct vxlan_rdst, list);
 }
 
-/* Find VXLAN socket based on network namespace and UDP port */
-static struct vxlan_sock *vxlan_find_sock(struct net *net, __be16 port)
+/* Find VXLAN socket based on network namespace, address family and UDP port */
+static struct vxlan_sock *vxlan_find_sock(struct net *net,
+					  sa_family_t family, __be16 port)
 {
 	struct vxlan_sock *vs;
 
 	hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
-		if (inet_sk(vs->sock->sk)->inet_sport == port)
+		if (inet_sk(vs->sock->sk)->inet_sport == port &&
+		    inet_sk(vs->sock->sk)->sk.sk_family == family)
 			return vs;
 	}
 	return NULL;
@@ -300,11 +302,12 @@ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, u32 id)
 }
 
 /* Look up VNI in a per net namespace table */
-static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id, __be16 port)
+static struct vxlan_dev *vxlan_find_vni(struct net *net, u32 id,
+					sa_family_t family, __be16 port)
 {
 	struct vxlan_sock *vs;
 
-	vs = vxlan_find_sock(net, port);
+	vs = vxlan_find_sock(net, family, port);
 	if (!vs)
 		return NULL;
 
@@ -1771,7 +1774,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 			struct vxlan_dev *dst_vxlan;
 
 			ip_rt_put(rt);
-			dst_vxlan = vxlan_find_vni(vxlan->net, vni, dst_port);
+			dst_vxlan = vxlan_find_vni(vxlan->net, vni,
+						   dst->sa.sa_family, dst_port);
 			if (!dst_vxlan)
 				goto tx_error;
 			vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1825,7 +1829,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
 			struct vxlan_dev *dst_vxlan;
 
 			dst_release(ndst);
-			dst_vxlan = vxlan_find_vni(vxlan->net, vni, dst_port);
+			dst_vxlan = vxlan_find_vni(vxlan->net, vni,
+						   dst->sa.sa_family, dst_port);
 			if (!dst_vxlan)
 				goto tx_error;
 			vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1985,13 +1990,15 @@ static int vxlan_init(struct net_device *dev)
 	struct vxlan_dev *vxlan = netdev_priv(dev);
 	struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
 	struct vxlan_sock *vs;
+	bool ipv6 = vxlan->flags & VXLAN_F_IPV6;
 
 	dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
 	if (!dev->tstats)
 		return -ENOMEM;
 
 	spin_lock(&vn->sock_lock);
-	vs = vxlan_find_sock(vxlan->net, vxlan->dst_port);
+	vs = vxlan_find_sock(vxlan->net, ipv6 ? AF_INET6 : AF_INET,
+			     vxlan->dst_port);
 	if (vs) {
 		/* If we have a socket with same port already, reuse it */
 		atomic_inc(&vs->refcnt);
@@ -2385,6 +2392,7 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
 {
 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 	struct vxlan_sock *vs;
+	bool ipv6 = flags & VXLAN_F_IPV6;
 
 	vs = vxlan_socket_create(net, port, rcv, data, flags);
 	if (!IS_ERR(vs))
@@ -2394,7 +2402,7 @@ struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
 		return vs;
 
 	spin_lock(&vn->sock_lock);
-	vs = vxlan_find_sock(net, port);
+	vs = vxlan_find_sock(net, ipv6 ? AF_INET6 : AF_INET, port);
 	if (vs) {
 		if (vs->rcv == rcv)
 			atomic_inc(&vs->refcnt);
@@ -2553,7 +2561,8 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
 	    nla_get_u8(data[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]))
 		vxlan->flags |= VXLAN_F_UDP_ZERO_CSUM6_RX;
 
-	if (vxlan_find_vni(net, vni, vxlan->dst_port)) {
+	if (vxlan_find_vni(net, vni, use_ipv6 ? AF_INET6 : AF_INET,
+			   vxlan->dst_port)) {
 		pr_info("duplicate VNI %u\n", vni);
 		return -EEXIST;
 	}
-- 
1.9.3

^ permalink raw reply related

* Re: [net-next PATCH 0/4] Clean up intel driver page reuse Rx code
From: Jeff Kirsher @ 2014-11-13 16:49 UTC (permalink / raw)
  To: Alexander Duyck; +Cc: netdev
In-Reply-To: <20141113161148.2790.22082.stgit@ahduyck-vm-fedora20>

[-- Attachment #1: Type: text/plain, Size: 1801 bytes --]

On Thu, 2014-11-13 at 08:18 -0800, Alexander Duyck wrote:
> This patch series cleans up the page reuse and Rx path so that all of the
> fixes that have been applied to any one driver are now in place for igb,
> fm10k, and ixgbe.  It occured to me that fm10k was missing the pfmemalloc
> bits, and ixgbe was missing some logic that reduced the number of writes
> needed as well as the pfmemalloc fix.
> 
> In addition ixgbe was carrying around some mostly-dead code that was
> wrapping a call to writel.  I removed it since it masked the fact that
> ixgbe was missing the mmiowb it was supposed to have between the tail write
> and the Tx queue lock release to prevent the MMIO access from racing
> between CPUs.
> 
> Also one change made to all 3 drivers is that we now only overwrite 3 of
> the 4 DWORDs in the Rx descriptor after allocation.  The last DWORD
> contains the upper 32 bits of the header address on fetch, and the length
> and vlan on writeback.  Since we are no longer using header split we don't
> need to clear it prior to descriptor fetch as it is unused so we can save
> ourselves a cycle on 32b systems by just leaving it untouched.
> 
> ---
> 
> Alexander Duyck (4):
>       igb: Clean-up page reuse code
>       fm10k: Clean-up page reuse code
>       ixgbe: Clean-up page reuse code
>       ixgbe: Remove tail write abstraction and add missing barrier
> 
> 
>  drivers/net/ethernet/intel/fm10k/fm10k_main.c |   34 ++++---
>  drivers/net/ethernet/intel/igb/igb_main.c     |   35 +++----
>  drivers/net/ethernet/intel/ixgbe/ixgbe.h      |    5 -
>  drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |  118 ++++++++++++-------------
>  4 files changed, 89 insertions(+), 103 deletions(-)
> 
> --

Thanks Alex, I will add your series to my queue.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply

* Re: [PATCH net-next 1/1] ipvlan: Initial check-in of the IPVLAN driver.
From: Mahesh Bandewar @ 2014-11-13 16:50 UTC (permalink / raw)
  To: Pavel Emelyanov
  Cc: netdev, Eric Dumazet, Maciej Zenczykowski, Laurent Chavey,
	Tim Hockin, David Miller, Brandon Philips
In-Reply-To: <546490E6.2050509@parallels.com>

On Thu, Nov 13, 2014 at 3:07 AM, Pavel Emelyanov <xemul@parallels.com> wrote:
>>>> +static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
>>>> +                        struct nlattr *tb[], struct nlattr *data[])
>>>> +{
>>>> +     struct ipvl_dev *ipvlan = netdev_priv(dev);
>>>> +     struct ipvl_port *port;
>>>> +     struct net_device *phy_dev;
>>>> +     int err;
>>>> +
>>>> +     ipvlan_dbg(3, "%s[%d]: Entering...\n", __func__, __LINE__);
>>>> +     if (!tb[IFLA_LINK]) {
>>>> +             ipvlan_dbg(3, "%s[%d]: Returning -EINVAL...\n",
>>>> +                        __func__, __LINE__);
>>>> +             return -EINVAL;
>>>> +     }
>>>> +
>>>> +     phy_dev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
>>>> +     if (phy_dev == NULL) {
>>>> +             ipvlan_dbg(3, "%s[%d]: Returning -ENODEV...\n",
>>>> +                        __func__, __LINE__);
>>>> +             return -ENODEV;
>>>> +     }
>>>> +
>>>> +     /* TODO will someone try creating ipvlan-dev on an ipvlan-virtual dev?*/
>>>> +     if (!ipvlan_dev_master(phy_dev)) {
>>>> +             err = ipvlan_port_create(phy_dev);
>>>> +             if (err < 0) {
>>>> +                     ipvlan_dbg(3, "%s[%d]: Returning error (%d)...\n",
>>>> +                                __func__, __LINE__, err);
>>>> +                     return err;
>>>> +             }
>>>> +     }
>>>> +
>>>> +     port = ipvlan_port_get_rtnl(phy_dev);
>>>> +     /* Get the mode if specified. */
>>>> +     if (data && data[IFLA_IPVLAN_MODE])
>>>> +             port->mode = nla_get_u16(data[IFLA_IPVLAN_MODE]);
>>>
>>> Should the invalid value be checked here? There are places
>>> where we BUG() in mode being "unknown".
>>>
>> Assuming the calls come over netlink, the ".validate" will be called
>> before ".newlink", so that would be unnecessary, isn't it?
>
> Yes, you're right. I've missed the validate callback.
>
>>>> +             break;
>>>> +
>>>
>>>> +static int ipvlan_addr4_event(struct notifier_block *unused,
>>>> +                           unsigned long event, void *ptr)
>>>> +{
>>>> +     struct in_ifaddr *if4 = (struct in_ifaddr *)ptr;
>>>> +     struct net_device *dev = (struct net_device *)if4->ifa_dev->dev;
>>>> +     struct ipvl_dev *ipvlan = netdev_priv(dev);
>>>> +     struct in_addr ip4_addr;
>>>> +
>>>> +     ipvlan_dbg(3, "%s[%d]: Entering...\n", __func__, __LINE__);
>>>> +     if (!ipvlan_dev_slave(dev))
>>>> +             return NOTIFY_DONE;
>>>> +
>>>> +     if (!ipvlan || !ipvlan->port)
>>>> +             return NOTIFY_DONE;
>>>> +
>>>> +     switch (event) {
>>>> +     case NETDEV_UP:
>>>
>>> Can it be (in the future) somehow restricted so that net-namespace wouldn't
>>> be able to assign arbitrary IP address here? One of the reasons for using
>>> such devices is to enforce the container to use the IP address given from
>>> the host.
>>>
>> Probably this could be a config (sysfs?) entry which would lockup the
>> config coming from ns when set. So code could look like -
>>           case NETDEV_UP:
>>                          if (!restrict_ns_config) {
>>                             ...
>>                          }
>>                          break;
>
> Maybe introduce some "lock" call for ipvlan device after which no new IP addresses
> can be assigned? And the configuration would look like
>
> 1. create ipvlan
> 2. move to proper net namespace
> 3. add addresses
> 4. lock
>
> ?
Yes. Exporting this "locked" property on the master device so that it
can be controlled from masters' net-ns. Only thing we have to ensure
is that both possibilities are allowed i.e. trusted ns where config do
not need to be locked as well as untrusted/hostile ns where one can
lock it down. However this is a future enhancement and if your
implementation idea is different than this concept; we can discuss it
at the time of implementation.
>
> Thanks,
> Pavel
>

^ permalink raw reply

* Re: [PATCH V4 2/3] can: m_can: update to support CAN FD features
From: Oliver Hartkopp @ 2014-11-13 16:56 UTC (permalink / raw)
  To: Marc Kleine-Budde, Dong Aisheng, linux-can
  Cc: wg, varkabhadram, netdev, linux-arm-kernel
In-Reply-To: <54648382.9080105@pengutronix.de>

On 11/13/2014 11:10 AM, Marc Kleine-Budde wrote:
> On 11/07/2014 09:45 AM, Dong Aisheng wrote:

>>  
>> -	if (id & RX_BUF_RTR) {
>> +	if (id & RX_BUF_ESI) {
>> +		cf->flags |= CANFD_ESI;
>> +		netdev_dbg(dev, "ESI Error\n");
>> +	}
>> +
>> +	if (!(dlc & RX_BUF_EDL) && (id & RX_BUF_RTR)) {
>>  		cf->can_id |= CAN_RTR_FLAG;
> 
> I just noticed, that you don't set the cf->dlc (or cf->len) in the RTR
> case. Please create a separate patch that fixes this problem.
> 
>>  	} else {
>>  		id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC);
>> -		cf->can_dlc = get_can_dlc((id >> 16) & 0x0F);
>> -		*(u32 *)(cf->data + 0) = m_can_fifo_read(priv, fgi,
>> -							 M_CAN_FIFO_DATA(0));
>> -		*(u32 *)(cf->data + 4) = m_can_fifo_read(priv, fgi,
>> -							 M_CAN_FIFO_DATA(1));
>> +		if (dlc & RX_BUF_EDL)
>> +			cf->len = can_dlc2len((id >> 16) & 0x0F);
>> +		else
>> +			cf->len = get_can_dlc((id >> 16) & 0x0F);
>> +

Grr. I missed that one too :-(

Thanks for catching it.

As you committed patch 1 & 3 you expect a new single patch containing the
(fixed) content of this patch 2, right?

Regards,
Oliver


^ permalink raw reply

* Re: [PATCH net-next 1/1] ipvlan: Initial check-in of the IPVLAN driver.
From: Pavel Emelyanov @ 2014-11-13 15:57 UTC (permalink / raw)
  To: Mahesh Bandewar
  Cc: netdev, Eric Dumazet, Maciej Zenczykowski, Laurent Chavey,
	Tim Hockin, David Miller, Brandon Philips
In-Reply-To: <CAF2d9jjmFymJdZmnfDCCUTRSSm-63RPaEFdB3TeYOq9S3jcPOA@mail.gmail.com>


>> Maybe introduce some "lock" call for ipvlan device after which no new IP addresses
>> can be assigned? And the configuration would look like
>>
>> 1. create ipvlan
>> 2. move to proper net namespace
>> 3. add addresses
>> 4. lock
>>
>> ?
> Yes. Exporting this "locked" property on the master device so that it
> can be controlled from masters' net-ns. Only thing we have to ensure
> is that both possibilities are allowed i.e. trusted ns where config do
> not need to be locked as well as untrusted/hostile ns where one can
> lock it down. However this is a future enhancement and if your
> implementation idea is different than this concept; we can discuss it
> at the time of implementation.

Sure. It's not a wish for the very first version of the set, it can
be added later.

Thanks,
Pavel

^ permalink raw reply


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