All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 22/25] usb: chipidea: Drop lock across event_notify during gadget stop
From: Peter Chen @ 2017-01-03  6:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161228225711.698-23-stephen.boyd@linaro.org>

On Wed, Dec 28, 2016 at 02:57:08PM -0800, Stephen Boyd wrote:
> The CI_HDRC_CONTROLLER_STOPPED_EVENT may want to call sleeping
> APIs similar to how _gadget_stop_activity() may. Let's drop the
> lock across the event so that glue drivers can make sleeping
> calls.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/udc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 0db56fb7e9e9..0d532a724d48 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -1793,10 +1793,10 @@ static int ci_udc_stop(struct usb_gadget *gadget)
>  
>  	if (ci->vbus_active) {
>  		hw_device_state(ci, 0);
> +		spin_unlock_irqrestore(&ci->lock, flags);
>  		if (ci->platdata->notify_event)
>  			ci->platdata->notify_event(ci,
>  			CI_HDRC_CONTROLLER_STOPPED_EVENT);
> -		spin_unlock_irqrestore(&ci->lock, flags);
>  		_gadget_stop_activity(&ci->gadget);
>  		spin_lock_irqsave(&ci->lock, flags);
>  		pm_runtime_put(&ci->gadget.dev);
> -- 

Acked-by: Peter Chen <peter.chen@nxp.com>

-- 

Best Regards,
Peter Chen

^ permalink raw reply

* Re: [PATCH 1/1] ipoib: remove unnecessary returned value check
From: Yuval Shaia @ 2017-01-03  6:46 UTC (permalink / raw)
  To: Yanjun Zhu
  Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	emilbart-Re5JQEeQqe8AvxtiuMwx3w,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dan.j.williams-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <586B0DB8.3060301-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>

On Tue, Jan 03, 2017 at 10:34:32AM +0800, Yanjun Zhu wrote:
> Any comment ?

You will have to make change also to __ipoib_vlan_add

> 
> 
> On 2016/12/19 20:49, Zhu Yanjun wrote:
> >In the function ipoib_set_dev_features, the returned value is always 0.
> >As such, it is not necessary to check the returned value.
> >This is not a bug. When I read the source code, I think it is not
> >necessary to check it.

Please rephrase - omit the words "I think".

> >
> >Signed-off-by: Zhu Yanjun <yanjun.zhu-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> >---
> >  drivers/infiniband/ulp/ipoib/ipoib.h      | 2 +-
> >  drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 ++------
> >  2 files changed, 3 insertions(+), 7 deletions(-)
> >
> >diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
> >index da12717..f568064 100644
> >--- a/drivers/infiniband/ulp/ipoib/ipoib.h
> >+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
> >@@ -593,7 +593,7 @@ void ipoib_pkey_open(struct ipoib_dev_priv *priv);
> >  void ipoib_drain_cq(struct net_device *dev);
> >  void ipoib_set_ethtool_ops(struct net_device *dev);
> >-int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca);
> >+void ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca);
> >  #define IPOIB_FLAGS_RC		0x80
> >  #define IPOIB_FLAGS_UC		0x40
> >diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
> >index 3ce0765..4e8e11e 100644
> >--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
> >+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
> >@@ -1984,7 +1984,7 @@ int ipoib_add_pkey_attr(struct net_device *dev)
> >  	return device_create_file(&dev->dev, &dev_attr_pkey);
> >  }
> >-int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
> >+void ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
> >  {
> >  	priv->hca_caps = hca->attrs.device_cap_flags;
> >@@ -1996,8 +1996,6 @@ int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
> >  		priv->dev->features |= priv->dev->hw_features;
> >  	}
> >-
> >-	return 0;
> >  }
> >  static struct net_device *ipoib_add_port(const char *format,
> >@@ -2037,9 +2035,7 @@ static struct net_device *ipoib_add_port(const char *format,
> >  		goto device_init_failed;
> >  	}
> >-	result = ipoib_set_dev_features(priv, hca);
> >-	if (result)
> >-		goto device_init_failed;
> >+	ipoib_set_dev_features(priv, hca);
> >  	/*
> >  	 * Set the full membership bit, so that we join the right
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] mmc: dw_mmc: update clock after ctrl reset in runtime resume
From: Ziyuan Xu @ 2017-01-03  6:46 UTC (permalink / raw)
  To: ulf.hansson, jh80.chung, shawn.lin
  Cc: linux-mmc, randy.li, linux-rockchip, Ziyuan Xu

Immediately after reset, issue the command which sets
update_clock_register_only bit, the card clock will restart.

MMC_PM_KEEP_POWER is disabled for SD card and eMMC slots, so that they
have no chance to invoke dw_mci_setup_bus for update clock behaviour.
Let's consummate it.

Fixes: e9ed883 ("mmc: dw_mmc: add runtime PM callback")
Reported-by: Randy Li <randy.li@rock-chips.com>
Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
---
 drivers/mmc/host/dw_mmc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index b44306b..71715b4 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -3357,6 +3357,8 @@ int dw_mci_runtime_resume(struct device *dev)
 		if (slot->mmc->pm_flags & MMC_PM_KEEP_POWER) {
 			dw_mci_set_ios(slot->mmc, &slot->mmc->ios);
 			dw_mci_setup_bus(slot, true);
+		} else {
+			mci_send_cmd(slot, SDMMC_CMD_UPD_CLK, 0);
 		}
 	}
 
-- 
2.7.4



^ permalink raw reply related

* Re: [TOOL] wg-config graduates to src/tools, becomes wg-auto-config
From: Jason A. Donenfeld @ 2017-01-03  6:57 UTC (permalink / raw)
  To: Daniel Kahn Gillmor; +Cc: WireGuard mailing list

On Tue, Jan 3, 2017 at 7:46 AM, Daniel Kahn Gillmor
<dkg@fifthhorseman.net> wrote:
> debian is unlikely to install this if it is expected to be named with a
> .bash suffix:

That's just the title in the source tree. The make file installs it as
`wg-auto-config`.

> That said, i'm not sure what you want with this.  If the ultimate goal
> is to have systemd-style .network files, you should ask for these
> changes in systemd itself.  That's likely the cleanest approach.  If you
> do this, please post a link here to the systemd github issue or pull
> request. :)

There already is a systemd-networkd pull request. I didn't write the
code for it, and it seems like it could use quite a bit of review, but
I'm pretty sure systemd-networkd .network files are going to happen.

The goal of this tool is just to have something quick&dirty for people
to use for flipping on and off their VPN. And it seems like some
people who don't use systemd-network wanted something easy they could
run from a "wireguard@.service" file.

If you have an objection to shipping this, I could just move it back
into contrib.

> (a) fork and exec ip from wg itself
> when running "wg setconf"

Not an option. wg(8) is intended to only take care of
wireguard-related things, and not overlap with ip(8). It should not be
a network management tool at all. In fact, the ultimate goal is to
fold its functionality into iproute2/ip(8).

> (b) name the wrapper something like
> /usr/bin/wg+ip

That's a decent idea for a name. But it does a _bit_ more than merely
combine the two utilities.

So, it seems like thing to do at this point would be to open this
thread up for bike-shedding over the name. What might we call this
tool to convey what it does?

- wg-helper
- wg-quick-setup
- wg-ezconfig
- wg-wrapper
- wg+ip+magic
- ??

^ permalink raw reply

* Re: LTP rwtest01 blocks on DAX mountpoint
From: Xiong Zhou @ 2017-01-03  6:49 UTC (permalink / raw)
  To: Ross Zwisler, Jan Kara, Xiong Zhou, linux-fsdevel, linux-nvdimm,
	linux-kernel
In-Reply-To: <20170102214941.GA2813@linux.intel.com>

On Mon, Jan 02, 2017 at 02:49:41PM -0700, Ross Zwisler wrote:
> On Mon, Jan 02, 2017 at 06:16:17PM +0100, Jan Kara wrote:
> > On Fri 30-12-16 17:33:53, Xiong Zhou wrote:
> > > On Sat, Dec 24, 2016 at 07:07:14PM +0800, Xiong Zhou wrote:
> > > > Hi lists,
snip
> > I was trying to reproduce this but for me rwtest01 completes just fine on
> > dax mountpoint (I've used your reproducer). So can you sample several
> > kernel stack traces to get a rough idea where the kernel is running?
> > Thanks!
> > 
> > 								Honza
> 
> I'm also unable to reproduce this issue.  I've tried with both the blamed
> commit:
> 4b4bb46 (HEAD) dax: clear dirty entry tags on cache flush
> and with v4.9-rc2.  Both pass the test in my setup.
> Perhaps the variable is the size of your PMEM partitions?
> # fdisk -l /dev/pmem0
> Disk /dev/pmem0: 16 GiB, 17179869184 bytes, 33554432 sectors
> Units: sectors of 1 * 512 = 512 bytes
> Sector size (logical/physical): 512 bytes / 4096 bytes
> I/O size (minimum/optimal): 4096 bytes / 4096 bytes
> Disklabel type: dos
> Disk identifier: 0xfe50c900
> Device       Boot    Start      End  Sectors Size Id Type
> /dev/pmem0p1          4096 25165823 25161728  12G 83 Linux
> /dev/pmem0p2      25165824 33550335  8384512   4G 83 Linux
> 
> What does your setup look like?
> I'm using the current tip of the LTP tree:
> 8cc4165  waitid02: define _XOPEN_SOURCE 500
> Thanks,
> - Ross

Thanks all for looking into it.

Turns out the rc2 relative updates fix this issue, so does
an old issue i reported a while ago:
multi-threads libvmmalloc fork test hang
https://lists.01.org/pipermail/linux-nvdimm/2016-October/007602.html

I'm able to reproduce these issues before rc2, now it
passes on current Linus tree:
c8b4ec8 Merge tag 'fscrypt-for-stable'

Thanks,
Xiong

> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" 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

* [Qemu-devel] [PATCH] virtio-crypto: fix possible integer and heap overflow
From: Gonglei @ 2017-01-03  6:50 UTC (permalink / raw)
  To: qemu-devel; +Cc: mst, liqiang6-s, Gonglei, qemu-stable

Because the 'size_t' type is 4 bytes in 32-bit platform, which
is the same with 'int'. It's easy to make 'max_len' to zero when
integer overflow and then cause heap overflow if 'max_len' is zero.

Using uint_64 instead of size_t to avoid the integer overflow.

Cc: qemu-stable@nongnu.org
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Tested-by: Li Qiang <liqiang6-s@360.cn>
---
 hw/virtio/virtio-crypto.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 978bb98..fc30bc3 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -416,7 +416,7 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev,
     uint32_t hash_start_src_offset = 0, len_to_hash = 0;
     uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;
 
-    size_t max_len, curr_size = 0;
+    uint64_t max_len, curr_size = 0;
     size_t s;
 
     /* Plain cipher */
@@ -441,7 +441,7 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev,
         return NULL;
     }
 
