test suite reviews and discussions
 help / color / mirror / Atom feed
From: "Qiu, Michael" <michael.qiu@intel.com>
To: "Xu, HuilongX" <huilongx.xu@intel.com>, "dts@dpdk.org" <dts@dpdk.org>
Subject: Re: [dts] [ PATCH V2] update framework for support fortville NIC test.
Date: Wed, 28 Jan 2015 06:39:27 +0000	[thread overview]
Message-ID: <533710CFB86FA344BFBF2D6802E60286CC4366@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <DF2A19295B96364286FEB7F3DDA27A46010A8906@SHSMSX104.ccr.corp.intel.com>

On 1/28/2015 2:29 PM, Xu, HuilongX wrote:
> Hi Michael,
> I will remove the code " if not os.path.exists("/sys/bus/pci/drivers/i40e/"+"0000:"+pci_bus):" in v3 patch,
> The code " self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/i40e/bind" % pci_bus, "# ")" for dut and tester NIC restore default kernel driver, when finish test.

Actually, you may hold on for for v3, because Marvin has a plan
re-construct those code :)

But if this block your work, I think you should think out a solution
about to solve the error of  "if not
os.path.exists("/sys/bus/pci/drivers/i40e/"+"0000:"+pci_bus)"


Thanks,
Michael
> Thanks  a lot.
>
> -----Original Message-----
> From: Qiu, Michael 
> Sent: Tuesday, January 27, 2015 4:46 PM
> To: Xu, HuilongX; dts@dpdk.org
> Subject: Re: [dts] [ PATCH V2] update framework for support fortville NIC test.
>
> On 1/27/2015 2:53 PM, Xu, HuilongX wrote:
>> Hi Michael,
>> Thanks  a lot for your comments.
>> You can check my V2 patch.
>>
>>> +                elif pci_id in ('8086:1583','8086:1584','8086:1572'):
>>> +                    if not os.path.exists("/sys/bus/pci/drivers/i40e/"+"0000:"+pci_bus):
>> This code is only support check the driver in tester, can’t check dut, so it’s a bug for check the driver status.
>> Maybe we can send a new patch for fix check  driver stats. It need include all driver eg, ixgeb, igb,i40e,e1000...
>>
>> Thanks  a lot
>>
>> -----Original Message-----
>> From: Qiu, Michael 
>> Sent: Tuesday, January 27, 2015 2:41 PM
>> To: Xu, HuilongX; dts@dpdk.org
>> Subject: Re: [dts] [ PATCH V2] update framework for support fortville NIC test.
>>
>> Hi, huilong
>>
>> Have you seen my comments with your v1 patch?
>>
>> Also you'd better to make update patch within the original thread.
>>
>> Thanks,
>> Michael
>> On 1/27/2015 1:54 PM, huilongx.xu wrote:
>>> execution_fortville.cfg is the test case list for fortville NIC
>>>
>>> crb.py, add fortville NIC kernel driver(i40e) in dts
>>>
>>> settings.py, add fortville NIC info in dts
>>>
>>> test_case.py, insmod and used i40e for fortvill NIC
>>>
>>> Signed-off-by: huilongx.xu <huilongx.xu@intel.com>
>>> ---
>>>  execution_fortville.cfg |   21 +++++++++++++++++++++
>>>  framework/crb.py        |    9 ++++++++-
>>>  framework/settings.py   |    6 ++++++
>>>  framework/test_case.py  |    4 ++++
>>>  4 files changed, 39 insertions(+), 1 deletions(-)
>>>  create mode 100644 execution_fortville.cfg
>>>
>>> diff --git a/execution_fortville.cfg b/execution_fortville.cfg
>>> new file mode 100644
>>> index 0000000..15f2ccf
>>> --- /dev/null
>>> +++ b/execution_fortville.cfg
>>> @@ -0,0 +1,21 @@
>>> +[Execution1]
>>> +crbs=<CRB IP Address>
>>> +drivername=<driver name igb_uio or vfio-pci>
>>> +test_suites=
>>> +    cmdline,
>>> +    hello_world,
>>> +    multiprocess,
>>> +    blacklist
>>> +targets=
>>> +    x86_64-native-linuxapp-gcc
>>> +parameters=nic_type=fortville_eagle:func=true
>>> +
>>> +[Execution2]
>>> +crbs=<Performance CRB IP Address>
>>> +drivername=<driver name igb_uio or vfio-pci>
>>> +test_suites=
>>> +    l2fwd,
>>> +    l3fwd
>>> +targets=
>>> +    x86_64-native-linuxapp-gcc
>>> +parameters=nic_type=fortville_eagle:perf=true
>>> diff --git a/framework/crb.py b/framework/crb.py
>>> index d41f51b..efd23b2 100644
>>> --- a/framework/crb.py
>>> +++ b/framework/crb.py
>>> @@ -150,7 +150,11 @@ class Crb(object):
>>>          self.send_expect("modprobe e1000e", "# ", 20)
>>>          self.send_expect("modprobe e1000", "# ", 20)
>>>          self.send_expect("modprobe virtio_net", "# ", 20)
>>> -
>>> + 
>>> +        self.send_expect("modprobe i40e", "# ", 60)
>>> +        out = self.send_expect("lsmod |grep i40e", "# ", 30)
>>> +        if "i40e" not in out:
>>> +           self.logger.error("please check the os install i40e driver already.");
>>>          try:
>>>              for (pci_bus, pci_id) in self.pci_devices_info:
>>>                  """
>>> @@ -173,6 +177,9 @@ class Crb(object):
>>>                          self.send_expect("echo -n 0000:%s > /sys/bus/pci/drivers/e1000/bind" % pci_bus, "# ")
>>>                  elif pci_id in ('1af4:1000'):
>>>                      self.send_expect("echo 0000%s > /sys/bus/pci/drivers/virtio-pci/bind" % pci_bus, "# ")
>>> +                elif pci_id in ('8086:1583','8086:1584','8086:1572'):
>>> +                    if not os.path.exists("/sys/bus/pci/drivers/i40e/"+"0000:"+pci_bus):
> You need to remove this line I think,  not acceptable, as you 
> os.path.exists, then why need self.send_expect() ?
>
> Actually, all these lines will be removed later.
>
> Thanks,
> Michael
>>> +                        self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/i40e/bind" % pci_bus, "# ")
>>>                  else:
>>>                      continue
>>>  
>>> diff --git a/framework/settings.py b/framework/settings.py
>>> index 2ef8db8..40b81fb 100644
>>> --- a/framework/settings.py
>>> +++ b/framework/settings.py
>>> @@ -55,6 +55,9 @@ NICS = {
>>>      'I217LM': '8086:153a',
>>>      'I218V': '8086:1559',
>>>      'I218LM': '8086:155a',
>>> +    'fortville_eagle': '8086:1572',
>>> +    'fortville_spirit': '8086:1583',
>>> +    'fortville_spirit_single': '8086:1584',
>>>  }
>>>  
>>>  DRIVERS = {
>>> @@ -80,6 +83,9 @@ DRIVERS = {
>>>      'I217LM': 'igb',
>>>      'I218V': 'igb',
>>>      'I218LM': 'igb',
>>> +    'fortville_eagle': 'i40e',
>>> +    'fortville_spirit': 'i40e',
>>> +    'fortville_spirit_single':'i40e'
>>>  }
>>>  
>>>  """
>>> diff --git a/framework/test_case.py b/framework/test_case.py
>>> index 706003f..07fdc36 100644
>>> --- a/framework/test_case.py
>>> +++ b/framework/test_case.py
>>> @@ -76,5 +76,9 @@ class TestCase(object):
>>>              bitrate *= 10  # 10 Gb NICs
>>>          elif self.nic == "avoton2c5":
>>>              bitrate *= 2.5  # 2.5 Gb NICs
>>> +        elif self.nic in ["fortville_spirit", "fortville_spirit_single"]:
>>> +            bitrate *= 40
>>> +        elif self.nic == 'fortville_eagle':
>>> +		    bitrate *= 10
>>>  
>>>          return bitrate * num_ports / 8 / (frame_size + 20)
>


\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0void vnic_register_cbacks(struct vnic_dev *vdev,
+#ifdef RTE_EAL_VFIO
+	void *(*buf_map)(void *priv, void *addr, size_t size),
+#endif
+	void *(*alloc_consistent)(void *priv, size_t size,
+	    dma_addr_t *dma_handle, u8 *name),
+	void (*free_consistent)(struct rte_pci_device *hwdev,
+	    size_t size, void *vaddr,
+	    dma_addr_t dma_handle))
+{
+#ifdef RTE_EAL_VFIO
+	vdev-&gt;buf_map = buf_map;
+#endif
+	vdev-&gt;alloc_consistent = alloc_consistent;
+	vdev-&gt;free_consistent = free_consistent;
+}
+
+static int vnic_dev_discover_res(struct vnic_dev *vdev,
+	struct vnic_dev_bar *bar, unsigned int num_bars)
+{
+	struct vnic_resource_header __iomem *rh;
+	struct mgmt_barmap_hdr __iomem *mrh;
+	struct vnic_resource __iomem *r;
+	u8 type;
+
+	if (num_bars == 0)
+		return -EINVAL;
+
+	if (bar-&gt;len &lt; VNIC_MAX_RES_HDR_SIZE) {
+		pr_err(&quot;vNIC BAR0 res hdr length error\n&quot;);
+		return -EINVAL;
+	}
+
+	rh  = bar-&gt;vaddr;
+	mrh = bar-&gt;vaddr;
+	if (!rh) {
+		pr_err(&quot;vNIC BAR0 res hdr not mem-mapped\n&quot;);
+		return -EINVAL;
+	}
+
+	/* Check for mgmt vnic in addition to normal vnic */
+	if ((ioread32(&amp;rh-&gt;magic) != VNIC_RES_MAGIC) ||
+		(ioread32(&amp;rh-&gt;version) != VNIC_RES_VERSION)) {
+		if ((ioread32(&amp;mrh-&gt;magic) != MGMTVNIC_MAGIC) ||
+			(ioread32(&amp;mrh-&gt;version) != MGMTVNIC_VERSION)) {
+			pr_err(&quot;vNIC BAR0 res magic/version error &quot; \
+				&quot;exp (%lx/%lx) or (%lx/%lx), curr (%x/%x)\n&quot;,
+				VNIC_RES_MAGIC, VNIC_RES_VERSION,
+				MGMTVNIC_MAGIC, MGMTVNIC_VERSION,
+				ioread32(&amp;rh-&gt;magic), ioread32(&amp;rh-&gt;version));
+			return -EINVAL;
+		}
+	}
+
+	if (ioread32(&amp;mrh-&gt;magic) == MGMTVNIC_MAGIC)
+		r = (struct vnic_resource __iomem *)(mrh + 1);
+	else
+		r = (struct vnic_resource __iomem *)(rh + 1);
+
+
+	while ((type = ioread8(&amp;r-&gt;type)) != RES_TYPE_EOL) {
+		u8 bar_num = ioread8(&amp;r-&gt;bar);
+		u32 bar_offset = ioread32(&amp;r-&gt;bar_offset);
+		u32 count = ioread32(&amp;r-&gt;count);
+		u32 len;
+
+		r++;
+
+		if (bar_num &gt;= num_bars)
+			continue;
+
+		if (!bar[bar_num].len || !bar[bar_num].vaddr)
+			continue;
+
+		switch (type) {
+		case RES_TYPE_WQ:
+		case RES_TYPE_RQ:
+		case RES_TYPE_CQ:
+		case RES_TYPE_INTR_CTRL:
+			/* each count is stride bytes long */
+			len = count * VNIC_RES_STRIDE;
+			if (len + bar_offset &gt; bar[bar_num].len) {
+				pr_err(&quot;vNIC BAR0 resource %d &quot; \
+					&quot;out-of-bounds, offset 0x%x + &quot; \
+					&quot;size 0x%x &gt; bar len 0x%lx\n&quot;,
+					type, bar_offset,
+					len,
+					bar[bar_num].len);
+				return -EINVAL;
+			}
+			break;
+		case RES_TYPE_INTR_PBA_LEGACY:
+		case RES_TYPE_DEVCMD:
+			len = count;
+			break;
+		default:
+			continue;
+		}
+
+		vdev-&gt;res[type].count = count;
+		vdev-&gt;res[type].vaddr = (char __iomem *)bar[bar_num].vaddr +
+		    bar_offset;
+		vdev-&gt;res[type].bus_addr = bar[bar_num].bus_addr + bar_offset;
+	}
+
+	return 0;
+}
+
+unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev,
+	enum vnic_res_type type)
+{
+	return vdev-&gt;res[type].count;
+}
+
+void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
+	unsigned int index)
+{
+	if (!vdev-&gt;res[type].vaddr)
+		return NULL;
+
+	switch (type) {
+	case RES_TYPE_WQ:
+	case RES_TYPE_RQ:
+	case RES_TYPE_CQ:
+	case RES_TYPE_INTR_CTRL:
+		return (char __iomem *)vdev-&gt;res[type].vaddr +
+			index * VNIC_RES_STRIDE;
+	default:
+		return (char __iomem *)vdev-&gt;res[type].vaddr;
+	}
+}
+
+unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring,
+	unsigned int desc_count, unsigned int desc_size)
+{
+	/* The base address of the desc rings must be 512 byte aligned.
+	 * Descriptor count is aligned to groups of 32 descriptors.  A
+	 * count of 0 means the maximum 4096 descriptors.  Descriptor
+	 * size is aligned to 16 bytes.
+	 */
+
+	unsigned int count_align = 32;
+	unsigned int desc_align = 16;
+
+	ring-&gt;base_align = 512;
+
+	if (desc_count == 0)
+		desc_count = 4096;
+
+	ring-&gt;desc_count = ALIGN(desc_count, count_align);
+
+	ring-&gt;desc_size = ALIGN(desc_size, desc_align);
+
+	ring-&gt;size = ring-&gt;desc_count * ring-&gt;desc_size;
+	ring-&gt;size_unaligned = ring-&gt;size + ring-&gt;base_align;
+
+	return ring-&gt;size_unaligned;
+}
+
+void vnic_set_hdr_split_size(struct vnic_dev *vdev, u16 size)
+{
+	vdev-&gt;split_hdr_size = size;
+}
+
+u16 vnic_get_hdr_split_size(struct vnic_dev *vdev)
+{
+	return vdev-&gt;split_hdr_size;
+}
+
+void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring)
+{
+	memset(ring-&gt;descs, 0, ring-&gt;size);
+}
+
+int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring,
+	unsigned int desc_count, unsigned int desc_size, unsigned int socket_id,
+	char *z_name)
+{
+	const struct rte_memzone *rz;
+
+	vnic_dev_desc_ring_size(ring, desc_count, desc_size);
+
+	rz = rte_memzone_reserve_aligned(z_name,
+		ring-&gt;size_unaligned, socket_id,
+		0, ENIC_ALIGN);
+	if (!rz) {
+		pr_err(&quot;Failed to allocate ring (size=%d), aborting\n&quot;,
+			(int)ring-&gt;size);
+		return -ENOMEM;
+	}
+
+#ifdef RTE_EAL_VFIO
+	ring-&gt;descs_unaligned = vdev-&gt;buf_map(vdev-&gt;priv, rz-&gt;addr,
+		(size_t)(rz-&gt;len));
+#else
+	ring-&gt;descs_unaligned = rz-&gt;addr;
+#endif
+	if (!ring-&gt;descs_unaligned) {
+		pr_err(&quot;Failed to map allocated ring (size=%d), aborting\n&quot;,
+			(int)ring-&gt;size);
+		return -ENOMEM;
+	}
+
+#ifdef RTE_EAL_VFIO
+	ring-&gt;base_addr_unaligned = (dma_addr_t)ring-&gt;descs_unaligned;
+#else
+	ring-&gt;base_addr_unaligned = (dma_addr_t)rz-&gt;phys_addr;
+#endif
+
+	ring-&gt;base_addr = ALIGN(ring-&gt;base_addr_unaligned,
+		ring-&gt;base_align);
+	ring-&gt;descs = (u8 *)ring-&gt;descs_unaligned +
+	    (ring-&gt;base_addr - ring-&gt;base_addr_unaligned);
+
+	vnic_dev_clear_desc_ring(ring);
+
+	ring-&gt;desc_avail = ring-&gt;desc_count - 1;
+
+	return 0;
+}
+
+void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring)
+{
+	if (ring-&gt;descs)
+		ring-&gt;descs = NULL;
+}
+
+static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
+	int wait)
+{
+	struct vnic_devcmd __iomem *devcmd = vdev-&gt;devcmd;
+	unsigned int i;
+	int delay;
+	u32 status;
+	int err;
+
+	status = ioread32(&amp;devcmd-&gt;status);
+	if (status == 0xFFFFFFFF) {
+		/* PCI-e target device is gone */
+		return -ENODEV;
+	}
+	if (status &amp; STAT_BUSY) {
+
+		pr_err(&quot;Busy devcmd %d\n&quot;,  _CMD_N(cmd));
+		return -EBUSY;
+	}
+
+	if (_CMD_DIR(cmd) &amp; _CMD_DIR_WRITE) {
+		for (i = 0; i &lt; VNIC_DEVCMD_NARGS; i++)
+			writeq(vdev-&gt;args[i], &amp;devcmd-&gt;args[i]);
+		wmb(); /* complete all writes initiated till now */
+	}
+
+	iowrite32(cmd, &amp;devcmd-&gt;cmd);
+
+	if ((_CMD_FLAGS(cmd) &amp; _CMD_FLAGS_NOWAIT))
+		return 0;
+
+	for (delay = 0; delay &lt; wait; delay++) {
+
+		udelay(100);
+
+		status = ioread32(&amp;devcmd-&gt;status);
+		if (status == 0xFFFFFFFF) {
+			/* PCI-e target device is gone */
+			return -ENODEV;
+		}
+
+		if (!(status &amp; STAT_BUSY)) {
+			if (status &amp; STAT_ERROR) {
+				err = -(int)readq(&amp;devcmd-&gt;args[0]);
+				if (cmd != CMD_CAPABILITY)
+					pr_err(&quot;Devcmd %d failed &quot; \
+						&quot;with error code %d\n&quot;,
+						_CMD_N(cmd), err);
+				return err;
+			}
+
+			if (_CMD_DIR(cmd) &amp; _CMD_DIR_READ) {
+				rmb();/* finish all reads initiated till now */
+				for (i = 0; i &lt; VNIC_DEVCMD_NARGS; i++)
+					vdev-&gt;args[i] = readq(&amp;devcmd-&gt;args[i]);
+			}
+
+			return 0;
+		}
+	}
+
+	pr_err(&quot;Timedout devcmd %d\n&quot;, _CMD_N(cmd));
+	return -ETIMEDOUT;
+}
+
+static int vnic_dev_cmd_proxy(struct vnic_dev *vdev,
+	enum vnic_devcmd_cmd proxy_cmd, enum vnic_devcmd_cmd cmd,
+	u64 *a0, u64 *a1, int wait)
+{
+	u32 status;
+	int err;
+
+	memset(vdev-&gt;args, 0, sizeof(vdev-&gt;args));
+
+	vdev-&gt;args[0] = vdev-&gt;proxy_index;
+	vdev-&gt;args[1] = cmd;
+	vdev-&gt;args[2] = *a0;
+	vdev-&gt;args[3] = *a1;
+
+	err = _vnic_dev_cmd(vdev, proxy_cmd, wait);
+	if (err)
+		return err;
+
+	status = (u32)vdev-&gt;args[0];
+	if (status &amp; STAT_ERROR) {
+		err = (int)vdev-&gt;args[1];
+		if (err != ERR_ECMDUNKNOWN ||
+		    cmd != CMD_CAPABILITY)
+			pr_err(&quot;Error %d proxy devcmd %d\n&quot;, err, _CMD_N(cmd));
+		return err;
+	}
+
+	*a0 = vdev-&gt;args[1];
+	*a1 = vdev-&gt;args[2];
+
+	return 0;
+}
+
+static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev,
+	enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)
+{
+	int err;
+
+	vdev-&gt;args[0] = *a0;
+	vdev-&gt;args[1] = *a1;
+
+	err = _vnic_dev_cmd(vdev, cmd, wait);
+
+	*a0 = vdev-&gt;args[0];
+	*a1 = vdev-&gt;args[1];
+
+	return err;
+}
+
+void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, u16 index)
+{
+	vdev-&gt;proxy = PROXY_BY_INDEX;
+	vdev-&gt;proxy_index = index;
+}
+
+void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf)
+{
+	vdev-&gt;proxy = PROXY_BY_BDF;
+	vdev-&gt;proxy_index = bdf;
+}
+
+void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev)
+{
+	vdev-&gt;proxy = PROXY_NONE;
+	vdev-&gt;proxy_index = 0;
+}
+
+int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
+	u64 *a0, u64 *a1, int wait)
+{
+	memset(vdev-&gt;args, 0, sizeof(vdev-&gt;args));
+
+	switch (vdev-&gt;proxy) {
+	case PROXY_BY_INDEX:
+		return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_INDEX, cmd,
+				a0, a1, wait);
+	case PROXY_BY_BDF:
+		return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_BDF, cmd,
+				a0, a1, wait);
+	case PROXY_NONE:
+	default:
+		return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait);
+	}
+}
+
+static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd)
+{
+	u64 a0 = (u32)cmd, a1 = 0;
+	int wait = 1000;
+	int err;
+
+	err = vnic_dev_cmd(vdev, CMD_CAPABILITY, &amp;a0, &amp;a1, wait);
+
+	return !(err || a0);
+}
+
+int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
+	void *value)
+{
+	u64 a0, a1;
+	int wait = 1000;
+	int err;
+
+	a0 = offset;
+	a1 = size;
+
+	err = vnic_dev_cmd(vdev, CMD_DEV_SPEC, &amp;a0, &amp;a1, wait);
+
+	switch (size) {
+	case 1:
+		*(u8 *)value = (u8)a0;
+		break;
+	case 2:
+		*(u16 *)value = (u16)a0;
+		break;
+	case 4:
+		*(u32 *)value = (u32)a0;
+		break;
+	case 8:
+		*(u64 *)value = a0;
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	return err;
+}
+
+int vnic_dev_stats_clear(struct vnic_dev *vdev)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+
+	return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &amp;a0, &amp;a1, wait);
+}
+
+int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats)
+{
+	u64 a0, a1;
+	int wait = 1000;
+	static instance;
+	char name[NAME_MAX];
+
+	if (!vdev-&gt;stats) {
+		snprintf(name, sizeof(name), &quot;vnic_stats-%d&quot;, instance++);
+		vdev-&gt;stats = vdev-&gt;alloc_consistent(vdev-&gt;priv,
+			sizeof(struct vnic_stats), &amp;vdev-&gt;stats_pa, name);
+		if (!vdev-&gt;stats)
+			return -ENOMEM;
+	}
+
+	*stats = vdev-&gt;stats;
+	a0 = vdev-&gt;stats_pa;
+	a1 = sizeof(struct vnic_stats);
+
+	return vnic_dev_cmd(vdev, CMD_STATS_DUMP, &amp;a0, &amp;a1, wait);
+}
+
+int vnic_dev_close(struct vnic_dev *vdev)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+
+	return vnic_dev_cmd(vdev, CMD_CLOSE, &amp;a0, &amp;a1, wait);
+}
+
+/** Deprecated.  @see vnic_dev_enable_wait */
+int vnic_dev_enable(struct vnic_dev *vdev)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+
+	return vnic_dev_cmd(vdev, CMD_ENABLE, &amp;a0, &amp;a1, wait);
+}
+
+int vnic_dev_enable_wait(struct vnic_dev *vdev)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+
+	if (vnic_dev_capable(vdev, CMD_ENABLE_WAIT))
+		return vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &amp;a0, &amp;a1, wait);
+	else
+		return vnic_dev_cmd(vdev, CMD_ENABLE, &amp;a0, &amp;a1, wait);
+}
+
+int vnic_dev_disable(struct vnic_dev *vdev)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+
+	return vnic_dev_cmd(vdev, CMD_DISABLE, &amp;a0, &amp;a1, wait);
+}
+
+int vnic_dev_open(struct vnic_dev *vdev, int arg)
+{
+	u64 a0 = (u32)arg, a1 = 0;
+	int wait = 1000;
+
+	return vnic_dev_cmd(vdev, CMD_OPEN, &amp;a0, &amp;a1, wait);
+}
+
+int vnic_dev_open_done(struct vnic_dev *vdev, int *done)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+	int err;
+
+	*done = 0;
+
+	err = vnic_dev_cmd(vdev, CMD_OPEN_STATUS, &amp;a0, &amp;a1, wait);
+	if (err)
+		return err;
+
+	*donËý\x05\0Ìý\x05\0Íý\x05\0Îý\x05\0Ïý\x05\0Ðý\x05\0Ñý\x05\0Òý\x05\0Óý\x05\0Ôý\x05\0Õý\x05\0Öý\x05\0×ý\x05\0Øý\x05\0Ùý\x05\0Úý\x05\0Ûý\x05\0Üý\x05\0Ýý\x05\0Þý\x05\0ßý\x05\0àý\x05\0áý\x05\0âý\x05\0ãý\x05\0äý\x05\0åý\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0e = (a0 == 0);
+
+	return 0;
+}
+
+int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg)
+{
+	u64 a0 = (u32)arg, a1 = 0;
+	int wait = 1000;
+
+	return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &amp;a0, &amp;a1, wait);
+}
+
+int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+	int err;
+
+	*done = 0;
+
+	err = vnic_dev_cmd(vdev, CMD_SOFT_RESET_STATUS, &amp;a0, &amp;a1, wait);
+	if (err)
+		return err;
+
+	*done = (a0 == 0);
+
+	return 0;
+}
+
+int vnic_dev_get_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
+{
+	u64 a0, a1;
+	int wait = 1000;
+	int err, i;
+
+	for (i = 0; i &lt; ETH_ALEN; i++)
+		mac_addr[i] = 0;
+
+	err = vnic_dev_cmd(vdev, CMD_GET_MAC_ADDR, &amp;a0, &amp;a1, wait);
+	if (err)
+		return err;
+
+	for (i = 0; i &lt; ETH_ALEN; i++)
+		mac_addr[i] = ((u8 *)&amp;a0)[i];
+
+	return 0;
+}
+
+int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
+	int broadcast, int promisc, int allmulti)
+{
+	u64 a0, a1 = 0;
+	int wait = 1000;
+	int err;
+
+	a0 = (directed ? CMD_PFILTER_DIRECTED : 0) |
+	     (multicast ? CMD_PFILTER_MULTICAST : 0) |
+	     (broadcast ? CMD_PFILTER_BROADCAST : 0) |
+	     (promisc ? CMD_PFILTER_PROMISCUOUS : 0) |
+	     (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0);
+
+	err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &amp;a0, &amp;a1, wait);
+	if (err)
+		pr_err(&quot;Can't set packet filter\n&quot;);
+
+	return err;
+}
+
+int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+	int err;
+	int i;
+
+	for (i = 0; i &lt; ETH_ALEN; i++)
+		((u8 *)&amp;a0)[i] = addr[i];
+
+	err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &amp;a0, &amp;a1, wait);
+	if (err)
+		pr_err(&quot;Can't add addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n&quot;,
+			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
+			err);
+
+	return err;
+}
+
+int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+	int err;
+	int i;
+
+	for (i = 0; i &lt; ETH_ALEN; i++)
+		((u8 *)&amp;a0)[i] = addr[i];
+
+	err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &amp;a0, &amp;a1, wait);
+	if (err)
+		pr_err(&quot;Can't del addr [%02x:%02x:%02x:%02x:%02x:%02x], %d\n&quot;,
+			addr[0], addr[1], addr[2], addr[3], addr[4], addr[5],
+			err);
+
+	return err;
+}
+
+int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
+	u8 ig_vlan_rewrite_mode)
+{
+	u64 a0 = ig_vlan_rewrite_mode, a1 = 0;
+	int wait = 1000;
+
+	if (vnic_dev_capable(vdev, CMD_IG_VLAN_REWRITE_MODE))
+		return vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE,
+				&amp;a0, &amp;a1, wait);
+	else
+		return 0;
+}
+
+int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
+{
+	u64 a0 = intr, a1 = 0;
+	int wait = 1000;
+	int err;
+
+	err = vnic_dev_cmd(vdev, CMD_IAR, &amp;a0, &amp;a1, wait);
+	if (err)
+		pr_err(&quot;Failed to raise INTR[%d], err %d\n&quot;, intr, err);
+
+	return err;
+}
+
+void vnic_dev_set_reset_flag(struct vnic_dev *vdev, int state)
+{
+	vdev-&gt;in_reset = state;
+}
+
+static inline int vnic_dev_in_reset(struct vnic_dev *vdev)
+{
+	return vdev-&gt;in_reset;
+}
+
+int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
+	void *notify_addr, dma_addr_t notify_pa, u16 intr)
+{
+	u64 a0, a1;
+	int wait = 1000;
+	int r;
+
+	memset(notify_addr, 0, sizeof(struct vnic_devcmd_notify));
+	if (!vnic_dev_in_reset(vdev)) {
+		vdev-&gt;notify = notify_addr;
+		vdev-&gt;notify_pa = notify_pa;
+	}
+
+	a0 = (u64)notify_pa;
+	a1 = ((u64)intr &lt;&lt; 32) &amp; 0x0000ffff00000000ULL;
+	a1 += sizeof(struct vnic_devcmd_notify);
+
+	r = vnic_dev_cmd(vdev, CMD_NOTIFY, &amp;a0, &amp;a1, wait);
+	if (!vnic_dev_in_reset(vdev))
+		vdev-&gt;notify_sz = (r == 0) ? (u32)a1 : 0;
+
+	return r;
+}
+
+int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
+{
+	void *notify_addr;
+	dma_addr_t notify_pa;
+	char name[NAME_MAX];
+	static int instance;
+
+	if (vdev-&gt;notify || vdev-&gt;notify_pa) {
+		pr_warn(&quot;notify block %p still allocated.\n&quot; \
+			&quot;Ignore if restarting port\n&quot;, vdev-&gt;notify);
+		return -EINVAL;
+	}
+
+	if (!vnic_dev_in_reset(vdev)) {
+		snprintf(name, sizeof(name), &quot;vnic_notify-%d&quot;, instance++);
+		notify_addr = vdev-&gt;alloc_consistent(vdev-&gt;priv,
+			sizeof(struct vnic_devcmd_notify),
+			&amp;notify_pa, name);
+		if (!notify_addr)
+			return -ENOMEM;
+	}
+
+	return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr);
+}
+
+int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev)
+{
+	u64 a0, a1;
+	int wait = 1000;
+	int err;
+
+	a0 = 0;  /* paddr = 0 to unset notify buffer */
+	a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */
+	a1 += sizeof(struct vnic_devcmd_notify);
+
+	err = vnic_dev_cmd(vdev, CMD_NOTIFY, &amp;a0, &amp;a1, wait);
+	if (!vnic_dev_in_reset(vdev)) {
+		vdev-&gt;notify = NULL;
+		vdev-&gt;notify_pa = 0;
+		vdev-&gt;notify_sz = 0;
+	}
+
+	return err;
+}
+
+int vnic_dev_notify_unset(struct vnic_dev *vdev)
+{
+	if (vdev-&gt;notify &amp;&amp; !vnic_dev_in_reset(vdev)) {
+		vdev-&gt;free_consistent(vdev-&gt;pdev,
+			sizeof(struct vnic_devcmd_notify),
+			vdev-&gt;notify,
+			vdev-&gt;notify_pa);
+	}
+
+	return vnic_dev_notify_unsetcmd(vdev);
+}
+
+static int vnic_dev_notify_ready(struct vnic_dev *vdev)
+{
+	u32 *words;
+	unsigned int nwords = vdev-&gt;notify_sz / 4;
+	unsigned int i;
+	u32 csum;
+
+	if (!vdev-&gt;notify || !vdev-&gt;notify_sz)
+		return 0;
+
+	do {
+		csum = 0;
+		rte_memcpy(&amp;vdev-&gt;notify_copy, vdev-&gt;notify, vdev-&gt;notify_sz);
+		words = (u32 *)&amp;vdev-&gt;notify_copy;
+		for (i = 1; i &lt; nwords; i++)
+			csum += words[i];
+	} while (csum != words[0]);
+
+	return 1;
+}
+
+int vnic_dev_init(struct vnic_dev *vdev, int arg)
+{
+	u64 a0 = (u32)arg, a1 = 0;
+	int wait = 1000;
+	int r = 0;
+
+	if (vnic_dev_capable(vdev, CMD_INIT))
+		r = vnic_dev_cmd(vdev, CMD_INIT, &amp;a0, &amp;a1, wait);
+	else {
+		vnic_dev_cmd(vdev, CMD_INIT_v1, &amp;a0, &amp;a1, wait);
+		if (a0 &amp; CMD_INITF_DEFAULT_MAC) {
+			/* Emulate these for old CMD_INIT_v1 which
+			 * didn't pass a0 so no CMD_INITF_*.
+			 */
+			vnic_dev_cmd(vdev, CMD_GET_MAC_ADDR, &amp;a0, &amp;a1, wait);
+			vnic_dev_cmd(vdev, CMD_ADDR_ADD, &amp;a0, &amp;a1, wait);
+		}
+	}
+	return r;
+}
+
+int vnic_dev_deinit(struct vnic_dev *vdev)
+{
+	u64 a0 = 0, a1 = 0;
+	int wait = 1000;
+
+	return vnic_dev_cmd(vdev, CMD_DEINIT, &amp;a0, &amp;a1, wait);
+}
+
+void vnic_dev_intr_coal_timer_info_default(struct vnic_dev *vdev)
+{
+	/* Default: hardware intr coal timer is in units of 1.5 usecs */
+	vdev-&gt;intr_coal_timer_info.mul = 2;
+	vdev-&gt;intr_coal_timer_info.div = 3;
+	vdev-&gt;intr_coal_timer_info.max_usec +		vnic_dev_intr_coal_timer_hw_to_usec(vdev, 0xffff);
+}
+
+int vnic_dev_link_status(struct vnic_dev *vdev)
+{
+	if (!vnic_dev_notify_ready(vdev))
+		return 0;
+
+	return vdev-&gt;notify_copy.link_state;
+}
+
+u32 vnic_dev_port_speed(struct vnic_dev *vdev)
+{
+	if (!vnic_dev_notify_ready(vdev))
+		return 0;
+
+	return vdev-&gt;notify_copy.port_speed;
+}
+
+void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
+	enum vnic_dev_intr_mode intr_mode)
+{
+	vdev-&gt;intr_mode = intr_mode;
+}
+
+enum vnic_dev_intr_mode vnic_dev_get_intr_mode(
+	struct vnic_dev *vdev)
+{
+	return vdev-&gt;intr_mode;
+}
+
+u32 vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev, u32 usec)
+{
+	return (usec * vdev-&gt;intr_coal_timer_info.mul) /
+		vdev-&gt;intr_coal_timer_info.div;
+}
+
+u32 vnic_dev_intr_coal_timer_hw_to_usec(struct vnic_dev *vdev, u32 hw_cycles)
+{
+	return (hw_cycles * vdev-&gt;intr_coal_timer_info.div) /
+		vdev-&gt;intr_coal_timer_info.mul;
+}
+
+u32 vnic_dev_get_intr_coal_timer_max(struct vnic_dev *vdev)
+{
+	return vdev-&gt;intr_coal_timer_info.max_usec;
+}
+
+void vnic_dev_unregister(struct vnic_dev *vdev)
+{
+	if (vdev) {
+		if (vdev-&gt;notify)
+			vdev-&gt;free_consistent(vdev-&gt;pdev,
+				sizeof(struct vnic_devcmd_notify),
+				vdev-&gt;notify,
+				vdev-&gt;notify_pa);
+		if (vdev-&gt;stats)
+			vdev-&gt;free_consistent(vdev-&gt;pdev,
+				sizeof(struct vnic_stats),
+				vdev-&gt;stats, vdev-&gt;stats_pa);
+		if (vdev-&gt;fw_info)
+			vdev-&gt;free_consistent(vdev-&gt;pdev,
+				sizeof(struct vnic_devcmd_fw_info),
+				vdev-&gt;fw_info, vdev-&gt;fw_info_pa);
+		kfree(vdev);
+	}
+}
+
+struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
+	void *priv, struct rte_pci_device *pdev, struct vnic_dev_bar *bar,
+	unsigned int num_bars)
+{
+	if (!vdev) {
+		vdev = kzalloc(sizeof(struct vnic_dev), GFP_ATOMIC);
+		if (!vdev)
+			return NULL;
+	}
+
+	vdev-&gt;priv = priv;
+	vdev-&gt;pdev = pdev;
+
+	if (vnic_dev_discover_res(vdev, bar, num_bars))
+		goto err_out;
+
+	vdev-&gt;devcmd = vnic_dev_get_res(vdev, RES_TYPE_DEVCMD, 0);
+	if (!vdev-&gt;devcmd)
+		goto err_out;
+
+	return vdev;
+
+err_out:
+	vnic_dev_unregister(vdev);
+	return NULL;
+}
+
+struct rte_pci_device *vnic_dev_get_pdev(struct vnic_dev *vdev)
+{
+	return vdev-&gt;pdev;
+}
+
+static int vnic_dev_cmd_status(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
+	int *status)
+{
+	u64 a0 = cmd, a1 = 0;
+	int wait = 1000;
+	int ret;
+
+	ret = vnic_dev_cmd(vdev, CMD_STATUS, &amp;a0, &amp;a1, wait);
+	if (!ret)
+		*status = (int)a0;
+
+	return ret;
+}
+
+int vnic_dev_set_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
+{
+	u64 a0, a1;
+	int wait = 1000;
+	int i;
+
+	for (i = 0; i &lt; ETH_ALEN; i++)
+		((u8 *)&amp;a0)[i] = mac_addr[i];
+
+	return vnic_dev_cmd(vdev, CMD_SET_MAC_ADDR, &amp;a0, &amp;a1, wait);
+}
+
+/*
+ *  vnic_dev_classifier: Add/Delete classifier entries
+ *  @vdev: vdev of the device
+ *  @cmd: CLSF_ADD for Add filter
+ *        CLSF_DEL for Delete filter
+ *  @entry: In case of ADD filter, the caller passes the RQ number in this
+ *          variable.
+ *          This function stores the filter_id returned by the
+ *          firmware in the same variable before return;
+ *
+ *          In case of DEL filter, the caller passes the RQ number. Return
+ *          value is irrelevant.
+ * @data: filter data
+ */
+int vnic_dev_classifier(struct vnic_dev *vdev, u8 cmd, u16 *entry,
+	struct filter *data)
+{
+	u64 a0, a1;
+	int wait = 1000;
+	dma_addr_t tlv_pa;
+	int ret = -EINVAL;
+	struct filter_tlv *tlv, *tlv_va;
+	struct filter_action *action;
+	u64 tlv_size;
+	static unsigned int unique_id;
+	char z_name[RTE_MEMZONE_NAMESIZE];
+
+	if (cmd == CLSF_ADD) {
+		tlv_size = sizeof(struct filter) +
+		    sizeof(struct filter_action) +
+		    2*sizeof(struct filter_tlv);
+		snprintf(z_name, sizeof(z_name), &quot;vnic_clsf_%d&quot;, unique_id++);
+		tlv_va = vdev-&gt;alloc_consistent(vdev-&gt;priv,
+			tlv_size, &amp;tlv_pa, z_name);
+		if (!tlv_va)
+			return -ENOMEM;
+		tlv = tlv_va;
+		a0 = tlv_pa;
+		a1 = tlv_size;
+		memset(tlv, 0, tlv_size);
+		tlv-&gt;type = CLSF_TLV_FILTER;
+		tlv-&gt;length = sizeof(struct filter);
+		*(struct filter *)&amp;tlv-&gt;val = *data;
+
+		tlv = (struct filter_tlv *)((char *)tlv +
+					 sizeof(struct filter_tlv) +
+					 sizeof(struct filter));
+
+		tlv-&gt;type = CLSF_TLV_ACTION;
+		tlv-&gt;length = sizeof(struct filter_action);
+		action = (struct filter_action *)&amp;tlv-&gt;val;
+		action-&gt;type = FILTER_ACTION_RQ_STEERING;
+		action-&gt;u.rq_idx = *entry;
+
+		ret = vnic_dev_cmd(vdev, CMD_ADD_FILTER, &amp;a0, &amp;a1, wait);
+		*entry = (u16)a0;
+		vdev-&gt;free_consistent(vdev-&gt;pdev, tlv_size, tlv_va, tlv_pa);
+	} else if (cmd == CLSF_DEL) {
+		a0 = *entry;
+		ret = vnic_dev_cmd(vdev, CMD_DEL_FILTER, &amp;a0, &amp;a1, wait);
+	}
+
+	return ret;
+}
diff --git a/lib/librte_pmd_enic/vnic/vnic_dev.h b/lib/librte_pmd_enic/vnic/vnic_dev.h
new file mode 100644
index 0000000..407b902
--- /dev/null
+++ b/lib/librte_pmd_enic/vnic/vnic_dev.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2008-2010 Cisco Systems, Inc.  All rights reserved.
+ * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
+ *
+ * Copyright (c) 2014, Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * &quot;AS IS&quot; 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 HOLDER 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.
+ *
+ */
+#ident &quot;$Id: vnic_dev.h 196958 2014-11-04 18:23:37Z xuywang $&quot;
+
+#ifndef _VNIC_DEV_H_
+#define _VNIC_DEV_H_
+
+#include &quot;enic_compat.h&quot;
+#include &quot;rte_pci.h&quot;
+#include &quot;vnic_resource.h&quot;
+#include &quot;vnic_devcmd.h&quot;
+
+#ifndef VNIC_PADDR_TARGET
+#define VNIC_PADDR_TARGET	0x0000000000000000ULL
+#endif
+
+#ifndef readq
+static inline u64 readq(void __iomem *reg)
+{
+	return ((u64)readl(reg + 0x4UL) &lt;&lt; 32) |
+		(u64)readl(reg);
+}
+
+static inline void writeq(u64 val, void __iomem *reg)
+{
+	writel(val &amp; 0xffffffff, reg);
+	writel(val &gt;&gt; 32, reg + 0x4UL);
+}
+#endif
+
+#undef pr_fmt
+#define pr_fmt(fmt) KBUILD_MODNAME &quot;: &quot; fmt
+
+enum vnic_dev_intr_mode {
+	VNIC_DEV_INTR_MODE_UNKNOWN,
+	VNIC_DEV_INTR_MODE_INTX,
+	VNIC_DEV_INTR_MODE_MSI,
+	VNIC_DEV_INTR_MODE_MSIX,
+};
+
+struct vnic_dev_bar {
+	void __iomem *vaddr;
+	dma_addr_t bus_addr;
+	unsigned long len;
+};
+
+struct vnic_dev_ring {
+	void *descs;
+	size_t size;
+	dma_addr_t base_addr;
+	size_t base_align;
+	void *descs_unaligned;
+	size_t size_unaligned;
+	dma_addr_t base_addr_unaligned;
+	unsigned int desc_size;
+	unsigned int desc_count;
+	unsigned int desc_avail;
+};
+
+struct vnic_dev_iomap_info {
+	dma_addr_t bus_addr;
+	unsigned long len;
+	void __iomem *vaddr;
+};
+
+struct vnic_dev;
+struct vnic_stats;
+
+void *vnic_dev_priv(struct vnic_dev *vdev);
+unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev,
+	enum vnic_res_type type);
+void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
+	unsigned int index);
+dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev,
+	enum vnic_res_type type, unsigned int index);
+uint8_t vnic_dev_get_res_bar(struct vnic_dev *vdev,
+	enum vnic_res_type type);
+uint32_t vnic_dev_get_res_offset(struct vnic_dev *vdev,
+	enum vnic_res_type type, unsigned int index);
From huilongx@shecgisg003.sh.intel.com  Wed Feb  4 03:59:14 2015
Return-Path: <huilongx@shecgisg003.sh.intel.com>
Received: from mga11.intel.com (mga11.intel.com [192.55.52.93])
 by dpdk.org (Postfix) with ESMTP id 647EDAD93
 for <dts@dpdk.org>; Wed,  4 Feb 2015 03:59:14 +0100 (CET)