-    max_len = iv_len + aad_len + src_len + dst_len + hash_result_len;
+    max_len = (uint64_t)iv_len + aad_len + src_len + dst_len + hash_result_len;
     if (unlikely(max_len > vcrypto->conf.max_size)) {
         virtio_error(vdev, "virtio-crypto too big length");
         return NULL;
-- 
1.8.3.1

^ permalink raw reply related

* Re: [PATCH 2/2] rainshadow-cec: new RainShadow Tech HDMI CEC driver
From: Dmitry Torokhov @ 2017-01-03  6:51 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media, linux-input, Hans Verkuil
In-Reply-To: <20161215130207.12913-3-hverkuil@xs4all.nl>

Hi Hans,

On Thu, Dec 15, 2016 at 02:02:07PM +0100, Hans Verkuil wrote:
> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> This driver supports the RainShadow Tech USB HDMI CEC adapter.
> 
> See: http://rainshadowtech.com/HdmiCecUsb.html
> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  MAINTAINERS                                       |   7 +
>  drivers/media/usb/Kconfig                         |   1 +
>  drivers/media/usb/Makefile                        |   1 +
>  drivers/media/usb/rainshadow-cec/Kconfig          |  10 +
>  drivers/media/usb/rainshadow-cec/Makefile         |   1 +
>  drivers/media/usb/rainshadow-cec/rainshadow-cec.c | 344 ++++++++++++++++++++++
>  6 files changed, 364 insertions(+)
>  create mode 100644 drivers/media/usb/rainshadow-cec/Kconfig
>  create mode 100644 drivers/media/usb/rainshadow-cec/Makefile
>  create mode 100644 drivers/media/usb/rainshadow-cec/rainshadow-cec.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 52cc077..78ebc5d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -10069,6 +10069,13 @@ L:	linux-fbdev@vger.kernel.org
>  S:	Maintained
>  F:	drivers/video/fbdev/aty/aty128fb.c
>  
> +RAINSHADOW-CEC DRIVER
> +M:	Hans Verkuil <hverkuil@xs4all.nl>
> +L:	linux-media@vger.kernel.org
> +T:	git git://linuxtv.org/media_tree.git
> +S:	Maintained
> +F:	drivers/media/usb/rainshadow-cec/*
> +
>  RALINK MIPS ARCHITECTURE
>  M:	John Crispin <john@phrozen.org>
>  L:	linux-mips@linux-mips.org
> diff --git a/drivers/media/usb/Kconfig b/drivers/media/usb/Kconfig
> index c9644b6..b24e753 100644
> --- a/drivers/media/usb/Kconfig
> +++ b/drivers/media/usb/Kconfig
> @@ -63,6 +63,7 @@ endif
>  if MEDIA_CEC_SUPPORT
>  	comment "USB HDMI CEC adapters"
>  source "drivers/media/usb/pulse8-cec/Kconfig"
> +source "drivers/media/usb/rainshadow-cec/Kconfig"
>  endif
>  
>  endif #MEDIA_USB_SUPPORT
> diff --git a/drivers/media/usb/Makefile b/drivers/media/usb/Makefile
> index 0f15e33..738b993 100644
> --- a/drivers/media/usb/Makefile
> +++ b/drivers/media/usb/Makefile
> @@ -25,3 +25,4 @@ obj-$(CONFIG_VIDEO_USBTV) += usbtv/
>  obj-$(CONFIG_VIDEO_GO7007) += go7007/
>  obj-$(CONFIG_DVB_AS102) += as102/
>  obj-$(CONFIG_USB_PULSE8_CEC) += pulse8-cec/
> +obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec/
> diff --git a/drivers/media/usb/rainshadow-cec/Kconfig b/drivers/media/usb/rainshadow-cec/Kconfig
> new file mode 100644
> index 0000000..447291b
> --- /dev/null
> +++ b/drivers/media/usb/rainshadow-cec/Kconfig
> @@ -0,0 +1,10 @@
> +config USB_RAINSHADOW_CEC
> +	tristate "RainShadow Tech HDMI CEC"
> +	depends on USB_ACM && MEDIA_CEC_SUPPORT
> +	select SERIO
> +	select SERIO_SERPORT
> +	---help---
> +	  This is a cec driver for the RainShadow Tech HDMI CEC device.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called rainshadow-cec.
> diff --git a/drivers/media/usb/rainshadow-cec/Makefile b/drivers/media/usb/rainshadow-cec/Makefile
> new file mode 100644
> index 0000000..a79fbc7
> --- /dev/null
> +++ b/drivers/media/usb/rainshadow-cec/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_USB_RAINSHADOW_CEC) += rainshadow-cec.o
> diff --git a/drivers/media/usb/rainshadow-cec/rainshadow-cec.c b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
> new file mode 100644
> index 0000000..dc7f287
> --- /dev/null
> +++ b/drivers/media/usb/rainshadow-cec/rainshadow-cec.c
> @@ -0,0 +1,344 @@
> +/*
> + * RainShadow Tech HDMI CEC driver
> + *
> + * Copyright 2016 Hans Verkuil <hverkuil@xs4all.nl
> + *
> + * 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 of 2 of the License, or (at your
> + * option) any later version. See the file COPYING in the main directory of
> + * this archive for more details.
> + */
> +
> +/*
> + * Notes:
> + *
> + * The higher level protocols are currently disabled. This can be added
> + * later, similar to how this is done for the Pulse Eight CEC driver.
> + *
> + * Documentation of the protocol is available here:
> + *
> + * http://rainshadowtech.com/doc/HDMICECtoUSBandRS232v2.0.pdf
> + */
> +
> +#include <linux/completion.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/workqueue.h>
> +#include <linux/serio.h>
> +#include <linux/slab.h>
> +#include <linux/time.h>
> +#include <linux/delay.h>
> +#include <linux/ctype.h>
> +
> +#include <media/cec.h>
> +
> +MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
> +MODULE_DESCRIPTION("RainShadow Tech HDMI CEC driver");
> +MODULE_LICENSE("GPL");
> +
> +static int debug;
> +module_param(debug, int, 0644);
> +MODULE_PARM_DESC(debug, "debug level (0-1)");
> +
> +#define DATA_SIZE 256
> +
> +struct rain {
> +	struct device *dev;
> +	struct serio *serio;
> +	struct cec_adapter *adap;
> +	struct completion cmd_done;
> +	struct work_struct work;
> +	struct cec_msg rx_msg;
> +	char data[DATA_SIZE];
> +	char buf[DATA_SIZE];
> +	unsigned int idx;
> +	bool started;
> +	struct mutex write_lock;
> +};
> +
> +static void rain_irq_work_handler(struct work_struct *work)
> +{
> +	struct rain *rain =
> +		container_of(work, struct rain, work);
> +	struct cec_msg *msg = &rain->rx_msg;
> +	const char *data = rain->data + 3;
> +	int stat = -1;
> +
> +	msg->len = 0;
> +	for (; *data; data++) {
> +		if (!isxdigit(*data))
> +			continue;
> +		if (isxdigit(data[0]) && isxdigit(data[1])) {
> +			if (msg->len == CEC_MAX_MSG_SIZE)
> +				break;
> +			hex2bin(msg->msg + msg->len, data, 2);
> +			msg->len++;
> +			data++;
> +			continue;
> +		}
> +		if (!data[1])
> +			stat = hex_to_bin(data[0]);
> +		break;
> +	}
> +
> +	if (rain->data[0] == 'R') {
> +		if (stat == 1 || stat == 2)
> +			cec_received_msg(rain->adap, msg);
> +		return;
> +	}
> +
> +	switch (stat) {
> +	case 1:
> +		cec_transmit_done(rain->adap, CEC_TX_STATUS_OK,
> +				  0, 0, 0, 0);
> +		break;
> +	case 2:
> +		cec_transmit_done(rain->adap, CEC_TX_STATUS_NACK,
> +				  0, 1, 0, 0);
> +		break;
> +	default:
> +		cec_transmit_done(rain->adap, CEC_TX_STATUS_LOW_DRIVE,
> +				  0, 0, 0, 1);
> +		break;
> +	}
> +}
> +
> +static irqreturn_t rain_interrupt(struct serio *serio, unsigned char data,
> +				    unsigned int flags)
> +{
> +	struct rain *rain = serio_get_drvdata(serio);
> +
> +	if (!rain->started && data != '?')
> +		return IRQ_HANDLED;
> +	if (data == '\r') {
> +		rain->buf[rain->idx] = '\0';
> +		if (debug)
> +			dev_info(rain->dev, "received: %s\n", rain->buf);

Just dev_dbg() please. I think everyone is using dynamic debug.

> +		strcpy(rain->data, rain->buf);
> +		if (!memcmp(rain->data, "REC", 3) ||
> +		    !memcmp(rain->data, "STA", 3))
> +			schedule_work(&rain->work);
> +		else
> +			complete(&rain->cmd_done);
> +		rain->idx = 0;
> +		rain->started = false;
> +		return IRQ_HANDLED;

This relies on work to complete before you receive the next message,
which is not always the case as far as I can understand.

> +	} else if (data == '?') {
> +		rain->idx = 0;
> +		rain->started = true;
> +		return IRQ_HANDLED;
> +	}
> +
> +	if (data == '\n') {

Should it be a "switch (data) {" ?

> +		rain->idx = 0;
> +		rain->started = false;
> +		return IRQ_HANDLED;
> +	}
> +	if (rain->idx >= DATA_SIZE - 1) {
> +		dev_dbg(rain->dev,
> +			"throwing away %d bytes of garbage\n", rain->idx);
> +		rain->idx = 0;
> +	}
> +	rain->buf[rain->idx++] = data;
> +	return IRQ_HANDLED;
> +}
> +
> +static void rain_disconnect(struct serio *serio)
> +{
> +	struct rain *rain = serio_get_drvdata(serio);
> +
> +	cec_unregister_adapter(rain->adap);
> +	dev_info(&serio->dev, "disconnected\n");
> +	serio_close(serio);
> +	serio_set_drvdata(serio, NULL);
> +	kfree(rain);
> +}
> +
> +static int rain_send(struct rain *rain, const char *command)
> +{
> +	int err = serio_write(rain->serio, '!');
> +
> +	if (debug)
> +		dev_info(rain->dev, "send: %s\n", command);
> +	while (!err && *command)
> +		err = serio_write(rain->serio, *command++);
> +	if (!err)
> +		err = serio_write(rain->serio, '~');
> +
> +	return err;
> +}
> +
> +static int rain_send_and_wait(struct rain *rain,
> +			      const char *cmd, const char *reply)
> +{
> +	int err;
> +
> +	init_completion(&rain->cmd_done);
> +
> +	mutex_lock(&rain->write_lock);
> +	err = rain_send(rain, cmd);
> +	if (err)
> +		goto err;
> +
> +	if (!wait_for_completion_timeout(&rain->cmd_done, HZ)) {
> +		err = -ETIMEDOUT;
> +		goto err;
> +	}
> +	if (reply && strncmp(rain->data, reply, strlen(reply))) {
> +		if (debug)
> +			dev_info(rain->dev,
> +				 "transmit of '%s': received '%s' instead of '%s'\n",
> +				 cmd, rain->data, reply);
> +		err = -EIO;
> +	}
> +err:
> +	mutex_unlock(&rain->write_lock);
> +	return err;
> +}
> +
> +static int rain_setup(struct rain *rain, struct serio *serio,
> +			struct cec_log_addrs *log_addrs, u16 *pa)
> +{
> +	u16 res;
> +	int err;
> +
> +	err = rain_send_and_wait(rain, "R", "REV");
> +	if (err)
> +		return err;
> +	dev_info(rain->dev, "Firmware version %s\n", rain->data + 4);
> +
> +	err = rain_send_and_wait(rain, "Q 1", "QTY");
> +	if (err)
> +		return err;
> +	err = rain_send_and_wait(rain, "c0000", "CFG");
> +	if (err)
> +		return err;
> +	return rain_send_and_wait(rain, "A F 0000", "ADR");

Given that this is instantiated via serport + inputattach the setup
sequence should be done in inputattach, not kernel.

> +}
> +
> +static int rain_cec_adap_enable(struct cec_adapter *adap, bool enable)
> +{
> +	return 0;
> +}
> +
> +static int rain_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
> +{
> +	struct rain *rain = adap->priv;
> +	u8 cmd[16];
> +
> +	if (log_addr == CEC_LOG_ADDR_INVALID)
> +		log_addr = CEC_LOG_ADDR_UNREGISTERED;
> +	snprintf(cmd, sizeof(cmd), "A %x", log_addr);
> +	return rain_send_and_wait(rain, cmd, "ADR");
> +}
> +
> +static int rain_cec_adap_transmit(struct cec_adapter *adap, u8 attempts,
> +				    u32 signal_free_time, struct cec_msg *msg)
> +{
> +	struct rain *rain = adap->priv;
> +	char cmd[2 * CEC_MAX_MSG_SIZE + 16];
> +	unsigned int i;
> +	int err;
> +
> +	if (msg->len == 1) {
> +		snprintf(cmd, sizeof(cmd), "x%x", cec_msg_destination(msg));
> +	} else {
> +		char hex[3];
> +
> +		snprintf(cmd, sizeof(cmd), "x%x %02x ",
> +			 cec_msg_destination(msg), msg->msg[1]);
> +		for (i = 2; i < msg->len; i++) {
> +			snprintf(hex, sizeof(hex), "%02x", msg->msg[i]);
> +			strncat(cmd, hex, sizeof(cmd));
> +		}
> +	}
> +	mutex_lock(&rain->write_lock);
> +	err = rain_send(rain, cmd);
> +	mutex_unlock(&rain->write_lock);
> +	return err;
> +}
> +
> +static const struct cec_adap_ops rain_cec_adap_ops = {
> +	.adap_enable = rain_cec_adap_enable,
> +	.adap_log_addr = rain_cec_adap_log_addr,
> +	.adap_transmit = rain_cec_adap_transmit,
> +};
> +
> +static int rain_connect(struct serio *serio, struct serio_driver *drv)
> +{
> +	u32 caps = CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS | CEC_CAP_PHYS_ADDR |
> +		CEC_CAP_PASSTHROUGH | CEC_CAP_RC | CEC_CAP_MONITOR_ALL;
> +	struct rain *rain;
> +	int err = -ENOMEM;
> +	struct cec_log_addrs log_addrs = {};
> +	u16 pa = CEC_PHYS_ADDR_INVALID;
> +
> +	rain = kzalloc(sizeof(*rain), GFP_KERNEL);
> +
> +	if (!rain)
> +		return -ENOMEM;
> +
> +	rain->serio = serio;
> +	rain->adap = cec_allocate_adapter(&rain_cec_adap_ops, rain,
> +		"HDMI CEC", caps, 1);
> +	err = PTR_ERR_OR_ZERO(rain->adap);
> +	if (err < 0)
> +		goto free_device;
> +
> +	rain->dev = &serio->dev;
> +	serio_set_drvdata(serio, rain);
> +	INIT_WORK(&rain->work, rain_irq_work_handler);
> +	mutex_init(&rain->write_lock);
> +
> +	err = serio_open(serio, drv);
> +	if (err)
> +		goto delete_adap;
> +
> +	err = rain_setup(rain, serio, &log_addrs, &pa);
> +	if (err)
> +		goto close_serio;
> +
> +	err = cec_register_adapter(rain->adap, &serio->dev);
> +	if (err < 0)
> +		goto close_serio;
> +
> +	rain->dev = &rain->adap->devnode.dev;
> +	return 0;
> +
> +close_serio:
> +	serio_close(serio);
> +delete_adap:
> +	cec_delete_adapter(rain->adap);
> +	serio_set_drvdata(serio, NULL);
> +free_device:
> +	kfree(rain);
> +	return err;
> +}
> +
> +static struct serio_device_id rain_serio_ids[] = {
> +	{
> +		.type	= SERIO_RS232,
> +		.proto	= SERIO_RAINSHADOW_CEC,
> +		.id	= SERIO_ANY,
> +		.extra	= SERIO_ANY,
> +	},
> +	{ 0 }
> +};
> +
> +MODULE_DEVICE_TABLE(serio, rain_serio_ids);
> +
> +static struct serio_driver rain_drv = {
> +	.driver		= {
> +		.name	= "rainshadow-cec",
> +	},
> +	.description	= "RainShadow Tech HDMI CEC driver",
> +	.id_table	= rain_serio_ids,
> +	.interrupt	= rain_interrupt,
> +	.connect	= rain_connect,
> +	.disconnect	= rain_disconnect,
> +};
> +
> +module_serio_driver(rain_drv);
> -- 
> 2.10.2
> 

Thanks.

-- 
Dmitry

^ permalink raw reply

* [PATCH 2/2] iio: Add linear accel sensor hid support
From: Song Hongyan @ 2017-01-03 15:13 UTC (permalink / raw)
  To: linux-input, linux-iio; +Cc: jikos, jic23, srinivas.pandruvada, Song Hongyan
In-Reply-To: <1483456430-6980-1-git-send-email-hongyan.song@intel.com>

Linear acceleration is a soft sensor it differs from a standard
accel sensor, it provides a three-dimensional vector representing
acceleration along each device axis, excluding gravity.
The sensor data is derives from standard accelerometer device
by filtering out the acceleration which is caused by the force
of Earth’s gravity.

The value can be used to perform gesture detection, it can also
serve as input to an inertial navigation system, which uses
dead reckoning.

More information can be found in:
http://www.usb.org/developers/hidpage/HUTRR59_-_Usages_for_Wearables.pdf

Linear accel sensor, gravity sensor and accelerometer have similar
channels and share channel usage ids. So the most of the code for
accel_3d can be reused.

Signed-off-by: Song Hongyan <hongyan.song@intel.com>
---
 drivers/iio/accel/hid-sensor-accel-3d.c | 42 +++++++++++++++++++++++++++++++++
 include/linux/hid-sensor-ids.h          |  3 +++
 2 files changed, 45 insertions(+)

diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c b/drivers/iio/accel/hid-sensor-accel-3d.c
index 9edd574..6ce460f 100644
--- a/drivers/iio/accel/hid-sensor-accel-3d.c
+++ b/drivers/iio/accel/hid-sensor-accel-3d.c
@@ -91,6 +91,41 @@ struct accel_3d_state {
 };
 
 /* Channel definitions */
+static const struct iio_chan_spec linear_accel_3d_channels[] = {
+	{
+		.type = IIO_LINEAR_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_X,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+		BIT(IIO_CHAN_INFO_SCALE) |
+		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+		BIT(IIO_CHAN_INFO_HYSTERESIS),
+		.scan_index = CHANNEL_SCAN_INDEX_X,
+	}, {
+		.type = IIO_LINEAR_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Y,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+		BIT(IIO_CHAN_INFO_SCALE) |
+		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+		BIT(IIO_CHAN_INFO_HYSTERESIS),
+		.scan_index = CHANNEL_SCAN_INDEX_Y,
+	}, {
+		.type = IIO_LINEAR_ACCEL,
+		.modified = 1,
+		.channel2 = IIO_MOD_Z,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
+		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_OFFSET) |
+		BIT(IIO_CHAN_INFO_SCALE) |
+		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
+		BIT(IIO_CHAN_INFO_HYSTERESIS),
+		.scan_index = CHANNEL_SCAN_INDEX_Z,
+	}
+};
+
+/* Channel definitions */
 static const struct iio_chan_spec gravity_channels[] = {
 	{
 		.type = IIO_GRAVITY,
@@ -354,6 +389,10 @@ static int hid_accel_3d_probe(struct platform_device *pdev)
 		name = "accel_3d";
 		channel_spec = accel_3d_channels;
 		channel_size = sizeof(accel_3d_channels);
+	} else if (hsdev->usage == HID_USAGE_SENSOR_LINEAR_ACCEL_3D) {
+		name = "linear_accel_3d";
+		channel_spec = linear_accel_3d_channels;
+		channel_size = sizeof(linear_accel_3d_channels);
 	} else {
 		name = "gravity";
 		channel_spec = gravity_channels;
@@ -452,6 +491,9 @@ static int hid_accel_3d_remove(struct platform_device *pdev)
 	{	/* gravity sensor */
 		.name = "HID-SENSOR-20007b",
 	},
+	{	/* linear_accel sensor */
+		.name = "HID-SENSOR-20007c",
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(platform, hid_accel_3d_ids);
diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-sensor-ids.h
index b6778fd2..b0b26a0 100644
--- a/include/linux/hid-sensor-ids.h
+++ b/include/linux/hid-sensor-ids.h
@@ -55,6 +55,9 @@
 /* Gravity vector */
 #define HID_USAGE_SENSOR_GRAVITY_VECTOR				0x20007B
 
+/* linear accel */
+#define HID_USAGE_SENSOR_LINEAR_ACCEL_3D			0x20007C
+
 /* ORIENTATION: Compass 3D: (200083) */
 #define HID_USAGE_SENSOR_COMPASS_3D				0x200083
 #define HID_USAGE_SENSOR_DATA_ORIENTATION			0x200470
-- 
1.9.1


^ permalink raw reply related

* Re: [PATCH 1/1] ipoib: remove unnecessary returned value check
From: Yuval Shaia @ 2017-01-03  6:51 UTC (permalink / raw)
  To: Yanjun Zhu
  Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	emilbart-Re5JQEeQqe8AvxtiuMwx3w,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	dan.j.williams-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <586B0DB8.3060301-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>

On Tue, Jan 03, 2017 at 10:34:32AM +0800, Yanjun Zhu wrote:
> Any comment ?

In addition to my previous mail, suggesting to change the commit header to
be more consistent.

IB/ipoib: Remove unnecessary returned value check

> 
> 
> On 2016/12/19 20:49, Zhu Yanjun wrote:
> >In the function ipoib_set_dev_features, the returned value is always 0.
> >As such, it is not necessary to check the returned value.
> >This is not a bug. When I read the source code, I think it is not
> >necessary to check it.
> >
> >Signed-off-by: Zhu Yanjun <yanjun.zhu-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
> >---
> >  drivers/infiniband/ulp/ipoib/ipoib.h      | 2 +-
> >  drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 ++------
> >  2 files changed, 3 insertions(+), 7 deletions(-)
> >
> >diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
> >index da12717..f568064 100644
> >--- a/drivers/infiniband/ulp/ipoib/ipoib.h
> >+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
> >@@ -593,7 +593,7 @@ void ipoib_pkey_open(struct ipoib_dev_priv *priv);
> >  void ipoib_drain_cq(struct net_device *dev);
> >  void ipoib_set_ethtool_ops(struct net_device *dev);
> >-int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca);
> >+void ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca);
> >  #define IPOIB_FLAGS_RC		0x80
> >  #define IPOIB_FLAGS_UC		0x40
> >diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
> >index 3ce0765..4e8e11e 100644
> >--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
> >+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
> >@@ -1984,7 +1984,7 @@ int ipoib_add_pkey_attr(struct net_device *dev)
> >  	return device_create_file(&dev->dev, &dev_attr_pkey);
> >  }
> >-int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
> >+void ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
> >  {
> >  	priv->hca_caps = hca->attrs.device_cap_flags;
> >@@ -1996,8 +1996,6 @@ int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca)
> >  		priv->dev->features |= priv->dev->hw_features;
> >  	}
> >-
> >-	return 0;
> >  }
> >  static struct net_device *ipoib_add_port(const char *format,
> >@@ -2037,9 +2035,7 @@ static struct net_device *ipoib_add_port(const char *format,
> >  		goto device_init_failed;
> >  	}
> >-	result = ipoib_set_dev_features(priv, hca);
> >-	if (result)
> >-		goto device_init_failed;
> >+	ipoib_set_dev_features(priv, hca);
> >  	/*
> >  	 * Set the full membership bit, so that we join the right
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v6 23/25] usb: chipidea: Pullup D+ in device mode via phy APIs
From: Peter Chen @ 2017-01-03  6:53 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: linux-usb, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Andy Gross, Bjorn Andersson, Neil Armstrong, Arnd Bergmann,
	Felipe Balbi, Peter Chen, Greg Kroah-Hartman
In-Reply-To: <20161228225711.698-24-stephen.boyd@linaro.org>

On Wed, Dec 28, 2016 at 02:57:09PM -0800, Stephen Boyd wrote:
> If the phy supports it, call phy_set_mode() to pull up D+ when
> required by setting the mode to PHY_MODE_USB_DEVICE. If we want
> to remove the pullup, set the mode to PHY_MODE_USB_HOST.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/udc.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 0d532a724d48..6d61fa0689b0 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -18,6 +18,7 @@
>  #include <linux/kernel.h>
>  #include <linux/slab.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/phy/phy.h>
>  #include <linux/usb/ch9.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/otg-fsm.h>
> @@ -1609,10 +1610,15 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
>  		return 0;
>  
>  	pm_runtime_get_sync(&ci->gadget.dev);
> -	if (is_on)
> +	if (is_on) {
> +		if (ci->phy)
> +			phy_set_mode(ci->phy, PHY_MODE_USB_DEVICE);
>  		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
> -	else
> +	} else {
>  		hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
> +		if (ci->phy)
> +			phy_set_mode(ci->phy, PHY_MODE_USB_HOST);
> +	}
>  	pm_runtime_put_sync(&ci->gadget.dev);
>  
>  	return 0;
> -- 

Would you describe the use case for it? Why not adding it at
role switch routine?

-- 

Best Regards,
Peter Chen

^ permalink raw reply

* [PATCH v6 23/25] usb: chipidea: Pullup D+ in device mode via phy APIs
From: Peter Chen @ 2017-01-03  6:53 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161228225711.698-24-stephen.boyd@linaro.org>

On Wed, Dec 28, 2016 at 02:57:09PM -0800, Stephen Boyd wrote:
> If the phy supports it, call phy_set_mode() to pull up D+ when
> required by setting the mode to PHY_MODE_USB_DEVICE. If we want
> to remove the pullup, set the mode to PHY_MODE_USB_HOST.
> 
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> ---
>  drivers/usb/chipidea/udc.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> index 0d532a724d48..6d61fa0689b0 100644
> --- a/drivers/usb/chipidea/udc.c
> +++ b/drivers/usb/chipidea/udc.c
> @@ -18,6 +18,7 @@
>  #include <linux/kernel.h>
>  #include <linux/slab.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/phy/phy.h>
>  #include <linux/usb/ch9.h>
>  #include <linux/usb/gadget.h>
>  #include <linux/usb/otg-fsm.h>
> @@ -1609,10 +1610,15 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
>  		return 0;
>  
>  	pm_runtime_get_sync(&ci->gadget.dev);
> -	if (is_on)
> +	if (is_on) {
> +		if (ci->phy)
> +			phy_set_mode(ci->phy, PHY_MODE_USB_DEVICE);
>  		hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
> -	else
> +	} else {
>  		hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
> +		if (ci->phy)
> +			phy_set_mode(ci->phy, PHY_MODE_USB_HOST);
> +	}
>  	pm_runtime_put_sync(&ci->gadget.dev);
>  
>  	return 0;
> -- 

Would you describe the use case for it? Why not adding it at
role switch routine?

-- 

Best Regards,
Peter Chen

^ permalink raw reply

* [PATCH v7 09/27] net/i40e: fix VF reset flow
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Qi Zhang, stable
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

From: Qi Zhang <qi.z.zhang@intel.com>

Add missing step during VF reset: PF should
set I40E_VFGEN_RSTAT to ACTIVE at end of the
VF reset operation or VF driver may not able
to detect that reset is already completed.
This patch also remove the unnecessary enum
for vfr state.

Fixes: 4861cde46116 ("i40e: new poll mode driver")

CC: stable@dpdk.org
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
 drivers/net/i40e/i40e_pf.c | 6 ++++--
 drivers/net/i40e/i40e_pf.h | 5 -----
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index 8b8a14f..2bc3355 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -139,7 +139,7 @@
 	abs_vf_id = vf_id + hw->func_caps.vf_base_id;
 
 	/* Notify VF that we are in VFR progress */
-	I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_PF_VFR_INPROGRESS);
+	I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_INPROGRESS);
 
 	/*
 	 * If require a SW VF reset, a VFLR interrupt will be generated,
@@ -220,7 +220,7 @@
 	}
 
 	/* Reset done, Set COMPLETE flag and clear reset bit */