Received: from fmsmga003.fm.intel.com ([10.253.24.29])
 by fmsmga102.fm.intel.com with ESMTP; 03 Feb 2015 18:59:13 -0800
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="4.97,862,1389772800"; d="scan'208";a="449485957"
Received: from shvmail01.sh.intel.com ([10.239.29.42])
 by FMSMGA003.fm.intel.com with ESMTP; 03 Feb 2015 18:45:01 -0800
Received: from shecgisg003.sh.intel.com (shecgisg003.sh.intel.com
 [10.239.29.90])
 by shvmail01.sh.intel.com with ESMTP id t142x9u1003231;
 Wed, 4 Feb 2015 10:59:09 +0800
Received: from shecgisg003.sh.intel.com (localhost [127.0.0.1])
 by shecgisg003.sh.intel.com (8.13.6/8.13.6/SuSE Linux 0.8) with ESMTP id
 t142x7kn018510; Wed, 4 Feb 2015 10:59:09 +0800
Received: (from huilongx@localhost)
 by shecgisg003.sh.intel.com (8.13.6/8.13.6/Submit) id t142x7Tb018506;
 Wed, 4 Feb 2015 10:59:07 +0800
From: "huilongx.xu" <huilongx.xu@intel.com>
To: dts@dpdk.org
Date: Wed,  4 Feb 2015 10:59:05 +0800
Message-Id: <1423018745-18475-1-git-send-email-huilongx.xu@intel.com>
X-Mailer: git-send-email 1.7.4.1
Subject: [dts] [PATCH V3] update framework  for support fortville NIC test
X-BeenThere: dts@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: test suite reviews and discussions <dts.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dts>,
 <mailto:dts-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dts/>