-	I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_PF_VFR_COMPLETED);
+	I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_COMPLETED);
 	val = I40E_READ_REG(hw, I40E_VPGEN_VFRTRIG(vf_id));
 	val &= ~I40E_VPGEN_VFRTRIG_VFSWR_MASK;
 	I40E_WRITE_REG(hw, I40E_VPGEN_VFRTRIG(vf_id), val);
@@ -248,6 +248,8 @@
 		return -EFAULT;
 	}
 
+	I40E_WRITE_REG(hw, I40E_VFGEN_RSTAT1(vf_id), I40E_VFR_VFACTIVE);
+
 	return ret;
 }
 
diff --git a/drivers/net/i40e/i40e_pf.h b/drivers/net/i40e/i40e_pf.h
index 59bf2ee..ada398b 100644
--- a/drivers/net/i40e/i40e_pf.h
+++ b/drivers/net/i40e/i40e_pf.h
@@ -48,11 +48,6 @@
 
 #define I40E_DPDK_OFFSET  0x100
 
-enum i40e_pf_vfr_state {
-	I40E_PF_VFR_INPROGRESS = 0,
-	I40E_PF_VFR_COMPLETED = 1,
-};
-
 /* DPDK pf driver specific command to VF */
 enum i40e_virtchnl_ops_dpdk {
 	/*
-- 
1.9.3

^ permalink raw reply related

* [PATCH v7 12/27] net/i40e: fix VF MAC address assignment
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Ferruh Yigit, stable
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

From: Ferruh Yigit <ferruh.yigit@intel.com>

If PF sets vf->mac_addr, in VF initialization hw->mac.addr will be set
to that same value. It is possible to check if PF set a MAC address or
not through the hw->mac.addr variable.

hw->mac.addr set by i40e_vf_parse_hw_config(), call stack is:

In PF side
i40e_pf_host_process_cmd_get_vf_resources()
    eth_addr_copy(vf->mac_addr, vf_res->vsi_res[0].default_mac_address)

In VF sise
i40evf_init_vf()
    i40evf_get_vf_resources()
            i40e_vf_parse_hw_config()
                    memcpy(hw->mac.addr, vsi_res->default_mac_addr)

Updated code is after i40evf_get_vf_resources() and can benefit from
hw->mac.addr variable.

Fixes: 89e6b86384bb ("i40evf: rework MAC address validation")

CC: stable@dpdk.org
Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
---
 drivers/net/i40e/i40e_ethdev_vf.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 5016249..0977095 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1193,7 +1193,6 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
 	int i, err, bufsz;
 	struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
-	struct ether_addr *p_mac_addr;
 	uint16_t interval =
 		i40e_calc_itr_interval(I40E_QUEUE_ITR_INTERVAL_MAX);
 
@@ -1270,13 +1269,10 @@ static int i40evf_dev_xstats_get(struct rte_eth_dev *dev,
 	vf->vsi.adapter = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 
 	/* Store the MAC address configured by host, or generate random one */
-	p_mac_addr = (struct ether_addr *)(vf->vsi_res->default_mac_addr);
-	if (is_valid_assigned_ether_addr(p_mac_addr)) { /* Configured by host */
-		ether_addr_copy(p_mac_addr, (struct ether_addr *)hw->mac.addr);
+	if (is_valid_assigned_ether_addr((struct ether_addr *)hw->mac.addr))
 		vf->flags |= I40E_FLAG_VF_MAC_BY_PF;
-	} else {
+	else
 		eth_random_addr(hw->mac.addr); /* Generate a random one */
-	}
 
 	/* If the PF host is not DPDK, set the interval of ITR0 to max*/
 	if (vf->version_major != I40E_DPDK_VERSION_MAJOR) {
-- 
1.9.3

^ permalink raw reply related

* [PATCH v7 26/27] net/i40e: fix segmentation fault in close
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Bernard Iremonger, stable
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

From: Bernard Iremonger <bernard.iremonger@intel.com>

The vsi's have already been released, so the second call to
i40e_vsi_release results in a segmentation fault.
The second call to i40e_vsi_release has been removed.

Fixes: 3cb446b4aeb2 ("i40e: free vmdq vsi when closing")

CC: stable@dpdk.org

Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index be45cfa..0b7c366 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1882,7 +1882,6 @@ static inline void i40e_GLQF_reg_init(struct i40e_hw *hw)
 	i40e_vsi_release(pf->main_vsi);
 
 	for (i = 0; i < pf->nb_cfg_vmdq_vsi; i++) {
-		i40e_vsi_release(pf->vmdq[i].vsi);
 		pf->vmdq[i].vsi = NULL;
 	}
 
@@ -4137,6 +4136,9 @@ enum i40e_status_code
 	if (!vsi)
 		return I40E_SUCCESS;
 
+	if (!vsi->adapter)
+		return I40E_ERR_BAD_PTR;
+
 	user_param = vsi->user_param;
 
 	pf = I40E_VSI_TO_PF(vsi);
-- 
1.9.3

^ permalink raw reply related

* [PATCH V2] arm64:dts:ls1046a: Add TMU device tree support
From: Jia Hongtao @ 2017-01-03  6:42 UTC (permalink / raw)
  To: shawnguo, rui.zhang, edubezval, yuantian.tang, robh+dt,
	scott.wood
  Cc: devicetree, linux-kernel, linux-arm-kernel, hongtao.jia

Also add nodes and properties for thermal management support.

Signed-off-by: Jia Hongtao <hongtao.jia@nxp.com>
---
Changes for V2:
* Update the subject title according to Shawn Guo's comment.
* Add comments for calibration data groups.
* Update "thermal-zones" property in a unified style with platform dts.

 arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 83 ++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 38806ca..df53a4a 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -45,6 +45,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	compatible = "fsl,ls1046a";
@@ -67,6 +68,7 @@
 			clocks = <&clockgen 1 0>;
 			next-level-cache = <&l2>;
 			cpu-idle-states = <&CPU_PH20>;
+			#cooling-cells = <2>;
 		};
 
 		cpu1: cpu@1 {
@@ -279,6 +281,87 @@
 			clocks = <&sysclk>;
 		};
 
+		tmu: tmu@1f00000 {
+			compatible = "fsl,qoriq-tmu";
+			reg = <0x0 0x1f00000 0x0 0x10000>;
+			interrupts = <0 33 0x4>;
+			fsl,tmu-range = <0xb0000 0x9002a 0x6004c 0x30062>;
+			fsl,tmu-calibration =
+				/* Calibration data group 1*/
+				<0x00000000 0x00000026
+				0x00000001 0x0000002d
+				0x00000002 0x00000032
+				0x00000003 0x00000039
+				0x00000004 0x0000003f
+				0x00000005 0x00000046
+				0x00000006 0x0000004d
+				0x00000007 0x00000054
+				0x00000008 0x0000005a
+				0x00000009 0x00000061
+				0x0000000a 0x0000006a
+				0x0000000b 0x00000071
+
+				/* Calibration data group 2*/
+				0x00010000 0x00000025
+				0x00010001 0x0000002c
+				0x00010002 0x00000035
+				0x00010003 0x0000003d
+				0x00010004 0x00000045
+				0x00010005 0x0000004e
+				0x00010006 0x00000057
+				0x00010007 0x00000061
+				0x00010008 0x0000006b
+				0x00010009 0x00000076
+
+				/* Calibration data group 3*/
+				0x00020000 0x00000029
+				0x00020001 0x00000033
+				0x00020002 0x0000003d
+				0x00020003 0x00000049
+				0x00020004 0x00000056
+				0x00020005 0x00000061
+				0x00020006 0x0000006d
+
+				/* Calibration data group 4*/
+				0x00030000 0x00000021
+				0x00030001 0x0000002a
+				0x00030002 0x0000003c
+				0x00030003 0x0000004e>;
+			big-endian;
+			#thermal-sensor-cells = <1>;
+		};
+
+		thermal-zones {
+			cpu_thermal: cpu-thermal {
+				polling-delay-passive = <1000>;
+				polling-delay = <5000>;
+				thermal-sensors = <&tmu 3>;
+
+				trips {
+					cpu_alert: cpu-alert {
+						temperature = <85000>;
+						hysteresis = <2000>;
+						type = "passive";
+					};
+
+					cpu_crit: cpu-crit {
+						temperature = <95000>;
+						hysteresis = <2000>;
+						type = "critical";
+					};
+				};
+
+				cooling-maps {
+					map0 {
+						trip = <&cpu_alert>;
+						cooling-device =
+							<&cpu0 THERMAL_NO_LIMIT
+							THERMAL_NO_LIMIT>;
+					};
+				};
+			};
+		};
+
 		dspi: dspi@2100000 {
 			compatible = "fsl,ls1021a-v1.0-dspi";
 			#address-cells = <1>;
-- 
2.1.0.27.g96db324

^ permalink raw reply related

* [PATCH v2 1/3] ARM: dts: imx6dl: Add Engicam i.CoreM6 DualLite/Solo RQS initial support
From: Shawn Guo @ 2017-01-03  6:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1483364420-10012-1-git-send-email-jagan@openedev.com>

On Mon, Jan 02, 2017 at 02:40:18PM +0100, Jagan Teki wrote:
> From: Jagan Teki <jagan@amarulasolutions.com>
> 
> i.CoreM6 DualLite/Solo modules are system on module solutions manufactured
> by Engicam with following characteristics:
> CPU           NXP i.MX6 DL, 800MHz
> RAM           1GB, 32, 64 bit, DDR3-800/1066
> NAND          SLC,512MB
> Power supply  Single 5V
> MAX LCD RES   FULLHD
> 
> and more info at
> http://www.engicam.com/en/products/embedded/som/standard/i-core-rqs-m6s-dl-d-q
> 
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Matteo Lisi <matteo.lisi@engicam.com>
> Cc: Michael Trimarchi <michael@amarulasolutions.com>
> Signed-off-by: Jagan Teki <jagan@amarulasolutions.com>

Applied all, thanks.

^ permalink raw reply

* Re: [PATCH v2 1/3] ARM: dts: imx6dl: Add Engicam i.CoreM6 DualLite/Solo RQS initial support
From: Shawn Guo @ 2017-01-03  6:55 UTC (permalink / raw)
  To: Jagan Teki
  Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Matteo Lisi,
	Michael Trimarchi, Jagan Teki
In-Reply-To: <1483364420-10012-1-git-send-email-jagan-oRp2ZoJdM/RWk0Htik3J/w@public.gmane.org>

On Mon, Jan 02, 2017 at 02:40:18PM +0100, Jagan Teki wrote:
> From: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
> 
> i.CoreM6 DualLite/Solo modules are system on module solutions manufactured
> by Engicam with following characteristics:
> CPU           NXP i.MX6 DL, 800MHz
> RAM           1GB, 32, 64 bit, DDR3-800/1066
> NAND          SLC,512MB
> Power supply  Single 5V
> MAX LCD RES   FULLHD
> 
> and more info at
> http://www.engicam.com/en/products/embedded/som/standard/i-core-rqs-m6s-dl-d-q
> 
> Cc: Shawn Guo <shawnguo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> Cc: Matteo Lisi <matteo.lisi-4s7YQHO/iPVBDgjK7y7TUQ@public.gmane.org>
> Cc: Michael Trimarchi <michael-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
> Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>

Applied all, thanks.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v7 00/27] Support VFD on i40e
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1480637533-37425-1-git-send-email-wenzhuo.lu@intel.com>

1, VF Daemon (VFD)
VFD is an idea to control all the VFs from PF.
As we need to support the scenario kernel PF + DPDK VF, DPDK follows the
interface between kernel PF + kernel VF.
We don't want to introduce too many new messages between PF and VF.
So this patch set adds some new APIs to control VFs directly from PF.
The new APIs include,
1) set VF MAC anti-spoofing
2) set VF VLAN anti-spoofing
3) set TX loopback
4) set VF unicast promiscuous mode
5) set VF multicast promiscuous mode
6) set VF MTU
7) get/reset VF stats
8) set VF MAC address
9) set VF VLAN stripping
10) VF VLAN insertion
12) set VF broadcast mode
12) set VF VLAN tag
13) set VF VLAN filter
VFD also includes VF to PF mailbox message management by APP.
When PF receives mailbox messages from VF, PF should call the callback
provided by APP to know if they're permitted to be processed.

2, Implement VF MAC address setting on VF.

v7:
- fix 32 bit compile error in patch 23.
- add new patches to configure VMDq.

v6:
- remove the support of DPDK PF + kernel VF. Will create a new patch set for it.
- reword the tittles of some patches.
- add sanity check for vsi, and other minor change.

v5:
- fix testpmd build error(s)
- fix i40e vf_rx_vlan
- remove redundant memset on dev_info
- add functions to .map file sorted

v4:
- rebase on latest next-net
- move patch 10/29 testpmd part to patch 18/29

v3:
- fix issue that VF does not work for i40e
- remove patch for VDMq receive mode init
- move get/reset VF stats API into rte_pmd_i40

v2:
- fix the compile issues.
- fix the checkpatch warning and typo.
- update the commit log of some patches.
- fix the invalid port ID issue of testpmd.

Bernard Iremonger (9):
  net/i40e: set VF VLAN insertion from PF
  net/i40e: set VF broadcast mode from PF
  net/i40e: set VF VLAN tag from PF
  net/i40e: set VF VLAN filter from PF
  app/testpmd: add command to test VF broadcast mode on i40e
  app/testpmd: add command to test VF VLAN tag on i40e
  app/testpmd: handle i40e in VF VLAN filter command
  net/i40e: fix segmentation fault in close
  app/testpmd: add command to configure VMDq