List-Post: <mailto:dts@dpdk.org>
List-Help: <mailto:dts-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dts>,
 <mailto:dts-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Wed, 04 Feb 2015 02:59:14 -0000

execution_fortville.cfg is the test case list for fortville NIC

crb.py, add fortville NIC kernel driver(i40e) in dts

settings.py, add fortville NIC info in dts

test_case.py, insmod and used i40e for fortvill NIC

Signed-off-by: huilongx.xu <huilongx.xu@intel.com>
---
 execution_fortville.cfg |   21 +++++++++++++++++++++
 framework/crb.py        |    8 +++++++-
 framework/settings.py   |    6 ++++++
 framework/test_case.py  |    4 ++++
 4 files changed, 38 insertions(+), 1 deletions(-)
 create mode 100644 execution_fortville.cfg

diff --git a/execution_fortville.cfg b/execution_fortville.cfg
new file mode 100644
index 0000000..15f2ccf
--- /dev/null
+++ b/execution_fortville.cfg
@@ -0,0 +1,21 @@
+[Execution1]
+crbs=<CRB IP Address>
+drivername=<driver name igb_uio or vfio-pci>
+test_suites+    cmdline,
+    hello_world,
+    multiprocess,
+    blacklist
+targets+    x86_64-native-linuxapp-gcc
+parameters=nic_type=fortville_eagle:func=true
+
+[Execution2]
+crbs=<Performance CRB IP Address>
+drivername=<driver name igb_uio or vfio-pci>
+test_suites+    l2fwd,
+    l3fwd
+targets+    x86_64-native-linuxapp-gcc
+parameters=nic_type=fortville_eagle:perf=true
diff --git a/framework/crb.py b/framework/crb.py
index d41f51b..03b9026 100644
--- a/framework/crb.py
+++ b/framework/crb.py
@@ -150,7 +150,11 @@ class Crb(object):
         self.send_expect("modprobe e1000e", "# ", 20)
         self.send_expect("modprobe e1000", "# ", 20)
         self.send_expect("modprobe virtio_net", "# ", 20)