Chen Jing D(Mark) (2):
  net/i40e: set VF VLAN strip from PF
  net/i40e: enhance in sanity check of MAC

Ferruh Yigit (3):
  net/i40e: set VF MAC from PF support
  net/i40e: set VF MAC from VF support
  net/i40e: fix VF MAC address assignment

Qi Zhang (3):
  net/i40e: enable VF MTU change
  net/i40e: fix VF reset flow
  net/i40e: set/clear VF stats from PF

Wenzhuo Lu (10):
  net/i40e: support link status notification
  net/i40e: add callback to user on VF to PF mbox msg
  net/i40e: set VF MAC anti-spoofing from PF
  net/i40e: set VF VLAN anti-spoofing from PF
  net/i40e: set Tx loopback from PF
  net/i40e: set VF unicast promisc mode from PF
  net/i40e: set VF multicast promisc mode from PF
  app/testpmd: use VFD APIs on i40e
  app/testpmd: use unicast promiscuous mode on i40e
  app/testpmd: use multicast promiscuous mode on i40e

 app/test-pmd/Makefile                       |   3 +
 app/test-pmd/cmdline.c                      | 629 ++++++++++++++++++--
 app/test-pmd/config.c                       |  13 -
 app/test-pmd/testpmd.c                      | 126 ++++
 app/test-pmd/testpmd.h                      |   3 +-
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  39 ++
 drivers/net/i40e/Makefile                   |   4 +-
 drivers/net/i40e/i40e_ethdev.c              | 874 +++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev.h              |   5 +-
 drivers/net/i40e/i40e_ethdev_vf.c           |  82 ++-
 drivers/net/i40e/i40e_pf.c                  | 244 ++++++--
 drivers/net/i40e/i40e_pf.h                  |   9 +-
 drivers/net/i40e/rte_pmd_i40e.h             | 328 +++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map   |  20 +
 14 files changed, 2266 insertions(+), 113 deletions(-)
 create mode 100644 drivers/net/i40e/rte_pmd_i40e.h

-- 
1.9.3

^ permalink raw reply

* [PATCH v7 01/27] net/i40e: support link status notification
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

Add an API to expose the ability, that PF can notify VF
when link status changes, to APP.
So if PF APP doesn't want to enable interruption but check
link status by itself, PF APP can let VF know link status
changed.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 drivers/net/i40e/Makefile                 |  4 ++-
 drivers/net/i40e/i40e_ethdev.c            | 28 +++++++++++++++
 drivers/net/i40e/i40e_pf.c                |  4 +--
 drivers/net/i40e/i40e_pf.h                |  4 ++-
 drivers/net/i40e/rte_pmd_i40e.h           | 58 +++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  7 ++++
 6 files changed, 101 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/i40e/rte_pmd_i40e.h

diff --git a/drivers/net/i40e/Makefile b/drivers/net/i40e/Makefile
index 66997b6..a2ef53c 100644
--- a/drivers/net/i40e/Makefile
+++ b/drivers/net/i40e/Makefile
@@ -1,6 +1,6 @@
 #   BSD LICENSE
 #
-#   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
@@ -111,6 +111,8 @@ ifeq ($(findstring RTE_MACHINE_CPUFLAG_SSE4_1,$(CFLAGS)),)
 CFLAGS_i40e_rxtx_vec_sse.o += -msse4.1
 endif
 
+# install this header file
+SYMLINK-$(CONFIG_RTE_LIBRTE_I40E_PMD)-include := rte_pmd_i40e.h
 
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += lib/librte_eal lib/librte_ether
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index f42f4ba..fc7e987 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -62,6 +62,7 @@
 #include "i40e_rxtx.h"
 #include "i40e_pf.h"
 #include "i40e_regs.h"
+#include "rte_pmd_i40e.h"
 
 #define ETH_I40E_FLOATING_VEB_ARG	"enable_floating_veb"
 #define ETH_I40E_FLOATING_VEB_LIST_ARG	"floating_veb_list"
@@ -9695,3 +9696,30 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	return ret;
 }
+
+int
+rte_pmd_i40e_ping_vfs(uint8_t port, uint16_t vf)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct i40e_pf *pf;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	if (vf > pf->vf_num - 1 || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid argument.");
+		return -EINVAL;
+	}
+
+	i40e_notify_vf_link_status(dev, &pf->vfs[vf]);
+
+	return 0;
+}
diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index ddfc140..f70712b 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -897,7 +897,7 @@
 	return ret;
 }
 
-static void
+void
 i40e_notify_vf_link_status(struct rte_eth_dev *dev, struct i40e_pf_vf *vf)
 {
 	struct i40e_virtchnl_pf_event event;
diff --git a/drivers/net/i40e/i40e_pf.h b/drivers/net/i40e/i40e_pf.h
index cddc45c..59bf2ee 100644
--- a/drivers/net/i40e/i40e_pf.h
+++ b/drivers/net/i40e/i40e_pf.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -123,5 +123,7 @@ void i40e_pf_host_handle_vf_msg(struct rte_eth_dev *dev,
 				uint8_t *msg, uint16_t msglen);
 int i40e_pf_host_init(struct rte_eth_dev *dev);
 int i40e_pf_host_uninit(struct rte_eth_dev *dev);
+void i40e_notify_vf_link_status(struct rte_eth_dev *dev,
+				struct i40e_pf_vf *vf);
 
 #endif /* _I40E_PF_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
new file mode 100644
index 0000000..14852f2
--- /dev/null
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -0,0 +1,58 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright (c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file rte_pmd_i40e.h
+ * i40e PMD specific functions.
+ *
+ **/
+
+#ifndef _PMD_I40E_H_
+#define _PMD_I40E_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Notify VF when PF link status changes.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* invalid.
+ */
+int rte_pmd_i40e_ping_vfs(uint8_t port, uint16_t vf);
+
+#endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index ef35398..3c6a192 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -2,3 +2,10 @@ DPDK_2.0 {
 
 	local: *;
 };
+
+DPDK_17.02 {
+	global:
+
+	rte_pmd_i40e_ping_vfs;
+
+} DPDK_2.0;
-- 
1.9.3

^ permalink raw reply related

* [PATCH v7 02/27] net/i40e: add callback to user on VF to PF mbox msg
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

The callback asks the user application if it is allowed to
perform the mailbox messages.

If the return value from user is RTE_PMD_I40E_MB_EVENT_PROCEED
then continue. If ACK or NACK, do nothing and send
not_supported to VF.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 drivers/net/i40e/i40e_pf.c      | 230 ++++++++++++++++++++++++++++++++++------
 drivers/net/i40e/rte_pmd_i40e.h |  21 ++++
 2 files changed, 216 insertions(+), 35 deletions(-)

diff --git a/drivers/net/i40e/i40e_pf.c b/drivers/net/i40e/i40e_pf.c
index f70712b..8b8a14f 100644
--- a/drivers/net/i40e/i40e_pf.c
+++ b/drivers/net/i40e/i40e_pf.c
@@ -55,6 +55,7 @@
 #include "i40e_ethdev.h"
 #include "i40e_rxtx.h"
 #include "i40e_pf.h"
+#include "rte_pmd_i40e.h"
 
 #define I40E_CFG_CRCSTRIP_DEFAULT 1
 
@@ -272,14 +273,23 @@
 }
 
 static void
-i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf)
+i40e_pf_host_process_cmd_version(struct i40e_pf_vf *vf, bool b_op)
 {
 	struct i40e_virtchnl_version_info info;
 
 	info.major = I40E_DPDK_VERSION_MAJOR;
 	info.minor = I40E_DPDK_VERSION_MINOR;
-	i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION,
-		I40E_SUCCESS, (uint8_t *)&info, sizeof(info));
+
+	if (b_op)
+		i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION,
+					    I40E_SUCCESS,
+					    (uint8_t *)&info,
+					    sizeof(info));
+	else
+		i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_VERSION,
+					    I40E_NOT_SUPPORTED,
+					    (uint8_t *)&info,
+					    sizeof(info));
 }
 
 static int