-
+
+        self.send_expect("modprobe i40e", "# ", 60)
+        out = self.send_expect("lsmod |grep i40e", "# ", 30)
+        if "i40e" not in out:
+           self.logger.error("please check the os install i40e driver already.");
         try:
             for (pci_bus, pci_id) in self.pci_devices_info:
                 """
@@ -173,6 +177,8 @@ class Crb(object):
                         self.send_expect("echo -n 0000:%s > /sys/bus/pci/drivers/e1000/bind" % pci_bus, "# ")
                 elif pci_id in ('1af4:1000'):
                     self.send_expect("echo 0000%s > /sys/bus/pci/drivers/virtio-pci/bind" % pci_bus, "# ")
+                elif pci_id in ('8086:1583','8086:1584','8086:1572'):
+                    self.send_expect("echo 0000:%s > /sys/bus/pci/drivers/i40e/bind" % pci_bus, "# ")
                 else:
                     continue

diff --git a/framework/settings.py b/framework/settings.py
index 2ef8db8..40b81fb 100644
--- a/framework/settings.py
+++ b/framework/settings.py
@@ -55,6 +55,9 @@ NICS = {
     'I217LM': '8086:153a',
     'I218V': '8086:1559',
     'I218LM': '8086:155a',
+    'fortville_eagle': '8086:1572',
+    'fortville_spirit': '8086:1583',
+    'fortville_spirit_single': '8086:1584',
 }

 DRIVERS = {
@@ -80,6 +83,9 @@ DRIVERS = {
     'I217LM': 'igb',
     'I218V': 'igb',
     'I218LM': 'igb',
+    'fortville_eagle': 'i40e',
+    'fortville_spirit': 'i40e',
+    'fortville_spirit_single':'i40e'
 }

 """
diff --git a/framework/test_case.py b/framework/test_case.py
index 706003f..07fdc36 100644
--- a/framework/test_case.py
+++ b/framework/test_case.py
@@ -76,5 +76,9 @@ class TestCase(object):
             bitrate *= 10  # 10 Gb NICs
         elif self.nic == "avoton2c5":
             bitrate *= 2.5  # 2.5 Gb NICs
+        elif self.nic in ["fortville_spirit", "fortville_spirit_single"]:
+            bitrate *= 40
+        elif self.nic == 'fortville_eagle':
+		    bitrate *= 10

         return bitrate * num_ports / 8 / (frame_size + 20)
--
1.7.4.4

      reply	other threads:[~2015-01-28  6:39 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-27  5:54 huilongx.xu
2015-01-27  6:40 ` Qiu, Michael
2015-01-27  6:53   ` Xu, HuilongX
2015-01-27  8:46     ` Qiu, Michael
2015-01-28  6:29       ` Xu, HuilongX
2015-01-28  6:39         ` Qiu, Michael [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=533710CFB86FA344BFBF2D6802E60286CC4366@shsmsx102.ccr.corp.intel.com \
    --to=michael.qiu@intel.com \
    --cc=dts@dpdk.org \
    --cc=huilongx.xu@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).