@@ -292,13 +302,20 @@
 }
 
 static int
-i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf)
+i40e_pf_host_process_cmd_get_vf_resource(struct i40e_pf_vf *vf, bool b_op)
 {
 	struct i40e_virtchnl_vf_resource *vf_res = NULL;
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
 	uint32_t len = 0;
 	int ret = I40E_SUCCESS;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(vf,
+					    I40E_VIRTCHNL_OP_GET_VF_RESOURCES,
+					    I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	/* only have 1 VSI by default */
 	len =  sizeof(struct i40e_virtchnl_vf_resource) +
 				I40E_DEFAULT_VF_VSI_NUM *
@@ -423,7 +440,8 @@
 static int
 i40e_pf_host_process_cmd_config_vsi_queues(struct i40e_pf_vf *vf,
 					   uint8_t *msg,
-					   uint16_t msglen)
+					   uint16_t msglen,
+					   bool b_op)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
 	struct i40e_vsi *vsi = vf->vsi;
@@ -432,6 +450,13 @@
 	struct i40e_virtchnl_queue_pair_info *vc_qpi;
 	int i, ret = I40E_SUCCESS;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(vf,
+					    I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES,
+					    I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (!msg || vc_vqci->num_queue_pairs > vsi->nb_qps ||
 		vc_vqci->num_queue_pairs > I40E_MAX_VSI_QP ||
 		msglen < I40E_VIRTCHNL_CONFIG_VSI_QUEUES_SIZE(vc_vqci,
@@ -482,7 +507,8 @@
 static int
 i40e_pf_host_process_cmd_config_vsi_queues_ext(struct i40e_pf_vf *vf,
 					       uint8_t *msg,
-					       uint16_t msglen)
+					       uint16_t msglen,
+					       bool b_op)
 {
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
 	struct i40e_vsi *vsi = vf->vsi;
@@ -491,6 +517,14 @@
 	struct i40e_virtchnl_queue_pair_ext_info *vc_qpei;
 	int i, ret = I40E_SUCCESS;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (!msg || vc_vqcei->num_queue_pairs > vsi->nb_qps ||
 		vc_vqcei->num_queue_pairs > I40E_MAX_VSI_QP ||
 		msglen < I40E_VIRTCHNL_CONFIG_VSI_QUEUES_SIZE(vc_vqcei,
@@ -539,12 +573,21 @@
 
 static int
 i40e_pf_host_process_cmd_config_irq_map(struct i40e_pf_vf *vf,
-					uint8_t *msg, uint16_t msglen)
+					uint8_t *msg, uint16_t msglen,
+					bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_irq_map_info *irqmap =
 	    (struct i40e_virtchnl_irq_map_info *)msg;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (msg == NULL || msglen < sizeof(struct i40e_virtchnl_irq_map_info)) {
 		PMD_DRV_LOG(ERR, "buffer too short");
 		ret = I40E_ERR_PARAM;
@@ -646,12 +689,21 @@
 static int
 i40e_pf_host_process_cmd_disable_queues(struct i40e_pf_vf *vf,
 					uint8_t *msg,
-					uint16_t msglen)
+					uint16_t msglen,
+					bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_queue_select *q_sel =
 		(struct i40e_virtchnl_queue_select *)msg;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_DISABLE_QUEUES,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (msg == NULL || msglen != sizeof(*q_sel)) {
 		ret = I40E_ERR_PARAM;
 		goto send_msg;
@@ -669,7 +721,8 @@
 static int
 i40e_pf_host_process_cmd_add_ether_address(struct i40e_pf_vf *vf,
 					   uint8_t *msg,
-					   uint16_t msglen)
+					   uint16_t msglen,
+					   bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_ether_addr_list *addr_list =
@@ -678,6 +731,14 @@
 	int i;
 	struct ether_addr *mac;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	memset(&filter, 0 , sizeof(struct i40e_mac_filter_info));
 
 	if (msg == NULL || msglen <= sizeof(*addr_list)) {
@@ -707,7 +768,8 @@
 static int
 i40e_pf_host_process_cmd_del_ether_address(struct i40e_pf_vf *vf,
 					   uint8_t *msg,
-					   uint16_t msglen)
+					   uint16_t msglen,
+					   bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_ether_addr_list *addr_list =
@@ -715,6 +777,14 @@
 	int i;
 	struct ether_addr *mac;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (msg == NULL || msglen <= sizeof(*addr_list)) {
 		PMD_DRV_LOG(ERR, "delete_ether_address argument too short");
 		ret = I40E_ERR_PARAM;
@@ -739,7 +809,8 @@
 
 static int
 i40e_pf_host_process_cmd_add_vlan(struct i40e_pf_vf *vf,
-				uint8_t *msg, uint16_t msglen)
+				uint8_t *msg, uint16_t msglen,
+				bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_vlan_filter_list *vlan_filter_list =
@@ -747,6 +818,14 @@
 	int i;
 	uint16_t *vid;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_ADD_VLAN,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) {
 		PMD_DRV_LOG(ERR, "add_vlan argument too short");
 		ret = I40E_ERR_PARAM;
@@ -771,7 +850,8 @@
 static int
 i40e_pf_host_process_cmd_del_vlan(struct i40e_pf_vf *vf,
 				  uint8_t *msg,
-				  uint16_t msglen)
+				  uint16_t msglen,
+				  bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_vlan_filter_list *vlan_filter_list =
@@ -779,6 +859,14 @@
 	int i;
 	uint16_t *vid;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_DEL_VLAN,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (msg == NULL || msglen <= sizeof(*vlan_filter_list)) {
 		PMD_DRV_LOG(ERR, "delete_vlan argument too short");
 		ret = I40E_ERR_PARAM;
@@ -803,7 +891,8 @@
 i40e_pf_host_process_cmd_config_promisc_mode(
 					struct i40e_pf_vf *vf,
 					uint8_t *msg,
-					uint16_t msglen)
+					uint16_t msglen,
+					bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_promisc_info *promisc =
@@ -811,6 +900,14 @@
 	struct i40e_hw *hw = I40E_PF_TO_HW(vf->pf);
 	bool unicast = FALSE, multicast = FALSE;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (msg == NULL || msglen != sizeof(*promisc)) {
 		ret = I40E_ERR_PARAM;
 		goto send_msg;
@@ -836,13 +933,20 @@
 }
 
 static int
-i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf)
+i40e_pf_host_process_cmd_get_stats(struct i40e_pf_vf *vf, bool b_op)
 {
 	i40e_update_vsi_stats(vf->vsi);
 
-	i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS,
-		I40E_SUCCESS, (uint8_t *)&vf->vsi->eth_stats,
-				sizeof(vf->vsi->eth_stats));
+	if (b_op)
+		i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS,
+					    I40E_SUCCESS,
+					    (uint8_t *)&vf->vsi->eth_stats,
+					    sizeof(vf->vsi->eth_stats));
+	else
+		i40e_pf_host_send_msg_to_vf(vf, I40E_VIRTCHNL_OP_GET_STATS,
+					    I40E_NOT_SUPPORTED,
+					    (uint8_t *)&vf->vsi->eth_stats,
+					    sizeof(vf->vsi->eth_stats));
 
 	return I40E_SUCCESS;
 }
@@ -851,12 +955,21 @@
 i40e_pf_host_process_cmd_cfg_vlan_offload(
 					struct i40e_pf_vf *vf,
 					uint8_t *msg,
-					uint16_t msglen)
+					uint16_t msglen,
+					bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_vlan_offload_info *offload =
 			(struct i40e_virtchnl_vlan_offload_info *)msg;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (msg == NULL || msglen != sizeof(*offload)) {
 		ret = I40E_ERR_PARAM;
 		goto send_msg;
@@ -877,12 +990,21 @@
 static int
 i40e_pf_host_process_cmd_cfg_pvid(struct i40e_pf_vf *vf,
 					uint8_t *msg,
-					uint16_t msglen)
+					uint16_t msglen,
+					bool b_op)
 {
 	int ret = I40E_SUCCESS;
 	struct i40e_virtchnl_pvid_info  *tpid_info =
 			(struct i40e_virtchnl_pvid_info *)msg;
 
+	if (!b_op) {
+		i40e_pf_host_send_msg_to_vf(
+			vf,
+			I40E_VIRTCHNL_OP_CFG_VLAN_PVID,
+			I40E_NOT_SUPPORTED, NULL, 0);
+		return ret;
+	}
+
 	if (msg == NULL || msglen != sizeof(*tpid_info)) {
 		ret = I40E_ERR_PARAM;
 		goto send_msg;
@@ -923,6 +1045,8 @@
 	struct i40e_pf_vf *vf;
 	/* AdminQ will pass absolute VF id, transfer to internal vf id */
 	uint16_t vf_id = abs_vf_id - hw->func_caps.vf_base_id;
+	struct rte_pmd_i40e_mb_event_param cb_param;
+	bool b_op = TRUE;
 
 	if (vf_id > pf->vf_num - 1 || !pf->vfs) {
 		PMD_DRV_LOG(ERR, "invalid argument");
@@ -937,10 +1061,35 @@
 		return;
 	}
 
+	/**
+	 * initialise structure to send to user application
+	 * will return response from user in retval field
+	 */
+	cb_param.retval = RTE_PMD_I40E_MB_EVENT_PROCEED;
+	cb_param.vfid = vf_id;
+	cb_param.msg_type = opcode;
+	cb_param.msg = (void *)msg;
+	cb_param.msglen = msglen;
+
+	/**
+	 * Ask user application if we're allowed to perform those functions.
+	 * If we get cb_param.retval == RTE_PMD_I40E_MB_EVENT_PROCEED,
+	 * then business as usual.
+	 * If RTE_PMD_I40E_MB_EVENT_NOOP_ACK or RTE_PMD_I40E_MB_EVENT_NOOP_NACK,
+	 * do nothing and send not_supported to VF. As PF must send a response
+	 * to VF and ACK/NACK is not defined.
+	 */
+	_rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_VF_MBOX, &cb_param);
+	if (cb_param.retval != RTE_PMD_I40E_MB_EVENT_PROCEED) {
+		PMD_DRV_LOG(WARNING, "VF to PF message(%d) is not permitted!",
+			    opcode);
+		b_op = FALSE;
+	}
+
 	switch (opcode) {
 	case I40E_VIRTCHNL_OP_VERSION :
 		PMD_DRV_LOG(INFO, "OP_VERSION received");
-		i40e_pf_host_process_cmd_version(vf);
+		i40e_pf_host_process_cmd_version(vf, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_RESET_VF :
 		PMD_DRV_LOG(INFO, "OP_RESET_VF received");
@@ -948,61 +1097,72 @@
 		break;
 	case I40E_VIRTCHNL_OP_GET_VF_RESOURCES:
 		PMD_DRV_LOG(INFO, "OP_GET_VF_RESOURCES received");
-		i40e_pf_host_process_cmd_get_vf_resource(vf);
+		i40e_pf_host_process_cmd_get_vf_resource(vf, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES:
 		PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES received");
-		i40e_pf_host_process_cmd_config_vsi_queues(vf, msg, msglen);
+		i40e_pf_host_process_cmd_config_vsi_queues(vf, msg,
+							   msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES_EXT:
 		PMD_DRV_LOG(INFO, "OP_CONFIG_VSI_QUEUES_EXT received");
 		i40e_pf_host_process_cmd_config_vsi_queues_ext(vf, msg,
-								msglen);
+							       msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP:
 		PMD_DRV_LOG(INFO, "OP_CONFIG_IRQ_MAP received");
-		i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen);
+		i40e_pf_host_process_cmd_config_irq_map(vf, msg, msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_ENABLE_QUEUES:
 		PMD_DRV_LOG(INFO, "OP_ENABLE_QUEUES received");
-		i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen);
-		i40e_notify_vf_link_status(dev, vf);
+		if (b_op) {
+			i40e_pf_host_process_cmd_enable_queues(vf, msg, msglen);
+			i40e_notify_vf_link_status(dev, vf);
+		} else {
+			i40e_pf_host_send_msg_to_vf(
+				vf, I40E_VIRTCHNL_OP_ENABLE_QUEUES,
+				I40E_NOT_SUPPORTED, NULL, 0);
+		}
 		break;
 	case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
 		PMD_DRV_LOG(INFO, "OP_DISABLE_QUEUE received");
-		i40e_pf_host_process_cmd_disable_queues(vf, msg, msglen);
+		i40e_pf_host_process_cmd_disable_queues(vf, msg, msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_ADD_ETHER_ADDRESS:
 		PMD_DRV_LOG(INFO, "OP_ADD_ETHER_ADDRESS received");
-		i40e_pf_host_process_cmd_add_ether_address(vf, msg, msglen);
+		i40e_pf_host_process_cmd_add_ether_address(vf, msg,
+							   msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_DEL_ETHER_ADDRESS:
 		PMD_DRV_LOG(INFO, "OP_DEL_ETHER_ADDRESS received");
-		i40e_pf_host_process_cmd_del_ether_address(vf, msg, msglen);
+		i40e_pf_host_process_cmd_del_ether_address(vf, msg,
+							   msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_ADD_VLAN:
 		PMD_DRV_LOG(INFO, "OP_ADD_VLAN received");
-		i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen);
+		i40e_pf_host_process_cmd_add_vlan(vf, msg, msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_DEL_VLAN:
 		PMD_DRV_LOG(INFO, "OP_DEL_VLAN received");
-		i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen);
+		i40e_pf_host_process_cmd_del_vlan(vf, msg, msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE:
 		PMD_DRV_LOG(INFO, "OP_CONFIG_PROMISCUOUS_MODE received");
-		i40e_pf_host_process_cmd_config_promisc_mode(vf, msg, msglen);
+		i40e_pf_host_process_cmd_config_promisc_mode(vf, msg,
+							     msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_GET_STATS:
 		PMD_DRV_LOG(INFO, "OP_GET_STATS received");
-		i40e_pf_host_process_cmd_get_stats(vf);
+		i40e_pf_host_process_cmd_get_stats(vf, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_CFG_VLAN_OFFLOAD:
 		PMD_DRV_LOG(INFO, "OP_CFG_VLAN_OFFLOAD received");
-		i40e_pf_host_process_cmd_cfg_vlan_offload(vf, msg, msglen);
+		i40e_pf_host_process_cmd_cfg_vlan_offload(vf, msg,
+							  msglen, b_op);
 		break;
 	case I40E_VIRTCHNL_OP_CFG_VLAN_PVID:
 		PMD_DRV_LOG(INFO, "OP_CFG_VLAN_PVID received");
-		i40e_pf_host_process_cmd_cfg_pvid(vf, msg, msglen);
+		i40e_pf_host_process_cmd_cfg_pvid(vf, msg, msglen, b_op);
 		break;
 	/* Don't add command supported below, which will
 	 * return an error code.
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 14852f2..eb7a72b 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -42,6 +42,27 @@
 #include <rte_ethdev.h>
 
 /**
+ * Response sent back to i40e driver from user app after callback
+ */
+enum rte_pmd_i40e_mb_event_rsp {
+	RTE_PMD_I40E_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
+	RTE_PMD_I40E_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+	RTE_PMD_I40E_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
+	RTE_PMD_I40E_MB_EVENT_MAX       /**< max value of this enum */
+};
+
+/**
+ * Data sent to the user application when the callback is executed.
+ */
+struct rte_pmd_i40e_mb_event_param {
+	uint16_t vfid;     /**< Virtual Function number */
+	uint16_t msg_type; /**< VF to PF message type, see i40e_virtchnl_ops */
+	uint16_t retval;   /**< return value */
+	void *msg;         /**< pointer to message */
+	uint16_t msglen;   /**< length of the message */
+};
+
+/**
  * Notify VF when PF link status changes.
  *
  * @param port
-- 
1.9.3

^ permalink raw reply related

* [PATCH v7 03/27] net/i40e: set VF MAC anti-spoofing from PF
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

Support enabling/disabling VF MAC anti-spoofing from
PF.
User can call the API on PF to enable/disable a specific
VF's MAC anti-spoofing.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 63 +++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 19 ++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 83 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index fc7e987..68c07de 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -9723,3 +9723,66 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	return 0;
 }
+
+int
+rte_pmd_i40e_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct i40e_pf *pf;
+	struct i40e_vsi *vsi;
+	struct i40e_hw *hw;
+	struct i40e_vsi_context ctxt;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	if (vf_id > pf->vf_num - 1 || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid argument.");
+		return -EINVAL;
+	}
+
+	vsi = pf->vfs[vf_id].vsi;
+	if (!vsi)
+		return -EINVAL;
+
+	/* Check if it has been already on or off */
+	if (vsi->info.valid_sections &
+		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SECURITY_VALID)) {
+		if (on) {
+			if ((vsi->info.sec_flags &
+			     I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK) ==
+			    I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK)
+				return 0; /* already on */
+		} else {
+			if ((vsi->info.sec_flags &
+			     I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK) == 0)
+				return 0; /* already off */
+		}
+	}
+
+	vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
+	if (on)
+		vsi->info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
+	else
+		vsi->info.sec_flags &= ~I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	(void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+	ctxt.seid = vsi->seid;
+
+	hw = I40E_VSI_TO_HW(vsi);
+	ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+	if (ret != I40E_SUCCESS)
+		PMD_DRV_LOG(ERR, "Failed to update VSI params");
+
+	return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index eb7a72b..52319cf 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -76,4 +76,23 @@ struct rte_pmd_i40e_mb_event_param {
  */
 int rte_pmd_i40e_ping_vfs(uint8_t port, uint16_t vf);
 
+/**
+ * Enable/Disable VF MAC anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set MAC anti spoofing.
+ * @param on
+ *    1 - Enable VFs MAC anti spoofing.
+ *    0 - Disable VFs MAC anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_mac_anti_spoof(uint8_t port,
+				       uint16_t vf_id,
+				       uint8_t on);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 3c6a192..0581209 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -7,5 +7,6 @@ DPDK_17.02 {
 	global:
 
 	rte_pmd_i40e_ping_vfs;
+	rte_pmd_i40e_set_vf_mac_anti_spoof;
 
 } DPDK_2.0;
-- 
1.9.3

^ permalink raw reply related

* [PATCH v7 05/27] net/i40e: set Tx loopback from PF
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

Support enabling/disabling TX loopback from PF.
User can call the API on PF to enable/disable TX loopback
for all the PF and VFs.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 222 ++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           |  16 +++
 drivers/net/i40e/rte_pmd_i40e_version.map |   1 +
 3 files changed, 239 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bcc59b2..a5d6d05 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -9898,3 +9898,225 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	return ret;
 }
+
+static int
+i40e_vsi_rm_mac_filter(struct i40e_vsi *vsi)
+{
+	struct i40e_mac_filter *f;
+	struct i40e_macvlan_filter *mv_f;
+	int i, vlan_num;
+	enum rte_mac_filter_type filter_type;
+	int ret = I40E_SUCCESS;
+
+	/* remove all the MACs */
+	TAILQ_FOREACH(f, &vsi->mac_list, next) {
+		vlan_num = vsi->vlan_num;
+		filter_type = f->mac_info.filter_type;
+		if (filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+		    filter_type == RTE_MACVLAN_HASH_MATCH) {
+			if (vlan_num == 0) {
+				PMD_DRV_LOG(ERR,
+					    "VLAN number shouldn't be 0\n");
+				return I40E_ERR_PARAM;
+			}
+		} else if (filter_type == RTE_MAC_PERFECT_MATCH ||
+			   filter_type == RTE_MAC_HASH_MATCH)
+			vlan_num = 1;
+
+		mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
+		if (!mv_f) {
+			PMD_DRV_LOG(ERR, "failed to allocate memory");
+			return I40E_ERR_NO_MEMORY;
+		}
+
+		for (i = 0; i < vlan_num; i++) {
+			mv_f[i].filter_type = filter_type;
+			(void)rte_memcpy(&mv_f[i].macaddr,
+					 &f->mac_info.mac_addr,
+					 ETH_ADDR_LEN);
+		}
+		if (filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+		    filter_type == RTE_MACVLAN_HASH_MATCH) {
+			ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num,
+							 &f->mac_info.mac_addr);
+			if (ret != I40E_SUCCESS) {
+				rte_free(mv_f);
+				return ret;
+			}
+		}
+
+		ret = i40e_remove_macvlan_filters(vsi, mv_f, vlan_num);
+		if (ret != I40E_SUCCESS) {
+			rte_free(mv_f);
+			return ret;
+		}
+
+		rte_free(mv_f);
+		ret = I40E_SUCCESS;
+	}
+
+	return ret;
+}
+
+static int
+i40e_vsi_restore_mac_filter(struct i40e_vsi *vsi)
+{
+	struct i40e_mac_filter *f;
+	struct i40e_macvlan_filter *mv_f;
+	int i, vlan_num = 0;
+	int ret = I40E_SUCCESS;
+
+	/* restore all the MACs */
+	TAILQ_FOREACH(f, &vsi->mac_list, next) {
+		if ((f->mac_info.filter_type == RTE_MACVLAN_PERFECT_MATCH) ||
+		    (f->mac_info.filter_type == RTE_MACVLAN_HASH_MATCH)) {
+			/**
+			 * If vlan_num is 0, that's the first time to add mac,
+			 * set mask for vlan_id 0.
+			 */
+			if (vsi->vlan_num == 0) {
+				i40e_set_vlan_filter(vsi, 0, 1);
+				vsi->vlan_num = 1;
+			}
+			vlan_num = vsi->vlan_num;
+		} else if ((f->mac_info.filter_type == RTE_MAC_PERFECT_MATCH) ||
+			   (f->mac_info.filter_type == RTE_MAC_HASH_MATCH))
+			vlan_num = 1;
+
+		mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
+		if (!mv_f) {
+			PMD_DRV_LOG(ERR, "failed to allocate memory");
+			return I40E_ERR_NO_MEMORY;
+		}
+
+		for (i = 0; i < vlan_num; i++) {
+			mv_f[i].filter_type = f->mac_info.filter_type;
+			(void)rte_memcpy(&mv_f[i].macaddr,
+					 &f->mac_info.mac_addr,
+					 ETH_ADDR_LEN);
+		}
+
+		if (f->mac_info.filter_type == RTE_MACVLAN_PERFECT_MATCH ||
+		    f->mac_info.filter_type == RTE_MACVLAN_HASH_MATCH) {
+			ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num,
+							 &f->mac_info.mac_addr);
+			if (ret != I40E_SUCCESS) {
+				rte_free(mv_f);
+				return ret;
+			}
+		}
+
+		ret = i40e_add_macvlan_filters(vsi, mv_f, vlan_num);
+		if (ret != I40E_SUCCESS) {
+			rte_free(mv_f);
+			return ret;
+		}
+
+		rte_free(mv_f);
+		ret = I40E_SUCCESS;
+	}
+
+	return ret;
+}
+
+static int
+i40e_vsi_set_tx_loopback(struct i40e_vsi *vsi, uint8_t on)
+{
+	struct i40e_vsi_context ctxt;
+	struct i40e_hw *hw;
+	int ret;
+
+	if (!vsi)
+		return -EINVAL;
+
+	hw = I40E_VSI_TO_HW(vsi);
+
+	/* Use the FW API if FW >= v5.0 */
+	if (hw->aq.fw_maj_ver < 5) {
+		PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback");
+		return -ENOTSUP;
+	}
+
+	/* Check if it has been already on or off */
+	if (vsi->info.valid_sections &
+		rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID)) {
+		if (on) {
+			if ((vsi->info.switch_id &
+			     I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB) ==
+			    I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB)
+				return 0; /* already on */
+		} else {
+			if ((vsi->info.switch_id &
+			     I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB) == 0)
+				return 0; /* already off */
+		}
+	}
+
+	/* remove all the MACs first */
+	ret = i40e_vsi_rm_mac_filter(vsi);
+	if (ret)
+		return ret;
+
+	vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+	if (on)
+		vsi->info.switch_id |= I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB;
+	else
+		vsi->info.switch_id &= ~I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB;
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	(void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+	ctxt.seid = vsi->seid;
+
+	ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+	if (ret != I40E_SUCCESS) {
+		PMD_DRV_LOG(ERR, "Failed to update VSI params");
+		return ret;
+	}
+
+	/* add all the MACs back */
+	ret = i40e_vsi_restore_mac_filter(vsi);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+int
+rte_pmd_i40e_set_tx_loopback(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct i40e_pf *pf;
+	struct i40e_pf_vf *vf;
+	struct i40e_vsi *vsi;
+	uint16_t vf_id;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	/* setup PF TX loopback */
+	vsi = pf->main_vsi;
+	ret = i40e_vsi_set_tx_loopback(vsi, on);
+	if (ret)
+		return ret;
+
+	/* setup TX loopback for all the VFs */
+	if (!pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid argument.");
+		return -EINVAL;
+	}
+
+	for (vf_id = 0; vf_id < pf->vf_num; vf_id++) {
+		vf = &pf->vfs[vf_id];
+		vsi = vf->vsi;
+
+		ret = i40e_vsi_set_tx_loopback(vsi, on);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index c8736c8..3c65be4 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -114,4 +114,20 @@ int rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port,
 					uint16_t vf_id,
 					uint8_t on);
 
+/**
+ * Enable/Disable TX loopback on all the PF and VFs.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable TX loopback.
+ *    0 - Disable TX loopback.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_tx_loopback(uint8_t port,
+				 uint8_t on);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 028f0ef..51eda65 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -7,6 +7,7 @@ DPDK_17.02 {
 	global:
 
 	rte_pmd_i40e_ping_vfs;
+	rte_pmd_i40e_set_tx_loopback;
 	rte_pmd_i40e_set_vf_mac_anti_spoof;
 	rte_pmd_i40e_set_vf_vlan_anti_spoof;
 
-- 
1.9.3

^ permalink raw reply related

* [PATCH v7 04/27] net/i40e: set VF VLAN anti-spoofing from PF
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

Support enabling/disabling VF VLAN anti-spoofing from
PF.
User can call the API on PF to enable/disable a specific
VF's VLAN anti-spoofing.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 116 +++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev.h            |   1 +
 drivers/net/i40e/rte_pmd_i40e.h           |  19 +++++
 drivers/net/i40e/rte_pmd_i40e_version.map |   1 +
 4 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 68c07de..bcc59b2 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -4418,6 +4418,7 @@ struct i40e_vsi *
 	vsi->max_macaddrs = I40E_NUM_MACADDR_MAX;
 	vsi->parent_vsi = uplink_vsi ? uplink_vsi : pf->main_vsi;
 	vsi->user_param = user_param;
+	vsi->vlan_anti_spoof_on = 0;
 	/* Allocate queues */
 	switch (vsi->type) {
 	case I40E_VSI_MAIN  :
@@ -5761,17 +5762,35 @@ struct i40e_vsi *
 			 uint16_t vlan_id, bool on)
 {
 	uint32_t vid_idx, vid_bit;
+	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+	struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
+	int ret;
 
 	if (vlan_id > ETH_VLAN_ID_MAX)
 		return;
 
 	vid_idx = I40E_VFTA_IDX(vlan_id);
 	vid_bit = I40E_VFTA_BIT(vlan_id);
+	vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
 
-	if (on)
+	if (on) {
+		if (vsi->vlan_anti_spoof_on) {
+			ret = i40e_aq_add_vlan(hw, vsi->seid,
+					       &vlan_data, 1, NULL);
+			if (ret != I40E_SUCCESS)
+				PMD_DRV_LOG(ERR, "Failed to add vlan filter");
+		}
 		vsi->vfta[vid_idx] |= vid_bit;
-	else
+	} else {
+		if (vsi->vlan_anti_spoof_on) {
+			ret = i40e_aq_remove_vlan(hw, vsi->seid,
+						  &vlan_data, 1, NULL);
+			if (ret != I40E_SUCCESS)
+				PMD_DRV_LOG(ERR,
+					    "Failed to remove vlan filter");
+		}
 		vsi->vfta[vid_idx] &= ~vid_bit;
+	}
 }
 
 /**
@@ -9786,3 +9805,96 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	return ret;
 }
+
+static int
+i40e_add_rm_all_vlan_filter(struct i40e_vsi *vsi, uint8_t add)
+{
+	uint32_t j, k;
+	uint16_t vlan_id;
+	struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
+	struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
+	int ret;
+
+	for (j = 0; j < I40E_VFTA_SIZE; j++) {
+		if (!vsi->vfta[j])
+			continue;
+
+		for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
+			if (!(vsi->vfta[j] & (1 << k)))
+				continue;
+
+			vlan_id = j * I40E_UINT32_BIT_SIZE + k;
+			vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
+			if (add)
+				ret = i40e_aq_add_vlan(hw, vsi->seid,
+						       &vlan_data, 1, NULL);
+			else
+				ret = i40e_aq_remove_vlan(hw, vsi->seid,
+							  &vlan_data, 1, NULL);
+			if (ret != I40E_SUCCESS) {
+				PMD_DRV_LOG(ERR,
+					    "Failed to add/rm vlan filter");
+				return ret;
+			}
+		}
+	}
+
+	return I40E_SUCCESS;
+}
+
+int
+rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct i40e_pf *pf;
+	struct i40e_vsi *vsi;
+	struct i40e_hw *hw;
+	struct i40e_vsi_context ctxt;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	if (vf_id > pf->vf_num - 1 || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid argument.");
+		return -EINVAL;
+	}
+
+	vsi = pf->vfs[vf_id].vsi;
+	if (!vsi)
+		return -EINVAL;
+
+	/* Check if it has been already on or off */
+	if (vsi->vlan_anti_spoof_on == on)
+		return 0; /* already on or off */
+
+	vsi->vlan_anti_spoof_on = on;
+	ret = i40e_add_rm_all_vlan_filter(vsi, on);
+	if (ret)
+		return ret;
+
+	vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
+	if (on)
+		vsi->info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK;
+	else
+		vsi->info.sec_flags &= ~I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK;
+
+	memset(&ctxt, 0, sizeof(ctxt));
+	(void)rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
+	ctxt.seid = vsi->seid;
+
+	hw = I40E_VSI_TO_HW(vsi);
+	ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
+	if (ret != I40E_SUCCESS)
+		PMD_DRV_LOG(ERR, "Failed to update VSI params");
+
+	return ret;
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 298cef4..0db140b 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -300,6 +300,7 @@ struct i40e_vsi {
 	uint16_t msix_intr; /* The MSIX interrupt binds to VSI */
 	uint16_t nb_msix;   /* The max number of msix vector */
 	uint8_t enabled_tc; /* The traffic class enabled */
+	uint8_t vlan_anti_spoof_on; /* The VLAN anti-spoofing enabled */
 	struct i40e_bw_info bw_info; /* VSI bandwidth information */
 };
 
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 52319cf..c8736c8 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -95,4 +95,23 @@ int rte_pmd_i40e_set_vf_mac_anti_spoof(uint8_t port,
 				       uint16_t vf_id,
 				       uint8_t on);
 
+/**
+ * Enable/Disable VF VLAN anti spoofing.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set VLAN anti spoofing.
+ * @param on
+ *    1 - Enable VFs VLAN anti spoofing.
+ *    0 - Disable VFs VLAN anti spoofing.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port,
+					uint16_t vf_id,
+					uint8_t on);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 0581209..028f0ef 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -8,5 +8,6 @@ DPDK_17.02 {
 
 	rte_pmd_i40e_ping_vfs;
 	rte_pmd_i40e_set_vf_mac_anti_spoof;
+	rte_pmd_i40e_set_vf_vlan_anti_spoof;
 
 } DPDK_2.0;
-- 
1.9.3

^ permalink raw reply related

* [PATCH v7 06/27] net/i40e: set VF unicast promisc mode from PF
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

Support enabling/disabling VF unicast promiscuous mode from
PF.
User can call the API on PF to enable/disable a specific
VF's unicast promiscuous mode.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 39 +++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 19 +++++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 59 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index a5d6d05..3d7ee03 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10120,3 +10120,42 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	return ret;
 }
+
+int
+rte_pmd_i40e_set_vf_unicast_promisc(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct i40e_pf *pf;
+	struct i40e_vsi *vsi;
+	struct i40e_hw *hw;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	if (vf_id > pf->vf_num - 1 || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid argument.");
+		return -EINVAL;
+	}
+
+	vsi = pf->vfs[vf_id].vsi;
+	if (!vsi)
+		return -EINVAL;
+
+	hw = I40E_VSI_TO_HW(vsi);
+
+	ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
+						  on, NULL, true);
+	if (ret != I40E_SUCCESS)
+		PMD_DRV_LOG(ERR, "Failed to set unicast promiscuous mode");
+
+	return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 3c65be4..4c98136 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -130,4 +130,23 @@ int rte_pmd_i40e_set_vf_vlan_anti_spoof(uint8_t port,
 int rte_pmd_i40e_set_tx_loopback(uint8_t port,
 				 uint8_t on);
 
+/**
+ * Enable/Disable VF unicast promiscuous mode.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set.
+ * @param on
+ *    1 - Enable.
+ *    0 - Disable.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_unicast_promisc(uint8_t port,
+					uint16_t vf_id,
+					uint8_t on);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 51eda65..35757a9 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -9,6 +9,7 @@ DPDK_17.02 {
 	rte_pmd_i40e_ping_vfs;
 	rte_pmd_i40e_set_tx_loopback;
 	rte_pmd_i40e_set_vf_mac_anti_spoof;
+	rte_pmd_i40e_set_vf_unicast_promisc;
 	rte_pmd_i40e_set_vf_vlan_anti_spoof;
 
 } DPDK_2.0;
-- 
1.9.3

^ permalink raw reply related

* [PATCH v7 07/27] net/i40e: set VF multicast promisc mode from PF
From: Wenzhuo Lu @ 2017-01-03  6:54 UTC (permalink / raw)
  To: dev; +Cc: Wenzhuo Lu
In-Reply-To: <1483426488-117332-1-git-send-email-wenzhuo.lu@intel.com>

Support enabling/disabling VF multicast promiscuous mode from
PF.
User can call the API on PF to enable/disable a specific
VF's multicast promiscuous mode.

Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c            | 39 +++++++++++++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 19 +++++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  1 +
 3 files changed, 59 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 3d7ee03..9d050c8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10159,3 +10159,42 @@ static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 
 	return ret;
 }
+
+int
+rte_pmd_i40e_set_vf_multicast_promisc(uint8_t port, uint16_t vf_id, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct i40e_pf *pf;
+	struct i40e_vsi *vsi;
+	struct i40e_hw *hw;
+	int ret;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+
+	if (vf_id > pf->vf_num - 1 || !pf->vfs) {
+		PMD_DRV_LOG(ERR, "Invalid argument.");
+		return -EINVAL;
+	}
+
+	vsi = pf->vfs[vf_id].vsi;
+	if (!vsi)
+		return -EINVAL;
+
+	hw = I40E_VSI_TO_HW(vsi);
+
+	ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
+						    on, NULL);
+	if (ret != I40E_SUCCESS)
+		PMD_DRV_LOG(ERR, "Failed to set multicast promiscuous mode");
+
+	return ret;
+}
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index 4c98136..9091520 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -149,4 +149,23 @@ int rte_pmd_i40e_set_vf_unicast_promisc(uint8_t port,
 					uint16_t vf_id,
 					uint8_t on);
 
+/**
+ * Enable/Disable VF multicast promiscuous mode.
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    VF on which to set.
+ * @param on
+ *    1 - Enable.
+ *    0 - Disable.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_i40e_set_vf_multicast_promisc(uint8_t port,
+					  uint16_t vf_id,
+					  uint8_t on);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index 35757a9..32939b2 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -9,6 +9,7 @@ DPDK_17.02 {
 	rte_pmd_i40e_ping_vfs;
 	rte_pmd_i40e_set_tx_loopback;
 	rte_pmd_i40e_set_vf_mac_anti_spoof;
+	rte_pmd_i40e_set_vf_multicast_promisc;
 	rte_pmd_i40e_set_vf_unicast_promisc;
 	rte_pmd_i40e_set_vf_vlan_anti_spoof;
 
-- 
1.9.3

^ permalink raw reply related


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.